2015-12-16 08:39 PM
Hi Everyone,
I'm working on getting the ST middleware USB device stack to work on my development board but I'm having a hard time with the way how STM32Cube does things. I've already spent 3-4 days troubleshooting this issue and found no solution. My problem is this piece of code (that's common to any USB device examples provided by ST):/**
* @brief This function handles USB-On-The-Go FS global interrupt request.
* @param None
* @retval None
*/
#ifdef USE_USB_FS void OTG_FS_IRQHandler(void) #else void OTG_HS_IRQHandler(void) #endif {HAL_PCD_IRQHandler(&hpcd);
} In all USB device examples provided by ST, HAL_PCB_IRQHandler() is executed from inside of the USB ISR to service the interrupt. That function will eventually bubble up and call my application code. The problem is my application code makes use of OS blocking function call (i.e SPI via DMA for reading/writing to/from uSD card) that cannot be executed from inside of an ISR. So what I did was moved HAL_PCD_IRQHandler() out of the ISR and into an OS task. The USB ISR would trigger an event, causing the task to exit its blocking state and execute HAL_PCD_IRQHandler() to service the interrupt. However, I noticed that if I don't clear the interrupt flags inside of the USB ISR, as soon as I exit it, it would be called again. To work around that, I disable the USB IRQ then exit out of the ISR like the following:#ifdef USE_USB_FS void OTG_FS_IRQHandler(void) #else void OTG_HS_IRQHandler(void) #endif {
uint8_t temp = 255;
// trigger the USB interrupt event
xQueueSendToBackFromISR(USBD_IntEvt, &temp, 0);
// disable USB interrupt until request has been handled by OS task
USB_DisableGlobalInt(hpcd.Instance);
} The OS task looks like this:static void USBD_IRQHandlerTask(void *pvParameters) {
uint8_t queueData;
while(1)
{
// wait for USB interrupt event to occur
xQueueReceive(USBD_IntEvt, &queueData, portMAX_DELAY);
// service USB interrupt
HAL_PCD_IRQHandler(&hpcd);
// re-enable USB interrupt
USB_EnableGlobalInt(hpcd.Instance);
}
} With the above modification, HAL_PCD_IRQHandler() is called from an OS task instead of the USB ISR. When it bubbles up and call my application code that calls some OS blocking functions, everything works out great. This modification works perfectly fine in Full Speed mode. But as soon as I switch to High Speed mode using an external USB PHY, it no longer work. Note that I did verify that it wasn't my hardware by running the High Speed mode example provided by ST, calling HAL_PCD_IRQHandler() from the ISR, and it worked. The only problem with that approach was, like I mentioned above, I couldn't make any OS blocking call since HAL_PCD_IRQHandler() was executed from an ISR. Has anyone had this issue porting this piece of code to an OS environment? How did you deal with it? Why did it work for Full Speed and not High Speed (with the modification I did above)? I have a feeling that by disabling the USB IRQ before exiting the USB ISR is what cause the issue with High Speed mode (but I just cannot confirm it nor find a work-around). Any help is greatly appreciated. Thanks!!2015-12-22 12:22 PM
Still haven't figured out this issue. Any help from anyone is greatly appreciated. Thanks!
BTW- does anybody know who I can contact at ST to help me out with issue I have with the driver/library provided by them? The company I work for buys a lot of chips from ST so I'm sure I can convince them to help us but it's just a matter of getting to the right person. Let me know, thanks!2015-12-22 12:58 PM
I'd recommend contacting via your local ST sales/distribution contacts, or FAE assigned to your company account. The IC and SW engineers really don't hang out or interact here, and probably are not setup for one-to-one customer interaction.