GCC Code Coverage Report


Directory: ./
File: firmware/controllers/algo/defaults/default_ignition.cpp
Date: 2025-11-16 14:52:24
Coverage Exec Excl Total
Lines: 95.8% 69 0 72
Functions: 100.0% 8 0 8
Branches: 90.9% 20 0 22
Decisions: 90.0% 18 - 20

Line Branch Decision Exec Source
1 #include "pch.h"
2
3 #include "defaults.h"
4 #include "table_helper.h"
5
6 #if EFI_ENGINE_CONTROL
7 593 static void setDefaultMultisparkParameters() {
8 // 1ms spark + 2ms dwell
9 593 engineConfiguration->multisparkSparkDuration = 1;
10 593 engineConfiguration->multisparkDwell = 2;
11
12 // Conservative defaults - probably won't blow up coils
13 593 engineConfiguration->multisparkMaxRpm = 1500;
14 593 engineConfiguration->multisparkMaxExtraSparkCount = 2;
15 593 engineConfiguration->multisparkMaxSparkingAngle = 30;
16 593 }
17
18 593 static void setDefaultIatTimingCorrection() {
19 593 setLinearCurve(config->ignitionIatCorrLoadBins, /*from=*/ 0, /*to*/ 140, 1);
20 #if IAT_IGN_CORR_COUNT == 8
21 593 copyArray(config->ignitionIatCorrTempBins, { -40, 0, 10, 20, 30, 40, 50, 60});
22
23 // top 5 rows are the same
24
2/2
✓ Branch 0 taken 2965 times.
✓ Branch 1 taken 593 times.
2/2
✓ Decision 'true' taken 2965 times.
✓ Decision 'false' taken 593 times.
3558 for (size_t i = 3; i < IAT_IGN_CORR_COUNT; i++) {
25 // 40 50 60 deg C
26 2965 copyArray(config->ignitionIatCorrTable[i], {0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -2.0, -3.0});
27 }
28
29 // 6th row tapers out
30 // 40 50 60 deg C
31 593 copyArray(config->ignitionIatCorrTable[2], {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -2.0});
32 #else
33 setLinearCurve(config->ignitionIatCorrTempBins, /*from=*/ -40, /*to*/ 60, 1);
34 #endif
35 593 }
36
37 593 static void setDefaultCltTimingCorrection() {
38 593 setLinearCurve(config->ignitionCltCorrLoadBins, /*from=*/ 0, /*to*/ 140, 1);
39 593 setLinearCurve(config->ignitionCltCorrTempBins, -20, 60, 1);
40
41 #if CLT_TIMING_TEMP_AXIS_SIZE == 5
42
2/2
✓ Branch 0 taken 2965 times.
✓ Branch 1 taken 593 times.
2/2
✓ Decision 'true' taken 2965 times.
✓ Decision 'false' taken 593 times.
3558 for (size_t i = 0; i < CLT_TIMING_TEMP_AXIS_SIZE; i++) {
43 // huh? use setArrayValues? and we probably get all zeros by default anyway?
44 2965 copyArray(config->ignitionCltCorrTable[i], {0.0, 0.0, 0.0, 0.0, 0.0});
45 }
46 #endif
47 593 }
48
49 593 static void setDefaultTrailingSparkTable() {
50 593 setLinearCurve(config->trailingSparkLoadBins, 20, 100, 1);
51 593 setRpmTableBin(config->trailingSparkRpmBins);
52
53 #if TRAILING_SPARK_SIZE == 4
54
2/2
✓ Branch 0 taken 2372 times.
✓ Branch 1 taken 593 times.
2/2
✓ Decision 'true' taken 2372 times.
✓ Decision 'false' taken 593 times.
2965 for (size_t i = 0; i < TRAILING_SPARK_SIZE; i++) {
55
1/1
✓ Branch 3 taken 2372 times.
2372 copyArray(config->trailingSparkTable[i], {7,9,10,12});
56 }
57 #endif
58
59 593 }
60
61 151813 static float getAdvanceForRpm(float rpm, float advanceMax) {
62
2/2
✓ Branch 0 taken 66418 times.
✓ Branch 1 taken 85395 times.
2/2
✓ Decision 'true' taken 66418 times.
✓ Decision 'false' taken 85395 times.
151813 if (rpm >= 3000) {
63 66418 return advanceMax;
64 }
65
66
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 85395 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 85395 times.
85395 if (rpm < 600) {
67 return 10;
68 }
69
70 85395 return interpolateMsg("advance", 600, 10, 3000, advanceMax, rpm);
71 }
72
73 #define round10(x) efiRound(x, 0.1)
74
75 151813 float getInitialAdvance(float rpm, float map, float advanceMax) {
76 151813 map = std::min(map, 100.0f);
77 151813 float advance = getAdvanceForRpm(rpm, advanceMax);
78
79
2/2
✓ Branch 0 taken 66418 times.
✓ Branch 1 taken 85395 times.
2/2
✓ Decision 'true' taken 66418 times.
✓ Decision 'false' taken 85395 times.
151813 if (rpm >= 3000)
80 66418 return round10(advance + 0.1 * (100 - map));
81 85395 return round10(advance + 0.1 * (100 - map) * rpm / 3000);
82 }
83
84 /**
85 * this method builds a good-enough base timing advance map bases on a number of heuristics
86 */
87 593 static void buildTimingMap(float advanceMax) {
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 593 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 593 times.
593 if (engineConfiguration->fuelAlgorithm != engine_load_mode_e::LM_SPEED_DENSITY) {
89 warning(ObdCode::CUSTOM_WRONG_ALGORITHM, "wrong algorithm for MAP-based timing");
90 return;
91 }
92 /**
93 * good enough (but do not trust us!) default timing map in case of MAP-based engine load
94 */
95
2/2
✓ Branch 0 taken 9488 times.
✓ Branch 1 taken 593 times.
2/2
✓ Decision 'true' taken 9488 times.
✓ Decision 'false' taken 593 times.
10081 for (int loadIndex = 0; loadIndex < IGN_LOAD_COUNT; loadIndex++) {
96 9488 float load = config->ignitionLoadBins[loadIndex];
97
2/2
✓ Branch 0 taken 151808 times.
✓ Branch 1 taken 9488 times.
2/2
✓ Decision 'true' taken 151808 times.
✓ Decision 'false' taken 9488 times.
161296 for (int rpmIndex = 0;rpmIndex<IGN_RPM_COUNT;rpmIndex++) {
98 151808 float rpm = config->ignitionRpmBins[rpmIndex];
99
1/1
✓ Branch 2 taken 151808 times.
151808 config->ignitionTable[loadIndex][rpmIndex] = getInitialAdvance(rpm, load, advanceMax);
100 }
101 }
102 }
103
104 593 void setDefaultIgnition() {
105 // Ignition base settings
106 593 engineConfiguration->isIgnitionEnabled = true;
107
108 593 engineConfiguration->timingMode = TM_DYNAMIC;
109 593 engineConfiguration->fixedModeTiming = 50;
110
111 593 engineConfiguration->minimumIgnitionTiming = -10;
112 593 engineConfiguration->maximumIgnitionTiming = 60;
113
114 // Dwell table - a bit conservative but reasonable
115 593 setConstantDwell(4);
116
117 593 setLinearCurve(config->dwellVoltageCorrVoltBins, 8, 15, 0.1);
118 593 setLinearCurve(config->dwellVoltageCorrValues, 1, 1, 1);
119
120 // Multispark
121 593 setDefaultMultisparkParameters();
122
123 // Ignition advance table
124 593 setLinearCurve(config->ignitionLoadBins, 20, 120, 3);
125 593 setTimingRpmBin(800, 7000);
126 593 buildTimingMap(35);
127
128 593 setDefaultTrailingSparkTable();
129
130 // CLT correction
131 593 setDefaultCltTimingCorrection();
132
133 // IAT correction
134 593 setDefaultIatTimingCorrection();
135
136 // Give default axes for cylinder trim tables
137 #if IGN_TRIM_SIZE == 4
138 593 copyArray(config->ignTrimRpmBins, { 1000, 3000, 5000, 7000 });
139 593 copyArray(config->ignTrimLoadBins, { 20, 50, 80, 100 });
140 #else
141 setRpmTableBin(config->ignTrimRpmBins);
142 setLinearCurve(config->ignTrimLoadBins, 20, 100);
143 #endif
144
145 // Default axes for VE blends
146
2/2
✓ Branch 1 taken 2372 times.
✓ Branch 2 taken 593 times.
2/2
✓ Decision 'true' taken 2372 times.
✓ Decision 'false' taken 593 times.
2965 for (size_t i = 0; i < efi::size(config->ignBlends); i++) {
147 2372 auto& blend = config->ignBlends[i];
148 2372 setLinearCurve(blend.loadBins, 0, 100, 10);
149 2372 setLinearCurve(blend.rpmBins, 0, 7000);
150
151 2372 setLinearCurve(blend.blendBins, 0, 100);
152 2372 setLinearCurve(blend.blendValues, 0, 100);
153 }
154 593 }
155 #endif // EFI_ENGINE_CONTROL
156