UART on Raspberry Pi 3

Raspberry Pi 3 is pretty awesome for including Wi-Fi and Bluetooth (with Bluetooth LE) at the $35 price point. It provides Wi-Fi through SDIO and Bluetooth through a serial port.

But when you receive your new Pi 3 (at a markup because it is rarely in stock), you will discover that the serial port you traditionally used no longer worked properly. All you got was garbage. This is because the PL011 UART is now used by the Bluetooth chip and the GPIO UART is now handled by a crappy mini-UART, which depends on the ‘core’ clock speed. The core here does not mean the usual ARM core; it is the GPU core which means that the GPU actually handles the mini-UART.

Let’s look at the changes between Pi 2 and Pi 3 related to the UART:
– /dev/ttyACM0, which used to refer to the GPIO UART in Pi 2, now refers to the Bluetooth UART
– There is a new /dev/ttyS0 which is assigned to the mini-UART
– The kernel cmdline changed from console=ttyACM0,115200 in Pi 2 to console=ttyS0,115200 in Pi 3
– start.elf *changes* the console parameter in cmdline.txt, replacing ttyACM0 with ttyS0 during runtime. This is a pretty significant non-intuitive change that is not officially documented anywhere.
– (earlier Raspbian change) getty is no longer started on ttyACM0/ttyS0 by inittab

There are two options to have a usable UART on Pi 3:
1. Re-assign the PL011 UART to the GPIO header by making changes to the device tree. You can either disable Bluetooth or reassign it to the mini-UART. The overlay README explains this pretty well.
2. Make the core clock speed constant so that the mini-UART becomes usable. This can be done by setting enable_uart to 1 in /boot/config.txt. The full explanation is at the Raspberry Pi forum thread.

Side note: The service that attaches the Bluetooth UART to bluez is systemd-only. It does not work if you switch to sysvinit or any other init system.

References:
https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=137932
https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=141195
https://github.com/raspberrypi/firmware/issues/553
https://github.com/RPi-Distro/repo/issues/22#issuecomment-191287788
https://github.com/RPi-Distro/repo/issues/22#issuecomment-192192651
https://github.com/RPi-Distro/repo/issues/22#issuecomment-192345936
https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README
http://elinux.org/RPiconfig