2021-06-20 12:25:46 +08:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
* @file blsp_eflash_loader_uart.c
|
|
|
|
* @version V1.2
|
|
|
|
* @date
|
|
|
|
* @brief This file is the peripheral case header file
|
|
|
|
******************************************************************************
|
|
|
|
* @attention
|
|
|
|
*
|
|
|
|
* <h2><center>© COPYRIGHT(c) 2018 Bouffalo Lab</center></h2>
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
* are permitted provided that the following conditions are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
|
|
* and/or other materials provided with the distribution.
|
|
|
|
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
******************************************************************************
|
2021-06-04 17:56:34 +08:00
|
|
|
*/
|
|
|
|
#include "bflb_eflash_loader_uart.h"
|
|
|
|
#include "bflb_eflash_loader_cmds.h"
|
|
|
|
#include "bflb_eflash_loader.h"
|
|
|
|
#include "bflb_platform.h"
|
|
|
|
#include "partition.h"
|
|
|
|
#include "hal_uart.h"
|
|
|
|
#include "drv_device.h"
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
#define LOCAL_FILE_NUM (0x0003)
|
|
|
|
#define UART_CLOCK (40000000)
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
static uint32_t g_detected_baudrate;
|
|
|
|
|
|
|
|
/* data buffer for read data and decrypt */
|
2021-06-20 12:25:46 +08:00
|
|
|
volatile uint32_t g_rx_buf_index = 0;
|
|
|
|
volatile uint32_t g_rx_buf_len = 0;
|
|
|
|
uint32_t g_eflash_loader_readbuf[2][(BFLB_EFLASH_LOADER_READBUF_SIZE + 3) / 4];
|
2021-06-04 17:56:34 +08:00
|
|
|
uint32_t g_eflash_loader_cmd_ack_buf[16];
|
|
|
|
static void bflb_eflash_loader_usart_if_deinit();
|
2021-06-20 12:25:46 +08:00
|
|
|
struct device *download_uart = NULL;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
enum uart_index_type board_get_debug_uart_index(void)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ATTR_TCM_SECTION uart0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t *buf = (uint8_t *)g_eflash_loader_readbuf[g_rx_buf_index];
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (state == UART_EVENT_RX_FIFO) {
|
2021-06-04 17:56:34 +08:00
|
|
|
//g_rx_buf_len += device_read(download_uart,0,buf,BFLB_EFLASH_LOADER_READBUF_SIZE-g_rx_buf_len);
|
2021-07-26 15:31:38 +08:00
|
|
|
arch_memcpy(buf + g_rx_buf_len, args, size);
|
2021-06-04 17:56:34 +08:00
|
|
|
g_rx_buf_len += size;
|
2021-06-20 12:25:46 +08:00
|
|
|
} else if (state == UART_EVENT_RTO) {
|
2021-06-04 17:56:34 +08:00
|
|
|
//g_rx_buf_len += device_read(download_uart,0,buf,BFLB_EFLASH_LOADER_READBUF_SIZE-g_rx_buf_len);
|
2021-07-26 15:31:38 +08:00
|
|
|
arch_memcpy(buf + g_rx_buf_len, args, size);
|
2021-06-04 17:56:34 +08:00
|
|
|
g_rx_buf_len += size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bflb_eflash_loader_usart_if_init(uint32_t bdrate)
|
|
|
|
{
|
2021-07-16 17:34:55 +08:00
|
|
|
uart_register(0, "download_uart");
|
2021-06-04 17:56:34 +08:00
|
|
|
download_uart = device_find("download_uart");
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (download_uart) {
|
2021-07-26 15:31:38 +08:00
|
|
|
UART_DEV(download_uart)->fifo_threshold = 16;
|
2021-06-04 17:56:34 +08:00
|
|
|
device_open(download_uart, DEVICE_OFLAG_STREAM_TX);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void bflb_eflash_loader_usart_if_enable_int(void)
|
|
|
|
{
|
|
|
|
struct device *uart = device_find("download_uart");
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
if (uart) {
|
2021-06-04 17:56:34 +08:00
|
|
|
device_close(uart);
|
|
|
|
device_open(download_uart, DEVICE_OFLAG_STREAM_TX | DEVICE_OFLAG_INT_RX);
|
|
|
|
device_set_callback(uart, uart0_irq_callback);
|
2021-06-20 12:25:46 +08:00
|
|
|
device_control(uart, DEVICE_CTRL_SET_INT, (void *)(UART_RX_FIFO_IT | UART_RTO_IT));
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
void bflb_eflash_loader_usart_if_send(uint8_t *data, uint32_t len)
|
2021-06-04 17:56:34 +08:00
|
|
|
{
|
|
|
|
device_write(download_uart, 0, data, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t bflb_eflash_loader_usart_if_wait_tx_idle(uint32_t timeout)
|
|
|
|
{
|
|
|
|
/*UART now can't judge tx idle now*/
|
|
|
|
bflb_platform_delay_ms(timeout);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
static uint32_t *bflb_eflash_loader_usart_if_receive(uint32_t *recv_len, uint16_t maxlen, uint16_t timeout)
|
2021-06-04 17:56:34 +08:00
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint8_t *buf = (uint8_t *)g_eflash_loader_readbuf[g_rx_buf_index];
|
|
|
|
uint16_t datalen = 0;
|
2021-07-26 15:31:38 +08:00
|
|
|
uint64_t time_now;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-07-26 15:31:38 +08:00
|
|
|
time_now = bflb_platform_get_time_ms();
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
do {
|
|
|
|
if (g_rx_buf_len >= 4) {
|
2021-06-04 17:56:34 +08:00
|
|
|
/* receive cmd id and data len*/
|
2021-06-20 12:25:46 +08:00
|
|
|
datalen = buf[2] + (buf[3] << 8);
|
|
|
|
|
|
|
|
if (g_rx_buf_len == datalen + 4) {
|
2021-06-04 17:56:34 +08:00
|
|
|
/*receive all the payload,return */
|
|
|
|
/* move on to next buffer */
|
2021-06-20 12:25:46 +08:00
|
|
|
g_rx_buf_index = (g_rx_buf_index + 1) % 2;
|
|
|
|
g_rx_buf_len = 0;
|
|
|
|
|
|
|
|
if (datalen <= BFLB_EFLASH_LOADER_CMD_DATA_MAX_LEN) {
|
|
|
|
*recv_len = datalen + 4;
|
|
|
|
return (uint32_t *)buf;
|
2021-06-04 17:56:34 +08:00
|
|
|
} else {
|
2021-06-20 12:25:46 +08:00
|
|
|
*recv_len = 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-26 15:31:38 +08:00
|
|
|
} while (bflb_platform_get_time_ms() - time_now < timeout);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
*recv_len = 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bflb_eflash_loader_usart_if_deinit()
|
|
|
|
{
|
|
|
|
struct device *uart = device_find("download_uart");
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (uart) {
|
2021-06-04 17:56:34 +08:00
|
|
|
device_close(uart);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t bflb_eflash_loader_uart_init()
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
bflb_eflash_loader_usart_if_deinit();
|
2021-06-04 17:56:34 +08:00
|
|
|
bflb_eflash_loader_usart_if_init(0);
|
|
|
|
|
|
|
|
return BFLB_EFLASH_LOADER_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t bflb_eflash_loader_uart_handshake_poll()
|
|
|
|
{
|
|
|
|
uint8_t buf[128];
|
|
|
|
uint32_t i;
|
|
|
|
uint32_t handshake_count = 0;
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t rcv_buf_len = 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
//rcv_buf_len = UART_ReceiveData(g_uart_if_id,buf,128);
|
2021-07-26 15:31:38 +08:00
|
|
|
//struct device *download_uart = device_find("download_uart");
|
2021-06-20 12:25:46 +08:00
|
|
|
if (download_uart) {
|
|
|
|
rcv_buf_len = device_read(download_uart, 0, buf, 128);
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
2021-06-20 12:25:46 +08:00
|
|
|
|
2021-06-04 17:56:34 +08:00
|
|
|
//while(1)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
if (rcv_buf_len >= 16) {
|
|
|
|
for (i = 0; i < 16; i++) {
|
|
|
|
if (buf[i] == BFLB_EFLASH_LOADER_HAND_SHAKE_BYTE) {
|
2021-06-04 17:56:34 +08:00
|
|
|
handshake_count++;
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
if (handshake_count > BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
|
|
|
|
break;
|
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
if (handshake_count >= BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
|
2021-06-04 17:56:34 +08:00
|
|
|
//reinit uart
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("handshake %d 0x55 rcv\r\n", handshake_count);
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
} else {
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("handshake err\r\n");
|
2021-06-04 17:56:34 +08:00
|
|
|
return BFLB_EFLASH_LOADER_HANDSHAKE_FAIL;
|
|
|
|
}
|
2021-06-20 12:25:46 +08:00
|
|
|
|
2021-06-04 17:56:34 +08:00
|
|
|
/*receive shake hanad signal*/
|
2021-06-20 12:25:46 +08:00
|
|
|
bflb_eflash_loader_usart_if_send((uint8_t *)"OK", 2);
|
2021-06-04 17:56:34 +08:00
|
|
|
bflb_platform_delay_ms(400);
|
2021-06-20 12:25:46 +08:00
|
|
|
|
2021-06-04 17:56:34 +08:00
|
|
|
/* consume the remaining bytes when shake hand(0x55) if needed */
|
2021-06-20 12:25:46 +08:00
|
|
|
rcv_buf_len = device_read(download_uart, 0, buf, 128); //UART_ReceiveData(g_uart_if_id,buf,128);
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("bflb_eflash_loader_usart_if_receive len %d\r\n", rcv_buf_len);
|
2021-06-04 17:56:34 +08:00
|
|
|
/*init rx info */
|
2021-06-20 12:25:46 +08:00
|
|
|
g_rx_buf_index = 0;
|
|
|
|
g_rx_buf_len = 0;
|
|
|
|
BL_WR_WORD(g_eflash_loader_readbuf[g_rx_buf_index], 0);
|
2021-06-04 17:56:34 +08:00
|
|
|
bflb_eflash_loader_usart_if_enable_int();
|
|
|
|
|
|
|
|
return BFLB_EFLASH_LOADER_HANDSHAKE_SUSS;
|
|
|
|
}
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t *bflb_eflash_loader_uart_recv(uint32_t *recv_len, uint32_t maxlen, uint32_t timeout)
|
2021-06-04 17:56:34 +08:00
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
return bflb_eflash_loader_usart_if_receive(recv_len, maxlen, timeout);
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
int32_t bflb_eflash_loader_uart_send(uint32_t *data, uint32_t len)
|
2021-06-04 17:56:34 +08:00
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
bflb_eflash_loader_usart_if_send((uint8_t *)data, len);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
return BFLB_EFLASH_LOADER_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t bflb_eflash_loader_usart_wait_tx_idle(uint32_t timeout)
|
|
|
|
{
|
|
|
|
return bflb_eflash_loader_usart_if_wait_tx_idle(timeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t bflb_eflash_loader_uart_change_rate(uint32_t oldval, uint32_t newval)
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t b = (uint32_t)((g_detected_baudrate * 1.0 * newval) / oldval);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-07-26 15:31:38 +08:00
|
|
|
//MSG("BDR:");
|
|
|
|
//MSG(oldval);
|
|
|
|
//MSG(newval);
|
|
|
|
//MSG(g_detected_baudrate);
|
|
|
|
//MSG(b);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
bflb_eflash_loader_usart_if_wait_tx_idle(BFLB_EFLASH_LOADER_IF_TX_IDLE_TIMEOUT);
|
|
|
|
|
|
|
|
bflb_eflash_loader_usart_if_init(b);
|
2021-06-20 12:25:46 +08:00
|
|
|
bflb_eflash_loader_usart_if_send((uint8_t *)"OK", 2);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
return BFLB_EFLASH_LOADER_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int32_t bflb_eflash_loader_uart_deinit()
|
|
|
|
{
|
|
|
|
/* delete uart deinit, when uart tx(gpio16) set input function, uart send 0xFF to uart tx fifo
|
|
|
|
bflb_eflash_loader_deinit_uart_gpio(g_abr_gpio_sel);
|
|
|
|
|
|
|
|
bflb_eflash_loader_usart_if_deinit();
|
|
|
|
*/
|
|
|
|
|
|
|
|
return BFLB_EFLASH_LOADER_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void bflb_eflash_loader_main()
|
|
|
|
{
|
2021-06-20 12:25:46 +08:00
|
|
|
int32_t ret;
|
2021-06-04 17:56:34 +08:00
|
|
|
uint32_t total_len;
|
2021-06-20 12:25:46 +08:00
|
|
|
uint32_t i, tmp, cmd_len;
|
|
|
|
uint8_t *recv_buf = NULL;
|
|
|
|
uint8_t err_cnt = 0;
|
|
|
|
uint8_t to_cnt = 0;
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("bflb_eflash_loader_main\r\n");
|
2021-06-04 17:56:34 +08:00
|
|
|
pt_table_dump();
|
|
|
|
pt_table_get_iap_para(&p_iap_param);
|
|
|
|
bflb_eflash_loader_cmd_init();
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
to_cnt = 0;
|
|
|
|
total_len = 0;
|
|
|
|
|
|
|
|
do {
|
|
|
|
total_len = 0;
|
|
|
|
recv_buf = (uint8_t *)bflb_eflash_loader_uart_recv(&total_len, BFLB_EFLASH_LOADER_READBUF_SIZE, BFLB_EFLASH_LOADER_IF_UART_RX_TIMEOUT);
|
|
|
|
|
|
|
|
if (total_len <= 0) {
|
2021-06-04 17:56:34 +08:00
|
|
|
to_cnt++;
|
|
|
|
}
|
2021-06-20 12:25:46 +08:00
|
|
|
} while (to_cnt < 2 && total_len <= 0);
|
|
|
|
|
|
|
|
if (to_cnt >= 2 || total_len <= 0) {
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("rcv err break\r\n");
|
2021-06-04 17:56:34 +08:00
|
|
|
break;
|
|
|
|
}
|
2021-06-20 12:25:46 +08:00
|
|
|
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("Recv\r\n");
|
2021-06-04 17:56:34 +08:00
|
|
|
//eflash_loader_dump_data(recv_buf,total_len);
|
2021-06-20 12:25:46 +08:00
|
|
|
cmd_len = recv_buf[2] + (recv_buf[3] << 8);
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("cmd_len %d\r\n", cmd_len);
|
2021-06-20 12:25:46 +08:00
|
|
|
|
2021-06-04 17:56:34 +08:00
|
|
|
/* Check checksum*/
|
2021-06-20 12:25:46 +08:00
|
|
|
if (recv_buf[1] != 0) {
|
|
|
|
tmp = 0;
|
|
|
|
|
|
|
|
for (i = 2; i < cmd_len + 4; i++) {
|
|
|
|
tmp += recv_buf[i];
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
if ((tmp & 0xff) != recv_buf[1]) {
|
2021-06-04 17:56:34 +08:00
|
|
|
/* FL+Error code(2bytes) */
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG("Checksum error %02x\r\n", tmp & 0xff);
|
2021-06-20 12:25:46 +08:00
|
|
|
g_eflash_loader_cmd_ack_buf[0] = BFLB_EFLASH_LOADER_CMD_NACK | ((BFLB_EFLASH_LOADER_CMD_CRC_ERROR << 16) & 0xffff0000);
|
|
|
|
bflb_eflash_loader_uart_send(g_eflash_loader_cmd_ack_buf, 4);
|
2021-06-04 17:56:34 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
ret = bflb_eflash_loader_cmd_process(recv_buf[0], recv_buf + 4, cmd_len);
|
|
|
|
|
|
|
|
if (ret != BFLB_EFLASH_LOADER_SUCCESS) {
|
2021-07-26 15:31:38 +08:00
|
|
|
MSG(" CMD Pro Ret %d\r\n", ret);
|
2021-06-04 17:56:34 +08:00
|
|
|
|
|
|
|
err_cnt++;
|
2021-06-20 12:25:46 +08:00
|
|
|
|
|
|
|
if (err_cnt > 2) {
|
2021-06-04 17:56:34 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-06-20 12:25:46 +08:00
|
|
|
}
|
2021-06-04 17:56:34 +08:00
|
|
|
|
2021-06-20 12:25:46 +08:00
|
|
|
/* read data finished,deinit and go on*/
|
|
|
|
bflb_eflash_loader_uart_deinit();
|
2021-06-04 17:56:34 +08:00
|
|
|
}
|