From bce5ed012bd87d7e8ead4014e0790ed7214d1cc0 Mon Sep 17 00:00:00 2001 From: Markus Lassila Date: Tue, 5 May 2026 09:19:43 +0300 Subject: [PATCH] samples: sm_at_client_shell: Fix UART stuck in re-enable Add fix for re-enabling the UART which was caused by the disable failing as the worker was cancelled. Signed-off-by: Markus Lassila --- include/sm_at_client.h | 6 ++--- lib/sm_at_client/sm_at_client.c | 37 ++++++++++++++++------------- samples/sm_at_client_shell/prj.conf | 1 + 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/include/sm_at_client.h b/include/sm_at_client.h index 27d236ce..549b017f 100644 --- a/include/sm_at_client.h +++ b/include/sm_at_client.h @@ -96,11 +96,9 @@ int sm_at_client_register_ri_handler(sm_ri_handler_t handler); * If automatic DTR UART handling is enabled, the library will enable DTR UART when RI * signal is detected, and disable it after inactivity timeout. * - * @param automatic If true, DTR UART is automatically managed by the library. - * @param inactivity Inactivity timeout for DTR UART disablement. Only used if @p - * automatic is true. + * @param inactivity Inactivity timeout for DTR UART disablement. */ -void sm_at_client_configure_dtr_uart(bool automatic, k_timeout_t inactivity); +void sm_at_client_automatic_dtr_uart(k_timeout_t inactivity); /** * @brief Disable DTR UART diff --git a/lib/sm_at_client/sm_at_client.c b/lib/sm_at_client/sm_at_client.c index 3720d94e..ab7aa62c 100644 --- a/lib/sm_at_client/sm_at_client.c +++ b/lib/sm_at_client/sm_at_client.c @@ -168,13 +168,13 @@ static int rx_enable(void) buf = buf_alloc(); if (!buf) { - LOG_DBG("Failed to allocate RX buffer"); + LOG_ERR("Failed to allocate RX buffer"); return -ENOMEM; } ret = uart_rx_enable(uart_dev, buf->buf, sizeof(buf->buf), UART_RX_TIMEOUT_US); - if (ret) { - LOG_WRN("uart_rx_enable failed: %d", ret); + if (ret && ret != -EBUSY) { + LOG_ERR("uart_rx_enable failed: %d", ret); buf_unref(buf->buf); return ret; } @@ -208,7 +208,10 @@ static int rx_disable(void) } /* Wait until RX is actually disabled. */ - k_sem_take(&uart_disabled_sem, K_MSEC(100)); + err = k_sem_take(&uart_disabled_sem, K_MSEC(100)); + if (err) { + LOG_ERR("UART RX disable timeout: %d", err); + } atomic_clear_bit(&uart_state, SM_AT_CLIENT_RX_ENABLED_BIT); return 0; @@ -451,9 +454,6 @@ static void reschedule_disable(void) if (dtr_config.active && dtr_config.automatic) { /* Restart the inactivity timer. */ k_work_reschedule(&dtr_uart_disable_work, dtr_config.inactivity); - } else { - /* Stop the inactivity timer. */ - k_work_cancel_delayable(&dtr_uart_disable_work); } } @@ -913,21 +913,24 @@ int sm_at_client_send_data(const uint8_t *const data, size_t datalen) return tx_write(data, datalen, true); } -void sm_at_client_configure_dtr_uart(bool automatic, k_timeout_t inactivity) +void sm_at_client_automatic_dtr_uart(k_timeout_t inactivity) { if (!initialized) { LOG_ERR("AT client not initialized"); return; } - dtr_config.automatic = automatic; + dtr_config.automatic = true; dtr_config.inactivity = inactivity; - if (dtr_config.automatic && !dtr_config.active && !ring_buf_is_empty(&tx_buf)) { - /* If automatic DTR UART is enabled and there is data to send, enable DTR UART. */ + if (!dtr_config.active && !ring_buf_is_empty(&tx_buf)) { + /* Automatic mode enabled with pending TX data: trigger enable. */ k_work_submit(&dtr_uart_enable_work); - } else { - reschedule_disable(); + } + + if (dtr_config.active) { + /* Restart the inactivity timer. */ + k_work_reschedule(&dtr_uart_disable_work, dtr_config.inactivity); } } @@ -938,7 +941,8 @@ void sm_at_client_disable_dtr_uart(void) return; } - sm_at_client_configure_dtr_uart(false, K_NO_WAIT); + dtr_config.automatic = false; + k_work_cancel(&dtr_uart_enable_work); k_work_reschedule(&dtr_uart_disable_work, K_NO_WAIT); } @@ -949,7 +953,8 @@ void sm_at_client_enable_dtr_uart(void) return; } - sm_at_client_configure_dtr_uart(false, K_NO_WAIT); + dtr_config.automatic = false; + k_work_cancel_delayable(&dtr_uart_disable_work); k_work_submit(&dtr_uart_enable_work); } @@ -993,7 +998,7 @@ int sm_at_client_shell_smsh_dtr_uart_auto(const struct shell *shell, size_t argc return -EINVAL; } - sm_at_client_configure_dtr_uart(true, K_MSEC(timeout)); + sm_at_client_automatic_dtr_uart(K_MSEC(timeout)); shell_print(shell, "Automatic DTR UART. Inactivity timeout %u ms", timeout); diff --git a/samples/sm_at_client_shell/prj.conf b/samples/sm_at_client_shell/prj.conf index 97e96a3a..7ab45183 100644 --- a/samples/sm_at_client_shell/prj.conf +++ b/samples/sm_at_client_shell/prj.conf @@ -19,6 +19,7 @@ CONFIG_SHELL_ARGC_MAX=40 CONFIG_SHELL_CMD_BUFF_SIZE=1024 CONFIG_SHELL_STACK_SIZE=2048 CONFIG_SHELL_LOG_BACKEND=n +CONFIG_LOG_RUNTIME_FILTERING=n CONFIG_PM_DEVICE=y CONFIG_PM_DEVICE_RUNTIME=y