mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-05-23 11:07:36 +08:00
barometer: Add ICP10100 and ICP1011
This commit is contained in:
committed by
Daniel Agar
parent
fe44e281e5
commit
258a563dd5
@@ -41,3 +41,4 @@ add_subdirectory(lps33hw)
|
||||
add_subdirectory(maiertek)
|
||||
add_subdirectory(ms5611)
|
||||
#add_subdirectory(tcbp001ta) # only for users who really need this
|
||||
add_subdirectory(invensense)
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
add_subdirectory(icp10100)
|
||||
add_subdirectory(icp10111)
|
||||
@@ -0,0 +1,46 @@
|
||||
############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
px4_add_module(
|
||||
MODULE drivers__invensense__icp10100
|
||||
MAIN icp10100
|
||||
COMPILE_FLAGS
|
||||
SRCS
|
||||
Inven_Sense_ICP10100_registers.hpp
|
||||
ICP10100.cpp
|
||||
ICP10100.hpp
|
||||
icp10100_main.cpp
|
||||
DEPENDS
|
||||
drivers_barometer
|
||||
px4_work_queue
|
||||
)
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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 "ICP10100.hpp"
|
||||
|
||||
using namespace time_literals;
|
||||
|
||||
ICP10100::ICP10100(const I2CSPIDriverConfig &config) :
|
||||
I2C(config),
|
||||
I2CSPIDriver(config),
|
||||
_px4_baro(get_device_id())
|
||||
{
|
||||
}
|
||||
|
||||
ICP10100::~ICP10100()
|
||||
{
|
||||
perf_free(_reset_perf);
|
||||
perf_free(_sample_perf);
|
||||
perf_free(_bad_transfer_perf);
|
||||
}
|
||||
|
||||
int
|
||||
ICP10100::init()
|
||||
{
|
||||
int ret = I2C::init();
|
||||
|
||||
if (ret != PX4_OK) {
|
||||
DEVICE_DEBUG("I2C::init failed (%i)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return Reset() ? 0 : -1;
|
||||
}
|
||||
|
||||
bool
|
||||
ICP10100::Reset()
|
||||
{
|
||||
_state = STATE::RESET;
|
||||
ScheduleClear();
|
||||
ScheduleNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ICP10100::print_status()
|
||||
{
|
||||
I2CSPIDriverBase::print_status();
|
||||
perf_print_counter(_reset_perf);
|
||||
perf_print_counter(_sample_perf);
|
||||
perf_print_counter(_bad_transfer_perf);
|
||||
}
|
||||
|
||||
int
|
||||
ICP10100::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
|
||||
ICP10100::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);
|
||||
|
||||
const hrt_abstime nowx = hrt_absolute_time();
|
||||
float temperature = _temperature_C;
|
||||
float pressure = _pressure_Pa; // to Pascal
|
||||
pressure = pressure / 100.0f; // to mbar
|
||||
|
||||
_px4_baro.set_error_count(perf_event_count(_bad_transfer_perf));
|
||||
_px4_baro.set_temperature(temperature);
|
||||
_px4_baro.update(nowx, pressure);
|
||||
|
||||
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
|
||||
ICP10100::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
|
||||
ICP10100::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
|
||||
ICP10100::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)
|
||||
{
|
||||
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
|
||||
ICP10100::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
|
||||
ICP10100::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);
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Inven_Sense_ICP10100_registers.hpp"
|
||||
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <lib/drivers/device/i2c.h>
|
||||
#include <lib/drivers/barometer/PX4Barometer.hpp>
|
||||
#include <lib/perf/perf_counter.h>
|
||||
#include <px4_platform_common/i2c_spi_buses.h>
|
||||
|
||||
using namespace Inven_Sense_ICP10100;
|
||||
|
||||
class ICP10100 : public device::I2C, public I2CSPIDriver<ICP10100>
|
||||
{
|
||||
public:
|
||||
ICP10100(const I2CSPIDriverConfig &config);
|
||||
~ICP10100() override;
|
||||
|
||||
static void print_usage();
|
||||
|
||||
void RunImpl();
|
||||
|
||||
int init() override;
|
||||
void print_status() override;
|
||||
|
||||
private:
|
||||
int probe() override;
|
||||
|
||||
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);
|
||||
|
||||
PX4Barometer _px4_baro;
|
||||
|
||||
perf_counter_t _reset_perf{perf_alloc(PC_COUNT, MODULE_NAME": reset")};
|
||||
perf_counter_t _sample_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": read")};
|
||||
perf_counter_t _bad_transfer_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad transfer")};
|
||||
|
||||
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,
|
||||
READ
|
||||
} _state{STATE::RESET};
|
||||
|
||||
enum class MODE : uint8_t {
|
||||
FAST,
|
||||
NORMAL,
|
||||
ACCURATE,
|
||||
VERY_ACCURATE
|
||||
} _mode{MODE::VERY_ACCURATE};
|
||||
};
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file icp10100_registers.hpp
|
||||
*
|
||||
* icp10100 registers.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Inven_Sense_ICP10100
|
||||
{
|
||||
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 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
|
||||
};
|
||||
} // namespace Inven_Sense_ICP10100
|
||||
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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 <px4_platform_common/px4_config.h>
|
||||
#include <px4_platform_common/getopt.h>
|
||||
#include <px4_platform_common/module.h>
|
||||
|
||||
#include "ICP10100.hpp"
|
||||
|
||||
void
|
||||
ICP10100::print_usage()
|
||||
{
|
||||
PRINT_MODULE_USAGE_NAME("icp10100", "driver");
|
||||
PRINT_MODULE_USAGE_SUBCATEGORY("baro");
|
||||
PRINT_MODULE_USAGE_COMMAND("start");
|
||||
PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false);
|
||||
PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x63);
|
||||
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
|
||||
}
|
||||
|
||||
extern "C" int icp10100_main(int argc, char *argv[])
|
||||
{
|
||||
using ThisDriver = ICP10100;
|
||||
BusCLIArguments cli{true, false};
|
||||
cli.i2c_address = I2C_ADDRESS_DEFAULT;
|
||||
cli.default_i2c_frequency = I2C_SPEED;
|
||||
|
||||
const char *verb = cli.parseDefaultArguments(argc, argv);
|
||||
|
||||
if (!verb) {
|
||||
ThisDriver::print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_ICP10100);
|
||||
|
||||
if (!strcmp(verb, "start")) {
|
||||
return ThisDriver::module_start(cli, iterator);
|
||||
|
||||
} else if (!strcmp(verb, "stop")) {
|
||||
return ThisDriver::module_stop(iterator);
|
||||
|
||||
} else if (!strcmp(verb, "status")) {
|
||||
return ThisDriver::module_status(iterator);
|
||||
}
|
||||
|
||||
ThisDriver::print_usage();
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
############################################################################
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
px4_add_module(
|
||||
MODULE drivers__invensense__icp10111
|
||||
MAIN icp10111
|
||||
COMPILE_FLAGS
|
||||
SRCS
|
||||
Inven_Sense_ICP10111_registers.hpp
|
||||
ICP10111.cpp
|
||||
ICP10111.hpp
|
||||
icp10111_main.cpp
|
||||
DEPENDS
|
||||
drivers_barometer
|
||||
px4_work_queue
|
||||
)
|
||||
+375
@@ -0,0 +1,375 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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),
|
||||
_px4_baro(get_device_id())
|
||||
{
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
const hrt_abstime nowx = hrt_absolute_time();
|
||||
float temperature = _temperature_C;
|
||||
float pressure = _pressure_Pa; // to Pascal
|
||||
pressure = pressure / 100.0f; // to mbar
|
||||
|
||||
_px4_baro.set_error_count(perf_event_count(_bad_transfer_perf));
|
||||
_px4_baro.set_temperature(temperature);
|
||||
_px4_baro.update(nowx, pressure);
|
||||
|
||||
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);
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Inven_Sense_ICP10111_registers.hpp"
|
||||
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <lib/drivers/device/i2c.h>
|
||||
#include <lib/drivers/barometer/PX4Barometer.hpp>
|
||||
#include <lib/perf/perf_counter.h>
|
||||
#include <px4_platform_common/i2c_spi_buses.h>
|
||||
|
||||
using namespace Inven_Sense_ICP10111;
|
||||
|
||||
class ICP10111 : public device::I2C, public I2CSPIDriver<ICP10111>
|
||||
{
|
||||
public:
|
||||
ICP10111(const I2CSPIDriverConfig &config);
|
||||
~ICP10111() override;
|
||||
|
||||
static void print_usage();
|
||||
|
||||
void RunImpl();
|
||||
|
||||
int init() override;
|
||||
void print_status() override;
|
||||
|
||||
private:
|
||||
int probe() override;
|
||||
|
||||
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);
|
||||
|
||||
PX4Barometer _px4_baro;
|
||||
|
||||
perf_counter_t _reset_perf{perf_alloc(PC_COUNT, MODULE_NAME": reset")};
|
||||
perf_counter_t _sample_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": read")};
|
||||
perf_counter_t _bad_transfer_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad transfer")};
|
||||
|
||||
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,
|
||||
READ
|
||||
} _state{STATE::RESET};
|
||||
|
||||
enum class MODE : uint8_t {
|
||||
FAST,
|
||||
NORMAL,
|
||||
ACCURATE,
|
||||
VERY_ACCURATE
|
||||
} _mode{MODE::VERY_ACCURATE};
|
||||
};
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file icp10111_registers.hpp
|
||||
*
|
||||
* icp10111 registers.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace Inven_Sense_ICP10111
|
||||
{
|
||||
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 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
|
||||
};
|
||||
} // namespace Inven_Sense_ICP10111
|
||||
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* 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 <px4_platform_common/px4_config.h>
|
||||
#include <px4_platform_common/getopt.h>
|
||||
#include <px4_platform_common/module.h>
|
||||
|
||||
#include "ICP10111.hpp"
|
||||
|
||||
void
|
||||
ICP10111::print_usage()
|
||||
{
|
||||
PRINT_MODULE_USAGE_NAME("icp10111", "driver");
|
||||
PRINT_MODULE_USAGE_SUBCATEGORY("baro");
|
||||
PRINT_MODULE_USAGE_COMMAND("start");
|
||||
PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false);
|
||||
PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x63);
|
||||
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
|
||||
}
|
||||
|
||||
extern "C" int icp10111_main(int argc, char *argv[])
|
||||
{
|
||||
using ThisDriver = ICP10111;
|
||||
BusCLIArguments cli{true, false};
|
||||
cli.i2c_address = I2C_ADDRESS_DEFAULT;
|
||||
cli.default_i2c_frequency = I2C_SPEED;
|
||||
|
||||
const char *verb = cli.parseDefaultArguments(argc, argv);
|
||||
|
||||
if (!verb) {
|
||||
ThisDriver::print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_ICP10111);
|
||||
|
||||
if (!strcmp(verb, "start")) {
|
||||
return ThisDriver::module_start(cli, iterator);
|
||||
|
||||
} else if (!strcmp(verb, "stop")) {
|
||||
return ThisDriver::module_stop(iterator);
|
||||
|
||||
} else if (!strcmp(verb, "status")) {
|
||||
return ThisDriver::module_status(iterator);
|
||||
}
|
||||
|
||||
ThisDriver::print_usage();
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user