Beispiel #1
0
int SBL_Execute()
{
	int retVal = NPI_LNX_SUCCESS;

	LOG_INFO("[SBL] Executing Serial Bootloader\n");

	if (!sblImageBuf || (sblImageLen <= 0))
	{
		LOG_ERROR("[SBL] No binary file found\n");
		retVal = NPI_LNX_FAILURE;
	}
	else
	{
		int sbResult = 0;
		sblState = SBL_STATE_SERIAL_BOOT;
		sbResult = sbExec(sblImageBuf, sblImageLen);

		if (sbResult != 0)
		{
			npiMsgData_t pMsg;

			LOG_WARN("[SBL] Serial boot loader failed. Attempting hard reset\n");
			// Trying again after a hard reset

			pMsg.len = 0;
			pMsg.subSys = RPC_SYS_SRV_CTRL | RPC_CMD_AREQ;
			pMsg.cmdId = NPI_LNX_CMD_ID_RESET_DEVICE;
			// Send command
			NPI_SendAsynchData( &pMsg );

			// After a very short delay attempt again
			LOG_INFO("[SBL] Send Handshake command\n");

			retVal = BOOT_HandshakeReq();

			if (retVal != NPI_LNX_SUCCESS)
			{
				LOG_FATAL("[SBL] Serial boot loader failed. Please restart application.\n");
			}
			else
			{
				// Try again
				retVal = sbExec(sblImageBuf, sblImageLen);
			}
		}
	}
	return retVal;
}
Beispiel #2
0
/**************************************************************************************************
 * @fn          sblExec
 *
 * @brief       Infinite SBL execute loop that jumps upon receiving a code enable.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblExec(void)
{
  uint32 dlyCnt = 0;

  while (1)
  {
    HalUARTPollUSB();

    if (sbExec() && sbImgValid())
    {
      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();
      }

      sblJump();
    }
    else if (dlyCnt++ & 0x4000)
    {
      SB_TOGGLE_LED1();
    }
  }
}
Beispiel #3
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;
    }
  }
}
Beispiel #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;
  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();
  }
}
Beispiel #5
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;
    }
  }
}
Beispiel #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;
  
  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;
}
Beispiel #7
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;
}