modem: gsm: Initialize the modem UART separately
This is needed if muxing is enabled in which case we must change the UART to muxing UART after the AT+CMUX command has succeed. Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
parent
be81b804f6
commit
775dcb222e
3 changed files with 81 additions and 19 deletions
|
@ -317,6 +317,30 @@ static void gsm_finalize_connection(struct gsm_modem *gsm)
|
||||||
}
|
}
|
||||||
|
|
||||||
set_ppp_carrier_on(gsm);
|
set_ppp_carrier_on(gsm);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_GSM_MUX) && gsm->mux_enabled) {
|
||||||
|
/* Re-use the original iface for AT channel */
|
||||||
|
ret = modem_iface_uart_init_dev(&gsm->context.iface,
|
||||||
|
gsm->at_dev->config->name);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DBG("iface %suart error %d", "AT ", ret);
|
||||||
|
} else {
|
||||||
|
/* Do a test and try to send AT command to modem */
|
||||||
|
ret = modem_cmd_send(&gsm->context.iface,
|
||||||
|
&gsm->context.cmd_handler,
|
||||||
|
&response_cmds[0],
|
||||||
|
ARRAY_SIZE(response_cmds),
|
||||||
|
"AT", &gsm->sem_response,
|
||||||
|
GSM_CMD_AT_TIMEOUT);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG_DBG("modem setup returned %d, %s",
|
||||||
|
ret, "AT cmds failed");
|
||||||
|
} else {
|
||||||
|
LOG_INF("AT channel %d connected to %s",
|
||||||
|
DLCI_AT, gsm->at_dev->config->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mux_enable(struct gsm_modem *gsm)
|
static int mux_enable(struct gsm_modem *gsm)
|
||||||
|
@ -455,16 +479,23 @@ static void mux_setup(struct k_work *work)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_DONE:
|
case STATE_DONE:
|
||||||
/* Re-use the original iface for AT channel */
|
/* At least the SIMCOM modem expects that the Internet
|
||||||
ret = modem_iface_uart_init(&gsm->context.iface,
|
* connection is created in PPP channel. We will need
|
||||||
&gsm->gsm_data,
|
* to attach the AT channel to context iface after the
|
||||||
gsm->at_dev->config->name);
|
* PPP connection is established in order to give AT commands
|
||||||
|
* to the modem.
|
||||||
|
*/
|
||||||
|
ret = modem_iface_uart_init_dev(&gsm->context.iface,
|
||||||
|
gsm->ppp_dev->config->name);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG_DBG("iface %suart error %d", "mux ", ret);
|
LOG_DBG("iface %suart error %d", "PPP ", ret);
|
||||||
gsm->mux_enabled = false;
|
gsm->mux_enabled = false;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG_INF("PPP channel %d connected to %s",
|
||||||
|
DLCI_PPP, gsm->ppp_dev->config->name);
|
||||||
|
|
||||||
gsm_finalize_connection(gsm);
|
gsm_finalize_connection(gsm);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,27 +121,15 @@ static int modem_iface_uart_write(struct modem_iface *iface,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int modem_iface_uart_init(struct modem_iface *iface,
|
int modem_iface_uart_init_dev(struct modem_iface *iface,
|
||||||
struct modem_iface_uart_data *data,
|
const char *dev_name)
|
||||||
const char *dev_name)
|
|
||||||
{
|
{
|
||||||
if (!iface || !data) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get UART device */
|
/* get UART device */
|
||||||
iface->dev = device_get_binding(dev_name);
|
iface->dev = device_get_binding(dev_name);
|
||||||
if (!iface->dev) {
|
if (!iface->dev) {
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
iface->iface_data = data;
|
|
||||||
iface->read = modem_iface_uart_read;
|
|
||||||
iface->write = modem_iface_uart_write;
|
|
||||||
|
|
||||||
ring_buf_init(&data->rx_rb, data->rx_rb_buf_len, data->rx_rb_buf);
|
|
||||||
k_sem_init(&data->rx_sem, 0, 1);
|
|
||||||
|
|
||||||
uart_irq_rx_disable(iface->dev);
|
uart_irq_rx_disable(iface->dev);
|
||||||
uart_irq_tx_disable(iface->dev);
|
uart_irq_tx_disable(iface->dev);
|
||||||
modem_iface_uart_flush(iface);
|
modem_iface_uart_flush(iface);
|
||||||
|
@ -150,3 +138,33 @@ int modem_iface_uart_init(struct modem_iface *iface,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int modem_iface_uart_init(struct modem_iface *iface,
|
||||||
|
struct modem_iface_uart_data *data,
|
||||||
|
const char *dev_name)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!iface || !data) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
iface->iface_data = data;
|
||||||
|
iface->read = modem_iface_uart_read;
|
||||||
|
iface->write = modem_iface_uart_write;
|
||||||
|
|
||||||
|
ring_buf_init(&data->rx_rb, data->rx_rb_buf_len, data->rx_rb_buf);
|
||||||
|
k_sem_init(&data->rx_sem, 0, 1);
|
||||||
|
|
||||||
|
/* get UART device */
|
||||||
|
ret = modem_iface_uart_init_dev(iface, dev_name);
|
||||||
|
if (ret < 0) {
|
||||||
|
iface->iface_data = NULL;
|
||||||
|
iface->read = NULL;
|
||||||
|
iface->write = NULL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,19 @@ struct modem_iface_uart_data {
|
||||||
struct k_sem rx_sem;
|
struct k_sem rx_sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Init modem interface device for UART
|
||||||
|
*
|
||||||
|
* @details This can be called after the init if the UART is changed.
|
||||||
|
*
|
||||||
|
* @param *iface: modem interface to initialize.
|
||||||
|
* @param *dev_name: name of the UART device to use
|
||||||
|
*
|
||||||
|
* @retval 0 if ok, < 0 if error.
|
||||||
|
*/
|
||||||
|
int modem_iface_uart_init_dev(struct modem_iface *iface,
|
||||||
|
const char *dev_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Init modem interface for UART
|
* @brief Init modem interface for UART
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue