diff options
author | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2023-11-21 02:25:32 +0700 |
---|---|---|
committer | Vadim Yanitskiy <vyanitskiy@sysmocom.de> | 2023-11-21 20:17:11 +0700 |
commit | ffdd99779df9c83ebd4b8460dff1c8da8da6dcba (patch) | |
tree | c088b01ca3bf7434ce227d3ab2f76856aa144931 /src | |
parent | dab6629f1c99f2a8e2371ef90544005667b0ba78 (diff) |
soft_uart: fix pulling a small number of Tx bits
Change-Id: I454c8786697a6f2389d56b350e6e20ca953fe859
Related: OS#4396
Diffstat (limited to 'src')
-rw-r--r-- | src/core/soft_uart.c | 28 |
1 files changed, 19 insertions, 9 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); |