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