diff --git a/boards/mro/x21-777/src/spi.cpp b/boards/mro/x21-777/src/spi.cpp index 0837a2c927..450bd37e0a 100644 --- a/boards/mro/x21-777/src/spi.cpp +++ b/boards/mro/x21-777/src/spi.cpp @@ -38,7 +38,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::SPI1, { initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), - initSPIDevice(DRV_IMU_DEVTYPE_ICM20608, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM20608G, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), initSPIDevice(DRV_BARO_DEVTYPE_MS5611, SPI::CS{GPIO::PortD, GPIO::Pin7}), initSPIDevice(DRV_IMU_DEVTYPE_MPU9250, SPI::CS{GPIO::PortC, GPIO::Pin2}, SPI::DRDY{GPIO::PortD, GPIO::Pin15}), }), diff --git a/boards/mro/x21/src/spi.cpp b/boards/mro/x21/src/spi.cpp index 0837a2c927..450bd37e0a 100644 --- a/boards/mro/x21/src/spi.cpp +++ b/boards/mro/x21/src/spi.cpp @@ -38,7 +38,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::SPI1, { initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), - initSPIDevice(DRV_IMU_DEVTYPE_ICM20608, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM20608G, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), initSPIDevice(DRV_BARO_DEVTYPE_MS5611, SPI::CS{GPIO::PortD, GPIO::Pin7}), initSPIDevice(DRV_IMU_DEVTYPE_MPU9250, SPI::CS{GPIO::PortC, GPIO::Pin2}, SPI::DRDY{GPIO::PortD, GPIO::Pin15}), }), diff --git a/boards/px4/fmu-v2/src/spi.cpp b/boards/px4/fmu-v2/src/spi.cpp index ff1013c065..8196dee040 100644 --- a/boards/px4/fmu-v2/src/spi.cpp +++ b/boards/px4/fmu-v2/src/spi.cpp @@ -186,7 +186,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION initSPIHWVersion(HW_VER_FMUV2MINI, { initSPIBus(SPI::Bus::SPI1, { - initSPIDevice(DRV_IMU_DEVTYPE_ICM20608, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM20608G, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), initSPIDevice(DRV_BARO_DEVTYPE_MS5611, SPI::CS{GPIO::PortD, GPIO::Pin7}), }, {GPIO::PortE, GPIO::Pin3}), initSPIBus(SPI::Bus::SPI2, { diff --git a/boards/px4/fmu-v3/src/spi.cpp b/boards/px4/fmu-v3/src/spi.cpp index ff1013c065..8196dee040 100644 --- a/boards/px4/fmu-v3/src/spi.cpp +++ b/boards/px4/fmu-v3/src/spi.cpp @@ -186,7 +186,7 @@ constexpr px4_spi_bus_all_hw_t px4_spi_buses_all_hw[BOARD_NUM_SPI_CFG_HW_VERSION initSPIHWVersion(HW_VER_FMUV2MINI, { initSPIBus(SPI::Bus::SPI1, { - initSPIDevice(DRV_IMU_DEVTYPE_ICM20608, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM20608G, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), initSPIDevice(DRV_BARO_DEVTYPE_MS5611, SPI::CS{GPIO::PortD, GPIO::Pin7}), }, {GPIO::PortE, GPIO::Pin3}), initSPIBus(SPI::Bus::SPI2, { diff --git a/boards/px4/fmu-v4/src/spi.cpp b/boards/px4/fmu-v4/src/spi.cpp index ff3d9a9298..7500e4ab84 100644 --- a/boards/px4/fmu-v4/src/spi.cpp +++ b/boards/px4/fmu-v4/src/spi.cpp @@ -39,7 +39,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::SPI1, { initSPIDevice(DRV_IMU_DEVTYPE_MPU9250, SPI::CS{GPIO::PortC, GPIO::Pin2}, SPI::DRDY{GPIO::PortD, GPIO::Pin15}), initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), - initSPIDevice(DRV_IMU_DEVTYPE_ICM20608, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM20608G, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), initSPIDevice(DRV_MAG_DEVTYPE_HMC5883, SPI::CS{GPIO::PortE, GPIO::Pin15}, SPI::DRDY{GPIO::PortE, GPIO::Pin12}), // hmc5983 initSPIDevice(DRV_MAG_DEVTYPE_LIS3MDL, SPI::CS{GPIO::PortE, GPIO::Pin15}, SPI::DRDY{GPIO::PortE, GPIO::Pin12}), }, {GPIO::PortE, GPIO::Pin3}), diff --git a/boards/px4/fmu-v4pro/src/spi.cpp b/boards/px4/fmu-v4pro/src/spi.cpp index 816c587cb0..2eaed39c0f 100644 --- a/boards/px4/fmu-v4pro/src/spi.cpp +++ b/boards/px4/fmu-v4pro/src/spi.cpp @@ -39,7 +39,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::SPI1, { initSPIDevice(DRV_IMU_DEVTYPE_MPU9250, SPI::CS{GPIO::PortC, GPIO::Pin2}, SPI::DRDY{GPIO::PortD, GPIO::Pin15}), initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), - initSPIDevice(DRV_IMU_DEVTYPE_ICM20608, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM20608G, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), initSPIDevice(DRV_MAG_DEVTYPE_LIS3MDL, SPI::CS{GPIO::PortE, GPIO::Pin15}, SPI::DRDY{GPIO::PortE, GPIO::Pin12}), initSPIDevice(DRV_BARO_DEVTYPE_MS5611, SPI::CS{GPIO::PortD, GPIO::Pin7}), }, {GPIO::PortE, GPIO::Pin3}), diff --git a/boards/uvify/core/src/spi.cpp b/boards/uvify/core/src/spi.cpp index 6c8c0f2cb2..47048ed43a 100644 --- a/boards/uvify/core/src/spi.cpp +++ b/boards/uvify/core/src/spi.cpp @@ -39,7 +39,7 @@ constexpr px4_spi_bus_t px4_spi_buses[SPI_BUS_MAX_BUS_ITEMS] = { initSPIBus(SPI::Bus::SPI1, { initSPIDevice(DRV_IMU_DEVTYPE_MPU9250, SPI::CS{GPIO::PortC, GPIO::Pin2}, SPI::DRDY{GPIO::PortD, GPIO::Pin15}), initSPIDevice(DRV_IMU_DEVTYPE_ICM20602, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), - initSPIDevice(DRV_IMU_DEVTYPE_ICM20608, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), + initSPIDevice(DRV_IMU_DEVTYPE_ICM20608G, SPI::CS{GPIO::PortC, GPIO::Pin15}, SPI::DRDY{GPIO::PortC, GPIO::Pin14}), initSPIDevice(DRV_MAG_DEVTYPE_HMC5883, SPI::CS{GPIO::PortE, GPIO::Pin15}, SPI::DRDY{GPIO::PortE, GPIO::Pin12}), // hmc5983 }, {GPIO::PortE, GPIO::Pin3}), initSPIBus(SPI::Bus::SPI2, { diff --git a/src/drivers/drv_sensor.h b/src/drivers/drv_sensor.h index 5268bdec02..2c46240631 100644 --- a/src/drivers/drv_sensor.h +++ b/src/drivers/drv_sensor.h @@ -88,7 +88,7 @@ #define DRV_ACC_DEVTYPE_ICM20602_LEGACY 0x37 #define DRV_IMU_DEVTYPE_ICM20602 0x38 #define DRV_ACC_DEVTYPE_ICM20608_LEGACY 0x39 -#define DRV_IMU_DEVTYPE_ICM20608 0x3A +#define DRV_IMU_DEVTYPE_ICM20608G 0x3A #define DRV_ACC_DEVTYPE_ICM20689_LEGACY 0x3B #define DRV_IMU_DEVTYPE_ICM20689 0x3C #define DRV_BARO_DEVTYPE_MS5611 0x3D diff --git a/src/drivers/imu/invensense/icm20608g/ICM20608G.cpp b/src/drivers/imu/invensense/icm20608g/ICM20608G.cpp index 0c5b565fd5..c182634fb3 100644 --- a/src/drivers/imu/invensense/icm20608g/ICM20608G.cpp +++ b/src/drivers/imu/invensense/icm20608g/ICM20608G.cpp @@ -45,13 +45,13 @@ ICM20608G::ICM20608G(I2CSPIBusOption bus_option, int bus, uint32_t device, enum SPI(MODULE_NAME, nullptr, bus, device, spi_mode, bus_frequency), I2CSPIDriver(MODULE_NAME, px4::device_bus_to_wq(get_device_id()), bus_option, bus), _drdy_gpio(drdy_gpio), - _px4_accel(get_device_id(), ORB_PRIO_VERY_HIGH, rotation), - _px4_gyro(get_device_id(), ORB_PRIO_VERY_HIGH, rotation) + _px4_accel(get_device_id(), ORB_PRIO_HIGH, rotation), + _px4_gyro(get_device_id(), ORB_PRIO_HIGH, rotation) { - set_device_type(DRV_IMU_DEVTYPE_ICM20608); + set_device_type(DRV_IMU_DEVTYPE_ICM20608G); - _px4_accel.set_device_type(DRV_IMU_DEVTYPE_ICM20608); - _px4_gyro.set_device_type(DRV_IMU_DEVTYPE_ICM20608); + _px4_accel.set_device_type(DRV_IMU_DEVTYPE_ICM20608G); + _px4_gyro.set_device_type(DRV_IMU_DEVTYPE_ICM20608G); ConfigureSampleRate(_px4_gyro.get_max_rate_hz()); } @@ -131,7 +131,7 @@ void ICM20608G::RunImpl() RegisterWrite(Register::PWR_MGMT_1, PWR_MGMT_1_BIT::DEVICE_RESET); _reset_timestamp = hrt_absolute_time(); _state = STATE::WAIT_FOR_RESET; - ScheduleDelayed(100); + ScheduleDelayed(1_ms); break; case STATE::WAIT_FOR_RESET: @@ -147,14 +147,14 @@ void ICM20608G::RunImpl() } else { // RESET not complete - if (hrt_elapsed_time(&_reset_timestamp) > 10_ms) { - PX4_ERR("Reset failed, retrying"); + if (hrt_elapsed_time(&_reset_timestamp) > 100_ms) { + PX4_DEBUG("Reset failed, retrying"); _state = STATE::RESET; - ScheduleDelayed(10_ms); + ScheduleDelayed(100_ms); } else { - PX4_DEBUG("Reset not complete, check again in 1 ms"); - ScheduleDelayed(1_ms); + PX4_DEBUG("Reset not complete, check again in 10 ms"); + ScheduleDelayed(10_ms); } } @@ -180,8 +180,8 @@ void ICM20608G::RunImpl() } else { PX4_DEBUG("Configure failed, retrying"); - // try again in 1 ms - ScheduleDelayed(1_ms); + // try again in 10 ms + ScheduleDelayed(10_ms); } break; @@ -195,7 +195,14 @@ void ICM20608G::RunImpl() ScheduleDelayed(10_ms); // timestamp set in data ready interrupt - samples = _fifo_read_samples.load(); + if (!_force_fifo_count_check) { + samples = _fifo_read_samples.load(); + + } else { + const uint16_t fifo_count = FIFOReadCount(); + samples = (fifo_count / sizeof(FIFO::DATA) / SAMPLES_PER_TRANSFER) * SAMPLES_PER_TRANSFER; // round down to nearest + } + timestamp_sample = _fifo_watermark_interrupt_timestamp; } @@ -208,13 +215,7 @@ void ICM20608G::RunImpl() // use the time now roughly corresponding with the last sample we'll pull from the FIFO timestamp_sample = hrt_absolute_time(); const uint16_t fifo_count = FIFOReadCount(); - - if (fifo_count == 0) { - failure = true; - perf_count(_fifo_empty_perf); - } - - samples = (fifo_count / sizeof(FIFO::DATA) / 2) * 2; // round down to nearest 2 + samples = (fifo_count / sizeof(FIFO::DATA) / SAMPLES_PER_TRANSFER) * SAMPLES_PER_TRANSFER; // round down to nearest } if (samples > FIFO_MAX_SAMPLES) { @@ -223,13 +224,17 @@ void ICM20608G::RunImpl() failure = true; FIFOReset(); - } else if (samples >= 2) { - // require at least 2 samples (we want at least 1 new accel sample per transfer) + } else if (samples >= SAMPLES_PER_TRANSFER) { + // require at least SAMPLES_PER_TRANSFER (we want at least 1 new accel sample per transfer) if (!FIFORead(timestamp_sample, samples)) { failure = true; _px4_accel.increase_error_count(); _px4_gyro.increase_error_count(); } + + } else if (samples == 0) { + failure = true; + perf_count(_fifo_empty_perf); } if (failure || hrt_elapsed_time(&_last_config_check_timestamp) > 10_ms) { @@ -264,22 +269,22 @@ void ICM20608G::ConfigureAccel() switch (ACCEL_FS_SEL) { case ACCEL_FS_SEL_2G: - _px4_accel.set_scale(CONSTANTS_ONE_G / 16384); + _px4_accel.set_scale(CONSTANTS_ONE_G / 16384.f); _px4_accel.set_range(2 * CONSTANTS_ONE_G); break; case ACCEL_FS_SEL_4G: - _px4_accel.set_scale(CONSTANTS_ONE_G / 8192); + _px4_accel.set_scale(CONSTANTS_ONE_G / 8192.f); _px4_accel.set_range(4 * CONSTANTS_ONE_G); break; case ACCEL_FS_SEL_8G: - _px4_accel.set_scale(CONSTANTS_ONE_G / 4096); + _px4_accel.set_scale(CONSTANTS_ONE_G / 4096.f); _px4_accel.set_range(8 * CONSTANTS_ONE_G); break; case ACCEL_FS_SEL_16G: - _px4_accel.set_scale(CONSTANTS_ONE_G / 2048); + _px4_accel.set_scale(CONSTANTS_ONE_G / 2048.f); _px4_accel.set_range(16 * CONSTANTS_ONE_G); break; } @@ -291,23 +296,23 @@ void ICM20608G::ConfigureGyro() switch (FS_SEL) { case FS_SEL_250_DPS: - _px4_gyro.set_scale(math::radians(1.0f / 131.f)); + _px4_gyro.set_scale(math::radians(1.f / 131.f)); _px4_gyro.set_range(math::radians(250.f)); break; case FS_SEL_500_DPS: - _px4_gyro.set_scale(math::radians(1.0f / 65.5f)); + _px4_gyro.set_scale(math::radians(1.f / 65.5f)); _px4_gyro.set_range(math::radians(500.f)); break; case FS_SEL_1000_DPS: - _px4_gyro.set_scale(math::radians(1.0f / 32.8f)); - _px4_gyro.set_range(math::radians(1000.0f)); + _px4_gyro.set_scale(math::radians(1.f / 32.8f)); + _px4_gyro.set_range(math::radians(1000.f)); break; case FS_SEL_2000_DPS: - _px4_gyro.set_scale(math::radians(1.0f / 16.4f)); - _px4_gyro.set_range(math::radians(2000.0f)); + _px4_gyro.set_scale(math::radians(1.f / 16.4f)); + _px4_gyro.set_range(math::radians(2000.f)); break; } } @@ -318,16 +323,19 @@ void ICM20608G::ConfigureSampleRate(int sample_rate) sample_rate = 1000; // default to 1 kHz } - _fifo_empty_interval_us = math::max(((1000000 / sample_rate) / 250) * 250, 250); // round down to nearest 250 us - _fifo_gyro_samples = math::min(_fifo_empty_interval_us / (1000000 / GYRO_RATE), FIFO_MAX_SAMPLES); + // round down to nearest FIFO sample dt * SAMPLES_PER_TRANSFER + const float min_interval = SAMPLES_PER_TRANSFER * FIFO_SAMPLE_DT; + _fifo_empty_interval_us = math::max(roundf((1e6f / (float)sample_rate) / min_interval) * min_interval, min_interval); + + _fifo_gyro_samples = math::min((float)_fifo_empty_interval_us / (1e6f / GYRO_RATE), (float)FIFO_MAX_SAMPLES); // recompute FIFO empty interval (us) with actual gyro sample limit - _fifo_empty_interval_us = _fifo_gyro_samples * (1000000 / GYRO_RATE); + _fifo_empty_interval_us = _fifo_gyro_samples * (1e6f / GYRO_RATE); - _fifo_accel_samples = math::min(_fifo_empty_interval_us / (1000000 / ACCEL_RATE), FIFO_MAX_SAMPLES); + _fifo_accel_samples = math::min(_fifo_empty_interval_us / (1e6f / ACCEL_RATE), (float)FIFO_MAX_SAMPLES); - _px4_accel.set_update_rate(1000000 / _fifo_empty_interval_us); - _px4_gyro.set_update_rate(1000000 / _fifo_empty_interval_us); + _px4_accel.set_update_rate(1e6f / _fifo_empty_interval_us); + _px4_gyro.set_update_rate(1e6f / _fifo_empty_interval_us); } bool ICM20608G::Configure() @@ -354,14 +362,14 @@ int ICM20608G::DataReadyInterruptCallback(int irq, void *context, void *arg) void ICM20608G::DataReady() { + perf_count(_drdy_interval_perf); + if (_data_ready_count.fetch_add(1) >= (_fifo_gyro_samples - 1)) { _data_ready_count.store(0); _fifo_watermark_interrupt_timestamp = hrt_absolute_time(); _fifo_read_samples.store(_fifo_gyro_samples); ScheduleNow(); } - - perf_count(_drdy_interval_perf); } bool ICM20608G::DataReadyInterruptConfigure() @@ -370,8 +378,8 @@ bool ICM20608G::DataReadyInterruptConfigure() return false; } - // Setup data ready on rising edge - return px4_arch_gpiosetevent(_drdy_gpio, true, false, true, &ICM20608G::DataReadyInterruptCallback, this) == 0; + // Setup data ready on falling edge + return px4_arch_gpiosetevent(_drdy_gpio, false, true, true, &ICM20608G::DataReadyInterruptCallback, this) == 0; } bool ICM20608G::DataReadyInterruptDisable() @@ -389,12 +397,12 @@ bool ICM20608G::RegisterCheck(const register_config_t ®_cfg, bool notify) const uint8_t reg_value = RegisterRead(reg_cfg.reg); - if (reg_cfg.set_bits && !(reg_value & reg_cfg.set_bits)) { + if (reg_cfg.set_bits && ((reg_value & reg_cfg.set_bits) != reg_cfg.set_bits)) { PX4_DEBUG("0x%02hhX: 0x%02hhX (0x%02hhX not set)", (uint8_t)reg_cfg.reg, reg_value, reg_cfg.set_bits); success = false; } - if (reg_cfg.clear_bits && (reg_value & reg_cfg.clear_bits)) { + if (reg_cfg.clear_bits && ((reg_value & reg_cfg.clear_bits) != 0)) { PX4_DEBUG("0x%02hhX: 0x%02hhX (0x%02hhX not cleared)", (uint8_t)reg_cfg.reg, reg_value, reg_cfg.clear_bits); success = false; } @@ -402,13 +410,6 @@ bool ICM20608G::RegisterCheck(const register_config_t ®_cfg, bool notify) if (!success) { RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits); - if (reg_cfg.reg == Register::ACCEL_CONFIG) { - ConfigureAccel(); - - } else if (reg_cfg.reg == Register::GYRO_CONFIG) { - ConfigureGyro(); - } - if (notify) { perf_count(_bad_register_perf); _px4_accel.increase_error_count(); @@ -449,16 +450,6 @@ void ICM20608G::RegisterSetAndClearBits(Register reg, uint8_t setbits, uint8_t c RegisterWrite(reg, val); } -void ICM20608G::RegisterSetBits(Register reg, uint8_t setbits) -{ - RegisterSetAndClearBits(reg, setbits, 0); -} - -void ICM20608G::RegisterClearBits(Register reg, uint8_t clearbits) -{ - RegisterSetAndClearBits(reg, 0, clearbits); -} - uint16_t ICM20608G::FIFOReadCount() { // read FIFO count @@ -477,7 +468,7 @@ bool ICM20608G::FIFORead(const hrt_abstime ×tamp_sample, uint16_t samples) { perf_begin(_transfer_perf); FIFOTransferBuffer buffer{}; - const size_t transfer_size = math::min(samples * sizeof(FIFO::DATA) + 1, FIFO::SIZE); + const size_t transfer_size = math::min(samples * sizeof(FIFO::DATA) + 3, FIFO::SIZE); if (transfer((uint8_t *)&buffer, (uint8_t *)&buffer, transfer_size) != PX4_OK) { perf_end(_transfer_perf); @@ -487,8 +478,41 @@ bool ICM20608G::FIFORead(const hrt_abstime ×tamp_sample, uint16_t samples) perf_end(_transfer_perf); - ProcessGyro(timestamp_sample, buffer, samples); - return ProcessAccel(timestamp_sample, buffer, samples); + const uint16_t fifo_count_bytes = combine(buffer.FIFO_COUNTH, buffer.FIFO_COUNTL); + const uint16_t fifo_count_samples = fifo_count_bytes / sizeof(FIFO::DATA); + + if (fifo_count_samples == 0) { + perf_count(_fifo_empty_perf); + return false; + } + + if (fifo_count_bytes >= FIFO::SIZE) { + perf_count(_fifo_overflow_perf); + FIFOReset(); + return false; + } + + const uint16_t valid_samples = math::min(samples, fifo_count_samples); + + if (fifo_count_samples < samples) { + // force check if there is somehow fewer samples actually in the FIFO (potentially a serious error) + _force_fifo_count_check = true; + + } else if (fifo_count_samples > samples + 4) { + // if we're more than a few samples behind force FIFO_COUNT check + _force_fifo_count_check = true; + + } else { + // skip earlier FIFO_COUNT and trust DRDY count if we're in sync + _force_fifo_count_check = false; + } + + if (valid_samples > 0) { + ProcessGyro(timestamp_sample, buffer, valid_samples); + return ProcessAccel(timestamp_sample, buffer, valid_samples); + } + + return false; } void ICM20608G::FIFOReset() @@ -498,9 +522,8 @@ void ICM20608G::FIFOReset() // FIFO_EN: disable FIFO RegisterWrite(Register::FIFO_EN, 0); - // USER_CTRL: disable FIFO and reset all signal paths - RegisterSetAndClearBits(Register::USER_CTRL, USER_CTRL_BIT::FIFO_RST | USER_CTRL_BIT::SIG_COND_RST, - USER_CTRL_BIT::FIFO_EN); + // USER_CTRL: reset FIFO + RegisterSetAndClearBits(Register::USER_CTRL, USER_CTRL_BIT::FIFO_RST, USER_CTRL_BIT::FIFO_EN); // reset while FIFO is disabled _data_ready_count.store(0); @@ -521,7 +544,8 @@ static bool fifo_accel_equal(const FIFO::DATA &f0, const FIFO::DATA &f1) return (memcmp(&f0.ACCEL_XOUT_H, &f1.ACCEL_XOUT_H, 6) == 0); } -bool ICM20608G::ProcessAccel(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, uint8_t samples) +bool ICM20608G::ProcessAccel(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, + const uint8_t samples) { PX4Accelerometer::FIFOSample accel; accel.timestamp_sample = timestamp_sample; @@ -532,8 +556,8 @@ bool ICM20608G::ProcessAccel(const hrt_abstime ×tamp_sample, const FIFOTran // accel data is doubled in FIFO, but might be shifted int accel_first_sample = 1; - if (samples >= 3) { - if (fifo_accel_equal(buffer.f[0], buffer.f[1])) { + if (samples >= 4) { + if (fifo_accel_equal(buffer.f[0], buffer.f[1]) && fifo_accel_equal(buffer.f[2], buffer.f[3])) { // [A0, A1, A2, A3] // A0==A1, A2==A3 accel_first_sample = 1; @@ -572,7 +596,8 @@ bool ICM20608G::ProcessAccel(const hrt_abstime ×tamp_sample, const FIFOTran return !bad_data; } -void ICM20608G::ProcessGyro(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, uint8_t samples) +void ICM20608G::ProcessGyro(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, + const uint8_t samples) { PX4Gyroscope::FIFOSample gyro; gyro.timestamp_sample = timestamp_sample; diff --git a/src/drivers/imu/invensense/icm20608g/ICM20608G.hpp b/src/drivers/imu/invensense/icm20608g/ICM20608G.hpp index e3cd8eda03..c920a37d3e 100644 --- a/src/drivers/imu/invensense/icm20608g/ICM20608G.hpp +++ b/src/drivers/imu/invensense/icm20608g/ICM20608G.hpp @@ -76,19 +76,23 @@ protected: void custom_method(const BusCLIArguments &cli) override; void exit_and_cleanup() override; private: - // Sensor Configuration - static constexpr uint32_t GYRO_RATE{8000}; // 8 kHz gyro - static constexpr uint32_t ACCEL_RATE{4000}; // 4 kHz accel - static constexpr uint32_t FIFO_MAX_SAMPLES{ math::min(FIFO::SIZE / sizeof(FIFO::DATA) + 1, sizeof(PX4Gyroscope::FIFOSample::x) / sizeof(PX4Gyroscope::FIFOSample::x[0]))}; + static constexpr float FIFO_SAMPLE_DT{125.f}; + static constexpr uint32_t SAMPLES_PER_TRANSFER{2}; // ensure at least 1 new accel sample per transfer + static constexpr float GYRO_RATE{1e6f / FIFO_SAMPLE_DT}; // 8 kHz gyro + static constexpr float ACCEL_RATE{GYRO_RATE / 2.f}; // 4 kHz accel + + static constexpr uint32_t FIFO_MAX_SAMPLES{math::min(FIFO::SIZE / sizeof(FIFO::DATA), sizeof(PX4Gyroscope::FIFOSample::x) / sizeof(PX4Gyroscope::FIFOSample::x[0]))}; // Transfer data struct FIFOTransferBuffer { - uint8_t cmd{static_cast(Register::FIFO_R_W) | DIR_READ}; + uint8_t cmd{static_cast(Register::FIFO_COUNTH) | DIR_READ}; + uint8_t FIFO_COUNTH{0}; + uint8_t FIFO_COUNTL{0}; FIFO::DATA f[FIFO_MAX_SAMPLES] {}; }; // ensure no struct padding - static_assert(sizeof(FIFOTransferBuffer) == (sizeof(uint8_t) + FIFO_MAX_SAMPLES *sizeof(FIFO::DATA))); + static_assert(sizeof(FIFOTransferBuffer) == (3 + FIFO_MAX_SAMPLES *sizeof(FIFO::DATA))); struct register_config_t { Register reg; @@ -113,15 +117,15 @@ private: uint8_t RegisterRead(Register reg); void RegisterWrite(Register reg, uint8_t value); void RegisterSetAndClearBits(Register reg, uint8_t setbits, uint8_t clearbits); - void RegisterSetBits(Register reg, uint8_t setbits); - void RegisterClearBits(Register reg, uint8_t clearbits); + void RegisterSetBits(Register reg, uint8_t setbits) { RegisterSetAndClearBits(reg, setbits, 0); } + void RegisterClearBits(Register reg, uint8_t clearbits) { RegisterSetAndClearBits(reg, 0, clearbits); } uint16_t FIFOReadCount(); bool FIFORead(const hrt_abstime ×tamp_sample, uint16_t samples); void FIFOReset(); - bool ProcessAccel(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, uint8_t samples); - void ProcessGyro(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, uint8_t samples); + bool ProcessAccel(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, const uint8_t samples); + void ProcessGyro(const hrt_abstime ×tamp_sample, const FIFOTransferBuffer &buffer, const uint8_t samples); void UpdateTemperature(); const spi_drdy_gpio_t _drdy_gpio; @@ -145,7 +149,7 @@ private: px4::atomic _data_ready_count{0}; px4::atomic _fifo_read_samples{0}; bool _data_ready_interrupt_enabled{false}; - uint8_t _checked_register{0}; + bool _force_fifo_count_check{true}; enum class STATE : uint8_t { RESET, @@ -156,20 +160,22 @@ private: STATE _state{STATE::RESET}; - uint16_t _fifo_empty_interval_us{1000}; // 1000 us / 1000 Hz transfer interval + uint16_t _fifo_empty_interval_us{1000}; // default 1000 us / 1000 Hz transfer interval uint8_t _fifo_gyro_samples{static_cast(_fifo_empty_interval_us / (1000000 / GYRO_RATE))}; uint8_t _fifo_accel_samples{static_cast(_fifo_empty_interval_us / (1000000 / ACCEL_RATE))}; - static constexpr uint8_t size_register_cfg{11}; + uint8_t _checked_register{0}; + static constexpr uint8_t size_register_cfg{9}; register_config_t _register_cfg[size_register_cfg] { // Register | Set bits, Clear bits { Register::PWR_MGMT_1, PWR_MGMT_1_BIT::CLKSEL_0, PWR_MGMT_1_BIT::DEVICE_RESET | PWR_MGMT_1_BIT::SLEEP }, { Register::ACCEL_CONFIG, ACCEL_CONFIG_BIT::ACCEL_FS_SEL_16G, 0 }, { Register::ACCEL_CONFIG2, ACCEL_CONFIG2_BIT::ACCEL_FCHOICE_B_BYPASS_DLPF, 0 }, { Register::GYRO_CONFIG, GYRO_CONFIG_BIT::FS_SEL_2000_DPS, GYRO_CONFIG_BIT::FCHOICE_B_8KHZ_BYPASS_DLPF }, - { Register::CONFIG, CONFIG_BIT::DLPF_CFG_BYPASS_DLPF_8KHZ, Bit7 | CONFIG_BIT::FIFO_MODE }, + { Register::CONFIG, CONFIG_BIT::FIFO_MODE | CONFIG_BIT::DLPF_CFG_BYPASS_DLPF_8KHZ, 0 }, { Register::USER_CTRL, USER_CTRL_BIT::FIFO_EN | USER_CTRL_BIT::I2C_IF_DIS, USER_CTRL_BIT::FIFO_RST | USER_CTRL_BIT::SIG_COND_RST }, { Register::FIFO_EN, FIFO_EN_BIT::XG_FIFO_EN | FIFO_EN_BIT::YG_FIFO_EN | FIFO_EN_BIT::ZG_FIFO_EN | FIFO_EN_BIT::ACCEL_FIFO_EN, FIFO_EN_BIT::TEMP_FIFO_EN }, + { Register::INT_PIN_CFG, INT_PIN_CFG_BIT::INT_LEVEL, 0 }, { Register::INT_ENABLE, INT_ENABLE_BIT::DATA_RDY_INT_EN, 0 } }; }; diff --git a/src/drivers/imu/invensense/icm20608g/InvenSense_ICM20608G_registers.hpp b/src/drivers/imu/invensense/icm20608g/InvenSense_ICM20608G_registers.hpp index aabf112f00..ffd156a5c0 100644 --- a/src/drivers/imu/invensense/icm20608g/InvenSense_ICM20608G_registers.hpp +++ b/src/drivers/imu/invensense/icm20608g/InvenSense_ICM20608G_registers.hpp @@ -70,6 +70,7 @@ enum class Register : uint8_t { FIFO_EN = 0x23, + INT_PIN_CFG = 0x37, INT_ENABLE = 0x38, TEMP_OUT_H = 0x41, @@ -126,9 +127,13 @@ enum FIFO_EN_BIT : uint8_t { ACCEL_FIFO_EN = Bit3, }; +// INT_PIN_CFG +enum INT_PIN_CFG_BIT : uint8_t { + INT_LEVEL = Bit7, +}; + // INT_ENABLE enum INT_ENABLE_BIT : uint8_t { - FIFO_OFLOW_EN = Bit4, DATA_RDY_INT_EN = Bit0 }; diff --git a/src/drivers/imu/invensense/icm20608g/icm20608g_main.cpp b/src/drivers/imu/invensense/icm20608g/icm20608g_main.cpp index 426b8dd3ef..5f321e2c6c 100644 --- a/src/drivers/imu/invensense/icm20608g/icm20608g_main.cpp +++ b/src/drivers/imu/invensense/icm20608g/icm20608g_main.cpp @@ -94,7 +94,7 @@ extern "C" int icm20608g_main(int argc, char *argv[]) return -1; } - BusInstanceIterator iterator(MODULE_NAME, cli, DRV_IMU_DEVTYPE_ICM20608); + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_IMU_DEVTYPE_ICM20608G); if (!strcmp(verb, "start")) { return ThisDriver::module_start(cli, iterator); diff --git a/src/drivers/imu/mpu6000/MPU6000.cpp b/src/drivers/imu/mpu6000/MPU6000.cpp index 0ad22a695b..49100394f2 100644 --- a/src/drivers/imu/mpu6000/MPU6000.cpp +++ b/src/drivers/imu/mpu6000/MPU6000.cpp @@ -65,8 +65,8 @@ MPU6000::MPU6000(device::Device *interface, enum Rotation rotation, int device_t break; case MPU_DEVICE_TYPE_ICM20608: - _px4_accel.set_device_type(DRV_IMU_DEVTYPE_ICM20608); - _px4_gyro.set_device_type(DRV_IMU_DEVTYPE_ICM20608); + _px4_accel.set_device_type(DRV_IMU_DEVTYPE_ICM20608G); + _px4_gyro.set_device_type(DRV_IMU_DEVTYPE_ICM20608G); break; case MPU_DEVICE_TYPE_ICM20689: diff --git a/src/drivers/imu/mpu6000/mpu6000_main.cpp b/src/drivers/imu/mpu6000/mpu6000_main.cpp index fe7c6f3728..adde91207f 100644 --- a/src/drivers/imu/mpu6000/mpu6000_main.cpp +++ b/src/drivers/imu/mpu6000/mpu6000_main.cpp @@ -162,7 +162,7 @@ mpu6000_main(int argc, char *argv[]) break; case MPU_DEVICE_TYPE_ICM20608: - dev_type_driver = DRV_IMU_DEVTYPE_ICM20608; + dev_type_driver = DRV_IMU_DEVTYPE_ICM20608G; break; case MPU_DEVICE_TYPE_ICM20689: diff --git a/src/lib/parameters/param_translation.cpp b/src/lib/parameters/param_translation.cpp index f0a58f4c80..929491b893 100644 --- a/src/lib/parameters/param_translation.cpp +++ b/src/lib/parameters/param_translation.cpp @@ -127,7 +127,7 @@ bool param_modify_on_import(const char *name, bson_type_t type, void *value) } if (device_id.devid_s.devtype == DRV_ACC_DEVTYPE_ICM20608_LEGACY) { - device_id.devid_s.devtype = DRV_IMU_DEVTYPE_ICM20608; + device_id.devid_s.devtype = DRV_IMU_DEVTYPE_ICM20608G; } if (device_id.devid_s.devtype == DRV_ACC_DEVTYPE_ICM20689_LEGACY) {