예제 #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
파일: sb_exec.c 프로젝트: Daan1992/WSN-Lab
/**************************************************************************************************
 * @fn          sbExec
 *
 * @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 sbExec(void)
{
  uint8 ch, rtrn = FALSE;

  while (SB_RX(&ch))
  {
    sbBuf[sbSte + sbIdx] = ch;
    switch (sbSte)
    {
    case SB_SOF_STATE:
      if (SB_SOF == ch)
      {
        sbSte = SB_LEN_STATE;
      }
      break;
    
    case SB_LEN_STATE:
      sbFcs = 0;
      sbSte = ((sbLen = ch) >= SB_BUF_SIZE) ? SB_SOF_STATE : SB_CMD1_STATE;
      break;

    case SB_CMD1_STATE:
      sbCmd1 = ch;
      sbSte = SB_CMD2_STATE;
      break;
    
    case SB_CMD2_STATE:
      sbCmd2 = ch;
      sbSte = (sbLen) ? SB_DATA_STATE : SB_FCS_STATE;
      break;

    case SB_DATA_STATE:
      if (++sbIdx == sbLen)
      {
        sbSte = SB_FCS_STATE;
      }
      break;
    
    case SB_FCS_STATE:
      if ((sbFcs == ch) && (sbCmd1 == SB_RPC_SYS_BOOT))
      {
        rtrn = sbCmnd();
      }
      else
      {
        // TODO - RemoTI did not have here or on bad length - adding could cause > 1 SB_INVALID_FCS
        //        for a single data packet which could put out of sync with PC for awhile or
        //        infinte, depending on PC-side?
        // sbResp(SB_INVALID_FCS, 1);
      }
    
      sbSte = sbIdx = 0;
      break;
    
    default:
      break;
    }
    sbFcs ^= ch;
  }

  return rtrn;
}