@@ -30,6 +30,10 @@ LOG_MODULE_REGISTER(modem_gsm, CONFIG_MODEM_LOG_LEVEL);
3030#include <time.h>
3131#endif
3232
33+ #if (CONFIG_MODEM_GSM_QUECTEL )
34+ #include "quectel-mdm.h"
35+ #endif
36+
3337#define GSM_UART_DEV_ID DT_INST_BUS(0)
3438#define GSM_UART_DEV_NAME DT_INST_BUS_LABEL(0)
3539#define GSM_CMD_READ_BUF 128
@@ -200,6 +204,15 @@ MODEM_CMD_DEFINE(gsm_cmd_error)
200204 return 0 ;
201205}
202206
207+ #if CONFIG_MODEM_GSM_QUECTEL
208+ /* Handler: Modem ready. */
209+ MODEM_CMD_DEFINE (on_cmd_unsol_rdy )
210+ {
211+ k_sem_give (& gsm .sem_response );
212+ return 0 ;
213+ }
214+ #endif
215+
203216static const struct modem_cmd response_cmds [] = {
204217 MODEM_CMD ("OK" , gsm_cmd_ok , 0U , "" ),
205218 MODEM_CMD ("ERROR" , gsm_cmd_error , 0U , "" ),
@@ -236,6 +249,12 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_cops)
236249 return 0 ;
237250}
238251
252+ #if CONFIG_MODEM_GSM_QUECTEL
253+ static const struct modem_cmd unsol_cmds [] = {
254+ MODEM_CMD ("RDY" , on_cmd_unsol_rdy , 0U , "" ),
255+ };
256+ #endif
257+
239258#if defined(CONFIG_MODEM_INFO )
240259#define MDM_MANUFACTURER_LENGTH 10
241260#define MDM_MODEL_LENGTH 16
@@ -1016,6 +1035,19 @@ static int mux_enable(struct gsm_modem *gsm)
10161035 STRINGIFY (CONFIG_GSM_MUX_MRU_DEFAULT_LEN ),
10171036 & gsm -> sem_response ,
10181037 GSM_CMD_AT_TIMEOUT );
1038+ #elif CONFIG_MODEM_GSM_QUECTEL
1039+ /* Quectel GSM modem */
1040+ ret = modem_cmd_send_nolock (& gsm -> context .iface ,
1041+ & gsm -> context .cmd_handler ,
1042+ & response_cmds [0 ],
1043+ ARRAY_SIZE (response_cmds ),
1044+ "AT+CMUX=0,0,5,"
1045+ STRINGIFY (CONFIG_GSM_MUX_MRU_DEFAULT_LEN ),
1046+ & gsm -> sem_response ,
1047+ GSM_CMD_AT_TIMEOUT );
1048+
1049+ /* Quectel requires some time to initialize the CMUX */
1050+ k_sleep (K_SECONDS (1 ));
10191051#else
10201052 /* Generic GSM modem */
10211053 ret = modem_cmd_send_nolock (& gsm -> context .iface ,
@@ -1175,6 +1207,24 @@ static void gsm_configure(struct k_work *work)
11751207 gsm_configure_work );
11761208 int ret = -1 ;
11771209
1210+ #if CONFIG_MODEM_GSM_QUECTEL
1211+ enable_power (& gsm -> context );
1212+ power_key_on (& gsm -> context );
1213+
1214+ LOG_INF ("Waiting for modem to boot up" );
1215+
1216+ ret = k_sem_take (& gsm -> sem_response , K_SECONDS (50 ));
1217+
1218+ if (ret == 0 ) {
1219+ LOG_INF ("Modem RDY" );
1220+ } else {
1221+ LOG_INF ("Time out waiting for modem RDY" );
1222+ (void )k_work_reschedule (& gsm -> gsm_configure_work , K_NO_WAIT );
1223+
1224+ return ;
1225+ }
1226+ #endif
1227+
11781228 LOG_DBG ("Starting modem %p configuration" , gsm );
11791229
11801230 ret = modem_cmd_send_nolock (& gsm -> context .iface ,
@@ -1248,6 +1298,33 @@ void gsm_ppp_stop(const struct device *dev)
12481298 struct gsm_modem * gsm = dev -> data ;
12491299 struct net_if * iface = gsm -> iface ;
12501300
1301+ #if (CONFIG_MODEM_GSM_QUECTEL )
1302+
1303+ int ret ;
1304+
1305+ LOG_INF ("Turning off modem..." );
1306+
1307+ /* FIXME: According to EC21 DS, after sending AT+QPOWD, the modem will
1308+ * respond "OK" followed by "POWERED DOWN", then only we can
1309+ * turn off the power. However in my testing I didn't get the
1310+ * "POWERED DOWN".
1311+ */
1312+ ret = modem_cmd_send_nolock (& gsm -> context .iface ,
1313+ & gsm -> context .cmd_handler ,
1314+ & response_cmds [0 ],
1315+ ARRAY_SIZE (response_cmds ),
1316+ "AT+QPOWD=0" ,
1317+ & gsm -> sem_response ,
1318+ GSM_CMD_AT_TIMEOUT );
1319+ if (ret < 0 ) {
1320+ LOG_ERR ("Modem took too long to power down normally" );
1321+ }
1322+
1323+ disable_power (& gsm -> context );
1324+
1325+ LOG_INF ("Modem powered down!" );
1326+ #endif
1327+
12511328 net_if_l2 (iface )-> enable (iface , false);
12521329
12531330 if (IS_ENABLED (CONFIG_GSM_MUX )) {
@@ -1274,6 +1351,10 @@ static int gsm_init(const struct device *dev)
12741351
12751352 gsm -> cmd_handler_data .cmds [CMD_RESP ] = response_cmds ;
12761353 gsm -> cmd_handler_data .cmds_len [CMD_RESP ] = ARRAY_SIZE (response_cmds );
1354+ #if (CONFIG_MODEM_GSM_QUECTEL )
1355+ gsm -> cmd_handler_data .cmds [CMD_UNSOL ] = unsol_cmds ;
1356+ gsm -> cmd_handler_data .cmds_len [CMD_UNSOL ] = ARRAY_SIZE (unsol_cmds );
1357+ #endif
12771358 gsm -> cmd_handler_data .match_buf = & gsm -> cmd_match_buf [0 ];
12781359 gsm -> cmd_handler_data .match_buf_len = sizeof (gsm -> cmd_match_buf );
12791360 gsm -> cmd_handler_data .buf_pool = & gsm_recv_pool ;
@@ -1302,6 +1383,12 @@ static int gsm_init(const struct device *dev)
13021383#endif /* CONFIG_MODEM_INFO */
13031384
13041385 gsm -> context .is_automatic_oper = false;
1386+
1387+ #if (CONFIG_MODEM_GSM_QUECTEL )
1388+ gsm -> context .pins = modem_pins ;
1389+ gsm -> context .pins_len = ARRAY_SIZE (modem_pins );
1390+ #endif
1391+
13051392 gsm -> gsm_data .rx_rb_buf = & gsm -> gsm_rx_rb_buf [0 ];
13061393 gsm -> gsm_data .rx_rb_buf_len = sizeof (gsm -> gsm_rx_rb_buf );
13071394
0 commit comments