2020-08-31 19:47:33 -07:00
|
|
|
#include "global.h"
|
2019-09-21 11:33:38 -07:00
|
|
|
#include "sensor.h"
|
2020-03-30 15:29:42 -07:00
|
|
|
#include "efilib.h"
|
|
|
|
#include "loggingcentral.h"
|
2019-09-21 11:33:38 -07:00
|
|
|
|
2020-03-30 15:29:42 -07:00
|
|
|
static const char* s_sensorNames[] = {
|
|
|
|
"Invalid",
|
|
|
|
"CLT",
|
|
|
|
"IAT",
|
2020-08-30 11:27:41 -07:00
|
|
|
"RPM",
|
|
|
|
"MAP",
|
|
|
|
"MAF",
|
2020-03-30 15:29:42 -07:00
|
|
|
|
|
|
|
"Oil Pressure",
|
|
|
|
|
2020-10-23 04:31:47 -07:00
|
|
|
"Fuel Pressure (LP)",
|
|
|
|
"Fuel Pressure (HP)",
|
2020-10-23 12:46:16 -07:00
|
|
|
"Fuel Pressure (injector)",
|
2020-10-23 04:31:47 -07:00
|
|
|
|
2020-03-30 15:29:42 -07:00
|
|
|
"TPS 1",
|
|
|
|
"TPS 1 Primary",
|
|
|
|
"TPS 1 Secondary",
|
|
|
|
|
|
|
|
"TPS 2",
|
|
|
|
"TPS 2 Primary",
|
|
|
|
"TPS 2 Secondary",
|
|
|
|
|
|
|
|
"Acc Pedal",
|
|
|
|
"Acc Pedal Primary",
|
|
|
|
"Acc Pedal Secondary",
|
|
|
|
|
2020-04-07 13:07:09 -07:00
|
|
|
"Driver Acc Intent",
|
|
|
|
|
|
|
|
"Aux Temp 1",
|
|
|
|
"Aux Temp 2",
|
2020-09-01 13:22:31 -07:00
|
|
|
|
2020-12-09 17:26:23 -08:00
|
|
|
"Lambda 1",
|
|
|
|
"Lambda 2",
|
2020-09-18 00:04:07 -07:00
|
|
|
|
|
|
|
"Wastegate Position",
|
|
|
|
"Idle Valve Position",
|
2021-01-05 04:57:26 -08:00
|
|
|
|
|
|
|
"Flex Fuel",
|
2021-02-03 05:55:40 -08:00
|
|
|
|
|
|
|
"Battery Voltage",
|
2021-02-07 15:54:41 -08:00
|
|
|
|
|
|
|
"Barometric Pressure",
|
2021-03-19 05:39:08 -07:00
|
|
|
|
|
|
|
"Fuel Level %",
|
2021-05-09 16:47:37 -07:00
|
|
|
|
|
|
|
"Aux 1",
|
|
|
|
"Aux 2",
|
|
|
|
"Aux 3",
|
|
|
|
"Aux 4",
|
2020-03-30 15:29:42 -07:00
|
|
|
};
|
|
|
|
|
2020-12-05 07:16:52 -08:00
|
|
|
// This struct represents one sensor in the registry.
|
|
|
|
// It stores whether the sensor should use a mock value,
|
|
|
|
// the value to use, and if not a pointer to the sensor that
|
|
|
|
// can provide a real value.
|
|
|
|
class SensorRegistryEntry {
|
|
|
|
public:
|
|
|
|
const Sensor* getSensor() {
|
|
|
|
return m_sensor;
|
|
|
|
}
|
|
|
|
|
2020-12-08 03:24:20 -08:00
|
|
|
void setMockValue(float value, bool mockRedundant) {
|
2020-12-05 07:16:52 -08:00
|
|
|
m_mockValue = value;
|
|
|
|
m_useMock = true;
|
2020-12-08 03:24:20 -08:00
|
|
|
m_mockRedundant = mockRedundant;
|
2020-12-05 07:16:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void resetMock() {
|
|
|
|
m_useMock = false;
|
|
|
|
m_mockValue = 0.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void reset() {
|
|
|
|
m_sensor = nullptr;
|
|
|
|
resetMock();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Register(Sensor* sensor) {
|
|
|
|
// If there's somebody already here - a consumer tried to double-register a sensor
|
|
|
|
if (m_sensor) {
|
|
|
|
// This sensor has already been registered. Don't re-register it.
|
2020-12-06 12:00:30 -08:00
|
|
|
firmwareError(CUSTOM_OBD_26, "Duplicate registration for sensor \"%s\"", sensor->getSensorName());
|
2020-12-05 07:16:52 -08:00
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
// Put the sensor in the registry
|
|
|
|
m_sensor = sensor;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SensorResult get() const {
|
|
|
|
// Check if mock
|
|
|
|
if (m_useMock) {
|
|
|
|
return m_mockValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the sensor out of the entry
|
|
|
|
const Sensor *s = m_sensor;
|
|
|
|
if (s) {
|
2021-03-12 20:32:41 -08:00
|
|
|
// If this sensor says it doesn't exist, return unexpected
|
|
|
|
if (!s->hasSensor()) {
|
|
|
|
return unexpected;
|
|
|
|
}
|
|
|
|
|
2020-12-05 07:16:52 -08:00
|
|
|
// If we found the sensor, ask it for a result.
|
|
|
|
return s->get();
|
|
|
|
}
|
|
|
|
|
|
|
|
// We've exhausted all valid ways to return something - sensor not found.
|
|
|
|
return unexpected;
|
|
|
|
}
|
|
|
|
|
2021-04-18 17:02:32 -07:00
|
|
|
void showInfo(const char* sensorName) const {
|
2020-12-05 07:16:52 -08:00
|
|
|
if (m_useMock) {
|
2021-04-18 17:02:32 -07:00
|
|
|
efiPrintf("Sensor \"%s\" mocked with value %.2f", sensorName, m_mockValue);
|
2020-12-05 07:16:52 -08:00
|
|
|
} else {
|
|
|
|
const auto sensor = m_sensor;
|
|
|
|
|
|
|
|
if (sensor) {
|
2021-04-18 17:02:32 -07:00
|
|
|
sensor->showInfo(sensorName);
|
2020-12-05 07:16:52 -08:00
|
|
|
} else {
|
2021-04-18 17:02:32 -07:00
|
|
|
efiPrintf("Sensor \"%s\" is not configured.", sensorName);
|
2020-12-05 07:16:52 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasSensor() const {
|
2021-03-12 20:32:41 -08:00
|
|
|
return m_useMock || (m_sensor && m_sensor->hasSensor());
|
2020-12-05 07:16:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
float getRaw() const {
|
|
|
|
const auto sensor = m_sensor;
|
|
|
|
|
2020-12-06 11:55:06 -08:00
|
|
|
if (sensor) {
|
|
|
|
return sensor->getRaw();
|
2020-12-05 07:16:52 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// We've exhausted all valid ways to return something - sensor not found.
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-12-06 11:55:06 -08:00
|
|
|
bool isRedundant() const {
|
|
|
|
const auto sensor = m_sensor;
|
|
|
|
|
|
|
|
if (sensor) {
|
|
|
|
return sensor->isRedundant();
|
|
|
|
}
|
|
|
|
|
2020-12-08 03:24:20 -08:00
|
|
|
if (m_useMock) {
|
|
|
|
return m_mockRedundant;
|
|
|
|
}
|
|
|
|
|
2020-12-06 11:55:06 -08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-12-05 07:16:52 -08:00
|
|
|
private:
|
|
|
|
bool m_useMock = false;
|
2020-12-08 03:24:20 -08:00
|
|
|
bool m_mockRedundant = false;
|
2020-12-05 07:16:52 -08:00
|
|
|
float m_mockValue;
|
|
|
|
Sensor* m_sensor = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
static SensorRegistryEntry s_sensorRegistry[static_cast<size_t>(SensorType::PlaceholderLast)] = {};
|
|
|
|
|
2020-04-07 13:07:09 -07:00
|
|
|
static_assert(efi::size(s_sensorNames) == efi::size(s_sensorRegistry));
|
2020-03-30 15:29:42 -07:00
|
|
|
|
2019-09-21 11:33:38 -07:00
|
|
|
bool Sensor::Register() {
|
2020-12-05 07:16:52 -08:00
|
|
|
return s_sensorRegistry[getIndex()].Register(this);
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void Sensor::resetRegistry() {
|
|
|
|
// Clear all entries
|
2020-03-30 15:29:42 -07:00
|
|
|
for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) {
|
2019-09-21 11:33:38 -07:00
|
|
|
auto &entry = s_sensorRegistry[i];
|
|
|
|
|
2020-08-29 13:22:57 -07:00
|
|
|
entry.reset();
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ SensorRegistryEntry *Sensor::getEntryForType(SensorType type) {
|
|
|
|
size_t index = getIndex(type);
|
|
|
|
// Check that we didn't get garbage
|
|
|
|
if (index >= getIndex(SensorType::PlaceholderLast)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return &s_sensorRegistry[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ const Sensor *Sensor::getSensorOfType(SensorType type) {
|
|
|
|
auto entry = getEntryForType(type);
|
2020-08-29 13:22:57 -07:00
|
|
|
return entry ? entry->getSensor() : nullptr;
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ SensorResult Sensor::get(SensorType type) {
|
|
|
|
const auto entry = getEntryForType(type);
|
|
|
|
|
|
|
|
// Check if this is a valid sensor entry
|
|
|
|
if (!entry) {
|
2020-04-19 05:37:43 -07:00
|
|
|
return unexpected;
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
2020-12-05 07:16:52 -08:00
|
|
|
return entry->get();
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
|
2020-01-12 00:25:23 -08:00
|
|
|
/*static*/ float Sensor::getRaw(SensorType type) {
|
|
|
|
const auto entry = getEntryForType(type);
|
|
|
|
|
2020-12-05 07:16:52 -08:00
|
|
|
return entry ? entry->getRaw() : 0;
|
2020-01-12 00:25:23 -08:00
|
|
|
}
|
|
|
|
|
2020-12-06 11:55:06 -08:00
|
|
|
/*static*/ bool Sensor::isRedundant(SensorType type) {
|
|
|
|
const auto entry = getEntryForType(type);
|
|
|
|
|
|
|
|
return entry ? entry->isRedundant() : false;
|
|
|
|
}
|
|
|
|
|
2020-04-02 05:04:12 -07:00
|
|
|
/*static*/ bool Sensor::hasSensor(SensorType type) {
|
|
|
|
const auto entry = getEntryForType(type);
|
|
|
|
|
2020-12-05 07:16:52 -08:00
|
|
|
return entry ? entry->hasSensor() : false;
|
2020-04-02 05:04:12 -07:00
|
|
|
}
|
|
|
|
|
2020-12-08 03:24:20 -08:00
|
|
|
/*static*/ void Sensor::setMockValue(SensorType type, float value, bool mockRedundant) {
|
2019-09-21 11:33:38 -07:00
|
|
|
auto entry = getEntryForType(type);
|
|
|
|
|
|
|
|
if (entry) {
|
2020-12-08 03:24:20 -08:00
|
|
|
entry->setMockValue(value, mockRedundant);
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void Sensor::setMockValue(int type, float value) {
|
|
|
|
// bounds check
|
|
|
|
if (type <= 0 || type >= static_cast<int>(SensorType::PlaceholderLast)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
setMockValue(static_cast<SensorType>(type), value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void Sensor::resetMockValue(SensorType type) {
|
|
|
|
auto entry = getEntryForType(type);
|
|
|
|
|
|
|
|
if (entry) {
|
2020-08-29 13:22:57 -07:00
|
|
|
entry->resetMock();
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ void Sensor::resetAllMocks() {
|
|
|
|
// Reset all mocks
|
2020-03-30 15:29:42 -07:00
|
|
|
for (size_t i = 0; i < efi::size(s_sensorRegistry); i++) {
|
2020-12-05 07:16:52 -08:00
|
|
|
s_sensorRegistry[i].resetMock();
|
2019-09-21 11:33:38 -07:00
|
|
|
}
|
|
|
|
}
|
2020-03-30 15:29:42 -07:00
|
|
|
|
|
|
|
/*static*/ const char* Sensor::getSensorName(SensorType type) {
|
|
|
|
return s_sensorNames[static_cast<size_t>(type)];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Print information about all sensors
|
2021-04-18 17:02:32 -07:00
|
|
|
/*static*/ void Sensor::showAllSensorInfo() {
|
2020-03-30 15:29:42 -07:00
|
|
|
for (size_t i = 1; i < efi::size(s_sensorRegistry); i++) {
|
|
|
|
auto& entry = s_sensorRegistry[i];
|
|
|
|
const char* name = s_sensorNames[i];
|
|
|
|
|
2021-04-18 17:02:32 -07:00
|
|
|
entry.showInfo(name);
|
2020-12-05 07:16:52 -08:00
|
|
|
}
|
|
|
|
}
|
2020-03-30 15:29:42 -07:00
|
|
|
|
2020-12-05 07:16:52 -08:00
|
|
|
// Print information about a particular sensor
|
2021-04-18 17:02:32 -07:00
|
|
|
/*static*/ void Sensor::showInfo(SensorType type) {
|
2020-12-05 07:16:52 -08:00
|
|
|
auto entry = getEntryForType(type);
|
|
|
|
|
|
|
|
if (entry) {
|
2021-04-18 17:02:32 -07:00
|
|
|
entry->showInfo(getSensorName(type));
|
2020-03-30 15:29:42 -07:00
|
|
|
}
|
|
|
|
}
|