When using ASYNC communications over an RF link it is often difficult to ensure that the receiver is properly syncronized at the byte level. If the receiver isn't syncronized you will see framing errors, invalid characters, or both.
Note: this discussion is based on the following constraints and asssumptions.
We can never transmit more than 3 consecutive 0's or 1's. (This accounts for the fact that many RF links have to remain at least moderately balanced. They cannot handle many consecutive zeros or ones).
Communications are assumed to use the same conventions as a standard UART. Specifically: START bits are the same condition on the line as a data bit of 0; STOP bits are the same condition on the line as a data bit of 1; and the LSBit (bit 0) is transmitted first.
We assume the receiving UART will detect a framing error and attempt to resynchronize whenever it sees a zero where it is expecting the stop bit (which should be a one).
We assume the receiving UART will start searching for a new start bit (0 state) immediately after the line returns to a 1 state after encountering a framing error condition.
First, we want to transmit a continuous alternating sequence of 0's and 1's to condition the receiver and set up the bit-level syncronization. We can do so by repeatedly transmitting the byte value 0x55 as a preamble. This works because we send:
START BIT (0)
bit 0 (1)
bit 1 (0)
.
.
.
bit 6 (1)
bit 7 (0)
STOP BIT (1)
The receiving UART will nicely sync on this, but of course it could be misaligned byte wise. There are 5 possible conditions:
Case A: The receive UART is properly aligned.
Case B: The receive UART is shifted 2 bit times (bit 6 is being treated as the stop bit, bit 7 as the start bit)
Case C: The receive UART is shifted 4 bit times (bit 4 is being treated as the stop bit, bit 5 as the start bit)
Case D: The receive UART is shifted 6 bit times (bit 2 is being treated as the stop bit, bit 3 as the start bit)
Case E: The receive UART is shifted 8 bit times (bit 0 is being treated as the stop bit, bit 1 as the start bit)
Now we have to come up with a way to convert the unaligned cases to the aligned case by taking advantage of the way the UART detects framing errors. We do this by transmitting a 0 data bit where the UART expects a stop bit (a 1). We carefully pick values to send so that the framing errors that we cause results in the UART translating the cases B, C, D and E to case A, sometimes through several steps.
First, we send the binary value B'01000100'. This will cause a framing error only in Cases C and E above (because bits 4 and 0 are the wrong state for a stop bit). In Case C, the UART will treat bit 7 as the next start bit, translating us to case B. In Case E, the UART will then treat bit 3 as the next start bit, translating us to case D.
Second, we send the binary value B'00010001'. This will cause a framing error only in Cases B and D above (because bits 6 and 2 are the wrong state for a stop bit). In Case B, the UART will treat the start bit of the next byte as the next start bit, translating us to Case A. In Case D, the UART will treat bit 5 as the next start bit, translating us to Case C.
Third, we send the binary value B'01000101'. This will cause a framing error only in Case C above (because bit 4 is the wrong state for a stop bit). In this case the UART will treat bit 7 as the next start bit, translating us to case B.
Finally, we send the binary value B'00010101'. This will cause a framing error only in Case B above (because bit 6 is the wrong state for a stop bit). In this case the UART will treat the start bit of the next byte as the next start bit, translating us to Case A.
So, in summary, the transmitter could send:
Preamble of "N" bytes of 0x55 (at this point the receiver is in any of the 5 cases)
B'01000100'(the receiver is in case A, B or D because we mapped C to B and E to D)
B'00010001' (the receiver is in case A or C because we mapped B to A and D to C)
B'01000101' (the receiver is in case A or B because we mapped C to B)
B'00010101' (the receiver is in case A because we mapped B to A)
And now we know we have the correct byte syncronization!
Comments:
A superb piece - exactly what I was looking for. Your use of the FERR correction is brilliant. Took me a while to figure out what you meant but once I did - fantastic!+