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
Or you can do this in the .config file with either of the following lines:
# integrate into the kernel
CONFIG_SERIAL_UARTLITE=y
# build as loadable module
CONFIG_SERIAL_UARTLITE=m
When using newer releases, and when more than one UART Lite is required in the system, the user should also configure the following configuration item
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>;
        };
Note how you can use the same interrupt, but for that to work you must OR the interrupts from the uarts to the interrupt-input.

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 except for the following:
  • serial-uartlite: Remove an un-necessary read of control register
  • serial-uartlite: Add runtime pm support
  • serial-uartlite: Disable clocks in the error path

Change Log

2016.3
  • None

2016.4
  • None

2017.1
Summary:
  • tty: serial: uartlite: Add structure for private data
  • tty: serial: uartlite: Add clock adaptation
Commits:
  • f221ad2 tty: serial: uartlite: Add structure for private data
  • 18f697c tty: serial: uartlite: Add clock adaptation

2017.2
  • None

2017.3
  • None

2017.4
  • None

2018.1
Summary:
  • uartlite: Adding a kernel parameter for the number of uartlites
Commits:
  • b44b96a uartlite: Adding a kernel parameter for the number of uartlites

2018.2
Summary:
  • tty: uartlite: Enable clocks at probe
  • tty: uartlite: Update the clock name

Commits:
  • 98ce4fa tty: uartlite: Enable clocks at probe
  • 8069fdtty: uartlite: Update the clock name
2018.3
Summary:
  • serial: uartlite: Use dynamic array for console port
  • serial: uartlite: Move uart register to probe
  • serial-uartlite: Add runtime support
  • serial-uartlite: Fix the unbind path
  • serial-uartlite: Change logic how console_port is setup
  • serial-uartlite: Use allocated structure instead of static ones

Commits:
  • a6ddea6 serial: uartlite: Use dynamic array for console port
  • a025703 tty: serial: uartlite: Move uart register to probe
  • e8302b7 serial-uartlite: Add runtime support
  • 5bb1cd2 serial-uartlite: Fix the unbind path
  • 9c5329b serial-uartlite: Change logic how console_port is setup
  • 472c0cf serial-uartlite: Use allocated structure instead of static ones
  • 967c635 serial-uartlite: Remove ULITE_NR_PORTS macro
2019.1
Summary:
  • serial: uartlite: fix null dereference on probe error path
  • serial-uartlite: pr_err() strings should end with newlines
  • serial-uartlite: fix null pointer dereference on pointer port
  • tty: serial: uartlite: Add structure for private data
  • tty: serial: uartlite: Add clock adaptation
  • tty: serial: uartlite: Add support for suspend and resume
Commits:
  • 24f4fd59 serial: uartlite: fix null dereference on probe error path
  • 4157571 serial-uartlite: fix null pointer dereference on pointer port
  • da7bf2 tty: serial: uartlite: Add structure for private data
  • 14288be  tty: serial: uartlite: Add clock adaptation
  • a3a1061 ty: serial: uartlite: Add support for suspend and resume
2019.2
  • None


2020.1
  • a5a3cc serial-uartlite: Remove ULITE_NR_PORTS macro
  • f3c2cad serial-uartlite: Use allocated structure instead of static ones
  • 3a4e28a serial-uartlite: Change logic how console_port is setup 

2020.2

  • None

2021.1

Summary:

  • serial-uartlite: Disable clocks in the error path
  • serial-uartlite: Add runtime pm support
  • serial-uartlite: Remove an un-necessary read of control register

Commits:

Related Links