I have had difficulty getting the CC1110's sleep timer to function. Thus far I've only concerned myself with PM0/PM1 as to avoid the infamous errata. Using DN106 as a guide, I've pieced together the following minimum test case. It's Figure 3 from DN106 inside a loop that flips a pin each pass through. If working properly, I should see the pin alternate back and forth; however, the processor never awakes from sleep (verified in the debugger) in either PM0 or PM1. I'm at a loss for where the problem lies
The hardware in question is a custom CC1110 board. Radio and GPIO functions are all working properly. There is no external 32kHz crystal installed, so I'm trying to run off the internal RC oscillator. Single stepping in the debugger shows the count registers of the sleep timer to be incrementing (implying the sleep timer is running).
void main(void) { // Initialize hardware char temp = WORTIME0; CLKCON = 0xB9; // TICKSPD = fRef/128; CLKSPD = fRef/2; Use Crystal // TICKSPD = 187.5 kHz; CLKSPD = 12 MHz while(!(SLEEP & 0x40)); SLEEP |= 0x04; // Interface controls LED = LED_OFF; P0DIR |= LED_MASK; for(;;) { // Go to sleep SLEEP = (SLEEP & 0xFC) | 0x01; asm("NOP"); asm("NOP"); asm("NOP"); if(SLEEP & 0x03) { WORCTL |= 0x04; // Reset Sleep Timer temp = WORTIME0; // Wait until a postitive 32 kHz edge while(temp == WORTIME0); temp = WORTIME0; // Wait until a postitive 32 kHz edge while(temp == WORTIME0); WOREVT1 = 0x10; WOREVT0 = 0x00; PCON |= 0x01; // Enter PM asm("NOP"); } // Flip LED LED = !LED; }}
Hi Jonathan,
You will need to enable the sleep timer interrupt in order to get the CPU to wake up from power modes.
Enable Sleep Timer interrupt and Global Interrupt by setting IEN0 = 0xA0;You will also need to add an Sleep Timer interrupt vector where you make sure you clear the interrupt flag.
--PS. Thank you for clicking Verify Answer if this answered your question!
I guess I'll close this with my results (so it's available for searching later). Adding the obvious fix (makes me feel a little silly), I can get it to wake up from PM0 but not PM1. Adding around the SLEEP |= 0x40 line:
while(!(SLEEP & 0x40)); SLEEP |= 0x04; WORIRQ |= 0x10; STIE = 1; EA = 1;
And an interrupt vector:
#pragma vector = ST_VECTORstatic __interrupt void SleepTimer(void) { STIF = 0; WORIRQ &= 0xFE; SLEEP &= 0xFC;}
The system will wake up from PM0 and operate properly; however, in PM1 it will wake up exactly once and then stay permanently asleep the next pass through the loop. This appears to be because it reenters sleep before the crystal oscillator stabilizes (a setting retained during the sleep). Adding a pre-sleep delay (such as timered PM0 sleep) or switching over the the HS RCOSC seems to fix that.
Hi,Try replace your xtal monitor instruction as follows:/*while(!(SLEEP & 0x40));*/while(CLKCON & 0x40);This will monitor [CLKCON.OSC] to ensure that the [HS XOSC] is not only stable,but also actually applied as system clock source before continuing code execution.Cheers,RF4ALL