Two independent asynchronous serial I/O ports are provided for the UART unit of the high-efficiency FIFO serial port based on the implementation of b0x (clock frequency: 60 MHz) on the ARM7, each communication port can work in the interrupt or DMA mode. That is, UART can generate an internal interrupt request or DMA request to transmit data between the CPU and the serial I/O port. It supports a transmission rate of up to 115.2 kb/s. Each UART channel contains two 16-bit first-in-first-out (FIFO) channels for receiving and sending signals respectively. 5/6 b0x UART includes programmable baud rate, infrared transmission/receiving, 1 start bit, 1 or 2 stop bit, 7/8/BIT data width and parity. Each UART contains a baud rate generator, receiver, transmitter, and Control Unit. The Unit consists of 1 [1].
1. FIFO Overview
1.1 FIFO Concept
First in first out (first in first out), that is, data first written to the first in first out (FIFO) will be read first. It is a storage unit used to cache data. You can store the data to be processed in this storage unit first, and then process the data in a centralized manner when the data volume reaches a certain amount to improve system performance. FIFO can be integrated into the chip. When the system requires a large buffer, it can also be implemented using a separate Ram. The b0x serial transceiver consists of a 16 B FIFO and a data Cer. The data to be transmitted is written into the FIFO, assigned to the transmitter, and finally sent out from the transmission pin shift, achieve the purpose of using the FIFO buffer for efficient communication.
1.2 meaning of FIFO
FIFO is an extremely important part of data transmission systems, especially when two system interfaces in different clock domains are used properly, it not only effectively matches the input/output rate of data transmission at the interface, but does not repeat, lose, or read invalid data, but also effectively improves the data transmission efficiency in the system. Using FIFO for serial communication is more efficient than traditional serial communication. It will centralize the sent and received data to avoid frequent bus operations and reduce the CPU burden. Therefore, the FIFO-based serial communication is widely used.
1.3 FIFO interrupt request
The UART of b0x has 7 Status (TX/Rx/error) signals: overflow error, parity error, frame error, breakpoint condition, receiving FIFO/buffer Data ready, sending FIFO/buffer null, and sending shift register null, these status signals are declared by the corresponding UART Status Register (utrstatn/uerstatn) [1].
When an error is received, if the interrupt enable bit in the control register (UConn) is set to 1, overflow error, parity error, frame error, and breakpoint error. Every one of the error states can send an error interrupt request. When an interrupted request in an incorrect receiving status is found, the interrupted request signal is recognized by the read uerstatn. If the receiving mode in the controller is selected as the interrupt mode, when the receiver transmits data from the receiving shift register to the receiving FIFO, it will activate the "full" status signal that can cause the reception interruption of the receiving FIFO. Similarly, if the sending mode in the controller is selected as the interrupt mode, when the transmitter transmits data from the FIFO to the sending shift register, the sending status signal in the "null" status that can cause sending interruption is activated. See table 1.
2. Implementation of FIFO Serial Communication
When a FIFO instance is restarted, the input and output pointers point to the 1st storage locations in the FIFO instance. Each write operation on the FIFO will direct the input pointer to the next storage location of the FIFO, and each read operation will direct the output pointer of the FIFO to the previous storage location of the FIFO. If the pointer needs to be moved from the last storage location to the 1st storage location, the FIFO will automatically implement this process without any restart operations on the pointer. In addition to the input and output ports, the FIFO usually has other status flag outputs, such as null and full. When the FIFO status is empty or full, the empty status and full status flag will have the corresponding output, that is, when the FIFO status is empty, the read operation cannot be performed, write operations cannot be performed when the FIFO is full [2].
2.1 configure special registers
To enable the target system to work properly, you must configure relevant registers, such as I/O port registers, serial port control registers, and serial port source/destination registers. There are two serial ports in the b0x. The serial port 0 is used as an example to configure related registers.
/* I/O port configuration, defining various related pin functions and pull-up resistance status */
Rpconc | = 0xf0000000;
Rpupc | = 0xc000;
Rpcone = (rpcone & 0x3ffeb) | 0x28;
Rpupe | = 0x6;
Rpconf = (rpconf & 0x3ff) + 0x124800;
Rpupf | = 0x1e0;
/* Define the serial port 0 working register group */
Rulcon0 = 0x3; // normal mode, no parity check, 1-bit stop bit, 8-Bit Data bit
Rucon0 = 0x245; // Rx is edge triggered, TX is level triggered, Disabled
// Timeout interruption, resulting in receiving error interruption, normal transmission,
// The sending and receiving modes are interrupted or polling.
Rufcon0 = (2 <6) | (1 <4) | (6) | 1; // first reset for FIFO startup
Rubrdiv0 = (mclk/(baud * 16); // mclk is 60000000, baud is 115200
2.2 FIFO serial sending module
The serial data transmission frame format is programmable, which contains 1 starting bit, 5 ~ 8 data bits, 1 Optional parity and 1 ~ Two Stop bits can be set through the line control register (UConn. The sender can also generate conditions for sending suspensions. The stop condition forces the serial output to remain in the logic 0 state. This state keeps the duration of more than one transmission frame. Generally, after one frame of transmitted data is completely transmitted, the stop signal is sent to the other party in this completely zero state. After the stop signal is sent, the transmitted data is continuously put into the output FIFO. The data to be sent is stored in the defined string pointer uart0txstr. The serial sending module sends data by reading the characters in the string. The core source code is as follows:
Void _ IRQ uart0_tx1_oint (void)
{
/* Determine whether the FIFO sending buffer is full or the string ends */
While (! (Rufstat0 & 0x200) & (* uart0txstr! = '/0 '))
{
Rutxh0 = * uart0txstr ++;
For (I = 0; I <700; I ++); // delay to prevent FIFO write errors
}
Ri_ispc = bit_utxd0;
If (* uart0txstr = '/0 ')
{
Rintmsk | = bit_utxd0;
Ri_ispc = bit_utxd0;
}
}
2.3 FIFO serial port receiving module
The format of the received data frame is the same as that of the sent data frame. It includes 1 start bit, 5 ~ 8 data bits, 1 Optional parity bits and 1 ~ Two Stop bits can be set through the line control register (UConn. The receiver can also detect overflow errors, parity errors, frame errors, and suspension conditions. In each case, one error flag is set.
(1) overflow error indicates that the new data overwrites the old data because the old data is not read in time.
(2) An error in parity indicates that the receiver has detected unexpected parity results.
(3) frame errors indicate that the received data has no valid Stop bits.
(4) The abort State indicates that the input of rxdn is kept as 0 and exceeds the transmission time of one frame [3].
(5) In FIFO mode, the receiving of FIFO is not empty, but the receiver has not received any data within the three-character period. Therefore, the receiving timeout occurs.
After reading the data from the receiving shift register, the receiving module is first stored in the receiving cache array keybuf. The keybufwrpt and keybufrdpt variables point to the currently written and read data in the cache array. When the receiving module writes 1 byte to the cache array, the keybufwrpt value is added to 1; when the uart_intgetkey reads 1 byte from the cache array, the keybufrdpt adds 1. The maximum value of the two variables is key_len. If the maximum value is exceeded, the value is set to zero. The core code of the receiving module is as follows [4]:
/* The receiving module reads the data in the shift register to the receiving cache array */
Void _ IRQ uart0_rx1_oint (void)
{
Ri_ispc = bit_urxd0;
If (rufstat0 = 0)
Uart_printf ("time out/N ");
While (rufstat0 & 0xf)> 0) // loop until FIFO
// The sending buffer is empty.
{
Keybuf [keybufwrpt ++] = rurxh0; // read the data in the receiving buffer and save it to the cache array.
If (keybufwrpt = key_buflen)
Keybufwrpt = 0;
}
}
/* Define a function to read data from the receiving cache array */
Char uart_intgetkey (void)
{
If (keybufrdpt = key_buflen)
Keybufrdpt = 0;
While (keybufwrpt = keybufrdpt); // wait until the FIFO is triggered
Return keybuf [keybufrdpt ++];
}
2.4 FIFO Fault Tolerance Module
In addition to receiving the FIFO register, UART also has one status FIFO. Status FIFO indicates which data is received without error in the FIFO register. Assume that the uart fifo receives the, B, C, D, and E characters consecutively, and a frame error occurs when receiving the B characters (that is, the character is not stopped ), an error occurred while receiving the D character. Although a UART error occurs, there is no error interruption because the characters containing the error have not been read by the CPU. Error interruption occurs when the characters are read, and the FIFO error Status Register is cleared only after the urxhn and uerstatn registers are read. The core code of the Fault Tolerance module is as follows [6].
Void _ IRQ uart0_rx1_oerrorint (void)
{
Ri_ispc = bit_uerr01;
Uart_printf ("uerstat0 = 0x % x/N", ruerstat0 & 0xf );
While (rufstat0 & 0xf)> 0)
{
Keybuf [keybufwrpt ++] = rurxh0;
If (keybufwrpt = key_buflen );
Keybufwrpt = 0;
}
}
3. Experiment results
This experiment is implemented on the platform of b0x and ads1.2 and achieves the expected results. Under the same conditions (temperature, voltage, and other external factors are ignored) the time spent on sending and receiving is shown in table 2.
Taking the transmission of 4 KB data as an example, table 2 shows that sending and receiving saves 0.547 076 S and 0.042 832 s respectively when using FIFO. Assume that the 1-bit data is transmitted in θ s and the data volume is n. In this case, we can see that the time difference between the use of FIFO and the use of FIFO is 15θ/16 s. It can be seen that the larger the data volume n, the smaller the use of the FIFO serial transmission mode, the more advantageous. This also shows the importance and necessity of FIFO in engineering applications that transmit large data volumes through serial ports.
In the context of increasingly wide application of serial communication, it is particularly important to increase the speed of serial communication. This article introduces the principle and implementation method of FIFO-based serial port dual-host communication based on the b0x microprocessor. This method is also applicable to other microprocessor configured with the FIFO buffer, it has strong applicability and versatility, and provides reference models for serial communication in engineering applications while learning and researching.