Files
checker_slave/source/elec_det/interface/EWUpdata.c
ranchuan d22fdc1ccb ew写延时验证成功,ej写流水号验证成功
解决上位机协议crc错误依然执行命令的bug
    注意:小板方案中芯片类型与主板不同时,使用槽任务可能造成各种异常问题(死机,死循环,不返回数据等)
2023-12-26 18:08:59 +08:00

481 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "base/define.h"
#include "basechecker.h"
#include "stdint.h"
#include "EWUpdata.h"
#include "driver/EWDriver.h"
#include "base/delay.h"
#include "hardware/adc_cfg.h"
#include "base/utility.h"
#include "hardware/power.h"
#include "hardware/timer_cfg.h"
#include "debug.h"
#include "commend.h"
#include "mystring.h"
#include "mystdlib.h"
#define UPDATA_PACK_LEN 128
#define UPDATA_BASE_ADDR 0x1000
#define UPDATA_DATA_LEN (11*1024)
#define UPDATA_FLAG_ADDR (0x7c)
#define BOOT_FLAG ((uint8_t []){0x99,0x66,0xaa,0x55})
#define UPDATA_FLAG ((uint8_t []){0xaa,0xbb,0xcc,0xdd})
#define UPDATA_CRC_ALL ((uint32_t *)(MC_CODE_ADDR+16*1024))[0]
#define UPDATA_CRC_APP ((uint32_t *)(MC_CODE_ADDR+16*1024))[1]
// 擦除
static uint8_t EW_bootErease(void)
{
uint8_t data[3]={0xfe,0x00,0x00};
uint8_t read[4]={0};
uint8_t ret=0;
DMod_SendBytesXor(data,2,1);
delay_ms(50);
ret=DMod_ReadBytesXor(read,4,100);
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]);
return ret;
}
static int cmd_jwt_boot_erase(list_def *argv)
{
int ret=0;
ret=EW_bootErease();
return ret;
}
commend_export(jwt_boot_erase,cmd_jwt_boot_erase,"jwt srase in boot")
// 跳转
static uint8_t EW_bootJump(void)
{
uint8_t data[3]={0xf9,0x00,0x00};
uint8_t read[4]={0};
uint8_t ret=0;
DMod_SendBytesXor(data,2,1);
ret=DMod_ReadBytesXor(read,4,100);
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]);
return ret;
}
static int cmd_jwt_boot_jump(list_def *argv)
{
int ret=0;
ret=EW_bootJump();
return ret;
}
commend_export(jwt_boot_jump,cmd_jwt_boot_jump,"jwt jump in boot")
// 充电
static uint8_t EW_bootCharg(void)
{
uint8_t data[4]={0xf8,0x01,0x01,0x00};
uint8_t read[4]={0};
uint8_t ret=0;
DMod_SendBytesXor(data,3,1);
delay_ms(2);
ret=DMod_ReadBytesXor(read,4,100);
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]);
return ret;
}
static int cmd_jwt_boot_charg(list_def *argv)
{
int ret=0;
ret=EW_bootCharg();
return ret;
}
commend_export(jwt_boot_charg,cmd_jwt_boot_charg,"jwt charg in boot")
// 放电
static uint8_t EW_bootDisCharg(void)
{
uint8_t data[4]={0xf8,0x01,0x00,0x00};
uint8_t read[4]={0};
uint8_t ret=0;
DMod_SendBytesXor(data,3,1);
ret=DMod_ReadBytesXor(read,4,100);
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]);
return ret;
}
static int cmd_jwt_boot_discharg(list_def *argv)
{
int ret=0;
ret=EW_bootDisCharg();
return ret;
}
commend_export(jwt_boot_discharg,cmd_jwt_boot_discharg,"jwt discharg in boot")
// 发送数据
// len 最长为128字节
static uint8_t EW_bootWrite(uint16_t addr,uint8_t *d,uint16_t len)
{
uint8_t ret=0;
uint8_t read[4]={0};
uint8_t *buf=rt_malloc(len+2+2+1);
if(buf==RT_NULL) return 1;
buf[0]=0xfc;
buf[1]=2+len;
buf[2]=addr&0xff;
buf[3]=addr>>8;
rt_memcpy(&buf[4],d,len);
LED2_Out=0;
DMod_SendBytesXor(buf,len+2+2,1);
LED2_Out=1;
ret=DMod_ReadBytesXor(read,4,100);
rt_free(buf);
if(ret){
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]);
}
return ret;
}
// 校验
static uint8_t EW_bootCheckCrc(uint16_t adr_start,uint16_t adr_end,uint32_t *crc)
{
uint8_t ret=0;
uint8_t cmd[7]={0xfb,0x04,adr_start&0xff,adr_start>>8,adr_end&0xff,adr_end>>8};
uint8_t read[4+4]={0};
DMod_SendBytesXor(cmd,6,1);
delay_ms(10);
ret=DMod_ReadBytesXor(read,8,100);
if(ret==0){
if(crc){
*crc=(read[3]<<24)|(read[4]<<16)|(read[5]<<8)|(read[6]<<0);
}
}
DBG_LOG("addr_start=0x%04x,addr_end=0x%04x.",adr_start,adr_end);
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,",
ret,read[0],read[1],read[2],read[3],read[4],read[5],read[6],read[7]);
return ret;
}
static int cmd_jwt_boot_checkcrc(list_def *argv)
{
int ret=0;
uint32_t crc=0;
ret=EW_bootCheckCrc(UPDATA_BASE_ADDR,UPDATA_BASE_ADDR+UPDATA_DATA_LEN,&crc);
cmd_print("jwt crc32=0x%04x.",crc);
//crc=Crc32Calu((uint32_t *)(MC_CODE_ADDR+UPDATA_BASE_ADDR),UPDATA_DATA_LEN);
crc=UPDATA_CRC_APP;
cmd_print("local crc32=0x%04x.",crc);
return ret;
}
commend_export(jwt_boot_checkcrc,cmd_jwt_boot_checkcrc,"jwt checkcrc in boot")
// 读取
static uint8_t EW_bootRead(uint16_t adr,uint8_t *buf,uint16_t len)
{
uint8_t ret=0;
uint8_t cmd[7]={0xfa,0x03,adr&0xff,adr>>8,len};
uint16_t read_len=2+len+1+1;
uint8_t *read=rt_malloc(read_len);
if(read==RT_NULL) return 1;
DMod_SendBytesXor(cmd,6,1);
ret=DMod_ReadBytesXor(read,read_len,100);
rt_memset(buf,0,len);
if(ret==0)
{
rt_memcpy(buf,&read[3],len);
}
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read[0],read[1],read[2],read[3]);
rt_free(read);
return ret;
}
// app:读取数据
static int EW_appRead(void)
{
uint8_t read_buf[4]={0};
int ret=0;
uint8_t addr=(uint8_t)(UPDATA_FLAG_ADDR/4);
DBG_LOG("addr=0x%02x.",addr);
ret=EW_ReadMTP(1,addr,read_buf,4);
DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,read_buf[0],read_buf[1],read_buf[2],read_buf[3]);
return ret;
}
static int cmd_jwt_app_read(list_def *argv)
{
int ret=0;
ret=EW_appRead();
return ret;
}
commend_export(jwt_app_read,cmd_jwt_app_read,"jwt read in app")
// app:通信测试
static int EW_appCommTest(void)
{
// uint8_t data[4]={0x11,0x22};
// uint8_t ret;
// DBG_LOG("send:%02x,%02x.",data[0],data[1]);
// ret=EW_CommTest(data,2,300);
// DBG_LOG("ret=%d,dat=%02x,%02x,%02x,%02x,",ret,data[0],data[1],data[2],data[3]);
// return ret;
return EW_appRead();
}
static int cmd_jwt_app_commtest(list_def *argv)
{
int ret=0;
ret=EW_appCommTest();
return ret;
}
commend_export(jwt_app_commtest,cmd_jwt_app_commtest,"jwt commtest in app")
// app:runbootloader
static void EW_appRunBoot(void)
{
EW_Charge(1,0,0);
delay_ms(6000);
EW_RunBootLoader(1,1);
DBG_LOG("run boot");
}
static int cmd_jwt_app_runboot(list_def *argv)
{
int ret=0;
EW_appRunBoot();
return ret;
}
commend_export(jwt_app_runboot,cmd_jwt_app_runboot,"jwt turn to bootloader")
typedef struct{
// 充电时间 6000
int time_charg;
// 加载app时间 6000
int time_loadapp;
// 总线关断时间 1000
int time_poweroff;
// 升级模式0无app时升级1无条件升级
int updata_mode;
// 模块状态
int state;
}ew_updata_def;
// 硬复位
int EW_HardReset(ew_updata_def *e)
{
EW_BUS_OFF;
delay_ms(e->time_poweroff);
EW_BUS_ON;
return 0;
}
// 判断模块在何种工作状态 1:boot 2:app
// 3:boot失败且app也失败
int EW_CheckState(ew_updata_def *e)
{
uint16_t ret=0;
delay_ms(100);
ret=EW_bootCharg();
if(ret==0){
delay_ms(e->time_charg);
e->state=1;
}else{
EW_HardReset(e);
delay_ms(e->time_loadapp);
ret=EW_appCommTest();
delay_ms(5);
if(ret==0){
e->state=2;
}else{
e->state=3;
}
}
return e->state;
}
// 跳转到app的方式
static int EW_TurnToBoot1(ew_updata_def *e)
{
DBG_LOG("turn to boot1");
delay_ms(5);
EW_EnWriteMTP(0,1);
delay_ms(5);
EW_RunBootLoader(0,0);
delay_ms(500);
if(EW_bootCharg()==0)
return 0;
else
return 1;
}
static int EW_TurnToBoot2(ew_updata_def *e)
{
DBG_LOG("turn to boot2");
delay_ms(5);
EW_EnWriteMTP(0,1);
delay_ms(5);
EW_WriteMTP(0,(uint8_t)(UPDATA_FLAG_ADDR/4),BOOT_FLAG,4);
delay_ms(5);
return 1;
}
// 跳转到bootloader
int EW_TurnToBoot(ew_updata_def *e)
{
typedef int (*turnfun)(ew_updata_def *e);
turnfun func_table[]={EW_TurnToBoot1,EW_TurnToBoot2};
int ret=0;
for(int i=0;i<2;i++){
if(e->state!=1){
ret=func_table[i](e);
if(ret){
EW_HardReset(e);
}
EW_CheckState(e);
}else{
break;
}
}
return e->state;
}
static void EW_ParamPrint(ew_updata_def *e)
{
DBG_LOG("time_charg=%d",e->time_charg);
DBG_LOG("time_loadapp=%d",e->time_loadapp);
DBG_LOG("time_poweroff=%d",e->time_poweroff);
DBG_LOG("updata_mode=%d",e->updata_mode);
}
// 升级
void EW_Updata(void)
{
Checker_RunCfg_st *cfg=&checker_runcfg;
uint16_t ret=0;
uint8_t read_buf[4]={0};
uint8_t *data=(uint8_t *)MC_CODE_ADDR+UPDATA_BASE_ADDR;
uint16_t len=UPDATA_DATA_LEN;
uint16_t addr=UPDATA_BASE_ADDR;
uint8_t pack_len=UPDATA_PACK_LEN;
uint32_t crc=0;
uint32_t crc_module=0;
ew_updata_def ew_updata={0};
// 充电时间 6000
ew_updata.time_charg=checker_runcfg.params[0];
// 加载app时间 6000
ew_updata.time_loadapp=checker_runcfg.params[1];
// 总线关断时间 1000
ew_updata.time_poweroff=checker_runcfg.params[2];
// 升级模式0无app时升级1无条件升级
ew_updata.updata_mode=checker_runcfg.params[3];
EW_ParamPrint(&ew_updata);
PowerCalibration_set(200,120);
ret=EW_CheckState(&ew_updata);
if(ret==2){
// 在app中
if(ew_updata.updata_mode==0){
DBG_LOG("no need updata.");
ret=0;
goto err;
}
}
ret=EW_TurnToBoot(&ew_updata);
// ret!=1 跳转到bootloader失败
if(ret!=1) {
DBG_WARN("turn to boot failed.ret=%d",ret);
ret=1;
goto err;
}
DBG_LOG("erase app");
ret=EW_bootErease();
if(ret) {ret=2;goto err;}
delay_ms(600);
while(len>0){
pack_len=len>UPDATA_PACK_LEN?UPDATA_PACK_LEN:len;
LED1_Out=!LED1_Out;
ret=EW_bootWrite(addr,data,pack_len);
addr+=pack_len;
data+=pack_len;
len-=pack_len;
if(ret) {ret=3;goto err;}
delay_ms(1);
}
//crc=Crc32Calu((uint32_t *)(MC_CODE_ADDR+UPDATA_BASE_ADDR),UPDATA_DATA_LEN);
crc=UPDATA_CRC_APP;
DBG_LOG("local crc:0x%04x.",crc);
ret=EW_bootCheckCrc(UPDATA_BASE_ADDR,UPDATA_BASE_ADDR+UPDATA_DATA_LEN,&crc_module);
DBG_LOG("module crc:0x%04x.",crc_module);
if(ret) {ret=4;goto err;}
if(crc!=crc_module){ret=5;goto err;}
delay_ms(50);
ret=EW_bootJump();
if(ret) {ret=6;goto err;}
delay_ms(ew_updata.time_loadapp);
ret=EW_EnWriteMTP(0,1);
if(ret) {ret=7;goto err;}
DBG_LOG("EW_EnWriteMTP success.");
delay_ms(5);
ret=EW_WriteMTP(1,(uint8_t)(UPDATA_FLAG_ADDR/4),UPDATA_FLAG,4);
if(ret) {ret=8;goto err;}
DBG_LOG("EW_WriteMTP success.");
delay_ms(20);
ret=EW_ReadMTP(1,(uint8_t)(UPDATA_FLAG_ADDR/4),read_buf,4);
if(ret) {ret=9;goto err;}
if(memcmp(read_buf,UPDATA_FLAG,4)!=0){
DBG_LOG("read_buf=0x%02d,0x%02d,0x%02d,0x%02d.",read_buf[0],read_buf[1],read_buf[2],read_buf[3]);
ret=10;goto err;
}
DBG_LOG("EW_ReadMTP check success.");
delay_ms(5);
XTBUS_OFF;
delay_ms(ew_updata.time_poweroff);
XTBUS_ON;
delay_ms(ew_updata.time_loadapp);
ret=EW_appCommTest();
if(ret) {ret=11;goto err;}
DBG_LOG("EW_appCommTest success.");
err:
DBG_LOG("ret=%d",ret);
Checker_SetRtv(&ret,checker_runcfg.rtv_count);
Checker_MaskResult(ret,checker_runcfg.task_info.runindex);
}
static int cmd_jwt_updata(list_def *argv)
{
int ret=0;
checker_runcfg.params[0]=6000;
checker_runcfg.params[1]=6000;
checker_runcfg.params[2]=1000;
checker_runcfg.params[3]=0;
checker_runcfg.rtv_count=0;
EW_Updata();
return ret;
}
commend_export(jwt_updata,cmd_jwt_updata,"jwt updata")