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.

CC2430, Simpliciti, and sleep mode

Other Parts Discussed in Thread: SIMPLICITI, CC2430

I'm writing a simple Simpliciti application where an end device samples an A/D channel once per second, then sends the data to an access point and then sleeps in between sampling.  I read DN106 and included the code from that app note.  What happens is that the end device goes to sleep, then wakes up once, then goes back to sleep and never wakes up again.  Here's the relavent code:

#pragma vector=ST_VECTOR
__interrupt void ST_IRQ (void)
{
   unsigned short sample=0;

   // Clear IRCON.STIF (Sleep Timer CPU interrupt flag)
   IRCON &= 0x7F;

   sample = AdcRead(0); // P0_0

   data_buffer[0] = LO_UINT16( sample );
   data_buffer[1] = HI_UINT16( sample );
   SMPL_Send(sLinkID1,data_buffer,BUFFER_LENGTH);

  // Set SLEEP.MODE according to desired PM, e.g. PM1.
  SLEEP = (SLEEP & 0xFC) | 0x01;
  // Apply three NOPs to allow the corresponding interrupt blocking to take
  // effect, before verifying the SLEEP.MODE bits below. Note that all
  // interrupts are blocked when SLEEP.MODE ‚ 0, thus the time between
  // setting SLEEP.MODE ‚ 0, and asserting PCON.IDLE should be as short as
  // possible. If an interrupt occurs before the NOPs have completed, then
  // the enabled ISR shall clear the SLEEP.MODE bits, according to the code
  // in Figure 7.
  asm("NOP");
  asm("NOP");
  asm("NOP");
  // If no interrupt was executed in between the above NOPs, then all
  // interrupts are effectively blocked when reaching this code position.
  // If the SLEEP.MODE bits have been cleared at this point, which means
  // that an ISR has indeed executed in between the above NOPs, then the
  // application will not enter PM{1 . 3} !
  if (SLEEP & 0x03)
  {
  // Set PCON.IDLE to enter the selected PM, e.g. PM1.
  PCON |= 0x01;
  // The SoC is now in PM and will only wake up upon Sleep Timer interrupt
  // or external Port interrupt.
  // First instruction upon exiting PM.
  asm("NOP");
  }

   // Clear the SLEEP.MODE bits, because an interrupt can also occur before
   // the SoC has actually entered PM. If this interrupt occurs in between the
   // three NOPs (that is; before the corresponding interrupt blocking has
   // actually taken effect) in Figure 2, then this clearing of the SLEEP.MODE
   // bits will ensure that the application does not enter PM{1 – 3}.
   SLEEP &= 0xFC; // Not required when resuming from PM0 }

void main(void)
{
  addr_t addr = {0x7A,0x56,0x34,MODULE_ADDR};

  // Set first byte of the buffer to the module address, don't overwrite.
  // MS bit, if set, used to indicate low battery
  data_buffer[0] = MODULE_ADDR;

  BSP_Init();

  ///////////// Code section #1 begin: Switch to [HS RCOSC] ////////////
  // Power up [HS RCOSC] (SLEEP.OSC_PD = 0)
  SLEEP &= ~0x04;
  // Wait until [HS RCOSC] is stable (SLEEP.HFRC_STB = 1)
  while ( ! (SLEEP & 0x20) );
  // Switch system clock source to HS RCOSC (CLKCON.OSC = 1)
  CLKCON |= 0x40;
  // Wait until system clock source has actually changed (CLKCON.OSC = 1)
  while ( !(CLKCON & 0x40) );
  // Power down [HS XOSC] (SLEEP.OSC_PD = 1)
  SLEEP |= 0x04;

 /* set device address before the
   * call to SMPL_Init(). If the address is set here the ROM value will not
   * be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call
   * will not take effect. One shot only. The IOCTL call below is conformal.
   */

  SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &addr);

  /* Keep trying to join until successful. Toggle LEDs to indicate that
   * joining has not occurred.
   */
  while (SMPL_SUCCESS != SMPL_Init(sCB))
  {
    toggleLED(1);
    SPIN_ABOUT_A_SECOND;
  }

  // LEDs on solid to indicate successful join.
  if (!BSP_LED1_IS_ON())
  {
    toggleLED(1);
  }

  // Keep trying to link...
  while (SMPL_SUCCESS != SMPL_Link(&sLinkID1))
  {
    toggleLED(1);
    SPIN_ABOUT_A_SECOND;
  }

  // wake up radio. we need it to listen for broad cast messages.
  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_AWAKE, 0);

  // turn on RX. default is RX off.
  SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0);

  // 24 bit register that sets when the wakeup timer triggers
  // uses 34 khz clock.  All 0xff's would be 8.2 min.
  ST2 = 0x00;
  ST1 = 0xFF;
  ST0 = 0xFF;

  IRCON &= 0x7F;  // Clear IRCON.STIF (Sleep Timer CPU interrupt flag)

  STIE = 1;
  EA = 1;

  // Set SLEEP.MODE according to desired PM, e.g. PM1.
  SLEEP = (SLEEP & 0xFC) | 0x01;
  // Apply three NOPs to allow the corresponding interrupt blocking to take
  // effect, before verifying the SLEEP.MODE bits below. Note that all
  // interrupts are blocked when SLEEP.MODE ‚ 0, thus the time between
  // setting SLEEP.MODE ‚ 0, and asserting PCON.IDLE should be as short as
  // possible. If an interrupt occurs before the NOPs have completed, then
  // the enabled ISR shall clear the SLEEP.MODE bits, according to the code
  // in Figure 7.
  asm("NOP");
  asm("NOP");
  asm("NOP");
  // If no interrupt was executed in between the above NOPs, then all
  // interrupts are effectively blocked when reaching this code position.
  // If the SLEEP.MODE bits have been cleared at this point, which means
  // that an ISR has indeed executed in between the above NOPs, then the
  // application will not enter PM{1 . 3} !
  if (SLEEP & 0x03)
  {
  // Set PCON.IDLE to enter the selected PM, e.g. PM1.
  PCON |= 0x01;
  // The SoC is now in PM and will only wake up upon Sleep Timer interrupt
  // or external Port interrupt.
  // First instruction upon exiting PM.
  asm("NOP");
  }

  while (1);
}

Any ideas?

  • Hello ds10001,

    I am having the same problem as you, (I am also using SimpliciTI)

    I want to  send 30 packages per seconde and in the the time between sending the packages I want to use a sleep timer for about 33 msec. so that I can go in a low power mode (like PM2) for about 33 msec.

    Can you tell me what the solution was in you code to get an nice sleep timer?

    Thank you very much!!

    Kind regards, Niels

  • Hello ds1001,

    The main problem I have whit DN 106 is that I don't know which parts of the code I have to use for the CC2430 and which parts of the code are for the other chips.

    Can you give me some direction in that difficult code?

    Thank you very much!

  • Hello ds10001,

    I am also having the problem that my end device goes to sleep then wakes up once, then goes back to sleep and never wakes up again.

    Do you know a solution for this problem??

    Thank you very much!!!