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.

sleep timer in CC2530

Other Parts Discussed in Thread: CC2530, CC2533

i would like to know if the 24bit sleep timer in CC2530 can be used as a general compare timer

basically i want the sleep timer to continue counting after compare event in active mode

and in PM2 mode i would want the count to reset to 0x000000 on a compare.  

  • bosco jacinto said:

    i would like to know if the 24bit sleep timer in CC2530 can be used as a general compare timer

    basically i want the sleep timer to continue counting after compare event in active mode

    Yes, the sleep timer can be used as a general counter in any power mode (except PM3). It will always keep counting after a compare has occurred

    bosco jacinto said:
    and in PM2 mode i would want the count to reset to 0x000000 on a compare.

    It is not possible to reset the sleep timer; it will always keep counting from power-up. In order to have the effect of a reset, you need to store an offset value that you subtract from the sleep timer value that you have read.

  • Thanks for the answers , well i got one other question

    My requirement is that i have to at certain times modify the sleep count value , according from what i know from the datasheet is that you can only write the compare value to the sleep timer registers and can only read the count value . Is there any way i can modify the current sleep count by writing the new sleep count ?

     

    Thanks in advance

  • No, you have to use an offset as I suggested. But you could hide this offset into library routines and thus make it transparent for the rest of your application.

  • i dint quite understand the meaning of offset apart from that a few other things are unclear

    1) does the sleep timer by default starts on reset after the 32khz clock is stable?

    2) what happens when the count value reachs the default compare value (oxFFFFFF) when in active mode and also in PM2 mode?

    3)can i write the sleep count in active mode directly? and if through the offset method how would i calculate the offset in the from of an equation ?

    Thanks

  • bosco jacinto said:
    1) does the sleep timer by default starts on reset after the 32khz clock is stable?

    The sleep timer starts on 0 on reset. Unfortunately, when you switch to the 32 kHz crystal, the sleep timer will count on the clock prior to stabilization. You must therefore wait for the crystal stabilizing time (approx. 500 ms) before you start using the sleep timer.

    bosco jacinto said:
    2) what happens when the count value reachs the default compare value (oxFFFFFF) when in active mode and also in PM2 mode?

    If you have an interrupt enabled, you will get an interrupt at that time. If you don't want to have any interrupt, just disable the sleep timer interrupt. When you enable the sleep timer interrupt, you should first clear STIF in case of a pending interrupt.

    bosco jacinto said:
    3)can i write the sleep count in active mode directly? and if through the offset method how would i calculate the offset in the from of an equation ?

    No, there is absolutely no way of writing to the sleep timer. I think the idea of an offset is probably best illustrated with a code example. The code is completely untested, so there may be errors:

    long st_offset;

    void set_st_value(unsigned long value) {
      // Emulates setting the sleep timer to a value
      unsigned long curr_st_val;
      // Disable sleep timer interrupt since the new offset will modify the time base
      STIE = 0;
      ((unsigned char *)(& curr_st_val))[0] = ST0;
      ((unsigned char *)(& curr_st_val))[1] = ST1;
      ((unsigned char *)(& curr_st_val))[2] = ST2;
      ((unsigned char *)(& curr_st_val))[3] = 0;

      st_offset = value - st_val;
    }

    unsigned long read_st_value(void) {
      // Reads the sleep timer and corrects for offset
      unsigned long curr_st_val;
      ((unsigned char *)(& curr_st_val))[0] = ST0;
      ((unsigned char *)(& curr_st_val))[1] = ST1;
      ((unsigned char *)(& curr_st_val))[2] = ST2;
      ((unsigned char *)(& curr_st_val))[3] = 0;
       return (curr_st_val + st_offset) & 0x00FFFFFFL;
    }

    void set_st_compare(unsigned long compare_val) {
      // Sets the ST compare to an offset corrected value
      unsigned long st_compare;
      st_compare = compare_val + st_offset;
      // Wait until sleep timer is ready to accept a new compare value
      while (STLOAD == 0);
      ST2 = ((unsigned char *)(& st_compare))[2];
      ST1 = ((unsigned char *)(& st_compare))[1];
      ST0 = ((unsigned char *)(& st_compare))[0];
      // Clear and enable ST interrupt
      STIF = 0;
      STIE = 1;
      // Global interrupt enable
      EA = 1;
    }

     

     

  • thanks the code example actually helped , well actually i need to put the device to sleep and then on wake up i need my sleep timer to start counting for 0

    but since i cant do that i will have to read the sleep timer in the wakeup isr and that would be my offset

  •  Hello,

        I am using CC2533 for asset tracking application and my application requires me to keep the device awake for 1 sec and in sleep for the next corresponding 4sec. I am using the example code which you have provided here, with a few alterations of my own. Am attaching the “SLEEP CODE” with this mail. Is there any hardware testing I can do to be sure that the device is in sleep mode at a particular point of time. Though I program the device(CC2533) to get into sleep mode, I am not SURE that the device is getting into sleep mode. Are there any other registers I need to configure than the ones I already have? Any kind of suggestions are welcome. Sorry for my ignorance.

     Thanks and Regards,

    Nikhil S.

     CODE -->

    unsigned long st_compare,done=0;

     

    #define _PRAGMA(x) _Pragma(#x)

     

    #define HAL_ISR_FUNC_DECLARATION10(f,v)   \

        _PRAGMA(vector=v) __near_func __interrupt void f(void)

    #define HAL_ISR_FUNC_PROTOTYPE10(f,v)     \

        _PRAGMA(vector=v) __near_func __interrupt void f(void)

    #define HAL_ISR_FUNCTION10(f,v)           \

        HAL_ISR_FUNC_PROTOTYPE10(f,v); HAL_ISR_FUNC_DECLARATION10(f,v)

     

    HAL_ISR_FUNCTION10( rfIsr10, ST_VECTOR )

    {

        STIF = 0;

      STIE = 1;

      done=!done;

      done=1; 

       if(done)

      {

     

        while (STLOAD == 0);

        st_compare = read_st_value();

        put_value(st_compare);

         P0_1=!P0_1;

       }

       if(!done)

      {

         while (STLOAD == 0);

        st_compare = read_st_value();

        put_value(st_compare);

         P0_1=!P0_1;

      }

     }

     

    unsigned long read_st_value(void)

    {

      unsigned long curr_st_val,st_offset=0x000020;

      if(done)

        st_offset=0x07D00;

      if(!done)

        st_offset=0x01F400;

      ((unsigned char *)(& curr_st_val))[0] = ST0;

      ((unsigned char *)(& curr_st_val))[1] = ST1;

      ((unsigned char *)(& curr_st_val))[2] = ST2;

      ((unsigned char *)(& curr_st_val))[3] = 0;

      return (curr_st_val + st_offset) & 0x00FFFFFFL;

    }

    void put_value(unsigned long st_compare)

    {

      ST2 = ((unsigned char *)(& st_compare))[2];

      ST1 = ((unsigned char *)(& st_compare))[1];

      ST0 = ((unsigned char *)(& st_compare))[0];

      while(STLOAD == 0x01);

    }

     

    main()

    {

    EA = 1;

    IEN0 |= 0xA0; 

    SLEEPCMD |= 0x02;

      STIF = 0;

      STIE = 1;

      EA = 1;

       while (STLOAD == 0);

       st_compare = read_st_value();

       ST2 = ((unsigned char *)(& st_compare))[2];

      ST1 = ((unsigned char *)(& st_compare))[1];

      ST0 = ((unsigned char *)(& st_compare))[0];

       while(1);

     }

     

  • Hi Hec,

    These routines will be useful for implementation. Just one doubt in mind,from where comes st_val in below loop? Or is it curr_st_val? Please clarify

    void set_st_value(unsigned long value) {
      // Emulates setting the sleep timer to a value
      unsigned long curr_st_val;
      // Disable sleep timer interrupt since the new offset will modify the time base
      STIE = 0;
      ((unsigned char *)(& curr_st_val))[0] = ST0;
      ((unsigned char *)(& curr_st_val))[1] = ST1;
      ((unsigned char *)(& curr_st_val))[2] = ST2;
      ((unsigned char *)(& curr_st_val))[3] = 0;

      st_offset = value - st_val;
    }


    With Regards,

    Harshal

  • Hi Harshal,

    Yes, this is supposed to be curr_st_val. As I wrote, this code was not tested, so there may be other errors as well.