|
|
  |
STM32 USB FS OTG |
|
|
|
Sep 18 2012, 15:11
|
Группа: Участник
Сообщений: 11
Регистрация: 9-09-12
Пользователь №: 73 458

|
Всмысле? Функция hwtx() выше, вызываю её вручную, по команде в UART консоль. Код while(1){ if((USART3->SR & USART_SR_RXNE)){ // data received char c=USART3->DR; //... if(c=='3'){hwtx();} }
|
|
|
|
|
Sep 18 2012, 22:30
|
Группа: Участник
Сообщений: 11
Регистрация: 9-09-12
Пользователь №: 73 458

|
Кажется, чего-то я в этой жизни не понимаю  Из девайса в комп через второй эндпоинт отправляется только один пакет, после чего этот эндпоинт наглухо виснет. Пробовал: 1. Сбрасывать FIFO через регистр GRSTCTL. Как выборочно, так и все. 2. Отключать-включать эндпоинт, ставить CNAK 3. Сбрасывать весь регистр DIEPCTL2 в ноль, и заново конфигурировать 4. Плясать с бубном Идеи закончились. После успешной отправки "Hello world" на комп, второй раз отправить не удаётся. Только перетыкание кабеля срабатывает.
|
|
|
|
|
Sep 19 2012, 15:01
|
Группа: Участник
Сообщений: 11
Регистрация: 9-09-12
Пользователь №: 73 458

|
(Назначение hwtx - слать Hello World. Исключительно для дебага, поэтому упрощена до безобразия) Скорее всего, я упустил что-то важное, но не могу понять что  Для общения через нулевой эндпоинт используется тот же алгоритм, и он работает. Разница только в типах эндпоинтов (control и bulk). И вот с bulk что-то не выходит. Код void hwtx(){ volatile uint32_t * fifo=(uint32_t *)OTG_FS_DFIFO2_BASE; int i; int len=12; char data[]={"Hello world\n"}; pprintf("1. FIFO: %i words free", OTG_FS->DTXFSTS2&0xFFFF); OTG_FS->DIEPTSIZ2=(1<<19)|(len<<0); // PKTCNT; XFRSIZ OTG_FS->DIEPCTL2|=(1UL<<31)|(1<<26); // EPENA; CNAK for(i=0;i<len;i+=4){ *fifo=((data[i+0]&0xFF)<<0)|((data[i+1]&0xFF)<<8)|((data[i+2]&0xFF)<<16)|((data[i+3]&0xFF)<<24); } pprintf("2. FIFO: %i words free", OTG_FS->DTXFSTS2&0xFFFF); }
Сообщение отредактировал SviMik - Sep 19 2012, 15:05
|
|
|
|
|
Sep 22 2012, 22:15
|
Группа: Участник
Сообщений: 11
Регистрация: 9-09-12
Пользователь №: 73 458

|
Я сдаюсь  Можете выложить какой-нибудь минимальный рабочий пример с USB? Или может я выложу свой проект целиком?
|
|
|
|
|
Mar 16 2015, 09:49
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Подниму древнюю тему.
STM32F107, родной стек из Cube напугал множеством лишних телодвижений. Почти 20 К кода за виртуальный COM мне кажется многовато. Пишу свой, запнулся на элементарном - не отсылаются данные (дескриптор). Получаю setup запрос на device descriptor размером 8 байт. Проверяю наличие места в FIFO (DTXFSTS0), там 0x40 слов. Прописываю в DIEPTSIZ0 количество пакетов (PKTCNT) = 1 и размер посылки (XFRSIZ) = 8. Прописываю в FIFO два слова. После записи каждого слова наблюдаю уменьшение на 1 содержимого DTXFSTS0. После записи обоих слов XFRSIZ становится равным нулю, а DTXFSTS0, соответственно, 0x3E. Запускаю обмен (одновременно выставляю CNAK и EPENA в DIEPCTL0). Попадаю в прерывание XFRC, то есть ядро думает, что пакет отправило. При этом PKTCNT становится равен нулю. Но комп посланного дескриптора не видит, а свободное место в FIFO увеличивается всего на одно слово (DTXFSTS0 становится равным 0x3F). Как будто ядро вместо восьми байтов отсылает не более четырех. Родной пример из Cube работает, и если никто не подскажет - буду вставлять отладочный вывод в пример Cube. Но, мало ли, кто-то знает что ему не нравится? Такое ощущение, что ядро при передаче неправильно воспринимает записанный в XFRSIZ размер, но он уменьшается до нуля именно в момент записи в FIFO последнего слова, четко в соотвествии с руководством пользователя. В общем уже третий вечер перечитываю руководство, хожу по шагам по своей программе и по примеру из Cube, вроде все делаю так же, а каменный цветок не выходит хоть тресни. Отсылка пакета нулевого размера (ZLP) после установки адреса проходит нормально.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 17 2015, 23:10
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Сергей Борщ @ Mar 16 2015, 11:49)  Но комп посланного дескриптора не видит, а свободное место в FIFO увеличивается всего на одно слово (DTXFSTS0 становится равным 0x3F). Как будто ядро вместо восьми байтов отсылает не более четырех. Разобрался. Нужно сначала запускать передачу установкой CNAK и EPENA, а уже потом запихивать данные в FIFO. Надо внимательнее читать документацию: Цитата Using one of the above mentioned methods, when the application determines that there is enough space to write a transmit packet, the application must first write into the endpoint control register, before writing the data into the data FIFO.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Apr 7 2015, 09:57
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Ещё разик подниму тему. На эти грабли: https://my.st.com/public/STe2ecommunities/m...rrentviews=1592 никто не наступал? Прикрутил библиотеку libopencm3, сделал из неё HID. Обмен - по нулевому endpoint'у блоками в 32 байта. setup-пакеты ходят нормально, а от data out пропадают первые 4 байта. Странный костыль в библиотеке - добавить тысячу NOP'ов перед считыванием - не помогает. Да и выглядит он некрасиво...
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 8 2015, 13:57
|
Участник

Группа: Участник
Сообщений: 31
Регистрация: 25-09-08
Пользователь №: 40 477

|
Цитата(esaulenka @ Apr 7 2015, 12:57)  Ещё разик подниму тему. На эти грабли: https://my.st.com/public/STe2ecommunities/m...rrentviews=1592 никто не наступал? Прикрутил библиотеку libopencm3, сделал из неё HID. Обмен - по нулевому endpoint'у блоками в 32 байта. setup-пакеты ходят нормально, а от data out пропадают первые 4 байта. Странный костыль в библиотеке - добавить тысячу NOP'ов перед считыванием - не помогает. Да и выглядит он некрасиво... Попробуйте стандартную от st - у меня вполне нормально завелась как CustomHID. Использовал STM32_USB-Host-Device_Lib_V2.1.0 на проце stm32f105, плюс FreeRtos. Делал CAN-USB сниффер - сливать дампы FMS j1939 с грузовиков. На стресс тестах правда пропускной способности USB не хватает - ограничение HID, но не хочется отказываться от использования дефолтных драйверов в windows. И я надеюсь что в реальных условиях такого потока не будет.  Правда на текущий момент есть два "нюанса": 1) Не работает на одном из ноутбуков у сотрудника - устройство обнаруживается, но данные в программу от устройства не поступают. Вполне возможно что проблемы не в либе - ноутбук этот ремонтный. Так же возможно проблема в компоненте HID для lazarus, который я использую в программе на большом брате. Все руки не доходят разобраться. 2) Несколько раз были замечены случаи переподключения устройства - внешне проявляется как будто устройство отключили и сразу подключили. Опять же склоняюсь к мысли, что это не из-за либы. Скорее всего это ошибки в моей реализации остального функционала - похоже что попадаю в HardFault и перегружаюсь по WDT. Проявляется этот глюк крайне редко - пока пытаюсь поймать. libopencm3 мельком смотрел - смутила необходимость в цикличном выполнении функции usbd_poll. В библиотеке от st все callback'и из OTG_FS_IRQHandler дергаются.
|
|
|
|
|
Apr 14 2015, 10:58
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Рекомендацию библиотеки ST спасибо. Знать, что оно таки работоспособно, это хорошо :-) Допилил этот CustomHID из крайней версии CubeMX (он там сломаный, просто куда-то потеряли кусок кода). Да, действительно, работает. Да, действительно, данные не теряет. При сравнении CubeMX и libopencm3 была обнаружена интересная особенность. Как известно, эндпоинт после завершения обмена становится неактивным, и его надо постоянно включать. Авторы libopencm3 делают это при первой же возможности (для OUT-транзакции - сразу после вычитывания из FIFO), а в "родной" библиотеке - после многочисленных действий (обработать пакет, подумать, какой будет следующим, какого он размера...). В итоге, в в libopencm3 в один фрейм попадает и SETUP с указанием "а сейчас будет SET REPORT" и собственно данные этого report'а. Точнее, не все данные, а сдвинутые на 4 байта (и дополненные мусором в конце). Подробности - с фоточками осциллографа (пардон за качество. флешки, которую он поймёт, под рукой нету..) и состоянием регистра прерываний, здесь (кликнуть по картинке, там две страницы). Если по приему setup пакета ничего не делать и не разрешать обратно эндпоинт в течении 1 мс, всё начинает работать корректно. Но меееедленно. Собственно, вопрос: 1) я правильно понимаю, что спецификация USB 2.0 Full Speed не запрещает посылать setup и out в один эндпоинт за один фрейм? 2) у кого-нибудь на этом FS OTG использовал возможность использовать несколько транзакций в одном фрейме? Цитата(johnshadow @ Apr 8 2015, 16:57)  2) Несколько раз были замечены случаи переподключения устройства - внешне проявляется как будто устройство отключили и сразу подключили. Опять же склоняюсь к мысли, что это не из-за либы. Скорее всего это ошибки в моей реализации остального функционала - похоже что попадаю в HardFault и перегружаюсь по WDT. Проявляется этот глюк крайне редко - пока пытаюсь поймать. Возможно, это какие-то "электрические" проблемы. Если рядом есть грузовик, надо рассчитывать, что в любой момент с неожиданной стороны придёт помеха. Цитата(johnshadow @ Apr 8 2015, 16:57)  libopencm3 мельком смотрел - смутила необходимость в цикличном выполнении функции usbd_poll. В библиотеке от st все callback'и из OTG_FS_IRQHandler дергаются. Не понимаю, почему так сделали, но там уже почти всё готово для оборачивания этого poll() в прерывание. Собственно, эта часть заработала почти сразу. Дальше - аналогично, штатными callback'оми (правда, тут они динамические - через указатели).
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|