GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 31 / 0 / 31
Functions: 100.0% 4 / 0 / 4
Branches: 100.0% 22 / 0 / 22
Decisions: 100.0% 14 / - / 14

firmware/controllers/engine_cycle/rotational_idle.cpp
Line Branch Decision Exec Source
1 #include "pch.h"
2 #include "rotational_idle.h"
3
4 701 RotationalIdle::RotationalIdle(){
5
6 701 }
7
8 21 bool RotationalIdle::shouldEngageRotationalIdle() {
9 21 rotationalIdleEngaged = false;
10
11
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 19 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 19 times.
21 if (!engineConfiguration->rotationalIdleController.enabled) {
12 2 return false;
13 }
14
15 //TODO: we need to use deadbands ond this!! (and on the tps/pps)
16
6/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 17 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 18 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 18 times.
19 if (engineConfiguration->rotationalIdleController.auto_engage_clt_enable && Sensor::getOrZero(SensorType::Clt) > engineConfiguration->rotationalIdleController.auto_engage_clt) {
17 1 rotationalIdleEngaged = true;
18 1 return true;
19 }
20
21 // TODO: auto_engage sounds too generic, maybe better auto_engage_pps_enable?
22
6/6
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 16 times.
✓ Branch 4 taken 1 time.
✓ Branch 5 taken 16 times.
✓ Branch 6 taken 2 times.
2/2
✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 2 times.
18 if (engineConfiguration->rotationalIdleController.auto_engage && Sensor::getOrZero(SensorType::DriverThrottleIntent) <= engineConfiguration->rotationalIdleController.max_tps) {
23 16 rotationalIdleEngaged = true;
24 16 return true; // tps is below the maximum
25 }
26
27 2 return false;
28 }
29
30 42 static bool calculateSkip(uint32_t counter, uint8_t max, uint8_t adder) {
31
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
2/2
✓ Decision 'true' taken 24 times.
✓ Decision 'false' taken 18 times.
42 if (max == 0) {
32 24 return false;
33 }
34 18 return ((counter % max) + adder) >= max;
35 }
36
37 /**
38 * Determines whether to skip spark based on rotational idle skip pattern configuration.
39 *
40 * The skip pattern works using modulo arithmetic with configurable accumulators:
41 * - Each accumulator has: acc_max (pattern period), acc_adder (phase shift), acc_offset (cylinder offset)
42 * - For each accumulator: counter = globalSparkCounter + offset + acc_offset
43 * - Skip condition: ((counter % acc_max) + acc_adder) >= acc_max
44 *
45 * Example with acc_max=2, acc_adder=1, acc_offset=0:
46 * counter=0: (0 % 2) + 1 = 1 < 2 -> fire spark
47 * counter=1: (1 % 2) + 1 = 2 >= 2 -> skip spark
48 * counter=2: (2 % 2) + 1 = 1 < 2 -> fire spark
49 * counter=3: (3 % 2) + 1 = 2 >= 2 -> skip spark
50 *
51 * If acc_max=0, that accumulator is disabled and won't skip.
52 *
53 * @return True if should skip a spark event.
54 */
55 16 bool RotationalIdle::shouldSkipSparkRotationalIdle() {
56 16 bool result = false;
57 16 auto cutMode = engineConfiguration->rotationalIdleController.cut_mode;
58
59
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 15 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 15 times.
16 if (cutMode == RotationalCutMode::Fuel) {
60 1 return false;
61 }
62
63
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 14 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 14 times.
15 if (!shouldEngageRotationalIdle()) {
64 1 rotationalIdleEngaged = false;
65 1 return false;
66 }
67
68 14 rotationalIdleEngaged = true;
69
70
71
2/2
✓ Branch 1 taken 42 times.
✓ Branch 2 taken 14 times.
2/2
✓ Decision 'true' taken 42 times.
✓ Decision 'false' taken 14 times.
56 for (size_t i = 0; i < efi::size(engineConfiguration->rotationalIdleController.accumulators); i++){
72 42 const auto& accConfig = engineConfiguration->rotationalIdleController.accumulators[i];
73
74 42 uint32_t counter = engine->engineState.globalSparkCounter + accConfig.acc_offset;
75 42 result |= calculateSkip(counter, accConfig.acc_max, accConfig.acc_adder);
76 }
77
78 14 return result;
79 }
80