drivers: modem: Added simcom sim7080 modem driver.

Implemented driver for the simcom sim7080 modem.
This driver features Socket offloading, TCP, UDP, DNS,
SMS, GPS and FTP.

Signed-off-by: Lukas Gehreke <lk.gehreke@gmail.com>
This commit is contained in:
Lukas Gehreke 2021-08-27 10:21:14 +02:00 committed by Carles Cufí
parent 11f936c87e
commit 53dea67733
12 changed files with 2910 additions and 3 deletions

View file

@ -295,7 +295,10 @@
/drivers/misc/ @tejlmand
/drivers/misc/ft8xx/ @hubertmis
/drivers/modem/hl7800.c @LairdCP/zephyr
/drivers/modem/simcom-sim7080.c @lgehreke
/drivers/modem/simcom-sim7080.h @lgehreke
/drivers/modem/Kconfig.hl7800 @LairdCP/zephyr
/drivers/modem/Kconfig.simcom-sim7080 @lgehreke
/drivers/pcie/ @dcpleung @nashif @jhedberg
/drivers/peci/ @albertofloyd @franciscomunoz @scottwcpg
/drivers/pinctrl/ @gmarull

View file

@ -38,3 +38,8 @@ if (CONFIG_MODEM_HL7800)
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
zephyr_library_sources(hl7800.c)
endif()
if (CONFIG_MODEM_SIM7080)
zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/ip)
zephyr_library_sources(simcom-sim7080.c)
endif()

View file

@ -145,5 +145,6 @@ source "drivers/modem/Kconfig.wncm14a2a"
source "drivers/modem/Kconfig.gsm"
source "drivers/modem/Kconfig.hl7800"
source "drivers/modem/Kconfig.simcom-sim7080"
endif # MODEM

View file

@ -0,0 +1,73 @@
# Simcom sim7080 driver options
# Copyright (C) 2021 metraTec GmbH
# SPDX-License-Identifier: Apache-2.0
config MODEM_SIM7080
bool "Sim7080 Driver"
select MODEM_CONTEXT
select MODEM_CMD_HANDLER
select MODEM_IFACE_UART
select MODEM_SOCKET
select NET_OFFLOAD
select NET_SOCKETS_OFFLOAD
imply GPIO
help
Enables the driver for the Sim7080 modem.
if MODEM_SIM7080
config MODEM_SIMCOM_SIM7080_RX_STACK_SIZE
int "Stack size for the simcom sim7080 modem driver rx thread"
default 1028
help
This stack is used by the simcom SIM7080 RX thread.
config MODEM_SIMCOM_SIM7080_RX_WORKQ_STACK_SIZE
int "Stack size for the simcom sim7080 modem driver work queue"
default 2048
help
This stack is used by the work queue.
config MODEM_SIMCOM_SIM7080_INIT_PRIORITY
int "simcom sim7080 driver init priority"
default 80
help
simcom sim7080 druver initialization priority.
config MODEM_SIMCOM_SIM7080_LTE_BANDS
string "LTE bands the driver can use"
default "8,20,28"
help
Comma separated list of usable lte bands.
config MODEM_SIMCOM_SIM7080_APN
string "APN for establishing a network connection"
default "internet"
help
This setting is used to set the APN name for the network connection
context. This value is specific to the network provider and may
need to be changed.
choice MODEM_SIMCOM_SIM7080_RAT
bool "Radio Access Technology Mode"
default MODEM_SIMCOM_SIM7080_RAT_NB1
config MODEM_SIMCOM_SIM7080_RAT_NB1
bool "NB-IoT"
help
Enable LTE NB-IoT mode.
config MODEM_SIMCOM_SIM7080_RAT_M1
bool "Cat-M1"
help
Enable Cat-M1 mode.
config MODEM_SIMCOM_SIM7080_RAT_GSM
bool "GSM"
help
Enable GSM mode.
endchoice
endif # MODEM_SIM7080

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,188 @@
/*
* Copyright (C) 2021 metraTec GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef SIMCOM_SIM7080_H
#define SIMCOM_SIM7080_H
#include <kernel.h>
#include <ctype.h>
#include <inttypes.h>
#include <errno.h>
#include <zephyr.h>
#include <drivers/gpio.h>
#include <drivers/modem/simcom-sim7080.h>
#include <device.h>
#include <devicetree.h>
#include <init.h>
#include <string.h>
#include <net/net_if.h>
#include <net/net_offload.h>
#include <net/socket_offload.h>
#include "modem_context.h"
#include "modem_cmd_handler.h"
#include "modem_iface_uart.h"
#include "modem_socket.h"
#define MDM_UART_DEV DEVICE_DT_GET(DT_INST_BUS(0))
#define MDM_MAX_DATA_LENGTH 1024
#define MDM_RECV_BUF_SIZE 1024
#define MDM_MAX_SOCKETS 5
#define MDM_BASE_SOCKET_NUM 0
#define MDM_RECV_MAX_BUF 30
#define BUF_ALLOC_TIMEOUT K_SECONDS(1)
#define MDM_CMD_TIMEOUT K_SECONDS(10)
#define MDM_REGISTRATION_TIMEOUT K_SECONDS(180)
#define MDM_CONNECT_TIMEOUT K_SECONDS(90)
#define MDM_PDP_TIMEOUT K_SECONDS(120)
#define MDM_DNS_TIMEOUT K_SECONDS(210)
#define MDM_WAIT_FOR_RSSI_DELAY K_SECONDS(2)
#define MDM_WAIT_FOR_RSSI_COUNT 30
#define MDM_MAX_AUTOBAUD 5
#define MDM_MAX_CEREG_WAITS 40
#define MDM_MAX_CGATT_WAITS 40
#define MDM_BOOT_TRIES 4
#define MDM_GNSS_PARSER_MAX_LEN 128
#define MDM_APN CONFIG_MODEM_SIMCOM_SIM7080_APN
#define MDM_LTE_BANDS CONFIG_MODEM_SIMCOM_SIM7080_LTE_BANDS
#define RSSI_TIMEOUT_SECS 30
#define MDM_SOCKET_PRIO 40
/*
* Default length of modem data.
*/
#define MDM_MANUFACTURER_LENGTH 12
#define MDM_MODEL_LENGTH 16
#define MDM_REVISION_LENGTH 64
#define MDM_IMEI_LENGTH 16
#define MDM_IMSI_LENGTH 16
#define MDM_ICCID_LENGTH 32
enum sim7080_state {
SIM7080_STATE_INIT = 0,
SIM7080_STATE_NETWORKING,
SIM7080_STATE_GNSS,
SIM7080_STATE_OFF,
};
/* Possible states of the ftp connection. */
enum sim7080_ftp_connection_state {
/* Not connected yet. */
SIM7080_FTP_CONNECTION_STATE_INITIAL = 0,
/* Connected and still data available. */
SIM7080_FTP_CONNECTION_STATE_CONNECTED,
/* All data transferred. */
SIM7080_FTP_CONNECTION_STATE_FINISHED,
/* Something went wrong. */
SIM7080_FTP_CONNECTION_STATE_ERROR,
};
/*
* Driver data.
*/
struct sim7080_data {
/*
* Network interface of the sim module.
*/
struct net_if *netif;
uint8_t mac_addr[6];
/*
* Uart interface of the modem.
*/
struct modem_iface_uart_data iface_data;
uint8_t iface_rb_buf[MDM_MAX_DATA_LENGTH];
/*
* Modem command handler.
*/
struct modem_cmd_handler_data cmd_handler_data;
uint8_t cmd_match_buf[MDM_RECV_BUF_SIZE + 1];
/*
* Modem socket data.
*/
struct modem_socket_config socket_config;
struct modem_socket sockets[MDM_MAX_SOCKETS];
/*
* Current state of the modem.
*/
enum sim7080_state state;
/*
* RSSI work
*/
struct k_work_delayable rssi_query_work;
/*
* Information over the modem.
*/
char mdm_manufacturer[MDM_MANUFACTURER_LENGTH];
char mdm_model[MDM_MODEL_LENGTH];
char mdm_revision[MDM_REVISION_LENGTH];
char mdm_imei[MDM_IMEI_LENGTH];
#if defined(CONFIG_MODEM_SIM_NUMBERS)
char mdm_imsi[MDM_IMSI_LENGTH];
char mdm_iccid[MDM_ICCID_LENGTH];
#endif /* #if defined(CONFIG_MODEM_SIM_NUMBERS) */
int mdm_rssi;
/*
* Current operating socket and statistics.
*/
int current_sock_fd;
int current_sock_written;
/*
* Network registration of the modem.
*/
uint8_t mdm_registration;
/*
* Whether gprs is attached or detached.
*/
uint8_t mdm_cgatt;
/*
* If the sim card is ready or not.
*/
bool cpin_ready;
/*
* Flag if the PDP context is active.
*/
bool pdp_active;
/* SMS buffer structure provided by read. */
struct sim7080_sms_buffer *sms_buffer;
/* Position in the sms buffer. */
uint8_t sms_buffer_pos;
/* Ftp related variables. */
struct {
/* User buffer for ftp data. */
char *read_buffer;
/* Length of the read buffer/number of bytes read. */
size_t nread;
/* State of the ftp connection. */
enum sim7080_ftp_connection_state state;
} ftp;
/*
* Semaphore(s).
*/
struct k_sem sem_response;
struct k_sem sem_tx_ready;
struct k_sem sem_dns;
struct k_sem sem_ftp;
};
/*
* Pin definitions
*/
static struct modem_pin modem_pins[] = { MODEM_PIN(
DT_INST_GPIO_LABEL(0, mdm_power_gpios), DT_INST_GPIO_PIN(0, mdm_power_gpios),
DT_INST_GPIO_FLAGS(0, mdm_power_gpios) | GPIO_OUTPUT_LOW) };
/*
* Socket read callback data.
*/
struct socket_read_data {
char *recv_buf;
size_t recv_buf_len;
struct sockaddr *recv_addr;
uint16_t recv_read_len;
};
#endif /* SIMCOM_SIM7080_H */

View file

@ -0,0 +1,16 @@
# Copyright (C) 2021 metraTec GmbH
# SPDX-License-Identifier: Apache-2.0
description: Simcom Sim7080 modem
compatible: "simcom,sim7080"
include: uart-device.yaml
properties:
label:
required: true
mdm-power-gpios:
type: phandle-array
required: true

View file

@ -540,6 +540,7 @@ silex-insight Silex Insight
siliconfile Siliconfile Technologies lnc.
siliconmitus Silicon Mitus, Inc.
siemens Siemens AG
simcom SIMCom Wireless Solutions Co., LTD
simtek Cypress Semiconductor Corporation (Simtek Corporation)
sinlinx Sinlinx Electronics Technology Co., LTD
sinovoip SinoVoip Co., Ltd

View file

@ -0,0 +1,218 @@
/*
* Copyright (C) 2021 metraTec GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_MODEM_SIMCOM_SIM7080_H
#define ZEPHYR_INCLUDE_DRIVERS_MODEM_SIMCOM_SIM7080_H
#include <zephyr/types.h>
#include <stdint.h>
#define SIM7080_GNSS_DATA_UTC_LEN 20
#define SIM7080_SMS_MAX_LEN 160
struct sim7080_gnss_data {
/**
* Whether gnss is powered or not.
*/
bool run_status;
/**
* Whether fix is acquired or not.
*/
bool fix_status;
/**
* UTC in format yyyyMMddhhmmss.sss
*/
char utc[SIM7080_GNSS_DATA_UTC_LEN];
/**
* Latitude in 10^-7 degree.
*/
int32_t lat;
/**
* Longitude in 10^-7 degree.
*/
int32_t lon;
/**
* Altitude in mm.
*/
int32_t alt;
/**
* Horizontal dilution of precision in 10^-2.
*/
uint16_t hdop;
/**
* Course over ground un 10^-2 degree.
*/
uint16_t cog;
/**
* Speed in 10^-1 km/h.
*/
uint16_t kmh;
};
/**
* Possible sms states in memory.
*/
enum sim7080_sms_stat {
SIM7080_SMS_STAT_REC_UNREAD = 0,
SIM7080_SMS_STAT_REC_READ,
SIM7080_SMS_STAT_STO_UNSENT,
SIM7080_SMS_STAT_STO_SENT,
SIM7080_SMS_STAT_ALL,
};
/**
* Possible ftp return codes.
*/
enum sim7080_ftp_rc {
/* Operation finished correctly. */
SIM7080_FTP_RC_OK = 0,
/* Session finished. */
SIM7080_FTP_RC_FINISHED,
/* An error occurred. */
SIM7080_FTP_RC_ERROR,
};
/**
* Buffer structure for sms.
*/
struct sim7080_sms {
/* First octet of the sms. */
uint8_t first_octet;
/* Message protocol identifier. */
uint8_t tp_pid;
/* Status of the sms in memory. */
enum sim7080_sms_stat stat;
/* Index of the sms in memory. */
uint16_t index;
/* Time the sms was received. */
struct {
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t timezone;
} time;
/* Buffered sms. */
char data[SIM7080_SMS_MAX_LEN + 1];
/* Length of the sms in buffer. */
uint8_t data_len;
};
/**
* Buffer structure for sms reads.
*/
struct sim7080_sms_buffer {
/* sms structures to read to. */
struct sim7080_sms *sms;
/* Number of sms structures. */
uint8_t nsms;
};
/**
* @brief Power on the Sim7080.
*
* @return 0 on success. Otherwise -1 is returned.
*/
int mdm_sim7080_power_on(void);
/**
* @brief Power off the Sim7080.
*
* @return 0 on success. Otherwise -1 is returned.
*/
int mdm_sim7080_power_off(void);
/**
* @brief Starts the modem in network operation mode.
*
* @return 0 on success. Otherwise <0 is returned.
*/
int mdm_sim7080_start_network(void);
/**
* @brief Starts the modem in gnss operation mode.
*
* @return 0 on success. Otherwise <0 is returned.
*/
int mdm_sim7080_start_gnss(void);
/**
* @brief Query gnss position form the modem.
*
* @return 0 on success. If no fix is acquired yet -EAGAIN is returned.
* Otherwise <0 is returned.
*/
int mdm_sim7080_query_gnss(struct sim7080_gnss_data *data);
/**
* Get the sim7080 manufacturer.
*/
const char *mdm_sim7080_get_manufacturer(void);
/**
* Get the sim7080 model information.
*/
const char *mdm_sim7080_get_model(void);
/**
* Get the sim7080 revision.
*/
const char *mdm_sim7080_get_revision(void);
/**
* Get the sim7080 imei number.
*/
const char *mdm_sim7080_get_imei(void);
/**
* Read sms from sim module.
*
* @param buffer Buffer structure for sms.
* @return Number of sms read on success. Otherwise -1 is returned.
*
* @note The buffer structure needs to be initialized to
* the size of the sms buffer. When this function finishes
* successful, nsms will be set to the number of sms read.
* If the whole structure is filled a subsequent read may
* be needed.
*/
int mdm_sim7080_read_sms(struct sim7080_sms_buffer *buffer);
/**
* Delete a sms at a given index.
*
* @param index The index of the sms in memory.
* @return 0 on success. Otherwise -1 is returned.
*/
int mdm_sim7080_delete_sms(uint16_t index);
/**
* Start a ftp get session.
*
* @param server The ftp servers address.
* @param user User name for the ftp server.
* @param passwd Password for the ftp user.
* @param file File to be downloaded.
* @param path Path to the file on the server.
* @return 0 if the session was started. Otherwise -1 is returned.
*/
int mdm_sim7080_ftp_get_start(const char *server, const char *user, const char *passwd,
const char *file, const char *path);
/**
* Read data from a ftp get session.
*
* @param dst The destination buffer.
* @param size Initialize to the size of dst. Gets set to the nuber
* of bytes actually read.
* @return According sim7080_ftp_rc.
*/
int mdm_sim7080_ftp_get_read(char *dst, size_t *size);
#endif /* ZEPHYR_INCLUDE_DRIVERS_MODEM_SIMCOM_SIM7080_H */

View file

@ -0,0 +1,8 @@
CONFIG_TEST=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_SERIAL=y
CONFIG_TEST_UART=y
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
CONFIG_MODEM=y
CONFIG_MODEM_SIM7080=y

View file

@ -4,10 +4,13 @@ common:
tests:
drivers.modem.build:
extra_args: CONF_FILE=modem.conf
platform_exclude: serpente particle_boron rak5010_nrf52840 litex_vexriscv
platform_exclude: serpente particle_boron rak5010_nrf52840 litex_vexriscv ip_k66f
drivers.modem.ublox_sara.build:
extra_args: CONF_FILE=modem_ublox_sara.conf
platform_exclude: serpente pinnacle_100_dvk litex_vexriscv
platform_exclude: serpente pinnacle_100_dvk litex_vexriscv ip_k66f
drivers.modem.simcom_sim7080.build:
extra_args: CONF_FILE=modem_simcom_sim7080.conf
platform_exclude: serpente pinnacle_100_dvk litex_vexriscv ip_k66f
drivers.modem.quectel_bg9x.build:
extra_args: CONF_FILE=modem_quectel_bg9x.conf
platform_exclude: serpente pinnacle_100_dvk litex_vexriscv
platform_exclude: serpente pinnacle_100_dvk litex_vexriscv ip_k66f

View file

@ -37,6 +37,13 @@ test_sara_r4: sara_r4 {
mdm-reset-gpios = <&test_gpio 0 0>;
};
test_simcom_sim7080: sim7080 {
compatible = "simcom,sim7080";
label = "simcom,sim7080";
mdm-power-gpios = <&test_gpio 0 0>;
};
test_quectel_bg9x: quectel_bg9x {
compatible = "quectel,bg9x";
label = "quectel,bg9x";