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