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