⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_suspend.c

📁 reference about wireless design which is helpful to everyone
💻 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 + -