Serial Nightmare

Connecting a serial device to raspberry pi should be dead easy…well…it is not…sometimes it can be a real nightmare.
There are two main reasons for this:

-Different SW versions, mainly the way Wheezy and Jessie are handling services.

-Different HW versions, Pi 3 and ZeroW are bluetooth enabled devices and this means a small re-arrangement in internal uarts.

I’ll try and clarify things a little bit. There is plenty of good information out there but sometimes it can get really confusing
since they are talking interchangeably about diferent SW and HW versions.

Raspberry PI UART inventory

There are two UARTS in all RPI SoCs. A PL011 and miniUART.
The  PL011 is mapped to /dev/ttyAMA0 and and the miniUART to /dev/ttyS0

Raspberry PI 2:
PL011-/dev/ttyAMA0 is used by default for terminal over serial and is accessible through GPIO14 and 15
miniUART-/dev/ttyAMA0 is not used anywhere by default

Raspberry PI 3/ZeroW: 
PL011-/dev/ttyAMA0 is used by default for Bluetooth
miniUART-/dev/ttyS0 is used by default for terminal over serial and is accessible through GPIO14 and 15

Aliases
It is obvious from the above that compatibility issues exist between different PI versions. 
ttyAMA0 and ttyS0 are used for different things between different versions. Following
May 16 Jessie release, symbolic links serial0 and serial1 are introduced to reference serial ports.
Depending on RPI HW they point to different ports.

Raspberry PI 2:

Raspberry PI 3/ZeroW

Serial0 will always point to the UART that is accessible through GPIO pins 14 and 15. This
ensures cross-compatibility of your code between different versions of PI.

 

Raspberry PI 2
TTY over serial  is enabled by default. The UART used for TTY is the PL011 (ttyAMA0). 
To get hold of ttyAMA0 and use it for other serial connections you first have to disable
terminal (TTY) over serial. There are two ways of doing this:

A) raspi-config

in “Interfaceing Options” choose “Serial” (Enable/Disable shell and kernel messages on the serial connection) and disable it.

 

 

 

B) edit /boot/cmdline.txt and remove any reference to ttyAMA0. In most cases you  will have to remove 
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200


This file normally contains an entry (in addition to the above) console=tty1 Do not delete this. 
At the end it should look similar to the one below:

Then disable the actual service itself:

Wheezy: Edit /etc/inittab and comment  out the line containing respawn:/sbin/getty -L ttyAMA0 115200
Jessie: sudo systemctl disable serial-getty@ttyAMA0.service

Usually (A) should be adequate – it automatically performs all steps decribed in (B).

In Jessie versions (May 2016 onwards) there is an new option in  /boot/config.txt
enable_uart

If you followed path (A)  then raspi-config will automatically have set enable_uart=0

if you followed path (B) then it should have remained enable_uart=1

Issue command ls /dev
If enable_uart is set to 1 then you should see ttyAMA0 in the list of devices otherwise it would be missing.
In any case edit /boot/config.txt and ensure that enable_uart=1 is at the end of the file.

Rebbot and toy are done.

 

Raspberry PI 3/ZeroW
TTY over serial  is enabled by default. The UART used for TTY is the miniUART (ttyS0).
The reason for the change in tty UART is that both the PI3 and the ZeroW are BT enabled devices
and BT is internally connected to PL011. To get hold of ttyS0 and use it for other serial connections
you first have to disable terminal (TTY) over serial. There are two ways of doing this:

A) raspi-config

in “Interfaceing Options” choose “Serial” (Enable/Disable shell and kernel messages on the serial connection) and disable it.

 

B) edit /boot/cmdline.txt and remove any reference to ttyAMA0. In most cases you  will have to remove 
console=serial0,115200


This file normally contains an entry (in addition to the above) console=tty1 Do not delete this. 
At the end it should look similar to the one below:

Then disable the actual service itself:

Wheezy: Edit /etc/inittab and comment  out the line containing respawn:/sbin/getty -L serial0 115200
Jessie: sudo systemctl disable serial-getty@serial0.service

Usually (A) should be adequate – it automatically performs all steps decribed in (B).

In Jessie versions (May 2016 onwards) there is an new option in  /boot/config.txt
enable_uart

If you followed path (A)  then raspi-config will automatically have set enable_uart=0

if you followed path (B) then it should have remained enable_uart=1

Issue command ls /dev
If enable_uart is set to 1 then you should see ttyS0 in the list of devices otherwise it would be missing.
In any case edit /boot/config.txt and ensure that enable_uart=1 is at the end of the file.

ttyS0 is an inferior port (in many aspects, including speed) compared to ttyAMA0. There are cases where you would want to swap ports
i.e. use ttyAMA0 for serial/GPIO communication and ttyS0 for bluetooth. This can be done very easily with device tree overlays.

edit /boot/config.txt and add  dtoverlay=pi3-miniuart-bt-overlay
..and reboot..

As you can see below, serial0 is now pointing to ttyAMA0 and serial1 to ttyS0, the ports are reversed.

If you want to disable bluetooth alltogether the cleanset ways is by means of dtoverlay. Edit /boot/config.txt
and add dtoverlay=pi3-disable-bt Optionally you might also disable the following service

sudo systemctl disable hciuart

There is also an overlay for disabling WiFi 
dtoverlay=pi3-disable-wifi

 

Be the first to comment

Leave a Reply

Your email address will not be published.


*