EC600U_esp32_iap_uart/esp32_iap/ec600u_port.c
2024-02-05 17:39:56 +08:00

205 lines
5.0 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.

#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;
}