.. include:: ./../../../../macros.txt .. include:: ./../../../../units.txt .. _UART_MODULE: UART Module =========== Module Files ------------ Driver ^^^^^^ - ``src/app/driver/uart/uart.c`` - ``src/app/driver/uart/uart.h`` - ``src/app/driver/dma/dma.c`` Configuration ^^^^^^^^^^^^^ - ``src/app/driver/config/uart_cfg.h`` Unit Test ^^^^^^^^^ - ``tests/unit/app/driver/uart/test_uart.c`` External Description -------------------- The driver exposes three core functionalities, - ``UART_Read()``, - ``UART_Printf()``, and - ``UART_HandleFlowControl()``. ``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``. ``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 ```` and a 128 byte sized buffer (``UART_PRINTF_BUFFER_SIZE``) as the formatting target buffer, which is then transmitted via |uart|. ``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. Internal Description -------------------- 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. 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.