/******************************************************************** Function: bool USBSleepOnSuspend(void) Summary: Places the core into sleep and sets up the USB module to wake up the device on USB activity. PreCondition: IPL (in the SR register) must be non-zero. Parameters: None Return Values: true - if entered sleep successfully false - if there was an error entering sleep Remarks: Please note that before calling this function that it is the responsibility of the application to place all of the other peripherals or board features into a lower power state if required. *******************************************************************/ bool USBSleepOnSuspend(void) { unsigned int U1EIE_save, U1IE_save, U1OTGIE_save; unsigned char USB1IE_save; #if defined(USB_POLLING) //If IPL is equal to 0 then there is no way for the USB module to // generate an interrupt to wake up the device. if(_IPL == 0) { return false; } //Set the interrupt priority to a level that will wake up the part (>0) // but will not cause a interrupt vector jump (USB1IP<=IPL) _USB1IP = 1; #endif //Save the old interrupt and CPU settings U1EIE_save = U1EIE; U1IE_save = U1IE; U1OTGIE_save = U1OTGIE; USB1IE_save = IEC5bits.USB1IE; //Disable all USB interrupts U1EIE = 0; U1IE = 0; U1OTGIE = 0; //Enable the interrupt IFS5bits.USB1IF = 0; U1OTGIEbits.ACTVIE = 1; USBClearInterruptFlag(USBActivityIFReg,USBActivityIFBitNum); IEC5bits.USB1IE = 1; Sleep(); #if defined(USB_POLLING) //Disable the interrupt _USB1IP = 0; #endif //restore the previous interrupt settings IEC5bits.USB1IE = USB1IE_save; U1EIE = U1EIE_save; U1IE = U1IE_save; U1OTGIE = U1OTGIE_save; return true; }
void __attribute__ ((interrupt)) _USB1Interrupt(void) { #if !defined(self_powered) if(U1OTGIRbits.ACTVIF) { IEC5bits.USB1IE = 0; U1OTGIEbits.ACTVIE = 0; IFS5bits.USB1IF = 0; //USBClearInterruptFlag(USBActivityIFReg,USBActivityIFBitNum); USBClearInterruptFlag(USBIdleIFReg,USBIdleIFBitNum); //USBSuspendControl = 0; } #endif }
/************************************************************************* Function: BOOL USBSleepOnSuspend(void) Summary: Places the PIC24F devices in sleep after enabling the USB activity flag to wake it back up. Conditions: IPL (in the SR register) must be non-zero. Input: None Return: TRUE - if entered sleep successfully FALSE - if there was an error entering sleep Remarks: None *************************************************************************/ BOOL USBSleepOnSuspend(void) { unsigned int U1EIE_save, U1IE_save, U1OTGIE_save; unsigned char USB1IE_save; //Save the old interrupt and CPU settings U1EIE_save = U1EIE; U1IE_save = U1IE; U1OTGIE_save = U1OTGIE; USB1IE_save = IEC5bits.USB1IE; #if defined(USB_POLLING) //If IPL is equal to 0 then there is no way for the USB module to // generate an interrupt to wake up the device. if(_IPL == 0) { return FALSE; } #endif //Disable all USB interrupts // 2011/12/13, mar: moved this code down where we do not exit in // polling mode. In Polling all usb-ir flags were disabled, and // we could never change to the activated state as the activate // enable bit was cleared. If we do not use any interrupts, the // IPL level is 0. U1EIE = 0; U1IE = 0; U1OTGIE = 0; #if defined(USB_POLLING) //Set the interrupt priority to a level that will wake up the part (>0) // but will not cause a interrupt vector jump (USB1IP<=IPL) _USB1IP = 1; #endif //Enable the interrupt IFS5bits.USB1IF = 0; U1OTGIEbits.ACTVIE = 1; USBClearInterruptFlag(USBActivityIFReg,USBActivityIFBitNum); IEC5bits.USB1IE = 1; { /* PIC24FJ64GB004 Family Silicon Errata: point 7 */ unsigned char spienbits[2]; #ifdef __PIC24FJ128GB202__ spienbits[0] = SPI1CON1Lbits.SPIEN; if(SPI2CON2L&0x8000) spienbits[1]=1; else spienbits[1]=0; SPI1CON1Lbits.SPIEN = 0; SPI2CON1L = (SPI2CON1L&0x7FFF); Sleep(); SPI1CON1Lbits.SPIEN = spienbits[0]; SPI2CON1L = ((SPI2CON1L&0x7FFF) | (spienbits[1]<<15)); #else spienbits[0] = SPI1STATbits.SPIEN; spienbits[1] = SPI2STATbits.SPIEN; SPI1STATbits.SPIEN = 0; SPI2STATbits.SPIEN = 0; Sleep(); SPI1STATbits.SPIEN = spienbits[0]; SPI2STATbits.SPIEN = spienbits[1]; #endif } #if defined(USB_POLLING) //Disable the interrupt _USB1IP = 0; #endif //restore the previous interrupt settings IEC5bits.USB1IE = USB1IE_save; U1EIE = U1EIE_save; U1IE = U1IE_save; U1OTGIE = U1OTGIE_save; return TRUE; }