/************************************************************************************************** * @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; }
/************************************************************************************************** * @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; }