2015-12-31 13:02:30 -08:00
|
|
|
/**
|
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"
|
|
|
|
#include "adc_inputs.h"
|
|
|
|
#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
|
|
|
|
|
|
|
/**
|
|
|
|
* We hold a reference to current decoder to reduce code branching
|
|
|
|
* to lookup decoder each time we need to decode
|
|
|
|
*/
|
|
|
|
static FastInterpolation *mapDecoder;
|
|
|
|
|
2016-06-18 09:01:50 -07:00
|
|
|
float decodePressure(float voltage, air_pressure_sensor_config_s * mapConfig DECLARE_ENGINE_PARAMETER_S) {
|
|
|
|
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:
|
|
|
|
return denso183.getValue(voltage);
|
|
|
|
case MT_MPX4250:
|
|
|
|
return mpx4250.getValue(voltage);
|
|
|
|
case MT_HONDA3BAR:
|
|
|
|
return honda3bar.getValue(voltage);
|
|
|
|
case MT_DODGE_NEON_2003:
|
|
|
|
return dodgeNeon2003.getValue(voltage);
|
|
|
|
case MT_SUBY_DENSO:
|
|
|
|
return subyDenso.getValue(voltage);
|
|
|
|
case MT_GM_3_BAR:
|
|
|
|
return gm3bar.getValue(voltage);
|
2016-06-12 08:03:43 -07:00
|
|
|
case MT_TOYOTA_89420_02010:
|
|
|
|
// todo: add calibration
|
2015-08-16 20:01:33 -07:00
|
|
|
case MT_MPX4100:
|
|
|
|
return mpx4100.getValue(voltage);
|
2015-07-10 06:01:56 -07:00
|
|
|
default:
|
2016-10-10 13:02:39 -07:00
|
|
|
firmwareError(CUSTOM_ERR_MAP_TYPE, "Unknown MAP type: %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
|
|
|
|
*/
|
|
|
|
float validateMap(float mapKPa DECLARE_ENGINE_PARAMETER_S) {
|
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
|
|
|
|
*/
|
|
|
|
float getMapByVoltage(float voltage DECLARE_ENGINE_PARAMETER_S) {
|
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;
|
2016-06-18 09:01:50 -07:00
|
|
|
return decodePressure(voltage, apConfig PASS_ENGINE_PARAMETER);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Manifold Absolute Pressure, in kPa
|
|
|
|
*/
|
|
|
|
float getRawMap(DECLARE_ENGINE_PARAMETER_F) {
|
|
|
|
if (engineConfiguration->hasFrequencyReportingMapSensor) {
|
|
|
|
return interpolate(boardConfiguration->mapFrequency0Kpa, 0, boardConfiguration->mapFrequency100Kpa, 100, mapFreq);
|
|
|
|
}
|
|
|
|
|
|
|
|
float voltage = getVoltageDivided("map", engineConfiguration->map.sensor.hwChannel);
|
|
|
|
return getMapByVoltage(voltage PASS_ENGINE_PARAMETER);
|
|
|
|
}
|
|
|
|
|
2016-01-11 14:01:33 -08:00
|
|
|
bool hasBaroSensor(DECLARE_ENGINE_PARAMETER_F) {
|
2016-12-17 08:01:40 -08:00
|
|
|
return engineConfiguration->baroSensor.hwChannel != EFI_ADC_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasMapSensor(DECLARE_ENGINE_PARAMETER_F) {
|
|
|
|
return engineConfiguration->map.sensor.hwChannel != EFI_ADC_NONE;
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
float getBaroPressure(DECLARE_ENGINE_PARAMETER_F) {
|
|
|
|
float voltage = getVoltageDivided("baro", engineConfiguration->baroSensor.hwChannel);
|
2016-06-18 09:01:50 -07:00
|
|
|
return decodePressure(voltage, &engineConfiguration->baroSensor PASS_ENGINE_PARAMETER);
|
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;
|
|
|
|
default:
|
2016-10-10 13:02:39 -07:00
|
|
|
firmwareError(CUSTOM_ERR_MAP_TYPE, "Unknown MAP type: %d", type);
|
2015-07-10 06:01:56 -07:00
|
|
|
return &customMap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void applyConfiguration(DECLARE_ENGINE_PARAMETER_F) {
|
|
|
|
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__)
|
|
|
|
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 {
|
|
|
|
scheduleMsg(logger, "map type=%d/%s MAP=%fkPa", engineConfiguration->map.sensor.type,
|
|
|
|
getAir_pressure_sensor_type_e(engineConfiguration->map.sensor.type),
|
|
|
|
getMap());
|
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-30 14:01:21 -07:00
|
|
|
if (hasBaroSensor(PASS_ENGINE_PARAMETER_F)) {
|
|
|
|
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 */
|
|
|
|
|
|
|
|
|
|
|
|
void initMapDecoder(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_S) {
|
|
|
|
logger = sharedLogger;
|
|
|
|
applyConfiguration(PASS_ENGINE_PARAMETER_F);
|
|
|
|
//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 */
|
|
|
|
|
|
|
|
void initMapDecoder(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_S) {
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* EFI_ANALOG_SENSORS */
|