fome-fw/firmware/controllers/sensors/map.cpp

257 lines
8.1 KiB
C++
Raw Normal View History

2015-12-31 13:02:30 -08:00
/**
2017-06-21 23:23:42 -07:00
*
* See also map_averaging.cpp
*
2017-01-03 03:05:22 -08:00
* @author Andrey Belomutskiy, (c) 2012-2017
2015-12-31 13:02:30 -08:00
*/
2015-07-10 06:01:56 -07:00
#include "main.h"
#include "engine_configuration.h"
#include "engine_math.h"
2017-11-24 16:16:00 -08:00
#include "analog_input.h"
2015-07-10 06:01:56 -07:00
#include "interpolation.h"
#include "error_handling.h"
#include "map.h"
2017-02-09 12:07:03 -08:00
#include "engine_controller.h"
2015-07-10 06:01:56 -07:00
#if EFI_PROD_CODE || defined(__DOXYGEN__)
#include "digital_input_hw.h"
#include "pin_repository.h"
#endif
#if EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
EXTERN_ENGINE;
static Logging *logger;
static FastInterpolation customMap;
static efitick_t prevWidthTimeNt = 0;
static float mapFreq = 0;
/**
* @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 mpx4250(0, 8, 5, 260);
2015-08-16 20:01:33 -07:00
static FastInterpolation mpx4100(0.3, 20, 4.9, 105);
2016-01-07 06:01:34 -08:00
/**
* 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
*/
2016-01-07 18:02:35 -08:00
//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 */);
2015-07-10 06:01:56 -07:00
2017-09-21 18:15:13 -07:00
static FastInterpolation densoToyota(3.7 - 2 /* volts */, 33.322271 /* kPa */, 3.7 /* volts */ , 100 /* kPa */);
2015-07-10 06:01:56 -07:00
/**
* We hold a reference to current decoder to reduce code branching
* to lookup decoder each time we need to decode
*/
static FastInterpolation *mapDecoder;
2017-09-21 20:31:46 -07:00
static FastInterpolation *getDecoder(air_pressure_sensor_type_e type);
2017-05-15 20:28:49 -07:00
float decodePressure(float voltage, air_pressure_sensor_config_s * mapConfig DECLARE_ENGINE_PARAMETER_SUFFIX) {
2016-06-18 09:01:50 -07:00
switch (mapConfig->type) {
2015-07-10 06:01:56 -07:00
case MT_CUSTOM:
// todo: migrate to 'FastInterpolation customMap'
2016-06-25 16:03:02 -07:00
return interpolate(engineConfiguration->mapLowValueVoltage, mapConfig->lowValue,
2016-06-26 11:01:41 -07:00
engineConfiguration->mapHighValueVoltage, mapConfig->highValue, voltage);
2015-07-10 06:01:56 -07:00
case MT_DENSO183:
case MT_MPX4250:
case MT_HONDA3BAR:
case MT_DODGE_NEON_2003:
case MT_SUBY_DENSO:
case MT_GM_3_BAR:
2016-06-12 08:03:43 -07:00
case MT_TOYOTA_89420_02010:
2015-08-16 20:01:33 -07:00
case MT_MPX4100:
2017-09-21 20:31:46 -07:00
return getDecoder(mapConfig->type)->getValue(voltage);
2015-07-10 06:01:56 -07:00
default:
2017-09-21 20:31:46 -07:00
firmwareError(CUSTOM_ERR_MAP_TYPE, "Unknown MAP type: p %d", mapConfig->type);
2015-07-10 06:01:56 -07:00
return NAN;
}
}
2015-09-06 18:02:46 -07:00
/**
* This function adds an error if MAP sensor value is outside of expected range
* @return unchanged mapKPa parameter
*/
2017-05-15 20:28:49 -07:00
float validateMap(float mapKPa DECLARE_ENGINE_PARAMETER_SUFFIX) {
2016-01-08 08:01:40 -08:00
if (cisnan(mapKPa) || mapKPa < CONFIG(mapErrorDetectionTooLow) || mapKPa > CONFIG(mapErrorDetectionTooHigh)) {
2017-01-15 12:06:23 -08:00
warning(OBD_Manifold_Absolute_Pressure_Circuit_Malfunction, "unexpected MAP value: %f", mapKPa);
2015-09-06 18:02:46 -07:00
return 0;
}
return mapKPa;
}
2015-07-10 06:01:56 -07:00
/**
* @brief MAP value decoded according to current settings
* @returns kPa value
*/
2017-05-15 20:28:49 -07:00
float getMapByVoltage(float voltage DECLARE_ENGINE_PARAMETER_SUFFIX) {
2016-01-26 17:02:45 -08:00
#if EFI_ENABLE_MOCK_ADC || defined(__DOXYGEN__)
int mapChannel = engineConfiguration->map.sensor.hwChannel;
if (engine->engineState.mockAdcState.hasMockAdc[mapChannel])
voltage = adcToVolts(engine->engineState.mockAdcState.getMockAdcValue(mapChannel) * engineConfiguration->analogInputDividerCoefficient);
#endif
2015-07-10 06:01:56 -07:00
// todo: migrate to mapDecoder once parameter listeners are ready
air_pressure_sensor_config_s * apConfig = &engineConfiguration->map.sensor;
2017-05-15 20:28:49 -07:00
return decodePressure(voltage, apConfig PASS_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
}
/**
* @return Manifold Absolute Pressure, in kPa
*/
2017-05-15 20:28:49 -07:00
float getRawMap(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2015-07-10 06:01:56 -07:00
if (engineConfiguration->hasFrequencyReportingMapSensor) {
return interpolate(boardConfiguration->mapFrequency0Kpa, 0, boardConfiguration->mapFrequency100Kpa, 100, mapFreq);
}
float voltage = getVoltageDivided("map", engineConfiguration->map.sensor.hwChannel);
2017-05-15 20:28:49 -07:00
return getMapByVoltage(voltage PASS_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
}
2017-05-15 20:28:49 -07:00
bool hasBaroSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2016-12-17 08:01:40 -08:00
return engineConfiguration->baroSensor.hwChannel != EFI_ADC_NONE;
}
2017-05-15 20:28:49 -07:00
bool hasMapSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2016-12-17 08:01:40 -08:00
return engineConfiguration->map.sensor.hwChannel != EFI_ADC_NONE;
2015-07-10 06:01:56 -07:00
}
2017-05-15 20:28:49 -07:00
float getBaroPressure(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2015-07-10 06:01:56 -07:00
float voltage = getVoltageDivided("baro", engineConfiguration->baroSensor.hwChannel);
2017-05-15 20:28:49 -07:00
return decodePressure(voltage, &engineConfiguration->baroSensor PASS_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
}
static FastInterpolation *getDecoder(air_pressure_sensor_type_e type) {
switch (type) {
case MT_CUSTOM:
return &customMap;
case MT_DENSO183:
return &denso183;
case MT_MPX4250:
return &mpx4250;
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;
2017-09-21 20:31:46 -07:00
case MT_TOYOTA_89420_02010:
return &densoToyota;
2015-07-10 06:01:56 -07:00
default:
2017-09-21 20:31:46 -07:00
firmwareError(CUSTOM_ERR_MAP_TYPE, "Unknown MAP type: d %d", type);
2015-07-10 06:01:56 -07:00
return &customMap;
}
}
2017-05-15 20:28:49 -07:00
static void applyConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2015-07-10 06:01:56 -07:00
air_pressure_sensor_config_s * apConfig = &engineConfiguration->map.sensor;
2016-06-25 16:03:02 -07:00
customMap.init(0, apConfig->lowValue, 5, apConfig->highValue);
2015-07-10 06:01:56 -07:00
mapDecoder = getDecoder(engineConfiguration->map.sensor.type);
}
static void digitalMapWidthCallback(void) {
efitick_t nowNt = getTimeNowNt();
mapFreq = 1000000.0 / NT2US(nowNt - prevWidthTimeNt);
prevWidthTimeNt = nowNt;
}
#if EFI_PROD_CODE || defined(__DOXYGEN__)
2017-08-06 13:29:14 -07:00
extern int mapMinBufferLength;
2015-07-10 06:01:56 -07:00
static void printMAPInfo(void) {
#if EFI_ANALOG_SENSORS || defined(__DOXYGEN__)
scheduleMsg(logger, "instant value=%fkPa", getRawMap());
2017-02-09 12:07:03 -08:00
2015-07-10 06:01:56 -07:00
if (engineConfiguration->hasFrequencyReportingMapSensor) {
scheduleMsg(logger, "instant value=%fHz @ %s", mapFreq, hwPortname(boardConfiguration->frequencyReportingMapInputPin));
} else {
2017-08-06 13:29:14 -07:00
scheduleMsg(logger, "map type=%d/%s MAP=%fkPa mapMinBufferLength=%d", engineConfiguration->map.sensor.type,
2015-07-10 06:01:56 -07:00
getAir_pressure_sensor_type_e(engineConfiguration->map.sensor.type),
2017-08-06 13:29:14 -07:00
getMap(),
mapMinBufferLength);
2015-07-10 06:01:56 -07:00
2017-02-09 12:07:03 -08:00
adc_channel_e mapAdc = engineConfiguration->map.sensor.hwChannel;
static char pinNameBuffer[16];
scheduleMsg(logger, "MAP %fv @%s", getVoltage("mapinfo", mapAdc),
getPinNameByAdcChannel("map", mapAdc, pinNameBuffer));
2015-07-10 06:01:56 -07:00
if (engineConfiguration->map.sensor.type == MT_CUSTOM) {
2016-06-26 11:01:41 -07:00
scheduleMsg(logger, "at %fv=%f at %fv=%f",
2016-06-25 16:03:02 -07:00
engineConfiguration->mapLowValueVoltage,
engineConfiguration->map.sensor.lowValue,
engineConfiguration->mapHighValueVoltage,
engineConfiguration->map.sensor.highValue);
2015-07-10 06:01:56 -07:00
}
}
2017-05-15 20:28:49 -07:00
if (hasBaroSensor(PASS_ENGINE_PARAMETER_SIGNATURE)) {
2015-08-30 14:01:21 -07:00
scheduleMsg(logger, "baro type=%d value=%f", engineConfiguration->baroSensor.type, getBaroPressure());
if (engineConfiguration->baroSensor.type == MT_CUSTOM) {
2016-06-25 16:03:02 -07:00
scheduleMsg(logger, "min=%f@%f max=%f@%f",
engineConfiguration->baroSensor.lowValue,
engineConfiguration->mapLowValueVoltage,
engineConfiguration->baroSensor.highValue,
engineConfiguration->mapHighValueVoltage);
2015-08-30 14:01:21 -07:00
}
2015-07-10 06:01:56 -07:00
}
#endif /* EFI_ANALOG_SENSORS */
}
#endif /* EFI_PROD_CODE */
2017-05-15 20:28:49 -07:00
void initMapDecoder(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
2015-07-10 06:01:56 -07:00
logger = sharedLogger;
2017-05-15 20:28:49 -07:00
applyConfiguration(PASS_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
//engine->configurationListeners.registerCallback(applyConfiguration);
#if EFI_PROD_CODE || defined(__DOXYGEN__)
if (engineConfiguration->hasFrequencyReportingMapSensor) {
digital_input_s* digitalMapInput = initWaveAnalyzerDriver("map freq", boardConfiguration->frequencyReportingMapInputPin);
startInputDriver(digitalMapInput, true);
digitalMapInput->widthListeners.registerCallback((VoidInt) digitalMapWidthCallback, NULL);
}
addConsoleAction("mapinfo", printMAPInfo);
#endif
}
#else /* EFI_ANALOG_SENSORS */
2017-05-15 20:28:49 -07:00
void initMapDecoder(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
2015-07-10 06:01:56 -07:00
}
#endif /* EFI_ANALOG_SENSORS */