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;
  uint8 sbExec_rc;

  sbReportState(SB_STATE_BOOTLOADER_ACTIVE);

  while (1)
  {
    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.
      for (dlyCnt = 0; dlyCnt < 0x40000; dlyCnt++)
      {
        sbUartPoll();
      }
      
      break;
    }
  }
}
Example #2
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 #3
0
/**************************************************************************************************
 * @fn          main
 *
 * @brief       ISR for the reset vector.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
void main(void)
{
  uint8 time_spent_validating;
  uint8 bootloaderForcedByMainApp = FALSE;
  uint32 mainAppCommandLocal = mainAppCommand;

  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. Without 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();

  if ((!bootloaderForcedByMainApp) && sbImgValid(&time_spent_validating))
  {
    if (sblWait(SBL_WAIT_TIME > time_spent_validating ? SBL_WAIT_TIME - time_spent_validating : 0))
    {
      if (znpCfg1 == ZNP_CFG1_SPI)
      {
        HalUARTUnInitSPI();
      }
      else
      {
        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

        HalUARTUnInitISR();
      }
      magicByte = SB_STACK_VALUE;

      // Simulate a reset for the Application code by an absolute jump to location 0x2000.
      asm("LJMP 0x2000\n");
      HAL_SYSTEM_RESET();
    }
  }

  sblExec();
  HAL_SYSTEM_RESET();
}
Example #4
0
/**************************************************************************************************
 * @fn          sblWait
 *
 * @brief       A timed-out wait loop that exits early upon receiving a force code/sbl byte.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE to run the code image, FALSE to run the SBL.
 **************************************************************************************************
 */
static uint8 sblWait(uint16 sbl_wait_time)
{
  uint32 dlyCnt;
  uint8 rtrn = FALSE;
  uint8 sbExec_rc;
  
  dlyCnt = (uint32)0x7332 * sbl_wait_time; //0x7332 gives about 1 second
  
  sbReportState(SB_STATE_WAITING);
  
  while (1)
  {
    sbUartPoll();
    
    sbExec_rc = sbExec();

    if (sbExec_rc == SB_CMND_ENABLE_STATE_REPORTING)
    {
      sbReportState(SB_STATE_WAITING);
    }
    else if ((sbExec_rc == SB_CMND_FORCE_RUN) || (SB2_PRESS))
    {
      dlyCnt = 0;
    }
    else if (((sbExec_rc != SB_CMND_IDLE) && (sbExec_rc != SB_CMND_UNSUPPORTED)) || (SB1_PRESS))
    {
      break;
    }
    
    if (dlyCnt-- == 0)
    {
      rtrn = TRUE;
      break;
    }
  }
  
  return rtrn;
}
Example #5
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");
}
Example #6
0
/**************************************************************************************************
 * @fn          sblWait
 *
 * @brief       A timed-out wait loop that exits early upon receiving a force code/sbl byte.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE to run the code image, FALSE to run the SBL.
 **************************************************************************************************
 */
static uint8 sblWait(uint16 sbl_wait_time)
{
  uint32 dlyCnt;
  uint8 rtrn = FALSE;
  uint8 sbExec_rc;
  uint8 ch;

  if (znpCfg1 == ZNP_CFG1_SPI)
  {
    // Slave signals ready for read by setting its ready flag first.
    SRDY_SET();
    // Flag to sbRx() to poll for 1 Rx byte instead of blocking read until MRDY_CLR.
    spiPoll = TRUE;
    dlyCnt = 0x38;  // About 50 msecs.
  }
  else
  {
    URX0IE = 1;
    HAL_ENABLE_INTERRUPTS();
    dlyCnt = (uint32)0x7332 * sbl_wait_time; //0x7332 gives about 1 second

    sbReportState(SB_STATE_WAITING);
  }

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

      sbExec_rc = sbExec();
      if (sbExec_rc == SB_CMND_ENABLE_STATE_REPORTING)
      {
        sbReportState(SB_STATE_WAITING);
      }
      else if (sbExec_rc == SB_CMND_FORCE_RUN)
      {
        dlyCnt = 0;
      }
      else if ((sbExec_rc != SB_CMND_IDLE) && (sbExec_rc != SB_CMND_UNSUPPORTED))
      {
        break;
      }
    }
    else // Note: the SPI implementation was left unchanged, since the new implementation
         // (as implemented for the UART) was not tested with SPI at this time.
    {
      if (sbRx(&ch, 1))
      {
        if (ch == SB_FORCE_BOOT)
        {
          break;
        }
        else if (ch == SB_FORCE_RUN)
        {
          dlyCnt = 0;
        }
      }
    }

    if (dlyCnt-- == 0)
    {
      rtrn = TRUE;
      break;
    }
  }

  if (znpCfg1 == ZNP_CFG1_SPI)
  {
    // Master blocks waiting for slave to clear its ready flag before continuing.
    SRDY_CLR();
    // Flag to sbRx() to now block while reading Rx bytes until MRDY_CLR.
    spiPoll = FALSE;
  }
  else
  {
    HAL_DISABLE_INTERRUPTS();
    URX0IE = 0;
  }

  return rtrn;
}