Describe the bug
Hardware:
- Raspberry Pi CM5 (RP1 UART, /dev/ttyAMA0, pl011-axi 1f00030000.serial)
- Also reproduced on Raspberry Pi 4 (PL011, /dev/ttyAMA0, pl011-axi fe201000.serial)
- OS: Raspberry Pi OS, kernel 6.x
- UART: 115200 baud, 8N1, /dev/ttyAMA0, dtoverlay=disable-bt
Problem:
Every time we call write() on /dev/ttyAMA0 after the TX line has been idle, the UART transmits 50–127 spurious garbage bytes before our actual data. This happens on every write after any idle period — not
only at port open.
The receiving device (a dsPIC33EP microcontroller) observes these extra bytes and responds with an error before the real command arrives.
This was confirmed by a 2014 Raspberry Pi forum post which described a 40µs low-going glitch on TX at every transmission start, visible on an oscilloscope.
What we have tried:
- Confirmed UART is /dev/ttyAMA0 (PL011, not mini-UART) with disable-bt overlay
- Serial console disabled (console=tty1 in cmdline.txt)
- cfmakeraw() + correct termios settings (CLOCAL, CREAD, CS8, no flow control)
- Opening with O_RDWR | O_NOCTTY | O_NONBLOCK
- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK) to remove non-blocking
- Keeping the port open (no open/close per transaction)
- 100Ω series resistor already present on TX line — does not fix the issue
Confirmed behaviour:
- The spurious bytes appear on every write() after TX has been idle
- They are genuine UART-level bytes (confirmed by the receiver logging them)
- The glitch is MORE severe on CM5 RP1 than Pi 4 PL011 (CM5 generates ~127 bytes vs Pi 4 ~50 bytes)
- No DMA configured for ttyAMA0: dmesg shows "there is not valid maps for state default" on Pi 4, and dw_axi_dmac exists on CM5 RP1 but is not connected to the UART in the device tree
Question:
- Is there a known driver-level fix or kernel parameter to suppress this spurious TX burst at idle→active transitions on PL011/RP1 UART?
- Is DMA mode available for ttyAMA0 on CM5 (RP1) and if so what device tree configuration is needed? We understand DMA might prevent kernel scheduler interruptions during TX which may be the root cause.
- Is there a recommended config.txt or termios setting to minimise this behaviour?
Workaround we are currently using:
We prepend 10 blank lines (\n × 10) to every command in the same write() call. The first \n absorbs the glitch burst; the real command follows cleanly. This works but adds latency
Steps to reproduce the behaviour
onnect a logic analyser or oscilloscope to GPIO 14 (TXD0). Alternatively connect a UART receiver (e.g. Arduino or another microcontroller) that echoes every received byte back.
Minimal reproduction code — save as uart_glitch_test.c:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main(void) {
int fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios tty;
tcgetattr(fd, &tty);
cfmakeraw(&tty);
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
tty.c_cflag |= CLOCAL | CREAD;
tcsetattr(fd, TCSANOW, &tty);
/* Port is now open and idle */
sleep(1);
/* First write after idle — observe TX on oscilloscope */
printf("Writing PING...\n");
write(fd, "PING\n", 5);
sleep(1);
/* Second write after idle — same glitch repeats */
printf("Writing PING again...\n");
write(fd, "PING\n", 5);
close(fd);
return 0;
}
Compile and run:
gcc uart_glitch_test.c -o uart_glitch_test && ./uart_glitch_test
Expected behaviour:
The oscilloscope or receiver sees exactly P I N G \n (5 bytes) for each write.
Actual behaviour:
Before each PING\n, the TX line transmits 50–127 spurious garbage bytes that the receiver picks up as unexpected data. This happens on every write() call after any idle period — not only at first use after
port open.
The receiver responds to the garbage bytes instead of the intended PING command. Only if the garbage happens to be ignored or absorbed does the real command succeed.
The glitch repeats identically on the second write — confirming it is not a one-time port-open artefact but occurs at every idle→active TX transition.
Observed on:
- Raspberry Pi CM5, kernel 6.6, /dev/ttyAMA0 (pl011-axi, RP1 chip)
- Raspberry Pi 4B, kernel 6.6, /dev/ttyAMA0 (pl011-axi, BCM2711)
- Both with dtoverlay=disable-bt, serial console disabled, no hardware flow contro
Device (s)
Raspberry Pi 4 Mod. B, Raspberry Pi 5
System
onnect a logic analyser or oscilloscope to GPIO 14 (TXD0). Alternatively connect a UART receiver (e.g. Arduino or another microcontroller) that echoes every received byte back.
Minimal reproduction code — save as uart_glitch_test.c:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main(void) {
int fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios tty;
tcgetattr(fd, &tty);
cfmakeraw(&tty);
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
tty.c_cflag |= CLOCAL | CREAD;
tcsetattr(fd, TCSANOW, &tty);
/* Port is now open and idle */
sleep(1);
/* First write after idle — observe TX on oscilloscope */
printf("Writing PING...\n");
write(fd, "PING\n", 5);
sleep(1);
/* Second write after idle — same glitch repeats */
printf("Writing PING again...\n");
write(fd, "PING\n", 5);
close(fd);
return 0;
}
Compile and run:
gcc uart_glitch_test.c -o uart_glitch_test && ./uart_glitch_test
Expected behaviour:
The oscilloscope or receiver sees exactly P I N G \n (5 bytes) for each write.
Actual behaviour:
Before each PING\n, the TX line transmits 50–127 spurious garbage bytes that the receiver picks up as unexpected data. This happens on every write() call after any idle period — not only at first use after
port open.
The receiver responds to the garbage bytes instead of the intended PING command. Only if the garbage happens to be ignored or absorbed does the real command succeed.
The glitch repeats identically on the second write — confirming it is not a one-time port-open artefact but occurs at every idle→active TX transition.
Observed on:
- Raspberry Pi CM5, kernel 6.6, /dev/ttyAMA0 (pl011-axi, RP1 chip)
- Raspberry Pi 4B, kernel 6.6, /dev/ttyAMA0 (pl011-axi, BCM2711)
- Both with dtoverlay=disable-bt, serial console disabled, no hardware flow contro
Logs
Additional context
No response
Describe the bug
Hardware:
Problem:
Every time we call write() on /dev/ttyAMA0 after the TX line has been idle, the UART transmits 50–127 spurious garbage bytes before our actual data. This happens on every write after any idle period — not
only at port open.
The receiving device (a dsPIC33EP microcontroller) observes these extra bytes and responds with an error before the real command arrives.
This was confirmed by a 2014 Raspberry Pi forum post which described a 40µs low-going glitch on TX at every transmission start, visible on an oscilloscope.
What we have tried:
Confirmed behaviour:
Question:
Workaround we are currently using:
We prepend 10 blank lines (\n × 10) to every command in the same write() call. The first \n absorbs the glitch burst; the real command follows cleanly. This works but adds latency
Steps to reproduce the behaviour
onnect a logic analyser or oscilloscope to GPIO 14 (TXD0). Alternatively connect a UART receiver (e.g. Arduino or another microcontroller) that echoes every received byte back.
Minimal reproduction code — save as uart_glitch_test.c:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main(void) {
int fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios tty;
tcgetattr(fd, &tty);
cfmakeraw(&tty);
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
tty.c_cflag |= CLOCAL | CREAD;
tcsetattr(fd, TCSANOW, &tty);
}
Compile and run:
gcc uart_glitch_test.c -o uart_glitch_test && ./uart_glitch_test
Expected behaviour:
The oscilloscope or receiver sees exactly P I N G \n (5 bytes) for each write.
Actual behaviour:
Before each PING\n, the TX line transmits 50–127 spurious garbage bytes that the receiver picks up as unexpected data. This happens on every write() call after any idle period — not only at first use after
port open.
The receiver responds to the garbage bytes instead of the intended PING command. Only if the garbage happens to be ignored or absorbed does the real command succeed.
The glitch repeats identically on the second write — confirming it is not a one-time port-open artefact but occurs at every idle→active TX transition.
Observed on:
Device (s)
Raspberry Pi 4 Mod. B, Raspberry Pi 5
System
onnect a logic analyser or oscilloscope to GPIO 14 (TXD0). Alternatively connect a UART receiver (e.g. Arduino or another microcontroller) that echoes every received byte back.
Minimal reproduction code — save as uart_glitch_test.c:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
int main(void) {
int fd = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NONBLOCK);
struct termios tty;
tcgetattr(fd, &tty);
cfmakeraw(&tty);
cfsetispeed(&tty, B115200);
cfsetospeed(&tty, B115200);
tty.c_cflag |= CLOCAL | CREAD;
tcsetattr(fd, TCSANOW, &tty);
}
Compile and run:
gcc uart_glitch_test.c -o uart_glitch_test && ./uart_glitch_test
Expected behaviour:
The oscilloscope or receiver sees exactly P I N G \n (5 bytes) for each write.
Actual behaviour:
Before each PING\n, the TX line transmits 50–127 spurious garbage bytes that the receiver picks up as unexpected data. This happens on every write() call after any idle period — not only at first use after
port open.
The receiver responds to the garbage bytes instead of the intended PING command. Only if the garbage happens to be ignored or absorbed does the real command succeed.
The glitch repeats identically on the second write — confirming it is not a one-time port-open artefact but occurs at every idle→active TX transition.
Observed on:
Logs
Additional context
No response