void stellaris_usb0_irq(void) { arm_cm_irq_entry(); uint status = USBIntStatusControl(USB0_BASE); //LTRACEF("usb irq, status 0x%x\n", status); if (status & USB_INTCTRL_RESET) { // reset LTRACEF("reset\n"); pending_addr_change = false; usb_callback(USB_CB_RESET, NULL); } if (status & USB_INTCTRL_CONNECT) { // reset LTRACEF("connect\n"); } status = USBIntStatusEndpoint(USB0_BASE); if (status & USB_INTEP_0) { // ep0 //LTRACEF("ep0\n"); ep0_irq(); } arm_cm_irq_exit(true); }
//***************************************************************************** // //! Handles OTG mode changes and also steers other USB interrupts from //! the controller to the correct handler in the USB stack. //! //! This interrupt handler is used in applications which require to operate //! in both host and device mode using OTG. When in host or device mode, it //! steers the USB hardware interrupt to the correct handler in the USB stack //! depending upon the current operating mode. It also handles other OTG //! related interrupt events. //! //! For successful OTG mode operation, an application must register //! USB0OTGModeIntHandler() in the CPU vector table as the interrupt handler //! for the USB0 interrupt. //! //! \note This interrupt handler should only be used on controllers that //! support OTG functionality. //! //! \return None. // //***************************************************************************** void USB0OTGModeIntHandler(void) { uint32_t ui32Status; tEventInfo sEvent; // // Read the USB interrupt status. // ui32Status = USBIntStatusControl(USB0_BASE); // // Check if this was an mode detect interrupt and under manual power // control. // if((ui32Status & USB_INTCTRL_MODE_DETECT) && (USBHCDPowerAutomatic(0) == 0)) { uint32_t ui32Mode; ui32Mode = USBModeGet(USB0_BASE); switch(ui32Mode) { // // Device is on the A side of the cable and power needs to be // applied. // case USB_OTG_MODE_ASIDE_NPWR: case USB_OTG_MODE_ASIDE_SESS: case USB_OTG_MODE_ASIDE_AVAL: { // // Since power is not automatically enabled, call the // registered event handler to allow the application to turn // on power. // sEvent.ui32Event = USB_EVENT_POWER_ENABLE; sEvent.ui32Instance = 0; InternalUSBHCDSendEvent(0, &sEvent, USBHCD_EVFLAG_PWREN); break; } // // Device is on the B side of the cable and powered. // case USB_OTG_MODE_BSIDE_DEV: { // // Now in device mode on the B side of the cable and will wait // for a connect before becoming a device. // g_eOTGModeState = eUSBOTGModeBWaitCon; break; } // // Any other mode detect indicates eUSBModeNone. // default: { // // Just inform the application that the mode was not device // or host. // USBOTGSetMode(eUSBModeNone); break; } } } // // If there was a VBUS error then the power should be shut off and the // system is reset to waiting for detection again. // if(ui32Status & USB_INTCTRL_VBUS_ERR) { // // Just inform the application that the mode was not device // or host. // USBOTGSetMode(eUSBModeNone); // // Return to idle mode. // g_eOTGModeState = eUSBOTGModeWait; } // // If there is a disconnect interrupt and the controller was on the B side // cable as a device then go back to the IDLE state. // if((ui32Status & USB_INTCTRL_DISCONNECT) && (g_eOTGModeState == eUSBOTGModeBDevice)) { // // No longer a device so switch to unconfigured mode. // USBOTGSetMode(eUSBModeNone); // // Return to idle mode. // g_eOTGModeState = eUSBOTGModeWait; return; } // // Handle receiving a reset. // if((ui32Status & USB_INTCTRL_RESET)&& (g_eOTGModeState != eUSBOTGModeBDevice)) { // // Getting a reset interrupt when not already a b side device indicates // that a host is resetting the device and the controller should // move to device mode. // g_eOTGModeState = eUSBOTGModeBDevice; // // Save the new mode. // USBOTGSetMode(eUSBModeDevice); } // // If there is a connect interrupt while the library is waiting for // one then move to full host mode state. // if(ui32Status & USB_INTCTRL_CONNECT) { // // Move to A side host state. // g_eOTGModeState = eUSBOTGModeAHost; // // Inform the application that controller is in host mode. // USBOTGSetMode(eUSBModeHost); } // // Call the correct device or host interrupt handler based on the current // mode of operation. // switch(g_eOTGModeState) { case eUSBOTGModeAHost: { // // Call the host interrupt handler if there is anything still to // process. // USBHostIntHandlerInternal(0, ui32Status); break; } // // Operating in pure device mode. // case eUSBOTGModeBDevice: { // // Call the device interrupt handler. // USBDeviceIntHandlerInternal(0, ui32Status); break; } default: { break; } } }
//***************************************************************************** // //! Steers USB interrupts from controller to the correct handler in the USB //! stack. //! //! This interrupt handler is used in applications which require to operate //! in both host and device mode. It steers the USB hardware interrupt to the //! correct handler in the USB stack depending upon the current operating mode //! of the application, USB device or host. //! //! For successful dual mode operation, an application must register //! USB0DualModeIntHandler() in the CPU vector table as the interrupt handler //! for the USB0 interrupt. This handler is responsible for steering //! interrupts to the device or host stack depending upon the chosen mode. //! //! \note Devices which do not require dual mode capability should register //! either USB0DeviceIntHandler() or USB0HostIntHandler() instead. Registering //! USB0DualModeIntHandler() for a single mode application will result in an //! application binary larger than required since library functions for both //! USB operating modes will be included even though only one mode is actually //! required. //! //! \return None. // //***************************************************************************** void USB0DualModeIntHandler(void) { uint32_t ui32Status; // // Read the USB interrupt status. // ui32Status = USBIntStatusControl(USB0_BASE); // // Pass through the subset of interrupts that we always want // the host stack to see regardless of whether or not we // are actually in host mode at this point. // if(ui32Status & USB_HOST_INTS) { // // Call the host's interrupt handler. // USBHostIntHandlerInternal(0, ui32Status & USB_HOST_INTS); // // We have already processed these interrupts so clear them // from the status. // ui32Status &= ~USB_HOST_INTS; } // // Steer the interrupt to the appropriate handler within the stack // depending upon our current operating mode. Note that we need to pass // the ui32Status parameter since the USB interrupt register is // clear-on-read. // switch(g_iUSBMode) { case eUSBModeNone: { // // No mode is set yet so we have no idea what to do. Just ignore // the interrupt. // break; } // // Operating in pure host mode. // case eUSBModeHost: { // // Call the host interrupt handler if there is anything still to // process. // USBHostIntHandlerInternal(0, ui32Status); break; } // // Operating in pure device mode. // case eUSBModeDevice: { // // Call the device interrupt handler. // USBDeviceIntHandlerInternal(0, ui32Status); break; } default: { break; } } }