2015-12-31 13:02:30 -08:00
|
|
|
/**
|
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2016
|
|
|
|
*/
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "main.h"
|
|
|
|
#include "tps.h"
|
|
|
|
#include "engine_configuration.h"
|
|
|
|
#include "interpolation.h"
|
|
|
|
#include "adc_inputs.h"
|
|
|
|
#include "allsensors.h"
|
|
|
|
|
|
|
|
#if !EFI_PROD_CODE
|
|
|
|
int mockTps;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
EXTERN_ENGINE;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*
|
|
|
|
* */
|
|
|
|
percent_t getTpsValue(int adc DECLARE_ENGINE_PARAMETER_S) {
|
|
|
|
if (engineConfiguration->tpsMin == engineConfiguration->tpsMax) {
|
|
|
|
warning(OBD_PCM_Processor_Fault, "Invalid TPS configuration: same value %d", engineConfiguration->tpsMin);
|
|
|
|
return NAN;
|
|
|
|
}
|
2016-06-12 21:02:04 -07:00
|
|
|
float result = interpolate(TPS_TS_CONVERSION * engineConfiguration->tpsMax, 0, TPS_TS_CONVERSION * engineConfiguration->tpsMin, 100, adc);
|
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
|
|
|
|
* */
|
|
|
|
float getTPSVoltage(DECLARE_ENGINE_PARAMETER_F) {
|
|
|
|
return getVoltageDivided("tps", engineConfiguration->tpsAdcChannel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return TPS ADC readings.
|
|
|
|
* We need ADC value because TunerStudio has a nice TPS configuration wizard, and this wizard
|
|
|
|
* wants a TPS value.
|
|
|
|
*/
|
2016-01-31 18:02:03 -08:00
|
|
|
int getTPS12bitAdc(DECLARE_ENGINE_PARAMETER_F) {
|
2015-07-10 06:01:56 -07:00
|
|
|
#if !EFI_PROD_CODE
|
|
|
|
if (mockTps != MOCK_UNDEFINED)
|
|
|
|
return mockTps;
|
|
|
|
#endif
|
2016-01-31 18:02:03 -08:00
|
|
|
if (engineConfiguration->tpsAdcChannel == 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
|
|
|
|
|
|
|
return getAdcValue("tps10", engineConfiguration->tpsAdcChannel);
|
|
|
|
// return tpsFastAdc / 4;
|
2015-07-10 06:01:56 -07:00
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif /* EFI_PROD_CODE */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Position on physical primary TPS
|
|
|
|
*/
|
2016-01-31 13:01:26 -08:00
|
|
|
static percent_t getPrimatyRawTPS(DECLARE_ENGINE_PARAMETER_F) {
|
2016-01-31 18:02:03 -08:00
|
|
|
percent_t tpsValue = getTpsValue(getTPS12bitAdc(PASS_ENGINE_PARAMETER_F) PASS_ENGINE_PARAMETER);
|
2015-07-10 06:01:56 -07:00
|
|
|
return tpsValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NO_TPS_MAGIC_VALUE 66.611
|
|
|
|
|
2016-01-11 14:01:33 -08:00
|
|
|
bool hasPedalPositionSensor(DECLARE_ENGINE_PARAMETER_F) {
|
2015-07-10 06:01:56 -07:00
|
|
|
return engineConfiguration->pedalPositionChannel != EFI_ADC_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
percent_t getPedalPosition(DECLARE_ENGINE_PARAMETER_F) {
|
|
|
|
float voltage = getVoltageDivided("pPS", engineConfiguration->pedalPositionChannel);
|
|
|
|
float result = interpolate(engineConfiguration->pedalPositionMin, 0, engineConfiguration->pedalPositionMax, 100, voltage);
|
|
|
|
|
|
|
|
// this would put the value into the 0-100 range
|
|
|
|
return maxF(0, minF(100, result));
|
|
|
|
}
|
|
|
|
|
|
|
|
percent_t getTPS(DECLARE_ENGINE_PARAMETER_F) {
|
|
|
|
if (!engineConfiguration->hasTpsSensor)
|
|
|
|
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
|
|
|
|
|
|
|
|
return getPrimatyRawTPS(PASS_ENGINE_PARAMETER_F);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|