Skip to content

Commit 59614a9

Browse files
ahmedarif193Ahmed ARIF
andauthored
optimize parity calculations in SerialPIO (#2932) (#2933)
use bit manipulation technique from http://www.graphics.stanford.edu/~seander/bithacks.html#ParityParallel for parity calculation Co-authored-by: Ahmed ARIF <[email protected]>
1 parent 227d71e commit 59614a9

File tree

1 file changed

+8
-11
lines changed

1 file changed

+8
-11
lines changed

cores/rp2040/SerialPIO.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,10 @@ static PIOProgram *_getRxProgram(int bits) {
6868
}
6969
// ------------------------------------------------------------------------
7070

71-
// TODO - this works, but there must be a faster/better way...
72-
static int __not_in_flash_func(_parity)(int bits, int data) {
73-
int p = 0;
74-
for (int b = 0; b < bits; b++) {
75-
p ^= (data & (1 << b)) ? 1 : 0;
76-
}
77-
return p;
71+
static int __not_in_flash_func(_parity)(int data) {
72+
data ^= data >> 4;
73+
data &= 0xf;
74+
return (0x6996 >> data) & 1;
7875
}
7976

8077
// We need to cache generated SerialPIOs so we can add data to them from
@@ -100,14 +97,14 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() {
10097
uint32_t decode = _rxPIO->rxf[_rxSM];
10198
uint32_t val = decode >> (32 - _rxBits - 1);
10299
if (_parity == UART_PARITY_EVEN) {
103-
int p = ::_parity(_bits, val);
100+
int p = ::_parity(val);
104101
int r = (val & (1 << _bits)) ? 1 : 0;
105102
if (p != r) {
106103
// TODO - parity error
107104
continue;
108105
}
109106
} else if (_parity == UART_PARITY_ODD) {
110-
int p = ::_parity(_bits, val);
107+
int p = ::_parity(val);
111108
int r = (val & (1 << _bits)) ? 1 : 0;
112109
if (p == r) {
113110
// TODO - parity error
@@ -374,10 +371,10 @@ size_t SerialPIO::write(uint8_t c) {
374371
if (_parity == UART_PARITY_NONE) {
375372
val |= 7 << _bits; // Set 2 stop bits, the HW will only transmit the required number
376373
} else if (_parity == UART_PARITY_EVEN) {
377-
val |= ::_parity(_bits, c) << _bits;
374+
val |= ::_parity(c) << _bits;
378375
val |= 7 << (_bits + 1);
379376
} else {
380-
val |= (1 ^ ::_parity(_bits, c)) << _bits;
377+
val |= (1 ^ ::_parity(c)) << _bits;
381378
val |= 7 << (_bits + 1);
382379
}
383380
val <<= 1; // Start bit = low

0 commit comments

Comments
 (0)