| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | // | |||
| 2 | // Created by kifir on 11/25/24. | |||
| 3 | // | |||
| 4 | ||||
| 5 | #include "pch.h" | |||
| 6 | ||||
| 7 | #if EFI_LAUNCH_CONTROL | |||
| 8 | #include "nitrous_controller.h" | |||
| 9 | ||||
| 10 | 1086 | void NitrousController::onSlowCallback() { | ||
| 11 |
2/2✓ Branch 0 taken 216 times.
✓ Branch 1 taken 870 times.
|
2/2✓ Decision 'true' taken 216 times.
✓ Decision 'false' taken 870 times.
|
1086 | if (engineConfiguration->nitrousControlEnabled) { |
| 12 | 216 | updateArmingState(); | ||
| 13 | 216 | updateSpeedConditionSatisfied(); | ||
| 14 | 216 | updateTpsConditionSatisfied(); | ||
| 15 | 216 | updateCltConditionSatisfied(); | ||
| 16 | 216 | updateMapConditionSatisfied(); | ||
| 17 | 216 | updateAfrConditionSatisfied(); | ||
| 18 | 216 | updateRpmConditionSatisfied(); | ||
| 19 | 216 | isNitrousCondition = ( | ||
| 20 |
6/6✓ Branch 0 taken 78 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 59 times.
✓ Branch 3 taken 19 times.
✓ Branch 4 taken 58 times.
✓ Branch 5 taken 1 time.
|
90 | isNitrousArmed && isNitrousSpeedCondition && isNitrousTpsCondition && isNitrousCltCondition | |
| 21 |
8/8✓ Branch 0 taken 90 times.
✓ Branch 1 taken 126 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 23 times.
✓ Branch 5 taken 12 times.
✓ Branch 6 taken 11 times.
✓ Branch 7 taken 12 times.
|
306 | && isNitrousMapCondition && isNitrousAfrCondition && isNitrousRpmCondition | |
| 22 | ); | |||
| 23 | } else { | |||
| 24 | 870 | isNitrousCondition = false; | ||
| 25 | } | |||
| 26 | 1086 | enginePins.nitrousRelay.setValue(isNitrousCondition); | ||
| 27 | 1086 | } | ||
| 28 | ||||
| 29 | 966 | float NitrousController::getFuelCoefficient() const { | ||
| 30 | 966 | float result = 1.0f; | ||
| 31 |
4/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 954 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 8 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 962 times.
|
966 | if (engineConfiguration->nitrousControlEnabled && isNitrousCondition) { |
| 32 | 4 | result += engineConfiguration->nitrousFuelAdderPercent / 100.0f; | ||
| 33 | } | |||
| 34 | 966 | return result; | ||
| 35 | } | |||
| 36 | ||||
| 37 | 216 | void NitrousController::updateArmingState() { | ||
| 38 |
2/3✓ Branch 0 taken 208 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
216 | switch (engineConfiguration->nitrousControlArmingMethod) { | |
| 39 |
1/1✓ Decision 'true' taken 208 times.
|
208 | case DIGITAL_SWITCH_INPUT: { | |
| 40 | 208 | isNitrousArmed = checkTriggerPinState(); | ||
| 41 | 208 | break; | ||
| 42 | } | |||
| 43 |
1/1✓ Decision 'true' taken 8 times.
|
8 | case LUA_GAUGE: { | |
| 44 | 8 | isNitrousArmed = checkLuaGauge(); | ||
| 45 | 8 | break; | ||
| 46 | } | |||
| 47 | ✗ | default: { // Unexpected value!!! | ||
| 48 | ✗ | isNitrousArmed = false; | ||
| 49 | ✗ | break; | ||
| 50 | } | |||
| 51 | } | |||
| 52 | 216 | } | ||
| 53 | ||||
| 54 | 216 | void NitrousController::updateSpeedConditionSatisfied() { | ||
| 55 |
2/2✓ Branch 0 taken 117 times.
✓ Branch 1 taken 99 times.
|
2/2✓ Decision 'true' taken 117 times.
✓ Decision 'false' taken 99 times.
|
216 | if (engineConfiguration->nitrousMinimumVehicleSpeed != 0) { |
| 56 | 117 | const expected<float> speed = Sensor::get(SensorType::VehicleSpeed); | ||
| 57 |
4/4✓ Branch 0 taken 105 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 27 times.
|
117 | isNitrousSpeedCondition = speed.Valid && (engineConfiguration->nitrousMinimumVehicleSpeed <= speed.Value); | |
| 58 | } else { | |||
| 59 | 99 | isNitrousSpeedCondition = true; | ||
| 60 | } | |||
| 61 | 216 | } | ||
| 62 | ||||
| 63 | 216 | void NitrousController::updateTpsConditionSatisfied() { | ||
| 64 |
2/2✓ Branch 0 taken 211 times.
✓ Branch 1 taken 5 times.
|
2/2✓ Decision 'true' taken 211 times.
✓ Decision 'false' taken 5 times.
|
216 | if (engineConfiguration->nitrousMinimumTps != 0) { |
| 65 | 211 | const expected<float> tps = Sensor::get(SensorType::DriverThrottleIntent); | ||
| 66 |
4/4✓ Branch 0 taken 98 times.
✓ Branch 1 taken 113 times.
✓ Branch 2 taken 73 times.
✓ Branch 3 taken 25 times.
|
211 | isNitrousTpsCondition = tps.Valid && (engineConfiguration->nitrousMinimumTps <= tps.Value); | |
| 67 | } else { | |||
| 68 | 5 | isNitrousTpsCondition = true; | ||
| 69 | } | |||
| 70 | 216 | } | ||
| 71 | ||||
| 72 | 216 | void NitrousController::updateCltConditionSatisfied() { | ||
| 73 |
2/2✓ Branch 0 taken 211 times.
✓ Branch 1 taken 5 times.
|
2/2✓ Decision 'true' taken 211 times.
✓ Decision 'false' taken 5 times.
|
216 | if (engineConfiguration->nitrousMinimumClt != 0) { |
| 74 | 211 | const expected<float> clt = Sensor::get(SensorType::Clt); | ||
| 75 |
4/4✓ Branch 0 taken 209 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 188 times.
✓ Branch 3 taken 21 times.
|
211 | isNitrousCltCondition = clt.Valid && (engineConfiguration->nitrousMinimumClt <= clt.Value); | |
| 76 | } else { | |||
| 77 | 5 | isNitrousCltCondition = true; | ||
| 78 | } | |||
| 79 | 216 | } | ||
| 80 | ||||
| 81 | 216 | void NitrousController::updateMapConditionSatisfied() { | ||
| 82 |
2/2✓ Branch 0 taken 117 times.
✓ Branch 1 taken 99 times.
|
2/2✓ Decision 'true' taken 117 times.
✓ Decision 'false' taken 99 times.
|
216 | if (engineConfiguration->nitrousMaximumMap != 0) { |
| 83 | 117 | const expected<float> map = Sensor::get(SensorType::Map); | ||
| 84 |
4/4✓ Branch 0 taken 72 times.
✓ Branch 1 taken 45 times.
✓ Branch 2 taken 58 times.
✓ Branch 3 taken 14 times.
|
117 | isNitrousMapCondition = map.Valid && (map.Value <= engineConfiguration->nitrousMaximumMap); | |
| 85 | } else { | |||
| 86 | 99 | isNitrousMapCondition = true; | ||
| 87 | } | |||
| 88 | 216 | } | ||
| 89 | ||||
| 90 | 216 | void NitrousController::updateAfrConditionSatisfied() { | ||
| 91 |
2/2✓ Branch 1 taken 211 times.
✓ Branch 2 taken 5 times.
|
2/2✓ Decision 'true' taken 211 times.
✓ Decision 'false' taken 5 times.
|
216 | if (static_cast<float>(engineConfiguration->nitrousMaximumAfr) != 0.0f) { |
| 92 | 211 | const expected<float> lambda1 = Sensor::get(SensorType::Lambda1); | ||
| 93 |
2/2✓ Branch 0 taken 65 times.
✓ Branch 1 taken 146 times.
|
2/2✓ Decision 'true' taken 65 times.
✓ Decision 'false' taken 146 times.
|
211 | if (lambda1.Valid) { |
| 94 | 65 | const float afr = lambda1.Value * STOICH_RATIO; | ||
| 95 | 65 | isNitrousAfrCondition = (afr <= static_cast<float>(engineConfiguration->nitrousMaximumAfr)); | ||
| 96 | } else { | |||
| 97 | 146 | isNitrousAfrCondition = false; | ||
| 98 | } | |||
| 99 | } else { | |||
| 100 | 5 | isNitrousAfrCondition = true; | ||
| 101 | } | |||
| 102 | 216 | } | ||
| 103 | ||||
| 104 | namespace { | |||
| 105 | MaxLimitWithHysteresis<UnstrictChecker> rpmHysteresis; | |||
| 106 | } | |||
| 107 | ||||
| 108 | 216 | void NitrousController::updateRpmConditionSatisfied() { | ||
| 109 | 216 | const expected<float> rpmSensorReading = Sensor::get(SensorType::Rpm); | ||
| 110 |
1/2✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 216 times.
✗ Decision 'false' not taken.
|
216 | if (rpmSensorReading.Valid) { |
| 111 | 216 | const float rpm = rpmSensorReading.Value; | ||
| 112 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 210 times.
|
216 | if (rpmHysteresis.checkIfLimitIsExceeded( | |
| 113 | rpm, | |||
| 114 | 216 | engineConfiguration->nitrousDeactivationRpm, | ||
| 115 | 216 | engineConfiguration->nitrousDeactivationRpmWindow | ||
| 116 | )) { | |||
| 117 | 6 | isNitrousRpmCondition = false; | ||
| 118 | } else { | |||
| 119 | 210 | isNitrousRpmCondition = (engineConfiguration->nitrousActivationRpm <= rpm); | ||
| 120 | } | |||
| 121 | } else { | |||
| 122 | ✗ | isNitrousRpmCondition = false; | ||
| 123 | } | |||
| 124 | 216 | } | ||
| 125 | ||||
| 126 | 208 | bool NitrousController::checkTriggerPinState() const { | ||
| 127 | 208 | bool result = false; | ||
| 128 | #if !EFI_SIMULATOR | |||
| 129 | 208 | const switch_input_pin_e triggerPin = engineConfiguration->nitrousControlTriggerPin; | ||
| 130 | 208 | const pin_input_mode_e triggerPinMode = engineConfiguration->nitrousControlTriggerPinMode; | ||
| 131 |
2/2✓ Branch 1 taken 118 times.
✓ Branch 2 taken 90 times.
|
208 | if (isBrainPinValid(triggerPin)) { | |
| 132 | 118 | result = efiReadPin(triggerPin, triggerPinMode); | ||
| 133 | } | |||
| 134 | #endif // !EFI_SIMULATOR | |||
| 135 | 208 | return result; | ||
| 136 | } | |||
| 137 | ||||
| 138 | 8 | bool NitrousController::checkLuaGauge() const { | ||
| 139 | 8 | bool result = false; | ||
| 140 | 8 | const SensorResult currentSensorResult = Sensor::get(getLuaGauge()); | ||
| 141 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
8 | if (currentSensorResult.Valid) { | |
| 142 | 6 | const float currentValue = currentSensorResult.Value; | ||
| 143 | 6 | const float armingValue = engineConfiguration->nitrousLuaGaugeArmingValue; | ||
| 144 |
2/3✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
6 | switch (engineConfiguration->nitrousLuaGaugeMeaning) { | |
| 145 | 3 | case LUA_GAUGE_LOWER_BOUND: { | ||
| 146 | 3 | result = (armingValue <= currentValue); | ||
| 147 | 3 | break; | ||
| 148 | } | |||
| 149 | 3 | case LUA_GAUGE_UPPER_BOUND: { | ||
| 150 | 3 | result = (currentValue <= armingValue); | ||
| 151 | 3 | break; | ||
| 152 | } | |||
| 153 | } | |||
| 154 | } | |||
| 155 | 8 | return result; | ||
| 156 | } | |||
| 157 | ||||
| 158 | 8 | SensorType NitrousController::getLuaGauge() const { | ||
| 159 | 8 | SensorType result = SensorType::LuaGauge1; | ||
| 160 |
1/9✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 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.
|
8 | switch (engineConfiguration->nitrousLuaGauge) { | |
| 161 | ✗ | case LUA_GAUGE_1: { | ||
| 162 | ✗ | break; | ||
| 163 | } | |||
| 164 | ✗ | case LUA_GAUGE_2: { | ||
| 165 | ✗ | result = SensorType::LuaGauge2; | ||
| 166 | ✗ | break; | ||
| 167 | } | |||
| 168 | 8 | case LUA_GAUGE_3: { | ||
| 169 | 8 | result = SensorType::LuaGauge3; | ||
| 170 | 8 | break; | ||
| 171 | } | |||
| 172 | ✗ | case LUA_GAUGE_4: { | ||
| 173 | ✗ | result = SensorType::LuaGauge4; | ||
| 174 | ✗ | break; | ||
| 175 | } | |||
| 176 | ✗ | case LUA_GAUGE_5: { | ||
| 177 | ✗ | result = SensorType::LuaGauge5; | ||
| 178 | ✗ | break; | ||
| 179 | } | |||
| 180 | ✗ | case LUA_GAUGE_6: { | ||
| 181 | ✗ | result = SensorType::LuaGauge6; | ||
| 182 | ✗ | break; | ||
| 183 | } | |||
| 184 | ✗ | case LUA_GAUGE_7: { | ||
| 185 | ✗ | result = SensorType::LuaGauge7; | ||
| 186 | ✗ | break; | ||
| 187 | } | |||
| 188 | ✗ | case LUA_GAUGE_8: { | ||
| 189 | ✗ | result = SensorType::LuaGauge8; | ||
| 190 | ✗ | break; | ||
| 191 | } | |||
| 192 | } | |||
| 193 | 8 | return result; | ||
| 194 | } | |||
| 195 | ||||
| 196 | #endif // EFI_LAUNCH_CONTROL | |||
| 197 |