Hello,
For one of the application, I want to put CC2510 in PM2 mode accurately for 10 msec, 1500 msec & 4990 msec. But I am not able to accurately obtain the sleep timing. For 10 msec, sometimes it comes as 4.69 msec, 8.68 msec. Below is the script I am using for entering the PM2 mode.
/***********************************************************************************
* @fn PM2Sleep
*
* @brief Function which put cc into sleep for given interval.
*
* @param UINT16 currentSleepInterval
* PM2 sleep interval time in the milliseconds
*
* @return void
************************************************************************************/
void PM2Sleep(UINT8 currentSleepIntervalHigh,UINT8 currentSleepIntervalLow)
{
UINT8 storedDescHigh = DMA0CFGH;
UINT8 storedDescLow = DMA0CFGL;
UINT8 temp;
// Setup + enable the Sleep Timer Interrupt, which is
// intended to wake-up the SoC from Power Mode 2.
setup_sleep_interrupt();
//Enter/exit Power Mode 2.
SLEEP &= ~SLEEP_OSC_PD;
while( !(SLEEP & SLEEP_HFRC_S) );
CLKCON = (CLKCON & ~CLKCON_CLKSPD) | CLKCON_OSC | CLKSPD_DIV_1;
while ( !(CLKCON & CLKCON_OSC) ) ;
SLEEP |= SLEEP_OSC_PD;
// Set LS XOSC as the Sleep Timer clock source (CLKCON.OSC32 = 0)
//CLKCON |= CLKCON_OSC32; // internal 32khz osc
CLKCON &= ~CLKCON_OSC32; // external 32khz osc
///////////////////////////////////////////////////////////////////////
////////// CC111xFx/CC251xFx Errata Note Code section Begin ///////////
///////////////////////////////////////////////////////////////////////
// Store current DMA channel 2 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;
// 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.
if ((activityFlag == 0)||(panicButtonPress)){
WORCTRL |= 0x05; // Reset Sleep Timer
//HAL_INT_ENABLE(INUM_P1INT, INT_ON);
}
else {
WORCTRL |= 0x01; // do not reset sleep timer
//HAL_INT_ENABLE(INUM_P1INT, INT_OFF);
}
temp = WORTIME0;
while(temp == WORTIME0);
temp = WORTIME0;
while(temp == WORTIME0);
// Set Sleep Timer Interval
//WOREVT1 = (currentSleepInterval >> 8) ;
//WOREVT0 = currentSleepInterval;
WOREVT1 = currentSleepIntervalHigh;
WOREVT0 = currentSleepIntervalLow;
temp = WORTIME0;
while(temp == WORTIME0);
// 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");
}
// 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;
halPowerClkMgmtSetMainClkSrc(CRYSTAL);
//CLKCON = (CLKCON & ~CLKCON_TICKSPD) | TICKSPD_DIV_128;
}
Please help