RS232 UART frame/data overrun error handling

I did some searches but did not find info on this. I am trying to understand what sort of error handling the Arduino HardwareSerial routines perform. Apparently little to none, from what I can tell.

First, I tried to boil down the Rx ISR code in the HardwareSerial.cpp file (for the ATmega328) to the bare minimum, and came up with the following. It appears to do a parity error check, but no others.

ISR(USART0_RX_vect)
{
    if (bit_is_clear(UCSR0A, UPE0)) {
      unsigned char c = UDR0;
      store_char(c, &rx_buffer);
    } else {
      unsigned char c = UDR0;
    };
}

Secondly, the ATmega328 d/s says the following:

20.11.2 UCSRnA – USART Control and Status Register n A

• Bit 4 – FEn: Frame Error
This bit is set if the next character in the receive buffer had a Frame Error when received. I.e., when the first stop
bit of the next character in the receive buffer is zero. This bit is valid until the receive buffer (UDRn) is read. The
FEn bit is zero when the stop bit of received data is one. Always set this bit to zero when writing to UCSRnA.

• Bit 3 – DORn: Data OverRun
This bit is set if a Data OverRun condition is detected. A Data OverRun occurs when the receive buffer is full (two
characters), it is a new character waiting in the Receive Shift Register, and a new start bit is detected. This bit is
valid until the receive buffer (UDRn) is read. Always set this bit to zero when writing to UCSRnA.

• Bit 2 – UPEn: USART Parity Error
This bit is set if the next character in the receive buffer had a Parity Error when received and the Parity Checking
was enabled at that point (UPMn1 = 1). This bit is valid until the receive buffer (UDRn) is read. Always set this bit to
zero when writing to UCSRnA.

All 3 items say "This bit is valid until the receive buffer (UDRn) is read".

So, putting 1 and 2 together, it appears that any Rx character that invokes an FE, DOR, or UPE error will likely be incorrect in the c = UDR0; assignment, but UART reception will NOT be disrupted in any way, and it will go on to receive any follow-on characters ok. IOW, such errors will just trigger flags, but they'll have no effect if ignored. The data will just be wrong.

Yes, no, maybe?

That's what it looks like to me; I'm going to go with "yes".

The data will just be wrong.

Except it isn't storing the wrong data.

I'm thinking the character that invoked the error flag will likely be wrong, let's say due to a noise spike that caused a framing error, but the UART will keep plugging along, so the next chars will be received OK. It appears to be only the parity error that causes no data to be stored.

Also, it occurred to me, the more likely case is the incoming data baudrate is different from the UART setting, so the UART just keeps putting out bad data, but doesn't hang in the process.

Why are you curious about the (lack of) error handling?

Actually, I was more curious as to whether the Rx UART might hang/whatever in case there were various frame/overrun errors. I should have realized then that it doesn't happen in the case the sender is using the wrong baudrate, so unlikely to happen for such cases. However, I do like to try and understand the basic underlying code too. After all, it could have read something like,

ISR(USART0_RX_vect)
{
    if ( !any-error() ) {
      unsigned char c = UDR0;
      store_char(c, &rx_buffer);
    } else {
      unsigned char c = UDR0;
    };
}

Also, I am currently in the process of building an RS232 master/slave network, where the master Tx pin goes to all the slave Rx pins, and the slave Tx pins are all wired-ANDed together. Normally, the slaves only "respond" to master transmissions [each slave has a unique node_address for filtering incoming msgs], but I also wanted to give the slaves ability to "request service", eg by sending a short "!!" msg, so there's a possibility that more than 1 slave might signal at the same time, and the msgs would clash. Then there would be Rx errors in the master UART.

The network should be working in the next day or two. Maybe I'll post how it goes. [probably should have posted this thread to the Networking section].

oric_dan:
Also, I am currently in the process of building an RS232 master/slave network, where the master Tx pin goes to all the slave Rx pins, and the slave Tx pins are all wired-ANDed together.

To protect them from a short-circuit?

(Isn't it a wired-OR?)

oric_dan:
...so there's a possibility that more than 1 slave might signal at the same time, and the msgs would clash.

A CRC on normal packets would be a good idea. Especially given how framing errors and overruns are handled.

(Isn't it a wired-OR?)

I've never been able to get to the bottom of that. Everyone says "wired-OR", but if you look at the logic of an open-collector bus if any input goes low so does the output, that's an AND function.

Therefore I usually say "wired-AND".


Rob Confused

Graynomad:
...if you look at the logic of an open-collector bus if any input goes low so does the output, that's an AND function.

Ah! Now the term makes sense. Thanks for that.

Not sayin' I'm right, that's just my take on it. Maybe there's a historical reason from diode-logic days or something.


Rob

Wired-AND diode ckt:

DTL NAND gate - wired-AND with inverter:

TTL NAND gate, upgrade on DTL NAND:

To protect them from a short-circuit?

The reason for using wired-AND is because, for RS232 UARTs, the idle state is high, and the active state is low, and only 1 signal goes low at a time, and the diodes isolate the inputs from each other. This is negative-logic, a wired-OR would be used for positive-logic.

I'm using diodes initially, but also bought a few 74HC logic gates last week, just in case.