mirror of https://github.com/ArduPilot/ardupilot
307 lines
11 KiB
C++
307 lines
11 KiB
C++
/*
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "AP_TemperatureSensor.h"
|
|
|
|
#if AP_TEMPERATURE_SENSOR_ENABLED
|
|
|
|
#include <AP_Vehicle/AP_Vehicle_Type.h>
|
|
|
|
#define AP_TEMPERATURE_SENSOR_DUMMY_METHODS_ENABLED (!(APM_BUILD_TYPE(APM_BUILD_ArduSub) || (AP_TEMPERATURE_SENSOR_ENABLED == 1)))
|
|
|
|
|
|
#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"
|
|
#include "AP_TemperatureSensor_Analog.h"
|
|
#include "AP_TemperatureSensor_DroneCAN.h"
|
|
|
|
#include <AP_Logger/AP_Logger.h>
|
|
#include <AP_Vehicle/AP_Vehicle_Type.h>
|
|
|
|
extern const AP_HAL::HAL& hal;
|
|
|
|
const AP_Param::GroupInfo AP_TemperatureSensor::var_info[] = {
|
|
|
|
// SKIP INDEX 0
|
|
|
|
// @Param: _LOG
|
|
// @DisplayName: Logging
|
|
// @Description: Enables temperature sensor logging
|
|
// @Values: 0:Disabled, 1:Enabled
|
|
// @User: Standard
|
|
AP_GROUPINFO("_LOG", 1, AP_TemperatureSensor, _log_flag, 0),
|
|
|
|
// SKIP Index 2-9 to be for parameters that apply to every sensor
|
|
|
|
// @Group: 1_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[0], "1_", 10, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 1_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[0], "1_", 19, AP_TemperatureSensor, backend_var_info[0]),
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 2
|
|
// @Group: 2_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[1], "2_", 11, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 2_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[1], "2_", 20, AP_TemperatureSensor, backend_var_info[1]),
|
|
#endif
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 3
|
|
// @Group: 3_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[2], "3_", 12, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 3_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[2], "3_", 21, AP_TemperatureSensor, backend_var_info[2]),
|
|
#endif
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 4
|
|
// @Group: 4_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[3], "4_", 13, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 4_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[3], "4_", 22, AP_TemperatureSensor, backend_var_info[3]),
|
|
#endif
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 5
|
|
// @Group: 5_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[4], "5_", 14, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 5_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[4], "5_", 23, AP_TemperatureSensor, backend_var_info[4]),
|
|
#endif
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 6
|
|
// @Group: 6_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[5], "6_", 15, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 6_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[5], "6_", 24, AP_TemperatureSensor, backend_var_info[5]),
|
|
#endif
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 7
|
|
// @Group: 7_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[6], "7_", 16, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 7_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[6], "7_", 25, AP_TemperatureSensor, backend_var_info[6]),
|
|
#endif
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 8
|
|
// @Group: 8_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[7], "8_", 17, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 8_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[7], "8_", 26, AP_TemperatureSensor, backend_var_info[7]),
|
|
#endif
|
|
|
|
#if AP_TEMPERATURE_SENSOR_MAX_INSTANCES >= 9
|
|
// @Group: 9_
|
|
// @Path: AP_TemperatureSensor_Params.cpp
|
|
AP_SUBGROUPINFO(_params[8], "9_", 18, AP_TemperatureSensor, AP_TemperatureSensor_Params),
|
|
|
|
// @Group: 9_
|
|
// @Path: AP_TemperatureSensor_Analog.cpp
|
|
AP_SUBGROUPVARPTR(drivers[8], "9_", 26, AP_TemperatureSensor, backend_var_info[8]),
|
|
#endif
|
|
|
|
AP_GROUPEND
|
|
};
|
|
|
|
const AP_Param::GroupInfo *AP_TemperatureSensor::backend_var_info[AP_TEMPERATURE_SENSOR_MAX_INSTANCES];
|
|
|
|
// Default Constructor
|
|
AP_TemperatureSensor::AP_TemperatureSensor()
|
|
{
|
|
AP_Param::setup_object_defaults(this, var_info);
|
|
|
|
if (_singleton != nullptr) {
|
|
AP_HAL::panic("AP_TemperatureSensor must be singleton");
|
|
}
|
|
_singleton = this;
|
|
}
|
|
|
|
// init - instantiate the temperature sensors
|
|
void AP_TemperatureSensor::init()
|
|
{
|
|
// check init has not been called before
|
|
if (_num_instances != 0) {
|
|
return;
|
|
}
|
|
|
|
// For Sub set the Default: Type to TSYS01 and I2C_ADDR of 0x77
|
|
#if APM_BUILD_TYPE(APM_BUILD_ArduSub) && AP_TEMPERATURE_SENSOR_TSYS01_ENABLED
|
|
AP_Param::set_default_by_name("TEMP1_TYPE", (float)AP_TemperatureSensor_Params::Type::TSYS01);
|
|
AP_Param::set_default_by_name("TEMP1_ADDR", TSYS01_ADDR_CSB0);
|
|
#endif
|
|
|
|
// create each instance
|
|
for (uint8_t instance = 0; instance < AP_TEMPERATURE_SENSOR_MAX_INSTANCES; instance++) {
|
|
_state[instance].instance = instance;
|
|
|
|
switch (get_type(instance)) {
|
|
#if AP_TEMPERATURE_SENSOR_TSYS01_ENABLED
|
|
case AP_TemperatureSensor_Params::Type::TSYS01:
|
|
drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_TSYS01(*this, _state[instance], _params[instance]);
|
|
break;
|
|
#endif
|
|
#if AP_TEMPERATURE_SENSOR_MCP9600_ENABLED
|
|
case AP_TemperatureSensor_Params::Type::MCP9600:
|
|
drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_MCP9600(*this, _state[instance], _params[instance]);
|
|
break;
|
|
#endif
|
|
#if AP_TEMPERATURE_SENSOR_MAX31865_ENABLED
|
|
case AP_TemperatureSensor_Params::Type::MAX31865:
|
|
drivers[instance] = NEW_NOTHROW 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_NOTHROW AP_TemperatureSensor_TSYS03(*this, _state[instance], _params[instance]);
|
|
break;
|
|
#endif
|
|
#if AP_TEMPERATURE_SENSOR_ANALOG_ENABLED
|
|
case AP_TemperatureSensor_Params::Type::ANALOG:
|
|
drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_Analog(*this, _state[instance], _params[instance]);
|
|
break;
|
|
#endif
|
|
#if AP_TEMPERATURE_SENSOR_DRONECAN_ENABLED
|
|
case AP_TemperatureSensor_Params::Type::DRONECAN:
|
|
drivers[instance] = NEW_NOTHROW AP_TemperatureSensor_DroneCAN(*this, _state[instance], _params[instance]);
|
|
break;
|
|
#endif
|
|
case AP_TemperatureSensor_Params::Type::NONE:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// call init function for each backend
|
|
if (drivers[instance] != nullptr) {
|
|
if (_state[instance].var_info != nullptr) {
|
|
// Load backend specific params
|
|
backend_var_info[instance] = _state[instance].var_info;
|
|
AP_Param::load_object_from_eeprom(drivers[instance], backend_var_info[instance]);
|
|
}
|
|
|
|
drivers[instance]->init();
|
|
// _num_instances is actually the index for looping over instances
|
|
// the user may have TEMP_TYPE=0 and TEMP2_TYPE=7, in which case
|
|
// there will be a gap, but as we always check for drivers[instances] being nullptr
|
|
// this is safe
|
|
_num_instances = instance + 1;
|
|
}
|
|
}
|
|
|
|
if (_num_instances > 0) {
|
|
// param count could have changed
|
|
AP_Param::invalidate_count();
|
|
}
|
|
}
|
|
|
|
// update: - For all active instances update temperature and log TEMP
|
|
void AP_TemperatureSensor::update()
|
|
{
|
|
for (uint8_t i=0; i<_num_instances; i++) {
|
|
if (drivers[i] != nullptr && get_type(i) != AP_TemperatureSensor_Params::Type::NONE) {
|
|
drivers[i]->update();
|
|
|
|
#if HAL_LOGGING_ENABLED
|
|
const AP_Logger *logger = AP_Logger::get_singleton();
|
|
if (logger != nullptr && _log_flag) {
|
|
drivers[i]->Log_Write_TEMP();
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
AP_TemperatureSensor_Params::Type AP_TemperatureSensor::get_type(const uint8_t instance) const
|
|
{
|
|
if (instance >= AP_TEMPERATURE_SENSOR_MAX_INSTANCES) {
|
|
return AP_TemperatureSensor_Params::Type::NONE;
|
|
}
|
|
return (AP_TemperatureSensor_Params::Type)_params[instance].type.get();
|
|
}
|
|
|
|
// returns true if there is a temperature reading
|
|
bool AP_TemperatureSensor::get_temperature(float &temp, const uint8_t instance) const
|
|
{
|
|
if (!healthy(instance)) {
|
|
return false;
|
|
}
|
|
|
|
temp = _state[instance].temperature;
|
|
return true;
|
|
}
|
|
|
|
bool AP_TemperatureSensor::healthy(const uint8_t instance) const
|
|
{
|
|
return instance < _num_instances && drivers[instance] != nullptr && drivers[instance]->healthy();
|
|
}
|
|
|
|
AP_TemperatureSensor_Params::Source AP_TemperatureSensor::get_source(const uint8_t instance) const
|
|
{
|
|
return healthy(instance) ? (AP_TemperatureSensor_Params::Source)_params[instance].source.get() : AP_TemperatureSensor_Params::Source::None;
|
|
}
|
|
|
|
int32_t AP_TemperatureSensor::get_source_id(const uint8_t instance) const
|
|
{
|
|
return healthy(instance) ? _params[instance].source_id.get() : 0;
|
|
}
|
|
#else
|
|
const AP_Param::GroupInfo AP_TemperatureSensor::var_info[] = { AP_GROUPEND };
|
|
|
|
void AP_TemperatureSensor::init() { };
|
|
void AP_TemperatureSensor::update() { };
|
|
bool AP_TemperatureSensor::get_temperature(float &temp, const uint8_t instance) const { return false; };
|
|
bool AP_TemperatureSensor::healthy(const uint8_t instance) const { return false; };
|
|
AP_TemperatureSensor_Params::Type AP_TemperatureSensor::get_type(const uint8_t instance) const { return AP_TemperatureSensor_Params::Type::NONE; };
|
|
AP_TemperatureSensor_Params::Source AP_TemperatureSensor::get_source(const uint8_t instance) const { return AP_TemperatureSensor_Params::Source::None; };
|
|
int32_t AP_TemperatureSensor::get_source_id(const uint8_t instance) const { return false; };
|
|
|
|
AP_TemperatureSensor::AP_TemperatureSensor() {}
|
|
|
|
#endif // AP_TEMPERATURE_SENSOR_DUMMY_METHODS_ENABLED
|
|
|
|
AP_TemperatureSensor *AP_TemperatureSensor::_singleton;
|
|
|
|
namespace AP {
|
|
AP_TemperatureSensor &temperature_sensor() {
|
|
return *AP_TemperatureSensor::get_singleton();
|
|
}
|
|
};
|
|
|
|
#endif // AP_TEMPERATURE_SENSOR_ENABLED
|