2.3. UART
2.3.1. Introduction
UART is a universal asynchronous transmitter-receiver, which provides a flexible way for full-duplex data exchange with external devices. The UART device in BL series MCU has the following characteristics:
Data bit length can choose 5/6/7/8 bits
Stop bit length can be selected 0.5/1/1.5/2 bits
Support odd/even/no parity bit
Support hardware flow control (RTS/CTS)
Automatic baud rate detection
Support LIN protocol (transceive BREAK/SYNC)
Send/receive FIFO
Support polling, interrupt, DMA transfer
Unique rto interrupt
2.3.2. UART Device Structure Definition
typedef struct uart_device
{
struct device parent;
uint8_t id;
uint32_t baudrate;
uart_databits_t databits;
uart_stopbits_t stopbits;
uart_parity_t parity;
uint8_t fifo_threshold;
void* tx_dma;
void* rx_dma;
} uart_device_t;
parent inherit the properties of the parent class
id serial port id, if serial port 0 is enabled, id is 0, if serial port 1 is enabled, id is 1, and so on
baudrate baud rate
databits data bits
stopbits stop bits
parity parity
fifo_threshold fifo threshold, the maximum value of different mcu is different
tx_dma additional send dma handle
rx_dma additional receive dma handle
databits
provides the following types
typedef enum
{
UART_DATA_LEN_5 = 0, /*!< Data length is 5 bits */
UART_DATA_LEN_6 = 1, /*!< Data length is 6 bits */
UART_DATA_LEN_7 = 2, /*!< Data length is 7 bits */
UART_DATA_LEN_8 = 3 /*!< Data length is 8 bits */
} uart_databits_t;
stopbits
provides the following types
typedef enum
{
UART_STOP_ONE = 0, /*!< One stop bit */
UART_STOP_ONE_D_FIVE = 1, /*!< 1.5 stop bit */
UART_STOP_TWO = 2 /*!< Two stop bits */
} uart_stopbits_t;
parity
provides the following types
typedef enum
{
UART_PAR_NONE = 0, /*!< No parity */
UART_PAR_ODD = 1, /*!< Parity bit is odd */
UART_PAR_EVEN = 2, /*!< Parity bit is even */
} uart_parity_t;
2.3.3. UART Device Parameter Configuration Table
Each UART device has a parameter configuration macro, the macro definition is located in the peripheral_config.h
file under the bsp/board/xxx
directory, and the variable definition is located in hal_uart.c
, so the user does not need to define variable. When the user opens the macro of the corresponding device, the configuration of the device will take effect. For example, open the macro BSP_USING_UART0
, UART0_CONFIG
will take effect, and the UART0
device can be registered and used.
/*Parameter configuration macro*/
#if defined(BSP_USING_UART0)
#ifndef UART0_CONFIG
#define UART0_CONFIG \
{ \
.id = 0, \
.baudrate = 2000000,\
.databits = UART_DATA_LEN_8, \
.stopbits = UART_STOP_ONE, \
.parity = UART_PAR_NONE, \
.fifo_threshold = 1, \
}
#endif
#endif
/*Variable definitions*/
static uart_device_t uartx_device[UART_MAX_INDEX] =
{
#ifdef BSP_USING_UART0
UART0_CONFIG,
#endif
#ifdef BSP_USING_UART1
UART1_CONFIG,
#endif
};
备注
The above configuration can be modified through UART_DEV(dev)->xxx
and can only be used before calling device_open
.
2.3.4. UART Device Interface
UART device interface follows which provided by the standard device driver management layer.
2.3.4.1. uart_register
uart_register
is used to register a UART device standard driver interface. Before registering, you need to open the macro definition of the corresponding UART device. For example, define the macro BSP_USING_UART0
to use the UART0
device. After the registration is completed, other interfaces can be used. If the macro is not defined, the UART0
device cannot be used.
int uart_register(enum uart_index_type index, const char *name);
index the index of the device to be registered
name device name
index
is used to select UART device configuration, one index corresponds to a UART device configuration, such as UART0_INDEX
corresponds to UART0_CONFIG
configuration, index
has the following optional types
enum uart_index_type
{
#ifdef BSP_USING_UART0
UART0_INDEX,
#endif
#ifdef BSP_USING_UART1
UART1_INDEX,
#endif
UART_MAX_INDEX
};
2.3.4.2. device_open
device_open
is used to open a UART device, this funtion calls uart_open
actually.
int device_open(struct device *dev, uint16_t oflag);
dev device handle
oflag open mode
return error code, 0 means opening is successful, others mean errors
oflag
provides the following types
#define DEVICE_OFLAG_STREAM_TX 0x001 /* The device is turned on in polling sending mode */
#define DEVICE_OFLAG_STREAM_RX 0x002 /* The device is turned on in rotation receiving mode */
#define DEVICE_OFLAG_INT_TX 0x004 /* The device is turned on in interrupt sending mode */
#define DEVICE_OFLAG_INT_RX 0x008 /* The device is turned on in interrupt receiving mode */
#define DEVICE_OFLAG_DMA_TX 0x010 /* The device is turned on in DMA transmission mode */
#define DEVICE_OFLAG_DMA_RX 0x020 /* The device is turned on in DMA receiving mode */
2.3.4.3. device_close
device_close
is used to close a UART device,this funtion calls uart_close
actually.
int device_close(struct device *dev);
dev device handle
return error code, 0 means closing is successful, others mean error
2.3.4.4. device_control
device_control
is used to control and modify the parameters of the UART device according to commands.This funtion calls uart_control
actually.
int device_control(struct device *dev, int cmd, void *args);
dev device handle
cmd device control command
args control parameters
return different control commands return different meanings.
In addition to standard control commands, UART device also has its own special control commands.
#define DEVICE_CTRL_UART_GET_TX_FIFO 0x10
#define DEVICE_CTRL_UART_GET_RX_FIFO 0x11
args
input is different depending on cmd
, the list is as follows:
cmd |
args |
description |
---|---|---|
DEVICE_CTRL_SET_INT |
uart_it_type |
Enable uart device interrupt |
DEVICE_CTRL_CLR_INT |
uart_it_type |
Disable uart device interrupt |
DEVICE_CTRL_CONFIG |
uart_param_cfg_t* |
Modify the serial port configuration |
DEVICE_CTRL_ATTACH_TX_DMA |
NULL |
Link to tx dma device |
DEVICE_CTRL_ATTACH_RX_DMA |
NULL |
Link to rx dma device |
DEVICE_CTRL_TX_DMA_SUSPEND |
NULL |
Suspend uart tx dma mode |
DEVICE_CTRL_RX_DMA_SUSPEND |
NULL |
Suspend uart rx dma mode |
DEVICE_CTRL_TX_DMA_RESUME |
NULL |
Resume uart tx dma mode |
DEVICE_CTRL_RX_DMA_RESUME |
NULL |
Resume uart rx dma mode |
DEVICE_CTRL_UART_GET_TX_FIFO |
uint32_t* |
Get the number of uart tx fifo |
DEVICE_CTRL_UART_GET_RX_FIFO |
uint32_t* |
Get the number of uart rx fifo |
2.3.4.5. device_write
device_write
is used to send data. The sending mode can be polling, interrupt, dma according to the open mode.This funtion calls uart_write
actually.
int device_write(struct device *dev, uint32_t pos, const void *buffer, uint32_t size);
dev device handle
pos useless
buffer the buffer to be written
size the length to be written
return error code, 0 means writing is successful, others mean errors
2.3.4.6. device_read
device_read
is used to receive data. The receiving mode can be polling, interrupt, dma according to the open mode.This funtion calls uart_read
actually.
int device_read(struct device *dev, uint32_t pos, void *buffer, uint32_t size);
dev device handle
pos useless
buffer the buffer to be read
size the length to be read
return error code, 0 means successful reading, others mean errors
2.3.4.7. device_set_callback
device_set_callback
is used to register a uart interrupt callback function.
int device_set_callback(struct device *dev, void (*callback)(struct device *dev, void *args, uint32_t size, uint32_t event));
dev device handle
callback the interrupt callback function to be registered
dev device handle
args receive and send buffer, the data type is uint8_t*
size transmission length
event interrupt event type
event
type definition is as follows:
enum uart_event_type
{
UART_EVENT_TX_END,
UART_EVENT_TX_FIFO,
UART_EVENT_RX_END,
UART_EVENT_RX_FIFO,
UART_EVENT_RTO,
UART_EVENT_UNKNOWN
};