void usb_handler(void) { if (USB_IDLE_FLAG) { /* Idle - suspend */ USBSuspend(); // // Must be defined in user code. ClearUsbInterruptFlag(USB_IDLE); } if (USB_RESET_FLAG) { usb_handle_reset(); ClearUsbInterruptFlag(USB_URST); } if (USB_ERROR_FLAG) { // usb_handle_error(); ClearAllUsbErrorInterruptFlags(); ClearUsbInterruptFlag(USB_UERR); } if (USB_STALL_FLAG) { ClearUsbInterruptFlag(USB_STALL); } if (USB_SOF_FLAG) { /* Start-of-frame */ if (sof_handler) sof_handler(); ClearUsbInterruptFlag(USB_SOF); } if (USB_TRANSACTION_FLAG) { if (!USB_STAT2EP(GetUsbTransaction())) usb_handle_transaction(); // Only handle EP0 transactions. ClearUsbInterruptFlag(USB_TRN); // JTR Missing! This is why Ian was only getting one interrupt?? } // Side effect: advance USTAT Fifo }
/****************************************************************************** * 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