From 21daa0f39817d47cb47f4eccbd45fab24959a25e Mon Sep 17 00:00:00 2001 From: CUAVmengxiao Date: Wed, 8 Jun 2022 14:48:18 +0800 Subject: [PATCH] drivers: add support for ICP101XX and ICP201XX --- src/drivers/barometer/Kconfig | 4 +- .../barometer/invensense/CMakeLists.txt | 6 +- src/drivers/barometer/invensense/Kconfig | 4 +- .../invensense/icp10111/ICP10111.cpp | 378 ------------- .../{icp10111 => icp101xx}/CMakeLists.txt | 14 +- .../ICP10100.cpp => icp101xx/ICP101XX.cpp} | 30 +- .../ICP10111.hpp => icp101xx/ICP101XX.hpp} | 12 +- .../Inven_Sense_ICP101XX_registers.hpp} | 10 +- .../barometer/invensense/icp101xx/Kconfig | 5 + .../icp101xx_main.cpp} | 14 +- .../{icp10100 => icp201xx}/CMakeLists.txt | 14 +- .../invensense/icp201xx/ICP201XX.cpp | 521 ++++++++++++++++++ .../ICP10100.hpp => icp201xx/ICP201XX.hpp} | 72 ++- .../Inven_Sense_ICP201XX_registers.hpp} | 56 +- .../barometer/invensense/icp201xx/Kconfig | 5 + .../icp201xx_main.cpp} | 14 +- src/drivers/drv_sensor.h | 4 +- 17 files changed, 680 insertions(+), 483 deletions(-) delete mode 100755 src/drivers/barometer/invensense/icp10111/ICP10111.cpp rename src/drivers/barometer/invensense/{icp10111 => icp101xx}/CMakeLists.txt (88%) rename src/drivers/barometer/invensense/{icp10100/ICP10100.cpp => icp101xx/ICP101XX.cpp} (94%) rename src/drivers/barometer/invensense/{icp10111/ICP10111.hpp => icp101xx/ICP101XX.hpp} (91%) rename src/drivers/barometer/invensense/{icp10111/Inven_Sense_ICP10111_registers.hpp => icp101xx/Inven_Sense_ICP101XX_registers.hpp} (91%) create mode 100755 src/drivers/barometer/invensense/icp101xx/Kconfig rename src/drivers/barometer/invensense/{icp10111/icp10111_main.cpp => icp101xx/icp101xx_main.cpp} (90%) rename src/drivers/barometer/invensense/{icp10100 => icp201xx}/CMakeLists.txt (88%) create mode 100755 src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp rename src/drivers/barometer/invensense/{icp10100/ICP10100.hpp => icp201xx/ICP201XX.hpp} (50%) rename src/drivers/barometer/invensense/{icp10100/Inven_Sense_ICP10100_registers.hpp => icp201xx/Inven_Sense_ICP201XX_registers.hpp} (64%) create mode 100755 src/drivers/barometer/invensense/icp201xx/Kconfig rename src/drivers/barometer/invensense/{icp10100/icp10100_main.cpp => icp201xx/icp201xx_main.cpp} (91%) diff --git a/src/drivers/barometer/Kconfig b/src/drivers/barometer/Kconfig index f99c053cf6..e13c24c272 100644 --- a/src/drivers/barometer/Kconfig +++ b/src/drivers/barometer/Kconfig @@ -9,7 +9,9 @@ menu "barometer" select DRIVERS_BAROMETER_LPS33HW select DRIVERS_BAROMETER_MS5611 select DRIVERS_BAROMETER_MAIERTEK_MPC2520 - select DRIVERS_BAROMETER_GOERTEK_SPL06 + select DRIVERS_BAROMETER_GOERTEK_SPL06 + select DRIVERS_BAROMETER_INVENSENSE_ICP101XX + select DRIVERS_BAROMETER_INVENSENSE_ICP201XX ---help--- Enable default set of barometer drivers rsource "*/Kconfig" diff --git a/src/drivers/barometer/invensense/CMakeLists.txt b/src/drivers/barometer/invensense/CMakeLists.txt index 1060e92e66..47e0670f87 100755 --- a/src/drivers/barometer/invensense/CMakeLists.txt +++ b/src/drivers/barometer/invensense/CMakeLists.txt @@ -1,6 +1,6 @@ ############################################################################ # -# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# Copyright (c) 2022 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 @@ -31,5 +31,5 @@ # ############################################################################ -add_subdirectory(icp10100) -add_subdirectory(icp10111) +add_subdirectory(icp101xx) +add_subdirectory(icp201xx) diff --git a/src/drivers/barometer/invensense/Kconfig b/src/drivers/barometer/invensense/Kconfig index 772bb882e8..6be15070d9 100644 --- a/src/drivers/barometer/invensense/Kconfig +++ b/src/drivers/barometer/invensense/Kconfig @@ -1,3 +1,3 @@ -menu "Invensense" +menu "InvenSense" rsource "*/Kconfig" -endmenu #Invensense +endmenu #InvenSense diff --git a/src/drivers/barometer/invensense/icp10111/ICP10111.cpp b/src/drivers/barometer/invensense/icp10111/ICP10111.cpp deleted file mode 100755 index 0b55816749..0000000000 --- a/src/drivers/barometer/invensense/icp10111/ICP10111.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/**************************************************************************** - * - * Copyright (c) 2021 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 "ICP10111.hpp" - -using namespace time_literals; - -ICP10111::ICP10111(const I2CSPIDriverConfig &config) : - I2C(config), - I2CSPIDriver(config) -{ -} - -ICP10111::~ICP10111() -{ - perf_free(_reset_perf); - perf_free(_sample_perf); - perf_free(_bad_transfer_perf); -} - -int -ICP10111::init() -{ - int ret = I2C::init(); - - if (ret != PX4_OK) { - DEVICE_DEBUG("I2C::init failed (%i)", ret); - return ret; - } - - return Reset() ? 0 : -1; -} - -bool -ICP10111::Reset() -{ - _state = STATE::RESET; - ScheduleClear(); - ScheduleNow(); - return true; -} - -void -ICP10111::print_status() -{ - I2CSPIDriverBase::print_status(); - perf_print_counter(_reset_perf); - perf_print_counter(_sample_perf); - perf_print_counter(_bad_transfer_perf); -} - -int -ICP10111::probe() -{ - uint16_t ID = 0; - read_response(Cmd::READ_ID, (uint8_t *)&ID, 2); - uint8_t PROD_ID = (ID >> 8) & 0x3f; - - if (PROD_ID != Product_ID) { - DEVICE_DEBUG("unexpected PROD_ID 0x%02x", PROD_ID); - return PX4_ERROR; - } - - return PX4_OK; -} - -void -ICP10111::RunImpl() -{ - const hrt_abstime now = hrt_absolute_time(); - - switch (_state) { - case STATE::RESET: - // Software Reset - send_command(Cmd::SOFT_RESET); - _reset_timestamp = now; - _failure_count = 0; - _state = STATE::WAIT_FOR_RESET; - perf_count(_reset_perf); - ScheduleDelayed(100_ms); // Power On Reset: max 100ms - break; - - case STATE::WAIT_FOR_RESET: { - // check product id - uint16_t ID = 0; - read_response(Cmd::READ_ID, (uint8_t *)&ID, 2); - uint8_t PROD_ID = (ID >> 8) & 0x3f; // Product ID Bits 5:0 - - if (PROD_ID == Product_ID) { - // if reset succeeded then read otp - _state = STATE::READ_OTP; - ScheduleDelayed(10_ms); // Time to coefficients are available. - - } 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::READ_OTP: { - // read otp - uint8_t addr_otp_cmd[3] = {0x00, 0x66, 0x9c}; - uint8_t otp_buf[3]; - uint8_t crc; - bool success = true; - - send_command(Cmd::SET_ADDR, addr_otp_cmd, 3); - - for (uint8_t i = 0; i < 4; i++) { - read_response(Cmd::READ_OTP, otp_buf, 3); - - crc = 0xFF; - - for (int j = 0; j < 2; j++) { - crc = (uint8_t)cal_crc(crc, otp_buf[j]); - } - - if (crc != otp_buf[2]) { - success = false; - break; - } - - _scal[i] = (otp_buf[0] << 8) | otp_buf[1]; - } - - if (success) { - _state = STATE::MEASURE; - - } else { - _state = STATE::RESET; - } - - ScheduleDelayed(10_ms); - } - break; - - case STATE::MEASURE: - if (Measure()) { - // if configure succeeded then start measurement cycle - _state = STATE::READ; - perf_begin(_sample_perf); - ScheduleDelayed(_measure_interval); - - } else { - // MEASURE not complete - if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) { - PX4_DEBUG("Measure failed, resetting"); - _state = STATE::RESET; - - } else { - PX4_DEBUG("Measure failed, retrying"); - } - - ScheduleDelayed(_measure_interval); - } - - break; - - case STATE::READ: { - uint8_t comp_data[9] {}; - bool success = false; - - if (read_measure_results(comp_data, 9) == PX4_OK) { - perf_end(_sample_perf); - - uint16_t _raw_t = (comp_data[0] << 8) | comp_data[1]; - uint32_t L_res_buf3 = comp_data[3]; // expand result bytes to 32bit to fix issues on 8-bit MCUs - uint32_t L_res_buf4 = comp_data[4]; - uint32_t L_res_buf6 = comp_data[6]; - uint32_t _raw_p = (L_res_buf3 << 16) | (L_res_buf4 << 8) | L_res_buf6; - - // constants for presure calculation - static constexpr float _pcal[3] = { 45000.0, 80000.0, 105000.0 }; - static constexpr float _lut_lower = 3.5 * 0x100000; // 1<<20 - static constexpr float _lut_upper = 11.5 * 0x100000; // 1<<20 - static constexpr float _quadr_factor = 1 / 16777216.0; - static constexpr float _offst_factor = 2048.0; - - // calculate temperature - float _temperature_C = -45.f + 175.f / 65536.f * _raw_t; - - // calculate pressure - float t = (float)(_raw_t - 32768); - float s1 = _lut_lower + (float)(_scal[0] * t * t) * _quadr_factor; - float s2 = _offst_factor * _scal[3] + (float)(_scal[1] * t * t) * _quadr_factor; - float s3 = _lut_upper + (float)(_scal[2] * t * t) * _quadr_factor; - float c = (s1 * s2 * (_pcal[0] - _pcal[1]) + - s2 * s3 * (_pcal[1] - _pcal[2]) + - s3 * s1 * (_pcal[2] - _pcal[0])) / - (s3 * (_pcal[0] - _pcal[1]) + - s1 * (_pcal[1] - _pcal[2]) + - s2 * (_pcal[2] - _pcal[0])); - float a = (_pcal[0] * s1 - _pcal[1] * s2 - (_pcal[1] - _pcal[0]) * c) / (s1 - s2); - float b = (_pcal[0] - a) * (s1 + c); - float _pressure_Pa = a + b / (c + _raw_p); - - float temperature = _temperature_C; - float pressure = _pressure_Pa; // to Pascal - - // publish - sensor_baro_s sensor_baro{}; - sensor_baro.timestamp_sample = now; - sensor_baro.device_id = get_device_id(); - sensor_baro.pressure = pressure; - sensor_baro.temperature = temperature; - sensor_baro.error_count = perf_event_count(_bad_transfer_perf); - sensor_baro.timestamp = hrt_absolute_time(); - _sensor_baro_pub.publish(sensor_baro); - - success = true; - - if (_failure_count > 0) { - _failure_count--; - } - - _state = STATE::MEASURE; - - } else { - perf_count(_bad_transfer_perf); - } - - if (!success) { - _failure_count++; - - // full reset if things are failing consistently - if (_failure_count > 10) { - Reset(); - return; - } - } - - ScheduleDelayed(1000_ms / 8 - _measure_interval); // 8Hz - } - - break; - } -} - -bool -ICP10111::Measure() -{ - /* - From ds-000186-icp-101xx-v1.0.pdf, page 6, table 1 - - Sensor Measurement Max Time - Mode Time (Forced) - Low Power (LP) 1.6 ms 1.8 ms - Normal (N) 5.6 ms 6.3 ms - Low Noise (LN) 20.8 ms 23.8 ms - Ultra Low Noise(ULN) 83.2 ms 94.5 ms - */ - Cmd cmd; - - switch (_mode) { - case MODE::FAST: - cmd = Cmd::MEAS_LP; - _measure_interval = 2_ms; - break; - - case MODE::ACCURATE: - cmd = Cmd::MEAS_LN; - _measure_interval = 24_ms; - break; - - case MODE::VERY_ACCURATE: - cmd = Cmd::MEAS_ULN; - _measure_interval = 95_ms; - break; - - case MODE::NORMAL: - default: - cmd = Cmd::MEAS_N; - _measure_interval = 7_ms; - break; - } - - if (send_command(cmd) != PX4_OK) { - return false; - } - - return true; -} - -int8_t -ICP10111::cal_crc(uint8_t seed, uint8_t data) -{ - int8_t poly = 0x31; - int8_t var2; - uint8_t i; - - for (i = 0; i < 8; i++) { - if ((seed & 0x80) ^ (data & 0x80)) { - var2 = 1; - - } else { - var2 = 0; - } - - seed = (seed & 0x7F) << 1; - data = (data & 0x7F) << 1; - seed = seed ^ (uint8_t)(poly * var2); - } - - return (int8_t)seed; -} - -int -ICP10111::read_measure_results(uint8_t *buf, uint8_t len) -{ - return transfer(nullptr, 0, buf, len); -} - -int -ICP10111::read_response(Cmd cmd, uint8_t *buf, uint8_t len) -{ - uint8_t buff[2]; - buff[0] = ((uint16_t)cmd >> 8) & 0xff; - buff[1] = (uint16_t)cmd & 0xff; - return transfer(&buff[0], 2, buf, len); -} - -int -ICP10111::send_command(Cmd cmd) -{ - uint8_t buf[2]; - buf[0] = ((uint16_t)cmd >> 8) & 0xff; - buf[1] = (uint16_t)cmd & 0xff; - return transfer(buf, sizeof(buf), nullptr, 0); -} - -int -ICP10111::send_command(Cmd cmd, uint8_t *data, uint8_t len) -{ - uint8_t buf[5]; - buf[0] = ((uint16_t)cmd >> 8) & 0xff; - buf[1] = (uint16_t)cmd & 0xff; - memcpy(&buf[2], data, len); - return transfer(&buf[0], len + 2, nullptr, 0); -} diff --git a/src/drivers/barometer/invensense/icp10111/CMakeLists.txt b/src/drivers/barometer/invensense/icp101xx/CMakeLists.txt similarity index 88% rename from src/drivers/barometer/invensense/icp10111/CMakeLists.txt rename to src/drivers/barometer/invensense/icp101xx/CMakeLists.txt index b0771e222d..beb253f95d 100755 --- a/src/drivers/barometer/invensense/icp10111/CMakeLists.txt +++ b/src/drivers/barometer/invensense/icp101xx/CMakeLists.txt @@ -1,6 +1,6 @@ ############################################################################ # -# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# Copyright (c) 2021-2022 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 @@ -32,14 +32,14 @@ ############################################################################ px4_add_module( - MODULE drivers__barometer__invensense__icp10111 - MAIN icp10111 + MODULE drivers__invensense__icp101xx + MAIN icp101xx COMPILE_FLAGS SRCS - Inven_Sense_ICP10111_registers.hpp - ICP10111.cpp - ICP10111.hpp - icp10111_main.cpp + Inven_Sense_ICP101XX_registers.hpp + ICP101XX.cpp + ICP101XX.hpp + icp101xx_main.cpp DEPENDS px4_work_queue ) diff --git a/src/drivers/barometer/invensense/icp10100/ICP10100.cpp b/src/drivers/barometer/invensense/icp101xx/ICP101XX.cpp similarity index 94% rename from src/drivers/barometer/invensense/icp10100/ICP10100.cpp rename to src/drivers/barometer/invensense/icp101xx/ICP101XX.cpp index 836194e16e..659ae9cb12 100755 --- a/src/drivers/barometer/invensense/icp10100/ICP10100.cpp +++ b/src/drivers/barometer/invensense/icp101xx/ICP101XX.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2021-2022 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 @@ -31,17 +31,17 @@ * ****************************************************************************/ -#include "ICP10100.hpp" +#include "ICP101XX.hpp" using namespace time_literals; -ICP10100::ICP10100(const I2CSPIDriverConfig &config) : +ICP101XX::ICP101XX(const I2CSPIDriverConfig &config) : I2C(config), I2CSPIDriver(config) { } -ICP10100::~ICP10100() +ICP101XX::~ICP101XX() { perf_free(_reset_perf); perf_free(_sample_perf); @@ -49,7 +49,7 @@ ICP10100::~ICP10100() } int -ICP10100::init() +ICP101XX::init() { int ret = I2C::init(); @@ -62,7 +62,7 @@ ICP10100::init() } bool -ICP10100::Reset() +ICP101XX::Reset() { _state = STATE::RESET; ScheduleClear(); @@ -71,7 +71,7 @@ ICP10100::Reset() } void -ICP10100::print_status() +ICP101XX::print_status() { I2CSPIDriverBase::print_status(); perf_print_counter(_reset_perf); @@ -80,7 +80,7 @@ ICP10100::print_status() } int -ICP10100::probe() +ICP101XX::probe() { uint16_t ID = 0; read_response(Cmd::READ_ID, (uint8_t *)&ID, 2); @@ -95,7 +95,7 @@ ICP10100::probe() } void -ICP10100::RunImpl() +ICP101XX::RunImpl() { const hrt_abstime now = hrt_absolute_time(); @@ -276,7 +276,7 @@ ICP10100::RunImpl() } bool -ICP10100::Measure() +ICP101XX::Measure() { /* From ds-000186-icp-101xx-v1.0.pdf, page 6, table 1 @@ -321,7 +321,7 @@ ICP10100::Measure() } int8_t -ICP10100::cal_crc(uint8_t seed, uint8_t data) +ICP101XX::cal_crc(uint8_t seed, uint8_t data) { int8_t poly = 0x31; int8_t var2; @@ -344,13 +344,13 @@ ICP10100::cal_crc(uint8_t seed, uint8_t data) } int -ICP10100::read_measure_results(uint8_t *buf, uint8_t len) +ICP101XX::read_measure_results(uint8_t *buf, uint8_t len) { return transfer(nullptr, 0, buf, len); } int -ICP10100::read_response(Cmd cmd, uint8_t *buf, uint8_t len) +ICP101XX::read_response(Cmd cmd, uint8_t *buf, uint8_t len) { uint8_t buff[2]; buff[0] = ((uint16_t)cmd >> 8) & 0xff; @@ -359,7 +359,7 @@ ICP10100::read_response(Cmd cmd, uint8_t *buf, uint8_t len) } int -ICP10100::send_command(Cmd cmd) +ICP101XX::send_command(Cmd cmd) { uint8_t buf[2]; buf[0] = ((uint16_t)cmd >> 8) & 0xff; @@ -368,7 +368,7 @@ ICP10100::send_command(Cmd cmd) } int -ICP10100::send_command(Cmd cmd, uint8_t *data, uint8_t len) +ICP101XX::send_command(Cmd cmd, uint8_t *data, uint8_t len) { uint8_t buf[5]; buf[0] = ((uint16_t)cmd >> 8) & 0xff; diff --git a/src/drivers/barometer/invensense/icp10111/ICP10111.hpp b/src/drivers/barometer/invensense/icp101xx/ICP101XX.hpp similarity index 91% rename from src/drivers/barometer/invensense/icp10111/ICP10111.hpp rename to src/drivers/barometer/invensense/icp101xx/ICP101XX.hpp index 54ace11369..284e4aad81 100755 --- a/src/drivers/barometer/invensense/icp10111/ICP10111.hpp +++ b/src/drivers/barometer/invensense/icp101xx/ICP101XX.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2021-2022 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 @@ -33,7 +33,7 @@ #pragma once -#include "Inven_Sense_ICP10111_registers.hpp" +#include "Inven_Sense_ICP101XX_registers.hpp" #include #include @@ -42,13 +42,13 @@ #include #include -using namespace Inven_Sense_ICP10111; +using namespace Inven_Sense_ICP101XX; -class ICP10111 : public device::I2C, public I2CSPIDriver +class ICP101XX : public device::I2C, public I2CSPIDriver { public: - ICP10111(const I2CSPIDriverConfig &config); - ~ICP10111() override; + ICP101XX(const I2CSPIDriverConfig &config); + ~ICP101XX() override; static void print_usage(); diff --git a/src/drivers/barometer/invensense/icp10111/Inven_Sense_ICP10111_registers.hpp b/src/drivers/barometer/invensense/icp101xx/Inven_Sense_ICP101XX_registers.hpp similarity index 91% rename from src/drivers/barometer/invensense/icp10111/Inven_Sense_ICP10111_registers.hpp rename to src/drivers/barometer/invensense/icp101xx/Inven_Sense_ICP101XX_registers.hpp index 907fa1b324..0f76907229 100755 --- a/src/drivers/barometer/invensense/icp10111/Inven_Sense_ICP10111_registers.hpp +++ b/src/drivers/barometer/invensense/icp101xx/Inven_Sense_ICP101XX_registers.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2021-2022 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 @@ -32,9 +32,9 @@ ****************************************************************************/ /** - * @file icp10111_registers.hpp + * @file icp101xx_registers.hpp * - * icp10111 registers. + * icp101xx registers. * */ @@ -42,7 +42,7 @@ #include -namespace Inven_Sense_ICP10111 +namespace Inven_Sense_ICP101XX { static constexpr uint32_t I2C_SPEED = 100 * 1000; // 100 kHz I2C serial interface static constexpr uint8_t I2C_ADDRESS_DEFAULT = 0x63; @@ -59,4 +59,4 @@ enum class Cmd : uint16_t { MEAS_ULN = 0x7866, SOFT_RESET = 0x805d }; -} // namespace Inven_Sense_ICP10111 +} // namespace Inven_Sense_ICP101XX diff --git a/src/drivers/barometer/invensense/icp101xx/Kconfig b/src/drivers/barometer/invensense/icp101xx/Kconfig new file mode 100755 index 0000000000..89e6b7e9c9 --- /dev/null +++ b/src/drivers/barometer/invensense/icp101xx/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_BAROMETER_INVENSENSE_ICP101XX + bool "icp101xx" + default n + ---help--- + Enable support for icp101xx diff --git a/src/drivers/barometer/invensense/icp10111/icp10111_main.cpp b/src/drivers/barometer/invensense/icp101xx/icp101xx_main.cpp similarity index 90% rename from src/drivers/barometer/invensense/icp10111/icp10111_main.cpp rename to src/drivers/barometer/invensense/icp101xx/icp101xx_main.cpp index c7cfb3d2ce..4abe7697e9 100755 --- a/src/drivers/barometer/invensense/icp10111/icp10111_main.cpp +++ b/src/drivers/barometer/invensense/icp101xx/icp101xx_main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2021-2022 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 @@ -35,12 +35,12 @@ #include #include -#include "ICP10111.hpp" +#include "ICP101XX.hpp" void -ICP10111::print_usage() +ICP101XX::print_usage() { - PRINT_MODULE_USAGE_NAME("icp10111", "driver"); + PRINT_MODULE_USAGE_NAME("icp101xx", "driver"); PRINT_MODULE_USAGE_SUBCATEGORY("baro"); PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); @@ -48,9 +48,9 @@ ICP10111::print_usage() PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); } -extern "C" int icp10111_main(int argc, char *argv[]) +extern "C" int icp101xx_main(int argc, char *argv[]) { - using ThisDriver = ICP10111; + using ThisDriver = ICP101XX; BusCLIArguments cli{true, false}; cli.i2c_address = I2C_ADDRESS_DEFAULT; cli.default_i2c_frequency = I2C_SPEED; @@ -62,7 +62,7 @@ extern "C" int icp10111_main(int argc, char *argv[]) return -1; } - BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_ICP10111); + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_ICP101XX); if (!strcmp(verb, "start")) { return ThisDriver::module_start(cli, iterator); diff --git a/src/drivers/barometer/invensense/icp10100/CMakeLists.txt b/src/drivers/barometer/invensense/icp201xx/CMakeLists.txt similarity index 88% rename from src/drivers/barometer/invensense/icp10100/CMakeLists.txt rename to src/drivers/barometer/invensense/icp201xx/CMakeLists.txt index d00ea60bcc..4b44b97b30 100755 --- a/src/drivers/barometer/invensense/icp10100/CMakeLists.txt +++ b/src/drivers/barometer/invensense/icp201xx/CMakeLists.txt @@ -1,6 +1,6 @@ ############################################################################ # -# Copyright (c) 2021 PX4 Development Team. All rights reserved. +# Copyright (c) 2022 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 @@ -32,14 +32,14 @@ ############################################################################ px4_add_module( - MODULE drivers__barometer__invensense__icp10100 - MAIN icp10100 + MODULE drivers__invensense__icp201xx + MAIN icp201xx COMPILE_FLAGS SRCS - Inven_Sense_ICP10100_registers.hpp - ICP10100.cpp - ICP10100.hpp - icp10100_main.cpp + Inven_Sense_ICP201XX_registers.hpp + ICP201XX.cpp + ICP201XX.hpp + icp201xx_main.cpp DEPENDS px4_work_queue ) diff --git a/src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp b/src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp new file mode 100755 index 0000000000..a863ac975b --- /dev/null +++ b/src/drivers/barometer/invensense/icp201xx/ICP201XX.cpp @@ -0,0 +1,521 @@ +/**************************************************************************** + * + * Copyright (c) 2022 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 "ICP201XX.hpp" +#include + +using namespace time_literals; + +ICP201XX::ICP201XX(const I2CSPIDriverConfig &config) : + I2C(config), + I2CSPIDriver(config) +{ +} + +ICP201XX::~ICP201XX() +{ + perf_free(_reset_perf); + perf_free(_sample_perf); + perf_free(_bad_transfer_perf); +} + +int +ICP201XX::init() +{ + int ret = I2C::init(); + + if (ret != PX4_OK) { + DEVICE_DEBUG("I2C::init failed (%i)", ret); + return ret; + } + + return Reset() ? 0 : -1; +} + +bool +ICP201XX::Reset() +{ + _state = STATE::SOFT_RESET; + ScheduleClear(); + ScheduleNow(); + return true; +} + +void +ICP201XX::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_reset_perf); + perf_print_counter(_sample_perf); + perf_print_counter(_bad_transfer_perf); +} + +int +ICP201XX::probe() +{ + uint8_t device_id = 0; + uint8_t ver = 0xFF; + read_reg(Register::DEVICE_ID, &device_id); + read_reg(Register::VERSION, &ver); + + if (device_id != EXPECTED_DEVICE_ID) { + DEVICE_DEBUG("unexpected device id 0x%02x", device_id); + return PX4_ERROR; + } + + if (ver != 0x00 && ver != 0xB2) { + DEVICE_DEBUG("unexpected version 0x%02x", ver); + return PX4_ERROR; + } + + return PX4_OK; +} + +void +ICP201XX::RunImpl() +{ + const hrt_abstime now = hrt_absolute_time(); + + switch (_state) { + case STATE::SOFT_RESET: { + /* Stop the measurement */ + mode_select(0x00); + + ScheduleDelayed(2_ms); + + /* Flush FIFO */ + flush_fifo(); + + /* Mask all interrupts */ + write_reg(Register::FIFO_CONFIG, 0x00); + write_reg(Register::INTERRUPT_MASK, 0xFF); + + _reset_timestamp = now; + _failure_count = 0; + perf_count(_reset_perf); + _state = STATE::OTP_BOOTUP_CFG; + ScheduleDelayed(10_ms); + } + break; + + case STATE::OTP_BOOTUP_CFG: { + uint8_t reg_value = 0; + uint8_t offset = 0, gain = 0, Hfosc = 0; + uint8_t version = 0; + uint8_t bootup_status = 0; + int ret = 0; + + /* read version register */ + if (read_reg(Register::VERSION, &version) != PX4_OK) { + ScheduleDelayed(10_ms); + break; + } + + if (version == 0xB2) { + /* B2 version Asic is detected. Boot up sequence is not required for B2 Asic, so returning */ + _state = STATE::CONFIG; + ScheduleDelayed(10_ms); + } + + /* Read boot up status and avoid re running boot up sequence if it is already done */ + if (read_reg(Register::OTP_MTP_OTP_STATUS2, &bootup_status) != PX4_OK) { + ScheduleDelayed(10_ms); + break; + } + + if (bootup_status & 0x01) { + /* Boot up sequence is already done, not required to repeat boot up sequence */ + _state = STATE::CONFIG; + ScheduleDelayed(10_ms); + break; + } + + /* Bring the ASIC in power mode to activate the OTP power domain and get access to the main registers */ + mode_select(0x04); + usleep(4_ms); + + /* Unlock the main registers */ + write_reg(Register::MASTER_LOCK, 0x1F); + + /* Enable the OTP and the write switch */ + read_reg(Register::OTP_MTP_OTP_CFG1, ®_value); + reg_value |= 0x03; + write_reg(Register::OTP_MTP_OTP_CFG1, reg_value); + usleep(10_us); + + /* Toggle the OTP reset pin */ + read_reg(Register::OTP_DEBUG2, ®_value); + reg_value |= 1 << 7; + write_reg(Register::OTP_DEBUG2, reg_value); + usleep(10_us); + + read_reg(Register::OTP_DEBUG2, ®_value); + reg_value &= ~(1 << 7); + write_reg(Register::OTP_DEBUG2, reg_value); + usleep(10_us); + + /* Program redundant read */ + write_reg(Register::OTP_MTP_MRA_LSB, 0x04); + write_reg(Register::OTP_MTP_MRA_MSB, 0x04); + write_reg(Register::OTP_MTP_MRB_LSB, 0x21); + write_reg(Register::OTP_MTP_MRB_MSB, 0x20); + write_reg(Register::OTP_MTP_MR_LSB, 0x10); + write_reg(Register::OTP_MTP_MR_MSB, 0x80); + + /* Read the data from register */ + ret |= read_otp_data(0xF8, 0x10, &offset); + ret |= read_otp_data(0xF9, 0x10, &gain); + ret |= read_otp_data(0xFA, 0x10, &Hfosc); + ScheduleDelayed(10_us); + + /* Write OTP values to main registers */ + ret |= read_reg(Register::TRIM1_MSB, ®_value); + + if (ret == 0) { + reg_value = (reg_value & (~0x3F)) | (offset & 0x3F); + ret |= write_reg(Register::TRIM1_MSB, reg_value); + } + + ret |= read_reg(Register::TRIM2_MSB, ®_value); + + if (ret == 0) { + reg_value = (reg_value & (~0x70)) | ((gain & 0x07) << 4); + ret |= write_reg(Register::TRIM2_MSB, reg_value); + } + + ret |= read_reg(Register::TRIM2_LSB, ®_value); + + if (ret == 0) { + reg_value = (reg_value & (~0x7F)) | (Hfosc & 0x7F); + ret |= write_reg(Register::TRIM2_LSB, reg_value); + } + + ScheduleDelayed(10_us); + + /* Update boot up status to 1 */ + if (ret == 0) { + ret |= read_reg(Register::OTP_MTP_OTP_STATUS2, ®_value); + + if (ret == 0) { + reg_value |= 0x01; + ret |= write_reg(Register::OTP_MTP_OTP_STATUS2, reg_value); + } + } + + /* Disable OTP and write switch */ + read_reg(Register::OTP_MTP_OTP_CFG1, ®_value); + reg_value &= ~0x03; + write_reg(Register::OTP_MTP_OTP_CFG1, reg_value); + + /* Lock the main register */ + write_reg(Register::MASTER_LOCK, 0x00); + + /* Move to standby */ + mode_select(0x00); + + ScheduleDelayed(10_ms); + } + break; + + case STATE::CONFIG: { + if (configure()) { + _state = STATE::WAIT_READ; + ScheduleDelayed(10_ms); + + } else { + if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) { + PX4_WARN("Configure failed, resetting"); + _state = STATE::SOFT_RESET; + + } else { + PX4_WARN("Configure failed, retrying"); + } + + ScheduleDelayed(100_ms); + } + } + break; + + case STATE::WAIT_READ: { + /* + * If FIR filter is enabled, it will cause a settling effect on the first 14 pressure values. + * Therefore the first 14 pressure output values are discarded. + **/ + uint8_t fifo_packets = 0; + uint8_t fifo_packets_to_skip = 14; + + do { + ScheduleDelayed(10_ms); + read_reg(Register::FIFO_FILL, &fifo_packets); + fifo_packets = (uint8_t)(fifo_packets & 0x1F); + } while (fifo_packets >= fifo_packets_to_skip); + + flush_fifo(); + fifo_packets = 0; + + do { + ScheduleDelayed(10_ms); + read_reg(Register::FIFO_FILL, &fifo_packets); + fifo_packets = (uint8_t)(fifo_packets & 0x1F); + } while (fifo_packets == 0); + + _state = STATE::READ; + perf_begin(_sample_perf); + ScheduleOnInterval(1_s / 30); + } + break; + + case STATE::READ: { + bool success = false; + float pressure, temperature; + + if (get_sensor_data(&pressure, &temperature)) { + perf_end(_sample_perf); + perf_begin(_sample_perf); + + sensor_baro_s sensor_baro{}; + sensor_baro.timestamp_sample = now; + sensor_baro.device_id = get_device_id(); + sensor_baro.pressure = pressure; + sensor_baro.temperature = temperature; + sensor_baro.error_count = perf_event_count(_bad_transfer_perf); + sensor_baro.timestamp = hrt_absolute_time(); + _sensor_baro_pub.publish(sensor_baro); + + success = true; + + if (_failure_count > 0) { + _failure_count--; + } + + } else { + perf_count(_bad_transfer_perf); + } + + if (!success) { + _failure_count++; + + if (_failure_count > 10) { + Reset(); + return; + } + } + } + break; + } +} + +void +ICP201XX::dummy_reg() +{ + do { + uint8_t reg = (uint8_t)Register::EMPTY; + uint8_t val = 0; + transfer((uint8_t *)®, 1, &val, 1); + } while (0); +} + +int +ICP201XX::read_reg(Register reg, uint8_t *buf, uint8_t len) +{ + int ret; + ret = transfer((uint8_t *)®, 1, buf, len); + dummy_reg(); + return ret; +} + +int +ICP201XX::read_reg(Register reg, uint8_t *val) +{ + return read_reg(reg, val, 1); +} + +int +ICP201XX::write_reg(Register reg, uint8_t val) +{ + uint8_t data[2] = { (uint8_t)reg, val }; + int ret; + ret = transfer(data, sizeof(data), nullptr, 0); + dummy_reg(); + return ret; +} + +int +ICP201XX::mode_select(uint8_t mode) +{ + uint8_t mode_sync_status = 0; + + do { + read_reg(Register::DEVICE_STATUS, &mode_sync_status, 1); + + if (mode_sync_status & 0x01) { + break; + } + + ScheduleDelayed(500_us); + } while (1); + + if (write_reg(Register::MODE_SELECT, mode) != PX4_OK) { + return PX4_ERROR; + } + + return PX4_OK; +} + +int +ICP201XX::read_otp_data(uint8_t addr, uint8_t cmd, uint8_t *val) +{ + uint8_t otp_status = 0xFF; + + /* Write the address content and read command */ + if (write_reg(Register::OTP_MTP_OTP_ADDR, addr) != PX4_OK) { + return PX4_ERROR; + } + + if (write_reg(Register::OTP_MTP_OTP_CMD, cmd) != PX4_OK) { + return PX4_ERROR; + } + + /* Wait for the OTP read to finish Monitor otp_status */ + do { + read_reg(Register::OTP_MTP_OTP_STATUS, &otp_status); + + if (otp_status == 0) { + break; + } + + ScheduleDelayed(1_us); + } while (1); + + /* Read the data from register */ + if (read_reg(Register::OTP_MTP_RD_DATA, val) != PX4_OK) { + return PX4_ERROR; + } + + return PX4_OK; +} + +bool +ICP201XX::get_sensor_data(float *pressure, float *temperature) +{ + bool success = false; + uint8_t fifo_packets = 0; + uint8_t fifo_data[96] {0}; + int32_t data_temp[16] {0}; + int32_t data_press[16] {0}; + + if (read_reg(Register::FIFO_FILL, &fifo_packets) == PX4_OK) { + fifo_packets = (uint8_t)(fifo_packets & 0x1F); + + if (fifo_packets > 0 && fifo_packets <= 16 && !read_reg(Register::FIFO_BASE, fifo_data, fifo_packets * 2 * 3)) { + uint8_t offset = 0; + + for (uint8_t i = 0; i < fifo_packets; i++) { + data_press[i] = (int32_t)(((fifo_data[offset + 2] & 0x0f) << 16) | (fifo_data[offset + 1] << 8) | fifo_data[offset]) ; + offset += 3; + data_temp[i] = (int32_t)(((fifo_data[offset + 2] & 0x0f) << 16) | (fifo_data[offset + 1] << 8) | fifo_data[offset]) ; + offset += 3; + } + + *pressure = 0; + *temperature = 0; + + for (uint8_t i = 0; i < fifo_packets; i++) { + /** P = (POUT/2^17)*40kPa + 70kPa **/ + if (data_press[i] & 0x080000) { + data_press[i] |= 0xFFF00000; + } + + *pressure += ((float)(data_press[i]) * 40 / 131072) + 70; + + /* T = (TOUT/2^18)*65C + 25C */ + if (data_temp[i] & 0x080000) { + data_temp[i] |= 0xFFF00000; + } + + *temperature += ((float)(data_temp[i]) * 65 / 262144) + 25; + } + + *pressure = *pressure * 1000 / fifo_packets; + *temperature = *temperature / fifo_packets; + success = true; + } + } + + return success; +} + +bool +ICP201XX::configure() +{ + uint8_t reg_value = 0; + + /* Initiate Triggered Operation: Stay in Standby mode */ + reg_value |= (reg_value & (~0x10)) | ((uint8_t)_forced_meas_trigger << 4); + + /* Power Mode Selection: Normal Mode */ + reg_value |= (reg_value & (~0x04)) | ((uint8_t)_power_mode << 2); + + /* FIFO Readout Mode Selection: Pressure first. */ + reg_value |= (reg_value & (~0x03)) | ((uint8_t)(_fifo_readout_mode)); + + /* Measurement Configuration: Mode2*/ + reg_value |= (reg_value & (~0xE0)) | (((uint8_t)_op_mode) << 5); + + /* Measurement Mode Selection: Continuous Measurements (duty cycled) */ + reg_value |= (reg_value & (~0x08)) | ((uint8_t)_meas_mode << 3); + + if (mode_select(reg_value) != PX4_OK) { + return false; + } + + return true; +} + +bool +ICP201XX::flush_fifo() +{ + uint8_t reg_value; + + if (read_reg(Register::FIFO_FILL, ®_value) != PX4_OK) { + return false; + } + + reg_value |= 0x80; + + if (write_reg(Register::FIFO_FILL, reg_value) != PX4_OK) { + return false; + } + + return true; +} diff --git a/src/drivers/barometer/invensense/icp10100/ICP10100.hpp b/src/drivers/barometer/invensense/icp201xx/ICP201XX.hpp similarity index 50% rename from src/drivers/barometer/invensense/icp10100/ICP10100.hpp rename to src/drivers/barometer/invensense/icp201xx/ICP201XX.hpp index ba887cd5e4..cbc746321f 100755 --- a/src/drivers/barometer/invensense/icp10100/ICP10100.hpp +++ b/src/drivers/barometer/invensense/icp201xx/ICP201XX.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (C) 2021 PX4 Development Team. All rights reserved. + * Copyright (C) 2022 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 @@ -33,7 +33,7 @@ #pragma once -#include "Inven_Sense_ICP10100_registers.hpp" +#include "Inven_Sense_ICP201XX_registers.hpp" #include #include @@ -42,13 +42,13 @@ #include #include -using namespace Inven_Sense_ICP10100; +using namespace Inven_Sense_ICP201XX; -class ICP10100 : public device::I2C, public I2CSPIDriver +class ICP201XX : public device::I2C, public I2CSPIDriver { public: - ICP10100(const I2CSPIDriverConfig &config); - ~ICP10100() override; + ICP201XX(const I2CSPIDriverConfig &config); + ~ICP201XX() override; static void print_usage(); @@ -62,13 +62,15 @@ private: bool Reset(); - bool Measure(); - - int8_t cal_crc(uint8_t seed, uint8_t data); - int read_measure_results(uint8_t *buf, uint8_t len); - int read_response(Cmd cmd, uint8_t *buf, uint8_t len); - int send_command(Cmd cmd); - int send_command(Cmd cmd, uint8_t *data, uint8_t len); + int read_reg(Register reg, uint8_t *val); + int read_reg(Register reg, uint8_t *buf, uint8_t len); + int write_reg(Register reg, uint8_t val); + int read_otp_data(uint8_t addr, uint8_t cmd, uint8_t *dat); + bool get_sensor_data(float *pressure, float *temperature); + int mode_select(uint8_t mode); + void dummy_reg(); + bool flush_fifo(); + bool configure(); uORB::PublicationMulti _sensor_baro_pub{ORB_ID(sensor_baro)}; @@ -79,21 +81,37 @@ private: hrt_abstime _reset_timestamp{0}; int _failure_count{0}; - unsigned _measure_interval{0}; - int16_t _scal[4]; - enum class STATE : uint8_t { - RESET, - WAIT_FOR_RESET, - READ_OTP, - MEASURE, + SOFT_RESET = 0, + OTP_BOOTUP_CFG, + CONFIG, + WAIT_READ, READ - } _state{STATE::RESET}; + } _state{STATE::SOFT_RESET}; - enum class MODE : uint8_t { - FAST, - NORMAL, - ACCURATE, - VERY_ACCURATE - } _mode{MODE::VERY_ACCURATE}; + enum class OP_MODE : uint8_t { + OP_MODE0 = 0, /* Mode 0: Bw:6.25 Hz ODR: 25Hz */ + OP_MODE1, /* Mode 1: Bw:30 Hz ODR: 120Hz */ + OP_MODE2, /* Mode 2: Bw:10 Hz ODR: 40Hz */ + OP_MODE3, /* Mode 3: Bw:0.5 Hz ODR: 2Hz */ + OP_MODE4, /* Mode 4: User configurable Mode */ + } _op_mode{OP_MODE::OP_MODE2}; + enum class FIFO_READOUT_MODE : uint8_t { + FIFO_READOUT_MODE_PRES_TEMP = 0, /* Pressure and temperature as pair and address wraps to the start address of the Pressure value ( pressure first ) */ + FIFO_READOUT_MODE_TEMP_ONLY = 1, /* Temperature only reporting */ + FIFO_READOUT_MODE_TEMP_PRES = 2, /* Pressure and temperature as pair and address wraps to the start address of the Temperature value ( Temperature first ) */ + FIFO_READOUT_MODE_PRES_ONLY = 3 /* Pressure only reporting */ + } _fifo_readout_mode{FIFO_READOUT_MODE::FIFO_READOUT_MODE_PRES_TEMP}; + enum class POWER_MODE : uint8_t { + POWER_MODE_NORMAL = 0, /* Normal Mode: Device is in standby and goes to active mode during the execution of a measurement */ + POWER_MODE_ACTIVE = 1 /* Active Mode: Power on DVDD and enable the high frequency clock */ + } _power_mode{POWER_MODE::POWER_MODE_NORMAL}; + enum MEAS_MODE : uint8_t { + MEAS_MODE_FORCED_TRIGGER = 0, /* Force trigger mode based on icp201xx_forced_meas_trigger_t **/ + MEAS_MODE_CONTINUOUS = 1 /* Continuous measurements based on selected mode ODR settings*/ + } _meas_mode{MEAS_MODE::MEAS_MODE_CONTINUOUS}; + enum FORCED_MEAS_TRIGGER : uint8_t { + FORCE_MEAS_STANDBY = 0, /* Stay in Stand by */ + FORCE_MEAS_TRIGGER_FORCE_MEAS = 1 /* Trigger for forced measurements */ + } _forced_meas_trigger{FORCED_MEAS_TRIGGER::FORCE_MEAS_STANDBY}; }; diff --git a/src/drivers/barometer/invensense/icp10100/Inven_Sense_ICP10100_registers.hpp b/src/drivers/barometer/invensense/icp201xx/Inven_Sense_ICP201XX_registers.hpp similarity index 64% rename from src/drivers/barometer/invensense/icp10100/Inven_Sense_ICP10100_registers.hpp rename to src/drivers/barometer/invensense/icp201xx/Inven_Sense_ICP201XX_registers.hpp index 558b7f14d1..56bd07c300 100755 --- a/src/drivers/barometer/invensense/icp10100/Inven_Sense_ICP10100_registers.hpp +++ b/src/drivers/barometer/invensense/icp201xx/Inven_Sense_ICP201XX_registers.hpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2022 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 @@ -32,9 +32,9 @@ ****************************************************************************/ /** - * @file icp10100_registers.hpp + * @file icp201xx_registers.hpp * - * icp10100 registers. + * icp201xx registers. * */ @@ -42,21 +42,45 @@ #include -namespace Inven_Sense_ICP10100 +namespace Inven_Sense_ICP201XX { static constexpr uint32_t I2C_SPEED = 100 * 1000; // 100 kHz I2C serial interface static constexpr uint8_t I2C_ADDRESS_DEFAULT = 0x63; +static constexpr uint8_t EXPECTED_DEVICE_ID = 0x63; -static constexpr uint8_t Product_ID = 0x08; - -enum class Cmd : uint16_t { - READ_ID = 0xefc8, - SET_ADDR = 0xc595, - READ_OTP = 0xc7f7, - MEAS_LP = 0x609c, - MEAS_N = 0x6825, - MEAS_LN = 0x70df, - MEAS_ULN = 0x7866, - SOFT_RESET = 0x805d +enum class Register : uint8_t { + EMPTY = 0x00, + TRIM1_MSB = 0x05, + TRIM2_LSB = 0x06, + TRIM2_MSB = 0x07, + DEVICE_ID = 0x0C, + OTP_MTP_OTP_CFG1 = 0xAC, + OTP_MTP_MR_LSB = 0xAD, + OTP_MTP_MR_MSB = 0xAE, + OTP_MTP_MRA_LSB = 0xAF, + OTP_MTP_MRA_MSB = 0xB0, + OTP_MTP_MRB_LSB = 0xB1, + OTP_MTP_MRB_MSB = 0xB2, + OTP_MTP_OTP_ADDR = 0xB5, + OTP_MTP_OTP_CMD = 0xB6, + OTP_MTP_RD_DATA = 0xB8, + OTP_MTP_OTP_STATUS = 0xB9, + OTP_DEBUG2 = 0xBC, + MASTER_LOCK = 0xBE, + OTP_MTP_OTP_STATUS2 = 0xBF, + MODE_SELECT = 0xC0, + INTERRUPT_STATUS = 0xC1, + INTERRUPT_MASK = 0xC2, + FIFO_CONFIG = 0xC3, + FIFO_FILL = 0xC4, + SPI_MODE = 0xC5, + PRESS_ABS_LSB = 0xC7, + PRESS_ABS_MSB = 0xC8, + PRESS_DELTA_LSB = 0xC9, + PRESS_DELTA_MSB = 0xCA, + DEVICE_STATUS = 0xCD, + I3C_INFO = 0xCE, + VERSION = 0xD3, + FIFO_BASE = 0xFA }; -} // namespace Inven_Sense_ICP10100 +} // namespace Inven_Sense_ICP201XX diff --git a/src/drivers/barometer/invensense/icp201xx/Kconfig b/src/drivers/barometer/invensense/icp201xx/Kconfig new file mode 100755 index 0000000000..79eacd3b69 --- /dev/null +++ b/src/drivers/barometer/invensense/icp201xx/Kconfig @@ -0,0 +1,5 @@ +menuconfig DRIVERS_BAROMETER_INVENSENSE_ICP201XX + bool "icp201xx" + default n + ---help--- + Enable support for icp201xx diff --git a/src/drivers/barometer/invensense/icp10100/icp10100_main.cpp b/src/drivers/barometer/invensense/icp201xx/icp201xx_main.cpp similarity index 91% rename from src/drivers/barometer/invensense/icp10100/icp10100_main.cpp rename to src/drivers/barometer/invensense/icp201xx/icp201xx_main.cpp index de4c0aa25e..d6f3fcc73b 100755 --- a/src/drivers/barometer/invensense/icp10100/icp10100_main.cpp +++ b/src/drivers/barometer/invensense/icp201xx/icp201xx_main.cpp @@ -1,6 +1,6 @@ /**************************************************************************** * - * Copyright (c) 2021 PX4 Development Team. All rights reserved. + * Copyright (c) 2022 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 @@ -35,12 +35,12 @@ #include #include -#include "ICP10100.hpp" +#include "ICP201XX.hpp" void -ICP10100::print_usage() +ICP201XX::print_usage() { - PRINT_MODULE_USAGE_NAME("icp10100", "driver"); + PRINT_MODULE_USAGE_NAME("icp201xx", "driver"); PRINT_MODULE_USAGE_SUBCATEGORY("baro"); PRINT_MODULE_USAGE_COMMAND("start"); PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); @@ -48,9 +48,9 @@ ICP10100::print_usage() PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); } -extern "C" int icp10100_main(int argc, char *argv[]) +extern "C" int icp201xx_main(int argc, char *argv[]) { - using ThisDriver = ICP10100; + using ThisDriver = ICP201XX; BusCLIArguments cli{true, false}; cli.i2c_address = I2C_ADDRESS_DEFAULT; cli.default_i2c_frequency = I2C_SPEED; @@ -62,7 +62,7 @@ extern "C" int icp10100_main(int argc, char *argv[]) return -1; } - BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_ICP10100); + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_ICP201XX); if (!strcmp(verb, "start")) { return ThisDriver::module_start(cli, iterator); diff --git a/src/drivers/drv_sensor.h b/src/drivers/drv_sensor.h index b0e45b7655..2d85fd84dc 100644 --- a/src/drivers/drv_sensor.h +++ b/src/drivers/drv_sensor.h @@ -216,8 +216,8 @@ #define DRV_FLOW_DEVTYPE_PX4FLOW 0xB5 #define DRV_FLOW_DEVTYPE_PAA3905 0xB6 -#define DRV_BARO_DEVTYPE_ICP10100 0xC0 -#define DRV_BARO_DEVTYPE_ICP10111 0xC1 +#define DRV_BARO_DEVTYPE_ICP101XX 0xB7 +#define DRV_BARO_DEVTYPE_ICP201XX 0xB8 #define DRV_DEVTYPE_UNUSED 0xff