4.44. UART Module

4.44.1. Module Files

4.44.1.1. Driver

  • src/app/driver/uart/uart.c

  • src/app/driver/uart/uart.h

  • src/app/driver/dma/dma.c

4.44.1.2. Configuration

  • src/app/driver/config/uart_cfg.h

4.44.1.3. Unit Test

  • tests/unit/app/driver/uart/test_uart.c

4.44.2. External Description

The driver exposes three core functionalities, - UART_Read(), - UART_Printf(), and - UART_HandleFlowControl().

4.44.2.1. UART_Read()

The reading functionality of the UART module is exposed via UART_Read(). UART_Read() attempts to read nrBytes from the UART reception queue ftsk_uartRxQueue into readData and returns the actual number of bytes read into readData.

4.44.2.2. UART_Printf()

The writing functionality is exposed via UART_Printf() . UART_Printf() is a variadic function similar to C’s standard printf(). It takes a formatting string pcFormatString as its first parameter and then an arbitrary number of additional parameters. In the background it uses C’s vsnprintf from <stdio.h> and a 128 byte sized buffer (UART_PRINTF_BUFFER_SIZE) as the formatting target buffer, which is then transmitted via UART.

4.44.2.3. UART_HandleFlowControl()

The flow control for UART is implemented entirely in software and is handled by UART_HandleFlowControl(). It is implemented as a standard XON/XOFF flow control scheme, with the macros UART_UPPER_CUTOFF and UART_LOWER_CUTOFF defining the upper and lower limits as a percentage of the length of the UART reception queue.

4.44.3. Internal Description

4.44.3.1. Reception

The reception works interrupt driven. On initialization of the UART driver the function sciReceive() is called with nrBytes = 1. sciReceive() is generated by TI HALCoGen and handles, as long as RX Interrupts are enabled for the SCI interface, the reception. When a byte is received an interrupt is triggered first calling the corresponding sciXYLevelInterrupt() function. X being the SCI interface (here 4 for SCI4) and Y being either High or Low based on the TI HALCoGen configuration for the SCI interface (here it is High). Since sciReceive() was configured to only receive a single byte, a call to sciNotification() is made. sciNotification() first calls UART_RxInterrupt() which handles the flow control reception of XON and XOFF, and inserts non flow control bytes into the UART reception queue ftsk_uartRxQueue. Secondly it calls sciReceive(), again with nrBytes = 1, to receive the next byte.

4.44.3.2. Transmission

The transmission of data via UART utilizes DMA (direct-memory access) to free the CPU during the data transfer between the RAM of the microcontroller and the SCI. UART_Write() sets up the individual DMA transfers, by writing to the DMA channel control package and enabling DMA interrupts for the SCI interface. The writes to the control package have to be performed in privilege mode and the binary semaphore uart_txSemaphore is used guard the DMA access. Once the DMA transfer is completed, the DMA interrupt is triggered and handled in dmaGroupANotification(). There the DMA interrupt for the SCI is disabled again and the semaphores guarding DMA and the UART_Printf-Buffer are returned.