Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | /** | |||
2 | * @file engine_configuration.cpp | |||
3 | * @brief Utility method related to the engine configuration data structure. | |||
4 | * | |||
5 | * @date Nov 22, 2013 | |||
6 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
7 | * | |||
8 | * This file is part of rusEfi - see http://rusefi.com | |||
9 | * | |||
10 | * rusEfi is free software; you can redistribute it and/or modify it under the terms of | |||
11 | * the GNU General Public License as published by the Free Software Foundation; either | |||
12 | * version 3 of the License, or (at your option) any later version. | |||
13 | * | |||
14 | * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without | |||
15 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
16 | * GNU General Public License for more details. | |||
17 | * | |||
18 | * You should have received a copy of the GNU General Public License along with this program. | |||
19 | * If not, see <http://www.gnu.org/licenses/>. | |||
20 | * | |||
21 | */ | |||
22 | ||||
23 | #include "pch.h" | |||
24 | #include "transition_events.h" | |||
25 | #include "speed_density.h" | |||
26 | #include "flash_main.h" | |||
27 | ||||
28 | #include "bench_test.h" | |||
29 | ||||
30 | #if EFI_ONBOARD_MEMS | |||
31 | #include "accelerometer.h" | |||
32 | #endif // EFI_ONBOARD_MEMS | |||
33 | ||||
34 | #include "defaults.h" | |||
35 | ||||
36 | #include "custom_engine.h" | |||
37 | ||||
38 | #include "boost_control.h" | |||
39 | #include "engine_configuration_defaults.h" | |||
40 | #if EFI_IDLE_CONTROL | |||
41 | #include "idle_thread.h" | |||
42 | #endif /* EFI_IDLE_CONTROL */ | |||
43 | ||||
44 | #if EFI_ALTERNATOR_CONTROL | |||
45 | #include "alternator_controller.h" | |||
46 | #endif | |||
47 | ||||
48 | #if EFI_ELECTRONIC_THROTTLE_BODY | |||
49 | #include "electronic_throttle.h" | |||
50 | #endif | |||
51 | ||||
52 | #include "hardware.h" | |||
53 | ||||
54 | #if EFI_PROD_CODE | |||
55 | #include "board.h" | |||
56 | #endif /* EFI_PROD_CODE */ | |||
57 | ||||
58 | #if EFI_EMULATE_POSITION_SENSORS | |||
59 | #include "trigger_emulator_algo.h" | |||
60 | #endif /* EFI_EMULATE_POSITION_SENSORS */ | |||
61 | ||||
62 | #if EFI_TUNER_STUDIO | |||
63 | #include "tunerstudio.h" | |||
64 | #endif | |||
65 | ||||
66 | #include "board_overrides.h" | |||
67 | ||||
68 | #define TS_DEFAULT_SPEED 38400 | |||
69 | ||||
70 | std::optional<setup_custom_board_overrides_type> custom_board_DefaultConfiguration; | |||
71 | std::optional<setup_custom_board_overrides_type> custom_board_ConfigOverrides; | |||
72 | ||||
73 | /** | |||
74 | * Current engine configuration. On firmware start we assign empty configuration, then | |||
75 | * we copy actual configuration after reading settings from flash. | |||
76 | * This is useful to compare old/current (activeConfiguration) and new/future (engineConfiguration) configurations in order to apply new settings. | |||
77 | * | |||
78 | * todo: place this field next to 'engineConfiguration'? | |||
79 | */ | |||
80 | static bool hasRememberedConfiguration = false; | |||
81 | #if EFI_ACTIVE_CONFIGURATION_IN_FLASH | |||
82 | #include "flash_int.h" | |||
83 | engine_configuration_s & activeConfiguration = reinterpret_cast<persistent_config_container_s*>(getFlashAddrFirstCopy())->persistentConfiguration.engineConfiguration; | |||
84 | // we cannot use this activeConfiguration until we call rememberCurrentConfiguration() | |||
85 | bool isActiveConfigurationVoid = true; | |||
86 | #else | |||
87 | static engine_configuration_s activeConfigurationLocalStorage; | |||
88 | engine_configuration_s & activeConfiguration = activeConfigurationLocalStorage; | |||
89 | #endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */ | |||
90 | ||||
91 | 802 | void rememberCurrentConfiguration() { | ||
92 | #if ! EFI_ACTIVE_CONFIGURATION_IN_FLASH | |||
93 | 802 | memcpy(&activeConfiguration, engineConfiguration, sizeof(engine_configuration_s)); | ||
94 | #else | |||
95 | isActiveConfigurationVoid = false; | |||
96 | #endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */ | |||
97 | 802 | hasRememberedConfiguration = true; | ||
98 | 802 | } | ||
99 | ||||
100 | ✗ | static void fillAfterString(char *string, int size) { | ||
101 | // we have to reset bytes after \0 symbol in order to calculate correct tune CRC from MSQ file | |||
102 | ✗ | for (int i = std::strlen(string) + 1; i < size; i++) { | ||
103 | ✗ | string[i] = 0; | ||
104 | } | |||
105 | ✗ | } | ||
106 | ||||
107 | ✗ | static void wipeStrings() { | ||
108 | ✗ | fillAfterString(engineConfiguration->engineMake, sizeof(vehicle_info_t)); | ||
109 | ✗ | fillAfterString(engineConfiguration->engineCode, sizeof(vehicle_info_t)); | ||
110 | ✗ | fillAfterString(engineConfiguration->vehicleName, sizeof(vehicle_info_t)); | ||
111 | ✗ | } | ||
112 | ||||
113 | ✗ | void onBurnRequest() { | ||
114 | ✗ | onTransitionEvent(TransitionEvent::BurnRequest); | ||
115 | ✗ | wipeStrings(); | ||
116 | ||||
117 | ✗ | incrementGlobalConfigurationVersion("burn"); | ||
118 | ✗ | } | ||
119 | ||||
120 | /** | |||
121 | * this hook is about https://github.com/rusefi/rusefi/wiki/Custom-Firmware and https://github.com/rusefi/rusefi/wiki/Canned-Tune-Process | |||
122 | * todo: why two hooks? is one already dead? | |||
123 | */ | |||
124 | 586 | PUBLIC_API_WEAK void boardBeforeTuneDefaults() { } | ||
125 | ||||
126 | // Weak link a stub so that every board doesn't have to implement this function | |||
127 | 219 | PUBLIC_API_WEAK void boardOnConfigurationChange(engine_configuration_s* /*previousConfiguration*/) { } | ||
128 | ||||
129 | /** | |||
130 | * this is the top-level method which should be called in case of any changes to engine configuration | |||
131 | * online tuning of most values in the maps does not count as configuration change, but 'Burn' command does | |||
132 | * | |||
133 | * this method is NOT currently invoked on ECU start - actual user input has to happen! | |||
134 | * See 'preCalculate' or 'startHardware' which are invoked BOTH on start and configuration change | |||
135 | */ | |||
136 |
1/1✓ Decision 'true' taken 219 times.
|
219 | void incrementGlobalConfigurationVersion(const char * msg) { | |
137 | 219 | onTransitionEvent(TransitionEvent::GlobalConfigurationVersion); | ||
138 | assertStackVoid("increment", ObdCode::STACK_USAGE_MISC, EXPECTED_REMAINING_STACK); | |||
139 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 219 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 219 times.
|
219 | if (!hasRememberedConfiguration) { |
140 | ✗ | criticalError("too early to invoke incrementGlobalConfigurationVersion %s", msg); | ||
141 | } | |||
142 | 219 | engine->globalConfigurationVersion++; | ||
143 | #if EFI_DETAILED_LOGGING | |||
144 | efiPrintf("set globalConfigurationVersion=%d", globalConfigurationVersion); | |||
145 | #endif /* EFI_DETAILED_LOGGING */ | |||
146 | ||||
147 | 219 | applyNewHardwareSettings(); | ||
148 | ||||
149 | 219 | boardOnConfigurationChange(&activeConfiguration); | ||
150 | ||||
151 | 219 | engine->preCalculate(); | ||
152 | ||||
153 | #if EFI_ELECTRONIC_THROTTLE_BODY | |||
154 | 219 | onConfigurationChangeElectronicThrottleCallback(&activeConfiguration); | ||
155 | #endif /* EFI_ELECTRONIC_THROTTLE_BODY */ | |||
156 | ||||
157 | #if EFI_ENGINE_CONTROL && EFI_PROD_CODE | |||
158 | onConfigurationChangeBenchTest(); | |||
159 | #endif | |||
160 | ||||
161 | #if EFI_SHAFT_POSITION_INPUT | |||
162 | 219 | onConfigurationChangeTriggerCallback(); | ||
163 | #endif /* EFI_SHAFT_POSITION_INPUT */ | |||
164 | #if EFI_EMULATE_POSITION_SENSORS && ! EFI_UNIT_TEST | |||
165 | onConfigurationChangeRpmEmulatorCallback(&activeConfiguration); | |||
166 | #endif /* EFI_EMULATE_POSITION_SENSORS */ | |||
167 | ||||
168 | 6789 | engine->engineModules.apply_all([](auto & m) { | ||
169 | 6789 | m.onConfigurationChange(&activeConfiguration); | ||
170 | 6789 | }); | ||
171 | rememberCurrentConfiguration(); | |||
172 | } | |||
173 | ||||
174 | /** | |||
175 | * @brief Sets the same dwell time across the whole getRpm() range | |||
176 | * set dwell X | |||
177 | */ | |||
178 | 1121 | void setConstantDwell(floatms_t dwellMs) { | ||
179 |
2/2✓ Branch 0 taken 8968 times.
✓ Branch 1 taken 1121 times.
|
2/2✓ Decision 'true' taken 8968 times.
✓ Decision 'false' taken 1121 times.
|
10089 | for (int i = 0; i < DWELL_CURVE_SIZE; i++) { |
180 | 8968 | config->sparkDwellRpmBins[i] = 1000 * i; | ||
181 | } | |||
182 | 1121 | setArrayValues(config->sparkDwellValues, dwellMs); | ||
183 | 1121 | } | ||
184 | ||||
185 | 591 | void setFuelTablesLoadBin(float minValue, float maxValue) { | ||
186 | 591 | setLinearCurve(config->injPhaseLoadBins, minValue, maxValue, 1); | ||
187 | 591 | setLinearCurve(config->veLoadBins, minValue, maxValue, 1); | ||
188 | 591 | setLinearCurve(config->lambdaLoadBins, minValue, maxValue, 1); | ||
189 | 591 | } | ||
190 | ||||
191 | 530 | void setWholeIatCorrTimingTable(float value) { | ||
192 | 530 | setTable(config->ignitionIatCorrTable, value); | ||
193 | 530 | } | ||
194 | ||||
195 | /** | |||
196 | * See also crankingTimingAngle | |||
197 | */ | |||
198 | 18 | void setWholeTimingTable(angle_t value) { | ||
199 | 18 | setTable(config->ignitionTable, value); | ||
200 | 18 | } | ||
201 | ||||
202 | #if EFI_ENGINE_CONTROL | |||
203 | namespace { | |||
204 | 2930 | void initTemperatureCurve( | ||
205 | float * const bins, | |||
206 | float * const values, | |||
207 | const int size, | |||
208 | const float defaultValue, | |||
209 | const float initialTemperature = -40.0f, | |||
210 | const float temperatureStep = 10.0f | |||
211 | ) { | |||
212 |
2/2✓ Branch 0 taken 21096 times.
✓ Branch 1 taken 2930 times.
|
2/2✓ Decision 'true' taken 21096 times.
✓ Decision 'false' taken 2930 times.
|
24026 | for (int i = 0; i < size; i++) { |
213 | 21096 | bins[i] = initialTemperature + i * temperatureStep; | ||
214 | 21096 | values[i] = defaultValue; // this correction is a multiplier | ||
215 | } | |||
216 | 2930 | } | ||
217 | ||||
218 | 2344 | void initBoostTemperatureCurve(float* const bins, float* const values, const float defaultValue) { | ||
219 | 2344 | initTemperatureCurve(bins, values, BOOST_CURVE_SIZE, defaultValue, 20.0f, 20.0f); | ||
220 | 2344 | } | ||
221 | } | |||
222 | #endif // EFI_ENGINE_CONTROL | |||
223 | ||||
224 | 586 | void prepareVoidConfiguration(engine_configuration_s *p_engineConfiguration) { | ||
225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 586 times.
|
586 | criticalAssertVoid(p_engineConfiguration != nullptr, "ec NULL"); | |
226 | 586 | efi::clear(p_engineConfiguration); | ||
227 | ||||
228 | 586 | p_engineConfiguration->clutchDownPinMode = PI_PULLUP; | ||
229 | 586 | p_engineConfiguration->clutchUpPinMode = PI_PULLUP; | ||
230 | 586 | p_engineConfiguration->brakePedalPinMode = PI_PULLUP; | ||
231 | } | |||
232 | ||||
233 | 586 | void setDefaultBasePins() { | ||
234 | #if EFI_PROD_CODE | |||
235 | // call overrided board-specific serial configuration setup, if needed (for custom boards only) | |||
236 | // needed also by bootloader code | |||
237 | setPinConfigurationOverrides(); | |||
238 | #endif /* EFI_PROD_CODE */ | |||
239 | ||||
240 | // set UART pads configuration based on the board | |||
241 | // needed also by bootloader code | |||
242 | #ifdef TS_SECONDARY_UxART_PORT | |||
243 | engineConfiguration->binarySerialTxPin = Gpio::C10; | |||
244 | engineConfiguration->binarySerialRxPin = Gpio::C11; | |||
245 | #endif // TS_SECONDARY_UxART_PORT | |||
246 | ||||
247 | 586 | engineConfiguration->tunerStudioSerialSpeed = TS_DEFAULT_SPEED; | ||
248 | 586 | engineConfiguration->uartConsoleSerialSpeed = 115200; | ||
249 | 586 | } | ||
250 | ||||
251 | // needed also by bootloader code | |||
252 | // at the moment bootloader does NOT really need SD card, this is a step towards future bootloader SD card usage | |||
253 | ✗ | void setDefaultSdCardParameters() { | ||
254 | ✗ | engineConfiguration->isSdCardEnabled = true; | ||
255 | ✗ | } | ||
256 | ||||
257 | #if EFI_ENGINE_CONTROL | |||
258 | ||||
259 | /** | |||
260 | * see also setTargetRpmCurve() | |||
261 | */ | |||
262 | 586 | static void setDefaultIdleSpeedTarget() { | ||
263 | #if CLT_CURVE_SIZE == 16 | |||
264 |
1/1✓ Branch 2 taken 586 times.
|
586 | copyArray(config->cltIdleRpmBins, { -30, - 20, -10, 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 , 110, 120 }); | |
265 |
1/1✓ Branch 2 taken 586 times.
|
586 | copyArray(config->cltIdleRpm, { 1350, 1350, 1300, 1200, 1150, 1100, 1050, 1000, 1000, 950, 950, 930, 900, 900, 1000, 1100 }); | |
266 | #endif // CLT_CURVE_SIZE | |||
267 | 586 | } | ||
268 | #endif // EFI_ENGINE_CONTROL | |||
269 | ||||
270 | /** | |||
271 | * see also setDefaultIdleSpeedTarget() | |||
272 | */ | |||
273 | 2 | void setTargetRpmCurve(float rpm) { | ||
274 | 2 | setLinearCurve(config->cltIdleRpmBins, CLT_CURVE_RANGE_FROM, 140, 10); | ||
275 | 2 | setLinearCurve(config->cltIdleRpm, rpm, rpm, 10); | ||
276 | 2 | } | ||
277 | ||||
278 | 586 | static void setDefaultGppwmParameters() { | ||
279 | // Same config for all channels | |||
280 |
2/2✓ Branch 1 taken 2344 times.
✓ Branch 2 taken 586 times.
|
2/2✓ Decision 'true' taken 2344 times.
✓ Decision 'false' taken 586 times.
|
2930 | for (size_t i = 0; i < efi::size(engineConfiguration->gppwm); i++) { |
281 | 2344 | auto& cfg = engineConfiguration->gppwm[i]; | ||
282 | 2344 | chsnprintf(engineConfiguration->gpPwmNote[i], sizeof(engineConfiguration->gpPwmNote[0]), "GPPWM%d", i); | ||
283 | ||||
284 | // Set default axes | |||
285 | 2344 | cfg.loadAxis = GPPWM_Zero; | ||
286 | 2344 | cfg.rpmAxis = GPPWM_Rpm; | ||
287 | ||||
288 | 2344 | cfg.pin = Gpio::Unassigned; | ||
289 | 2344 | cfg.dutyIfError = 0; | ||
290 | 2344 | cfg.onAboveDuty = 60; | ||
291 | 2344 | cfg.offBelowDuty = 50; | ||
292 | 2344 | cfg.pwmFrequency = 250; | ||
293 | ||||
294 |
2/2✓ Branch 1 taken 18752 times.
✓ Branch 2 taken 2344 times.
|
2/2✓ Decision 'true' taken 18752 times.
✓ Decision 'false' taken 2344 times.
|
21096 | for (size_t j = 0; j < efi::size(cfg.loadBins); j++) { |
295 | 18752 | uint8_t z = j * 100 / (efi::size(cfg.loadBins) - 1); | ||
296 | 18752 | cfg.loadBins[j] = z; | ||
297 | ||||
298 | // Fill some values in the table | |||
299 |
2/2✓ Branch 1 taken 150016 times.
✓ Branch 2 taken 18752 times.
|
2/2✓ Decision 'true' taken 150016 times.
✓ Decision 'false' taken 18752 times.
|
168768 | for (size_t k = 0; k < efi::size(cfg.rpmBins); k++) { |
300 | 150016 | cfg.table[j][k] = z; | ||
301 | } | |||
302 | ||||
303 | } | |||
304 | ||||
305 |
2/2✓ Branch 1 taken 18752 times.
✓ Branch 2 taken 2344 times.
|
2/2✓ Decision 'true' taken 18752 times.
✓ Decision 'false' taken 2344 times.
|
21096 | for (size_t j = 0; j < efi::size(cfg.rpmBins); j++) { |
306 | 18752 | cfg.rpmBins[j] = 1000 * j; | ||
307 | } | |||
308 | } | |||
309 | 586 | } | ||
310 | ||||
311 | 586 | static void setDefaultBoostOpenLoopParameters() { | ||
312 | 586 | engineConfiguration->boostOpenLoopYAxis = GPPWM_Tps; | ||
313 | 586 | } | ||
314 | ||||
315 | #if EFI_ENGINE_CONTROL | |||
316 | 586 | static void setDefaultEngineNoiseTable() { | ||
317 | 586 | setRpmTableBin(config->knockNoiseRpmBins); | ||
318 | ||||
319 | 586 | engineConfiguration->knockDetectionWindowStart = 15.0 + 5.0; | ||
320 | 586 | engineConfiguration->knockSamplingDuration = 45; | ||
321 | ||||
322 | 586 | setArrayValues(config->knockBaseNoise, -20); | ||
323 | 586 | } | ||
324 | #endif // EFI_ENGINE_CONTROL | |||
325 | ||||
326 | 586 | static void setDefaultCanSettings() { | ||
327 | // OBD-II default rate is 500kbps | |||
328 | 586 | engineConfiguration->canBaudRate = B500KBPS; | ||
329 | 586 | engineConfiguration->can2BaudRate = B500KBPS; | ||
330 | ||||
331 | 586 | engineConfiguration->canSleepPeriodMs = 50; | ||
332 | 586 | engineConfiguration->canReadEnabled = true; | ||
333 | 586 | engineConfiguration->canWriteEnabled = true; | ||
334 | 586 | engineConfiguration->canVssScaling = 1.0f; | ||
335 | ||||
336 | // Don't enable, but set default address | |||
337 | 586 | engineConfiguration->verboseCanBaseAddress = CAN_DEFAULT_BASE; | ||
338 | 586 | } | ||
339 | ||||
340 | 586 | static void setDefaultScriptParameters() { | ||
341 | 586 | setLinearCurve(config->scriptTable1LoadBins, 20, 120, 10); | ||
342 | 586 | setRpmTableBin(config->scriptTable1RpmBins); | ||
343 | 586 | setLinearCurve(config->scriptTable2LoadBins, 20, 120, 10); | ||
344 | 586 | setRpmTableBin(config->scriptTable2RpmBins); | ||
345 | 586 | setLinearCurve(config->scriptTable3LoadBins, 20, 120, 10); | ||
346 | 586 | setRpmTableBin(config->scriptTable3RpmBins); | ||
347 | 586 | setLinearCurve(config->scriptTable4LoadBins, 20, 120, 10); | ||
348 | 586 | setRpmTableBin(config->scriptTable4RpmBins); | ||
349 | 586 | } | ||
350 | ||||
351 | 586 | static void setDefaultIdleOpenLoopParameters() { | ||
352 | 586 | setRpmTableBin(config->rpmIdleCorrBins); | ||
353 | 586 | setLinearCurve(config->cltIdleCorrBins, CLT_CURVE_RANGE_FROM, 140, 10); | ||
354 |
2/2✓ Branch 0 taken 1172 times.
✓ Branch 1 taken 586 times.
|
2/2✓ Decision 'true' taken 1172 times.
✓ Decision 'false' taken 586 times.
|
1758 | for (size_t i = 0; i < CLT_IDLE_TABLE_RPM_SIZE; i++) { |
355 | 1172 | setLinearCurve(config->cltIdleCorrTable[i], 75.0, 50, 5); | ||
356 | } | |||
357 | 586 | } | ||
358 | ||||
359 | /** | |||
360 | * @brief Global default engine configuration | |||
361 | * This method sets the global engine configuration defaults. These default values are then | |||
362 | * overridden by engine-specific defaults and the settings are saved in flash memory. | |||
363 | * | |||
364 | * This method is invoked only when new configuration is needed: | |||
365 | * * recently re-flashed chip | |||
366 | * * flash version of configuration failed CRC check or appears to be older then FLASH_DATA_VERSION | |||
367 | * * 'rewriteconfig' command | |||
368 | * * 'set engine_type X' command | |||
369 | * | |||
370 | * This method should only change the state of the configuration data structure but should NOT change the state of | |||
371 | * anything else. | |||
372 | * | |||
373 | * This method should NOT be setting any default pinout | |||
374 | */ | |||
375 | 586 | static void setDefaultEngineConfiguration() { | ||
376 | #if (! EFI_UNIT_TEST) | |||
377 | efi::clear(persistentState.persistentConfiguration); | |||
378 | #endif | |||
379 | 586 | prepareVoidConfiguration(engineConfiguration); | ||
380 | ||||
381 | #if EFI_BOOST_CONTROL | |||
382 | 586 | setDefaultBoostParameters(); | ||
383 | #endif | |||
384 | ||||
385 | 586 | setDefaultCanSettings(); | ||
386 | ||||
387 | 586 | engineConfiguration->sdCardLogFrequency = 50; | ||
388 | ||||
389 | 586 | setDefaultGppwmParameters(); | ||
390 | 586 | setDefaultBoostOpenLoopParameters(); | ||
391 | 586 | setDefaultScriptParameters(); | ||
392 | ||||
393 | #if EFI_ENGINE_CONTROL | |||
394 | 586 | setDefaultBaseEngine(); | ||
395 | 586 | setDefaultFuel(); | ||
396 | 586 | setDefaultIgnition(); | ||
397 | 586 | setDefaultCranking(); | ||
398 | ||||
399 | // VVT closed loop, totally random values! | |||
400 | 586 | engineConfiguration->auxPid[0].pFactor = 2; | ||
401 | 586 | engineConfiguration->auxPid[0].iFactor = 0.005; | ||
402 | 586 | engineConfiguration->auxPid[0].dFactor = 0; | ||
403 | 586 | engineConfiguration->auxPid[0].offset = 33; | ||
404 | 586 | engineConfiguration->auxPid[0].minValue = 10; | ||
405 | 586 | engineConfiguration->auxPid[0].maxValue = 90; | ||
406 | ||||
407 | 586 | engineConfiguration->vvtOutputFrequency = DEFAULT_SOLENOID_FREQUENCY; // VVT solenoid control | ||
408 | ||||
409 | 586 | engineConfiguration->isCylinderCleanupEnabled = true; | ||
410 | ||||
411 | 586 | engineConfiguration->auxPid[0].minValue = 10; | ||
412 | 586 | engineConfiguration->auxPid[0].maxValue = 90; | ||
413 | 586 | engineConfiguration->auxPid[1].minValue = 10; | ||
414 | 586 | engineConfiguration->auxPid[1].maxValue = 90; | ||
415 | ||||
416 | 586 | engineConfiguration->turboSpeedSensorMultiplier = 1; | ||
417 | ||||
418 | #if EFI_IDLE_CONTROL | |||
419 | 586 | setDefaultIdleParameters(); | ||
420 | #endif /* EFI_IDLE_CONTROL */ | |||
421 | ||||
422 | #if EFI_ELECTRONIC_THROTTLE_BODY | |||
423 | 586 | setDefaultEtbParameters(); | ||
424 | 586 | setDefaultEtbBiasCurve(); | ||
425 | #endif /* EFI_ELECTRONIC_THROTTLE_BODY */ | |||
426 | ||||
427 | 586 | setBosch0280218037(); | ||
428 | ||||
429 | 586 | engineConfiguration->mapMinBufferLength = 1; | ||
430 | 586 | engineConfiguration->vvtActivationDelayMs = 6000; | ||
431 | ||||
432 | 586 | engineConfiguration->startCrankingDuration = 3; | ||
433 | ||||
434 | 586 | engineConfiguration->maxAcRpm = 5000; | ||
435 | 586 | engineConfiguration->maxAcClt = 100; | ||
436 | 586 | engineConfiguration->maxAcTps = 75; | ||
437 | ||||
438 | 586 | initTemperatureCurve(IAT_FUEL_CORRECTION_CURVE, 1); | ||
439 | ||||
440 | 586 | initBoostTemperatureCurve(config->cltBoostCorrBins, config->cltBoostCorr, 1.0f); | ||
441 | 586 | initBoostTemperatureCurve(config->iatBoostCorrBins, config->iatBoostCorr, 1.0f); | ||
442 | 586 | initBoostTemperatureCurve(config->cltBoostAdderBins, config->cltBoostAdder, 0.0f); | ||
443 | 586 | initBoostTemperatureCurve(config->iatBoostAdderBins, config->iatBoostAdder, 0.0f); | ||
444 | ||||
445 | 586 | engineConfiguration->alternatorControl.minValue = 0; | ||
446 | 586 | engineConfiguration->alternatorControl.maxValue = 90; | ||
447 | ||||
448 | 586 | setLinearCurve(config->scriptCurve1Bins, 0, 100, 1); | ||
449 | 586 | setLinearCurve(config->scriptCurve1, 0, 100, 1); | ||
450 | ||||
451 | 586 | setLinearCurve(config->scriptCurve2Bins, 0, 100, /*precision*/1); | ||
452 | 586 | setLinearCurve(config->scriptCurve2, 30, 170, 1); | ||
453 | ||||
454 | 586 | setLinearCurve(config->scriptCurve3Bins, 0, 100, 1); | ||
455 | 586 | setLinearCurve(config->scriptCurve4Bins, 0, 100, 1); | ||
456 | 586 | setLinearCurve(config->scriptCurve5Bins, 0, 100, 1); | ||
457 | 586 | setLinearCurve(config->scriptCurve6Bins, 0, 100, 1); | ||
458 | ||||
459 | 586 | setLinearCurve(config->alsIgnRetardLoadBins, 2, 10, /*precision*/1); | ||
460 | 586 | setRpmTableBin(config->alsIgnRetardrpmBins); | ||
461 | 586 | setLinearCurve(config->alsFuelAdjustmentLoadBins, 2, 10, /*precision*/1); | ||
462 | 586 | setRpmTableBin(config->alsFuelAdjustmentrpmBins); | ||
463 | 586 | setLinearCurve(config->fuelLevelBins, 0, 5); | ||
464 | ||||
465 | ||||
466 | 586 | setRpmTableBin(engineConfiguration->map.samplingAngleBins); | ||
467 | 586 | setLinearCurve(engineConfiguration->map.samplingAngle, 100, 130, 1); | ||
468 | 586 | setRpmTableBin(engineConfiguration->map.samplingWindowBins); | ||
469 | 586 | setLinearCurve(engineConfiguration->map.samplingWindow, 50, 50, 1); | ||
470 | ||||
471 | #if VVT_TABLE_SIZE == 8 | |||
472 | 586 | setLinearCurve(config->vvtTable1LoadBins, 20, 120, 10); | ||
473 | 586 | setLinearCurve(config->vvtTable2LoadBins, 20, 120, 10); | ||
474 | #else | |||
475 | setLinearCurve(config->vvtTable1LoadBins, 20, 120, 5); | |||
476 | setLinearCurve(config->vvtTable2LoadBins, 20, 120, 5); | |||
477 | #endif | |||
478 | 586 | setRpmTableBin(config->vvtTable1RpmBins); | ||
479 | 586 | setRpmTableBin(config->vvtTable2RpmBins); | ||
480 | ||||
481 | 586 | setDefaultEngineNoiseTable(); | ||
482 | ||||
483 | // is this same old setCommonNTCSensor? | |||
484 | 586 | engineConfiguration->clt.config = {0, 23.8889, 48.8889, 9500, 2100, 1000, 1500}; | ||
485 | ||||
486 | 586 | setCommonNTCSensorParameters(&engineConfiguration->iat); | ||
487 | ||||
488 | // wow unit tests have much cooler setDefaultLaunchParameters method | |||
489 | 586 | engineConfiguration->launchRpm = 3000; | ||
490 | // engineConfiguration->launchTimingRetard = 10; | |||
491 | 586 | engineConfiguration->launchRpmWindow = 500; | ||
492 | 586 | engineConfiguration->launchSpeedThreshold = 30; | ||
493 | ||||
494 | 586 | engineConfiguration->engineSnifferRpmThreshold = 2500; | ||
495 | ||||
496 | /** | |||
497 | * Idle control defaults | |||
498 | */ | |||
499 | 586 | setDefaultIdleSpeedTarget(); | ||
500 | // setTargetRpmCurve(1200); | |||
501 | ||||
502 | 586 | engineConfiguration->idleRpmPid.pFactor = 0.05; | ||
503 | 586 | engineConfiguration->idleRpmPid.iFactor = 0.002; | ||
504 | ||||
505 | 586 | engineConfiguration->idleRpmPid.minValue = -20; | ||
506 | 586 | engineConfiguration->idleRpmPid.maxValue = 20; | ||
507 | /** | |||
508 | * between variation between different sensor and weather and fabrication tolerance | |||
509 | * five percent looks like a safer default | |||
510 | */ | |||
511 | 586 | engineConfiguration->idlePidDeactivationTpsThreshold = 5; | ||
512 | ||||
513 | 586 | engineConfiguration->idle.solenoidFrequency = DEFAULT_SOLENOID_FREQUENCY; | ||
514 | // set idle_position 50 | |||
515 | 586 | setDefaultIdleOpenLoopParameters(); | ||
516 | // engineConfiguration->idleMode = IM_AUTO; | |||
517 | 586 | engineConfiguration->idleMode = idle_mode_e::IM_MANUAL; | ||
518 | ||||
519 | 586 | engineConfiguration->useStepperIdle = false; | ||
520 | ||||
521 | 586 | setLinearCurve(config->iacCoastingRpmBins, 0, 8000, 1); | ||
522 | ||||
523 | #if !EFI_UNIT_TEST | |||
524 | engineConfiguration->analogInputDividerCoefficient = 2; | |||
525 | #endif | |||
526 | ||||
527 | ||||
528 | 586 | setTPS1Calibration(convertVoltageTo10bitADC(0), | ||
529 | 586 | convertVoltageTo10bitADC(5), | ||
530 | 586 | convertVoltageTo10bitADC(5), | ||
531 | 586 | convertVoltageTo10bitADC(0)); | ||
532 | ||||
533 | 586 | engineConfiguration->tps2Min = convertVoltageTo10bitADC(0); | ||
534 | 586 | engineConfiguration->tps2Max = convertVoltageTo10bitADC(5); | ||
535 | 586 | engineConfiguration->tps2SecondaryMin = convertVoltageTo10bitADC(5); | ||
536 | 586 | engineConfiguration->tps2SecondaryMax = convertVoltageTo10bitADC(0); | ||
537 | ||||
538 | 586 | engineConfiguration->idlePositionMin = PACK_MULT_VOLTAGE * 0; | ||
539 | 586 | engineConfiguration->idlePositionMax = PACK_MULT_VOLTAGE * 5; | ||
540 | 586 | engineConfiguration->wastegatePositionClosedVoltage = 0.0; | ||
541 | 586 | engineConfiguration->wastegatePositionOpenedVoltage = 5.0; | ||
542 | 586 | engineConfiguration->tpsErrorDetectionTooLow = -10; // -10% open | ||
543 | 586 | engineConfiguration->tpsErrorDetectionTooHigh = 110; // 110% open | ||
544 | ||||
545 | 586 | engineConfiguration->oilPressure.v1 = 0.5f; | ||
546 | 586 | engineConfiguration->oilPressure.v2 = 4.5f; | ||
547 | 586 | engineConfiguration->oilPressure.value1 = 0; | ||
548 | 586 | engineConfiguration->oilPressure.value2 = 689.476f; // 100psi = 689.476kPa | ||
549 | ||||
550 | 586 | engineConfiguration->mapLowValueVoltage = 0; | ||
551 | // todo: start using this for custom MAP | |||
552 | 586 | engineConfiguration->mapHighValueVoltage = 5; | ||
553 | ||||
554 | 586 | engineConfiguration->cylinderBore = 87.5; | ||
555 | ||||
556 | 586 | setBoschHDEV_5_injectors(); | ||
557 | ||||
558 | 586 | setEgoSensor(ES_14Point7_Free); | ||
559 | ||||
560 | 586 | engineConfiguration->adcVcc = 3.0; | ||
561 | ||||
562 | 586 | engineConfiguration->map.sensor.type = MT_MPX4250; | ||
563 | ||||
564 | 586 | engineConfiguration->baroSensor.type = MT_CUSTOM; | ||
565 | 586 | engineConfiguration->baroSensor.lowValue = 0; | ||
566 | 586 | engineConfiguration->baroSensor.highValue = 500; | ||
567 | ||||
568 | #if EFI_PROD_CODE | |||
569 | engineConfiguration->engineChartSize = 300; | |||
570 | #else | |||
571 | // need more events for automated test | |||
572 | 586 | engineConfiguration->engineChartSize = 400; | ||
573 | #endif | |||
574 | ||||
575 | #if EFI_PROD_CODE || EFI_SIMULATOR | |||
576 | // some tests broke with map averaging, see https://github.com/rusefi/rusefi/issues/7868 | |||
577 | engineConfiguration->isMapAveragingEnabled = true; | |||
578 | #endif | |||
579 | 586 | engineConfiguration->isWaveAnalyzerEnabled = true; | ||
580 | ||||
581 | 586 | engineConfiguration->acIdleRpmTarget = 900; | ||
582 | 586 | engineConfiguration->acDelay = engine_configuration_defaults::AC_DELAY; | ||
583 | 586 | engineConfiguration->minAcPressure = engine_configuration_defaults::MIN_AC_PRESSURE; | ||
584 | 586 | engineConfiguration->maxAcPressure = engine_configuration_defaults::MAX_AC_PRESSURE; | ||
585 | 586 | engineConfiguration->acPressureEnableHyst = engine_configuration_defaults::AC_PRESSURE_ENABLE_HYST; | ||
586 | 586 | engineConfiguration->acIdleExtraOffset = 15; | ||
587 | ||||
588 | 586 | engineConfiguration->nitrousMinimumTps = engine_configuration_defaults::NITROUS_MINIMUM_TPS; | ||
589 | 586 | engineConfiguration->nitrousMinimumClt = engine_configuration_defaults::NITROUS_MINIMUM_CLT; | ||
590 | 586 | engineConfiguration->nitrousMaximumAfr = engine_configuration_defaults::NITROUS_MAXIMUM_AFR; | ||
591 | 586 | engineConfiguration->nitrousActivationRpm = engine_configuration_defaults::NITROUS_ACTIVATION_RPM; | ||
592 | 586 | engineConfiguration->nitrousDeactivationRpm = engine_configuration_defaults::NITROUS_DEACTIVATION_RPM; | ||
593 | 586 | engineConfiguration->nitrousDeactivationRpmWindow = engine_configuration_defaults::NITROUS_DEACTIVATION_RPM_WINDOW; | ||
594 | ||||
595 | 586 | engineConfiguration->triggerSimulatorRpm = DEFAULT_SELT_STIM_RPM; | ||
596 | 586 | engineConfiguration->simulatorCamPosition[0] = DEFAULT_SELT_STIM_VVT0; | ||
597 | ||||
598 | 586 | engineConfiguration->alternatorPwmFrequency = DEFAULT_SOLENOID_FREQUENCY; | ||
599 | ||||
600 | 586 | engineConfiguration->isAlternatorControlEnabled = false; | ||
601 | ||||
602 | 586 | engineConfiguration->driveWheelRevPerKm = 1000; | ||
603 | 586 | engineConfiguration->finalGearRatio = 1; | ||
604 | 586 | engineConfiguration->vssGearRatio = 3.73; | ||
605 | 586 | engineConfiguration->vssToothCount = 21; | ||
606 | ||||
607 | 586 | engineConfiguration->mapErrorDetectionTooLow = 5; | ||
608 | // todo: default limits should be hard-coded for each sensor type | |||
609 | // https://github.com/rusefi/rusefi/issues/4030 | |||
610 | 586 | engineConfiguration->mapErrorDetectionTooHigh = 410; | ||
611 | ||||
612 | 586 | setLinearCurve(config->throttleEstimateEffectiveAreaBins, 0, 100); | ||
613 | #endif // EFI_ENGINE_CONTROL | |||
614 | #include "default_script.lua" | |||
615 | 586 | } | ||
616 | ||||
617 | #if defined(STM32F7) && defined(HARDWARE_CI) | |||
618 | // part of F7 drama looks like we are having a hard time erasing configuration on HW CI :( | |||
619 | #define IGNORE_FLASH_CONFIGURATION true | |||
620 | #endif | |||
621 | ||||
622 | // by default, do not ignore config from flash! use it! | |||
623 | #ifndef IGNORE_FLASH_CONFIGURATION | |||
624 | #define IGNORE_FLASH_CONFIGURATION false | |||
625 | #endif | |||
626 | ||||
627 | ✗ | void loadConfiguration() { | ||
628 | ||||
629 | #if ! EFI_ACTIVE_CONFIGURATION_IN_FLASH | |||
630 | // Clear the active configuration so that registered output pins (etc) detect the change on startup and init properly | |||
631 | ✗ | prepareVoidConfiguration(&activeConfiguration); | ||
632 | #endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */ | |||
633 | ||||
634 | /* If board have any storage */ | |||
635 | #if EFI_CONFIGURATION_STORAGE | |||
636 | if (IGNORE_FLASH_CONFIGURATION) { | |||
637 | engineConfiguration->engineType = DEFAULT_ENGINE_TYPE; | |||
638 | resetConfigurationExt(engineConfiguration->engineType); | |||
639 | writeToFlashNow(); | |||
640 | } else { | |||
641 | // this call reads configuration from flash memory or sets default configuration | |||
642 | // if flash state does not look right. | |||
643 | readFromFlash(); | |||
644 | } | |||
645 | #else | |||
646 | // This board doesn't load configuration, initialize the default | |||
647 | ✗ | engineConfiguration->engineType = DEFAULT_ENGINE_TYPE; | ||
648 | ✗ | resetConfigurationExt(engineConfiguration->engineType); | ||
649 | #endif /* EFI_CONFIGURATION_STORAGE */ | |||
650 | ||||
651 | // Force any board configuration options that humans shouldn't be able to change | |||
652 | ✗ | call_board_override(custom_board_ConfigOverrides); | ||
653 | ✗ | } | ||
654 | ||||
655 | 586 | void resetConfigurationExt(configuration_callback_t boardCallback, engine_type_e engineType) { | ||
656 | 586 | enginePins.reset(); // that's mostly important for functional tests | ||
657 | /** | |||
658 | * Let's apply global defaults first | |||
659 | */ | |||
660 | 586 | setDefaultEngineConfiguration(); | ||
661 | ||||
662 | /** | |||
663 | * custom board engine defaults. Yes, this overlaps with (older) engine_type_e approach. | |||
664 | */ | |||
665 | 586 | boardBeforeTuneDefaults(); | ||
666 | ||||
667 | // set initial pin groups | |||
668 | 586 | setDefaultBasePins(); | ||
669 | ||||
670 |
2/2✓ Branch 0 taken 584 times.
✓ Branch 1 taken 2 times.
|
2/2✓ Decision 'true' taken 584 times.
✓ Decision 'false' taken 2 times.
|
586 | if (boardCallback != nullptr) { |
671 | 584 | boardCallback(engineConfiguration); | ||
672 | } | |||
673 | ||||
674 | #if EFI_PROD_CODE | |||
675 | // call board-specific configuration setup, if needed (for custom boards only) | |||
676 | call_board_override(custom_board_DefaultConfiguration); | |||
677 | call_board_override(custom_board_ConfigOverrides); | |||
678 | #endif // EFI_PROD_CODE | |||
679 | ||||
680 | 586 | engineConfiguration->engineType = engineType; | ||
681 | 586 | applyEngineType(engineType); | ||
682 | 586 | applyNonPersistentConfiguration(); | ||
683 | 586 | } | ||
684 | ||||
685 | 575 | void emptyCallbackWithConfiguration(engine_configuration_s * p_engineConfiguration) { | ||
686 | UNUSED(p_engineConfiguration); | |||
687 | 575 | } | ||
688 | ||||
689 | 1 | void resetConfigurationExt(engine_type_e engineType) { | ||
690 | 1 | resetConfigurationExt(&emptyCallbackWithConfiguration, engineType); | ||
691 | 1 | } | ||
692 | ||||
693 | 587 | void applyNonPersistentConfiguration() { | ||
694 | #if EFI_PROD_CODE | |||
695 | efiAssertVoid(ObdCode::CUSTOM_APPLY_STACK, hasLotsOfRemainingStack(), "apply c"); | |||
696 | efiPrintf("applyNonPersistentConfiguration()"); | |||
697 | #endif | |||
698 | ||||
699 | #if EFI_ENGINE_CONTROL | |||
700 | 587 | engine->updateTriggerConfiguration(); | ||
701 | #endif // EFI_ENGINE_CONTROL | |||
702 | 587 | } | ||
703 | ||||
704 | 653 | void setCamOperationMode() { | ||
705 | 653 | engineConfiguration->skippedWheelOnCam = true; | ||
706 | 653 | } | ||
707 | ||||
708 | 23 | void setCrankOperationMode() { | ||
709 | // this is related to 'setDefaultBaseEngine' having 'skippedWheelOnCam = true' which is a weird fact by itself | |||
710 | 23 | engineConfiguration->skippedWheelOnCam = false; | ||
711 | 23 | } | ||
712 | ||||
713 | 14 | void commonFrankensoAnalogInputs() { | ||
714 | /** | |||
715 | * VBatt | |||
716 | */ | |||
717 | 14 | engineConfiguration->vbattAdcChannel = EFI_ADC_14; | ||
718 | 14 | } | ||
719 | ||||
720 | ✗ | void setBoardDefaultConfiguration() { | ||
721 | // custom_board_DefaultConfiguration | |||
722 | ✗ | } | ||
723 | ✗ | void setBoardConfigOverrides() { | ||
724 | // time to force migration to custom_board_ConfigOverrides | |||
725 | ✗ | } | ||
726 | ||||
727 | ✗ | PUBLIC_API_WEAK int hackHellenBoardId(int detectedId) { return detectedId; } | ||
728 | ||||
729 | ✗ | PUBLIC_API_WEAK void onBoardStandBy() { } | ||
730 | ||||
731 | ✗ | PUBLIC_API_WEAK_SOMETHING_WEIRD int getBoardMetaOutputsCount() { return 0; } | ||
732 | // default implementation: treat all outputs as low side | |||
733 | ✗ | PUBLIC_API_WEAK int getBoardMetaLowSideOutputsCount() { return getBoardMetaOutputsCount(); } | ||
734 | ✗ | PUBLIC_API_WEAK Gpio* getBoardMetaOutputs() { return nullptr; } | ||
735 | ✗ | PUBLIC_API_WEAK int getBoardMetaDcOutputsCount() { return 0; } | ||
736 |