This repository has been archived on 2023-07-17. You can view files and clone it, but cannot push or open issues or pull requests.
bl_mcu_sdk/examples/boot2_isp/bflb_eflash_loader_uart.c
2023-02-24 21:33:36 +08:00

298 lines
9.5 KiB
C

/**
******************************************************************************
* @file blsp_eflash_loader_uart.c
* @version V1.2
* @date
* @brief This file is the peripheral case header file
******************************************************************************
* @attention
*
* <h2><center>&copy; 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.
*
******************************************************************************
*/
#include "bflb_eflash_loader.h"
#include "blsp_port.h"
#include "blsp_common.h"
#include "partition.h"
#include "bflb_uart.h"
#include "bflb_port_boot2.h"
#include "bflb_uart.h"
static uint32_t g_detected_baudrate;
struct bflb_device_s *uartx;
static void bflb_eflash_loader_usart_if_deinit();
#define UART_FIFO_LEN 32
void bflb_dump_data(uint8_t *buf, uint32_t size)
{
for (int i = 0; i < size; i++) {
if (i % 16 == 0)
LOG_F("\r\n");
LOG_F("%02x ", buf[i]);
}
LOG_F("\r\n");
}
static uint32_t uart_read_all_data(uint8_t *buf,uint32_t maxlen)
{
return bflb_uart_get(uartx, buf, maxlen);
}
void ATTR_TCM_SECTION uart0_irq_callback(struct device *dev, void *args, uint32_t size, uint32_t state)
{
}
void ATTR_TCM_SECTION uart_isr(int irq, void *arg)
{
uint32_t intstatus = bflb_uart_get_intstatus(uartx);
if (intstatus & UART_INTSTS_RX_FIFO) {
uint8_t *buf=(uint8_t *)g_eflash_loader_readbuf[g_rx_buf_index];
g_rx_buf_len+=uart_read_all_data(buf+g_rx_buf_len,
BFLB_EFLASH_LOADER_READBUF_SIZE-g_rx_buf_len);
bflb_uart_int_clear(uartx, UART_INTSTS_RX_FIFO);
}
if (intstatus & UART_INTSTS_RTO) {
uint8_t *buf=(uint8_t *)g_eflash_loader_readbuf[g_rx_buf_index];
g_rx_buf_len+=uart_read_all_data(buf+g_rx_buf_len,
BFLB_EFLASH_LOADER_READBUF_SIZE-g_rx_buf_len);
bflb_uart_int_clear(uartx, UART_INTCLR_RTO);
}
}
static void bflb_eflash_loader_usart_if_init(uint32_t bdrate)
{
struct bflb_uart_config_s cfg;
hal_boot2_uart_gpio_init();
uartx = bflb_device_get_by_name("uart0");
cfg.baudrate = 2000000;
cfg.data_bits = UART_DATA_BITS_8;
cfg.stop_bits = UART_STOP_BITS_1;
cfg.parity = UART_PARITY_NONE;
cfg.flow_ctrl = 0;
cfg.tx_fifo_threshold = 16;
cfg.rx_fifo_threshold = 16;
bflb_uart_init(uartx, &cfg);
}
void bflb_eflash_loader_usart_if_enable_int(void)
{
bflb_uart_rxint_mask(uartx,false);
}
ATTR_TCM_SECTION void bflb_eflash_loader_usart_if_send(uint8_t *data, uint32_t len)
{
//uartx = bflb_device_get_by_name("uart0");
bflb_uart_put(uartx, data, len);
}
int32_t bflb_eflash_loader_usart_if_wait_tx_idle(uint32_t timeout)
{
/*UART now can't judge tx idle now*/
bflb_mtimer_delay_ms(timeout);
return 0;
}
ATTR_TCM_SECTION static uint32_t *bflb_eflash_loader_usart_if_receive(uint32_t *recv_len, uint16_t maxlen, uint16_t timeout)
{
uint8_t *buf = (uint8_t *)g_eflash_loader_readbuf[g_rx_buf_index];
uint16_t datalen = 0;
uint64_t time_now;
time_now = bflb_mtimer_get_time_ms();
do {
if (g_rx_buf_len >= 4) {
/* receive cmd id and data len*/
datalen = buf[2] + (buf[3] << 8);
if (g_rx_buf_len == datalen + 4) {
/*receive all the payload,return */
/* move on to next buffer */
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;
} else {
*recv_len = 0;
return NULL;
}
}
}
} while (bflb_mtimer_get_time_ms() - time_now < timeout);
*recv_len = 0;
return NULL;
}
static void bflb_eflash_loader_usart_if_deinit()
{
uartx = bflb_device_get_by_name("uart0");
bflb_uart_deinit(uartx);
}
int32_t bflb_eflash_loader_uart_init()
{
bflb_eflash_loader_usart_if_deinit();
bflb_eflash_loader_usart_if_init(0);
return BFLB_EFLASH_LOADER_SUCCESS;
}
int32_t bflb_eflash_loader_uart_handshake_poll(uint32_t timeout)
{
uint8_t buf[UART_FIFO_LEN] = { 0 };
uint32_t i;
uint32_t handshake_count = 0;
uint32_t rcv_buf_len = 0;
//rcv_buf_len = UART_ReceiveData(g_uart_if_id,buf,128);
//uartx = bflb_device_get_by_name("uart0");
rcv_buf_len = bflb_uart_get(uartx, buf, UART_FIFO_LEN);
//while(1)
{
if (rcv_buf_len >= BFLB_EFLASH_LOADER_HAND_SHAKE_RCV_COUNT) {
for (i = 0; i < BFLB_EFLASH_LOADER_HAND_SHAKE_RCV_COUNT; i++) {
if (buf[i] == BFLB_EFLASH_LOADER_HAND_SHAKE_BYTE) {
handshake_count++;
if (handshake_count > BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
break;
}
}
}
}
}
if (handshake_count < BFLB_EFLASH_LAODER_HAND_SHAKE_SUSS_COUNT) {
return -1;
}
#if defined(CHIP_BL606P) || defined(CHIP_BL808) || defined(CHIP_BL616) || defined(CHIP_WB03)
/*receive shake hanad signal*/
bflb_eflash_loader_usart_if_send((uint8_t *)"Boot2 ISP Ready", strlen("Boot2 ISP Ready"));
bflb_mtimer_delay_ms(2);
hal_reboot_config(HAL_REBOOT_FROM_INTERFACE);
GLB_SW_System_Reset();
while (1)
;
#endif
#if defined(CHIP_BL602) || defined(CHIP_BL702)
#define BFLB_EFLASH_LAODER_COMSUME_55_TIMEOUT 20
uint64_t nowtime;
/*receive shake hanad signal*/
bflb_eflash_loader_usart_if_send((uint8_t *)"Boot2 ISP Shakehand Suss", strlen("Boot2 ISP Shakehand Suss"));
/* consume the remaining bytes when shake hand(0x55) if needed */
nowtime = bflb_mtimer_get_time_ms();
do {
rcv_buf_len = bflb_uart_get(uartx,buf,UART_FIFO_LEN);
if (rcv_buf_len > 0) {
nowtime = bflb_mtimer_get_time_ms();
}
} while (bflb_mtimer_get_time_ms() - nowtime < BFLB_EFLASH_LAODER_COMSUME_55_TIMEOUT);
/*init rx info */
g_rx_buf_index = 0;
g_rx_buf_len = 0;
simple_malloc_init(g_malloc_buf, sizeof(g_malloc_buf));
g_eflash_loader_readbuf[0] = vmalloc(BFLB_EFLASH_LOADER_READBUF_SIZE);
g_eflash_loader_readbuf[1] = vmalloc(BFLB_EFLASH_LOADER_READBUF_SIZE);
arch_memset(g_eflash_loader_readbuf[0], 0, BFLB_EFLASH_LOADER_READBUF_SIZE);
arch_memset(g_eflash_loader_readbuf[1], 0, BFLB_EFLASH_LOADER_READBUF_SIZE);
bflb_irq_attach(uartx->irq_num, uart_isr, NULL);
bflb_eflash_loader_usart_if_enable_int();
bflb_irq_enable(uartx->irq_num);
bflb_eflash_loader_usart_if_send((uint8_t *)"Boot2 ISP Ready", strlen("Boot2 ISP Ready"));
bflb_uart_set_console(NULL);
#endif
return 0;
}
uint32_t ATTR_TCM_SECTION *bflb_eflash_loader_uart_recv(uint32_t *recv_len, uint32_t maxlen, uint32_t timeout)
{
return bflb_eflash_loader_usart_if_receive(recv_len, maxlen, timeout);
}
ATTR_TCM_SECTION int32_t bflb_eflash_loader_uart_send(uint32_t *data, uint32_t len)
{
bflb_eflash_loader_usart_if_send((uint8_t *)data, len);
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)
{
uint32_t b = (uint32_t)((g_detected_baudrate * 1.0 * newval) / oldval);
//LOG_F("BDR:");
//LOG_F(oldval);
//LOG_F(newval);
//LOG_F(g_detected_baudrate);
//LOG_F(b);
bflb_eflash_loader_usart_if_wait_tx_idle(BFLB_EFLASH_LOADER_IF_TX_IDLE_TIMEOUT);
bflb_eflash_loader_usart_if_init(b);
bflb_eflash_loader_usart_if_send((uint8_t *)"OK", 2);
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;
}