Hi Siri
- If the worst thing that could happend is that the sleeptime is 128 times longer than intended, it cannot be the problem I'm looking for, since the device hangs forever!!!
- I have seen the new errata rev.C, but was not sure that the crystal startup-problem could generate the "hang" problem, are you agree?
- Is there som source-code that implements the work-around (sec. 1.2), since I'm a bit confused about solving this problem!!!
- Below is my sleep-routine, is this correct implemented?
void sleepTimer(unsigned short sec)
{
uint32 tempSec = sec*4;
// Initialization of source buffers and DMA descriptor for the DMA transfer
// (ref. CC111xFx/CC251xFx Errata Note)
uint8 PM2_BUF[7] = {0x06,0x06,0x06,0x06,0x06,0x06,0x04};
uint8 dmaDesc[8] = {0x00,0x00,0xDF,0xBE,0x00,0x07,0x20,0x42};
int8 EVENT0_HIGH = tempSec>>8;
int8 EVENT0_LOW = tempSec;
volatile uint8 storedDescHigh = DMA0CFGH;
volatile uint8 storedDescLow = DMA0CFGL;
int8 temp;
if(!sec)
return;
WORCTRL |= 1;
// Switch system clock source to HS RCOSC and max CPU speed:
// Note that this is critical for Power Mode 2. After reset or
// exiting Power Mode 2 the system clock source is HS RCOSC,
// but to emphasize the requirement we choose to be explicit here.
SLEEP &= ~SLEEP_OSC_PD;
while( !(SLEEP & SLEEP_HFRC_S) );
CLKCON = (CLKCON & ~CLKCON_CLKSPD) | CLKCON_OSC | CLKSPD_DIV_2;
while ( !(CLKCON & CLKCON_OSC) ) ;
SLEEP |= SLEEP_OSC_PD;
// Set LS XOSC as the Sleep Timer clock source (CLKCON.OSC32 = 0)
CLKCON &= ~CLKCON_OSC32;
// Wait some time in Active Mode, and set SRF04EB LED1 before
// entering Power Mode 2
// for(activeModeCnt = 0; activeModeCnt < ACT_MODE_TIME; activeModeCnt++);
// P1_0 = 1;
///////////////////////////////////////////////////////////////////////
////////// CC111xFx/CC251xFx Errata Note Code section Begin ///////////
///////////////////////////////////////////////////////////////////////
// Store current DMA channel 0 descriptor and abort any ongoing transfers,
// if the channel is in use.
storedDescHigh = DMA0CFGH;
storedDescLow = DMA0CFGL;
DMAARM |= (DMAARM_ABORT | DMAARM0);
// Update descriptor with correct source.
dmaDesc[0] = (uint16)&PM2_BUF >> 8;
dmaDesc[1] = (uint16)&PM2_BUF;
// Associate the descriptor with DMA channel 0 and arm the DMA channel
DMA0CFGH = (uint16)&dmaDesc >> 8;
DMA0CFGL = (uint16)&dmaDesc;
DMAARM = DMAARM0;
// Align with positive 32 kHz clock edge as described in the
// "Sleep Timer and Power Modes" chapter of the data sheet.
WORCTL = 0X04;
temp = WORTIME0;
while( temp == WORTIME0 );
temp = WORTIME0;
while( temp == WORTIME0 );
// Set Sleep Timer Interval
WOREVT0 = EVENT0_HIGH;
WOREVT1 = EVENT0_LOW;
// NOTE! At this point, make sure all interrupts that will not be used to
// wake from PM are disabled as described in the "Power Management Control"
// chapter of the data sheet.
// The following code is timing critical and should be done in the
// order as shown here with no intervening code.
// Align with positive 32 kHz clock edge as described in the
// "Sleep Timer and Power Modes" chapter of the data sheet.
temp = WORTIME0;
while(temp == WORTIME0); // Wait until a positive 32 kHz edge
// Make sure HS XOSC is powered down when entering PM{2 - 3} and that
// the flash cache is disabled.
MEMCTR |= MEMCTR_CACHD;
SLEEP = 0x06;
// Enter power mode as described in chapter "Power Management Control"
// in the data sheet. Make sure DMA channel 0 is triggered just before
// setting [PCON.IDLE].
asm("NOP");
asm("NOP");
asm("NOP");
if(SLEEP & 0x03)
{
asm("MOV 0xD7,#0x01"); // DMAREQ = 0x01;
asm("NOP"); // Needed to perfectly align the DMA transfer.
asm("ORL 0x87,#0x01"); // PCON |= 0x01 -- Now in PM2;
asm("NOP"); // First call when awake
}
// End of timing critical code
// Enable Flash Cache.
MEMCTR &= ~MEMCTR_CACHD;
// Update DMA channel 0 with original descriptor and arm channel if it was
// in use before PM was entered.
DMA0CFGH = storedDescHigh;
DMA0CFGL = storedDescLow;
DMAARM = DMAARM0;
///////////////////////////////////////////////////////////////////////
/////////// CC111xFx/CC251xFx Errata Note Code section End ////////////
///////////////////////////////////////////////////////////////////////
// Wait until HS RCOSC is stable
while( !(SLEEP & SLEEP_HFRC_S) );
// Set LS XOSC as the clock oscillator for the Sleep Timer (CLKCON.OSC32 = 0)
CLKCON &= ~CLKCON_OSC32;
}
BR
Allan