Представьте: ваш следующий железный проект зависит от чипа, чьи авторы не потрудились написать руководство.
Вот такая закавыка с CH341 и Python. Эта дешёвая USB-заслонка — с ZIF-сокетом и всем остальным — манит I2C, SPI, GPIO в режиме EPP/MEM. Только удачи вам в поисках чего-то кроме тощего даташита. Я прошёл весь этот реверсинг-кроличью нору вместо вас.
CH341 не новичок. Он давно околачивается в программаторах. На первый взгляд пугает. Мало деталей — успокаивает. Ищешь доки. Даташит? Скелет. Руководство по программированию? Ноль. Регистры? Ха.
Драйверы под все ОС есть. А вот код — тут сообщество отрабатывает сполна. Респект репозиторию https://github.com/danguer/pych341 — чистое золото, если лень вникать.
Почему CH341 играет в прятки с тремя гранями?
Назначения пинов переключают зверя между режимами. UART: скучный последовательный порт. Втыкай и молись. PRINT: порт принтера в притворстве. Зевота. EPP/MEM: настоящее дело — мастер I2C, драйвер SPI-слейва, площадка для GPIO. Даже хаки с параллельной памятью, если ностальгия по ретро.
Даташит накидывает схемы пинов. Вагон тумана. Врывается pyusb. Vendor ID 0x1A86, product ID 0x5512. Обнюхиваем эндпоинты. Bulk in, bulk out. Записи в опкод-обёртках; чтение — сырые данные в кайф.
WCH сливает Linux-зип: https://www.wch-ic.com/downloads/CH341PAR_LINUX_ZIP.html. Ведёт к https://github.com/WCHSoftGroup/ch341par_linux. Демо, либа, модуль ядра. Либ зовёт ядро с аргументами. Функций куча — часть для родственных CH347, другие мёртвые. Параллельная память? DOA.
Исходники либы? Классика жанра.
README ведёт к https://github.com/WCHSoftGroup/ch34x_mphsi_master_linux. Чище. I2C через ch341_i2c_stream. Танец пакетов: CH341_CMD_I2C_STREAM на старте, STA для начала, OUT/IN с длинами через OR, STO на стоп, END на финише.
Логика-анализатор подтверждает: STA генерит старт, STO — стоп. Адрес? 7-битный сдвиг, бит R/W прицепом (0 запись, 1 чтение). Без няньки — вы хозяин шины.
Чтобы записать данные на устройство, просто: # отправляем 0xFF на адрес 0xC0 address = 0xC0 data = 0xFF cmd = ( I2CCmd.MODE_STREAM, I2CCmd.START, # сигнал старта I2CCmd.DIR_OUT | 2, # отправляем 1 байт данных плюс 1 байт адреса address << 1, # 7-битный адрес и 0 как бит R/W data, I2CCmd.STOP, # сигнал стопа I2CCmd.END, )
Из оригинального поста. Чисто, в духе Arduino Wire. Чтение? Сначала адрес (R/W=1), потом засасывай байты. Хитро, но pyusb заставляет петь.
Вот в чём дело — мутность WCH отдаёт духом embedded 90-х. Помните битвы по реверсу FT232? То же время. CH341 в том же ключе: сообщество затыкает дыры, рождая либы вроде pych341. Мой вердикт? Бедность доков предвещает бум Python-экосистемы. Дешёвый хакинг железа для бюджетных мейкеров. Смелый прогноз: к 2025-му половина I2C-проектов на Raspberry Pi уйдёт на него, обогнав дорогие FT-штуки.
Сможет ли Python приручить зверя CH341?
Коротко: да. Но с оспинами.
Pyusb ставится на раз. Хватаем девайс, клеймим интерфейс, эндпоинты на прицеле. Записи в опкодах-бандлах; чип разворачивает для шин. SPI? Похожий стрим: режим, делитель частоты, потом поток данных. GPIO? Прямые тычки пинов в MEM-режиме.
Ловушек полно. Несовпадение эндпоинтов валит сессии. Частоты? Даташит шепчет. Осциллограф и проба-эrror. Та “dev”-плата? Идеал для прототипов, стоковые программаторы требуют джамперов.
Либу? Pych341 абстрагирует бардак. Класс I2C в стиле smbus. SPI тоже. Битмаски GPIO. Тестировано на Linux — Windows обходит ядро через user-space pyusb.
Но WCH, почините наконец свои доки. Этот реверс-гринд? Лишняя морока. Корпо-жаргон зовёт это “универсальным”. Я бы сказал — недопечённым.
Копаем глубже: гайд TI по I2C (https://www.ti.com/lit/an/sbaa565/sbaa565.pdf) латкает дыры. Повторные старты в стриме? Хакабельно. Многобайтовое чтение? Цепочка IN-команд.
Рант в абзац: код сообщества — лоскутное одеяло. Ch341par_linux мешает C-либу с ядро-хаками, pych341 сияет чистым Python. Выбирайте яд.
Зачем ковыряться в этом чипе-изгое в 2024-м?
Цена. Платы за 2-5 баксов рвут ESP32 в USB-мос