From HPS, how to sending and receive from FPGA UART (Altera UART QSYS IP)


How do I read and write from my HPS/SoC to a Altera UART setup in qsys?

Should the drivers load automatically if I’m using the GSRD 16.1 for Arria 10?

If the drivers load automatically, how do I access them? I know from Nios, it’s open("/dev/uart",“rw+”)
but that uses the nios hal layer and not across a H2F bridge.



Did you generated a device tree with the hardware in the FPGA? The OS learns about the hardware during boot using the device tree.


Yes. And the uarts are present in the device tree. I just don’t know what the uart device name is from Linux and whether I have to write a driver to use “open(”/dev/???"). I can do “ls /dev/” and see tons of tty0, […], but nothing that looks like my uart’s name.


To get the built-in linux driver to recognize the UART, the “compatible” line in the device tree must match what the driver is looking for. I couldn’t get it to work until I used this compatible line (I’m using Altera’s 16550 UART, yours may be different):

compatible = “altr,16550-FIFO128”;

The full device tree entry is:

uart3: serial3@0x100000200 {
  compatible = "altr,16550-FIFO128";
  reg = <0x00000001 0x00000200 0x00000200>;
  interrupt-parent = <&intc>;
  interrupts = <0 72 4>;
  //clocks = <&pll_148_74 0>;
  clock-frequency = <148500000>;
  fifo-size = <128>;
  reg-io-width = <4>;
  reg-shift = <2>;
  status = "okay";
}; //end serial3@0x100000200 (uart3)

If you do “dmesg | grep tty” from your command prompt, you should find which tty is assigned to the uart. My output for the above UART looks like this:

[ 0.276608] ff200200.serial3: ttyS3 at MMIO 0xff200200 (irq = 51, base_baud = 9281250) is a Altera 16550 FIFO128


Hello Tim,

I am trying to get the uart1 working on DE0 Nano board. I have enabled the option in the Qsys folder, and loaded the SD card with new preloader and device tree. In DE0 Nano, the ‘ttyS0’ is used for console, so I am using uart1. Following is the output for ‘dmesg | grep tty’

root@cv5:~# dmesg | grep tty
[    0.271170] console [ttyS0] disabled
[    0.271206] ffc02000.serial: ttyS0 at MMIO 0xffc02000 (irq = 21, base_baud = 6250000) is a 16550A
[    0.911939] console [ttyS0] enabled
[    0.915975] ffc03000.serial: ttyS1 at MMIO 0xffc03000 (irq = 22, base_baud = 6250000) is a 16550A
[    2.269179] ttyS0 - failed to request DMA
[    3.692892] systemd[1]: Created slice system-serial\x2dgetty.slice.
[    3.756462] systemd[1]: Created slice system-getty.slice.
[  473.023856] ttyS1 - failed to request DMA

And following is the device tree code :

		hps_0_uart1: serial@0xffc03000 {
			compatible = "snps,dw-apb-uart-17.0", "snps,dw-apb-uart";
			reg = <0xffc03000 0x00000100>;
			interrupt-parent = <&hps_0_arm_gic_0>;
			interrupts = <0 163 4>;
			clocks = <&l4_sp_clk>;
			reg-io-width = <4>;	/* embeddedsw.dts.params.reg-io-width type NUMBER */
			reg-shift = <2>;	/* embeddedsw.dts.params.reg-shift type NUMBER */
			status = "okay";	/* embeddedsw.dts.params.status type STRING */
		}; //end serial@0xffc03000 (hps_0_uart1)

How did you identify that you have been using altera UART 16550.?
Should my code have the following :
compatible = “16550A” ??

Background :
I am able to open the device file ‘/dev/ttyS1’, however any write to the file descriptor does not provide any change in signal at the transmitter pin(configured GPIOs as Tx and Rx).



From your snippetts, it looks like ttyS0 and ttyS1 are each finding an HPS UART. The device tree snippet you have there shows the entry for the HPS uart, not an FPGA fabric UART. If you want the FPGA fabric UART to be found, it must be in the device tree as a separate entity. See my previous posting.


Hi Tim,
I’ve copied your DTS code verbatim, except I’ve changed it to the 32 FIFO option, which seems to be available. However, I cannot get the system to recognise it. I’ve got my Altera 16550 UART built onto the lwaxi bus, same as you, I have a 148.5MHz clock, same as you. My start address is different, but nothing gets attempted to register even. I’ve got my uart3 within the “bridge” section of the DTS, where the two GPIO interrupts are located - and these work, and do get registered.

If it won’t load on boot, is there a way of loading the driver using insmod or similar? I can see the registers responding correctly if I probe the UART manually.

Many thanks,