Skip to content

Commit 5927d4e

Browse files
Fix SerialPIO sampling, avoid reading random garbage (#544)
Adjust the 1/2 bit time to match the number of extra cycles in the actual PIO loop. Throw out the entire start bit, which results in sampling the data at the midpoint and not the starting time of a bit (which was causing random failures on read data). Tested at 300bps all the way to 2,000,000bps using a loopback connection. Fixes #360
1 parent 5dee051 commit 5927d4e

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

cores/rp2040/SerialPIO.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() {
9797
}
9898
while (!pio_sm_is_rx_fifo_empty(_rxPIO, _rxSM)) {
9999
uint32_t decode = _rxPIO->rxf[_rxSM];
100-
decode >>= 32 - _rxBits;
100+
decode >>= 33 - _rxBits;
101101
uint32_t val = 0;
102102
for (int b = 0; b < _bits + 1; b++) {
103103
val |= (decode & (1 << (b * 2))) ? 1 << b : 0;
@@ -229,7 +229,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
229229
pio_sm_clear_fifos(_rxPIO, _rxSM); // Remove any existing data
230230

231231
// Put phase divider into OSR w/o using add'l program memory
232-
pio_sm_put_blocking(_rxPIO, _rxSM, clock_get_hz(clk_sys) / (_baud * 2) - 2);
232+
pio_sm_put_blocking(_rxPIO, _rxSM, clock_get_hz(clk_sys) / (_baud * 2) - 5 /* insns in PIO halfbit loop */);
233233
pio_sm_exec(_rxPIO, _rxSM, pio_encode_pull(false, false));
234234

235235
// Join the TX FIFO to the RX one now that we don't need it

0 commit comments

Comments
 (0)