fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmocore/+/35045?usp=email )
Change subject: [WIP] soft_uart: implement OSMO_SUART_RX_MODE_N_FRAMES ...................................................................... [WIP] soft_uart: implement OSMO_SUART_RX_MODE_N_FRAMES This is a hack allowing us to examine the receiver's internal buffer without having to wait for a timeout to expire. I am not sure if such mode would be useful for anything else. Maybe adding API to access the Rx msgb would be a more flexible solution? Change-Id: Ib3249a06c84f3ddb2723d0787db51873c4707d81 Related: OS#4396 --- M include/osmocom/core/soft_uart.h M src/core/soft_uart.c 2 files changed, 67 insertions(+), 11 deletions(-) git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/45/35045/1 diff --git a/include/osmocom/core/soft_uart.h b/include/osmocom/core/soft_uart.h index 6088922..19af0cf 100644 --- a/include/osmocom/core/soft_uart.h +++ b/include/osmocom/core/soft_uart.h @@ -45,6 +45,14 @@ }; #endif +/*! Rx data pulling mode */ +enum osmo_soft_uart_rx_mode { + /*! the .rx_cb() is called on timeout */ + OSMO_SUART_RX_MODE_TIMEOUT, + /*! the .rx_cb() is called on a specified number of UART frames */ + OSMO_SUART_RX_MODE_N_FRAMES, +}; + /* configuration for a soft-uart */ struct osmo_soft_uart_cfg { /*! number of data bits (typically 5, 6, 7 or 8) */ @@ -53,14 +61,25 @@ uint8_t num_stop_bits; /*! parity mode (none, even, odd) */ enum osmo_soft_uart_parity_mode parity_mode; + /*! size of transmit buffer */ unsigned int tx_buf_size; - /*! size of receive buffer; UART will buffer up to that number of characters - * before calling the receive call-back */ + /*! size of receive buffer */ unsigned int rx_buf_size; - /*! receive timeout; UART will flush receive buffer via the receive call-back - * after indicated number of milli-seconds even if it is not full yet */ - unsigned int rx_timeout_ms; + + /*! Rx data pulling mode */ + enum osmo_soft_uart_rx_mode rx_pull_mode; + /*! Rx data pulling parameters */ + union { + /*! receive timeout for OSMO_SUART_RX_MODE_TIMEOUT; UART will flush receive + * buffer via the receive call-back after indicated number of milli-seconds + * even if it is not full yet. */ + unsigned int rx_timeout_ms; + /*! number of received UART frames for OSMO_SUART_RX_MODE_N_FRAMES; UART + * will flush receive buffer via the receive call-back after indicated number + * of UART frames had been received. */ + unsigned int rx_n_uart_frames; + } rx_pull_param; /*! opaque application-private data; passed to call-backs */ void *priv; diff --git a/src/core/soft_uart.c b/src/core/soft_uart.c index 9b6ca05..c7179a6 100644 --- a/src/core/soft_uart.c +++ b/src/core/soft_uart.c @@ -47,6 +47,7 @@ unsigned int flags; unsigned int status; struct osmo_timer_list timer; + unsigned int n_uart_frames; enum suart_flow_state flow_state; } rx; struct { @@ -71,7 +72,8 @@ .parity_mode = OSMO_SUART_PARITY_NONE, .tx_buf_size = 1024, .rx_buf_size = 1024, - .rx_timeout_ms = 100, + .rx_pull_mode = OSMO_SUART_RX_MODE_TIMEOUT, + .rx_pull_param = { .rx_timeout_ms = 100 }, .priv = NULL, .rx_cb = NULL, .status_change_cb = NULL, @@ -105,12 +107,29 @@ msgb_put_u8(suart->rx.msg, ch); msg_len = msgb_length(suart->rx.msg); - /* first character in new message: start timer */ - if (msg_len == 1) { - osmo_timer_schedule(&suart->rx.timer, suart->cfg.rx_timeout_ms / 1000, - (suart->cfg.rx_timeout_ms % 1000) * 1000); - } else if (msg_len >= suart->cfg.rx_buf_size || suart->rx.flags) { + /* flush immediately: + * a) when the Rx buffer gets full; + * b) when a parity/framing error is occured. */ + if (msg_len >= suart->cfg.rx_buf_size || suart->rx.flags) { suart_flush_rx(suart); + return; + } + + switch (suart->cfg.rx_pull_mode) { + case OSMO_SUART_RX_MODE_TIMEOUT: + /* first character in new message: start timer */ + if (msg_len == 1) { + unsigned int rx_timeout_ms = suart->cfg.rx_pull_param.rx_timeout_ms; + osmo_timer_schedule(&suart->rx.timer, rx_timeout_ms / 1000, + (rx_timeout_ms % 1000) * 1000); + } + break; + case OSMO_SUART_RX_MODE_N_FRAMES: + if (suart->rx.n_uart_frames >= suart->cfg.rx_pull_param.rx_n_uart_frames) { + suart->rx.n_uart_frames = 0; + suart_flush_rx(suart); + } + break; } } @@ -171,6 +190,7 @@ if (suart->rx.bit_count >= (suart->cfg.num_data_bits + suart->cfg.num_stop_bits)) { /* we have accumulated enough stop bits */ + suart->rx.n_uart_frames++; suart_rx_ch(suart, suart->rx.shift_reg); suart->rx.flow_state = SUART_FLOW_ST_IDLE; } @@ -358,10 +378,12 @@ if (cfg->rx_buf_size == 0) return -EINVAL; +#if 0 if (suart->cfg.rx_buf_size > cfg->rx_buf_size || suart->cfg.rx_timeout_ms > cfg->rx_timeout_ms) { suart_flush_rx(suart); } +#endif suart->cfg = *cfg; -- To view, visit https://gerrit.osmocom.org/c/libosmocore/+/35045?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: Ib3249a06c84f3ddb2723d0787db51873c4707d81 Gerrit-Change-Number: 35045 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanits...@sysmocom.de> Gerrit-MessageType: newchange