Skip to content

Commit 9f4839b

Browse files
committed
driver: Add Zephyr modem driver for Serial Modem 2.0
Add Zephyr modem driver for Serial Modem 2.0, including the nRF91M1 module. Add simplified Kconfig for enabling eDRX and PSM for commonly used values. Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
1 parent 20a8bc1 commit 9f4839b

9 files changed

Lines changed: 286 additions & 2 deletions

File tree

drivers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
44

55
add_subdirectory_ifdef(CONFIG_DTR_UART dtr_uart)
6+
add_subdirectory_ifdef(CONFIG_MODEM_NRF91SM nrf91-sm)

drivers/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55

66
menu "Drivers"
77
rsource "dtr_uart/Kconfig"
8+
rsource "nrf91-sm/Kconfig"
89
endmenu

drivers/nrf91-sm/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
zephyr_library()
8+
zephyr_library_sources(nordic_nrf91sm.c)

drivers/nrf91-sm/Kconfig

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#
2+
# Copyright (c) 2026 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
6+
config MODEM_NRF91SM
7+
bool "Nordic nRF91 Serial Modem support"
8+
default y
9+
depends on DT_HAS_NORDIC_NRF91_SM_V2_ENABLED
10+
select MODEM_CELLULAR
11+
help
12+
Modem driver for Nordic nRF91 series running
13+
the Serial Modem application version 2.0 or later.
14+
15+
if MODEM_NRF91SM
16+
17+
choice
18+
prompt "Request eDRX"
19+
default MODEM_NRF91SM_EDRX_NO
20+
21+
config MODEM_NRF91SM_EDRX_NO
22+
bool "No eDRX"
23+
24+
config MODEM_NRF91SM_EDRX_512
25+
bool "5.12 s eDRX cycle"
26+
27+
config MODEM_NRF91SM_EDRX_1024
28+
bool "10.24 s eDRX cycle"
29+
30+
config MODEM_NRF91SM_EDRX_2048
31+
bool "20.48 s eDRX cycle"
32+
33+
config MODEM_NRF91SM_EDRX_MANUAL
34+
bool "Define eDRX value manually"
35+
36+
endchoice # Request eDRX
37+
38+
config MODEM_NRF91SM_EDRX_MANUAL_VALUE
39+
string "eDRX value for AT+CEDRXS command"
40+
default "0010"
41+
depends on MODEM_NRF91SM_EDRX_MANUAL
42+
help
43+
String. Half a byte in 4-bit format.
44+
See AT manual for AT+CEDRXS command for details.
45+
46+
choice
47+
prompt "Set custom paging time window"
48+
default MODEM_NRF91SM_PTW_DEFAULT
49+
depends on !MODEM_NRF91SM_EDRX_NO
50+
51+
config MODEM_NRF91SM_PTW_DEFAULT
52+
bool "Default paging time window"
53+
54+
config MODEM_NRF91SM_PTW_128S
55+
bool "1.28 s paging time window"
56+
57+
config MODEM_NRF91SM_PTW_256S
58+
bool "2.56 s paging time window"
59+
60+
config MODEM_NRF91SM_PTW_512S
61+
bool "5.12 s paging time window"
62+
63+
config MODEM_NRF91SM_PTW_1024S
64+
bool "10.24 s paging time window"
65+
66+
config MODEM_NRF91SM_PTW_MANUAL
67+
bool "Define paging time window value manually"
68+
69+
endchoice # Set custom paging time window
70+
71+
config MODEM_NRF91SM_PTW_MANUAL_VALUE
72+
string "Paging time window value for AT%XPTW command"
73+
default "0011"
74+
depends on MODEM_NRF91SM_PTW_MANUAL
75+
help
76+
String. Half a byte in 4-bit format.
77+
See AT manual for AT%XPTW command for details.
78+
79+
choice
80+
prompt "Request PSM"
81+
default MODEM_NRF91SM_PSM_NO
82+
83+
config MODEM_NRF91SM_PSM_NO
84+
bool "No PSM"
85+
86+
config MODEM_NRF91SM_PSM_10S
87+
bool "10 s active time"
88+
89+
config MODEM_NRF91SM_PSM_20S
90+
bool "20 s active time"
91+
92+
config MODEM_NRF91SM_PSM_1M
93+
bool "1 min active time"
94+
95+
endchoice # Request PSM
96+
97+
choice
98+
prompt "PSM periodic TAU"
99+
default MODEM_NRF91SM_PSM_TAU_1H
100+
depends on !MODEM_NRF91SM_PSM_NO
101+
102+
config MODEM_NRF91SM_PSM_TAU_1H
103+
bool "1 h periodic TAU"
104+
105+
config MODEM_NRF91SM_PSM_TAU_6H
106+
bool "6 h periodic TAU"
107+
108+
config MODEM_NRF91SM_PSM_TAU_12H
109+
bool "12 h periodic TAU"
110+
111+
endchoice # PSM periodic TAU
112+
113+
config MODEM_NRF91SM_ENABLE_UART_LOGGING
114+
bool "Enable UART logging in the modem"
115+
help
116+
Use AT#XLOG=1 command to enable UART logging in the modem.
117+
Debug logs are sent from the secondary UART.
118+
119+
endif # MODEM_NRF91SM

drivers/nrf91-sm/nordic_nrf91sm.c

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#include <zephyr/drivers/modem/modem_cellular.h>
2+
#include <zephyr/device.h>
3+
4+
MODEM_CELLULAR_COMMON_CHAT_MATCHES();
5+
6+
MODEM_CHAT_MATCH_DEFINE(xiccid_match, "%XICCID: ", "", modem_cellular_chat_on_iccid);
7+
MODEM_CHAT_MATCH_DEFINE(uicc_initialized, "%XSIM: 1", "", NULL);
8+
9+
10+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(init_chat_script_cmds,
11+
MODEM_CHAT_SCRIPT_CMD_RESP("AT", ok_match),
12+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMEE=1", ok_match),
13+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGSN", imei_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
14+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
15+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMI", cgmi_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
16+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMR", cgmr_match), MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
17+
MODEM_CHAT_SCRIPT_CMD_RESP("AT#XCMUXURC=1", ok_match),
18+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XSIM=1", ok_match),
19+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XSIM?\rAT+CFUN=41", uicc_initialized),
20+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XICCID", xiccid_match),
21+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
22+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CIMI", cimi_match),
23+
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
24+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XSIM=0", ok_match),
25+
26+
#if defined(CONFIG_MODEM_NRF91SM_ENABLE_UART_LOGGING)
27+
MODEM_CHAT_SCRIPT_CMD_RESP("AT#XLOG=1", ok_match),
28+
#endif
29+
#if defined(CONFIG_MODEM_NRF91SM_EDRX_NO)
30+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEDRXS=0,4", ok_match),
31+
#elif defined(CONFIG_MODEM_NRF91SM_EDRX_512)
32+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEDRXS=1,4,\"0000\"", ok_match),
33+
#elif defined(CONFIG_MODEM_NRF91SM_EDRX_1024)
34+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEDRXS=1,4,\"0001\"", ok_match),
35+
#elif defined(CONFIG_MODEM_NRF91SM_EDRX_2048)
36+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEDRXS=1,4,\"0010\"", ok_match),
37+
#elif defined(CONFIG_MODEM_NRF91SM_EDRX_MANUAL)
38+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEDRXS=1,4,\""
39+
STRINGIFY(CONFIG_MODEM_NRF91SM_EDRX_MANUAL_VALUE) "\"", ok_match),
40+
#endif
41+
42+
#if defined(CONFIG_MODEM_NRF91SM_PTW_128S)
43+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XPTW=4,\"0000\"", ok_match),
44+
#elif defined(CONFIG_MODEM_NRF91SM_PTW_256S)
45+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XPTW=4,\"0001\"", ok_match),
46+
#elif defined(CONFIG_MODEM_NRF91SM_PTW_512S)
47+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XPTW=4,\"0010\"", ok_match),
48+
#elif defined(CONFIG_MODEM_NRF91SM_PTW_1024S)
49+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XPTW=4,\"0011\"", ok_match),
50+
#elif defined(CONFIG_MODEM_NRF91SM_PTW_MANUAL)
51+
MODEM_CHAT_SCRIPT_CMD_RESP("AT%XPTW=4,\""
52+
STRINGIFY(CONFIG_MODEM_NRF91SM_PTW_MANUAL_VALUE) "\"", ok_match),
53+
#endif
54+
55+
#if !defined(CONFIG_MODEM_NRF91SM_PSM_NO)
56+
#if defined(CONFIG_MODEM_NRF91SM_PSM_TAU_1H)
57+
#define TAU_VALUE "00100001"
58+
#elif defined(CONFIG_MODEM_NRF91SM_PSM_TAU_6H)
59+
#define TAU_VALUE "00100110"
60+
#elif defined(CONFIG_MODEM_NRF91SM_PSM_TAU_12H)
61+
#define TAU_VALUE "00101100"
62+
#endif
63+
#endif /* CONFIG_MODEM_NRF91SM_PSM_NO */
64+
65+
#if defined(CONFIG_MODEM_NRF91SM_PSM_NO)
66+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CPSMS=0", ok_match),
67+
#elif defined(CONFIG_MODEM_NRF91SM_PSM_10S)
68+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CPSMS=1,,,\"" TAU_VALUE
69+
"\", \"00000101\"", ok_match),
70+
#elif defined(CONFIG_MODEM_NRF91SM_PSM_20S)
71+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CPSMS=1,,,\"" TAU_VALUE
72+
"\", \"00001010\"", ok_match),
73+
#elif defined(CONFIG_MODEM_NRF91SM_PSM_1M)
74+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CPSMS=1,,,\"" TAU_VALUE
75+
"\", \"00100001\"", ok_match),
76+
#endif
77+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CMUX=0", ok_match));
78+
79+
MODEM_CHAT_SCRIPT_DEFINE(init_chat_script, init_chat_script_cmds, abort_matches,
80+
modem_cellular_chat_callback_handler, 10);
81+
82+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(network_cmds,
83+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=1", ok_match),
84+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG?", ok_match),
85+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=1", ok_match));
86+
87+
MODEM_CHAT_SCRIPT_DEFINE(network_chat_script, network_cmds,
88+
abort_matches, modem_cellular_chat_callback_handler, 10);
89+
90+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(dial_chat_script_cmds,
91+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGDATA", connect_match));
92+
93+
MODEM_CHAT_SCRIPT_DEFINE(dial_chat_script, dial_chat_script_cmds, abort_matches,
94+
modem_cellular_chat_callback_handler, 10);
95+
96+
MODEM_CHAT_SCRIPT_CMDS_DEFINE(shutdown_chat_script_cmds,
97+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CEREG=0", ok_match),
98+
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CFUN=0", ok_match));
99+
100+
MODEM_CHAT_SCRIPT_DEFINE(shutdown_chat_script, shutdown_chat_script_cmds, abort_matches,
101+
modem_cellular_chat_callback_handler, 10);
102+
103+
static const struct modem_cellular_config_scripts nrf91_sm_scripts = {
104+
.init = &init_chat_script,
105+
.network = &network_chat_script,
106+
.dial = &dial_chat_script,
107+
.shutdown = &shutdown_chat_script,
108+
};
109+
110+
#define NRF91SM_DEVICE(inst) \
111+
MODEM_DT_INST_PPP_DEFINE(inst, MODEM_CELLULAR_INST_NAME(ppp, inst), NULL, 98, 1500, 64); \
112+
\
113+
static struct modem_cellular_data MODEM_CELLULAR_INST_NAME(data, inst) = { \
114+
.chat_delimiter = "\r", \
115+
.chat_filter = "\n", \
116+
.ppp = &MODEM_CELLULAR_INST_NAME(ppp, inst), \
117+
}; \
118+
\
119+
MODEM_CELLULAR_DEFINE_AND_INIT_USER_PIPES(inst, (user_pipe_0, 3), (user_pipe_1, 4)) \
120+
\
121+
MODEM_CELLULAR_DEFINE_INSTANCE(inst, 0, 500, 5000, 100, true, &nrf91_sm_scripts)
122+
123+
#define DT_DRV_COMPAT nordic_nrf91_sm_v2
124+
DT_INST_FOREACH_STATUS_OKAY(NRF91SM_DEVICE)
125+
#undef DT_DRV_COMPAT
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Copyright (c) 2026 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
title: Nordic nRF91 Serial Modem
5+
6+
description: |
7+
Nordic nRF91 series running the Serial Modem application version 2.0 or later.
8+
This includes the nRF91M1 module.
9+
10+
compatible: "nordic,nrf91-sm-v2"
11+
12+
include: zephyr,cellular-modem-device.yaml
13+
14+
properties:
15+
zephyr,use-default-pdp-ctx:
16+
default: 1
17+
18+
zephyr,mdm-reset-behavior:
19+
default: ["toggle_on_recovery"]

samples/sm_ppp_shell/boards/nrf54l15dk_nrf54l15_cpuapp.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,10 @@ CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC=y
1313
# For debugging purposes, enable GPIO shell commands.
1414
CONFIG_GPIO=y
1515
CONFIG_GPIO_SHELL=y
16+
17+
CONFIG_SHELL_WILDCARD=n
18+
CONFIG_MODEM_AT_SHELL=y
19+
CONFIG_MODEM_AT_USER_PIPE_IDX=0
20+
CONFIG_MODEM_CMUX_MSC_FC_THRESHOLD=32
21+
22+
CONFIG_MODEM_NRF91SM_ENABLE_UART_LOGGING=y

samples/sm_ppp_shell/boards/nrf54l15dk_nrf54l15_cpuapp.overlay

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
zephyr,console = &uart20;
2525
zephyr,shell-uart = &uart20;
2626
};
27+
aliases {
28+
modem = &modem;
29+
};
2730
};
2831

2932
/* Zephyr modem UART <-> nRF91 Serial Modem UART */
@@ -35,14 +38,15 @@
3538

3639
/* Nordic nRF91 Serial Modem configuration */
3740
modem: modem {
38-
compatible = "nordic,nrf91-slm";
41+
compatible = "nordic,nrf91-sm-v2";
3942
status = "okay";
4043
mdm-ring-gpios = <&gpio1 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
4144
mdm-dtr-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
4245
zephyr,pm-device-runtime-auto;
4346
cmux-enable-runtime-power-save;
4447
cmux-close-pipe-on-power-save;
4548
cmux-idle-timeout-ms = <5000>;
49+
autostarts;
4650
};
4751
};
4852

samples/sm_ppp_shell/boards/nrf54l15dk_nrf54l15_cpuapp_ns.overlay

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
/* Nordic nRF91 Serial Modem configuration */
3737
modem: modem {
38-
compatible = "nordic,nrf91-slm";
38+
compatible = "nordic,nrf91m1";
3939
status = "okay";
4040
mdm-ring-gpios = <&gpio1 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>;
4141
mdm-dtr-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;

0 commit comments

Comments
 (0)