rusefi/firmware/controllers/engine_controller.cpp

732 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/>.
*/
2018-09-16 19:26:57 -07:00
#include "global.h"
#include "os_access.h"
2015-07-10 06:01:56 -07:00
#include "trigger_central.h"
#include "engine_controller.h"
#include "fsio_core.h"
#include "fsio_impl.h"
#include "idle_thread.h"
2019-12-23 21:03:53 -08:00
#include "advance_map.h"
2015-07-10 06:01:56 -07:00
#include "rpm_calculator.h"
#include "main_trigger_callback.h"
#include "io_pins.h"
#include "flash_main.h"
#include "bench_test.h"
2019-07-06 17:15:49 -07:00
#include "os_util.h"
2015-07-10 06:01:56 -07:00
#include "engine_math.h"
#include "allsensors.h"
#include "electronic_throttle.h"
#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"
2015-07-10 06:01:56 -07:00
#include "fuel_math.h"
#include "settings.h"
2016-06-27 19:02:41 -07:00
#include "aux_pid.h"
2019-12-23 21:26:23 -08:00
#include "spark_logic.h"
#include "aux_valves.h"
2017-08-28 17:11:32 -07:00
#include "accelerometer.h"
2019-10-11 17:43:21 -07:00
#include "perf_trace.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"
#include "gppwm.h"
#include "date_stamp.h"
#include "buttonshift.h"
#include "start_stop.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"
#endif /* EFI_UNIT_TEST */
2019-09-21 12:43:18 -07:00
2020-04-26 14:07:39 -07:00
#include "adc_inputs.h"
2020-04-26 14:40:12 -07:00
#include "pwm_generator_logic.h"
2020-04-26 14:07:39 -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"
2015-07-10 06:01:56 -07:00
#include "lcd_controller.h"
#include "pin_repository.h"
2016-08-20 20:02:09 -07:00
#endif /* EFI_PROD_CODE */
2015-07-10 06:01:56 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_CJ125
#include "cj125.h"
#endif /* EFI_CJ125 */
2018-11-03 06:44:34 -07:00
EXTERN_ENGINE;
2020-03-22 21:01:59 -07:00
#if !EFI_UNIT_TEST
static LoggingWithStorage logger("Engine Controller");
/**
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;
Engine * engine = &___engine;
#endif /* EFI_UNIT_TEST */
2019-12-23 21:03:53 -08:00
void initDataStructures(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
#if EFI_ENGINE_CONTROL
2019-12-23 21:03:53 -08:00
initFuelMap(PASS_ENGINE_PARAMETER_SIGNATURE);
initTimingMap(PASS_ENGINE_PARAMETER_SIGNATURE);
initSpeedDensity(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif // EFI_ENGINE_CONTROL
2019-12-23 21:03:53 -08:00
}
2019-09-19 21:34:42 -07:00
#if EFI_ENABLE_MOCK_ADC
2020-03-22 21:01:59 -07:00
static void initMockVoltage(void) {
#if EFI_SIMULATOR
setMockCltVoltage(2);
setMockIatVoltage(2);
#endif /* EFI_SIMULATOR */
2019-09-19 21:34:42 -07:00
}
2020-03-22 21:01:59 -07:00
#endif /* EFI_ENABLE_MOCK_ADC */
2015-07-10 06:01:56 -07:00
2020-03-22 21:01:59 -07:00
#if !EFI_UNIT_TEST
2015-07-10 06:01:56 -07:00
static void doPeriodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE);
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(PASS_ENGINE_PARAMETER_SIGNATURE);
}
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 {
counter++;
#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.setValue(counter % 2);
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
}
}
private:
int counter = 0;
};
static EngineStateBlinkingTask engineStateBlinkingTask;
2015-07-10 06:01:56 -07:00
2016-02-05 13:01:55 -08:00
/**
* number of SysClock ticks in one ms
*/
2017-03-21 11:58:14 -07:00
#define TICKS_IN_MS (CH_CFG_ST_FREQUENCY / 1000)
2016-02-05 13:01:55 -08:00
// todo: this overflows pretty fast!
2015-07-10 06:01:56 -07:00
efitimems_t currentTimeMillis(void) {
// todo: migrate to getTimeNowUs? or not?
2017-03-21 11:58:14 -07:00
return chVTGetSystemTimeX() / TICKS_IN_MS;
2015-07-10 06:01:56 -07:00
}
2016-02-05 13:01:55 -08:00
// todo: this overflows pretty fast!
2016-07-14 20:02:55 -07:00
efitimesec_t getTimeNowSeconds(void) {
2016-02-05 13:01:55 -08:00
return currentTimeMillis() / 1000;
2015-07-10 06:01:56 -07:00
}
2016-01-08 12:01:38 -08:00
static void resetAccel(void) {
engine->engineLoadAccelEnrichment.resetAE();
engine->tpsAccelEnrichment.resetAE();
2019-10-16 21:06:54 -07:00
2020-07-20 00:55:45 -07:00
for (unsigned int i = 0; i < efi::size(engine->injectionEvents.elements); i++)
2019-10-16 21:06:54 -07:00
{
2020-07-20 00:55:45 -07:00
engine->injectionEvents.elements[i].wallFuel.resetWF();
2019-10-16 21:06:54 -07:00
}
2016-01-08 12:01:38 -08:00
}
2019-07-07 16:59:48 -07:00
static void doPeriodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
2020-03-22 21:01:59 -07:00
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
2019-02-23 09:33:49 -08:00
efiAssertVoid(CUSTOM_ERR_6661, getCurrentRemainingStack() > 64, "lowStckOnEv");
2015-07-10 06:01:56 -07:00
#if EFI_PROD_CODE
2020-03-23 07:32:41 -07:00
slowStartStopButtonCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
2020-04-01 18:22:54 -07:00
#endif /* EFI_PROD_CODE */
efitick_t nowNt = getTimeNowNt();
if (nowNt - engine->triggerCentral.vvtSyncTimeNt >= NT_PER_SECOND) {
// loss of VVT sync
engine->triggerCentral.vvtSyncTimeNt = 0;
}
2020-10-03 22:26:29 -07:00
// for performance reasons this assertion related to mainTriggerCallback should better be here
efiAssertVoid(CUSTOM_IGN_MATH_STATE, !CONFIG(useOnlyRisingEdgeForTrigger) || CONFIG(ignMathCalculateAtIndex) % 2 == 0, "invalid ignMathCalculateAtIndex");
2020-03-23 07:32:41 -07:00
2017-07-06 16:33:25 -07:00
/**
* Update engine RPM state if needed (check timeouts).
*/
bool isSpinning = engine->rpmCalculator.checkIfSpinning(nowNt PASS_ENGINE_PARAMETER_SUFFIX);
if (!isSpinning) {
engine->rpmCalculator.setStopSpinning(PASS_ENGINE_PARAMETER_SIGNATURE);
}
2017-07-06 16:33:25 -07:00
if (ENGINE(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
*/
2019-04-12 19:07:03 -07:00
#if EFI_INTERNAL_FLASH
2015-07-10 06:01:56 -07:00
writeToFlashIfPending();
2018-12-23 21:31:26 -08:00
#endif /* EFI_INTERNAL_FLASH */
2016-01-08 12:01:38 -08:00
resetAccel();
}
if (!engine->rpmCalculator.isStopped()) {
updatePrimeInjectionPulseState(PASS_ENGINE_PARAMETER_SIGNATURE);
2015-09-03 06:01:31 -07:00
}
2015-07-10 06:01:56 -07:00
if (engine->versionForConfigurationListeners.isOld(engine->getGlobalConfigurationVersion())) {
2016-01-31 13:01:26 -08:00
updateAccelParameters();
2015-07-10 06:01:56 -07:00
}
engine->periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
2020-03-22 21:01:59 -07:00
#endif /* if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT */
if (CONFIG(tcuEnabled)) {
engine->gearController->update();
}
2015-07-10 06:01:56 -07:00
}
2017-05-15 20:28:49 -07:00
void initPeriodicEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
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
2016-12-27 11:04:04 -08:00
if (hwChannel == EFI_ADC_NONE) {
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
}
static char pinNameBuffer[16];
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
static void printAnalogChannelInfoExt(const char *name, adc_channel_e hwChannel, float adcVoltage,
float dividerCoeff) {
2019-04-12 19:07:03 -07:00
#if HAL_USE_ADC
2015-07-10 06:01:56 -07:00
if (hwChannel == EFI_ADC_NONE) {
scheduleMsg(&logger, "ADC is not assigned for %s", name);
return;
}
float voltage = adcVoltage * dividerCoeff;
scheduleMsg(&logger, "%s ADC%d %s %s adc=%.2f/input=%.2fv/divider=%.2f", name, hwChannel, getAdc_channel_mode_e(getAdcMode(hwChannel)),
2016-12-27 11:04:04 -08:00
getPinNameByAdcChannel(name, hwChannel, pinNameBuffer), adcVoltage, voltage, dividerCoeff);
2020-03-22 21:01:59 -07:00
#endif /* HAL_USE_ADC */
2015-07-10 06:01:56 -07:00
}
static void printAnalogChannelInfo(const char *name, adc_channel_e hwChannel) {
2019-04-12 19:07:03 -07:00
#if HAL_USE_ADC
2020-08-23 14:21:08 -07:00
printAnalogChannelInfoExt(name, hwChannel, getVoltage(name, hwChannel PASS_ENGINE_PARAMETER_SUFFIX), engineConfiguration->analogInputDividerCoefficient);
2020-03-22 21:01:59 -07:00
#endif /* HAL_USE_ADC */
2015-07-10 06:01:56 -07:00
}
static void printAnalogInfo(void) {
2018-01-23 09:05:14 -08:00
scheduleMsg(&logger, "analogInputDividerCoefficient: %.2f", engineConfiguration->analogInputDividerCoefficient);
2015-07-10 06:01:56 -07:00
printAnalogChannelInfo("hip9011", engineConfiguration->hipOutputChannel);
printAnalogChannelInfo("fuel gauge", engineConfiguration->fuelLevelSensor);
2020-08-22 05:06:04 -07:00
printAnalogChannelInfo("TPS1 Primary", engineConfiguration->tps1_1AdcChannel);
printAnalogChannelInfo("TPS1 Secondary", engineConfiguration->tps1_2AdcChannel);
printAnalogChannelInfo("TPS2 Primary", engineConfiguration->tps2_1AdcChannel);
printAnalogChannelInfo("TPS2 Secondary", engineConfiguration->tps2_2AdcChannel);
printAnalogChannelInfo("LPF", engineConfiguration->lowPressureFuel.hwChannel);
printAnalogChannelInfo("HPF", engineConfiguration->highPressureFuel.hwChannel);
printAnalogChannelInfo("pPS1", engineConfiguration->throttlePedalPositionAdcChannel);
printAnalogChannelInfo("pPS2", engineConfiguration->throttlePedalPositionSecondAdcChannel);
printAnalogChannelInfo("CLT", engineConfiguration->clt.adcChannel);
printAnalogChannelInfo("IAT", engineConfiguration->iat.adcChannel);
2020-07-27 17:23:57 -07:00
printAnalogChannelInfo("AuxT1", engineConfiguration->auxTempSensor1.adcChannel);
printAnalogChannelInfo("AuxT2", engineConfiguration->auxTempSensor2.adcChannel);
printAnalogChannelInfo("MAF", engineConfiguration->mafAdcChannel);
2017-08-06 16:43:01 -07:00
for (int i = 0; i < FSIO_ANALOG_INPUT_COUNT ; i++) {
2016-05-15 21:02:01 -07:00
adc_channel_e ch = engineConfiguration->fsioAdc[i];
printAnalogChannelInfo("FSIO analog", ch);
2016-05-15 21:02:01 -07:00
}
2015-07-10 06:01:56 -07:00
printAnalogChannelInfo("AFR", engineConfiguration->afr.hwChannel);
printAnalogChannelInfo("MAP", engineConfiguration->map.sensor.hwChannel);
printAnalogChannelInfo("BARO", engineConfiguration->baroSensor.hwChannel);
printAnalogChannelInfo("extKno", engineConfiguration->externalKnockSenseAdc);
2015-07-10 06:01:56 -07:00
printAnalogChannelInfo("OilP", engineConfiguration->oilPressure.hwChannel);
2020-03-23 20:16:57 -07:00
printAnalogChannelInfo("CJ UR", engineConfiguration->cj125ur);
printAnalogChannelInfo("CJ UA", engineConfiguration->cj125ua);
2015-07-10 06:01:56 -07:00
printAnalogChannelInfo("HIP9011", engineConfiguration->hipOutputChannel);
2020-03-23 20:16:57 -07:00
printAnalogChannelInfoExt("Vbatt", engineConfiguration->vbattAdcChannel, getVoltage("vbatt", engineConfiguration->vbattAdcChannel PASS_ENGINE_PARAMETER_SUFFIX),
2015-07-10 06:01:56 -07:00
engineConfiguration->vbattDividerCoeff);
}
#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
*/
scheduleMsg(&logger, "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
*/
scheduleMsg(&logger, "byte%s%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, value);
2015-07-10 06:01:56 -07:00
}
static void onConfigurationChanged() {
#if EFI_TUNER_STUDIO
// on start-up rusEfi would read from working copy of TS while
// we have a lot of console commands which write into real copy of configuration directly
// we have a bit of a mess here
syncTunerStudioCopy();
#endif /* EFI_TUNER_STUDIO */
incrementGlobalConfigurationVersion(PASS_ENGINE_PARAMETER_SIGNATURE);
}
2015-07-10 06:01:56 -07:00
static void setBit(const char *offsetStr, const char *bitStr, const char *valueStr) {
int offset = atoi(offsetStr);
if (absI(offset) == absI(ERROR_CODE)) {
scheduleMsg(&logger, "invalid offset [%s]", offsetStr);
return;
}
if (isOutOfBounds(offset)) {
return;
}
int bit = atoi(bitStr);
if (absI(bit) == absI(ERROR_CODE)) {
scheduleMsg(&logger, "invalid bit [%s]", bitStr);
return;
}
int value = atoi(valueStr);
if (absI(value) == absI(ERROR_CODE)) {
scheduleMsg(&logger, "invalid value [%s]", valueStr);
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
*/
scheduleMsg(&logger, "bit%s%d/%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, bit, value);
onConfigurationChanged();
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);
onConfigurationChanged();
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);
onConfigurationChanged();
}
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
*/
scheduleMsg(&logger, "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
*/
scheduleMsg(&logger, "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);
onConfigurationChanged();
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
*/
scheduleMsg(&logger, "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);
if (absI(offset) == absI(ERROR_CODE)) {
scheduleMsg(&logger, "invalid offset [%s]", offsetStr);
return;
}
if (isOutOfBounds(offset))
return;
float value = atoff(valueStr);
if (cisnan(value)) {
scheduleMsg(&logger, "invalid value [%s]", valueStr);
return;
}
float *ptr = (float *) (&((char *) engineConfiguration)[offset]);
2015-07-10 06:01:56 -07:00
*ptr = value;
getFloat(offset);
onConfigurationChanged();
2015-07-10 06:01:56 -07:00
}
2016-01-12 19:01:53 -08:00
static void initConfigActions(void) {
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);
}
// todo: move this logic somewhere else?
static void getKnockInfo(void) {
adc_channel_e hwChannel = engineConfiguration->externalKnockSenseAdc;
2016-12-27 11:04:04 -08:00
scheduleMsg(&logger, "externalKnockSenseAdc on ADC", getPinNameByAdcChannel("knock", hwChannel, pinNameBuffer));
2015-07-10 06:01:56 -07:00
engine->printKnockState();
}
2019-12-23 19:30:58 -08:00
#endif /* EFI_UNIT_TEST */
2015-07-10 06:01:56 -07:00
2019-12-23 19:30:58 -08:00
// this method is used by real firmware and simulator and unit test
2017-05-15 20:28:49 -07:00
void commonInitEngineController(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
2019-12-23 19:40:23 -08:00
initInterpolation(sharedLogger);
2018-01-30 11:53:13 -08:00
#if EFI_SIMULATOR
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
*/
prepareShapes(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif /* EFI_PROD_CODE && EFI_ENGINE_CONTROL */
2019-12-23 19:30:58 -08:00
2019-01-31 08:57:15 -08:00
#if EFI_ENABLE_MOCK_ADC
2016-01-23 15:01:40 -08:00
initMockVoltage();
2019-01-31 08:57:15 -08:00
#endif /* EFI_ENABLE_MOCK_ADC */
2016-01-18 19:01:26 -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 */
2015-07-10 06:01:56 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_TUNER_STUDIO
startTunerStudioConnectivity();
#endif /* EFI_TUNER_STUDIO */
2015-07-10 06:01:56 -07:00
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
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(sharedLogger);
#endif /* EFI_UNIT_TEST */
initSensors(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
initAccelEnrichment(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
#if EFI_FSIO
initFsioImpl(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
#endif /* EFI_FSIO */
initGpPwm(PASS_ENGINE_PARAMETER_SIGNATURE);
#if EFI_IDLE_CONTROL
startIdleThread(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
#endif /* EFI_IDLE_CONTROL */
initButtonShift(PASS_ENGINE_PARAMETER_SIGNATURE);
initButtonDebounce(sharedLogger);
initStartStopButton(PASS_ENGINE_PARAMETER_SIGNATURE);
2020-04-26 14:50:03 -07:00
#if EFI_ELECTRONIC_THROTTLE_BODY
initElectronicThrottle(PASS_ENGINE_PARAMETER_SIGNATURE);
#endif /* EFI_ELECTRONIC_THROTTLE_BODY */
#if EFI_MAP_AVERAGING
if (engineConfiguration->isMapAveragingEnabled) {
initMapAveraging(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
}
#endif /* EFI_MAP_AVERAGING */
#if EFI_BOOST_CONTROL
initBoostCtrl(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
#endif /* EFI_BOOST_CONTROL */
#if EFI_LAUNCH_CONTROL
initLaunchControl(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
#endif
2019-12-23 19:50:04 -08:00
#if EFI_SHAFT_POSITION_INPUT
/**
* there is an implicit dependency on the fact that 'tachometer' listener is the 1st listener - this case
* other listeners can access current RPM value
*/
initRpmCalculator(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
#endif /* EFI_SHAFT_POSITION_INPUT */
2019-12-23 20:25:08 -08:00
#if (EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT) || EFI_SIMULATOR || EFI_UNIT_TEST
if (CONFIG(isEngineControlEnabled)) {
2019-12-23 21:26:23 -08:00
initAuxValves(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
2019-12-23 20:25:08 -08:00
/**
2019-12-23 21:26:23 -08:00
* This method adds trigger listener which actually schedules ignition
2019-12-23 20:25:08 -08:00
*/
2019-12-23 21:26:23 -08:00
initSparkLogic(sharedLogger);
2019-12-23 20:25:08 -08:00
initMainEventListener(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
2020-11-09 19:53:46 -08:00
#if EFI_HPFP
2020-11-05 13:42:56 -08:00
initHPFP(PASS_ENGINE_PARAMETER_SIGNATURE);
2020-11-09 19:53:23 -08:00
#endif // EFI_HPFP
2019-12-23 20:25:08 -08:00
}
#endif /* EFI_ENGINE_CONTROL */
2020-04-01 16:00:56 -07:00
initTachometer(PASS_ENGINE_PARAMETER_SIGNATURE);
2016-01-12 19:01:53 -08:00
}
2019-12-23 19:30:58 -08:00
#if !EFI_UNIT_TEST
2017-05-15 20:28:49 -07:00
void initEngineContoller(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
2016-01-12 19:01:53 -08:00
addConsoleAction("analoginfo", printAnalogInfo);
2019-12-23 20:32:43 -08:00
#if EFI_PROD_CODE && EFI_ENGINE_CONTROL
initBenchTest(sharedLogger);
2019-12-23 20:32:43 -08:00
#endif /* EFI_PROD_CODE && EFI_ENGINE_CONTROL */
2016-01-12 19:01:53 -08:00
commonInitEngineController(sharedLogger);
#if EFI_LOGIC_ANALYZER
2015-07-10 06:01:56 -07:00
if (engineConfiguration->isWaveAnalyzerEnabled) {
initWaveAnalyzer(sharedLogger);
}
#endif /* EFI_LOGIC_ANALYZER */
2015-07-10 06:01:56 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_CJ125
2018-01-22 09:24:03 -08:00
/**
* this uses SimplePwm which depends on scheduler, has to be initialized after scheduler
*/
2018-11-03 10:38:02 -07:00
initCJ125(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
2018-11-03 06:44:34 -07:00
#endif /* EFI_CJ125 */
2018-01-22 09:24:03 -08:00
2016-08-25 21:01:55 -07:00
// periodic events need to be initialized after fuel&spark pins to avoid a warning
2017-05-15 20:28:49 -07:00
initPeriodicEvents(PASS_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
2016-06-01 17:01:36 -07:00
if (hasFirmwareError()) {
return;
}
engineStateBlinkingTask.Start();
2015-07-10 06:01:56 -07:00
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
2019-04-12 19:07:03 -07:00
#if EFI_ALTERNATOR_CONTROL
initAlternatorCtrl(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
2020-03-23 17:44:34 -07:00
#endif /* EFI_ALTERNATOR_CONTROL */
2015-07-10 06:01:56 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_AUX_PID
2016-06-27 19:02:41 -07:00
initAuxPid(sharedLogger);
2020-03-23 17:44:34 -07:00
#endif /* EFI_AUX_PID */
2016-06-27 19:02:41 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_MALFUNCTION_INDICATOR
2016-12-27 21:02:03 -08:00
initMalfunctionIndicator();
2015-07-10 06:01:56 -07:00
#endif /* EFI_MALFUNCTION_INDICATOR */
initEgoAveraging(PASS_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
if (engineConfiguration->externalKnockSenseAdc != EFI_ADC_NONE) {
addConsoleAction("knockinfo", getKnockInfo);
}
2019-04-12 19:07:03 -07:00
#if EFI_PROD_CODE
2015-07-10 06:01:56 -07:00
addConsoleAction("reset_accel", resetAccel);
2017-03-19 14:42:15 -07:00
#endif /* EFI_PROD_CODE */
2015-07-10 06:01:56 -07:00
2019-04-12 19:07:03 -07:00
#if EFI_HD44780_LCD
2015-07-10 06:01:56 -07:00
initLcdController();
2017-03-19 14:42:15 -07:00
#endif /* EFI_HD44780_LCD */
2015-08-19 13:01:36 -07:00
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
2020-11-10 15:26:46 -08:00
#define RAM_UNUSED_SIZE 3400
2019-02-06 20:30:53 -08:00
#endif
#ifndef CCM_UNUSED_SIZE
2020-08-31 18:30:47 -07:00
#define CCM_UNUSED_SIZE 2900
2019-02-06 20:30:53 -08:00
#endif
static char UNUSED_RAM_SIZE[RAM_UNUSED_SIZE];
static 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 */