Uartlite Driver
Uartlite Driver
Introduction
The LogiCORE™ IP AXI Universal Asynchronous Receiver Transmitter (UART) Lite core provides between UART signals and the Advanced Microcontroller Bus Architecture (AMBA®) AXI interface and also provides a controller interface for asynchronous serial data transfer. This soft LogiCORE™ IP core is designed to interface with the AXI4-Lite protocol.HW IP Features
- AXI4-Lite interface for register access and data transfers
- Full duplex
- 16-character transmit and receive FIFOs
- Configurable number of data bits (5-8) in a character
- Configurable parity bit (odd or even or none)
- Configurable baud rate
Features supported in driver
- Supports 16-character transmit and receive FIFOs
- Configurable number of data bits (5-8) in a character
- Configurable parity bit (odd or even or none)
Missing Features, Known Issues and Limitations
- None
Kernel Configuration
To enable the uartlite driver in the linux kernel you either have to integrate it or build it as kernel module (.ko). You can enable it with:make menuconfig ---> Device Drivers ---> Character devices ---> Serial drivers ---> Xilinx uartlite serial port support
# integrate into the kernel CONFIG_SERIAL_UARTLITE=y # build as loadable module CONFIG_SERIAL_UARTLITE=m
to increase the number of UART ports in the driver. The driver statically allocates port data structures based on this configuration item. The port-number device tree
property is used for each UART Lite device node and is used to index into a port data structure in the driver. The port-number is similar to the alias number such that
it is affected by the total number of UARTs in the system (including PS UARTs).
CONFIG_SERIAL_UARTLITE_NR_UARTS=<total number of UARTs in the system>
Devicetree
Here's how the devicetree entry could look like.
uartlite_0@42C00000 { compatible = "xlnx,xps-uartlite-1.00.a"; reg = <0x42C00000 0x10000>; interrupt-parent = <&gic>; interrupts = <0 59 4>; clock = <100000000>; }; uartlite_1@42C10000 { compatible = "xlnx,xps-uartlite-1.00.a"; reg = <0x42C10000 0x10000>; interrupt-parent = <&gic>; interrupts = <0 59 4>; clock = <100000000>; };
Vivado Block Design
Here's how the axi_uartlite can be instantiated twice in a Vivado Block Design.
Instead of connecting the interrupt outputs directly to IRQ_F2P they can also be OR-ed with the Utility Reduced Logic to connect them to only one interrupt channel. The interrupt outputs (irq_0, irq_1) generate a small positive going pulse for the rising edge sensitive interrupt input (IRQ_F2P).
Test procedure
The driver source file in the linux kernel at drivers/tty/serial/uartlite.c limits the number of supported UARTs to 16. If you need to increase that number, adjust this define near the top of the file:#define ULITE_NR_UARTS 16
After that you of course have to rebuild the kernel and deploy it to your Zynq device.
Using the uartlite in Linux
With the FPGA binary loaded, the updated devicetree and updated kernel you should see one or more /dev/ttyULx devices.
Beware that linux puts all uarts in Canonical Mode, something you might not want in an embedded system. Chances are you want to use Non-Canonical or Raw Mode. Also don't use fopen / fprintf / fputs / etc. if you want raw access, use open / close / read / write instead.
$echo 123456789 > /dev/ttyUL0
Expected Output
root@Xilinx-ZC1751-DC2:~# root@Xilinx-ZC1751-DC2:~# echo 123456789 > /dev/ttyUL0 [ 70.634844] 123456789 root@Xilinx-ZC1751-DC2:~# echo 123456789abcd > /dev/ttyUL0 [ 75.774761] 123456789abcd
Mainline Status
This driver is currently in sync with mainline kernel driver.Change Log
2024.1
Summary:
- Use uart_xmit_advance()
- Make uart_remove_one_port() return void
- Explicitly include correct DT includes
- Use dynamic allocation for major number when uart ports > 4
Commits:
852322f - serial: uartlite: Use uart_xmit_advance()
d5b3d02 - serial: Make uart_remove_one_port() return void
29e5c44 - tty: Explicitly include correct DT includes
ff8f20a - serial: uartlite: Use dynamic allocation for major number when uart ports > 4
2023.2
- None
2023.1
Summary:
- Make uart_console_write->putchar()'s character an unsigned char
- serial: uartlite: Fix BRKINT clearing
- serial: Make ->set_termios() old ktermios const
Commits:
3f8bab1 - serial: make uart_console_write->putchar()'s character an unsigned char
3f7fed4 - serial: uartlite: Fix BRKINT clearing
bec5b81 - serial: Make ->set_termios() old ktermios const
2022.2
Summary:
- Revert da7ece39ff75 Remove an un-necessary read of control register
Commits:
80ca8dd - serial-uartlite: Revert da7ece39ff75 Remove an un-necessary read of control register
2022.1
- None