drivers/modem/modem_cellular.c: Improve bus pipe usage
This commit improves the usage of the bus pipe (connected to UART) to only open it when the modem is actually powered and ready, not when leaving the idle state. This ensures the pipe is flushed before sending the init script, and re-enables the UART driver if it is disabled due to errors. While building a test platform based on the nRF9160 and a Quectel BG95, it was discovered that the nRF9160 correctly throws UART errors if the RX is enabled while the UART RX line is low (which was due to the modem being powered down). The improvements should also help help remove the "<wrn> modem_chat: receive buffer overrun" warning which would occur during startup as the pipe was opened, but nothing was receiving the data, causing the buffer to overflow. Signed-off-by: Bjarki Arge Andreasen <bjarkix123@gmail.com>
This commit is contained in:
parent
c2647ff24b
commit
2d2d3ececd
1 changed files with 67 additions and 41 deletions
|
@ -50,6 +50,8 @@ enum modem_cellular_event {
|
|||
MODEM_CELLULAR_EVENT_TIMEOUT,
|
||||
MODEM_CELLULAR_EVENT_REGISTERED,
|
||||
MODEM_CELLULAR_EVENT_DEREGISTERED,
|
||||
MODEM_CELLULAR_EVENT_BUS_OPENED,
|
||||
MODEM_CELLULAR_EVENT_BUS_CLOSED,
|
||||
};
|
||||
|
||||
struct modem_cellular_data {
|
||||
|
@ -172,6 +174,10 @@ static const char *modem_cellular_event_str(enum modem_cellular_event event)
|
|||
return "registered";
|
||||
case MODEM_CELLULAR_EVENT_DEREGISTERED:
|
||||
return "deregistered";
|
||||
case MODEM_CELLULAR_EVENT_BUS_OPENED:
|
||||
return "bus opened";
|
||||
case MODEM_CELLULAR_EVENT_BUS_CLOSED:
|
||||
return "bus closed";
|
||||
}
|
||||
|
||||
return "";
|
||||
|
@ -191,6 +197,26 @@ static void modem_cellular_delegate_event(struct modem_cellular_data *data,
|
|||
static void modem_cellular_event_handler(struct modem_cellular_data *data,
|
||||
enum modem_cellular_event evt);
|
||||
|
||||
static void modem_cellular_bus_pipe_handler(struct modem_pipe *pipe,
|
||||
enum modem_pipe_event event,
|
||||
void *user_data)
|
||||
{
|
||||
struct modem_cellular_data *data = (struct modem_cellular_data *)user_data;
|
||||
|
||||
switch (event) {
|
||||
case MODEM_PIPE_EVENT_OPENED:
|
||||
modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_OPENED);
|
||||
break;
|
||||
|
||||
case MODEM_PIPE_EVENT_CLOSED:
|
||||
modem_cellular_delegate_event(data, MODEM_CELLULAR_EVENT_BUS_CLOSED);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void modem_cellular_dlci1_pipe_handler(struct modem_pipe *pipe,
|
||||
enum modem_pipe_event event,
|
||||
void *user_data)
|
||||
|
@ -401,7 +427,7 @@ static int modem_cellular_on_idle_state_enter(struct modem_cellular_data *data)
|
|||
modem_chat_release(&data->chat);
|
||||
modem_ppp_release(data->ppp);
|
||||
modem_cmux_release(&data->cmux);
|
||||
modem_pipe_close(data->uart_pipe);
|
||||
modem_pipe_close_async(data->uart_pipe);
|
||||
k_sem_give(&data->suspended_sem);
|
||||
return 0;
|
||||
}
|
||||
|
@ -447,10 +473,6 @@ static int modem_cellular_on_idle_state_leave(struct modem_cellular_data *data)
|
|||
gpio_pin_set_dt(&config->reset_gpio, 0);
|
||||
}
|
||||
|
||||
if (modem_pipe_open(data->uart_pipe) < 0) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -556,14 +578,8 @@ static void modem_cellular_await_power_on_event_handler(struct modem_cellular_da
|
|||
|
||||
static int modem_cellular_on_run_init_script_state_enter(struct modem_cellular_data *data)
|
||||
{
|
||||
const struct modem_cellular_config *config =
|
||||
(const struct modem_cellular_config *)data->dev->config;
|
||||
|
||||
if (modem_chat_attach(&data->chat, data->uart_pipe) < 0) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return modem_chat_script_run(&data->chat, config->init_chat_script);
|
||||
modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
|
||||
return modem_pipe_open_async(data->uart_pipe);
|
||||
}
|
||||
|
||||
static void modem_cellular_run_init_script_event_handler(struct modem_cellular_data *data,
|
||||
|
@ -573,10 +589,21 @@ static void modem_cellular_run_init_script_event_handler(struct modem_cellular_d
|
|||
(const struct modem_cellular_config *)data->dev->config;
|
||||
|
||||
switch (evt) {
|
||||
case MODEM_CELLULAR_EVENT_BUS_OPENED:
|
||||
modem_chat_attach(&data->chat, data->uart_pipe);
|
||||
modem_chat_script_run(&data->chat, config->init_chat_script);
|
||||
break;
|
||||
|
||||
case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
|
||||
net_if_set_link_addr(modem_ppp_get_iface(data->ppp), data->imei,
|
||||
ARRAY_SIZE(data->imei), NET_LINK_UNKNOWN);
|
||||
|
||||
modem_chat_release(&data->chat);
|
||||
modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
|
||||
modem_pipe_close_async(data->uart_pipe);
|
||||
break;
|
||||
|
||||
case MODEM_CELLULAR_EVENT_BUS_CLOSED:
|
||||
modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_CONNECT_CMUX);
|
||||
break;
|
||||
|
||||
|
@ -603,19 +630,13 @@ static void modem_cellular_run_init_script_event_handler(struct modem_cellular_d
|
|||
}
|
||||
}
|
||||
|
||||
static int modem_cellular_on_run_init_script_state_leave(struct modem_cellular_data *data)
|
||||
{
|
||||
modem_chat_release(&data->chat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int modem_cellular_on_connect_cmux_state_enter(struct modem_cellular_data *data)
|
||||
{
|
||||
if (modem_cmux_attach(&data->cmux, data->uart_pipe) < 0) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
modem_cellular_start_timer(data, K_MSEC(500));
|
||||
/*
|
||||
* Allow modem to switch bus into CMUX mode. Some modems disable UART RX while
|
||||
* switching, resulting in UART RX errors as bus is no longer pulled up by modem.
|
||||
*/
|
||||
modem_cellular_start_timer(data, K_MSEC(100));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -624,6 +645,11 @@ static void modem_cellular_connect_cmux_event_handler(struct modem_cellular_data
|
|||
{
|
||||
switch (evt) {
|
||||
case MODEM_CELLULAR_EVENT_TIMEOUT:
|
||||
modem_pipe_attach(data->uart_pipe, modem_cellular_bus_pipe_handler, data);
|
||||
modem_pipe_open_async(data->uart_pipe);
|
||||
|
||||
case MODEM_CELLULAR_EVENT_BUS_OPENED:
|
||||
modem_cmux_attach(&data->cmux, data->uart_pipe);
|
||||
modem_cmux_connect_async(&data->cmux);
|
||||
break;
|
||||
|
||||
|
@ -700,20 +726,23 @@ static int modem_cellular_on_open_dlci2_state_leave(struct modem_cellular_data *
|
|||
|
||||
static int modem_cellular_on_run_dial_script_state_enter(struct modem_cellular_data *data)
|
||||
{
|
||||
const struct modem_cellular_config *config =
|
||||
(const struct modem_cellular_config *)data->dev->config;
|
||||
|
||||
if (modem_chat_attach(&data->chat, data->dlci1_pipe) < 0) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
return modem_chat_script_run(&data->chat, config->dial_chat_script);
|
||||
/* Allow modem time to enter command mode before running dial script */
|
||||
modem_cellular_start_timer(data, K_MSEC(100));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void modem_cellular_run_dial_script_event_handler(struct modem_cellular_data *data,
|
||||
enum modem_cellular_event evt)
|
||||
{
|
||||
const struct modem_cellular_config *config =
|
||||
(const struct modem_cellular_config *)data->dev->config;
|
||||
|
||||
switch (evt) {
|
||||
case MODEM_CELLULAR_EVENT_TIMEOUT:
|
||||
modem_chat_attach(&data->chat, data->dlci1_pipe);
|
||||
modem_chat_script_run(&data->chat, config->dial_chat_script);
|
||||
break;
|
||||
|
||||
case MODEM_CELLULAR_EVENT_SCRIPT_SUCCESS:
|
||||
modem_cellular_enter_state(data, MODEM_CELLULAR_STATE_AWAIT_REGISTERED);
|
||||
break;
|
||||
|
@ -792,6 +821,7 @@ static int modem_cellular_on_carrier_on_state_leave(struct modem_cellular_data *
|
|||
|
||||
static int modem_cellular_on_init_power_off_state_enter(struct modem_cellular_data *data)
|
||||
{
|
||||
modem_pipe_close_async(data->uart_pipe);
|
||||
modem_cellular_start_timer(data, K_MSEC(2000));
|
||||
return 0;
|
||||
}
|
||||
|
@ -965,10 +995,6 @@ static int modem_cellular_on_state_leave(struct modem_cellular_data *data)
|
|||
ret = modem_cellular_on_power_on_pulse_state_leave(data);
|
||||
break;
|
||||
|
||||
case MODEM_CELLULAR_STATE_RUN_INIT_SCRIPT:
|
||||
ret = modem_cellular_on_run_init_script_state_leave(data);
|
||||
break;
|
||||
|
||||
case MODEM_CELLULAR_STATE_OPEN_DLCI1:
|
||||
ret = modem_cellular_on_open_dlci1_state_leave(data);
|
||||
break;
|
||||
|
@ -1262,7 +1288,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(quectel_bg95_init_chat_script_cmds,
|
|||
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
|
||||
100));
|
||||
0));
|
||||
|
||||
MODEM_CHAT_SCRIPT_DEFINE(quectel_bg95_init_chat_script, quectel_bg95_init_chat_script_cmds,
|
||||
abort_matches, modem_cellular_chat_callback_handler, 10);
|
||||
|
@ -1298,7 +1324,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(zephyr_gsm_ppp_init_chat_script_cmds,
|
|||
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
|
||||
100));
|
||||
0));
|
||||
|
||||
MODEM_CHAT_SCRIPT_DEFINE(zephyr_gsm_ppp_init_chat_script, zephyr_gsm_ppp_init_chat_script_cmds,
|
||||
abort_matches, modem_cellular_chat_callback_handler, 10);
|
||||
|
@ -1334,7 +1360,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(simcom_sim7080_init_chat_script_cmds,
|
|||
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
|
||||
100));
|
||||
0));
|
||||
|
||||
MODEM_CHAT_SCRIPT_DEFINE(simcom_sim7080_init_chat_script, simcom_sim7080_init_chat_script_cmds,
|
||||
abort_matches, modem_cellular_chat_callback_handler, 10);
|
||||
|
@ -1370,7 +1396,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(u_blox_sara_r4_init_chat_script_cmds,
|
|||
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
|
||||
100));
|
||||
0));
|
||||
|
||||
MODEM_CHAT_SCRIPT_DEFINE(u_blox_sara_r4_init_chat_script, u_blox_sara_r4_init_chat_script_cmds,
|
||||
abort_matches, modem_cellular_chat_callback_handler, 10);
|
||||
|
@ -1406,7 +1432,7 @@ MODEM_CHAT_SCRIPT_CMDS_DEFINE(swir_hl7800_init_chat_script_cmds,
|
|||
MODEM_CHAT_SCRIPT_CMD_RESP("", ok_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP("AT+CGMM", cgmm_match),
|
||||
MODEM_CHAT_SCRIPT_CMD_RESP_NONE("AT+CMUX=0,0,5,127,10,3,30,10,2",
|
||||
100));
|
||||
0));
|
||||
|
||||
MODEM_CHAT_SCRIPT_DEFINE(swir_hl7800_init_chat_script, swir_hl7800_init_chat_script_cmds,
|
||||
abort_matches, modem_cellular_chat_callback_handler, 10);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue