GCC Code Coverage Report


Directory: ./
File: firmware/controllers/start_stop.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 80.0% 44 0 55
Functions: 100.0% 6 0 6
Branches: 52.4% 22 0 42
Decisions: 56.2% 18 - 32

Line Branch Decision Exec Source
1 #include "pch.h"
2
3 /**
4 * See test_start_stop.cpp
5 */
6
7 #include "start_stop.h"
8 #include "ignition_controller.h"
9
10 #if EFI_SHAFT_POSITION_INPUT
11 802 void initStartStopButton() {
12 /* startCrankingDuration is efitimesec_t, so we need to multiply it by 1000 to get milliseconds*/
13 802 engine->startStopState.startStopButtonDebounce.init((engineConfiguration->startCrankingDuration*1000),
14 802 engineConfiguration->startStopButtonPin,
15 802 engineConfiguration->startStopButtonMode,
16 802 engineConfiguration->startRequestPinInverted);
17 802 }
18
19 1 void doStartCranking() {
20 1 bool wasStarterEngaged = enginePins.starterControl.getAndSet(1);
21
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if (!wasStarterEngaged) {
22 1 engine->startStopState.startStopStateLastPush.reset();
23 1 efiPrintf("Let's crank this engine for up to %d seconds via %s!",
24 engineConfiguration->startCrankingDuration,
25 hwPortname(engineConfiguration->starterControlPin));
26 }
27 1 }
28
29 1 void startStopButtonToggle() {
30 1 engine->engineState.startStopStateToggleCounter++;
31
32
1/2
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if (engine->rpmCalculator.isStopped()) {
33 1 doStartCranking();
34 } else if (engine->rpmCalculator.isRunning()) {
35 doScheduleStopEngine(StopRequestedReason::StartButton);
36 }
37 1 }
38
39 2 static void disengageStarterIfNeeded() {
40
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
2 if (engine->rpmCalculator.isRunning()) {
41 // turn starter off once engine is now running!
42 bool wasStarterEngaged = enginePins.starterControl.getAndSet(0);
43 if (wasStarterEngaged) {
44 efiPrintf("Engine runs we can disengage the starter");
45 }
46 } else {
47
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 1 time.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 1 time.
2 if (engine->startStopState.startStopStateLastPush.hasElapsedSec(engineConfiguration->startCrankingDuration)) {
48 1 bool wasStarterEngaged = enginePins.starterControl.getAndSet(0);
49
1/2
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
1 if (wasStarterEngaged) {
50 1 efiPrintf("Cranking timeout %d seconds", engineConfiguration->startCrankingDuration);
51 }
52 }
53 }
54 2 }
55
56 6 PUBLIC_API_WEAK bool isCrankingSuppressed() {
57 6 return false;
58 }
59
60 6 void slowStartStopButtonCallback() {
61
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 6 times.
6 if (!isIgnVoltage()) {
62 // nothing to crank if we are powered only via USB
63 engine->startStopState.timeSinceIgnitionPower.reset();
64 return;
65
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 5 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 5 times.
6 } else if (engine->startStopState.isFirstTime) {
66 // initialize when first time with proper power
67 1 engine->startStopState.timeSinceIgnitionPower.reset();
68 1 engine->startStopState.isFirstTime = false;
69 }
70
71
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 6 times.
6 if (engine->startStopState.timeSinceIgnitionPower.getElapsedUs() < MS2US(engineConfiguration->startButtonSuppressOnStartUpMs)) {
72 // where are odd cases of start button combined with ECU power source button we do not want to crank right on start
73 return;
74 }
75
76
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
1/2
✓ Decision 'true' taken 6 times.
✗ Decision 'false' not taken.
6 if (engine->rpmCalculator.isStopped()) {
77
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 6 times.
6 if (engineConfiguration->crankingCondition == CC_BRAKE && !engine->brakePedalSwitchedState) {
78 return;
79 }
80
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 6 times.
6 if (engineConfiguration->crankingCondition == CC_CLUTCH && !engine->clutchUpSwitchedState) {
81 return;
82 }
83
84
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 6 times.
6 if (isCrankingSuppressed()) {
85 return;
86 }
87 }
88
89 6 bool startStopState = engine->startStopState.startStopButtonDebounce.readPinEvent();
90
91
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 3 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 5 times.
6 if (startStopState && !engine->engineState.startStopState) {
92 // we are here on transition from 0 to 1
93 1 startStopButtonToggle();
94 }
95 // todo: we shall extract start_stop.txt from engine_state.txt
96 6 engine->engineState.startStopState = startStopState;
97 6 engine->engineState.startStopPhysicalState = engine->startStopState.startStopButtonDebounce.getPhysicalState();
98
99 6 bool isStarterEngaged = enginePins.starterControl.getLogicValue();
100
101
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 4 times.
6 if (isStarterEngaged) {
102 2 disengageStarterIfNeeded();
103 }
104 }
105 #endif // EFI_SHAFT_POSITION_INPUT
106