0

I have a sensor which every 1 second spits out a 32-character serial stream at 9600 baud. I hooked it up to the mini-UART pins on the GPIO connector. What I saw was bad data.

After staring at the received data (and looking at the actual data on an oscilloscope) for a while it became clear that it was "losing synchronization" with the data. i.e. even though it was supposed to start capturing data at the falling edge after a stop bit, it was obviously capturing bits at other times, leading to garbled characters.

Now here was the confusing part: I also had a different sensor from another company that was working PERFECTLY on the original mini-UART. So why would one sensor work fine and the other not, with the same RPi configuration?

The sensor with the bad readings also uses the parity bit. It was set to provide even parity, so the parity bit could be high or low depending in the data in the previous 8 bit slots.

As another experiment, I used the various switches in config.txt (disable-bt for example) to use the AMA0 UART instead of the S0 UART, and everything worked fine!!! So the problem is obviously with the S0 UART and not the AMA0 UART.

2

The documentation does hint that there are various problems/shortcomings with the mini-UART but it still did not explain why it was screwing up. I finally found the reference that helped to explain the behavior.

The key was finally reading section 2.2 of the BCM2835 ARM Peripherals documents, link found on the RPi site. This section describes the mini-UART operation in a bit more detail.

The document noted above says:

After receiving a start bit and 8 (or 7) data bits the receiver waits for one half bit time and then starts scanning for the next start bit. The mini UART does not check if the stop bit is high or wait for the stop bit to appear. As a result of this a UART1_RX input line which is continuously low (a break condition or an error in connection or GPIO setup) causes the receiver to continuously receive 0x00 symbols.

Link to doc: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf

So what was happening was that the UART would receive the 8 data bits, and if the parity was already even in the data, the parity bit (which is bit 9 in the serial stream) would be low. Instead of using it as a parity bit, the UART would see that as a low and interpret that as a start condition and start receiving another character. Of course the next bit or two would be high as these are the stop bits, and after that you get a low for the next start, etc, so the data received was nonsense.

So in summary, the mini-UART on RPi 3 and earlier simply will not work if you have data that uses parity checking!!! In this case the sensor I have cannot be told to not use parity, so the only way I can use it with the RPi3 or earlier is to swap the UART's as noted above.

I have tried the same experiment with the RPi 4. Best as I can tell this problem has been fixed. I seem to be able to use either UART on the 4 and it works as expected.

I will conclude by just noting that this was a ridiculously stupid design decision on the chip designers part.

| improve this answer | |
  • 1
    This is a repost of an earlier post I tried to make, which got closed so I could not change it to a Q&A format. Mods feel free to delete that earlier post... – Larry Klein Mar 4 at 13:03
  • This is good and useful information. I'll upvote it if you do one thing: add a link to the document you referenced. Wrt your comment about that being a "ridiculously stupid design decision", I'll say two things: 1. it probably wasn't a decision, 2. yeah, not a great design. But they've made worse boo-boos IMHO. – Seamus Mar 5 at 20:48
  • added link to document – Larry Klein Mar 5 at 21:57
  • To summarise - if you ignore the well documented limitations of the interface it does unexpected things. – Milliways Mar 5 at 23:48
  • I'm sorry but I disagree. The documents I read said "does not support parity" which is NOT the same as "if your device happens to use the parity bit, it will garble your data". A benign "ignore parity" is what I read from the docs, not a wholesale "screws your data up". – Larry Klein Mar 6 at 0:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.