aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-11-16 00:44:42 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-11-21 00:58:53 +0700
commit1c2b8c1eb73cbd752749bc7e9e484ca320b95e92 (patch)
tree1011c9fc251e712703bb54c0b261137ed967a8c7 /src
parent1a3b511b328b8fa315d6ba52133a4a1471a56376 (diff)
soft_uart: implement parity checking for the receiver
Diffstat (limited to 'src')
-rw-r--r--src/core/soft_uart.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/src/core/soft_uart.c b/src/core/soft_uart.c
index c7c80206..d8ce9d9a 100644
--- a/src/core/soft_uart.c
+++ b/src/core/soft_uart.c
@@ -43,7 +43,7 @@ struct osmo_soft_uart {
uint8_t bit_count;
uint8_t shift_reg;
struct msgb *msg;
- ubit_t parity_bit;
+ ubit_t parity_bit; /* 0 (even) / 1 (odd) */
unsigned int flags;
unsigned int status;
struct osmo_timer_list timer;
@@ -117,13 +117,16 @@ static inline void osmo_uart_rx_bit(struct osmo_soft_uart *suart, const ubit_t b
suart->rx.flags = 0x00;
suart->rx.shift_reg = 0;
suart->rx.bit_count = 0;
+ suart->rx.parity_bit = 0;
}
break;
case SUART_FLOW_ST_DATA:
suart->rx.bit_count++;
suart->rx.shift_reg >>= 1;
- if (bit != 0)
+ if (bit != 0) {
+ suart->rx.parity_bit = !suart->rx.parity_bit; /* flip */
suart->rx.shift_reg |= 0x80;
+ }
if (suart->rx.bit_count >= suart->cfg.num_data_bits) {
/* we have accumulated enough data bits */
if (suart->cfg.parity_mode != OSMO_SUART_PARITY_NONE)
@@ -133,7 +136,22 @@ static inline void osmo_uart_rx_bit(struct osmo_soft_uart *suart, const ubit_t b
}
break;
case SUART_FLOW_ST_PARITY:
- /* TODO: actually verify parity */
+ switch (suart->cfg.parity_mode) {
+ case OSMO_SUART_PARITY_EVEN:
+ /* number of 1-bits (in both data and parity) shall be even */
+ if (suart->rx.parity_bit != bit)
+ suart->rx.flags |= OSMO_SUART_F_PARITY_ERROR;
+ break;
+ case OSMO_SUART_PARITY_ODD:
+ /* number of 1-bits (in both data and parity) shall be odd */
+ if (suart->rx.parity_bit == bit)
+ suart->rx.flags |= OSMO_SUART_F_PARITY_ERROR;
+ break;
+ case OSMO_SUART_PARITY_NONE: /* shall not happen */
+ default:
+ OSMO_ASSERT(0);
+ }
+
suart->rx.flow_state = SUART_FLOW_ST_STOP;
break;
case SUART_FLOW_ST_STOP: