Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 73 additions & 12 deletions src/main/io/gps_ublox.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ static const char * baudInitDataNMEA[GPS_BAUDRATE_COUNT] = {

static ubx_nav_sig_info satelites[UBLOX_MAX_SIGNALS] = {};

// From MON-VER, where a dual band receiver names itself (FWVER=SPGL1L5)
static bool ubxDualBand = false;

// MON-RF noise value (noisePerMS) reported by UBX-MON-RF as U2 at payload offset 0x10
static uint16_t monRfNoisePerMs = 0;
static uint16_t monAgcCount = 0;
Expand Down Expand Up @@ -355,6 +358,42 @@ static int configureGNSS_SBAS(ubx_gnss_element_t * gnss_block)
return 1;
}

// The selected constellations the receiver has, cut to what it can track at once: it
// rejects a configuration it cannot run. The ones INAV has off by default go first
static uint8_t ubloxGnssToEnable(void)
{
static const uint8_t leaveOutFirst[] = {
UBX_MON_GNSS_GLONASS_MASK, UBX_MON_GNSS_BEIDOU_MASK, UBX_MON_GNSS_GALILEO_MASK
};

uint8_t gnss = UBX_MON_GNSS_GPS_MASK;
if (gpsState.gpsConfig->ubloxUseGalileo) {
gnss |= UBX_MON_GNSS_GALILEO_MASK;
}
if (gpsState.gpsConfig->ubloxUseBeidou) {
gnss |= UBX_MON_GNSS_BEIDOU_MASK;
}
if (gpsState.gpsConfig->ubloxUseGlonass) {
gnss |= UBX_MON_GNSS_GLONASS_MASK;
}

// Until MON-GNSS answers, the selection goes out as it is
if (!ubx_capabilities.supported) {
return gnss;
}

gnss &= ubx_capabilities.supported;

for (unsigned i = 0; i < ARRAYLEN(leaveOutFirst); i++) {
if (ubx_capabilities.capMaxGnss <= 0 || __builtin_popcount(gnss) <= ubx_capabilities.capMaxGnss) {
break;
}
gnss &= ~leaveOutFirst[i];
}

return gnss;
}

static int configureGNSS_GALILEO(ubx_gnss_element_t * gnss_block)
{
if (!gpsUbloxHasGalileo()) {
Expand All @@ -368,7 +407,7 @@ static int configureGNSS_GALILEO(ubx_gnss_element_t * gnss_block)
// 0x10 = Galileo E5a // off by default
// 0x20 = Galileo E5b // off by default
gnss_block->sigCfgMask = 0x01;
if (gpsState.gpsConfig->ubloxUseGalileo) {
if (ubloxGnssToEnable() & UBX_MON_GNSS_GALILEO_MASK) {
gnss_block->enabled = 1;
gnss_block->resTrkCh = 4;
} else {
Expand All @@ -392,7 +431,7 @@ static int configureGNSS_BEIDOU(ubx_gnss_element_t * gnss_block)
// 0x10 = BeiDou B2I // off by default
// 0x80 = BeiDou B2A // off by default
gnss_block->sigCfgMask = 0x01;
if (gpsState.gpsConfig->ubloxUseBeidou) {
if (ubloxGnssToEnable() & UBX_MON_GNSS_BEIDOU_MASK) {
gnss_block->enabled = 1;
gnss_block->resTrkCh = 4;
} else {
Expand Down Expand Up @@ -434,7 +473,7 @@ static int configureGNSS_GLONASS(ubx_gnss_element_t * gnss_block)
// 0x01 = GLONASS L1
// 0x10 = GLONASS L2 // off by default
gnss_block->sigCfgMask = 0x01;
if (gpsState.gpsConfig->ubloxUseGlonass) {
if (ubloxGnssToEnable() & UBX_MON_GNSS_GLONASS_MASK) {
gnss_block->enabled = 1;
gnss_block->resTrkCh = 4;
} else {
Expand All @@ -447,32 +486,44 @@ static int configureGNSS_GLONASS(ubx_gnss_element_t * gnss_block)

static void configureGNSS10(void)
{
const uint8_t gnss = ubloxGnssToEnable();
const bool useGalileo = gnss & UBX_MON_GNSS_GALILEO_MASK;
const bool useBeidou = gnss & UBX_MON_GNSS_BEIDOU_MASK;
const bool useGlonass = gnss & UBX_MON_GNSS_GLONASS_MASK;

// A dual band receiver has B1C, not B1I, and rejects one band enabled without the other
const bool useB1C = ubxDualBand || useGlonass;

ubx_config_data8_payload_t gnssConfigValues[] = {
// SBAS
{UBLOX_CFG_SIGNAL_SBAS_ENA, gpsState.gpsConfig->sbasMode == SBAS_NONE ? 0 : 1},
{UBLOX_CFG_SIGNAL_SBAS_L1CA_ENA, gpsState.gpsConfig->sbasMode == SBAS_NONE ? 0 : 1},

// Galileo
{UBLOX_CFG_SIGNAL_GAL_ENA, gpsState.gpsConfig->ubloxUseGalileo},
{UBLOX_CFG_SIGNAL_GAL_E1_ENA, gpsState.gpsConfig->ubloxUseGalileo},
{UBLOX_CFG_SIGNAL_GAL_ENA, useGalileo},
{UBLOX_CFG_SIGNAL_GAL_E1_ENA, useGalileo},

// Beidou
// M10 can't use BDS_B1I and Glonass together. Instead, use BDS_B1C
{UBLOX_CFG_SIGNAL_BDS_ENA, gpsState.gpsConfig->ubloxUseBeidou},
{UBLOX_CFG_SIGNAL_BDS_B1_ENA, gpsState.gpsConfig->ubloxUseBeidou && ! gpsState.gpsConfig->ubloxUseGlonass},
{UBLOX_CFG_SIGNAL_BDS_B1C_ENA, gpsState.gpsConfig->ubloxUseBeidou && gpsState.gpsConfig->ubloxUseGlonass},
{UBLOX_CFG_SIGNAL_BDS_ENA, useBeidou},
{UBLOX_CFG_SIGNAL_BDS_B1_ENA, useBeidou && !useB1C},
{UBLOX_CFG_SIGNAL_BDS_B1C_ENA, useBeidou && useB1C},

// Should be enabled with GPS
{UBLOX_CFG_QZSS_ENA, 1},
{UBLOX_CFG_QZSS_L1CA_ENA, 1},
{UBLOX_CFG_QZSS_L1S_ENA, 1},

// Glonass
{UBLOX_CFG_GLO_ENA, gpsState.gpsConfig->ubloxUseGlonass},
{UBLOX_CFG_GLO_L1_ENA, gpsState.gpsConfig->ubloxUseGlonass}
// Glonass, must stay last so it can be left out
{UBLOX_CFG_GLO_ENA, useGlonass},
{UBLOX_CFG_GLO_L1_ENA, useGlonass}
};

ubloxSendSetCfgBytes(gnssConfigValues, 12);
// A receiver without Glonass rejects the whole message over its keys. An empty mask
// means MON-GNSS never answered: send them all
const bool noGlonass = ubx_capabilities.supported && !gpsUbloxHasGlonass();

ubloxSendSetCfgBytes(gnssConfigValues, noGlonass ? 10 : 12);
}

static void configureGNSS(void)
Expand Down Expand Up @@ -765,6 +816,13 @@ static bool gpsParseFrameUBLOX(void)
break;
}
}

for (int j = 40; j < _payload_length; j += 30) {
if (strnstr((const char *)(_buffer.bytes + j), "L1L5", 30)) {
ubxDualBand = true;
break;
}
}
}
}
break;
Expand Down Expand Up @@ -1250,6 +1308,7 @@ STATIC_PROTOTHREAD(gpsProtocolStateThread)

// Attempt to detect GPS hw version
gpsState.hwVersion = UBX_HW_VERSION_UNKNOWN;
ubxDualBand = false;
gpsState.autoConfigStep = 0;

// Configure GPS module if enabled
Expand All @@ -1262,6 +1321,8 @@ STATIC_PROTOTHREAD(gpsProtocolStateThread)

gpsState.autoConfigStep = 0;
ubx_capabilities.supported = ubx_capabilities.enabledGnss = ubx_capabilities.defaultGnss = 0;
// Or the wait below ends at once on the count from before a restart, with an empty mask
ubx_capabilities.capMaxGnss = 0;
// M7 and earlier will never get pass this step, so skip it (#9440).
// UBLOX documents that this is M8N and later
if (gpsState.hwVersion > UBX_HW_VERSION_UBLOX7) {
Expand Down
Loading