diff --git a/firmware/controllers/can/can_dash.cpp b/firmware/controllers/can/can_dash.cpp index 9c56b09ac1..93b44f3a13 100644 --- a/firmware/controllers/can/can_dash.cpp +++ b/firmware/controllers/can/can_dash.cpp @@ -953,7 +953,7 @@ void canDashboardHaltech(CanCycle cycle) { msg[4] = 0x00; msg[5] = 0x00; /* Barometric pressure */ - tmp = (uint16_t)(getBaroPressure()*10); + tmp = (uint16_t)(Sensor::getOrZero(SensorType::BarometricPressure) * 10); msg[6] = (tmp >> 8); msg[7] = (tmp & 0x00ff); } diff --git a/firmware/controllers/gauges/lcd_controller.cpp b/firmware/controllers/gauges/lcd_controller.cpp index 92a64478b9..5e62f365d5 100644 --- a/firmware/controllers/gauges/lcd_controller.cpp +++ b/firmware/controllers/gauges/lcd_controller.cpp @@ -198,7 +198,7 @@ static void showLine(lcd_line_e line, int /*screenY*/) { #if EFI_ANALOG_SENSORS case LL_BARO: if (Sensor::hasSensor(SensorType::BarometricPressure)) { - lcdPrintf("Baro: %.2f", getBaroPressure()); + lcdPrintf("Baro: %.2f", Sensor::getOrZero(SensorType::BarometricPressure)); } else { lcdPrintf("Baro: none"); } diff --git a/firmware/controllers/sensors/map.cpp b/firmware/controllers/sensors/map.cpp index 247dff9abc..8fd79d4df1 100644 --- a/firmware/controllers/sensors/map.cpp +++ b/firmware/controllers/sensors/map.cpp @@ -7,164 +7,24 @@ */ #include "pch.h" -#if EFI_PROD_CODE -#include "digital_input_icu.h" -#include "digital_input_exti.h" -#endif - #if EFI_ANALOG_SENSORS -static FastInterpolation customMap; - -// See 'useFixedBaroCorrFromMap' -static float storedInitialBaroPressure = NAN; - -/** - * @brief MAP value decoded for a 1.83 Honda sensor - * -6.64kPa at zero volts - * 182.78kPa at 5 volts - * - * about 3 volts at 100kPa - * - * @returns kPa value - */ -static FastInterpolation denso183(0, -6.64, 5, 182.78); - -/** - * MAP sensor output voltage of 3.0v = a gauge reading of 0 in. Hg - * MAP sensor output voltage of 0.5v = a gauge reading of 27 in. Hg - */ -static FastInterpolation honda3bar(0.5, 91.422, 3.0, 0); - -static FastInterpolation subyDenso(0, 0, 5, 200); - -static FastInterpolation gm3bar(0.631, 40, 4.914, 304); - -static FastInterpolation gm2bar(0, 8.8, 5, 208); - -static FastInterpolation gm1bar(0, 10, 5, 105); - -static FastInterpolation mpx4250(0, 8, 5, 260); - -static FastInterpolation mpx4250A(0.25, 20, 4.875, 250); - -static FastInterpolation mpxh6400(1 /*volts*/, 90 /*kPa*/, 3 /*volts*/, 250 /*kPa*/); - -static FastInterpolation mpx4100(0.3, 20, 4.9, 105); - -/** - * http://easyautodiagnostics.com/chrysler/2.0L-2.4L/map-sensor-diagnostic-test-1 - * or maybe - * https://books.google.com/books?id=3q85p56_PxIC page 132 - * https://books.google.com/books?id=3q85p56_PxIC&q=chrysler+map#v=snippet&q=chrysler%20map&f=false - */ -//static FastInterpolation dodgeNeon2003(0.5 /* volts */, 0 /* kPa */, 4.5 /* volts */ , 100 /* kPa */); -static FastInterpolation dodgeNeon2003(0.4 /* volts */, 15.34 /* kPa */, 4.5 /* volts */ , 100 /* kPa */); - -static FastInterpolation densoToyota(3.7 - 2 /* volts */, 33.322271 /* kPa */, 3.7 /* volts */ , 100 /* kPa */); - -/** - * Open question how to get this Miata NB2 sensor read MAP - */ -static FastInterpolation mazda1bar(0 /* volts */, 2.5 /* kPa */, 5 /* volts */ , 117 /* kPa */); - -/** - * Bosch 2.5 Bar TMap Map Sensor with IAT - */ -static FastInterpolation bosch2_5(0.4 /* volts */, 20 /* kPa */, 4.65 /* volts */ , 250 /* kPa */); - -static FastInterpolation *getDecoder(air_pressure_sensor_type_e type); - -float decodePressure(float voltage, air_pressure_sensor_config_s * mapConfig) { - switch (mapConfig->type) { - case MT_CUSTOM: - // todo: migrate to 'FastInterpolation customMap' - return interpolateMsg("map", engineConfiguration->mapLowValueVoltage, mapConfig->lowValue, - engineConfiguration->mapHighValueVoltage, mapConfig->highValue, voltage); - case MT_DENSO183: - case MT_MPX4250: - case MT_MPX4250A: - case MT_HONDA3BAR: - case MT_DODGE_NEON_2003: - case MT_SUBY_DENSO: - case MT_GM_3_BAR: - case MT_GM_2_BAR: - case MT_GM_1_BAR: - case MT_TOYOTA_89420_02010: - case MT_MPX4100: - case MT_BOSCH_2_5: - case MT_MAZDA_1_BAR: - case MT_MPXH6400: - return getDecoder(mapConfig->type)->getValue(voltage); - default: - firmwareError(CUSTOM_ERR_MAP_TYPE, "Unknown MAP type: pressure %d", mapConfig->type); - return NAN; - } -} - /** * This function checks if Baro/MAP sensor value is inside of expected range * @return unchanged mapKPa parameter or NaN */ static float validateBaroMap(float mapKPa) { const float atmoPressure = 100.0f; - const float atmoPressureRange = 15.0f; // 85..115 - if (cisnan(mapKPa) || absF(mapKPa - atmoPressure) > atmoPressureRange) { + + // Highest interstate is the Eisenhower Tunnel at 11158 feet -> 66 kpa + // Lowest point is the Dead Sea, -1411 feet -> 106 kpa + if (cisnan(mapKPa) || mapKPa > 110 || mapKPa < 60) { warning(OBD_Barometric_Press_Circ, "Invalid start-up baro pressure = %.2fkPa", mapKPa); return NAN; } return mapKPa; } -float getBaroPressure() { - // Override the real Baro sensor with the stored initial MAP value, if the option is set. - if (engineConfiguration->useFixedBaroCorrFromMap) - return storedInitialBaroPressure; - float voltage = getVoltageDivided("baro", engineConfiguration->baroSensor.hwChannel); - return decodePressure(voltage, &engineConfiguration->baroSensor); -} - -static FastInterpolation *getDecoder(air_pressure_sensor_type_e type) { - switch (type) { - case MT_DENSO183: - return &denso183; - case MT_MPX4250: - return &mpx4250; - case MT_MPX4100: - return &mpx4100; - case MT_MPX4250A: - return &mpx4250A; - case MT_MPXH6400: - return &mpxh6400; - case MT_HONDA3BAR: - return &honda3bar; - case MT_DODGE_NEON_2003: - return &dodgeNeon2003; - case MT_SUBY_DENSO: - return &subyDenso; - case MT_GM_3_BAR: - return &gm3bar; - case MT_GM_2_BAR: - return &gm2bar; - case MT_GM_1_BAR: - return &gm1bar; - case MT_TOYOTA_89420_02010: - return &densoToyota; - case MT_MAZDA_1_BAR: - return &mazda1bar; - case MT_BOSCH_2_5: - return &bosch2_5; - default: - firmwareError(CUSTOM_ERR_MAP_TYPE, "Unknown MAP type: decoder %d", type); - return &customMap; - } -} - -static void applyConfiguration() { - air_pressure_sensor_config_s * apConfig = &engineConfiguration->map.sensor; - customMap.init(0, apConfig->lowValue, 5, apConfig->highValue); -} - #if EFI_PROD_CODE extern int mapMinBufferLength; @@ -207,23 +67,23 @@ static void printMAPInfo() { } #endif /* EFI_PROD_CODE */ - void initMapDecoder() { - applyConfiguration(); - if (engineConfiguration->useFixedBaroCorrFromMap) { // Read initial MAP sensor value and store it for Baro correction. - storedInitialBaroPressure = Sensor::get(SensorType::MapSlow).value_or(101.325); + float storedInitialBaroPressure = Sensor::get(SensorType::MapSlow).value_or(101.325); efiPrintf("Get initial baro MAP pressure = %.2fkPa", storedInitialBaroPressure); // validate if it's within a reasonable range (the engine should not be spinning etc.) storedInitialBaroPressure = validateBaroMap(storedInitialBaroPressure); if (!cisnan(storedInitialBaroPressure)) { efiPrintf("Using this fixed MAP pressure to override the baro correction!"); + + // TODO: do literally anything other than this + Sensor::setMockValue(SensorType::BarometricPressure, storedInitialBaroPressure); } else { efiPrintf("The baro pressure is invalid. The fixed baro correction will be disabled!"); } } - + #if EFI_PROD_CODE addConsoleAction("mapinfo", printMAPInfo); #endif diff --git a/firmware/controllers/sensors/map.h b/firmware/controllers/sensors/map.h index f7a989ebc1..6199c1da84 100644 --- a/firmware/controllers/sensors/map.h +++ b/firmware/controllers/sensors/map.h @@ -11,10 +11,6 @@ struct air_pressure_sensor_config_s; void initMapDecoder(); -float getBaroPressure(); - -float decodePressure(float voltage, air_pressure_sensor_config_s * mapConfig); - #define KPA_PER_PSI 6.89475728f #define PSI2KPA(psi) (KPA_PER_PSI * (psi)) diff --git a/firmware/init/sensor/init_map.cpp b/firmware/init/sensor/init_map.cpp index 473abfee10..3b08e6bb8c 100644 --- a/firmware/init/sensor/init_map.cpp +++ b/firmware/init/sensor/init_map.cpp @@ -7,18 +7,8 @@ #include "function_pointer_sensor.h" #include "identity_func.h" -struct GetBaroWrapper { - float getBaro() { - return ::getBaroPressure(); - } -}; - -static GetBaroWrapper baroWrapper; - -static FunctionPointerSensor baroSensor(SensorType::BarometricPressure, -[]() { - return baroWrapper.getBaro(); -}); +static LinearFunc baroConverter; +static FunctionalSensor baroSensor(SensorType::BarometricPressure, MS2NT(50)); // This converter is shared between both fast and slow: the only difference is // how the *voltage* is determined, not how its converted to a pressure. @@ -51,8 +41,7 @@ struct MapCfg { float map2; }; -static MapCfg getMapCfg() { - auto sensorType = engineConfiguration->map.sensor.type; +static MapCfg getMapCfg(air_pressure_sensor_type_e sensorType) { switch (sensorType) { case MT_DENSO183: return {0, -6.64, 5, 182.78}; @@ -97,10 +86,10 @@ static MapCfg getMapCfg() { }} } -void configureMapFunction() { - auto cfg = getMapCfg(); +void configureMapFunction(LinearFunc& converter, air_pressure_sensor_type_e sensorType) { + auto cfg = getMapCfg(engineConfiguration->map.sensor.type); - mapConverter.configure( + converter.configure( cfg.v1, cfg.map1, cfg.v2, @@ -111,12 +100,10 @@ void configureMapFunction() { } void initMap() { - auto mapChannel = engineConfiguration->map.sensor.hwChannel; - if (isAdcChannelValid(mapChannel)) { // Set up the conversion function - configureMapFunction(); + configureMapFunction(mapConverter, engineConfiguration->map.sensor.type); slowMapSensor.setFunction(mapConverter); fastMapSensor.setFunction(identityFunction); @@ -129,12 +116,18 @@ void initMap() { AdcSubscription::SubscribeSensor(slowMapSensor, mapChannel, 100); } - // Only register if configured - if (isAdcChannelValid(engineConfiguration->baroSensor.hwChannel)) { + auto baroChannel = engineConfiguration->baroSensor.hwChannel; + if (isAdcChannelValid(baroChannel)) { + configureMapFunction(baroConverter, engineConfiguration->baroSensor.type); + + baroSensor.setFunction(baroConverter); baroSensor.Register(); + + AdcSubscription::SubscribeSensor(baroSensor, baroChannel, 10); } } void deinitMap() { AdcSubscription::UnsubscribeSensor(slowMapSensor); + AdcSubscription::UnsubscribeSensor(baroSensor); } diff --git a/firmware/init/sensor/init_sensors.cpp b/firmware/init/sensor/init_sensors.cpp index 2d47d5dc22..915028624f 100644 --- a/firmware/init/sensor/init_sensors.cpp +++ b/firmware/init/sensor/init_sensors.cpp @@ -33,7 +33,6 @@ void deInitIfValid(const char* msg, adc_channel_e channel) { static void initOldAnalogInputs() { initIfValid("AFR", engineConfiguration->afr.hwChannel); - initIfValid("Baro", engineConfiguration->baroSensor.hwChannel); initIfValid("AUXF#1", engineConfiguration->auxFastSensor1_adcChannel); initIfValid("CJ125 UR", engineConfiguration->cj125ur); initIfValid("CJ125 UA", engineConfiguration->cj125ua); @@ -41,7 +40,6 @@ static void initOldAnalogInputs() { static void deInitOldAnalogInputs() { deInitIfValid("AFR", activeConfiguration.afr.hwChannel); - deInitIfValid("Baro", activeConfiguration.baroSensor.hwChannel); deInitIfValid("AUXF#1", activeConfiguration.auxFastSensor1_adcChannel); deInitIfValid("CJ125 UR", activeConfiguration.cj125ur); deInitIfValid("CJ125 UA", activeConfiguration.cj125ua); diff --git a/firmware/util/math/interpolation.cpp b/firmware/util/math/interpolation.cpp index ea6f3727b6..d38df3bbaa 100644 --- a/firmware/util/math/interpolation.cpp +++ b/firmware/util/math/interpolation.cpp @@ -60,27 +60,6 @@ static void testBinary() { #endif -FastInterpolation::FastInterpolation() { - init(0, 0, 1, 1); -} - -FastInterpolation::FastInterpolation(float x1, float y1, float x2, float y2) { - init(x1, y1, x2, y2); -} - -void FastInterpolation::init(float x1, float y1, float x2, float y2) { - if (x1 == x2) { - firmwareError(CUSTOM_ERR_INTERPOLATE, "init: Same x1 and x2 in interpolate: %.2f/%.2f", x1, x2); - return; - } - a = INTERPOLATION_A(x1, y1, x2, y2); - b = y1 - a * x1; -} - -float FastInterpolation::getValue(float x) const { - return a * x + b; -} - /** @brief Linear interpolation by two points * * @param x1 key of the first point @@ -176,5 +155,4 @@ void initInterpolation() { #if BINARY_PERF && ! EFI_UNIT_TEST addConsoleAction("binarytest", testBinary); #endif - } diff --git a/firmware/util/math/interpolation.h b/firmware/util/math/interpolation.h index cc0f5f191c..aaf38302aa 100644 --- a/firmware/util/math/interpolation.h +++ b/firmware/util/math/interpolation.h @@ -219,13 +219,3 @@ void setCurveValue(const kType bins[], VType values[], int size, float key, floa } void initInterpolation(); - -class FastInterpolation { -public: - FastInterpolation(); - FastInterpolation(float x1, float y1, float x2, float y2); - void init(float x1, float y1, float x2, float y2); - float getValue(float x) const; -private: - float a, b; -}; diff --git a/unit_tests/tests/test_sensors.cpp b/unit_tests/tests/test_sensors.cpp deleted file mode 100644 index ae4654fad7..0000000000 --- a/unit_tests/tests/test_sensors.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file test_sensors.cpp - * - * @date Dec 7, 2013 - * @author Andrey Belomutskiy, (c) 2012-2020 - */ - -#include "pch.h" - -TEST(sensors, mapDecoding) { - EngineTestHelper eth(FORD_INLINE_6_1995); - - air_pressure_sensor_config_s s; - s.type = MT_DENSO183; - - assertEqualsM("denso 0 volts", -6.64, decodePressure(0, &s)); - ASSERT_FLOAT_EQ(31.244, decodePressure(1, &s)); - - s.type = MT_MPX4250; - ASSERT_EQ( 8, decodePressure(0, &s)) << "MPX_4250 0 volts"; - ASSERT_FLOAT_EQ(58.4, decodePressure(1, &s)); -} diff --git a/unit_tests/tests/tests.mk b/unit_tests/tests/tests.mk index 11d91f8e8b..1b3ba4770e 100644 --- a/unit_tests/tests/tests.mk +++ b/unit_tests/tests/tests.mk @@ -63,7 +63,6 @@ TESTS_SRC_CPP = \ tests/test_log_buffer.cpp \ tests/test_signal_executor.cpp \ tests/test_cpp_memory_layout.cpp \ - tests/test_sensors.cpp \ tests/test_pid_auto.cpp \ tests/test_pid.cpp \ tests/test_accel_enrichment.cpp \