GCC Code Coverage Report


Directory: ./
File: firmware/controllers/algo/shift_torque_reduction_controller.cpp
Date: 2025-10-03 00:57:22
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 1120 void ShiftTorqueReductionController::update() {
18
2/2
✓ Branch 0 taken 553 times.
✓ Branch 1 taken 567 times.
2/2
✓ Decision 'true' taken 553 times.
✓ Decision 'false' taken 567 times.
1120 if (engineConfiguration->torqueReductionEnabled) {
19 553 updateTriggerPinState();
20 553 updateTimeConditionSatisfied();
21 553 updateRpmConditionSatisfied();
22 553 updateAppConditionSatisfied();
23
24
2/2
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 9 times.
833 isFlatShiftConditionSatisfied = torqueReductionTriggerPinState && isTimeConditionSatisfied
25
6/6
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 273 times.
✓ Branch 2 taken 264 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 253 times.
833 && isRpmConditionSatisfied && isAppConditionSatisfied;
26 }
27 1120 }
28
29 1109 float ShiftTorqueReductionController::getSparkSkipRatio() const {
30 1109 float result = 0.0f;
31 1109 auto torqueReductionXAxis = readGppwmChannel(config->torqueReductionCutXaxis);
32 1109 int8_t currentGear = Sensor::getOrZero(SensorType::DetectedGear);
33
34
4/4
✓ Branch 0 taken 559 times.
✓ Branch 1 taken 550 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 548 times.
2/2
✓ Decision 'true' taken 11 times.
✓ Decision 'false' taken 1098 times.
1109 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 1109 return result;
42 }
43
44 553 void ShiftTorqueReductionController::updateTriggerPinState() {
45
4/5
✓ Branch 0 taken 220 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 138 times.
✓ Branch 3 taken 138 times.
✗ Branch 4 not taken.
553 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 220 engine->engineState.lua.torqueReductionState
51 );
52 220 break;
53 }
54
1/1
✓ Decision 'true' taken 57 times.
57 case LAUNCH_BUTTON: {
55 57 updateTriggerPinState(
56 engineConfiguration->launchActivatePin,
57 57 engineConfiguration->launchActivatePinMode,
58 false
59 );
60 57 break;
61 }
62
1/1
✓ Decision 'true' taken 138 times.
138 case TORQUE_REDUCTION_CLUTCH_DOWN_SWITCH: {
63 138 updateTriggerPinState(
64 engineConfiguration->clutchDownPin,
65 138 engineConfiguration->clutchDownPinMode,
66 138 engine->engineState.lua.clutchDownState
67 );
68 138 break;
69 }
70
1/1
✓ Decision 'true' taken 138 times.
138 case TORQUE_REDUCTION_CLUTCH_UP_SWITCH: {
71 138 updateTriggerPinState(
72 engineConfiguration->clutchUpPin,
73 138 engineConfiguration->clutchUpPinMode,
74 138 engine->engineState.lua.clutchUpState
75 );
76 138 break;
77 }
78 default: {
79 break; // we shouldn't be here!
80 }
81 }
82 553 }
83
84 285 static bool isShiftTorqueBelowTemperatureThreshold() {
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 285 times.
285 if (engineConfiguration->torqueReductionActivationTemperature == 0) {
86 return false;
87 }
88 285 return Sensor::getOrZero(SensorType::Clt) < engineConfiguration->torqueReductionActivationTemperature;
89 }
90
91 // todo: rename method since we now check temperature not just pin state
92 553 void ShiftTorqueReductionController::updateTriggerPinState(
93 const switch_input_pin_e pin,
94 const pin_input_mode_e mode,
95 const bool invalidPinState
96 ) {
97
2/2
✓ Branch 0 taken 285 times.
✓ Branch 1 taken 268 times.
2/2
✓ Decision 'true' taken 285 times.
✓ Decision 'false' taken 268 times.
553 if (!torqueReductionTriggerPinState) {
98 285 isBelowTemperatureThreshold = isShiftTorqueBelowTemperatureThreshold();
99
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 285 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 285 times.
285 if (isBelowTemperatureThreshold) {
100 // disable by not even reading control pin below threshold temperature, unless already active
101 return;
102 }
103 }
104
105 #if !EFI_SIMULATOR
106 553 isTorqueReductionTriggerPinValid = isBrainPinValid(pin);
107 553 const bool previousTorqueReductionTriggerPinState = torqueReductionTriggerPinState;
108
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 265 times.
2/2
✓ Decision 'true' taken 288 times.
✓ Decision 'false' taken 265 times.
553 if (isTorqueReductionTriggerPinValid) {
109 288 torqueReductionTriggerPinState = efiReadPin(pin, mode);
110 } else {
111 265 torqueReductionTriggerPinState = invalidPinState;
112 }
113
4/4
✓ Branch 0 taken 285 times.
✓ Branch 1 taken 268 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 249 times.
2/2
✓ Decision 'true' taken 36 times.
✓ Decision 'false' taken 517 times.
553 if (!previousTorqueReductionTriggerPinState && torqueReductionTriggerPinState) {
114 36 m_pinTriggeredTimer.reset();
115 }
116 #endif // !EFI_SIMULATOR
117 }
118
119 553 void ShiftTorqueReductionController::updateTimeConditionSatisfied() {
120 553 auto torqueReductionTimeXaxis = readGppwmChannel(config->torqueReductionTimeXaxis);
121 553 int8_t currentGear = Sensor::getOrZero(SensorType::DetectedGear);
122
123 1106 auto torqueReductionTime = interpolate3d(
124 553 config->torqueReductionTimeTable,
125 553 config->torqueReductionTimeGearBins, currentGear,
126 553 config->torqueReductionTimeXBins, torqueReductionTimeXaxis.Value
127 );
128
129 1106 isTimeConditionSatisfied = torqueReductionTriggerPinState
130
6/6
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 273 times.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 242 times.
✓ Branch 4 taken 33 times.
✓ Branch 5 taken 5 times.
586 ? !engineConfiguration->limitTorqueReductionTime ||
131 ((0.0f < torqueReductionTime)
132
2/2
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 4 times.
33 && !m_pinTriggeredTimer.hasElapsedMs(torqueReductionTime)
133 )
134 : false;
135 553 }
136
137 553 void ShiftTorqueReductionController::updateRpmConditionSatisfied() {
138 553 const float currentRpm = Sensor::getOrZero(SensorType::Rpm);
139 553 isRpmConditionSatisfied = (engineConfiguration->torqueReductionArmingRpm <= currentRpm);
140 553 }
141
142 553 void ShiftTorqueReductionController::updateAppConditionSatisfied() {
143 553 const SensorResult currentApp = Sensor::get(SensorType::DriverThrottleIntent);
144
145
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 527 times.
2/2
✓ Decision 'true' taken 26 times.
✓ Decision 'false' taken 527 times.
553 if (currentApp.Valid) {
146 26 isAppConditionSatisfied = (engineConfiguration->torqueReductionArmingApp <= currentApp.Value);
147 } else {
148 527 isAppConditionSatisfied = false;
149 }
150 553 }
151
152 11 float ShiftTorqueReductionController::getTorqueReductionIgnitionRetard() const {
153 11 auto torqueReductionXAxis = readGppwmChannel(config->torqueReductionIgnitionRetardXaxis);
154 11 int8_t currentGear = Sensor::getOrZero(SensorType::DetectedGear);
155
156 22 return interpolate3d(
157 11 config->torqueReductionIgnitionRetardTable,
158 11 config->torqueReductionIgnitionRetardGearBins, currentGear,
159 11 config->torqueReductionIgnitionRetardXBins, torqueReductionXAxis.Value
160 11 );
161 }
162
163 #endif // EFI_LAUNCH_CONTROL
164