778 lines
20 KiB
C
778 lines
20 KiB
C
#include "app_config.h"
|
|
#if(USER_UART_UPDATE_ENABLE) && (UART_UPDATE_ROLE == UART_UPDATE_MASTER)
|
|
#include "typedef.h"
|
|
#include "update_loader_download.h"
|
|
#include "os/os_api.h"
|
|
#include "system/task.h"
|
|
#include "update.h"
|
|
#include "gpio.h"
|
|
#include "uart_update.h"
|
|
#include "asm/uart_dev.h"
|
|
#include "asm/clock.h"
|
|
#include "timer.h"
|
|
#include "system/fs/fs.h"
|
|
|
|
static volatile u32 uart_to_cnt = 0;
|
|
static volatile u32 uart_file_offset = 0;
|
|
static volatile u16 rx_cnt; //收数据计数
|
|
|
|
typedef struct _uart_updte_ctl_t {
|
|
OS_SEM sem;
|
|
OS_SEM rx_sem;
|
|
OS_SEM sd_sem;
|
|
volatile u16 timemax;
|
|
volatile u16 timeout;
|
|
volatile u8 flag;
|
|
volatile u8 err_code;
|
|
u8 update_sta;
|
|
u8 update_percent;
|
|
u32 update_total_size;
|
|
u32 update_send_size;
|
|
u8 rx_cmd[0x30];
|
|
u16 cmd_len;
|
|
u16 uart_timer_hdl;
|
|
u32 offset_addr;
|
|
} uart_update_ctl_t;
|
|
|
|
static uart_update_ctl_t uart_update_ctl;
|
|
#define __this (&uart_update_ctl)
|
|
|
|
#define LOG_TAG "[UART_UPDATE]"
|
|
#define LOG_ERROR_ENABLE
|
|
#define LOG_DEBUG_ENABLE
|
|
#define LOG_INFO_ENABLE
|
|
#define LOG_CLI_ENABLE
|
|
#include "debug.h"
|
|
|
|
#define RETRY_TIME 4//重试n次
|
|
#define PACKET_TIMEOUT 200//ms
|
|
|
|
#define FILE_READ_UNIT 512 //
|
|
#define UART_DEFAULT_BAUD 9600
|
|
#define UART_UPDATE_BAUD (50*10000L)
|
|
#define TIME_TICK_UNIT (10) //unit:ms
|
|
//命令
|
|
#define CMD_UPDATE_START 0x01
|
|
#define CMD_UPDATE_READ 0x02
|
|
#define CMD_UPDATE_END 0x03
|
|
#define CMD_SEND_UPDATE_LEN 0x04
|
|
#define CMD_KEEP_ALIVE 0x05
|
|
|
|
#define UART_DEFALT_SEND_DATA_LEN 256
|
|
|
|
|
|
#define READ_LIT_U16(a) (*((u8*)(a)) + (*((u8*)(a)+1)<<8))
|
|
#define READ_LIT_U32(a) (*((u8*)(a)) + (*((u8*)(a)+1)<<8) + (*((u8*)(a)+2)<<16) + (*((u8*)(a)+3)<<24))
|
|
|
|
#define WRITE_LIT_U16(a,src) {*((u8*)(a)+1) = (u8)(src>>8); *((u8*)(a)+0) = (u8)(src&0xff); }
|
|
#define WRITE_LIT_U32(a,src) {*((u8*)(a)+3) = (u8)((src)>>24); *((u8*)(a)+2) = (u8)(((src)>>16)&0xff);*((u8*)(a)+1) = (u8)(((src)>>8)&0xff);*((u8*)(a)+0) = (u8)((src)&0xff);}
|
|
|
|
#define THIS_TASK_NAME "uart_update"
|
|
|
|
|
|
static protocal_frame_t protocal_frame __attribute__((aligned(4)));
|
|
u32 update_baudrate = 9600; //初始波特率
|
|
static uart_update_cfg update_cfg;
|
|
void *fd = NULL;
|
|
|
|
u32 uart_dev_receive_data(void *buf, u32 relen, u32 addr);
|
|
void uart_set_dir(u8 mode);
|
|
void uart_update_write(u8 *data, u32 len);
|
|
void uart_update_set_baud(u32 baudrate);
|
|
void uart_close_deal(void);
|
|
void uart_hw_init(uart_update_cfg update_cfg, void (*cb)(void *, u32));
|
|
void uart_data_decode(u8 *buf, u16 len);
|
|
|
|
/* enum { */
|
|
/* SEEK_SET = 0x0, */
|
|
/* SEEK_CUR = 0x1, */
|
|
/* SEEK_END = 0X2, */
|
|
/* }; */
|
|
|
|
|
|
enum {
|
|
RX_DATA_READY = 0,
|
|
RX_DATA_TIMEOUT,
|
|
RX_DATA_SUCC,
|
|
};
|
|
|
|
void uart_update_set_offset_addr(u32 offset)
|
|
{
|
|
__this->offset_addr = offset;
|
|
}
|
|
|
|
void uart_data_decode(u8 *buf, u16 len)
|
|
{
|
|
u16 crc, crc0, i, ch;
|
|
/* printf("decode_len:%d\n", len); */
|
|
/* put_buf(buf, len); */
|
|
for (i = 0; i < len; i++) {
|
|
ch = buf[i];
|
|
__recheck:
|
|
if (rx_cnt == 0) {
|
|
if (ch == SYNC_MARK0) {
|
|
protocal_frame.raw_data[rx_cnt++] = ch;
|
|
}
|
|
} else if (rx_cnt == 1) {
|
|
protocal_frame.raw_data[rx_cnt++] = ch;
|
|
if (ch != SYNC_MARK1) {
|
|
rx_cnt = 0;
|
|
goto __recheck;
|
|
}
|
|
} else if (rx_cnt < 4) {
|
|
protocal_frame.raw_data[rx_cnt++] = ch;
|
|
} else {
|
|
protocal_frame.raw_data[rx_cnt++] = ch;
|
|
if (rx_cnt == (protocal_frame.data.length + SYNC_SIZE)) {
|
|
rx_cnt = 0;
|
|
extern u16 CRC16(void *ptr, u32 len);
|
|
crc = CRC16(protocal_frame.raw_data, protocal_frame.data.length + SYNC_SIZE - 2);
|
|
memcpy(&crc0, &protocal_frame.raw_data[protocal_frame.data.length + SYNC_SIZE - 2], 2);
|
|
if (crc0 == crc) {
|
|
__this->timemax = 0;
|
|
if (protocal_frame.data.length <= sizeof(__this->rx_cmd)) {
|
|
memcpy(__this->rx_cmd, &(protocal_frame.data.data), protocal_frame.data.length);
|
|
__this->flag = RX_DATA_SUCC;
|
|
os_sem_post(&__this->rx_sem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool uart_send_packet(u8 *buf, u16 length)
|
|
{
|
|
bool ret;
|
|
u16 crc;
|
|
u8 *buffer;
|
|
|
|
buffer = (u8 *)&protocal_frame;
|
|
protocal_frame.data.mark0 = SYNC_MARK0;
|
|
protocal_frame.data.mark1 = SYNC_MARK1;
|
|
protocal_frame.data.length = length;
|
|
memcpy((char *)&buffer[4], buf, length);
|
|
crc = CRC16(buffer, length + SYNC_SIZE - 2);
|
|
memcpy(buffer + 4 + length, &crc, 2);
|
|
uart_set_dir(0);//设为输出
|
|
uart_update_write((u8 *)&protocal_frame, length + SYNC_SIZE);
|
|
uart_set_dir(1);
|
|
return ret;
|
|
}
|
|
|
|
//read file by file operation handle
|
|
u32 ufw_data_read_api(u8 *buff, u32 addr, u32 size)
|
|
{
|
|
//To do...
|
|
if (fd) {
|
|
addr += __this->offset_addr; //多芯片ufw偏移
|
|
fseek(fd, addr, SEEK_SET);
|
|
return fread(fd, buff, size);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//open file and get file operation handle
|
|
bool ufw_file_op_init(char *update_path)
|
|
{
|
|
if (fd) {
|
|
fclose(fd);
|
|
}
|
|
//To do
|
|
fd = fopen(update_path, "r");
|
|
if (!fd) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//close the file and release resource
|
|
void ufw_file_op_close(void)
|
|
{
|
|
if (fd) {
|
|
fclose(fd);
|
|
fd = NULL;
|
|
}
|
|
//To do
|
|
}
|
|
|
|
static u32 update_data_read_from_file(void *p, u32 addr, u32 len)
|
|
{
|
|
u8 *buffer;
|
|
struct file_info *p_file_info;
|
|
u32 read_len = 0;
|
|
|
|
if (len > FILE_READ_UNIT) {
|
|
return (u32) - 1;
|
|
}
|
|
|
|
buffer = malloc(len + sizeof(struct file_info));
|
|
if (buffer) {
|
|
p_file_info = (struct file_info *)buffer;
|
|
p_file_info->cmd = CMD_UART_UPDATE_READ;
|
|
p_file_info->addr = addr;
|
|
p_file_info->len = len;
|
|
read_len = ufw_data_read_api(buffer + sizeof(struct file_info), addr, len);
|
|
} else {
|
|
return (u32) - 2;
|
|
}
|
|
|
|
uart_send_packet(buffer, len + sizeof(struct file_info));
|
|
|
|
if (buffer) {
|
|
free(buffer);
|
|
}
|
|
|
|
return read_len;
|
|
}
|
|
|
|
static u32 update_data_read_and_send(u32 addr, u32 len, u8 wait_ack)
|
|
{
|
|
u8 *buffer;
|
|
struct file_info *p_file_info;
|
|
u32 read_len = 0;
|
|
|
|
if (len > FILE_READ_UNIT) {
|
|
return (u32) - 1;
|
|
}
|
|
|
|
|
|
buffer = malloc(len + sizeof(struct file_info));
|
|
if (buffer) {
|
|
p_file_info = (struct file_info *)buffer;
|
|
p_file_info->cmd = CMD_UART_SEND_DATA;
|
|
p_file_info->addr = addr;
|
|
p_file_info->len = len;
|
|
read_len = ufw_data_read_api(buffer + sizeof(struct file_info), addr, len);
|
|
} else {
|
|
return (u32) - 2;
|
|
}
|
|
|
|
uart_send_packet(buffer, len + sizeof(struct file_info));
|
|
|
|
if (buffer) {
|
|
free(buffer);
|
|
}
|
|
|
|
return read_len;
|
|
}
|
|
|
|
enum {
|
|
UPDATE_STA_NONE = 0,
|
|
UPDATE_STA_READY,
|
|
UPDATE_STA_START,
|
|
UPDATE_STA_TIMEOUT,
|
|
UPDATE_STA_LOADER_DOWNLOAD_FINISH,
|
|
UPDATE_STA_SUCC,
|
|
UPDATE_STA_FAIL,
|
|
};
|
|
|
|
enum {
|
|
UPDATE_ERR_NONE = 0,
|
|
UPDATE_ERR_KEY,
|
|
UPDATE_ERR_VERIFY,
|
|
|
|
UPDATE_ERR_LOADER_DOWNLOAD_SUCC = 0x80,
|
|
};
|
|
|
|
static void uart_update_err_code_handle(u8 code)
|
|
{
|
|
if (code) {
|
|
if (UPDATE_ERR_LOADER_DOWNLOAD_SUCC == code) {
|
|
__this->update_percent = 100;
|
|
__this->update_send_size = 0;
|
|
__this->update_total_size = 0;
|
|
__this->update_sta = UPDATE_STA_LOADER_DOWNLOAD_FINISH;
|
|
log_info("loader dn succ\n");
|
|
} else {
|
|
__this->update_sta = UPDATE_STA_FAIL;
|
|
log_error("update_err:%x\n", code);
|
|
}
|
|
} else {
|
|
__this->update_percent = 100;
|
|
__this->update_sta = UPDATE_STA_SUCC;
|
|
log_info("update all succ\n");
|
|
}
|
|
}
|
|
|
|
|
|
static int uart_update_wait_rev_data(timeout)
|
|
{
|
|
u32 err;
|
|
__this->flag = RX_DATA_READY;
|
|
__this->timeout = 0;
|
|
__this->timemax = (timeout + 1) / TIME_TICK_UNIT;
|
|
|
|
err = os_sem_pend(&__this->rx_sem, 2000);
|
|
|
|
if (OS_NO_ERR != err) {
|
|
log_info("wait tm out\n");
|
|
}
|
|
|
|
__this->timemax = __this->timeout = 0;
|
|
|
|
if (__this->flag == RX_DATA_SUCC) {
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int uart_update_api_write_then_read(u8 *buf, u8 length, u8 timeout)
|
|
{
|
|
int ret = FALSE;
|
|
|
|
uart_send_packet(buf, length);
|
|
if (timeout) {
|
|
ret = uart_update_wait_rev_data(timeout);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool uart_update_send_update_ready(char *file_update_path)
|
|
{
|
|
u8 ut_cmd[1];
|
|
ut_cmd[0] = CMD_UART_UPDATE_READY;
|
|
|
|
if (ufw_file_op_init(file_update_path)) {
|
|
__this->update_sta = UPDATE_STA_READY;
|
|
uart_send_packet(ut_cmd, sizeof(ut_cmd));
|
|
log_info("uart_update_send_update_ready\n");
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool get_uart_update_sta(void)
|
|
{
|
|
return (__this->update_sta == UPDATE_STA_READY || __this->update_sta == UPDATE_STA_START) ? TRUE : FALSE;
|
|
}
|
|
|
|
static void update_process_run(void)
|
|
{
|
|
update_baudrate = UART_DEFAULT_BAUD;
|
|
uart_update_set_baud(update_baudrate);
|
|
|
|
__this->update_total_size = 0;
|
|
__this->update_percent = 0;
|
|
__this->update_send_size = 0;
|
|
__this->offset_addr = 0; //多芯片升级ufw偏移
|
|
|
|
u8 *pbuf = &__this->rx_cmd;
|
|
while (1) {
|
|
if (OS_NO_ERR != os_sem_pend(&__this->rx_sem, 800)) {
|
|
log_info("uart_timeout\n");
|
|
__this->update_sta = UPDATE_STA_TIMEOUT;
|
|
update_baudrate = 9600;
|
|
uart_update_set_baud(update_baudrate);
|
|
continue;
|
|
}
|
|
|
|
//os_time_dly(1);
|
|
|
|
switch (pbuf[0]) {
|
|
case CMD_UPDATE_START:
|
|
log_info("CMD_UPDATE_START\n");
|
|
__this->update_sta = UPDATE_STA_START;
|
|
update_baudrate = UART_UPDATE_BAUD;
|
|
WRITE_LIT_U32(pbuf + 1, update_baudrate);
|
|
uart_send_packet(pbuf, 1 + sizeof(u32));
|
|
log_info("use baud:%x\n", update_baudrate);
|
|
uart_update_set_baud(update_baudrate);
|
|
break;
|
|
|
|
case CMD_UPDATE_READ: {
|
|
u32 addr = READ_LIT_U32(&pbuf[1]);
|
|
u32 len = READ_LIT_U32(&pbuf[1 + sizeof(u32)]);
|
|
if (__this->update_total_size) {
|
|
__this->update_send_size += len;
|
|
__this->update_percent = (__this->update_send_size * 100) / __this->update_total_size;
|
|
if (__this->update_percent >= 99) {
|
|
__this->update_percent = 99;
|
|
}
|
|
log_info("send data process:%x\n", __this->update_percent);
|
|
}
|
|
log_info("CMD_UPDATE_READ\n");
|
|
update_data_read_from_file(NULL, addr, len);
|
|
}
|
|
break;
|
|
|
|
case CMD_UPDATE_END:
|
|
log_info("CMD_UPDATE_END\n");
|
|
uart_update_err_code_handle(pbuf[1]);
|
|
uart_send_packet(pbuf, 1);
|
|
break;
|
|
|
|
case CMD_SEND_UPDATE_LEN:
|
|
__this->update_total_size = READ_LIT_U32(&pbuf[1]);
|
|
__this->update_percent = 0;
|
|
__this->update_send_size = 0;
|
|
log_info("update_total_size:%x\n", __this->update_total_size);
|
|
uart_send_packet(pbuf, 1);
|
|
break;
|
|
|
|
case CMD_KEEP_ALIVE:
|
|
uart_send_packet(pbuf, 1);
|
|
break;
|
|
|
|
case CMD_UART_ACK:
|
|
log_info("CMD_UART_ACK -> CMD_UART_SEND_DATA\n");
|
|
os_sem_post(&__this->sd_sem);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void uart_timeout_handler(void *priv)
|
|
{
|
|
if (__this->timemax) {
|
|
__this->timeout++;
|
|
if (__this->timeout > __this->timemax) {
|
|
__this->timemax = 0;
|
|
__this->flag = RX_DATA_TIMEOUT;
|
|
os_sem_post(&__this->rx_sem);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void update_loader_download_task(void *p)
|
|
{
|
|
log_info("create %s task\n", THIS_TASK_NAME);
|
|
os_sem_create(&__this->sem, 0);
|
|
os_sem_create(&__this->rx_sem, 0);
|
|
os_sem_create(&__this->sd_sem, 0);
|
|
|
|
|
|
while (1) {
|
|
update_process_run();
|
|
}
|
|
}
|
|
|
|
void uart_update_init(uart_update_cfg *cfg)
|
|
{
|
|
memcpy(&update_cfg, cfg, sizeof(uart_update_cfg));
|
|
task_create(update_loader_download_task, NULL, THIS_TASK_NAME);
|
|
uart_hw_init(update_cfg, uart_data_decode);
|
|
|
|
}
|
|
|
|
void uart_update_exit(void)
|
|
{
|
|
log_info("uart update exit\n");
|
|
|
|
if (__this->uart_timer_hdl) {
|
|
sys_timer_del(__this->uart_timer_hdl);
|
|
}
|
|
|
|
os_sem_del(&__this->sem, 0);
|
|
os_sem_del(&__this->rx_sem, 0);
|
|
|
|
ufw_file_op_close();
|
|
|
|
uart_close_deal();
|
|
|
|
task_kill(THIS_TASK_NAME);
|
|
}
|
|
|
|
static void clock_critical_enter(void)
|
|
{
|
|
|
|
}
|
|
|
|
static void clock_critical_exit(void)
|
|
{
|
|
uart_update_set_baud(update_baudrate);
|
|
}
|
|
CLOCK_CRITICAL_HANDLE_REG(uart_update, clock_critical_enter, clock_critical_exit)
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
#if MUTIL_CPU_UART_UPDATE_ENABLE
|
|
|
|
#include "app_config.h"
|
|
#include "typedef.h"
|
|
#include "update_loader_download.h"
|
|
#include "os/os_api.h"
|
|
#include "system/task.h"
|
|
#include "update.h"
|
|
#include "gpio.h"
|
|
#include "uart_update.h"
|
|
#include "asm/uart_dev.h"
|
|
#include "system/fs/fs.h"
|
|
#include "avctp_user.h"
|
|
|
|
#define UART_UPDATE_DATA_LEN 256
|
|
static uart_bus_t *uart_update_hdl = NULL;
|
|
static u8 uart_update_cbuf[UART_UPDATE_DATA_LEN * 2] __attribute__((aligned(4)));
|
|
#define UART_UPDATE_TX_PORT IO_PORTA_03
|
|
#define UART_UPDATE_RX_PORT IO_PORTA_03
|
|
#define UART_UPDATE_BAUDRATE 500 * 1000 //115200
|
|
static protocal_frame_t protocal_frame __attribute__((aligned(4)));
|
|
static u32 send_len = 0;
|
|
static OS_MUTEX uart_mutex;
|
|
static u32 ot_time = 100;
|
|
static update_op_api_t *uart_op = NULL;
|
|
static u8 uart_init_flag = 1;
|
|
|
|
static u8 uart_init()
|
|
{
|
|
u8 ret = 0;
|
|
struct uart_platform_data_t u_arg = {0};
|
|
u_arg.tx_pin = UART_UPDATE_TX_PORT;
|
|
u_arg.rx_pin = UART_UPDATE_RX_PORT;
|
|
u_arg.rx_cbuf = uart_update_cbuf;
|
|
u_arg.rx_cbuf_size = UART_UPDATE_DATA_LEN * 2;
|
|
u_arg.frame_length = UART_UPDATE_DATA_LEN * 2;
|
|
u_arg.rx_timeout = 5;
|
|
/* u_arg.isr_cbfun = uart_isr_hook; */
|
|
u_arg.baud = UART_UPDATE_BAUDRATE;
|
|
u_arg.is_9bit = 0;
|
|
|
|
|
|
r_printf("uart_dev_open() ...\n");
|
|
uart_update_hdl = uart_dev_open(&u_arg);
|
|
if (uart_update_hdl != NULL) {
|
|
r_printf("success\n");
|
|
ret = 0;
|
|
} else {
|
|
ret = 1;
|
|
r_printf("false\n");
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
static u8 uart_update_packet_data(u8 cmd, u8 *buf, u32 addr, u16 len)
|
|
{
|
|
u8 ret = 0;
|
|
u16 crc;
|
|
u8 *buffer;
|
|
u8 *data_buffer;
|
|
u16 length = len;
|
|
|
|
struct file_info *p_file_info;
|
|
data_buffer = malloc(len + sizeof(struct file_info));
|
|
if (data_buffer) {
|
|
switch (cmd) {
|
|
case CMD_UART_SEND_DATA:
|
|
p_file_info = (struct file_info *)data_buffer;
|
|
p_file_info->cmd = cmd;
|
|
p_file_info->addr = addr;
|
|
p_file_info->len = len;
|
|
memcpy(data_buffer + sizeof(struct file_info), buf, len);
|
|
length = len + sizeof(struct file_info);
|
|
break;
|
|
case CMD_UART_UPDATE_END:
|
|
default:
|
|
memcpy(data_buffer, buf, len);
|
|
length = len;
|
|
break;
|
|
}
|
|
} else {
|
|
ret = 1;
|
|
goto __exit;
|
|
}
|
|
|
|
|
|
buffer = (u8 *)&protocal_frame;
|
|
memset(buffer, 0, sizeof(protocal_frame_t));
|
|
protocal_frame.data.mark0 = SYNC_MARK0;
|
|
protocal_frame.data.mark1 = SYNC_MARK1;
|
|
protocal_frame.data.length = length;
|
|
memcpy((char *)&buffer[4], data_buffer, length);
|
|
crc = CRC16(buffer, length + SYNC_SIZE - 2);
|
|
memcpy(buffer + 4 + length, &crc, 2);
|
|
|
|
send_len = length + SYNC_SIZE;
|
|
|
|
__exit:
|
|
if (data_buffer) {
|
|
free(data_buffer);
|
|
data_buffer = NULL;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static u8 uart_update_check_ack(u8 cmd, u8 *buf, u32 rx_len)
|
|
{
|
|
u16 crc, crc0, i, ch;
|
|
u32 ut_rx_cnt = 0;
|
|
u8 ret = 0xff;
|
|
/* printf("decode_len:%d\n", rx_len); */
|
|
/* put_buf(buf, rx_len); */
|
|
for (i = 0; i < rx_len; i++) {
|
|
ch = buf[i];
|
|
__recheck:
|
|
if (ut_rx_cnt == 0) {
|
|
if (ch == SYNC_MARK0) {
|
|
protocal_frame.raw_data[ut_rx_cnt++] = ch;
|
|
}
|
|
} else if (ut_rx_cnt == 1) {
|
|
protocal_frame.raw_data[ut_rx_cnt++] = ch;
|
|
if (ch != SYNC_MARK1) {
|
|
ut_rx_cnt = 0;
|
|
goto __recheck;
|
|
}
|
|
} else if (ut_rx_cnt < 4) {
|
|
protocal_frame.raw_data[ut_rx_cnt++] = ch;
|
|
} else {
|
|
protocal_frame.raw_data[ut_rx_cnt++] = ch;
|
|
if (ut_rx_cnt == (protocal_frame.data.length + SYNC_SIZE)) {
|
|
ut_rx_cnt = 0;
|
|
crc = CRC16(protocal_frame.raw_data, protocal_frame.data.length + SYNC_SIZE - 2);
|
|
memcpy(&crc0, &protocal_frame.raw_data[protocal_frame.data.length + SYNC_SIZE - 2], 2);
|
|
if (crc0 == crc) {
|
|
u8 *buffer = (u8 *)&protocal_frame;
|
|
if (buffer[4] == cmd) {
|
|
ret = buffer[5];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static u32 uart_update_read(u8 *rx_buf, u32 total_len)
|
|
{
|
|
u32 start_time = timer_get_ms();
|
|
u32 rlen = total_len;
|
|
u32 rx_len = 0;
|
|
while (1) {
|
|
rlen = uart_update_hdl->read(rx_buf, rlen, ot_time);
|
|
rx_len += rlen;
|
|
if (rx_len == total_len || rx_len >= 9) {
|
|
break;
|
|
} else {
|
|
rx_buf += rlen;
|
|
rlen = total_len - rx_len;
|
|
}
|
|
if ((timer_get_ms() - start_time) >= ot_time) {
|
|
break;
|
|
}
|
|
}
|
|
return rx_len;
|
|
}
|
|
|
|
u8 uart_update_tx_packet(u8 cmd, void *data, u32 addr, u16 len, u8 wait_ack)
|
|
{
|
|
u8 ret = 0;
|
|
os_mutex_pend(&uart_mutex, 0);
|
|
ret = uart_update_packet_data(cmd, data, addr, len);
|
|
if (ret) {
|
|
y_printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__);
|
|
return 1;
|
|
}
|
|
putchar('W');
|
|
uart_update_hdl->write((u8 *)&protocal_frame, send_len);
|
|
/* printf(">>>[test]:len = %d\n", send_len); */
|
|
/* put_buf((u8 *)&protocal_frame, send_len); */
|
|
if (wait_ack) {
|
|
u8 *rx_buf = malloc(UART_UPDATE_DATA_LEN);
|
|
ASSERT(rx_buf);
|
|
u32 rx_len = uart_update_read(rx_buf, UART_UPDATE_DATA_LEN);
|
|
ret = uart_update_check_ack(cmd, rx_buf, rx_len);
|
|
if (rx_buf) {
|
|
free(rx_buf);
|
|
rx_buf = NULL;
|
|
}
|
|
}
|
|
/* y_printf(">>>[test]:ret = %d\n", ret); */
|
|
os_mutex_post(&uart_mutex);
|
|
return ret;
|
|
}
|
|
|
|
u8 uart_update_init_uart_type()
|
|
{
|
|
u8 ret = 0;
|
|
if (uart_init_flag) {
|
|
os_mutex_create(&uart_mutex);
|
|
ret = uart_init();
|
|
uart_init_flag = 0;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void uart_update_change_ot_time(u32 new_time)
|
|
{
|
|
ot_time = new_time;
|
|
}
|
|
|
|
|
|
int uart_update_send_data(void *op_hdl, void *info)
|
|
{
|
|
/* clk_set("sys", 96000000); */
|
|
if (!info || !op_hdl) {
|
|
y_printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__);
|
|
return -1;
|
|
}
|
|
|
|
uart_op = (update_op_api_t *)op_hdl;
|
|
int ret = 0;
|
|
mutil_ufw_info *p = (mutil_ufw_info *)info;
|
|
|
|
ot_time = (p->ufw_len + 64 * 1024 - 1) / (64 * 1024) * 500; //AD100那边每64K需要等待时间是300ms。
|
|
ot_time += 500;
|
|
y_printf(">>>[test]:ot_time = %dms, p->ufw_len = %d\n", ot_time, p->ufw_len);
|
|
|
|
u32 send_addr = 0;//p->ufw_addr;
|
|
u32 send_len = UART_UPDATE_DATA_LEN;
|
|
|
|
u8 *send_buf = malloc(UART_UPDATE_DATA_LEN);
|
|
uart_op->f_seek(NULL, SEEK_SET, send_addr);
|
|
uart_op->f_read(NULL, send_buf, send_len);
|
|
ret = uart_update_tx_packet(CMD_UART_SEND_DATA, send_buf, send_addr, send_len, 1); //先发一包数据
|
|
if (ret) {
|
|
y_printf("\n >>>[test]:func = %s,line= %d\n", __FUNCTION__, __LINE__);
|
|
goto __exit;
|
|
}
|
|
|
|
#if (LED_LYRICS_ENABLE && TCFG_LRC_LYRICS_ENABLE)
|
|
user_send_cmd_prepare(USER_CTRL_DISCONNECTION_HCI, 0, NULL);
|
|
#endif
|
|
|
|
ot_time = 50; //第一次交互之后都比较快
|
|
send_addr += send_len;
|
|
while (1) {
|
|
putchar('a');
|
|
if ((send_addr + send_len) > p->ufw_len) {
|
|
send_len = p->ufw_len - send_addr;
|
|
}
|
|
|
|
uart_op->f_seek(NULL, SEEK_SET, send_addr);
|
|
uart_op->f_read(NULL, send_buf, send_len);
|
|
ret = uart_update_tx_packet(CMD_UART_SEND_DATA, send_buf, send_addr, send_len, 1);
|
|
if (ret) {
|
|
goto __exit;
|
|
}
|
|
send_addr += send_len;
|
|
if (send_addr == p->ufw_len) {
|
|
ret = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
__exit:
|
|
if (send_buf) {
|
|
free(send_buf);
|
|
send_buf = NULL;
|
|
}
|
|
u8 end_buf[2];
|
|
end_buf[0] = CMD_UART_UPDATE_END;
|
|
end_buf[1] = ret;
|
|
ot_time = (p->ufw_len + 64 * 1024 - 1) / (64 * 1024) * 500; //AD100那边每64K需要等待时间是300ms。
|
|
ret = uart_update_tx_packet(CMD_UART_UPDATE_END, end_buf, 0, 2, 1);
|
|
y_printf(">>>[test]:update over ret = %d\n", ret);
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|