GCC Code Coverage Report


Directory: ./
File: firmware/controllers/actuators/boost_control.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 96.7% 174 0 180
Functions: 100.0% 18 0 18
Branches: 81.4% 83 0 102
Decisions: 87.5% 42 - 48

Line Branch Decision Exec Source
1 /*
2 * boost_control.cpp
3 *
4 * Created on: 13. des. 2019
5 * Author: Ola Ruud
6 */
7 #include "pch.h"
8
9 #if EFI_BOOST_CONTROL
10
11 #include "boost_control.h"
12 #include "electronic_throttle.h"
13 #include "gppwm_channel_reader.h"
14
15 #if defined(HAS_OS_ACCESS)
16 #error "Unexpected OS ACCESS HERE"
17 #endif
18
19 namespace {
20 Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, uint16_t> boostMapOpen{"bo"};
21 Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, uint16_t> boostMapClosed{"bc"};
22 Map2D<BOOST_CURVE_SIZE, float, float> boostCltCorr { "clt" };
23 Map2D<BOOST_CURVE_SIZE, float, float> boostIatCorr { "iat" };
24 Map2D<BOOST_CURVE_SIZE, float, float> boostCltAdder { "clt (adder)" };
25 Map2D<BOOST_CURVE_SIZE, float, float> boostIatAdder { "iat (adder)" };
26 SimplePwm boostPwmControl("boost");
27 }
28
29 607 void BoostController::init(
30 IPwm* const pwm,
31 const ValueProvider3D* const openLoopMap,
32 const ValueProvider3D* const closedLoopTargetMap,
33 const ValueProvider2D& cltMultiplierProvider,
34 const ValueProvider2D& iatMultiplierProvider,
35 const ValueProvider2D& cltAdderProvider,
36 const ValueProvider2D& iatAdderProvider,
37 pid_s* const pidParams
38 ) {
39 607 m_pwm = pwm;
40 607 m_openLoopMap = openLoopMap;
41 607 m_closedLoopTargetMap = closedLoopTargetMap;
42 607 m_cltBoostCorrMap = &cltMultiplierProvider;
43 607 m_iatBoostCorrMap = &iatMultiplierProvider;
44 607 m_cltBoostAdderMap = &cltAdderProvider;
45 607 m_iatBoostAdderMap = &iatAdderProvider;
46
47 607 m_pid.initPidClass(pidParams);
48 607 resetLua();
49
50 607 hasInitBoost = true;
51 607 }
52
53 607 void BoostController::resetLua() {
54 607 luaTargetAdd = 0;
55 607 luaTargetMult = 1;
56 607 luaOpenLoopAdd = 0;
57 607 }
58
59 219 void BoostController::onConfigurationChange(engine_configuration_s const * previousConfig) {
60 #if EFI_PROD_CODE
61 initBoostCtrl();
62 #endif
63
64
3/6
✓ Branch 0 taken 219 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 219 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 219 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 219 times.
219 if (!previousConfig || !m_pid.isSame(&previousConfig->boostPid)) {
65 m_shouldResetPid = true;
66 }
67 219 }
68
69 2 expected<float> BoostController::observePlant() {
70
1/1
✓ Branch 2 taken 2 times.
2 expected<float> map = Sensor::get(SensorType::Map);
71
3/4
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
2 if (!map.Valid && engineConfiguration->boostType != CLOSED_LOOP) {
72 // if we're in open loop only let's somewhat operate even without valid Map sensor
73 map = 0;
74 }
75 2 isPlantValid = map.Valid;
76 2 return map;
77 }
78
79 36 expected<float> BoostController::getSetpoint() {
80 // If we're in open loop only mode, disregard any target computation.
81 // Open loop needs to work even in case of invalid closed loop config
82 36 isNotClosedLoop = engineConfiguration->boostType != CLOSED_LOOP;
83
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 35 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 35 times.
36 if (isNotClosedLoop) {
84 1 boostControllerClosedLoopPart = 0;
85 1 return (float)boostControllerClosedLoopPart;
86 }
87
88
1/1
✓ Branch 1 taken 35 times.
35 float rpm = Sensor::getOrZero(SensorType::Rpm);
89
90
1/1
✓ Branch 1 taken 35 times.
35 auto driverIntent = Sensor::get(SensorType::DriverThrottleIntent);
91 35 isTpsInvalid = !driverIntent.Valid;
92
93
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 33 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 33 times.
35 if (isTpsInvalid) {
94 2 return unexpected;
95 }
96
97
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
✗ Branch 3 not taken.
33 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_closedLoopTargetMap != nullptr, "boost closed loop target", unexpected);
98
99
1/1
✓ Branch 2 taken 33 times.
33 float target = m_closedLoopTargetMap->getValue(rpm, driverIntent.Value);
100 #if EFI_ENGINE_CONTROL
101 // Add any blends if configured
102
2/2
✓ Branch 1 taken 66 times.
✓ Branch 2 taken 33 times.
2/2
✓ Decision 'true' taken 66 times.
✓ Decision 'false' taken 33 times.
99 for (size_t i = 0; i < efi::size(config->boostClosedLoopBlends); i++) {
103
1/1
✓ Branch 2 taken 66 times.
66 auto result = calculateBlend(config->boostClosedLoopBlends[i], rpm, driverIntent.Value);
104
105 66 engine->outputChannels.boostClosedLoopBlendParameter[i] = result.BlendParameter;
106 66 engine->outputChannels.boostClosedLoopBlendBias[i] = result.Bias;
107 66 engine->outputChannels.boostClosedLoopBlendOutput[i] = result.Value;
108 66 engine->outputChannels.boostClosedLoopBlendYAxis[i] = result.TableYAxis;
109
110 66 target += result.Value;
111 }
112 #endif //EFI_ENGINE_CONTROL
113
114 33 target *= luaTargetMult;
115 33 target += luaTargetAdd;
116
1/1
✓ Branch 2 taken 33 times.
33 const std::optional<float> temperatureAdder = getBoostControlTargetTemperatureAdder();
117
2/2
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 2 times.
2/2
✓ Decision 'true' taken 31 times.
✓ Decision 'false' taken 2 times.
33 if (temperatureAdder.has_value()) {
118
1/1
✓ Branch 1 taken 31 times.
31 target += temperatureAdder.value();
119 }
120 33 return target;
121 }
122
123 64 expected<percent_t> BoostController::getOpenLoop(float target) {
124 // Boost control open loop doesn't care about target - only TPS/RPM
125 UNUSED(target);
126
127
1/1
✓ Branch 1 taken 64 times.
64 float rpm = Sensor::getOrZero(SensorType::Rpm);
128
1/1
✓ Branch 1 taken 64 times.
64 auto driverIntent = readGppwmChannel(engineConfiguration->boostOpenLoopYAxis);
129
130 64 isTpsInvalid = !driverIntent.Valid;
131
132
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 63 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 63 times.
64 if (isTpsInvalid) {
133 1 return unexpected;
134 }
135
136
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
63 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_openLoopMap != nullptr, "boost open loop", unexpected);
137
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
63 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_cltBoostCorrMap != nullptr, "boost CLT multiplier", unexpected);
138
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 63 times.
✗ Branch 3 not taken.
63 efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_iatBoostCorrMap != nullptr, "boost IAT multiplier", unexpected);
139
140
1/1
✓ Branch 2 taken 63 times.
63 percent_t openLoop = luaOpenLoopAdd + getBoostControlDutyCycleWithTemperatureCorrections(rpm, driverIntent.Value);
141 63 openLoopYAxis = driverIntent.Value;
142
143 #if EFI_ENGINE_CONTROL
144 // Add any blends if configured
145
2/2
✓ Branch 1 taken 126 times.
✓ Branch 2 taken 63 times.
2/2
✓ Decision 'true' taken 126 times.
✓ Decision 'false' taken 63 times.
189 for (size_t i = 0; i < efi::size(config->boostOpenLoopBlends); i++) {
146
1/1
✓ Branch 2 taken 126 times.
126 auto result = calculateBlend(config->boostOpenLoopBlends[i], rpm, driverIntent.Value);
147
148 126 engine->outputChannels.boostOpenLoopBlendParameter[i] = result.BlendParameter;
149 126 engine->outputChannels.boostOpenLoopBlendBias[i] = result.Bias;
150 126 engine->outputChannels.boostOpenLoopBlendOutput[i] = result.Value;
151 126 engine->outputChannels.boostOpenLoopBlendYAxis[i] = result.TableYAxis;
152
153 126 openLoop += result.Value;
154 }
155 #endif // EFI_ENGINE_CONTROL
156
157 // Add gear-based adder
158
1/1
✓ Branch 1 taken 63 times.
63 auto gear = Sensor::getOrZero(SensorType::DetectedGear);
159 63 float gearAdder = engineConfiguration->gearBasedOpenLoopBoostAdder[static_cast<int>(gear) + 1];
160 63 openLoop += gearAdder;
161
162 63 openLoopPart = openLoop;
163 63 return openLoop;
164 }
165
166 10 percent_t BoostController::getClosedLoopImpl(float target, float manifoldPressure) {
167 // If we're in open loop only mode, make no closed loop correction.
168 10 isNotClosedLoop = engineConfiguration->boostType != CLOSED_LOOP;
169
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
2/2
✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 8 times.
10 if (isNotClosedLoop) {
170 2 return 0;
171 }
172
173 // Reset PID if requested
174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 8 times.
8 if (m_shouldResetPid) {
175 m_pid.reset();
176 m_shouldResetPid = false;
177 }
178
179 // If the engine isn't running, don't correct.
180 8 isZeroRpm = Sensor::getOrZero(SensorType::Rpm) == 0;
181
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
2/2
✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 4 times.
8 if (isZeroRpm) {
182 4 m_pid.reset();
183 4 return 0;
184 }
185
186 4 isBelowClosedLoopThreshold = manifoldPressure < engineConfiguration->minimumBoostClosedLoopMap;
187
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 3 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 3 times.
4 if (isBelowClosedLoopThreshold) {
188 // We're below the CL threshold, inhibit CL for now
189 1 m_pid.reset();
190 1 return 0;
191 }
192
193 3 return m_pid.getOutput(target, manifoldPressure, FAST_CALLBACK_PERIOD_MS / 1000.0f);
194 }
195
196 63 float BoostController::getBoostControlDutyCycleWithTemperatureCorrections(
197 const float rpm,
198 const float driverIntent
199 ) const {
200
1/1
✓ Branch 1 taken 63 times.
63 float result = m_openLoopMap->getValue(rpm, driverIntent);
201
1/1
✓ Branch 2 taken 63 times.
63 std::optional<float> cltBoostMultiplier = getBoostTemperatureCorrection(SensorType::Clt, *m_cltBoostCorrMap);
202
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 7 times.
2/2
✓ Decision 'true' taken 56 times.
✓ Decision 'false' taken 7 times.
63 if (cltBoostMultiplier.has_value()) {
203
1/1
✓ Branch 1 taken 56 times.
56 result *= cltBoostMultiplier.value();
204 }
205
1/1
✓ Branch 2 taken 63 times.
63 std::optional<float> iatBoostMultiplier = getBoostTemperatureCorrection(SensorType::Iat, *m_iatBoostCorrMap);
206
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 7 times.
2/2
✓ Decision 'true' taken 56 times.
✓ Decision 'false' taken 7 times.
63 if (iatBoostMultiplier.has_value()) {
207
1/1
✓ Branch 1 taken 56 times.
56 result *= iatBoostMultiplier.value();
208 }
209 126 return result;
210 }
211
212 33 std::optional<float> BoostController::getBoostControlTargetTemperatureAdder() const {
213
1/1
✓ Branch 2 taken 33 times.
33 std::optional<float> result = getBoostTemperatureCorrection(SensorType::Clt, *m_cltBoostAdderMap);
214
1/1
✓ Branch 2 taken 33 times.
33 const std::optional<float> iatBoostAdder = getBoostTemperatureCorrection(SensorType::Iat, *m_iatBoostAdderMap);
215
2/2
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 7 times.
2/2
✓ Decision 'true' taken 26 times.
✓ Decision 'false' taken 7 times.
33 if (iatBoostAdder.has_value()) {
216
2/2
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 5 times.
2/2
✓ Decision 'true' taken 21 times.
✓ Decision 'false' taken 5 times.
26 if (result.has_value()) {
217
2/2
✓ Branch 1 taken 21 times.
✓ Branch 4 taken 21 times.
21 result.value() += iatBoostAdder.value();
218 } else {
219 5 result = iatBoostAdder;
220 }
221 }
222 66 return result;
223 }
224
225 192 std::optional<float> BoostController::getBoostTemperatureCorrection(
226 const SensorType sensorType,
227 const ValueProvider2D& correctionCurve
228 ) const {
229 192 const SensorResult temperature = Sensor::get(sensorType);
230
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 28 times.
2/2
✓ Decision 'true' taken 164 times.
✓ Decision 'false' taken 28 times.
192 if (temperature.Valid) {
231
1/1
✓ Branch 2 taken 164 times.
164 const std::optional<float> boostCorrection = correctionCurve.getValue(temperature.Value);
232
1/2
✓ Branch 1 taken 164 times.
✗ Branch 2 not taken.
1/2
✓ Decision 'true' taken 164 times.
✗ Decision 'false' not taken.
164 if (boostCorrection.has_value()) {
233
1/1
✓ Branch 1 taken 164 times.
164 return std::make_optional<float>(boostCorrection.value());
234 }
235 }
236 28 return {};
237 }
238
239
240 10 expected<percent_t> BoostController::getClosedLoop(float target, float manifoldPressure) {
241
1/1
✓ Branch 2 taken 10 times.
10 boostControllerClosedLoopPart = getClosedLoopImpl(target, manifoldPressure);
242
243 10 m_pid.postState(engine->outputChannels.boostStatus);
244
245 10 boostControlTarget = target;
246
247 10 return (float)boostControllerClosedLoopPart;
248 }
249
250 1122 bool isBoostControlSolenoidMode() {
251 1122 return isBrainPinValid(engineConfiguration->boostControlPin);
252 }
253
254 1124 void BoostController::setOutput(expected<float> output) {
255 // this clamping is just for happier gauge #6339
256
1/1
✓ Branch 3 taken 1124 times.
1124 boostOutput = clampPercentValue(output.value_or(engineConfiguration->boostControlSafeDutyCycle));
257
258
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 4 times.
2/2
✓ Decision 'true' taken 1120 times.
✓ Decision 'false' taken 4 times.
1124 if (!engineConfiguration->isBoostControlEnabled) {
259 // If not enabled, force 0% output
260 1120 boostOutput = 0;
261 }
262
263 1124 float duty = PERCENT_TO_DUTY(boostOutput);
264
265
6/6
✓ Branch 0 taken 1122 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 1121 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 1123 times.
2/2
✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 1123 times.
1124 if (m_pwm && isBoostControlSolenoidMode()) {
266 1 m_pwm->setSimplePwmDutyCycle(duty);
267 } else {
268 #if EFI_ELECTRONIC_THROTTLE_BODY
269 // inject wastegate position into DC controllers, pretty weird workflow to be honest
270 // todo: should it be DC controller pulling?
271 1123 setEtbWastegatePosition(boostOutput);
272 #endif // EFI_ELECTRONIC_THROTTLE_BODY
273 }
274 1124 }
275
276 1120 void BoostController::onFastCallback() {
277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1120 times.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 1120 times.
1120 if (!hasInitBoost) {
278 return;
279 }
280
281 1120 m_pid.iTermMin = -20;
282 1120 m_pid.iTermMax = 20;
283
284 1120 rpmTooLow = Sensor::getOrZero(SensorType::Rpm) < engineConfiguration->boostControlMinRpm;
285 1120 tpsTooLow = Sensor::getOrZero(SensorType::Tps1) < engineConfiguration->boostControlMinTps;
286 1120 mapTooLow = Sensor::getOrZero(SensorType::Map) < engineConfiguration->boostControlMinMap;
287
288
3/6
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 912 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 208 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1120 isBoostControlled = !(rpmTooLow || tpsTooLow || mapTooLow);
289
290
1/2
✓ Branch 0 taken 1120 times.
✗ Branch 1 not taken.
1/2
✓ Decision 'true' taken 1120 times.
✗ Decision 'false' not taken.
1120 if (!isBoostControlled) {
291 // Passing unexpected will use the safe duty cycle configured by the user
292
1/1
✓ Branch 3 taken 1120 times.
1120 setOutput(unexpected);
293 } else {
294 ClosedLoopController::update();
295 }
296 }
297
298 586 void setDefaultBoostParameters() {
299 586 engineConfiguration->boostPwmFrequency = 33;
300 586 engineConfiguration->boostPid.offset = 0;
301 586 engineConfiguration->boostPid.pFactor = 0.5;
302 586 engineConfiguration->boostPid.iFactor = 0.3;
303 586 engineConfiguration->boostPid.maxValue = 20;
304 586 engineConfiguration->boostPid.minValue = -20;
305 586 engineConfiguration->boostControlPinMode = OM_DEFAULT;
306
307 586 setRpmTableBin(config->boostRpmBins);
308 586 setLinearCurve(config->boostOpenLoopLoadBins, 0, 100, 1);
309 586 setLinearCurve(config->boostClosedLoopLoadBins, 0, 100, 1);
310
311
2/2
✓ Branch 0 taken 4688 times.
✓ Branch 1 taken 586 times.
2/2
✓ Decision 'true' taken 4688 times.
✓ Decision 'false' taken 586 times.
5274 for (int loadIndex = 0; loadIndex < BOOST_LOAD_COUNT; loadIndex++) {
312
2/2
✓ Branch 0 taken 37504 times.
✓ Branch 1 taken 4688 times.
2/2
✓ Decision 'true' taken 37504 times.
✓ Decision 'false' taken 4688 times.
42192 for (int rpmIndex = 0; rpmIndex < BOOST_RPM_COUNT; rpmIndex++) {
313 37504 config->boostTableClosedLoop[loadIndex][rpmIndex] = (float)config->boostClosedLoopLoadBins[loadIndex];
314 }
315 }
316
317 // Defaults for ETB-style wastegate actuator
318 586 engineConfiguration->etbWastegatePid.pFactor = 1;
319 586 engineConfiguration->etbWastegatePid.minValue = -60;
320 586 engineConfiguration->etbWastegatePid.maxValue = 60;
321 586 }
322
323 219 void startBoostPin() {
324 #if !EFI_UNIT_TEST
325 // Only init if a pin is set, no need to start PWM without a pin
326 if (!engineConfiguration->isBoostControlEnabled || !isBrainPinValid(engineConfiguration->boostControlPin)) {
327 return;
328 }
329
330 startSimplePwm(
331 &boostPwmControl,
332 "Boost",
333 &engine->scheduler,
334 &enginePins.boostPin,
335 engineConfiguration->boostPwmFrequency,
336 /*dutyCycle*/0
337 );
338 #endif /* EFI_UNIT_TEST */
339 219 }
340
341 600 void initBoostCtrl() {
342 #if EFI_PROD_CODE
343 if (engine->module<BoostController>().unmock().hasInitBoost) {
344 // already initialized - nothing to do here
345 return;
346 }
347 // todo: why do we have 'isBoostControlEnabled' setting exactly?
348 // 'initVvtActuators' is an example of a subsystem without explicit enable
349 if (!engineConfiguration->isBoostControlEnabled) {
350 return;
351 }
352
353 bool hasAnyEtbWastegate = false;
354
355 for (size_t i = 0; i < efi::size(engineConfiguration->etbFunctions); i++) {
356 hasAnyEtbWastegate |= engineConfiguration->etbFunctions[i] == DC_Wastegate;
357 }
358
359 // If we have neither a boost PWM pin nor ETB wastegate, nothing more to do
360 if (!isBrainPinValid(engineConfiguration->boostControlPin) && !hasAnyEtbWastegate) {
361 return;
362 }
363 #endif
364
365 // Set up open & closed loop tables
366 600 boostMapOpen.initTable(config->boostTableOpenLoop, config->boostRpmBins, config->boostOpenLoopLoadBins);
367 600 boostMapClosed.initTable(config->boostTableClosedLoop, config->boostRpmBins, config->boostClosedLoopLoadBins);
368 600 boostCltCorr.initTable(config->cltBoostCorr, config->cltBoostCorrBins);
369 600 boostIatCorr.initTable(config->iatBoostCorr, config->iatBoostCorrBins);
370 600 boostCltAdder.initTable(config->cltBoostAdder, config->cltBoostAdderBins);
371 600 boostIatAdder.initTable(config->iatBoostAdder, config->iatBoostAdderBins);
372
373 // Set up boost controller instance
374 600 engine->module<BoostController>().unmock().init(
375 &boostPwmControl,
376 &boostMapOpen,
377 &boostMapClosed,
378 boostCltCorr,
379 boostIatCorr,
380 boostCltAdder,
381 boostIatAdder,
382 600 &engineConfiguration->boostPid
383 );
384
385 #if !EFI_UNIT_TEST
386 startBoostPin();
387 #endif
388 600 }
389
390 586 void BoostController::setDefaultConfiguration(){
391 586 engineConfiguration->boostCutPressure = 300;
392 586 engineConfiguration->boostCutPressureHyst = 20;
393 586 engineConfiguration->boostControlMinRpm = 2000;
394 586 engineConfiguration->boostControlMinTps = 30;
395 586 engineConfiguration->boostControlMinMap = 110;
396 586 }
397
398 #endif // EFI_BOOST_CONTROL
399