diff --git a/js/msp/MSPHelper.js b/js/msp/MSPHelper.js
index 2cc00953d..cb03e98db 100644
--- a/js/msp/MSPHelper.js
+++ b/js/msp/MSPHelper.js
@@ -198,6 +198,12 @@ var mspHelper = (function () {
FC.GPS_DATA.hdop = data.getUint16(14, true);
FC.GPS_DATA.eph = data.getUint16(16, true);
FC.GPS_DATA.epv = data.getUint16(18, true);
+ // Check if hwVersion field exists (firmware with extended MSP_GPSSTATISTICS)
+ if (data.byteLength >= 24) {
+ FC.GPS_DATA.hwVersion = data.getUint32(20, true);
+ } else {
+ FC.GPS_DATA.hwVersion = 0; // Unknown for older firmware
+ }
break;
case MSPCodes.MSP2_ADSB_VEHICLE_LIST:
var byteOffsetCounter = 0;
diff --git a/locale/en/messages.json b/locale/en/messages.json
index c16540af6..d1e7a2f8e 100644
--- a/locale/en/messages.json
+++ b/locale/en/messages.json
@@ -1209,6 +1209,24 @@
"configurationGPSUseGlonass": {
"message": "Gps use Glonass Satellites (RU)"
},
+ "gpsPresetMode": {
+ "message": "GPS Configuration Preset"
+ },
+ "gpsPresetModeHelp": {
+ "message": "Choose a preset optimized for your GPS module, or use Manual for custom configuration. Auto-detect will identify your GPS module if connected."
+ },
+ "gpsUpdateRate": {
+ "message": "GPS Update Rate (Hz)"
+ },
+ "gpsUpdateRateHelp": {
+ "message": "How often the GPS module sends position updates. Higher rates provide lower latency but may reduce accuracy with multiple constellations on M10 modules."
+ },
+ "gpsAutoDetectFailed": {
+ "message": "Could not auto-detect GPS module. Please connect flight controller or select manual preset."
+ },
+ "gpsAutoDetectSuccess": {
+ "message": "GPS module detected:"
+ },
"tzOffset": {
"message": "Timezone Offset"
},
diff --git a/tabs/gps.html b/tabs/gps.html
index b74cfca21..aa5025adb 100644
--- a/tabs/gps.html
+++ b/tabs/gps.html
@@ -38,16 +38,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
diff --git a/tabs/gps.js b/tabs/gps.js
index c882e3737..c148db1db 100644
--- a/tabs/gps.js
+++ b/tabs/gps.js
@@ -200,6 +200,148 @@ TABS.gps.initialize = function (callback) {
gps_ubx_sbas_e.val(FC.MISC.gps_ubx_sbas);
+ // GPS Preset Configuration
+ const GPS_PRESETS = {
+ m8: {
+ name: "u-blox M8",
+ galileo: true,
+ glonass: true,
+ beidou: true,
+ rate: 8,
+ description: [
+ "4 GNSS constellations for maximum accuracy",
+ "8Hz update rate (conservative for M8)",
+ "Best for: Navigation, position hold, slower aircraft"
+ ]
+ },
+ 'm9-precision': {
+ name: "u-blox M9 (Precision Mode)",
+ galileo: true,
+ glonass: false,
+ beidou: true,
+ rate: 5,
+ description: [
+ "3 GNSS constellations (GPS+Galileo+Beidou) → 32 satellites",
+ "5Hz update rate, HDOP ~1.0-1.3",
+ "Best for: Long-range cruise, position hold, navigation missions"
+ ]
+ },
+ 'm9-sport': {
+ name: "u-blox M9 (Sport Mode)",
+ galileo: true,
+ glonass: false,
+ beidou: true,
+ rate: 10,
+ description: [
+ "3 GNSS constellations (GPS+Galileo+Beidou) → 16 satellites",
+ "10Hz update rate (hardware limit), HDOP ~2.0-2.5",
+ "Best for: Fast flying, racing, acrobatics, quick response"
+ ]
+ },
+ m10: {
+ name: "u-blox M10",
+ galileo: true,
+ glonass: false,
+ beidou: true,
+ rate: 8,
+ description: [
+ "3 GNSS constellations (GPS+Galileo+Beidou)",
+ "8Hz update rate (safe for M10 default CPU clock)",
+ "Best for: General use, balanced performance"
+ ]
+ },
+ 'm10-highperf': {
+ name: "u-blox M10 (High-Performance)",
+ galileo: true,
+ glonass: true,
+ beidou: true,
+ rate: 10,
+ description: [
+ "4 GNSS constellations for maximum satellites",
+ "10Hz update rate (requires high-performance CPU clock)",
+ "Only use if you KNOW your M10 has high-performance clock enabled"
+ ]
+ },
+ manual: {
+ name: "Manual Settings",
+ description: [
+ "Full control over constellation selection and update rate",
+ "For advanced users and special requirements"
+ ]
+ }
+ };
+
+ function detectGPSPreset(hwVersion) {
+ switch(hwVersion) {
+ case 800: return 'm8';
+ case 900: return 'm9-precision'; // Default to precision mode for better accuracy
+ case 1000: return 'm10';
+ default: return 'manual';
+ }
+ }
+
+ function applyGPSPreset(presetId) {
+ // Handle special cases first (before checking GPS_PRESETS)
+ if (presetId === 'manual') {
+ // Enable all controls
+ $('.preset-controlled').prop('disabled', false);
+ $('#gps_ublox_nav_hz').prop('disabled', false);
+ $('#preset_info').hide();
+ return;
+ }
+
+ if (presetId === 'auto') {
+ // Try to auto-detect from FC
+ if (FC.GPS_DATA && FC.GPS_DATA.hwVersion) {
+ const detectedPreset = detectGPSPreset(FC.GPS_DATA.hwVersion);
+ applyGPSPreset(detectedPreset);
+ $('#gps_preset_mode').val(detectedPreset);
+ GUI.log(i18n.getMessage('gpsAutoDetectSuccess') + ' ' + GPS_PRESETS[detectedPreset].name);
+ } else {
+ // Fall back to manual if can't detect
+ applyGPSPreset('manual');
+ $('#gps_preset_mode').val('manual');
+ GUI.log(i18n.getMessage('gpsAutoDetectFailed'));
+ }
+ return;
+ }
+
+ // Normal preset application
+ const preset = GPS_PRESETS[presetId];
+ if (!preset) return;
+
+ // Apply preset values (trigger change for state consistency)
+ $('#gps_use_galileo').prop('checked', preset.galileo).trigger('change');
+ $('#gps_use_glonass').prop('checked', preset.glonass).trigger('change');
+ $('#gps_use_beidou').prop('checked', preset.beidou).trigger('change');
+ $('#gps_ublox_nav_hz').val(preset.rate).trigger('change');
+
+ // Disable controls (user can see but not edit)
+ $('.preset-controlled').prop('disabled', true);
+ $('#gps_ublox_nav_hz').prop('disabled', true);
+
+ // Show preset info
+ $('#preset_name').text(preset.name);
+ $('#preset_details').html(preset.description.map(d => `
${d}`).join(''));
+ $('#preset_info').show();
+ }
+
+ // Set up preset mode handler
+ $('#gps_preset_mode').on('change', function() {
+ applyGPSPreset($(this).val());
+ });
+
+ // Initialize - try auto-detect if GPS data available, otherwise manual
+ if (FC.GPS_DATA && FC.GPS_DATA.hwVersion && FC.GPS_DATA.hwVersion > 0) {
+ // GPS data already available (e.g., from previous tab load)
+ const detectedPreset = detectGPSPreset(FC.GPS_DATA.hwVersion);
+ applyGPSPreset(detectedPreset);
+ $('#gps_preset_mode').val(detectedPreset);
+ } else {
+ // GPS data not yet available, default to manual
+ applyGPSPreset('manual');
+ }
+
let mapView = new View({
center: [0, 0],
zoom: 15