2014-01-21 05:04 AM
Here is the list of known bugs in the USB / OTG library v2.1.0:
files - usbd_cdc_core.c / usbd_conf.h
ep descriptors should not use
#ifdef USE_USB_OTG_HS
but use instead
#ifndef USE_EMBEDDED_PHY
file - usb_bsp.c
function USB_OTG_BSP_Init
For OTH-HS using Internal Phy
RCC_AHB1PeriphClockLPModeCmd( RCC_AHB1Periph_OTG_HS_ULPI, DISABLE);
This problem was discovered some time ago, when OTG-HS is in use and device is put in sleep mode, the ULPI clocks must be switched off, otherwise the OTG functionality is broken.
Whenever GPIO_InitStructure is used, it must be properly initialized first (otherwise it is causing strange side effects):
GPIO_StructInit(&GPIO_InitStructure);
file - usb_dcd_int.c
Search for ''emptyintr'' occurence, where the source code is trying to clear this flag. There are two occurrences:
CLEAR_IN_EP_INTR(1, emptyintr);
CLEAR_IN_EP_INTR( epnum , emptyintr);It is read only flag, which cannot be cleared, so this interrupt must be masked instead:
fifoemptymsk = 0x1 << epnum;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0)This problem is causing high CPU load, but the USB is working.
file - usbd_core.c
USBD_Init function
correct order:/* Force Device Mode*/
USB_OTG_SetCurrentMode(pdev, DEVICE_MODE);/* Enable Interrupts */USB_OTG_BSP_EnableInterrupt(pdev);On some hosts this is blocking proper enumeration of our device.
file usbh_core.cmissing proper error handlingUSBH_HandleControl function
case CTRL_STATUS_IN_WAIT:URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);
if ( URB_Status == URB_DONE)
{ /* Control transfers completed, Exit the State Machine */
phost->gState = phost->gStateBkp;
phost->Control.state = CTRL_COMPLETE;
}
else if (URB_Status == URB_ERROR)
{
phost->Control.state = CTRL_ERROR;
}
else if((HCD_GetCurrentFrame(pdev)\
- phost->Control.timer) > timeout)
{
phost->Control.state = CTRL_ERROR;
}
else if(URB_Status == URB_STALL)
{
/* Control transfers completed, Exit the State Machine */
phost->gState = phost->gStateBkp;
phost->Control.state = CTRL_STALL; //addedstatus = USBH_NOT_SUPPORTED; //added
}
break;
2014-01-21 11:59 PM
Thanks.
Couldn't you get this post get sticky (to appear always at the top of the list)? JW2014-04-02 03:56 AM
Hi,
Can I receive USB OTG FS WakeUp interrupt under Standby Mode for the processor STM32F437?According to the datasheet the answer is ''Yes'' but I could not practical!Can you help me by practical advice?2014-04-02 10:25 AM
> garberman.sergey:
> Can I receive USB OTG FS WakeUp interrupt under Standby Mode for the processor STM32F437? USB Wakeup event is passed to NVIC over EXTI 2.5 External interrupt/event line mapping (p380, DM00031pdf) EXTI line 18 is connected to the USB OTG FS Wakeup event - NVIC position:42 OTG_FS_WKUP EXTI line 20 is connected to the USB OTG HS (configured in FS) Wakeup event - NVIC position:76 OTG_HS_WKUP STM32_USB-Host-Device_Lib_V2.1.0 has already implemented these events. a) initialization
\STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\HID\inc\usb_conf.h
/****************** USB OTG FS CONFIGURATION **********************************/
#ifdef USB_OTG_FS_CORE
...
#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
/****************** USB OTG HS CONFIGURATION **********************************/
#ifdef USB_OTG_HS_CORE
...
#define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
#endif
\STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\HID\src\usb_bsp.c
void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
{
...
#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
EXTI_ClearITPendingBit(EXTI_Line18);
EXTI_InitStructure.EXTI_Line = EXTI_Line18;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line18);
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line18);
#endif
#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
EXTI_ClearITPendingBit(EXTI_Line20);
EXTI_InitStructure.EXTI_Line = EXTI_Line20;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line20);
NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_WKUP_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_ClearITPendingBit(EXTI_Line20);
#endif
b) ISRs
\STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\HID\src\stm32fxxx_it.c
#ifdef USE_USB_OTG_FS
void OTG_FS_WKUP_IRQHandler(void)
{
...
}
#ifdef USE_USB_OTG_HS
void OTG_HS_WKUP_IRQHandler(void)
{
...
]
Tsuneo
2014-04-03 12:53 AM
Many thanks, Tsuneo!
But I had been tried this sample and didn't get results! Of course, I implemented it into my project... which not trivial.May be, you know (link) a simple project for example?2014-04-29 11:52 AM
Got another bug for you:
https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F4%2c%20USB%20HS%20with%20ULPI%20and%20SuspendWakeup&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&To...2014-04-30 03:45 AM
--- a/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
+++ b/Libraries/STM32_USB_Device_Library/Class/cdc/src/usbd_cdc_core.c
@@ -625,7 +625,7 @@ static uint8_t usbd_cdc_Setup (void *pdev,
else /* No Data request */
{
/* Transfer the command to the interface layer */
- APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
+ APP_FOPS.pIf_Ctrl(req->bRequest, (uint8_t*)req, 0);
}
Here is another library fix I picked up from the forums,
''
Modify usbd_cdc_Setup() to pass the request buffer into the APP_FOPS.pIf_Ctrl() function pointer
callback.
Change is per instructions by chinzei.tsuneo on the st forums to enable passing the
''No data request'' setup packets through to the callback function for processing.
''
2014-04-30 03:55 AM
Is it within the license for the library to be able to push it to some place like github? It seems a waste for everyone to be applying the same set of fixes to the library over and over.
2014-04-30 05:45 AM
file - usb_dcd_int.c
Search for ''emptyintr'' occurence, where the source code is trying to clear this flag. There are two occurrences:
CLEAR_IN_EP_INTR(1, emptyintr);
CLEAR_IN_EP_INTR( epnum , emptyintr);It is read only flag, which cannot be cleared, so this interrupt must be masked instead:
fifoemptymsk = 0x1 << epnum;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0)This problem is causing high CPU load, but the USB is working.
Re: this fix, I've applied this change to DCD_WriteEmptyTxFifo() that I found from another forum discussion. This function appears to be called at all locations where the CLEAR_*** calls are made so it looked like a better fix:
/**
* @brief DCD_WriteEmptyTxFifo
* check FIFO for the next packet to be loaded
* @param pdev: device instance
* @retval status
*/
static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
{
USB_OTG_DTXFSTSn_TypeDef txstatus;
USB_OTG_EP *ep;
uint32_t len = 0;
uint32_t len32b;
txstatus.d32 = 0;
ep = &pdev->dev.in_ep[epnum];
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
len32b = (len + 3) / 4;
txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
while (txstatus.b.txfspcavail > len32b &&
ep->xfer_count <
ep-
>xfer_len &&
ep->xfer_len != 0)
{
/* Write the FIFO */
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
len32b = (len + 3) / 4;
USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
ep->xfer_buff += len;
ep->xfer_count += len;
#if 1
// NOTE: Fix from [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flooded%20empty%20FIFO%20interrupts%20still%20make%20USB%20devices%20crawl¤tviews=413]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flooded%20empty%20FIFO%20interrupts%20still%20make%20USB%20devices%20crawl¤tviews=413
if( ep->xfer_count >= ep->xfer_len){
uint32_t fifoemptymsk = 1 <<
epnum
;
USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
break;
}
#endif
txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
}
return 1;
}
2014-04-30 06:02 AM
file - usbd_core.c
USBD_Init function
correct order:/* Force Device Mode*/
USB_OTG_SetCurrentMode(pdev, DEVICE_MODE); /* Enable Interrupts */ USB_OTG_BSP_EnableInterrupt(pdev);On some hosts this is blocking proper enumeration of our device.
I'm not seeing the call to USB_OTG_SetCurrentMode() in my version of USBD_Init():
/**
* @brief USBD_Init
* Initailizes the device stack and load the class driver
* @param pdev: device instance
* @param core_address: USB OTG core ID
* @param class_cb: Class callback structure address
* @param usr_cb: User callback structure address
* @retval None
*/
void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID,
USBD_DEVICE *pDevice,
USBD_Class_cb_TypeDef *class_cb,
USBD_Usr_cb_TypeDef *usr_cb)
{
/* Hardware Init */
USB_OTG_BSP_Init(pdev);
USBD_DeInit(pdev);
/*Register class and user callbacks */
pdev->dev.class_cb = class_cb;
pdev->dev.usr_cb = usr_cb;
pdev->dev.usr_device = pDevice;
/* set USB OTG core params */
DCD_Init(pdev , coreID);
/* Upon Init call usr callback */
pdev->dev.usr_cb->Init();
/* Enable Interrupts */
USB_OTG_BSP_EnableInterrupt(pdev);
}
Is this fix suggesting that a call to USB_OTG_SetCurrentMode() be added prior to enabling interrupts?