AM64x MCU+ SDK  08.02.00
UART

UART is used to translate the data between the chip and a serial port. The UART driver provides API to perform read and write to any of the UART peripherals on the board, with the multiple modes of operation.

Features Supported

SysConfig Features

Note
It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.

SysConfig can be used to configure below parameters apart from common configuration like Clock,MPU,RAT and others.

  • UART module configuration parmaters like baudrate, parity type, datalength and others.
  • UART instances and pin configurations.
  • Interrupt mode option is used to select one of the following.
    • Polling Mode.
    • Interrupt Mode in which driver manages the interrupt service routine.
    • User Managed Interrupt in which user manages the interrupt service routine. This mode can be used in low latency applications.
  • Based on above parameters, the SysConfig generated code does below as part of Drivers_open and Drivers_close functions
    • Set UART instance parameter configuration.
    • Driver ISR registration if Interrupt Mode is enabled.
    • Skip driver ISR registration if "User Managed Interrupt" mode is configured.
  • In case of DMA mode, please configure UDMA instance to PKTDMA_0.

Features NOT Supported

  • UART_READ_RETURN_MODE_PARTIAL is not supported in DMA mode of operation
  • MODEM control functions
  • IrDA(Infrared Data Association) and CIR(Consumer Infrared) features

Usage Overview

API Sequence

To use the UART driver to send data or receive, the application calls the following APIs:

  • UART_init() : Initialize the UART driver.
  • UART_Params_init(): Initialize a UART_Params structure with default values. Then change the parameters from non-default values as needed.
  • UART_open() : Open an instance of the UART driver, passing the initialized parameters, or NULL, and an index to the configuration to open (detailed later).
  • UART_write(): Transmit data. This function takes a UART_Transaction argument that describes the transfer that is requested.
  • UART_read() : Receive data. This function takes a UART_Transaction argument that describes the receive that is requested.
  • UART_close(): De-initialize the UART instance.
  • UART_deinit(): De-Initialize the UART driver.

Initializing the UART Driver

UART_init() must be called before any other UART APIs. This function iterates through the elements of the UART_config[] array, calling the element's device implementation UART initialization function. Please note that initializing UART driver is taken care by the SysConfig generated code.

Opening the UART Driver

After initializing the UART driver by calling UART_init(), the application can open a UART instance by calling UART_open(). Please note that opening UART driver is taken care by the SysConfig generated code. This function takes an index into the UART_config[] array, and the UART parameters data structure. The UART instance is specified by the index of the UART in UART_config[]. Calling UART_open() second time with the same index previously passed to UART_open() will result in an error. You can, though, re-use the index if the instance is closed via UART_close().

If no UART_Params_init structure is passed to UART_open(), default values are used. If the open call is successful, it returns a non-NULL value.

UART Write Mode

The UART driver supports two transfer modes of operation: interrupt and polling mode. In polling mode a task's code execution is blocked until a UART transaction has completed or a timeout has occurred.

In interrupt mode, again there are two modes blocking and callback. The transfer mode is determined by the UART_Params.writeMode parameter. The UART driver defaults to blocking mode, if the application does not set it. Once a UART driver is opened, the only way to change the operation mode is to close and re-open the UART instance with the new write mode.

In blocking mode, a task's code execution is blocked until a UART transaction has completed or a timeout has occurred. This ensures that only one UART transfer operates at a given time. Other tasks requesting UART transfers while a transfer is currently taking place will receive an error as return value. If a timeout occurs the transfer is cancelled, the task is unblocked & will receive an error as return value. The transaction count field will have the number of bytes transferred successfully before the timeout.

In callback mode, a UART transaction functions asynchronously, which means that it does not block code execution. After a UART transaction has been completed, the UART driver calls a user-provided callback function. Callback mode is supported in the execution context of tasks and hardware interrupt routines.

UART Read Mode

The UART driver supports two read modes of operation: interrupt and polling mode. In polling mode a task's code execution is blocked until a UART transaction has completed or a timeout has occurred.

In interrupt mode, again there are two modes blocking and callback. The read mode is determined by the UART_Params.readMode parameter. The UART driver defaults to blocking mode, if the application does not set it. Once a UART driver is opened, the only way to change the operation mode is to close and re-open the UART instance with the new read mode.

In blocking mode, a task's code execution is blocked until a UART transaction has completed or a timeout has occurred. This ensures that only one UART read completes at a given time. Other tasks requesting UART read while a read is currently taking place will receive an error as return value. If a timeout occurs the read is cancelled, the task is unblocked & will receive an error as return value. The transaction count field will have the number of bytes read successfully before the timeout.

In callback mode, a UART transaction functions asynchronously, which means that it does not block code execution. After a UART transaction has been completed, the UART driver calls a user-provided callback function. Callback mode is supported in the execution context of tasks and hardware interrupt routines.

There is an additional UART_Params.readReturnMode parameter. UART_READ_RETURN_MODE_FULL unblocks or performs a callback when the read buffer has been filled with the number of bytes passed to UART_read(). UART_READ_RETURN_MODE_PARTIAL unblocks or performs a callback whenever a read timeout error occurs on the UART peripheral. The read timeout occurs if the read FIFO is non-empty and no new data has been received for a specific number of clock cycles w.r.o device/baudrate dependent. This mode can be used when the exact number of bytes to be read is not known.

Important Usage Guidelines

  • In case of DMA mode, as R5F core is not Cache Coherent, Cache Writeback is required if R5F writes to the buffers. And before reading the buffers, application needs to invalidate those. Please refer UART Echo DMA.

Example Usage

Include the below file to access the APIs

#include <drivers/uart.h>

Instance Open Example

UART_Params params;
UART_Params_init(&params); /* Initialize parameters */
params.baudRate = 115200;
gUartHandle = UART_open(CONFIG_UART0, &params);
DebugP_assert(gUartHandle != NULL);

Instance Close Example

UART_close(gUartHandle);

Write Transfer Example

int32_t transferOK;
UART_Transaction transaction;
uint8_t txBuffer[APP_UART_MSGSIZE];
UART_Transaction_init(&transaction);
/* Initiate write */
transaction.count = APP_UART_MSGSIZE;
transaction.buf = (void *)txBuffer;
transaction.args = NULL;
transferOK = UART_write(gUartHandle, &transaction);
if((SystemP_SUCCESS != transferOK) ||
{
/* UART transfer failed!! */
DebugP_assert(FALSE);
}

Read Transfer Example

int32_t transferOK;
UART_Transaction transaction;
uint8_t rxBuffer[APP_UART_MSGSIZE];
UART_Transaction_init(&transaction);
/* Initiate read */
transaction.count = APP_UART_MSGSIZE;
transaction.buf = (void *)rxBuffer;
transaction.args = NULL;
transferOK = UART_read(gUartHandle, &transaction);
if((SystemP_SUCCESS != transferOK) ||
{
/* UART transfer failed!! */
DebugP_assert(FALSE);
}

Write Non-Blocking Transfer Example

void write_callback(UART_Handle handle, UART_Transaction *trans)
{
gNumBytesWritten = trans->count;
SemaphoreP_post(&gUartWriteDoneSem);
return;
}
void write_transfer_nonblocking(void)
{
int32_t transferOK;
UART_Transaction transaction;
uint8_t txBuffer[APP_UART_MSGSIZE];
UART_Transaction_init(&transaction);
/* Initiate write */
transaction.count = APP_UART_MSGSIZE;
transaction.buf = (void *)txBuffer;
transaction.args = NULL;
transferOK = UART_write(gUartHandle, &transaction);
if((SystemP_SUCCESS != transferOK) ||
{
/* UART transfer failed!! */
DebugP_assert(FALSE);
}
else
{
/* Wait for callback */
SemaphoreP_pend(&gUartWriteDoneSem, SystemP_WAIT_FOREVER);
DebugP_assert(gNumBytesWritten == transaction.count);
}
}

Read Non-Blocking Transfer Example

void read_callback(UART_Handle handle, UART_Transaction *trans)
{
gNumBytesRead = trans->count;
SemaphoreP_post(&gUartReadDoneSem);
return;
}
void read_transfer_nonblocking(void)
{
int32_t transferOK;
UART_Transaction transaction;
uint8_t rxBuffer[APP_UART_MSGSIZE];
UART_Transaction_init(&transaction);
/* Initiate read */
transaction.count = APP_UART_MSGSIZE;
transaction.buf = (void *)rxBuffer;
transaction.args = NULL;
transferOK = UART_read(gUartHandle, &transaction);
if((SystemP_SUCCESS != transferOK) ||
{
/* UART transfer failed!! */
DebugP_assert(FALSE);
}
else
{
/* Wait for callback */
DebugP_assert(gNumBytesRead == transaction.count);
}
}

API

APIs for UART

UART_Transaction_init
static void UART_Transaction_init(UART_Transaction *trans)
Function to initialize the UART_Transaction struct to its defaults.
Definition: uart/v0/uart.h:875
UART_TRANSFER_STATUS_SUCCESS
#define UART_TRANSFER_STATUS_SUCCESS
Transaction success.
Definition: uart/v0/uart.h:96
UART_Handle
void * UART_Handle
A handle that is returned from a UART_open() call.
Definition: uart/v0/uart.h:85
SystemP_WAIT_FOREVER
#define SystemP_WAIT_FOREVER
Value to use when needing a timeout of infinity or wait forver until resource is available.
Definition: SystemP.h:83
UART_write
int32_t UART_write(UART_Handle handle, UART_Transaction *trans)
Function to perform UART write operation.
UART_close
void UART_close(UART_Handle handle)
Function to close a UART peripheral specified by the UART handle.
UART_Transaction::args
void * args
Definition: uart/v0/uart.h:435
uart.h
DebugP_assertNoLog
#define DebugP_assertNoLog(expression)
Function to call for assert check, no logs are printed.
Definition: DebugP.h:175
UART_Params
UART Parameters.
Definition: uart/v0/uart.h:460
UART_Params::baudRate
uint32_t baudRate
Definition: uart/v0/uart.h:461
SystemP_SUCCESS
#define SystemP_SUCCESS
Return status when the API execution was successful.
Definition: SystemP.h:56
UART_Transaction::status
uint32_t status
Definition: uart/v0/uart.h:433
UART_Transaction
Data structure used with UART_read() and UART_write()
Definition: uart/v0/uart.h:423
UART_open
UART_Handle UART_open(uint32_t index, const UART_Params *prms)
This function opens a given UART peripheral.
SemaphoreP_post
void SemaphoreP_post(SemaphoreP_Object *obj)
Post a semaphore object or unlock a mutex.
UART_Params_init
static void UART_Params_init(UART_Params *prms)
Function to initialize the UART_Params struct to its defaults.
Definition: uart/v0/uart.h:849
UART_read
int32_t UART_read(UART_Handle handle, UART_Transaction *trans)
Function to perform UART read operation.
DebugP_assert
#define DebugP_assert(expression)
Function to call for assert check.
Definition: DebugP.h:159
UART_Transaction::buf
void * buf
Definition: uart/v0/uart.h:424
SemaphoreP_pend
int32_t SemaphoreP_pend(SemaphoreP_Object *obj, uint32_t timeToWaitInTicks)
Pend on a semaphore object or lock a mutex.
UART_Transaction::count
uint32_t count
Definition: uart/v0/uart.h:427