Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Переподключение USB VCP для stm32f105
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Still Enemy
Дано: есть ПЛИС на базе МК stm32105. К ней прикручен usb, программно поднят cdc по примерам от st и допилены операции приёма/передачи. В неопределённый момент usb кабель выдергивается(возможно даже в момент передачи/приёма, но это не суть). Через некоторое время подключается обратно.
Найти:
1)как программно отлавливать отключение usb кабеля? что при этом не плохо бы сделать?
2)как собственно программно отлавливать обратно подключенный кабель?
Still Enemy
Вообще ни у кого ни одной идеи нет? Никто не сталкивался с такой проблемой?
smalcom
VBUS вообщето пропадает.
toweroff
Цитата(smalcom @ Mar 14 2015, 23:11) *
VBUS вообщето пропадает.

если куда нужно подключен wink.gif
а то просто на питание вешают
A. Fig Lee
В ст шной библиотеке есть ивенты и на дисконнект и на ресет и так далее
toweroff
Цитата(A. Fig Lee @ Mar 15 2015, 02:38) *
В ст шной библиотеке

для филпсов не видел...
error, sof, reset, power, suspend, resume... disconnect не видел
корки разные, но события-то должны быть? покажите
Still Enemy
Цитата(A. Fig Lee @ Mar 15 2015, 02:38) *
В ст шной библиотеке есть ивенты и на дисконнект и на ресет и так далее

Хорошо, я глянул в дебаге как что происходит при отключении/включении кабеля
1 подключение кабеля: после прерывания почему то сваливается в Handle Suspend Interrupt, затем Handle Reset Interrupt->Handle Enumeration done Interrupt->Handle Reset Interrupt->Handle Enumeration done Interrupt. Всё хорошо, устройство определилось
1 отключение кабеля: кидает USBSUSP в регистре OTG_FS_GINTSTS и собственно обрабатывается Handle Suspend Interrupt.
2 подключение: Handle Suspend Interrupt->Handle Reset Interrupt->Handle Enumeration done. Но устройство не определяется как положено, а висит как Unknown Device.
Все последующие подключения/отключения никаких прерываний не кидают.
И тут самое интересное, что в обработчике прерываний есть Handle Connection event Interrupt и Handle Disconnection event Interrupt, но в эти обработчики программа не попадает за всё то время, в которое я делал эти манипуляции.
Если вы знаете, что есть эти ивенты, то возможно вы знаете как ими пользоваться? Знаете почему при отключении сваливается в Handle Suspend Interrupt. Расскажите пожалуйста или скажите как поправить, что бы всё работало.
Still Enemy
Я полазил по коду. В обработчик Connection/Disconnection event Interrupt программа в действительности и не может пройти, ибо замаскированы SRQINT и OTGINT. Хотя собственно эти обработчики, кроме как сброс бита прерывания, ничего не делают.
Почему входит в Suspend mode тоже понятно:
Цитата
Выдержка из usb nutshell.
Вход в Suspend Mode
Устройство USB приостанавливается (переходит в режим Suspend), когда на шине нет активности более чем 3.0 мс. В течение следующих 7 мс устройство должно отключиться, и не потреблять ток больше, чем заданный ток suspend. Таким образом, через 10 мс после прекращения активности шины ток потребления от неё не должен превышать suspend current. Для поддержания состояния соединения к приостановленному хабу или хосту, устройство во время режима Suspend должно все еще предоставлять питание на pull up нагрузочный резистор, определяющий выбор скорости.

Но всё равно не понятно чего не хватает устройству для работы... Почему то при повторном подключении кабеля обрабатывается один раз Handle Reset Interrupt->Handle Enumeration done, а не два раза как при первом соединении. Хотя почему кидает USBSUSP при первом подключении кабеля, так и не стало ясно. Так же почему то перестало кидать прерывание USBSUSP при отключении кабеля, чудеса... И еще не понятно, почему не формируются прерывания при подключении/отключении кабеля после второго подключения кабеля. Вопросов много, ответов нет...
toweroff
А устройство после отключения кабеля остается с включенным Pullup к D+? Возможно, там собака порылась
Still Enemy
Цитата(toweroff @ Mar 16 2015, 18:05) *
А устройство после отключения кабеля остается с включенным Pullup к D+? Возможно, там собака порылась

Возможно, завтра попробую на работе. Но в usb nutshell написано обратное. Или я не правильно понял?
Цитата
Выдержка из usb nutshell.
Вход в Suspend Mode
Устройство USB приостанавливается (переходит в режим Suspend), когда на шине нет активности более чем 3.0 мс. В течение следующих 7 мс устройство должно отключиться, и не потреблять ток больше, чем заданный ток suspend. Таким образом, через 10 мс после прекращения активности шины ток потребления от неё не должен превышать suspend current. Для поддержания состояния соединения к приостановленному хабу или хосту, устройство во время режима Suspend должно все еще предоставлять питание на pull up нагрузочный резистор, определяющий выбор скорости.
Still Enemy
Цитата(toweroff @ Mar 16 2015, 18:05) *
А устройство после отключения кабеля остается с включенным Pullup к D+? Возможно, там собака порылась

Пробовал софтварно отключать подтяжку, после отключения кабеля кидает HardFault_Handler в startup_stm32f105xc.s
smalcom
во. значит по событию ПО пытается вызвать неопределённый обработчик.
Still Enemy
Цитата(smalcom @ Mar 18 2015, 12:13) *
во. значит по событию ПО пытается вызвать неопределённый обработчик.

Я на самом деле просто делал видимо не правильно. Я подтяжку вырубал с помощью регистра GCCFG и сбрасывал бит VBUSBSEN. После чего вылетало Hard Fault.
Я почитал, правильно было сбрасывать потяжку софтаврным дисконектом в регистре DCTL выставлял единицу в бит SDIS. Ничего не поменялось кароч.
Still Enemy
Хочу поднять старую тему, ибо я решил проблему. Может быть это кому и поможет.
Не знаю как у других, но у меня вылетал Hard Fault, после функции free(), собственно сразу же после повторного присоединения кабеля.
Так что её тупо надо закомментить, потому как она смысловой нагрузки не несёт(только отрицательную нагрузку).
Вызов этой функции лежит в usbd_cdc.c в функции USBD_CDC_DeInit:
Код
static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev,
                                 uint8_t cfgidx)
{
  uint8_t ret = 0;
  
  /* Open EP IN */
  USBD_LL_CloseEP(pdev,
              CDC_IN_EP);
  
  /* Open EP OUT */
  USBD_LL_CloseEP(pdev,
              CDC_OUT_EP);
  
  /* Open Command IN EP */
  USBD_LL_CloseEP(pdev,
              CDC_CMD_EP);
  
  
  /* DeInit  physical Interface components */
  if(pdev->pClassData != NULL)
  {
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
    //USBD_free(pdev->pClassData);
    pdev->pClassData = NULL;
  }

Примерно так должно быть.
Причина глюка проста: по задумке разработчиков HAL драйверов, указатель pdev->pClassData должен освобождаться из динамической памяти функцией free, хотя никакими функциями типа calloc, malloc память не выделялась. Да и вообще в данных драйверах никакого управления памятью нет. Так что будет достаточно строчки pdev->pClassData = NULL, чтобы всё работало!
Сергей Борщ
Нет, так лучше не чинить. Если потом все же по каким-то причинам захочется динамического выделения, то пользователь пойдет править USBD_malloc и USBD_free, не подозревая, что вызов USBD_free закоменнтирован. И получит утечку памяти. Так что лучше закомментировать вызов free(). Ну а то, что останется вызов лишней пустой функции - так такого Г в этом коде навалом, никто и не заметит несколько лишних байтов.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.