/****************************************************************************** * Function: void interrupt USB_ISR() * Input: * Output: None * Overview: The USB stat interrupt service routine * Note: None *****************************************************************************/ void interrupt 7 USB_ISR() { if(USBCTL0_LPRESF) { USBCTL0_USBRESMEN = 0; } if(INTSTAT_RESUMEF && INTENB_RESUME) USB_WakeFrom_Suspend(); if(INTSTAT_USBRSTF && INTENB_USBRST) { INTSTAT = 0xBF; if(Usb_Device_State == USB_SUSPEND) Usb_State_Flag |= WAKE_UP_BY_RESET; USB_Bus_Reset_Handler(); } if(INTSTAT_SOFTOKF && INTENB_SOFTOK) { USB_SOF_Handler(); } if(INTSTAT_STALLF && INTENB_STALL ) USB_Stall_Handler(); if(INTSTAT_ERRORF && INTENB_ERROR) USB_Error_Handler(); if(INTSTAT_SLEEPF && INTENB_SLEEP) { INTSTAT_SLEEPF = 1; USBCTL0_USBRESMEN = 1; Old_Usb_State = Usb_Device_State ; Usb_Device_State = USB_ENTER_SUSPEND; /*do not hope enter into suspend */ } if(INTSTAT_TOKDNEF && INTENB_TOKDNE) { USB_Transaction_Handler(); INTSTAT_TOKDNEF = 1; /*write 1 to clear*/ } return; }
/****************************************************************************** * Function: void USBDriverService(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This routine is the heart of this firmware. It manages * all USB interrupts. * * Note: Device state transitions through the following stages: * DETACHED -> ATTACHED -> POWERED -> DEFAULT -> * ADDRESS_PENDING -> ADDRESSED -> CONFIGURED -> READY *****************************************************************************/ void USBDriverService(void) { /* * Pointless to continue servicing if USB cable is not even attached. */ if(usb_device_state == DETACHED_STATE) return; /* * Task A: Service USB Activity Interrupt */ if(UIRbits.ACTVIF && UIEbits.ACTVIE) USBWakeFromSuspend(); /* * Pointless to continue servicing if the device is in suspend mode. */ if(UCONbits.SUSPND==1) return; /* * Task B: Service USB Bus Reset Interrupt. * When bus reset is received during suspend, ACTVIF will be set first, * once the UCONbits.SUSPND is clear, then the URSTIF bit will be asserted. * This is why URSTIF is checked after ACTVIF. */ if(UIRbits.URSTIF && UIEbits.URSTIE) USBProtocolResetHandler(); /* * Task C: Service other USB interrupts */ if(UIRbits.IDLEIF && UIEbits.IDLEIE) USBSuspend(); if(UIRbits.SOFIF && UIEbits.SOFIE) USB_SOF_Handler(); if(UIRbits.STALLIF && UIEbits.STALLIE) USBStallHandler(); // if(UIRbits.UERRIF && UIEbits.UERRIE) USBErrorHandler(); /* * Pointless to continue servicing if the host has not sent a bus reset. * Once bus reset is received, the device transitions into the DEFAULT * state and is ready for communication. */ if(usb_device_state < DEFAULT_STATE) return; /* * Task D: Servicing USB Transaction Complete Interrupt */ for(bTRNIFCount = 0; bTRNIFCount < 4; bTRNIFCount++) { if(UIRbits.TRNIF && UIEbits.TRNIE) { /* * USBCtrlEPService only services transactions over EP0. * It ignores all other EP transactions. */ if(USBCtrlEPService() == 0) // If not an EP0 transaction, then clear TRNIF. { /* * Other EP can be serviced later by responsible device class firmware. * Each device driver knows when an OUT or IN transaction is ready by * checking the buffer ownership bit. * An OUT EP should always be owned by SIE until the data is ready. * An IN EP should always be owned by CPU until the data is ready. * * Because of this logic, it is not necessary to save the USTAT value * of non-EP0 transactions. */ UIRbits.TRNIF = 0; /* * At least six Tcy are needed in between clearing UIR<TRNIF> * and when it becomes reasserted when the USTAT FIFO has more * than one entry in it. * * No Nops are needed here because the number of instruction * cycles between clearing the TRNIF here to the next flag * check is longer than the required minimum of six Tcy due * to the for loop logic of bTRNIFCount. This is true even * when all optimization options in C18 are enabled. */ } }//end if(UIRbits.TRNIF && UIEbits.TRNIE) else break; }// end for(bTRNIFCount = 0; bTRNIFCount < 4; bTRNIFCount++) }//end USBDriverService
/****************************************************************************** * Function: void USBDriverService(void) * * PreCondition: None * * Input: None * * Output: None * * Side Effects: None * * Overview: This routine is the heart of this firmware. It manages * all USB interrupts. * * Note: Device state transitions through the following stages: * DETACHED -> ATTACHED -> POWERED -> DEFAULT -> * ADDRESS_PENDING -> ADDRESSED -> CONFIGURED -> READY *****************************************************************************/ void USBDriverService(void) { /* * Pointless to continue servicing if USB cable is not even attached. */ if(usb_device_state == DETACHED_STATE) return; /* * Task A: Service USB Activity Interrupt */ if(UIRbits.ACTVIF && UIEbits.ACTVIE) USBWakeFromSuspend(); /* * Pointless to continue servicing if the device is in suspend mode. */ if(UCONbits.SUSPND==1) return; /* * Task B: Service USB Bus Reset Interrupt. * When bus reset is received during suspend, ACTVIF will be set first, * once the UCONbits.SUSPND is clear, then the URSTIF bit will be asserted. * This is why URSTIF is checked after ACTVIF. */ if(UIRbits.URSTIF && UIEbits.URSTIE) USBProtocolResetHandler(); /* * Task C: Service other USB interrupts */ if(UIRbits.IDLEIF && UIEbits.IDLEIE) USBSuspend(); if(UIRbits.SOFIF && UIEbits.SOFIE) USB_SOF_Handler(); if(UIRbits.STALLIF && UIEbits.STALLIE) USBStallHandler(); if(UIRbits.UERRIF && UIEbits.UERRIE) USBErrorHandler(); /* * Pointless to continue servicing if the host has not sent a bus reset. * Once bus reset is received, the device transitions into the DEFAULT * state and is ready for communication. */ if(usb_device_state < DEFAULT_STATE) return; /* * Task D: Servicing USB Transaction Complete Interrupt */ if(UIRbits.TRNIF && UIEbits.TRNIE) { /* * USBCtrlEPService only services transactions over EP0. * It ignores all other EP transactions. */ USBCtrlEPService(); /* * Other EP can be serviced later by responsible device class firmware. * Each device driver knows when an OUT or IN transaction is ready by * checking the buffer ownership bit. * An OUT EP should always be owned by SIE until the data is ready. * An IN EP should always be owned by CPU until the data is ready. * * Because of this logic, it is not necessary to save the USTAT value * of non-EP0 transactions. */ UIRbits.TRNIF = 0; }//end if(UIRbits.TRNIF && UIEbits.TRNIE) }//end USBDriverService