Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | #include "pch.h" | |||
2 | ||||
3 | #include "adc_subscription.h" | |||
4 | #include "linear_func.h" | |||
5 | #include "fallback_sensor.h" | |||
6 | #include "functional_sensor.h" | |||
7 | #include "map_averaging.h" | |||
8 | ||||
9 | static LinearFunc baroConverter; | |||
10 | static FunctionalSensor baroSensor(SensorType::BarometricPressure, MS2NT(50)); | |||
11 | ||||
12 | // This converter is shared between both fast and slow: the only difference is | |||
13 | // how the *voltage* is determined, not how its converted to a pressure. | |||
14 | static LinearFunc mapConverter; | |||
15 | static FunctionalSensor slowMapSensor(SensorType::MapSlow, MS2NT(50)); | |||
16 | // unfinished/dead? static FunctionalSensor slowMapSensor2(SensorType::MapSlow2, MS2NT(50)); | |||
17 | static FunctionalSensor compressorDischargePress(SensorType::CompressorDischargePressure, MS2NT(50)); | |||
18 | static FunctionalSensor throttleInletPress(SensorType::ThrottleInletPressure, MS2NT(50)); | |||
19 | ||||
20 | // lowest reasonable idle is maybe 600 rpm | |||
21 | // one sample per cycle (1 cylinder, or "sample one cyl" mode) gives a period of 100ms | |||
22 | // add some margin -> 200ms timeout for fast MAP sampling | |||
23 | // 'fast' means averaged? why is that fast again?! | |||
24 | static MapAverager fastMapSensor(SensorType::MapFast, MS2NT(200)); | |||
25 | static MapAverager fastMapSensor2(SensorType::MapFast2, MS2NT(200)); | |||
26 | ||||
27 | // instant map values are injected here | |||
28 | 31 | MapAverager& getMapAvg(size_t cylinderBankIndex) { | ||
29 | // May 2025: cylinderBankIndex is always zero, second MAP sensor feature is not finished | |||
30 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | return cylinderBankIndex == 0 ? fastMapSensor : fastMapSensor2; | |
31 | } | |||
32 | ||||
33 | // Combine MAP sensors: prefer fast sensor, but use slow if fast is unavailable. | |||
34 | static FallbackSensor mapCombiner(SensorType::Map, SensorType::MapFast, SensorType::MapSlow); | |||
35 | static FallbackSensor mapCombiner2(SensorType::Map2, SensorType::MapFast2, SensorType::MapSlow2); | |||
36 | ||||
37 | // helper struct for the local getMapCfg function | |||
38 | struct MapCfg { | |||
39 | float v1; | |||
40 | float map1; | |||
41 | float v2; | |||
42 | float map2; | |||
43 | }; | |||
44 | ||||
45 | 4 | static MapCfg getMapCfg(air_pressure_sensor_type_e sensorType) { | ||
46 |
1/16✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
|
4 | switch (sensorType) { | |
47 | ✗ | case MT_DENSO183: | ||
48 | ✗ | return {0, -6.64, 5, 182.78}; | ||
49 | ✗ | case MT_MPX4100: | ||
50 | ✗ | return {0.306, 20, 4.897, 105}; | ||
51 |
1/1✓ Decision 'true' taken 4 times.
|
4 | case MT_MPX4250: | |
52 | case MT_MPX4250A: | |||
53 |
1/1✓ Decision 'true' taken 4 times.
|
4 | return {0.204, 20, 4.896, 250}; | |
54 | ✗ | case MT_HONDA3BAR: | ||
55 | ✗ | return {0.5, 91.422, 3.0, 0}; | ||
56 | ✗ | case MT_DODGE_NEON_2003: | ||
57 | ✗ | return {0.4, 15.34, 4.5, 100}; | ||
58 | ✗ | case MT_SUBY_DENSO: | ||
59 | ✗ | return {0, 0, 5, 200}; | ||
60 | ✗ | case MT_GM_3_BAR: | ||
61 | ✗ | return {0.631, 40, 4.914, 304}; | ||
62 | ✗ | case MT_GM_2_BAR: | ||
63 | ✗ | return {0, 8.8, 5, 208}; | ||
64 | ✗ | case MT_GM_1_BAR: | ||
65 | ✗ | return {0, 10, 5, 105}; | ||
66 | ✗ | case MT_TOYOTA_89420_02010: | ||
67 | ✗ | return {3.7 - 2, 33.32, 3.7, 100}; | ||
68 | ✗ | case MT_MAZDA_1_BAR: | ||
69 | ✗ | return {0, 2.5, 5, 117}; | ||
70 | ✗ | case MT_BOSCH_2_5: | ||
71 | // kpa=54.11764705882353v−1.6470588235294201 | |||
72 | ✗ | return {0.4 , 20 , 4.65, 250}; | ||
73 | ✗ | case MT_MPXH6400: | ||
74 | ✗ | return {0.2, 20, 4.8, 400}; | ||
75 | ✗ | case MT_MPXH6300: | ||
76 | ✗ | return {1.0, 60, 4.5, 270}; | ||
77 | ✗ | default: | ||
78 | ✗ | firmwareError(ObdCode::CUSTOM_ERR_MAP_TYPE, "Unknown MAP type: decoder %d", sensorType); | ||
79 | // falls through to custom | |||
80 | ✗ | return {}; | ||
81 | ✗ | case MT_CUSTOM: { | ||
82 | ✗ | auto& mapConfig = engineConfiguration->map.sensor; | ||
83 | return { | |||
84 | ✗ | engineConfiguration->mapLowValueVoltage, | ||
85 | ✗ | mapConfig.lowValue, | ||
86 | ✗ | engineConfiguration->mapHighValueVoltage, | ||
87 | ✗ | mapConfig.highValue | ||
88 | ✗ | }; | ||
89 | }} | |||
90 | } | |||
91 | ||||
92 | 4 | void configureMapFunction(LinearFunc& converter, air_pressure_sensor_type_e sensorType) { | ||
93 | 4 | auto cfg = getMapCfg(sensorType); | ||
94 | ||||
95 | 4 | converter.configure( | ||
96 | cfg.v1, | |||
97 | cfg.map1, | |||
98 | cfg.v2, | |||
99 | cfg.map2, | |||
100 | engineConfiguration->mapErrorDetectionTooLow, | |||
101 | engineConfiguration->mapErrorDetectionTooHigh | |||
102 | ); | |||
103 | 4 | } | ||
104 | ||||
105 | 4 | void initMap() { | ||
106 | // Set up the conversion function | |||
107 | 4 | configureMapFunction(mapConverter, engineConfiguration->map.sensor.type); | ||
108 | ||||
109 | 4 | slowMapSensor.setFunction(mapConverter); | ||
110 | // unfinished/dead? slowMapSensor2.setFunction(mapConverter); | |||
111 | 4 | fastMapSensor.setFunction(mapConverter); | ||
112 | 4 | fastMapSensor2.setFunction(mapConverter); | ||
113 | 4 | compressorDischargePress.setFunction(mapConverter); | ||
114 | 4 | throttleInletPress.setFunction(mapConverter); | ||
115 | ||||
116 | 4 | auto mapChannel = engineConfiguration->map.sensor.hwChannel; | ||
117 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 2 taken 3 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 3 times.
|
4 | if (isAdcChannelValid(mapChannel)) { |
118 | 1 | slowMapSensor.Register(); | ||
119 | // unfinished/dead? slowMapSensor2.Register(); | |||
120 | 1 | fastMapSensor.Register(); | ||
121 | 1 | fastMapSensor2.Register(); | ||
122 | 1 | mapCombiner.Register(); | ||
123 | 1 | mapCombiner2.Register(); | ||
124 | ||||
125 | // Configure slow MAP as a normal analog sensor | |||
126 | // it's possible/probably that slow and fast both read from same physical pin, apparently that's fine?! | |||
127 | 1 | AdcSubscription::SubscribeSensor(slowMapSensor, mapChannel, 100); | ||
128 | } | |||
129 | ||||
130 | 4 | AdcSubscription::SubscribeSensor(throttleInletPress, engineConfiguration->throttleInletPressureChannel, 100); | ||
131 | 4 | AdcSubscription::SubscribeSensor(compressorDischargePress, engineConfiguration->compressorDischargePressureChannel, 100); | ||
132 | ||||
133 | 4 | auto baroChannel = engineConfiguration->baroSensor.hwChannel; | ||
134 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 4 times.
|
4 | if (isAdcChannelValid(baroChannel)) { |
135 | ✗ | configureMapFunction(baroConverter, engineConfiguration->baroSensor.type); | ||
136 | ||||
137 | ✗ | baroSensor.setFunction(baroConverter); | ||
138 | ✗ | baroSensor.Register(); | ||
139 | ||||
140 | ✗ | AdcSubscription::SubscribeSensor(baroSensor, baroChannel, 10); | ||
141 | } | |||
142 | 4 | } | ||
143 | ||||
144 | ✗ | void deinitMap() { | ||
145 | ✗ | AdcSubscription::UnsubscribeSensor(slowMapSensor, engineConfiguration->map.sensor.hwChannel); | ||
146 | ✗ | AdcSubscription::UnsubscribeSensor(baroSensor, engineConfiguration->baroSensor.hwChannel); | ||
147 | ✗ | AdcSubscription::UnsubscribeSensor(throttleInletPress, engineConfiguration->throttleInletPressureChannel); | ||
148 | ✗ | AdcSubscription::UnsubscribeSensor(compressorDischargePress, engineConfiguration->compressorDischargePressureChannel); | ||
149 | ✗ | } | ||
150 |