Files
kunlun/driver/extern/virtualchannel/vc_upgrade/vc_upgrade.c
2024-09-28 14:24:04 +08:00

951 lines
26 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.

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
//common
#include "os_types.h"
#include "iot_errno_api.h"
#include "iot_ringbuf_api.h"
#include "iot_gpio_api.h"
#include "os_mem_api.h"
#include "iot_board_api.h"
#include "iot_io_api.h"
#include "os_utils_api.h"
#include "os_timer_api.h"
#include "iot_img_hdr.h"
#include "iot_ntoh_api.h"
#include "iot_oem.h"
#include "iot_board.h"
#include "vc_task.h"
#include "vc_upgrade.h"
#include "vc_upgrade_driver.h"
/* define ring buffer size, unit is byte */
#define VC_UPGRADE_RING_BUF_SIZE (256 + 32)
/* define stm32 upgrade file min size, unit is byte */
#define VC_UPGRADE_STM32_FILE_SIZE_MIN 10
/* define the waiting time for serial port reception, unit is ms */
#define VC_UPGARDE_CMD_WAIT_TIME 500
/* define monitor timer period, unit is ms */
#define VC_UPGRADE_TIMER_PERIOD 100
/* define stm32 upgrade fw header buffer size. */
#define VC_UPGRADE_FW_HEAD_BUFFER_SIZE 256
/* define send data is the fw data. */
#define VC_UPGRADE_FW_DATA 0
/* define send data is the fw data header. */
#define VC_UPGRADE_FW_DATA_HEADER 1
#define VC_UPGRADE_FW_DEV_TYPE 0xdc03
#define VC_UPGRADE_FW_GUARD 0xa4e49a17
typedef struct _vc_upgrade_t {
/* init flag, 1 mean succeed */
uint8_t init_flag;
/* stm32 boot0 gpio */
uint8_t gpio_boot0;
/* stm32 reset gpio */
uint8_t gpio_reset;
/* ring buf, save uart data */
ringbuf_t ring_buf;
/* stm32 handle */
stm32_t *stm32;
/* upgrade file addr */
uint8_t *file_addr;
/* upgrade file size */
uint32_t file_size;
/* upgrade status */
vc_upgrd_state_e status;
/* percentage of data sent */
uint32_t percentage;
/* write buffer */
uint8_t *buffer_w;
/* read buffer */
uint8_t *buffer_r;
/* write data lenght */
uint32_t len_transf;
/* current addr of the stm32 to write */
uint32_t addr_curr;
/* header addr of the stm32 to write */
uint32_t addr_headr;
/* data offset of upd file */
uint32_t offset_curr;
/* header offset of upd file */
uint32_t offset_header;
/* send the completion flag, 1 -> completion */
uint8_t flag_transf_over;
} vc_upgrade_t;
#if INCLUDE_VIRTUAL_CHANNEL
vc_upgrade_t *g_upgrade = NULL;
static const uint8_t stm32_bin[] = {
#include "stm32_bin.txt"
};
static stm32_err_t vc_upgrade_buffer_compare(uint8_t *buf_w,
uint8_t *buf_r, uint32_t len)
{
if (buf_w == NULL || buf_r == NULL || len == 0) {
return STM32_ERR_UNKNOWN;
}
for(uint32_t i = 0; i < len; i++) {
if (buf_w[i] != buf_r[i]) {
stm32_dbg_printf("Failed to verify at address 0x%08x, "
"expected 0x%02x and found 0x%02x\n", g_upgrade->addr_curr + i,
buf_w[i], buf_r[i]);
return STM32_ERR_UNKNOWN;
}
}
return STM32_ERR_OK;
}
static stm32_err_t vc_upgrade_stm32_file_transfer_once(uint8_t type)
{
uint32_t max_wlen = STM32_MAX_TX_PAYLOAD_LENGTH;
uint32_t *addr_temp = NULL, *offset = NULL;
uint32_t len = 0;
uint32_t addr_end = 0x0;
uint32_t file_size;
uint8_t *buffer = NULL;
stm32_t *stm32 = NULL;
stm32_err_t err = STM32_ERR_UNKNOWN;
uint32_t left = 0;
uint32_t reason = 0;
(void)reason;
(void)left; //eliminate compile errors
if (!g_upgrade || !g_upgrade->init_flag || !g_upgrade->stm32->is_connect) {
reason = 1;
goto out;
}
stm32 = g_upgrade->stm32;
addr_end = g_upgrade->stm32->dev->fl_end;
file_size = g_upgrade->file_size;
buffer = g_upgrade->buffer_w;
if (VC_UPGRADE_FW_DATA_HEADER == type) {
addr_temp = &g_upgrade->addr_headr;
offset = &g_upgrade->offset_header;
} else {
addr_temp = &g_upgrade->addr_curr;
offset = &g_upgrade->offset_curr;
}
if (*addr_temp >= addr_end || *offset >= file_size) {
*addr_temp = 0;
*offset = 0;
g_upgrade->flag_transf_over = 1;
reason = 2;
goto out;
}
left = addr_end - *addr_temp;
len = max_wlen > left ? left : max_wlen;
len = len > file_size - *offset ? file_size - *offset : len;
if (VC_UPGRADE_FW_DATA_HEADER == type) {
len = HEADER_TOLTAL_SIZE;
}
stm32_dbg_printf("addr:0x%08x, offset:%d, len:%d\n",*addr_temp, *offset, len);
os_mem_cpy(buffer, &g_upgrade->file_addr[*offset], len);
err = stm32_send_write_data(stm32, buffer, len);
if (err != STM32_ERR_OK) {
g_upgrade->status = VC_UPGRD_STATE_ERR;
reason = 3;
goto out;
}
g_upgrade->len_transf = len;
if (VC_UPGRADE_FW_DATA == type) {
*addr_temp += len;
*offset += len;
g_upgrade->percentage = 100 * (*offset) / file_size;
/* prevent additional write cmd from being executed once after burning */
if (g_upgrade->percentage == 100) {
g_upgrade->flag_transf_over = 1;
}
}
out:
stm32_dbg_printf("result:%d, reason:%d \n", err, reason);
return err;
}
static uint32_t vc_upgrade_status_handle(uint8_t state)
{
uint32_t result = ERR_OK;
int32_t reason = 0;
uint32_t spage = 0;
uint32_t pages = 0;
(void)reason; //eliminate compile errors
if (state >= UPGRADE_STATE_MAX) {
reason = -1;
result = ERR_FAIL;
goto out;
}
reason = state;
switch (state) {
case UPGRADE_SEND_INIT:
result = stm32_send_get_version_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_GET_VERSION;
break;
case UPGRADE_SEND_GET_VERSION:
result = stm32_send_get_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_GET;
break;
case UPGRADE_SEND_GET:
result = stm32_send_get_id_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_GET_ID;
break;
case UPGRADE_SEND_GET_ID:
result = stm32_send_erase_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_ERASE;
g_upgrade->status = VC_UPGRD_STATE_CLEAR_STORAGE_HEADER;
break;
case UPGRADE_SEND_ERASE_DATA:
result = stm32_send_erase_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_ERASE;
g_upgrade->status = VC_UPGRD_STATE_CLEAR_STORAGE;
break;
case UPGRADE_SEND_ERASE:
if (VC_UPGRD_STATE_CLEAR_STORAGE_HEADER == g_upgrade->status) {
spage = (g_upgrade->stm32->dev->fl_end - g_upgrade->stm32->dev->fl_start)
/ g_upgrade->stm32->dev->fl_ps[0] - 1;
pages = 1;
result = stm32_send_erase_page_info(g_upgrade->stm32, spage, pages);
g_upgrade->stm32->state = UPGRADE_SEND_ERASE_DATA;
} else {
//now, we'll just erase from the first page
spage = 0;
pages = flash_addr_to_page_ceil(g_upgrade->stm32,
g_upgrade->stm32->dev->fl_start + g_upgrade->file_size) - spage;
result = stm32_send_erase_page_info(g_upgrade->stm32, spage, pages);
g_upgrade->stm32->state = UPGRADE_SEND_ERASE_PAGE_INFO;
}
break;
case UPGRADE_SEND_ERASE_PAGE_INFO:
result = stm32_send_write_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_WRITE;
g_upgrade->status = VC_UPGRD_STATE_WRITE_HEADER;
break;
case UPGRADE_SEND_WRITE:
if (VC_UPGRD_STATE_WRITE_HEADER == g_upgrade->status) {
result = stm32_send_write_addr(g_upgrade->stm32, g_upgrade->addr_headr);
} else {
result = stm32_send_write_addr(g_upgrade->stm32, g_upgrade->addr_curr);
}
g_upgrade->stm32->state = UPGRADE_SEND_WRITE_ADDR;
break;
case UPGRADE_SEND_WRITE_ADDR:
if (VC_UPGRD_STATE_WRITE_HEADER == g_upgrade->status) {
result = vc_upgrade_stm32_file_transfer_once(VC_UPGRADE_FW_DATA_HEADER);
} else {
result = vc_upgrade_stm32_file_transfer_once(VC_UPGRADE_FW_DATA);
}
g_upgrade->stm32->state = UPGRADE_SEND_WRITE_DATA;
break;
case UPGRADE_SEND_WRITE_DATA:
result = stm32_send_read_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_READ;
break;
case UPGRADE_SEND_READ:
if (VC_UPGRD_STATE_WRITE_HEADER == g_upgrade->status) {
result = stm32_send_read_addr(g_upgrade->stm32, g_upgrade->addr_headr);
} else {
result = stm32_send_read_addr(g_upgrade->stm32,
g_upgrade->addr_curr - g_upgrade->len_transf);
}
g_upgrade->stm32->state = UPGRADE_SEND_READ_ADDR;
break;
case UPGRADE_SEND_READ_ADDR:
result = stm32_send_read_length(g_upgrade->stm32, g_upgrade->len_transf);
g_upgrade->stm32->state = UPGRADE_SEND_READ_LENGTH;
break;
case UPGRADE_SEND_READ_LENGTH:
result = stm32_send_read_rdata(g_upgrade->stm32,
g_upgrade->buffer_r, g_upgrade->len_transf);
result |= vc_upgrade_buffer_compare(g_upgrade->buffer_w,
g_upgrade->buffer_r, g_upgrade->len_transf);
if (g_upgrade->flag_transf_over != 1) {
result = stm32_send_write_cmd(g_upgrade->stm32);
g_upgrade->stm32->state = UPGRADE_SEND_WRITE;
if (result == ERR_OK) {
g_upgrade->status = VC_UPGRD_STATE_WRITE_DATA;
}
} else {
g_upgrade->status = VC_UPGRD_STATE_ENDUP;
}
break;
default:
result = STM32_ERR_UNKNOWN;
break;
}
out:
stm32_dbg_printf("result:%d, reason:%d \n", result, reason);
return result;
}
static uint32_t vc_upgrade_status_refresh(uint8_t state, uint32_t len)
{
uint32_t needed_len = 0;
uint32_t result = ERR_OK;
int32_t reason = 0;
(void)reason; //eliminate compile errors
if (state >= UPGRADE_STATE_MAX) {
reason = -1;
result = ERR_FAIL;
goto out;
}
if (g_upgrade->status == VC_UPGRD_STATE_ERR) {
reason = -2;
result = ERR_FAIL;
goto out;
}
reason = state;
switch (state) {
case UPGRADE_SEND_INIT:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_send_init_handle(g_upgrade->stm32);
break;
case UPGRADE_SEND_GET_VERSION:
needed_len = 5;
if (len < needed_len) {
break;
}
result = stm32_send_get_version_handle(g_upgrade->stm32);
break;
case UPGRADE_SEND_GET:
needed_len = 15;
if (len < needed_len) {
break;
}
result = stm32_send_get_handle(g_upgrade->stm32);
break;
case UPGRADE_SEND_GET_ID:
needed_len = 5;
if (len < needed_len) {
break;
}
result = stm32_send_get_id_handle(g_upgrade->stm32);
g_upgrade->addr_curr = g_upgrade->stm32->dev->fl_start;
g_upgrade->addr_headr = g_upgrade->stm32->dev->fl_end -
VC_UPGRADE_FW_HEAD_BUFFER_SIZE;
break;
case UPGRADE_SEND_ERASE:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_ERASE_DATA:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_ERASE_PAGE_INFO:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_WRITE:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_WRITE_ADDR:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_WRITE_DATA:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_READ:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_READ_ADDR:
needed_len = 1;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
case UPGRADE_SEND_READ_LENGTH:
needed_len = 1 + g_upgrade->len_transf;
if (len < needed_len) {
break;
}
result = stm32_get_ack(g_upgrade->stm32);
break;
default:
result = STM32_ERR_UNKNOWN;
break;
}
if (len < needed_len) {
goto out;
}
if (result != STM32_ERR_OK) {
g_upgrade->status = VC_UPGRD_STATE_ERR;
stm32_dbg_printf("result:%d, reason:%d \n", result, reason);
goto out;
}
//Go to the next step
result = vc_upgrade_status_handle(state);
if (result != STM32_ERR_OK) {
g_upgrade->status = VC_UPGRD_STATE_ERR;
goto out;
}
out:
return result;
}
uint32_t vc_upgrd_receive_func(uint8_t *p_buf, uint32_t len)
{
IOT_ASSERT(p_buf);
if (len == 0 || g_upgrade == NULL) {
return ERR_FAIL;
}
#if 0
iot_printf("uart rec len:%d, data:");
for (uint32_t i = 0; i < len; i++) {
iot_printf("%02X ", p_buf[i]);
}
iot_printf("\n");
#endif
uint32_t free_size = iot_ringbuf_size(&g_upgrade->ring_buf)
- iot_ringbuf_elements(&g_upgrade->ring_buf);
if (free_size < len) {
return ERR_FAIL;
}
(void)iot_ringbuf_puts(&g_upgrade->ring_buf, p_buf, len);
(void)vc_upgrade_status_refresh(g_upgrade->stm32->state,
iot_ringbuf_elements(&g_upgrade->ring_buf));
return ERR_OK;
}
uint32_t vc_upgrade_pull_data_from_ringbuf(uint8_t *buf, uint32_t len)
{
uint32_t result = ERR_OK;
uint32_t len_readed = 0;
uint32_t temp = 0;
IOT_ASSERT(buf);
if (!g_upgrade || len == 0) {
result = ERR_FAIL;
goto out;
}
while(len_readed < len) {
temp = iot_ringbuf_gets(&g_upgrade->ring_buf, buf, len - len_readed);
len_readed += temp;
}
out:
return result;
}
void vc_upgrade_state_moniter(uint32_t counter)
{
static uint8_t state_old = UPGRADE_STATE_MAX;
static uint32_t run_time = 0; //ms
if (state_old != g_upgrade->stm32->state) {
state_old = g_upgrade->stm32->state;
run_time = 0;
return;
}
/* gets the command execution time,
the maximum change is the interval between calls to this function */
run_time += counter;
if (state_old == UPGRADE_SEND_WRITE_DATA
|| state_old == UPGRADE_SEND_READ_LENGTH) {
if (run_time > VC_UPGARDE_CMD_WAIT_TIME * 10) {
g_upgrade->status = VC_UPGRD_STATE_ERR;
}
} else {
if (run_time > VC_UPGARDE_CMD_WAIT_TIME) {
g_upgrade->status = VC_UPGRD_STATE_ERR;
}
}
stm32_dbg_printf("state:%d, percentage:%d\n",
g_upgrade->status, g_upgrade->percentage);
return;
}
uint32_t vc_upgrade_module_init(void)
{
uint8_t reason = 0;
uint8_t *ptr_ring = NULL;
uint32_t result = ERR_FAIL;
uint8_t rst_reason = 0;
g_upgrade = (vc_upgrade_t *)os_mem_malloc(IOT_DRIVER_MID, sizeof(vc_upgrade_t));
if (g_upgrade == NULL) {
reason = 1;
goto out;
}
os_mem_set(g_upgrade, 0x0, sizeof(vc_upgrade_t));
g_upgrade->status = VC_UPGRD_STATE_IDLE;
//gpio init
g_upgrade->gpio_boot0 = iot_board_get_gpio(GPIO_VC_EXT_CHIP_BOOT);
g_upgrade->gpio_reset = iot_board_get_gpio(GPIO_VC_EXT_CHIP_RST);
if (g_upgrade->gpio_boot0 == GPIO_NO_VALID
|| g_upgrade->gpio_reset == GPIO_NO_VALID) {
reason = 2;
goto free_upgrade;
}
if (iot_gpio_open_as_output(g_upgrade->gpio_boot0) != ERR_OK) {
reason = 3;
goto free_upgrade;
}
if (iot_gpio_open_as_output(g_upgrade->gpio_reset) != ERR_OK) {
(void)iot_gpio_close(g_upgrade->gpio_boot0);
reason = 4;
goto free_upgrade;
}
stm32_dbg_printf("GPIO_VC_EXT_CHIP_BOOT:%d, GPIO_VC_EXT_CHIP_RST:%d \n",
g_upgrade->gpio_boot0, g_upgrade->gpio_reset);
iot_gpio_set_pull_mode(g_upgrade->gpio_boot0, GPIO_PULL_DOWN);
iot_gpio_set_pull_mode(g_upgrade->gpio_reset, GPIO_PULL_UP);
//ring buffer init
ptr_ring = (uint8_t *)os_mem_malloc(IOT_DRIVER_MID, VC_UPGRADE_RING_BUF_SIZE);
if (ptr_ring == NULL) {
reason = 5;
goto close_gpio;
}
os_mem_set(ptr_ring, 0x0, VC_UPGRADE_RING_BUF_SIZE);
iot_ringbuf_init(&g_upgrade->ring_buf, ptr_ring, VC_UPGRADE_RING_BUF_SIZE);
//stm32 handle init
g_upgrade->stm32 = (stm32_t*)os_mem_malloc(IOT_DRIVER_MID, sizeof(stm32_t));
if (g_upgrade->stm32 == NULL) {
reason = 6;
goto free_ringbuf;
}
g_upgrade->stm32->cmd = (stm32_cmd_t *)os_mem_malloc(IOT_DRIVER_MID,
sizeof(stm32_cmd_t));
if (g_upgrade->stm32->cmd == NULL) {
reason = 7;
goto free_stm32;
}
//0xff -> STM32_CMD_ERR
os_mem_set(g_upgrade->stm32->cmd, 0xff, sizeof(stm32_cmd_t));
g_upgrade->stm32->port = os_mem_malloc(IOT_DRIVER_MID, sizeof(port_interface_t));
if (g_upgrade->stm32->port == NULL) {
reason = 8;
goto free_stm32;
}
g_upgrade->file_addr = (uint8_t *)stm32_bin;
g_upgrade->file_size = sizeof(stm32_bin) / sizeof(stm32_bin[0]);
stm32_dbg_printf("upgrade file size:%d \n", g_upgrade->file_size);
if (g_upgrade->file_size < VC_UPGRADE_STM32_FILE_SIZE_MIN) {
reason = 9;
goto free_stm32;
}
if (vc_module_upgrade_register_receive(vc_upgrd_receive_func) != ERR_OK) {
reason = 10;
goto free_stm32;
}
/**
* USB V2的板子kl1控制GD32的boot&reset初始状态不符合GD32的正常启动
* 需要在fw层控制GD32的power up
* USB V3的板子kl1控制pin修改后默认状态可以直接power up GD32
* 因此不需要这里再次power up
* 如kl芯片crash软复位了这里reset一下把两边状态重新对上。
*/
if (iot_board_get_boot_reason(&rst_reason) != SYSTEM_RESET_PWR
|| (iot_oem_get_board_id() == BOARD_HTZDCCO01
&& iot_board_hw_version_hex() == HW_VERSION_CCO_USB_V2)) {
vc_upgrd_ext_chip_reset(VC_UPGRD_RESET_TO_POWERUP);
}
//init secceed
g_upgrade->init_flag = 1;
g_upgrade->stm32->port->read = vc_upgrade_pull_data_from_ringbuf;
result = ERR_OK;
goto out;
free_stm32:
if (g_upgrade->stm32) {
if (g_upgrade->stm32->port) {
os_mem_free(g_upgrade->stm32->port);
}
if (g_upgrade->stm32->cmd) {
os_mem_free(g_upgrade->stm32->cmd);
}
os_mem_free(g_upgrade->stm32);
}
g_upgrade->stm32 = NULL;
free_ringbuf:
os_mem_free(ptr_ring);
close_gpio:
(void)iot_gpio_close(g_upgrade->gpio_boot0);
(void)iot_gpio_close(g_upgrade->gpio_reset);
free_upgrade:
os_mem_free(g_upgrade);
g_upgrade = NULL;
out:
iot_printf("%s result:%d, reason:%d\n", __FUNCTION__, result, reason);
return result;
}
void vc_upgrade_modele_deinit(void)
{
if (g_upgrade) {
if (g_upgrade->stm32) {
if (g_upgrade->stm32->cmd) {
os_mem_free(g_upgrade->stm32->cmd);
}
if (g_upgrade->stm32->port) {
os_mem_free(g_upgrade->stm32->port);
}
os_mem_free(g_upgrade->stm32);
}
if (g_upgrade->ring_buf.data) {
os_mem_free(g_upgrade->ring_buf.data);
}
os_mem_free(g_upgrade);
g_upgrade = NULL;
}
}
//stm32 model: boot0=1, boot1=x -> rom
// boot0=0, boot1=x -> flash
static uint32_t vc_upgrade_stm32_boot_model_select(uint8_t model)
{
uint32_t result = ERR_FAIL;
if (!g_upgrade) {
goto out;
}
if (model == VC_UPGRD_RESET_TO_DOWNLOAD) {
if (iot_gpio_value_set(g_upgrade->gpio_boot0, 1) != ERR_OK) {
goto out;
}
} else if (model == VC_UPGRD_RESET_TO_POWERUP) {
if (iot_gpio_value_set(g_upgrade->gpio_boot0, 0) != ERR_OK) {
goto out;
}
if (g_upgrade->stm32->is_connect) {
g_upgrade->stm32->is_connect = 0;
}
}
result = ERR_OK;
out:
return result;
}
static uint32_t vc_upgrade_stm32_reset(void)
{
uint32_t result = ERR_FAIL;
if (!g_upgrade) {
goto out;
}
if (iot_gpio_value_set(g_upgrade->gpio_reset, 0) != ERR_OK) {
goto out;
}
/* keep low level, reset stm32 */
os_delay(3);
if (iot_gpio_value_set(g_upgrade->gpio_reset, 1) != ERR_OK) {
goto out;
}
result = ERR_OK;
out:
return result;
}
uint32_t vc_upgrd_ext_chip_reset(uint8_t flag)
{
uint32_t result = ERR_OK;
uint8_t reason = 0;
if (flag >= VC_UPGRD_RESET_MAX) {
result = ERR_INVAL;
reason = 1;
goto out;
}
if (!g_upgrade) {
reason = 2;
goto out;
}
if (vc_upgrade_stm32_boot_model_select(flag) != ERR_OK) {
reason = 3;
result = ERR_FAIL;
goto out;
}
if (vc_upgrade_stm32_reset() != ERR_OK) {
reason = 4;
result = ERR_FAIL;
goto out;
}
out:
iot_printf("%s result:%d, reason:%d\n", __FUNCTION__, result, reason);
return result;
}
uint32_t vc_upgrd_set_start(vc_upgrd_send_func p_func)
{
uint32_t result = ERR_FAIL;
uint8_t reason = 0;
(void)reason; //eliminate compile errors
if (!g_upgrade) {
reason = 1;
goto out;
}
if (!p_func) {
result = ERR_INVAL;
reason = 2;
goto out;
}
if (g_upgrade->stm32->port->write != p_func) {
g_upgrade->stm32->port->write = p_func;
}
if (g_upgrade->buffer_r == NULL) {
g_upgrade->buffer_r = (uint8_t *)os_mem_malloc(IOT_STM32_MODULE_ID,
STM32_MAX_RX_PAYLOAD_LENGTH);
if (g_upgrade->buffer_r == NULL) {
reason = 3;
goto out;
}
}
if (g_upgrade->buffer_w == NULL) {
g_upgrade->buffer_w = (uint8_t *)os_mem_malloc(IOT_STM32_MODULE_ID,
STM32_MAX_TX_PAYLOAD_LENGTH);
if (g_upgrade->buffer_w == NULL) {
reason = 4;
goto mem_err;
}
}
g_upgrade->stm32->state = UPGRADE_SEND_INIT;
g_upgrade->flag_transf_over = 0;
/* start offset of the upd file for stm32 */
g_upgrade->offset_curr = sizeof(imgHdr);
g_upgrade->offset_header = 0;
g_upgrade->len_transf = 0;
g_upgrade->percentage = 0;
g_upgrade->status = VC_UPGRD_STATE_IDLE;
if (stm32_send_init_cmd(g_upgrade->stm32) != STM32_ERR_OK) {
reason = 5;
g_upgrade->status = VC_UPGRD_STATE_ENDUP;
goto out;
}
return ERR_OK;
mem_err:
os_mem_free(g_upgrade->buffer_r);
g_upgrade->buffer_r = NULL;
out:
iot_printf("%s result:%d reason:%d\n", __FUNCTION__, result, reason);
return result;
}
uint32_t vc_upgrd_set_stop(void)
{
uint32_t result = ERR_FAIL;
if (!g_upgrade) {
goto out;
}
result = vc_upgrade_stm32_boot_model_select(VC_UPGRD_RESET_TO_POWERUP);
if (result != ERR_OK) {
goto out;
}
if (vc_upgrade_stm32_reset() != ERR_OK) {
goto out;
}
if (g_upgrade->buffer_r != NULL) {
os_mem_free(g_upgrade->buffer_r);
g_upgrade->buffer_r = NULL;
}
if (g_upgrade->buffer_w != NULL) {
os_mem_free(g_upgrade->buffer_w);
g_upgrade->buffer_w = NULL;
}
g_upgrade->status = VC_UPGRD_STATE_ENDUP;
result = ERR_OK;
out:
stm32_dbg_printf("result:%d \n", result);
return result;
}
vc_upgrd_state_e vc_upgrd_get_state(void)
{
if (!g_upgrade) {
return VC_UPGRD_STATE_ERR;
}
return g_upgrade->status;
}
uint32_t vc_upgrd_get_percentage(void)
{
if (!g_upgrade) {
return 0;
}
return g_upgrade->percentage;
}
uint32_t vc_upgrd_get_firmware_info(vc_fw_ver_t *p_fw)
{
imgHdr hdr = {0};
if ((NULL == p_fw) || (!g_upgrade)) {
return ERR_FAIL;
}
img_header_construct(&hdr, (char*)g_upgrade->file_addr);
if ((VC_UPGRADE_FW_DEV_TYPE == iot_imghdr_get_devType(&hdr)) &&
(VC_UPGRADE_FW_GUARD == iot_imghdr_get_guard(&hdr))) {
p_fw->crc32 = iot_imghdr_get_imgCRC(&hdr);
p_fw->version = iot_imghdr_get_imgVer(&hdr);
p_fw->length = iot_imghdr_get_imgSize(&hdr);
} else {
iot_printf("[VC] get local fw info failed!!!\n");
}
return ERR_OK;
}
#else
uint32_t vc_upgrade_module_init(void)
{
return ERR_OK;
}
void vc_upgrade_modele_deinit(void)
{
return;
}
uint32_t vc_upgrd_ext_chip_reset(uint8_t flag)
{
(void)flag;
return ERR_OK;
}
uint32_t vc_upgrd_set_start(vc_upgrd_send_func p_func)
{
(void)p_func;
return ERR_OK;
}
uint32_t vc_upgrd_set_stop(void)
{
return ERR_OK;
}
vc_upgrd_state_e vc_upgrd_get_state(void)
{
return VC_UPGRD_STATE_IDLE;
}
uint32_t vc_upgrd_get_percentage(void)
{
return ERR_OK;
}
uint32_t vc_upgrd_receive_func(uint8_t *p_buf, uint32_t len)
{
(void)p_buf;
(void)len;
return ERR_OK;
}
uint32_t vc_upgrd_get_firmware_info(vc_fw_ver_t *p_fw)
{
if (NULL == p_fw) {
return ERR_FAIL;
}
p_fw->crc32 = 0;
p_fw->length = 0;
p_fw->version = 0;
return ERR_OK;
}
#endif