2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* @file engine_controller.cpp
|
|
|
|
* @brief Controllers package entry point code
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @date Feb 7, 2013
|
2019-07-09 05:33:40 -07:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2019
|
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"
|
2019-07-03 18:48:04 -07:00
|
|
|
#include "os_access.h"
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_SENSOR_CHART
|
2019-01-11 15:46:16 -08:00
|
|
|
#include "sensor_chart.h"
|
|
|
|
#endif
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "engine_configuration.h"
|
|
|
|
#include "trigger_central.h"
|
|
|
|
#include "engine_controller.h"
|
|
|
|
#include "fsio_core.h"
|
|
|
|
#include "fsio_impl.h"
|
|
|
|
#include "idle_thread.h"
|
|
|
|
#include "rpm_calculator.h"
|
|
|
|
#include "signal_executor.h"
|
|
|
|
#include "main_trigger_callback.h"
|
|
|
|
#include "io_pins.h"
|
|
|
|
#include "flash_main.h"
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_TUNER_STUDIO
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "tunerstudio.h"
|
2019-01-11 15:46:16 -08:00
|
|
|
#endif
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "injector_central.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"
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_WAVE_ANALYZER
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "wave_analyzer.h"
|
2019-01-11 15:46:16 -08:00
|
|
|
#endif
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "allsensors.h"
|
|
|
|
#include "electronic_throttle.h"
|
|
|
|
#include "map_averaging.h"
|
|
|
|
#include "malfunction_central.h"
|
|
|
|
#include "malfunction_indicator.h"
|
|
|
|
#include "engine.h"
|
|
|
|
#include "algo.h"
|
2019-03-31 13:56:13 -07:00
|
|
|
#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"
|
2017-08-28 17:11:32 -07:00
|
|
|
#include "accelerometer.h"
|
2019-03-31 14:14:53 -07:00
|
|
|
#include "counter64.h"
|
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
|
|
|
#include "AdcConfiguration.h"
|
2016-08-20 20:02:09 -07:00
|
|
|
#endif /* HAL_USE_ADC */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-07-09 05:33:40 -07:00
|
|
|
#if defined(EFI_BOOTLOADER_INCLUDE_CODE)
|
|
|
|
#include "bootloader/bootloader.h"
|
|
|
|
#endif /* EFI_BOOTLOADER_INCLUDE_CODE */
|
|
|
|
|
|
|
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
|
|
|
#include "periodic_task.h"
|
|
|
|
#endif
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "pwm_generator.h"
|
|
|
|
#include "adc_inputs.h"
|
2019-03-31 14:44:34 -07:00
|
|
|
|
2019-03-29 06:11:13 -07:00
|
|
|
#include "pwm_tester.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "pwm_generator.h"
|
|
|
|
#include "lcd_controller.h"
|
|
|
|
#include "pin_repository.h"
|
2015-08-19 13:01:36 -07:00
|
|
|
#include "tachometer.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
|
2019-04-09 16:12:35 -07:00
|
|
|
#include "cj125.h"
|
2019-07-09 05:33:40 -07:00
|
|
|
#endif /* EFI_CJ125 */
|
2018-11-03 06:44:34 -07:00
|
|
|
|
2019-05-12 17:24:35 -07:00
|
|
|
// this method is used by real firmware and simulator and unit test
|
|
|
|
void mostCommonInitEngineController(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|
|
|
initSensors(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
|
|
|
|
initAccelEnrichment(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
|
2019-05-12 17:31:28 -07:00
|
|
|
#if EFI_FSIO
|
|
|
|
initFsioImpl(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
|
|
|
|
#endif /* EFI_FSIO */
|
2019-05-12 17:24:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if !EFI_UNIT_TEST
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
extern bool hasFirmwareErrorFlag;
|
2017-02-24 16:42:34 -08:00
|
|
|
extern EnginePins enginePins;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-06-04 12:01:40 -07:00
|
|
|
EXTERN_ENGINE;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-07-09 05:33:40 -07:00
|
|
|
static void doPeriodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-07-09 05:33:40 -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 {
|
|
|
|
// we need at least protection from zero value while resetting configuration
|
|
|
|
int periodMs = maxI(50, CONFIGB(generalPeriodicThreadPeriodMs));
|
|
|
|
return periodMs;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static PeriodicFastController fastController;
|
|
|
|
static PeriodicSlowController slowController;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
static LoggingWithStorage logger("Engine Controller");
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* todo: this should probably become 'static', i.e. private, and propagated around explicitly?
|
|
|
|
*/
|
2019-01-27 23:59:14 -08:00
|
|
|
Engine ___engine CCM_OPTIONAL;
|
|
|
|
Engine * engine = &___engine;
|
|
|
|
#endif /* EFI_PROD_CODE || EFI_SIMULATOR */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
static msg_t csThread(void) {
|
|
|
|
chRegSetThreadName("status");
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_SHAFT_POSITION_INPUT
|
2015-07-10 06:01:56 -07:00
|
|
|
while (true) {
|
2017-07-06 05:49:55 -07:00
|
|
|
int is_cranking = ENGINE(rpmCalculator).isCranking(PASS_ENGINE_PARAMETER_SIGNATURE);
|
2017-07-08 08:02:28 -07:00
|
|
|
bool is_running = ENGINE(rpmCalculator).isRunning(PASS_ENGINE_PARAMETER_SIGNATURE);
|
2015-07-10 06:01:56 -07:00
|
|
|
if (is_running) {
|
|
|
|
// blinking while running
|
2018-07-26 12:51:06 -07:00
|
|
|
enginePins.runningLedPin.setValue(0);
|
2015-07-10 06:01:56 -07:00
|
|
|
chThdSleepMilliseconds(50);
|
2018-07-26 12:51:06 -07:00
|
|
|
enginePins.runningLedPin.setValue(1);
|
2015-07-10 06:01:56 -07:00
|
|
|
chThdSleepMilliseconds(50);
|
|
|
|
} else {
|
|
|
|
// constant on while cranking and off if engine is stopped
|
2018-07-26 12:51:06 -07:00
|
|
|
enginePins.runningLedPin.setValue(is_cranking);
|
2015-07-10 06:01:56 -07:00
|
|
|
chThdSleepMilliseconds(100);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* EFI_SHAFT_POSITION_INPUT */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE
|
2017-06-08 19:54:51 -07:00
|
|
|
static Overflow64Counter halTime;
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2015-12-26 13:01:56 -08:00
|
|
|
/**
|
|
|
|
* 64-bit result would not overflow, but that's complex stuff for our 32-bit MCU
|
|
|
|
*/
|
2015-07-10 06:01:56 -07:00
|
|
|
//todo: macro to save method invocation
|
|
|
|
efitimeus_t getTimeNowUs(void) {
|
|
|
|
return getTimeNowNt() / (CORE_CLOCK / 1000000);
|
|
|
|
}
|
|
|
|
|
|
|
|
//todo: macro to save method invocation
|
|
|
|
efitick_t getTimeNowNt(void) {
|
2017-06-08 20:05:05 -07:00
|
|
|
#if EFI_PROD_CODE
|
|
|
|
bool alreadyLocked = lockAnyContext();
|
|
|
|
efitime_t localH = halTime.state.highBits;
|
|
|
|
uint32_t localLow = halTime.state.lowBits;
|
|
|
|
|
2019-05-07 16:32:08 -07:00
|
|
|
uint32_t value = getTimeNowLowerNt();
|
2017-06-08 20:05:05 -07:00
|
|
|
|
|
|
|
if (value < localLow) {
|
|
|
|
// new value less than previous value means there was an overflow in that 32 bit counter
|
|
|
|
localH += 0x100000000LL;
|
|
|
|
}
|
|
|
|
|
|
|
|
efitime_t result = localH + value;
|
|
|
|
|
|
|
|
if (!alreadyLocked) {
|
|
|
|
unlockAnyContext();
|
|
|
|
}
|
|
|
|
return result;
|
2019-05-12 17:24:35 -07:00
|
|
|
#else /* EFI_PROD_CODE */
|
2017-06-08 20:05:05 -07:00
|
|
|
// todo: why is this implementation not used?
|
|
|
|
/**
|
|
|
|
* this method is lock-free and thread-safe, that's because the 'update' method
|
|
|
|
* is atomic with a critical zone requirement.
|
|
|
|
*
|
|
|
|
* http://stackoverflow.com/questions/5162673/how-to-read-two-32bit-counters-as-a-64bit-integer-without-race-condition
|
|
|
|
*/
|
|
|
|
efitime_t localH;
|
|
|
|
efitime_t localH2;
|
|
|
|
uint32_t localLow;
|
|
|
|
int counter = 0;
|
|
|
|
do {
|
|
|
|
localH = halTime.state.highBits;
|
|
|
|
localLow = halTime.state.lowBits;
|
|
|
|
localH2 = halTime.state.highBits;
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE
|
2017-06-08 20:05:05 -07:00
|
|
|
if (counter++ == 10000)
|
|
|
|
chDbgPanic("lock-free frozen");
|
|
|
|
#endif /* EFI_PROD_CODE */
|
|
|
|
} while (localH != localH2);
|
|
|
|
/**
|
|
|
|
* We need to take current counter after making a local 64 bit snapshot
|
|
|
|
*/
|
2019-05-07 16:32:08 -07:00
|
|
|
uint32_t value = getTimeNowLowerNt();
|
2017-06-08 20:05:05 -07:00
|
|
|
|
|
|
|
if (value < localLow) {
|
|
|
|
// new value less than previous value means there was an overflow in that 32 bit counter
|
|
|
|
localH += 0x100000000LL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return localH + value;
|
2019-05-12 17:24:35 -07:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2017-06-08 20:05:05 -07:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* EFI_PROD_CODE */
|
|
|
|
|
2016-01-08 12:01:38 -08:00
|
|
|
static void resetAccel(void) {
|
|
|
|
engine->engineLoadAccelEnrichment.reset();
|
|
|
|
engine->tpsAccelEnrichment.reset();
|
2019-07-12 19:36:54 -07:00
|
|
|
engine->wallFuel.resetWF();
|
2016-01-08 12:01:38 -08:00
|
|
|
}
|
|
|
|
|
2018-12-23 21:46:02 -08:00
|
|
|
static int previousSecond;
|
2018-12-23 21:31:26 -08:00
|
|
|
|
|
|
|
#if EFI_CLOCK_LOCKS
|
|
|
|
|
|
|
|
typedef FLStack<int, 16> irq_enter_timestamps_t;
|
|
|
|
|
|
|
|
static irq_enter_timestamps_t irqEnterTimestamps;
|
|
|
|
|
|
|
|
void irqEnterHook(void) {
|
2019-05-07 16:32:08 -07:00
|
|
|
irqEnterTimestamps.push(getTimeNowLowerNt());
|
2018-12-23 21:31:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int currentIrqDurationAccumulator = 0;
|
|
|
|
static int currentIrqCounter = 0;
|
|
|
|
/**
|
|
|
|
* See also maxLockedDuration
|
|
|
|
*/
|
|
|
|
int perSecondIrqDuration = 0;
|
|
|
|
int perSecondIrqCounter = 0;
|
|
|
|
void irqExitHook(void) {
|
|
|
|
int enterTime = irqEnterTimestamps.pop();
|
2019-05-07 16:32:08 -07:00
|
|
|
currentIrqDurationAccumulator += (getTimeNowLowerNt() - enterTime);
|
2018-12-23 21:31:26 -08:00
|
|
|
currentIrqCounter++;
|
|
|
|
}
|
|
|
|
#endif /* EFI_CLOCK_LOCKS */
|
|
|
|
|
|
|
|
static void invokePerSecond(void) {
|
|
|
|
#if EFI_CLOCK_LOCKS
|
|
|
|
// this data transfer is not atomic but should be totally good enough
|
|
|
|
perSecondIrqDuration = currentIrqDurationAccumulator;
|
|
|
|
perSecondIrqCounter = currentIrqCounter;
|
|
|
|
currentIrqDurationAccumulator = currentIrqCounter = 0;
|
|
|
|
#endif /* EFI_CLOCK_LOCKS */
|
|
|
|
}
|
|
|
|
|
2019-07-07 16:59:48 -07:00
|
|
|
static void doPeriodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
2019-04-12 19:07:03 -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
|
|
|
|
/**
|
|
|
|
* We need to push current value into the 64 bit counter often enough so that we do not miss an overflow
|
|
|
|
*/
|
|
|
|
bool alreadyLocked = lockAnyContext();
|
2019-05-07 16:32:08 -07:00
|
|
|
updateAndSet(&halTime.state, getTimeNowLowerNt());
|
2015-07-10 06:01:56 -07:00
|
|
|
if (!alreadyLocked) {
|
|
|
|
unlockAnyContext();
|
|
|
|
}
|
2018-12-23 21:31:26 -08:00
|
|
|
int timeSeconds = getTimeNowSeconds();
|
|
|
|
if (previousSecond != timeSeconds) {
|
|
|
|
previousSecond = timeSeconds;
|
|
|
|
invokePerSecond();
|
|
|
|
}
|
|
|
|
#endif /* EFI_PROD_CODE */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-07-06 16:33:25 -07:00
|
|
|
/**
|
|
|
|
* Update engine RPM state if needed (check timeouts).
|
|
|
|
*/
|
2019-01-24 20:44:29 -08:00
|
|
|
bool isSpinning = engine->rpmCalculator.checkIfSpinning(getTimeNowNt() PASS_ENGINE_PARAMETER_SUFFIX);
|
2019-01-24 18:12:55 -08:00
|
|
|
if (!isSpinning) {
|
|
|
|
engine->rpmCalculator.setStopSpinning(PASS_ENGINE_PARAMETER_SIGNATURE);
|
|
|
|
}
|
2017-07-06 16:33:25 -07:00
|
|
|
|
2017-07-06 16:15:10 -07:00
|
|
|
if (engine->rpmCalculator.isStopped(PASS_ENGINE_PARAMETER_SIGNATURE)) {
|
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();
|
2017-12-23 11:15:35 -08:00
|
|
|
} else {
|
|
|
|
updatePrimeInjectionPulseState(PASS_ENGINE_PARAMETER_SIGNATURE);
|
2015-09-03 06:01:31 -07:00
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-04-15 18:09:43 -07:00
|
|
|
if (engine->versionForConfigurationListeners.isOld(engine->getGlobalConfigurationVersion())) {
|
2016-01-31 13:01:26 -08:00
|
|
|
updateAccelParameters();
|
2016-02-06 14:01:38 -08:00
|
|
|
engine->engineState.warmupAfrPid.reset();
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-01-14 07:58:38 -08:00
|
|
|
engine->periodicSlowCallback(PASS_ENGINE_PARAMETER_SIGNATURE);
|
2019-01-31 08:57:15 -08:00
|
|
|
#endif
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2017-05-15 20:28:49 -07:00
|
|
|
void initPeriodicEvents(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
2019-07-09 13:08:49 -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
|
2016-12-27 11:04:04 -08:00
|
|
|
if (hwChannel == EFI_ADC_NONE) {
|
|
|
|
strcpy(buffer, "NONE");
|
|
|
|
} else {
|
|
|
|
strcpy((char*) buffer, portname(getAdcChannelPort(msg, hwChannel)));
|
|
|
|
itoa10(&buffer[2], getAdcChannelPin(hwChannel));
|
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
#else
|
|
|
|
strcpy(buffer, "NONE");
|
|
|
|
#endif
|
|
|
|
return (char*) buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fastAdc.isHwUsed(hwChannel)) {
|
2019-01-09 19:57:33 -08:00
|
|
|
scheduleMsg(&logger, "fast enabled=%s", boolToString(CONFIGB(isFastAdcEnabled)));
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
float voltage = adcVoltage * dividerCoeff;
|
2018-01-23 09:05:14 -08:00
|
|
|
scheduleMsg(&logger, "%s ADC%d %s %s adc=%.2f/input=%.2fv/divider=%.2f", name, hwChannel, getAdcMode(hwChannel),
|
2016-12-27 11:04:04 -08:00
|
|
|
getPinNameByAdcChannel(name, hwChannel, pinNameBuffer), adcVoltage, voltage, dividerCoeff);
|
2015-07-10 06:01:56 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void printAnalogChannelInfo(const char *name, adc_channel_e hwChannel) {
|
2019-04-12 19:07:03 -07:00
|
|
|
#if HAL_USE_ADC
|
2015-07-10 06:01:56 -07:00
|
|
|
printAnalogChannelInfoExt(name, hwChannel, getVoltage("print", hwChannel), engineConfiguration->analogInputDividerCoefficient);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2019-06-30 11:28:47 -07:00
|
|
|
printAnalogChannelInfo("TPS", engineConfiguration->tps1_1AdcChannel);
|
2019-01-26 21:02:58 -08:00
|
|
|
printAnalogChannelInfo("pPS", engineConfiguration->throttlePedalPositionAdcChannel);
|
2016-12-17 06:02:59 -08:00
|
|
|
if (engineConfiguration->clt.adcChannel != EFI_ADC_NONE) {
|
|
|
|
printAnalogChannelInfo("CLT", engineConfiguration->clt.adcChannel);
|
|
|
|
}
|
|
|
|
if (engineConfiguration->iat.adcChannel != EFI_ADC_NONE) {
|
2015-07-10 06:01:56 -07:00
|
|
|
printAnalogChannelInfo("IAT", engineConfiguration->iat.adcChannel);
|
|
|
|
}
|
|
|
|
if (hasMafSensor()) {
|
|
|
|
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];
|
|
|
|
if (ch != EFI_ADC_NONE) {
|
|
|
|
printAnalogChannelInfo("fsio", ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
printAnalogChannelInfo("AFR", engineConfiguration->afr.hwChannel);
|
2017-05-15 20:28:49 -07:00
|
|
|
if (hasMapSensor(PASS_ENGINE_PARAMETER_SIGNATURE)) {
|
2015-07-10 06:01:56 -07:00
|
|
|
printAnalogChannelInfo("MAP", engineConfiguration->map.sensor.hwChannel);
|
|
|
|
}
|
2017-05-15 20:28:49 -07:00
|
|
|
if (hasBaroSensor(PASS_ENGINE_PARAMETER_SIGNATURE)) {
|
2015-07-10 06:01:56 -07:00
|
|
|
printAnalogChannelInfo("BARO", engineConfiguration->baroSensor.hwChannel);
|
|
|
|
}
|
|
|
|
if (engineConfiguration->externalKnockSenseAdc != EFI_ADC_NONE) {
|
|
|
|
printAnalogChannelInfo("extKno", engineConfiguration->externalKnockSenseAdc);
|
|
|
|
}
|
|
|
|
|
2017-11-15 11:30:13 -08:00
|
|
|
printAnalogChannelInfo("OilP", engineConfiguration->oilPressure.hwChannel);
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
printAnalogChannelInfo("A/C sw", engineConfiguration->acSwitchAdc);
|
|
|
|
printAnalogChannelInfo("HIP9011", engineConfiguration->hipOutputChannel);
|
|
|
|
printAnalogChannelInfoExt("Vbatt", engineConfiguration->vbattAdcChannel, getVoltage("vbatt", engineConfiguration->vbattAdcChannel),
|
|
|
|
engineConfiguration->vbattDividerCoeff);
|
|
|
|
}
|
|
|
|
|
|
|
|
static THD_WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE); // declare thread stack
|
|
|
|
|
|
|
|
#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
|
|
|
*/
|
2019-04-08 08:19:07 -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
|
2019-04-08 08:19:07 -07:00
|
|
|
*/
|
|
|
|
scheduleMsg(&logger, "byte%s%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, value);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-04-08 08:57:16 -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
|
|
|
*/
|
2019-04-08 08:19:07 -07:00
|
|
|
scheduleMsg(&logger, "bit%s%d/%d is %d", CONSOLE_DATA_PROTOCOL_TAG, offset, bit, value);
|
2019-04-08 08:57:16 -07:00
|
|
|
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);
|
2019-04-08 08:57:16 -07:00
|
|
|
onConfigurationChanged();
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-04-08 08:19:07 -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);
|
2019-04-08 08:57:16 -07:00
|
|
|
onConfigurationChanged();
|
2019-04-08 08:19:07 -07:00
|
|
|
}
|
|
|
|
|
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
|
|
|
*/
|
2019-04-08 08:19:07 -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
|
|
|
*/
|
2019-04-08 08:19:07 -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);
|
2019-04-08 08:57:16 -07:00
|
|
|
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
|
|
|
*/
|
2019-04-08 08:19:07 -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;
|
|
|
|
}
|
2019-01-04 21:57:09 -08:00
|
|
|
float *ptr = (float *) (&((char *) engineConfiguration)[offset]);
|
2015-07-10 06:01:56 -07:00
|
|
|
*ptr = value;
|
|
|
|
getFloat(offset);
|
2019-04-08 08:57:16 -07:00
|
|
|
onConfigurationChanged();
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2016-01-23 15:01:40 -08:00
|
|
|
#if EFI_ENABLE_MOCK_ADC || EFI_SIMULATOR
|
|
|
|
|
|
|
|
static void setMockVoltage(int hwChannel, float voltage) {
|
|
|
|
engine->engineState.mockAdcState.setMockVoltage(hwChannel, voltage);
|
|
|
|
}
|
|
|
|
|
2017-11-27 18:10:49 -08:00
|
|
|
void setMockCltVoltage(float voltage) {
|
2016-01-23 15:01:40 -08:00
|
|
|
setMockVoltage(engineConfiguration->clt.adcChannel, voltage);
|
|
|
|
}
|
|
|
|
|
2017-11-27 18:10:49 -08:00
|
|
|
void setMockIatVoltage(float voltage) {
|
2016-01-23 15:01:40 -08:00
|
|
|
setMockVoltage(engineConfiguration->iat.adcChannel, voltage);
|
|
|
|
}
|
|
|
|
|
2017-11-27 18:10:49 -08:00
|
|
|
void setMockMafVoltage(float voltage) {
|
2016-01-23 15:01:40 -08:00
|
|
|
setMockVoltage(engineConfiguration->mafAdcChannel, voltage);
|
|
|
|
}
|
|
|
|
|
2017-11-27 18:10:49 -08:00
|
|
|
void setMockAfrVoltage(float voltage) {
|
2016-01-23 15:01:40 -08:00
|
|
|
setMockVoltage(engineConfiguration->afr.hwChannel, voltage);
|
|
|
|
}
|
|
|
|
|
2017-11-27 18:10:49 -08:00
|
|
|
void setMockTpsVoltage(float voltage) {
|
2019-06-30 11:28:47 -07:00
|
|
|
setMockVoltage(engineConfiguration->tps1_1AdcChannel, voltage);
|
2016-01-23 15:01:40 -08:00
|
|
|
}
|
|
|
|
|
2017-11-27 18:10:49 -08:00
|
|
|
void setMockMapVoltage(float voltage) {
|
2016-01-23 15:01:40 -08:00
|
|
|
setMockVoltage(engineConfiguration->map.sensor.hwChannel, voltage);
|
|
|
|
}
|
|
|
|
|
2017-11-27 18:10:49 -08:00
|
|
|
void setMockVBattVoltage(float voltage) {
|
2016-01-23 15:01:40 -08:00
|
|
|
setMockVoltage(engineConfiguration->vbattAdcChannel, voltage);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void initMockVoltage(void) {
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_SIMULATOR
|
2017-11-27 18:25:33 -08:00
|
|
|
setMockCltVoltage(2);
|
2016-07-25 22:04:34 -07:00
|
|
|
#endif /* EFI_SIMULATOR */
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_SIMULATOR
|
2017-11-27 18:25:33 -08:00
|
|
|
setMockIatVoltage(2);
|
2016-07-25 22:04:34 -07:00
|
|
|
#endif /* EFI_SIMULATOR */
|
|
|
|
|
2016-01-23 15:01:40 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* EFI_ENABLE_MOCK_ADC */
|
|
|
|
|
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);
|
2019-04-08 08:19:07 -07:00
|
|
|
addConsoleActionII("set_byte", (VoidIntInt) setByte);
|
2015-07-10 06:01:56 -07:00
|
|
|
addConsoleActionSSS("set_bit", setBit);
|
2019-04-08 08:19:07 -07:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
addConsoleActionI("get_float", getFloat);
|
|
|
|
addConsoleActionI("get_int", getInt);
|
|
|
|
addConsoleActionI("get_short", getShort);
|
2019-04-08 08:19:07 -07:00
|
|
|
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-05-12 17:24:35 -07:00
|
|
|
// this method is used by real firmware and simulator but not unit tests
|
2017-05-15 20:28:49 -07:00
|
|
|
void commonInitEngineController(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
2018-01-30 11:53:13 -08:00
|
|
|
#if EFI_SIMULATOR
|
|
|
|
printf("commonInitEngineController\n");
|
|
|
|
#endif
|
2015-07-10 06:01:56 -07:00
|
|
|
initConfigActions();
|
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 */
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
2015-07-10 06:01:56 -07:00
|
|
|
// todo: this is a mess, remove code duplication with simulator
|
2017-05-07 17:40:10 -07:00
|
|
|
initSettings();
|
2015-07-10 06:01:56 -07:00
|
|
|
#endif
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_TUNER_STUDIO
|
2015-07-10 06:01:56 -07:00
|
|
|
if (engineConfiguration->isTunerStudioEnabled) {
|
|
|
|
startTunerStudioConnectivity();
|
|
|
|
}
|
2019-05-12 17:24:35 -07:00
|
|
|
#endif /* EFI_TUNER_STUDIO */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
if (hasFirmwareError()) {
|
|
|
|
return;
|
|
|
|
}
|
2019-05-12 17:24:35 -07:00
|
|
|
mostCommonInitEngineController(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
|
2016-01-12 19:01:53 -08:00
|
|
|
}
|
|
|
|
|
2017-05-15 20:28:49 -07:00
|
|
|
void initEngineContoller(Logging *sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
2018-01-30 11:53:13 -08:00
|
|
|
#if EFI_SIMULATOR
|
|
|
|
printf("initEngineContoller\n");
|
|
|
|
#endif
|
2016-01-12 19:01:53 -08:00
|
|
|
addConsoleAction("analoginfo", printAnalogInfo);
|
|
|
|
commonInitEngineController(sharedLogger);
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE
|
2015-07-10 06:01:56 -07:00
|
|
|
initPwmGenerator();
|
|
|
|
#endif
|
|
|
|
|
2017-05-07 17:40:10 -07:00
|
|
|
initAlgo(sharedLogger);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_WAVE_ANALYZER
|
2015-07-10 06:01:56 -07:00
|
|
|
if (engineConfiguration->isWaveAnalyzerEnabled) {
|
|
|
|
initWaveAnalyzer(sharedLogger);
|
|
|
|
}
|
|
|
|
#endif /* EFI_WAVE_ANALYZER */
|
|
|
|
|
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
|
|
|
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_SHAFT_POSITION_INPUT
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* there is an implicit dependency on the fact that 'tachometer' listener is the 1st listener - this case
|
|
|
|
* other listeners can access current RPM value
|
|
|
|
*/
|
2019-01-20 21:10:09 -08:00
|
|
|
initRpmCalculator(sharedLogger PASS_ENGINE_PARAMETER_SUFFIX);
|
2015-07-10 06:01:56 -07:00
|
|
|
#endif /* EFI_SHAFT_POSITION_INPUT */
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE && EFI_ENGINE_CONTROL
|
2016-08-25 21:01:55 -07:00
|
|
|
initInjectorCentral(sharedLogger);
|
|
|
|
#endif /* EFI_PROD_CODE && EFI_ENGINE_CONTROL */
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
// multiple issues with this initMapAdjusterThread();
|
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;
|
|
|
|
}
|
|
|
|
|
2018-12-27 06:40:40 -08:00
|
|
|
chThdCreateStatic(csThreadStack, sizeof(csThreadStack), LOWPRIO, (tfunc_t)(void*) csThread, NULL);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE && EFI_ENGINE_CONTROL
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* This has to go after 'initInjectorCentral' and 'initInjectorCentral' in order to
|
|
|
|
* properly detect un-assigned output pins
|
|
|
|
*/
|
2017-05-15 20:28:49 -07:00
|
|
|
prepareShapes(PASS_ENGINE_PARAMETER_SIGNATURE);
|
2016-08-25 21:01:55 -07:00
|
|
|
#endif /* EFI_PROD_CODE && EFI_ENGINE_CONTROL */
|
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
|
|
|
|
|
|
|
initMalfunctionCentral();
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_ALTERNATOR_CONTROL
|
2015-07-10 06:01:56 -07:00
|
|
|
initAlternatorCtrl(sharedLogger);
|
|
|
|
#endif
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_AUX_PID
|
2016-06-27 19:02:41 -07:00
|
|
|
initAuxPid(sharedLogger);
|
|
|
|
#endif
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_ELECTRONIC_THROTTLE_BODY
|
2015-07-10 06:01:56 -07:00
|
|
|
initElectronicThrottle();
|
|
|
|
#endif /* EFI_ELECTRONIC_THROTTLE_BODY */
|
|
|
|
|
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 */
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_MAP_AVERAGING
|
2015-07-10 06:01:56 -07:00
|
|
|
if (engineConfiguration->isMapAveragingEnabled) {
|
|
|
|
initMapAveraging(sharedLogger, engine);
|
|
|
|
}
|
|
|
|
#endif /* EFI_MAP_AVERAGING */
|
|
|
|
|
2018-01-23 05:24:13 -08:00
|
|
|
initEgoAveraging(PASS_ENGINE_PARAMETER_SIGNATURE);
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
|
2019-01-09 19:57:33 -08:00
|
|
|
if (CONFIGB(isEngineControlEnabled)) {
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* This method initialized the main listener which actually runs injectors & ignition
|
|
|
|
*/
|
2017-05-25 19:28:04 -07:00
|
|
|
initMainEventListener(sharedLogger DECLARE_ENGINE_PARAMETER_SUFFIX);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
#endif /* EFI_ENGINE_CONTROL */
|
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_IDLE_CONTROL
|
2017-04-29 18:16:26 -07:00
|
|
|
startIdleThread(sharedLogger);
|
2017-03-19 14:42:15 -07:00
|
|
|
#endif /* EFI_IDLE_CONTROL */
|
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
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE
|
2015-08-19 13:01:36 -07:00
|
|
|
initTachometer();
|
2017-03-19 14:42:15 -07:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
2018-03-24 18:13:08 -07:00
|
|
|
|
2019-01-14 06:04:29 -08:00
|
|
|
// these two variables are here only to let us know how much RAM is available, also these
|
2019-01-14 09:56:53 -08:00
|
|
|
// 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
|
2019-02-06 20:30:53 -08:00
|
|
|
#ifndef RAM_UNUSED_SIZE
|
2019-07-09 23:21:47 -07:00
|
|
|
#define RAM_UNUSED_SIZE 13000
|
2019-02-06 20:30:53 -08:00
|
|
|
#endif
|
|
|
|
#ifndef CCM_UNUSED_SIZE
|
2019-07-06 18:02:48 -07:00
|
|
|
#define CCM_UNUSED_SIZE 4600
|
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 */
|
2019-07-12 11:24:45 -07:00
|
|
|
return 20190712;
|
2018-03-24 18:13:08 -07:00
|
|
|
}
|
2019-04-09 20:00:17 -07:00
|
|
|
#endif /* EFI_UNIT_TEST */
|