From e20215087f7bec80649ff1d5a6e86c059089e732 Mon Sep 17 00:00:00 2001 From: Eric Katzfey Date: Thu, 7 Mar 2024 15:11:37 -0800 Subject: [PATCH] Moving from Qurt specific icm4266p driver to mainline version --- boards/modalai/voxl2-slpi/default.px4board | 1 + boards/modalai/voxl2-slpi/src/CMakeLists.txt | 1 - .../src/drivers/icm42688p/CMakeLists.txt | 48 - .../src/drivers/icm42688p/ICM42688P.cpp | 991 ------------------ .../src/drivers/icm42688p/ICM42688P.hpp | 235 ----- .../InvenSense_ICM42688P_registers.hpp | 430 -------- .../src/drivers/icm42688p/icm42688p_main.cpp | 116 -- .../imu/invensense/icm42688p/ICM42688P.hpp | 2 +- 8 files changed, 2 insertions(+), 1822 deletions(-) delete mode 100644 boards/modalai/voxl2-slpi/src/drivers/icm42688p/CMakeLists.txt delete mode 100644 boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.cpp delete mode 100644 boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.hpp delete mode 100644 boards/modalai/voxl2-slpi/src/drivers/icm42688p/InvenSense_ICM42688P_registers.hpp delete mode 100644 boards/modalai/voxl2-slpi/src/drivers/icm42688p/icm42688p_main.cpp diff --git a/boards/modalai/voxl2-slpi/default.px4board b/boards/modalai/voxl2-slpi/default.px4board index 23cf292adedb..0182f68babc4 100644 --- a/boards/modalai/voxl2-slpi/default.px4board +++ b/boards/modalai/voxl2-slpi/default.px4board @@ -4,6 +4,7 @@ CONFIG_DRIVERS_ACTUATORS_VOXL_ESC=y CONFIG_DRIVERS_BAROMETER_INVENSENSE_ICP101XX=y CONFIG_DRIVERS_DISTANCE_SENSOR_VL53L0X=y CONFIG_DRIVERS_DISTANCE_SENSOR_VL53L1X=y +CONFIG_DRIVERS_IMU_INVENSENSE_ICM42688P=y CONFIG_DRIVERS_LIGHTS_RGBLED_NCP5623C=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8308=y CONFIG_DRIVERS_MAGNETOMETER_ISENTEK_IST8310=y diff --git a/boards/modalai/voxl2-slpi/src/CMakeLists.txt b/boards/modalai/voxl2-slpi/src/CMakeLists.txt index f23a75ebf115..bb35ef068a33 100644 --- a/boards/modalai/voxl2-slpi/src/CMakeLists.txt +++ b/boards/modalai/voxl2-slpi/src/CMakeLists.txt @@ -44,7 +44,6 @@ add_library(drivers_board ) # Add custom drivers for SLPI -# add_subdirectory(${PX4_BOARD_DIR}/src/drivers/icm42688p) add_subdirectory(${PX4_BOARD_DIR}/src/drivers/rc_controller) add_subdirectory(${PX4_BOARD_DIR}/src/drivers/mavlink_rc_in) # add_subdirectory(${PX4_BOARD_DIR}/src/drivers/spektrum_rc) diff --git a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/CMakeLists.txt b/boards/modalai/voxl2-slpi/src/drivers/icm42688p/CMakeLists.txt deleted file mode 100644 index 1f8e2102a5d9..000000000000 --- a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -############################################################################ -# -# Copyright (c) 2020 PX4 Development Team. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. -# 3. Neither the name PX4 nor the names of its contributors may be -# used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# -############################################################################ -px4_add_module( - MODULE drivers__imu__invensense__icm42688p - MAIN icm42688p - COMPILE_FLAGS - ${MAX_CUSTOM_OPT_LEVEL} - SRCS - icm42688p_main.cpp - ICM42688P.cpp - ICM42688P.hpp - InvenSense_ICM42688P_registers.hpp - DEPENDS - px4_work_queue - drivers_accelerometer - drivers_gyroscope - drivers__device - ) diff --git a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.cpp b/boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.cpp deleted file mode 100644 index 50c26171e3dc..000000000000 --- a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.cpp +++ /dev/null @@ -1,991 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2020 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#include "ICM42688P.hpp" - -bool hitl_mode = false; - -using namespace time_literals; - -static constexpr int16_t combine(uint8_t msb, uint8_t lsb) -{ - return (msb << 8u) | lsb; -} - -ICM42688P::ICM42688P(const I2CSPIDriverConfig &config) : - // SPI(DRV_IMU_DEVTYPE_ICM42688P, MODULE_NAME, bus, device, spi_mode, bus_frequency), - // I2CSPIDriver(MODULE_NAME, px4::device_bus_to_wq(get_device_id()), bus_option, bus), - // _drdy_gpio(drdy_gpio) - SPI(config), - I2CSPIDriver(config), - _drdy_gpio(config.drdy_gpio), - _px4_accel(get_device_id(), config.rotation), - _px4_gyro(get_device_id(), config.rotation) -{ - if (config.drdy_gpio != 0) { - _drdy_missed_perf = perf_alloc(PC_COUNT, MODULE_NAME": DRDY missed"); - } - - if (!hitl_mode) { - // _px4_accel = std::make_shared(get_device_id(), rotation); - // _px4_gyro = std::make_shared(get_device_id(), rotation); - ConfigureSampleRate(_px4_gyro.get_max_rate_hz()); - // _imu_server_pub.advertise(); - - } else { - ConfigureSampleRate(0); - } -} - -ICM42688P::~ICM42688P() -{ - perf_free(_bad_register_perf); - perf_free(_bad_transfer_perf); - perf_free(_fifo_empty_perf); - perf_free(_fifo_overflow_perf); - perf_free(_fifo_reset_perf); - perf_free(_drdy_missed_perf); - - // if (!hitl_mode){ - // _imu_server_pub.unadvertise(); - // } -} - -int ICM42688P::init() -{ - int ret = SPI::init(); - - if (ret != PX4_OK) { - DEVICE_DEBUG("SPI::init failed (%i)", ret); - return ret; - } - - return Reset() ? 0 : -1; -} - -bool ICM42688P::Reset() -{ - _state = STATE::RESET; - DataReadyInterruptDisable(); - ScheduleClear(); - ScheduleNow(); - return true; -} - -void ICM42688P::exit_and_cleanup() -{ - DataReadyInterruptDisable(); - I2CSPIDriverBase::exit_and_cleanup(); -} - -void ICM42688P::print_status() -{ - I2CSPIDriverBase::print_status(); - - PX4_INFO("FIFO empty interval: %d us (%.1f Hz)", _fifo_empty_interval_us, 1e6 / _fifo_empty_interval_us); - - perf_print_counter(_bad_register_perf); - perf_print_counter(_bad_transfer_perf); - perf_print_counter(_fifo_empty_perf); - perf_print_counter(_fifo_overflow_perf); - perf_print_counter(_fifo_reset_perf); - perf_print_counter(_drdy_missed_perf); -} - -int ICM42688P::probe() -{ - for (int i = 0; i < 3; i++) { - uint8_t whoami = RegisterRead(Register::BANK_0::WHO_AM_I); - - if (whoami == WHOAMI) { - PX4_INFO("ICM42688P::probe successful!"); - return PX4_OK; - - } else { - DEVICE_DEBUG("unexpected WHO_AM_I 0x%02x", whoami); - - uint8_t reg_bank_sel = RegisterRead(Register::BANK_0::REG_BANK_SEL); - int bank = reg_bank_sel >> 4; - - if (bank >= 1 && bank <= 3) { - DEVICE_DEBUG("incorrect register bank for WHO_AM_I REG_BANK_SEL:0x%02x, bank:%d", reg_bank_sel, bank); - // force bank selection and retry - SelectRegisterBank(REG_BANK_SEL_BIT::USER_BANK_0, true); - } - } - } - - return PX4_ERROR; -} - -void ICM42688P::RunImpl() -{ - PX4_INFO(">>> ICM42688P this: %p", this); - - const hrt_abstime now = hrt_absolute_time(); - - switch (_state) { - case STATE::RESET: - // DEVICE_CONFIG: Software reset configuration - RegisterWrite(Register::BANK_0::DEVICE_CONFIG, DEVICE_CONFIG_BIT::SOFT_RESET_CONFIG); - _reset_timestamp = now; - _failure_count = 0; - _state = STATE::WAIT_FOR_RESET; - ScheduleDelayed(2_ms); // to be safe wait 2 ms for soft reset to be effective - break; - - case STATE::WAIT_FOR_RESET: - if ((RegisterRead(Register::BANK_0::WHO_AM_I) == WHOAMI) - && (RegisterRead(Register::BANK_0::DEVICE_CONFIG) == 0x00) - && (RegisterRead(Register::BANK_0::INT_STATUS) & INT_STATUS_BIT::RESET_DONE_INT)) { - - _state = STATE::CONFIGURE; - ScheduleDelayed(10_ms); // 30 ms gyro startup time, 10 ms accel from sleep to valid data - - } else { - // RESET not complete - if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) { - PX4_DEBUG("Reset failed, retrying"); - _state = STATE::RESET; - ScheduleDelayed(100_ms); - - } else { - PX4_DEBUG("Reset not complete, check again in 10 ms"); - ScheduleDelayed(10_ms); - } - } - - break; - - case STATE::CONFIGURE: - - if (Configure()) { - - // Wakeup accel and gyro after configuring registers - ScheduleDelayed(1_ms); // add a delay here to be safe - RegisterWrite(Register::BANK_0::PWR_MGMT0, PWR_MGMT0_BIT::GYRO_MODE_LOW_NOISE | PWR_MGMT0_BIT::ACCEL_MODE_LOW_NOISE); - ScheduleDelayed(30_ms); // 30 ms gyro startup time, 10 ms accel from sleep to valid data - - // if configure succeeded then start reading from FIFO - _state = STATE::FIFO_READ; - - if (DataReadyInterruptConfigure()) { - _data_ready_interrupt_enabled = true; - - // backup schedule as a watchdog timeout - ScheduleDelayed(100_ms); - - } else { - PX4_ERR("ICM42688P::RunImpl interrupt configuration failed"); - - _data_ready_interrupt_enabled = false; - ScheduleOnInterval(_fifo_empty_interval_us, _fifo_empty_interval_us); - } - - FIFOReset(); - - } else { - - PX4_ERR("ICM42688P::RunImpl configuration failed"); - - // CONFIGURE not complete - if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) { - PX4_DEBUG("Configure failed, resetting"); - _state = STATE::RESET; - - } else { - PX4_DEBUG("Configure failed, retrying"); - } - - ScheduleDelayed(100_ms); - } - - break; - - case STATE::FIFO_READ: { -#ifndef __PX4_QURT - uint32_t samples = 0; - - if (_data_ready_interrupt_enabled) { - // scheduled from interrupt if _drdy_fifo_read_samples was set as expected - if (_drdy_fifo_read_samples.fetch_and(0) != _fifo_gyro_samples) { - perf_count(_drdy_missed_perf); - - } else { - samples = _fifo_gyro_samples; - } - - // push backup schedule back - ScheduleDelayed(_fifo_empty_interval_us * 2); - } - - if (samples == 0) { - // check current FIFO count - const uint16_t fifo_count = FIFOReadCount(); - - if (fifo_count >= FIFO::SIZE) { - FIFOReset(); - perf_count(_fifo_overflow_perf); - - } else if (fifo_count == 0) { - perf_count(_fifo_empty_perf); - - } else { - // FIFO count (size in bytes) - samples = (fifo_count / sizeof(FIFO::DATA)); - - if (samples > FIFO_MAX_SAMPLES) { - // not technically an overflow, but more samples than we expected or can publish - FIFOReset(); - perf_count(_fifo_overflow_perf); - samples = 0; - } - } - } - - bool success = false; - - if (samples >= 1) { - if (FIFORead(now, samples)) { - success = true; - - if (_failure_count > 0) { - _failure_count--; - } - } - } - - if (!success) { - _failure_count++; - - // full reset if things are failing consistently - if (_failure_count > 10) { - Reset(); - return; - } - } - - // check configuration registers periodically or immediately following any failure - if (RegisterCheck(_register_bank0_cfg[_checked_register_bank0]) - && RegisterCheck(_register_bank1_cfg[_checked_register_bank1]) - && RegisterCheck(_register_bank2_cfg[_checked_register_bank2]) - ) { - _last_config_check_timestamp = now; - _checked_register_bank0 = (_checked_register_bank0 + 1) % size_register_bank0_cfg; - _checked_register_bank1 = (_checked_register_bank1 + 1) % size_register_bank1_cfg; - _checked_register_bank2 = (_checked_register_bank2 + 1) % size_register_bank2_cfg; - - } else { - // register check failed, force reset - perf_count(_bad_register_perf); - Reset(); - } - -#endif - } - - break; - } -} - -void ICM42688P::ConfigureSampleRate(int sample_rate) -{ - if (sample_rate == 0) { - sample_rate = 800; // default to 800 Hz - } - - // round down to nearest FIFO sample dt - const float min_interval = FIFO_SAMPLE_DT; - _fifo_empty_interval_us = math::max(roundf((1e6f / (float)sample_rate) / min_interval) * min_interval, min_interval); - - _fifo_gyro_samples = roundf(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 * (1e6f / GYRO_RATE); - - ConfigureFIFOWatermark(_fifo_gyro_samples); -} - -void ICM42688P::ConfigureFIFOWatermark(uint8_t samples) -{ - // FIFO watermark threshold in number of bytes - const uint16_t fifo_watermark_threshold = samples * sizeof(FIFO::DATA); - - for (auto &r : _register_bank0_cfg) { - if (r.reg == Register::BANK_0::FIFO_CONFIG2) { - // FIFO_WM[7:0] FIFO_CONFIG2 - r.set_bits = fifo_watermark_threshold & 0xFF; - - } else if (r.reg == Register::BANK_0::FIFO_CONFIG3) { - // FIFO_WM[11:8] FIFO_CONFIG3 - r.set_bits = (fifo_watermark_threshold >> 8) & 0x0F; - } - } -} - -void ICM42688P::SelectRegisterBank(enum REG_BANK_SEL_BIT bank, bool force) -{ - if (bank != _last_register_bank || force) { - // select BANK_0 - uint8_t cmd_bank_sel[2] {}; - cmd_bank_sel[0] = static_cast(Register::BANK_0::REG_BANK_SEL); - cmd_bank_sel[1] = bank; - transfer(cmd_bank_sel, cmd_bank_sel, sizeof(cmd_bank_sel)); - - _last_register_bank = bank; - } -} - -bool ICM42688P::Configure() -{ - // first set and clear all configured register bits - for (const auto ®_cfg : _register_bank0_cfg) { - RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits); - } - - for (const auto ®_cfg : _register_bank1_cfg) { - RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits); - } - - for (const auto ®_cfg : _register_bank2_cfg) { - RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits); - } - - // now check that all are configured - bool success = true; - - for (const auto ®_cfg : _register_bank0_cfg) { - if (!RegisterCheck(reg_cfg)) { - success = false; - } - } - - for (const auto ®_cfg : _register_bank1_cfg) { - if (!RegisterCheck(reg_cfg)) { - success = false; - } - } - - for (const auto ®_cfg : _register_bank2_cfg) { - if (!RegisterCheck(reg_cfg)) { - success = false; - } - } - - // // 20-bits data format used - // // the only FSR settings that are operational are ±2000dps for gyroscope and ±16g for accelerometer - if (!hitl_mode) { - _px4_accel.set_range(16.f * CONSTANTS_ONE_G); - _px4_accel.set_scale(CONSTANTS_ONE_G / 8192.f); - _px4_gyro.set_range(math::radians(2000.f)); - _px4_gyro.set_scale(math::radians(1.f / 131.f)); - } - - return success; -} - -static bool interrupt_debug = false; -static uint32_t interrupt_debug_count = 0; -static const uint32_t interrupt_debug_trigger = 800; -static hrt_abstime last_interrupt_time = 0; -static hrt_abstime avg_interrupt_delta = 0; -static hrt_abstime max_interrupt_delta = 0; -static hrt_abstime min_interrupt_delta = 60 * 1000 * 1000; -static hrt_abstime cumulative_interrupt_delta = 0; - -int ICM42688P::DataReadyInterruptCallback(int irq, void *context, void *arg) -{ - hrt_abstime current_interrupt_time = hrt_absolute_time(); - - if (interrupt_debug) { - if (last_interrupt_time) { - hrt_abstime interrupt_delta_time = current_interrupt_time - last_interrupt_time; - - if (interrupt_delta_time > max_interrupt_delta) { max_interrupt_delta = interrupt_delta_time; } - - if (interrupt_delta_time < min_interrupt_delta) { min_interrupt_delta = interrupt_delta_time; } - - cumulative_interrupt_delta += interrupt_delta_time; - } - - last_interrupt_time = current_interrupt_time; - - interrupt_debug_count++; - - if (interrupt_debug_count == interrupt_debug_trigger) { - avg_interrupt_delta = cumulative_interrupt_delta / interrupt_debug_trigger; - PX4_INFO(">>> Max: %llu, Min: %llu, Avg: %llu", max_interrupt_delta, - min_interrupt_delta, avg_interrupt_delta); - interrupt_debug_count = 0; - cumulative_interrupt_delta = 0; - } - } - - static_cast(arg)->DataReady(); - - return 0; -} - -void ICM42688P::DataReady() -{ -#ifndef __PX4_QURT - uint32_t expected = 0; - - if (_drdy_fifo_read_samples.compare_exchange(&expected, _fifo_gyro_samples)) { - ScheduleNow(); - } - -#else - uint16_t fifo_byte_count = FIFOReadCount(); - - FIFORead(hrt_absolute_time(), fifo_byte_count / sizeof(FIFO::DATA)); -#endif -} - -bool ICM42688P::DataReadyInterruptConfigure() -{ - if (_drdy_gpio == 0) { - return false; - } - - // Setup data ready on falling edge - return px4_arch_gpiosetevent(_drdy_gpio, false, true, true, &DataReadyInterruptCallback, this) == 0; -} - -bool ICM42688P::DataReadyInterruptDisable() -{ - if (_drdy_gpio == 0) { - return false; - } - - return px4_arch_gpiosetevent(_drdy_gpio, false, false, false, nullptr, nullptr) == 0; -} - -template -bool ICM42688P::RegisterCheck(const T ®_cfg) -{ - bool success = true; - - const uint8_t reg_value = RegisterRead(reg_cfg.reg); - - 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) != 0)) { - PX4_DEBUG("0x%02hhX: 0x%02hhX (0x%02hhX not cleared)", (uint8_t)reg_cfg.reg, reg_value, reg_cfg.clear_bits); - success = false; - } - - return success; -} - -template -uint8_t ICM42688P::RegisterRead(T reg) -{ - uint8_t cmd[2] {}; - cmd[0] = static_cast(reg) | DIR_READ; - SelectRegisterBank(reg); - transfer(cmd, cmd, sizeof(cmd)); - return cmd[1]; -} - -template -void ICM42688P::RegisterWrite(T reg, uint8_t value) -{ - uint8_t cmd[2] { (uint8_t)reg, value }; - SelectRegisterBank(reg); - transfer(cmd, cmd, sizeof(cmd)); -} - -template -void ICM42688P::RegisterSetAndClearBits(T reg, uint8_t setbits, uint8_t clearbits) -{ - const uint8_t orig_val = RegisterRead(reg); - - uint8_t val = (orig_val & ~clearbits) | setbits; - - if (orig_val != val) { - RegisterWrite(reg, val); - } -} - -uint16_t ICM42688P::FIFOReadCount() -{ - // read FIFO count - uint8_t fifo_count_buf[3] {}; - fifo_count_buf[0] = static_cast(Register::BANK_0::FIFO_COUNTH) | DIR_READ; - SelectRegisterBank(REG_BANK_SEL_BIT::USER_BANK_0); - - if (transfer(fifo_count_buf, fifo_count_buf, sizeof(fifo_count_buf)) != PX4_OK) { - perf_count(_bad_transfer_perf); - return 0; - } - - return combine(fifo_count_buf[1], fifo_count_buf[2]); -} - -// static uint32_t debug_decimator = 0; -// static hrt_abstime last_sample_time = 0; -// static bool imu_debug = true; - -bool ICM42688P::FIFORead(const hrt_abstime ×tamp_sample, uint16_t samples) -{ - FIFOTransferBuffer buffer{}; - const size_t max_transfer_size = 10 * sizeof(FIFO::DATA) + 4; - const size_t transfer_size = math::min(samples * sizeof(FIFO::DATA) + 4, max_transfer_size); - SelectRegisterBank(REG_BANK_SEL_BIT::USER_BANK_0); - - if (transfer((uint8_t *)&buffer, (uint8_t *)&buffer, transfer_size) != PX4_OK) { - perf_count(_bad_transfer_perf); - return false; - } - - if (buffer.INT_STATUS & INT_STATUS_BIT::FIFO_FULL_INT) { - perf_count(_fifo_overflow_perf); - FIFOReset(); - return false; - } - - const uint16_t fifo_count_bytes = combine(buffer.FIFO_COUNTH, buffer.FIFO_COUNTL); - - if (fifo_count_bytes >= FIFO::SIZE) { - perf_count(_fifo_overflow_perf); - FIFOReset(); - return false; - } - - const uint16_t fifo_count_samples = fifo_count_bytes / sizeof(FIFO::DATA); - - if (fifo_count_samples == 0) { - perf_count(_fifo_empty_perf); - return false; - } - - // check FIFO header in every sample - uint16_t valid_samples = 0; - - // for (int i = 0; i < math::min(samples, fifo_count_samples); i++) { - for (int i = 0; i < math::min(samples, (uint16_t) 10); i++) { - bool valid = true; - - // With FIFO_ACCEL_EN and FIFO_GYRO_EN header should be 8’b_0110_10xx - const uint8_t FIFO_HEADER = buffer.f[i].FIFO_Header; - - if (FIFO_HEADER & FIFO::FIFO_HEADER_BIT::HEADER_MSG) { - // FIFO sample empty if HEADER_MSG set - valid = false; - - } else if (!(FIFO_HEADER & FIFO::FIFO_HEADER_BIT::HEADER_ACCEL)) { - // accel bit not set - valid = false; - - } else if (!(FIFO_HEADER & FIFO::FIFO_HEADER_BIT::HEADER_GYRO)) { - // gyro bit not set - valid = false; - - } else if (!(FIFO_HEADER & FIFO::FIFO_HEADER_BIT::HEADER_20)) { - // Packet does not contain a new and valid extended 20-bit data - valid = false; - - } else if (FIFO_HEADER & FIFO::FIFO_HEADER_BIT::HEADER_ODR_ACCEL) { - // accel ODR changed - valid = false; - - } else if (FIFO_HEADER & FIFO::FIFO_HEADER_BIT::HEADER_ODR_GYRO) { - // gyro ODR changed - valid = false; - } - - if (valid) { - valid_samples++; - - } else { - perf_count(_bad_transfer_perf); - break; - } - } - - // if (imu_debug) { - // debug_decimator++; - // if (debug_decimator == 801) { - // debug_decimator = 0; - // PX4_INFO("Initial: %u Next: %u Valid: %u Delta: %llu", samples, fifo_count_samples, valid_samples, timestamp_sample - last_sample_time); - // } - // last_sample_time = timestamp_sample; - // } - - if (valid_samples > 0) { - if (ProcessTemperature(buffer.f, valid_samples)) { - ProcessGyro(timestamp_sample, buffer.f, valid_samples); - ProcessAccel(timestamp_sample, buffer.f, valid_samples); - ProcessIMU(timestamp_sample, buffer.f, valid_samples); - return true; - } - } - - return false; -} - -void ICM42688P::FIFOReset() -{ - perf_count(_fifo_reset_perf); - - // SIGNAL_PATH_RESET: FIFO flush - RegisterSetBits(Register::BANK_0::SIGNAL_PATH_RESET, SIGNAL_PATH_RESET_BIT::FIFO_FLUSH); - - // reset while FIFO is disabled - _drdy_fifo_read_samples.store(0); -} - -static constexpr int32_t reassemble_20bit(const uint32_t a, const uint32_t b, const uint32_t c) -{ - // 0xXXXAABBC - uint32_t high = ((a << 12) & 0x000FF000); - uint32_t low = ((b << 4) & 0x00000FF0); - uint32_t lowest = (c & 0x0000000F); - - uint32_t x = high | low | lowest; - - if (a & Bit7) { - // sign extend - x |= 0xFFF00000u; - } - - return static_cast(x); -} - -void ICM42688P::ProcessIMU(const hrt_abstime ×tamp_sample, const FIFO::DATA fifo[], const uint8_t samples) -{ - float accel_x = 0.0, accel_y = 0.0, accel_z = 0.0; - float gyro_x = 0.0, gyro_y = 0.0, gyro_z = 0.0; - - for (int i = 0; i < samples; i++) { - _imu_server_decimator++; - - if (_imu_server_decimator == 8) { - _imu_server_decimator = 0; - // 20 bit hires mode - - // Sign extension + Accel [19:12] + Accel [11:4] + Accel [3:2] (20 bit extension byte) - // Accel data is 18 bit - int32_t temp_accel_x = reassemble_20bit(fifo[i].ACCEL_DATA_X1, fifo[i].ACCEL_DATA_X0, - fifo[i].Ext_Accel_X_Gyro_X & 0xF0 >> 4); - int32_t temp_accel_y = reassemble_20bit(fifo[i].ACCEL_DATA_Y1, fifo[i].ACCEL_DATA_Y0, - fifo[i].Ext_Accel_Y_Gyro_Y & 0xF0 >> 4); - int32_t temp_accel_z = reassemble_20bit(fifo[i].ACCEL_DATA_Z1, fifo[i].ACCEL_DATA_Z0, - fifo[i].Ext_Accel_Z_Gyro_Z & 0xF0 >> 4); - - // Gyro [19:12] + Gyro [11:4] + Gyro [3:0] (bottom 4 bits of 20 bit extension byte) - int32_t temp_gyro_x = reassemble_20bit(fifo[i].GYRO_DATA_X1, fifo[i].GYRO_DATA_X0, - fifo[i].Ext_Accel_X_Gyro_X & 0x0F); - int32_t temp_gyro_y = reassemble_20bit(fifo[i].GYRO_DATA_Y1, fifo[i].GYRO_DATA_Y0, - fifo[i].Ext_Accel_Y_Gyro_Y & 0x0F); - int32_t temp_gyro_z = reassemble_20bit(fifo[i].GYRO_DATA_Z1, fifo[i].GYRO_DATA_Z0, - fifo[i].Ext_Accel_Z_Gyro_Z & 0x0F); - - // accel samples invalid if -524288 - if (temp_accel_x != -524288 && temp_accel_y != -524288 && temp_accel_z != -524288) { - // shift accel by 2 (2 least significant bits are always 0) - accel_x = (float) temp_accel_x / 4.f; - accel_y = (float) temp_accel_y / 4.f; - accel_z = (float) temp_accel_z / 4.f; - - // shift gyro by 1 (least significant bit is always 0) - gyro_x = (float) temp_gyro_x / 2.f; - gyro_y = (float) temp_gyro_y / 2.f; - gyro_z = (float) temp_gyro_z / 2.f; - - // correct frame for publication - // sensor's frame is +x forward, +y left, +z up - // flip y & z to publish right handed with z down (x forward, y right, z down) - accel_y = -accel_y; - accel_z = -accel_z; - gyro_y = -gyro_y; - gyro_z = -gyro_z; - - // Scale everything appropriately - float accel_scale_factor = (CONSTANTS_ONE_G / 8192.f); - accel_x *= accel_scale_factor; - accel_y *= accel_scale_factor; - accel_z *= accel_scale_factor; - - float gyro_scale_factor = math::radians(1.f / 131.f); - gyro_x *= gyro_scale_factor; - gyro_y *= gyro_scale_factor; - gyro_z *= gyro_scale_factor; - - // Store the data in our array - _imu_server_data.accel_x[_imu_server_index] = accel_x; - _imu_server_data.accel_y[_imu_server_index] = accel_y; - _imu_server_data.accel_z[_imu_server_index] = accel_z; - _imu_server_data.gyro_x[_imu_server_index] = gyro_x; - _imu_server_data.gyro_y[_imu_server_index] = gyro_y; - _imu_server_data.gyro_z[_imu_server_index] = gyro_z; - _imu_server_data.ts[_imu_server_index] = timestamp_sample - (125 * (samples - 1 - i)); - _imu_server_index++; - - // If array is full, publish the data - if (_imu_server_index == 10) { - _imu_server_index = 0; - _imu_server_data.timestamp = hrt_absolute_time(); - _imu_server_data.temperature = 0; // Not used right now - _imu_server_pub.publish(_imu_server_data); - } - } - } - } -} - -void ICM42688P::ProcessAccel(const hrt_abstime ×tamp_sample, const FIFO::DATA fifo[], const uint8_t samples) -{ - sensor_accel_fifo_s accel{}; - accel.timestamp_sample = timestamp_sample; - accel.samples = 0; - accel.dt = FIFO_SAMPLE_DT; - - // 18-bits of accelerometer data - bool scale_20bit = false; - - // first pass - for (int i = 0; i < samples; i++) { - // 20 bit hires mode - // Sign extension + Accel [19:12] + Accel [11:4] + Accel [3:2] (20 bit extension byte) - // Accel data is 18 bit () - int32_t accel_x = reassemble_20bit(fifo[i].ACCEL_DATA_X1, fifo[i].ACCEL_DATA_X0, - fifo[i].Ext_Accel_X_Gyro_X & 0xF0 >> 4); - int32_t accel_y = reassemble_20bit(fifo[i].ACCEL_DATA_Y1, fifo[i].ACCEL_DATA_Y0, - fifo[i].Ext_Accel_Y_Gyro_Y & 0xF0 >> 4); - int32_t accel_z = reassemble_20bit(fifo[i].ACCEL_DATA_Z1, fifo[i].ACCEL_DATA_Z0, - fifo[i].Ext_Accel_Z_Gyro_Z & 0xF0 >> 4); - - // sample invalid if -524288 - if (accel_x != -524288 && accel_y != -524288 && accel_z != -524288) { - // check if any values are going to exceed int16 limits - static constexpr int16_t max_accel = INT16_MAX; - static constexpr int16_t min_accel = INT16_MIN; - - if (accel_x >= max_accel || accel_x <= min_accel) { - scale_20bit = true; - } - - if (accel_y >= max_accel || accel_y <= min_accel) { - scale_20bit = true; - } - - if (accel_z >= max_accel || accel_z <= min_accel) { - scale_20bit = true; - } - - // shift by 2 (2 least significant bits are always 0) - accel.x[accel.samples] = accel_x / 4; - accel.y[accel.samples] = accel_y / 4; - accel.z[accel.samples] = accel_z / 4; - accel.samples++; - } - } - - if (!scale_20bit) { - // if highres enabled accel data is always 8192 LSB/g - if (!hitl_mode) { - _px4_accel.set_scale(CONSTANTS_ONE_G / 8192.f); - } - - } else { - // 20 bit data scaled to 16 bit (2^4) - for (int i = 0; i < samples; i++) { - // 20 bit hires mode - // Sign extension + Accel [19:12] + Accel [11:4] + Accel [3:2] (20 bit extension byte) - // Accel data is 18 bit () - int16_t accel_x = combine(fifo[i].ACCEL_DATA_X1, fifo[i].ACCEL_DATA_X0); - int16_t accel_y = combine(fifo[i].ACCEL_DATA_Y1, fifo[i].ACCEL_DATA_Y0); - int16_t accel_z = combine(fifo[i].ACCEL_DATA_Z1, fifo[i].ACCEL_DATA_Z0); - - accel.x[i] = accel_x; - accel.y[i] = accel_y; - accel.z[i] = accel_z; - } - - if (!hitl_mode) { - _px4_accel.set_scale(CONSTANTS_ONE_G / 2048.f); - } - } - - // correct frame for publication - for (int i = 0; i < accel.samples; i++) { - // sensor's frame is +x forward, +y left, +z up - // flip y & z to publish right handed with z down (x forward, y right, z down) - accel.x[i] = accel.x[i]; - accel.y[i] = (accel.y[i] == INT16_MIN) ? INT16_MAX : -accel.y[i]; - accel.z[i] = (accel.z[i] == INT16_MIN) ? INT16_MAX : -accel.z[i]; - } - - if (!hitl_mode) { - _px4_accel.set_error_count(perf_event_count(_bad_register_perf) + perf_event_count(_bad_transfer_perf) + - perf_event_count(_fifo_empty_perf) + perf_event_count(_fifo_overflow_perf)); - } - - if (accel.samples > 0) { - if (!hitl_mode) { - _px4_accel.updateFIFO(accel); - } - } -} - -void ICM42688P::ProcessGyro(const hrt_abstime ×tamp_sample, const FIFO::DATA fifo[], const uint8_t samples) -{ - sensor_gyro_fifo_s gyro{}; - gyro.timestamp_sample = timestamp_sample; - gyro.samples = 0; - gyro.dt = FIFO_SAMPLE_DT; - - // 20-bits of gyroscope data - bool scale_20bit = false; - - // first pass - for (int i = 0; i < samples; i++) { - // 20 bit hires mode - // Gyro [19:12] + Gyro [11:4] + Gyro [3:0] (bottom 4 bits of 20 bit extension byte) - int32_t gyro_x = reassemble_20bit(fifo[i].GYRO_DATA_X1, fifo[i].GYRO_DATA_X0, fifo[i].Ext_Accel_X_Gyro_X & 0x0F); - int32_t gyro_y = reassemble_20bit(fifo[i].GYRO_DATA_Y1, fifo[i].GYRO_DATA_Y0, fifo[i].Ext_Accel_Y_Gyro_Y & 0x0F); - int32_t gyro_z = reassemble_20bit(fifo[i].GYRO_DATA_Z1, fifo[i].GYRO_DATA_Z0, fifo[i].Ext_Accel_Z_Gyro_Z & 0x0F); - - // check if any values are going to exceed int16 limits - static constexpr int16_t max_gyro = INT16_MAX; - static constexpr int16_t min_gyro = INT16_MIN; - - if (gyro_x >= max_gyro || gyro_x <= min_gyro) { - scale_20bit = true; - } - - if (gyro_y >= max_gyro || gyro_y <= min_gyro) { - scale_20bit = true; - } - - if (gyro_z >= max_gyro || gyro_z <= min_gyro) { - scale_20bit = true; - } - - gyro.x[gyro.samples] = gyro_x / 2; - gyro.y[gyro.samples] = gyro_y / 2; - gyro.z[gyro.samples] = gyro_z / 2; - gyro.samples++; - } - - if (!scale_20bit) { - // if highres enabled gyro data is always 131 LSB/dps - if (!hitl_mode) { - _px4_gyro.set_scale(math::radians(1.f / 131.f)); - } - - } else { - // 20 bit data scaled to 16 bit (2^4) - for (int i = 0; i < samples; i++) { - gyro.x[i] = combine(fifo[i].GYRO_DATA_X1, fifo[i].GYRO_DATA_X0); - gyro.y[i] = combine(fifo[i].GYRO_DATA_Y1, fifo[i].GYRO_DATA_Y0); - gyro.z[i] = combine(fifo[i].GYRO_DATA_Z1, fifo[i].GYRO_DATA_Z0); - } - - if (!hitl_mode) { - _px4_gyro.set_scale(math::radians(2000.f / 32768.f)); - } - } - - // correct frame for publication - for (int i = 0; i < gyro.samples; i++) { - // sensor's frame is +x forward, +y left, +z up - // flip y & z to publish right handed with z down (x forward, y right, z down) - gyro.x[i] = gyro.x[i]; - gyro.y[i] = (gyro.y[i] == INT16_MIN) ? INT16_MAX : -gyro.y[i]; - gyro.z[i] = (gyro.z[i] == INT16_MIN) ? INT16_MAX : -gyro.z[i]; - } - - if (!hitl_mode) { - _px4_gyro.set_error_count(perf_event_count(_bad_register_perf) + perf_event_count(_bad_transfer_perf) + - perf_event_count(_fifo_empty_perf) + perf_event_count(_fifo_overflow_perf)); - } - - if (gyro.samples > 0) { - if (!hitl_mode) { - _px4_gyro.updateFIFO(gyro); - } - } -} - -bool ICM42688P::ProcessTemperature(const FIFO::DATA fifo[], const uint8_t samples) -{ - int16_t temperature[FIFO_MAX_SAMPLES]; - float temperature_sum{0}; - - int valid_samples = 0; - - for (int i = 0; i < samples; i++) { - const int16_t t = combine(fifo[i].TEMP_DATA1, fifo[i].TEMP_DATA0); - - // sample invalid if -32768 - if (t != -32768) { - temperature_sum += t; - temperature[valid_samples] = t; - valid_samples++; - } - } - - if (valid_samples > 0) { - const float temperature_avg = temperature_sum / valid_samples; - - for (int i = 0; i < valid_samples; i++) { - // temperature changing wildly is an indication of a transfer error - if (fabsf(temperature[i] - temperature_avg) > 1000) { - perf_count(_bad_transfer_perf); - return false; - } - } - - // use average temperature reading - const float TEMP_degC = (temperature_avg / TEMPERATURE_SENSITIVITY) + TEMPERATURE_OFFSET; - - if (PX4_ISFINITE(TEMP_degC)) { - if (!hitl_mode) { - _px4_accel.set_temperature(TEMP_degC); - _px4_gyro.set_temperature(TEMP_degC); - return true; - } - - } else { - perf_count(_bad_transfer_perf); - } - } - - return false; -} diff --git a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.hpp b/boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.hpp deleted file mode 100644 index e5c63dd9f98a..000000000000 --- a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/ICM42688P.hpp +++ /dev/null @@ -1,235 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2020 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * @file ICM42688P.hpp - * - * Driver for the Invensense ICM42688P connected via SPI. - * - */ - -#pragma once - -#include "InvenSense_ICM42688P_registers.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace InvenSense_ICM42688P; - -extern bool hitl_mode; - -class ICM42688P : public device::SPI, public I2CSPIDriver -{ -public: - // ICM42688P(I2CSPIBusOption bus_option, int bus, uint32_t device, enum Rotation rotation, int bus_frequency, - // spi_mode_e spi_mode, spi_drdy_gpio_t drdy_gpio); - ICM42688P(const I2CSPIDriverConfig &config); - ~ICM42688P() override; - - // static I2CSPIDriverBase *instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, - // int runtime_instance); - static void print_usage(); - - void RunImpl(); - - int init() override; - void print_status() override; - -private: - void exit_and_cleanup() override; - - // Sensor Configuration - static constexpr float IMU_ODR{8000.f}; // 8kHz accel & gyro ODR configured - static constexpr float FIFO_SAMPLE_DT{1e6f / IMU_ODR}; - static constexpr float GYRO_RATE{1e6f / FIFO_SAMPLE_DT}; - static constexpr float ACCEL_RATE{1e6f / FIFO_SAMPLE_DT}; - - // maximum FIFO samples per transfer is limited to the size of sensor_accel_fifo/sensor_gyro_fifo - // static constexpr uint32_t FIFO_MAX_SAMPLES{math::min(math::min(FIFO::SIZE / sizeof(FIFO::DATA), sizeof(sensor_gyro_fifo_s::x) / sizeof(sensor_gyro_fifo_s::x[0])), sizeof(sensor_accel_fifo_s::x) / sizeof(sensor_accel_fifo_s::x[0]) * (int)(GYRO_RATE / ACCEL_RATE))}; - static constexpr uint32_t FIFO_MAX_SAMPLES{10}; - - // Transfer data - struct FIFOTransferBuffer { - uint8_t cmd{static_cast(Register::BANK_0::INT_STATUS) | DIR_READ}; - uint8_t INT_STATUS{0}; - uint8_t FIFO_COUNTH{0}; - uint8_t FIFO_COUNTL{0}; - FIFO::DATA f[FIFO_MAX_SAMPLES] {}; - }; - // ensure no struct padding - static_assert(sizeof(FIFOTransferBuffer) == (4 + FIFO_MAX_SAMPLES *sizeof(FIFO::DATA)), - "Invalid FIFOTransferBuffer size"); - - struct register_bank0_config_t { - Register::BANK_0 reg; - uint8_t set_bits{0}; - uint8_t clear_bits{0}; - }; - - struct register_bank1_config_t { - Register::BANK_1 reg; - uint8_t set_bits{0}; - uint8_t clear_bits{0}; - }; - - struct register_bank2_config_t { - Register::BANK_2 reg; - uint8_t set_bits{0}; - uint8_t clear_bits{0}; - }; - - int probe() override; - - bool Reset(); - - bool Configure(); - void ConfigureSampleRate(int sample_rate); - void ConfigureFIFOWatermark(uint8_t samples); - - void SelectRegisterBank(enum REG_BANK_SEL_BIT bank, bool force = false); - void SelectRegisterBank(Register::BANK_0 reg) { SelectRegisterBank(REG_BANK_SEL_BIT::USER_BANK_0); } - void SelectRegisterBank(Register::BANK_1 reg) { SelectRegisterBank(REG_BANK_SEL_BIT::USER_BANK_1); } - void SelectRegisterBank(Register::BANK_2 reg) { SelectRegisterBank(REG_BANK_SEL_BIT::USER_BANK_2); } - - static int DataReadyInterruptCallback(int irq, void *context, void *arg); - void DataReady(); - bool DataReadyInterruptConfigure(); - bool DataReadyInterruptDisable(); - - template bool RegisterCheck(const T ®_cfg); - template uint8_t RegisterRead(T reg); - template void RegisterWrite(T reg, uint8_t value); - template void RegisterSetAndClearBits(T reg, uint8_t setbits, uint8_t clearbits); - template void RegisterSetBits(T reg, uint8_t setbits) { RegisterSetAndClearBits(reg, setbits, 0); } - template void RegisterClearBits(T reg, uint8_t clearbits) { RegisterSetAndClearBits(reg, 0, clearbits); } - - uint16_t FIFOReadCount(); - bool FIFORead(const hrt_abstime ×tamp_sample, uint16_t samples); - void FIFOReset(); - - void ProcessIMU(const hrt_abstime ×tamp_sample, const FIFO::DATA fifo[], const uint8_t samples); - void ProcessAccel(const hrt_abstime ×tamp_sample, const FIFO::DATA fifo[], const uint8_t samples); - void ProcessGyro(const hrt_abstime ×tamp_sample, const FIFO::DATA fifo[], const uint8_t samples); - bool ProcessTemperature(const FIFO::DATA fifo[], const uint8_t samples); - - const spi_drdy_gpio_t _drdy_gpio; - - // std::shared_ptr _px4_accel; - // std::shared_ptr _px4_gyro; - PX4Accelerometer _px4_accel; - PX4Gyroscope _px4_gyro; - - perf_counter_t _bad_register_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad register")}; - perf_counter_t _bad_transfer_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad transfer")}; - perf_counter_t _fifo_empty_perf{perf_alloc(PC_COUNT, MODULE_NAME": FIFO empty")}; - perf_counter_t _fifo_overflow_perf{perf_alloc(PC_COUNT, MODULE_NAME": FIFO overflow")}; - perf_counter_t _fifo_reset_perf{perf_alloc(PC_COUNT, MODULE_NAME": FIFO reset")}; - perf_counter_t _drdy_missed_perf{nullptr}; - - hrt_abstime _reset_timestamp{0}; - hrt_abstime _last_config_check_timestamp{0}; - hrt_abstime _temperature_update_timestamp{0}; - int _failure_count{0}; - - enum REG_BANK_SEL_BIT _last_register_bank {REG_BANK_SEL_BIT::USER_BANK_0}; - - px4::atomic _drdy_fifo_read_samples{0}; - bool _data_ready_interrupt_enabled{false}; - - enum class STATE : uint8_t { - RESET, - WAIT_FOR_RESET, - CONFIGURE, - FIFO_READ, - } _state{STATE::RESET}; - - uint16_t _fifo_empty_interval_us{1250}; // default 1250 us / 800 Hz transfer interval - uint32_t _fifo_gyro_samples{static_cast(_fifo_empty_interval_us / (1000000 / GYRO_RATE))}; - - uint8_t _checked_register_bank0{0}; - static constexpr uint8_t size_register_bank0_cfg{12}; - register_bank0_config_t _register_bank0_cfg[size_register_bank0_cfg] { - // Register | Set bits, Clear bits - { Register::BANK_0::INT_CONFIG, INT_CONFIG_BIT::INT1_MODE | INT_CONFIG_BIT::INT1_DRIVE_CIRCUIT, INT_CONFIG_BIT::INT1_POLARITY }, - { Register::BANK_0::FIFO_CONFIG, FIFO_CONFIG_BIT::FIFO_MODE_STOP_ON_FULL, 0 }, - { Register::BANK_0::GYRO_CONFIG0, GYRO_CONFIG0_BIT::GYRO_FS_SEL_2000_DPS | GYRO_CONFIG0_BIT::GYRO_ODR_8KHZ_SET, GYRO_CONFIG0_BIT::GYRO_ODR_8KHZ_CLEAR }, - { Register::BANK_0::ACCEL_CONFIG0, ACCEL_CONFIG0_BIT::ACCEL_FS_SEL_16G | ACCEL_CONFIG0_BIT::ACCEL_ODR_8KHZ_SET, ACCEL_CONFIG0_BIT::ACCEL_ODR_8KHZ_CLEAR }, - { Register::BANK_0::GYRO_CONFIG1, 0, GYRO_CONFIG1_BIT::GYRO_UI_FILT_ORD }, - { Register::BANK_0::GYRO_ACCEL_CONFIG0, 0, GYRO_ACCEL_CONFIG0_BIT::ACCEL_UI_FILT_BW | GYRO_ACCEL_CONFIG0_BIT::GYRO_UI_FILT_BW }, - { Register::BANK_0::ACCEL_CONFIG1, 0, ACCEL_CONFIG1_BIT::ACCEL_UI_FILT_ORD }, - { Register::BANK_0::FIFO_CONFIG1, FIFO_CONFIG1_BIT::FIFO_WM_GT_TH | FIFO_CONFIG1_BIT::FIFO_HIRES_EN | FIFO_CONFIG1_BIT::FIFO_TEMP_EN | FIFO_CONFIG1_BIT::FIFO_GYRO_EN | FIFO_CONFIG1_BIT::FIFO_ACCEL_EN, 0 }, - { Register::BANK_0::FIFO_CONFIG2, 0, 0 }, // FIFO_WM[7:0] set at runtime - { Register::BANK_0::FIFO_CONFIG3, 0, 0 }, // FIFO_WM[11:8] set at runtime - { Register::BANK_0::INT_CONFIG0, INT_CONFIG0_BIT::CLEAR_ON_FIFO_READ, 0 }, - { Register::BANK_0::INT_SOURCE0, INT_SOURCE0_BIT::FIFO_THS_INT1_EN, 0 }, - }; - - uint8_t _checked_register_bank1{0}; - static constexpr uint8_t size_register_bank1_cfg{4}; - register_bank1_config_t _register_bank1_cfg[size_register_bank1_cfg] { - // Register | Set bits, Clear bits - { Register::BANK_1::GYRO_CONFIG_STATIC2, 0, GYRO_CONFIG_STATIC2_BIT::GYRO_NF_DIS | GYRO_CONFIG_STATIC2_BIT::GYRO_AAF_DIS }, - { Register::BANK_1::GYRO_CONFIG_STATIC3, GYRO_CONFIG_STATIC3_BIT::GYRO_AAF_DELT_SET, GYRO_CONFIG_STATIC3_BIT::GYRO_AAF_DELT_CLEAR}, - { Register::BANK_1::GYRO_CONFIG_STATIC4, GYRO_CONFIG_STATIC4_BIT::GYRO_AAF_DELTSQR_LOW_SET, GYRO_CONFIG_STATIC4_BIT::GYRO_AAF_DELTSQR_LOW_CLEAR}, - { Register::BANK_1::GYRO_CONFIG_STATIC5, GYRO_CONFIG_STATIC5_BIT::GYRO_AAF_BITSHIFT_SET | GYRO_CONFIG_STATIC5_BIT::GYRO_AAF_DELTSQR_HIGH_SET, GYRO_CONFIG_STATIC5_BIT::GYRO_AAF_BITSHIFT_CLEAR | GYRO_CONFIG_STATIC5_BIT::GYRO_AAF_DELTSQR_HIGH_CLEAR}, - }; - - uint8_t _checked_register_bank2{0}; - static constexpr uint8_t size_register_bank2_cfg{3}; - register_bank2_config_t _register_bank2_cfg[size_register_bank2_cfg] { - // Register | Set bits, Clear bits - { Register::BANK_2::ACCEL_CONFIG_STATIC2, ACCEL_CONFIG_STATIC2_BIT::ACCEL_AAF_DELT_SET, ACCEL_CONFIG_STATIC2_BIT::ACCEL_AAF_DELT_CLEAR | ACCEL_CONFIG_STATIC2_BIT::ACCEL_AAF_DIS }, - { Register::BANK_2::ACCEL_CONFIG_STATIC3, ACCEL_CONFIG_STATIC3_BIT::ACCEL_AAF_DELTSQR_LOW_SET, ACCEL_CONFIG_STATIC3_BIT::ACCEL_AAF_DELTSQR_LOW_CLEAR }, - { Register::BANK_2::ACCEL_CONFIG_STATIC4, ACCEL_CONFIG_STATIC4_BIT::ACCEL_AAF_BITSHIFT_SET | ACCEL_CONFIG_STATIC4_BIT::ACCEL_AAF_DELTSQR_HIGH_SET, ACCEL_CONFIG_STATIC4_BIT::ACCEL_AAF_BITSHIFT_CLEAR | ACCEL_CONFIG_STATIC4_BIT::ACCEL_AAF_DELTSQR_HIGH_CLEAR }, - }; - - uint32_t _temperature_samples{0}; - - // Support for the IMU server - uint32_t _imu_server_index{0}; - uint32_t _imu_server_decimator{0}; - imu_server_s _imu_server_data; - uORB::Publication _imu_server_pub{ORB_ID(imu_server)}; - -}; diff --git a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/InvenSense_ICM42688P_registers.hpp b/boards/modalai/voxl2-slpi/src/drivers/icm42688p/InvenSense_ICM42688P_registers.hpp deleted file mode 100644 index b3c020bd7619..000000000000 --- a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/InvenSense_ICM42688P_registers.hpp +++ /dev/null @@ -1,430 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2020 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/** - * @file InvenSense_ICM42688P_registers.hpp - * - * Invensense ICM-42688-P registers. - * - */ - -#pragma once - -#include - -namespace InvenSense_ICM42688P -{ -// TODO: move to a central header -static constexpr uint8_t Bit0 = (1 << 0); -static constexpr uint8_t Bit1 = (1 << 1); -static constexpr uint8_t Bit2 = (1 << 2); -static constexpr uint8_t Bit3 = (1 << 3); -static constexpr uint8_t Bit4 = (1 << 4); -static constexpr uint8_t Bit5 = (1 << 5); -static constexpr uint8_t Bit6 = (1 << 6); -static constexpr uint8_t Bit7 = (1 << 7); - -static constexpr uint32_t SPI_SPEED = 24 * 1000 * 1000; // 24 MHz SPI -static constexpr uint8_t DIR_READ = 0x80; - -static constexpr uint8_t WHOAMI = 0x47; - -static constexpr float TEMPERATURE_SENSITIVITY = 132.48f; // LSB/C -static constexpr float TEMPERATURE_OFFSET = 25.f; // C - -namespace Register -{ - -enum class BANK_0 : uint8_t { - DEVICE_CONFIG = 0x11, - - INT_CONFIG = 0x14, - - FIFO_CONFIG = 0x16, - - TEMP_DATA1 = 0x1D, - TEMP_DATA0 = 0x1E, - - INT_STATUS = 0x2D, - FIFO_COUNTH = 0x2E, - FIFO_COUNTL = 0x2F, - FIFO_DATA = 0x30, - - SIGNAL_PATH_RESET = 0x4B, - INTF_CONFIG0 = 0x4C, - INTF_CONFIG1 = 0x4D, - PWR_MGMT0 = 0x4E, - GYRO_CONFIG0 = 0x4F, - ACCEL_CONFIG0 = 0x50, - GYRO_CONFIG1 = 0x51, - GYRO_ACCEL_CONFIG0 = 0x52, - ACCEL_CONFIG1 = 0x53, - - FIFO_CONFIG1 = 0x5F, - FIFO_CONFIG2 = 0x60, - FIFO_CONFIG3 = 0x61, - - INT_CONFIG0 = 0x63, - - INT_SOURCE0 = 0x65, - - SELF_TEST_CONFIG = 0x70, - - WHO_AM_I = 0x75, - REG_BANK_SEL = 0x76, -}; - -enum class BANK_1 : uint8_t { - GYRO_CONFIG_STATIC2 = 0x0B, - GYRO_CONFIG_STATIC3 = 0x0C, - GYRO_CONFIG_STATIC4 = 0x0D, - GYRO_CONFIG_STATIC5 = 0x0E, - INTF_CONFIG5 = 0x7B, -}; -enum class BANK_2 : uint8_t { - ACCEL_CONFIG_STATIC2 = 0x03, - ACCEL_CONFIG_STATIC3 = 0x04, - ACCEL_CONFIG_STATIC4 = 0x05, -}; - -}; - -//---------------- BANK0 Register bits - -// DEVICE_CONFIG -enum DEVICE_CONFIG_BIT : uint8_t { - SOFT_RESET_CONFIG = Bit0, // -}; - -// INT_CONFIG -enum INT_CONFIG_BIT : uint8_t { - INT1_MODE = Bit2, - INT1_DRIVE_CIRCUIT = Bit1, - INT1_POLARITY = Bit0, -}; - -// FIFO_CONFIG -enum FIFO_CONFIG_BIT : uint8_t { - // 7:6 FIFO_MODE - FIFO_MODE_STOP_ON_FULL = Bit7 | Bit6, // 11: STOP-on-FULL Mode -}; - -// INT_STATUS -enum INT_STATUS_BIT : uint8_t { - RESET_DONE_INT = Bit4, - DATA_RDY_INT = Bit3, - FIFO_THS_INT = Bit2, - FIFO_FULL_INT = Bit1, -}; - -// SIGNAL_PATH_RESET -enum SIGNAL_PATH_RESET_BIT : uint8_t { - ABORT_AND_RESET = Bit3, - FIFO_FLUSH = Bit1, -}; - -// PWR_MGMT0 -enum PWR_MGMT0_BIT : uint8_t { - GYRO_MODE_LOW_NOISE = Bit3 | Bit2, // 11: Places gyroscope in Low Noise (LN) Mode - ACCEL_MODE_LOW_NOISE = Bit1 | Bit0, // 11: Places accelerometer in Low Noise (LN) Mode -}; - -// GYRO_CONFIG0 -enum GYRO_CONFIG0_BIT : uint8_t { - // 7:5 GYRO_FS_SEL - GYRO_FS_SEL_2000_DPS = 0, // 0b000 = ±2000dps (default) - GYRO_FS_SEL_1000_DPS = Bit5, - GYRO_FS_SEL_500_DPS = Bit6, - GYRO_FS_SEL_250_DPS = Bit6 | Bit5, - GYRO_FS_SEL_125_DPS = Bit7, - - - // 3:0 GYRO_ODR - // 0001: 32kHz - GYRO_ODR_32KHZ_SET = Bit0, - GYRO_ODR_32KHZ_CLEAR = Bit3 | Bit2 | Bit0, - // 0010: 16kHz - GYRO_ODR_16KHZ_SET = Bit1, - GYRO_ODR_16KHZ_CLEAR = Bit3 | Bit2 | Bit0, - // 0011: 8kHz - GYRO_ODR_8KHZ_SET = Bit1 | Bit0, - GYRO_ODR_8KHZ_CLEAR = Bit3 | Bit2, - // 0110: 1kHz (default) - GYRO_ODR_1KHZ_SET = Bit2 | Bit1, - GYRO_ODR_1KHZ_CLEAR = Bit3 | Bit0, -}; - -// ACCEL_CONFIG0 -enum ACCEL_CONFIG0_BIT : uint8_t { - // 7:5 ACCEL_FS_SEL - ACCEL_FS_SEL_16G = 0, // 000: ±16g (default) - ACCEL_FS_SEL_8G = Bit5, - ACCEL_FS_SEL_4G = Bit6, - ACCEL_FS_SEL_2G = Bit6 | Bit5, - - - // 3:0 ACCEL_ODR - // 0001: 32kHz - ACCEL_ODR_32KHZ_SET = Bit0, - ACCEL_ODR_32KHZ_CLEAR = Bit3 | Bit2 | Bit0, - // 0010: 16kHz - ACCEL_ODR_16KHZ_SET = Bit1, - ACCEL_ODR_16KHZ_CLEAR = Bit3 | Bit2 | Bit0, - // 0011: 8kHz - ACCEL_ODR_8KHZ_SET = Bit1 | Bit0, - ACCEL_ODR_8KHZ_CLEAR = Bit3 | Bit2, - // 0110: 1kHz (default) - ACCEL_ODR_1KHZ_SET = Bit2 | Bit1, - ACCEL_ODR_1KHZ_CLEAR = Bit3 | Bit0, -}; - -// GYRO_CONFIG1 -enum GYRO_CONFIG1_BIT : uint8_t { - GYRO_UI_FILT_ORD = Bit3 | Bit2, // 00: 1st Order -}; - -// GYRO_ACCEL_CONFIG0 -enum GYRO_ACCEL_CONFIG0_BIT : uint8_t { - // 7:4 ACCEL_UI_FILT_BW - ACCEL_UI_FILT_BW = Bit7 | Bit6 | Bit5 | Bit4, // 0: BW=ODR/2 - - // 3:0 GYRO_UI_FILT_BW - GYRO_UI_FILT_BW = Bit3 | Bit2 | Bit1 | Bit0, // 0: BW=ODR/2 -}; - -// ACCEL_CONFIG1 -enum ACCEL_CONFIG1_BIT : uint8_t { - ACCEL_UI_FILT_ORD = Bit4 | Bit3, // 00: 1st Order -}; - -// FIFO_CONFIG1 -enum FIFO_CONFIG1_BIT : uint8_t { - FIFO_RESUME_PARTIAL_RD = Bit6, - FIFO_WM_GT_TH = Bit5, - FIFO_HIRES_EN = Bit4, - FIFO_TEMP_EN = Bit2, - FIFO_GYRO_EN = Bit1, - FIFO_ACCEL_EN = Bit0, -}; - -// INT_CONFIG0 -enum INT_CONFIG0_BIT : uint8_t { - // 3:2 FIFO_THS_INT_CLEAR - CLEAR_ON_FIFO_READ = Bit3, -}; - -// INT_SOURCE0 -enum INT_SOURCE0_BIT : uint8_t { - UI_FSYNC_INT1_EN = Bit6, - PLL_RDY_INT1_EN = Bit5, - RESET_DONE_INT1_EN = Bit4, - UI_DRDY_INT1_EN = Bit3, - FIFO_THS_INT1_EN = Bit2, // FIFO threshold interrupt routed to INT1 - FIFO_FULL_INT1_EN = Bit1, - UI_AGC_RDY_INT1_EN = Bit0, -}; - -// REG_BANK_SEL -enum REG_BANK_SEL_BIT : uint8_t { - USER_BANK_0 = 0, // 0: Select USER BANK 0. - USER_BANK_1 = Bit0, // 1: Select USER BANK 1. - USER_BANK_2 = Bit1, // 2: Select USER BANK 2. - USER_BANK_3 = Bit1 | Bit0, // 3: Select USER BANK 3. -}; - - -//---------------- BANK1 Register bits - -// GYRO_CONFIG_STATIC2 -enum GYRO_CONFIG_STATIC2_BIT : uint8_t { - GYRO_AAF_DIS = Bit1, - GYRO_NF_DIS = Bit0, -}; - -// GYRO_CONFIG_STATIC3 -enum GYRO_CONFIG_STATIC3_BIT : uint8_t { - - // 585 Hz - GYRO_AAF_DELT_SET = Bit3 | Bit2 | Bit0, //13 - GYRO_AAF_DELT_CLEAR = Bit5 | Bit4 | Bit1, - - // 213 Hz - // GYRO_AAF_DELT_SET = Bit2 | Bit0, //5 - // GYRO_AAF_DELT_CLEAR = Bit5 | Bit4 | Bit3 | Bit1, - - // 126 Hz - //GYRO_AAF_DELT_SET = Bit1 | Bit0, //3 - //GYRO_AAF_DELT_CLEAR = Bit5 | Bit4 | Bit3 | Bit2, - - // 42 Hz - // GYRO_AAF_DELT_SET = Bit0, //1 - // GYRO_AAF_DELT_CLEAR = Bit5 | Bit4 | Bit3 | Bit2 | Bit1, - -}; - -// GYRO_CONFIG_STATIC4 -enum GYRO_CONFIG_STATIC4_BIT : uint8_t { - - // 585 Hz - GYRO_AAF_DELTSQR_LOW_SET = Bit7 | Bit5 | Bit3 | Bit1, //170 - GYRO_AAF_DELTSQR_LOW_CLEAR = Bit6 | Bit4 | Bit2 | Bit0, - - // 213 Hz - // GYRO_AAF_DELTSQR_LOW_SET = Bit4 | Bit3 | Bit0, //25 - // GYRO_AAF_DELTSQR_LOW_CLEAR = Bit7 | Bit6 | Bit5 | Bit2 | Bit1, - - // 126 Hz - //GYRO_AAF_DELTSQR_LOW_SET = Bit3 | Bit0, //9 - //GYRO_AAF_DELTSQR_LOW_CLEAR = Bit7 | Bit6 | Bit5 | Bit4 | Bit2 | Bit1, - - // 42 Hz - // GYRO_AAF_DELTSQR_LOW_SET = Bit0, //1 - // GYRO_AAF_DELTSQR_LOW_CLEAR = Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1, -}; - -// GYRO_CONFIG_STATIC5 -enum GYRO_CONFIG_STATIC5_BIT : uint8_t { - - // 585 Hz - GYRO_AAF_DELTSQR_HIGH_SET = 0, - GYRO_AAF_DELTSQR_HIGH_CLEAR = Bit3 | Bit2 | Bit1 | Bit0, - GYRO_AAF_BITSHIFT_SET = Bit7, // 8 << 4 - GYRO_AAF_BITSHIFT_CLEAR = Bit6 | Bit5 | Bit4, - - // 213 Hz - // GYRO_AAF_DELTSQR_HIGH_SET = 0, - // GYRO_AAF_DELTSQR_HIGH_CLEAR = Bit3 | Bit2 | Bit1 | Bit0, - // GYRO_AAF_BITSHIFT_SET = Bit7 | Bit5, //10 - // GYRO_AAF_BITSHIFT_CLEAR = Bit6 | Bit4, - - // 126 Hz - // GYRO_AAF_BITSHIFT_SET = Bit7 | Bit6, //12 - // GYRO_AAF_BITSHIFT_CLEAR = Bit5 | Bit4, - - // 42 Hz - // GYRO_AAF_BITSHIFT_SET = Bit7 | Bit6 | Bit5 | Bit4, //15 - // GYRO_AAF_BITSHIFT_CLEAR = 0, - - -}; - - -//---------------- BANK2 Register bits - -// ACCEL_CONFIG_STATIC2 -enum ACCEL_CONFIG_STATIC2_BIT : uint8_t { - ACCEL_AAF_DIS = Bit0, - ACCEL_AAF_DELT = Bit3 | Bit1, - - // 213 Hz - ACCEL_AAF_DELT_SET = Bit3 | Bit1, //5 - ACCEL_AAF_DELT_CLEAR = Bit6 | Bit5 | Bit4 | Bit2, - - // 42 Hz - // ACCEL_AAF_DELT_SET = Bit1, //1 - // ACCEL_AAF_DELT_CLEAR = Bit6 | Bit5 | Bit4 | Bit3 | Bit2, -}; - -// ACCEL_CONFIG_STATIC3 -enum ACCEL_CONFIG_STATIC3_BIT : uint8_t { - ACCEL_AAF_DELTSQR_LOW = Bit4 | Bit3 | Bit0, - // 213 Hz - ACCEL_AAF_DELTSQR_LOW_SET = Bit4 | Bit3 | Bit0, //25 - ACCEL_AAF_DELTSQR_LOW_CLEAR = Bit7 | Bit6 | Bit5 | Bit2 | Bit1, - - // 42 Hz - // ACCEL_AAF_DELTSQR_LOW_SET = Bit0, //1 - // ACCEL_AAF_DELTSQR_LOW_CLEAR = Bit7 | Bit6 | Bit5 | Bit4 | Bit3 | Bit2 | Bit1, - -}; - -// ACCEL_CONFIG_STATIC4 -enum ACCEL_CONFIG_STATIC4_BIT : uint8_t { - ACCEL_AAF_BITSHIFT = Bit7 | Bit5, - ACCEL_AAF_DELTSQR_HIGH = 0, - // 213 Hz - ACCEL_AAF_BITSHIFT_SET = Bit7 | Bit5, //10 - ACCEL_AAF_BITSHIFT_CLEAR = Bit6 | Bit4, - - // 42 Hz - // ACCEL_AAF_BITSHIFT_SET = Bit7 | Bit6 | Bit5 | Bit4, //15 - // ACCEL_AAF_BITSHIFT_CLEAR = 0, - - ACCEL_AAF_DELTSQR_HIGH_SET = 0, - ACCEL_AAF_DELTSQR_HIGH_CLEAR = Bit3 | Bit2 | Bit1 | Bit0, -}; - - -namespace FIFO -{ -static constexpr size_t SIZE = 2048; - -// FIFO_DATA layout when FIFO_CONFIG1 has FIFO_GYRO_EN and FIFO_ACCEL_EN set - -// Packet 4 -struct DATA { - uint8_t FIFO_Header; - uint8_t ACCEL_DATA_X1; // Accel X [19:12] - uint8_t ACCEL_DATA_X0; // Accel X [11:4] - uint8_t ACCEL_DATA_Y1; // Accel Y [19:12] - uint8_t ACCEL_DATA_Y0; // Accel Y [11:4] - uint8_t ACCEL_DATA_Z1; // Accel Z [19:12] - uint8_t ACCEL_DATA_Z0; // Accel Z [11:4] - uint8_t GYRO_DATA_X1; // Gyro X [19:12] - uint8_t GYRO_DATA_X0; // Gyro X [11:4] - uint8_t GYRO_DATA_Y1; // Gyro Y [19:12] - uint8_t GYRO_DATA_Y0; // Gyro Y [11:4] - uint8_t GYRO_DATA_Z1; // Gyro Z [19:12] - uint8_t GYRO_DATA_Z0; // Gyro Z [11:4] - uint8_t TEMP_DATA1; // Temperature[15:8] - uint8_t TEMP_DATA0; // Temperature[7:0] - uint8_t TimeStamp_h; // TimeStamp[15:8] - uint8_t TimeStamp_l; // TimeStamp[7:0] - uint8_t Ext_Accel_X_Gyro_X; // Accel X [3:0] Gyro X [3:0] - uint8_t Ext_Accel_Y_Gyro_Y; // Accel Y [3:0] Gyro Y [3:0] - uint8_t Ext_Accel_Z_Gyro_Z; // Accel Z [3:0] Gyro Z [3:0] -}; - -// With FIFO_ACCEL_EN and FIFO_GYRO_EN header should be 8’b_0110_10xx -enum FIFO_HEADER_BIT : uint8_t { - HEADER_MSG = Bit7, // 1: FIFO is empty - HEADER_ACCEL = Bit6, // 1: Packet is sized so that accel data have location in the packet, FIFO_ACCEL_EN must be 1 - HEADER_GYRO = Bit5, // 1: Packet is sized so that gyro data have location in the packet, FIFO_GYRO_EN must be1 - HEADER_20 = Bit4, // 1: Packet has a new and valid sample of extended 20-bit data for gyro and/or accel - HEADER_TIMESTAMP_FSYNC = Bit3 | Bit2, - HEADER_ODR_ACCEL = Bit1, // 1: The ODR for accel is different for this accel data packet compared to the previous accel packet - HEADER_ODR_GYRO = Bit0, // 1: The ODR for gyro is different for this gyro data packet compared to the previous gyro packet -}; - -} -} // namespace InvenSense_ICM42688P diff --git a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/icm42688p_main.cpp b/boards/modalai/voxl2-slpi/src/drivers/icm42688p/icm42688p_main.cpp deleted file mode 100644 index 38deecdf57cb..000000000000 --- a/boards/modalai/voxl2-slpi/src/drivers/icm42688p/icm42688p_main.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2020 PX4 Development Team. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name PX4 nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -#include "ICM42688P.hpp" - -#include -#include -#include - -void ICM42688P::print_usage() -{ - PRINT_MODULE_USAGE_NAME("icm42688p", "driver"); - PRINT_MODULE_USAGE_SUBCATEGORY("imu"); - PRINT_MODULE_USAGE_COMMAND("start"); - PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(false, true); - PRINT_MODULE_USAGE_PARAM_INT('R', 0, 0, 35, "Rotation", true); - PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); -} - -// I2CSPIDriverBase *ICM42688P::instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, -// int runtime_instance) -// { -// ICM42688P *instance = new ICM42688P(iterator.configuredBusOption(), iterator.bus(), iterator.devid(), cli.rotation, -// cli.bus_frequency, cli.spi_mode, iterator.DRDYGPIO()); -// -// if (!instance) { -// PX4_ERR("alloc failed"); -// return nullptr; -// } -// -// if (OK != instance->init()) { -// delete instance; -// return nullptr; -// } -// -// return instance; -// } - -extern "C" int icm42688p_main(int argc, char *argv[]) -{ - - for (int i = 0; i <= argc - 1; i++) { - if (std::string(argv[i]) == "-h") { - argv[i] = 0; - hitl_mode = true; - break; - } - } - - int ch; - using ThisDriver = ICM42688P; - BusCLIArguments cli{false, true}; - cli.default_spi_frequency = SPI_SPEED; - - while ((ch = cli.getOpt(argc, argv, "R:")) != EOF) { - switch (ch) { - case 'R': - cli.rotation = (enum Rotation)atoi(cli.optArg()); - break; - } - } - - const char *verb = cli.optArg(); - - if (!verb) { - ThisDriver::print_usage(); - return -1; - } - - BusInstanceIterator iterator(MODULE_NAME, cli, DRV_IMU_DEVTYPE_ICM42688P); - - if (!strcmp(verb, "start")) { - return ThisDriver::module_start(cli, iterator); - } - - if (!strcmp(verb, "stop")) { - return ThisDriver::module_stop(iterator); - } - - if (!strcmp(verb, "status")) { - return ThisDriver::module_status(iterator); - } - - ThisDriver::print_usage(); - return -1; -} diff --git a/src/drivers/imu/invensense/icm42688p/ICM42688P.hpp b/src/drivers/imu/invensense/icm42688p/ICM42688P.hpp index f8c938a5cdc3..a2fc22a9f2e0 100644 --- a/src/drivers/imu/invensense/icm42688p/ICM42688P.hpp +++ b/src/drivers/imu/invensense/icm42688p/ICM42688P.hpp @@ -88,7 +88,7 @@ class ICM42688P : public device::SPI, public I2CSPIDriver FIFO::DATA f[FIFO_MAX_SAMPLES] {}; }; // ensure no struct padding - static_assert(sizeof(FIFOTransferBuffer) == (4 + FIFO_MAX_SAMPLES *sizeof(FIFO::DATA))); + static_assert(sizeof(FIFOTransferBuffer) == (4 + FIFO_MAX_SAMPLES *sizeof(FIFO::DATA)), "Invalid transfer buffer size"); struct register_bank0_config_t { Register::BANK_0 reg;