EC600U_esp32_iap_uart/esp32_iap/ec600u_port.c

205 lines
5.0 KiB
C
Raw Normal View History

2024-02-05 17:39:56 +08:00
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ql_api_osi.h"
#include "ql_log.h"
#include "ql_gpio.h"
#include "ql_uart.h"
#include "ec600u_port.h"
#include "typedef.h"
#define SERIAL_FLASHER_RESET_HOLD_TIME_MS 100
#define SERIAL_FLASHER_BOOT_HOLD_TIME_MS 50
#define UART_PORT QL_UART_PORT_1
#define UART_BAUDRATE QL_UART_BAUD_115200
#define QL_UART_RX_BUFF_SIZE 2048
#define QL_UART_TX_BUFF_SIZE 2048
#define RESET_PIN 33
#define RESET_FUN 0
#define RESET_GPIO 19
#define GPIO0_PIN 34
#define GPIO0_FUN 0
#define GPIO0_GPIO 18
#define QL_GPIODEMO_LOG_LEVEL QL_LOG_LEVEL_INFO
#define LOGI(msg, ...) QL_LOG(QL_GPIODEMO_LOG_LEVEL, "ec600u_port", msg, ##__VA_ARGS__)
#define MIN(a, b) (a < b ? a : b)
static int64_t s_time_end;
static int32_t s_uart_port;
static int32_t s_reset_trigger_gpio;
static int32_t s_gpio0_trigger_gpio;
ql_sem_t *sem_write;
ql_sem_t *sem_read;
static void esp32_uart_notify_cb(unsigned int ind_type, ql_uart_port_number_e port, unsigned int size)
{
switch(ind_type)
{
case QUEC_UART_RX_OVERFLOW_IND: //rx buffer overflow
case QUEC_UART_RX_RECV_DATA_IND:
ql_rtos_semaphore_release(sem_read);
break;
case QUEC_UART_TX_FIFO_COMPLETE_IND:
ql_rtos_semaphore_release(sem_write);
break;
}
}
/* 串口阻塞读写操作timeout单位ms */
static int uart_read_block(unsigned char *data, unsigned int data_len, unsigned int timeout)
{
uint32_t read_len = 0;
uint32_t len = 0;
read_len = ql_uart_read(UART_PORT, data, data_len);
len += read_len;
while (len < data_len)
{
if (QL_OSI_SUCCESS != ql_rtos_semaphore_wait(sem_read, timeout)) break;
read_len = ql_uart_read(UART_PORT, data + len, data_len - len);
len += read_len;
}
return len;
}
static int uart_write_block(unsigned char *data, unsigned int data_len, unsigned int timeout)
{
unsigned int write_len = 0;
write_len = ql_uart_write(UART_PORT, data, data_len);
if (QL_OSI_SUCCESS != ql_rtos_semaphore_wait(sem_write, timeout))
return -1;
return write_len;
}
int loader_port_ec600u_init(void)
{
int ret;
s_uart_port = UART_PORT;
s_reset_trigger_gpio = RESET_GPIO;
s_gpio0_trigger_gpio = GPIO0_GPIO;
/* 串口初始化 */
ql_uart_config_s uart_cfg = {0};
uart_cfg.baudrate = UART_BAUDRATE;
uart_cfg.flow_ctrl = QL_FC_NONE;
uart_cfg.data_bit = QL_UART_DATABIT_8;
uart_cfg.stop_bit = QL_UART_STOP_1;
uart_cfg.parity_bit = QL_UART_PARITY_NONE;
ret = ql_uart_set_dcbconfig(UART_PORT, &uart_cfg);
if (QL_UART_SUCCESS != ret)
{
LOGI("uart dcbconfig err, ret: 0x%x", ret);
return -1;
}
ret = ql_uart_open(UART_PORT);
if (QL_UART_SUCCESS != ret)
{
LOGI("uart open err, ret: 0x%x", ret);
return -1;
}
ql_rtos_semaphore_create (&sem_read, 0);
ql_rtos_semaphore_create (&sem_write, 0);
ret = ql_uart_register_cb(UART_PORT, esp32_uart_notify_cb);
if (QL_UART_SUCCESS != ret)
{
LOGI("uart register callback err, ret: 0x%x", ret);
ql_uart_close(UART_PORT);
return -1;
}
/* 初始化reset,gpio0引脚 */
ql_pin_set_func(RESET_PIN, RESET_FUN);
ql_gpio_deinit(RESET_GPIO);
ql_gpio_init(RESET_GPIO, GPIO_OUTPUT, PULL_UP, LVL_HIGH);
ql_pin_set_func(GPIO0_PIN, GPIO0_FUN);
ql_gpio_deinit(GPIO0_GPIO);
ql_gpio_init(GPIO0_GPIO, GPIO_OUTPUT, PULL_UP, LVL_HIGH);
return 0;
}
void loader_port_ec600u_deinit(void)
{
ql_uart_close(UART_PORT);
ql_gpio_deinit(RESET_GPIO);
ql_gpio_deinit(GPIO0_GPIO);
}
int loader_port_write(const uint8_t *data, uint16_t size, uint32_t timeout)
{
int ret = 0;
ret = uart_write_block(data, size, timeout)
if (ret < 0) return -1;
else if (ret != size) return -2;
return 0;
}
int loader_port_read(uint8_t *data, uint16_t size, uint32_t timeout)
{
int ret = 0;
ret = uart_read_block(data, size, timeout);
if (ret < 0) return -1;
else if (ret != size) return -2;
return 0;
}
// Set GPIO0 LOW, then
// assert reset pin for 50 milliseconds.
void loader_port_enter_bootloader(void)
{
ql_gpio_set_level(GPIO0_GPIO, LVL_LOW);
loader_port_reset_target();
ql_rtos_task_sleep_ms(SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
ql_gpio_set_level(GPIO0_GPIO, LVL_HIGH);
}
void loader_port_reset_target(void)
{
ql_gpio_set_level(RESET_GPIO, LVL_LOW);
ql_rtos_task_sleep_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
ql_gpio_set_level(RESET_GPIO, LVL_HIGH);
}
void loader_port_delay_ms(uint32_t ms)
{
ql_rtos_task_sleep_ms(ms);
}
uint32_t get_time_us(void)
{
ql_timeval_t timeval;
if (QL_OSI_SUCCESS != ql_gettimeofday(&timeval)) return -1;
return timeval.usec;
}
void loader_port_start_timer(uint32_t ms)
{
s_time_end = get_time_us() + ms * 1000;
}
uint32_t loader_port_remaining_time(void)
{
int64_t remaining = (s_time_end - get_time_us()) / 1000;
return (remaining > 0) ? (uint32_t)remaining : 0;
}