Add TCBP001TA Barometer Driver (#14774)

This commit is contained in:
斯东Stone 2021-02-25 09:11:58 -06:00 committed by GitHub
parent 6482120d9a
commit e5b689e33c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 971 additions and 0 deletions

View File

@ -39,3 +39,4 @@ add_subdirectory(lps22hb)
add_subdirectory(lps33hw)
#add_subdirectory(mpl3115a2) # not ready for general inclusion
add_subdirectory(ms5611)
#add_subdirectory(tcbp001ta) # only for users who really need this

View File

@ -0,0 +1,44 @@
############################################################################
#
# Copyright (c) 2020 PX4 Development Team. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name PX4 nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
px4_add_module(
MODULE drivers__barometer__tcbp001ta
MAIN tcbp001ta
SRCS
tcbp001ta.cpp
tcbp001ta_spi.cpp
tcbp001ta_main.cpp
DEPENDS
drivers_barometer
px4_work_queue
)

View File

@ -0,0 +1,179 @@
/****************************************************************************
*
* Copyright (C) 2020 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file tcbp001ta/defines.h
*
* Shared defines for the TCBP001TA barometer driver.
*
* @author Xiaowei Zhao <xiaowei_zhao1013@163.com>
* @author Stone White <stone@thone.io>
*
*/
#pragma once
#include <inttypes.h>
#define TCBP001TA_ADDR_CAL 0x10 /* address of calibration data */
#define TCBP001TA_ADDR_DATA 0x00 /* address of presure data */
#define TCBP001TA_ADDR_PRS_DATA 0X00 /* address of presure data */
#define TCBP001TA_ADDR_TMP_DATA 0x03 /* address of tempature data */
#define TCBP001TA_ADDR_PRS_CFG 0x06
#define TCBP001TA_ADDR_TMP_CFG 0x07
#define TCBP001TA_ADDR_MEAS_CFG 0x08
#define TCBP001TA_ADDR_CFG_REG 0x09
#define TCBP001TA_ADDR_INT_STS 0x0A
#define TCBP001TA_ADDR_FIFO_STS 0x0B
#define TCBP001TA_ADDR_RESET 0x0C /* reset */
#define TCBP001TA_ADDR_ID 0x0D /* product and revision ID */
#define TCBP001TA_ADDR_TMP_COEF_SRCE 0x28
#define TCBP001TA_VALUE_ID 0x10 /* chip id */
#define TCBP001TA_VALUE_RESET 0x89 /* reset */
#define TCBP001TA_PRS_TMP_RATE_1 (0x0 << 4)
#define TCBP001TA_PRS_TMP_RATE_2 (0x1 << 4)
#define TCBP001TA_PRS_TMP_RATE_4 (0x2 << 4)
#define TCBP001TA_PRS_TMP_RATE_8 (0x3 << 4)
#define TCBP001TA_PRS_TMP_RATE_16 (0x4 << 4)
#define TCBP001TA_PRS_TMP_RATE_32 (0x5 << 4)
#define TCBP001TA_PRS_TMP_RATE_64 (0x6 << 4)
#define TCBP001TA_PRS_TMP_RATE_128 (0x7 << 4)
#define TCBP001TA_PRS_TMP_PRC 0x0
#define TCBP001TA_PRS_TMP_PRC_2 0x1
#define TCBP001TA_PRS_TMP_PRC_4 0x2
#define TCBP001TA_PRS_TMP_PRC_8 0x3
#define TCBP001TA_PRS_TMP_PRC_16 0x4
#define TCBP001TA_PRS_TMP_PRC_32 0x5
#define TCBP001TA_PRS_TMP_PRC_64 0x6
#define TCBP001TA_PRS_TMP_PRC_128 0x7
#define TCBP001TA_TMP_EXT_ASIC 0x00
#define TCBP001TA_TMP_EXT_MEMS 0x80
#define TCBP001TA_MT_INIT 6400 /* max measure time of initial p + t in us */
#define TCBP001TA_MT 2300 /* max measure time of p or t in us */
#define POW_2_23_MINUS_1 0x7FFFFF //implies 2^23-1
#define POW_2_24 0x1000000
#define POW_2_15_MINUS_1 0x7FFF
#define POW_2_16 0x10000
#define POW_2_11_MINUS_1 0x7FF
#define POW_2_12 0x1000
#define POW_2_20 0x100000
#define POW_2_19_MINUS_1 524287
namespace tcbp001ta
{
#pragma pack(push,1)
struct calibration_s {
uint8_t c0_h;
uint8_t c0l_1h;
uint8_t c1l;
uint8_t c00h;
uint8_t c00m;
uint8_t c00l_10h;
uint8_t c10m;
uint8_t c10l;
uint8_t c01h;
uint8_t c01l;
uint8_t c11h;
uint8_t c11l;
uint8_t c20h;
uint8_t c20l;
uint8_t c21h;
uint8_t c21l;
uint8_t c30h;
uint8_t c30l;
}; //calibration data
struct data_s {
uint8_t p_msb;
uint8_t p_lsb;
uint8_t p_xlsb;
uint8_t t_msb;
uint8_t t_lsb;
uint8_t t_xlsb;
}; // data
#pragma pack(pop)
struct fcalibration_s {
int16_t c0; // 12bit
int16_t c1; // 12bit
int32_t c00; // 20bit
int32_t c10; // 20bit
int16_t c01; // 16bit
int16_t c11; // 16bit
int16_t c20; // 16bit
int16_t c21; // 16bit
int16_t c30; // 16bit
};
class ITCBP001TA
{
public:
virtual ~ITCBP001TA() = default;
virtual int init() = 0;
// read reg value
virtual uint8_t get_reg(uint8_t addr) = 0;
// write reg value
virtual int set_reg(uint8_t value, uint8_t addr) = 0;
// bulk read of data into buffer, return same pointer
virtual tcbp001ta::data_s *get_data(uint8_t addr) = 0;
// bulk read of calibration data into buffer, return same pointer
virtual tcbp001ta::calibration_s *get_calibration(uint8_t addr) = 0;
virtual uint32_t get_device_id() const = 0;
};
} /* namespace */
/* interface factories */
extern tcbp001ta::ITCBP001TA *tcbp001ta_spi_interface(uint8_t busnum, uint32_t device);
extern tcbp001ta::ITCBP001TA *tcbp001ta_i2c_interface(uint8_t busnum, uint32_t device);
typedef tcbp001ta::ITCBP001TA *(*TCBP001TA_constructor)(uint8_t, uint32_t);

View File

@ -0,0 +1,322 @@
/****************************************************************************
*
* Copyright (c) 2020 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file tcbp001ta.cpp
*
* Driver for TCBP001TA barometer.
*
* @author Xiaowei Zhao <xiaowei_zhao1013@163.com>
* @author Stone White <stone@thone.io>
*
*/
#include "tcbp001ta.hpp"
TCBP001TA::TCBP001TA(tcbp001ta::ITCBP001TA *interface) :
ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(interface->get_device_id())),
_px4_baro(interface->get_device_id()),
_interface(interface),
_sample_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": sample")),
_measure_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": measure")),
_comms_errors(perf_alloc(PC_COUNT, MODULE_NAME": comms errors"))
{
_px4_baro.set_device_type(DRV_BARO_DEVTYPE_TCBP001TA);
}
TCBP001TA::~TCBP001TA()
{
// make sure we are truly inactive
Stop();
// free perf counters
perf_free(_sample_perf);
perf_free(_measure_perf);
perf_free(_comms_errors);
delete _interface;
}
int
TCBP001TA::init()
{
// reset sensor
_interface->set_reg(TCBP001TA_VALUE_RESET, TCBP001TA_ADDR_RESET);
usleep(10000);
// check id
if (_interface->get_reg(TCBP001TA_ADDR_ID) != TCBP001TA_VALUE_ID) {
PX4_WARN("id of your baro is not: 0x%02x", TCBP001TA_VALUE_ID);
return -EIO;
}
// Presure write [0x6 | (0x3 << 4)] to 0x06
_interface->set_reg(TCBP001TA_PRS_TMP_PRC_64 | TCBP001TA_PRS_TMP_RATE_8, TCBP001TA_ADDR_PRS_CFG);
// Temperature write [0x80 | 0x1 | (0x2 << 4)] to 0x07
_interface->set_reg(TCBP001TA_TMP_EXT_MEMS | TCBP001TA_PRS_TMP_PRC_2 | TCBP001TA_PRS_TMP_RATE_4,
TCBP001TA_ADDR_TMP_CFG);
// write 0x00 to 0x09
_interface->set_reg(0x00, TCBP001TA_ADDR_CFG_REG);
tmp_osr_scale_coeff = TCBP001TA_get_scaling_coef(0);
prs_osr_scale_coeff = TCBP001TA_get_scaling_coef(0);
// get calibration and pre process them
_cal = _interface->get_calibration(TCBP001TA_ADDR_CAL);
if (_cal == nullptr) {
PX4_INFO("init failed");
return -EIO;
}
_fcal.c0 = (_cal->c0_h << 4) + ((_cal->c0l_1h >> 4) & 0x0F);
if (_fcal.c0 > POW_2_11_MINUS_1) {
_fcal.c0 = _fcal.c0 - POW_2_12;
}
_fcal.c1 = (_cal->c1l + ((_cal->c0l_1h & 0x0F) << 8));
if (_fcal.c1 > POW_2_11_MINUS_1) {
_fcal.c1 = _fcal.c1 - POW_2_12;
}
_fcal.c00 = ((_cal->c00m << 4) + (_cal->c00h << 12)) + ((_cal->c00l_10h >> 4) & 0x0F);
if (_fcal.c00 > POW_2_19_MINUS_1) {
_fcal.c00 = _fcal.c00 - POW_2_20;
}
_fcal.c10 = ((_cal->c00l_10h & 0x0F) << 16) + _cal->c10l + (_cal->c10m << 8);
if (_fcal.c10 > POW_2_19_MINUS_1) {
_fcal.c10 = _fcal.c10 - POW_2_20;
}
_fcal.c01 = (_cal->c01l + (_cal->c01h << 8));
//if(_fcal.c01 > POW_2_15_MINUS_1)
//_fcal.c01 = _fcal.c01 - POW_2_16;
_fcal.c11 = (_cal->c11l + (_cal->c11h << 8));
//if(_fcal.c11 > POW_2_15_MINUS_1)
//_fcal.c11 = _fcal.c11 - POW_2_16;
_fcal.c20 = (_cal->c20l + (_cal->c20h << 8));
//if(_fcal.c20 > POW_2_15_MINUS_1)
//_fcal.c20 = _fcal.c20 - POW_2_16;
_fcal.c21 = (_cal->c21l + (_cal->c21h << 8));
//if(_fcal.c21 > POW_2_15_MINUS_1)
//_fcal.c21 = _fcal.c21 - POW_2_16;
_fcal.c30 = (_cal->c30l + (_cal->c30h << 8));
//if(_fcal.c30 > POW_2_15_MINUS_1)
//_fcal.c30 = _fcal.c30 - POW_2_16;
Start();
return OK;
}
void
TCBP001TA::Start()
{
// reset the report ring and state machine
_collect_phase = false;
// schedule a cycle to start things
ScheduleNow();
}
void
TCBP001TA::Stop()
{
ScheduleClear();
}
void
TCBP001TA::Run()
{
if (_collect_phase) {
collect();
} else {
measure();
}
ScheduleDelayed(_measure_interval);
}
int
TCBP001TA::measure()
{
perf_begin(_measure_perf);
_collect_phase = true;
// start measure
//int ret = _interface->set_reg(_curr_ctrl | TCBP001TA_CTRL_MODE_FORCE, TCBP001TA_ADDR_CTRL);
//if (ret != OK) {
//perf_count(_comms_errors);
//perf_cancel(_measure_perf);
//return -EIO;
//}
perf_end(_measure_perf);
return OK;
}
int
TCBP001TA::collect()
{
perf_begin(_sample_perf);
_collect_phase = false;
// this should be fairly close to the end of the conversion, so the best approximation of the time
const hrt_abstime timestamp_sample = hrt_absolute_time();
//write 0x02 to reg 0x08 Temperature
_interface->set_reg(0x02, TCBP001TA_ADDR_MEAS_CFG);
tcbp001ta::data_s *data_temp = _interface->get_data(TCBP001TA_ADDR_TMP_DATA);
if (data_temp == nullptr) {
perf_count(_comms_errors);
perf_cancel(_sample_perf);
return -EIO;
}
uint32_t p_raw = (data_temp->p_msb << 16 | data_temp->p_lsb << 8) + (data_temp->p_xlsb);
//write 0x01 to reg 0x08 Pressure
_interface->set_reg(0x01, TCBP001TA_ADDR_MEAS_CFG);
tcbp001ta::data_s *data_pres = _interface->get_data(TCBP001TA_ADDR_PRS_DATA);
if (data_pres == nullptr) {
perf_count(_comms_errors);
perf_cancel(_sample_perf);
return -EIO;
}
uint32_t t_raw = (data_pres->t_msb << 16 | data_pres->t_lsb << 8) + (data_pres->t_xlsb);
// PX4_INFO("p raw %f", p_raw);
// PX4_INFO("t raw %f", t_raw);
// PX4_INFO("data 0 %d data 1 %d data2 %d", data_temp->p_msb, data_temp->p_lsb, data_temp->p_xlsb);
// PX4_INFO("data 3 %d data 4 %d data5 %d", data_pres->t_msb, data_pres->t_lsb, data_pres->t_xlsb);
// Temperature
float Traw_sc = (float)t_raw / (float)(tmp_osr_scale_coeff);
const float T = (_fcal.c0 / 2.0f) + (float)(_fcal.c1 * Traw_sc);
// Pressure
float Praw_sc = (float) p_raw / (float)(prs_osr_scale_coeff);
const float P = _fcal.c00 +
Praw_sc * (_fcal.c10 + Praw_sc * (_fcal.c20 + Praw_sc * _fcal.c30)) +
Praw_sc * _fcal.c01 +
Praw_sc * Praw_sc * (_fcal.c11 + Praw_sc * _fcal.c21);
_px4_baro.set_error_count(perf_event_count(_comms_errors));
_px4_baro.set_temperature(T);
float pressure = P / 100.0f; // to mbar
// PX4_INFO("press %f", double(pressure));
_px4_baro.update(timestamp_sample, pressure);
perf_end(_sample_perf);
return OK;
}
void
TCBP001TA::print_info()
{
perf_print_counter(_sample_perf);
perf_print_counter(_measure_perf);
perf_print_counter(_comms_errors);
_px4_baro.print_status();
}
uint32_t
TCBP001TA::TCBP001TA_get_scaling_coef(uint8_t osr)
{
uint32_t scaling_coeff;
switch (osr) {
case 0:
scaling_coeff = 524288;
break;
case 1:
scaling_coeff = 1572864;
break;
case 2:
scaling_coeff = 3670016;
break;
case 3:
scaling_coeff = 7864320;
break;
case 4:
scaling_coeff = 253952;
break;
case 5:
scaling_coeff = 516096;
break;
case 6:
scaling_coeff = 1040384;
break;
case 7:
scaling_coeff = 2088960;
break;
default:
scaling_coeff = 524288;
break;
}
return scaling_coeff;
}

View File

@ -0,0 +1,82 @@
/****************************************************************************
*
* Copyright (c) 2020 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#pragma once
#include "defines.h"
#include <drivers/drv_hrt.h>
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
#include <lib/drivers/barometer/PX4Barometer.hpp>
#include <lib/perf/perf_counter.h>
class TCBP001TA : public px4::ScheduledWorkItem
{
public:
TCBP001TA(tcbp001ta::ITCBP001TA *interface);
virtual ~TCBP001TA();
int init();
void print_info();
uint32_t tmp_osr_scale_coeff;
uint32_t prs_osr_scale_coeff;
uint32_t TCBP001TA_get_scaling_coef(uint8_t osr);
private:
void Run() override;
void Start();
void Stop();
int measure(); //start measure
int collect(); //get results and publish
PX4Barometer _px4_baro;
tcbp001ta::ITCBP001TA *_interface;
// set config, recommended settings
//static constexpr uint8_t _curr_ctrl{TCBP001TA_CTRL_P16 | TCBP001TA_CTRL_T2};
static constexpr uint32_t _measure_interval{TCBP001TA_MT_INIT + TCBP001TA_MT *(16 - 1 + 2 - 1)};
bool _collect_phase{false};
perf_counter_t _sample_perf;
perf_counter_t _measure_perf;
perf_counter_t _comms_errors;
tcbp001ta::calibration_s *_cal{nullptr}; //stored calibration constants
tcbp001ta::fcalibration_s _fcal{}; //pre processed calibration constants
};

View File

@ -0,0 +1,196 @@
/****************************************************************************
*
* Copyright (c) 2020 PX4 Development Team. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#include <px4_platform_common/px4_config.h>
#include <px4_platform_common/getopt.h>
#include "tcbp001ta.hpp"
enum class TCBP001TA_BUS {
SPI_INTERNAL = 0
};
namespace tcbp001ta
{
// list of supported bus configurations
struct tcbp001ta_bus_option {
TCBP001TA_BUS busid;
TCBP001TA_constructor interface_constructor;
uint8_t busnum;
uint32_t address;
TCBP001TA *dev;
} bus_options[] = {
{ TCBP001TA_BUS::SPI_INTERNAL, &tcbp001ta_spi_interface, PX4_SPI_BUS_BARO, PX4_SPIDEV_BARO, nullptr },
};
// find a bus structure for a busid
static struct tcbp001ta_bus_option *find_bus(TCBP001TA_BUS busid)
{
for (tcbp001ta_bus_option &bus_option : bus_options) {
if ((
busid == bus_option.busid) && bus_option.dev != nullptr) {
return &bus_option;
}
}
return nullptr;
}
static bool start_bus(tcbp001ta_bus_option &bus)
{
tcbp001ta::ITCBP001TA *interface = bus.interface_constructor(bus.busnum, bus.address);
if ((interface == nullptr) || (interface->init() != PX4_OK)) {
PX4_WARN("no device on bus %u", (unsigned)bus.busid);
delete interface;
return false;
}
TCBP001TA *dev = new TCBP001TA(interface);
if (dev == nullptr) {
PX4_ERR("driver allocate failed");
delete interface;
return false;
}
if (dev->init() != PX4_OK) {
PX4_ERR("driver start failed");
delete dev; // TCBP001TA deletes the interface
return false;
}
bus.dev = dev;
return true;
}
static int start(TCBP001TA_BUS busid)
{
for (tcbp001ta_bus_option &bus_option : bus_options) {
if (bus_option.dev != nullptr) {
// this device is already started
PX4_WARN("already started");
continue;
}
if (bus_option.busid != busid) {
// not the one that is asked for
continue;
}
if (start_bus(bus_option)) {
return PX4_OK;
}
}
return PX4_ERROR;
}
static int stop(TCBP001TA_BUS busid)
{
tcbp001ta_bus_option *bus = find_bus(busid);
if (bus != nullptr && bus->dev != nullptr) {
delete bus->dev;
bus->dev = nullptr;
} else {
PX4_WARN("driver not running");
return PX4_ERROR;
}
return PX4_OK;
}
static int status(TCBP001TA_BUS busid)
{
tcbp001ta_bus_option *bus = find_bus(busid);
if (bus != nullptr && bus->dev != nullptr) {
bus->dev->print_info();
return PX4_OK;
}
PX4_WARN("driver not running");
return PX4_ERROR;
}
static int usage()
{
PX4_INFO("missing command: try 'start', 'stop', 'status'");
PX4_INFO("options:");
PX4_INFO(" -X (i2c external bus)");
PX4_INFO(" -I (i2c internal bus)");
PX4_INFO(" -s (spi internal bus)");
PX4_INFO(" -S (spi external bus)");
return 0;
}
} // namespace
extern "C" int tcbp001ta_main(int argc, char *argv[])
{
int myoptind = 1;
// int ch;
// const char *myoptarg = nullptr;
TCBP001TA_BUS busid;
busid = TCBP001TA_BUS::SPI_INTERNAL;
// if (myoptind >= argc) {
// return tcbp001ta::usage();
// }
const char *verb = argv[myoptind];
if (!strcmp(verb, "start")) {
PX4_INFO("start");
return tcbp001ta::start(busid);
} else if (!strcmp(verb, "stop")) {
return tcbp001ta::stop(busid);
} else if (!strcmp(verb, "status")) {
return tcbp001ta::status(busid);
}
return tcbp001ta::usage();
}

View File

@ -0,0 +1,146 @@
/****************************************************************************
*
* Copyright (c) 2016-2019 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 tcbp001ta_spi.cpp
*
* SPI interface for TCBP001TA.
*
* @author Xiaowei Zhao <xiaowei_zhao1013@163.com>
* @author Stone White <stone@thone.io>
*
*/
#include "defines.h"
#include <px4_platform_common/px4_config.h>
#include <drivers/device/spi.h>
/* SPI protocol address bits */
#define DIR_READ (1<<7) //for set
#define DIR_WRITE ~(1<<7) //for clear
#pragma pack(push,1)
struct spi_data_s {
uint8_t addr;
struct tcbp001ta::data_s data;
};
struct spi_calibration_s {
uint8_t addr;
struct tcbp001ta::calibration_s cal;
};
#pragma pack(pop)
class TCBP001TA_SPI: public device::SPI, public tcbp001ta::ITCBP001TA
{
public:
TCBP001TA_SPI(uint8_t bus, uint32_t device);
virtual ~TCBP001TA_SPI() override = default;
int init() override { return SPI::init(); }
uint8_t get_reg(uint8_t addr) override;
int set_reg(uint8_t value, uint8_t addr) override;
tcbp001ta::data_s *get_data(uint8_t addr) override;
tcbp001ta::calibration_s *get_calibration(uint8_t addr) override;
uint32_t get_device_id() const override { return device::SPI::get_device_id(); }
private:
spi_calibration_s _cal{};
spi_data_s _data{};
};
tcbp001ta::ITCBP001TA *
tcbp001ta_spi_interface(uint8_t busnum, uint32_t device)
{
return new TCBP001TA_SPI(busnum, device);
}
TCBP001TA_SPI::TCBP001TA_SPI(uint8_t bus, uint32_t device) :
SPI("TCBP001TA_SPI", nullptr, bus, device, SPIDEV_MODE3, 10 * 1000 * 1000)
{
}
uint8_t
TCBP001TA_SPI::get_reg(uint8_t addr)
{
uint8_t cmd[2] = { (uint8_t)(addr | DIR_READ), 0}; // set MSB bit
transfer(&cmd[0], &cmd[0], 2);
return cmd[1];
}
int
TCBP001TA_SPI::set_reg(uint8_t value, uint8_t addr)
{
uint8_t cmd[2] = { (uint8_t)(addr & DIR_WRITE), value}; // clear MSB bit
return transfer(&cmd[0], nullptr, 2);
}
tcbp001ta::data_s *
TCBP001TA_SPI::get_data(uint8_t addr)
{
_data.addr = (uint8_t)(addr | DIR_READ); // set MSB bit
// PX4_INFO("addr %02x", addr);
// PX4_INFO("addr %02x", _data.addr);
if (transfer((uint8_t *)&_data, (uint8_t *)&_data, sizeof(spi_data_s)) == OK) {
// PX4_INFO("t xlsb data %d", _data.data.t_xlsb);
// PX4_INFO("t msb data %d", _data.data.t_msb);
// PX4_INFO("t lsb data %d", _data.data.t_lsb);
// PX4_INFO("p xlsb data %d", _data.data.p_xlsb);
// PX4_INFO("p msb data %d", _data.data.p_msb);
// PX4_INFO("p lsb data %d", _data.data.p_lsb);
return &(_data.data);
} else {
return nullptr;
}
}
tcbp001ta::calibration_s *
TCBP001TA_SPI::get_calibration(uint8_t addr)
{
_cal.addr = addr | DIR_READ;
if (transfer((uint8_t *)&_cal, (uint8_t *)&_cal, sizeof(spi_calibration_s)) == OK) {
return &(_cal.cal);
} else {
return nullptr;
}
}

View File

@ -106,6 +106,7 @@
#define DRV_DIFF_PRESS_DEVTYPE_SDP32 0x4A
#define DRV_DIFF_PRESS_DEVTYPE_SDP33 0x4B
#define DRV_BARO_DEVTYPE_LPS33HW 0x4C
#define DRV_BARO_DEVTYPE_TCBP001TA 0x4D
#define DRV_BARO_DEVTYPE_MPL3115A2 0x51
#define DRV_ACC_DEVTYPE_FXOS8701C 0x52