void usbIrqHandler(void) #endif { uint8_t statusCommon, statusIn, statusOut, indexSave; #if SLAB_USB_HANDLER_CB // Callback to user before processing USBD_EnterHandler(); #endif // Get the interrupt sources statusCommon = USB_GetCommonInts(); statusIn = USB_GetInInts(); statusOut = USB_GetOutInts(); #if SLAB_USB_POLLED_MODE if ((statusCommon == 0) && (statusIn == 0) && (statusOut == 0)) { return; } #endif // Save the current index indexSave = USB_GetIndex(); // Check Common USB Interrupts if (USB_IsSofIntActive(statusCommon)) { #if SLAB_USB_SOF_CB USBD_SofCb(USB_GetSofNumber()); #endif // SLAB_USB_SOF_CB // Check for unhandled USB packets on EP0 and set the corresponding IN or // OUT interrupt active flag if necessary. if (((myUsbDevice.ep0.misc.bits.outPacketPending == true) && (myUsbDevice.ep0.state == D_EP_RECEIVING)) || ((myUsbDevice.ep0.misc.bits.inPacketPending == true) && (myUsbDevice.ep0.state == D_EP_TRANSMITTING))) { USB_SetEp0IntActive(statusIn); } // Check for unhandled USB OUT packets and set the corresponding OUT // interrupt active flag if necessary. #if SLAB_USB_EP1OUT_USED if ((myUsbDevice.ep1out.misc.bits.outPacketPending == true) && (myUsbDevice.ep1out.state == D_EP_RECEIVING)) { USB_SetOut1IntActive(statusOut); } #endif #if SLAB_USB_EP2OUT_USED if ((myUsbDevice.ep2out.misc.bits.outPacketPending == true) && (myUsbDevice.ep2out.state == D_EP_RECEIVING)) { USB_SetOut2IntActive(statusOut); } #endif #if SLAB_USB_EP3OUT_USED if ((myUsbDevice.ep3out.misc.bits.outPacketPending == true) && (myUsbDevice.ep3out.state == D_EP_RECEIVING)) { USB_SetOut3IntActive(statusOut); } #endif #if (SLAB_USB_EP3IN_USED && (SLAB_USB_EP3IN_TRANSFER_TYPE == USB_EPTYPE_ISOC)) if ((myUsbDevice.ep3in.misc.bits.inPacketPending == true) && (myUsbDevice.ep3in.state == D_EP_TRANSMITTING)) { USB_SetIn3IntActive(statusIn); } #endif } if (USB_IsResetIntActive(statusCommon)) { handleUsbResetInt(); // If VBUS is not present on detection of a USB reset, enter suspend mode. #if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF) if (USB_IsVbusOn() == false) { USB_SetSuspendIntActive(statusCommon); } #endif } if (USB_IsResumeIntActive(statusCommon)) { handleUsbResumeInt(); } if (USB_IsSuspendIntActive(statusCommon)) { handleUsbSuspendInt(); } #if SLAB_USB_EP3IN_USED if (USB_IsIn3IntActive(statusIn)) { handleUsbIn3Int(); } #endif // EP3IN_USED #if SLAB_USB_EP3OUT_USED if (USB_IsOut3IntActive(statusOut)) { handleUsbOut3Int(); } #endif // EP3OUT_USED #if SLAB_USB_EP2IN_USED if (USB_IsIn2IntActive(statusIn)) { handleUsbIn2Int(); } #endif // EP2IN_USED #if SLAB_USB_EP1IN_USED if (USB_IsIn1IntActive(statusIn)) { handleUsbIn1Int(); } #endif // EP1IN_USED #if SLAB_USB_EP2OUT_USED if (USB_IsOut2IntActive(statusOut)) { handleUsbOut2Int(); } #endif // EP2OUT_USED #if SLAB_USB_EP1OUT_USED if (USB_IsOut1IntActive(statusOut)) { handleUsbOut1Int(); } #endif // EP1OUT_USED // Check USB Endpoint 0 Interrupt if (USB_IsEp0IntActive(statusIn)) { handleUsbEp0Int(); } // Restore index USB_SetIndex(indexSave); #if SLAB_USB_HANDLER_CB // Callback to user before exiting USBD_ExitHandler(); #endif }
void USBD_Suspend(void) { uint8_t i; bool regulatorEnabled, prefetchEnabled; USB_SaveSfrPage(); // If the USB_PWRSAVE_MODE_ONVBUSOFF is enabled, we can enter suspend if VBUS // is not present even if the USB has not detected a suspend event. #if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) || \ (SLAB_USB_BUS_POWERED)) if (USB_IsSuspended() == true) #else if ((USB_IsSuspended() == true) || (USB_IsVbusOn() == false)) #endif { USB_SuspendTransceiver(); #if SLAB_USB_FULL_SPEED USB_SetSuspendClock(); #endif // Get the state of the prefetch engine enable bit and disable the prefetch // engine prefetchEnabled = USB_IsPrefetchEnabled(); USB_DisablePrefetch(); // Get the state of the internal regulator before suspending it. if (USB_IsRegulatorEnabled() == true) { regulatorEnabled = true; #if (SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_FASTWAKE) USB_SuspendRegulatorFastWake(); #else USB_SuspendRegulator(); // Wait at least 12 clock instructions before halting the internal oscillator for (i = 0; i < 3; i++) { } #endif } else { regulatorEnabled = false; } do { USB_SuspendOscillator(); // When we arrive here, the device has waked from suspend mode. #if SLAB_USB_REMOTE_WAKEUP_ENABLED // If remote wakeup is enabled, query the application if the remote // wakeup event occurred. If so, exit USBD_Suspend(). if (USB_IsSuspended() == true) { if (USBD_RemoteWakeupCb() == true) { break; } } #endif #if ((!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) && \ (SLAB_USB_BUS_POWERED == 0)) // If the USB_PWRSAVE_MODE_ONVBUSOFF mode is disabled, VBUS has been // removed, so exit USBD_Suspend(). if (USB_IsVbusOn() == false) { break; } #endif } while (USB_IsSuspended() == true); // Restore the internal regulator if (regulatorEnabled == true) { USB_UnsuspendRegulator(); } // Restore the prefetch engine if (prefetchEnabled == true) { USB_EnablePrefetch(); } #if SLAB_USB_FULL_SPEED // Restore the clock USB_SetNormalClock(); #endif USB_EnableTransceiver(); } USB_RestoreSfrPage(); }
/***************************************************************************//** * @brief Handles USB port reset interrupt * @details After receiving a USB reset, halt all endpoints except for * Endpoint 0, set the device state, and configure USB hardware. ******************************************************************************/ static void handleUsbResetInt(void) { // Setup EP0 to receive SETUP packets myUsbDevice.ep0.state = D_EP_IDLE; // Halt all other endpoints #if SLAB_USB_EP1IN_USED myUsbDevice.ep1in.state = D_EP_HALT; #endif #if SLAB_USB_EP2IN_USED myUsbDevice.ep2in.state = D_EP_HALT; #endif #if SLAB_USB_EP3IN_USED myUsbDevice.ep3in.state = D_EP_HALT; #endif #if SLAB_USB_EP1OUT_USED myUsbDevice.ep1out.state = D_EP_HALT; #endif #if SLAB_USB_EP2OUT_USED myUsbDevice.ep2out.state = D_EP_HALT; #endif #if SLAB_USB_EP3OUT_USED myUsbDevice.ep3out.state = D_EP_HALT; #endif // After a USB reset, some USB hardware configurations will be reset and must // be reconfigured. // Re-enable clock recovery #if SLAB_USB_CLOCK_RECOVERY_ENABLED #if SLAB_USB_FULL_SPEED USB_EnableFullSpeedClockRecovery(); #else USB_EnableLowSpeedClockRecovery(); #endif #endif // Re-enable USB interrupts USB_EnableSuspendDetection(); USB_EnableDeviceInts(); // If VBUS is preset, put the device in the Default state. // Otherwise, put it in the Attached state. //#if (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) // If VBUS is preset, put the device in the Default state. // Otherwise, put it in the Attached state. // If the device is bus-powered, always put it in the Default state #if (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF) && !SLAB_USB_BUS_POWERED) if (USB_IsVbusOn()) { USBD_SetUsbState(USBD_STATE_DEFAULT); } else { USBD_SetUsbState(USBD_STATE_ATTACHED); } #else USBD_SetUsbState(USBD_STATE_DEFAULT); #endif // (!(SLAB_USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF)) #if SLAB_USB_RESET_CB // Make the USB Reset Callback USBD_ResetCb(); #endif }
int8_t USBD_Init(const USBD_Init_TypeDef *p) { uint8_t i; USB_SaveSfrPage(); USB_DisableInts(); // This forces the liner to bring in the contents efm8_usbdint // It is place here since all users MUST call this function // for the library to work properly forceModuleLoad_usbint(); // Zero out the myUsbDevice struct, then initialize all non-zero members for (i = 0; i < sizeof(myUsbDevice); i++) { *((uint8_t MEM_MODEL_SEG *)&myUsbDevice + i) = 0; } // Get the USB descriptors from p myUsbDevice.deviceDescriptor = p->deviceDescriptor; myUsbDevice.configDescriptor = (USB_ConfigurationDescriptor_TypeDef *)p->configDescriptor; myUsbDevice.stringDescriptors = p->stringDescriptors; myUsbDevice.numberOfStrings = p->numberOfStrings; // Enable USB clock #if SLAB_USB_FULL_SPEED USB_SetClockIntOsc(); USB_SelectFullSpeed(); #else USB_SetClockIntOscDiv8(); USB_SelectLowSpeed(); #endif // SLAB_USB_FULL_SPEED // Enable or disable VBUS detection #if SLAB_USB_BUS_POWERED USB_VbusDetectDisable(); #else USB_VbusDetectEnable(); #endif USB_ForceReset(); USB_EnableDeviceInts(); USBD_Connect(); // If VBUS is present, the state should be Default. // Otherwise, it is Attached. #if SLAB_USB_BUS_POWERED myUsbDevice.state = USBD_STATE_DEFAULT; #else if (USB_IsVbusOn()) { myUsbDevice.state = USBD_STATE_DEFAULT; } else { myUsbDevice.state = USBD_STATE_ATTACHED; } #endif // Only enable USB interrupts when not in polled mode #if (SLAB_USB_POLLED_MODE == 0) USB_EnableInts(); #endif USB_RestoreSfrPage(); USB_DisableInhibit(); return USB_STATUS_OK; }