UART (Universal Asynchronous Receiver Transmitter) The UART module is intended to provide the system with a bi-directional communication channel with the user. Thus, it is possible to send simple commands or extract information status from the system using a communication terminal. Description on how UART is defined and how it works is very easy to find. This webpage only intends to give an overview of the most important parts. What is a UART port? By definition, UARTs are modules capable to translate a parallel data communication to a serial communication and vicersa. There are several standards based on this principle such as EIA, RS-232 or RS-422. It also contemplates different electrical implementations such as differential data transmission. It is a well extended communication system and often integrated within micro-controllers. How does it work? The UART module, when transmitting, retrieves the parallel data and transmit one bit at a time in sequence. The receiver at the other end, is expected to identify the transmission frame and compose the transmitted data picking each bit a time. This modules normally include resources such as shift-registers to ease the transmission sequence and reconstruction. The beauty of the system resides in the fact that it can be build without the need of generating additional signals to control de communication. Modules should be capable to retrieve any message sent by watching the data channel. The logic levels determine whether there is an on-going transmission or it remains silent. Thus, it exist an initial state, known by both ends, that enables the detection of a new data transmission. This scheme is shown in figure TODO. The high electrical (and logic) level on the line, while in idle state, is a legacy of telegraphs technology, where it determined if the communication line was broken or not. The data transmission begins by forcing the line to logic level low, so the receiver awakens, and attaching in sequence the bits of data (LSB to MSB). The number of data bits might vary depending on the standard employed (5 to 9). When it is used less than 9 bits, it can be optionally followed by a parity check bit. Finally, it is transmitted one or two stop bits. These last bits, ensure the line is left in the idle state and ready for a new transmission. It is also used to separate one data transmission from the other. There is an additional security mechanism associated with the power down of the line. If it is held low for a time longer than a character, it is assumed that the line is broken and an alarm should be triggered. From the point of view of UART receiver, there are not additional signals that can indicate or synchronize data transmission with the transmitter. Therefore, the receiver is always monitoring the data channel at a rate higher than the bit rate of the channel. It is normally accepted a factor 8 between the bit transmission and bit sampling rate. It duty begins by determining if a new start bit is being received. If the line is held low for a half of the bit time, it can be considered that a new transmission is taking place. Otherwise, it is discarded as noise pulse on the data channel. Once it is determined the start bit, channel samples are sequentially stored in a shift register. Each one of those samples separated by a bit time. As shown in Figure TODO The process continues until all samples required are obtained, including parity bit if it is sent. The rest of transmitted bits are ignored as they are intended to set the line idle. Note that there is no synchronization with any other clock source and that both systems maintain their own clock source. Data retrieval and sample synchronization is only determined by the falling edge of the start bit. Thus, the extracted samples are retrieved from what it is expected to be the centre part of the bit (minimal uncertainty). The de-serialized data is then acknowledge by setting the appropriate signal. Normally a double register scheme is employed, so one register is used to store last character received while it is being received the next one. Another approach is to implement mechanism to store received characters so system retrieving them has enough time and no overflow occurs. The later is usually implemented with FIFO modules, so the data can be retrieved at a pace different from the one it is generated. UART Module design Although it is a single module, the UART module is comprised by two differentiated functions: Transmission & Reception. The transmission section of the module is quite straight forward to implement, thus it is left for the last part. On the other hand, the receiver section of the module requires a deeper understanding on the signal being transmitted through the channel. In order to properly design the receiver module, it is necessary first to select which would be the bit rate on the channel. UART channels speed's are already standardized so it is easier to interoperate between different devices. Sometimes, the channel transmission rate is expressed as a Baud rate. If that is the case, it is needed a conversion towards a bit rate. Once the value is known, the relation between the channel's bit rate and sampling rate of the receiver can be obtained. It might happen that such relation can not be represented by an integer number. In that case, it is wise to select factor which does not compromise the reception of the bits by reading non-real values. -- TODO EQUACION A straight forward conversion (if frequency values have already been selected) is to use such expression as a constant value within the module, so all dependent functions within the module are aware at the pace every function should behave. This pace will be the one in charge while retrieving the bits from the transmission channel. Note that it is not equal for all the steps (states) required to obtain such transmitted data. The number of states for the receiver is flexible depending on the preference of the designer. Even so, there are three clear stages to implement the receiver which compromise: Start/idle, Data bit(s) and Stop bit(s) It is not mentioned in this first approach the parity bit checking. It is left to be discussed later, as it is an optional property in the UART communication channel. Then, the design should be continued by determining which is the triggering event for each one of the states and what are the expected actions in each one of them. During the "idle" state, the receiver should be monitoring the channel for the falling edge of the start bit. Nevertheless, the state machine is not expected to jump from the idle state to data retrieval state as soon as such edge is detected. It is necessary to recall that the receiver is clocked at a frequency several times higher than the bit rate of the channel and the chances of having a false edge due to noise over the channel. Therefore, the trigger event is determined by calculating how long has been held down the communication channel. Among others, two approaches which can be used are:
Any of the previous can achieve the task at hand. It is interesting, though, to attempt both approaches as a practise or figure out alternative solutions to detect the state jump event. The design continues with reception of the data bits that follow the start bit. There are two major differences in this state (or states) with respect with the start bit detection. In this case, the number of samples to account for matches the number of bit samples, since it was determined half the start bit. It is taken into consideration this time marks to approximately retrieve which is the best sample for each one of the following bits. This fact was already described in figure TODO. The second major difference is found in the fact that middle bit sample is read in sequence until the character is completed. Regardless of the noise in the channel, each bit in stored in sequence until the parity or stop bit is reached. Then, the last state (MSB) is left as soon as the sample is stored in the buffered register (shifting or multiplexed). Once again, the implementation on the behaviour during the state(s) is open to different solutions:
Either of the presented solutions are valid to store the transmitted sequence of bits (LSB to MSB) into a buffer register. The selected solution should also take into account the implementation of other features requested for the receiver. A not very neat implementation could stop the design at this point by resetting the FSM to its idle state and activating which ever signal is used to flag the reception of a new character. It is not advise to do so, as the module might be employed in other designs which require a more robust solution. As it was mentioned earlier, there is the possibility of having a cut in the line of communication fixing a '0' logic level on said line. Thus, in order to consider correct the transmitted character, the stop bit(s) should also be sampled and compared with what it is expected. The result on the comparison can determine if there was a fault on the line or an incorrect implementation regarding the transmission bit rate (samples are not correctly retrieved). If no error was found, the receiver can acknowledge the reception of a new character. Otherwise, the system reading the characters should be informed of the erroneous reception of the character or a fault in the communication channel. Accordingly to the previously mentioned design, some possible implementations of the receiver FSM are shown in figure TODO The flag signals should be updated on the reception of a new character. But, the system should be provided with the means to acknowledge the triggering of such flag signals. Otherwise, it is not possible to distinguish a new character from a previously received. On the other hand, if the system can't attend and acknowledge all transmitted characters on time, it is possible to build the system so each character is stored in an auxiliary buffer. This approach implements a self-acknowledge scheme, achievable internally or externally to the module. The transmitter section does not depend on external signals or synchronization to transmit the sequence of bits that determine a character. Like the receiver, the transmitter states can be matched with the bits transmitted along the channel. In this case, there is no dependency on the channel (assumed full-duplex) so the section is only awaiting the "go" signal from the system. Thus, a feasible distribution of states in the transmitter section can be:
The Idle state can be configured as the preamble of any character transmission. The module awaits until it receives the start transmission from the system to read the character to transmit and initiate the transmission using the start bit. It is recommended to store the character to be transmitted so it is lowered the dependency of holding the value on the input port during the whole transmission. Once again, the designer has several options to do so. For example, it could be used a shift register or a multiplexed register. The transmitter is expected to hold the output levels as long as the duration of the bit. Thus, it is necessary to maintain the value at the output port for the equivalent number of samples for a bit. This is done for each one of the bits that compose the transmitted character. Therefore, the next steps have a prefixed duration and a configured jump towards the next state in the sequence. No difficulties are found during the transmission of bits (start, data and parity) in sequence. The main issues (if any) are represented by the calculation of the parity bit (if used) and the behaviour during the transmission of stop bit(s). The first is going to be later discussed and related to the implementation of the receiver. The second is related to the fact that a sequence of characters can be immediately one after the other. Thus, there should be no "gap" between the stop bit of one character and the start bit of the next one. Idle and Stop bit(s) states are requested to hold a logic high on the line, so it should not be a problem to merge both states. Nevertheless, there is an external dependent event on Idle state while Stop bit(s) is forced to maintain the value for a period of time (Number of samples). Such issue can be overcome by using the entering of the merged state as a temporary disabling event for the start signal (start was disabled during the whole transmission). A timeout counter can disable the start signal during the transmission of Stop bit(s) and remain in the final count until a new transmission is issued. A merged state would then enable the continuous transmission of characters without gaps while maintaining the integrity of the transmitted signal. A graphical representation for this architecture is presented in Figure TODO. Up to this point, it has been presented and discussed the implementation of two independent sections of an UART module for a single or full-duplex communication. Half duplex communication would require the capability to disable transmitter and receiver to avoid interferences between them. It would be also recommended to use arbitration before starting any communication in the shared data channel. (Optionally) Parity Checking UART communication can include a simple mechanism to detect errors on transmission. As it names instantiates, the parity check is a method devised to add an extra bit to set the total number of '1' transmitted to an odd or even number. Table TODO presents some examples regarding transmitted words and the calculated value for odd and even parity. Upon reception of the transmitted data, it is compared a calculated parity bit with the one sent along the data. The result of the comparison would determine if an error has been detected or not. Whenever one bit (or an odd number of bits) varies in the data transmission, the calculated parity bit on reception will differ from the one sent by the transmitter. If the number or changed bits is an even number, the receiver won't be able to determine that the transmission has incurred in errors. Examples on both cases are presented in figure TODO Although it is a limited integrity verification scheme, the parity check can provide means to determine erroneous transmissions. It use is highly related to the environment in which is going to be used. Low electromagnetic noise or short wired connection would probably do not require the implementation of parity bit. Noisier environments could benefit from it. In any case, a system implementing the parity bit requires a way to analise the transmitted data and determine the value of the parity bit. One approach would be using the parallel representation of the data word to be sent. The other approach would rely on calculating the parity bit while serializing the data into the channel. The later approach presents a more suitable and quicker solution as it can also be used in the transmitter to calculate on the run which is the value of the parity bit to compare. Parity bit calculation on the run is based on XOR gate to account the number of ones in the data word as they are being serialized. It is selected the seed for the accounting depending on whether it is desired an odd or even parity check. TODO: Choose . Then, bit by bit, the result is compared for the remainder of the data word and the final result is attached to the transmission character after the MSB data bit. An example on how it works is shown in FIGURE TODO Figure TODO: Parity calculation with xor gates Implementation on the receiver follows a similar procedure, with the exception of performing a comparison with the calculated parity bit with the receiver bit and produce a decision. It could be decided to alert from fault transmissions, so the decision is transferred to another module. Another possible action would discard the erroneous character and assume there was not any transmission. The disadvantage of the second solution is the loss of total awareness on the transmission channel and a source of uncertainty of the communication channel's correct function. (Optionally) Multiple baud rates UART communication channel can be implemented using different transmission rates. The standard contemplates speeds such as TODO. Therefore, it would be a valuable feature to implement the UART communication module with the capability to configure, dynamically, its transmission rate. It is understood by "dynamic" the capability to change the transmission rate before any transmission (already downloaded design) where both ends are aware of such change. It is necessary to enforce the constraint of not being able to change the transmission rate while an ongoing transmission. This variation would affect the duration of the bits and/or change the samples retrieved, so the system is leaded towards an erroneous behaviour. Thus, the configuration of the new transmission rate should only be enabled while in idle state as shown in TODO Figure TODO: Update scheme on rate configuration and sample counter Please note that in the receiver case, the detection of the start bit was embedded in the idle state. Therefore, the configuration of the new transmission rate should be blocked not only in the other states, but while the channel is forcing a possible start bit. The new transmission rate is determined by the number of samples used to define a transmission bit. High bit speed rates would allow fewer number of samples, so there is a direct relationship between the module clock and the maximum achievable speed rate. Lower speed rates are translated in a greater number of samples. Proposed implementation uses a double buffered register where it is saved the current speed rate and the desired speed rate. First register is only updated when the previously described requirements are met and the second is used to determine the bit's number of samples for the current speed rate. This approach takes into account that the second register can be used to actually store the number of samples for the bit or select among different pre-configured number of samples. Either way, this desired number of samples should not be transferred to the other register while in transmission/reception. Note that it is not necesary to implement a "four" registers to store bit and half bit samples. The half bit samples can be obtained by shifting one bit (MSB->LSB) of the total number of samples for a bit. The shifting is translated as a integer division by 2. Further work All elements detailed in the present document are aimed to the generation of an UART communication channel with uni-directional or full duplex channel. There is still an alternative solution which involves sharing the physical communication channel between the transmitters and receivers at each end of the line. This implementation, though, is outside the scope of the current project. It would be a good exercise to investigate how input/output pins are driven and which sort of protocol is followed to arbitrate between both ends of the communication channel to use it. |