Auratos 0 8 сентября, 2017 Опубликовано 8 сентября, 2017 · Жалоба Добрый день. Не нашел отдельной ветки для STM-контроллеров, поэтому пишу сюда. Имеется контроллер STM32F107RCT6. Задействовал у него модуль USB и взял с сайта ST последнюю версию библиотеки и драйвера USB (STM32_USB_OTG_Driver v2.2.0). На плате также имеется GSM-модуль фирмы SIMCOM. Спаяли две платы с данными контроллерами. Одна работает, вторая "болеет". Проблема в том, что если не вставлена SIM-карта, то USB модуль работает отлично. Но со вставленной SIM-картой и после прохождения этапа регистрации в сети перестает работать обмен данными через USB: принимать данные - принимает, но обратно не передает. Попробовали сначала перепаять контроллер и просмотреть линии, ведущие к USB - не помогло. Стал теперь копаться в драйвере. В рабочей версии платы при попытке передать данные в USB порт в функции USBD_OTG_ISR_Handler дважды генерируется некое прерывание, которое драйвер относит к группе inepint uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintr_status; uint32_t retval = 0; if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */ { gintr_status.d32 = USB_OTG_ReadCoreItr(pdev); ... if (gintr_status.b.inepint) { retval |= DCD_HandleInEP_ISR(pdev); } ... } return retval; } При обнаружении данного прерывания вызывается функция DCD_HandleInEP_ISR static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_DIEPINTn_TypeDef diepint; uint32_t ep_intr; uint32_t epnum = 0; uint32_t fifoemptymsk; diepint.d32 = 0; ep_intr = USB_OTG_ReadDevAllInEPItr(pdev); while ( ep_intr ) { if ((ep_intr & 0x1) == 0x01) /* In ITR */ { diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */ if ( diepint.b.xfercompl ) { fifoemptymsk = 0x1 << epnum; USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); CLEAR_IN_EP_INTR(epnum, xfercompl); /* TX COMPLETE */ USBD_DCD_INT_fops->DataInStage(pdev , epnum); if (pdev->cfg.dma_enable == 1) { if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN)) { /* prepare to rx more setup packets */ USB_OTG_EP0_OutStart(pdev); } } } if ( diepint.b.timeout ) { CLEAR_IN_EP_INTR(epnum, timeout); } if (diepint.b.intktxfemp) { CLEAR_IN_EP_INTR(epnum, intktxfemp); } if (diepint.b.inepnakeff) { CLEAR_IN_EP_INTR(epnum, inepnakeff); } if ( diepint.b.epdisabled ) { CLEAR_IN_EP_INTR(epnum, epdisabled); } if (diepint.b.emptyintr) { DCD_WriteEmptyTxFifo(pdev , epnum); } } epnum++; ep_intr >>= 1; } return 1; } За эти два прерывания, про которые я упомянул, поочередно взводятся два флага: diepint.b.emptyintr и diepint.b.xfercompl. Возведение diepint.b.xfercompl как раз и сигнализирует о том, что данные пошли на отправку. Но в нерабочей плате взводится только diepint.b.emptyintr, и статус USB так и остается как "занят", но при этом данные не передались. Стал копаться глубже и зашел в тупик. Подскажите, пожалуйста, что можно посмотреть еще? Линии, регистры? Любая подсказка Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 8 сентября, 2017 Опубликовано 8 сентября, 2017 · Жалоба Я на таком контроллере наступил на грабли, когда использовал UART, который сидит на ножке USB connect. Даже если не использовать флажок "коннект", сама USB-периферия начинает вести себя неадекватно, если работать по UART'у (т.е. менять уровень на этой ноге). Не оно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться