2020-11-09

eddy_em: (Default)
2020-11-09 09:27 pm

Нафиг не нужная поделка

Зашел на одном из форумов спор, что невозможно поднять (N-1) устройство CDC-ACM на микроконтроллере с N концевыми точками (N<=8). ОК, держите СЕМЬ CDC на одном устройстве.
Правда, я стал реализовывать это на STM32F103, подзабыв, какое он Г по сравнению с нулевой серией. А ведь там буфер под USB — всего-то 512 байт! Из них 64 уже занято описанием конечных точек плюс минимум 16 байт надо выделить на EP0. Получается 61 с небольшим байт на каждое устройство. Ближайшее круглое число — 32, так что пришлось буферы Rx/Tx каждого CDC урезать до 16 байт. Дескриптор конфигурации — просто ад! В полпервого ночи я его с первой попытки правильно заполнить не осилил (хоть и выделил те места, в которые нужно вносить изменения). Таки нужно такие вещи автоматом генерировать. Как же это работает без INTERRUPT IN? Да очень просто: я еще когда лепил эмуляцию PL2303, обратил внимание на то, что вообще никогда хост не работает с этой конечной точкой. И ее можно даже не инициализировать! Но, однако, она должна быть указана в дескрипторе. Как победить ситуацию? Ответ увидел где-то на SO или забугорном форуме: нужно просто указывать "виртуальную" конечную точку. На STM32F103/0x2 всего 8 конечных точек, а стандарт USB допускает использование шестнадцати. Следовательно, т.к. у нас EP0 занята, остается еще 7 конечных точек. Каждую настраиваем как INOUT (и в обработчике не забываем, что и на IN, и на OUT необходимо выставлять Tx valid — я с этим уже немного потупить успел), а вот для INTERRUPT IN указываем несуществующие точки, начиная с номера восемь!
Понятно, что всякие обработчики вроде SET_CONTROL_LINE_STATE использовать для выставления флага установленного соединения нельзя: ведь теперь аж 7 независимых каналов! И каждый работает с этой EP0. Поэтому писать приходится постоянно в каждый канал (разве что можно поставить флажок, что канал пока что не активен; а потом не писать в этот канал, пока не получим прерывание IN, в нем флажок и сбросим; но мне такой вариант городить лень было).
Пока могу лишь одно применение этой штуке придумать: когда я делал хронометр, меня просили сделать возможным подключение "малинки" для проксирования на нее данных с GPS. Либо этот UART можно было использовать как отладку. С таким диким устройством можно все в один USB запихать ☺ Только перейти на более вменяемый микроконтроллер (может, на 303?).