diff options
author | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2023-11-16 00:44:42 +0700 |
---|---|---|
committer | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2023-11-21 00:58:53 +0700 |
commit | 1c2b8c1eb73cbd752749bc7e9e484ca320b95e92 (patch) | |
tree | 1011c9fc251e712703bb54c0b261137ed967a8c7 /src | |
parent | 1a3b511b328b8fa315d6ba52133a4a1471a56376 (diff) |
soft_uart: implement parity checking for the receiver
Change-Id: I28be2ca19d423447a718fb518566d52ae1967ec7
Related: OS#4396
Diffstat (limited to 'src')
-rw-r--r-- | src/core/soft_uart.c | 24 |
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: |