diff --git a/src/ubx.cpp b/src/ubx.cpp index 8bbd26b..129f6b4 100644 --- a/src/ubx.cpp +++ b/src/ubx.cpp @@ -93,6 +93,7 @@ GPSDriverUBX::configure(unsigned &baudrate, OutputMode output_mode, GNSSSystemsM { _configured = false; _output_mode = output_mode; + _gnssSystems = gnssSystems; ubx_payload_tx_cfg_prt_t cfg_prt[2]; @@ -380,6 +381,80 @@ int GPSDriverUBX::configureDevicePreV27() return -1; } + /* configure active GNSS systems (number of channels and used signals taken from U-Center default) */ + if (static_cast(_gnssSystems) != 0) { + memset(&_buf.payload_tx_cfg_gnss, 0, sizeof(_buf.payload_tx_cfg_gnss)); + _buf.payload_tx_cfg_gnss.msgVer = 0x00; + _buf.payload_tx_cfg_gnss.numTrkChHw = 0x00; // read only + _buf.payload_tx_cfg_gnss.numTrkChUse = 0xFF; // use max number of HW channels + _buf.payload_tx_cfg_gnss.numConfigBlocks = 7; // always configure all systems + + // GPS and QZSS should always be enabled and disabled together, according to uBlox + _buf.payload_tx_cfg_gnss.block[0].gnssId = UBX_TX_CFG_GNSS_GNSSID_GPS; + _buf.payload_tx_cfg_gnss.block[1].gnssId = UBX_TX_CFG_GNSS_GNSSID_QZSS; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_GPS) { + UBX_DEBUG("GNSS Systems: Use GPS + QZSS"); + _buf.payload_tx_cfg_gnss.block[0].resTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[0].maxTrkCh = 16; + _buf.payload_tx_cfg_gnss.block[0].flags = UBX_TX_CFG_GNSS_FLAGS_GPS_L1CA | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + _buf.payload_tx_cfg_gnss.block[1].resTrkCh = 0; + _buf.payload_tx_cfg_gnss.block[1].maxTrkCh = 3; + _buf.payload_tx_cfg_gnss.block[1].flags = UBX_TX_CFG_GNSS_FLAGS_QZSS_L1CA | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[2].gnssId = UBX_TX_CFG_GNSS_GNSSID_SBAS; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_SBAS) { + UBX_DEBUG("GNSS Systems: Use SBAS"); + _buf.payload_tx_cfg_gnss.block[2].resTrkCh = 1; + _buf.payload_tx_cfg_gnss.block[2].maxTrkCh = 3; + _buf.payload_tx_cfg_gnss.block[2].flags = UBX_TX_CFG_GNSS_FLAGS_SBAS_L1CA | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[3].gnssId = UBX_TX_CFG_GNSS_GNSSID_GALILEO; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_GALILEO) { + UBX_DEBUG("GNSS Systems: Use Galileo"); + _buf.payload_tx_cfg_gnss.block[3].resTrkCh = 4; + _buf.payload_tx_cfg_gnss.block[3].maxTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[3].flags = UBX_TX_CFG_GNSS_FLAGS_GALILEO_E1 | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[4].gnssId = UBX_TX_CFG_GNSS_GNSSID_BEIDOU; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_BEIDOU) { + UBX_DEBUG("GNSS Systems: Use BeiDou"); + _buf.payload_tx_cfg_gnss.block[4].resTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[4].maxTrkCh = 16; + _buf.payload_tx_cfg_gnss.block[4].flags = UBX_TX_CFG_GNSS_FLAGS_BEIDOU_B1I | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[5].gnssId = UBX_TX_CFG_GNSS_GNSSID_GLONASS; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_GLONASS) { + UBX_DEBUG("GNSS Systems: Use GLONASS"); + _buf.payload_tx_cfg_gnss.block[5].resTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[5].maxTrkCh = 14; + _buf.payload_tx_cfg_gnss.block[5].flags = UBX_TX_CFG_GNSS_FLAGS_GLONASS_L1 | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + // IMES always disabled + _buf.payload_tx_cfg_gnss.block[6].gnssId = UBX_TX_CFG_GNSS_GNSSID_IMES; + _buf.payload_tx_cfg_gnss.block[6].flags = 0; + + // send message + if (!sendMessage(UBX_MSG_CFG_GNSS, (uint8_t *)&_buf, sizeof(_buf.payload_tx_cfg_gnss))) { + GPS_ERR("UBX CFG-GNSS message send failed"); + return -1; + } + + if (waitForAck(UBX_MSG_CFG_GNSS, UBX_CONFIG_TIMEOUT, true) < 0) { + GPS_ERR("UBX CFG-GNSS message ACK failed"); + return -1; + } + } + /* configure message rates */ /* the last argument is divisor for measurement rate (set by CFG RATE), i.e. 1 means 5Hz */ @@ -472,6 +547,80 @@ int GPSDriverUBX::configureDevice() waitForAck(UBX_MSG_CFG_VALSET, UBX_CONFIG_TIMEOUT, false); + // configure active GNSS systems (number of channels and used signals taken from U-Center default) + if (static_cast(_gnssSystems) != 0) { + memset(&_buf.payload_tx_cfg_gnss, 0, sizeof(_buf.payload_tx_cfg_gnss)); + _buf.payload_tx_cfg_gnss.msgVer = 0x00; + _buf.payload_tx_cfg_gnss.numTrkChHw = 0x00; // read only + _buf.payload_tx_cfg_gnss.numTrkChUse = 0xFF; // use max number of HW channels + _buf.payload_tx_cfg_gnss.numConfigBlocks = 7; // always configure all systems + + // GPS and QZSS should always be enabled and disabled together, according to uBlox + _buf.payload_tx_cfg_gnss.block[0].gnssId = UBX_TX_CFG_GNSS_GNSSID_GPS; + _buf.payload_tx_cfg_gnss.block[1].gnssId = UBX_TX_CFG_GNSS_GNSSID_QZSS; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_GPS) { + UBX_DEBUG("GNSS Systems: Use GPS + QZSS"); + _buf.payload_tx_cfg_gnss.block[0].resTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[0].maxTrkCh = 16; + _buf.payload_tx_cfg_gnss.block[0].flags = UBX_TX_CFG_GNSS_FLAGS_GPS_L1CA | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + _buf.payload_tx_cfg_gnss.block[1].resTrkCh = 0; + _buf.payload_tx_cfg_gnss.block[1].maxTrkCh = 3; + _buf.payload_tx_cfg_gnss.block[1].flags = UBX_TX_CFG_GNSS_FLAGS_QZSS_L1CA | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[2].gnssId = UBX_TX_CFG_GNSS_GNSSID_SBAS; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_SBAS) { + UBX_DEBUG("GNSS Systems: Use SBAS"); + _buf.payload_tx_cfg_gnss.block[2].resTrkCh = 1; + _buf.payload_tx_cfg_gnss.block[2].maxTrkCh = 3; + _buf.payload_tx_cfg_gnss.block[2].flags = UBX_TX_CFG_GNSS_FLAGS_SBAS_L1CA | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[3].gnssId = UBX_TX_CFG_GNSS_GNSSID_GALILEO; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_GALILEO) { + UBX_DEBUG("GNSS Systems: Use Galileo"); + _buf.payload_tx_cfg_gnss.block[3].resTrkCh = 4; + _buf.payload_tx_cfg_gnss.block[3].maxTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[3].flags = UBX_TX_CFG_GNSS_FLAGS_GALILEO_E1 | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[4].gnssId = UBX_TX_CFG_GNSS_GNSSID_BEIDOU; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_BEIDOU) { + UBX_DEBUG("GNSS Systems: Use BeiDou"); + _buf.payload_tx_cfg_gnss.block[4].resTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[4].maxTrkCh = 16; + _buf.payload_tx_cfg_gnss.block[4].flags = UBX_TX_CFG_GNSS_FLAGS_BEIDOU_B1I | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + _buf.payload_tx_cfg_gnss.block[5].gnssId = UBX_TX_CFG_GNSS_GNSSID_GLONASS; + + if (_gnssSystems & GNSSSystemsMask::ENABLE_GLONASS) { + UBX_DEBUG("GNSS Systems: Use GLONASS"); + _buf.payload_tx_cfg_gnss.block[5].resTrkCh = 8; + _buf.payload_tx_cfg_gnss.block[5].maxTrkCh = 14; + _buf.payload_tx_cfg_gnss.block[5].flags = UBX_TX_CFG_GNSS_FLAGS_GLONASS_L1 | UBX_TX_CFG_GNSS_FLAGS_ENABLE; + } + + // IMES always disabled + _buf.payload_tx_cfg_gnss.block[6].gnssId = UBX_TX_CFG_GNSS_GNSSID_IMES; + _buf.payload_tx_cfg_gnss.block[6].flags = 0; + + // send message + if (!sendMessage(UBX_MSG_CFG_GNSS, (uint8_t *)&_buf, sizeof(_buf.payload_tx_cfg_gnss))) { + GPS_ERR("UBX CFG-GNSS message send failed"); + return -1; + } + + if (waitForAck(UBX_MSG_CFG_GNSS, UBX_CONFIG_TIMEOUT, true) < 0) { + GPS_ERR("UBX CFG-GNSS message ACK failed"); + return -1; + } + } + // Configure message rates // Send a new CFG-VALSET message to make sure it does not get too large cfg_valset_msg_size = initCfgValset(); diff --git a/src/ubx.h b/src/ubx.h index 160ea0f..74120cc 100644 --- a/src/ubx.h +++ b/src/ubx.h @@ -101,6 +101,7 @@ #define UBX_ID_CFG_RST 0x04 #define UBX_ID_CFG_SBAS 0x16 #define UBX_ID_CFG_TMODE3 0x71 // deprecated in protocol version >= 27 -> use CFG_VALSET +#define UBX_ID_CFG_GNSS 0x3E #define UBX_ID_CFG_VALSET 0x8A #define UBX_ID_CFG_VALGET 0x8B #define UBX_ID_CFG_VALDEL 0x8C @@ -151,6 +152,7 @@ #define UBX_MSG_CFG_RST ((UBX_CLASS_CFG) | UBX_ID_CFG_RST << 8) #define UBX_MSG_CFG_SBAS ((UBX_CLASS_CFG) | UBX_ID_CFG_SBAS << 8) #define UBX_MSG_CFG_TMODE3 ((UBX_CLASS_CFG) | UBX_ID_CFG_TMODE3 << 8) +#define UBX_MSG_CFG_GNSS ((UBX_CLASS_CFG) | UBX_ID_CFG_GNSS << 8) #define UBX_MSG_CFG_VALGET ((UBX_CLASS_CFG) | UBX_ID_CFG_VALGET << 8) #define UBX_MSG_CFG_VALSET ((UBX_CLASS_CFG) | UBX_ID_CFG_VALSET << 8) #define UBX_MSG_CFG_VALDEL ((UBX_CLASS_CFG) | UBX_ID_CFG_VALDEL << 8) @@ -226,6 +228,34 @@ #define UBX_TX_CFG_RST_MODE_HARDWARE 0 #define UBX_TX_CFG_RST_MODE_SOFTWARE 1 +/* TX CFG-GNSS message contents + */ +#define UBX_TX_CFG_GNSS_GNSSID_GPS 0 /**< gnssId of GPS */ +#define UBX_TX_CFG_GNSS_GNSSID_SBAS 1 /**< gnssId of SBAS */ +#define UBX_TX_CFG_GNSS_GNSSID_GALILEO 2 /**< gnssId of Galileo */ +#define UBX_TX_CFG_GNSS_GNSSID_BEIDOU 3 /**< gnssId of BeiDou */ +#define UBX_TX_CFG_GNSS_GNSSID_IMES 4 /**< gnssId of IMES */ +#define UBX_TX_CFG_GNSS_GNSSID_QZSS 5 /**< gnssId of QZSS */ +#define UBX_TX_CFG_GNSS_GNSSID_GLONASS 6 /**< gnssId of GLONASS */ +#define UBX_TX_CFG_GNSS_FLAGS_ENABLE 0x00000001 /**< Enable this GNSS system */ +#define UBX_TX_CFG_GNSS_FLAGS_GPS_L1CA 0x00010000 /**< GPS: Use L1C/A Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_GPS_L2C 0x00100000 /**< GPS: Use L2C Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_GPS_L5 0x00200000 /**< GPS: Use L5 Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_SBAS_L1CA 0x00010000 /**< SBAS: Use L1C/A Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_GALILEO_E1 0x00010000 /**< Galileo: Use E1 Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_GALILEO_E5A 0x00100000 /**< Galileo: Use E5a Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_GALILEO_E5B 0x00200000 /**< Galileo: Use E5b Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_BEIDOU_B1I 0x00010000 /**< BeiDou: Use B1I Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_BEIDOU_B2I 0x00100000 /**< BeiDou: Use B2I Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_BEIDOU_B2A 0x00800000 /**< BeiDou: Use B2A Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_IMES_L1 0x00010000 /**< IMES: Use L1 Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_QZSS_L1CA 0x00010000 /**< QZSS: Use L1C/A Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_QZSS_L1S 0x00040000 /**< QZSS: Use L1S Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_QZSS_L2C 0x00100000 /**< QZSS: Use L2C Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_QZSS_L5 0x00200000 /**< QZSS: Use L5 Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_GLONASS_L1 0x00010000 /**< GLONASS: Use L1 Signal */ +#define UBX_TX_CFG_GNSS_FLAGS_GLONASS_L2 0x00100000 /**< GLONASS: Use L2 Signal */ + /* Key ID's for CFG-VAL{GET,SET,DEL} */ #define UBX_CFG_KEY_CFG_UART1_BAUDRATE 0x40520001 #define UBX_CFG_KEY_CFG_UART1_STOPBITS 0x20520002 @@ -718,6 +748,23 @@ typedef struct { uint8_t reserved3[8]; } ubx_payload_tx_cfg_tmode3_t; +typedef struct { + uint8_t msgVer; /**< Message version (expected 0x00) */ + uint8_t numTrkChHw; /**< Number of tracking channels available (read only) */ + uint8_t numTrkChUse; /**< Number of tracking channels to use (0xFF for numTrkChHw) */ + uint8_t numConfigBlocks; /**< Count of repeated blocks */ + + struct ubx_payload_tx_cgf_gnss_block_t { + uint8_t gnssId; /**< GNSS ID */ + uint8_t resTrkCh; /**< Number of reseved (minimum) tracking channels */ + uint8_t maxTrkCh; /**< Maximum number or tracking channels */ + uint8_t reserved1; + uint32_t flags; /**< Bitfield flags (see UBX_TX_CFG_GNSS_FLAGS_*) */ + }; + + ubx_payload_tx_cgf_gnss_block_t block[7]; /**< GPS, SBAS, Galileo, BeiDou, IMES 0-8, QZSS, GLONASS */ +} ubx_payload_tx_cfg_gnss_t; + /* NAV RELPOSNED (protocol version 27+) */ typedef struct { uint8_t version; /**< message version (expected 0x01) */ @@ -772,6 +819,7 @@ typedef union { ubx_payload_tx_cfg_tmode3_t payload_tx_cfg_tmode3; ubx_payload_tx_cfg_cfg_t payload_tx_cfg_cfg; ubx_payload_tx_cfg_valset_t payload_tx_cfg_valset; + ubx_payload_tx_cfg_gnss_t payload_tx_cfg_gnss; ubx_payload_rx_nav_relposned_t payload_rx_nav_relposned; } ubx_buf_t; @@ -1001,6 +1049,8 @@ class GPSDriverUBX : public GPSBaseStationSupport OutputMode _output_mode{OutputMode::GPS}; + GNSSSystemsMask _gnssSystems{}; + RTCMParsing *_rtcm_parsing{nullptr}; const UBXMode _mode;