drivers: modem: ublox-sara-r4: Support SARA-U2 modems, sense VINT
This adds support for SARA-U2 modems. They have different timings on the PWR_ON pin, don't support AT+CESQ and require a manual GPRS connection setup. The VINT pin is used as a more reliable and faster way to power on the modem. Based on work by Göran Weinholt <goran.weinholt@endian.se> Signed-off-by: Michael Scott <mike@foundries.io>
This commit is contained in:
parent
ebf6520d87
commit
ee92cf4d68
8 changed files with 136 additions and 12 deletions
|
@ -58,9 +58,13 @@ config UART_1_NRF_UARTE
|
||||||
config UART_1_NRF_FLOW_CONTROL
|
config UART_1_NRF_FLOW_CONTROL
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config MODEM_UBLOX_SARA_R4
|
config MODEM_UBLOX_SARA
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
choice MODEM_UBLOX_SARA_VARIANT
|
||||||
|
default MODEM_UBLOX_SARA_R4
|
||||||
|
endchoice
|
||||||
|
|
||||||
config UART_INTERRUPT_DRIVEN
|
config UART_INTERRUPT_DRIVEN
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ static int board_particle_boron_init(struct device *dev)
|
||||||
|
|
||||||
external_antenna(false);
|
external_antenna(false);
|
||||||
|
|
||||||
#if defined(CONFIG_MODEM_UBLOX_SARA_R4)
|
#if defined(CONFIG_MODEM_UBLOX_SARA)
|
||||||
struct device *gpio_dev;
|
struct device *gpio_dev;
|
||||||
|
|
||||||
/* Enable the serial buffer for SARA-R4 modem */
|
/* Enable the serial buffer for SARA-R4 modem */
|
||||||
|
@ -52,6 +52,7 @@ static int board_particle_boron_init(struct device *dev)
|
||||||
|
|
||||||
gpio_pin_configure(gpio_dev, SERIAL_BUFFER_ENABLE_GPIO_PIN,
|
gpio_pin_configure(gpio_dev, SERIAL_BUFFER_ENABLE_GPIO_PIN,
|
||||||
GPIO_DIR_OUT);
|
GPIO_DIR_OUT);
|
||||||
|
gpio_pin_write(gpio_dev, SERIAL_BUFFER_ENABLE_GPIO_PIN, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -48,5 +48,6 @@
|
||||||
|
|
||||||
mdm-power-gpios = <&gpio0 16 0>;
|
mdm-power-gpios = <&gpio0 16 0>;
|
||||||
mdm-reset-gpios = <&gpio0 12 0>;
|
mdm-reset-gpios = <&gpio0 12 0>;
|
||||||
|
mdm-vint-gpios = <&gpio0 2 0>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# Enable u-blox SARA-R4 modem
|
# Enable u-blox SARA-R4 modem
|
||||||
CONFIG_MODEM=y
|
CONFIG_MODEM=y
|
||||||
CONFIG_MODEM_SHELL=y
|
CONFIG_MODEM_SHELL=y
|
||||||
|
CONFIG_MODEM_UBLOX_SARA=y
|
||||||
CONFIG_MODEM_UBLOX_SARA_R4=y
|
CONFIG_MODEM_UBLOX_SARA_R4=y
|
||||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ zephyr_sources_ifdef(CONFIG_MODEM_IFACE_UART modem_iface_uart.c)
|
||||||
zephyr_sources_ifdef(CONFIG_MODEM_CMD_HANDLER modem_cmd_handler.c)
|
zephyr_sources_ifdef(CONFIG_MODEM_CMD_HANDLER modem_cmd_handler.c)
|
||||||
zephyr_sources_ifdef(CONFIG_MODEM_SOCKET modem_socket.c)
|
zephyr_sources_ifdef(CONFIG_MODEM_SOCKET modem_socket.c)
|
||||||
|
|
||||||
if(CONFIG_MODEM_UBLOX_SARA_R4)
|
if(CONFIG_MODEM_UBLOX_SARA)
|
||||||
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
|
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
|
||||||
zephyr_library_sources(ublox-sara-r4.c)
|
zephyr_library_sources(ublox-sara-r4.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
#
|
#
|
||||||
|
|
||||||
config MODEM_UBLOX_SARA_R4
|
config MODEM_UBLOX_SARA
|
||||||
bool "Enable u-blox SARA-R4 LTE-CatM1/NB-IoT modem driver"
|
bool "Enable u-blox SARA modem driver"
|
||||||
select MODEM_CONTEXT
|
select MODEM_CONTEXT
|
||||||
select MODEM_CMD_HANDLER
|
select MODEM_CMD_HANDLER
|
||||||
select MODEM_IFACE_UART
|
select MODEM_IFACE_UART
|
||||||
|
@ -19,7 +19,23 @@ config MODEM_UBLOX_SARA_R4
|
||||||
Choose this setting to enable u-blox SARA-R4 LTE-CatM1/NB-IoT modem
|
Choose this setting to enable u-blox SARA-R4 LTE-CatM1/NB-IoT modem
|
||||||
driver.
|
driver.
|
||||||
|
|
||||||
if MODEM_UBLOX_SARA_R4
|
if MODEM_UBLOX_SARA
|
||||||
|
|
||||||
|
choice MODEM_UBLOX_SARA_VARIANT
|
||||||
|
bool "u-blox SARA variant selection"
|
||||||
|
default MODEM_UBLOX_SARA_R4
|
||||||
|
|
||||||
|
config MODEM_UBLOX_SARA_R4
|
||||||
|
bool "u-blox SARA-R4"
|
||||||
|
help
|
||||||
|
Enable support for SARA-R4 modem
|
||||||
|
|
||||||
|
config MODEM_UBLOX_SARA_U2
|
||||||
|
bool "u-blox SARA-U2"
|
||||||
|
help
|
||||||
|
Enable support for SARA-U2 modem
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
config MODEM_UBLOX_SARA_R4_NAME
|
config MODEM_UBLOX_SARA_R4_NAME
|
||||||
string "Driver name"
|
string "Driver name"
|
||||||
|
@ -64,4 +80,4 @@ config MODEM_UBLOX_SARA_R4_INIT_PRIORITY
|
||||||
Note that the priority needs to be lower than the net stack
|
Note that the priority needs to be lower than the net stack
|
||||||
so that it can start before the networking sub-system.
|
so that it can start before the networking sub-system.
|
||||||
|
|
||||||
endif # MODEM_UBLOX_SARA_R4
|
endif # MODEM_UBLOX_SARA
|
||||||
|
|
|
@ -33,6 +33,9 @@ LOG_MODULE_REGISTER(modem_ublox_sara_r4, CONFIG_MODEM_LOG_LEVEL);
|
||||||
enum mdm_control_pins {
|
enum mdm_control_pins {
|
||||||
MDM_POWER = 0,
|
MDM_POWER = 0,
|
||||||
MDM_RESET,
|
MDM_RESET,
|
||||||
|
#if defined(DT_UBLOX_SARA_R4_0_MDM_VINT_GPIOS_CONTROLLER)
|
||||||
|
MDM_VINT,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct modem_pin modem_pins[] = {
|
static struct modem_pin modem_pins[] = {
|
||||||
|
@ -44,6 +47,11 @@ static struct modem_pin modem_pins[] = {
|
||||||
MODEM_PIN(DT_INST_0_UBLOX_SARA_R4_MDM_RESET_GPIOS_CONTROLLER,
|
MODEM_PIN(DT_INST_0_UBLOX_SARA_R4_MDM_RESET_GPIOS_CONTROLLER,
|
||||||
DT_INST_0_UBLOX_SARA_R4_MDM_RESET_GPIOS_PIN, GPIO_DIR_OUT),
|
DT_INST_0_UBLOX_SARA_R4_MDM_RESET_GPIOS_PIN, GPIO_DIR_OUT),
|
||||||
|
|
||||||
|
#if defined(DT_UBLOX_SARA_R4_0_MDM_VINT_GPIOS_CONTROLLER)
|
||||||
|
/* MDM_VINT */
|
||||||
|
MODEM_PIN(DT_INST_0_UBLOX_SARA_R4_MDM_VINT_GPIOS_CONTROLLER,
|
||||||
|
DT_INST_0_UBLOX_SARA_R4_MDM_VINT_GPIOS_PIN, GPIO_DIR_IN),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MDM_UART_DEV_NAME DT_INST_0_UBLOX_SARA_R4_BUS_NAME
|
#define MDM_UART_DEV_NAME DT_INST_0_UBLOX_SARA_R4_BUS_NAME
|
||||||
|
@ -52,10 +60,14 @@ static struct modem_pin modem_pins[] = {
|
||||||
#define MDM_POWER_DISABLE 0
|
#define MDM_POWER_DISABLE 0
|
||||||
#define MDM_RESET_NOT_ASSERTED 1
|
#define MDM_RESET_NOT_ASSERTED 1
|
||||||
#define MDM_RESET_ASSERTED 0
|
#define MDM_RESET_ASSERTED 0
|
||||||
|
#if defined(DT_UBLOX_SARA_R4_0_MDM_VINT_GPIOS_CONTROLLER)
|
||||||
|
#define MDM_VINT_ENABLE 1
|
||||||
|
#define MDM_VINT_DISABLE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MDM_CMD_TIMEOUT K_SECONDS(10)
|
#define MDM_CMD_TIMEOUT K_SECONDS(10)
|
||||||
#define MDM_REGISTRATION_TIMEOUT K_SECONDS(180)
|
#define MDM_REGISTRATION_TIMEOUT K_SECONDS(180)
|
||||||
#define MDM_PROMPT_CMD_DELAY K_MSEC(10)
|
#define MDM_PROMPT_CMD_DELAY K_MSEC(75)
|
||||||
|
|
||||||
#define MDM_MAX_DATA_LENGTH 1024
|
#define MDM_MAX_DATA_LENGTH 1024
|
||||||
#define MDM_RECV_MAX_BUF 30
|
#define MDM_RECV_MAX_BUF 30
|
||||||
|
@ -255,7 +267,7 @@ static int send_socket_data(struct modem_socket *sock,
|
||||||
|
|
||||||
/* slight pause per spec so that @ prompt is received */
|
/* slight pause per spec so that @ prompt is received */
|
||||||
k_sleep(MDM_PROMPT_CMD_DELAY);
|
k_sleep(MDM_PROMPT_CMD_DELAY);
|
||||||
|
#if defined(CONFIG_MODEM_UBLOX_SARA_R4)
|
||||||
/*
|
/*
|
||||||
* HACK: Apparently, enabling HEX transmit mode also
|
* HACK: Apparently, enabling HEX transmit mode also
|
||||||
* affects the BINARY send method. We need to encode
|
* affects the BINARY send method. We need to encode
|
||||||
|
@ -266,6 +278,9 @@ static int send_socket_data(struct modem_socket *sock,
|
||||||
snprintk(send_buf, sizeof(send_buf), "%02x", buf[i]);
|
snprintk(send_buf, sizeof(send_buf), "%02x", buf[i]);
|
||||||
mctx.iface.write(&mctx.iface, send_buf, 2U);
|
mctx.iface.write(&mctx.iface, send_buf, 2U);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
mctx.iface.write(&mctx.iface, buf, buf_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (timeout == K_NO_WAIT) {
|
if (timeout == K_NO_WAIT) {
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -367,6 +382,7 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_imei)
|
||||||
LOG_INF("IMEI: %s", log_strdup(mdata.mdm_imei));
|
LOG_INF("IMEI: %s", log_strdup(mdata.mdm_imei));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(CONFIG_MODEM_UBLOX_SARA_U2)
|
||||||
/*
|
/*
|
||||||
* Handler: +CESQ: <rxlev>[0],<ber>[1],<rscp>[2],<ecn0>[3],<rsrq>[4],<rsrp>[5]
|
* Handler: +CESQ: <rxlev>[0],<ber>[1],<rscp>[2],<ecn0>[3],<rsrq>[4],<rsrp>[5]
|
||||||
*/
|
*/
|
||||||
|
@ -383,6 +399,27 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_rssi_cesq)
|
||||||
|
|
||||||
LOG_INF("RSRP: %d", mctx.data_rssi);
|
LOG_INF("RSRP: %d", mctx.data_rssi);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
|
||||||
|
/* Handler: +CSQ: <signal_power>[0],<qual>[1] */
|
||||||
|
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_rssi_csq)
|
||||||
|
{
|
||||||
|
int rssi;
|
||||||
|
|
||||||
|
rssi = ATOI(argv[1], 0, "qual");
|
||||||
|
if (rssi == 31) {
|
||||||
|
mctx.data_rssi = -46;
|
||||||
|
} else if (rssi >= 0 && rssi <= 31) {
|
||||||
|
/* FIXME: This value depends on the RAT */
|
||||||
|
mctx.data_rssi = -110 + ((rssi * 2) + 1);
|
||||||
|
} else {
|
||||||
|
mctx.data_rssi = -1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INF("QUAL: %d", mctx.data_rssi);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Modem Socket Command Handlers
|
* Modem Socket Command Handlers
|
||||||
|
@ -595,21 +632,53 @@ static int pin_init(void)
|
||||||
|
|
||||||
LOG_DBG("MDM_POWER_PIN -> DISABLE");
|
LOG_DBG("MDM_POWER_PIN -> DISABLE");
|
||||||
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_DISABLE);
|
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_DISABLE);
|
||||||
|
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
|
||||||
|
k_sleep(K_SECONDS(1));
|
||||||
|
#else
|
||||||
k_sleep(K_SECONDS(4));
|
k_sleep(K_SECONDS(4));
|
||||||
|
#endif
|
||||||
LOG_DBG("MDM_POWER_PIN -> ENABLE");
|
LOG_DBG("MDM_POWER_PIN -> ENABLE");
|
||||||
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
|
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
|
||||||
k_sleep(K_SECONDS(1));
|
k_sleep(K_SECONDS(1));
|
||||||
|
|
||||||
/* make sure module is powered off */
|
/* make sure module is powered off */
|
||||||
|
#if defined(DT_UBLOX_SARA_R4_0_MDM_VINT_GPIOS_CONTROLLER)
|
||||||
|
LOG_DBG("Waiting for MDM_VINT_PIN = 0");
|
||||||
|
|
||||||
|
do {
|
||||||
|
k_sleep(K_MSEC(100));
|
||||||
|
} while (modem_pin_read(&mctx, MDM_VINT) != MDM_VINT_DISABLE);
|
||||||
|
#else
|
||||||
k_sleep(K_SECONDS(8));
|
k_sleep(K_SECONDS(8));
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG_DBG("MDM_POWER_PIN -> DISABLE");
|
LOG_DBG("MDM_POWER_PIN -> DISABLE");
|
||||||
|
|
||||||
|
unsigned int irq_lock_key = irq_lock();
|
||||||
|
|
||||||
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_DISABLE);
|
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_DISABLE);
|
||||||
|
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
|
||||||
|
k_usleep(50); /* 50-80 microseconds */
|
||||||
|
#else
|
||||||
k_sleep(K_SECONDS(1));
|
k_sleep(K_SECONDS(1));
|
||||||
LOG_DBG("MDM_POWER_PIN -> ENABLE");
|
#endif
|
||||||
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
|
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
|
||||||
|
|
||||||
|
irq_unlock(irq_lock_key);
|
||||||
|
|
||||||
|
LOG_DBG("MDM_POWER_PIN -> ENABLE");
|
||||||
|
|
||||||
|
#if defined(DT_UBLOX_SARA_R4_0_MDM_VINT_GPIOS_CONTROLLER)
|
||||||
|
LOG_DBG("Waiting for MDM_VINT_PIN = 1");
|
||||||
|
do {
|
||||||
|
k_sleep(K_MSEC(100));
|
||||||
|
} while (modem_pin_read(&mctx, MDM_VINT) != MDM_VINT_ENABLE);
|
||||||
|
#else
|
||||||
k_sleep(K_SECONDS(10));
|
k_sleep(K_SECONDS(10));
|
||||||
|
#endif
|
||||||
|
|
||||||
modem_pin_config(&mctx, MDM_POWER, GPIO_DIR_IN);
|
modem_pin_config(&mctx, MDM_POWER, GPIO_DIR_IN);
|
||||||
|
|
||||||
LOG_INF("... Done!");
|
LOG_INF("... Done!");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -617,9 +686,14 @@ static int pin_init(void)
|
||||||
|
|
||||||
static void modem_rssi_query_work(struct k_work *work)
|
static void modem_rssi_query_work(struct k_work *work)
|
||||||
{
|
{
|
||||||
struct modem_cmd cmd = MODEM_CMD("+CESQ: ", on_cmd_atcmdinfo_rssi_cesq,
|
struct modem_cmd cmd =
|
||||||
6U, ",");
|
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
|
||||||
|
MODEM_CMD("+CSQ: ", on_cmd_atcmdinfo_rssi_csq, 2U, ",");
|
||||||
|
static char *send_cmd = "AT+CSQ";
|
||||||
|
#else
|
||||||
|
MODEM_CMD("+CESQ: ", on_cmd_atcmdinfo_rssi_cesq, 6U, ",");
|
||||||
static char *send_cmd = "AT+CESQ";
|
static char *send_cmd = "AT+CESQ";
|
||||||
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* query modem RSSI */
|
/* query modem RSSI */
|
||||||
|
@ -668,6 +742,18 @@ static void modem_reset(void)
|
||||||
SETUP_CMD_NOHANDLE("AT+CFUN=1"),
|
SETUP_CMD_NOHANDLE("AT+CFUN=1"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
|
||||||
|
static struct setup_cmd u2_setup_cmds[] = {
|
||||||
|
/* set the APN */
|
||||||
|
SETUP_CMD_NOHANDLE("AT+UPSD=0,1,\""
|
||||||
|
CONFIG_MODEM_UBLOX_SARA_R4_MANUAL_MCCMNO "\""),
|
||||||
|
/* set dynamic IP */
|
||||||
|
SETUP_CMD_NOHANDLE("AT+UPSD=0,7,\"0.0.0.0\""),
|
||||||
|
/* activate the GPRS connection */
|
||||||
|
SETUP_CMD_NOHANDLE("AT+UPSDA=0,3"),
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* bring down network interface */
|
/* bring down network interface */
|
||||||
atomic_clear_bit(mdata.net_iface->if_dev->flags, NET_IF_UP);
|
atomic_clear_bit(mdata.net_iface->if_dev->flags, NET_IF_UP);
|
||||||
|
|
||||||
|
@ -767,6 +853,17 @@ restart:
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
|
||||||
|
ret = modem_cmd_handler_setup_cmds(&mctx.iface, &mctx.cmd_handler,
|
||||||
|
u2_setup_cmds,
|
||||||
|
ARRAY_SIZE(u2_setup_cmds),
|
||||||
|
&mdata.sem_response,
|
||||||
|
MDM_REGISTRATION_TIMEOUT);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG_INF("Network is ready.");
|
LOG_INF("Network is ready.");
|
||||||
|
|
||||||
/* Set iface up */
|
/* Set iface up */
|
||||||
|
|
|
@ -26,3 +26,7 @@ properties:
|
||||||
mdm-reset-gpios:
|
mdm-reset-gpios:
|
||||||
type: compound
|
type: compound
|
||||||
category: required
|
category: required
|
||||||
|
|
||||||
|
mdm-vint-gpios:
|
||||||
|
type: compound
|
||||||
|
category: optional
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue