Skip to content

Instantly share code, notes, and snippets.

@yeokm1
Last active October 9, 2021 09:59
Show Gist options
  • Save yeokm1/d6c3ca927919c61257cd to your computer and use it in GitHub Desktop.
Save yeokm1/d6c3ca927919c61257cd to your computer and use it in GitHub Desktop.
Arch Linux Raspberry Pi 3 configuration to use both Serial Debug Port and Bluetooth

The new Raspberry Pi 3 released on 29 Feb 2016 has issues with its UART port as the pinout GPIO 14/15 on the pin header is now based on a low throughput mini-UART.

To understand the issue better than reading the wall of text below, you can see the talk I gave on this issue.

The actual hardware UART on the BCM2837 SoC has now been assigned to handle Bluetooth with the BCM43438 Wifi/Bluetooth chip. More details can be found here and here.

This mini-UART does not produce a stable baud rate as it fluctuates based on the Core clock speed whenever it rises or falls. The result is that the serial debug output is practically unusable. On Raspbian you may see garbage or nothing at all. The solution is simple, add core_freq=250 to /boot/config.txt to cap the core frequency to a constant value. This option is soon to be discouraged in favour of enable_uart=1 which Arch Linux already supports.

A "pi-bluetooth" package that exists in Raspbian is also not available in Arch Linux (yet) so Bluetooth support is not ready although an AUR package exists to enable BT.

In this gist, I will detail out all the steps required to enable the debug console on the miniUART and install Bluetooth support. At the same time, I have alternative instructions should you want to swap the Bluetooth to use the mini-UART and the debug console to use hardware UART instead.

Required hardware:

  1. Raspberry Pi 3 Model B
  2. 3.3V USB-TTL cable like this from Adafruit or HDMI screen with keyboard or SSH.
  3. Network connection to download packages

Preparing the SD Card

  1. Copy the partition image to your microSD Card based on the installation guide here.
  2. Open the boot partition of the microSD card which should be the small 100MB partition.
  3. Open config.txt
  4. Add the following lines to the end of the file
enable_uart=1

The enable_uart=1 multiplier will cap the CPU speed of your ARM CPU to a constant 600Mhz instead of fluctuating speed up to 1.2Ghz so the baud rate of the mini-UART will be stable. This is roughly equivalent to earlier attempts to solve the problem with core_freq=250.

For extra information, you can also add dtoverlay=pi3-miniuart-bt to switch the pin mappings of the BCM2837 so the Serial Debug port will use the hardware UART and the Bluetooth part of the wireless chip will use the mini-UART.

  1. Unmount the SD card and insert into your Rpi3 and plug your USB-TTL cable.

Install Yaourt

We will need to install the pi-bluetooth package. This package has been ported from Raspbian and posted on AUR by someone. But before that, we should install Yaourt, a tool to install AUR packages.

Using a terminal program on your computer like screen with the serial-TTL console cable, login with default user:alarm, password:alarm. Do not use root yet as makepkg does not like root.

screen /dev/ttyUSB0 115200

#Arch Linux 4.1.19-2-ARCH (ttyS0)

#alarmpi login: alarm
#Password: alarm

#Install package-query, a dependency for Yaourt

su -c "pacman -Syu --needed wget base-devel yajl git"
#Install everything when asked. Password for root is "root"

git clone https://aur.archlinux.org/package-query.git
cd package-query
makepkg -s
su -c "pacman -U package-query-1.8-2-armv7h.pkg.tar.xz"

cd ..

git clone https://aur.archlinux.org/yaourt.git
cd yaourt
makepkg -s
su -c "pacman -U yaourt-1.8.1-1-any.pkg.tar.xz"

Configuring Bluetooth

Continue from the above using the alarm account.

#You might have to remove the existing bluez package if you have istalled it as pi-bluetooth downloads the bluez source code to do some patching before installation.

yaourt -S pi-bluetooth
#1. Enter "1" to install the only package
#2. Give root password (default "root") when asked
#3. Do NOT edit PKGBUILD or anything else when they say "Unsupported Package" or similar warnings. Press "N".
#4. Answer Yes to install any requested dependencies or building

#Do not enable the brcm43438.service now if you have specified `dtoverlay=pi3-miniuart-bt` to swap the Bluetooth to use mini-UART. You have to edit the brcm43438.service first.

#Login as root with default password "root"

su

#ONLY edit the brcm43438.service file if you want Bluetooth to use mini-UART (/dev/ttyS0) instead of hardware UART (/dev/ttyAMA0). 
#That is, if you have specified "dtoverlay=pi3-miniuart-bt" in "/boot/config.txt" earlier

nano /lib/systemd/system/brcm43438.service
#Edit the file to replace all references of /dev/ttyAMA0 with /dev/ttyS0 as below

#start
[Unit]
Description=Broadcom BCM43438 bluetooth HCI
ConditionPathIsDirectory=/proc/device-tree/soc/gpio@7e200000/bt_pins
Before=bluetooth.service
After=dev-ttyS0.device

[Service]
Type=simple
ExecStart=/usr/bin/hciattach-rpi3 -n /dev/ttyS0 bcm43xx 921600 noflow -

[Install]
WantedBy=multi-user.target
#end

systemctl enable brcm43438.service
reboot

If you set the Bluetooth communication to go through the mini-UART channel, the performance will be significantly degraded in theory. In fact, you may want to reduce the baud rate from 921600 to something lower like 460800 or even as low as 115200. However, it should be enough for Bluetooth Low Energy applications. Higher speed data/audio transfer on Bluetooth classic may face issues. You will also need to set core_freq=250 or force_turbo=1 in /boot/config.txt so the baud rate of the mini-UART will be stable to use Bluetooth.

If you use just enable_uart=1 in /boot/config.txt, your RPi 3 will just be slow but everything should work as per normal.

References

  1. UART boot overlay for Raspbian
  2. pi-bluetooth on Arch Linux
  3. enable_uart=1 explanation
  4. Issue on Github
@olanod
Copy link

olanod commented Apr 10, 2017

What would be needed to make bluetooth work without the pi-bluetooth package? new version of bluez deprecates hciattach and btattach should be used instead and apart from that it just feels hacky to use that package

@lukywong
Copy link

lukywong commented May 8, 2017

can this solution use Serial Debug Port and bluetooth at the same time?

@yeokm1
Copy link
Author

yeokm1 commented Jun 1, 2017

@olanod, I'm not sure about this yet.

@lukywong, Serial Debug port and bluetooth can be used at the same time.

@rthomas67
Copy link

Haven't tried tweaking the UART settings in /boot/config.txt yet, but this seems to be the btattach translation of the hciattach command that is in the AUR pi-bluetooth package.

btattach -N -B /dev/ttyAMA0 -P bcm -S 921600

Also, this looks for /lib/firmware/brcm/BCM.hcd instead of /etc/firmware/BCM43430A1.hcd (where AUR pi-bluetooth installs it), so you might need to move/rename that file.

When it runs, it shows this error (which I'm not sure means anything, but it might be related to the UART issues):
Bluetooth: hci0: BCM: failed to write clock (-56)

@MichaelKlemm
Copy link

Hi @rthomas67 !
I got the same error using btattach. Why btattach should report an error while hciattach doesn't? Is there any other difference why btattach isn't working? Using the old hciattach, everything was working fine.
Best regards,
Michael

@footniko
Copy link

footniko commented Jun 8, 2019

uname -a
Linux alarm 4.19.46-2-ARCH #1 SMP PREEMPT Tue Jun 4 00:09:00 UTC 2019 armv7l GNU/Linux

Adding enable_uart=1 in the /boot/config.txt causes kernel panic on RPi3 and the system doesn't boot at all.
Is there any workaround on this?

@yeokm1
Copy link
Author

yeokm1 commented Jun 9, 2019

Hi @footniko, I'm not sure about this as I've not been using this in a long time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment