PASII/CandeII_1.4/Driver/ota.c

308 lines
9.3 KiB
C
Raw Normal View History

#include "ota.h"
#include "lib.h"
#include "debug.h"
#include <string.h>
#include "delay.h"
#include "softtimer.h"
#include "DebugLog.h"
#ifdef _OTA_
uint8_t ota_state=0;
uint8_t ota_writecnt=0;
uint16_t ota_section_size=0,ota_receive_size=0,ota_section_check=0,ota_receive_check=0;
uint32_t ota_section_offset=0;
static uint8_t EvtBuf[sizeof(struct hci_evt)];
struct hci_evt *pevt = (struct hci_evt *)EvtBuf;
__align(4) struct ota_write_info ota_w;
#define p_flash_stack ((uint8_t *) 0x2000074a)
static void EvtCommandComplete(uint8_t opcode, uint8_t *ret_parm, uint8_t ret_len)
{
pevt->evtcode = EVT_COMMAND_COMPLETE;
pevt->evtlen = ret_len + CMD_COMPLETE_HDR_SZ;
pevt->evtparm.EvtCommandComplete.opcode= opcode;
memcpy((uint8_t *)&pevt->evtparm.EvtCommandComplete.RetParm, ret_parm, ret_len);
}
void CmdFwErase(void)
{
struct ret_fw_erase_cmd Ret;
// DBGPRINTF(("CmdFwErase\r\n"));
CodeErase();
Ret.status = ERR_COMMAND_SUCCESS;
EvtCommandComplete(CMD_FW_ERASE, (uint8_t *)&Ret, sizeof (Ret));
}
static void Cmd4KSETTINGWrite(struct cmd_fw_write *p_cmd)
{
struct ret_fw_erase_cmd Ret;
if(p_cmd->offset>4096) return;
if((p_cmd->offset+p_cmd->sz)>4096) p_cmd->sz=4096-p_cmd->offset;
memcpy(p_flash_stack+p_cmd->offset,p_cmd->data,p_cmd->sz);
DBGPRINTF("cmd4KSETTINGWrite %x %x\r\n",p_cmd->offset,p_cmd->sz);
Ret.status = ERR_COMMAND_SUCCESS;
EvtCommandComplete(CMD_FW_WRITE, (uint8_t *)&Ret, sizeof (Ret));
}
static void CmdFwWriteStart(uint8_t status,uint16_t sz,uint16_t checksum)
{
struct ret_fw_write_start_cmd Ret;
Ret.sz=sz;
Ret.checksum=checksum;
Ret.status=status;
EvtCommandComplete(CMD_FW_WRITE_START, (uint8_t *)&Ret, sizeof (Ret));
}
static void Cmd4KSETTINGUpgrade(struct cmd_4ksetting_upgrade *p_cmd)
{
struct ret_fw_erase_cmd Ret;
uint8_t temp = 0;
temp = Setting4kUpdate(p_flash_stack,p_cmd->checksum,p_cmd->Xor);
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
DBGPRINTF("CodeUpdate=%d %x %x\r\n", temp,p_cmd->checksum,p_cmd->Xor);
#endif
if(temp==0)
Ret.status = ERR_COMMAND_FAILED;
else
{
Ret.status = ERR_COMMAND_SUCCESS;
}
EvtCommandComplete(CMD_FW_UPGRADE, (uint8_t *)&Ret, sizeof (Ret));
}
static void CmdFwUpgradev20(struct cmd_fw_upgrade_V20 *p_cmd)
{
struct ret_fw_erase_cmd Ret;
uint8_t temp = 0;
if(ota_w.idx != 0)
CodeWrite(ota_w.cnt*32, ota_w.idx, ota_w.buf);
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
DBGPRINTF("ota sz:%x checksum:%x ",p_cmd->sz,p_cmd->checksum);
#endif
temp = CodeUpdate(NULL, NULL, p_cmd->sz, p_cmd->checksum);
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
DBGPRINTF("CodeUpdatev20=%d\r\n", temp);
#endif
if(temp==0)
Ret.status = ERR_COMMAND_FAILED;
else
Ret.status = ERR_COMMAND_SUCCESS;
EvtCommandComplete(CMD_FW_UPGRADE, (uint8_t *)&Ret, sizeof (Ret));
}
static void CmdFlashdataUpgradev30(struct cmd_fw_upgrade_V20 *p_cmd)
{
struct ret_fw_erase_cmd Ret;
uint8_t temp = 0;
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
DBGPRINTF("ota sz:%x checksum:%x ",p_cmd->sz,p_cmd->checksum);
#endif
temp = FlashDataUpdate(p_cmd->sz, p_cmd->checksum);
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
DBGPRINTF("CodeUpdatev30=%d\r\n", temp);
#endif
if(temp==0)
Ret.status = ERR_COMMAND_FAILED;
else
Ret.status = ERR_COMMAND_SUCCESS;
EvtCommandComplete(CMD_FW_UPGRADE, (uint8_t *)&Ret, sizeof (Ret));
}
void ota_cmd(uint8_t *p_cmd, uint8_t sz)
{
struct hci_cmd *pcmd = (struct hci_cmd*)p_cmd;
if((ota_section_size==0) || (ota_state==0))
{
switch(pcmd->opcode)
{
case CMD_FW_ERASE:
BLSetConnectionUpdate(0); //ota
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("CMD_FW_ERASE\r\n");
#endif
//CmdFwErase();//<2F><><EFBFBD>÷ŵ<C3B7>main<69><6E><EFBFBD><EFBFBD>while(1)<29><><EFBFBD><EFBFBD>
Timer_Evt_Start(EVT_1S_OTA);
ota_state=1;
ota_section_offset=0;
break;
case CMD_4KSETTING_ERASE:
BLSetConnectionUpdate(0); //ota
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("4KSETTING_ERASE \r\n");
#endif
ota_state=4;
ota_section_offset=0;
break;
case CMD_4KSETTING_WRITE:
Cmd4KSETTINGWrite(&pcmd->cmdparm.CmdFwWrite);
ota_state=5;
break;
case CMD_4KSETTING_UPGRADE:
Cmd4KSETTINGUpgrade(&pcmd->cmdparm.Cmd4ksettingUpgrade);
ota_state=6;
break;
case CMD_FW_UPGRADEV20:
CmdFwUpgradev20(&pcmd->cmdparm.CmdFwUpgradeV20);
ota_state=3;
break;
case CMD_FW_WRITE_START:
ota_section_size=pcmd->cmdparm.CmdFwWriteStart.sz;
ota_section_check=pcmd->cmdparm.CmdFwWriteStart.checksum;
ota_section_offset=pcmd->cmdparm.CmdFwWriteStart.offset;
ota_receive_size=0;
ota_receive_check=0;
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("CMD_FW_WRITE_START offset:%x,size:%x checksum:%x\r\n",pcmd->cmdparm.CmdFwWriteStart.offset,ota_section_size,pcmd->cmdparm.CmdFwWriteStart.checksum);
#endif
break;
case CMD_FLASHDATA_ERASE:
BLSetConnectionUpdate(0); //ota
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("FLASHDATA_ERASE \r\n");
#endif
//EraseFlashData(0, 30); //<2F><><EFBFBD><EFBFBD>FLASHDATA<54><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>СΪ120KB<4B><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĿΪ120KB/4KB=30 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>Ƚϳ<C8BD><CFB3><EFBFBD>ʱ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD>APP<50>Ƕ<EFBFBD>Ҫ<EFBFBD><D2AA>ʱһ<CAB1><D2BB>
Timer_Evt_Start(EVT_1S_OTA);
ota_state=7;
ota_section_offset=0;
break;
case CMD_FLASHDATA_START:
ota_section_size=pcmd->cmdparm.CmdFwWriteStart.sz;
ota_section_check=pcmd->cmdparm.CmdFwWriteStart.checksum;
ota_section_offset=pcmd->cmdparm.CmdFwWriteStart.offset;
ota_receive_size=0;
ota_receive_check=0;
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("FLASHDATA_WRITE_START offset:%x,size:%x checksum:%x\r\n",pcmd->cmdparm.CmdFwWriteStart.offset,ota_section_size,pcmd->cmdparm.CmdFwWriteStart.checksum);
#endif
break;
case CMD_FLASHDATA_UPGRADEV30:
CmdFlashdataUpgradev30(&pcmd->cmdparm.CmdFwUpgradeV20);
ota_state=3;
break;
}
}
else
{
uint16_t idx;
ota_writecnt =0;
for(idx=0; idx < sz ; idx++)
ota_receive_check += p_cmd[idx];
if(((int)p_cmd % 4)!=0)
{
memcpy(ota_w.buf,p_cmd,sz);
if((ota_state==2) || (ota_state==1))
{
idx=CodeWrite(ota_section_offset+ota_receive_size, sz, ota_w.buf);
// #if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
// dbg_printf("CodeWrite noalign:%x %x",ota_section_offset+ota_receive_size,idx);
// #endif
}
else if((ota_state==8) || (ota_state==7))
{
WriteFlashData(ota_section_offset+ota_receive_size, sz, ota_w.buf);
// #if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
// dbg_printf("FlashData noalign ");
// #endif
}
}
else
{
if((ota_state==2) || (ota_state==1))
{
idx=CodeWrite(ota_section_offset+ota_receive_size, sz, p_cmd);
// #if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
// dbg_printf("CodeWrite align:%x %x",ota_section_offset+ota_receive_size,idx);
// #endif
}
else if((ota_state==8) || (ota_state==7))
{
WriteFlashData(ota_section_offset+ota_receive_size, sz, p_cmd);
// #if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
// dbg_printf("FlashData align ");
// #endif
}
}
// #if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
// dbg_printf("section_offset:%x receive_size:%x section_size:%x\r\n",ota_section_offset,ota_receive_size,ota_section_size);
// #endif
ota_receive_size +=sz;
if(ota_receive_size>=ota_section_size)
{
if(ota_receive_check==ota_section_check)
{
CmdFwWriteStart(ERR_COMMAND_SUCCESS,ota_receive_size,ota_receive_check);
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("section OK! ");
#endif
}
else
{
CmdFwWriteStart(ERR_COMMAND_FAILED,ota_receive_size,ota_receive_check);
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("section faile! ");
#endif
}
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
dbg_printf("ota_receive_check:%x ota_section_check:%x\r\n",ota_receive_check,ota_section_check);
#endif
ota_variable_clear(false);
}
}
}
void ota_variable_clear(uint8_t all)
{
if(all)
{
ota_state=0;
ota_writecnt=0;
}
ota_section_size=0;
ota_section_check=0;
ota_receive_size=0;
ota_receive_check=0;
ota_section_offset=0;
}
void ota_rsp(uint8_t *p_rsp, uint8_t *p_sz)
{
memcpy(p_rsp, EvtBuf, pevt->evtlen + 2);
*p_sz = pevt->evtlen + 2;
memset(EvtBuf,0,sizeof(EvtBuf));
}
#endif