| 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 |