GCC Code Coverage Report


Directory: ./
File: firmware/init/sensor/init_map.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 39.5% 30 0 76
Functions: 80.0% 4 0 5
Branches: 22.7% 5 0 22
Decisions: 23.8% 5 - 21

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