Enabling an External UART on AutoPi TMU CM4 Devices
Prerequisites
- SSH access or Physical HDMI/USB console.
- Micro‑jumper wires or a breakout header to reach pins 27/28.
- A multimeter (optional but handy for continuity checks).
Why GPIO 0/1?
The CM4 has six UART blocks but only GPIO 0 & 1 expose the pins for UART 2 (alt‑function 4). Your other free pins—GPIO22‑24, 27
—can do many clever things (SPI, PCM, PWM) but not TX/RX. Hence we use the HAT‑EEPROM I²C pins (ID_SD
, ID_SC
) for serial use.
Normally the Pi firmware tugs GPIO0/1
low during the first 200 ms of boot while it looks for a HAT EEPROM. The force_eeprom_read=0
flag in the next section disables that so your external device sees a clean idle‑high line from power‑up.
1 Hardware wiring
HAT label | BCM GPIO | UART2 signal | Connect to |
---|---|---|---|
ID_SD | 0 | TXD2 (Pi → device) | RX of the external device |
ID_SC | 1 | RXD2 (device → Pi) | TX of the external device |
I2C1_SDA* | 2 | CTS2 (optional) | RTS of the device |
I2C1_SCL* | 3 | RTS2 (optional) | CTS of the device |
GND | — | — | Common ground |
Wire CTS/RTS only if you need hardware flow control and intend to enable it in the dtoverlay
.
AutoPi TMU CM4 External Device
┌──────────────┐ ┌────────────┐
ID_SD│27 TXD2 ➔──┼────►│ RX │
ID_SC│28 RXD2 ◄──┼─────│ TX │
SDA │ 3 CTS2 ◄──┼─────│ RTS (opt) │
SCL │ 5 RTS2 ➔──┼────►│ CTS (opt) │
GND │ 6 GND ───┼─────│ GND │
└──────────────┘ └────────────┘
If the external device works at 5 V TTL or ±12 V RS‑232, you must level‑shift or use a proper line driver (e.g. MAX3232, SN65HVD230 for RS‑485). Direct 5 V into a CM4 pin can permanently damage the SoC.
2 Enable UART2 in config.txt
Open the file with sudo nano /boot/config.txt
and add:
# === External UART2 on GPIO0/1 ===
force_eeprom_read=0 # skip HAT‑EEPROM probe on GPIO0/1
dtoverlay=uart2 # TX=GPIO0, RX=GPIO1 => /dev/ttyAMA1
#dtoverlay=uart2,ctsrts # remove # to enable flow control on GPIO2/3
enable_uart=1 # leave as‑is if already present
Save, exit, and sudo reboot
.
Check dmesg after the reboot:
dmesg | grep -i ttyAMA1
You should see a line similar to ttyAMA1 at MMIO 0x.....
confirming the driver is active.
3 Verify with a loop‑back test
-
Jumper
GPIO0
toGPIO1
directly on the HAT. -
Open a terminal on the Pi and run:
stty -F /dev/ttyAMA1 115200 raw -echo
echo "hello" > /dev/ttyAMA1 &
cat < /dev/ttyAMA1 -
The word
hello
should appear. Press Ctrl‑C, remove the jumper, and connect your real device.
Alternative: use minicom
sudo apt install -y minicom
minicom -b 115200 -D /dev/ttyAMA1
Minicom gives you scroll‑back, line‑ending control and macros—handy for debugging.
4 Using the port in Python
import serial
ser = serial.Serial(
port='/dev/ttyAMA1',
baudrate=115200,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
ser.write(b'AT\r') # send a modem‑style command
print(ser.readline()) # read back a line
ser.close()
Python’s pyserial
package makes scripting trivial—ideal for quick sensor polls.
5 Troubleshooting
Symptom | Likely cause & fix |
---|---|
No /dev/ttyAMA1 | Overlay typo or missing enable_uart=1 . Re‑check /boot/config.txt . |
Boot hang with garbage on console | Another service (e.g. serial‑getty@ttyAMA1.service ) grabbed the port. Disable it with sudo systemctl disable --now serial-getty@ttyAMA1.service . |
Lines held low for ~0.2 s after power‑up | force_eeprom_read=0 missing; firmware still probing EEPROM. |
Flow‑control ignored | Verify you removed # in dtoverlay=uart2,ctsrts and wired GPIO2/3 correctly. |
Overruns at >1 Mbit/s | Increase init_uart_clock in config.txt or use DMA mode via dwc_uart_fifo_enable=1 . |
6 Advanced topics
Disable I²C on GPIO0/1 entirely
If another overlay or user‑space application tries to re‑enable I²C0, add dtparam=i2c_vc=off
to config.txt
.
Throughput tuning
Use core_freq_min=250
to keep the UART clock stable during idle throttling, and prefer 8N1 framing for max payload density.