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

Reply via email to