Добрый день. Не нашел отдельной ветки для 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 так и остается как "занят", но при этом данные не передались. Стал копаться глубже и зашел в тупик.
Подскажите, пожалуйста, что можно посмотреть еще? Линии, регистры? Любая подсказка