2021-07-25 22:05:17 -07:00
# include "pch.h"
2020-02-03 22:54:05 -08:00
# include "adc_subscription.h"
# include "functional_sensor.h"
2020-05-18 11:32:00 -07:00
# include "redundant_sensor.h"
2021-04-05 12:57:03 -07:00
# include "redundant_ford_tps.h"
2020-03-22 14:29:01 -07:00
# include "proxy_sensor.h"
2020-02-03 22:54:05 -08:00
# include "linear_func.h"
# include "tps.h"
2022-11-28 23:03:46 -08:00
# include "auto_generated_sensor.h"
2023-10-30 19:13:29 -07:00
# include "defaults.h"
2022-11-25 07:13:57 -08:00
2022-06-04 09:07:28 -07:00
struct TpsConfig {
adc_channel_e channel ;
float closed ;
float open ;
float min ;
float max ;
} ;
class FuncSensPair {
public :
2024-04-21 17:38:55 -07:00
AdcSubscriptionEntry * adc = nullptr ;
2022-06-04 09:07:28 -07:00
FuncSensPair ( float divideInput , SensorType type )
: m_func ( divideInput )
, m_sens ( type , MS2NT ( 10 ) )
{
m_sens . setFunction ( m_func ) ;
}
2020-02-03 22:54:05 -08:00
2022-06-04 09:07:28 -07:00
bool init ( const TpsConfig & cfg ) {
// If the configuration was invalid, don't continue to configure the sensor
if ( ! configure ( cfg ) ) {
return false ;
}
2020-05-18 11:32:00 -07:00
2024-04-22 20:23:03 -07:00
adc = AdcSubscription : : SubscribeSensor ( m_sens , cfg . channel , /*lowpassCutoffHz*/ 200 ) ;
2020-02-03 22:54:05 -08:00
2022-06-04 09:07:28 -07:00
return m_sens . Register ( ) ;
}
2021-04-05 12:57:03 -07:00
2023-01-10 11:10:30 -08:00
void deinit ( ) {
2022-06-04 09:07:28 -07:00
AdcSubscription : : UnsubscribeSensor ( m_sens ) ;
}
2020-05-23 16:48:32 -07:00
2022-06-04 09:07:28 -07:00
SensorType type ( ) const {
return m_sens . type ( ) ;
}
2020-03-22 14:09:46 -07:00
2022-06-04 09:07:28 -07:00
const char * name ( ) const {
return m_sens . getSensorName ( ) ;
}
2020-03-22 14:29:01 -07:00
2022-06-04 09:07:28 -07:00
private :
bool configure ( const TpsConfig & cfg ) {
// Only configure if we have a channel
if ( ! isAdcChannelValid ( cfg . channel ) ) {
2022-11-28 23:10:55 -08:00
# if EFI_UNIT_TEST
printf ( " Configured NO hardware %s \n " , name ( ) ) ;
# endif
2022-06-04 09:07:28 -07:00
return false ;
}
float scaledClosed = cfg . closed / m_func . getDivideInput ( ) ;
float scaledOpen = cfg . open / m_func . getDivideInput ( ) ;
float split = absF ( scaledOpen - scaledClosed ) ;
// If the voltage for closed vs. open is very near, something is wrong with your calibration
if ( split < 0.5f ) {
2023-04-11 17:01:34 -07:00
firmwareError ( ObdCode : : OBD_TPS_Configuration , " \" %s \" problem: open %.2f/closed %.2f cal values are too close together. Check your calibration and wiring! " , name ( ) ,
2022-06-04 09:07:28 -07:00
cfg . open ,
cfg . closed ) ;
return false ;
}
m_func . configure (
cfg . closed , 0 ,
2023-03-01 13:53:48 -08:00
cfg . open , POSITION_FULLY_OPEN ,
2022-06-04 09:07:28 -07:00
cfg . min , cfg . max
) ;
2022-11-28 23:10:55 -08:00
# if EFI_UNIT_TEST
printf ( " Configured YES %s \n " , name ( ) ) ;
# endif
2022-06-04 09:07:28 -07:00
return true ;
2020-12-06 20:19:57 -08:00
}
2022-06-04 09:07:28 -07:00
LinearFunc m_func ;
FunctionalSensor m_sens ;
} ;
struct RedundantPair {
public :
RedundantPair ( FuncSensPair & pri , FuncSensPair & sec , SensorType outputType )
: m_pri ( pri )
, m_sec ( sec )
, m_redund ( outputType , m_pri . type ( ) , m_sec . type ( ) )
{
}
2020-12-05 21:41:49 -08:00
2023-06-11 17:30:44 -07:00
void init ( bool isFordTps , RedundantFordTps * fordTps , float secondaryMaximum , const TpsConfig & primary , const TpsConfig & secondary , bool allowIdenticalSensors = false ) {
2022-07-28 06:46:19 -07:00
bool hasFirst = m_pri . init ( primary ) ;
if ( ! hasFirst ) {
// no input if we have no first channel
return ;
}
2023-06-11 17:30:44 -07:00
if ( ! allowIdenticalSensors ) {
2022-06-04 09:07:28 -07:00
// Check that the primary and secondary aren't too close together - if so, the user may have done
// an unsafe thing where they wired a single sensor to both inputs. Don't do that!
bool hasBothSensors = isAdcChannelValid ( primary . channel ) & & isAdcChannelValid ( secondary . channel ) ;
bool tooCloseClosed = absF ( primary . closed - secondary . closed ) < 0.2f ;
bool tooCloseOpen = absF ( primary . open - secondary . open ) < 0.2f ;
if ( hasBothSensors & & tooCloseClosed & & tooCloseOpen ) {
2023-04-11 17:01:34 -07:00
firmwareError ( ObdCode : : OBD_TPS_Configuration , " Configuration for redundant pair %s/%s are too similar - did you wire one sensor to both inputs...? " , m_pri . name ( ) , m_sec . name ( ) ) ;
2022-06-04 09:07:28 -07:00
return ;
}
}
bool hasSecond = m_sec . init ( secondary ) ;
2023-10-30 19:13:29 -07:00
if ( engineConfiguration - > etbSplit < = 0 | | engineConfiguration - > etbSplit > MAX_TPS_PPS_DISCREPANCY ) {
engineConfiguration - > etbSplit = MAX_TPS_PPS_DISCREPANCY ;
}
2022-06-04 09:07:28 -07:00
if ( isFordTps & & fordTps ) {
// we have a secondary
2023-10-30 19:13:29 -07:00
fordTps - > configure ( engineConfiguration - > etbSplit , secondaryMaximum ) ;
2022-06-04 09:07:28 -07:00
fordTps - > Register ( ) ;
} else {
// not ford TPS
2023-10-30 19:13:29 -07:00
m_redund . configure ( engineConfiguration - > etbSplit , ! hasSecond ) ;
2022-11-28 23:03:46 -08:00
# if EFI_UNIT_TEST
printf ( " init m_redund.Register() %s \n " , getSensorType ( m_redund . type ( ) ) ) ;
# endif
2022-06-04 09:07:28 -07:00
m_redund . Register ( ) ;
}
}
2020-12-05 21:41:49 -08:00
2023-01-10 11:10:30 -08:00
void deinit ( bool isFordTps , RedundantFordTps * fordTps ) {
m_pri . deinit ( ) ;
m_sec . deinit ( ) ;
if ( isFordTps & & fordTps ) {
fordTps - > unregister ( ) ;
} else {
m_redund . unregister ( ) ;
}
2020-12-05 21:41:49 -08:00
}
2024-04-21 17:38:55 -07:00
void updateUnfilteredRawValues ( ) {
engine - > outputChannels . rawRawPpsPrimary = m_pri . adc = = nullptr ? 0 : m_pri . adc - > sensorVolts ;
engine - > outputChannels . rawRawPpsSecondary = m_sec . adc = = nullptr ? 0 : m_sec . adc - > sensorVolts ;
}
2022-06-04 09:07:28 -07:00
private :
FuncSensPair & m_pri ;
FuncSensPair & m_sec ;
2020-12-05 21:41:49 -08:00
2022-06-04 09:07:28 -07:00
RedundantSensor m_redund ;
} ;
2020-02-08 01:22:23 -08:00
2022-06-04 09:07:28 -07:00
static FuncSensPair tps1p ( TPS_TS_CONVERSION , SensorType : : Tps1Primary ) ;
static FuncSensPair tps1s ( TPS_TS_CONVERSION , SensorType : : Tps1Secondary ) ;
static FuncSensPair tps2p ( TPS_TS_CONVERSION , SensorType : : Tps2Primary ) ;
static FuncSensPair tps2s ( TPS_TS_CONVERSION , SensorType : : Tps2Secondary ) ;
2020-02-03 22:54:05 -08:00
2022-06-04 09:07:28 -07:00
// Used in case of "normal", non-Ford ETB TPS
2023-02-23 01:37:27 -08:00
static RedundantPair analogTps1 ( tps1p , tps1s , SensorType : : Tps1 ) ;
2022-06-04 09:07:28 -07:00
static RedundantPair tps2 ( tps2p , tps2s , SensorType : : Tps2 ) ;
2020-02-03 22:54:05 -08:00
2023-03-01 06:19:22 -08:00
SentTps sentTps ;
2023-02-23 02:26:42 -08:00
2022-06-04 09:07:28 -07:00
// Used only in case of weird Ford-style ETB TPS
static RedundantFordTps fordTps1 ( SensorType : : Tps1 , SensorType : : Tps1Primary , SensorType : : Tps1Secondary ) ;
static RedundantFordTps fordTps2 ( SensorType : : Tps2 , SensorType : : Tps2Primary , SensorType : : Tps2Secondary ) ;
2023-01-10 11:10:30 -08:00
static RedundantFordTps fordPps ( SensorType : : AcceleratorPedal , SensorType : : AcceleratorPedalPrimary , SensorType : : AcceleratorPedalSecondary ) ;
2020-02-03 22:54:05 -08:00
2022-06-04 09:07:28 -07:00
// Pedal sensors and redundancy
static FuncSensPair pedalPrimary ( 1 , SensorType : : AcceleratorPedalPrimary ) ;
static FuncSensPair pedalSecondary ( 1 , SensorType : : AcceleratorPedalSecondary ) ;
static RedundantPair pedal ( pedalPrimary , pedalSecondary , SensorType : : AcceleratorPedal ) ;
2020-05-18 11:32:00 -07:00
2024-04-21 17:38:55 -07:00
void updateUnfilteredRawPedal ( ) {
pedal . updateUnfilteredRawValues ( ) ;
}
2022-06-04 09:07:28 -07:00
// This sensor indicates the driver's throttle intent - Pedal if we have one, TPS if not.
static ProxySensor driverIntent ( SensorType : : DriverThrottleIntent ) ;
2020-05-18 11:32:00 -07:00
2022-06-04 09:07:28 -07:00
// These sensors are TPS-like, so handle them in here too
static FuncSensPair wastegate ( PACK_MULT_VOLTAGE , SensorType : : WastegatePosition ) ;
static FuncSensPair idlePos ( PACK_MULT_VOLTAGE , SensorType : : IdlePosition ) ;
2020-02-03 22:54:05 -08:00
2023-02-23 01:37:27 -08:00
bool isDigitalTps1 ( ) {
return isBrainPinValid ( engineConfiguration - > sentInputPins [ 0 ] ) & & engineConfiguration - > sentEtbType ! = SentEtbType : : NONE ;
}
2021-11-16 01:15:29 -08:00
void initTps ( ) {
2023-09-05 18:28:39 -07:00
criticalAssertVoid ( engineConfiguration ! = nullptr , " null engineConfiguration " ) ;
2024-04-22 20:25:41 -07:00
percent_t minTpsPps = engineConfiguration - > tpsErrorDetectionTooLow ;
percent_t maxTpsPps = engineConfiguration - > tpsErrorDetectionTooHigh ;
2020-04-05 06:10:08 -07:00
2021-11-17 00:54:21 -08:00
if ( ! engineConfiguration - > consumeObdSensors ) {
bool isFordTps = engineConfiguration - > useFordRedundantTps ;
2023-01-10 11:10:30 -08:00
bool isFordPps = engineConfiguration - > useFordRedundantPps ;
2022-06-04 09:07:28 -07:00
2023-01-10 11:10:30 -08:00
float tpsSecondaryMaximum = engineConfiguration - > tpsSecondaryMaximum ;
if ( tpsSecondaryMaximum < 20 ) {
// don't allow <20% split point
tpsSecondaryMaximum = 20 ;
}
2023-02-28 19:10:19 -08:00
if ( isDigitalTps1 ( ) ) {
sentTps . Register ( ) ;
} else {
analogTps1 . init ( isFordTps , & fordTps1 , tpsSecondaryMaximum ,
2024-04-22 20:25:41 -07:00
{ engineConfiguration - > tps1_1AdcChannel , ( float ) engineConfiguration - > tpsMin , ( float ) engineConfiguration - > tpsMax , minTpsPps , maxTpsPps } ,
{ engineConfiguration - > tps1_2AdcChannel , ( float ) engineConfiguration - > tps1SecondaryMin , ( float ) engineConfiguration - > tps1SecondaryMax , minTpsPps , maxTpsPps }
2023-02-28 19:10:19 -08:00
) ;
}
2022-06-04 09:07:28 -07:00
2023-01-10 11:10:30 -08:00
tps2 . init ( isFordTps , & fordTps2 , tpsSecondaryMaximum ,
2024-04-22 20:25:41 -07:00
{ engineConfiguration - > tps2_1AdcChannel , ( float ) engineConfiguration - > tps2Min , ( float ) engineConfiguration - > tps2Max , minTpsPps , maxTpsPps } ,
{ engineConfiguration - > tps2_2AdcChannel , ( float ) engineConfiguration - > tps2SecondaryMin , ( float ) engineConfiguration - > tps2SecondaryMax , minTpsPps , maxTpsPps }
2022-06-04 09:07:28 -07:00
) ;
2021-04-05 12:57:03 -07:00
2023-01-10 11:10:30 -08:00
float ppsSecondaryMaximum = engineConfiguration - > ppsSecondaryMaximum ;
if ( ppsSecondaryMaximum < 20 ) {
// don't allow <20% split point
ppsSecondaryMaximum = 20 ;
}
2023-06-11 17:30:44 -07:00
// Pedal sensors
pedal . init ( isFordPps , & fordPps , ppsSecondaryMaximum ,
2024-04-22 20:25:41 -07:00
{ engineConfiguration - > throttlePedalPositionAdcChannel , engineConfiguration - > throttlePedalUpVoltage , engineConfiguration - > throttlePedalWOTVoltage , minTpsPps , maxTpsPps } ,
{ engineConfiguration - > throttlePedalPositionSecondAdcChannel , engineConfiguration - > throttlePedalSecondaryUpVoltage , engineConfiguration - > throttlePedalSecondaryWOTVoltage , minTpsPps , maxTpsPps } ,
2023-06-11 17:30:44 -07:00
engineConfiguration - > allowIdenticalPps
) ;
2020-09-18 00:04:07 -07:00
// TPS-like stuff that isn't actually a TPS
2024-04-22 20:25:41 -07:00
wastegate . init ( { engineConfiguration - > wastegatePositionSensor , ( float ) engineConfiguration - > wastegatePositionMin , ( float ) engineConfiguration - > wastegatePositionMax , minTpsPps , maxTpsPps } ) ;
idlePos . init ( { engineConfiguration - > idlePositionChannel , ( float ) engineConfiguration - > idlePositionMin , ( float ) engineConfiguration - > idlePositionMax , minTpsPps , maxTpsPps } ) ;
2020-09-06 17:21:01 -07:00
}
2020-03-22 14:29:01 -07:00
// Route the pedal or TPS to driverIntent as appropriate
2021-11-17 00:54:21 -08:00
if ( isAdcChannelValid ( engineConfiguration - > throttlePedalPositionAdcChannel ) ) {
2020-03-22 14:29:01 -07:00
driverIntent . setProxiedSensor ( SensorType : : AcceleratorPedal ) ;
} else {
driverIntent . setProxiedSensor ( SensorType : : Tps1 ) ;
}
2020-04-01 17:21:03 -07:00
2020-12-06 12:00:30 -08:00
driverIntent . Register ( ) ;
2020-02-03 22:54:05 -08:00
}
2020-02-08 01:22:23 -08:00
2021-08-24 13:41:16 -07:00
void deinitTps ( ) {
2023-01-10 11:10:30 -08:00
bool isFordTps = activeConfiguration . useFordRedundantTps ;
bool isFordPps = activeConfiguration . useFordRedundantPps ;
2023-02-23 01:37:27 -08:00
analogTps1 . deinit ( isFordTps , & fordTps1 ) ;
2023-01-10 11:10:30 -08:00
tps2 . deinit ( isFordTps , & fordTps2 ) ;
2023-11-02 07:39:35 -07:00
pedal . deinit ( isFordPps , & fordPps ) ;
2020-09-18 00:04:07 -07:00
2023-02-23 02:26:42 -08:00
sentTps . unregister ( ) ;
2023-01-10 11:10:30 -08:00
wastegate . deinit ( ) ;
idlePos . deinit ( ) ;
2020-02-08 01:22:23 -08:00
}