2014-04-30 02:45 PM
I'm trying to get a USB Host running using code from STM32_USB-Host-Device_Lib_V2.1.0 with openocd on an STM32f215rg board with FS USB using internal PHY. But it dies trying to enable the OTG_FS interrupt.
As in the examples, USBH_Init() calls USB_OTG_BSP_EnableInterrupt(), and that calls NVIC_Init() for OTG_FS_IRQn. But that ends up in UsageFault_Handler(). What does that suggest I'm missing? Thanks!
void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_OTG1_FS);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_OTG1_FS);
/* Configure ID pin as Host */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; // GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_OTG1_FS);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE);
}
void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void USBH_Init(USB_OTG_CORE_HANDLE *pdev,
USB_OTG_CORE_ID_TypeDef coreID,
USBH_HOST *phost,
USBH_Class_cb_TypeDef *class_cb,
USBH_Usr_cb_TypeDef *usr_cb)
{
/* Hardware Init */
USB_OTG_BSP_Init(pdev);
/* configure GPIO pin used for switching VBUS power */
USB_OTG_BSP_ConfigVBUS(0);
/* Host de-initializations */
USBH_DeInit(pdev, phost);
/*Register class and user callbacks */
phost->class_cb = class_cb;
phost->usr_cb = usr_cb;
/* Start the USB OTG core */
HCD_Init(pdev , coreID);
/* Upon Init call usr call back */
phost->usr_cb->Init();
/* Enable Interrupts */
USB_OTG_BSP_EnableInterrupt(pdev);
}
#stm32f215
2014-05-01 02:10 AM
Hi
Usage fault : http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/BABBGBEC.html Probably an alignment issue - make sure the instance of 'pdev' is on a 32bit boundary. All the example code I have seen make sure the device instance is aligned. It is possible that alignment has caused instructions to become out of alignment generating unknown instructions. Or could be a divide by zero.2014-05-01 09:13 AM
Thanks for the hints. Yes, both my USB_OTG_CORE_HANDLE and USBH_HOST are within __ALIGN_BEGIN/__ALIGN_END blocks. (And it's not a divide by 0--at least it doesn't end up in __aeabi_idiv0 anyway.)
The other structs passed into USBH_Init are USBH_Usr_cb_TypeDef USBH_MSC_cb and USR_cb, but those don't need alignment syntax too, do they? I started with this example as my starting point: STM32_USB-Host-Device_Lib_V2.1.0/Project/USB_Host_Examples/MSC but rearranged it to compile with openocd. So close, yet so far...2014-05-01 09:22 AM
Hi
The other things it can be then is ''an undefined instruction'' ''invalid state on instruction execution'' ''error on exception return'' I do not think it is likely to be anything to do with instructions (since they are all generated by the compiler). It could be that an instruction is not word aligned or the alignment has been shifted so instructions get corrupted but I doubt it. That leave Error on exception return. Since most of the USB stack is built on IRQs/ISRs that is very likely. Have you tried you code without/with a device plugged in? I have not implemented a Host before so - does the Interrupt Enable clear the interrupt bit before enabling IRQs?2014-05-01 11:11 AM
Sorting out the interrupts does seem like the right direction, with the mess shifting around depending on whether a device is plugged and on whether or not USE_ACCURATE_TIME is defined, which uses a timer interrupt. Looks like example host code clears the timer interrupt before enabling but not the OTG_FS_IRQn. Thanks for the suggestions.