789 lines
21 KiB
C
789 lines
21 KiB
C
/********************************************************************************
|
||
Copyright (C), Sinowealth Electronic. Ltd.
|
||
Author: Sino
|
||
Version: V0.0
|
||
Date: 2020/04/26
|
||
History:
|
||
V2.0 2020/04/26 Preliminary
|
||
********************************************************************************/
|
||
#include "MCURegister.h"
|
||
#include "C51_TYPE.H"
|
||
#include "Flash.h"
|
||
#include "IapIsp.h"
|
||
|
||
BOOL bIapIspFlg; //0:表示当前执行IAP操作;1:表示当前执行ISP操作
|
||
BOOL bHandsheakOkFlg;
|
||
BOOL bUartSndOverFlg;
|
||
U16 uiUartRcvChkSum;
|
||
U8 ucUartErrCode;
|
||
U8 ucUartBufPT;
|
||
U32 ulIapDataPtr;
|
||
U32 ulIapChksum;
|
||
U32 ulIapRecDataLen;
|
||
U8 ucIapIndexBk;
|
||
U8 ucIapRestCommand;
|
||
U8 xdata ucUartBuf[150];
|
||
U8 xdata ucIapBuf[MCU_CODE_SECTOR_SIZE];
|
||
|
||
extern void UARTInit(void);
|
||
/*************************************************************************************************
|
||
* 函数名: UartSendAck
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 当Slave接收完数据并处理完成后,开始返回数据
|
||
*************************************************************************************************/
|
||
void UartSendAck(void)
|
||
{
|
||
U8 i, DataBak;
|
||
U16 CheckSum = 0;
|
||
|
||
ucUartBuf[LENGTH] = 0x00;
|
||
ucUartBuf[COMMAND] = 0x0B;
|
||
|
||
DataBak = ucUartBuf[SOURCE]; //交换源ID和目标ID
|
||
ucUartBuf[SOURCE] = ucUartBuf[TARGET];
|
||
ucUartBuf[TARGET] = DataBak;
|
||
|
||
for(i=2; i<(ucUartBuf[LENGTH]+7); i++)
|
||
{
|
||
CheckSum += ucUartBuf[i];
|
||
}
|
||
|
||
ucUartBuf[7+ucUartBuf[LENGTH]] = (U8)CheckSum;
|
||
ucUartBuf[8+ucUartBuf[LENGTH]] = (U8)(CheckSum>>8);
|
||
|
||
bUartSndOverFlg = 0;
|
||
UartTxEn(ucUartBuf[ucUartBufPT]);
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: IapHandShake
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 握手协议,进入IAP或者ISP烧写流程
|
||
bIapIspFlg: 0--IAP操作;1--ISP操作
|
||
*************************************************************************************************/
|
||
void IapHandShake(void)
|
||
{
|
||
ucUartBuf[INDEXES] = 0;
|
||
if(ucUartBuf[DATA]=='I' && ucUartBuf[DATA+1]=='A' && ucUartBuf[DATA+2]=='P')
|
||
{
|
||
bIapIspFlg = IAP_MODE;
|
||
bHandsheakOkFlg = 1;
|
||
}
|
||
else if(ucUartBuf[DATA]=='I' && ucUartBuf[DATA+1]=='S' && ucUartBuf[DATA+2]=='P')
|
||
{
|
||
bIapIspFlg = ISP_MODE;
|
||
bHandsheakOkFlg = 1;
|
||
}
|
||
else
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_HANDSHAKE; //握手失败
|
||
bHandsheakOkFlg = 0;
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: IapBeginAck
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: IAP或ISP开始操作,擦除CODE的备份区30K
|
||
*************************************************************************************************/
|
||
void IapBeginAck(void)
|
||
{
|
||
U8 i, SectorNum, McuFlashType;
|
||
U32 McuFlashAddr;
|
||
|
||
ulIapDataPtr = 0;
|
||
ulIapChksum = 0;
|
||
ulIapRecDataLen = 0;
|
||
ulIapRecDataLen = ((U32)ucUartBuf[DATA+3]<<24) //数据长度
|
||
| ((U32)ucUartBuf[DATA+2]<<16)
|
||
| ((U32)ucUartBuf[DATA+1]<<8)
|
||
| (U32)ucUartBuf[DATA];
|
||
|
||
if(!bHandsheakOkFlg)
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_HANDSHAKE; //握手失败
|
||
}
|
||
|
||
if((ulIapRecDataLen > IAP_BK_CODE_SIZE) && (bIapIspFlg == IAP_MODE))
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_SIZE; //如果数据长度不等于IAP和ISP长度,则默认为长度异常
|
||
}
|
||
else if((ulIapRecDataLen > ISP_CODE_SIZE) && (bIapIspFlg == ISP_MODE))
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_SIZE; //如果数据长度不等于IAP和ISP长度,则默认为长度异常
|
||
}
|
||
else
|
||
{
|
||
ucUartBuf[INDEXES] = 0; //先预设回复成功
|
||
ucIapIndexBk = 0;
|
||
|
||
//1. 如果当前操作是ISP,则先擦除BOOT区的标志,然后在BOOT_FLG_ISP_ADD中写ISP_FLG标志0xA5
|
||
ucMcuFlashWrValid = 0x55; //设置MCU Code区可操作标志,防止误写
|
||
McuFlashEraseSector(BOOT_FLG_START_ADDR, MCU_TYPE_CODE);
|
||
if(McuFlashBlankCheck(BOOT_FLG_START_ADDR, MCU_TYPE_CODE)) //擦除结束后,需要查空
|
||
{
|
||
if(bIapIspFlg == ISP_MODE)
|
||
{
|
||
McuFlashWrOneByte(BOOT_FLG_ISP_ADDR, ISP_FLG, MCU_TYPE_CODE);
|
||
if(McuFlashRdOneByte(BOOT_FLG_ISP_ADDR, MCU_TYPE_CODE) != ISP_FLG)
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_WR; //Write失败
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_ERASE; //Erase失败
|
||
}
|
||
ucMcuFlashWrValid = 0;
|
||
|
||
//2. 不管是IAP还是ISP,都先擦除程序的所有Sector,如果是ISP,则还需要擦除EEPROM区
|
||
if(ucUartBuf[INDEXES] == 0) //检查ucUartBuf[INDEXES]
|
||
{
|
||
SectorNum = ulIapRecDataLen/MCU_CODE_SECTOR_SIZE;
|
||
for(i=0; i<SectorNum; i++) //先擦除CODE备份区的Sector
|
||
{
|
||
McuFlashType = MCU_TYPE_CODE; //先默认擦除flash
|
||
if(bIapIspFlg == ISP_MODE)
|
||
{
|
||
McuFlashAddr = ISP_CODE_START_ADDR; //ISP起始地址
|
||
}
|
||
else
|
||
{
|
||
McuFlashAddr = IAP_BK_CODE_START_ADDR; //IAP起始地址
|
||
}
|
||
McuFlashAddr += (U16)i*512; //确定被擦除页起始地址
|
||
|
||
if(bIapIspFlg == ISP_MODE) //ISP模式下直接擦除EEPROM
|
||
{
|
||
if(i>=(SectorNum-APP_PARA_SIZE/MCU_CODE_SECTOR_SIZE)) //EEPROM按sector擦除
|
||
{
|
||
McuFlashType = MCU_TYPE_E2P;
|
||
McuFlashAddr = (U16)(i+APP_PARA_SIZE/MCU_CODE_SECTOR_SIZE-SectorNum)*512;
|
||
}
|
||
}
|
||
|
||
ucMcuFlashWrValid = 0x55; //设置MCU Code区可操作标志,防止误写
|
||
McuFlashEraseSector(McuFlashAddr, McuFlashType);
|
||
if(!McuFlashBlankCheck(McuFlashAddr, McuFlashType)) //擦除结束后,需要查空
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_ERASE; //Erase失败
|
||
}
|
||
ucMcuFlashWrValid = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_INDEX;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: IapWrSector
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 写入1个Sector数据
|
||
*************************************************************************************************/
|
||
BOOL IapWrSector(void)
|
||
{
|
||
BOOL Result = 1;
|
||
U16 i;
|
||
U32 McuFlashAddr;
|
||
U8 McuFlashType;
|
||
|
||
for(i=0; i<MCU_CODE_SECTOR_SIZE; i++) //连续写1个sector
|
||
{
|
||
McuFlashType = MCU_TYPE_CODE;
|
||
if(bIapIspFlg == ISP_MODE) //ISP
|
||
{
|
||
McuFlashAddr = ISP_CODE_START_ADDR + ulIapDataPtr;
|
||
if(McuFlashAddr >= (ulIapRecDataLen+BOOT_CODE_SIZE-APP_PARA_SIZE))
|
||
{
|
||
McuFlashAddr = McuFlashAddr - (ulIapRecDataLen+BOOT_CODE_SIZE-APP_PARA_SIZE);
|
||
McuFlashType = MCU_TYPE_E2P; //ISP更新EEPROM区
|
||
}
|
||
}
|
||
else
|
||
{
|
||
McuFlashAddr = IAP_BK_CODE_START_ADDR + ulIapDataPtr;
|
||
}
|
||
McuFlashWrOneByte(McuFlashAddr, ucIapBuf[i], McuFlashType);
|
||
if(ucIapBuf[i] != McuFlashRdOneByte(McuFlashAddr, McuFlashType))
|
||
{
|
||
Result = 0;
|
||
break;
|
||
}
|
||
ulIapDataPtr++;
|
||
}
|
||
|
||
return Result;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: IapReceiveData
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 接收数据,同时将数据写入的MCU CODE区
|
||
*************************************************************************************************/
|
||
void IapReceiveData(void)
|
||
{
|
||
U16 i;
|
||
U8 j;
|
||
U32 McuFlashAddr;
|
||
U8 McuFlashType;
|
||
|
||
bHandsheakOkFlg = 0;
|
||
|
||
if( ((ucUartBuf[INDEXES]<ucIapIndexBk) || (ucUartBuf[INDEXES]>(ucIapIndexBk+4))) && (ucUartBuf[INDEXES] != 0) ) //yangweilei
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_INDEX; //数据索引错误,首先判断是否连续,其次判断是否超出范围
|
||
}
|
||
else
|
||
{
|
||
ucIapIndexBk = ucUartBuf[INDEXES];
|
||
ucUartBuf[INDEXES] = 0;
|
||
if(ucUartBuf[LENGTH] == 0)
|
||
{
|
||
ulIapDataPtr += 512; //如果传递的长度为0,表示当前128个字节为0,指针加,但不写(增加150mS/1K)
|
||
}
|
||
else
|
||
{
|
||
j = ucIapIndexBk % 4; //目前暂定sector长度为512bytes,每次传输128bytes,所以定义为4
|
||
for(i=0; i<ucUartBuf[LENGTH]; i++)
|
||
{
|
||
ucIapBuf[i+(U16)j*ucUartBuf[LENGTH]] = ucUartBuf[DATA+i];
|
||
}
|
||
if(j == 3) //连续接收满1个sector,才进行写入操作
|
||
{
|
||
ucMcuFlashWrValid = 0x55; //设置MCU Code区可操作标志,防止误写
|
||
if(!IapWrSector()) //第一次写sector错误,则擦除后再写一次
|
||
{
|
||
if(ulIapDataPtr >= MCU_CODE_SECTOR_SIZE)
|
||
{
|
||
ulIapDataPtr -= MCU_CODE_SECTOR_SIZE; //指针返回到该Sector起始
|
||
}
|
||
else
|
||
{
|
||
ulIapDataPtr = 0;
|
||
}
|
||
|
||
McuFlashType = MCU_TYPE_CODE; //默认是CODE区
|
||
if(bIapIspFlg == ISP_MODE) //ISP
|
||
{
|
||
McuFlashAddr = ISP_CODE_START_ADDR + ulIapDataPtr;
|
||
if(McuFlashAddr >= (ulIapRecDataLen+BOOT_CODE_SIZE-APP_PARA_SIZE))
|
||
{
|
||
McuFlashAddr = McuFlashAddr - (ulIapRecDataLen+BOOT_CODE_SIZE-APP_PARA_SIZE);
|
||
McuFlashType = MCU_TYPE_E2P; //ISP更新EEPROM区
|
||
}
|
||
}
|
||
else
|
||
{
|
||
McuFlashAddr = IAP_BK_CODE_START_ADDR + ulIapDataPtr;
|
||
}
|
||
ucMcuFlashWrValid = 0x55;
|
||
McuFlashEraseSector(McuFlashAddr, McuFlashType);
|
||
if(McuFlashBlankCheck(McuFlashAddr, McuFlashType)) //擦除结束后,需要查空
|
||
{
|
||
if(!IapWrSector()) //如果连续写两次错误,则返回给上位机异常
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_WR; //写入错误
|
||
}
|
||
else
|
||
{
|
||
goto UpdateChksum;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_ERASE; //擦除错误
|
||
}
|
||
}
|
||
else //512Bytes写入正确,才更新checksum值
|
||
{
|
||
UpdateChksum:
|
||
for(j=0; j<MCU_CODE_SECTOR_SIZE/4; j++) //计算checksum需要按照32bit,尽量兼容STM32
|
||
{
|
||
ulIapChksum += (((U32)ucIapBuf[j*4+3]<<24)
|
||
| ((U32)ucIapBuf[j*4+2]<<16)
|
||
| ((U32)ucIapBuf[j*4+1]<<8)
|
||
| ((U32)ucIapBuf[j*4+0]));
|
||
}
|
||
}
|
||
|
||
ucMcuFlashWrValid = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: IapRDataVerify
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 验证CheckSum是否正确
|
||
*************************************************************************************************/
|
||
void IapRDataVerify(void)
|
||
{
|
||
U32 CheckSum = 0;
|
||
|
||
CheckSum = ((U32)ucUartBuf[DATA+3]<<24) //获取上位机下发的校验和
|
||
| ((U32)ucUartBuf[DATA+2]<<16)
|
||
| ((U32)ucUartBuf[DATA+1]<<8)
|
||
| ((U32)ucUartBuf[DATA+0]);
|
||
|
||
if(ulIapChksum != CheckSum) //数据校验失败
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_CRC;
|
||
}
|
||
else
|
||
{
|
||
ucUartBuf[INDEXES] = 0; //数据校验成功
|
||
}
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: IapCmdReset
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 当IAP和ISP正常Program结束之后,上位机发送复位指令,程序会跳转到0x0000地址
|
||
ISP,程序会擦除BOOT区的标志区,ISP结束
|
||
IAP,程序会擦除BOOT区的标志区,同时将标志区的最后一个字节写0x5A,APP会自动升级
|
||
*************************************************************************************************/
|
||
void IapCmdReset(void)
|
||
{
|
||
ucUartBuf[INDEXES] = 0;
|
||
ucIapRestCommand = IAP_CMD_RESET;
|
||
|
||
ucMcuFlashWrValid = 0x55; //设置MCU Code区可操作标志,防止误写
|
||
McuFlashEraseSector(BOOT_FLG_START_ADDR, MCU_TYPE_CODE);
|
||
if(McuFlashBlankCheck(BOOT_FLG_START_ADDR, MCU_TYPE_CODE)) //擦除结束后,需要查空
|
||
{
|
||
if(bIapIspFlg == IAP_MODE) //IAP升级结束后,需要将BOOT区的标志区最后一个字节写0x5A
|
||
{
|
||
McuFlashWrOneByte(BOOT_FLG_IAP_ADDR, IAP_FLG, MCU_TYPE_CODE);
|
||
if(McuFlashRdOneByte(BOOT_FLG_IAP_ADDR, MCU_TYPE_CODE) != IAP_FLG)
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_WR; //Write失败
|
||
ucIapRestCommand = 0;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ucUartBuf[INDEXES] = IAPERROR_ERASE; //擦除失败
|
||
ucIapRestCommand = 0;
|
||
}
|
||
ucMcuFlashWrValid = 0;
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: UartCmdProcess
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: 处理IAP和ISP的四条命令
|
||
*************************************************************************************************/
|
||
void UartCmdProcess(void)
|
||
{
|
||
ucUartBufPT = 0;
|
||
if(uiUartRcvChkSum != ((ucUartBuf[ucUartBuf[LENGTH]+8]<<8) + ucUartBuf[ucUartBuf[LENGTH]+7]))
|
||
{
|
||
ucUartErrCode |= IAPERROR_CHECKSUM;
|
||
}
|
||
|
||
if(ucUartErrCode != 0) //如果有错误代码则不执行命令处理
|
||
{
|
||
ucUartBuf[INDEXES] = ucUartErrCode;
|
||
}
|
||
else
|
||
{
|
||
if(ucUartBuf[COMMAND] == IAP_CMD_HANDSHAKE) //IAP和ISP握手协议,上位机连续发两次
|
||
{
|
||
IapHandShake();
|
||
}
|
||
else if(ucUartBuf[COMMAND] == IAP_CMD_BEGIN) //开始IAP或ISP,并将CODE区/EEP区全部擦除
|
||
{
|
||
IapBeginAck();
|
||
}
|
||
else if(ucUartBuf[COMMAND] == IAP_CMD_TRANS) //接收数据、写入、校验
|
||
{
|
||
IapReceiveData();
|
||
}
|
||
else if(ucUartBuf[COMMAND] == IAP_CMD_VERIFY) //
|
||
{
|
||
IapRDataVerify();
|
||
}
|
||
else if(ucUartBuf[COMMAND] == IAP_CMD_RESET)
|
||
{
|
||
IapCmdReset();
|
||
}
|
||
}
|
||
|
||
UartSendAck();
|
||
}
|
||
|
||
|
||
/*************************************************************************************************
|
||
* 函数名: BootIapIsp
|
||
* 参 数: 无
|
||
* 返回值: 无
|
||
* 描 述: IAP和ISP函数处理
|
||
*************************************************************************************************/
|
||
void BootIapIsp(void)
|
||
{
|
||
ulIapDataPtr = 0;
|
||
ulIapChksum = 0;
|
||
ucIapRestCommand = 0;
|
||
UARTInit();
|
||
while(1)
|
||
{
|
||
#if ((UART_DEFINE >= 1)&&(UART_DEFINE<= 30))
|
||
{
|
||
if(RI)
|
||
{
|
||
//BootMcuWdtClear(); //在该程序循环中,未接收到UART通讯,则判定通讯异常,触发看门狗
|
||
ucUartBuf[ucUartBufPT] = SBUF;
|
||
ucUartBufPT++;
|
||
if(ucUartBufPT >= 140) //该指针不会超过140
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
if(ucUartBufPT == 1)
|
||
{
|
||
if(ucUartBuf[HEARD1] != 0x5A) //检查帧头是否Wie0x5AA5
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
|
||
}
|
||
else if(ucUartBufPT == 2)
|
||
{
|
||
|
||
if(ucUartBuf[HEARD2] != 0xA5)
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
else
|
||
{
|
||
uiUartRcvChkSum = 0; //帧头判断正确
|
||
ucUartErrCode = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
if(ucUartBufPT < (ucUartBuf[LENGTH]+9))
|
||
{
|
||
if(ucUartBufPT <= (ucUartBuf[LENGTH]+7))
|
||
{
|
||
uiUartRcvChkSum += ucUartBuf[ucUartBufPT-1];
|
||
}
|
||
|
||
if(ucUartBufPT == (TARGET+1)) //检查ID
|
||
{
|
||
|
||
if(ucUartBuf[TARGET] != IAP_BMSID)
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
}
|
||
else if(ucUartBufPT == (COMMAND+1)) //检测COMMAND
|
||
{
|
||
if((ucUartBuf[COMMAND] != IAP_CMD_HANDSHAKE)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_BEGIN)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_TRANS)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_VERIFY)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_RESET))
|
||
{
|
||
ucUartErrCode |= IAPERROR_CMD;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
BootMcuWdtClear();
|
||
UartCmdProcess();
|
||
}
|
||
}
|
||
RI = 0;
|
||
}
|
||
|
||
if(TI)
|
||
{
|
||
BootMcuWdtClear(); //在该程序循环中,未接收到UART通讯,则判定通讯异常,触发看门狗
|
||
|
||
if(ucUartBufPT >= (ucUartBuf[LENGTH]+8))
|
||
{
|
||
UartRxEn(); //Allow UART receive data
|
||
ucUartBufPT = 0;
|
||
ucUartBuf[0] = 0;
|
||
ucUartBuf[1] = 0;
|
||
ucUartBuf[2] = 0;
|
||
bUartSndOverFlg = 1;
|
||
}
|
||
else
|
||
{
|
||
ucUartBufPT++;
|
||
UartTxEn(ucUartBuf[ucUartBufPT]);
|
||
}
|
||
|
||
TI = 0;
|
||
}
|
||
|
||
if(ucIapRestCommand == IAP_CMD_RESET)
|
||
{
|
||
BootMcuWdtClear();
|
||
if(bUartSndOverFlg) //Reset帧回复结束
|
||
{
|
||
bUartSndOverFlg = 0;
|
||
ucIapRestCommand = 0;
|
||
((void(code*)(void))0x0000)();
|
||
}
|
||
}
|
||
}
|
||
#elif ((UART_DEFINE >= 31)&&(UART_DEFINE<= 60))
|
||
{
|
||
INSCON = 0x40;
|
||
if(RI1)
|
||
{
|
||
//BootMcuWdtClear(); //在该程序循环中,未接收到UART通讯,则判定通讯异常,触发看门狗
|
||
ucUartBuf[ucUartBufPT] = SBUF1;
|
||
INSCON = 0x00;
|
||
ucUartBufPT++;
|
||
if(ucUartBufPT >= 140) //该指针不会超过140
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
if(ucUartBufPT == 1)
|
||
{
|
||
if(ucUartBuf[HEARD1] != 0x5A) //检查帧头是否Wie0x5AA5
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
|
||
}
|
||
else if(ucUartBufPT == 2)
|
||
{
|
||
|
||
if(ucUartBuf[HEARD2] != 0xA5)
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
else
|
||
{
|
||
uiUartRcvChkSum = 0; //帧头判断正确
|
||
ucUartErrCode = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
if(ucUartBufPT < (ucUartBuf[LENGTH]+9))
|
||
{
|
||
if(ucUartBufPT <= (ucUartBuf[LENGTH]+7))
|
||
{
|
||
uiUartRcvChkSum += ucUartBuf[ucUartBufPT-1];
|
||
}
|
||
|
||
if(ucUartBufPT == (TARGET+1)) //检查ID
|
||
{
|
||
|
||
if(ucUartBuf[TARGET] != IAP_BMSID)
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
}
|
||
else if(ucUartBufPT == (COMMAND+1)) //检测COMMAND
|
||
{
|
||
if((ucUartBuf[COMMAND] != IAP_CMD_HANDSHAKE)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_BEGIN)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_TRANS)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_VERIFY)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_RESET))
|
||
{
|
||
ucUartErrCode |= IAPERROR_CMD;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
BootMcuWdtClear();
|
||
UartCmdProcess();
|
||
}
|
||
}
|
||
INSCON = 0x40;
|
||
RI1 = 0;
|
||
INSCON = 0x00;
|
||
}
|
||
INSCON = 0x40;
|
||
|
||
if(TI1)
|
||
{
|
||
INSCON = 0x00;
|
||
BootMcuWdtClear(); //在该程序循环中,未接收到UART通讯,则判定通讯异常,触发看门狗
|
||
|
||
if(ucUartBufPT >= (ucUartBuf[LENGTH]+8))
|
||
{
|
||
UartRxEn(); //Allow UART receive data
|
||
ucUartBufPT = 0;
|
||
ucUartBuf[0] = 0;
|
||
ucUartBuf[1] = 0;
|
||
ucUartBuf[2] = 0;
|
||
bUartSndOverFlg = 1;
|
||
}
|
||
else
|
||
{
|
||
ucUartBufPT++;
|
||
UartTxEn(ucUartBuf[ucUartBufPT]);
|
||
}
|
||
INSCON = 0x40;
|
||
|
||
TI1 = 0;
|
||
INSCON = 0x00;
|
||
}
|
||
|
||
if(ucIapRestCommand == IAP_CMD_RESET)
|
||
{
|
||
BootMcuWdtClear();
|
||
if(bUartSndOverFlg) //Reset帧回复结束
|
||
{
|
||
bUartSndOverFlg = 0;
|
||
ucIapRestCommand = 0;
|
||
((void(code*)(void))0x0000)();
|
||
}
|
||
}
|
||
}
|
||
#elif ( UART_DEFINE == 61)
|
||
{
|
||
INSCON = 0x40;
|
||
if(RI2)
|
||
{
|
||
//BootMcuWdtClear(); //在该程序循环中,未接收到UART通讯,则判定通讯异常,触发看门狗
|
||
ucUartBuf[ucUartBufPT] = SBUF2;
|
||
INSCON = 0x00;
|
||
ucUartBufPT++;
|
||
if(ucUartBufPT >= 140) //该指针不会超过140
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
if(ucUartBufPT == 1)
|
||
{
|
||
if(ucUartBuf[HEARD1] != 0x5A) //检查帧头是否Wie0x5AA5
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
|
||
}
|
||
else if(ucUartBufPT == 2)
|
||
{
|
||
|
||
if(ucUartBuf[HEARD2] != 0xA5)
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
else
|
||
{
|
||
uiUartRcvChkSum = 0; //帧头判断正确
|
||
ucUartErrCode = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
if(ucUartBufPT < (ucUartBuf[LENGTH]+9))
|
||
{
|
||
if(ucUartBufPT <= (ucUartBuf[LENGTH]+7))
|
||
{
|
||
uiUartRcvChkSum += ucUartBuf[ucUartBufPT-1];
|
||
}
|
||
|
||
if(ucUartBufPT == (TARGET+1)) //检查ID
|
||
{
|
||
|
||
if(ucUartBuf[TARGET] != IAP_BMSID)
|
||
{
|
||
ucUartBufPT = 0;
|
||
}
|
||
}
|
||
else if(ucUartBufPT == (COMMAND+1)) //检测COMMAND
|
||
{
|
||
if((ucUartBuf[COMMAND] != IAP_CMD_HANDSHAKE)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_BEGIN)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_TRANS)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_VERIFY)
|
||
&& (ucUartBuf[COMMAND] != IAP_CMD_RESET))
|
||
{
|
||
ucUartErrCode |= IAPERROR_CMD;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
BootMcuWdtClear();
|
||
UartCmdProcess();
|
||
}
|
||
}
|
||
INSCON = 0x40;
|
||
RI2 = 0;
|
||
INSCON = 0x00;
|
||
}
|
||
INSCON = 0x40;
|
||
|
||
if(TI2)
|
||
{
|
||
INSCON = 0x00;
|
||
BootMcuWdtClear(); //在该程序循环中,未接收到UART通讯,则判定通讯异常,触发看门狗
|
||
|
||
if(ucUartBufPT >= (ucUartBuf[LENGTH]+8))
|
||
{
|
||
UartRxEn(); //Allow UART receive data
|
||
ucUartBufPT = 0;
|
||
ucUartBuf[0] = 0;
|
||
ucUartBuf[1] = 0;
|
||
ucUartBuf[2] = 0;
|
||
bUartSndOverFlg = 1;
|
||
}
|
||
else
|
||
{
|
||
ucUartBufPT++;
|
||
UartTxEn(ucUartBuf[ucUartBufPT]);
|
||
}
|
||
INSCON = 0x40;
|
||
|
||
TI2 = 0;
|
||
INSCON = 0x00;
|
||
}
|
||
|
||
if(ucIapRestCommand == IAP_CMD_RESET)
|
||
{
|
||
BootMcuWdtClear();
|
||
if(bUartSndOverFlg) //Reset帧回复结束
|
||
{
|
||
bUartSndOverFlg = 0;
|
||
ucIapRestCommand = 0;
|
||
((void(code*)(void))0x0000)();
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|