laforge has submitted this change. ( https://gerrit.osmocom.org/c/libosmocore/+/35022?usp=email )
Change subject: soft_uart: rework osmo_uart_rx_bit() to use flow state ...................................................................... soft_uart: rework osmo_uart_rx_bit() to use flow state Change-Id: I40ab5d12b6f7087daa51405468f5c4ea639561ea Related: OS#4396 --- M src/core/soft_uart.c 1 file changed, 55 insertions(+), 38 deletions(-) Approvals: laforge: Looks good to me, approved Jenkins Builder: Verified jolly: Looks good to me, but someone else must approve diff --git a/src/core/soft_uart.c b/src/core/soft_uart.c index 5b58848..c7c8020 100644 --- a/src/core/soft_uart.c +++ b/src/core/soft_uart.c @@ -26,6 +26,14 @@ #include <osmocom/core/timer.h> #include <osmocom/core/soft_uart.h> +/*! Rx/Tx flow state of a soft-UART */ +enum suart_flow_state { + SUART_FLOW_ST_IDLE, /*!< waiting for a start bit or Tx data */ + SUART_FLOW_ST_DATA, /*!< receiving/transmitting data bits */ + SUART_FLOW_ST_PARITY, /*!< receiving/transmitting parity bits */ + SUART_FLOW_ST_STOP, /*!< receiving/transmitting stop bits */ +}; + /*! Internal state of a soft-UART */ struct osmo_soft_uart { struct osmo_soft_uart_cfg cfg; @@ -39,6 +47,7 @@ unsigned int flags; unsigned int status; struct osmo_timer_list timer; + enum suart_flow_state flow_state; } rx; struct { bool running; @@ -98,50 +107,46 @@ /* receive a single bit */ static inline void osmo_uart_rx_bit(struct osmo_soft_uart *suart, const ubit_t bit) { - unsigned int num_parity_bits = 0; - if (!suart->rx.running) return; - if (suart->rx.bit_count == 0) { - /* start bit is 0. Wait if there is none */ - if (bit == 0) { - /* START bit */ - suart->rx.flags = 0; + switch (suart->rx.flow_state) { + case SUART_FLOW_ST_IDLE: + if (bit == 0) { /* start bit condition */ + suart->rx.flow_state = SUART_FLOW_ST_DATA; + suart->rx.flags = 0x00; suart->rx.shift_reg = 0; - suart->rx.bit_count++; - } - return; - } - - if (suart->cfg.parity_mode != OSMO_SUART_PARITY_NONE) - num_parity_bits = 1; - - suart->rx.bit_count++; - if (suart->rx.bit_count <= 1 + suart->cfg.num_data_bits) { - /* DATA bit */ - suart->rx.shift_reg = suart->rx.shift_reg >> 1; - if (bit) - suart->rx.shift_reg |= 0x80; - } else if (suart->cfg.parity_mode != OSMO_SUART_PARITY_NONE && - suart->rx.bit_count == 1 + suart->cfg.num_data_bits + 1) { - /* PARITY bit */ - suart->rx.parity_bit = bit; - /* TODO: verify parity */ - //suart->rx.flags |= OSMO_SUART_F_PARITY_ERROR; - } else if (suart->rx.bit_count <= - 1 + suart->cfg.num_data_bits + num_parity_bits + suart->cfg.num_stop_bits) { - /* STOP bit */ - if (bit != 1) { - fprintf(stderr, "framing error: stop bit %u != 1\n", suart->rx.bit_count); - suart->rx.flags |= OSMO_SUART_F_FRAMING_ERROR; - } - - if (suart->rx.bit_count == 1 + suart->cfg.num_data_bits + num_parity_bits + suart->cfg.num_stop_bits) { - //printf("Rx: 0x%02x %c\n", suart->rx.shift_reg, suart->rx.shift_reg); - suart_rx_ch(suart, suart->rx.shift_reg); suart->rx.bit_count = 0; } + break; + case SUART_FLOW_ST_DATA: + suart->rx.bit_count++; + suart->rx.shift_reg >>= 1; + if (bit != 0) + 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) + suart->rx.flow_state = SUART_FLOW_ST_PARITY; + else + suart->rx.flow_state = SUART_FLOW_ST_STOP; + } + break; + case SUART_FLOW_ST_PARITY: + /* TODO: actually verify parity */ + suart->rx.flow_state = SUART_FLOW_ST_STOP; + break; + case SUART_FLOW_ST_STOP: + suart->rx.bit_count++; + if (bit != 1) + suart->rx.flags |= OSMO_SUART_F_FRAMING_ERROR; + + if (suart->rx.bit_count >= (suart->cfg.num_data_bits + suart->cfg.num_stop_bits)) { + /* we have accumulated enough stop bits */ + suart_rx_ch(suart, suart->rx.shift_reg); + suart->rx.flow_state = SUART_FLOW_ST_IDLE; + } + break; } } @@ -291,10 +296,12 @@ if (!enable && suart->rx.running) { suart_flush_rx(suart); suart->rx.running = false; + suart->rx.flow_state = SUART_FLOW_ST_IDLE; } else if (enable && !suart->rx.running) { if (!suart->rx.msg) suart->rx.msg = msgb_alloc_c(suart, suart->cfg.rx_buf_size, "soft_uart rx"); suart->rx.running = true; + suart->rx.flow_state = SUART_FLOW_ST_IDLE; } return 0; -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35022?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: libosmocore Gerrit-Branch: master Gerrit-Change-Id: I40ab5d12b6f7087daa51405468f5c4ea639561ea Gerrit-Change-Number: 35022 Gerrit-PatchSet: 4 Gerrit-Owner: fixeria <vyanits...@sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: jolly <andr...@eversberg.eu> Gerrit-Reviewer: laforge <lafo...@osmocom.org> Gerrit-MessageType: merged