Skip to content

Commit da7e09c

Browse files
committed
app: Add overlay for mdm-power-gpios
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>
1 parent 1f9783b commit da7e09c

8 files changed

Lines changed: 125 additions & 62 deletions

File tree

app/Kconfig

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,6 @@ config SM_UART_TX_BUF_SIZE
7979
If the buffers are full, will send synchronously.
8080
These buffers are not used when CMUX is in use.
8181

82-
#
83-
# GPIO functionality
84-
#
85-
config SM_START_SLEEP
86-
bool "Enter sleep on startup"
87-
help
88-
If enabled, the SiP is put into deep sleep when powered on.
89-
TODO: DTR to wake up from sleep is not implemented yet.
90-
9182
#
9283
# Automatic network attach
9384
#

app/overlay-zephyr-modem.conf

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,5 @@
44
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
55
#
66

7-
# The nRF91 is power-managed by Zephyr's modem_cellular driver running on the other chip.
8-
CONFIG_SM_START_SLEEP=y
9-
107
# Compatibility with cellular modem driver.
118
CONFIG_SM_MODEM_CELLULAR=y

app/overlay-zephyr-modem.overlay

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/ {
8+
chosen {
9+
ncs,sm-power-gpios = &power_gpios;
10+
};
11+
};
12+
13+
/ {
14+
power_gpios: sm-power-gpios {
15+
compatible = "nordic,sm-power-gpios";
16+
power-gpios = <&gpio0 22 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
17+
status = "okay";
18+
};
19+
};
20+
21+
&gpio0 {
22+
status = "okay";
23+
/* Use PORT events to save power */
24+
sense-edge-mask = <0xFFFFFFFF>;
25+
};

app/sample.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,8 @@ tests:
136136
build_only: true
137137
extra_args:
138138
- EXTRA_CONF_FILE="overlay-cmux.conf;overlay-ppp.conf;overlay-zephyr-modem.conf"
139-
- EXTRA_DTC_OVERLAY_FILE="overlay-external-mcu.overlay"
139+
- EXTRA_DTC_OVERLAY_FILE="overlay-external-mcu.overlay;overlay-zephyr-modem.overlay"
140140
platform_allow:
141-
- nrf9160dk/nrf9160/ns
142141
- nrf9161dk/nrf9161/ns
143142
- nrf9151dk/nrf9151/ns
144143
integration_platforms:

app/src/main.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,11 @@ int start_execute(void)
202202

203203
LOG_INF("Serial Modem");
204204

205-
sm_ctrl_pin_init();
205+
err = sm_ctrl_pin_init();
206+
if (err) {
207+
LOG_ERR("Failed to init ctrl_pin: %d", err);
208+
return err;
209+
}
206210

207211
/* This will send "READY" or "INIT ERROR" to UART so after this nothing
208212
* should be done that can fail
@@ -228,6 +232,8 @@ int main(void)
228232
nrf_power_resetreas_clear(NRF_POWER_NS, 0x70017);
229233
LOG_DBG("RR: 0x%08x", rr);
230234

235+
sm_ctrl_pin_init_gpios();
236+
231237
/* Init and load settings */
232238
if (sm_settings_init() != 0) {
233239
LOG_WRN("Failed to init sm settings");
@@ -254,13 +260,12 @@ int main(void)
254260

255261
check_app_fota_status();
256262

257-
#if defined(CONFIG_SM_START_SLEEP)
258-
263+
#if DT_NODE_HAS_PROP(DT_NODELABEL(modem), mdm_power_gpios)
259264
if (!(rr & NRF_POWER_RESETREAS_OFF_MASK)) { /* DETECT signal from GPIO */
260265

261-
sm_ctrl_pin_enter_sleep_no_uninit();
266+
sm_ctrl_pin_enter_sleep_no_uninit(true);
262267
}
263-
#endif /* CONFIG_SM_START_SLEEP */
268+
#endif
264269

265270
ret = start_execute();
266271
exit:

app/src/sm_ctrl_pin.c

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,20 @@
1818

1919
LOG_MODULE_REGISTER(sm_ctrl_pin, CONFIG_SM_LOG_LEVEL);
2020

21-
#if DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_uart), dtr_gpios)
21+
#define SM_DTR_GPIOS DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_uart), dtr_gpios)
22+
#define SM_MDM_PWR_GPIOS DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_power_gpios), power_gpios)
23+
24+
#if SM_DTR_GPIOS
2225
static const struct gpio_dt_spec dtr_gpio =
2326
GPIO_DT_SPEC_GET_OR(DT_CHOSEN(ncs_sm_uart), dtr_gpios, {0});
2427

25-
static struct gpio_callback gpio_cb;
28+
static struct gpio_callback dtr_gpio_cb;
29+
#endif
30+
#if SM_MDM_PWR_GPIOS
31+
static const struct gpio_dt_spec mdm_pwr_gpio =
32+
GPIO_DT_SPEC_GET_OR(DT_CHOSEN(ncs_sm_power_gpios), power_gpios, {0});
33+
34+
static struct gpio_callback mdm_pwr_gpio_cb;
2635
#endif
2736

2837
static int ext_xtal_control(bool xtal_on)
@@ -58,7 +67,7 @@ static int ext_xtal_control(bool xtal_on)
5867
return err;
5968
}
6069

61-
#if DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_uart), dtr_gpios)
70+
#if SM_DTR_GPIOS
6271
static void dtr_enable_fn(struct k_work *)
6372
{
6473
LOG_INF("DTR pin callback work function.");
@@ -82,7 +91,7 @@ static void dtr_pin_callback(const struct device *dev, struct gpio_callback *gpi
8291

8392
int sm_ctrl_pin_ready(void)
8493
{
85-
#if DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_uart), dtr_gpios)
94+
#if SM_DTR_GPIOS
8695
if (gpio_is_ready_dt(&dtr_gpio)) {
8796
return 0;
8897
}
@@ -91,31 +100,15 @@ int sm_ctrl_pin_ready(void)
91100
return -EFAULT;
92101
}
93102

94-
void sm_ctrl_pin_enter_sleep(void)
103+
void sm_ctrl_pin_enter_sleep_no_uninit(bool at_host_power_off)
95104
{
96-
#if DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_uart), dtr_gpios)
97-
int err;
98-
99-
err = sm_ctrl_pin_ready();
100-
if (err) {
101-
return;
105+
#if SM_DTR_GPIOS || SM_MDM_PWR_GPIOS
106+
if (at_host_power_off) {
107+
sm_at_host_power_off();
102108
}
103109

104-
/* Stop threads, uninitialize host and disable DTR UART. */
105-
sm_at_host_uninit();
106-
107-
/* Only power off the modem if it has not been put
108-
* in flight mode to allow reducing NVM wear.
109-
*/
110-
if (!sm_is_modem_functional_mode(LTE_LC_FUNC_MODE_OFFLINE)) {
111-
sm_power_off_modem();
112-
}
113-
114-
gpio_pin_interrupt_configure_dt(&dtr_gpio, GPIO_INT_DISABLE);
115-
116-
LOG_INF("Entering sleep.");
110+
LOG_INF("Entering sleep. No uninit.");
117111
LOG_PANIC();
118-
nrf_gpio_cfg_sense_set(dtr_gpio.pin, NRF_GPIO_PIN_SENSE_LOW);
119112

120113
k_sleep(K_MSEC(100));
121114

@@ -124,26 +117,27 @@ void sm_ctrl_pin_enter_sleep(void)
124117
#endif
125118
}
126119

127-
/* TODO: Cellular modem driver uses pulse triggered power management, which is not suitable with
128-
* the current implementation.
129-
*/
130-
void sm_ctrl_pin_enter_sleep_no_uninit(void)
120+
void sm_ctrl_pin_enter_sleep(void)
131121
{
132-
#if DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_uart), dtr_gpios)
133-
LOG_INF("Entering sleep.");
134-
LOG_PANIC();
135-
nrf_gpio_cfg_sense_set(dtr_gpio.pin, NRF_GPIO_PIN_SENSE_LOW);
122+
#if SM_DTR_GPIOS || SM_MDM_PWR_GPIOS
136123

137-
k_sleep(K_MSEC(100));
124+
/* Stop threads, uninitialize host and disable DTR UART. */
125+
sm_at_host_uninit();
138126

139-
nrf_regulators_system_off(NRF_REGULATORS_NS);
140-
assert(false);
127+
/* Only power off the modem if it has not been put
128+
* in flight mode to allow reducing NVM wear.
129+
*/
130+
if (!sm_is_modem_functional_mode(LTE_LC_FUNC_MODE_OFFLINE)) {
131+
sm_power_off_modem();
132+
}
133+
134+
sm_ctrl_pin_enter_sleep_no_uninit(false);
141135
#endif
142136
}
143137

144138
void sm_ctrl_pin_enter_idle(void)
145139
{
146-
#if DT_NODE_HAS_PROP(DT_CHOSEN(ncs_sm_uart), dtr_gpios)
140+
#if SM_DTR_GPIOS
147141
LOG_INF("Entering idle.");
148142
int err;
149143

@@ -152,8 +146,8 @@ void sm_ctrl_pin_enter_idle(void)
152146
return;
153147
}
154148

155-
gpio_init_callback(&gpio_cb, dtr_pin_callback, BIT(dtr_gpio.pin));
156-
err = gpio_add_callback_dt(&dtr_gpio, &gpio_cb);
149+
gpio_init_callback(&dtr_gpio_cb, dtr_pin_callback, BIT(dtr_gpio.pin));
150+
err = gpio_add_callback_dt(&dtr_gpio, &dtr_gpio_cb);
157151
if (err) {
158152
LOG_ERR("gpio_add_callback failed: %d", err);
159153
return;
@@ -175,15 +169,48 @@ void sm_ctrl_pin_enter_shutdown(void)
175169
assert(false);
176170
}
177171

172+
void sm_ctrl_pin_init_gpios(void)
173+
{
174+
#if SM_MDM_PWR_GPIOS
175+
/* Configure Modem Power GPIO */
176+
if (!gpio_is_ready_dt(&mdm_pwr_gpio)) {
177+
LOG_ERR("Modem Power GPIO not ready");
178+
return;
179+
}
180+
int err = gpio_pin_configure_dt(&mdm_pwr_gpio, GPIO_INPUT);
181+
182+
if (err < 0) {
183+
LOG_ERR("Failed to configure Modem Power GPIO (%d).", err);
184+
}
185+
#endif
186+
}
187+
178188
int sm_ctrl_pin_init(void)
179189
{
180190
int err;
181191

182192
err = ext_xtal_control(true);
183-
if (err < 0) {
193+
if (err) {
184194
LOG_ERR("Failed to enable ext XTAL: %d", err);
185195
return err;
186196
}
187197

188-
return err;
198+
#if SM_DTR_GPIOS
199+
nrf_gpio_cfg_sense_set(dtr_gpio.pin, NRF_GPIO_PIN_SENSE_LOW);
200+
#endif
201+
#if SM_MDM_PWR_GPIOS
202+
err = gpio_pin_interrupt_configure_dt(&mdm_pwr_gpio, GPIO_INT_EDGE_TO_ACTIVE);
203+
if (err) {
204+
LOG_ERR("Failed to configure Modem Power GPIO interrupt (%d).", err);
205+
return err;
206+
}
207+
gpio_init_callback(&mdm_pwr_gpio_cb, NULL, BIT(mdm_pwr_gpio.pin));
208+
err = gpio_add_callback_dt(&mdm_pwr_gpio, &mdm_pwr_gpio_cb);
209+
if (err) {
210+
LOG_ERR("Failed to add Modem Power GPIO callback (%d).", err);
211+
return err;
212+
}
213+
nrf_gpio_cfg_sense_set(mdm_pwr_gpio.pin, NRF_GPIO_PIN_SENSE_LOW);
214+
#endif
215+
return 0;
189216
}

app/src/sm_ctrl_pin.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,28 @@ void sm_ctrl_pin_enter_sleep(void);
3232

3333
/**
3434
* @brief Enter sleep without uninitializing AT host.
35+
*
36+
* @param at_host_power_off If true, power off AT host before entering sleep.
3537
*/
36-
void sm_ctrl_pin_enter_sleep_no_uninit(void);
38+
void sm_ctrl_pin_enter_sleep_no_uninit(bool at_host_power_off);
3739

3840
/**
3941
* @brief nRF91 Series SiP enters System OFF mode.
4042
*/
4143
void sm_ctrl_pin_enter_shutdown(void);
4244

45+
/**
46+
* @brief Initialize Serial Modem control pins.
47+
*/
48+
void sm_ctrl_pin_init_gpios(void);
49+
4350
/**
4451
* @brief Initialize Serial Modem control pin module.
4552
*
4653
* @retval 0 on success, nonzero otherwise.
4754
*/
4855
int sm_ctrl_pin_init(void);
4956

50-
5157
/** @} */
5258

5359
#endif /* SM_CTRL_PIN_ */
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) 2025 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
4+
description: |
5+
Serial Modem power pin for Zephyr Modem.
6+
7+
compatible: "nordic,sm-power-gpios"
8+
9+
properties:
10+
power-gpios:
11+
type: phandle-array
12+
description: Input. Power GPIO pin.
13+
required: true

0 commit comments

Comments
 (0)