/************************************************************************************************/ /** * @file usart_bsp.c * @author MCU Ecosystem Development Team * @brief USART BSP函数,实现USART配置等功能。 * 发送采用串口DMA中断方式,接收有两种方式,串口中断接收和串口DMA+空闲中断接收,当使用adc功能时,默认采用ADC+DMA方式接收,故此时应该屏蔽掉UART1_DMA_RX_ENABLE * 采用第一种方式接收。否则会造成冲突,因为CIU32L051C8T6只有一个DMA接收通道 * * ************************************************************************************************** * @attention * Copyright (c) CEC Huada Electronic Design Co.,Ltd. All rights reserved. * ************************************************************************************************** */ /*------------------------------------------includes--------------------------------------------*/ #include "drV_uart.h" #include "rtthread.h" #include "serial.h" #include "lwrb.h" #include "lwutil.h" #include "bsp_history.h" #include "drv_gpio.h" #include "bsp_sensor.h" #include "completion.h" #define LOG_TAG "drv_uart" #define LOG_LVL LOG_LVL_DBG #include // #define UART1_DMA_RX_ENABLE /*-------------------------------------用户自定义-----------------*/ /* 定时器的控制块 */ rt_timer_t uart2_rx_timer; #ifdef UART3_4_ENABLE rt_timer_t uart3_rx_timer; struct rt_semaphore uart3_rx_sem; #endif rt_timer_t lpuart1_rx_timer; #ifdef UART1_DMA_RX_ENABLE rt_sem_t uart1_rx_sem; static rt_uint8_t _uart1_rx_dma_buffer[UART1_RX_BUFFER_LENGTH] = {0}; ALIGN(RT_ALIGN_SIZE) static char uart1_rx_thread_stack[UART1_RX_THREAD_STACK_SIZE]; struct rt_thread uart1_rx_thread; #endif #ifdef DEBUG_OUTPUT_SELECT rt_sem_t uart1_rx_ok_sem = RT_NULL; #endif rt_sem_t lpuart1_rx_ok_sem; /*Ring buffer instance for TX data*/ lwrb_t uart1_tx_rb; lwrb_t uart3_tx_rb; lwrb_t lpuart1_tx_rb; /*Ring buffer data array for TX*/ uint8_t uart1_tx_rb_data[UART1_TX_RB_LENGTH]; uint8_t uart3_tx_rb_data[UART3_TX_RB_LENGTH]; uint8_t lpuart1_tx_rb_data[LPUART1_TX_RB_LENGTH]; /*Ring buffer instance for RX data*/ lwrb_t uart1_rx_rb; lwrb_t uart2_rx_rb; lwrb_t uart3_rx_rb; lwrb_t lpuart1_rx_rb; /*Ring buffer data array for RX*/ uint8_t uart1_rx_rb_data[UART1_RX_RB_LENGTH]; uint8_t uart2_rx_rb_data[UART2_RX_RB_LENGTH]; uint8_t uart3_rx_rb_data[UART1_RX_RB_LENGTH]; uint8_t lpuart1_rx_rb_data[LPUART1_RX_RB_LENGTH]; volatile size_t _uart1_tx_dma_current_len; // #define BSP_USING_UART3 // static struct ciu32_uart_config uart_config[] = // { // #ifdef BSP_USING_UART1 // { // "uart1", // USART1, // USART1_IRQn, // }, // #endif // #ifdef BSP_USING_UART2 // { // "uart2", // UART2, // UART2_IRQn, // }, // #endif // #ifdef BSP_USING_UART3 // { // "uart3", // UART3, // UART3_4_IRQn, // }, // #endif // #ifdef BSP_USING_LPUART1 // { // "lpuart1", // LPUART1, // LPUART1_IRQn, // }, // #endif // #ifdef BSP_USING_LPUART2 // { // "lpuart2", // LPUART2, // LPUART2_IRQn, // }, // #endif // }; /*-----------------------------------------------------------------*/ #ifdef UART1_DMA_RX_ENABLE /** * @brief DMA配置函数 * @param distination DMA传输目的地址 * @param number DMA传输字符数 * @retval 无 */ void Uart1_Dma_Rec_Data_Cfg(void) { std_dma_config_t dma_config = {0}; /* 配置DMA 源地址、目的地址和传输数据大小,并使能DMA */ dma_config.src_addr = (uint32_t)&USART1->RDR; dma_config.dst_addr = (uint32_t)_uart1_rx_dma_buffer; dma_config.data_number = LWUTIL_ARRAYSIZE(_uart1_rx_dma_buffer); dma_config.dma_channel = DMA_CHANNEL_0; std_dma_start_transmit(&dma_config); } #endif /** * @brief DMA配置函数 * @param source DMA源地址 * @param number DMA传输字符数 * @retval 无 */ void Uart1_Dma_Send_Data(uint32_t *source, uint32_t number) { std_dma_config_t dma_config = {0}; /* 配置DMA 源地址、目的地址和传输数据大小,并使能DMA */ dma_config.src_addr = (uint32_t)source; dma_config.dst_addr = (uint32_t)&USART1->TDR; dma_config.data_number = number; dma_config.dma_channel = UART1_DMA_TX_CHANNEL; std_dma_start_transmit(&dma_config); } /** * @brief DMA通道初始化 * @retval 无 */ void __Uart1_Dma_Init(void) { std_dma_init_t dma_init_param = {0}; /* DMA外设时钟使能 */ std_rcc_ahb_clk_enable(RCC_PERIPH_CLK_DMA); #ifdef UART1_DMA_RX_ENABLE /* dma_init_param 结构体初始化 */ dma_init_param.dma_channel = UART1_DMA_RX_CHANNEL; dma_init_param.dma_req_id = DMA_REQUEST_USART1_RX; dma_init_param.transfer_type = DMA_BLOCK_TRANSFER; dma_init_param.src_addr_inc = DMA_SRC_INC_DISABLE; dma_init_param.dst_addr_inc = DMA_DST_INC_ENABLE; dma_init_param.data_size = DMA_DATA_SIZE_BYTE; dma_init_param.mode = DMA_MODE_CIRCULAR; std_dma_init(&dma_init_param); #endif // UART1_DMA_RX_ENABLE 1 /* dma_init_param 结构体初始化 */ dma_init_param.dma_channel = UART1_DMA_TX_CHANNEL; dma_init_param.dma_req_id = DMA_REQUEST_USART1_TX; dma_init_param.transfer_type = DMA_BLOCK_TRANSFER; dma_init_param.src_addr_inc = DMA_SRC_INC_ENABLE; dma_init_param.dst_addr_inc = DMA_DST_INC_DISABLE; dma_init_param.data_size = DMA_DATA_SIZE_BYTE; dma_init_param.mode = DMA_MODE_NORMAL; std_dma_init(&dma_init_param); #ifdef UART1_DMA_RX_ENABLE /* 使能接收中断 */ std_dma_interrupt_enable(UART1_DMA_RX_CHANNEL, DMA_INTERRUPT_TF); std_dma_interrupt_enable(UART1_DMA_RX_CHANNEL, DMA_INTERRUPT_TH); std_dma_interrupt_enable(UART1_DMA_RX_CHANNEL, DMA_INTERRUPT_TE); #endif /* 使能发送中断 */ // std_dma_interrupt_enable(UART1_DMA_TX_CHANNEL, DMA_INTERRUPT_TF); #ifdef UART1_DMA_RX_ENABLE /* NVIC初始化 */ NVIC_SetPriority(UART1_DMA_RX_IRQ_CHANNEL, NVIC_PRIO_1); NVIC_EnableIRQ(UART1_DMA_RX_IRQ_CHANNEL); #endif NVIC_SetPriority(UART1_DMA_TX_IRQ_CHANNEL, NVIC_PRIO_1); NVIC_EnableIRQ(UART1_DMA_TX_IRQ_CHANNEL); #ifdef UART1_DMA_RX_ENABLE Uart1_Dma_Rec_Data_Cfg(); // DMA接收数据配置 std_dma_enable(UART1_DMA_RX_CHANNEL); #endif std_dma_disable(UART1_DMA_TX_CHANNEL); } /** * @brief UART1 GPIO初始化 * @retval 无 */ void __Uart1_Gpio_Init(void) { std_gpio_init_t usart_gpio_init = {0}; usart_gpio_init.pin = UART1_TX_GPIO_PIN; usart_gpio_init.mode = GPIO_MODE_ALTERNATE; usart_gpio_init.output_type = GPIO_OUTPUT_PUSHPULL; usart_gpio_init.pull = GPIO_PULLUP; usart_gpio_init.alternate = GPIO_AF1_USART1; std_gpio_init(UART1_TX_GPIO_PORT, &usart_gpio_init); usart_gpio_init.pin = UART1_RX_GPIO_PIN; usart_gpio_init.mode = GPIO_MODE_ALTERNATE; usart_gpio_init.output_type = GPIO_OUTPUT_PUSHPULL; usart_gpio_init.pull = GPIO_PULLUP; usart_gpio_init.alternate = GPIO_AF1_USART1; std_gpio_init(UART1_RX_GPIO_PORT, &usart_gpio_init); } /** * @brief UART2 GPIO初始化 * @retval 无 */ void __Uart2_Gpio_Init(void) { std_gpio_init_t tmp_gpio_cfg = {0}; /* UART2 GPIO引脚配置 PB6 ------> UART2发送引脚 PB7 ------> UART2接收引脚 */ #if 0 tmp_gpio_cfg.pin = UART2_TX_GPIO_PIN; tmp_gpio_cfg.mode = GPIO_MODE_ALTERNATE; tmp_gpio_cfg.output_type = GPIO_OUTPUT_PUSHPULL; tmp_gpio_cfg.pull = GPIO_PULLUP; tmp_gpio_cfg.alternate = GPIO_AF1_UART2; std_gpio_init(UART2_TX_GPIO_PORT, &tmp_gpio_cfg); #endif tmp_gpio_cfg.pin = UART2_RX_GPIO_PIN; tmp_gpio_cfg.mode = GPIO_MODE_ALTERNATE; tmp_gpio_cfg.output_type = GPIO_OUTPUT_PUSHPULL; tmp_gpio_cfg.pull = GPIO_PULLUP; tmp_gpio_cfg.alternate = GPIO_AF1_UART2; //这个复用功能配置有点麻烦,得判断到底使用的那个 std_gpio_init(UART2_RX_GPIO_PORT, &tmp_gpio_cfg); } #ifdef UART3_4_ENABLE /** * @brief UART3 GPIO初始化 * @retval 无 */ void __Uart3_Gpio_Init(void) { // /* GPIO外设时钟使能 */ // std_rcc_gpio_clk_enable(RCC_PERIPH_CLK_GPIOB); // std_gpio_init_t tmp_gpio_cfg = {0}; // /* UART3 GPIO引脚配置 // PB6 ------> UART3发送引脚 // PB7 ------> UART3接收引脚 // */ // tmp_gpio_cfg.pin = UART3_TX_GPIO_PIN; // tmp_gpio_cfg.mode = GPIO_MODE_ALTERNATE; // tmp_gpio_cfg.output_type = GPIO_OUTPUT_PUSHPULL; // tmp_gpio_cfg.pull = GPIO_PULLUP; // tmp_gpio_cfg.alternate = GPIO_AF7_UART3; // std_gpio_init(UART3_TX_GPIO_PORT, &tmp_gpio_cfg); // tmp_gpio_cfg.pin = UART3_RX_GPIO_PIN; // tmp_gpio_cfg.mode = GPIO_MODE_ALTERNATE; // tmp_gpio_cfg.output_type = GPIO_OUTPUT_PUSHPULL; // tmp_gpio_cfg.pull = GPIO_PULLUP; // tmp_gpio_cfg.alternate = GPIO_AF7_UART3; // std_gpio_init(UART3_RX_GPIO_PORT, &tmp_gpio_cfg); rt_pin_mode(UART3_TX_GPIO_PIN, PIN_MODE_ALTERNATE); rt_pin_mode(UART3_RX_GPIO_PIN, PIN_MODE_ALTERNATE); } #endif /** * @brief LPUART1 GPIO初始化 * @retval 无 */ void __Lpuart1_Gpio_Init(void) { std_gpio_init_t tmp_gpio_cfg = {0}; /* LPUART1 GPIO引脚配置 PB11 ------> LPUART1发送引脚 PB10 ------> LPUART1接收引脚 */ tmp_gpio_cfg.pin = LPUART1_TX_GPIO_PIN; tmp_gpio_cfg.mode = GPIO_MODE_ALTERNATE; tmp_gpio_cfg.output_type = GPIO_OUTPUT_PUSHPULL; tmp_gpio_cfg.pull = GPIO_PULLUP; tmp_gpio_cfg.alternate = GPIO_AF6_LPUART1; std_gpio_init(LPUART1_TX_GPIO_PORT, &tmp_gpio_cfg); tmp_gpio_cfg.pin = LPUART1_RX_GPIO_PIN; tmp_gpio_cfg.mode = GPIO_MODE_ALTERNATE; tmp_gpio_cfg.output_type = GPIO_OUTPUT_PUSHPULL; tmp_gpio_cfg.pull = GPIO_PULLUP; tmp_gpio_cfg.alternate = GPIO_AF6_LPUART1; std_gpio_init(LPUART1_RX_GPIO_PORT, &tmp_gpio_cfg); } /** * @brief USART1初始化 * @retval 无 */ void __Uart1_Cfg(uint32_t baudrate, uint32_t par) { /* USART1时钟使能 */ std_rcc_apb2_clk_enable(RCC_PERIPH_CLK_USART1); std_usart_init_t usart_config = {0}; usart_config.direction = USART_DIRECTION_SEND_RECEIVE; usart_config.baudrate = baudrate; usart_config.wordlength = USART_WORDLENGTH_8BITS; usart_config.stopbits = USART_STOPBITS_1; usart_config.parity = par; usart_config.hardware_flow = USART_FLOWCONTROL_NONE; /* USART初始化 */ if (STD_OK != std_usart_init(USART1, &usart_config)) { /* 波特率配置不正确处理代码 */ while (1); } #ifdef UART1_DMA_RX_ENABLE /* 使能USART DMA接收 */ std_usart_dma_rx_enable(USART1); // 串口DMA接收使能 #endif std_usart_enable(USART1); // 串口使能 /* NVIC初始化 */ NVIC_SetPriority(USART1_IRQn, 1); NVIC_EnableIRQ(USART1_IRQn); // std_usart_cr1_interrupt_enable(USART1, USART_CR1_INTERRUPT_PE); // std_usart_cr1_interrupt_enable(USART1, USART_CR3_INTERRUPT_ERR); std_usart_cr1_interrupt_enable(USART1, USART_CR1_INTERRUPT_IDLE); #ifndef UART1_DMA_RX_ENABLE std_usart_cr1_interrupt_enable(USART1, USART_CR1_INTERRUPT_RXNE); #endif // !UART1_DMA_RX_ENABLE } /** * @brief UART2初始化配置 * @retval 无 */ void __Uart2_Cfg(uint32_t baudrate, uint32_t par) { /* UART2时钟使能 */ std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_UART2); std_usart_init_t usart_config = {0}; usart_config.direction = USART_DIRECTION_RECEIVE; usart_config.baudrate = baudrate; usart_config.wordlength = USART_WORDLENGTH_8BITS; usart_config.stopbits = USART_STOPBITS_1; usart_config.parity = par; usart_config.hardware_flow = USART_FLOWCONTROL_NONE; /* USART初始化 */ if (STD_OK != std_usart_init(UART2, &usart_config)) { /* 波特率配置不正确处理代码 */ while (1); } std_usart_enable(UART2); // 串口使能 /* NVIC初始化 */ NVIC_SetPriority(UART2_IRQn, 3); NVIC_EnableIRQ(UART2_IRQn); std_usart_cr1_interrupt_enable(UART2, USART_CR1_INTERRUPT_RXNE); } #ifdef UART3_4_ENABLE /** * @brief UART3初始化配置 * @retval 无 */ void __Uart3_Cfg(uint32_t baudrate, uint32_t par) { /* UART2时钟使能 */ std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_UART3); std_usart_init_t usart_config = {0}; usart_config.direction = USART_DIRECTION_RECEIVE; usart_config.baudrate = baudrate; usart_config.wordlength = USART_WORDLENGTH_8BITS; usart_config.stopbits = USART_STOPBITS_1; usart_config.parity = par; usart_config.hardware_flow = USART_FLOWCONTROL_NONE; /* USART初始化 */ if (STD_OK != std_usart_init(UART3, &usart_config)) { /* 波特率配置不正确处理代码 */ while (1); } std_usart_enable(UART3); // 串口使能 /* NVIC初始化 */ NVIC_SetPriority(UART3_4_IRQn, 2); NVIC_EnableIRQ(UART3_4_IRQn); std_usart_cr1_interrupt_enable(UART3, USART_CR1_INTERRUPT_RXNE); std_usart_cr1_interrupt_enable(UART3, USART_CR3_INTERRUPT_ERR); } #endif /** * @brief LPUART初始化配置,时钟源为RCH * @retval 无 */ void __Lpuart_Init(uint32_t baudrate, uint32_t par) { std_lpuart_init_t lpuart_config = {0}; /* 配置LPUART 时钟源为RCH */ std_rcc_set_lpuart1clk_source(RCC_LPUART1_ASYNC_CLK_SRC_RCH); /* 配置LPUART 外设时钟 */ std_rcc_apb1_clk_enable(RCC_PERIPH_CLK_LPUART1); /* LPUART 模块初始化 */ lpuart_config.prescaler = LPUART_PRESCALER_DIV1; lpuart_config.baudrate = baudrate; lpuart_config.parity = par; lpuart_config.stopbits = LPUART_STOPBITS_1; lpuart_config.wordlength = LPUART_WORDLENGTH_9BITS; lpuart_config.direction = LPUART_DIRECTION_SEND_RECEIVE; /* LPUART 初始化 */ if (STD_OK != std_lpuart_init(LPUART1, &lpuart_config)) { /* 波特率配置不正确处理代码 */ while (1); } /* 配置LPUART中断优先级以及使能LPUART的NVIC中断 */ NVIC_SetPriority(LPUART1_IRQn, NVIC_PRIO_1); NVIC_EnableIRQ(LPUART1_IRQn); std_usart_cr1_interrupt_enable(LPUART1, USART_CR1_INTERRUPT_RXNE); std_usart_cr1_interrupt_enable(LPUART1, USART_CR3_INTERRUPT_ERR); } void __UART1_Init(uint32_t baudrate, uint32_t par) { /* Initialize ringbuff */ lwrb_init(&uart1_rx_rb, uart1_rx_rb_data, sizeof(uart1_rx_rb_data)); lwrb_init(&uart1_tx_rb, uart1_tx_rb_data, sizeof(uart1_tx_rb_data)); /* 串口DMA配置 */ __Uart1_Dma_Init(); /* GPIO初始化 */ __Uart1_Gpio_Init(); /* UASRT1初始化 */ __Uart1_Cfg(baudrate, par); LOG_I("USART1 Init"); } void UART2_Init(uint32_t baudrate, uint32_t par) { /* Initialize ringbuff */ lwrb_init(&uart2_rx_rb, uart2_rx_rb_data, sizeof(uart2_rx_rb_data)); /* GPIO初始化 */ __Uart2_Gpio_Init(); /* USRT2初始化 */ __Uart2_Cfg(baudrate, par); LOG_I("UART2 Init"); } #ifdef UART3_4_ENABLE void __UART3_Init(uint32_t baudrate, uint32_t par) { /* Initialize ringbuff */ lwrb_init(&uart3_tx_rb, uart3_tx_rb_data, sizeof(uart3_tx_rb_data)); lwrb_init(&uart3_rx_rb, uart3_rx_rb_data, sizeof(uart3_rx_rb_data)); /* GPIO初始化 */ __Uart3_Gpio_Init(); /* USRT3初始化 */ __Uart3_Cfg(baudrate, par); LOG_I("UART3 Init"); } #endif void LPUART1_Init(uint32_t baudrate, uint32_t par) { /* Initialize ringbuff */ lwrb_init(&lpuart1_rx_rb, lpuart1_rx_rb_data, sizeof(lpuart1_rx_rb_data)); lwrb_init(&lpuart1_tx_rb, lpuart1_tx_rb_data, sizeof(lpuart1_tx_rb_data)); /* GPIO初始化 */ __Lpuart1_Gpio_Init(); /* UASRT1初始化 */ __Lpuart_Init(baudrate, par); LOG_I("LPUART1_Init"); } #ifdef UART1_DMA_RX_ENABLE /** * \brief Process received data over UART1 * Data are written to RX ringbuffer for application processing at latter stage * \param[in] data: Data to process * \param[in] len: Length in units of bytes */ rt_inline void _UART1_ProcessData(const void *data, size_t len) { /* Write data to receive buffer */ lwrb_write(&uart1_rx_rb, data, len); } static void _UART1_RxCheck(void) { static size_t old_pos; size_t pos; /* Calculate current position in buffer and check for new data available */ pos = LWUTIL_ARRAYSIZE(_uart1_rx_dma_buffer) - std_dma_get_transfer_data_number(UART1_DMA_RX_CHANNEL); // LOG_D("pos: %d", pos); // LOG_D("std_dma_get_transfer_data_number(DMA_CHANNEL_0): %d", std_dma_get_transfer_data_number(DMA_CHANNEL_0)); /* Check change in received data */ if (pos != old_pos) { /* Current position is over previous one */ if (pos > old_pos) { _UART1_ProcessData(&_uart1_rx_dma_buffer[old_pos], pos - old_pos); } else { _UART1_ProcessData(&_uart1_rx_dma_buffer[old_pos], LWUTIL_ARRAYSIZE(_uart1_rx_dma_buffer) - old_pos); if (pos > 0) { _UART1_ProcessData(&_uart1_rx_dma_buffer[0], pos); } } old_pos = pos; /* Save current position as old for next transfers */ } } #endif // UART1_DMA_RX_ENABLE /** * \brief Check if DMA is active and if not try to send data * \return `1` if transfer just started, `0` if on-going or no data to transmit */ static void _UART1_StartTxDMATransfer(void) { rt_enter_critical(); if (_uart1_tx_dma_current_len == 0 && (_uart1_tx_dma_current_len = lwrb_get_linear_block_read_length(&uart1_tx_rb)) > 0) { /* Disable channel if enabled */ std_dma_disable(UART1_DMA_TX_CHANNEL); // 如果DMA通道只给串口1使用,那只需要在初始化使能就行,不需要关闭 std_usart_dma_tx_disable(USART1); std_dma_interrupt_disable(UART1_DMA_TX_CHANNEL, DMA_INTERRUPT_TF); // 发送完成关闭DMA通道中断 /* Clear all flags */ std_dma_clear_flag(DMA_CLEAR_TF1); Uart1_Dma_Send_Data(lwrb_get_linear_block_read_address(&uart1_tx_rb), _uart1_tx_dma_current_len); std_dma_interrupt_enable(UART1_DMA_TX_CHANNEL, DMA_INTERRUPT_TF); // 发送时打开DMA通道中断 /* enable transfer */ std_dma_enable(UART1_DMA_TX_CHANNEL); std_usart_dma_tx_enable(USART1); } rt_exit_critical(); } rt_uint32_t UART1_Write(const void *data, size_t len) { rt_uint32_t ret = 0; if (lwrb_get_free(&uart1_tx_rb) >= len) { ret = lwrb_write(&uart1_tx_rb, data, len); _UART1_StartTxDMATransfer(); /* Then try to start transfer */ } return ret; } /*采用中断方式发送数据*/ rt_uint32_t UART3_Write(const void *data, size_t len) { rt_uint32_t ret = 0; if (lwrb_get_free(&uart3_tx_rb) >= len) { ret = lwrb_write(&uart3_tx_rb, data, len); std_lpuart_cr1_interrupt_enable(UART3, LPUART_CR1_INTERRUPT_TXE); } return ret; } rt_uint32_t LPUART1_Write(const void *data, size_t len) { rt_uint32_t ret = 0; if (lwrb_get_free(&lpuart1_tx_rb) >= len) { ret = lwrb_write(&lpuart1_tx_rb, data, len); std_lpuart_cr1_interrupt_enable(LPUART1, LPUART_CR1_INTERRUPT_TXE); } return ret; } /** * \brief Send string to UART1 * \param[in] str: String to send */ rt_uint32_t UART1_SendString(const char *str) { return UART1_Write(str, rt_strlen(str)); } rt_uint32_t LPUART1_SendString(const char *str) { return LPUART1_Write(str, rt_strlen(str)); } rt_uint32_t UART3_Read(void *buf, size_t len) { if (lwrb_get_full(&uart3_rx_rb) >= len) { return lwrb_read(&uart3_rx_rb, buf, len); } return RT_ERROR; } /** * \brief UART2 RX complete callback * \param[in] */ void Uart2_Rx_Complate_Check_Entry(void *parameter) { static size_t last_pos = 0; size_t pos = lwrb_get_full(&uart2_rx_rb); // 如果上次长度与当前长度相同且大于0,则认为接收完成 if (last_pos == pos && pos > 0) { // LOG_D("uart2_rx_rb: %d", pos); #if 0 /*测试读取*/ { uint8_t sensor_rx_data[64] = {0}; //确保读取的数据量不超过剩余的数据量 size_t read_size = ((pos < sizeof(sensor_rx_data)) ? pos : sizeof(sensor_rx_data)); lwrb_read(&uart2_rx_rb, sensor_rx_data, read_size); LOG_D("uart2_rx_rb: %s", sensor_rx_data); } #endif // TODO: 处理接收到的数据 rt_sem_release(&sensor_rx_sem); // 清空last_pos以准备下一次接收 last_pos = 0; } // 检查是否有新的数据到达 if (pos > 0) { last_pos = pos; } } #ifdef UART3_4_ENABLE /** * \brief UART3 RX complete callback * \param[in] */ void Uart3_Rx_Complate_Check_Entry(void *parameter) { static size_t last_pos = 0; size_t pos = lwrb_get_full(&uart3_rx_rb); // 如果上次长度与当前长度相同且大于0,则认为接收完成 if (last_pos == pos && pos > 0) { // LOG_D("uart3_rx_rb: %d", pos); #if 0 /*测试读取*/ { uint8_t uart3_rx_data[64] = {0}; //确保读取的数据量不超过剩余的数据量 size_t read_size = ((pos < sizeof(uart3_rx_data)) ? pos : sizeof(uart3_rx_data)); lwrb_read(&uart3_rx_rb, uart3_rx_data, read_size); LOG_D("uart3_rx_rb: %s", uart3_rx_data); } #endif // TODO: 处理接收到的数据 rt_sem_release(&uart3_rx_sem); // 清空last_pos以准备下一次接收 last_pos = 0; } // 检查是否有新的数据到达 if (pos > 0) { last_pos = pos; } } #endif /** * \brief LPUART1 RX complete callback * \param[in] */ void Lpuart_Rx_Complate_Check_Entry(void *parameter) { static size_t last_pos = 0; size_t pos = lwrb_get_full(&lpuart1_rx_rb); // 如果上次长度与当前长度相同且大于0,则认为接收完成 if (last_pos == pos && pos > 0) { // LOG_D("lpuart1_rx_rb: %d", pos); // TODO: 处理接收到的数据 rt_completion_done(&hr_rx_completion); /*测试读取*/ { #if 0 uint8_t lp_rx_data[16] = {0}; 确保读取的数据量不超过剩余的数据量 size_t read_size = ((pos < sizeof(lp_rx_data)) ? pos : sizeof(lp_rx_data)); lwrb_read(&lpuart1_rx_rb, lp_rx_data, read_size); LPUART1_Write(lp_rx_data, read_size); #endif } // 清空last_pos以准备下一次接收 last_pos = 0; } // 检查是否有新的数据到达 if (pos > 0) { last_pos = pos; } } #ifdef UART1_DMA_RX_ENABLE static void Uart1_Rx_Thread_Entry(void *parameter) { LOG_D("Uart1_Rx_Thread_Entry"); while (1) { rt_sem_take(uart1_rx_sem, RT_WAITING_FOREVER); _UART1_RxCheck(); } } /** * @brief DMA通道0中断服务函数 UART1 RX * @retval 无 */ void DMA_Channel0_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); if ((std_dma_get_interrupt_enable(UART1_DMA_RX_CHANNEL, DMA_INTERRUPT_TH)) && (std_dma_get_flag(DMA_FLAG_TH0))) { std_dma_clear_flag(DMA_CLEAR_TH0); rt_sem_release(uart1_rx_sem); } if ((std_dma_get_interrupt_enable(UART1_DMA_RX_CHANNEL, DMA_INTERRUPT_TF)) && (std_dma_get_flag(DMA_FLAG_TF0))) { std_dma_clear_flag(DMA_CLEAR_TF0); rt_sem_release(uart1_rx_sem); } if ((std_dma_get_interrupt_enable(UART1_DMA_RX_CHANNEL, DMA_INTERRUPT_TE)) && (std_dma_get_flag(DMA_FLAG_TE0))) { std_dma_clear_flag(DMA_CLEAR_TE0); } /* Implement other events when needed */ /* leave interrupt */ rt_interrupt_leave(); } #endif /** * @brief DMA通道1中断服务函数 * @retval 无 */ void DMA_Channel1_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); /* DMA传输完成中断服务 */ if ((std_dma_get_interrupt_enable(UART1_DMA_TX_CHANNEL, DMA_INTERRUPT_TF)) && (std_dma_get_flag(DMA_FLAG_TF1))) { std_dma_clear_flag(DMA_CLEAR_TF1); lwrb_skip(&uart1_tx_rb, _uart1_tx_dma_current_len); /* Skip buffer, it has been successfully sent out */ _uart1_tx_dma_current_len = 0; /* Reset data length */ _UART1_StartTxDMATransfer(); } /* leave interrupt */ rt_interrupt_leave(); } /** * @brief USART1 中断服务函数 * @retval 无 */ void USART1_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); #ifndef UART1_DMA_RX_ENABLE /* 接收到字节 */ if (((std_usart_get_cr1_interrupt_enable(USART1, USART_CR1_INTERRUPT_RXNE)) && (std_usart_get_flag(USART1, USART_FLAG_RXNE))) != RESET) { uint8_t data = (uint8_t)std_usart_rx_read_data(USART1); lwrb_write(&uart1_rx_rb, &data, 1); } #endif /* USART 空闲中断 */ if (((std_usart_get_cr1_interrupt_enable(USART1, USART_CR1_INTERRUPT_IDLE)) && (std_usart_get_flag(USART1, USART_FLAG_IDLE))) != RESET) { std_usart_clear_flag(USART1, USART_CLEAR_IDLE); #ifdef DEBUG_OUTPUT_SELECT #ifdef UART1_DMA_RX_ENABLE rt_sem_release(uart1_rx_sem); rt_sem_release(uart1_rx_ok_sem); #else rt_sem_release(uart1_rx_ok_sem); #endif //! UART1_DMA_RX_ENABLE #endif //! DEBUG_OUTPUT_SELECT } /* leave interrupt */ rt_interrupt_leave(); } /** * @brief UART2中断服务函数 * @retval 无 */ void UART2_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); /* 检查到RXNE标志置1后读取接收数据 */ if (((std_usart_get_cr1_interrupt_enable(UART2, USART_CR1_INTERRUPT_RXNE)) && (std_usart_get_flag(UART2, USART_FLAG_RXNE))) != RESET) { uint8_t data = (uint8_t)std_usart_rx_read_data(UART2); lwrb_write(&uart2_rx_rb, &data, 1); } /* leave interrupt */ rt_interrupt_leave(); } #ifdef UART3_4_ENABLE /** * @brief UART3中断服务函数 * @retval 无 */ void UART3_4_IRQHandler(void) { uint8_t data = 0; /* enter interrupt */ rt_interrupt_enter(); /* 检查到RXNE标志置1后读取接收数据 */ if (((std_usart_get_cr1_interrupt_enable(UART3, USART_CR1_INTERRUPT_RXNE)) && (std_usart_get_flag(UART3, USART_FLAG_RXNE))) != RESET) { data = (uint8_t)std_usart_rx_read_data(UART3); lwrb_write(&uart3_rx_rb, &data, 1); } /* 检查到发送寄存器为空标志置1后写入发送数据 */ if (((std_usart_get_cr1_interrupt_enable(UART3, USART_CR1_INTERRUPT_TXE)) && (std_usart_get_flag(UART3, USART_FLAG_TXE))) != RESET) { if (lwrb_get_full(&uart3_tx_rb)) { lwrb_read(&uart3_tx_rb, &data, 1); std_usart_tx_write_data(UART3, data); } else { std_usart_cr1_interrupt_disable(UART3, USART_CR1_INTERRUPT_TXE); } } /* 检测到发送完成中断 */ if (((std_usart_get_cr1_interrupt_enable(UART3, LPUART_CR1_INTERRUPT_TC)) && (std_usart_get_flag(UART3, USART_FLAG_TC))) != RESET) { std_usart_clear_flag(UART3, LPUART_FLAG_TC); /* 禁止发送完成中断*/ std_usart_cr1_interrupt_disable(UART3, USART_CR1_INTERRUPT_TC); } if (((std_usart_get_cr1_interrupt_enable(UART3, USART_CR3_INTERRUPT_ERR)) && (std_usart_get_flag(UART3, USART_FLAG_ORE))) != RESET) { std_usart_clear_flag(UART3, USART_FLAG_TC); data = (uint8_t)std_usart_rx_read_data(UART3); } /* leave interrupt */ rt_interrupt_leave(); } #endif /** * @brief LPUART中断服务函数 * @retval 无 */ void LPUART1_IRQHandler(void) { /* enter interrupt */ rt_interrupt_enter(); uint8_t data = 0; /* 检查到RXNE标志置1后读取接收数据 */ if (((std_lpuart_cr1_get_interrupt_enable(LPUART1, LPUART_CR1_INTERRUPT_RXNE)) && (std_lpuart_get_flag(LPUART1, LPUART_FLAG_RXNE))) != RESET) { data = (uint8_t)std_lpuart_rx_data_read(LPUART1); lwrb_write(&lpuart1_rx_rb, &data, 1); } /* 检查到发送寄存器为空标志置1后写入发送数据 */ if (((std_lpuart_cr1_get_interrupt_enable(LPUART1, LPUART_CR1_INTERRUPT_TXE)) && (std_lpuart_get_flag(LPUART1, LPUART_FLAG_TXE))) != RESET) { if (lwrb_get_full(&lpuart1_tx_rb)) { lwrb_read(&lpuart1_tx_rb, &data, 1); std_lpuart_tx_data_write(LPUART1, data); } else { std_lpuart_cr1_interrupt_disable(LPUART1, LPUART_CR1_INTERRUPT_TXE); } } /* 检测到发送完成中断 */ if (((std_lpuart_cr1_get_interrupt_enable(LPUART1, LPUART_CR1_INTERRUPT_TC)) && (std_lpuart_get_flag(LPUART1, LPUART_FLAG_TC))) != RESET) { std_lpuart_clear_flag(LPUART1, LPUART_FLAG_TC); /* 禁止发送完成中断*/ std_lpuart_cr1_interrupt_disable(LPUART1, LPUART_CR1_INTERRUPT_TC); } if (((std_lpuart_cr1_get_interrupt_enable(LPUART1, USART_CR3_INTERRUPT_ERR)) && (std_lpuart_get_flag(LPUART1, LPUART_FLAG_ORE))) != RESET) { std_lpuart_clear_flag(LPUART1, LPUART_FLAG_TC); data = (uint8_t)std_lpuart_rx_data_read(LPUART1); } /* leave interrupt */ rt_interrupt_leave(); } static int _UART_SemCreate(void) { #ifdef UART1_DMA_RX_ENABLE uart1_rx_sem = rt_sem_create("uart1_rx_sem", 0, RT_IPC_FLAG_FIFO); if (uart1_rx_sem == RT_NULL) { LOG_D("create uart1_rx_sem create fail"); } #endif #ifdef DEBUG_OUTPUT_SELECT uart1_rx_ok_sem = rt_sem_create("uart1_rx_ok_sem", 0, RT_IPC_FLAG_FIFO); if (uart1_rx_ok_sem == RT_NULL) { RTT_LOG_D("create uart1_rx_ok_sem create fail"); } #endif // 采用软件定时器方式,检测串口接收是否完成 uart2_rx_timer = rt_timer_create("uart2_rx_time", Uart2_Rx_Complate_Check_Entry, RT_NULL, 10, RT_TIMER_FLAG_PERIODIC); if (uart2_rx_timer != RT_NULL) rt_timer_start(uart2_rx_timer); /* 启动定时器 */ #ifdef UART3_4_ENABLE uart3_rx_timer = rt_timer_create("uart3_rx_time", Uart3_Rx_Complate_Check_Entry, RT_NULL, 10, RT_TIMER_FLAG_PERIODIC); if (uart3_rx_timer != RT_NULL) rt_timer_start(uart3_rx_timer);/* 启动定时器 */ #endif lpuart1_rx_timer = rt_timer_create("lp1_rx_time", Lpuart_Rx_Complate_Check_Entry, RT_NULL, 10, RT_TIMER_FLAG_PERIODIC); if (lpuart1_rx_timer != RT_NULL) rt_timer_start(lpuart1_rx_timer); /* 启动定时器 */ #ifdef UART1_DMA_RX_ENABLE if (rt_thread_init(&uart1_rx_thread, "uart1_rx_thread", Uart1_Rx_Thread_Entry, RT_NULL, &uart1_rx_thread_stack[0], sizeof(uart1_rx_thread_stack), UART1_RX_THREAD_PRIORITY, UART1_RX_THREAD_TIMESLICE) == RT_EOK) { LOG_I("startup uart1_dma_rx_thread return = %d", rt_thread_startup(&uart1_rx_thread)); } #endif // return 0; } INIT_PREV_EXPORT(_UART_SemCreate); int rt_hw_usart_init(void) { __UART1_Init(BAUD_RATE_921600, USART_PARITY_NONE); // 这个是初始化串口配置,下面的是对接设备框架 return 0; } INIT_PREV_EXPORT(rt_hw_usart_init); #if 0 /*串口注册设备,主要用于AT设备的对接*/ static rt_size_t rt_serial_read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size) { struct rt_serial_device *serial; RT_ASSERT(dev != RT_NULL); if (size == 0) return 0; // TODO:这里得要判断一下,是那个串口缓冲区得数据,就调用那个缓冲器BUF, if (AT_DEVICE_NAME == "uart3") { // TODO:需要实现这个读函数 return UART3_Read(buffer, size); } } static rt_size_t rt_serial_write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size) { RT_ASSERT(dev != RT_NULL); if (size == 0) return 0; // TODO:这里得要判断一下,是那个串口缓冲区得数据,就调用那个缓冲器BUF, if (AT_DEVICE_NAME == "uart2") { // TODO:需要实现这个读函数 return UART3_Write(buffer, size); } } /** * @brief Register the serial device. * @param serial RT-thread serial device. * @param name The device driver's name * @param flag The capabilities flag of device. * @param data The device driver's data. * @return Return the status of the operation. */ rt_err_t rt_hw_serial_register(struct rt_serial_device *serial, const char *name, rt_uint32_t flag, void *data) { rt_err_t ret; struct rt_device *device; RT_ASSERT(serial != RT_NULL); device = &(serial->parent); device->type = RT_Device_Class_Char; device->rx_indicate = RT_NULL; device->tx_complete = RT_NULL; device->init = RT_NULL; device->open = RT_NULL; device->close = RT_NULL; device->read = rt_serial_read; device->write = rt_serial_write; device->control = RT_NULL; device->user_data = data; /* register a character device */ ret = rt_device_register(device, name, flag); return ret; } static struct ciu32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0}; int rt_hw_usart_init(void) { __UART1_Init(BAUD_RATE_115200, USART_PARITY_NONE); // 这个是初始化串口配置,下面的是对接设备框架 rt_size_t obj_num = sizeof(uart_obj) / sizeof(struct ciu32_uart); struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; rt_err_t result = 0; /*在此修改不属于默认参数的值*/ for (int i = 0; i < obj_num; i++) { /* init UART object */ uart_obj[i].config = &uart_config[i]; uart_obj[i].serial.config = config; /* register UART device */ result = rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, &uart_obj[i]); RT_ASSERT(result == RT_EOK); } return result; } INIT_BOARD_EXPORT(rt_hw_usart_init); #endif // !0