ADD: GNSS Driver for U-BLOX M10 & Support for UBX Messages
MODEM_UBX: Adds Support for UBX Messages in Modem Subsystem. GNSS API Supported: get_supported_systems, set_fix_rate, get_fix_rate, set_enabled_systems, get_enabled_systems, set_navigation_mode, get_navigation_mode. Boards Tested: MIMXRT1062_FMURT6, VMU_RT1170. Note: Partial support for U-BLOX Messages is provided as of now. Signed-off-by: Sumit Batra <sumit.batra@nxp.com> Signed-off-by: Mayank Mahajan <mayankmahajan.x@nxp.com>
This commit is contained in:
parent
bc140e1a36
commit
3d81167eaf
|
@ -9,3 +9,5 @@ zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA0183 gnss_nmea0183.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA0183_MATCH gnss_nmea0183_match.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GNSS_NMEA_GENERIC gnss_nmea_generic.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GNSS_QUECTEL_LCX6G gnss_quectel_lcx6g.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GNSS_U_BLOX_M10 gnss_u_blox_m10.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_GNSS_U_BLOX_PROTOCOL gnss_u_blox_protocol/gnss_u_blox_protocol.c)
|
||||
|
|
|
@ -60,11 +60,18 @@ config GNSS_INIT_PRIORITY
|
|||
help
|
||||
Driver initialization priority for GNSS drivers.
|
||||
|
||||
config GNSS_U_BLOX_PROTOCOL
|
||||
bool "GNSS U-BLOX protocol"
|
||||
select MODEM_UBX
|
||||
help
|
||||
Enable gnss u-blox protocol.
|
||||
|
||||
module = GNSS
|
||||
module-str = gnss
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
rsource "Kconfig.generic"
|
||||
rsource "Kconfig.quectel_lcx6g"
|
||||
rsource "Kconfig.u_blox_m10"
|
||||
|
||||
endif
|
||||
|
|
29
drivers/gnss/Kconfig.u_blox_m10
Normal file
29
drivers/gnss/Kconfig.u_blox_m10
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Copyright 2024 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config GNSS_U_BLOX_M10
|
||||
bool "U-BLOX M10 GNSS Module"
|
||||
default y
|
||||
depends on GNSS
|
||||
depends on DT_HAS_U_BLOX_M10_ENABLED
|
||||
select MODEM_MODULES
|
||||
select MODEM_BACKEND_UART
|
||||
select MODEM_CHAT
|
||||
select MODEM_UBX
|
||||
select GNSS_PARSE
|
||||
select GNSS_NMEA0183
|
||||
select GNSS_NMEA0183_MATCH
|
||||
select GNSS_U_BLOX_PROTOCOL
|
||||
select UART_USE_RUNTIME_CONFIGURE
|
||||
help
|
||||
Enable U-BLOX M10 GNSS modem driver.
|
||||
|
||||
config GNSS_U_BLOX_M10_SATELLITES_COUNT
|
||||
int "Maximum satellite count"
|
||||
depends on GNSS_SATELLITES
|
||||
default 24
|
||||
help
|
||||
Maximum number of satellite that the driver that can be decoded from
|
||||
the GNSS device. This does not affect the number of devices that the
|
||||
device is actually tracking, just how many of those can be reported
|
||||
in the satellites callback.
|
1045
drivers/gnss/gnss_u_blox_m10.c
Normal file
1045
drivers/gnss/gnss_u_blox_m10.c
Normal file
File diff suppressed because it is too large
Load diff
180
drivers/gnss/gnss_u_blox_protocol/gnss_u_blox_protocol.c
Normal file
180
drivers/gnss/gnss_u_blox_protocol/gnss_u_blox_protocol.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "gnss_u_blox_protocol.h"
|
||||
|
||||
const uint32_t ubx_baudrate[UBX_BAUDRATE_COUNT] = {
|
||||
4800,
|
||||
9600,
|
||||
19200,
|
||||
38400,
|
||||
57600,
|
||||
115200,
|
||||
230400,
|
||||
460800,
|
||||
921600,
|
||||
};
|
||||
|
||||
static inline int ubx_validate_payload_size_ack(uint8_t msg_id, uint16_t payload_size)
|
||||
{
|
||||
switch (msg_id) {
|
||||
case UBX_ACK_ACK:
|
||||
return payload_size == UBX_CFG_ACK_PAYLOAD_SZ ? 0 : -1;
|
||||
case UBX_ACK_NAK:
|
||||
return payload_size == UBX_CFG_NAK_PAYLOAD_SZ ? 0 : -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int ubx_validate_payload_size_cfg(uint8_t msg_id, uint16_t payload_size)
|
||||
{
|
||||
switch (msg_id) {
|
||||
case UBX_CFG_RATE:
|
||||
return payload_size == UBX_CFG_RATE_PAYLOAD_SZ ? 0 : -1;
|
||||
case UBX_CFG_PRT:
|
||||
return (payload_size == UBX_CFG_PRT_POLL_PAYLOAD_SZ ||
|
||||
payload_size == UBX_CFG_PRT_SET_PAYLOAD_SZ) ? 0 : -1;
|
||||
case UBX_CFG_RST:
|
||||
return payload_size == UBX_CFG_RST_PAYLOAD_SZ ? 0 : -1;
|
||||
case UBX_CFG_NAV5:
|
||||
return payload_size == UBX_CFG_NAV5_PAYLOAD_SZ ? 0 : -1;
|
||||
case UBX_CFG_GNSS:
|
||||
return ((payload_size - UBX_CFG_GNSS_PAYLOAD_INIT_SZ) %
|
||||
UBX_CFG_GNSS_PAYLOAD_CFG_BLK_SZ == 0) ? 0 : -1;
|
||||
case UBX_CFG_MSG:
|
||||
return payload_size == UBX_CFG_MSG_PAYLOAD_SZ ? 0 : -1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int ubx_validate_payload_size(uint8_t msg_cls, uint8_t msg_id, uint16_t payload_size)
|
||||
{
|
||||
if (payload_size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (payload_size > UBX_PAYLOAD_SZ_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (msg_cls) {
|
||||
case UBX_CLASS_ACK:
|
||||
return ubx_validate_payload_size_ack(msg_id, payload_size);
|
||||
case UBX_CLASS_CFG:
|
||||
return ubx_validate_payload_size_cfg(msg_id, payload_size);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int ubx_create_and_validate_frame(uint8_t *ubx_frame, uint16_t ubx_frame_size, uint8_t msg_cls,
|
||||
uint8_t msg_id, const void *payload, uint16_t payload_size)
|
||||
{
|
||||
if (ubx_validate_payload_size(msg_cls, msg_id, payload_size)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return modem_ubx_create_frame(ubx_frame, ubx_frame_size, msg_cls, msg_id, payload,
|
||||
payload_size);
|
||||
}
|
||||
|
||||
void ubx_cfg_ack_payload_default(struct ubx_cfg_ack_payload *payload)
|
||||
{
|
||||
payload->message_class = UBX_CLASS_CFG;
|
||||
payload->message_id = UBX_CFG_PRT;
|
||||
}
|
||||
|
||||
void ubx_cfg_rate_payload_default(struct ubx_cfg_rate_payload *payload)
|
||||
{
|
||||
payload->meas_rate_ms = 1000;
|
||||
payload->nav_rate = 1;
|
||||
payload->time_ref = UBX_CFG_RATE_TIME_REF_UTC;
|
||||
}
|
||||
|
||||
void ubx_cfg_prt_poll_payload_default(struct ubx_cfg_prt_poll_payload *payload)
|
||||
{
|
||||
payload->port_id = UBX_PORT_NUMBER_UART;
|
||||
}
|
||||
|
||||
void ubx_cfg_prt_set_payload_default(struct ubx_cfg_prt_set_payload *payload)
|
||||
{
|
||||
payload->port_id = UBX_PORT_NUMBER_UART;
|
||||
payload->reserved0 = UBX_CFG_PRT_RESERVED0;
|
||||
payload->tx_ready_pin_conf = UBX_CFG_PRT_TX_READY_PIN_CONF_POL_HIGH;
|
||||
payload->port_mode = UBX_CFG_PRT_PORT_MODE_CHAR_LEN_8 | UBX_CFG_PRT_PORT_MODE_PARITY_NONE |
|
||||
UBX_CFG_PRT_PORT_MODE_STOP_BITS_1;
|
||||
payload->baudrate = ubx_baudrate[3];
|
||||
payload->in_proto_mask = UBX_CFG_PRT_IN_PROTO_UBX | UBX_CFG_PRT_IN_PROTO_NMEA |
|
||||
UBX_CFG_PRT_IN_PROTO_RTCM;
|
||||
payload->out_proto_mask = UBX_CFG_PRT_OUT_PROTO_UBX | UBX_CFG_PRT_OUT_PROTO_NMEA |
|
||||
UBX_CFG_PRT_OUT_PROTO_RTCM3;
|
||||
payload->flags = UBX_CFG_PRT_FLAGS_DEFAULT;
|
||||
payload->reserved1 = UBX_CFG_PRT_RESERVED1;
|
||||
}
|
||||
|
||||
void ubx_cfg_rst_payload_default(struct ubx_cfg_rst_payload *payload)
|
||||
{
|
||||
payload->nav_bbr_mask = UBX_CFG_RST_NAV_BBR_MASK_HOT_START;
|
||||
payload->reset_mode = UBX_CFG_RST_RESET_MODE_CONTROLLED_SOFT_RESET;
|
||||
payload->reserved0 = UBX_CFG_RST_RESERVED0;
|
||||
}
|
||||
|
||||
void ubx_cfg_nav5_payload_default(struct ubx_cfg_nav5_payload *payload)
|
||||
{
|
||||
payload->mask = UBX_CFG_NAV5_MASK_ALL;
|
||||
payload->dyn_model = UBX_DYN_MODEL_PORTABLE;
|
||||
|
||||
payload->fix_mode = UBX_FIX_AUTO_FIX;
|
||||
|
||||
payload->fixed_alt = UBX_CFG_NAV5_FIXED_ALT_DEFAULT;
|
||||
payload->fixed_alt_var = UBX_CFG_NAV5_FIXED_ALT_VAR_DEFAULT;
|
||||
|
||||
payload->min_elev = UBX_CFG_NAV5_MIN_ELEV_DEFAULT;
|
||||
payload->dr_limit = UBX_CFG_NAV5_DR_LIMIT_DEFAULT;
|
||||
|
||||
payload->p_dop = UBX_CFG_NAV5_P_DOP_DEFAULT;
|
||||
payload->t_dop = UBX_CFG_NAV5_T_DOP_DEFAULT;
|
||||
payload->p_acc = UBX_CFG_NAV5_P_ACC_DEFAULT;
|
||||
payload->t_acc = UBX_CFG_NAV5_T_ACC_DEFAULT;
|
||||
|
||||
payload->static_hold_threshold = UBX_CFG_NAV5_STATIC_HOLD_THRESHOLD_DEFAULT;
|
||||
payload->dgnss_timeout = UBX_CFG_NAV5_DGNSS_TIMEOUT_DEFAULT;
|
||||
payload->cno_threshold_num_svs = UBX_CFG_NAV5_CNO_THRESHOLD_NUM_SVS_DEFAULT;
|
||||
payload->cno_threshold = UBX_CFG_NAV5_CNO_THRESHOLD_DEFAULT;
|
||||
|
||||
payload->reserved0 = UBX_CFG_NAV5_RESERVED0;
|
||||
|
||||
payload->static_hold_dist_threshold = UBX_CFG_NAV5_STATIC_HOLD_DIST_THRESHOLD;
|
||||
payload->utc_standard = UBX_CFG_NAV5_UTC_STANDARD_DEFAULT;
|
||||
}
|
||||
|
||||
static struct ubx_cfg_gnss_payload_config_block ubx_cfg_gnss_payload_config_block_default = {
|
||||
.gnss_id = UBX_GNSS_ID_GPS,
|
||||
.num_res_trk_ch = 0x00,
|
||||
.max_num_trk_ch = 0x00,
|
||||
.reserved0 = UBX_CFG_GNSS_RESERVED0,
|
||||
.flags = UBX_CFG_GNSS_FLAG_ENABLE | UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L1C_A,
|
||||
};
|
||||
|
||||
void ubx_cfg_gnss_payload_default(struct ubx_cfg_gnss_payload *payload)
|
||||
{
|
||||
payload->msg_ver = UBX_CFG_GNSS_MSG_VER;
|
||||
payload->num_trk_ch_hw = UBX_CFG_GNSS_NUM_TRK_CH_HW_DEFAULT;
|
||||
payload->num_trk_ch_use = UBX_CFG_GNSS_NUM_TRK_CH_USE_DEFAULT;
|
||||
|
||||
for (int i = 0; i < payload->num_config_blocks; ++i) {
|
||||
payload->config_blocks[i] = ubx_cfg_gnss_payload_config_block_default;
|
||||
}
|
||||
}
|
||||
|
||||
void ubx_cfg_msg_payload_default(struct ubx_cfg_msg_payload *payload)
|
||||
{
|
||||
payload->message_class = UBX_CLASS_NMEA;
|
||||
payload->message_id = UBX_NMEA_GGA;
|
||||
payload->rate = UBX_CFG_MSG_RATE_DEFAULT;
|
||||
}
|
251
drivers/gnss/gnss_u_blox_protocol/gnss_u_blox_protocol.h
Normal file
251
drivers/gnss/gnss_u_blox_protocol/gnss_u_blox_protocol.h
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/modem/ubx.h>
|
||||
#include "gnss_u_blox_protocol_defines.h"
|
||||
|
||||
#ifndef ZEPHYR_U_BLOX_PROTOCOL_
|
||||
#define ZEPHYR_U_BLOX_PROTOCOL_
|
||||
|
||||
#define UBX_BAUDRATE_COUNT 9
|
||||
|
||||
/* When a configuration frame is sent, the device requires some delay to reflect the changes. */
|
||||
/* TODO: check what is the precise waiting time for each message. */
|
||||
#define UBX_CFG_RST_WAIT_MS 6000
|
||||
#define UBX_CFG_GNSS_WAIT_MS 6000
|
||||
#define UBX_CFG_NAV5_WAIT_MS 6000
|
||||
|
||||
extern const uint32_t ubx_baudrate[UBX_BAUDRATE_COUNT];
|
||||
|
||||
#define UBX_FRM_GET_PAYLOAD_SZ 0
|
||||
#define UBX_CFG_ACK_PAYLOAD_SZ 2
|
||||
#define UBX_CFG_NAK_PAYLOAD_SZ 2
|
||||
#define UBX_CFG_RATE_PAYLOAD_SZ 6
|
||||
#define UBX_CFG_PRT_POLL_PAYLOAD_SZ 1
|
||||
#define UBX_CFG_PRT_POLL_FRM_SZ (UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_PRT_POLL_PAYLOAD_SZ)
|
||||
#define UBX_CFG_PRT_SET_PAYLOAD_SZ 20
|
||||
#define UBX_CFG_PRT_SET_FRM_SZ (UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_PRT_SET_PAYLOAD_SZ)
|
||||
#define UBX_CFG_RST_PAYLOAD_SZ 4
|
||||
#define UBX_CFG_RST_FRM_SZ (UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_RST_PAYLOAD_SZ)
|
||||
#define UBX_CFG_NAV5_PAYLOAD_SZ 36
|
||||
#define UBX_CFG_NAV5_FRM_SZ (UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_NAV5_PAYLOAD_SZ)
|
||||
#define UBX_CFG_MSG_PAYLOAD_SZ 3
|
||||
#define UBX_CFG_MSG_FRM_SZ (UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_MSG_PAYLOAD_SZ)
|
||||
#define UBX_CFG_GNSS_PAYLOAD_INIT_SZ 4
|
||||
#define UBX_CFG_GNSS_PAYLOAD_CFG_BLK_SZ 8
|
||||
#define UBX_CFG_GNSS_PAYLOAD_SZ(n) \
|
||||
(UBX_CFG_GNSS_PAYLOAD_INIT_SZ + UBX_CFG_GNSS_PAYLOAD_CFG_BLK_SZ * n)
|
||||
#define UBX_CFG_GNSS_FRM_SZ(n) (UBX_FRM_SZ_WO_PAYLOAD + UBX_CFG_GNSS_PAYLOAD_SZ(n))
|
||||
|
||||
|
||||
int ubx_create_and_validate_frame(uint8_t *ubx_frame, uint16_t ubx_frame_size, uint8_t msg_cls,
|
||||
uint8_t msg_id, const void *payload, uint16_t payload_size);
|
||||
|
||||
struct ubx_cfg_ack_payload {
|
||||
uint8_t message_class;
|
||||
uint8_t message_id;
|
||||
};
|
||||
|
||||
void ubx_cfg_ack_payload_default(struct ubx_cfg_ack_payload *payload);
|
||||
|
||||
#define UBX_CFG_RATE_TIME_REF_UTC 0 /* Align measurements to UTC time. */
|
||||
#define UBX_CFG_RATE_TIME_REF_GPS 1 /* Align measurements to GPS time. */
|
||||
#define UBX_CFG_RATE_TIME_REF_GLO 2 /* Align measurements to GLONASS time. */
|
||||
#define UBX_CFG_RATE_TIME_REF_BDS 3 /* Align measurements to BeiDou time. */
|
||||
#define UBX_CFG_RATE_TIME_REF_GAL 4 /* Align measurements to Galileo time. */
|
||||
|
||||
struct ubx_cfg_rate_payload {
|
||||
uint16_t meas_rate_ms;
|
||||
uint16_t nav_rate;
|
||||
uint16_t time_ref;
|
||||
};
|
||||
|
||||
void ubx_cfg_rate_payload_default(struct ubx_cfg_rate_payload *payload);
|
||||
|
||||
struct ubx_cfg_prt_poll_payload {
|
||||
uint8_t port_id;
|
||||
};
|
||||
|
||||
void ubx_cfg_prt_poll_payload_default(struct ubx_cfg_prt_poll_payload *payload);
|
||||
|
||||
#define UBX_CFG_PRT_IN_PROTO_UBX BIT(0)
|
||||
#define UBX_CFG_PRT_IN_PROTO_NMEA BIT(1)
|
||||
#define UBX_CFG_PRT_IN_PROTO_RTCM BIT(2)
|
||||
#define UBX_CFG_PRT_IN_PROTO_RTCM3 BIT(5)
|
||||
#define UBX_CFG_PRT_OUT_PROTO_UBX BIT(0)
|
||||
#define UBX_CFG_PRT_OUT_PROTO_NMEA BIT(1)
|
||||
#define UBX_CFG_PRT_OUT_PROTO_RTCM3 BIT(5)
|
||||
|
||||
#define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_5 0U
|
||||
#define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_6 BIT(6)
|
||||
#define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_7 BIT(7)
|
||||
#define UBX_CFG_PRT_PORT_MODE_CHAR_LEN_8 (BIT(6) | BIT(7))
|
||||
|
||||
#define UBX_CFG_PRT_PORT_MODE_PARITY_EVEN 0U
|
||||
#define UBX_CFG_PRT_PORT_MODE_PARITY_ODD BIT(9)
|
||||
#define UBX_CFG_PRT_PORT_MODE_PARITY_NONE BIT(11)
|
||||
|
||||
#define UBX_CFG_PRT_PORT_MODE_STOP_BITS_1 0U
|
||||
#define UBX_CFG_PRT_PORT_MODE_STOP_BITS_1_HALF BIT(12)
|
||||
#define UBX_CFG_PRT_PORT_MODE_STOP_BITS_2 BIT(13)
|
||||
#define UBX_CFG_PRT_PORT_MODE_STOP_BITS_HALF (BIT(12) | BIT(13))
|
||||
|
||||
#define UBX_CFG_PRT_RESERVED0 0x00
|
||||
#define UBX_CFG_PRT_TX_READY_PIN_CONF_DEFAULT 0x0000
|
||||
#define UBX_CFG_PRT_TX_READY_PIN_CONF_EN BIT(0)
|
||||
#define UBX_CFG_PRT_TX_READY_PIN_CONF_POL_LOW BIT(1)
|
||||
#define UBX_CFG_PRT_TX_READY_PIN_CONF_POL_HIGH 0U
|
||||
#define UBX_CFG_PRT_RESERVED1 0x00
|
||||
#define UBX_CFG_PRT_FLAGS_DEFAULT 0x0000
|
||||
#define UBX_CFG_PRT_FLAGS_EXTENDED_TX_TIMEOUT BIT(0)
|
||||
|
||||
struct ubx_cfg_prt_set_payload {
|
||||
uint8_t port_id;
|
||||
uint8_t reserved0;
|
||||
uint16_t tx_ready_pin_conf;
|
||||
uint32_t port_mode;
|
||||
uint32_t baudrate;
|
||||
uint16_t in_proto_mask;
|
||||
uint16_t out_proto_mask;
|
||||
uint16_t flags;
|
||||
uint8_t reserved1;
|
||||
};
|
||||
|
||||
void ubx_cfg_prt_set_payload_default(struct ubx_cfg_prt_set_payload *payload);
|
||||
|
||||
#define UBX_CFG_RST_NAV_BBR_MASK_HOT_START 0x0000
|
||||
#define UBX_CFG_RST_NAV_BBR_MASK_WARM_START 0x0001
|
||||
#define UBX_CFG_RST_NAV_BBR_MASK_COLD_START 0xFFFF
|
||||
|
||||
#define UBX_CFG_RST_RESET_MODE_HARD_RESET 0x00
|
||||
#define UBX_CFG_RST_RESET_MODE_CONTROLLED_SOFT_RESET 0x01
|
||||
#define UBX_CFG_RST_RESET_MODE_CONTROLLED_SOFT_RESET_GNSS_ONLY 0x02
|
||||
#define UBX_CFG_RST_RESET_MODE_HARD_RESET_AFTER_SHUTDOWN 0x04
|
||||
#define UBX_CFG_RST_RESET_MODE_CONTROLLED_GNSS_STOP 0x08
|
||||
#define UBX_CFG_RST_RESET_MODE_CONTROLLED_GNSS_START 0x09
|
||||
|
||||
#define UBX_CFG_RST_RESERVED0 0x00
|
||||
|
||||
struct ubx_cfg_rst_payload {
|
||||
uint16_t nav_bbr_mask;
|
||||
uint8_t reset_mode;
|
||||
uint8_t reserved0;
|
||||
};
|
||||
|
||||
void ubx_cfg_rst_payload_default(struct ubx_cfg_rst_payload *payload);
|
||||
|
||||
#define UBX_CFG_NAV5_MASK_ALL 0x05FF
|
||||
#define UBX_CFG_NAV5_FIX_MODE_DEFAULT UBX_FIX_AUTO_FIX
|
||||
#define UBX_CFG_NAV5_FIXED_ALT_DEFAULT 0
|
||||
#define UBX_CFG_NAV5_FIXED_ALT_VAR_DEFAULT 1U
|
||||
#define UBX_CFG_NAV5_MIN_ELEV_DEFAULT 5
|
||||
#define UBX_CFG_NAV5_DR_LIMIT_DEFAULT 3U
|
||||
#define UBX_CFG_NAV5_P_DOP_DEFAULT 100U
|
||||
#define UBX_CFG_NAV5_T_DOP_DEFAULT 100U
|
||||
#define UBX_CFG_NAV5_P_ACC_DEFAULT 100U
|
||||
#define UBX_CFG_NAV5_T_ACC_DEFAULT 350U
|
||||
#define UBX_CFG_NAV5_STATIC_HOLD_THRESHOLD_DEFAULT 0U
|
||||
#define UBX_CFG_NAV5_DGNSS_TIMEOUT_DEFAULT 60U
|
||||
#define UBX_CFG_NAV5_CNO_THRESHOLD_NUM_SVS_DEFAULT 0U
|
||||
#define UBX_CFG_NAV5_CNO_THRESHOLD_DEFAULT 0U
|
||||
#define UBX_CFG_NAV5_RESERVED0 0U
|
||||
#define UBX_CFG_NAV5_STATIC_HOLD_DIST_THRESHOLD 0U
|
||||
#define UBX_CFG_NAV5_UTC_STANDARD_DEFAULT UBX_UTC_AUTOUTC
|
||||
|
||||
struct ubx_cfg_nav5_payload {
|
||||
uint16_t mask;
|
||||
uint8_t dyn_model;
|
||||
|
||||
uint8_t fix_mode;
|
||||
|
||||
int32_t fixed_alt;
|
||||
uint32_t fixed_alt_var;
|
||||
|
||||
int8_t min_elev;
|
||||
uint8_t dr_limit;
|
||||
|
||||
uint16_t p_dop;
|
||||
uint16_t t_dop;
|
||||
uint16_t p_acc;
|
||||
uint16_t t_acc;
|
||||
|
||||
uint8_t static_hold_threshold;
|
||||
uint8_t dgnss_timeout;
|
||||
uint8_t cno_threshold_num_svs;
|
||||
uint8_t cno_threshold;
|
||||
|
||||
uint16_t reserved0;
|
||||
|
||||
uint16_t static_hold_dist_threshold;
|
||||
uint8_t utc_standard;
|
||||
};
|
||||
|
||||
void ubx_cfg_nav5_payload_default(struct ubx_cfg_nav5_payload *payload);
|
||||
|
||||
#define UBX_CFG_GNSS_MSG_VER 0x00
|
||||
#define UBX_CFG_GNSS_NUM_TRK_CH_HW_DEFAULT 0x31
|
||||
#define UBX_CFG_GNSS_NUM_TRK_CH_USE_DEFAULT 0x31
|
||||
|
||||
#define UBX_CFG_GNSS_RESERVED0 0x00
|
||||
#define UBX_CFG_GNSS_FLAG_ENABLE BIT(0)
|
||||
#define UBX_CFG_GNSS_FLAG_DISABLE 0U
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT 16
|
||||
/* When gnss_id is 0 (GPS) */
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L1C_A (0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L2C (0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GPS_L5 (0x20 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
/* When gnss_id is 1 (SBAS) */
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_SBAS_L1C_A (0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
/* When gnss_id is 2 (Galileo) */
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GALILEO_E1 (0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GALILEO_E5A (0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GALILEO_E5B (0x20 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
/* When gnss_id is 3 (BeiDou) */
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_BEIDOU_B1I (0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_BEIDOU_B2I (0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_BEIDOU_B2A (0x80 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
/* When gnss_id is 4 (IMES) */
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_IMES_L1 (0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
/* When gnss_id is 5 (QZSS) */
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L1C_A (0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L1S (0x04 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L2C (0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_QZSS_L5 (0x20 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
/* When gnss_id is 6 (GLONASS) */
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GLONASS_L1 (0x01 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
#define UBX_CFG_GNSS_FLAG_SGN_CNF_GLONASS_L2 (0x10 << UBX_CFG_GNSS_FLAG_SGN_CNF_SHIFT)
|
||||
|
||||
struct ubx_cfg_gnss_payload_config_block {
|
||||
uint8_t gnss_id;
|
||||
uint8_t num_res_trk_ch;
|
||||
uint8_t max_num_trk_ch;
|
||||
uint8_t reserved0;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct ubx_cfg_gnss_payload {
|
||||
uint8_t msg_ver;
|
||||
uint8_t num_trk_ch_hw;
|
||||
uint8_t num_trk_ch_use;
|
||||
uint8_t num_config_blocks;
|
||||
struct ubx_cfg_gnss_payload_config_block config_blocks[];
|
||||
};
|
||||
|
||||
void ubx_cfg_gnss_payload_default(struct ubx_cfg_gnss_payload *payload);
|
||||
|
||||
#define UBX_CFG_MSG_RATE_DEFAULT 1
|
||||
|
||||
struct ubx_cfg_msg_payload {
|
||||
uint8_t message_class;
|
||||
uint8_t message_id;
|
||||
uint8_t rate;
|
||||
};
|
||||
|
||||
void ubx_cfg_msg_payload_default(struct ubx_cfg_msg_payload *payload);
|
||||
|
||||
#endif /* ZEPHYR_U_BLOX_PROTOCOL_ */
|
258
drivers/gnss/gnss_u_blox_protocol/gnss_u_blox_protocol_defines.h
Normal file
258
drivers/gnss/gnss_u_blox_protocol/gnss_u_blox_protocol_defines.h
Normal file
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/* Referred some enum definitions from file "include/zephyr/drivers/gnss/ublox_neo_m8_defines.h"
|
||||
* from the pull request #46447 (link - https://github.com/zephyrproject-rtos/zephyr/pull/46447).
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_U_BLOX_PROTOCOL_DEFINES_
|
||||
#define ZEPHYR_U_BLOX_PROTOCOL_DEFINES_
|
||||
|
||||
enum ubx_gnss_id {
|
||||
UBX_GNSS_ID_GPS = 0,
|
||||
UBX_GNSS_ID_SBAS = 1,
|
||||
UBX_GNSS_ID_GALILEO = 2,
|
||||
UBX_GNSS_ID_BEIDOU = 3,
|
||||
UBX_GNSS_ID_IMES = 4,
|
||||
UBX_GNSS_ID_QZSS = 5,
|
||||
UBX_GNSS_ID_GLONASS = 6,
|
||||
};
|
||||
|
||||
enum ubx_port_number {
|
||||
UBX_PORT_NUMBER_DDC = 0,
|
||||
UBX_PORT_NUMBER_UART,
|
||||
UBX_PORT_NUMBER_USB,
|
||||
UBX_PORT_NUMBER_SPI,
|
||||
};
|
||||
|
||||
enum ubx_dynamic_model {
|
||||
UBX_DYN_MODEL_PORTABLE = 0,
|
||||
UBX_DYN_MODEL_STATIONARY = 2,
|
||||
UBX_DYN_MODEL_PEDESTRIAN = 3,
|
||||
UBX_DYN_MODEL_AUTOMOTIV = 4,
|
||||
UBX_DYN_MODEL_SEA = 5,
|
||||
UBX_DYN_MODEL_AIRBONE1G = 6,
|
||||
UBX_DYN_MODEL_AIRBONE2G = 7,
|
||||
UBX_DYN_MODEL_AIRBONE4G = 8,
|
||||
UBX_DYN_MODEL_WIRST = 9,
|
||||
UBX_DYN_MODEL_BIKE = 10,
|
||||
};
|
||||
|
||||
enum ubx_fix_mode {
|
||||
UBX_FIX_P_2D = 1,
|
||||
UBX_FIX_P_3D,
|
||||
UBX_FIX_AUTO_FIX,
|
||||
};
|
||||
|
||||
enum ubx_utc_standard {
|
||||
UBX_UTC_AUTOUTC = 0,
|
||||
UBX_UTC_GPS = 3,
|
||||
UBX_UTC_GALILEO = 5,
|
||||
UBX_UTC_GLONASS,
|
||||
UBX_UTC_BEIDOU,
|
||||
UBX_UTC_NAVIC,
|
||||
};
|
||||
|
||||
enum ubx_msg_class {
|
||||
UBX_CLASS_NAV = 0x01,
|
||||
UBX_CLASS_RXM = 0x02,
|
||||
UBX_CLASS_INF = 0x04,
|
||||
UBX_CLASS_ACK = 0x05,
|
||||
UBX_CLASS_CFG = 0x06,
|
||||
UBX_CLASS_UPD = 0x09,
|
||||
UBX_CLASS_MON = 0x0A,
|
||||
UBX_CLASS_AID = 0x0B,
|
||||
UBX_CLASS_TIM = 0x0D,
|
||||
UBX_CLASS_ESF = 0x10,
|
||||
UBX_CLASS_MGA = 0x13,
|
||||
UBX_CLASS_LOG = 0x21,
|
||||
UBX_CLASS_SEC = 0x27,
|
||||
UBX_CLASS_HNR = 0x28,
|
||||
UBX_CLASS_NMEA = 0xF0,
|
||||
};
|
||||
|
||||
enum ubx_ack_message {
|
||||
UBX_ACK_ACK = 0x01,
|
||||
UBX_ACK_NAK = 0x00,
|
||||
};
|
||||
|
||||
enum ubx_config_message {
|
||||
UBX_CFG_ANT = 0x13,
|
||||
UBX_CFG_BATCH = 0x93,
|
||||
UBX_CFG_CFG = 0x09,
|
||||
UBX_CFG_DAT = 0x06,
|
||||
UBX_CFG_DGNSS = 0x70,
|
||||
UBX_CFG_DOSC = 0x61,
|
||||
UBX_CFG_ESFALG = 0x56,
|
||||
UBX_CFG_ESFAE = 0x4C,
|
||||
UBX_CFG_ESFGE = 0x4D,
|
||||
UBX_CFG_ESFWTE = 0x82,
|
||||
UBX_CFG_ESRCE = 0x60,
|
||||
UBX_CFG_GEOFENCE = 0x69,
|
||||
UBX_CFG_GNSS = 0x3E,
|
||||
UBX_CFG_HNR = 0x5C,
|
||||
UBX_CFG_INF = 0x02,
|
||||
UBX_CFG_ITFM = 0x39,
|
||||
UBX_CFG_LOGFILTER = 0x47,
|
||||
UBX_CFG_MSG = 0x01,
|
||||
UBX_CFG_NAV5 = 0x24,
|
||||
UBX_CFG_NAVX5 = 0x23,
|
||||
UBX_CFG_NMEA = 0x17,
|
||||
UBX_CFG_ODO = 0x1E,
|
||||
UBX_CFG_PM2 = 0x3B,
|
||||
UBX_CFG_PMS = 0x86,
|
||||
UBX_CFG_PRT = 0x00,
|
||||
UBX_CFG_PWR = 0x57,
|
||||
UBX_CFG_RATE = 0x08,
|
||||
UBX_CFG_RINV = 0x34,
|
||||
UBX_CFG_RST = 0x04,
|
||||
UBX_CFG_RXM = 0x11,
|
||||
UBX_CFG_SBAS = 0x16,
|
||||
UBX_CFG_SENIF = 0x88,
|
||||
UBX_CFG_SLAS = 0x8D,
|
||||
UBX_CFG_SMGR = 0x62,
|
||||
UBX_CFG_SPT = 0x64,
|
||||
UBX_CFG_TMODE2 = 0x3D,
|
||||
UBX_CFG_TMODE3 = 0x71,
|
||||
UBX_CFG_TP5 = 0x31,
|
||||
UBX_CFG_TXSLOT = 0x53,
|
||||
UBX_CFG_USB = 0x1B,
|
||||
};
|
||||
|
||||
enum ubx_information_message {
|
||||
UBX_INF_DEBUG = 0x04,
|
||||
UBX_INF_ERROR = 0x00,
|
||||
UBX_INF_NOTICE = 0x02,
|
||||
UBX_INF_TEST = 0x03,
|
||||
UBX_INF_WARNING = 0x01,
|
||||
};
|
||||
|
||||
enum ubx_logging_message {
|
||||
UBX_LOG_BATCH = 0x11,
|
||||
UBX_LOG_CREATE = 0x07,
|
||||
UBX_LOG_ERASE = 0x03,
|
||||
UBX_LOG_FINDTIME = 0x0E,
|
||||
UBX_LOG_INFO = 0x08,
|
||||
UBX_LOG_RETRIEVEBATCH = 0x10,
|
||||
UBX_LOG_RETRIEVEPOSEXTRA = 0x0f,
|
||||
UBX_LOG_RETRIEVEPOS = 0x0b,
|
||||
UBX_LOG_RETRIEVESTRING = 0x0d,
|
||||
UBX_LOG_RETRIEVE = 0x09,
|
||||
UBX_LOG_STRING = 0x04,
|
||||
};
|
||||
|
||||
enum ubx_multiple_gnss_assistance_message {
|
||||
UBX_MGA_ACK = 0x60,
|
||||
UBX_MGA_ANO = 0x20,
|
||||
UBX_MGA_BDS = 0x03,
|
||||
UBX_MGA_DBD = 0x80,
|
||||
UBX_MGA_FLASH = 0x21,
|
||||
UBX_MGA_GAL = 0x02,
|
||||
UBX_MGA_GLO = 0x06,
|
||||
UBX_MGA_GPS = 0x00,
|
||||
UBX_MGA_INI = 0x40,
|
||||
UBX_MGA_QZSS = 0x05,
|
||||
};
|
||||
|
||||
enum ubx_monitoring_message {
|
||||
UBX_MON_BATCH = 0x32,
|
||||
UBX_MON_GNSS = 0x28,
|
||||
UBX_MON_HW2 = 0x0B,
|
||||
UBX_MON_HW = 0x09,
|
||||
UBX_MON_IO = 0x02,
|
||||
UBX_MON_MSGPP = 0x06,
|
||||
UBX_MON_PATCH = 0x27,
|
||||
UBX_MON_RXBUF = 0x07,
|
||||
UBX_MON_RXR = 0x21,
|
||||
UBX_MON_SMGR = 0x2E,
|
||||
UBX_MON_SPT = 0x2F,
|
||||
UBX_MON_TXBUF = 0x08,
|
||||
UBX_MON_VER = 0x04,
|
||||
};
|
||||
|
||||
enum ubx_nagivation_results_message {
|
||||
UBX_NAV_AOPSTATUS = 0x60,
|
||||
UBX_NAV_ATT = 0x05,
|
||||
UBX_NAV_CLOCK = 0x22,
|
||||
UBX_NAV_COV = 0x36,
|
||||
UBX_NAV_DGPS = 0x31,
|
||||
UBX_NAV_DOP = 0x04,
|
||||
UBX_NAV_EELL = 0x3d,
|
||||
UBX_NAV_EOE = 0x61,
|
||||
UBX_NAV_GEOFENCE = 0x39,
|
||||
UBX_NAV_HPPOSECEF = 0x13,
|
||||
UBX_NAV_HPPOSLLH = 0x14,
|
||||
UBX_NAV_NMI = 0x28,
|
||||
UBX_NAV_ODO = 0x09,
|
||||
UBX_NAV_ORB = 0x34,
|
||||
UBX_NAV_POSECEF = 0x01,
|
||||
UBX_NAV_POSLLH = 0x02,
|
||||
UBX_NAV_PVT = 0x07,
|
||||
UBX_NAV_RELPOSNED = 0x3C,
|
||||
UBX_NAV_RESETODO = 0x10,
|
||||
UBX_NAV_SAT = 0x35,
|
||||
UBX_NAV_SBAS = 0x32,
|
||||
UBX_NAV_SLAS = 0x42,
|
||||
UBX_NAV_SOL = 0x06,
|
||||
UBX_NAV_STATUS = 0x03,
|
||||
UBX_NAV_SVINFO = 0x30,
|
||||
UBX_NAV_SVIN = 0x3B,
|
||||
UBX_NAV_TIMEBDS = 0x24,
|
||||
UBX_NAV_TIMEGAL = 0x25,
|
||||
UBX_NAV_TIMEGLO = 0x23,
|
||||
UBX_NAV_TIMEGPS = 0x20,
|
||||
UBX_NAV_TIMELS = 0x26,
|
||||
UBX_NAV_TIMEUTC = 0x21,
|
||||
UBX_NAV_VELECEF = 0x11,
|
||||
UBX_NAV_VELNED = 0x12,
|
||||
};
|
||||
|
||||
enum ubx_receiver_manager_message {
|
||||
UBX_RXM_IMES = 0x61,
|
||||
UBX_RXM_MEASX = 0x14,
|
||||
UBX_RXM_PMREQ = 0x41,
|
||||
UBX_RXM_RAWX = 0x15,
|
||||
UBX_RXM_RLM = 0x59,
|
||||
UBX_RXM_RTCM = 0x32,
|
||||
UBX_RXM_SFRBX = 0x13,
|
||||
};
|
||||
|
||||
enum ubx_timing_message {
|
||||
UBX_TIM_DOSC = 0x11,
|
||||
UBX_TIM_FCHG = 0x16,
|
||||
UBX_TIM_HOC = 0x17,
|
||||
UBX_TIM_SMEAS = 0x13,
|
||||
UBX_TIM_SVIN = 0x04,
|
||||
UBX_TIM_TM2 = 0x03,
|
||||
UBX_TIM_TOS = 0x12,
|
||||
UBX_TIM_TP = 0x01,
|
||||
UBX_TIM_VCOCAL = 0x15,
|
||||
UBX_TIM_VRFY = 0x06,
|
||||
};
|
||||
|
||||
enum ubx_nmea_message_id {
|
||||
UBX_NMEA_DTM = 0x0A,
|
||||
UBX_NMEA_GBQ = 0x44,
|
||||
UBX_NMEA_GBS = 0x09,
|
||||
UBX_NMEA_GGA = 0x00,
|
||||
UBX_NMEA_GLL = 0x01,
|
||||
UBX_NMEA_GLQ = 0x43,
|
||||
UBX_NMEA_GNQ = 0x42,
|
||||
UBX_NMEA_GNS = 0x0D,
|
||||
UBX_NMEA_GPQ = 0x40,
|
||||
UBX_NMEA_GRS = 0x06,
|
||||
UBX_NMEA_GSA = 0x02,
|
||||
UBX_NMEA_GST = 0x07,
|
||||
UBX_NMEA_GSV = 0x03,
|
||||
UBX_NMEA_RMC = 0x04,
|
||||
UBX_NMEA_THS = 0x0E,
|
||||
UBX_NMEA_TXT = 0x41,
|
||||
UBX_NMEA_VLW = 0x0F,
|
||||
UBX_NMEA_VTG = 0x05,
|
||||
UBX_NMEA_ZDA = 0x08,
|
||||
};
|
||||
|
||||
#endif /* ZEPHYR_U_BLOX_PROTOCOL_DEFINES_ */
|
17
dts/bindings/gnss/u-blox,m10.yaml
Normal file
17
dts/bindings/gnss/u-blox,m10.yaml
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright 2024 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: U-BLOX M10 GNSS Module
|
||||
|
||||
compatible: "u-blox,m10"
|
||||
|
||||
include:
|
||||
- uart-device.yaml
|
||||
|
||||
properties:
|
||||
uart-baudrate:
|
||||
type: int
|
||||
description: |
|
||||
Baudrate for communication on the UART port.
|
||||
default: 115200
|
||||
enum: [4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600]
|
23
include/zephyr/dt-bindings/gnss/u_blox_m10.h
Normal file
23
include/zephyr/dt-bindings/gnss/u_blox_m10.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_U_BLOX_M10_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_U_BLOX_M10_H_
|
||||
|
||||
#include <zephyr/dt-bindings/dt-util.h>
|
||||
|
||||
/* UART Baudrate. */
|
||||
#define UBX_M10_UART_BAUDRATE_4800 0x00
|
||||
#define UBX_M10_UART_BAUDRATE_9600 0x01
|
||||
#define UBX_M10_UART_BAUDRATE_19200 0x02
|
||||
#define UBX_M10_UART_BAUDRATE_38400 0x03
|
||||
#define UBX_M10_UART_BAUDRATE_57600 0x04
|
||||
#define UBX_M10_UART_BAUDRATE_115200 0x05
|
||||
#define UBX_M10_UART_BAUDRATE_230400 0x06
|
||||
#define UBX_M10_UART_BAUDRATE_460800 0x07
|
||||
#define UBX_M10_UART_BAUDRATE_921600 0x08
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_U_BLOX_M10_H_ */
|
175
include/zephyr/modem/ubx.h
Normal file
175
include/zephyr/modem/ubx.h
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/types.h>
|
||||
#include <zephyr/sys/atomic.h>
|
||||
|
||||
#include <zephyr/modem/pipe.h>
|
||||
|
||||
#ifndef ZEPHYR_MODEM_UBX_
|
||||
#define ZEPHYR_MODEM_UBX_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Modem Ubx
|
||||
* @defgroup modem_ubx Modem Ubx
|
||||
* @ingroup modem
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define UBX_FRM_HEADER_SZ 6
|
||||
#define UBX_FRM_FOOTER_SZ 2
|
||||
#define UBX_FRM_SZ_WITHOUT_PAYLOAD (UBX_FRM_HEADER_SZ + UBX_FRM_FOOTER_SZ)
|
||||
#define UBX_FRM_SZ(payload_size) (payload_size + UBX_FRM_SZ_WITHOUT_PAYLOAD)
|
||||
|
||||
#define UBX_PREAMBLE_SYNC_CHAR_1 0xB5
|
||||
#define UBX_PREAMBLE_SYNC_CHAR_2 0x62
|
||||
|
||||
#define UBX_FRM_PREAMBLE_SYNC_CHAR_1_IDX 0
|
||||
#define UBX_FRM_PREAMBLE_SYNC_CHAR_2_IDX 1
|
||||
#define UBX_FRM_MSG_CLASS_IDX 2
|
||||
#define UBX_FRM_MSG_ID_IDX 3
|
||||
#define UBX_FRM_PAYLOAD_SZ_L_IDX 4
|
||||
#define UBX_FRM_PAYLOAD_SZ_H_IDX 5
|
||||
#define UBX_FRM_PAYLOAD_IDX 6
|
||||
#define UBX_FRM_CHECKSUM_START_IDX 2
|
||||
#define UBX_FRM_CHECKSUM_STOP_IDX(frame_len) (frame_len - 2)
|
||||
|
||||
#define UBX_PAYLOAD_SZ_MAX 256
|
||||
#define UBX_FRM_SZ_MAX UBX_FRM_SZ(UBX_PAYLOAD_SZ_MAX)
|
||||
|
||||
struct ubx_frame {
|
||||
uint8_t preamble_sync_char_1;
|
||||
uint8_t preamble_sync_char_2;
|
||||
uint8_t message_class;
|
||||
uint8_t message_id;
|
||||
uint8_t payload_size_low;
|
||||
uint8_t payload_size_high;
|
||||
uint8_t payload_and_checksum[];
|
||||
};
|
||||
|
||||
struct modem_ubx_script {
|
||||
struct ubx_frame *request;
|
||||
struct ubx_frame *response;
|
||||
struct ubx_frame *match;
|
||||
|
||||
uint16_t retry_count;
|
||||
k_timeout_t timeout;
|
||||
};
|
||||
|
||||
struct modem_ubx {
|
||||
void *user_data;
|
||||
|
||||
atomic_t state;
|
||||
|
||||
uint8_t *receive_buf;
|
||||
uint16_t receive_buf_size;
|
||||
|
||||
uint8_t *work_buf;
|
||||
uint16_t work_buf_size;
|
||||
uint16_t work_buf_len;
|
||||
bool ubx_preamble_sync_chars_received;
|
||||
|
||||
const struct modem_ubx_script *script;
|
||||
|
||||
struct modem_pipe *pipe;
|
||||
|
||||
struct k_work send_work;
|
||||
struct k_work process_work;
|
||||
struct k_sem script_stopped_sem;
|
||||
struct k_sem script_running_sem;
|
||||
};
|
||||
|
||||
struct modem_ubx_config {
|
||||
void *user_data;
|
||||
|
||||
uint8_t *receive_buf;
|
||||
uint16_t receive_buf_size;
|
||||
uint8_t *work_buf;
|
||||
uint16_t work_buf_size;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Attach pipe to Modem Ubx
|
||||
*
|
||||
* @param ubx Modem Ubx instance
|
||||
* @param pipe Pipe instance to attach Modem Ubx instance to
|
||||
* @returns 0 if successful
|
||||
* @returns negative errno code if failure
|
||||
* @note Modem Ubx instance is enabled if successful
|
||||
*/
|
||||
int modem_ubx_attach(struct modem_ubx *ubx, struct modem_pipe *pipe);
|
||||
|
||||
/**
|
||||
* @brief Release pipe from Modem Ubx instance
|
||||
*
|
||||
* @param ubx Modem Ubx instance
|
||||
*/
|
||||
void modem_ubx_release(struct modem_ubx *ubx);
|
||||
|
||||
/**
|
||||
* @brief Initialize Modem Ubx instance
|
||||
* @param ubx Modem Ubx instance
|
||||
* @param config Configuration which shall be applied to the Modem Ubx instance
|
||||
* @note Modem Ubx instance must be attached to a pipe instance
|
||||
*/
|
||||
int modem_ubx_init(struct modem_ubx *ubx, const struct modem_ubx_config *config);
|
||||
|
||||
/**
|
||||
* @brief Writes the ubx frame in script.request and reads back its response (if available)
|
||||
* @details For each ubx frame sent, the device responds in 0, 1 or both of the following ways:
|
||||
* 1. The device sends back a UBX-ACK frame to denote 'acknowledge' and 'not-acknowledge'.
|
||||
* Note: the message id of UBX-ACK frame determines whether the device acknowledged.
|
||||
* Ex: when we send a UBX-CFG frame, the device responds with a UBX-ACK frame.
|
||||
* 2. The device sends back the same frame that we sent to it, with it's payload populated.
|
||||
* It's used to get the current configuration corresponding to the frame that we sent.
|
||||
* Ex: frame types such as "get" or "poll" ubx frames respond this way.
|
||||
* This response (if received) is written to script.response.
|
||||
*
|
||||
* This function writes the ubx frame in script.request then reads back it's response.
|
||||
* If script.match is not NULL, then every ubx frame received from the device is compared with
|
||||
* script.match to check if a match occurred. This could be used to match UBX-ACK frame sent
|
||||
* from the device by populating script.match with UBX-ACK that the script expects to receive.
|
||||
*
|
||||
* The script terminates when either of the following happens:
|
||||
* 1. script.match is successfully received and matched.
|
||||
* 2. timeout (denoted by script.timeout) occurs.
|
||||
* @param ubx Modem Ubx instance
|
||||
* @param script Script to be executed
|
||||
* @note The length of ubx frame in the script.request should not exceed UBX_FRM_SZ_MAX
|
||||
* @note Modem Ubx instance must be attached to a pipe instance
|
||||
* @returns 0 if device acknowledged via UBX-ACK and no "get" response was received
|
||||
* @returns positive integer denoting the length of "get" response that was received
|
||||
* @returns negative errno code if failure
|
||||
*/
|
||||
int modem_ubx_run_script(struct modem_ubx *ubx, const struct modem_ubx_script *script);
|
||||
|
||||
/**
|
||||
* @brief Initialize ubx frame
|
||||
* @param ubx_frame Ubx frame buffer
|
||||
* @param ubx_frame_size Ubx frame buffer size
|
||||
* @param msg_cls Message class
|
||||
* @param msg_id Message id
|
||||
* @param payload Payload buffer
|
||||
* @param payload_size Payload buffer size
|
||||
* @returns positive integer denoting the length of the ubx frame created
|
||||
* @returns negative errno code if failure
|
||||
*/
|
||||
int modem_ubx_create_frame(uint8_t *ubx_frame, uint16_t ubx_frame_size, uint8_t msg_cls,
|
||||
uint8_t msg_id, const void *payload, uint16_t payload_size);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_MODEM_UBX_ */
|
4
samples/drivers/gnss/boards/mimxrt1062_fmurt6.conf
Normal file
4
samples/drivers/gnss/boards/mimxrt1062_fmurt6.conf
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Copyright 2024 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
25
samples/drivers/gnss/boards/mimxrt1062_fmurt6.overlay
Normal file
25
samples/drivers/gnss/boards/mimxrt1062_fmurt6.overlay
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
gnss = &lpuart2;
|
||||
};
|
||||
};
|
||||
|
||||
&lpuart2 {
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
pinctrl-0 = <&pinmux_lpuart2>;
|
||||
pinctrl-1 = <&pinmux_lpuart2_sleep>;
|
||||
pinctrl-names = "default", "sleep";
|
||||
|
||||
u_blox_m10: u-blox,m10 {
|
||||
status = "okay";
|
||||
compatible = "u-blox,m10";
|
||||
uart-baudrate = <115200>;
|
||||
};
|
||||
};
|
22
samples/drivers/gnss/boards/vmu_rt1170.overlay
Normal file
22
samples/drivers/gnss/boards/vmu_rt1170.overlay
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
aliases {
|
||||
gnss = &lpuart3;
|
||||
};
|
||||
};
|
||||
|
||||
&lpuart3 {
|
||||
status = "okay";
|
||||
current-speed = <115200>;
|
||||
|
||||
u_blox_m10: u-blox,m10 {
|
||||
status = "okay";
|
||||
compatible = "u-blox,m10";
|
||||
uart-baudrate = <115200>;
|
||||
};
|
||||
};
|
|
@ -9,6 +9,7 @@ zephyr_library_sources_ifdef(CONFIG_MODEM_CHAT modem_chat.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_MODEM_CMUX modem_cmux.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MODEM_PIPE modem_pipe.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MODEM_PPP modem_ppp.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_MODEM_UBX modem_ubx.c)
|
||||
|
||||
add_subdirectory(backends)
|
||||
|
||||
|
|
|
@ -54,6 +54,21 @@ config MODEM_PPP_NET_BUF_FRAG_SIZE
|
|||
|
||||
endif
|
||||
|
||||
config MODEM_UBX
|
||||
bool "Modem U-BLOX module"
|
||||
select RING_BUFFER
|
||||
select MODEM_PIPE
|
||||
help
|
||||
Enable Modem U-BLOX module.
|
||||
|
||||
if MODEM_UBX
|
||||
|
||||
config MODEM_UBX_LOG_BUFFER
|
||||
int "Modem U-BLOX log buffer size"
|
||||
default 128
|
||||
|
||||
endif
|
||||
|
||||
module = MODEM_MODULES
|
||||
module-str = modem_modules
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
|
338
subsys/modem/modem_ubx.c
Normal file
338
subsys/modem/modem_ubx.c
Normal file
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* Copyright 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/modem/ubx.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(modem_ubx, CONFIG_MODEM_MODULES_LOG_LEVEL);
|
||||
|
||||
#define MODEM_UBX_STATE_ATTACHED_BIT 0
|
||||
|
||||
static int modem_ubx_validate_frame_size(uint16_t ubx_frame_size, uint8_t msg_cls, uint8_t msg_id,
|
||||
uint16_t payload_size)
|
||||
{
|
||||
if (ubx_frame_size > UBX_FRM_SZ_MAX ||
|
||||
ubx_frame_size < UBX_FRM_SZ_WITHOUT_PAYLOAD ||
|
||||
ubx_frame_size < UBX_FRM_SZ_WITHOUT_PAYLOAD + payload_size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int modem_ubx_create_frame(uint8_t *ubx_frame, uint16_t ubx_frame_size, uint8_t msg_cls,
|
||||
uint8_t msg_id, const void *payload, uint16_t payload_size)
|
||||
{
|
||||
if (modem_ubx_validate_frame_size(ubx_frame_size, msg_cls, msg_id, payload_size)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct ubx_frame *frame = (struct ubx_frame *) ubx_frame;
|
||||
|
||||
frame->preamble_sync_char_1 = UBX_PREAMBLE_SYNC_CHAR_1;
|
||||
frame->preamble_sync_char_2 = UBX_PREAMBLE_SYNC_CHAR_2;
|
||||
frame->message_class = msg_cls;
|
||||
frame->message_id = msg_id;
|
||||
frame->payload_size_low = payload_size;
|
||||
frame->payload_size_high = payload_size >> 8;
|
||||
|
||||
memcpy(frame->payload_and_checksum, payload, payload_size);
|
||||
|
||||
uint16_t ubx_frame_len = payload_size + UBX_FRM_SZ_WITHOUT_PAYLOAD;
|
||||
|
||||
uint8_t ckA = 0, ckB = 0;
|
||||
|
||||
for (unsigned int i = UBX_FRM_CHECKSUM_START_IDX;
|
||||
i < (UBX_FRM_CHECKSUM_STOP_IDX(ubx_frame_len)); i++) {
|
||||
ckA += ubx_frame[i];
|
||||
ckB += ckA;
|
||||
}
|
||||
|
||||
frame->payload_and_checksum[payload_size] = ckA;
|
||||
frame->payload_and_checksum[payload_size + 1] = ckB;
|
||||
|
||||
return ubx_frame_len;
|
||||
}
|
||||
|
||||
static void modem_ubx_reset_received_ubx_preamble_sync_chars(struct modem_ubx *ubx)
|
||||
{
|
||||
ubx->ubx_preamble_sync_chars_received = false;
|
||||
}
|
||||
|
||||
static void modem_ubx_reset_parser(struct modem_ubx *ubx)
|
||||
{
|
||||
modem_ubx_reset_received_ubx_preamble_sync_chars(ubx);
|
||||
}
|
||||
|
||||
static int modem_ubx_get_payload_length(struct ubx_frame *frame)
|
||||
{
|
||||
uint16_t payload_len = frame->payload_size_high;
|
||||
|
||||
payload_len = payload_len << 8;
|
||||
|
||||
return payload_len | frame->payload_size_low;
|
||||
}
|
||||
|
||||
static int modem_ubx_get_frame_length(struct ubx_frame *frame)
|
||||
{
|
||||
return modem_ubx_get_payload_length(frame) + UBX_FRM_SZ_WITHOUT_PAYLOAD;
|
||||
}
|
||||
|
||||
static bool modem_ubx_match_frame_type(struct ubx_frame *frame_1, struct ubx_frame *frame_2)
|
||||
{
|
||||
if (frame_1->message_class == frame_2->message_class
|
||||
&& frame_1->message_id == frame_2->message_id) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool modem_ubx_match_frame_full(struct ubx_frame *frame_1, struct ubx_frame *frame_2)
|
||||
{
|
||||
if (modem_ubx_get_frame_length(frame_1) != modem_ubx_get_frame_length(frame_2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (memcmp(frame_1, frame_2, modem_ubx_get_frame_length(frame_1)) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void modem_ubx_script_init(struct modem_ubx *ubx, const struct modem_ubx_script *script)
|
||||
{
|
||||
ubx->script = script;
|
||||
}
|
||||
|
||||
static int modem_ubx_run_script_helper(struct modem_ubx *ubx, const struct modem_ubx_script *script)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ubx->pipe == NULL) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
k_sem_reset(&ubx->script_stopped_sem);
|
||||
|
||||
modem_ubx_reset_parser(ubx);
|
||||
|
||||
k_work_submit(&ubx->send_work);
|
||||
|
||||
if (ubx->script->match == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = k_sem_take(&ubx->script_stopped_sem, script->timeout);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int modem_ubx_run_script(struct modem_ubx *ubx, const struct modem_ubx_script *script)
|
||||
{
|
||||
int ret, attempt;
|
||||
|
||||
if (modem_ubx_get_frame_length(script->request) > UBX_FRM_SZ_MAX) {
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
if (atomic_test_bit(&ubx->state, MODEM_UBX_STATE_ATTACHED_BIT) == false) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
ret = k_sem_take(&ubx->script_running_sem, K_FOREVER);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
modem_ubx_script_init(ubx, script);
|
||||
|
||||
for (attempt = 0; attempt < script->retry_count; ++attempt) {
|
||||
ret = modem_ubx_run_script_helper(ubx, script);
|
||||
if (ret > -1) {
|
||||
LOG_INF("Successfully executed script on attempt: %d.", attempt);
|
||||
break;
|
||||
} else if (ret == -EPERM) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
LOG_ERR("Failed to execute script successfully. Attempts: %d.", attempt);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
unlock:
|
||||
k_sem_give(&ubx->script_running_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void modem_ubx_pipe_callback(struct modem_pipe *pipe, enum modem_pipe_event event,
|
||||
void *user_data)
|
||||
{
|
||||
struct modem_ubx *ubx = (struct modem_ubx *)user_data;
|
||||
|
||||
if (event == MODEM_PIPE_EVENT_RECEIVE_READY) {
|
||||
k_work_submit(&ubx->process_work);
|
||||
}
|
||||
}
|
||||
|
||||
static void modem_ubx_send_handler(struct k_work *item)
|
||||
{
|
||||
struct modem_ubx *ubx = CONTAINER_OF(item, struct modem_ubx, send_work);
|
||||
int ret, tx_frame_len;
|
||||
|
||||
tx_frame_len = modem_ubx_get_frame_length(ubx->script->request);
|
||||
ret = modem_pipe_transmit(ubx->pipe, (const uint8_t *) ubx->script->request, tx_frame_len);
|
||||
if (ret < tx_frame_len) {
|
||||
LOG_ERR("Ubx frame transmission failed. Returned %d.", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int modem_ubx_process_received_ubx_frame(struct modem_ubx *ubx)
|
||||
{
|
||||
int ret;
|
||||
struct ubx_frame *received = (struct ubx_frame *) ubx->work_buf;
|
||||
|
||||
if (modem_ubx_match_frame_full(received, ubx->script->match) == true) {
|
||||
/* Frame matched successfully. Terminate the script. */
|
||||
k_sem_give(&ubx->script_stopped_sem);
|
||||
ret = 0;
|
||||
} else if (modem_ubx_match_frame_type(received, ubx->script->request) == true) {
|
||||
/* Response received successfully. Script not ended. */
|
||||
memcpy(ubx->script->response, ubx->work_buf, ubx->work_buf_len);
|
||||
ret = -1;
|
||||
} else {
|
||||
/* Ignore the received frame. The device may automatically send periodic frames.
|
||||
* These frames are not relevant for our script's execution and must be ignored.
|
||||
*/
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
modem_ubx_reset_parser(ubx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int modem_ubx_process_received_byte(struct modem_ubx *ubx, uint8_t byte)
|
||||
{
|
||||
static uint8_t prev_byte;
|
||||
static uint16_t rx_ubx_frame_len;
|
||||
|
||||
if (ubx->ubx_preamble_sync_chars_received == false) {
|
||||
if (prev_byte == UBX_PREAMBLE_SYNC_CHAR_1 && byte == UBX_PREAMBLE_SYNC_CHAR_2) {
|
||||
ubx->ubx_preamble_sync_chars_received = true;
|
||||
ubx->work_buf[0] = UBX_PREAMBLE_SYNC_CHAR_1;
|
||||
ubx->work_buf[1] = UBX_PREAMBLE_SYNC_CHAR_2;
|
||||
ubx->work_buf_len = 2;
|
||||
}
|
||||
} else {
|
||||
ubx->work_buf[ubx->work_buf_len] = byte;
|
||||
++ubx->work_buf_len;
|
||||
|
||||
if (ubx->work_buf_len == UBX_FRM_HEADER_SZ) {
|
||||
uint16_t rx_ubx_payload_len = ubx->work_buf[UBX_FRM_PAYLOAD_SZ_H_IDX];
|
||||
|
||||
rx_ubx_payload_len = ubx->work_buf[UBX_FRM_PAYLOAD_SZ_H_IDX] << 8;
|
||||
rx_ubx_payload_len |= ubx->work_buf[UBX_FRM_PAYLOAD_SZ_L_IDX];
|
||||
|
||||
rx_ubx_frame_len = rx_ubx_payload_len + UBX_FRM_SZ_WITHOUT_PAYLOAD;
|
||||
}
|
||||
|
||||
if (ubx->work_buf_len == rx_ubx_frame_len) {
|
||||
return modem_ubx_process_received_ubx_frame(ubx);
|
||||
}
|
||||
}
|
||||
|
||||
prev_byte = byte;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void modem_ubx_process_handler(struct k_work *item)
|
||||
{
|
||||
struct modem_ubx *ubx = CONTAINER_OF(item, struct modem_ubx, process_work);
|
||||
int ret;
|
||||
|
||||
ret = modem_pipe_receive(ubx->pipe, ubx->receive_buf, ubx->receive_buf_size);
|
||||
if (ret < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ret; i++) {
|
||||
ret = modem_ubx_process_received_byte(ubx, ubx->receive_buf[i]);
|
||||
if (ret == 0) { /* Frame matched successfully. Terminate the script. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k_work_submit(&ubx->process_work);
|
||||
}
|
||||
|
||||
int modem_ubx_attach(struct modem_ubx *ubx, struct modem_pipe *pipe)
|
||||
{
|
||||
if (atomic_test_and_set_bit(&ubx->state, MODEM_UBX_STATE_ATTACHED_BIT) == true) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ubx->pipe = pipe;
|
||||
modem_pipe_attach(ubx->pipe, modem_ubx_pipe_callback, ubx);
|
||||
k_sem_give(&ubx->script_running_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void modem_ubx_release(struct modem_ubx *ubx)
|
||||
{
|
||||
struct k_work_sync sync;
|
||||
|
||||
if (atomic_test_and_clear_bit(&ubx->state, MODEM_UBX_STATE_ATTACHED_BIT) == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
modem_pipe_release(ubx->pipe);
|
||||
k_work_cancel_sync(&ubx->send_work, &sync);
|
||||
k_work_cancel_sync(&ubx->process_work, &sync);
|
||||
k_sem_reset(&ubx->script_stopped_sem);
|
||||
k_sem_reset(&ubx->script_running_sem);
|
||||
ubx->work_buf_len = 0;
|
||||
modem_ubx_reset_parser(ubx);
|
||||
ubx->pipe = NULL;
|
||||
}
|
||||
|
||||
int modem_ubx_init(struct modem_ubx *ubx, const struct modem_ubx_config *config)
|
||||
{
|
||||
__ASSERT_NO_MSG(ubx != NULL);
|
||||
__ASSERT_NO_MSG(config != NULL);
|
||||
__ASSERT_NO_MSG(config->receive_buf != NULL);
|
||||
__ASSERT_NO_MSG(config->receive_buf_size > 0);
|
||||
__ASSERT_NO_MSG(config->work_buf != NULL);
|
||||
__ASSERT_NO_MSG(config->work_buf_size > 0);
|
||||
|
||||
memset(ubx, 0x00, sizeof(*ubx));
|
||||
ubx->user_data = config->user_data;
|
||||
|
||||
ubx->receive_buf = config->receive_buf;
|
||||
ubx->receive_buf_size = config->receive_buf_size;
|
||||
ubx->work_buf = config->work_buf;
|
||||
ubx->work_buf_size = config->work_buf_size;
|
||||
|
||||
ubx->pipe = NULL;
|
||||
|
||||
k_work_init(&ubx->send_work, modem_ubx_send_handler);
|
||||
k_work_init(&ubx->process_work, modem_ubx_process_handler);
|
||||
k_sem_init(&ubx->script_stopped_sem, 0, 1);
|
||||
k_sem_init(&ubx->script_running_sem, 1, 1);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue