GCC Code Coverage Report


Directory: ./
File: firmware/controllers/algo/shift_torque_reduction_controller.cpp
Date: 2025-10-24 14:26:41
Coverage Exec Excl Total
Lines: 95.5% 84 0 88
Functions: 100.0% 9 0 9
Branches: 92.7% 38 0 41
Decisions: 85.7% 18 - 21

Line Branch Decision Exec Source
1 //
2 // Created by kifir on 9/27/24.
3 //
4
5 #include "pch.h"
6
7 #if EFI_LAUNCH_CONTROL
8 #include "shift_torque_reduction_controller.h"
9 #include "boost_control.h"
10 #include "launch_control.h"
11 #include "advance_map.h"
12 #include "engine_state.h"
13 #include "advance_map.h"
14 #include "tinymt32.h"
15 #include "gppwm_channel_reader.h"
16
17 1101 void ShiftTorqueReductionController::update() {
18
2/2
✓ Branch 0 taken 529 times.
✓ Branch 1 taken 572 times.
2/2
✓ Decision 'true' taken 529 times.
✓ Decision 'false' taken 572 times.
1101 if (engineConfiguration->torqueReductionEnabled) {
19 529 updateTriggerPinState();
20 529 updateTimeConditionSatisfied();
21 529 updateRpmConditionSatisfied();
22 529 updateAppConditionSatisfied();
23
24
2/2
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 9 times.
799 isFlatShiftConditionSatisfied = torqueReductionTriggerPinState && isTimeConditionSatisfied
25
6/6
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 259 times.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 243 times.
799 && isRpmConditionSatisfied && isAppConditionSatisfied;
26 }
27 1101 }
28
29 1090 float ShiftTorqueReductionController::getSparkSkipRatio() const {
30 1090 float result = 0.0f;
31 1090 auto torqueReductionXAxis = readGppwmChannel(config->torqueReductionCutXaxis);
32 1090 int8_t currentGear = Sensor::getOrZero(SensorType::DetectedGear);
33
34
4/4
✓ Branch 0 taken 535 times.
✓ Branch 1 taken 555 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 524 times.
2/2
✓ Decision 'true' taken 11 times.
✓ Decision 'false' taken 1079 times.
1090 if (engineConfiguration->torqueReductionEnabled && isFlatShiftConditionSatisfied) {
35 11 result = interpolate3d(
36 11 config->torqueReductionIgnitionCutTable,
37 11 config->torqueReductionCutGearBins, currentGear,
38 11 config->torqueReductionCutXBins, torqueReductionXAxis.Value
39 ) / 100.0f;
40 }
41 1090 return result;
42 }
43
44 529 void ShiftTorqueReductionController::updateTriggerPinState() {
45
4/5
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 114 times.
✗ Branch 4 not taken.
529 switch (engineConfiguration->torqueReductionActivationMode) {
46
1/1
✓ Decision 'true' taken 220 times.
220 case TORQUE_REDUCTION_BUTTON: {
47 220 updateTriggerPinState(
48 engineConfiguration->torqueReductionTriggerPin,
49 220 engineConfiguration->torqueReductionTriggerPinMode,
50 /*invertPhysicalPin*/false,
51 220 engine->engineState.lua.torqueReductionState
52 );
53 220 break;
54 }
55
1/1
✓ Decision 'true' taken 57 times.
57 case LAUNCH_BUTTON: {
56 57 updateTriggerPinState(
57 engineConfiguration->launchActivatePin,
58 57 engineConfiguration->launchActivatePinMode,
59 /*invertPhysicalPin*/false,
60 false
61 );
62 57 break;
63 }
64
1/1
✓ Decision 'true' taken 138 times.
138 case TORQUE_REDUCTION_CLUTCH_DOWN_SWITCH: {
65 138 updateTriggerPinState(
66 engineConfiguration->clutchDownPin,
67 138 engineConfiguration->clutchDownPinMode,
68 /*invertPhysicalPin*/false,
69 138 engine->engineState.lua.clutchDownState
70 );
71 138 break;
72 }
73
1/1
✓ Decision 'true' taken 114 times.
114 case TORQUE_REDUCTION_CLUTCH_UP_SWITCH: {
74 114 updateTriggerPinState(
75 engineConfiguration->clutchUpPin,
76 114 engineConfiguration->clutchUpPinMode,
77 /*invertPhysicalPin*/true,
78 114 engine->engineState.lua.clutchUpState
79 );
80 114 break;
81 }
82 default: {
83 break; // we shouldn't be here!
84 }
85 }
86 529 }
87
88 272 static bool isShiftTorqueBelowTemperatureThreshold() {
89
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 272 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 272 times.
272 if (engineConfiguration->torqueReductionActivationTemperature == 0) {
90 return false;
91 }
92 272 return Sensor::getOrZero(SensorType::Clt) < engineConfiguration->torqueReductionActivationTemperature;
93 }
94
95 // todo: rename method since we now check temperature not just pin state
96 529 void ShiftTorqueReductionController::updateTriggerPinState(
97 const switch_input_pin_e pin,
98 const pin_input_mode_e mode,
99 const bool invertPhysicalPin,
100 const bool invalidPinState
101 ) {
102
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 257 times.
2/2
✓ Decision 'true' taken 272 times.
✓ Decision 'false' taken 257 times.
529 if (!torqueReductionTriggerPinState) {
103 272 isBelowTemperatureThreshold = isShiftTorqueBelowTemperatureThreshold();
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 272 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 272 times.
272 if (isBelowTemperatureThreshold) {
105 // disable by not even reading control pin below threshold temperature, unless already active
106 return;
107 }
108 }
109
110 #if !EFI_SIMULATOR
111 529 isTorqueReductionTriggerPinValid = isBrainPinValid(pin);
112 529 const bool previousTorqueReductionTriggerPinState = torqueReductionTriggerPinState;
113
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 265 times.
2/2
✓ Decision 'true' taken 264 times.
✓ Decision 'false' taken 265 times.
529 if (isTorqueReductionTriggerPinValid) {
114 264 torqueReductionTriggerPinState = efiReadPin(pin, mode) ^ invertPhysicalPin;
115 } else {
116 265 torqueReductionTriggerPinState = invalidPinState;
117 }
118
4/4
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 257 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 236 times.
2/2
✓ Decision 'true' taken 36 times.
✓ Decision 'false' taken 493 times.
529 if (!previousTorqueReductionTriggerPinState && torqueReductionTriggerPinState) {
119 36 m_pinTriggeredTimer.reset();
120 }
121 #endif // !EFI_SIMULATOR
122 }
123
124 529 void ShiftTorqueReductionController::updateTimeConditionSatisfied() {
125 529 auto torqueReductionTimeXaxis = readGppwmChannel(config->torqueReductionTimeXaxis);
126 529 int8_t currentGear = Sensor::getOrZero(SensorType::DetectedGear);
127
128 1058 auto torqueReductionTime = interpolate3d(
129 529 config->torqueReductionTimeTable,
130 529 config->torqueReductionTimeGearBins, currentGear,
131 529 config->torqueReductionTimeXBins, torqueReductionTimeXaxis.Value
132 );
133
134 1058 isTimeConditionSatisfied = torqueReductionTriggerPinState
135
6/6
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 259 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 232 times.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 5 times.
562 ? !engineConfiguration->limitTorqueReductionTime ||
136 ((0.0f < torqueReductionTime)
137
2/2
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 4 times.
33 && !m_pinTriggeredTimer.hasElapsedMs(torqueReductionTime)
138 )
139 : false;
140 529 }
141
142 529 void ShiftTorqueReductionController::updateRpmConditionSatisfied() {
143 529 const float currentRpm = Sensor::getOrZero(SensorType::Rpm);
144 529 isRpmConditionSatisfied = (engineConfiguration->torqueReductionArmingRpm <= currentRpm);
145 529 }
146
147 529 void ShiftTorqueReductionController::updateAppConditionSatisfied() {
148 529 const SensorResult currentApp = Sensor::get(SensorType::DriverThrottleIntent);
149
150
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 503 times.
2/2
✓ Decision 'true' taken 26 times.
✓ Decision 'false' taken 503 times.
529 if (currentApp.Valid) {
151 26 isAppConditionSatisfied = (engineConfiguration->torqueReductionArmingApp <= currentApp.Value);
152 } else {
153 503 isAppConditionSatisfied = false;
154 }
155 529 }
156
157 11 float ShiftTorqueReductionController::getTorqueReductionIgnitionRetard() const {
158 11 auto torqueReductionXAxis = readGppwmChannel(config->torqueReductionIgnitionRetardXaxis);
159 11 int8_t currentGear = Sensor::getOrZero(SensorType::DetectedGear);
160
161 22 return interpolate3d(
162 11 config->torqueReductionIgnitionRetardTable,
163 11 config->torqueReductionIgnitionRetardGearBins, currentGear,
164 11 config->torqueReductionIgnitionRetardXBins, torqueReductionXAxis.Value
165 11 );
166 }
167
168 #endif // EFI_LAUNCH_CONTROL
169