GCC Code Coverage Report


Directory: ./
File: firmware/controllers/algo/nitrous_controller.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 80.6% 100 0 124
Functions: 100.0% 12 0 12
Branches: 84.5% 60 0 71
Decisions: 90.5% 19 - 21

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 1085 void NitrousController::onSlowCallback() {
11
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 869 times.
2/2
✓ Decision 'true' taken 216 times.
✓ Decision 'false' taken 869 times.
1085 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 869 isNitrousCondition = false;
25 }
26 1085 enginePins.nitrousRelay.setValue(isNitrousCondition);
27 1085 }
28
29 986 float NitrousController::getFuelCoefficient() const {
30 986 float result = 1.0f;
31
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 974 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 8 times.
2/2
✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 982 times.
986 if (engineConfiguration->nitrousControlEnabled && isNitrousCondition) {
32 4 result += engineConfiguration->nitrousFuelAdderPercent / 100.0f;
33 }
34 986 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