Example #1
0
/**************************************************************************************************
 * @fn          sblExec
 *
 * @brief       Infinite SBL execute loop that returns upon receiving a code enable.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblExec(void)
{
  uint32 dlyCnt = 0;
  vddWait(VDD_MIN_NV);
  HAL_ENABLE_INTERRUPTS();

  while (1)
  {
    if (dlyCnt++ & 0x4000)
    {
      SB_TOGGLE_LED1();
    }

    HalUARTPollUSB();
    if (sbExec())
    {
      break;
    }
  }

  SB_TURN_ON_LED1();
  SB_TURN_ON_LED2();
  // Delay to allow the SB_ENABLE_CMD response to be flushed.
  for (dlyCnt = 0; dlyCnt < 0x40000; dlyCnt++)
  {
    HalUARTPollUSB();
  }
}
Example #2
0
/******************************************************************************
 * @fn      bootMain
 *
 * @brief   ISR for the reset vector.
 *
 * @param   None.
 *
 * @return  None.
 */
void bootMain(void)
{
  extern void _ivecRst2(void);   // hal_ivec.s43 defines this reset re-direct operation.

  HAL_BOOT_INIT();
  vddWait(VDD_MIN_RUN);

  while (1)
  {
    uint16 crc[2];

    crc[0] = *((uint16*)LO_ROM_BEG);
    crc[1] = *((uint16*)LO_ROM_BEG+1);

    if (crc[0] == crc[1])
    {
      break;
    }
    else if ((crc[0] != 0) && (crc[0] == crcCalc()))
    {
      FCTL3 = FWKEY;                      // Clear Lock bit.
      FCTL1 = FWKEY + WRT;                // Set WRT bit for write operation
      *((uint16*)LO_ROM_BEG+1) = crc[0];  // Write CRC shadow
      FCTL1 = FWKEY;                      // Clear WRT bit
      FCTL3 = FWKEY + LOCK;               // Set LOCK bit
    }
    else
    {
      dl2rc();
    }
  }

  _ivecRst2();
}
Example #3
0
/**************************************************************************************************
 * @fn          sblInit
 *
 * @brief       Initialization for SBL.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblInit(void)
{
  HAL_BOARD_INIT();
  vddWait(VDD_MIN_RUN);
  magicByte = SB_MAGIC_VALUE;

  /* This is in place of calling HalDmaInit() which would require init of the other 4 DMA
   * descriptors in addition to just Channel 0.
   */
  HAL_DMA_SET_ADDR_DESC0(&dmaCh0);
  HalUARTInitUSB();
}
Example #4
0
/**************************************************************************************************
 * @fn          sblExec
 *
 * @brief       Infinite SBL execute loop that returns upon receiving a code enable.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblExec(void)
{

  uint32 dlyCnt = 0;
  uint8 sbExec_rc;

  if (znpCfg1 == ZNP_CFG1_UART)
  {
    URX0IE = 1;
    HAL_ENABLE_INTERRUPTS();
	
    sbReportState(SB_STATE_BOOTLOADER_ACTIVE);
  }
  else
  {
    /* For preventing an unknown delay after sending SB_FORCE_BOOT and before being able to send
       SB_HANDSHAKE_CMD, this call was moved to the processing of SB_HANDSHAKE_CMD, which has an
       associated response (SB_FORCE_BOOT does not have any response). This change was required
       for the bootloader to work on the Alektrona gateway reference board. It was verified only
       with UART, so at the moment the behavior for SPI is left unchanged. */
    vddWait(VDD_MIN_NV);
  }

  while (1)
  {
    if (znpCfg1 == ZNP_CFG1_UART)
    {
      sbUartPoll();
    }

    sbExec_rc = sbExec();
    if (sbExec_rc == SB_CMND_ENABLE_STATE_REPORTING)
    {
      sbReportState(SB_STATE_BOOTLOADER_ACTIVE);
    }
    else if (sbExec_rc == SB_CMND_ENABLED_CMD_OK)
    {
      // Delay to allow the SB_ENABLE_CMD response to be flushed.
      if (znpCfg1 == ZNP_CFG1_UART)
      {
        for (dlyCnt = 0; dlyCnt < 0x40000; dlyCnt++)
        {
          sbUartPoll();
        }

        URX0IE = 0;
      }
      break;
    }
  }
}
Example #5
0
/**************************************************************************************************
 * @fn          sblInit
 *
 * @brief       Initialization for SBL.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblInit(void)
{
  HAL_BOARD_INIT();
  vddWait(VDD_MIN_RUN);
  magicByte = SB_MAGIC_VALUE;

  /* This is in place of calling HalDmaInit() which would require init of the other 4 DMA
   * descriptors in addition to just Channel 0.
   */
  HAL_DMA_SET_ADDR_DESC0(&dmaCh0);

#if defined CC2530_MK
  znpCfg1 = ZNP_CFG1_SPI;
#else
  znpCfg1 = P2_0;
#endif
  if (znpCfg1 == ZNP_CFG1_SPI)
  {
    SRDY_CLR();

    // Select general purpose on I/O pins.
    P0SEL &= ~(NP_RDYIn_BIT);      // P0.3 MRDY - GPIO
    P0SEL &= ~(NP_RDYOut_BIT);     // P0.4 SRDY - GPIO

    // Select GPIO direction.
    P0DIR &= ~NP_RDYIn_BIT;        // P0.3 MRDY - IN
    P0DIR |= NP_RDYOut_BIT;        // P0.4 SRDY - OUT

    P0INP &= ~NP_RDYIn_BIT;        // Pullup/down enable of MRDY input.
    P2INP &= ~BV(5);               // Pullup all P0 inputs.

    HalUARTInitSPI();
  }
  else
  {
    halUARTCfg_t uartConfig;

    HalUARTInitISR();
    uartConfig.configured           = TRUE;
    uartConfig.baudRate             = HAL_UART_BR_115200;
    uartConfig.flowControl          = FALSE;
    uartConfig.flowControlThreshold = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.rx.maxBufSize        = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.tx.maxBufSize        = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.idleTimeout          = 0;  // CC2530 by #define - see hal_board_cfg.h
    uartConfig.intEnable            = TRUE;
    uartConfig.callBackFunc         = NULL;
    HalUARTOpenISR(&uartConfig);
  }
}
Example #6
0
/**************************************************************************************************
 * @fn          main
 *
 * @brief       C-code main functionality.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void main(void)
{
  vddWait(VDD_MIN_RUN);
  HAL_BOARD_INIT();

  // make sure the DMA channel is selected before we attempt to
  // to write anything to flash.
  sblInit();
  
  if (sbImgValid())
  {
    if ((SB_UART_DELAY == 0) || ResetWasWatchDog)
    {
      sblJump();
    }

    sblWait();
  }

  vddWait(VDD_MIN_NV);
  sblExec();
  HAL_SYSTEM_RESET();
}
Example #7
0
/**************************************************************************************************
 * @fn          main
 *
 * @brief       C-code main functionality.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void main(void)
{
  vddWait(VDD_MIN_RUN);
  HAL_BOARD_INIT();

  if (sbImgValid())
  {
    if ((SB_UART_DELAY == 0) || ResetWasWatchDog)
    {
      sblJump();
    }

    sblInit();
    sblWait();
  }
  else
  {
    sblInit();
  }

  vddWait(VDD_MIN_NV);
  sblExec();
  HAL_SYSTEM_RESET();
}
Example #8
0
/******************************************************************************
 * @fn      dl2rc
 *
 * @brief   Copy the DL image to the RC image location.
 *
 *  NOTE:   Assumes that DL image at least fills lower flash.
 *          Assumes that DL image ends on a flash page boundary.
 *
 * @param   None.
 *
 * @return  None.
 */
static void dl2rc(void)
{
  uint32 addr = DATA_OFFSET;
  uint32 addr2 = HI_ROM_BEG;
  uint16 *ptr;
  preamble_t preamble;
  uint16 buf;
  uint8 cnt = 0;

  vddWait(VDD_MIN_OTA);
  HalOTARead(DATA_OFFSET+PREAMBLE_OFFSET, (uint8 *)&preamble, sizeof(preamble_t), HAL_OTA_DL);
  FCTL3 = FWKEY;                   // Clear Lock bit.

  for (ptr = (uint16 *)LO_ROM_BEG; ptr <= (uint16 *)LO_ROM_END ; )
  {
    FCTL1 = FWKEY + ERASE;         // Set Erase bit.
    *ptr = 0;                      // Dummy write to erase Flash segment.
    FCTL1 = FWKEY + WRT;           // Set WRT bit for write operation

    do
    {
      HalXNVRead(addr, (uint8 *)&buf, 2);
      *ptr++ = buf;
      addr += 2;
    } while (--cnt);               // Wrap a uint8 once to count 256 * 2 = 512.
  }

  for (; addr < preamble.programLength+DATA_OFFSET; )
  {
    FCTL1 = FWKEY + ERASE;         // Set Erase bit.
    __data20_write_char(addr2,0);  // Dummy write to erase Flash segment.
    FCTL1 = FWKEY + WRT;           // Set WRT bit for write operation

    do
    {
      HalXNVRead(addr, (uint8 *)&buf, 2);
      __data20_write_short(addr2, buf);
      addr2 += 2;
      addr += 2;
    } while (--cnt);               // Wrap a uint8 once to count 256 * 2 = 512.
  }

  FCTL1 = FWKEY;                   // Clear WRT bit
  FCTL3 = FWKEY + LOCK;            // Set LOCK bit
}
Example #9
0
/**************************************************************************************************
 * @fn          main
 *
 * @brief       C-code main function.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void main(void)
{
  vddWait();

  HAL_BOARD_INIT();

  /* This is in place of calling HalDmaInit() which would require init of the other 4 DMA
   * descriptors in addition to just Channel 0.
   */
  HAL_DMA_SET_ADDR_DESC0(&dmaCh0);

  // Map flash bank #7 into XDATA for access to "ROM mapped as data".
  MEMCTR = (MEMCTR & 0xF8) | 0x07;

  imgSelect();         // Attempt to select and run an image.

  SLEEPCMD |= 0x03;    // PM3, All clock oscillators off, voltage regulator off.
  halSleepExec();
  HAL_SYSTEM_RESET();  // Should not get here.
}
Example #10
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");
}