CIU32_L051_M307R/drivers/src/drv_uart.c

1175 lines
33 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.

/************************************************************************************************/
/**
* @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 <ulog.h>
// #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