This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2510: CC2510 Sleep Timer

Part Number: CC2510

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

  • Venugopal,

    Please see the "CC1110, CC2510 Basic Software Examples" available here: https://www.ti.com/lit/zip/swrc117 

    In cc1110_cc2510_Basic Software_Examples/source/examples/pm you will find powermode2.c which shows how to properly enter power mode 2, and then exit on sleep timer interrupt.

    Regards,

    Daniel

  • Hello Daniel,

    I am using the sample code only. Below are the results I got,

    WORCTRL |= 0x05

    EVENT0 (MSB Byte) EVENT0 (LSB Byte) Actual Time (msec) Expected Time (msec)
    0 20 18.8 19.5
    0 30 28.6 29.3
    0 40 38.4 39
    0 50 48 48.8
    0 60 57.9 58.6
    0 100 96.8 97.65
    0 200 193 195.3
    0 300 289 292.97
    0 500 483 488.27
    0 1000 976 976
    0 2000 1950 1953.1

    The expected time is as per datasheet calculation?

    Is this the best we can get ?

  • Venugopal,

    Are you using a 32.768 kHz crystal oscillator, or the low-power RC oscillator? Are you running on custom hardware? Have you verified clock timings in other power modes? Depending on your hardware setup, the delta between expected and measured will make sense.

    Regards,

    Daniel