TM4C123G Launchpad UART Programming
EK-TM4C123GXL Launchpad UART Programming
- Many of the TI ARM chips come with up to eight on-chip UART ports. They are designated as UART0 - UART7.
- In the TI LaunchPad, the UART0 port of the TM4C123GH6PM is connected to the ICDI (In-Circuit Debug Interface), which is connected to a USB connector.
- This ICDI USB connection contains three distinct functions:
- Programming (downloading) using LM Flash Programming software
- Debugging using JTAG (Stellaris In-Circuit Debug Interface)
- To use as a virtual COM port
Virtual COM Port
- When the USB cable connects the Tiva LaunchPad, the device driver at the host PC establishes a virtual connection between the PC and the UART0 of the TM4C123GH6PM device.
- On the LaunchPad, the connection appears as UART0.
- On the host PC, it appears as a COM (/dev/ttyACM0) port and will work with communication software on the PC such as a terminal emulator (gtkterm, PuTTY, minicom, etc).
- It is called a virtual connection because there is no need for an additional cable to make this connection.
UART Base Addresses
TI TM4C123GH6PM can have up to 8 UART ports. They are designated as UART0 to UART7. The following shows their Base addresses in the memory map
- UART0 base: 0x4000.C000
- UART1 base: 0x4000.D000
- UART2 base: 0x4000.E000
- UART3 base: 0x4000.F000
- UART4 base: 0x4001.0000
- UART5 base: 0x4001.1000
- UART6 base: 0x4001.2000
- UART7 base: 0x4001.3000
UART Registers Setup
There are many special function registers associated with each of the above UARTs. We will be using the UART0 as an example since a virtual connection is available on the TI Tiva LaunchPad.
Baudrate Generator (UARTIBRD)
Two registers are used to set the baud rate:
- They are UART Integer Baud-Rate Divisor (UARTIBRD) and UART Fractional Baud-Rate Divisor (UARTFBRD).
- Of the 32-bit of the UARTIBRD, only lower 16 bits are used and of the 32-bit of the UARTFBRD, only the lower 6 bits are used.
- That gives us total of 22 bits (16 bits integer + 6 bits of fraction). To reduce the rate of error and use the standard baud rate, we should use both of the above divisor registers when we program the baud rate.
The baud rate can be calculated using the following formula:
Desired Baud Rate = SysClk / (16 — ClkDiv)
where the SysCLK is the working system clock connected to the UART and ClkDiv is the values we load into divisor registers. The system clock fed to the CPU can come from XTAL, PLL, or an internal RC. For TI Tiva LaunchPad, the default system clock is 16 MHz. So we can rearrange the above formula as:
Desired Baud Rate = 16MHz / (16 - ClkDiv) = 1MHz / ClkDiv
The ClkDiv value gives us both the integer and fractional values needed for the UARTIBRD and UARTFBRD registers. While the integer portion of the divisor is easy to calculate using a simple calculator, the calculation of the fraction part requires some mathematical manipulation. One way would be, to multiply the fraction by 64 and round it by adding 0.5 to it.
Baudrate Calculation Example
Assume SysCLK Frequency = 16MHz. Find the values for the divisor registers of UARTIBRD and UARTFBRD for the following standard baud rates:
(a) 4800 (b) 9600 (c) 57,600 (d) 115,200
By default, 16 MHz System Clock is divided by 16 before it is fed to the UART. Therefore, we have 16MHz/16 = 1MHz and ClkDiv = 1MHz/baud rate.
(a) 1MHz/4800 = 208.3333, UARTIBRD = 208 and UARTFBRD = (0.3333 * 64) + 0.5 = 21.8312 = 21 (b) 1MHz/9600 = 104.166666, UARTIBRD = 104 and UARTFBRD = (0.16666 * 64) + 0.5 = 11 (c) 1MHz/57600 = 17.361, UARTIBRD = 17 and UARTFBRD = (0.361* 64) + 0.5 = 23 (d) 1MHz/115200 = 8.680,UARTIBRD = 8 and UARTFBRD = (0.680 * 64) + 0.5 = 44
In the above Example, it must be noted that default clock is divide-by-16. We can change it to divide-by-8 by setting to 1 the HSE bit of the UART Control (UARTCTL) register.
UART Control (UARTCTL)
The next important register in UART is the control register. It is a 32-bit register and many of the bits are unused. For us the most important bits are RXE, TXE, HSE, and UARTEN.
- UARTEN (D0) UART enable: This allows one to enable or disable the UART. During the initialization we must disable it while modifying some of the UART registers.
- HSE (D5) High Speed enable: For the baud rate divisor, by default the system clock is divided by 16 before it is fed to the UART. We can change it to divide-by-8 by setting the HSE = 1 to run higher Baud rate with a low system clock frequency.
- RXE (D8) Receive enable: We must enable this bit to receive data.
- TXE (D9) Transmit Enable: We must enable this bit to transmit data.
- The other bits of this register are used for MODEM signals such as CTS (clear to send), RTS (request to send), parity bit, and so on.
UART Line Control (UARTLCRH)
This is the register we use to set the number of bits per character (data length) in a frame and number of stop bits among other things.
- STP2 (D3) stop bit2. The stop bit can be 1 or 2. The default is 1 stop bit at the end of each frame. If the receiving device is slow, we can use 2 stop bits by making the STP2 = 1.
- WLEN (D6 -D5) Word Length: The number of bits per character data in each frame can be 5, 6, 7, or 8. Generally, we use 8 bits for each character data frame. Notice that default is 5 bits and we must change it to 8 bits as shown below:
- FEN (D4) FIFO enable: TI Tiva UART has an internal 16-byte FIFO (first in first out) buffer to store data for transmission. There is also another 16-byte FIFO buffer to save all the received bytes.
- By enabling FEN bit, we can write up to 16 bytes of data block into its transmission FIFO buffer and let it transfer one byte at a time.
- The programmer may set up a threshold for the UART to notify the CPU when the level of the FIFO passes the threshold.
- There is also a 16 byte FIFO for the receiver to buffer the incoming data.
- Upon Reset, the default for FIFO buffer size is 1 byte (character mode).
UART Data (UARTDR)
To transmit a byte of data we must place it in UART Data register. Although it is a 32-bit register, only the lower 8 bits (D0 - D7) are used. It must be noted that "A write to this register initiates a transmission from the UART." In the same way, the received byte is placed in this register and must be retrieved by reading it before it is lost. For transmit, only the lower 8 bits are used. For the receive, the lower 8 bits holds the received byte and other extra 4 bits of D8 - D11 are used for error detection such as framing error, parity error, and so on. There is another register called UARTRSR/UARTRCR (UART Receive Status Error/Error Clear) that can be used to check the source of error.