Lecture 11 - UART Programming ----------------------------- 10:10 UART Recap - UART = Universal Asynchronous Receiver Transmitter - A UART transmits bytes over a serial connection one bit at a time - A UART receiver reconstruct the received bits into bytes - The transmitter and receiver run at the same speed = baudrate The transmitter and receiver are asynchronous That is, even though the TX and RX both know how long a symbol takes to transmit, the RX does not know precisely when the TX starts sending it. - The baudrate is the speed of symbols on the wire from transmitter to receiver - One byte is decomposed into the following symbols Start Bit 8 Data bits, LSB to MSB (optionally \7) An optional Parity Bit One or (optionally) Two Stop bits - Notation: #DATABITS {N, E, O} #STOPBITS 8N1 = 8 databits, no partity, 1 stop bit 8E2 = 8 databits, even parity, 2 stop bits - Parity bit is an error checking bit Symbol sequence for an 8-bit scheme start b0 b1 b2 b3 b4 b5 b6 b7 p stop 0 1 EVEN Parity: p = b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7 ODD Parity: p = b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7 ^ 1 - If the baudrate is 9600 then the bitrate can be no more than 8/10 x 9600 bits per second or 960 bytes per second. Standard Baud Rates 1200 2400 4800 9600 19200 38400 57600 115200 460800 921600 Note that high baud rates imply that the receiver needs to be high quality. Typically, the receiver needs to sample the UART connection much faster than the baudrate, in order to accurately estimate the beginning of the start bit In practice, you would use 9600 and then slowly increase of the configuration allows it. 10:15 UART Hardware See USER Guide MSP432P4, page 905 (Fig 24-1 - eUSCI_A0) Main components: 1. Transmit Shift Register Transmit Buffer 2. Receive Shift Register Receive Buffer 3. Baud Rate Generator -> generates the symbol clock The UART hardware is driven through 18 registers that cover multiple modes of operation (including IrDA for infrared communications and framing format for multi-point communications). We will study the operation of the UART trough the driverlib functions. However, there is one aspect that we have to explain at the level of the hardware and the MSP432 User Guide: the programming of the Baud Rate. 10:20 Symbol Synchronization We first discuss the process of symbol synchronization. This will explain, at high level, how a UART receiver is able to pick up the correct bits coming from a transmitter. We assume that the transmitter and receiver are set to the correct baud rate. The only problem left is that the receiver needs to know when to sample the bits coming from the transmitter. If we connect a UART transmitter to a UART receiver, then they need to use SYNCHRONIZED baud rate clocks. Simply setting the same baud rate is not enough, since the baud clock may still be mis-aligned. TX CLK --+ +----+ +----+ +----+ +----- | | | | | | | | +----+ +----+ +----+ +----+ | | | | | | MISALIGNED MISALIGNED MISALIGNED | | | | | | RX CLK --+ +----+ +----+ +----+ +----- | | | | | | | | +----+ +----+ +----+ +----+ | | | | | | The receiver uses the start bit for this purpose. When the down-going edge of the start bit is seen, the receiver will start an internal counter. Since the receiver knows how long a symbol period will take, the receiver can also guess when the MIDDLE of a symbol period occurs. For example, assume the ASCII 'A' transmission of last lecture. We have to send '0100000101' start bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 stop TX ---+ +-----+ +-----+ +-----+---- | | | | | | +-----+ +-----+-----+-----+-----+-----+ +-----+ | | | Receiver detects start of first symbol | | |--| sampling moment will be exactly in the middle of the symbol | |.....|.....|.....|.....|.....|.....|.....|.....|.....| | | read bit0 | read bit 1 | read bit 2 | read bit 3 | read bit 4 | read bit 5 | read bit 6 | read bit 7 expect '1' Important to remember (for the rest of the story), is that the receiver symbol clock is 'synchronized' at the falling edge of the start bit, and from that point on it simply counts symbol periods (using the internal counter) to find each next sample instant. 10:30 Baud Rate Generation The symbol clock is created from the UART input clock (typically the processor transmission clock) by dividing it by a programmable factor N FBRCLK ---> divide-by-N --> baudrate FBRCLK stands for 'baud rate (generator) clock' In practical settings, we will need to find N for a desired baud rate at a given clock frequency. For example, FBRCLK = 3MHz and baudrate = 9600, then N = 3000000 / 9600 = 312.5 So we can time a symbol at 9600 baud by counting to 312 (approximately) at 3MHz. 3MHz --> COUNTER == 312? -+---> 9600 baud clock ^ | |reset | +-------------+ Of course, we are making an error here: 312.5 is not 312! And the problem with these fractional errors is that they will ACCUMULATE over subsequent symbols (ie. subsequent bits) For example, let's you measure out steps of 6 '-', but use only 5 '-' at each step. You can see the absolute error increase for each step: correct length +------+------+------+------+------+ | | wrong length +-----+-----+-----+-----+-----+ | |....| <-- error By the 5th step, the error is almost a complete symbol period! For the receiver, this means that, if we measure the symbol period wrong, we diverge from the ideal symbol sampling instant towards the edges of the symbol, which is unreliable. Therefore, we need to have a very precise symbol timing, which is maintained throughout the transmission of the entire byte. The receiver will align on the reception of the start bit, and will measure the ENTIRE symbol sequence timing according to the exact position of the start bit. So we have to adjust for these fractional errors. The solution for the microcontroller, rather than using a floating point adder (which is too expensive!), is to use a 'modulation technique'. If we have to count to 312.5, we will do a 'modulated count' as follows: For bit 0, count to 312 (ie. count 0 extra) For bit 1, count to 313 (ie. count 1 extra) For bit 2, count to 312 (ie. count 0 extra) For bit 3, count to 313 (ie. count 1 extra) For bit 4, count to 312 (ie. count 0 extra) For bit 5, count to 313 (ie. count 1 extra) For bit 6, count to 312 (ie. count 0 extra) For bit 7, count to 313 (ie. count 1 extra) So, on average, we have counted to 312.5 over 8 bits. The '01010101' pattern is called the 'modulation pattern'. In hex, this modulation pattern would be '0x55'. In summary, if we need to set a baud rate generator for a given baud rate B and we have a uart clock F, then we work as follows: (1) Determine the divisor N = F / B (2) The integer part of N becomes the 'divider' (3) The fractional part of N becomes a 'modulator' byte PLEASE NOTE: The explanation above leaves out some low-level details of the baud rate generation process, and it conentrates on the principal operation. The baud rate setting operations are given in in section 24.3.10 of the MSP432 USER GUIDE. In the MSP432, the following parameters must be chosen: (1) OVERSAMPLING MODE or not -> If N > 16, use oversampling mode, otherwise not (2) In OVERSAMPLING - N = F / B UCBR = INT(N) >> 4 UCBRF = INT(N) & 15; UCBRS = modulation value according to table (FRAC(N)) (3) In LOW-FREQUENCY MODE - N = F / B UCBR = INT(N) UCBRS = modulation value according to table (FRAC(N)) 10:40 Setting the Baud Rate - Example Example 1: Using 24.3.10, find the baud rate settings for F = 16 MHz B = 115200 N = F / B = 138.888888 -> we can use oversampling mode UCBR = 8 UCBRF = 10 -> the fractional part is 0.88888 UCBRS = 0xF7 Example 2: Using 24.3.10, find the baud rate settings for F = 500 KHz B = 115200 N = F / B = 4.34 -> we cannot use oversampling mode UCBR = 4 -> the fractional part is 0.34 UCBRS = 0x49 10:50 UART Configuration Example from Lab 2: eUSCI_UART_Config uartConfig = { EUSCI_A_UART_CLOCKSOURCE_SMCLK, // SMCLK Clock Source = 3MHz 19, // UCBR = 19 8, // UCBRF = 8 0xAA, // UCBRS = 0xAA EUSCI_A_UART_NO_PARITY, // No Parity EUSCI_A_UART_LSB_FIRST, // LSB First EUSCI_A_UART_ONE_STOP_BIT, // One stop bit EUSCI_A_UART_MODE, // UART mode EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION // Oversampling }; void InitUART() { UART_initModule(EUSCI_A0_BASE, &uartConfig); UART_enableModule(EUSCI_A0_BASE); GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1, GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION); } 10:55 Conclusions - UART Recap - UART Baud Rate Configuration - UART Initialization To be discussed: - UART ERRORS - Other UART Software Function Calls -------- What can go wrong? Lots of things! The diagnosis is limited to three cases. Each of these cases has a flag in the UART Status Register OVERRUN ERROR: There's a new character received, and the software did not pick up the previous character. In that case, we lost the previously received character in the RECEIVE REGISTER FRAMING ERROR: The value of the stop bit is not as expected! It is expected to be 1, but the receiver found a 0 That means that either the line is dead (always 0), or the baud rate is incorrectly configured, or there is some unexpected noise on the line. In any case, the last received character is lost, because the stop bit is not as expected. PARITY ERROR: The Parity bit is of a different value than expected. The means that the parity is configured incorrectly, or that there is a transmission error. While the software uses ReadUART() and DataRdyUART(), it should also poll for errors to evaluate if the UART is operating correctly. Furthermore, a UART can also be configured to generate interrupts when an error happens.