gab 0 22 сентября, 2020 Опубликовано 22 сентября, 2020 · Жалоба Собственно, вот и вся проблема. :( Внешний кварц 16МГц. Осциллограф показывает 16МГц. Через mcuconf.h настроил тактирование. Вроде всё верно. #define STM32_NO_INIT FALSE #define STM32_PVD_ENABLE FALSE #define STM32_PLS STM32_PLS_LEV0 #define STM32_HSI_ENABLED TRUE #define STM32_LSI_ENABLED TRUE #define STM32_HSE_ENABLED TRUE #define STM32_LSE_ENABLED FALSE #define STM32_SW STM32_SW_PLL #define STM32_PLLSRC STM32_PLLSRC_HSE #define STM32_PREDIV_VALUE 2 // 16MHZ HSE -> 72MHZ SYSCLK #define STM32_PLLMUL_VALUE 9 #define STM32_HPRE STM32_HPRE_DIV1 // 72MHz AHB #define STM32_PPRE1 STM32_PPRE1_DIV2 // 36MHz APB1 #define STM32_PPRE2 STM32_PPRE2_DIV2 // 72MHz APB2 #define STM32_MCOSEL STM32_MCOSEL_NOCLOCK #define STM32_ADC12PRES STM32_ADC12PRES_DIV1 Программа стартует, отрабатывает следующий код: sduObjectInit(&SDU1); sduStart(&SDU1, &serusbcfg); usbDisconnectBus(serusbcfg.usbp); chThdSleepMilliseconds(1500); usbStart(serusbcfg.usbp, &usbcfg); usbConnectBus(serusbcfg.usbp); И навечно остаётся в следующем коде, моргая светодиодом: while (SDU1.config->usbp->state != USB_ACTIVE) { led_toggle(STATUS_LED); chThdSleepMilliseconds(500); } в обработчике: static void usb_event(USBDriver *usbp, usbevent_t event) { extern SerialUSBDriver SDU1; switch (event) { case USB_EVENT_ADDRESS: return; case USB_EVENT_CONFIGURED: chSysLockFromISR(); /* Enables the endpoints specified into the configuration. Note, this callback is invoked from an ISR so I-Class functions must be used.*/ usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config); usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config); /* Resetting the state of the CDC subsystem.*/ sduConfigureHookI(&SDU1); chSysUnlockFromISR(); return; case USB_EVENT_RESET: /* Falls into.*/ case USB_EVENT_UNCONFIGURED: /* Falls into.*/ case USB_EVENT_SUSPEND: chSysLockFromISR(); /* Disconnection event on suspend.*/ sduSuspendHookI(&SDU1); chSysUnlockFromISR(); return; case USB_EVENT_WAKEUP: chSysLockFromISR(); /* Connection event on wakeup.*/ sduWakeupHookI(&SDU1); chSysUnlockFromISR(); return; case USB_EVENT_STALLED: return; } return; } несколько раз дёргается USB_EVENT_RESET, после USB_EVENT_SUSPEND и всё. Событие USB_EVENT_CONFIGURED никогда не приходит. Операционка говорит, что не может прочитать дескриптор устройства. Резистор подтяжки есть. По шине что-то дёргается. Уже не знаю куда копать. :( Update: В режиме DFU определяется системой нормально. Т.е. физический канал USB - рабочий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AleksBak 0 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба 14 часов назад, gab сказал: Уже не знаю куда копать. :( А Вы CubeMX используете? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gab 0 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба Нет. Мэйкфайлы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба 15 часов назад, gab сказал: несколько раз дёргается USB_EVENT_RESET, после USB_EVENT_SUSPEND и всё Надо ставить точку останова в обработчике и смотреть, есть ли запросы к EP0 и корректно ли они отрабатываются. Именно через нее читаются дескрипторы. Но надо быть готовым к тому, что на этапе конфигурации каждая остановка в обработчике вызовет ошибку на шине. То есть на момент остановки у вас в отладчике должны быть открыты нужные регистры, вы смотрите их содержимое и перезапукаете программу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gab 0 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба Так не доходит до конфигурации. Точка останова стоит на "usb_event". Ещё один момент. на чипе написано STM32F302C8T6 или CBT6, трудно разглядеть. А пишет: Info : device id = 0x10036422 Info : flash size = 128kbytes Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба 58 минут назад, gab сказал: Так не доходит до конфигурации. Точка останова стоит на "usb_event". usb_event() - это не обрабтчик прерывания USB, а некая функция, которая вызывается при возникновнии в программе каких-то событий. Вас же должен интересовать обработчик прерывания, который занимается всей "грязной работой". P.S. а на каком языке у вас название города в профиле написано? Просто любопытно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gab 0 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба Вот определение: /** * @name Low level driver helper macros * @{ */ /** * @brief Common ISR code, usb event callback. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] evt USB event code * * @notapi */ #define _usb_isr_invoke_event_cb(usbp, evt) { \ if (((usbp)->config->event_cb) != NULL) { \ (usbp)->config->event_cb(usbp, evt); \ } \ } event_cb и есть этот usb_event. Ещё есть usb_serve_endpoints, но он не вызывается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба 9 минут назад, gab сказал: event_cb и есть этот usb_event. Да хоть горшком назовите. При возникновении аппаратного события USB ядро вызывает обработчик прерывания, адрес которого записан в векторе 0x0000 0168 (USB High priority interrupt) или 0x0000 016C (USB Low priority interrupt). Вот ту функцию, которая называется USB_чего-то-там_Handler() и указатель на которую вы или ваша библиотека записали в соответствующий вектор, вам и надо смотреть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gab 0 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба OSAL_IRQ_HANDLER(STM32_USB1_LP_HANDLER) { uint32_t istr; USBDriver *usbp = &USBD1; OSAL_IRQ_PROLOGUE(); istr = STM32_USB->ISTR; /* USB bus reset condition handling.*/ if (istr & ISTR_RESET) { STM32_USB->ISTR = ~ISTR_RESET; _usb_reset(usbp); } /* USB bus SUSPEND condition handling.*/ if (istr & ISTR_SUSP) { STM32_USB->CNTR |= CNTR_FSUSP; #if STM32_USB_LOW_POWER_ON_SUSPEND STM32_USB->CNTR |= CNTR_LP_MODE; #endif STM32_USB->ISTR = ~ISTR_SUSP; _usb_suspend(usbp); } /* USB bus WAKEUP condition handling.*/ if (istr & ISTR_WKUP) { uint32_t fnr = STM32_USB->FNR; if (!(fnr & FNR_RXDP)) { STM32_USB->CNTR &= ~CNTR_FSUSP; _usb_wakeup(usbp); } #if STM32_USB_LOW_POWER_ON_SUSPEND else { /* Just noise, going back in SUSPEND mode, reference manual 22.4.5, table 169.*/ STM32_USB->CNTR |= CNTR_LP_MODE; } #endif STM32_USB->ISTR = ~ISTR_WKUP; } /* SOF handling.*/ if (istr & ISTR_SOF) { _usb_isr_invoke_sof_cb(usbp); STM32_USB->ISTR = ~ISTR_SOF; } /* Endpoint events handling.*/ while (istr & ISTR_CTR) { usb_serve_endpoints(usbp, istr & ISTR_EP_ID_MASK); istr = STM32_USB->ISTR; } OSAL_IRQ_EPILOGUE(); } Вот весь обработчик. За время связи вызывается 3 раза. Флаги ISTR: 1. RESET 2. ESOF | RESET | SUSP 3. ESOF Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gab 0 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба Вывод dmesg в линуксе: [117379.864359] usb 1-1: new full-speed USB device number 18 using xhci_hcd [117379.992115] usb 1-1: device descriptor read/64, error -71 [117380.227595] usb 1-1: device descriptor read/64, error -71 [117380.335552] usb usb1-port1: attempt power cycle [117380.985577] usb 1-1: new full-speed USB device number 19 using xhci_hcd [117380.985719] usb 1-1: Device not responding to setup address. [117381.193652] usb 1-1: Device not responding to setup address. [117381.401082] usb 1-1: device not accepting address 19, error -71 [117381.528772] usb 1-1: new full-speed USB device number 20 using xhci_hcd [117381.528990] usb 1-1: Device not responding to setup address. [117381.736693] usb 1-1: Device not responding to setup address. [117381.736778] debugfs: Directory '05' with parent 'devices' already present! [117381.943880] usb 1-1: device not accepting address 20, error -71 [117381.944062] usb usb1-port1: unable to enumerate USB device Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба 48 МГц на USB-контроллер подаётся? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gab 0 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба На A8 вытащил MCO. PCLK/2 = 36МГц. Точнее 35,999. USB прескалер - 1,5. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 23 сентября, 2020 Опубликовано 23 сентября, 2020 · Жалоба Давайте смотреть, что делает _usb_reset(usbp) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 61 24 сентября, 2020 Опубликовано 24 сентября, 2020 · Жалоба Пример STM32\STM32F3xx\USB_CDC_IAD работает ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gab 0 24 сентября, 2020 Опубликовано 24 сентября, 2020 · Жалоба Не работает. Почти. Если поставить ld-скрипт от 303, то загружается, моргает светодиодом и не определяется. ld-скрипт от 302 - не влезает. На чипе написано STM32F302C8T6 или CBT6, трудно разглядеть. OpenOCD пишет: Info : device id = 0x10036422 Info : flash size = 128kbytes Отрубил тесты. Влезло. Моргает и не определяется. 8 hours ago, Сергей Борщ said: Давайте смотреть, что делает _usb_reset(usbp) /** * @brief USB reset routine. * @details This function must be invoked when an USB bus reset condition is * detected. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void _usb_reset(USBDriver *usbp) { unsigned i; /* State transition.*/ usbp->state = USB_READY; /* Resetting internal state.*/ usbp->status = 0; usbp->address = 0; usbp->configuration = 0; usbp->transmitting = 0; usbp->receiving = 0; /* Invalidates all endpoints into the USBDriver structure.*/ for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { #if USB_USE_WAIT == TRUE /* Signaling the event to threads waiting on endpoints.*/ if (usbp->epc[i] != NULL) { osalSysLockFromISR(); if (usbp->epc[i]->in_state != NULL) { osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); } if (usbp->epc[i]->out_state != NULL) { osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); } osalSysUnlockFromISR(); } #endif usbp->epc[i] = NULL; } /* EP0 state machine initialization.*/ usbp->ep0state = USB_EP0_STP_WAITING; /* Low level reset.*/ usb_lld_reset(usbp); /* Notification of reset event.*/ _usb_isr_invoke_event_cb(usbp, USB_EVENT_RESET); } /** * @brief USB low level reset routine. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_reset(USBDriver *usbp) { uint32_t cntr; /* Post reset initialization.*/ STM32_USB->BTABLE = BTABLE_ADDR; STM32_USB->ISTR = 0; STM32_USB->DADDR = DADDR_EF; cntr = /*CNTR_ESOFM | */ CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM | /*CNTR_ERRM | CNTR_PMAOVRM |*/ CNTR_CTRM; /* The SOF interrupt is only enabled if a callback is defined for this service because it is an high rate source.*/ if (usbp->config->sof_cb != NULL) cntr |= CNTR_SOFM; STM32_USB->CNTR = cntr; /* Resets the packet memory allocator.*/ usb_pm_reset(usbp); /* EP0 initialization.*/ usbp->epc[0] = &ep0config; usb_lld_init_endpoint(usbp, 0); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться