示例#1
0
/**************************************************************************************************
 * @fn          sblPoll
 *
 * @brief       Boot Loader main executive processing.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE if sbCmnd() returns TRUE, indicating that an SB_ENABLE_CMD succeeded;
 *              FALSE otherwise.
 **************************************************************************************************
 */
uint8 sblPoll(void)
{
    /* Parse the incoming packet’s header, and verify its FCS. Valid packets are transferred to
     * sbCmnd() for further processing. For detailed packet format, please see the document "Serial
     * Boot Loader for CC2538".
     */
    static uint8  sbFrameId, sbCmd, sbFcs, sbSte = SB_SOF_STATE;
    static uint32 sbLen;
    static uint32 sbIdx;
    uint8         ch, rtrn = FALSE;

    while(sbRx(&ch, 1))
    {
        switch (sbSte)
        {
        case SB_SOF_STATE:
            if (SB_SOF == ch)
            {
                sbSte = SB_LEN_STATE;
                sbIdx = 0;
            }
            break;

        /* this field is kept for backward compatibility of the protocol. */
        case SB_LEN_STATE:
            /* In case the length is larger than 254, this fields is set to 0xFF,
             * and there is an additional 32bit length, located in another location
             * in this header.
             */
            sbLen = ch;
            sbFcs = 0;
            sbSte = SB_FRAME_ID_STATE;
            break;

        case SB_FRAME_ID_STATE:
            sbFrameId = ch;
            sbSte = SB_CMD_STATE;
            break;

        case SB_CMD_STATE:
            sbCmd = ch;

            switch (sbLen)
            {
            case 0:
                sbSte = SB_FCS_STATE;
                break;
            case 0xFF:
                sbSte = SB_LEN1_STATE;
                break;
            default:
                sbSte = SB_DATA_STATE;
                break;
            }
            break;

        case SB_LEN1_STATE:
            sbLen = ch;
            sbSte = SB_LEN2_STATE;
            break;

        case SB_LEN2_STATE:
            sbLen += ch << 8;
            sbSte = SB_LEN3_STATE;
            break;

        case SB_LEN3_STATE:
            sbLen += ch << 16;
            sbSte = SB_LEN4_STATE;
            break;

        case SB_LEN4_STATE:
            sbLen += ch << 24;
            sbSte = (sbLen) ? SB_DATA_STATE : SB_FCS_STATE;
            break;

        case SB_DATA_STATE:
            if (sbIdx >= sizeof(_sbBuf))
            {
                /* discard this packet. the payload is too long. */
                sbSte = SB_SOF_STATE;
            }
            else
            {
                sbBuf[sbIdx] = ch;
                sbIdx++;
                if (sbIdx == sbLen)
                {
                    sbSte = SB_FCS_STATE;
                }
            }
            break;

        case SB_FCS_STATE:
            if ((sbFcs == ch) &&  (sbFrameId == SB_RPC_SYS_BOOT))
            {
                rtrn = sbCmnd(sbCmd, sbLen);
            }
            sbSte = SB_SOF_STATE;
            break;

        default:
            break;
        }
        sbFcs ^= ch;
    }

    return rtrn;
}
示例#2
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;
}