diff --git a/ExtLibs/Utilities/Device.cs b/ExtLibs/Utilities/Device.cs
index 07a94b9951..44fb59a48a 100644
--- a/ExtLibs/Utilities/Device.cs
+++ b/ExtLibs/Utilities/Device.cs
@@ -1,256 +1,294 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-
-namespace MissionPlanner.Utilities
-{
- ///
- /// https://github.com/ArduPilot/ardupilot/blob/master/Tools/scripts/decode_devid.py
- ///
- public class Device
- {
-
- // from ap_hal\device.h
- public enum BusType
- {
- BUS_TYPE_UNKNOWN = 0,
- BUS_TYPE_I2C = 1,
- BUS_TYPE_SPI = 2,
- BUS_TYPE_UAVCAN = 3,
- BUS_TYPE_SITL = 4,
- BUS_TYPE_MSP = 5,
- BUS_TYPE_SERIAL = 6,
- }
-
- public enum Speed
- {
- SPEED_HIGH,
- SPEED_LOW,
- }
-
- //nuttx\include\nuttx\spi.h
- public enum spi_dev_e
- {
- SPIDEV_NONE = 0, /* Not a valid value */
- SPIDEV_MMCSD, /* Select SPI MMC/SD device */
- SPIDEV_FLASH, /* Select SPI FLASH device */
- SPIDEV_ETHERNET, /* Select SPI ethernet device */
- SPIDEV_DISPLAY, /* Select SPI LCD/OLED display device */
- SPIDEV_WIRELESS, /* Select SPI Wireless device */
- SPIDEV_TOUCHSCREEN, /* Select SPI touchscreen device */
- SPIDEV_EXPANDER, /* Select SPI I/O expander device */
- SPIDEV_MUX, /* Select SPI multiplexer device */
- SPIDEV_AUDIO_DATA, /* Select SPI audio codec device data port */
- SPIDEV_AUDIO_CTRL, /* Select SPI audio codec device control port */
- };
-
- // float = 1 sign, 8 exponents, 23 significand
-
- public struct DeviceStructure
- {
- private readonly string _paramname;
-
- // the data
- public UInt32 devid;
-
- // accessors
- public BusType bus_type { get { return (BusType)(devid & 0x7); } } // : 3;
- public byte bus { get { return (byte)((devid >> 3) & 0x1f); } } //: 5; // which instance of the bus type
- public byte address { get { return (byte)((devid >> 8) & 0xff); } } // address on the bus (eg. I2C address)
- public byte devtype { get { return (byte)((devid >> 16) & 0xff); } } // device class specific device type
-
-
- public compass_type devtypecompass { get { return (compass_type)devtype; } }
- public imu_types devtypeimu { get { return (imu_types)devtype; } }
-
- public baro_types devtypebaro { get { return (baro_types)devtype; } }
-
- public airspeed_types devtypeairspd { get { return (airspeed_types)devtype; } }
-
- public DeviceStructure(string paramname, UInt32 id)
- {
- devid = id;
- _paramname = paramname;
- }
-
- public DeviceStructure(UInt32 id)
- {
- devid = id;
- _paramname = "";
-
- Console.WriteLine(ToString());
- }
-
- public override string ToString()
- {
- return string.Format("{5} devid {4} bus type {0} bus {1} address {2} devtype {3} ",
- bus_type.ToString().Replace("BUS_TYPE_", ""),
- bus, address,
- (_paramname.Contains("COMPASS") ? devtypecompass.ToString() :
- _paramname.Contains("BARO") ? devtypebaro.ToString() :
- _paramname.Contains("ASP") ? devtypeairspd.ToString() :
- _paramname.Contains("INS") ? devtypeimu.ToString() :
- $"{devtypecompass.ToString()} or {devtypeimu.ToString()} or {devtypebaro.ToString()} or {devtypeimu.ToString()} ").Replace("DEVTYPE_",
- ""),
- devid, _paramname);
- }
-
- // https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_Compass/AP_Compass_Backend.h#L49
- public enum compass_type
- {
- DEVTYPE_HMC5883_OLD = 0x01,
- DEVTYPE_HMC5883 = 0x07,
- DEVTYPE_LSM303D = 0x02,
- DEVTYPE_AK8963 = 0x04,
- DEVTYPE_BMM150 = 0x05,
- DEVTYPE_LSM9DS1 = 0x06,
- DEVTYPE_LIS3MDL = 0x08,
- DEVTYPE_AK09916 = 0x09,
- DEVTYPE_IST8310 = 0x0A,
- DEVTYPE_ICM20948 = 0x0B,
- DEVTYPE_MMC3416 = 0x0C,
- DEVTYPE_QMC5883L = 0x0D,
- DEVTYPE_MAG3110 = 0x0E,
- DEVTYPE_SITL = 0x0F,
- DEVTYPE_IST8308 = 0x10,
- DEVTYPE_RM3100 = 0x11,
- DEVTYPE_RM3100_2 = 0x12, // unused, past mistake
- DEVTYPE_MMC5883 = 0x13,
- DEVTYPE_AK09918 = 0x14,
- DEVTYPE_AK09915 = 0x15,
- DEVTYPE_QMC5883P = 0x16,
- DEVTYPE_BMM350 = 0x17,
- DEVTYPE_IIS2MDC = 0x18,
- DEVTYPE_LIS2MDL = 0x19,
- }
-
- //https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_InertialSensor/AP_InertialSensor_Backend.h#L95
- public enum imu_types
- {
- DEVTYPE_BMI160 = 0x09,
- DEVTYPE_L3G4200D = 0x10,
- DEVTYPE_ACC_LSM303D = 0x11,
- DEVTYPE_ACC_BMA180 = 0x12,
- DEVTYPE_ACC_MPU6000 = 0x13,
- DEVTYPE_ACC_MPU9250 = 0x16,
- DEVTYPE_ACC_IIS328DQ = 0x17,
- DEVTYPE_ACC_LSM9DS1 = 0x18,
- DEVTYPE_GYR_MPU6000 = 0x21,
- DEVTYPE_GYR_L3GD20 = 0x22,
- DEVTYPE_GYR_MPU9250 = 0x24,
- DEVTYPE_GYR_I3G4250D = 0x25,
- DEVTYPE_GYR_LSM9DS1 = 0x26,
- DEVTYPE_INS_ICM20789 = 0x27,
- DEVTYPE_INS_ICM20689 = 0x28,
- DEVTYPE_INS_BMI055 = 0x29,
- DEVTYPE_SITL = 0x2A,
- DEVTYPE_INS_BMI088 = 0x2B,
- DEVTYPE_INS_ICM20948 = 0x2C,
- DEVTYPE_INS_ICM20648 = 0x2D,
- DEVTYPE_INS_ICM20649 = 0x2E,
- DEVTYPE_INS_ICM20602 = 0x2F,
- DEVTYPE_INS_ICM20601 = 0x30,
- DEVTYPE_INS_ADIS1647X = 0x31,
- DEVTYPE_SERIAL = 0x32,
- DEVTYPE_INS_ICM40609 = 0x33,
- DEVTYPE_INS_ICM42688 = 0x34,
- DEVTYPE_INS_ICM42605 = 0x35,
- DEVTYPE_INS_ICM40605 = 0x36,
- DEVTYPE_INS_IIM42652 = 0x37,
- DEVTYPE_BMI270 = 0x38,
- DEVTYPE_INS_BMI085 = 0x39,
- DEVTYPE_INS_ICM42670 = 0x3A,
- DEVTYPE_INS_ICM45686 = 0x3B,
- DEVTYPE_INS_SCHA63T = 0x3C,
- DEVTYPE_INS_IIM42653 = 0x3D,
- DEVTYPE_INS_LSM6DSV = 0x3E,
- DEVTYPE_INS_ASM330 = 0x3F,
- };
-
- //https://github.com/tridge/ardupilot/blob/master/libraries/AP_Baro/AP_Baro_Backend.h#L40
- public enum baro_types
- {
- DEVTYPE_BARO_SITL = 0x01,
- DEVTYPE_BARO_BMP085 = 0x02,
- DEVTYPE_BARO_BMP280 = 0x03,
- DEVTYPE_BARO_BMP388 = 0x04,
- DEVTYPE_BARO_DPS280 = 0x05,
- DEVTYPE_BARO_DPS310 = 0x06,
- DEVTYPE_BARO_FBM320 = 0x07,
- DEVTYPE_BARO_ICM20789 = 0x08,
- DEVTYPE_BARO_KELLERLD = 0x09,
- DEVTYPE_BARO_LPS2XH = 0x0A,
- DEVTYPE_BARO_MS5611 = 0x0B,
- DEVTYPE_BARO_SPL06 = 0x0C,
- DEVTYPE_BARO_DRONECAN = 0x0D,
- DEVTYPE_BARO_MSP = 0x0E,
- DEVTYPE_BARO_ICP101XX = 0x0F,
- DEVTYPE_BARO_ICP201XX = 0x10,
- DEVTYPE_BARO_MS5607 = 0x11,
- DEVTYPE_BARO_MS5837_30BA = 0x12,
- DEVTYPE_BARO_MS5637 = 0x13,
- DEVTYPE_BARO_BMP390 = 0x14,
- DEVTYPE_BARO_BMP581 = 0x15,
- DEVTYPE_BARO_SPA06 = 0x16,
- DEVTYPE_BARO_AUAV = 0x17,
- DEVTYPE_BARO_MS5837_02BA = 0x18,
- };
-
- //https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_Airspeed/AP_Airspeed_Backend.h#L99
- public enum airspeed_types
- {
- DEVTYPE_AIRSPEED_SITL = 0x01,
- DEVTYPE_AIRSPEED_MS4525 = 0x02,
- DEVTYPE_AIRSPEED_MS5525 = 0x03,
- DEVTYPE_AIRSPEED_DLVR = 0x04,
- DEVTYPE_AIRSPEED_MSP = 0x05,
- DEVTYPE_AIRSPEED_SDP3X = 0x06,
- DEVTYPE_AIRSPEED_DRONECAN = 0x07,
- DEVTYPE_AIRSPEED_ANALOG = 0x08,
- DEVTYPE_AIRSPEED_NMEA = 0x09,
- DEVTYPE_AIRSPEED_ASP5033 = 0x0A,
- };
-
- public enum px4_i2c_bus
- {
- PX4_I2C_BUS_ONBOARD = 0,
- PX4_I2C_BUS_EXPANSION = 1
- }
-
- // from PX4Firmware\src\drivers\boards\px4fmu-v2\board_config.h
- public enum px4_spi_bus
- {
- PX4_SPI_BUS_SENSORS = 1,
- PX4_SPI_BUS_RAMTRON = 2,
- PX4_SPI_BUS_EXT = 4,
- }
- }
-
- //DEV_ID
- //DEV_ID2
- //DEV_ID3
-
- //ap_hal - device.h
- //set_device_type
- //get_bus_id
-
- /**
-* make a bus id given bus type, bus number, bus address and
-* device type This is for use by devices that do not use one of
-* the standard HAL Device types, such as UAVCAN devices
-*/
- /*
- static uint32_t make_bus_id(enum BusType bus_type, uint8_t bus, uint8_t address, uint8_t devtype) {
- union DeviceId d;
- d.devid_s.bus_type = bus_type;
- d.devid_s.bus = bus;
- d.devid_s.address = address;
- d.devid_s.devtype = devtype;
- return d.devid;
- */
-
- // devid is a union of bus type, bus, address and devtype
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace MissionPlanner.Utilities
+{
+ ///
+ /// https://github.com/ArduPilot/ardupilot/blob/master/Tools/scripts/decode_devid.py
+ ///
+ public class Device
+ {
+
+ // from ap_hal\device.h
+ public enum BusType
+ {
+ BUS_TYPE_UNKNOWN = 0,
+ BUS_TYPE_I2C = 1,
+ BUS_TYPE_SPI = 2,
+ BUS_TYPE_UAVCAN = 3,
+ BUS_TYPE_SITL = 4,
+ BUS_TYPE_MSP = 5,
+ BUS_TYPE_SERIAL = 6,
+ }
+
+ public enum Speed
+ {
+ SPEED_HIGH,
+ SPEED_LOW,
+ }
+
+ //nuttx\include\nuttx\spi.h
+ public enum spi_dev_e
+ {
+ SPIDEV_NONE = 0, /* Not a valid value */
+ SPIDEV_MMCSD, /* Select SPI MMC/SD device */
+ SPIDEV_FLASH, /* Select SPI FLASH device */
+ SPIDEV_ETHERNET, /* Select SPI ethernet device */
+ SPIDEV_DISPLAY, /* Select SPI LCD/OLED display device */
+ SPIDEV_WIRELESS, /* Select SPI Wireless device */
+ SPIDEV_TOUCHSCREEN, /* Select SPI touchscreen device */
+ SPIDEV_EXPANDER, /* Select SPI I/O expander device */
+ SPIDEV_MUX, /* Select SPI multiplexer device */
+ SPIDEV_AUDIO_DATA, /* Select SPI audio codec device data port */
+ SPIDEV_AUDIO_CTRL, /* Select SPI audio codec device control port */
+ };
+
+ // float = 1 sign, 8 exponents, 23 significand
+
+ public struct DeviceStructure
+ {
+ private readonly string _paramname;
+
+ // the data
+ public UInt32 devid;
+
+ // accessors
+ public BusType bus_type { get { return (BusType)(devid & 0x7); } } // : 3;
+ public byte bus { get { return (byte)((devid >> 3) & 0x1f); } } //: 5; // which instance of the bus type
+ public byte address { get { return (byte)((devid >> 8) & 0xff); } } // address on the bus (eg. I2C address)
+ public byte devtype { get { return (byte)((devid >> 16) & 0xff); } } // device class specific device type
+
+
+ public compass_type devtypecompass { get { return (compass_type)devtype; } }
+ public imu_types devtypeimu { get { return (imu_types)devtype; } }
+
+ public baro_types devtypebaro { get { return (baro_types)devtype; } }
+
+ public airspeed_types devtypeairspd { get { return (airspeed_types)devtype; } }
+
+ // MAVn_DEVID identifies which device a MAVLink channel's parameters (MAVn_SRx, etc) apply to.
+ // The family lives in devtype (AP_HAL::Device::DeviceType), the port/instance within that
+ // family in bus/address, mirroring how AP_SerialManager::UARTState::get_device_id() packs it.
+ // https://github.com/ArduPilot/ardupilot/pull/29762
+ public string devtypemavlink
+ {
+ get
+ {
+ if (devid == 0)
+ return "Unknown";
+
+ switch ((mavlink_devtype)devtype)
+ {
+ case mavlink_devtype.UART:
+ return address == 0 ? "SERIAL0 (USB)" : "SERIAL" + address;
+ case mavlink_devtype.NETWORKING:
+ return "NET_P" + (address + 1);
+ case mavlink_devtype.CANBUS:
+ return "CAN_D" + (bus + 1) + "_UC_S" + (address + 1);
+ case mavlink_devtype.SCRIPTING:
+ return "SCR_SDEV" + (address + 1);
+ default:
+ return devid.ToString();
+ }
+ }
+ }
+
+ public DeviceStructure(string paramname, UInt32 id)
+ {
+ devid = id;
+ _paramname = paramname;
+ }
+
+ public DeviceStructure(UInt32 id)
+ {
+ devid = id;
+ _paramname = "";
+
+ Console.WriteLine(ToString());
+ }
+
+ public override string ToString()
+ {
+ return string.Format("{5} devid {4} bus type {0} bus {1} address {2} devtype {3} ",
+ bus_type.ToString().Replace("BUS_TYPE_", ""),
+ bus, address,
+ (_paramname.Contains("COMPASS") ? devtypecompass.ToString() :
+ _paramname.Contains("BARO") ? devtypebaro.ToString() :
+ _paramname.Contains("ASP") ? devtypeairspd.ToString() :
+ _paramname.Contains("INS") ? devtypeimu.ToString() :
+ $"{devtypecompass.ToString()} or {devtypeimu.ToString()} or {devtypebaro.ToString()} or {devtypeimu.ToString()} ").Replace("DEVTYPE_",
+ ""),
+ devid, _paramname);
+ }
+
+ // https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_Compass/AP_Compass_Backend.h#L49
+ public enum compass_type
+ {
+ DEVTYPE_HMC5883_OLD = 0x01,
+ DEVTYPE_HMC5883 = 0x07,
+ DEVTYPE_LSM303D = 0x02,
+ DEVTYPE_AK8963 = 0x04,
+ DEVTYPE_BMM150 = 0x05,
+ DEVTYPE_LSM9DS1 = 0x06,
+ DEVTYPE_LIS3MDL = 0x08,
+ DEVTYPE_AK09916 = 0x09,
+ DEVTYPE_IST8310 = 0x0A,
+ DEVTYPE_ICM20948 = 0x0B,
+ DEVTYPE_MMC3416 = 0x0C,
+ DEVTYPE_QMC5883L = 0x0D,
+ DEVTYPE_MAG3110 = 0x0E,
+ DEVTYPE_SITL = 0x0F,
+ DEVTYPE_IST8308 = 0x10,
+ DEVTYPE_RM3100 = 0x11,
+ DEVTYPE_RM3100_2 = 0x12, // unused, past mistake
+ DEVTYPE_MMC5883 = 0x13,
+ DEVTYPE_AK09918 = 0x14,
+ DEVTYPE_AK09915 = 0x15,
+ DEVTYPE_QMC5883P = 0x16,
+ DEVTYPE_BMM350 = 0x17,
+ DEVTYPE_IIS2MDC = 0x18,
+ DEVTYPE_LIS2MDL = 0x19,
+ }
+
+ //https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_InertialSensor/AP_InertialSensor_Backend.h#L95
+ public enum imu_types
+ {
+ DEVTYPE_BMI160 = 0x09,
+ DEVTYPE_L3G4200D = 0x10,
+ DEVTYPE_ACC_LSM303D = 0x11,
+ DEVTYPE_ACC_BMA180 = 0x12,
+ DEVTYPE_ACC_MPU6000 = 0x13,
+ DEVTYPE_ACC_MPU9250 = 0x16,
+ DEVTYPE_ACC_IIS328DQ = 0x17,
+ DEVTYPE_ACC_LSM9DS1 = 0x18,
+ DEVTYPE_GYR_MPU6000 = 0x21,
+ DEVTYPE_GYR_L3GD20 = 0x22,
+ DEVTYPE_GYR_MPU9250 = 0x24,
+ DEVTYPE_GYR_I3G4250D = 0x25,
+ DEVTYPE_GYR_LSM9DS1 = 0x26,
+ DEVTYPE_INS_ICM20789 = 0x27,
+ DEVTYPE_INS_ICM20689 = 0x28,
+ DEVTYPE_INS_BMI055 = 0x29,
+ DEVTYPE_SITL = 0x2A,
+ DEVTYPE_INS_BMI088 = 0x2B,
+ DEVTYPE_INS_ICM20948 = 0x2C,
+ DEVTYPE_INS_ICM20648 = 0x2D,
+ DEVTYPE_INS_ICM20649 = 0x2E,
+ DEVTYPE_INS_ICM20602 = 0x2F,
+ DEVTYPE_INS_ICM20601 = 0x30,
+ DEVTYPE_INS_ADIS1647X = 0x31,
+ DEVTYPE_SERIAL = 0x32,
+ DEVTYPE_INS_ICM40609 = 0x33,
+ DEVTYPE_INS_ICM42688 = 0x34,
+ DEVTYPE_INS_ICM42605 = 0x35,
+ DEVTYPE_INS_ICM40605 = 0x36,
+ DEVTYPE_INS_IIM42652 = 0x37,
+ DEVTYPE_BMI270 = 0x38,
+ DEVTYPE_INS_BMI085 = 0x39,
+ DEVTYPE_INS_ICM42670 = 0x3A,
+ DEVTYPE_INS_ICM45686 = 0x3B,
+ DEVTYPE_INS_SCHA63T = 0x3C,
+ DEVTYPE_INS_IIM42653 = 0x3D,
+ DEVTYPE_INS_LSM6DSV = 0x3E,
+ DEVTYPE_INS_ASM330 = 0x3F,
+ };
+
+ //https://github.com/tridge/ardupilot/blob/master/libraries/AP_Baro/AP_Baro_Backend.h#L40
+ public enum baro_types
+ {
+ DEVTYPE_BARO_SITL = 0x01,
+ DEVTYPE_BARO_BMP085 = 0x02,
+ DEVTYPE_BARO_BMP280 = 0x03,
+ DEVTYPE_BARO_BMP388 = 0x04,
+ DEVTYPE_BARO_DPS280 = 0x05,
+ DEVTYPE_BARO_DPS310 = 0x06,
+ DEVTYPE_BARO_FBM320 = 0x07,
+ DEVTYPE_BARO_ICM20789 = 0x08,
+ DEVTYPE_BARO_KELLERLD = 0x09,
+ DEVTYPE_BARO_LPS2XH = 0x0A,
+ DEVTYPE_BARO_MS5611 = 0x0B,
+ DEVTYPE_BARO_SPL06 = 0x0C,
+ DEVTYPE_BARO_DRONECAN = 0x0D,
+ DEVTYPE_BARO_MSP = 0x0E,
+ DEVTYPE_BARO_ICP101XX = 0x0F,
+ DEVTYPE_BARO_ICP201XX = 0x10,
+ DEVTYPE_BARO_MS5607 = 0x11,
+ DEVTYPE_BARO_MS5837_30BA = 0x12,
+ DEVTYPE_BARO_MS5637 = 0x13,
+ DEVTYPE_BARO_BMP390 = 0x14,
+ DEVTYPE_BARO_BMP581 = 0x15,
+ DEVTYPE_BARO_SPA06 = 0x16,
+ DEVTYPE_BARO_AUAV = 0x17,
+ DEVTYPE_BARO_MS5837_02BA = 0x18,
+ };
+
+ //https://github.com/ArduPilot/ardupilot/blob/master/libraries/AP_Airspeed/AP_Airspeed_Backend.h#L99
+ public enum airspeed_types
+ {
+ DEVTYPE_AIRSPEED_SITL = 0x01,
+ DEVTYPE_AIRSPEED_MS4525 = 0x02,
+ DEVTYPE_AIRSPEED_MS5525 = 0x03,
+ DEVTYPE_AIRSPEED_DLVR = 0x04,
+ DEVTYPE_AIRSPEED_MSP = 0x05,
+ DEVTYPE_AIRSPEED_SDP3X = 0x06,
+ DEVTYPE_AIRSPEED_DRONECAN = 0x07,
+ DEVTYPE_AIRSPEED_ANALOG = 0x08,
+ DEVTYPE_AIRSPEED_NMEA = 0x09,
+ DEVTYPE_AIRSPEED_ASP5033 = 0x0A,
+ };
+
+ // MAVn_DEVID device family, from AP_HAL::Device::DeviceType as used by
+ // AP_SerialManager::UARTState::get_device_id() (devid bits 16-23).
+ // https://github.com/ArduPilot/ardupilot/pull/29762
+ public enum mavlink_devtype
+ {
+ UART = 1,
+ NETWORKING = 2,
+ CANBUS = 3,
+ SCRIPTING = 4,
+ };
+
+ public enum px4_i2c_bus
+ {
+ PX4_I2C_BUS_ONBOARD = 0,
+ PX4_I2C_BUS_EXPANSION = 1
+ }
+
+ // from PX4Firmware\src\drivers\boards\px4fmu-v2\board_config.h
+ public enum px4_spi_bus
+ {
+ PX4_SPI_BUS_SENSORS = 1,
+ PX4_SPI_BUS_RAMTRON = 2,
+ PX4_SPI_BUS_EXT = 4,
+ }
+ }
+
+ //DEV_ID
+ //DEV_ID2
+ //DEV_ID3
+
+ //ap_hal - device.h
+ //set_device_type
+ //get_bus_id
+
+ /**
+* make a bus id given bus type, bus number, bus address and
+* device type This is for use by devices that do not use one of
+* the standard HAL Device types, such as UAVCAN devices
+*/
+ /*
+ static uint32_t make_bus_id(enum BusType bus_type, uint8_t bus, uint8_t address, uint8_t devtype) {
+ union DeviceId d;
+ d.devid_s.bus_type = bus_type;
+ d.devid_s.bus = bus;
+ d.devid_s.address = address;
+ d.devid_s.devtype = devtype;
+ return d.devid;
+ */
+
+ // devid is a union of bus type, bus, address and devtype
+ }
+}
diff --git a/GCSViews/ConfigurationView/DeviceInfo.cs b/GCSViews/ConfigurationView/DeviceInfo.cs
index b01bc784d6..d6bd025c4f 100644
--- a/GCSViews/ConfigurationView/DeviceInfo.cs
+++ b/GCSViews/ConfigurationView/DeviceInfo.cs
@@ -31,6 +31,9 @@ public string DevType
if (_devid.bus_type == Device.BusType.BUS_TYPE_UAVCAN)
return "SENSOR_ID#" + (_devid.devtype).ToString();
+ if (ParamName.StartsWith("MAV") && ParamName.EndsWith("_DEVID"))
+ return _devid.devtypemavlink;
+
if(ParamName.Contains("COMP"))
return _devid.devtypecompass.ToString().Replace("DEVTYPE_", "");
diff --git a/MissionPlannerTests/Utilities/DeviceInfoTests.cs b/MissionPlannerTests/Utilities/DeviceInfoTests.cs
new file mode 100644
index 0000000000..23227bbb13
--- /dev/null
+++ b/MissionPlannerTests/Utilities/DeviceInfoTests.cs
@@ -0,0 +1,69 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using MissionPlanner.GCSViews.ConfigurationView;
+using System.Collections.Generic;
+
+namespace MissionPlanner.Utilities.Tests
+{
+ [TestClass()]
+ public class DeviceInfoTests
+ {
+ // devid = bus_type(6=BUS_TYPE_SERIAL) | (bus<<3) | (address<<8) | (devtype<<16),
+ // matching AP_SerialManager::UARTState::get_device_id() and the values ArduPilot
+ // publishes in GCS_MAVLink_Parameters.cpp for MAVn_DEVID.
+ [TestMethod()]
+ public void MavDevIdKnownValuesTest()
+ {
+ var expected = new Dictionary()
+ {
+ { 0, "Unknown" },
+ { 65542, "SERIAL0 (USB)" },
+ { 65798, "SERIAL1" },
+ { 66054, "SERIAL2" },
+ { 66310, "SERIAL3" },
+ { 66566, "SERIAL4" },
+ { 66822, "SERIAL5" },
+ { 67078, "SERIAL6" },
+ { 67334, "SERIAL7" },
+ { 67590, "SERIAL8" },
+ { 67846, "SERIAL9" },
+ { 131078, "NET_P1" },
+ { 131334, "NET_P2" },
+ { 131590, "NET_P3" },
+ { 131846, "NET_P4" },
+ { 196614, "CAN_D1_UC_S1" },
+ { 196870, "CAN_D1_UC_S2" },
+ { 197126, "CAN_D1_UC_S3" },
+ { 196622, "CAN_D2_UC_S1" },
+ { 196878, "CAN_D2_UC_S2" },
+ { 197134, "CAN_D2_UC_S3" },
+ { 262150, "SCR_SDEV1" },
+ { 262406, "SCR_SDEV2" },
+ { 262662, "SCR_SDEV3" },
+ };
+
+ foreach (var kvp in expected)
+ {
+ var info = new DeviceInfo(0, "MAV1_DEVID", kvp.Key);
+ Assert.AreEqual(kvp.Value, info.DevType, "devid " + kvp.Key + " should decode to " + kvp.Value);
+ }
+ }
+
+ // SERIAL10 isn't in ArduPilot's published table, but the decode is closed-form on
+ // (devtype, bus, address) rather than an enumerated list, so it still resolves.
+ [TestMethod()]
+ public void MavDevIdUnlistedSerialPortDecodesTest()
+ {
+ var info = new DeviceInfo(0, "MAV1_DEVID", 68102); // 6 | (10<<8) | (1<<16)
+ Assert.AreEqual("SERIAL10", info.DevType);
+ }
+
+ // devtype=5 is not a defined AP_HAL::Device::DeviceType, so this must fall back to the
+ // raw number rather than throwing or guessing.
+ [TestMethod()]
+ public void MavDevIdUnknownFamilyFallsBackToNumberTest()
+ {
+ var info = new DeviceInfo(0, "MAV2_DEVID", 327686); // 6 | (5<<16)
+ Assert.AreEqual("327686", info.DevType);
+ }
+ }
+}