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

216 lines
6.1 KiB
C++
Raw Normal View History

2015-12-31 13:02:30 -08:00
/**
2018-01-20 17:55:31 -08:00
* @author Andrey Belomutskiy, (c) 2012-2018
2015-12-31 13:02:30 -08:00
*/
2017-11-24 16:16:00 -08:00
#include "engine.h"
2015-07-10 06:01:56 -07:00
#include "tps.h"
#include "interpolation.h"
2017-11-24 16:16:00 -08:00
#include "analog_input.h"
2019-04-29 22:21:09 -07:00
#if EFI_PROD_CODE
#include "settings.h"
#endif /* EFI_PROD_CODE */
2015-07-10 06:01:56 -07:00
2019-04-29 22:21:09 -07:00
EXTERN_ENGINE;
2017-11-16 11:44:53 -08:00
2019-04-24 14:00:05 -07:00
/**
* set mock_pedal_position X
* See also directPwmValue
*/
2019-03-02 12:04:42 -08:00
percent_t mockPedalPosition = MOCK_UNDEFINED;
2015-07-10 06:01:56 -07:00
2019-05-27 11:21:12 -07:00
#if !EFI_PROD_CODE
2017-11-16 07:29:40 -08:00
/**
* this allows unit tests to simulate TPS position
*/
void setMockTpsAdc(percent_t tpsPosition DECLARE_ENGINE_PARAMETER_SUFFIX) {
engine->mockTpsAdcValue = TPS_TS_CONVERSION * tpsPosition;
2017-11-16 07:29:40 -08:00
}
void setMockTpsValue(percent_t tpsPosition DECLARE_ENGINE_PARAMETER_SUFFIX) {
engine->mockTpsValue = tpsPosition;
2019-05-27 11:21:12 -07:00
}
#endif /* EFI_PROD_CODE */
void setMockPedalPosition(percent_t value DECLARE_ENGINE_PARAMETER_SUFFIX) {
2017-11-16 11:44:53 -08:00
mockPedalPosition = value;
}
2015-07-10 06:01:56 -07:00
/**
* We are using one instance for read and another for modification, this is how we get lock-free thread-safety
*
*/
static tps_roc_s states[2];
2016-01-31 18:02:03 -08:00
// todo if TPS_FAST_ADC
//int tpsFastAdc = 0;
2015-07-10 06:01:56 -07:00
static volatile int tpsRocIndex = 0;
/**
* this method is lock-free thread-safe if invoked only from one thread
*/
2016-02-04 11:01:38 -08:00
void saveTpsState(efitimeus_t now, float curValue) {
2015-07-10 06:01:56 -07:00
int tpsNextIndex = (tpsRocIndex + 1) % 2;
tps_roc_s *cur = &states[tpsRocIndex];
tps_roc_s *next = &states[tpsNextIndex];
next->prevTime = cur->curTime;
next->prevValue = cur->curValue;
next->curTime = now;
next->curValue = curValue;
//int diffSysticks = overflowDiff(now, cur->curTime);
2016-02-04 11:01:38 -08:00
float diffSeconds = 0;// TODO: do we need this? diffSysticks * 1.0 / CH_FREQUENCY;
2015-07-10 06:01:56 -07:00
next->rateOfChange = (curValue - cur->curValue) / diffSeconds;
// here we update volatile index
tpsRocIndex = tpsNextIndex;
}
/**
* this read-only method is lock-free thread-safe
*/
float getTpsRateOfChange(void) {
return states[tpsRocIndex].rateOfChange;
}
/*
* Return current TPS position based on configured ADC levels, and adc
*
* */
2017-05-15 20:28:49 -07:00
percent_t getTpsValue(int adc DECLARE_ENGINE_PARAMETER_SUFFIX) {
2015-07-10 06:01:56 -07:00
if (engineConfiguration->tpsMin == engineConfiguration->tpsMax) {
2017-01-22 06:03:08 -08:00
warning(CUSTOM_INVALID_TPS_SETTING, "Invalid TPS configuration: same value %d", engineConfiguration->tpsMin);
2015-07-10 06:01:56 -07:00
return NAN;
}
2018-06-12 02:45:11 -07:00
float result = interpolateMsg("TPS", TPS_TS_CONVERSION * engineConfiguration->tpsMax, 100, TPS_TS_CONVERSION * engineConfiguration->tpsMin, 0, adc);
2016-12-17 09:03:02 -08:00
if (result < engineConfiguration->tpsErrorDetectionTooLow) {
2019-04-12 19:07:03 -07:00
#if EFI_PROD_CODE
2017-03-03 20:24:32 -08:00
// too much noise with simulator
2018-01-23 09:05:14 -08:00
warning(OBD_Throttle_Position_Sensor_Circuit_Malfunction, "TPS too low: %.2f", result);
2017-03-03 20:24:32 -08:00
#endif /* EFI_PROD_CODE */
2016-12-17 09:03:02 -08:00
}
if (result > engineConfiguration->tpsErrorDetectionTooHigh) {
2019-04-12 19:07:03 -07:00
#if EFI_PROD_CODE
2017-03-03 20:24:32 -08:00
// too much noise with simulator
2018-01-23 09:05:14 -08:00
warning(OBD_Throttle_Position_Sensor_Range_Performance_Problem, "TPS too high: %.2f", result);
2017-03-03 20:24:32 -08:00
#endif /* EFI_PROD_CODE */
2016-12-17 09:03:02 -08:00
}
2015-07-10 06:01:56 -07:00
// this would put the value into the 0-100 range
return maxF(0, minF(100, result));
}
/*
* Return voltage on TPS AND channel
* */
2017-05-15 20:28:49 -07:00
float getTPSVoltage(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2019-05-05 09:02:42 -07:00
return getVoltageDivided("tps", engineConfiguration->tps1_1AdcChannel);
2015-07-10 06:01:56 -07:00
}
/*
* Return TPS ADC readings.
* We need ADC value because TunerStudio has a nice TPS configuration wizard, and this wizard
* wants a TPS value.
*/
2017-05-15 20:28:49 -07:00
int getTPS12bitAdc(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2015-07-10 06:01:56 -07:00
#if !EFI_PROD_CODE
if (engine->mockTpsAdcValue != MOCK_UNDEFINED) {
return engine->mockTpsAdcValue;
2017-11-16 07:29:40 -08:00
}
2015-07-10 06:01:56 -07:00
#endif
2019-05-05 09:02:42 -07:00
if (engineConfiguration->tps1_1AdcChannel == EFI_ADC_NONE)
2015-07-10 06:01:56 -07:00
return -1;
#if EFI_PROD_CODE
2016-01-31 18:02:03 -08:00
2019-05-05 09:02:42 -07:00
return getAdcValue("tps10", engineConfiguration->tps1_1AdcChannel);
2016-01-31 18:02:03 -08:00
// return tpsFastAdc / 4;
2015-07-10 06:01:56 -07:00
#else
return 0;
#endif /* EFI_PROD_CODE */
}
2019-04-29 22:21:09 -07:00
void grabTPSIsClosed() {
#if EFI_PROD_CODE
engineConfiguration->tpsMin = getTPS10bitAdc();
printTPSInfo();
#endif /* EFI_PROD_CODE */
}
void grabTPSIsWideOpen() {
#if EFI_PROD_CODE
engineConfiguration->tpsMax = getTPS10bitAdc();
printTPSInfo();
#endif /* EFI_PROD_CODE */
}
2019-04-30 15:46:39 -07:00
void grabPedalIsUp() {
#if EFI_PROD_CODE
float voltage = getVoltageDivided("pPS", engineConfiguration->throttlePedalPositionAdcChannel);
engineConfiguration->throttlePedalUpVoltage = voltage;
#endif /* EFI_PROD_CODE */
}
void grabPedalIsWideOpen() {
#if EFI_PROD_CODE
float voltage = getVoltageDivided("pPS", engineConfiguration->throttlePedalPositionAdcChannel);
engineConfiguration->throttlePedalWOTVoltage = voltage;
#endif /* EFI_PROD_CODE */
}
2015-07-10 06:01:56 -07:00
/**
* @brief Position on physical primary TPS
*/
2017-05-15 20:28:49 -07:00
static percent_t getPrimatyRawTPS(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
percent_t tpsValue = getTpsValue(getTPS12bitAdc(PASS_ENGINE_PARAMETER_SIGNATURE) PASS_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
return tpsValue;
}
#define NO_TPS_MAGIC_VALUE 66.611
2017-05-15 20:28:49 -07:00
bool hasPedalPositionSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
return engineConfiguration->throttlePedalPositionAdcChannel != EFI_ADC_NONE;
2015-07-10 06:01:56 -07:00
}
2017-05-15 20:28:49 -07:00
percent_t getPedalPosition(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2017-11-16 11:44:53 -08:00
if (mockPedalPosition != MOCK_UNDEFINED) {
return mockPedalPosition;
}
float voltage = getVoltageDivided("pPS", engineConfiguration->throttlePedalPositionAdcChannel);
2018-06-12 02:45:11 -07:00
float result = interpolateMsg("pedal", engineConfiguration->throttlePedalUpVoltage, 0, engineConfiguration->throttlePedalWOTVoltage, 100, voltage);
2015-07-10 06:01:56 -07:00
// this would put the value into the 0-100 range
return maxF(0, minF(100, result));
}
2017-05-15 20:28:49 -07:00
bool hasTpsSensor(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2019-05-05 09:02:42 -07:00
return engineConfiguration->tps1_1AdcChannel != EFI_ADC_NONE;
2016-12-17 08:01:40 -08:00
}
2017-05-15 20:28:49 -07:00
percent_t getTPS(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2019-05-27 11:21:12 -07:00
#if !EFI_PROD_CODE
if (!cisnan(engine->mockTpsValue)) {
return engine->mockTpsValue;
2019-05-27 11:21:12 -07:00
}
#endif /* EFI_PROD_CODE */
2017-05-15 20:28:49 -07:00
if (!hasTpsSensor(PASS_ENGINE_PARAMETER_SIGNATURE))
2015-07-10 06:01:56 -07:00
return NO_TPS_MAGIC_VALUE;
// todo: if (config->isDualTps)
// todo: blah blah
// todo: if two TPS do not match - show OBD code via malfunction_central.c
2017-05-15 20:28:49 -07:00
return getPrimatyRawTPS(PASS_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
}
void setBosch0280750009(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
// see http://rusefi.com/wiki/index.php?title=Vehicle:VW_Passat_2002_1.8
engineConfiguration->tpsMin = 159;
engineConfiguration->tpsMax = 957;
// todo: add 2nd TPS sensor calibration
}
2015-07-10 06:01:56 -07:00
int convertVoltageTo10bitADC(float voltage) {
// divided by 2 because of voltage divider, then converted into 10bit ADC value (TunerStudio format)
return (int) (voltage / 2 * 1024 / 3.3);
}