Skip to content
Permalink
Browse files

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>
  • Loading branch information...
mike-scott authored and ioannisg committed Aug 7, 2019
1 parent ebf6520 commit ee92cf4d68f3c90eb37acd62a069f79bdb1aba97
@@ -58,9 +58,13 @@ config UART_1_NRF_UARTE
config UART_1_NRF_FLOW_CONTROL
default y

config MODEM_UBLOX_SARA_R4
config MODEM_UBLOX_SARA
default y

choice MODEM_UBLOX_SARA_VARIANT
default MODEM_UBLOX_SARA_R4
endchoice

config UART_INTERRUPT_DRIVEN
default y

@@ -39,7 +39,7 @@ static int board_particle_boron_init(struct device *dev)

external_antenna(false);

#if defined(CONFIG_MODEM_UBLOX_SARA_R4)
#if defined(CONFIG_MODEM_UBLOX_SARA)
struct device *gpio_dev;

/* 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_DIR_OUT);
gpio_pin_write(gpio_dev, SERIAL_BUFFER_ENABLE_GPIO_PIN, 0);
#endif

return 0;
@@ -48,5 +48,6 @@

mdm-power-gpios = <&gpio0 16 0>;
mdm-reset-gpios = <&gpio0 12 0>;
mdm-vint-gpios = <&gpio0 2 0>;
};
};
@@ -1,6 +1,7 @@
# Enable u-blox SARA-R4 modem
CONFIG_MODEM=y
CONFIG_MODEM_SHELL=y
CONFIG_MODEM_UBLOX_SARA=y
CONFIG_MODEM_UBLOX_SARA_R4=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_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_sources(ublox-sara-r4.c)
endif()
@@ -6,8 +6,8 @@
# SPDX-License-Identifier: Apache-2.0
#

config MODEM_UBLOX_SARA_R4
bool "Enable u-blox SARA-R4 LTE-CatM1/NB-IoT modem driver"
config MODEM_UBLOX_SARA
bool "Enable u-blox SARA modem driver"
select MODEM_CONTEXT
select MODEM_CMD_HANDLER
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
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
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
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 {
MDM_POWER = 0,
MDM_RESET,
#if defined(DT_UBLOX_SARA_R4_0_MDM_VINT_GPIOS_CONTROLLER)
MDM_VINT,
#endif
};

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,
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
@@ -52,10 +60,14 @@ static struct modem_pin modem_pins[] = {
#define MDM_POWER_DISABLE 0
#define MDM_RESET_NOT_ASSERTED 1
#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_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_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 */
k_sleep(MDM_PROMPT_CMD_DELAY);

#if defined(CONFIG_MODEM_UBLOX_SARA_R4)
/*
* HACK: Apparently, enabling HEX transmit mode also
* 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]);
mctx.iface.write(&mctx.iface, send_buf, 2U);
}
#else
mctx.iface.write(&mctx.iface, buf, buf_len);
#endif

if (timeout == K_NO_WAIT) {
ret = 0;
@@ -367,6 +382,7 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_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]
*/
@@ -383,6 +399,27 @@ MODEM_CMD_DEFINE(on_cmd_atcmdinfo_rssi_cesq)

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
@@ -595,31 +632,68 @@ static int pin_init(void)

LOG_DBG("MDM_POWER_PIN -> 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));
#endif
LOG_DBG("MDM_POWER_PIN -> ENABLE");
modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
k_sleep(K_SECONDS(1));

/* 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));
#endif

LOG_DBG("MDM_POWER_PIN -> DISABLE");

unsigned int irq_lock_key = irq_lock();

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));
LOG_DBG("MDM_POWER_PIN -> ENABLE");
#endif
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));
#endif

modem_pin_config(&mctx, MDM_POWER, GPIO_DIR_IN);

LOG_INF("... Done!");

return 0;
}

static void modem_rssi_query_work(struct k_work *work)
{
struct modem_cmd cmd = MODEM_CMD("+CESQ: ", on_cmd_atcmdinfo_rssi_cesq,
6U, ",");
struct modem_cmd cmd =
#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";
#endif
int ret;

/* query modem RSSI */
@@ -668,6 +742,18 @@ static void modem_reset(void)
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 */
atomic_clear_bit(mdata.net_iface->if_dev->flags, NET_IF_UP);

@@ -767,6 +853,17 @@ static void modem_reset(void)
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.");

/* Set iface up */
@@ -26,3 +26,7 @@ properties:
mdm-reset-gpios:
type: compound
category: required

mdm-vint-gpios:
type: compound
category: optional

0 comments on commit ee92cf4

Please sign in to comment.
You can’t perform that action at this time.