drivers: modem: add Sierra Wireless HL7800 Modem Driver

The driver utilizes the CONFIG_NET_OFFLOAD setting to avoid the
normal handling of IP packets, and instead uses a socket-like
UART interface to handle incoming and outgoing data via AT commands.

Signed-off-by: Ryan Erickson <ryan.erickson@lairdconnect.com>
This commit is contained in:
Ryan Erickson 2020-08-27 15:43:58 -05:00 committed by Carles Cufí
commit eca8842b67
6 changed files with 5495 additions and 0 deletions

View file

@ -26,3 +26,8 @@ if(CONFIG_MODEM_GSM_PPP)
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
zephyr_library_sources(gsm_ppp.c)
endif()
if (CONFIG_MODEM_HL7800)
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
zephyr_library_sources(hl7800.c)
endif()

View file

@ -137,4 +137,6 @@ source "drivers/modem/Kconfig.ublox-sara-r4"
source "drivers/modem/Kconfig.wncm14a2a"
source "drivers/modem/Kconfig.gsm"
source "drivers/modem/Kconfig.hl7800"
endif # MODEM

View file

@ -0,0 +1,261 @@
# Sierra Wireless HL7800 modem driver options
# Copyright (c) 2020 Laird Connectivity
# SPDX-License-Identifier: Apache-2.0
menuconfig MODEM_HL7800
bool "Enable Sierra Wireless HL7800 modem driver"
select MODEM_RECEIVER
select NET_OFFLOAD
select DEVICE_POWER_MANAGEMENT
imply GPIO
help
Choose this setting to enable
Sierra Wireless HL7800 LTE-M/NB-IoT modem driver.
if MODEM_HL7800
config MODEM_HL7800_FW_UPDATE
bool "Enable firmware update"
select FILE_SYSTEM
help
Enable the ability to update the HL7800 via XMODEM
by providing an update file to the update API.
config MODEM_HL7800_SET_APN_NAME_ON_STARTUP
bool "Set APN name during driver init"
help
If APN doesn't match MODEM_HL7800_APN_NAME on startup,
then it will be set.
if MODEM_HL7800_SET_APN_NAME_ON_STARTUP
config MODEM_HL7800_APN_NAME
string "APN name for establishing network connection"
help
This setting is used in the AT+CGDCONT command to set the APN name
for the PDP context.
endif # MODEM_HL7800_SET_APN_NAME_ON_STARTUP
choice MODEM_HL7800_RAT
bool "Radio Access Technology Mode"
default MODEM_HL7800_RAT_NO_CHANGE
config MODEM_HL7800_RAT_NO_CHANGE
bool "Don't change the RAT"
help
Leave the HL7800 RAT unchanged during modem init.
config MODEM_HL7800_RAT_M1
bool "LTE-M1"
help
Enable LTE Cat-M1 mode during modem init.
config MODEM_HL7800_RAT_NB1
bool "NB-IoT"
help
Enable LTE Cat-NB1 mode during modem init.
endchoice
menuconfig MODEM_HL7800_CONFIGURE_BANDS
bool "Configure modem bands"
default "y"
help
Choose this setting to configure which LTE bands the
HL7800 modem should use.
if MODEM_HL7800_CONFIGURE_BANDS
config MODEM_HL7800_BAND_1
bool "Enable Band 1 (2000MHz)"
default "y"
help
Enable Band 1 (2000MHz)
config MODEM_HL7800_BAND_2
bool "Enable Band 2 (1900MHz)"
default "y"
help
Enable Band 2 (1900MHz)
config MODEM_HL7800_BAND_3
bool "Enable Band 3 (1800MHz)"
default "y"
help
Enable Band 3 (1800MHz)
config MODEM_HL7800_BAND_4
bool "Enable Band 4 (1700MHz)"
default "y"
help
Enable Band 4 (1700MHz)
config MODEM_HL7800_BAND_5
bool "Enable Band 5 (850MHz)"
default "y"
help
Enable Band 5 (850MHz)
config MODEM_HL7800_BAND_8
bool "Enable Band 8 (900MHz)"
default "y"
help
Enable Band 8 (900MHz)
config MODEM_HL7800_BAND_9
bool "Enable Band 9 (1900MHz)"
help
Enable Band 9 (1900MHz)
config MODEM_HL7800_BAND_10
bool "Enable Band 10 (2100MHz)"
help
Enable Band 10 (2100MHz)
config MODEM_HL7800_BAND_12
bool "Enable Band 12 (700MHz)"
default "y"
help
Enable Band 12 (700MHz)
config MODEM_HL7800_BAND_13
bool "Enable Band 13 (700MHz)"
default "y"
help
Enable Band 13 (700MHz)
config MODEM_HL7800_BAND_14
bool "Enable Band 14 (700MHz)"
help
Enable Band 14 (700MHz)
config MODEM_HL7800_BAND_17
bool "Enable Band 17 (700MHz)"
help
Enable Band 17 (700MHz)
config MODEM_HL7800_BAND_18
bool "Enable Band 18 (800MHz)"
help
Enable Band 18 (800MHz)
config MODEM_HL7800_BAND_19
bool "Enable Band 19 (800MHz)"
help
Enable Band 19 (800MHz)
config MODEM_HL7800_BAND_20
bool "Enable Band 20 (800MHz)"
default "y"
help
Enable Band 20 (800MHz)
config MODEM_HL7800_BAND_25
bool "Enable Band 25 (1900MHz)"
help
Enable Band 25 (1900MHz)
config MODEM_HL7800_BAND_26
bool "Enable Band 26 (800MHz)"
help
Enable Band 26 (800MHz)
config MODEM_HL7800_BAND_27
bool "Enable Band 27 (800MHz)"
help
Enable Band 27 (800MHz)
config MODEM_HL7800_BAND_28
bool "Enable Band 28 (700MHz)"
default "y"
help
Enable Band 28 (700MHz)
config MODEM_HL7800_BAND_66
bool "Enable Band 66 (1800MHz)"
help
Enable Band 66 (1800MHz)
endif # MODEM_HL7800_CONFIGURE_BAND
menuconfig MODEM_HL7800_LOW_POWER_MODE
bool "Enable low power modes"
help
Choose this setting to enable a low power mode for the HL7800 modem
if MODEM_HL7800_LOW_POWER_MODE
choice
prompt "Low Power Mode"
default MODEM_HL7800_EDRX
config MODEM_HL7800_EDRX
bool "eDRX"
help
Enable LTE eDRX
config MODEM_HL7800_PSM
bool "PSM"
help
Enable Power Save Mode (PSM)
endchoice
if MODEM_HL7800_EDRX
config MODEM_HL7800_EDRX_VALUE
string "Requested eDRX timer"
default "0101"
help
Half a byte in a 4-bit format. The eDRX value refers to bit 4 to 1
of octet 3 of the Extended DRX parameters information element.
Default value is 81.92 seconds.
endif # MODEM_HL7800_EDRX
if MODEM_HL7800_PSM
config MODEM_HL7800_PSM_PERIODIC_TAU
string "Requested extended periodic TAU timer"
default "10000010"
help
Requested extended periodic TAU (tracking area update) value (T3412)
to be allocated to the UE in E-UTRAN. One byte in an 8-bit format.
Default value is 1 minute.
config MODEM_HL7800_PSM_ACTIVE_TIME
string "Requested active time"
default "00001111"
help
Requested Active Time value (T3324) to be allocated to the UE.
One byte in an 8-bit format. Default value is 30 seconds.
endif # MODEM_HL7800_PSM
endif # MODEM_HL7800_LOW_POWER_MODE
config MODEM_HL7800_RX_STACK_SIZE
int "Size of the stack for the HL7800 modem driver RX thread"
default 1024
help
This stack is used by the HL7800 RX thread.
config MODEM_HL7800_RX_WORKQ_STACK_SIZE
int "Size of the stack for the HL7800 modem driver work queue"
default 2048
help
This stack is used by the work queue to pass off net_pkt data
to the rest of the network stack, letting the rx thread continue
processing data.
config MODEM_HL7800_INIT_PRIORITY
int "HL7800 driver init priority"
default 80
help
HL7800 device driver initialization priority.
Do not mess with it unless you know what you are doing.
Note that the priority needs to be lower than the net stack
so that it can start before the networking sub-system.
endif # MODEM_HL7800

4902
drivers/modem/hl7800.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,55 @@
#
# Copyright (c) 2020, Laird Connectivity
#
# SPDX-License-Identifier: Apache-2.0
#
description: Sierra Wireless HL7800 Modem
compatible: "swi,hl7800"
include: uart-device.yaml
properties:
label:
required: true
mdm-wake-gpios:
type: phandle-array
required: true
mdm-reset-gpios:
type: phandle-array
required: true
mdm-pwr-on-gpios:
type: phandle-array
required: true
mdm-fast-shutd-gpios:
type: phandle-array
required: true
mdm-uart-dtr-gpios:
type: phandle-array
required: true
mdm-vgpio-gpios:
type: phandle-array
required: true
mdm-uart-dsr-gpios:
type: phandle-array
required: true
mdm-uart-cts-gpios:
type: phandle-array
required: true
mdm-gpio2-gpios:
type: phandle-array
required: false
mdm-gpio6-gpios:
type: phandle-array
required: true

View file

@ -0,0 +1,270 @@
/** @file
* @brief HL7800 modem public API header file.
*
* Allows an application to control the HL7800 modem.
*
* Copyright (c) 2020 Laird Connectivity
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_MODEM_HL7800_H_
#define ZEPHYR_INCLUDE_DRIVERS_MODEM_HL7800_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_NEWLIB_LIBC
#include <time.h>
#endif
/* The size includes the NUL character, the strlen doesn't */
#define MDM_HL7800_REVISION_MAX_SIZE 29
#define MDM_HL7800_REVISION_MAX_STRLEN (MDM_HL7800_REVISION_MAX_SIZE - 1)
#define MDM_HL7800_IMEI_SIZE 16
#define MDM_HL7800_IMEI_STRLEN (MDM_HL7800_IMEI_SIZE - 1)
#define MDM_HL7800_ICCID_SIZE 21
#define MDM_HL7800_ICCID_STRLEN (MDM_HL7800_ICCID_SIZE - 1)
#define MDM_HL7800_SERIAL_NUMBER_SIZE 15
#define MDM_HL7800_SERIAL_NUMBER_STRLEN (MDM_HL7800_SERIAL_NUMBER_SIZE - 1)
#define MDM_HL7800_APN_MAX_SIZE 64
#define MDM_HL7800_APN_USERNAME_MAX_SIZE 65
#define MDM_HL7800_APN_PASSWORD_MAX_SIZE 65
#define MDM_HL7800_APN_MAX_STRLEN (MDM_HL7800_APN_MAX_SIZE - 1)
#define MDM_HL7800_APN_USERNAME_MAX_STRLEN \
(MDM_HL7800_APN_USERNAME_MAX_SIZE - 1)
#define MDM_HL7800_APN_PASSWORD_MAX_STRLEN \
(MDM_HL7800_APN_PASSWORD_MAX_SIZE - 1)
#define MDM_HL7800_APN_CMD_MAX_SIZE \
(32 + MDM_HL7800_APN_USERNAME_MAX_STRLEN + \
MDM_HL7800_APN_PASSWORD_MAX_STRLEN)
#define MDM_HL7800_APN_CMD_MAX_STRLEN (MDM_HL7800_APN_CMD_MAX_SIZE - 1)
struct mdm_hl7800_apn {
char value[MDM_HL7800_APN_MAX_SIZE];
char username[MDM_HL7800_APN_USERNAME_MAX_SIZE];
char password[MDM_HL7800_APN_PASSWORD_MAX_SIZE];
};
#define MDM_HL7800_LTE_BAND_STR_SIZE 21
#define MDM_HL7800_LTE_BAND_STRLEN (MDM_HL7800_LTE_BAND_STR_SIZE - 1)
enum mdm_hl7800_radio_mode { MDM_RAT_CAT_M1 = 0, MDM_RAT_CAT_NB1 };
enum mdm_hl7800_event {
HL7800_EVENT_RESERVED = 0,
HL7800_EVENT_NETWORK_STATE_CHANGE,
HL7800_EVENT_APN_UPDATE,
HL7800_EVENT_RSSI,
HL7800_EVENT_SINR,
HL7800_EVENT_STARTUP_STATE_CHANGE,
HL7800_EVENT_SLEEP_STATE_CHANGE,
HL7800_EVENT_RAT,
HL7800_EVENT_BANDS,
HL7800_EVENT_ACTIVE_BANDS,
HL7800_EVENT_FOTA_STATE,
HL7800_EVENT_FOTA_COUNT,
HL7800_EVENT_REVISION
};
enum mdm_hl7800_startup_state {
HL7800_STARTUP_STATE_READY = 0,
HL7800_STARTUP_STATE_WAITING_FOR_ACCESS_CODE,
HL7800_STARTUP_STATE_SIM_NOT_PRESENT,
HL7800_STARTUP_STATE_SIMLOCK,
HL7800_STARTUP_STATE_UNRECOVERABLE_ERROR,
HL7800_STARTUP_STATE_UNKNOWN,
HL7800_STARTUP_STATE_INACTIVE_SIM
};
enum mdm_hl7800_network_state {
HL7800_NOT_REGISTERED = 0,
HL7800_HOME_NETWORK,
HL7800_SEARCHING,
HL7800_REGISTRATION_DENIED,
HL7800_OUT_OF_COVERAGE,
HL7800_ROAMING,
HL7800_EMERGENCY = 8,
/* Laird defined states */
HL7800_UNABLE_TO_CONFIGURE = 0xf0
};
enum mdm_hl7800_sleep_state {
HL7800_SLEEP_STATE_UNINITIALIZED = 0,
HL7800_SLEEP_STATE_ASLEEP,
HL7800_SLEEP_STATE_AWAKE
};
enum mdm_hl7800_fota_state {
HL7800_FOTA_IDLE,
HL7800_FOTA_START,
HL7800_FOTA_WIP,
HL7800_FOTA_PAD,
HL7800_FOTA_SEND_EOT,
HL7800_FOTA_FILE_ERROR,
HL7800_FOTA_INSTALL,
HL7800_FOTA_REBOOT_AND_RECONFIGURE,
HL7800_FOTA_COMPLETE,
};
/* The modem reports state values as an enumeration and a string */
struct mdm_hl7800_compound_event {
uint8_t code;
char *string;
};
/**
* event - The type of event
* event_data - Pointer to event specific data structure
* HL7800_EVENT_NETWORK_STATE_CHANGE - compound event
* HL7800_EVENT_APN_UPDATE - struct mdm_hl7800_apn
* HL7800_EVENT_RSSI - int
* HL7800_EVENT_SINR - int
* HL7800_EVENT_STARTUP_STATE_CHANGE - compound event
* HL7800_EVENT_SLEEP_STATE_CHANGE - compound event
* HL7800_EVENT_RAT - int
* HL7800_EVENT_BANDS - string
* HL7800_EVENT_ACTIVE_BANDS - string
* HL7800_EVENT_FOTA_STATE - compound event
* HL7800_EVENT_FOTA_COUNT - uint32_t
* HL7800_EVENT_REVISION - string
*/
typedef void (*mdm_hl7800_event_callback_t)(enum mdm_hl7800_event event,
void *event_data);
/**
* @brief Power off the HL7800
*
* @return int32_t 0 for success
*/
int32_t mdm_hl7800_power_off(void);
/**
* @brief Reset the HL7800
*
* @return int32_t 0 for success
*/
int32_t mdm_hl7800_reset(void);
/**
* @brief Control the wake signals to the HL7800.
* @note this API should only be used for debug purposes.
*
* @param awake True to keep the HL7800 awake, False to allow sleep
*/
void mdm_hl7800_wakeup(bool awake);
/**
* @brief Send an AT command to the HL7800.
* @note this API should only be used for debug purposes.
*
* @param data AT command string
* @return int32_t 0 for success
*/
int32_t mdm_hl7800_send_at_cmd(const uint8_t *data);
/**
* @brief Get the signal quality of the HL7800
*
* @param rsrp Reference Signals Received Power (dBm)
* Range = -140 dBm to -44 dBm
* @param sinr Signal to Interference plus Noise Ratio (dBm)
* Range = -128 dBm to 40dBm
*/
void mdm_hl7800_get_signal_quality(int *rsrp, int *sinr);
/**
* @brief Get the SIM card ICCID
*
*/
char *mdm_hl7800_get_iccid(void);
/**
* @brief Get the HL7800 serial number
*
*/
char *mdm_hl7800_get_sn(void);
/**
* @brief Get the HL7800 IMEI
*
*/
char *mdm_hl7800_get_imei(void);
/**
* @brief Get the HL7800 firmware version
*
*/
char *mdm_hl7800_get_fw_version(void);
/**
* @brief Update the Access Point Name in the modem.
*
* @retval 0 on success, negative on failure.
*/
int32_t mdm_hl7800_update_apn(char *access_point_name);
/**
* @brief Update the Radio Access Technology (mode).
*
* @retval 0 on success, negative on failure.
*/
int32_t mdm_hl7800_update_rat(enum mdm_hl7800_radio_mode value);
/**
* @retval true if RAT value is valid
*/
bool mdm_hl7800_valid_rat(uint8_t value);
/**
* @brief Register a function that is called when a modem event occurs.
*
* @param cb event callback
*/
void mdm_hl7800_register_event_callback(mdm_hl7800_event_callback_t cb);
/**
* @brief Force modem module to generate status events.
*
* @note This can be used to get the current state when a module initializes
* later than the modem.
*/
void mdm_hl7800_generate_status_events(void);
#ifdef CONFIG_NEWLIB_LIBC
/**
* @brief Get the local time from the modem's real time clock.
*
* @param tm time structure
* @param offset The amount the local time is offset from GMT/UTC in seconds.
*
* @param 0 if successful
*/
int32_t mdm_hl7800_get_local_time(struct tm *tm, int32_t *offset);
#endif
#ifdef CONFIG_MODEM_HL7800_FW_UPDATE
/**
* @brief Update the HL7800 via XMODEM protocol. During the firmware update
* no other modem fuctions will be available.
*
* @param file_path Absolute path of the update file
*
* @param 0 if successful
*/
int32_t mdm_hl7800_update_fw(char *file_path);
#endif
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_DRIVERS_MODEM_HL7800_H_ */