Second serial port


The definition is on Allwinner R8 User Manual V1.1.pdf

Example for portB

mul_sel GPIO mode (multiplex function) page324…325 ref:page 322
pio.pull pull up/down resistor page 326
drv_level current driver level page 326 this is the GPIO value page 326

The page 324 explain how the offset works in the #define portion of the code.


Thanks @danjperron

I think I got just what I needed, control GPIO with command line tool (such as wiringpi gpio tool) with sunxi-tools, but unfortunately apt-get install sunxi-tools does not install all tools, so build from scratch in less than 2 minutes (as root)

apt-get install libusb-1.0 pkg-config
git clone
cd sunxi-tools

then you got a magic tool called sunxi-pio

root@chip02:~/sunxi-tools# ./sunxi-pio
sunxi-pio v1.4.2-14-gb5ba2d3

usage: ./sunxi-pio -m|-i input [-o output] pin..
 -m                             mmap - read pin state from system
 -i                             read pin state from file
 -o                             save pin state data to file
 print                          Show all pins
 Pxx                            Show pin
 Pxx<mode><pull><drive><data>   Configure pin
 Pxx=data,drive                 Configure GPIO output
 Pxx*count                      Oscillate GPIO output (mmap mode only)
 Pxx?pull                       Configure GPIO input
 clean                          Clean input pins

        mode 0-7, 0=input, 1=ouput, 2-7 I/O function
        pull 0=none, 1=up, 2=down
        drive 0-3, I/O drive level

and the magic (because help syntax is a bit confusing to me)

  • Set pin D4 to input no pull up
    ./sunxi-pio -m "PD4<0><1>"
  • Set pin D4 to input no pull down
    ./sunxi-pio -m "PD4<0><2>"
  • Set pin D4 to output no pull up/down
    ./sunxi-pio -m "PD4<1><0>"
  • Set pin D4 to LOW
    ./sunxi-pio -m PD4=0
  • Set pin D4 to High
    ./sunxi-pio -m PD4=1
  • Set pin D4 to output no pull up/down and set to low and 20mA out max
    ./sunxi-pio -m "PD4<1><0><1><0>"

See this link for more parameters details

And may be configuring uart2 is as simple as
./sunxi-pio -m "PD2<3><1><0>"
./sunxi-pio -m "PD3<3><0><0>"

Confirmed this is working after copy of tool to bin
cp ./sunxi-pio /usr/bin/gpio

then rc.local is

#!/bin/sh -e
# rc.local

# configure uart2
/usr/bin/gpio -m "PD2<3><1><0>"
/usr/bin/gpio -m "PD3<3><0><0>"
# reset module 
/usr/bin/gpio -m "PD4<1><0><1><0>"
/bin/sleep 1
/usr/bin/gpio -m PD4=1
exit 0

rebooted and all is fine :wink:


I wouldn’t recommend to use this software to manipulate GPIO all the times.

It is okay to set gpio at start, like I did with setGPIOuart2, or use your method but.

Like I said before, there is no way to set a specific bit without reading the register first.
When you write a GPIO bit you need to read the full 32bits register , do an OR or AND and overwite the 32 bits register. It is possible that when you read the first time the register , another process already change one of the bits and when you overwrite it again the other bit return to is previous state. and this is bad!!!

The prefer way is to go with the /sys/class/gpio method. The pinctrl-lock mecanism prevent concurrent access!

Maybe there is a way to add the pinctrl-lock to the C code ? I didn’t check that option.

On The Raspberry Pi you have bit access, special register do the OR/AND for you.
But not on the CHIP! you set the full 32 bits register :frowning:


Got it, absolutely right, not very safe, I understood,

I like /sys/class/gpio but on new kernel 4.4.13, numbering has changed again and thus chip documentation is not updated. We already have 3 numbering version 4.3, 4.4.11 and 4.4.13 :frowning:

root@chip02:~# uname -a
Linux chip02 4.4.13-ntc-mlc #1 SMP Thu Nov 3 01:28:54 UTC 2016 armv7l GNU/Linux
root@chip02:~# ls -1 /sys/class/gpio


Hi @danjperron

Now I got UART2 working fine, I would like to have SPI but I can’t see any SPI device in /dev/, as far as I understand it need to be compiled in kernel or did I missed something ?

Would it be complicated to have also SPI working with your sun5i-r8-chip.dtb file ?

Thanks for your help


There is a dtbo already in your chip

just add theses lines into you /etc/rc.local and reboot. You will have SPI device /dev/spi32766.0 which is spi2.0

mkdir -p /sys/kernel/config/device-tree/overlays/spi
cat /lib/firmware/nextthingco/chip/sample-spi.dtbo > /sys/kernel/config/device-tree/overlays/spi/dtbo

Official documentation for enabling SPI?
[solved] Enable SPI and UART on CHIP

Wonderfull, got it working

Does this SPI pinout is the following on U14 connector ?
CS U14_27
CLK U14_28
MOSI U14_29
MISO U14_30



You got it! :wink:

don’t forget that the device is 32766.0


If you connect the chip to a PC, and leave it to install the device. (You might need the flash drivers installed), it comes up as a 115200 baud COM port. By default it runs mingetty and wants a login.


I don’t think is true for the second port which is about that post


Need help,
Trying to compile DTS myself , and second serial do not work, error in dmesg :
[ 0.310000] 1c28400.serial: ttyS0 at MMIO 0x1c28400 (irq = 28, base_baud = 1500000) is a U6_16550A
[ 0.915000] console [ttyS0] enabled
[ 0.920000] dw-apb-uart 1c28800.serial: clock rate not defined
[ 0.930000] dw-apb-uart: probe of 1c28800.serial failed with error -22
[ 0.960000] 1c28c00.serial: ttyS1 at MMIO 0x1c28c00 (irq = 30, base_baud = 1500000) is a U6_16550A

Any ideas, what is done wrong ?


Got solved,
Also, need to modify : sun5i-a13.dtsi
and in part apb1_gates: add <18> and “apb1_uart2”


Could you add a page to the community wiki giving complete instructions so others can find it and use it without going through the same pain?

Thanks, Steve


This is also describe on previous post near the top.


@iot_steve : Yes, I will add page on community WiKi later , first I need to register there as user :slight_smile:

To all : If you plan to speed up UART more then 2.xxMbps , do not use minicom for testing , it’s fail on high speeds.
Python Serial helped me, and it’s works ok with high speed serial.
And yes, for high speed UART ( >1.5Mbps ) , kernel need be patched / hacked a little …


Interesting, I just saw that the uart2 function got added into the kernel pinctrl for GR8 but not for a13:


Has someone figured out how to convert the device tree changes to an overlay? I’m fine with switching the pin function using memory-mapped I/O but I’d rather not compile a full DTB…


Don’t you also need to disable kernel console messages? Probably using:
dmesg -D

(Use -E to reenable console logging)

Also, it might be a good idea (if you’re going to disable the console getty permanently) to simply “stop” it (rather than “mask” it), and make the command conditional on a new boot option. The kernel ignores unknown boot options for exactly this reason. Perhaps something like this in rc.local:
if ! grep -q "leave_console_getty_running" then systemctl stop serial-getty@ttyS0.service fi

Use u-boot to add “leave_console_getty_running” to your boot options if you ever run into trouble.

What do you mean by this? Why won’t the chip boot with RX connected?

(This thread is excellent, btw! Thanks to all for the excellent research!)



Reboot but do not connect uart1-RX otherwise it won’t boot!
What do you mean by this? Why won’t the chip boot with RX connected?

(This thread is excellent, btw! Thanks to all for the excellent research!)


I got problem with uboot. Any character received in uart1 less than 2 seconds after reset will force the uboot console!
It is in the documentation .


oh yeah – that. forgot about that issue. so if you want to repurpose ttyS0, you need to ensure that no characters will arrive right after a system reset. might or might not be hard, depending on the application. good to remember.