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.

Low-Power on Chronos

Other Parts Discussed in Thread: SIMPLICITI

I am trying to use low-power mode on the Chronos watch.  I am using CCS v5.2 and SimpliciTI to communicate with another device.  The Chronos is only receiving two bytes of data every two seconds and displaying the value on the watch.  I would like to be in low power mode when not receiving data.  Where should I enter and exit low power mode?

I have the following functions that have been modified from the example peer-to-peer application:

- static void linkFrom().

- static uint8_t sRxCallback(linkID_t port). 

In function linkFrom(), low-power mode is entered after a reply has been sent.  The callback function sRxCallback() exits low-power.

When the application runs, sRxCallback() is called and updates the display but the while(1) in function linkFrom() is never runs.

Any suggestions on the proper use of low-power for this application.

 

static void linkFrom()

{

  uint8_t  msg[2], tid = 0;

  u8 string[8];

 

 

  /* listen for link forever... */

  display_chars(LCD_SEG_L1_3_0, (u8 *) " 321", SEG_ON); // status message

  while (1)

  {

    if (SMPL_SUCCESS == SMPL_LinkListen(&sLinkID2))

    {

      break;

    }

    /* Implement fail-to-link policy here. otherwise, listen again. */

  }

 

  display_chars(LCD_SEG_L1_3_0, (u8 *) " -- ", SEG_ON); // double dash on LCD Line1

  memcpy(string, " SRN02", 6);

  display_chars(LCD_SEG_L2_5_0, string, SEG_ON);        // message on LCE Line2

   /* turn on LED1 on the peer in response to receiving a frame. */

   *msg = 0x01;

 

   /* turn on RX. default is RX off. */

   SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);

 

   while (1)

   {

     /* Wait for a frame to be received. The Rx handler, which is running in

      * ISR thread, will post to this semaphore allowing the application to

      * send the reply message in the user thread.

      */

     if (sSemaphore)

     {

       *(msg+1) = ++tid;

       SMPL_Send(sLinkID2, msg, 2);

 

       /* Reset semaphore. This is not properly protected and there is a race

        * here. In theory we could miss a message. Good enough for a demo, though.

        */

 

       sSemaphore = 0;

 

       // Reply has been sent. go into Low-Power

       _BIS_SR(LPM3_bits + GIE);

     }

   }

}

 

 

/* handle received messages */

static uint8_t sRxCallback(linkID_t port)

{

  static int ToggleFlag = 0;

  uint8_t msg[2], len;

  uint8_t value = 0;

  u8 *str;

  uint8_t ret_val = 0;

 

  // exit Low-power mode so linkFrom() will run

  _BIC_SR(LPM3_bits);

 

  /* is the callback for the link ID we want to handle? */

  if (port == sLinkID2)

  {

    /* yes. go get the frame. we know this call will succeed. */

     if ((SMPL_SUCCESS == SMPL_Receive(sLinkID2, msg, &len)) && len)

     {

       /* Check the application sequence number to detect

        * late or missing frames...

        */

       value = msg[1];

       if ((value > 0) && (value < 100))

       {

           // good number, diaplay it.

           str = int_to_array(value, 3, 1);

           display_chars(LCD_SEG_L1_3_1, str, SEG_ON);

           sRxTid = value;

       }

       else

       {

           // invalid number, display double dash.

           display_chars(LCD_SEG_L1_3_0, (u8 *) " -- ", SEG_ON);

           sRxTid = value;

       }

 

       // just toggle the % symbol so we know it's alive.

       if (ToggleFlag != 0)

        {

          display_symbol(LCD_SYMB_PERCENT, SEG_ON);

          ToggleFlag = 0;

        }

        else

        {

          display_symbol(LCD_SYMB_PERCENT, SEG_OFF);

          ToggleFlag = 1;

        }

 

       /* Post to the semaphore to let application know so it sends

        * the reply

        */

       sSemaphore = 1;

       /* drop frame. we're done with it. */

       ret_val = 1;

     }

  }

  /* keep frame for later handling */

  return(ret_val);

}

 

  • Before diving into specifics, would you mind providing some clarification on what the network topology looks like?  It sounds like this may be a peer-to-peer type network, but I don't want to just assume that is the case.

    From a low power mode standpoint, is your intention to keep the radio receiver running to be listening for messages, or would you want the entire radio and MCU to be in a low power mode, then wake up periodically?

  • I am running in a peer-to-peer network.  A sensor with an Anaren A1101R09A radio sends data to the Chronos watch every two seconds.

    I have the Chronos radio receiver running continuously just listening for messages and it drains the battery quickly.

  • Does your application require reception of every message sent by the sensor unit, which transmits data every 2 seconds?  Or can it handle dropping data packets?

    If you place the Chronos radio into low power state, at that point it will not be able to receive any messages from the sensor.  You could have your Chronos firmware also wake up periodically, turn the radio on and scan for messages, then go back to sleep.  You will need to be careful about duty cycles as you may yourself in a scenario where the sensor and Chronos watch may be out of sync and "chasing" each other.

    Would you be able to provide additional clarity on what your application can tolerate and expectations you have of the data transmissions?

  • The application does require receiving data every two seconds.  I could sync the sensor and Chronos time and have the Chronos exit low-power and start the radio before the sensor sends the message. Then turn off the radio after the message is received and go into a low-power state.

     

    Can I turn on/off the radio with the following commands?

    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SLEEP, 0);

     

  • Yes, those are the IOCTL commands to use to configure the radio in a sleep mode and wake it up.

  • I ended up using: 

    SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0);

     

    Which command is preferred for conserving power?

  • Both the IOCTL_ACT_RADIO_RXIDLE and IOCTL_ACT_RADIO_SLEEP place the radio subsystem of the CC430 into a lower power state.  The question is to degree and whether your application can handle the associated tradeoffs.  The CC430 Family User's Guide can provide some detail into the differences between the radio subsystem IDLE state and SLEEP state.  Regarding the power consumption difference, the CC430 datasheet will show the current consumption for the radio subsystem in the various low power states.

    The SLEEP will be a lower power state, but will take the radio subsystem longer to wake up.

  • You could use Wake-On-Radio. Its a rx polling hardware function of this SoC, with that the device that detect if another device is sending. It is possible to implement it in SimpliciTI/the Chronos Project although it is not officially supported.