From 7390e6ecef32d90721206357a31cb9ad465ec7ba Mon Sep 17 00:00:00 2001 From: Leonard Hall Date: Sat, 22 Jul 2023 10:52:02 +0930 Subject: [PATCH] AP_TemperatureSensor: Add TSYS03 support --- .../AP_TemperatureSensor.cpp | 6 + .../AP_TemperatureSensor.h | 2 + .../AP_TemperatureSensor_Params.cpp | 2 +- .../AP_TemperatureSensor_Params.h | 1 + .../AP_TemperatureSensor_TSYS03.cpp | 120 ++++++++++++++++++ .../AP_TemperatureSensor_TSYS03.h | 54 ++++++++ 6 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.cpp create mode 100644 libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.h diff --git a/libraries/AP_TemperatureSensor/AP_TemperatureSensor.cpp b/libraries/AP_TemperatureSensor/AP_TemperatureSensor.cpp index fce79c1a3b..3bcdb614bd 100644 --- a/libraries/AP_TemperatureSensor/AP_TemperatureSensor.cpp +++ b/libraries/AP_TemperatureSensor/AP_TemperatureSensor.cpp @@ -25,6 +25,7 @@ #if !AP_TEMPERATURE_SENSOR_DUMMY_METHODS_ENABLED #include "AP_TemperatureSensor_TSYS01.h" +#include "AP_TemperatureSensor_TSYS03.h" #include "AP_TemperatureSensor_MCP9600.h" #include "AP_TemperatureSensor_MAX31865.h" @@ -141,6 +142,11 @@ void AP_TemperatureSensor::init() case AP_TemperatureSensor_Params::Type::MAX31865: drivers[instance] = new AP_TemperatureSensor_MAX31865(*this, _state[instance], _params[instance]); break; +#endif +#if AP_TEMPERATURE_SENSOR_TSYS03_ENABLED + case AP_TemperatureSensor_Params::Type::TSYS03: + drivers[instance] = new AP_TemperatureSensor_TSYS03(*this, _state[instance], _params[instance]); + break; #endif case AP_TemperatureSensor_Params::Type::NONE: default: diff --git a/libraries/AP_TemperatureSensor/AP_TemperatureSensor.h b/libraries/AP_TemperatureSensor/AP_TemperatureSensor.h index cf5cdc84c1..ca0abed8b6 100644 --- a/libraries/AP_TemperatureSensor/AP_TemperatureSensor.h +++ b/libraries/AP_TemperatureSensor/AP_TemperatureSensor.h @@ -25,6 +25,7 @@ class AP_TemperatureSensor_Backend; class AP_TemperatureSensor_TSYS01; class AP_TemperatureSensor_MCP9600; class AP_TemperatureSensor_MAX31865; +class AP_TemperatureSensor_TSYS03; class AP_TemperatureSensor { @@ -32,6 +33,7 @@ class AP_TemperatureSensor friend class AP_TemperatureSensor_TSYS01; friend class AP_TemperatureSensor_MCP9600; friend class AP_TemperatureSensor_MAX31865; + friend class AP_TemperatureSensor_TSYS03; public: diff --git a/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.cpp b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.cpp index bb721d747c..9d0ad2f455 100644 --- a/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.cpp +++ b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.cpp @@ -34,7 +34,7 @@ const AP_Param::GroupInfo AP_TemperatureSensor_Params::var_info[] = { // @Param: TYPE // @DisplayName: Temperature Sensor Type // @Description: Enables temperature sensors - // @Values: 0:Disabled, 1:TSYS01, 2:MCP9600, 3:MAX31865 + // @Values: 0:Disabled, 1:TSYS01, 2:MCP9600, 3:MAX31865, 4:TSYS03 // @User: Standard // @RebootRequired: True AP_GROUPINFO_FLAGS("TYPE", 1, AP_TemperatureSensor_Params, type, (float)Type::NONE, AP_PARAM_FLAG_ENABLE), diff --git a/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.h b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.h index d2321864e3..1cda825d64 100644 --- a/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.h +++ b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_Params.h @@ -31,6 +31,7 @@ public: TSYS01 = 1, MCP9600 = 2, MAX31865 = 3, + TSYS03 = 4, }; // option to map to another system component diff --git a/libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.cpp b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.cpp new file mode 100644 index 0000000000..649a0063a3 --- /dev/null +++ b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.cpp @@ -0,0 +1,120 @@ +/* + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include "AP_TemperatureSensor_TSYS03.h" + +#if AP_TEMPERATURE_SENSOR_TSYS03_ENABLED +#include +#include +#include +#include + +#include + +#ifndef AP_TEMPERATURE_SENSOR_TSYS03_ENFORCE_KNOWN_VALID_I2C_ADDRESS +#define AP_TEMPERATURE_SENSOR_TSYS03_ENFORCE_KNOWN_VALID_I2C_ADDRESS 1 +#endif + +extern const AP_HAL::HAL &hal; + +static const uint8_t TSYS03_CMD_RESET = 0x1E; +static const uint8_t TSYS03_CMD_CONVERT = 0x46; +static const uint8_t TSYS03_CMD_READ_ADC = 0x00; + +void AP_TemperatureSensor_TSYS03::init() +{ + constexpr char name[] = "TSYS03"; + +#if AP_TEMPERATURE_SENSOR_TSYS03_ENFORCE_KNOWN_VALID_I2C_ADDRESS + // I2C Address: Default to using TSYS03_ADDR_CSB0 & Check I2C Address is Correct + if ((_params.bus_address != TSYS03_ADDR_CSB0) ) { + GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "%s wrong I2C addr of 0x%2X, setting to 0x%2X", name, (unsigned)_params.bus_address.get(), (unsigned)TSYS03_ADDR_CSB0); + _params.bus_address.set(TSYS03_ADDR_CSB0); + } +#endif + + _dev = std::move(hal.i2c_mgr->get_device(_params.bus, _params.bus_address)); + if (!_dev) { + GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "%s device is null!", name); + return; + } + + WITH_SEMAPHORE(_dev->get_semaphore()); + + _dev->set_retries(10); + + // reset + if (!_dev->transfer(&TSYS03_CMD_RESET, 1, nullptr, 0)) { + GCS_SEND_TEXT(MAV_SEVERITY_WARNING, "%s reset failed", name); + return; + } + + hal.scheduler->delay(4); + + start_next_sample(); + + // lower retries for run + _dev->set_retries(3); + + /* Request 20Hz update */ + // Max conversion time is 9.04 ms + _dev->register_periodic_callback(50 * AP_USEC_PER_MSEC, + FUNCTOR_BIND_MEMBER(&AP_TemperatureSensor_TSYS03::_timer, void)); +} + +uint16_t AP_TemperatureSensor_TSYS03::read_adc() const +{ + uint8_t val[3]; + if (!_dev->transfer(&TSYS03_CMD_READ_ADC, 1, val, 3)) { + return 0; + } + + // ensure crc is correct: + uint8_t expected_crc = 0; + for (uint8_t i=0; i<2; i++) { + expected_crc = crc8_dvb(expected_crc, val[i], 0x31); + } + if (expected_crc != val[2]) { + return 0; + } + + return UINT16_VALUE(val[0],val[1]); +} + +void AP_TemperatureSensor_TSYS03::_timer(void) +{ + const uint16_t adc = read_adc(); + + if (adc != 0) { + const float temp = calculate(adc); + set_temperature(temp); + } + + start_next_sample(); +} + +void AP_TemperatureSensor_TSYS03::start_next_sample() +{ + _dev->transfer(&TSYS03_CMD_CONVERT, 1, nullptr, 0); +} + +float AP_TemperatureSensor_TSYS03::calculate(const uint16_t adc) const +{ + const float temperature = -40.0 + adc * 165 / (powf(2, 16) - 1.0); + + return temperature; +} + +#endif // AP_TEMPERATURE_SENSOR_TSYS03_ENABLED diff --git a/libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.h b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.h new file mode 100644 index 0000000000..609cf5a10a --- /dev/null +++ b/libraries/AP_TemperatureSensor/AP_TemperatureSensor_TSYS03.h @@ -0,0 +1,54 @@ +/* + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +/* + * I2C driver for Measurement Specialties MEAS TSYS03 digital temperature sensor + */ + +#pragma once +#include "AP_TemperatureSensor_Backend.h" + +#ifndef AP_TEMPERATURE_SENSOR_TSYS03_ENABLED +#define AP_TEMPERATURE_SENSOR_TSYS03_ENABLED AP_TEMPERATURE_SENSOR_ENABLED +#endif + +#if AP_TEMPERATURE_SENSOR_TSYS03_ENABLED + +#define TSYS03_ADDR_CSB0 0x40 + +class AP_TemperatureSensor_TSYS03 : public AP_TemperatureSensor_Backend { + using AP_TemperatureSensor_Backend::AP_TemperatureSensor_Backend; + +public: + void init(void) override; + + void update() override {}; + + +private: + // reset device + bool reset(void) const; + + // begin an ADC conversion (min:7.40ms typ:8.22ms max:9.04ms) + void start_next_sample(); + uint16_t read_adc(void) const; + + // update the temperature, called at 20Hz + void _timer(void); + + // calculate temperature using adc reading and internal calibration + float calculate(const uint16_t adc) const; +}; +#endif // AP_TEMPERATURE_SENSOR_TSYS03_ENABLED