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.

Wakeup from PM2, using an external interrupt CC2510, and the WORTIME register values

Other Parts Discussed in Thread: CC2510

When (WORTIME1:WORTIME0) is read without aligning to +pve edge of slow clock, after external interrupt wakeup from PM2, the values are not consistent. When read after aligning to +ve edge of slow clock, the value seems to be consistent, but it takes any where from "100us  to 3ms" to align to +ve edge. Is there any particular order to do this??

If I have the following code Immediately after wake up from PM2 due to external interrupt,

 

 

temp1lsb = WORTIME0;

temp1msb = WORTIME1;

char temp = WORTIME0;
while(temp == WORTIME0);

temp2lsb = WORTIME0;

temp2msb = WORTIME1;

 

The temp2lsb, and temp2msb are correct relative to the time it entered in to sleep mode.

temp1lsb is read as "4", and temp1msb is read as "0"

 

The problem is it takes any where from 100us to 3.2ms for the loop.

Any Ideas what is going on??

Thanks!!

 

 

 

 

  • Hi,

    When waking up from PM2 the value in the WORTIME registers are those who where retained during power mode (i.e the value at the time one entered PM). The WORTIME register will not be updated with the current value until the next clock edge, but the trick is that when sleeping for longer than ~4ms the sleep timer logic is running at a 256 Hz clock and it’s this clock edge one have to wait for. So depending on where you are in a 256 Hz period, the while loop might take up to 3.906 msec.

    Hope this explanation helps. It will be added to the datasheet in the next update.

    Rgds,
    Kjetil

  • Thanks, that explains the behavior I see.

    Also in the data sheet "table-32" says the CLKCON is retained when coming out of PM2/PM3, but the CLKCON register definition says the CLKCON.OSC32K bit is reset to RC mode after it wakes up from PM2/PM3.

    I am assuming that the information in the  CLKCON register definition is correct. If so, Is there any way to avoid turning off XOSC32K. Also if I clear the CLKCON.OSC32K(setting in XOSC mode), immediatly after wake from PM2 will that keep XOSC32k mode always??

    Regards,

    Suresh

  • singam said:

    Also in the data sheet "table-32" says the CLKCON is retained when coming out of PM2/PM3, but the CLKCON register definition says the CLKCON.OSC32K bit is reset to RC mode after it wakes up from PM2/PM3.

    I am assuming that the information in the  CLKCON register definition is correct. If so, Is there any way to avoid turning off XOSC32K. Also if I clear the CLKCON.OSC32K(setting in XOSC mode), immediatly after wake from PM2 will that keep XOSC32k mode always??

    Dear CC Support,

    I am working on the same issue and want to ask kindly for an answer to this important question from sinam.

    Addionally I need more information about this issue mentioned from Kjetil

    kjetil said:

    The WORTIME register will not be updated with the current value until the next clock edge, but the trick is that when sleeping for longer than ~4ms the sleep timer logic is running at a 256 Hz clock and it’s this clock edge one have to wait for. So depending on where you are in a 256 Hz period, the while loop might take up to 3.906 msec.

    When I wait after leaving PM2 (caused by a ext. interrupt) as recommended for the next 32kHz clock edge is then the resulting value read from WORTIME correctly including the wait time? I need the exact sleep time being in PM2 in order to correct long term SW timers. The time when the ext. interrupt happens is not important to me.

    I am seeing forward to get answers to this critical questions.

    Thank a lot!

    regards

    spachner

  • Hi Spachner & Sinam.

    spachner said:
    I am working on the same issue and want to ask kindly for an answer to this important question from sinam.

    If I'm not mistaken, the CLKCON register definition is faulty. If you have selected the XOSC32K as source, it will remain so even in PM and upon waking up.

    spachner said:
    When I wait after leaving PM2 (caused by a ext. interrupt) as recommended for the next 32kHz clock edge is then the resulting value read from WORTIME correctly including the wait time? I need the exact sleep time being in PM2 in order to correct long term SW timers. The time when the ext. interrupt happens is not important to me.

    You will read the value of the WORTIME at that event. If you need to calculate how long you have slept you will either have to reset the sleeptimer prior to entering PM (remember that the timer will be reset to 4 and also take into account the edges one have to wait for prior to entering PM2) or optionally you can read WORTIME and store it in the part of the RAM that is retained and calculate the sleep period afterwords.

    Hope this clarifies things.

    Regards,
    Kjetil

  • Hi Kjetil,

    many thanks for your quick ansers.

    Kjetil said:

    You will read the value of the WORTIME at that event. If you need to calculate how long you have slept you will either have to reset the sleeptimer prior to entering PM (remember that the timer will be reset to 4 and also take into account the edges one have to wait for prior to entering PM2) or optionally you can read WORTIME and store it in the part of the RAM that is retained and calculate the sleep period afterwords.

    I am not sure what you mean with "at that event". When you mean that the time the external interrupt happens is frozen in WORTIME then I cannot verify this behaviour.

    I made today some hours experiments concerning that and I found that I do get the sleep time including the time until the very first clock will happens, i.e. I get the time when the external event happens (CC wakes up) plus the time until the next 1/256 clock apears.

    I found also, that immediately after the very first 1/256 clock the normal 32kHz clock is established again.

    regards

    spachner

  • Hi again,

    Bad choice of words. at that event should be at the instant of reading the register.

    What you found out in the experiment is how things should work.

    Kjetil

     

  • Regarding the 256Hz clock.

    I have an application where I am using the the CC2510, and the period the device sleeps changes from 250mS to 32S.

    In another post, I have posted the following information:

    -------------------------------------------------------------------------------

    I have an application where I sleep for 250mS and wake for about 2mS. On one board only the 250mS sleep suddenly becomes 32S, which is 128 times as long (Note: the 32S is measured using my wrist watch, so it may not be exactly 128 times as long).

    Needless to say, WORCTRL.WOR_RES setting of 00, which I am using would mean the maximum possible time for the Sleep Timer would be 2 seconds, but I get 32 seconds.

    The 32 seconds I get implies that both the WORCTRL.WOR_RES, and the WORTIME0/1 setting are being changed. If this were a software bug it should happen on multiple boards, but it only happens on one board. The clock source I use is and external 32.768kHz XTAL. Vcc=3.0V.

    Rebooting via /RESET toggle or Power cycling makes the board go back to 250mS Sleep operation.

    -------------------------------------------------------------------------------

    but a quick calculation 32768Hz / 256Hz = 128 would also explain the same behavior.

    TI Staff, please comment on this urgent issue.

    (Mr?) Spachner , if you you be available to share some insight into this and other problem, I would be most grateful

    Karel

    karel at tandd dot co dot jp

     

  • Dear Karel,

    I did not encouter your problem that the sleep time enlarged suddenly. My application is similar. Sleep time is about 1 s and uptime about 0.7 ms. If I can help any further please reply.

    spachner (male :-) )

  • Dear Karel,

    Just a quick question. Have you aligned the sleep entry on a positive 32 kHz edge like described in chapter 12.8.2 in the datasheet (and errata note for the device).Failing to do this can cause unstable behavior like the one you mentioned.

    Regards,
    Kjetil

  • Kjetil,

    Thanks for the input. There is a chance that the the board in question had code which did not align the operation. I will reprogram the board (with my most recent code)  and monitor it.

    Thanks.

    Karel

  • Hi Kjetil,

    What if sleep timer event0 is the reason for entering active mode? WORTIME is reset (set to 0) when event0 occurs. Is this reset also delayed up to ~4 ms due to 256 Hz clock as described by you? Or can I read WORTIME directly (w/o aligning to WORTIME0 change) with 0 as result if I know event0 is the reason for waking up? Is the followingh sequence correct:

    Enable sleep timer IRQ (sleep timer the only thing that can wake cc1110)

    Enter PM2 according to DN106

    assert(WORTIME == 0)

    BR / Björn

  • Hi Bjørn

     

    When waking up from PM2 due to the SLEEP timer you can read WORTIME0 immediately in the SLEEP timer ISR and you will read 0.

     

    I did the following in the start of the ISR:

     

    temp = WORTIME0;

    if (temp == 0)

          toggle a LED

    else

          Do nothing

     

    In this case the LED was toggling every time the chip woke up from PM2

     

    I also did the following:

     

    temp = WORTIME0;

    while(temp == WORTIME0);

    temp = WORTIME0;

    if (temp == 1)

          toggle a LED

    else

          Do nothing

     

    Also In this case the LED was toggling, confirming that you will read 0 in WORTIME0 as soon as you wake up from PM2.

  • Dear all,

    I have a quite similar application with exactly the same strange behavior as Mr. Karel posted. I sleep for 1000ms and wake up for about 100ms to communicate with a SPI device and send data on TX. On most boards the application runs as it was designed for. BUT on some other boards it seems that the time base during normal operation suddenly increments by 128 times. When it comes to send data on TX the 26MHz works fine and data could be transmitted. Afterwards the application sleeps again exceptionally longer. A reset (disconnecting from power source) has the consequence that the time base comes back to 1000ms.

    Entering in PM2 was done according to the Errata Note and datasheet.

    What else could be the reason for? I kindly ask for an answer to my very important question!

        ///////////////////////////////////////////////////////////////////////
        ////////// 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;

        // 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);

        // Set Sleep Timer Interval
        WOREVT0 = EVENT0_HIGH;
        WOREVT1 = EVENT0_LOW;

        // 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
        }

  • Hi

    Do you remember to clear the MODE bits in all interrupts used to wake the radio from SLEEP?

    Entering power modes must be aligned to the 32 kHz clock edge (if power modes are entered on an edge you risk that the SLEEP timer will sleep 128 times too long).

    If you use for example port interrupts to wake up the chip from PM2 it is necessary to clear the MODE bits in the port ISR. This is stated in the data sheet (p. 76).
    If you fail to do so, there is a chance that you get a port interrupt after the last 32 kHz alignment before entering PM2 (see example below):

    temp = WORTIME0;
    while( temp == WORTIME0 );
    MEMCTR |= MEMCTR_CACHD;
    SLEEP = 0x06;

    asm("NOP");
    asm("NOP");
    asm("NOP");
    if( SLEEP & 0x03 ) {
    Assume a port interrupt is happening here. The time it takes to jump to the ISR and execute the code might take more than 15.624 us. That means that entering PM2 can happen on a 32 kHz edge, causing the 1/128 bug to appear. If the last thing done in the port ISR is to clear the MODE bits in the SLEEP register, the chip will enter PM0 instead. Entering PM0 will NOT trigger the 1/128 bug even if it is happening on an edge. The data sheet is currently stating that also the entering of PM0 needs to be aligned to the 32 kHz, but this is not correct.

    I do not know the plans for the CC2510 data sheet but I know that this in on the list on things that will be updated in the CC1110 data sheet.

    BR

    Siri

  • Hi Siri

    Finally after some months trying to solve the problem with the described strange behavior I think I have got the solution.

    I used the code as I already wrote in my last mail straight from the errata posted on TI webpage. As there are several identical problems on the CC1110 I have done the following update to the original errata code:

        temp = WORTIME0;
        while(temp == WORTIME0);

        WOREVT0 = EVENT0_HIGH;
        WOREVT1 = EVENT0_LOW;

        temp = WORTIME0;
        while(temp == WORTIME0);

        MEMCTR |= MEMCTR_CACHD;
        SLEEP = 0x06;
        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
        }

     

    Since this code change fortunately (up to now) I could not encounter any similar strange behavior on our product based on CC2510:    

        temp = WORTIME0;
        while(temp == WORTIME0);

        WOREVT0 = EVENT0_HIGH;
        WOREVT1 = EVENT0_LOW;

    My question: Apart from the datasheet do you agree that the original errata code for CC2510 on TI webpage also has this bug and is not suitable for further implementations?

  • Hi

    The errata states: “The code marked blue below is timing critical and should be done in the order as shown here with no intervening code.

     

    // NOTE! At this point, make sure all interrupts that will not be used to

    // wake from PM are disabled as described in chapter 13.1.3 of the datasheet.

    // Align with positive 32 kHz clock edge as described in chapter 13.8.2 of the datasheet.

    char temp = WORTIME0;

    while( temp == WORTIME0);

    // Make sure XOSC is powered down when entering PM2/3 and that the flash cache is disabled

    // NB! Replace 0x06 with 0x07 if power mode 3 is chosen instead

    MEMCTR |= 0x02;

    SLEEP = 0x06;

    // Enter power mode as described in chapter 13.1.3 in the datasheet. 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;

    asm("NOP");

    }

     

    In your original code you do the following after the aligning:

     

    WOREVT0 = EVENT0_HIGH;
    WOREVT1 = EVENT0_LOW;

     

    This is NOT in accordance with the errata note.

     

    If you look at page 123 of the data sheet is says that updating WOREVT0 and 1 should be aligned to a 32 kHz edge as well.

     

    That means that if you follow the errata note and the data sheet you will find that you must first do an alignment to avoid changing the event on an edge. Then you must implement the code in the errata and do a new alignment to avoid entering PM2 on an edge.

    BR

    Siri

  • Hi Siri,

    Could you please have a look at the provided basic code example for CC1110/CC2510 on www.ti.com/litv/zip/swrc117

     

    The following powermode2.c code example exactly shows both WOREVT lines within the errata code as discussed.

    swrc117.zip\cc1110_cc2510_Basic Software_Examples\source\examples\pm

     

    Just for understanding: Setting up a project according to this code example errata code will end up in troubles. Is that correct?

  • Hi

    I agree that the code example is not in accordance with the errata note, and the errata note is the one that is correct. I will report this issue.

    BR

    Siri