Страница 1 из 2
STM32 USB на регистрах
Добавлено: Ср авг 13, 2025 12:25:48
Cliff
Здравствуйте. Есть ли тут гуру, у кого есть успехи в USB на регистрах на stm32?
Конкретно чип stm32g474ceu6
Необходимо реализовать CDC (Serial Com)
В качестве базиса взял Middleware библитеку от ST, хоть там и крайне сложно разобраться из-за многочисленных переходов между разными модулями (HAL, LL, PCD и т.д.). Так же долго курил Reference Manual от ST и Документацию по USB протоколу в разных нарезках.
Первая проблема, с которой столкнулся: нигде нет рекомендованного процесса обработки запросов от хоста к устройству. С дебагом тоже сложно, т.к. таймауты на ответы очень маленькие.
Чего добился в своих изысканиях - полностью проходит инициализация:
- все дескрипторы пересылаются
- в списке USB устройств на хосте устройство появляется с нужными описаниями
- serial-порт в системе есть
- при подключении к serial-порту проходят стадии CDC_SET_CONTROL_LINE_STATE и CDC_SET_LINE_CODING, параметры передачи получаю
Т.к. я делал на базе Middleware от ST, двойную буферизацию не использовал, применены две доп точки:
- ID=1 - Data = Bulk-type, in/out, размер буфера 64 байта
- ID=2 - Notify = interrupt, 8 байт, передача только в сторону хоста.
Но вот при попытке передачи данных начались проблемы. Отправку в сторону хоста вообще не понял, как отладить.
При отправке с хоста на устройство возникли две проблемы, пояснения по которым и прошу от гуру:
1. Прерывание USB_ISTR_CTR возникает, но получается ситуация, когда указанная в ISTR конечная точка точка в своём регистре не имеет битов RX/TX/SETUP, а напрямую бит CTR в регистре ISTR не снимается. Это делается только через снятие битов RX/TX/SETUP у конечной точки. Если игнорировать ситуацию, обработчик прерываний постоянно вызывается, пока есть флаг USB_ISTR_CTR.
В цикле проверил другие точки, там есть те, у которых данные биты установлены. Обработка таких точек со снятием RX/TX/SETUP решило проблему с флагом USB_ISTR_CTR, однако уткнулся во вторую проблему.
2. Решив костыльно проблему-1, получил запуск обработки RX (от хоста к устройству) для Data-точки (ID=1), однако, читаю RX-регистр этой точки и вижу там значение: 0x84c4.
Согласно документации:
- 0x84 относится к размеру буфера и соответствует 64 байт (это то, что я сам указал).
- 0xc4 - это размер данных = 196 байт, т.е. получается исходно некорректное значение.
Пробовал уменьшать размер буфера до 32 байт, верхний байт RX-буфера меняется корректно, а нижний остаётся 0xc4.
Подозреваю, что это всё ещё следствие первой проблемы. А первая проблема - следствие ещё более ранне ошибки. Только вот уже перестал понимать, в какую сторону копать. ИИ вообще на серьёзных щах утверждает, что проблема-1 - это вообще стандартная ситуация и её именно так надо решать, и что мол об этом даже ST говорит. Но таких утверждений от ST я не нашёл в интернетах, а в Middleware никаких подобных костылей тоже нет.
Re: STM32 USB на регистрах
Добавлено: Ср авг 13, 2025 16:04:33
HardWareMan
Я сейчас тоже "распрямляю" реализацию ST. Почти заработало, правда на данным момент только под STM32F1xx. Такая сложная реализация у них только из-за универсальности: там подключаются калбэки для обработки нужного железа (FS/HS CORE), подключаются калбэки нужного класса и т.д. Двойная и тройная буферизация. А ещё, что мне не нравится, бесконтрольные скрытые объекты в ОЗУ, я люблю контролировать распил ОЗУ. Я пару раз просто выносил эти объекты в свою структуру и пробрасывал указатели на них в недра этого бардака, но потом просто достало и решил для себя сделать прозрачный простой монолитный вариант. Кстати, до HAL был StdPeriph и у него не было поддержки USB (у HAL это внутри PCD и USB), поэтому тогда реализация USB была более прозрачной, а сейчас имеем что имеем.
Re: STM32 USB на регистрах
Добавлено: Ср авг 13, 2025 19:47:51
Cliff
[uquote="HardWareMan",url="/forum/viewtopic.php?p=4738376#p4738376"]Такая сложная реализация у них только из-за универсальности[/uquote]
Да, я это хорошо понимаю. По той же причине этим занялся.Очень уж там чрезмерно ветвистые деревья и переходные процессы между разными библиотеками.
Дайте знать, как получится! Прям очень интересно. USB в F1 на базовом уровне, вроде б, не отличается от G4.
Я пока что сейчас делаю отладку состояний регистров, сравнивая их в рабочем варианте от ST и своём.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 09:12:17
HardWareMan
У меня, кстати, есть USB Custom HID на Паскале. Отлично работает, результат такого же распрямления юзером под ником Pelikan с форума mikroe. Я его адаптировал для 437 в прошлом и даже переключал между USB FS и USB HS. Можете его просто перекрасить в C, например, если надо.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 10:36:19
nibelung
[uquote="Cliff",url="/forum/viewtopic.php?p=4738297#p4738297"]С дебагом тоже сложно, т.к. таймауты на ответы очень маленькие.[/uquote]
Прежде чем начинать разбираться с USB, желательно разобратся, чем и как вы отлаживаете. ST-Link для этой цели не очень подходит - вывод отладочной информации через SWO ломает логику работы USB контроллера. В последовательный порт можно выводить только буфер через DMA, иначе, тоже ломается логика. Точка останова в обработчике прерываний настоящее содержимое регистров не покажет, чтобы его посмотреть нужно до остановки копировать содержимое регистров в глобальные переменные.
Полгода назад пилил совой стек для G474 на регистрах, в библиотеке от ST подсмотрел только инициализацию USB контроллера до первого прерывания по RESET, немного его не доделал. Отладчик J-Link, в проект подключен отладочный вывод через SEGGER RTT. Никаких чудес в работе не заметил, все как по даташиту.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 16:50:26
jcxz
[uquote="Cliff",url="/forum/viewtopic.php?p=4738297#p4738297"]Здравствуйте. Есть ли тут гуру, у кого есть успехи в USB на регистрах на stm32?[/uquote]Есть.
Добавлено after 4 hours 34 minutes 6 seconds:
[uquote="nibelung",url="/forum/viewtopic.php?p=4738554#p4738554"]В последовательный порт можно выводить только буфер через DMA, иначе, тоже ломается логика.[/uquote]С этим не согласен. С DMA может быть лучше, но не факт.
В одном проекте отлаживал работу USB-стека со сниффером (событий и USB-кадров) в UART - никаких проблем. Всё обошлось без DMA, с обычным выводом в UART по прерываниям.
Если руки кривые - то и DMA не поможет их выпрямить, а если умеючи - то DMA не обязателен.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 17:01:42
HardWareMan
В качестве прямо экстремального варианта можно выделить один порт на выдачу 8 или 16 битных данных и собирать их через LA. При этом стоимость будет всего лишь в одной команде вывода в регистр ODR.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 18:08:03
jcxz
[uquote="HardWareMan",url="/forum/viewtopic.php?p=4738647#p4738647"]В качестве прямо экстремального варианта можно выделить один порт на выдачу 8 или 16 битных данных и собирать их через LA. При этом стоимость будет всего лишь в одной команде вывода в регистр ODR.[/uquote]Это чуть лучше, чем отлаживать USB посредством мигающего светодиода.
Но зачем так жёстко-то? UART вполне нормально справляется с такой задачей.
Вот вывод USB-сниффера моего текущего проекта во время энумерации:
Спойлер

Поток строк, начинающихся с "UDBG." выплёвывается в UART во время USB-энумерации на 921600 бод. Это расшифровка операций, выполняемых USB-стеком. Конечно это работает с буферизацией в ОЗУ МК. Но работает как видно и без DMA прекрасно. А для современных МК размер ОЗУ-буфера в ~8...16 КБ - как правило не является проблемой.
Расшифровка всех USB-кадров выполняется в МК. И весь обмен виден наглядно. Отлаживаться удобно.
Если обмен по USB не очень интенсивный, то и после энумерации (при нормальной работе) этот снифер успевает всё прокачивать.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 18:26:56
nibelung
[uquote="jcxz",url="/forum/viewtopic.php?p=4738670#p4738670"]Конечно это работает с буферизацией в ОЗУ МК. Но работает как видно и без DMA прекрасно.[/uquote]
Согласен, ключевое слово здесь буферизация, а как будет выводиться буфер по прерываниям или через DMA это уже кому как удобно.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 19:47:21
HardWareMan
[uquote="jcxz",url="/forum/viewtopic.php?p=4738670#p4738670"]Но зачем так жёстко-то? UART вполне нормально справляется с такой задачей.
Вот вывод USB-сниффера моего текущего проекта во время энумерации:[/uquote]
А мне такие выкрутасы не нужны, у меня аппаратный снифер есть. Поэтому, отладка USB на каком-нибудь STM32F042 вполне реально для меня.

Я его показывал на
соседнем форуме, если кому интересно. С фоточками кишочков. Ну а на безрыбье да, UART вполне годен при наличии достаточного количества ОЗУ.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 19:52:17
Cliff
Спасибо большое, что откликнулось столько народу.
Проблему решил. Первое сообщение можно игнорировать, всё там описанное не актуально. Бага оказалась в адресации регистров точек. Причём, настолько хорошо замаскировалась, что найти её не мог несколько недель, при всех вариациях отладки и сёрфинга по коду. Получилось, что data-point не была настроена совсем, хотя "всё говорило об обратном". Это при том, что подозрения на криво настроенную data-точку были приоритетными и этому уделялось много времени.
Сейчас всё работает, данные передаются в обе стороны. Такую цену за настолько мелкую помарку я ещё не платил, танцую уже второй час.
Зато перебрал много разных подходов к реализации обработки setup-запросов, в связи с чем у меня всё-таки есть несколько вопросов:
1. Правильно ли я понимаю, что по завершению обработки любого setup-запроса от хоста, включая data-stage, может быть только три варианта:
- отправляем пустой пакет хосту (ок)
- отправляем данные хосту (если он их хочет)
- отправляем stall (выставлением stat-битов в регистре точки-0)
Игнорировать запросы не стоит, но при этом нужно обработать STD_POINT_CLEAR_FEUTURE, в котором снять stall.
Так?
2. stall-биты выставляем на RX или TX в зависимости от старшего бита в bmRequestType? Тут я так и не разобрался. Внутри ST там в каких-то ситуаций ставится только RX/TX, а в коких-то сразу оба. Логики я не понял.
3. В ST-библиотеке, как я понял, для точки-0 реализован принцип: сначала принимаем запрос полностью, оставляем RX-NAK, выполняем отправку ответа на хост, и только в TX-прерывании выставляем RX-VALID. Т.е. фазы приёма и передачи жёстко разделены. Является ли эта логика рекомендованной? Или можно сразу после обработки setup-пакета выставлять RX-VALID и дальше уже делать что хочется (отправлять, stall и т.д.), т.е. приём и передача параллелятся, как для остальных точек.
Кто как реализует?
4. Есть ли разница при обработке CTR-прерывания для точки-0 ориентироваться только на SETUP+CTR_RX/CTR_TX или ISTR_DIR + SETUP/CTR_RX. У ST реализован второй вариант и я решил остановиться на том же. Но видел у разных блогеров разные подходы. Есть какие-то рекомендации?
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 20:03:18
jcxz
[uquote="HardWareMan",url="/forum/viewtopic.php?p=4738725#p4738725"]А мне такие выкрутасы не нужны, у меня аппаратный снифер есть. Поэтому, отладка USB на каком-нибудь STM32F042 вполне реально для меня.
форуме, если кому интересно. С фоточками кишочков. Ну а на безрыбье да, UART вполне годен при наличии достаточного количества ОЗУ.[/uquote]Аппаратный сниффер хорош когда USB-стек уже отлажен. Кем-то. И работает правильно. Но тема-то "USB на регистрах". Т.е. как я понимаю - "своими руками".
Вот отлаживаете вы свой USB-стек, и не понимаете чего-то в работе внутренних регистров USB-периферии (потому как в мануале описано оно часто - из рук вон). Что-то работает не так, как вы ожидали. И вы хотите понаблюдать поведение каких-то полей регистров USB в реальном времени - во время обмена по USB. Как вам поможет ваш аппаратный сниффер? Очевидно - никак. И JTAG тут - слабый помощник (как уже отметили выше).
А в свой сниффер я запросто добавлю захват интересующего меня регистра или переменной в нужном месте работы программы. И всё сразу увижу.
Так что это внешний аппаратный сниффер - "на безрыбье".

Аппаратный сниффер есть и у меня. Но если бы он помогал
в отладке своего USB-стека - я бы свой сниффер не писал бы.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 20:23:07
Nranddek
кстати, во какой нашёл (у меня нет аппаратного, решил полазить)
"USB-анализатор протокола USB-снайпер USB-инструмент анализа данных адаптированный к Wireshark"
https://aliexpress.ru/item/1005009237087361.html однако, он в три-четыре раза дешевле (и проще), чем у
HardWareMan, что несколько смущает...
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 20:36:11
jcxz
[uquote="Cliff",url="/forum/viewtopic.php?p=4738728#p4738728"]1. Правильно ли я понимаю, что по завершению обработки любого setup-запроса от хоста, включая data-stage, может быть только три варианта:[/uquote]Что такое "setup-запрос" - я не знаю, но data-stage setup-транзакции всегда передаётся от хоста к ведомому. А значит - никакие данные к хосту в ней отправить вы не можете. И квитируется setup-транзакция как правило - автоматически самой USB-периферией (а не программным USB-стеком). Т.е. - если USB-периферия проинициализирована, то она сама автоматически отправит ACK на setup-транзакцию. Для отправки данных ведомый->хост (после setup-транзакции) хост, если нужно, инициирует следующую IN-транзакцию. В которой ведомый и может отправить свои ответные данные.
Также и пакеты квитирования - есть: ACK, NACK, STALL. (в USB_HS ещё есть дополнительные)
[uquote="Cliff",url="/forum/viewtopic.php?p=4738728#p4738728"]Кто как реализует?[/uquote]Советую почитать документацию на USB-шину. Чтобы знать что такое: пакеты, транзакции и пр.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 20:38:53
HardWareMan
jcxz, по внешнему поведению часто достаточно понимания, что не так внутри. Хотя, конечно, у каждого свои фломастеры.
Nranddek, есть такой прибор, да. Это клон опенсурсного варианта, причём на том же алике есть ещё дешевле. Вот
исходный проект.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 20:46:23
jcxz
[uquote="HardWareMan",url="/forum/viewtopic.php?p=4738742#p4738742"]
jcxz, по внешнему поведению часто достаточно понимания, что не так внутри. Хотя, конечно, у каждого свои фломастеры.[/uquote]Эх! где-ж вы были, когда я свой USB-стек отлаживал. И спрашивал о поведении непонятных мне регистров USB на форумах, и никто не мог подсказать.
Только этот сниффер и подсказал.
"По внешнему поведению" - это примерно как диагностировать и лечить больного, основываясь только на внешних проявлениях болезни - цвете мочи и густоте кала.

Далеко не каждую болезнь можно победить не заглядывая внутрь больного. Чаще всего необходимо на внутренние
органы регистры посмотреть.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 22:09:40
nibelung
Cliff
1 - в общем верно. Если девайс может обработать сетуп - отвечает ZLP или данными. Если не может обработать сетуп - выставляет STALL. Снимать STALL программно не нужно, для EP0 STALL снимается аппаратно при получении от хоста SOF. CLEAR_FEATURE от хоста приходит с адресом ендпоит 1..n вот для указного ендпоинта и нужно снимать STALL программно.
2 - логику я тоже не понял, поэтому всегда ставлю STALL и на RX и на TX.
3 - В режиме CONTROL ендпоинт работает по принципу запрос - ответ, пока девайс не ответит на запрос хоста очередного запроса не будет, поэтому работать будет любой из двух методов. Я, чтобы не плодить сущностный, EP0 обрабатываю ровно также как и остальные.
4 - второй вариант, потому, что он эффективнее по коду.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 23:10:35
Cliff
jcxz, вспоминаю себя в мои 18-25, когда я один умный, а кругом одни д....
конечно же я это всё изучил и прекрасно понимаю, о чём вы. Меня интересует работа с протоколом в связке с аппаратной реализацией в stm32.
nibelung, большое спасибо! максимально чётко и по делу! Все вопросы отпали.
Re: STM32 USB на регистрах
Добавлено: Чт авг 14, 2025 23:38:10
Adrift
[uquote="Cliff",url="/forum/viewtopic.php?p=4738728#p4738728"]2. stall-биты выставляем на RX или TX в зависимости от старшего бита в bmRequestType? Тут я так и не разобрался. Внутри ST там в каких-то ситуаций ставится только RX/TX, а в коких-то сразу оба. Логики я не понял.[/uquote]
Я переделывал ST-ую либу и оба там выставляются только в функции ctrlError(), не помню как она в оригинале называлась.
Re: STM32 USB на регистрах
Добавлено: Пт авг 15, 2025 08:43:56
azhel12
У уважаемого COKPOWEHEU на хабре есть цикл статей по теме, так и называются "USB на регистрах: XXXX", крайне рекомендую.