This section introduces the Universal Asynchronous Receiver/Transmitter (UART) APIs including terms and acronyms, supported features, software architecture, details on how to use this driver, UART function groups, enums, structures and functions.
More...
This section introduces the Universal Asynchronous Receiver/Transmitter (UART) APIs including terms and acronyms, supported features, software architecture, details on how to use this driver, UART function groups, enums, structures and functions.
Terms and acronyms
| Terms | Details |
| CTS | This UART pin is used to indicate if the device can transmit data. It is used only when the UART hardware flow control is enabled. |
| GPIO | General Purpose Input Output is a generic pin on an integrated circuit defined as an input or output pin, and controlled by the user at runtime. |
| MCU | Micro Controller Unit is a small computer on a single integrated circuit containing a processor core, memory and programmable input/output peripherals. |
| NVIC | The Nested Vectored Interrupt Controller (NVIC) is the interrupt controller of ARM Cortex-M. |
| RTS | This UART pin is used to indicate if the device can receive data. It is used only when the UART hardware flow control is enabled. |
| RXD | This UART pin is used for receiving data. |
| TX/RX | Abbreviation of Transmit/Receive. |
| TXD | This UART pin is used for sending data. |
| UART | Universal Asynchronous Receiver/Transmitter is usually an individual (or part of an) integrated circuit (IC) used for serial communications over a micro-controller unit (MCU) or peripheral device serial port. For an introduction to UART, please refer to UART in Wikipedia . |
| VFIFO DMA | Virtual First In First Out Direct Memory Access is a special DMA used to transfer data between memory and UART without MCU's handle. |
Supported features
- Support poll and DMA modes.
Based on user configuration, UART operates in different modes:
- Polling mode: In this mode, whether the data has been received or sent is determined by polling the UART status register. To receive data, it reads the data from the data register. To send the data, it writes to the data register. When a task calls the UART driver API in the polling mode, it blocks the other tasks from running, until the API in the polling mode returns.
- DMA mode: In this mode, a separate VFIFO DMA hardware is enabled to transmit or receive data between the VFIFO DMA buffer and the UART hardware. The occupancy rate of the CPU in this mode is very low, as the CPU is not involved in the operation of transmitting or receiving data byte by byte.
- Support two types of flow control modes.
UART flow control mechanism is used to synchronize the data transfer between a receiver and a transmitter to prevent data loss during the transfer.
- Software flow control: Receive operation: UART automatically sends XOFF character to the peer, if there is no space in the receiving FIFO. And automatically sends XON character, if the receiving FIFO becomes available. Transmit operation: UART raises an interrupt and updates the status of the related register when receiving XOFF or XON character. The values of XON and XOFF can be configured if needed.
- Hardware flow control: The UART automatically activates the request to send (RTS) pin when the space in the receiving FIFO becomes available and automatically deactivates the RTS pin when the space in the receiving FIFO is unavailable. Transmit operation: The UART automatically sends the data when it detects the clear to send (CTS) input pin is active. In both receive or transmit operations, UART raises an interrupt if requests to send (RTS) or clear to send (CTS) are active.
- Support custom configuration.
In addition to the default settings of the UART driver APIs, the user has access to auxiliary UART APIs for UART driver configuration to further customize the settings such as baud rate, flow control, escape character and more.
Software architecture of UART
- Polling mode:
In this mode, a user directly calls hal_uart_get_char(), hal_uart_put_char(), hal_uart_receive_polling() or hal_uart_send_polling() to transmit or receive data. UART driver polls the status of UART transmit or receive operation in a loop. Once it's ready, UART driver fetches the data by reading from the data register or sends the data by writing to the data register. The hal_uart_get_char(), hal_uart_put_char(), hal_uart_receive_polling() and hal_uart_send_polling() are blocking calls. The calling to these APIs is blocked until the data has been received or sent. For architecture diagram in this mode, please refer to HAL Driver Model.
- DMA mode:
Unlike polling mode, VFIFO DMA hardware and transmit (TX) or receive (RX) buffers are required to operate in the DMA mode. The VFIFO DMA hardware is a special DMA used with the UART data transmit and receive operations. The VFIFO DMA hardware assists MCU to transmit or receive data and prevents copying the data from buffer byte by byte only by MCU itself. TX/RX buffers are used to cache the data during transmit and receive operations. The UART hardware is not used when the user reads or writes to and from the buffer. It is more useful for the receiving channel, as it's uncertain when the data is received and the user has no option to continuously request UART hardware status.
In this mode, user should call hal_uart_set_dma() function to initialize the DMA hardware before transmitting or receiving the data. The TX/RX buffers are registered in DMA hardware with their corresponding addresses and sizes.
For transmit operation, call hal_uart_send_dma() function to transmit data. UART driver will query free space in the TX buffer, if the free space is greater than or equal to the requested data size, the UART driver will copy user data to the TX buffer and return with requested data length. If the free space is smaller than the requested data size, the UART driver will only copy the user data that fits into the TX buffer and activate the VFIFO DMA TX threshold interrupt. The UART driver will then return the data size that was actually transmitted. The user should check the return value, then decide whether to wait for sending out remaining data when the TX buffer becomes available again. The UART driver triggers a VFIFO DMA interrupt if the data is transmitted partially and the remaining data length is less than the threshold of the transmit buffer. Then the VFIFO DMA interrupt handler is called. The DMA interrupt handler will call user's callback to notify that the transmit buffer is available to transmit data either using callback or user's task. During this period, other tasks can also be performed.
For receive operation, hal_uart_receive_dma() function is used and the UART driver provides the same functionality as during the transmit operation. It also checks the receive buffer and fetches data from the receive buffer until it's empty. If the data length fetched is less than requested length from the user, the UART driver activates the VFIFO DMA RX threshold interrupt. When there is enough data cached in the receive buffer, the VFIFO DMA RX threshold interrupt is triggered. Then the VFIFO DMA RX handler calls the user's callback to notify that the receive buffer is available. User can receive data from the receive buffer again by calling UART HAL receive interface. During this period, other tasks can also be performed. For architecture diagram in this mode, please refer to HAL Driver Model.
How to use this driver
- Configure GPIO pins used by the UART hardware.
- User should configure GPIO pins used by the UART. Those pins include TXD and RXD. If the hardware flow control is enabled, RTS and CTS should be enabled, too. Concerning issues about how to configure UART pins, please refer to GPIO of driver document.
- sample code:
void uart_pinmux_init(void)
{
}
- Use UART in polling mode.
- Use UART in DMA mode.
- Step 1. Call hal_uart_init() to configure the UART in DMA mode.
- Step 2. Call hal_uart_set_dma() to configure the VFIFO DMA hardware. Note: the address should be non_cacheable, for more information, please refer to GDMA part.
- Step 3. Call hal_uart_register_callback() to register a callback function.
- Step 4. Call hal_uart_receive_dma() to receive data from the UART.
- Step 5. Call hal_uart_send_dma() to transmit data to the UART.
- Step 6. Call hal_uart_deinit() to de-initialize the UART port.
- sample code:
static volatile uint32_t receive_notice = 0;
static volatile uint32_t send_notice = 0;
static char rx_vfifo_buffer[512] __attribute__ ((section(".noncached_zidata")));
static char tx_vfifo_buffer[512] __attribute__ ((section(".noncached_zidata")));
static void uart_dma_application(void)
{
char buffer[64];
char *pbuf;
uint32_t left, snd_cnt, rcv_cnt;
char uart_prompt[] = "UART DMA mode begin\n";
left = 64;
pbuf = buffer;
while(1){
left -= rcv_cnt;
pbuf += rcv_cnt;
if(left == 0)
break;
while(!receive_notice);
receive_notice = 0;
}
left = 64;
pbuf = buffer;
while(1){
left -= snd_cnt;
pbuf += snd_cnt;
if(left == 0)
break;
while(!send_notice);
send_notice = 0;
}
}
{
send_notice = 1;
receive_notice = 1;
}
|
| hal_uart_status_t | hal_uart_init (hal_uart_port_t uart_port, hal_uart_config_t *uart_config) |
| | This function initializes the UART hardware with basic functionality. More...
|
| |
| hal_uart_status_t | hal_uart_deinit (hal_uart_port_t uart_port) |
| | This function deinitializes the UART hardware to its default status. More...
|
| |
| void | hal_uart_put_char (hal_uart_port_t uart_port, char byte) |
| | This function places one character at a time to the UART port in a polling mode. More...
|
| |
| char | hal_uart_get_char (hal_uart_port_t uart_port) |
| | This function gets one character from UART port in a polling mode. More...
|
| |
| uint32_t | hal_uart_get_char_unblocking (hal_uart_port_t uart_port) |
| | This function gets one character from UART port in the unblocking polling mode. More...
|
| |
| uint32_t | hal_uart_send_polling (hal_uart_port_t uart_port, const uint8_t *data, uint32_t size) |
| | This function sends user data byte by byte in a polling mode. More...
|
| |
| uint32_t | hal_uart_send_dma (hal_uart_port_t uart_port, const uint8_t *data, uint32_t size) |
| | This function sends user data in a VFIFO DMA mode. More...
|
| |
| uint32_t | hal_uart_receive_polling (hal_uart_port_t uart_port, uint8_t *buffer, uint32_t size) |
| | This function receives data byte by byte in a polling mode. More...
|
| |
| uint32_t | hal_uart_receive_dma (hal_uart_port_t uart_port, uint8_t *buffer, uint32_t size) |
| | This function receives user data in a VFIFO DMA mode. More...
|
| |
| uint32_t | hal_uart_get_available_send_space (hal_uart_port_t uart_port) |
| | This function queries available space in the VFIFO TX buffer. More...
|
| |
| uint32_t | hal_uart_get_available_receive_bytes (hal_uart_port_t uart_port) |
| | This function queries available data in the VFIFO RX buffer. More...
|
| |
| hal_uart_status_t | hal_uart_register_callback (hal_uart_port_t uart_port, hal_uart_callback_t user_callback, void *user_data) |
| | This function registers user's callback in the UART driver. More...
|
| |
| hal_uart_status_t | hal_uart_set_hardware_flowcontrol (hal_uart_port_t uart_port) |
| | This function sets and enables hardware flow control of the UART. More...
|
| |
| hal_uart_status_t | hal_uart_set_software_flowcontrol (hal_uart_port_t uart_port, uint8_t xon, uint8_t xoff, uint8_t escape_character) |
| | This function sets and enables software flow control of the UART. More...
|
| |
| hal_uart_status_t | hal_uart_disable_flowcontrol (hal_uart_port_t uart_port) |
| | This function disables flow control of the UART. More...
|
| |
| hal_uart_status_t | hal_uart_set_baudrate (hal_uart_port_t uart_port, hal_uart_baudrate_t baudrate) |
| | This function sets a baud rate for the UART frame. More...
|
| |
| hal_uart_status_t | hal_uart_set_format (hal_uart_port_t uart_port, const hal_uart_config_t *config) |
| | This function sets the UART's frame parameter. More...
|
| |
| hal_uart_status_t | hal_uart_set_dma (hal_uart_port_t uart_port, const hal_uart_dma_config_t *dma_config) |
| | This function sets the VFIFO DMA hardware relative to the UART. More...
|
| |
This function disables flow control of the UART.
It disables the UART hardware to notify about a peer flow control event by automatically activating or deactivating an RTS output. The UART hardware is disabled to detect flow control indicator from peer based on the CTS input pin. This function will also disable the software flow control.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
- Returns
- HAL_UART_STATUS_OK, if the operation completed successfully.
HAL_UART_STATUS_ERROR_PARAMETER, if parameter is invalid.
HAL_UART_STATUS_ERROR_UNINITIALIZED, if the UART has not been initialized.
This function queries available data in the VFIFO RX buffer.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
- Returns
- Available data of the VFIFO RX buffer.
- Note
- This function is used only in DMA mode.
This function queries available space in the VFIFO TX buffer.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
- Returns
- Available space of the VFIFO TX buffer.
- Note
- This function is used only in a DMA mode.
This function gets one character from UART port in a polling mode.
In this function, driver first polls the status of a UART receive operation in a loop until it's ready. Then driver get the character from UART receive register and return it.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
- Returns
- the characters received from the UART port.
This function gets one character from UART port in the unblocking polling mode.
In this function, driver directly polls the status of a UART receive operation. If data is not ready, return error data (-1). If data is ready, get the character from the UART receive register and return it.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
- Returns
- the character received from the UART port or error code to indicate that there is no valid character in the UART port.
- Example
2 value = hal_uart_get_char_unblocking(HAL_UART_0);
3 if (value == 0xffffffff) {
4 // Get error code, there is no valid character in the UART port.
6 // Get the valid character from the UART port.
This function initializes the UART hardware with basic functionality.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | uart_config | specifies configure parameters for UART hardware initialization. |
- Returns
- HAL_UART_STATUS_OK if OK.
HAL_UART_STATUS_ERROR_BUSY if the UART hardware has been initialized before.
HAL_UART_STATUS_ERROR_PARAMETER if parameter is invalid.
This function places one character at a time to the UART port in a polling mode.
In this function, driver first poll the status of UART transmit in a loop until it's ready. Then driver places the character in the UART transmit register and returns from this function.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | byte | specifies the data to send. |
| uint32_t hal_uart_receive_dma |
( |
hal_uart_port_t |
uart_port, |
|
|
uint8_t * |
buffer, |
|
|
uint32_t |
size |
|
) |
| |
This function receives user data in a VFIFO DMA mode.
In this function, driver first polls the available data in the VFIFO RX buffer. Then driver receives user data from the VFIFO RX buffer and places to the available free space. If the driver can't get all user data from VFIFO RX buffer, it will turn the VFIFO DMA RX interrupt on so that user is notified when VFIFO RX buffer becomes available again. At last, the driver returns the bytes that are received from the VFIFO RX buffer. User should check the outcome to make sure that data is completely received from the VFIFO RX buffer.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | buffer | specifies pointer to the user's data buffer. |
| [in] | size | specifies size of the user's data buffer. |
- Returns
- the characters received from the UART port.
| uint32_t hal_uart_receive_polling |
( |
hal_uart_port_t |
uart_port, |
|
|
uint8_t * |
buffer, |
|
|
uint32_t |
size |
|
) |
| |
This function receives data byte by byte in a polling mode.
In this function, driver first polls the status of a UART receive operation in a loop until it's ready. Then the driver gets the character from the UART transmit register and continues this operation until all user data is received. The final output is to get the character from the UART receive register and return it.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | buffer | specifies pointer to the user's data buffer. |
| [in] | size | specifies size of the user's data buffer. |
- Returns
- the characters received from the UART port.
This function registers user's callback in the UART driver.
This callback is used when the UART operates in a VFIFO DMA mode, then notifies the user if the UART Transmit is ready again. Also this callback is called in the UART VFIFO DMA interrupt handler.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | user_callback | specifies user's callback |
| [in] | user_data | specifies user's data for this callback |
- Returns
- HAL_UART_STATUS_OK, if the operation completed successfully.
HAL_UART_STATUS_ERROR_BUSY, if the UART port is already registered.
HAL_UART_STATUS_ERROR_UNINITIALIZED, if the UART has not been initialized.
HAL_UART_STATUS_ERROR_PARAMETER, if parameter is invalid.
| uint32_t hal_uart_send_dma |
( |
hal_uart_port_t |
uart_port, |
|
|
const uint8_t * |
data, |
|
|
uint32_t |
size |
|
) |
| |
This function sends user data in a VFIFO DMA mode.
In this function, driver first polls the free space in the VFIFO TX buffer. Then driver puts user data into the VFIFO TX buffer, that fits into the free space. If driver can't put all user data into VFIFO TX buffer, it will turn the VFIFO DMA TX interrupt on so that user is notified when VFIFO TX buffer becomes available again. At last, the driver returns the bytes that are placed in the VFIFO TX buffer. User should check the outcome to make sure that data is completely placed in the VFIFO TX buffer.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | data | specifies pointer to the user's data buffer. |
| [in] | size | specifies size of the user's data buffer. |
- Returns
- bytes of transmitted data.
- Note
- User must call hal_uart_init() before calling this function.
| uint32_t hal_uart_send_polling |
( |
hal_uart_port_t |
uart_port, |
|
|
const uint8_t * |
data, |
|
|
uint32_t |
size |
|
) |
| |
This function sends user data byte by byte in a polling mode.
In this function, driver first poll status of UART transmit in a loop until it's ready. Then driver put the character into UART transmit register. Driver continues this operation until all user data is sent out, then it returns the transmitted bytes.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | data | specifies pointer to the user's data buffer. |
| [in] | size | specifies size of the user's data buffer. |
- Returns
- bytes of transmitted data.
This function sets a baud rate for the UART frame.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | baudrate | specifies baud rate for the UART frame. |
- Returns
- HAL_UART_STATUS_OK, if the operation completed successfully.
HAL_UART_STATUS_ERROR_PARAMETER, if parameter is invalid.
HAL_UART_STATUS_ERROR_UNINITIALIZED, if the UART has not been initialized.
- Example
1 hal_uart_set_baudrate(HAL_UART_0, HAL_UART_BAUDRATE_115200);
This function sets the VFIFO DMA hardware relative to the UART.
With the help of the VFIFO DMA hardware, MCU doesn't need to copy data between the user buffer and the UART FIFO byte by byte. The MCU will be open to other tasks while the VFIFO DMA is copying data. The user is required to set threshold, address and size of the VFIFO TX/RX buffer for its proper operation.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | dma_config | specifies a user defined VFIFO DMA configuration parameter. |
- Returns
- HAL_UART_STATUS_OK, if the operation completed successfully.
HAL_UART_STATUS_ERROR_PARAMETER, if parameter is invalid.
HAL_UART_STATUS_ERROR_UNINITIALIZED, if UART has not been initialized.
- Note
- This function must be called after hal_uart_init().
This function sets the UART's frame parameter.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | config | specifies a user defined frame parameter. |
- Returns
- HAL_UART_STATUS_OK, if the operation completed successfully.
HAL_UART_STATUS_ERROR_PARAMETER, if parameter is invalid.
HAL_UART_STATUS_ERROR_UNINITIALIZED, if the UART has not been initialized.
- Example
1 hal_uart_config_t uart_config;
3 uart_config.baudrate = HAL_UART_BAUDRATE_921600;
4 uart_config.parity = HAL_UART_PARITY_NONE;
5 uart_config.stop_bit = HAL_UART_STOP_BIT_1;
6 uart_config.word_length = HAL_UART_WORD_LENGTH_8;
8 hal_uart_set_format(HAL_UART_0, &uart_config);
This function sets and enables hardware flow control of the UART.
It enables the UART hardware to notify about a peer flow control event by automatically activating or deactivating an RTS output. Also the UART hardware can detect flow control indicator from peer based on the CTS input pin. For both RTS and CTS events, the UART hardware triggers interrupts.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
- Returns
- HAL_UART_STATUS_OK, if the operation completed successfully.
HAL_UART_STATUS_ERROR_PARAMETER, if parameter is invalid.
HAL_UART_STATUS_ERROR_UNINITIALIZED, if the UART has not been initialized.
This function sets and enables software flow control of the UART.
It enables the UART hardware to notify about a peer flow control event by sending an automatic XON or XOFF output. Also the UART hardware can issue flow control events if it receives XON or XOFF characters. For both transmit and receive operations, the UART hardware triggers interrupts. For transmit operation, escape characters are inserted before XON, XOFF and itself. For receive operation, if the UART hardware receives an escape character, it then reverses the consecutive byte and places it in the receive FIFO.
- Parameters
-
| [in] | uart_port | initializes the specified UART port number. |
| [in] | xon | specifies user defined XON character that indicates if the data transmission is turned on. |
| [in] | xoff | specifies user defined XOFF character that indicates if the data transmission is turned off. |
| [in] | escape_character | specifies a user defined escape character. |
- Returns
- HAL_UART_STATUS_OK, if the operation completed successfully.
HAL_UART_STATUS_ERROR_PARAMETER, if parameter is invalid.
HAL_UART_STATUS_ERROR_UNINITIALIZED, if the UART has not been initialized.
- Example
3 uint8_t escape_character = 0x77;
5 hal_uart_set_software_flowcontrol(HAL_UART_0, xon, xoff, escape_character);