diff --git a/firmware/controllers/sensors/functional_sensor.cpp b/firmware/controllers/sensors/functional_sensor.cpp new file mode 100644 index 0000000000..bc45bb0a9b --- /dev/null +++ b/firmware/controllers/sensors/functional_sensor.cpp @@ -0,0 +1,26 @@ +#include "functional_sensor.h" + +void FunctionalSensor::postRawValue(float inputValue) { + // Report the raw value + float *rawReportLocation = m_rawReportingLocation; + if (rawReportLocation) { + *rawReportLocation = inputValue; + } + + // If no function is set, this sensor isn't valid. + if (!m_function) { + invalidate(); + return; + } + + auto r = m_function->convert(inputValue); + + // This has to happen so that we set the valid bit after + // the value is stored, to prevent the data race of reading + // an old invalid value + if (r.Valid) { + setValidValue(r.Value); + } else { + invalidate(); + } +} diff --git a/firmware/controllers/sensors/functional_sensor.h b/firmware/controllers/sensors/functional_sensor.h index 0a292f8860..c9ffe0f5f4 100644 --- a/firmware/controllers/sensors/functional_sensor.h +++ b/firmware/controllers/sensors/functional_sensor.h @@ -12,13 +12,6 @@ #include -struct FunctionalSensorBase : public StoredValueSensor { - FunctionalSensorBase(SensorType type) - : StoredValueSensor(type) {} - - virtual void postRawValue(float value) = 0; -}; - /** * @brief Class for sensors that convert from some raw floating point * value (ex: voltage, frequency, pulse width) to a sensor reading. @@ -30,46 +23,24 @@ struct FunctionalSensorBase : public StoredValueSensor { * Register an instance of the new class with an interface * that provides and posts raw values so the sensor can update. */ -template -class FunctionalSensor final : public FunctionalSensorBase { - static_assert(std::is_base_of_v, "TFunc must inherit from SensorConverter"); - static_assert(std::is_default_constructible_v, "TFunc must be default constructible"); - +class FunctionalSensor final : public StoredValueSensor { public: explicit FunctionalSensor(SensorType type) - : FunctionalSensorBase(type) {} + : StoredValueSensor(type) { } - void postRawValue(float inputValue) { - // Report the raw value - float *rawReportLocation = m_rawReportingLocation; - if (rawReportLocation) { - *rawReportLocation = inputValue; - } - - auto r = m_function.convert(inputValue); - - // This has to happen so that we set the valid bit after - // the value is stored, to prevent the data race of reading - // an old invalid value - if (r.Valid) { - setValidValue(r.Value); - } else { - invalidate(); - } - } + void postRawValue(float inputValue); void setRawReportingLocation(float *rawReportingLocation) { m_rawReportingLocation = rawReportingLocation; } - // Allow access to the underlying function - TFunc &f() { - return m_function; + void setFunction(SensorConverter& func) { + m_function = &func; } private: float *m_rawReportingLocation = nullptr; // Conversion function for this sensor - TFunc m_function; + SensorConverter* m_function = nullptr; }; diff --git a/firmware/controllers/sensors/sensors.mk b/firmware/controllers/sensors/sensors.mk index 926c95e094..4bb3173353 100644 --- a/firmware/controllers/sensors/sensors.mk +++ b/firmware/controllers/sensors/sensors.mk @@ -11,4 +11,5 @@ CONTROLLERS_SENSORS_SRC_CPP = $(PROJECT_DIR)/controllers/sensors/thermistors.cp $(PROJECT_DIR)/controllers/sensors/maf2map.cpp \ $(PROJECT_DIR)/controllers/sensors/hip9011_lookup.cpp \ $(PROJECT_DIR)/controllers/sensors/sensor.cpp \ + $(PROJECT_DIR)/controllers/sensors/functional_sensor.cpp \ $(PROJECT_DIR)/controllers/sensors/converters/linear_func.cpp diff --git a/firmware/hw_layer/adc_subscription.cpp b/firmware/hw_layer/adc_subscription.cpp index 076490d79b..5e8eb55d86 100644 --- a/firmware/hw_layer/adc_subscription.cpp +++ b/firmware/hw_layer/adc_subscription.cpp @@ -10,7 +10,7 @@ EXTERN_ENGINE; #if !EFI_UNIT_TEST struct AdcSubscriptionEntry { - FunctionalSensorBase *Sensor; + FunctionalSensor *Sensor; float VoltsPerAdcVolt; adc_channel_e Channel; }; @@ -18,7 +18,7 @@ struct AdcSubscriptionEntry { static size_t s_nextEntry = 0; static AdcSubscriptionEntry s_entries[8]; -void AdcSubscription::SubscribeSensor(FunctionalSensorBase &sensor, +void AdcSubscription::SubscribeSensor(FunctionalSensor &sensor, adc_channel_e channel, float voltsPerAdcVolt /*= 0.0f*/) { // Don't subscribe null channels diff --git a/firmware/hw_layer/adc_subscription.h b/firmware/hw_layer/adc_subscription.h index 1cb41d3258..676c97c2bf 100644 --- a/firmware/hw_layer/adc_subscription.h +++ b/firmware/hw_layer/adc_subscription.h @@ -9,6 +9,6 @@ class AdcSubscription { public: - static void SubscribeSensor(FunctionalSensorBase &sensor, adc_channel_e channel, float voltsPerAdcVolt = 0.0f); + static void SubscribeSensor(FunctionalSensor &sensor, adc_channel_e channel, float voltsPerAdcVolt = 0.0f); static void UpdateSubscribers(); }; diff --git a/firmware/init/sensor/init_oil_pressure.cpp b/firmware/init/sensor/init_oil_pressure.cpp index 8e06614f19..d5256cb699 100644 --- a/firmware/init/sensor/init_oil_pressure.cpp +++ b/firmware/init/sensor/init_oil_pressure.cpp @@ -10,7 +10,8 @@ EXTERN_ENGINE; extern TunerStudioOutputChannels tsOutputChannels; -FunctionalSensor oilpSensor(SensorType::OilPressure); +LinearFunc oilpSensorFunc; +FunctionalSensor oilpSensor(SensorType::OilPressure); void initOilPressure() { // Only register if we have a sensor @@ -29,7 +30,8 @@ void initOilPressure() { float greaterOutput = val1 > val2 ? val1 : val2; // Allow slightly negative output (-5kpa) so as to not fail the sensor when engine is off - oilpSensor.f().configure(sensorCfg->v1, val1, sensorCfg->v2, val2, /*minOutput*/ -5, greaterOutput); + oilpSensorFunc.configure(sensorCfg->v1, val1, sensorCfg->v2, val2, /*minOutput*/ -5, greaterOutput); + oilpSensor.setFunction(oilpSensorFunc); // Tell it to report to its output channel oilpSensor.setReportingLocation(&tsOutputChannels.oilPressure); diff --git a/unit_tests/tests/sensor/functional_sensor.cpp b/unit_tests/tests/sensor/func_sensor.cpp similarity index 89% rename from unit_tests/tests/sensor/functional_sensor.cpp rename to unit_tests/tests/sensor/func_sensor.cpp index e373ca949b..e57802038e 100644 --- a/unit_tests/tests/sensor/functional_sensor.cpp +++ b/unit_tests/tests/sensor/func_sensor.cpp @@ -17,6 +17,7 @@ protected: : dut(SensorType::Clt) {} void SetUp() override { + dut.setFunction(func); Sensor::resetRegistry(); } @@ -24,7 +25,8 @@ protected: Sensor::resetRegistry(); } - FunctionalSensor dut; + FunctionalSensor dut; + DoublerFunc func; }; TEST_F(SensorConverted, TestValid) { @@ -64,8 +66,3 @@ TEST_F(SensorConverted, TestInvalid) { EXPECT_FLOAT_EQ(s.Value, 0); } } - -TEST_F(SensorConverted, TestGet) { - // we're only checking that this compiles - DoublerFunc &f = dut.f(); -} diff --git a/unit_tests/tests/tests.mk b/unit_tests/tests/tests.mk index 141ba3e198..9ec6665e81 100644 --- a/unit_tests/tests/tests.mk +++ b/unit_tests/tests/tests.mk @@ -29,7 +29,7 @@ TESTS_SRC_CPP = \ tests/test_gpiochip.cpp \ \ tests/sensor/basic_sensor.cpp \ - tests/sensor/functional_sensor.cpp \ + tests/sensor/func_sensor.cpp \ tests/sensor/function_pointer_sensor.cpp \ tests/sensor/mock_sensor.cpp \ tests/sensor/sensor_reader.cpp \