///=====================================================================
//文件名称：ueupdate.h文件
//制作单位：SD-Arm(sumcu.suda.edu.cn)
//更新记录：20181201-20200627
//移植规则：【固定】
///=====================================================================

#ifndef UEUPDATE_H     //防止重复定义（UEUPDATE_H  开头)
#define UEUPDATE_H

#include "flash.h"
#include "uart.h"
#include "gec.h"
#include "emuart.h"
//更新开始帧    共9个字节     帧标识为0
#pragma  pack(push,1)
struct startData
{
	uint8_t type;       //帧标识 0
	uint8_t style;      //更新方式，0：整体替换更新；1：整体保留更新；2：增量保留更新
	uint16_t frameNum;  //总帧数
	uint16_t curFrame;  //当前帧号
	uint32_t codeSize;  //更新代码总大小（用于定位flash擦除时定位扇区位置和大小）
};
#pragma  pack(pop)

//更新复制帧    共474个字节    帧标识为1
#pragma  pack(push,1)
struct copyData
{
	uint8_t type;          //帧标识 1
	uint16_t curFrame;     //当前帧号
	uint8_t segNum;        //复制数据段个数
	uint32_t addInfo[94];  //复制数据段地址信息（2个一组，起始地址、复制地址）
	uint16_t lenInfo[47];  //复制数据段长度信息
};
#pragma  pack(pop)

//更新插入帧    共476个字节    帧标识为2
#pragma  pack(push,1)
struct insertData
{
	uint8_t type;          //帧标识 2
	uint16_t curFrame;     //当前帧号
	uint8_t segNum;        //插入代码段个数
	uint32_t addInfo[12];  //插入代码段地址信息
	uint16_t lenInfo[12];  //插入代码段长度信息
	uint8_t data[400];     //插入数据
};
#pragma  pack(pop)

//更新检查帧    共84个字节    帧标识为3
#pragma  pack(push,1)
struct checkData
{
	uint8_t type;            //帧标识 3
	uint16_t curFrame;       //当前帧号
	uint8_t loseNum;         //丢失帧数
	uint16_t loseFrame[40];  //丢失帧号，最多40个
};
#pragma  pack(pop)

//更新命令帧    共3个字节    帧标识为4
#pragma  pack(push,1)
struct updateData
{
	uint8_t type;       //帧标识 4
	uint16_t curFrame;  //当前帧号
};
#pragma  pack(pop)

//更新返回帧    共4个字节    帧标识为5
#pragma  pack(push,1)
struct backData
{
	uint8_t type;       //帧标识 5
	uint16_t curFrame;  //当前帧号
	uint8_t flag;       //返回状态 0：成功；其他：失败
};
#pragma  pack(pop)
//======================================================================
//函数名称：ueupdate_init
//函数参数：startSector：用户程序起始扇区号；endSector：用户程序结束扇区号+1；
//       sectSize：芯片扇区大小
//函数返回：无
//功能概要：实现终端程序更新功能初始化，并设置用户程序起始和结束扇区号
//       flash模块的初始化和帧标志初始化
//======================================================================
void ueupdate_init(uint8_t startSector,uint8_t endSector,uint16_t sectSize);

//======================================================================
//函数名称：ueupdate_reinit
//函数参数：buf:接收到的更新数据;len:接收到的更新数据长度
//函数返回：
//       1：开始整体替换更新；
//       4：丢帧；
//功能概要：根据开始更新数据帧，重新初始化Ueupdate构件。该函数仅用于整体替换更新情况，因为从User程序
//       跳回BIOS程序，ueupdate构件的初始状态未能保留，需要重新初始化更新状态变量。
//======================================================================
uint8_t ueupdate_reinit(uint8_t *buf,uint16_t len);

//======================================================================
//函数名称：ueupdate_reframe
//函数参数：buf:接收到的更新数据;len:接收到的更新数据长度
//函数返回：0：接收并执行更新操作（部分）成功；1：代码更新完毕
//       2：帧标识错误；3：丢帧
//功能概要：接收并解析更新数据，并进行相应的操作，包括更新开始、更新复制、更新插入、更新检查、更新命令
//======================================================================
uint8_t ueupdate_reframe(uint8_t *buf,uint16_t len);



//======================================================================
//函数名称：ueupdate_backGet
//函数参数：buf:待返回更新的数据，len:待返回更新的数据长度
//函数返回：
//功能概要：解析接收到的数据，获取返回数据，提示上位机更新操作执行状态
//======================================================================
uint8_t ueupdate_backGet(uint8_t *buf,uint16_t *len);

//======================================================================
//函数名称：ueupdate_checkGet
//函数参数：buf:更新检查数据，len:更新检查数据长度
//函数返回：
//功能概要：返回更新检查帧数据，提示上位机更新过程中的丢帧状态
//======================================================================
uint8_t ueupdate_checkGet(uint8_t *buf,uint16_t *len);

//======================================================================
//函数名称：ueupdate_dataJudge
//函数参数：data:接收到的上位机数据，len:待检查的数据长度
//函数返回：0：数据满足更新帧结构；其他：数据不满足更新帧结构
//功能概要：检查传入数据是否满足更新上位机传输过来的数据
//======================================================================
uint8_t ueupdate_dataJudge(uint8_t *data,uint16_t len);


uint8_t updateJudge();

#endif
