aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-11-21 02:25:32 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-11-21 20:17:11 +0700
commitffdd99779df9c83ebd4b8460dff1c8da8da6dcba (patch)
treec088b01ca3bf7434ce227d3ab2f76856aa144931
parentdab6629f1c99f2a8e2371ef90544005667b0ba78 (diff)
soft_uart: fix pulling a small number of Tx bits
-rw-r--r--src/core/soft_uart.c28
-rw-r--r--tests/soft_uart/soft_uart_test.ok85
2 files changed, 40 insertions, 73 deletions
diff --git a/src/core/soft_uart.c b/src/core/soft_uart.c
index c94070fa..e0f07802 100644
--- a/src/core/soft_uart.c
+++ b/src/core/soft_uart.c
@@ -217,7 +217,7 @@ static inline ubit_t osmo_uart_tx_bit(struct osmo_soft_uart *suart, struct msgb
switch (suart->tx.flow_state) {
case SUART_FLOW_ST_IDLE:
- if (msgb_length(msg) > 0) { /* if we have pending data */
+ if (msg && msgb_length(msg) > 0) { /* if we have pending data */
suart->tx.shift_reg = msgb_pull_u8(msg);
suart->tx.flow_state = SUART_FLOW_ST_DATA;
suart->tx.bit_count = 0;
@@ -283,21 +283,31 @@ static inline ubit_t osmo_uart_tx_bit(struct osmo_soft_uart *suart, struct msgb
int osmo_soft_uart_tx_ubits(struct osmo_soft_uart *suart, ubit_t *ubits, size_t n_ubits)
{
const struct osmo_soft_uart_cfg *cfg = &suart->cfg;
- size_t n_frame_bits;
- struct msgb *msg;
+ size_t n_frame_bits, n_chars;
+ struct msgb *msg = NULL;
/* calculate UART frame size for the effective config */
n_frame_bits = 1 + cfg->num_data_bits + cfg->num_stop_bits;
if (cfg->parity_mode != OSMO_SUART_PARITY_NONE)
n_frame_bits += 1;
- /* allocate a Tx buffer msgb */
- msg = msgb_alloc_c(suart, n_ubits / n_frame_bits, "soft_uart_tx");
- OSMO_ASSERT(msg != NULL);
+ /* calculate the number of characters we can fit into n_ubits */
+ n_chars = n_ubits / n_frame_bits;
+ if (n_chars == 0) {
+ /* we can transmit at least one character */
+ if (suart->tx.flow_state == SUART_FLOW_ST_IDLE)
+ n_chars = 1;
+ }
+
+ if (n_chars > 0) {
+ /* allocate a Tx buffer msgb */
+ msg = msgb_alloc_c(suart, n_chars, "soft_uart_tx");
+ OSMO_ASSERT(msg != NULL);
- /* call the .tx_cb() to populate the Tx buffer */
- OSMO_ASSERT(cfg->tx_cb != NULL);
- suart->cfg.tx_cb(cfg->priv, msg);
+ /* call the .tx_cb() to populate the Tx buffer */
+ OSMO_ASSERT(cfg->tx_cb != NULL);
+ suart->cfg.tx_cb(cfg->priv, msg);
+ }
for (size_t i = 0; i < n_ubits; i++)
ubits[i] = osmo_uart_tx_bit(suart, msg);
diff --git a/tests/soft_uart/soft_uart_test.ok b/tests/soft_uart/soft_uart_test.ok
index a160ad30..9ce3bc8e 100644
--- a/tests/soft_uart/soft_uart_test.ok
+++ b/tests/soft_uart/soft_uart_test.ok
@@ -172,74 +172,31 @@ test_tx_rx_exec_one(n_bits_total=32): 00000101 00000011 00000001 00000001
suart_tx_cb(len=0/4):
test_tx_rx_exec_one(n_bits_total=32): 11111111 11111111 11111111 11111111
======== test_tx_rx_pull_n(): pulling 32 bits (1 at a time)
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-11111111111111111111111111111111
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+01010101010101010101010101010101
======== test_tx_rx_pull_n(): feeding 32 bits into the receiver
+suart_rx_cb(flags=00): 55 55 55
======== test_tx_rx_pull_n(): pulling 32 bits (2 at a time)
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-11111111111111111111111111111111
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+01010101010101010101010101010101
======== test_tx_rx_pull_n(): feeding 32 bits into the receiver
+suart_rx_cb(flags=00): 55 55 55
======== test_tx_rx_pull_n(): pulling 32 bits (4 at a time)
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-11111111111111111111111111111111
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+01010101011101010101011101010101
======== test_tx_rx_pull_n(): feeding 32 bits into the receiver
+suart_rx_cb(flags=00): 55 55
======== test_tx_rx_pull_n(): pulling 32 bits (8 at a time)
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-suart_tx_cb(len=0/0):
-11111111111111111111111111111111
+suart_tx_cb(len=1/1): 55
+suart_tx_cb(len=1/1): 55
+01010101011111110101010101111111
======== test_tx_rx_pull_n(): feeding 32 bits into the receiver
+suart_rx_cb(flags=00): 55 55