2010-11-05 09:00 AM
STM32_USB-FS-Device_Lib Errors
2011-05-17 05:14 AM
As Stefano pointed out on this topic, the delay routine touches SysTick timer in the STM32_USB-FS-Device_Lib for STM32F105-7. It causes unpredictable error on RTOS.
https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/ST%20USB_LIBS%203.2.0
Replace uDELAY(usec) and mDELAY(msec) with RTOS-specific delay routines.
These delay routines are #define'd on otgd_fs_cal.h
In the USB stack, both routines calls USB_OTG_BSP_uDelay() (hw_config.c), which touches to SysTick timer.
mDELAY(50 or 25) is used in these routines,
otgd_fs_cal.c: OTGD_FS_CoreInit(), OTGD_FS_SetDeviceMode()
otgd_fs_pcd.c: PCD_DevConnect(), PCD_DevDisconnect()
For Keil RL-RTX, os_dly_wait() fits to this purpose well.
uDELAY(5) is used in these routines,
otgd_fs_cal.c: twice in OTGD_FS_CoreReset(), OTGD_FS_FlushTxFifo(), OTGD_FS_FlushRxFifo()
uDELAY() is too short to replace with os_dly_wait(), which runs on system tick. You may need to write a custom routine, which polls STK_VAL of SysTick timer or other one.
Tsuneo
2011-05-17 05:14 AM
Thanks Tsuneo, that seems to have resolved the issue. Although some care is needed in the implementation since the delay can be called form an interrupt context.
The USB I/O now seems robust, however simply connecting the USB cable still affects the performance and functionality of other tasks in my application, so I shall need to investigate further.2011-05-17 05:14 AM
The remaining issues were in my code. All good now, thanks again.
2011-05-17 05:14 AM
> Although some care is needed in the implementation since the delay can be called form an interrupt context.
As of mDELAY(),
OTGD_FS_CoreInit(), OTGD_FS_SetDeviceMode(), PCD_DevConnect() and PCD_DevDisconnect() are called just from USB_Init() in this call tree.
USB_Init()
- pProperty->Init()
- - Virtual_Com_Port_init()
- - - USB_SIL_Init()
- - - - OTG_DEV_Init()
- - - - - PCD_Init()
- - - - - - OTGD_FS_CoreInit()
- - - - - - - OTGD_FS_SetDeviceMode()
- - - - - - - - mDELAY()
- - - PowerOn()
PowerOn()
PowerOff()
- USB_Cable_Config()
- - USB_DevConnect()
- - - PCD_DevConnect()
- - - - mDELAY()
- - USB_DevDisconnect()
- - - PCD_DevDisconnect()
- - - - mDELAY()
PowerOff() is not called from anywhere.
Usually, USB_Init() is included in the start-up task, invoked from os_sys_init().
Therefore(), we can replace mDELAY() with os_dly_wait() without any trouble.
As of uDELAY(), it is called from the IRQ Handler, too.
But no re-entrant occurs to uDELAY().
Therefore, simple timer-polling delay works well.
USB_Init()
- pProperty->Init()
- - Virtual_Com_Port_init()
- - - USB_SIL_Init()
- - - - OTG_DEV_Init()
- - - - - PCD_Init()
- - - - - - OTGD_FS_CoreInit()
- - - - - - - OTGD_FS_CoreReset()
- - - - - - - - uDELAY()
USB_Init()
- pProperty->Init()
- - Virtual_Com_Port_init()
- - - USB_SIL_Init()
- - - - OTG_DEV_Init()
- - - - - PCD_Init()
- - - - - - OTGD_FS_CoreInitDev()
- - - - - - - OTGD_FS_FlushTxFifo()
- - - - - - - - uDELAY()
- - - - - - - OTGD_FS_FlushRxFifo()
- - - - - - - - uDELAY()
OTG_FS_IRQHandler()
- STM32_PCD_OTG_ISR_Handler()
- - OTGD_FS_Handle_UsbReset_ISR()
- - - OTGD_FS_DEVICE_RESET
- - - - Device_Property.Reset()
- - - - - Virtual_Com_Port_Reset()
- - - - - - OTG_DEV_EP_Init()
- - - - - - - PCD_EP_Flush()
- - - - - - - - OTGD_FS_FlushTxFifo()
- - - - - - - - - uDELAY()
- - - - - - - - OTGD_FS_FlushRxFifo()
- - - - - - - - - uDELAY()
- - - OTGD_FS_FlushTxFifo()
- - - - uDELAY()
Tsuneo