Exemple #1
0
/***************************************************************************************************
 * @fn      HalLedOnOff
 *
 * @brief   Turns specified LED ON or OFF
 *
 * @param   leds - LED bit mask
 *          mode - LED_ON,LED_OFF,
 *
 * @return  none
 ***************************************************************************************************/
void HalLedOnOff (uint8 leds, uint8 mode)
{
  if (leds & HAL_LED_1)
  {
    if (mode == HAL_LED_MODE_ON)
    {
      HAL_TURN_ON_LED1();
    }
    else
    {
      HAL_TURN_OFF_LED1();
    }
  }

  if (leds & HAL_LED_2)
  {
    if (mode == HAL_LED_MODE_ON)
    {
      HAL_TURN_ON_LED2();
    }
    else
    {
      HAL_TURN_OFF_LED2();
    }
  }

  if (leds & HAL_LED_3)
  {
    if (mode == HAL_LED_MODE_ON)
    {
      HAL_TURN_ON_LED3();
    }
    else
    {
      HAL_TURN_OFF_LED3();
    }
  }

  if (leds & HAL_LED_4)
  {
    if (mode == HAL_LED_MODE_ON)
    {
      HAL_TURN_ON_LED4();
    }
    else
    {
      HAL_TURN_OFF_LED4();
    }
  }

  /* Remember current state */
  if (mode)
  {
    HalLedState |= leds;
  }
  else
  {
    HalLedState &= (leds ^ 0xFF);
  }
}
Exemple #2
0
/***************************************************************************************************
 * @fn      HalLedOnOff
 *
 * @brief   Turns specified LED ON or OFF
 *
 * @param   leds - LED bit mask
 *          mode - LED_ON,LED_OFF,
 *
 * @return  none
 ***************************************************************************************************/
void HalLedOnOff( uint8 leds, uint8 mode )
{
  if ( leds & HAL_LED_1 )
  {
    if ( mode == HAL_LED_MODE_ON )
      HAL_TURN_ON_LED1();
    else
      HAL_TURN_OFF_LED1();
  }

  if ( leds & HAL_LED_2 )
  {
    if ( mode == HAL_LED_MODE_ON )
      HAL_TURN_ON_LED2();
    else
      HAL_TURN_OFF_LED2();
  }

  if ( leds & HAL_LED_3 )
  {
    if ( mode == HAL_LED_MODE_ON )
      HAL_TURN_ON_LED3();
    else
      HAL_TURN_OFF_LED3();
  }

  if ( leds & HAL_LED_4 )
  {
    if ( mode == HAL_LED_MODE_ON )
      HAL_TURN_ON_LED4();
    else
      HAL_TURN_OFF_LED4();
  }

    // Remember current state
  if ( mode )
    ledState |= leds;
  else
    ledState &= (0xff ^ leds);

}
Exemple #3
0
/**************************************************************************************************
 * @fn          halAssertHazardLights
 *
 * @brief       Blink LEDs to indicate an error.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
void halAssertHazardLights(void)
{
  enum
  {
    DEBUG_DATA_RSTACK_HIGH_OFS,
    DEBUG_DATA_RSTACK_LOW_OFS,
    DEBUG_DATA_TX_ACTIVE_OFS,
    DEBUG_DATA_RX_ACTIVE_OFS,

#if (defined HAL_MCU_AVR) || (defined HAL_MCU_CC2430)
    DEBUG_DATA_INT_MASK_OFS,
#elif (defined HAL_MCU_CC2530) || (defined HAL_MCU_CC2533)
    DEBUG_DATA_INT_MASK0_OFS,
    DEBUG_DATA_INT_MASK1_OFS,
#endif

    DEBUG_DATA_SIZE
  };

  uint8 buttonHeld;
  uint8 debugData[DEBUG_DATA_SIZE];

  /* disable all interrupts before anything else */
  HAL_DISABLE_INTERRUPTS();

  /*-------------------------------------------------------------------------------
   *  Initialize LEDs and turn them off.
   */
  HAL_BOARD_INIT();

  HAL_TURN_OFF_LED1();
  HAL_TURN_OFF_LED2();
  HAL_TURN_OFF_LED3();
  HAL_TURN_OFF_LED4();

  /*-------------------------------------------------------------------------------
   *  Master infinite loop.
   */
  for (;;)
  {
    buttonHeld = 0;

    /*-------------------------------------------------------------------------------
     *  "Hazard lights" loop.  A held keypress will exit this loop.
     */
    do
    {
      HAL_LED_BLINK_DELAY();

      /* toggle LEDS, the #ifdefs are in case HAL has logically remapped non-existent LEDs */
#if (HAL_NUM_LEDS >= 1)
      HAL_TOGGLE_LED1();
#if (HAL_NUM_LEDS >= 2)
      HAL_TOGGLE_LED2();
#if (HAL_NUM_LEDS >= 3)
      HAL_TOGGLE_LED3();
#if (HAL_NUM_LEDS >= 4)
      HAL_TOGGLE_LED4();
#endif
#endif
#endif
#endif

      /* escape hatch to continue execution, set escape to '1' to continue execution */
      {
        static uint8 escape = 0;
        if (escape)
        {
          escape = 0;
          return;
        }
      }

      /* break out of loop if button is held long enough */
      if (HAL_PUSH_BUTTON1())
      {
        buttonHeld++;
      }
      else
      {
        buttonHeld = 0;
      }
    }
    while (buttonHeld != 10);  /* loop until button is held specified number of loops */

    /*-------------------------------------------------------------------------------
     *  Just exited from "hazard lights" loop.
     */

    /* turn off all LEDs */
    HAL_TURN_OFF_LED1();
    HAL_TURN_OFF_LED2();
    HAL_TURN_OFF_LED3();
    HAL_TURN_OFF_LED4();

    /* wait for button release */
    HAL_DEBOUNCE(!HAL_PUSH_BUTTON1());

    /*-------------------------------------------------------------------------------
     *  Load debug data into memory.
     */
#ifdef HAL_MCU_AVR
    {
      uint8 * pStack;
      pStack = (uint8 *) SP;
      pStack++; /* point to return address on stack */
      debugData[DEBUG_DATA_RSTACK_HIGH_OFS] = *pStack;
      pStack++;
      debugData[DEBUG_DATA_RSTACK_LOW_OFS] = *pStack;
    }
    debugData[DEBUG_DATA_INT_MASK_OFS] = EIMSK;
#endif

#if (defined HAL_MCU_CC2430)
    debugData[DEBUG_DATA_INT_MASK_OFS] = RFIM;
#elif (defined HAL_MCU_CC2530) || (defined HAL_MCU_CC2533)
    debugData[DEBUG_DATA_INT_MASK0_OFS] = RFIRQM0;
    debugData[DEBUG_DATA_INT_MASK1_OFS] = RFIRQM1;
#endif


#if (defined HAL_MCU_AVR) || (defined HAL_MCU_CC2430) || (defined HAL_MCU_CC2530) || \
    (defined HAL_MCU_CC2533) || (defined HAL_MCU_MSP430)
    debugData[DEBUG_DATA_TX_ACTIVE_OFS] = macTxActive;
    debugData[DEBUG_DATA_RX_ACTIVE_OFS] = macRxActive;
#endif

   /* initialize for data dump loop */
    {
      uint8 iBit;
      uint8 iByte;

      iBit  = 0;
      iByte = 0;

      /*-------------------------------------------------------------------------------
       *  Data dump loop.  A button press cycles data bits to an LED.
       */
      while (iByte < DEBUG_DATA_SIZE)
      {
        /* wait for key press */
        while(!HAL_PUSH_BUTTON1());

        /* turn on all LEDs for first bit of byte, turn on three LEDs if not first bit */
        HAL_TURN_ON_LED1();
        HAL_TURN_ON_LED2();
        HAL_TURN_ON_LED3();
        if (iBit == 0)
        {
          HAL_TURN_ON_LED4();
        }
        else
        {
          HAL_TURN_OFF_LED4();
        }

        /* wait for debounced key release */
        HAL_DEBOUNCE(!HAL_PUSH_BUTTON1());

        /* turn off all LEDs */
        HAL_TURN_OFF_LED1();
        HAL_TURN_OFF_LED2();
        HAL_TURN_OFF_LED3();
        HAL_TURN_OFF_LED4();

        /* output value of data bit to LED1 */
        if (debugData[iByte] & (1 << (7 - iBit)))
        {
          HAL_TURN_ON_LED1();
        }
        else
        {
          HAL_TURN_OFF_LED1();
        }

        /* advance to next bit */
        iBit++;
        if (iBit == 8)
        {
          iBit = 0;
          iByte++;
        }
      }
    }

    /*
     *  About to enter "hazard lights" loop again.  Turn off LED1 in case the last bit
     *  displayed happened to be one.  This guarantees all LEDs are off at the start of
     *  the flashing loop which uses a toggle operation to change LED states.
     */
    HAL_TURN_OFF_LED1();
  }
}
Exemple #4
0
/**************************************************************************************************
 * @fn          main
 *
 * @brief       C-code main functionality.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void main(void)
{
  uint8 time_spent_validating;
  uint8 bootloaderForcedByMainApp = FALSE;
  uint32 mainAppCommandLocal = mainAppCommand;

  vddWait(VDD_MIN_RUN);

  mainAppCommand = MAIN_APP_CMD_NONE;
    
  if (mainAppCommandLocal == MAIN_APP_CMD_FORCE_BOOTLOADER)
  {
    bootloaderForcedByMainApp = TRUE;
  }
  else if ((mainAppCommandLocal == MAIN_APP_CMD_PASS_THROUGH) || ((SLEEPSTA & LRESET) == RESETWD))
  {
    // If reset due to WatchDog Timer - Transfer control to the main application immediately.
    // WatchDog Timer reset causes the hardware to disconnect the USB. Withought this jump here,
    // the SBL code will try to initiaize the CDC too early, which causes undesired behavior on the host
    // (e.g. on beaglebone black - the host gets stuck)
    asm("LJMP 0x2000\n");
  }

  sblInit(bootloaderForcedByMainApp);
  
  HAL_TURN_ON_LED1();
  HAL_TURN_ON_LED2();
  
  if ((!bootloaderForcedByMainApp) && (sbImgValid(&time_spent_validating)))
  {
    HAL_TURN_OFF_LED2();
    
    if (sblWait(SBL_WAIT_TIME > time_spent_validating ? SBL_WAIT_TIME - time_spent_validating : 0))
    {
      HAL_TURN_OFF_LED1();
      
      sbReportState(SB_STATE_EXECUTING_IMAGE);
      
      while(sblIsUartTxPending())
      {
        sbUartPoll();
      }
      
      SLEEP(0x2600); //Give the last bytes in the HW TX fifo (if any) enough time to be transmitted

      while (SB1_PRESS || SB2_PRESS);
      
      sblUnInit();
      
      // Simulate a reset for the Application code by an absolute jump to location 0x2000.
      asm("LJMP 0x2000\n");
    }
  }
  
  HAL_TURN_OFF_LED1();
  HAL_TURN_ON_LED2();
  
  vddWait(VDD_MIN_NV);
  sblExec();

  sblUnInit();

  asm("LJMP 0x2000\n");
}
Exemple #5
0
/**************************************************************************************************
 * @fn          halSleep
 *
 * @brief       This function is called from the OSAL task loop using and existing OSAL
 *              interface.  It sets the low power mode of the MAC and the CC2530.
 *
 * input parameters
 *
 * @param       osal_timeout - Next OSAL timer timeout.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void halSleep( uint16 osal_timeout )
{
  uint32        timeout;
  uint32        macTimeout = 0;

  /* get next OSAL timer expiration converted to 320 usec units */
  timeout = HAL_SLEEP_MS_TO_320US(osal_timeout);
  if (timeout == 0)
  {
    timeout = MAC_PwrNextTimeout();
  }
  else
  {
    /* get next MAC timer expiration */
    macTimeout = MAC_PwrNextTimeout();

    /* get lesser of two timeouts */
    if ((macTimeout != 0) && (macTimeout < timeout))
    {
      timeout = macTimeout;
    }
  }

  /* HAL_SLEEP_PM2 is entered only if the timeout is zero and
   * the device is a stimulated device.
   */
  halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP : HAL_SLEEP_TIMER;

  /* DEEP sleep can only be entered when zgPollRate == 0.
   * This is to eliminate any possibility of entering PM3 between
   * two network timers.
   */
#if ZG_BUILD_ENDDEVICE_TYPE && defined (NWK_AUTO_POLL)
  if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
      (timeout == 0 && zgPollRate == 0))
#else
  if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
      (timeout == 0))
#endif
  {
    halIntState_t ien0, ien1, ien2;

    HAL_ASSERT(HAL_INTERRUPTS_ARE_ENABLED());
    HAL_DISABLE_INTERRUPTS();

    /* always use "deep sleep" to turn off radio VREG on CC2530 */
    if (halSleepPconValue != 0 && MAC_PwrOffReq(MAC_PWR_SLEEP_DEEP) == MAC_SUCCESS)
    {
      /* The PCON value is not zero. There is no interrupt overriding the 
       * sleep decision. Also, the radio granted the sleep request.
       */

#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
      /* get peripherals ready for sleep */
      HalKeyEnterSleep();
#endif

#ifdef HAL_SLEEP_DEBUG_LED
      HAL_TURN_OFF_LED3();
#else
      /* use this to turn LEDs off during sleep */
      HalLedEnterSleep();
#endif

      /* enable sleep timer interrupt */
      if (timeout != 0)
      {
        if (timeout > HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ))
        {
          timeout -= HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME );
          halSleepSetTimer(HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ));
        }
        else
        {
          /* set sleep timer */
          halSleepSetTimer(timeout);
        }

        /* set up sleep timer interrupt */
        HAL_SLEEP_TIMER_CLEAR_INT();
        HAL_SLEEP_TIMER_ENABLE_INT();
      }

#ifdef HAL_SLEEP_DEBUG_LED
      if (halPwrMgtMode == CC2530_PM1)
      {
        HAL_TURN_ON_LED1();
      }
      else
      {
        HAL_TURN_OFF_LED1();
      }
#endif

      if (ZNP_CFG1_UART == znpCfg1)
      {
        HalUARTSuspend();
      }

      /* Prep CC2530 power mode */
      HAL_SLEEP_PREP_POWER_MODE(halPwrMgtMode);

      /* save interrupt enable registers and disable all interrupts */
      HAL_SLEEP_IE_BACKUP_AND_DISABLE(ien0, ien1, ien2);
      HAL_ENABLE_INTERRUPTS();

      /* set CC2530 power mode, interrupt is disabled after this function
       * Note that an ISR (that could wake up from power mode) which runs
       * between the previous instruction enabling interrupts and before
       * power mode is set would switch the halSleepPconValue so that
       * power mode shall not be entered in such a case. 
       */
      HAL_SLEEP_SET_POWER_MODE();

      /* Disable interrupt immediately */
      HAL_DISABLE_INTERRUPTS();

      /* restore interrupt enable registers */
      HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);

      /* disable sleep timer interrupt */
      HAL_SLEEP_TIMER_DISABLE_INT();

      if (ZNP_CFG1_UART == znpCfg1)
      {
        HalUARTResume();
      }

#ifdef HAL_SLEEP_DEBUG_LED
      HAL_TURN_ON_LED3();
#else
      /* use this to turn LEDs back on after sleep */
      HalLedExitSleep();
#endif

#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
      /* handle peripherals */
      (void)HalKeyExitSleep();
#endif

      /* power on the MAC; blocks until completion */
      MAC_PwrOnReq();

      HAL_ENABLE_INTERRUPTS();

      /* For CC2530, T2 interrupt won’t be generated when the current count is greater than
       * the comparator. The interrupt is only generated when the current count is equal to
       * the comparator. When the CC2530 is waking up from sleep, there is a small window
       * that the count may be grater than the comparator, therefore, missing the interrupt.
       * This workaround will call the T2 ISR when the current T2 count is greater than the
       * comparator. The problem only occurs when POWER_SAVING is turned on, i.e. the 32KHz
       * drives the chip in sleep and SYNC start is used.
       */
      macMcuTimer2OverflowWorkaround();
    }
    else
    {
      /* Sleep request is not granted. Check PCON value to see why the sleep is not granted. */
      if (halSleepPconValue == 0)
      {
        /* An interrupt may have changed the sleep decision. Do not sleep at all. Turn on 
         * the interrupt, exit normally, and the next sleep will be allowed.
         */
        HAL_ENABLE_INTERRUPTS();
      }
      else
      {
        /* PCON value is okay but Radio cannot enter power mode hence just put CPU to idle mode.
         * Interrupt will be enabled in halSleepEnterIdleMode().
         */
        halSleepEnterIdleMode(timeout);
      }
    }
  }
  else if (timeout > PM_MIN_IDLE_TIME)
  {
    /* Timeout is too close to enter power mode. Try idle mode. */
    HAL_DISABLE_INTERRUPTS();

    /* Interrupt will be enabled in halSleepEnterIdleMode(). */
    halSleepEnterIdleMode(timeout);
  }
}
Exemple #6
0
/**************************************************************************************************
 * @fn          halSleep
 *
 * @brief       This function is called from the OSAL task loop using and existing OSAL
 *              interface.  It sets the low power mode of the MAC and the CC2530.
 *
 * input parameters
 *
 * @param       osal_timeout - Next OSAL timer timeout.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void halSleep( uint16 osal_timeout )
{
  uint32        timeout;
  uint32        macTimeout = 0;

  halAccumulatedSleepTime = 0;

  /* get next OSAL timer expiration converted to 320 usec units */
  timeout = HAL_SLEEP_MS_TO_320US(osal_timeout);
  if (timeout == 0)
  {
    timeout = MAC_PwrNextTimeout();
  }
  else
  {
    /* get next MAC timer expiration */
    macTimeout = MAC_PwrNextTimeout();

    /* get lesser of two timeouts */
    if ((macTimeout != 0) && (macTimeout < timeout))
    {
      timeout = macTimeout;
    }
  }

  /* HAL_SLEEP_PM2 is entered only if the timeout is zero and
   * the device is a stimulated device.
   */
  halPwrMgtMode = (timeout == 0) ? HAL_SLEEP_DEEP : HAL_SLEEP_TIMER;

  /* DEEP sleep can only be entered when zgPollRate == 0.
   * This is to eliminate any possibility of entering PM3 between
   * two network timers.
   */
#if ZG_BUILD_ENDDEVICE_TYPE && defined (NWK_AUTO_POLL)
  if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
      (timeout == 0 && zgPollRate == 0))
#else
  if ((timeout > HAL_SLEEP_MS_TO_320US(PM_MIN_SLEEP_TIME)) ||
      (timeout == 0))
#endif
  {
    halIntState_t ien0, ien1, ien2;

    HAL_ASSERT(HAL_INTERRUPTS_ARE_ENABLED());
    HAL_DISABLE_INTERRUPTS();

    /* always use "deep sleep" to turn off radio VREG on CC2530 */
    if (MAC_PwrOffReq(MAC_PWR_SLEEP_DEEP) == MAC_SUCCESS)
    {
#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
      /* get peripherals ready for sleep */
      HalKeyEnterSleep();
#endif

#ifdef HAL_SLEEP_DEBUG_LED
      HAL_TURN_OFF_LED3();
#else
      /* use this to turn LEDs off during sleep */
      HalLedEnterSleep();
#endif

      /* enable sleep timer interrupt */
      if (timeout != 0)
      {
        if (timeout > HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ))
        {
          timeout -= HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME );
          halSleepSetTimer(HAL_SLEEP_MS_TO_320US( MAX_SLEEP_TIME ));
        }
        else
        {
          /* set sleep timer */
          halSleepSetTimer(timeout);
        }

        /* set up sleep timer interrupt */
        HAL_SLEEP_TIMER_CLEAR_INT();
        HAL_SLEEP_TIMER_ENABLE_INT();
      }

#ifdef HAL_SLEEP_DEBUG_LED
      if (halPwrMgtMode == CC2530_PM1)
      {
        HAL_TURN_ON_LED1();
      }
      else
      {
        HAL_TURN_OFF_LED1();
      }
#endif

      /* save interrupt enable registers and disable all interrupts */
      HAL_SLEEP_IE_BACKUP_AND_DISABLE(ien0, ien1, ien2);
      HAL_ENABLE_INTERRUPTS();

      /* set CC2530 power mode, interrupt is disabled after this function */
      HAL_SLEEP_SET_POWER_MODE(halPwrMgtMode);

      /* the interrupt is disabled - see halSetSleepMode() */

      /* restore interrupt enable registers */
      HAL_SLEEP_IE_RESTORE(ien0, ien1, ien2);

      /* disable sleep timer interrupt */
      HAL_SLEEP_TIMER_DISABLE_INT();

      /* Calculate timer elasped */
      halAccumulatedSleepTime += (HalTimerElapsed() / TICK_COUNT);


#ifdef HAL_SLEEP_DEBUG_LED
      HAL_TURN_ON_LED3();
#else
      /* use this to turn LEDs back on after sleep */
      HalLedExitSleep();
#endif

#if ((defined HAL_KEY) && (HAL_KEY == TRUE))
      /* handle peripherals */
      (void)HalKeyExitSleep();
#endif

      /* power on the MAC; blocks until completion */
      MAC_PwrOnReq();

      HAL_ENABLE_INTERRUPTS();

      /* For CC2530, T2 interrupt won’t be generated when the current count is greater than
       * the comparator. The interrupt is only generated when the current count is equal to
       * the comparator. When the CC2530 is waking up from sleep, there is a small window
       * that the count may be grater than the comparator, therefore, missing the interrupt.
       * This workaround will call the T2 ISR when the current T2 count is greater than the
       * comparator. The problem only occurs when POWER_SAVING is turned on, i.e. the 32KHz
       * drives the chip in sleep and SYNC start is used.
       */
      macMcuTimer2OverflowWorkaround();
    }
    else
    {
      HAL_ENABLE_INTERRUPTS();
    }
  }
}