rusefi/firmware/controllers/engine_controller.cpp

761 lines
21 KiB
C++
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file engine_controller.cpp
* @brief Controllers package entry point code
*
*
*
* @date Feb 7, 2013
2020-01-07 21:02:40 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2015-07-10 06:01:56 -07:00
*
* This file is part of rusEfi - see http://rusefi.com
*
* rusEfi is free software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "pch.h"
2022-09-07 12:56:45 -07:00
2015-07-10 06:01:56 -07:00
#include "trigger_central.h"
2022-07-14 04:52:58 -07:00
#include "script_impl.h"
2015-07-10 06:01:56 -07:00
#include "idle_thread.h"
#include "hardware.h"
2019-12-23 21:03:53 -08:00
#include "advance_map.h"
2015-07-10 06:01:56 -07:00
#include "main_trigger_callback.h"
#include "flash_main.h"
#include "bench_test.h"
#include "mmc_card.h"
2015-07-10 06:01:56 -07:00
#include "electronic_throttle.h"
#include "trigger_emulator_algo.h"
2015-07-10 06:01:56 -07:00
#include "map_averaging.h"
2020-11-05 13:42:56 -08:00
#include "high_pressure_fuel_pump.h"
2015-07-10 06:01:56 -07:00
#include "malfunction_central.h"
#include "malfunction_indicator.h"
2019-12-23 21:03:53 -08:00
#include "speed_density.h"
#include "local_version_holder.h"
#include "alternator_controller.h"
2023-11-24 22:41:39 -08:00
#include "can_bench_test.h"
#include "engine_emulator.h"
2015-07-10 06:01:56 -07:00
#include "fuel_math.h"
2019-12-23 21:26:23 -08:00
#include "spark_logic.h"
#include "status_loop.h"
2019-12-23 21:26:23 -08:00
#include "aux_valves.h"
2017-08-28 17:11:32 -07:00
#include "accelerometer.h"
#include "vvt.h"
#include "boost_control.h"
2020-03-23 17:44:34 -07:00
#include "launch_control.h"
2020-04-01 16:00:56 -07:00
#include "tachometer.h"
2023-10-15 14:59:39 -07:00
#include "speedometer.h"
#include "gppwm.h"
#include "date_stamp.h"
#include "rusefi_lua.h"
#include "buttonshift.h"
#include "start_stop.h"
#include "dynoview.h"
#include "vr_pwm.h"
#include "adc_subscription.h"
#include "gc_generic.h"
2015-07-10 06:01:56 -07:00
2019-12-23 20:25:08 -08:00
#if EFI_SENSOR_CHART
#include "sensor_chart.h"
2020-03-22 21:01:59 -07:00
#endif /* EFI_SENSOR_CHART */
2019-12-23 20:25:08 -08:00
#if EFI_TUNER_STUDIO
#include "tunerstudio.h"
2020-03-22 21:01:59 -07:00
#endif /* EFI_TUNER_STUDIO */
2019-12-23 20:25:08 -08:00
#if EFI_LOGIC_ANALYZER
#include "logic_analyzer.h"
2020-03-22 21:01:59 -07:00
#endif /* EFI_LOGIC_ANALYZER */
2019-12-23 20:25:08 -08:00
2019-04-12 19:07:03 -07:00
#if HAL_USE_ADC
2015-07-10 06:01:56 -07:00
#include "AdcConfiguration.h"
2016-08-20 20:02:09 -07:00
#endif /* HAL_USE_ADC */
2015-07-10 06:01:56 -07:00
#if defined(EFI_BOOTLOADER_INCLUDE_CODE)
#include "bootloader/bootloader.h"
#endif /* EFI_BOOTLOADER_INCLUDE_CODE */
#include "periodic_task.h"
2020-04-26 14:07:39 -07:00
2019-09-21 12:43:18 -07:00
#if ! EFI_UNIT_TEST
2019-09-21 12:33:13 -07:00
#include "init.h"
2023-11-24 15:38:17 -08:00
#include "mpu_util.h"
#endif /* EFI_UNIT_TEST */
2019-09-21 12:43:18 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_PROD_CODE
2019-03-29 06:11:13 -07:00
#include "pwm_tester.h"
2016-08-20 20:02:09 -07:00
#endif /* EFI_PROD_CODE */
2015-07-10 06:01:56 -07:00
2020-03-22 21:01:59 -07:00
#if !EFI_UNIT_TEST
/**
2020-08-26 17:49:21 -07:00
* Would love to pass reference to configuration object into constructor but C++ does allow attributes after parenthesized initializer
2020-03-22 21:01:59 -07:00
*/
Engine ___engine CCM_OPTIONAL;
#else // EFI_UNIT_TEST
Engine * engine;
2020-03-22 21:01:59 -07:00
#endif /* EFI_UNIT_TEST */
void initDataStructures() {
#if EFI_ENGINE_CONTROL
initFuelMap();
initSpeedDensity();
#endif // EFI_ENGINE_CONTROL
2019-12-23 21:03:53 -08:00
}
2020-03-22 21:01:59 -07:00
#if !EFI_UNIT_TEST
2015-07-10 06:01:56 -07:00
static void doPeriodicSlowCallback();
2015-07-10 06:01:56 -07:00
class PeriodicFastController : public PeriodicTimerController {
void PeriodicTask() override {
engine->periodicFastCallback();
}
int getPeriodMs() override {
return FAST_CALLBACK_PERIOD_MS;
}
};
class PeriodicSlowController : public PeriodicTimerController {
void PeriodicTask() override {
doPeriodicSlowCallback();
}
int getPeriodMs() override {
2020-06-13 19:46:10 -07:00
// no reason to have this configurable, looks like everyone is happy with 20Hz
return SLOW_CALLBACK_PERIOD_MS;
}
};
static PeriodicFastController fastController;
static PeriodicSlowController slowController;
2015-07-10 06:01:56 -07:00
class EngineStateBlinkingTask : public PeriodicTimerController {
int getPeriodMs() override {
return 50;
}
void PeriodicTask() override {
#if EFI_SHAFT_POSITION_INPUT
bool is_running = engine->rpmCalculator.isRunning();
#else
bool is_running = false;
2020-03-22 21:01:59 -07:00
#endif /* EFI_SHAFT_POSITION_INPUT */
2015-07-10 06:01:56 -07:00
if (is_running) {
// blink in running mode
enginePins.runningLedPin.toggle();
2015-07-10 06:01:56 -07:00
} else {
int is_cranking = engine->rpmCalculator.isCranking();
2018-07-26 12:51:06 -07:00
enginePins.runningLedPin.setValue(is_cranking);
2015-07-10 06:01:56 -07:00
}
}
};
static EngineStateBlinkingTask engineStateBlinkingTask;
2015-07-10 06:01:56 -07:00
static void resetAccel() {
engine->tpsAccelEnrichment.resetAE();
2023-05-23 21:52:52 -07:00
#if EFI_ENGINE_CONTROL
for (size_t i = 0; i < efi::size(engine->injectionEvents.elements); i++)
2019-10-16 21:06:54 -07:00
{
2023-10-12 21:23:09 -07:00
engine->injectionEvents.elements[i].getWallFuel().resetWF();
2019-10-16 21:06:54 -07:00
}
2023-05-23 21:52:52 -07:00
#endif // EFI_ENGINE_CONTROL
2016-01-08 12:01:38 -08:00
}
static void doPeriodicSlowCallback() {
#if EFI_SHAFT_POSITION_INPUT
efiAssertVoid(ObdCode::CUSTOM_ERR_6661, getCurrentRemainingStack() > 64, "lowStckOnEv");
slowStartStopButtonCallback();
engine->rpmCalculator.onSlowCallback();
if (engine->rpmCalculator.isStopped()) {
resetAccel();
}
2017-07-06 16:33:25 -07:00
if (engine->versionForConfigurationListeners.isOld(engine->getGlobalConfigurationVersion())) {
updateAccelParameters();
}
#endif /* EFI_SHAFT_POSITION_INPUT */
engine->periodicSlowCallback();
#if EFI_SHAFT_POSITION_INPUT
if (engine->triggerCentral.directSelfStimulation || engine->rpmCalculator.isStopped()) {
/**
* rusEfi usually runs on hardware which halts execution while writing to internal flash, so we
* postpone writes to until engine is stopped. Writes in case of self-stimulation are fine.
*
* todo: allow writing if 2nd bank of flash is used
*/
#if (EFI_STORAGE_INT_FLASH == TRUE) || (EFI_STORAGE_MFS == TRUE)
2015-07-10 06:01:56 -07:00
writeToFlashIfPending();
#endif /* (EFI_STORAGE_INT_FLASH == TRUE) || (EFI_STORAGE_MFS == TRUE) */
}
2023-11-08 19:21:13 -08:00
#else /* if EFI_SHAFT_POSITION_INPUT */
#if (EFI_STORAGE_INT_FLASH == TRUE) || (EFI_STORAGE_MFS == TRUE)
2023-09-06 14:48:59 -07:00
writeToFlashIfPending();
#endif /* (EFI_STORAGE_INT_FLASH == TRUE) || (EFI_STORAGE_MFS == TRUE) */
#endif /* EFI_SHAFT_POSITION_INPUT */
#if EFI_TCU
if (engineConfiguration->tcuEnabled && engineConfiguration->gearControllerMode != GearControllerMode::None) {
if (engine->gearController == NULL) {
initGearController();
} else if (engine->gearController->getMode() != engineConfiguration->gearControllerMode) {
initGearController();
}
engine->gearController->update();
}
#endif // EFI_TCU
2023-11-24 15:15:50 -08:00
tryResetWatchdog();
2015-07-10 06:01:56 -07:00
}
void initPeriodicEvents() {
2022-07-21 12:17:32 -07:00
slowController.start();
fastController.start();
2015-07-10 06:01:56 -07:00
}
2016-12-27 11:04:04 -08:00
char * getPinNameByAdcChannel(const char *msg, adc_channel_e hwChannel, char *buffer) {
2019-04-12 19:07:03 -07:00
#if HAL_USE_ADC
if (!isAdcChannelValid(hwChannel)) {
2016-12-27 11:04:04 -08:00
strcpy(buffer, "NONE");
} else {
strcpy(buffer, portname(getAdcChannelPort(msg, hwChannel)));
2016-12-27 11:04:04 -08:00
itoa10(&buffer[2], getAdcChannelPin(hwChannel));
}
2015-07-10 06:01:56 -07:00
#else
strcpy(buffer, "NONE");
2020-03-22 21:01:59 -07:00
#endif /* HAL_USE_ADC */
return buffer;
2015-07-10 06:01:56 -07:00
}
2019-04-12 19:07:03 -07:00
#if HAL_USE_ADC
2015-07-10 06:01:56 -07:00
extern AdcDevice fastAdc;
2020-03-22 21:01:59 -07:00
#endif /* HAL_USE_ADC */
2015-07-10 06:01:56 -07:00
2024-03-15 11:42:01 -07:00
#if EFI_PROD_CODE
static void printSensorInfo() {
#if HAL_USE_ADC
// Print info about analog mappings
AdcSubscription::PrintInfo();
#endif // HAL_USE_ADC
2020-03-23 20:16:57 -07:00
// Print info about all sensors
Sensor::showAllSensorInfo();
2015-07-10 06:01:56 -07:00
}
2024-03-15 11:42:01 -07:00
#endif // EFI_PROD_CODE
2015-07-10 06:01:56 -07:00
#define isOutOfBounds(offset) ((offset<0) || (offset) >= (int) sizeof(engine_configuration_s))
static void getShort(int offset) {
if (isOutOfBounds(offset))
return;
uint16_t *ptr = (uint16_t *) (&((char *) engineConfiguration)[offset]);
uint16_t value = *ptr;
/**
2019-05-02 14:52:48 -07:00
* this response is part of rusEfi console API
2015-07-10 06:01:56 -07:00
*/
efiPrintf("short%s%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, value);
}
static void getByte(int offset) {
if (isOutOfBounds(offset))
return;
uint8_t *ptr = (uint8_t *) (&((char *) engineConfiguration)[offset]);
uint8_t value = *ptr;
/**
2019-05-02 14:52:48 -07:00
* this response is part of rusEfi console API
*/
efiPrintf("byte%s%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, value);
2015-07-10 06:01:56 -07:00
}
static void setBit(const char *offsetStr, const char *bitStr, const char *valueStr) {
int offset = atoi(offsetStr);
2022-10-27 19:17:50 -07:00
if (absI(offset) == absI(ATOI_ERROR_CODE)) {
efiPrintf("invalid offset [%s]", offsetStr);
2015-07-10 06:01:56 -07:00
return;
}
if (isOutOfBounds(offset)) {
return;
}
int bit = atoi(bitStr);
2022-10-27 19:17:50 -07:00
if (absI(bit) == absI(ATOI_ERROR_CODE)) {
efiPrintf("invalid bit [%s]", bitStr);
2015-07-10 06:01:56 -07:00
return;
}
int value = atoi(valueStr);
2022-10-27 19:17:50 -07:00
if (absI(value) == absI(ATOI_ERROR_CODE)) {
efiPrintf("invalid value [%s]", valueStr);
2015-07-10 06:01:56 -07:00
return;
}
int *ptr = (int *) (&((char *) engineConfiguration)[offset]);
*ptr ^= (-value ^ *ptr) & (1 << bit);
/**
2019-05-02 14:52:48 -07:00
* this response is part of rusEfi console API
2015-07-10 06:01:56 -07:00
*/
efiPrintf("bit%s%d/%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, bit, value);
2023-04-19 19:09:48 -07:00
incrementGlobalConfigurationVersion("setBit");
2015-07-10 06:01:56 -07:00
}
static void setShort(const int offset, const int value) {
if (isOutOfBounds(offset))
return;
uint16_t *ptr = (uint16_t *) (&((char *) engineConfiguration)[offset]);
*ptr = (uint16_t) value;
getShort(offset);
2023-04-19 19:09:48 -07:00
incrementGlobalConfigurationVersion("setShort");
2015-07-10 06:01:56 -07:00
}
static void setByte(const int offset, const int value) {
if (isOutOfBounds(offset))
return;
uint8_t *ptr = (uint8_t *) (&((char *) engineConfiguration)[offset]);
*ptr = (uint8_t) value;
getByte(offset);
2023-04-19 19:09:48 -07:00
incrementGlobalConfigurationVersion("setByte");
}
2015-07-10 06:01:56 -07:00
static void getBit(int offset, int bit) {
if (isOutOfBounds(offset))
return;
int *ptr = (int *) (&((char *) engineConfiguration)[offset]);
int value = (*ptr >> bit) & 1;
/**
2019-05-02 14:52:48 -07:00
* this response is part of rusEfi console API
2015-07-10 06:01:56 -07:00
*/
efiPrintf("bit%s%d/%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, bit, value);
2015-07-10 06:01:56 -07:00
}
static void getInt(int offset) {
if (isOutOfBounds(offset))
return;
int *ptr = (int *) (&((char *) engineConfiguration)[offset]);
int value = *ptr;
/**
2019-05-02 14:52:48 -07:00
* this response is part of rusEfi console API
2015-07-10 06:01:56 -07:00
*/
efiPrintf("int%s%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, value);
2015-07-10 06:01:56 -07:00
}
static void setInt(const int offset, const int value) {
if (isOutOfBounds(offset))
return;
int *ptr = (int *) (&((char *) engineConfiguration)[offset]);
*ptr = value;
getInt(offset);
2023-04-19 19:09:48 -07:00
incrementGlobalConfigurationVersion("setInt");
2015-07-10 06:01:56 -07:00
}
static void getFloat(int offset) {
if (isOutOfBounds(offset))
return;
float *ptr = (float *) (&((char *) engineConfiguration)[offset]);
float value = *ptr;
/**
2019-05-02 14:52:48 -07:00
* this response is part of rusEfi console API
2015-07-10 06:01:56 -07:00
*/
efiPrintf("float%s%d is %.5f", CONSOLE_DATA_PROTOCOL_TAG, offset, value);
2015-07-10 06:01:56 -07:00
}
static void setFloat(const char *offsetStr, const char *valueStr) {
int offset = atoi(offsetStr);
2022-10-27 19:17:50 -07:00
if (absI(offset) == absI(ATOI_ERROR_CODE)) {
efiPrintf("invalid offset [%s]", offsetStr);
2015-07-10 06:01:56 -07:00
return;
}
if (isOutOfBounds(offset))
return;
float value = atoff(valueStr);
if (cisnan(value)) {
efiPrintf("invalid value [%s]", valueStr);
2015-07-10 06:01:56 -07:00
return;
}
float *ptr = (float *) (&((char *) engineConfiguration)[offset]);
2015-07-10 06:01:56 -07:00
*ptr = value;
getFloat(offset);
2023-04-19 19:09:48 -07:00
incrementGlobalConfigurationVersion("setFloat");
2015-07-10 06:01:56 -07:00
}
static void initConfigActions() {
2015-07-10 06:01:56 -07:00
addConsoleActionSS("set_float", (VoidCharPtrCharPtr) setFloat);
addConsoleActionII("set_int", (VoidIntInt) setInt);
addConsoleActionII("set_short", (VoidIntInt) setShort);
addConsoleActionII("set_byte", (VoidIntInt) setByte);
2015-07-10 06:01:56 -07:00
addConsoleActionSSS("set_bit", setBit);
2015-07-10 06:01:56 -07:00
addConsoleActionI("get_float", getFloat);
addConsoleActionI("get_int", getInt);
addConsoleActionI("get_short", getShort);
addConsoleActionI("get_byte", getByte);
2015-07-10 06:01:56 -07:00
addConsoleActionII("get_bit", getBit);
}
2019-12-23 19:30:58 -08:00
#endif /* EFI_UNIT_TEST */
2015-07-10 06:01:56 -07:00
// one-time start-up
2019-12-23 19:30:58 -08:00
// this method is used by real firmware and simulator and unit test
void commonInitEngineController() {
#if EFI_PROD_CODE
addConsoleAction("sensorinfo", printSensorInfo);
addConsoleAction("reset_accel", resetAccel);
#endif /* EFI_PROD_CODE */
initInterpolation();
2019-12-23 19:40:23 -08:00
2022-11-28 23:21:36 -08:00
#if EFI_SIMULATOR || EFI_UNIT_TEST
2018-01-30 11:53:13 -08:00
printf("commonInitEngineController\n");
#endif
2019-12-23 19:30:58 -08:00
#if !EFI_UNIT_TEST
2015-07-10 06:01:56 -07:00
initConfigActions();
2019-12-23 19:30:58 -08:00
#endif /* EFI_UNIT_TEST */
2019-12-23 20:32:43 -08:00
#if EFI_ENGINE_CONTROL
/**
* This has to go after 'enginePins.startPins()' in order to
2019-12-23 20:32:43 -08:00
* properly detect un-assigned output pins
*/
2022-09-13 22:24:19 -07:00
prepareOutputSignals();
engine->injectionEvents.addFuelEvents();
#endif // EFI_ENGINE_CONTROL
2019-12-23 20:32:43 -08:00
2019-04-12 19:07:03 -07:00
#if EFI_SENSOR_CHART
2016-05-28 16:02:28 -07:00
initSensorChart();
#endif /* EFI_SENSOR_CHART */
2019-12-23 19:30:58 -08:00
#if EFI_PROD_CODE || EFI_SIMULATOR
initSettings();
2015-07-10 06:01:56 -07:00
if (hasFirmwareError()) {
return;
}
2019-12-23 19:30:58 -08:00
#endif
2023-10-14 12:59:33 -07:00
#if ! EFI_UNIT_TEST && EFI_ENGINE_CONTROL
initBenchTest();
#endif /* ! EFI_UNIT_TEST && EFI_ENGINE_CONTROL */
#if EFI_ALTERNATOR_CONTROL
initAlternatorCtrl();
#endif /* EFI_ALTERNATOR_CONTROL */
#if EFI_VVT_PID
initVvtActuators();
#endif /* EFI_VVT_PID */
#if EFI_MALFUNCTION_INDICATOR
initMalfunctionIndicator();
#endif /* EFI_MALFUNCTION_INDICATOR */
2020-04-26 14:50:03 -07:00
#if !EFI_UNIT_TEST
// This is tested independently - don't configure sensors for tests.
// This lets us selectively mock them for each test.
initNewSensors();
2020-04-26 14:50:03 -07:00
#endif /* EFI_UNIT_TEST */
initSensors();
2020-04-26 14:50:03 -07:00
initAccelEnrichment();
2020-04-26 14:50:03 -07:00
2022-07-14 04:52:58 -07:00
initScriptImpl();
2020-04-26 14:50:03 -07:00
initGpPwm();
2020-04-26 14:50:03 -07:00
#if EFI_IDLE_CONTROL
startIdleThread();
2020-04-26 14:50:03 -07:00
#endif /* EFI_IDLE_CONTROL */
#if EFI_TCU
initGearController();
#endif
initButtonDebounce();
2020-04-26 14:50:03 -07:00
#if EFI_ELECTRONIC_THROTTLE_BODY
initElectronicThrottle();
2020-04-26 14:50:03 -07:00
#endif /* EFI_ELECTRONIC_THROTTLE_BODY */
#if EFI_MAP_AVERAGING
if (engineConfiguration->isMapAveragingEnabled) {
initMapAveraging();
2020-04-26 14:50:03 -07:00
}
#endif /* EFI_MAP_AVERAGING */
#if EFI_BOOST_CONTROL
initBoostCtrl();
2020-04-26 14:50:03 -07:00
#endif /* EFI_BOOST_CONTROL */
#if EFI_LAUNCH_CONTROL
initLaunchControl();
#endif
2024-02-03 14:02:30 -08:00
initIgnitionAdvanceControl();
#if EFI_UNIT_TEST
engine->rpmCalculator.Register();
#endif /* EFI_UNIT_TEST */
2019-12-23 20:25:08 -08:00
#if (EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT) || EFI_SIMULATOR || EFI_UNIT_TEST
2023-03-13 13:25:45 -07:00
initAuxValves();
2019-12-23 20:25:08 -08:00
#endif /* EFI_ENGINE_CONTROL */
initTachometer();
2023-10-15 14:59:39 -07:00
initSpeedometer();
2016-01-12 19:01:53 -08:00
}
2021-08-16 03:59:43 -07:00
// Returns false if there's an obvious problem with the loaded configuration
bool validateConfig() {
if (engineConfiguration->cylindersCount > MAX_CYLINDER_COUNT) {
criticalError("Invalid cylinder count: %d", engineConfiguration->cylindersCount);
2021-08-16 03:59:43 -07:00
return false;
}
ensureArrayIsAscending("Batt Lag", engineConfiguration->injector.battLagCorrBins);
#if EFI_ENGINE_CONTROL
2021-08-16 03:59:43 -07:00
// Fueling
{
ensureArrayIsAscending("VE load", config->veLoadBins);
ensureArrayIsAscending("VE RPM", config->veRpmBins);
ensureArrayIsAscending("Lambda/AFR load", config->lambdaLoadBins);
ensureArrayIsAscending("Lambda/AFR RPM", config->lambdaRpmBins);
ensureArrayIsAscending("Fuel CLT mult", config->cltFuelCorrBins);
ensureArrayIsAscending("Fuel IAT mult", config->iatFuelCorrBins);
ensureArrayIsAscending("Injection phase load", config->injPhaseLoadBins);
ensureArrayIsAscending("Injection phase RPM", config->injPhaseRpmBins);
ensureArrayIsAscendingOrDefault("Fuel Level Sensor", config->fuelLevelBins);
2023-11-13 15:34:46 -08:00
ensureArrayIsAscendingOrDefault("Fuel Trim Rpm", config->fuelTrimRpmBins);
ensureArrayIsAscendingOrDefault("Fuel Trim Load", config->fuelTrimLoadBins);
2023-06-06 16:26:21 -07:00
ensureArrayIsAscendingOrDefault("TC slip", engineConfiguration->tractionControlSlipBins);
ensureArrayIsAscendingOrDefault("TC speed", engineConfiguration->tractionControlSpeedBins);
2021-08-16 03:59:43 -07:00
ensureArrayIsAscending("TPS/TPS AE from", config->tpsTpsAccelFromRpmBins);
ensureArrayIsAscending("TPS/TPS AE to", config->tpsTpsAccelToRpmBins);
ensureArrayIsAscendingOrDefault("TPS TPS RPM correction", config->tpsTspCorrValuesBins);
ensureArrayIsAscendingOrDefault("Staging Load", config->injectorStagingLoadBins);
ensureArrayIsAscendingOrDefault("Staging RPM", config->injectorStagingRpmBins);
2021-08-16 03:59:43 -07:00
}
// Ignition
{
ensureArrayIsAscending("Dwell RPM", config->sparkDwellRpmBins);
2021-08-16 03:59:43 -07:00
ensureArrayIsAscending("Ignition load", config->ignitionLoadBins);
ensureArrayIsAscending("Ignition RPM", config->ignitionRpmBins);
2023-11-13 15:34:46 -08:00
ensureArrayIsAscendingOrDefault("Ign Trim Rpm", config->ignTrimRpmBins);
ensureArrayIsAscendingOrDefault("Ign Trim Load", config->ignTrimLoadBins);
2021-08-16 03:59:43 -07:00
ensureArrayIsAscending("Ignition CLT corr", config->cltTimingBins);
2021-08-16 03:59:43 -07:00
2023-01-07 14:48:43 -08:00
ensureArrayIsAscending("Ignition IAT corr IAT", config->ignitionIatCorrTempBins);
ensureArrayIsAscending("Ignition IAT corr Load", config->ignitionIatCorrLoadBins);
2021-08-16 03:59:43 -07:00
}
ensureArrayIsAscendingOrDefault("Map estimate TPS", config->mapEstimateTpsBins);
ensureArrayIsAscendingOrDefault("Map estimate RPM", config->mapEstimateRpmBins);
#endif // EFI_ENGINE_CONTROL
2021-08-16 03:59:43 -07:00
ensureArrayIsAscendingOrDefault("Script Curve 1", config->scriptCurve1Bins);
ensureArrayIsAscendingOrDefault("Script Curve 2", config->scriptCurve2Bins);
ensureArrayIsAscendingOrDefault("Script Curve 3", config->scriptCurve3Bins);
ensureArrayIsAscendingOrDefault("Script Curve 4", config->scriptCurve4Bins);
ensureArrayIsAscendingOrDefault("Script Curve 5", config->scriptCurve5Bins);
ensureArrayIsAscendingOrDefault("Script Curve 6", config->scriptCurve6Bins);
// todo: huh? why does this not work on CI? ensureArrayIsAscendingOrDefault("Dwell Correction Voltage", engineConfiguration->dwellVoltageCorrVoltBins);
2021-08-16 04:21:07 -07:00
ensureArrayIsAscending("MAF decoding", config->mafDecodingBins);
2021-08-16 03:59:43 -07:00
// Cranking tables
ensureArrayIsAscending("Cranking fuel mult", config->crankingFuelBins);
ensureArrayIsAscending("Cranking duration", config->crankingCycleBins);
ensureArrayIsAscending("Cranking TPS", config->crankingTpsBins);
2021-08-16 03:59:43 -07:00
// Idle tables
ensureArrayIsAscending("Idle target RPM", config->cltIdleRpmBins);
2021-08-16 03:59:43 -07:00
ensureArrayIsAscending("Idle warmup mult", config->cltIdleCorrBins);
ensureArrayIsAscendingOrDefault("Idle coasting RPM", config->iacCoastingRpmBins);
ensureArrayIsAscendingOrDefault("Idle VE RPM", config->idleVeRpmBins);
ensureArrayIsAscendingOrDefault("Idle VE Load", config->idleVeLoadBins);
ensureArrayIsAscendingOrDefault("Idle timing", config->idleAdvanceBins);
2021-08-16 04:21:07 -07:00
for (size_t index = 0; index < efi::size(engineConfiguration->vrThreshold); index++) {
auto& cfg = engineConfiguration->vrThreshold[index];
2021-09-18 19:12:22 -07:00
if (cfg.pin == Gpio::Unassigned) {
2021-09-18 19:12:22 -07:00
continue;
}
ensureArrayIsAscending("VR Bins", cfg.rpmBins);
}
2021-08-16 03:59:43 -07:00
2022-02-06 16:17:22 -08:00
#if EFI_BOOST_CONTROL
2021-08-16 03:59:43 -07:00
// Boost
ensureArrayIsAscending("Boost control TPS", config->boostTpsBins);
ensureArrayIsAscending("Boost control RPM", config->boostRpmBins);
2022-02-06 16:17:22 -08:00
#endif // EFI_BOOST_CONTROL
2021-08-16 03:59:43 -07:00
#if EFI_ANTILAG_SYSTEM
// ALS
ensureArrayIsAscendingOrDefault("ign ALS TPS", config->alsIgnRetardLoadBins);
ensureArrayIsAscendingOrDefault("ign ALS RPM", config->alsIgnRetardrpmBins);
ensureArrayIsAscendingOrDefault("fuel ALS TPS", config->alsFuelAdjustmentLoadBins);
ensureArrayIsAscendingOrDefault("fuel ALS RPM", config->alsFuelAdjustmentrpmBins);
#endif // EFI_ANTILAG_SYSTEM
#if EFI_ELECTRONIC_THROTTLE_BODY
2021-08-16 03:59:43 -07:00
// ETB
ensureArrayIsAscending("Pedal map pedal", config->pedalToTpsPedalBins);
ensureArrayIsAscending("Pedal map RPM", config->pedalToTpsRpmBins);
#endif // EFI_ELECTRONIC_THROTTLE_BODY
2021-08-16 03:59:43 -07:00
if (isGdiEngine()) {
ensureArrayIsAscending("HPFP compensation", config->hpfpCompensationRpmBins);
ensureArrayIsAscending("HPFP deadtime", config->hpfpDeadtimeVoltsBins);
ensureArrayIsAscending("HPFP lobe profile", config->hpfpLobeProfileQuantityBins);
ensureArrayIsAscending("HPFP target rpm", config->hpfpTargetRpmBins);
ensureArrayIsAscending("HPFP target load", config->hpfpTargetLoadBins);
2021-12-31 16:08:47 -08:00
}
2021-08-16 03:59:43 -07:00
// VVT
if (isBrainPinValid(engineConfiguration->camInputs[0])) {
ensureArrayIsAscending("VVT intake load", config->vvtTable1LoadBins);
ensureArrayIsAscending("VVT intake RPM", config->vvtTable1RpmBins);
}
#if CAM_INPUTS_COUNT != 1
if (isBrainPinValid(engineConfiguration->camInputs[1])) {
ensureArrayIsAscending("VVT exhaust load", config->vvtTable2LoadBins);
ensureArrayIsAscending("VVT exhaust RPM", config->vvtTable2RpmBins);
}
#endif
2021-08-16 03:59:43 -07:00
return true;
}
2019-12-23 19:30:58 -08:00
#if !EFI_UNIT_TEST
void commonEarlyInit() {
// Start this early - it will start LED blinking and such
startStatusThreads();
#if EFI_SHAFT_POSITION_INPUT
// todo: figure out better startup logic
initTriggerCentral();
#endif /* EFI_SHAFT_POSITION_INPUT */
/**
* Initialize hardware drivers
*/
initHardware();
2024-01-19 16:04:48 -08:00
initQcBenchControls();
2023-11-24 22:41:39 -08:00
#if EFI_FILE_LOGGING
initMmcCard();
#endif /* EFI_FILE_LOGGING */
#if EFI_ENGINE_EMULATOR
initEngineEmulator();
#endif
#if EFI_LUA
startLua();
#endif // EFI_LUA
#if EFI_CAN_SERIAL
// needs to be called after initCan() inside initHardware()
startCanConsole();
#endif /* EFI_CAN_SERIAL */
#if HW_CHECK_ALWAYS_STIMULATE
// we need a special binary for final assembly check. We cannot afford to require too much software or too many steps
// to be executed at the place of assembly
2023-04-19 17:29:33 -07:00
enableTriggerStimulator(/*incGlobalConfiguration*/false);
#endif // HW_CHECK_ALWAYS_STIMULATE
}
// one-time start-up
void initRealHardwareEngineController() {
commonInitEngineController();
initWarningRunningPins();
2016-01-12 19:01:53 -08:00
#if EFI_LOGIC_ANALYZER
2015-07-10 06:01:56 -07:00
if (engineConfiguration->isWaveAnalyzerEnabled) {
initWaveAnalyzer();
2015-07-10 06:01:56 -07:00
}
#endif /* EFI_LOGIC_ANALYZER */
2015-07-10 06:01:56 -07:00
2016-06-01 17:01:36 -07:00
if (hasFirmwareError()) {
return;
}
2022-07-21 12:17:32 -07:00
engineStateBlinkingTask.start();
2015-07-10 06:01:56 -07:00
initVrThresholdPwm();
2019-04-12 19:07:03 -07:00
#if EFI_PWM_TESTER
2015-07-10 06:01:56 -07:00
initPwmTester();
2017-03-19 14:42:15 -07:00
#endif /* EFI_PWM_TESTER */
2015-07-10 06:01:56 -07:00
}
2018-03-24 18:13:08 -07:00
2020-05-03 09:40:43 -07:00
/**
* these two variables are here only to let us know how much RAM is available, also these
* help to notice when RAM usage goes up - if a code change adds to RAM usage these variables would fail
* linking process which is the way to raise the alarm
*
* You get "cannot move location counter backwards" linker error when you run out of RAM. When you run out of RAM you shall reduce these
2020-08-02 14:21:07 -07:00
* UNUSED_SIZE constants.
2020-05-03 09:40:43 -07:00
*/
2019-02-06 20:30:53 -08:00
#ifndef RAM_UNUSED_SIZE
2022-10-21 09:10:31 -07:00
#define RAM_UNUSED_SIZE 30000
2019-02-06 20:30:53 -08:00
#endif
#ifndef CCM_UNUSED_SIZE
2022-10-21 09:22:08 -07:00
#define CCM_UNUSED_SIZE 512
2019-02-06 20:30:53 -08:00
#endif
2023-11-17 09:06:21 -08:00
static volatile char UNUSED_RAM_SIZE[RAM_UNUSED_SIZE];
static volatile char UNUSED_CCM_SIZE[CCM_UNUSED_SIZE] CCM_OPTIONAL;
2018-03-24 18:13:08 -07:00
/**
* See also VCS_VERSION
*/
int getRusEfiVersion(void) {
if (UNUSED_RAM_SIZE[0] != 0)
return 123; // this is here to make the compiler happy about the unused array
if (UNUSED_CCM_SIZE[0] * 0 != 0)
return 3211; // this is here to make the compiler happy about the unused array
2019-04-12 19:07:03 -07:00
#if defined(EFI_BOOTLOADER_INCLUDE_CODE)
2018-03-24 18:13:08 -07:00
// make bootloader code happy too
if (initBootloader() != 0)
return 123;
#endif /* EFI_BOOTLOADER_INCLUDE_CODE */
return VCS_DATE;
2018-03-24 18:13:08 -07:00
}
#endif /* EFI_UNIT_TEST */