Skip to content

DTR/RI UART#8

Merged
MarkusLassila merged 4 commits into
nrfconnect:mainfrom
MarkusLassila:dtr-ri
Oct 8, 2025
Merged

DTR/RI UART#8
MarkusLassila merged 4 commits into
nrfconnect:mainfrom
MarkusLassila:dtr-ri

Conversation

@MarkusLassila
Copy link
Copy Markdown
Contributor

@MarkusLassila MarkusLassila commented Sep 25, 2025

JIRA: SLM-105

drivers: DTR/RI virtual UART implementation
app: Take DTR/RI into use
sm_host: DTR/RI implementation for host side

Documentation changes to be done as a separate PR.

@MarkusLassila MarkusLassila changed the title Dtr ri DTR/RI UART Sep 25, 2025
@MarkusLassila MarkusLassila force-pushed the dtr-ri branch 4 times, most recently from a97d88a to 195b329 Compare October 2, 2025 09:51
@MarkusLassila MarkusLassila marked this pull request as ready for review October 2, 2025 09:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements DTR (Data Terminal Ready) and RI (Ring Indicator) virtual UART functionality for Serial Modem. It replaces the previous GPIO-based power and indication pin implementation with a standardized DTR/RI UART approach.

  • Adds DTR/RI UART driver that implements the UART API with DTR flow control and RI signaling
  • Migrates host library from GPIO pin management to DTR/RI automatic UART control
  • Updates application and board configurations to use the new DTR/RI device tree bindings

Reviewed Changes

Copilot reviewed 47 out of 47 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
drivers/dtr_uart/ New DTR/RI UART driver implementation with power management and flow control
lib/sm_host/sm_host.c Refactored to use DTR/RI automatic UART management instead of GPIO power/indicate pins
include/sm_host.h Updated API to support DTR/RI handler registration and automatic UART configuration
app/src/ Updated application code to remove GPIO power/indicate pin handling and use DTR/RI callbacks
dts/bindings/ New device tree bindings for DTR/RI UART configuration
app/boards/ Board-specific overlays migrated from GPIO config to DTR/RI device tree nodes

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread lib/sm_host/sm_host.c
Comment thread drivers/dtr_uart/dtr_uart.c Outdated
Comment thread drivers/dtr_uart/dtr_uart.c
Comment thread app/src/sm_uart_handler.c
@MarkusLassila MarkusLassila force-pushed the dtr-ri branch 2 times, most recently from 52d5abe to 1f2dd1e Compare October 2, 2025 12:11
@SeppoTakalo
Copy link
Copy Markdown
Contributor

I believe all .DTS files now require changes so that it does not leave UART pins floating:

This is a piece from my nrf9160_nrf52840.conf:

&pinctrl {
	uart1_sleep_pull: uart1_sleep_pull {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 18)>,
				<NRF_PSEL(UART_RX, 0, 17)>,
				<NRF_PSEL(UART_RTS, 0, 21)>,
				<NRF_PSEL(UART_CTS, 0, 19)>;
			low-power-enable;
			bias-pull-up;
		};
	};
};

So the bias-pull-up sets up the pull-up on the pin when UART is shut down.
This is required so that we don't end up getting lots of garbage in the UART line that is sleeping.

Technically, you could separate those groups so that you only leave pull-up on lines that UART should be driving, not RX lines. I think it is safer.

Comment thread app/overlay-zephyr-modem-nrf9160dk-nrf52840.conf Outdated
Comment thread app/boards/nrf9131ek_nrf9131_ns.overlay Outdated
Comment thread app/src/sm_at_host.c Outdated
Comment thread drivers/dtr_uart/CMakeLists.txt Outdated
Comment thread drivers/dtr_uart/Kconfig
Copy link
Copy Markdown
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get rid of unnecessary typecasts in dtr_uart.c

void * converts perfectly to other type when assigning.

diff --git a/drivers/dtr_uart/dtr_uart.c b/drivers/dtr_uart/dtr_uart.c
index 0fe97d7ede5e..75ad12becb79 100644
--- a/drivers/dtr_uart/dtr_uart.c
+++ b/drivers/dtr_uart/dtr_uart.c
@@ -69,25 +69,15 @@ struct dtr_uart_config {

static void user_callback(const struct device *dev, struct uart_event *evt);

-static inline struct dtr_uart_data *get_dev_data(const struct device *dev)
-{
-       return dev->data;
-}
-
static inline const struct dtr_uart_config *get_dev_config(const struct device *dev)
{
        return dev->config;
}

-static inline const struct device *get_dev(struct dtr_uart_data *data)
-{
-       return data->dev;
-}
-
/* --- Power Management --- */
static void power_on_uart(struct dtr_uart_data *data)
{
-       const struct dtr_uart_config *config = get_dev_config(get_dev(data));
+       const struct dtr_uart_config *config = data->dev->config;
        enum pm_device_state state = PM_DEVICE_STATE_OFF;

        int err = pm_device_state_get(config->uart, &state);
@@ -106,7 +96,7 @@ static void power_on_uart(struct dtr_uart_data *data)

static void power_off_uart(struct dtr_uart_data *data)
{
-       const struct dtr_uart_config *config = get_dev_config(get_dev(data));
+       const struct dtr_uart_config *config = data->dev->config;
        enum pm_device_state state = PM_DEVICE_STATE_OFF;

        int err = pm_device_state_get(config->uart, &state);
@@ -134,7 +124,7 @@ static void tx_complete(struct dtr_uart_data *data)

static void activate_tx(struct dtr_uart_data *data)
{
-       const struct dtr_uart_config *config = get_dev_config(get_dev(data));
+       const struct dtr_uart_config *config = data->dev->config;

        if (data->tx_buf) {
                int err;

So only proper usage of inlining the typecast is

gpio_pin_set_dt(&get_dev_config(data->dev)->ri_gpio, 0);

Comment thread drivers/dtr_uart/dtr_uart.c Outdated
@MarkusLassila MarkusLassila force-pushed the dtr-ri branch 2 times, most recently from 0675166 to 9484f7b Compare October 3, 2025 09:35

dtr_uart0: dtr-uart {
compatible = "nordic,dtr-uart";
dtr-gpios = <&gpio0 28 (GPIO_PULL_UP | GPIO_ACTIVE_HIGH)>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be PULL_UP | ACTIVE_LOW, so if nobody is driving the pin it will be in "inactive" state?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With DK's SM should run immediately when the DK is plugged in. So DTR should be asserted by default. Pushing the button down will then deassert DTR.

I am not 100% on EK board, but I would expect the same functionality to make sense.

Copy link
Copy Markdown
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm OK with the code.
We should clarify the <PULL_UP | ACTIVE_HIGH/LOW> but that can be a follow up PR as well.

@SeppoTakalo
Copy link
Copy Markdown
Contributor

And FYI: functionally this works against my ongoing CMUX+DTR work.

@MarkusLassila
Copy link
Copy Markdown
Contributor Author

@SeppoTakalo: #8 (comment) this is not addressed. Follow up questions in chat.

Comment thread include/sm_host.h Outdated
Comment thread app/boards/nrf9131ek_nrf9131_ns.conf
Comment thread app/prj.conf Outdated
Comment thread app/sample.yaml
Comment thread app/sample.yaml
Comment thread app/overlay-external-mcu.overlay
Comment thread app/sample.yaml
Comment thread lib/sm_host/sm_host.c Outdated
Comment thread lib/sm_host/sm_host.c Outdated
Comment thread lib/sm_host/sm_host.c Outdated
@MarkusLassila MarkusLassila force-pushed the dtr-ri branch 3 times, most recently from 0585b60 to 4bff7be Compare October 6, 2025 11:31
@MarkusLassila MarkusLassila force-pushed the dtr-ri branch 3 times, most recently from 5948425 to c187931 Compare October 6, 2025 12:42
@MarkusLassila
Copy link
Copy Markdown
Contributor Author

Ping @SeppoTakalo to review the mdm-pwr-gpios commit.

Comment thread app/overlay-zephyr-modem.overlay Outdated
Comment thread app/overlay-disable-dtr.overlay Outdated
Comment thread app/overlay-external-mcu.overlay
Comment thread lib/sm_host/sm_host.c Outdated
@MarkusLassila MarkusLassila force-pushed the dtr-ri branch 2 times, most recently from 85c49f7 to da7e09c Compare October 7, 2025 06:31
Comment thread app/src/sm_ctrl_pin.c Outdated
Comment thread app/src/sm_ctrl_pin.c Outdated
Copy link
Copy Markdown
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

I think we could fine-tune the example overlays later, we should proceed to merging and testing this PR in CI

@MarkusLassila MarkusLassila force-pushed the dtr-ri branch 2 times, most recently from 9cf3272 to 64afa50 Compare October 7, 2025 13:42
Terms:
Data Terminal Equipment (DTE), AKA. host.
Data Communication Equipment (DCE), AKA. Serial Modem.
Data Terminal Ready (DTR)
Ring Indicate (RI)

DTR operation:
When DCE notices DTR asserted fom DTE, it resumes UART, enables
RX and sends any possibly pending TX data.

When DCE notices DTR deasserted from DTE, it aborts possible TX,
disables RX and suspends UART.

RI operation:
When DCE observes DTR deasserted and it needs to send data, it sets
RI up to notify DTE.

Application integration:
* uart_rx_enable is used as indicator that application is ready.
* UART_RX_BUF_REQUEST is sent by virtual UART to application to
  request a buffer.
* Logic level 1 is asserted, use DT to change 0/1 level of that.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
Signed-off-by: Markus Lassila <markus.lassila@nordicsemi.no>

dtr

dtr
DTR-uart is taken into use in the Serial Modem application.

Following Kconfigs are removed and replaced with devicetree
overlays: CONFIG_SM_POWER_PIN, CONFIG_SM_INDICATE_PIN and
CONFIG_SM_INDICATE_TIME.

Signed-off-by: Markus Lassila <markus.lassila@nordicsemi.no>
Terms:
Data Terminal Equipment (DTE), AKA. host.
Data Communication Equipment (DCE), AKA. Serial Modem.
Data Terminal Ready (DTR)
Ring Indicate (RI)

DTR operation for DTE:
When DTE wants to enable UART, it resumes UART, enables RX,
asserts DTR and sends any possible pending TX data.

When DTE wants to disable UART, it aborts possible TX,
deasserts DTR, disables RX and suspends UART.

The UART control in DTE can be done either manual or automatic.
With automatic control, UART will be enabled when there is a TX
request and disabled after a configured timeout has passed since
UART was last active.

Replaces following Kconfigs with dtr-gpios & ri-gpios:
CONFIG_SM_HOST_POWER_PIN, CONFIG_SM_HOST_POWER_PIN_TIME and
CONFIG_SM_HOST_INDICATE_PIN.

Signed-off-by: Markus Lassila <markus.lassila@nordicsemi.no>
Adds overlay overlay-zephyr-modem.overlay for mdm-power-gpios,
so that Cellular Modem driver, which does not currently support
DTR, can power on and power off Serial Modem.

Kconfig CONFIG_SM_START_SLEEP removed. Serial Modem Will start
from sleep if mdm-power-gpios is included.

Signed-off-by: Markus Lassila <markus.lassila@nordicsemi.no>
@MarkusLassila MarkusLassila merged commit 6c8cb9f into nrfconnect:main Oct 8, 2025
1 check passed
trantanen referenced this pull request in trantanen/ncs-serial-modem Oct 22, 2025
PPP connection has been opened automatically when AT+CFUN=1 is done and
PDN has been activated even without PPP request using AT#XPPP=1.
This is now changed so you need to issue AT#XPPP=1
in order to start PPP. This can be done before or after AT+CFUN=1.

Enabled CONFIG_MODEM_BACKEND_UART_ASYNC_HWFC forgotten in PR #8

Jira: SLM-85

Signed-off-by: Tommi Rantanen <tommi.rantanen@nordicsemi.no>
@MarkusLassila MarkusLassila deleted the dtr-ri branch November 18, 2025 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants