📄 usb_suspend.c
字号:
/// \addtogroup module_usb_suspend
/// @{
#include "cc2511_usb_library_headers.h"
static __xdata BYTE ramCode[14]; ///< Contain the code holding the chip in PM1 while the USB is in suspend.
static __xdata VFPT pRamCode = 0; ///< Funtion pointer used to get the chip to execute code from XDATA.
/** \brief Put the chip into power mode 1 during USB suspend.
*
* This function must be called from main, do not call from inside any interrupt service routine.
* Only call this function once for each USB suspend event, clear the USB suspend event flag before calling this function.
* When calling this function the chip will be taken to power mode 1.
* Do NOT turn of the 48 MHz crystal before calling this function.
* To comply with the USB spec, this functin must be called within 10 ms after the USB SUSPEND event flag is set.
* The chip will stay in power mode 1 until a USB resume or USB reset is detected on the USB bus.
* The sleep timer can be used to regularly wake the chip up to listen for incoming RF packets,
* this way remote wakeup can be supported.
* It is important that all interrupt service routines that may potentially wake the chip from power mode 1 during USB suspend
* wait for the XOSC to become stable before doing anything.
* E.g. all ISR must start with the code:
* while( ! XOSC_STABLE );
*
*/
void usbsuspEnter(void)
{
pRamCode();//enter supend loop, running code from XDATA.
}
/** \brief Call during USB suspend to perform a remote wakeup.
* This function will wake the chip from power mode 1, resume the USB part and signal a remote wakeup to the host (PC).
* Note that this function will block for 10 ms while doing the remote wakeup signaling.
* A remote wakeup can only be performed if usbfwData.remoteWakeup is TRUE,
* e.g. the host has granted this device the right to perform a remote wakeup.
*
* \return BOOL \n
* If \c TRUE the device have the right to perform a remote wakeup, and a remote wakeup have been performed. \n
* If \c FALSE the device does not have the right to perform a remote wakeup, and a remote wakeup have not been performed. \n
*/
BOOL usbsuspDoRemoteWakeup(void)
{
if(! usbfwData.remoteWakeup) return FALSE;//we are not allowed to do remote wakeup
usbsuspExit();
while(! XOSC_STABLE); //wait for XOSC to start
usbirqData.inSuspend = FALSE;
USBPOW |= 0x04; //signal USB resume on the USB bus
halWait(10); //hold the signaling for 10 ms.
USBPOW &= ~0x04; // release USB resume on the USB bus
return TRUE;//remote wakeup performed.
}
/** \brief Internal function, do not call from application.
*
* This function is called from usb_interrupt.c when a suspend interrupt occurs.
* It should not be called from anywhere else.
* The function make the preparations necessary to ensure that the chip will wake from PM1 when the resume interrupt occurs.
* The chip will not enter PM1 until \ref usbsuspEnter() is called.
* \ref usbsuspEnter() should be called from main within 10 ms after receiving the SUSPEND interrupt to comply with USB spec.
* Taking the chip to PM1 is necessary to comply with USB current consumption limitations.
* The sleep timer may wake the chip up at regular intervals to listen for packets, this way remote wakeup can be supported.
*/
void usbsuspInit(void)
{
pRamCode = (VFPT) ((UINT16) ((__xdata BYTE *) &ramCode[0]));
//SLEEP &= ~0x03; / ANL SLEEP, #0xFC
ramCode[0] = 0x53;
ramCode[1] = 0xBE;
ramCode[2] = 0xFC;
//SLEEP |= 0x01; / ORL SLEEP, #0x01
ramCode[3] = 0x43;
ramCode[4] = 0xBE;
ramCode[5] = 0x01;
//PCON = 0x01; / MOV PCON, #0x01
ramCode[6] = 0x75;
ramCode[7] = 0x87;
ramCode[8] = 0x01;
//while(inSuspend); / MOW A, inSuspend
ramCode[9] = 0xE5;
ramCode[10] = (BYTE) ((__data BYTE *) &usbirqData.inSuspend);
//JNZ -12
ramCode[11] = 0x70;
ramCode[12] = 0xF3;
//return; / RET
ramCode[13] = 0x22;
}
/** \brief Internal function, do not call from application..
*
* This function is automatically called from usb_interrupt.c when a USB resume or USB reset interrupt occurs
* It will get the chip out of power mode 1.
*/
void usbsuspExit(void)
{
// The USB part is no longer in suspend, remove the PCON = 0x01 instruction to avoid entering PM1.
// The chip will exit the suspend loop when the crystal is stable and the P2 USB resume or reset interrutp has occured.
ramCode[6] = 0x00; //NOP
ramCode[7] = 0x00; //NOP
ramCode[8] = 0x00; //NOP
}
//@}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -