android13/hardware/rockchip/gps/TD1030HAL/update.c

320 lines
6.2 KiB
C
Raw Normal View History

2024-06-22 08:45:49 -04:00
#include "update.h"
#include "sdbp.h"
#include "tdgnss.h"
#include "serial.h"
#define BURN_MAX_LEN 512
int com_fd = -1;
extern int update_mode;
int update_sync_count = -1;
int update_sync_total = 0;
typedef struct _update_data_
{
byte *data;
int offset;
int len;
}_update_data_;
_update_data_ update_d = {NULL,0,0};
typedef enum{
UP_IDEL = 0x00,
UP_ENT,
UP_CON,
UP_ERA,
UP_WRI_A,
UP_WRI_E,
UP_VER,
UP_FAIL,
UP_CMP
}STATE_TYPE;
STATE_TYPE update_state = UP_IDEL;
void update_td_get_sync(int *sync_now, int *sync_total)
{
*sync_now = update_sync_count;
*sync_total = update_sync_total;
}
int update_td_init(const unsigned char *update_data, int data_len, int comid)
{
D("update_td_init called.\n");
if(comid < 0)
{
return UPDATE_COM_TX_ERROR;
}
update_d.data = (unsigned char *)malloc(data_len);
if(NULL == update_d.data)
{
D("update_td_init malloc data error.\n");
return UPDATE_DATA_MALLOC_ERROR;
}
com_fd = comid;
memcpy(update_d.data, update_data, data_len);
update_d.len = data_len;
update_d.offset = 0;
update_state = UP_ENT;
update_sync_count = 0;
update_sync_total = data_len / BURN_MAX_LEN;
D("update_td_init returned. update len: %d. sync total: %d.\n", update_d.len, update_sync_total);
return 1;
}
static void update_end(void)
{
D("update end called\n");
SDBP_UPD_REBOOT();
usleep(10000);
if(update_d.data)
free(update_d.data);
update_d.data = NULL;
update_d.len = 0;
update_d.offset = 0;
update_state = UP_IDEL;
update_mode = 0;
}
int update_td_enter_update(void)
{
int datalen;
int waitcnt = 0;
int repeat_send_times = 0;
while(update_sync_count <= update_sync_total)
{
update_state = UP_WRI_A;
datalen = (update_sync_count != update_sync_total) ? BURN_MAX_LEN : (update_d.len - update_sync_total * BURN_MAX_LEN);
if(datalen <= 0)break;
if(0 == SDBP_UPD_WRITE_I(update_d.data, update_d.offset, datalen))
{
update_d.offset += datalen;
update_sync_count++;
continue;
}
else
{
update_d.offset += datalen;
update_sync_count++;
}
waitcnt = 0;
while(update_state != UP_WRI_E&& waitcnt < 200){usleep(15000);waitcnt ++;}
if(waitcnt >= 200)
{
repeat_send_times ++;
update_d.offset -= datalen;
update_sync_count--;
}
if(repeat_send_times >= 10)
{
D("Error : Upgrade timeout");
update_state = UP_FAIL;
break;
}
}
if(update_d.offset == update_d.len)
{
D("Succeed : upgrade finish %d/%d",update_d.offset,update_d.len);
update_state = UP_VER;
SDBP_QUE_VER_I();
return 1;
}
else
{
D("ERROR : upgrade 0 %d/%d",update_d.offset,update_d.len);
update_state = UP_FAIL;
return 0;
}
}
void update_td_set_BaudRate(int BaudRate)
{
UARTPara para;
para.com = 1;
para.databit = 0;
para.stopbit = 0;
para.checkbit = 0;
if(BaudRate == 115200)
{
para.baudrate = 6;
SDBP_CFG_UART_I(para, 0); //115200 0 not save; 1 autosave
usleep(1000000);
BaudRateChange(B115200);//how to check 115200 or not
usleep(500000);
D("Succeed : Set BaudRate to %d",BaudRate);
}
else if(BaudRate == 9600)
{
para.baudrate = 2;
SDBP_CFG_UART_I(para, 0); //115200 0 not save; 1 autosave
usleep(1000000);
BaudRateChange(B9600);//how to check 115200 or not
usleep(500000);
D("Succeed : Set BaudRate to %d",BaudRate);
}
}
void* update_td_handler_thread(void *arg)
{
(void)arg;
int again_times = 0;
do
{
do
{
SDBP_UPD_ENTER();
again_times ++;
DiscardBuffer();
BaudRateChange(B9600);
Write55();
usleep(100000);
update_state = UP_CON;
SDBP_UPD_CONFIRM_I();
usleep(500000);
}while(update_state != UP_ERA && again_times < 5);
if(again_times >= 5)
{
goto Fail;
}
SDBP_CANCEL_PROTECT_I_C1();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C3();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C2();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C1();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C4();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C5();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C2();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C1();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C6();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C7();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C8();
usleep(50000);
SDBP_CANCEL_PROTECT_I_C2();
usleep(50000);
update_td_set_BaudRate(115200);
update_state = UP_ERA;
SDBP_UPD_ERASE_I1();
usleep(6000000);
}while(update_state != UP_WRI_A&& again_times < 5);
if(again_times >= 5)
{
goto Fail;
}
if(update_td_enter_update() == 0)
{
goto Fail;
}
again_times = 0;
while(update_state != UP_CMP&& again_times < 5){again_times ++;usleep(500000);}
if(again_times >= 5)
{
goto Fail;
}
update_end();
update_td_set_BaudRate(tdconfig.uartboadrate);
return 0;
Fail:
update_end();
BaudRateChange(B9600);
// update_td_set_BaudRate(tdconfig.uartboadrate);
update_state = UP_FAIL;
return 0;
}
int update_td_handler_return(unsigned char *data)
{
switch(update_state)
{
case UP_VER:
if(SDBP_QUE_VER_O(data, 0) == 1)
{
D("Succeed : SDBP_QUE_VER_O");
SendResultToApp(1);
update_state = UP_CMP;
return UPDATE_SUCCESS;
}
break;
case UP_ENT:break;
case UP_CON:
if(SDBP_UPD_CONFIRM_O(data, 0) == 1)
{
D("Succeed : SDBP_UPD_CONFIRM_O");
update_state = UP_ERA;
}
break;
case UP_ERA:
if(1 == SDBP_PUB_ACK(data,eraseID, 0))
{
D("Succeed : SDBP_PUB_ACK ERASE");
update_state = UP_ERA;
}
else if(1== SDBP_UPD_ERASE_O1(data, 0))
{
D("Succeed : SDBP_UPD_ERASE_O1");
update_state = UP_WRI_A;
}
break;
case UP_WRI_A:
if(1== SDBP_UPD_WRITE_O(data, 0))
{
D("Succeed : SDBP_UPD_WRITE_O");
update_state = UP_WRI_E;
SendResultToApp(2);
}
break;
case UP_IDEL:break;
default:
break;
}
return UPDATE_ING;
}