2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* @file engine.cpp
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This might be a http://en.wikipedia.org/wiki/God_object but that's best way I can
|
|
|
|
* express myself in C/C++. I am open for suggestions :)
|
|
|
|
*
|
|
|
|
* @date May 21, 2014
|
2020-01-07 21:02:40 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
|
|
|
|
2021-07-25 18:23:23 -07:00
|
|
|
#include "pch.h"
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "trigger_central.h"
|
|
|
|
#include "fuel_math.h"
|
|
|
|
#include "advance_map.h"
|
|
|
|
#include "speed_density.h"
|
2016-01-01 16:02:59 -08:00
|
|
|
#include "advance_map.h"
|
2019-07-06 17:15:49 -07:00
|
|
|
#include "os_util.h"
|
2020-11-19 03:56:02 -08:00
|
|
|
#include "os_access.h"
|
2017-11-26 19:30:37 -08:00
|
|
|
#include "aux_valves.h"
|
2018-02-06 12:47:19 -08:00
|
|
|
#include "map_averaging.h"
|
2019-01-14 07:58:38 -08:00
|
|
|
#include "fsio_impl.h"
|
2019-10-11 17:43:21 -07:00
|
|
|
#include "perf_trace.h"
|
2020-09-07 12:08:54 -07:00
|
|
|
#include "backup_ram.h"
|
2020-11-11 18:47:19 -08:00
|
|
|
#include "idle_thread.h"
|
2020-11-03 15:06:32 -08:00
|
|
|
#include "idle_hardware.h"
|
2020-04-26 11:06:28 -07:00
|
|
|
#include "gppwm.h"
|
2020-08-21 12:36:43 -07:00
|
|
|
#include "tachometer.h"
|
2020-12-04 17:28:48 -08:00
|
|
|
#include "dynoview.h"
|
2021-01-18 04:04:14 -08:00
|
|
|
#include "boost_control.h"
|
2021-06-11 03:25:12 -07:00
|
|
|
#include "fan_control.h"
|
2021-06-27 15:51:34 -07:00
|
|
|
#include "ac_control.h"
|
2021-07-28 04:44:44 -07:00
|
|
|
#include "vr_pwm.h"
|
2020-10-19 19:04:06 -07:00
|
|
|
#if EFI_MC33816
|
|
|
|
#include "mc33816.h"
|
|
|
|
#endif // EFI_MC33816
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE
|
2020-10-11 19:46:08 -07:00
|
|
|
#include "trigger_emulator_algo.h"
|
2020-03-26 05:03:55 -07:00
|
|
|
#include "bench_test.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#else
|
|
|
|
#define isRunningBenchTest() true
|
2016-01-23 15:01:40 -08:00
|
|
|
#endif /* EFI_PROD_CODE */
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-09-06 17:30:27 -07:00
|
|
|
#if (BOARD_TLE8888_COUNT > 0)
|
|
|
|
#include "gpio/tle8888.h"
|
|
|
|
#endif
|
|
|
|
|
2019-12-21 17:43:11 -08:00
|
|
|
#if EFI_ENGINE_SNIFFER
|
|
|
|
#include "engine_sniffer.h"
|
|
|
|
extern int waveChartUsedSize;
|
|
|
|
extern WaveChart waveChart;
|
|
|
|
#endif /* EFI_ENGINE_SNIFFER */
|
|
|
|
|
2019-01-05 20:48:37 -08:00
|
|
|
FsioState::FsioState() {
|
|
|
|
#if EFI_ENABLE_ENGINE_WARNING
|
|
|
|
isEngineWarning = FALSE;
|
|
|
|
#endif
|
|
|
|
#if EFI_ENABLE_CRITICAL_ENGINE_STOP
|
|
|
|
isCriticalEngineCondition = FALSE;
|
|
|
|
#endif
|
|
|
|
}
|
2016-01-23 15:01:40 -08:00
|
|
|
|
2019-12-21 17:43:11 -08:00
|
|
|
void Engine::resetEngineSnifferIfInTestMode() {
|
|
|
|
#if EFI_ENGINE_SNIFFER
|
2020-08-08 08:25:17 -07:00
|
|
|
if (isFunctionalTestMode) {
|
2019-12-21 20:27:54 -08:00
|
|
|
// TODO: what is the exact reasoning for the exact engine sniffer pause time I wonder
|
|
|
|
waveChart.pauseEngineSnifferUntilNt = getTimeNowNt() + MS2NT(300);
|
2019-12-21 17:43:11 -08:00
|
|
|
waveChart.reset();
|
|
|
|
}
|
|
|
|
#endif /* EFI_ENGINE_SNIFFER */
|
|
|
|
}
|
|
|
|
|
2021-10-24 14:05:37 -07:00
|
|
|
/**
|
|
|
|
* VVT decoding delegates to universal trigger decoder. Here we map vvt_mode_e into corresponding trigger_type_e
|
|
|
|
*/
|
2020-08-26 10:30:55 -07:00
|
|
|
trigger_type_e getVvtTriggerType(vvt_mode_e vvtMode) {
|
|
|
|
switch (vvtMode) {
|
2021-12-31 12:47:25 -08:00
|
|
|
case VVT_INACTIVE:
|
|
|
|
return TT_ONE;
|
2020-08-26 10:30:55 -07:00
|
|
|
case VVT_2JZ:
|
|
|
|
return TT_VVT_JZ;
|
2021-02-08 15:20:53 -08:00
|
|
|
case VVT_MIATA_NB2:
|
2020-08-26 10:30:55 -07:00
|
|
|
return TT_VVT_MIATA_NB2;
|
2020-08-26 21:43:23 -07:00
|
|
|
case VVT_BOSCH_QUICK_START:
|
|
|
|
return TT_VVT_BOSCH_QUICK_START;
|
2021-10-28 12:57:23 -07:00
|
|
|
case VVT_HONDA_K:
|
|
|
|
case VVT_TOYOTA_4_1:
|
2020-08-26 10:30:55 -07:00
|
|
|
case VVT_FIRST_HALF:
|
|
|
|
case VVT_SECOND_HALF:
|
2021-12-07 17:00:50 -08:00
|
|
|
case VVT_MAP_V_TWIN_ANOTHER:
|
2020-08-26 10:30:55 -07:00
|
|
|
return TT_ONE;
|
2020-12-03 20:54:08 -08:00
|
|
|
case VVT_FORD_ST170:
|
|
|
|
return TT_FORD_ST170;
|
2021-03-22 04:48:29 -07:00
|
|
|
case VVT_BARRA_3_PLUS_1:
|
|
|
|
return TT_VVT_BARRA_3_PLUS_1;
|
2021-07-03 06:43:27 -07:00
|
|
|
case VVT_NISSAN_VQ:
|
2021-07-16 21:27:56 -07:00
|
|
|
return TT_VVT_NISSAN_VQ35;
|
2021-11-05 12:33:22 -07:00
|
|
|
case VVT_NISSAN_MR:
|
|
|
|
return TT_NISSAN_MR18_CAM_VVT;
|
2020-08-26 10:30:55 -07:00
|
|
|
default:
|
2021-07-03 06:43:27 -07:00
|
|
|
firmwareError(OBD_PCM_Processor_Fault, "getVvtTriggerType for %s", getVvt_mode_e(vvtMode));
|
2021-07-03 06:48:59 -07:00
|
|
|
return TT_ONE; // we have to return something for the sake of -Werror=return-type
|
2020-08-26 10:30:55 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
static void initVvtShape(int camIndex, TriggerState &initState) {
|
2021-04-07 12:17:01 -07:00
|
|
|
vvt_mode_e vvtMode = engineConfiguration->vvtMode[camIndex];
|
2021-02-08 19:07:14 -08:00
|
|
|
|
2021-02-08 18:28:57 -08:00
|
|
|
if (vvtMode != VVT_INACTIVE) {
|
|
|
|
trigger_config_s config;
|
2021-11-02 14:11:44 -07:00
|
|
|
// todo: should 'vvtWithRealDecoder' be used here?
|
2021-12-31 12:47:25 -08:00
|
|
|
config.type = getVvtTriggerType(vvtMode);
|
2021-02-08 18:28:57 -08:00
|
|
|
|
2021-12-31 12:47:25 -08:00
|
|
|
auto& shape = engine->triggerCentral.vvtShape[camIndex];
|
|
|
|
shape.initializeTriggerWaveform(
|
2021-02-08 18:28:57 -08:00
|
|
|
engineConfiguration->ambiguousOperationMode,
|
2021-11-17 00:54:21 -08:00
|
|
|
engineConfiguration->vvtCamSensorUseRise, &config);
|
2021-02-08 18:28:57 -08:00
|
|
|
|
2021-12-31 12:47:25 -08:00
|
|
|
shape.initializeSyncPoint(initState,
|
2021-04-07 12:17:01 -07:00
|
|
|
engine->vvtTriggerConfiguration[camIndex],
|
2021-02-08 18:28:57 -08:00
|
|
|
config);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::initializeTriggerWaveform() {
|
2020-08-26 20:35:11 -07:00
|
|
|
static TriggerState initState;
|
|
|
|
|
2020-10-05 13:42:50 -07:00
|
|
|
// Re-read config in case it's changed
|
|
|
|
primaryTriggerConfiguration.update();
|
2021-02-08 19:21:02 -08:00
|
|
|
for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
|
|
|
|
vvtTriggerConfiguration[camIndex].update();
|
|
|
|
}
|
2020-10-05 13:42:50 -07:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
|
2018-12-25 18:18:14 -08:00
|
|
|
// we have a confusing threading model so some synchronization would not hurt
|
2020-11-19 03:56:02 -08:00
|
|
|
chibios_rt::CriticalSectionLocker csl;
|
2018-12-25 18:18:14 -08:00
|
|
|
|
2021-04-21 11:28:48 -07:00
|
|
|
TRIGGER_WAVEFORM(initializeTriggerWaveform(
|
2019-08-07 21:32:31 -07:00
|
|
|
engineConfiguration->ambiguousOperationMode,
|
2018-12-25 19:47:29 -08:00
|
|
|
engineConfiguration->useOnlyRisingEdgeForTrigger, &engineConfiguration->trigger));
|
2018-12-25 18:18:14 -08:00
|
|
|
|
2021-05-23 17:52:18 -07:00
|
|
|
/**
|
|
|
|
* this is only useful while troubleshooting a new trigger shape in the field
|
|
|
|
* in very VERY rare circumstances
|
|
|
|
*/
|
2021-11-17 00:54:21 -08:00
|
|
|
if (engineConfiguration->overrideTriggerGaps) {
|
2021-05-25 14:15:48 -07:00
|
|
|
int gapIndex = 0;
|
2021-11-17 00:54:21 -08:00
|
|
|
for (;gapIndex<=engineConfiguration->overrideTriggerGaps;gapIndex++) {
|
|
|
|
float gapOverrideFrom = engineConfiguration->triggerGapOverrideFrom[gapIndex];
|
|
|
|
float gapOverrideTo = engineConfiguration->triggerGapOverrideTo[gapIndex];
|
2021-10-30 07:45:32 -07:00
|
|
|
TRIGGER_WAVEFORM(setTriggerSynchronizationGap3(/*gapIndex*/gapIndex, gapOverrideFrom, gapOverrideTo));
|
2021-05-23 17:52:18 -07:00
|
|
|
}
|
2021-05-25 14:15:48 -07:00
|
|
|
for (;gapIndex<GAP_TRACKING_LENGTH;gapIndex++) {
|
2021-11-17 00:54:21 -08:00
|
|
|
engine->triggerCentral.triggerShape.syncronizationRatioFrom[gapIndex] = NAN;
|
|
|
|
engine->triggerCentral.triggerShape.syncronizationRatioTo[gapIndex] = NAN;
|
2021-05-25 14:15:48 -07:00
|
|
|
}
|
2021-05-23 17:52:18 -07:00
|
|
|
}
|
|
|
|
|
2019-12-07 22:09:39 -08:00
|
|
|
if (!TRIGGER_WAVEFORM(shapeDefinitionError)) {
|
2018-12-25 18:18:14 -08:00
|
|
|
/**
|
2020-08-25 09:45:25 -07:00
|
|
|
* 'initState' instance of TriggerState is used only to initialize 'this' TriggerWaveform instance
|
2018-12-25 18:18:14 -08:00
|
|
|
* #192 BUG real hardware trigger events could be coming even while we are initializing trigger
|
|
|
|
*/
|
2021-11-17 00:54:21 -08:00
|
|
|
calculateTriggerSynchPoint(engine->triggerCentral.triggerShape,
|
2021-11-16 01:15:29 -08:00
|
|
|
initState);
|
2018-12-25 18:18:14 -08:00
|
|
|
|
2021-11-17 00:54:21 -08:00
|
|
|
engine->triggerCentral.triggerState.name = "TRG";
|
2019-12-07 22:09:39 -08:00
|
|
|
engine->engineCycleEventCount = TRIGGER_WAVEFORM(getLength());
|
2018-12-25 18:18:14 -08:00
|
|
|
}
|
|
|
|
|
2021-12-31 12:47:25 -08:00
|
|
|
engine->triggerCentral.vvtState[0][0].name = "VVT B1 Int";
|
|
|
|
engine->triggerCentral.vvtState[0][1].name = "VVT B1 Exh";
|
|
|
|
engine->triggerCentral.vvtState[1][0].name = "VVT B2 Int";
|
|
|
|
engine->triggerCentral.vvtState[1][1].name = "VVT B2 Exh";
|
2020-08-26 10:30:55 -07:00
|
|
|
|
2021-05-23 17:52:18 -07:00
|
|
|
for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
|
2021-11-16 01:15:29 -08:00
|
|
|
initVvtShape(camIndex, initState);
|
2021-05-23 17:52:18 -07:00
|
|
|
}
|
2020-08-26 10:30:55 -07:00
|
|
|
|
2019-12-07 22:09:39 -08:00
|
|
|
if (!TRIGGER_WAVEFORM(shapeDefinitionError)) {
|
2021-11-16 01:15:29 -08:00
|
|
|
prepareOutputSignals();
|
2018-12-25 18:18:14 -08:00
|
|
|
}
|
2019-01-31 14:55:23 -08:00
|
|
|
#endif /* EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT */
|
2019-01-14 07:58:38 -08:00
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
static void cylinderCleanupControl() {
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_ENGINE_CONTROL
|
2019-01-14 07:58:38 -08:00
|
|
|
bool newValue;
|
|
|
|
if (engineConfiguration->isCylinderCleanupEnabled) {
|
2021-10-05 16:59:07 -07:00
|
|
|
newValue = !engine->rpmCalculator.isRunning() && Sensor::getOrZero(SensorType::DriverThrottleIntent) > CLEANUP_MODE_TPS;
|
2019-01-14 07:58:38 -08:00
|
|
|
} else {
|
|
|
|
newValue = false;
|
|
|
|
}
|
|
|
|
if (newValue != engine->isCylinderCleanupMode) {
|
|
|
|
engine->isCylinderCleanupMode = newValue;
|
2021-04-19 05:11:59 -07:00
|
|
|
efiPrintf("isCylinderCleanupMode %s", boolToString(newValue));
|
2019-01-14 07:58:38 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-12-27 14:41:28 -08:00
|
|
|
#if ANALOG_HW_CHECK_MODE
|
2020-07-27 19:49:59 -07:00
|
|
|
static void assertCloseTo(const char * msg, float actual, float expected) {
|
2020-09-19 13:07:09 -07:00
|
|
|
if (actual < 0.75 * expected || actual > 1.25 * expected) {
|
2020-07-27 19:49:59 -07:00
|
|
|
firmwareError(OBD_PCM_Processor_Fault, "%s analog input validation failed %f vs %f", msg, actual, expected);
|
|
|
|
}
|
|
|
|
}
|
2020-12-27 14:41:28 -08:00
|
|
|
#endif // ANALOG_HW_CHECK_MODE
|
2020-07-27 19:49:59 -07:00
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::periodicSlowCallback() {
|
2019-10-11 17:43:21 -07:00
|
|
|
ScopePerf perf(PE::EnginePeriodicSlowCallback);
|
2020-10-05 13:42:50 -07:00
|
|
|
|
|
|
|
// Re-read config in case it's changed
|
|
|
|
primaryTriggerConfiguration.update();
|
2021-02-08 19:21:02 -08:00
|
|
|
for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
|
|
|
|
vvtTriggerConfiguration[camIndex].update();
|
|
|
|
}
|
2020-10-05 13:42:50 -07:00
|
|
|
|
2019-01-14 07:58:38 -08:00
|
|
|
watchdog();
|
2021-11-16 01:15:29 -08:00
|
|
|
updateSlowSensors();
|
|
|
|
checkShutdown();
|
2019-01-14 07:58:38 -08:00
|
|
|
|
2022-01-23 12:31:39 -08:00
|
|
|
tpsAccelEnrichment.onNewValue(Sensor::getOrZero(SensorType::Tps1));
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
updateVrPwm();
|
2021-07-28 04:44:44 -07:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_FSIO
|
2021-11-16 01:15:29 -08:00
|
|
|
runFsio();
|
2019-11-25 17:08:01 -08:00
|
|
|
#else
|
2021-11-16 01:15:29 -08:00
|
|
|
runHardcodedFsio();
|
2019-11-25 17:08:01 -08:00
|
|
|
#endif /* EFI_FSIO */
|
2018-12-25 18:18:14 -08:00
|
|
|
|
2020-04-26 11:06:28 -07:00
|
|
|
updateGppwm();
|
|
|
|
|
2021-11-17 10:45:10 -08:00
|
|
|
engine->engineModules.apply_all([](auto & m) { m.onSlowCallback(); });
|
2020-11-11 18:47:19 -08:00
|
|
|
|
2021-11-25 04:59:31 -08:00
|
|
|
updateFans(module<AcController>().unmock().isAcEnabled());
|
|
|
|
|
2021-01-18 04:04:14 -08:00
|
|
|
#if EFI_BOOST_CONTROL
|
|
|
|
updateBoostControl();
|
|
|
|
#endif // EFI_BOOST_CONTROL
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
cylinderCleanupControl();
|
2019-01-14 07:58:38 -08:00
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
standardAirCharge = getStandardAirCharge();
|
2020-05-05 05:01:40 -07:00
|
|
|
|
2019-09-06 17:30:27 -07:00
|
|
|
#if (BOARD_TLE8888_COUNT > 0)
|
2021-05-14 07:54:40 -07:00
|
|
|
tle8888startup();
|
2019-09-06 17:30:27 -07:00
|
|
|
#endif
|
|
|
|
|
2020-12-04 17:28:48 -08:00
|
|
|
#if EFI_DYNO_VIEW
|
2021-11-16 01:15:29 -08:00
|
|
|
updateDynoView();
|
2020-12-04 17:28:48 -08:00
|
|
|
#endif
|
|
|
|
|
2020-07-27 19:49:59 -07:00
|
|
|
slowCallBackWasInvoked = true;
|
|
|
|
|
2021-05-14 07:54:40 -07:00
|
|
|
#if EFI_PROD_CODE
|
|
|
|
void baroLps25Update();
|
|
|
|
baroLps25Update();
|
|
|
|
#endif // EFI_PROD_CODE
|
2021-03-04 19:39:20 -08:00
|
|
|
|
2020-12-27 14:41:28 -08:00
|
|
|
#if ANALOG_HW_CHECK_MODE
|
2021-11-17 00:54:21 -08:00
|
|
|
efiAssertVoid(OBD_PCM_Processor_Fault, isAdcChannelValid(engineConfiguration->clt.adcChannel), "No CLT setting");
|
2020-10-11 16:05:56 -07:00
|
|
|
efitimesec_t secondsNow = getTimeNowSeconds();
|
|
|
|
if (secondsNow > 2 && secondsNow < 180) {
|
2020-10-11 19:46:08 -07:00
|
|
|
assertCloseTo("RPM", Sensor::get(SensorType::Rpm).Value, HW_CHECK_RPM);
|
|
|
|
} else if (!hasFirmwareError() && secondsNow > 180) {
|
2020-10-11 19:57:31 -07:00
|
|
|
static bool isHappyTest = false;
|
2020-10-11 19:46:08 -07:00
|
|
|
if (!isHappyTest) {
|
|
|
|
setTriggerEmulatorRPM(5 * HW_CHECK_RPM);
|
2021-04-19 05:11:59 -07:00
|
|
|
efiPrintf("TEST PASSED");
|
2020-10-11 19:46:08 -07:00
|
|
|
isHappyTest = true;
|
|
|
|
}
|
2020-10-11 16:05:56 -07:00
|
|
|
}
|
2020-08-31 18:05:04 -07:00
|
|
|
assertCloseTo("clt", Sensor::get(SensorType::Clt).Value, 49.3);
|
|
|
|
assertCloseTo("iat", Sensor::get(SensorType::Iat).Value, 73.2);
|
|
|
|
assertCloseTo("aut1", Sensor::get(SensorType::AuxTemp1).Value, 13.8);
|
|
|
|
assertCloseTo("aut2", Sensor::get(SensorType::AuxTemp2).Value, 6.2);
|
2020-12-27 14:41:28 -08:00
|
|
|
#endif // ANALOG_HW_CHECK_MODE
|
2018-12-25 18:18:14 -08:00
|
|
|
}
|
|
|
|
|
2019-01-14 07:58:38 -08:00
|
|
|
|
2019-08-16 20:00:28 -07:00
|
|
|
#if (BOARD_TLE8888_COUNT > 0)
|
|
|
|
extern float vBattForTle8888;
|
|
|
|
#endif /* BOARD_TLE8888_COUNT */
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* We are executing these heavy (logarithm) methods from outside the trigger callbacks for performance reasons.
|
2016-01-01 14:02:49 -08:00
|
|
|
* See also periodicFastCallback
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::updateSlowSensors() {
|
|
|
|
updateSwitchInputs();
|
2020-12-26 18:31:41 -08:00
|
|
|
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_ENGINE_CONTROL
|
2022-01-20 19:42:13 -08:00
|
|
|
int rpm = Sensor::getOrZero(SensorType::Rpm);
|
2021-11-17 00:54:21 -08:00
|
|
|
isEngineChartEnabled = engineConfiguration->isEngineChartEnabled && rpm < engineConfiguration->engineSnifferRpmThreshold;
|
|
|
|
sensorChartMode = rpm < engineConfiguration->sensorSnifferRpmThreshold ? engineConfiguration->sensorChartMode : SC_OFF;
|
2016-01-30 19:03:36 -08:00
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
engineState.updateSlowSensors();
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-08-16 20:00:28 -07:00
|
|
|
#if (BOARD_TLE8888_COUNT > 0)
|
|
|
|
// nasty value injection into C driver which would not be able to access Engine class
|
2021-03-11 19:52:34 -08:00
|
|
|
vBattForTle8888 = Sensor::get(SensorType::BatteryVoltage).value_or(VBAT_FALLBACK_VALUE);
|
2019-08-16 20:00:28 -07:00
|
|
|
#endif /* BOARD_TLE8888_COUNT */
|
|
|
|
|
2019-01-31 08:57:15 -08:00
|
|
|
#endif
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2021-12-15 14:48:21 -08:00
|
|
|
static bool getClutchUpState() {
|
2021-12-15 16:20:07 -08:00
|
|
|
#if EFI_GPIO_HARDWARE
|
2021-12-15 14:48:21 -08:00
|
|
|
if (isBrainPinValid(engineConfiguration->clutchUpPin)) {
|
|
|
|
return engineConfiguration->clutchUpPinInverted ^ efiReadPin(engineConfiguration->clutchUpPin);
|
|
|
|
}
|
2021-12-15 16:20:07 -08:00
|
|
|
#endif // EFI_GPIO_HARDWARE
|
2021-12-15 14:48:21 -08:00
|
|
|
return engine->engineState.luaAdjustments.clutchUpState;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool getBrakePedalState() {
|
2021-12-15 16:20:07 -08:00
|
|
|
#if EFI_GPIO_HARDWARE
|
2021-12-17 13:33:43 -08:00
|
|
|
if (isBrainPinValid(engineConfiguration->brakePedalPin)) {
|
2021-12-15 14:48:21 -08:00
|
|
|
return efiReadPin(engineConfiguration->brakePedalPin);
|
|
|
|
}
|
|
|
|
return engine->engineState.luaAdjustments.brakePedalState;
|
2021-12-15 16:20:07 -08:00
|
|
|
#endif // EFI_GPIO_HARDWARE
|
2021-12-15 14:48:21 -08:00
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::updateSwitchInputs() {
|
2020-12-26 18:31:41 -08:00
|
|
|
#if EFI_GPIO_HARDWARE
|
|
|
|
// this value is not used yet
|
2021-11-17 00:54:21 -08:00
|
|
|
if (isBrainPinValid(engineConfiguration->clutchDownPin)) {
|
|
|
|
engine->clutchDownState = engineConfiguration->clutchDownPinInverted ^ efiReadPin(engineConfiguration->clutchDownPin);
|
2020-12-26 18:31:41 -08:00
|
|
|
}
|
2021-11-16 01:15:29 -08:00
|
|
|
if (hasAcToggle()) {
|
|
|
|
bool result = getAcToggle();
|
2020-12-26 18:31:41 -08:00
|
|
|
if (engine->acSwitchState != result) {
|
|
|
|
engine->acSwitchState = result;
|
|
|
|
engine->acSwitchLastChangeTime = getTimeNowUs();
|
|
|
|
}
|
|
|
|
engine->acSwitchState = result;
|
|
|
|
}
|
2021-12-15 14:48:21 -08:00
|
|
|
engine->clutchUpState = getClutchUpState();
|
|
|
|
|
2021-11-17 00:54:21 -08:00
|
|
|
if (isBrainPinValid(engineConfiguration->throttlePedalUpPin)) {
|
2022-01-10 16:48:45 -08:00
|
|
|
engine->module<IdleController>().unmock().throttlePedalUpState = efiReadPin(engineConfiguration->throttlePedalUpPin);
|
2020-12-26 18:31:41 -08:00
|
|
|
}
|
|
|
|
|
2021-12-15 14:48:21 -08:00
|
|
|
engine->brakePedalState = getBrakePedalState();
|
|
|
|
|
2020-12-26 18:31:41 -08:00
|
|
|
#endif // EFI_GPIO_HARDWARE
|
|
|
|
}
|
|
|
|
|
2021-03-15 07:23:19 -07:00
|
|
|
void Engine::onTriggerSignalEvent() {
|
2015-07-10 06:01:56 -07:00
|
|
|
isSpinning = true;
|
|
|
|
}
|
|
|
|
|
2020-10-04 16:29:26 -07:00
|
|
|
Engine::Engine() {
|
2016-12-18 07:02:38 -08:00
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
2019-01-05 20:33:04 -08:00
|
|
|
/**
|
|
|
|
* @see scheduleStopEngine()
|
|
|
|
* @return true if there is a reason to stop engine
|
|
|
|
*/
|
2019-06-08 06:51:36 -07:00
|
|
|
bool Engine::needToStopEngine(efitick_t nowNt) const {
|
2019-01-05 20:33:04 -08:00
|
|
|
return stopEngineRequestTimeNt != 0 &&
|
2020-01-19 19:23:41 -08:00
|
|
|
nowNt - stopEngineRequestTimeNt < 3 * NT_PER_SECOND;
|
2019-01-05 20:33:04 -08:00
|
|
|
}
|
|
|
|
|
2019-01-15 18:51:09 -08:00
|
|
|
int Engine::getGlobalConfigurationVersion(void) const {
|
|
|
|
return globalConfigurationVersion;
|
|
|
|
}
|
|
|
|
|
2016-12-18 07:02:38 -08:00
|
|
|
void Engine::reset() {
|
2016-01-14 21:01:42 -08:00
|
|
|
/**
|
|
|
|
* it's important for fixAngle() that engineCycle field never has zero
|
|
|
|
*/
|
|
|
|
engineCycle = getEngineCycle(FOUR_STROKE_CRANK_SENSOR);
|
2015-07-10 06:01:56 -07:00
|
|
|
memset(&ignitionPin, 0, sizeof(ignitionPin));
|
|
|
|
}
|
|
|
|
|
2016-01-01 14:02:49 -08:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* Here we have a bunch of stuff which should invoked after configuration change
|
|
|
|
* so that we can prepare some helper structures
|
|
|
|
*/
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::preCalculate() {
|
2020-05-09 19:43:39 -07:00
|
|
|
#if EFI_TUNER_STUDIO
|
|
|
|
// we take 2 bytes of crc32, no idea if it's right to call it crc16 or not
|
2020-05-09 21:59:32 -07:00
|
|
|
// we have a hack here - we rely on the fact that engineMake is the first of three relevant fields
|
2021-12-07 17:18:47 -08:00
|
|
|
engine->outputChannels.engineMakeCodeNameCrc16 = crc32(engineConfiguration->engineMake, 3 * VEHICLE_INFO_SIZE);
|
2020-06-04 17:43:52 -07:00
|
|
|
|
2020-06-04 21:43:05 -07:00
|
|
|
// we need and can empty warning message for CRC purposes
|
2021-02-16 13:58:54 -08:00
|
|
|
memset(config->warning_message, 0, sizeof(error_message_t));
|
2021-12-07 17:18:47 -08:00
|
|
|
engine->outputChannels.tuneCrc16 = crc32(config, sizeof(persistent_config_s));
|
2020-05-09 19:43:39 -07:00
|
|
|
#endif /* EFI_TUNER_STUDIO */
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2020-02-26 15:16:35 -08:00
|
|
|
#if EFI_SHAFT_POSITION_INPUT
|
2019-12-05 22:57:11 -08:00
|
|
|
void Engine::OnTriggerStateDecodingError() {
|
2020-01-26 03:12:01 -08:00
|
|
|
warning(CUSTOM_SYNC_COUNT_MISMATCH, "trigger not happy current %d/%d/%d expected %d/%d/%d",
|
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[0],
|
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[1],
|
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[2],
|
2021-06-26 19:07:26 -07:00
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(0)),
|
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(1)),
|
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(2)));
|
2020-01-26 03:28:33 -08:00
|
|
|
triggerCentral.triggerState.setTriggerErrorState();
|
|
|
|
|
2020-01-26 03:12:01 -08:00
|
|
|
|
|
|
|
triggerCentral.triggerState.totalTriggerErrorCounter++;
|
2021-11-17 00:54:21 -08:00
|
|
|
if (engineConfiguration->verboseTriggerSynchDetails || (triggerCentral.triggerState.someSortOfTriggerError && !engineConfiguration->silentTriggerError)) {
|
2020-01-26 03:12:01 -08:00
|
|
|
#if EFI_PROD_CODE
|
2021-04-19 05:11:59 -07:00
|
|
|
efiPrintf("error: synchronizationPoint @ index %d expected %d/%d/%d got %d/%d/%d",
|
2020-01-26 03:12:01 -08:00
|
|
|
triggerCentral.triggerState.currentCycle.current_index,
|
2021-06-26 19:07:26 -07:00
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(0)),
|
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(1)),
|
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(2)),
|
2020-01-26 03:12:01 -08:00
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[0],
|
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[1],
|
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[2]);
|
|
|
|
#endif /* EFI_PROD_CODE */
|
|
|
|
}
|
|
|
|
|
2019-12-05 22:57:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Engine::OnTriggerStateProperState(efitick_t nowNt) {
|
2020-09-05 15:49:42 -07:00
|
|
|
rpmCalculator.setSpinningUp(nowNt);
|
2019-12-05 22:57:11 -08:00
|
|
|
}
|
|
|
|
|
2020-01-26 09:02:54 -08:00
|
|
|
void Engine::OnTriggerSynchronizationLost() {
|
|
|
|
// Needed for early instant-RPM detection
|
2021-02-16 13:58:54 -08:00
|
|
|
rpmCalculator.setStopSpinning();
|
2021-12-27 09:09:38 -08:00
|
|
|
|
|
|
|
triggerCentral.triggerState.resetTriggerState();
|
|
|
|
|
|
|
|
for (size_t i = 0; i < efi::size(triggerCentral.vvtState); i++) {
|
|
|
|
for (size_t j = 0; j < efi::size(triggerCentral.vvtState[0]); j++) {
|
|
|
|
triggerCentral.vvtState[i][j].resetTriggerState();
|
|
|
|
}
|
|
|
|
}
|
2020-01-26 09:02:54 -08:00
|
|
|
}
|
|
|
|
|
2020-01-26 00:33:45 -08:00
|
|
|
void Engine::OnTriggerInvalidIndex(int currentIndex) {
|
|
|
|
// let's not show a warning if we are just starting to spin
|
2022-01-20 19:42:13 -08:00
|
|
|
if (Sensor::getOrZero(SensorType::Rpm) != 0) {
|
2020-01-26 00:33:45 -08:00
|
|
|
warning(CUSTOM_SYNC_ERROR, "sync error: index #%d above total size %d", currentIndex, triggerCentral.triggerShape.getSize());
|
2020-01-26 03:28:33 -08:00
|
|
|
triggerCentral.triggerState.setTriggerErrorState();
|
2020-01-26 00:33:45 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-22 10:25:35 -08:00
|
|
|
void Engine::OnTriggerSyncronization(bool wasSynchronized) {
|
2020-01-23 10:39:50 -08:00
|
|
|
// We only care about trigger shape once we have synchronized trigger. Anything could happen
|
|
|
|
// during first revolution and it's fine
|
|
|
|
if (wasSynchronized) {
|
|
|
|
/**
|
|
|
|
* We can check if things are fine by comparing the number of events in a cycle with the expected number of event.
|
|
|
|
*/
|
2020-10-05 11:22:59 -07:00
|
|
|
bool isDecodingError = triggerCentral.triggerState.validateEventCounters(triggerCentral.triggerShape);
|
2020-01-23 10:39:50 -08:00
|
|
|
|
|
|
|
enginePins.triggerDecoderErrorPin.setValue(isDecodingError);
|
|
|
|
|
|
|
|
// 'triggerStateListener is not null' means we are running a real engine and now just preparing trigger shape
|
|
|
|
// that's a bit of a hack, a sweet OOP solution would be a real callback or at least 'needDecodingErrorLogic' method?
|
|
|
|
if (isDecodingError) {
|
|
|
|
OnTriggerStateDecodingError();
|
|
|
|
}
|
|
|
|
|
|
|
|
engine->triggerErrorDetection.add(isDecodingError);
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
if (triggerCentral.isTriggerDecoderError()) {
|
2020-01-23 10:39:50 -08:00
|
|
|
warning(CUSTOM_OBD_TRG_DECODING, "trigger decoding issue. expected %d/%d/%d got %d/%d/%d",
|
2021-06-26 19:11:42 -07:00
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(0)),
|
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(1)),
|
|
|
|
TRIGGER_WAVEFORM(getExpectedEventCount(2)),
|
2020-01-23 10:39:50 -08:00
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[0],
|
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[1],
|
|
|
|
triggerCentral.triggerState.currentCycle.eventCount[2]);
|
|
|
|
}
|
|
|
|
}
|
2020-01-22 10:25:35 -08:00
|
|
|
|
|
|
|
}
|
2020-02-26 15:16:35 -08:00
|
|
|
#endif
|
2019-12-05 22:57:11 -08:00
|
|
|
|
2020-10-04 16:29:26 -07:00
|
|
|
void Engine::injectEngineReferences() {
|
2020-10-05 13:42:50 -07:00
|
|
|
primaryTriggerConfiguration.update();
|
2021-02-08 19:21:02 -08:00
|
|
|
for (int camIndex = 0;camIndex < CAMS_PER_BANK;camIndex++) {
|
|
|
|
vvtTriggerConfiguration[camIndex].update();
|
|
|
|
}
|
2020-10-04 16:29:26 -07:00
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::setConfig() {
|
2021-05-20 17:00:32 -07:00
|
|
|
efi::clear(config);
|
2020-10-04 16:29:26 -07:00
|
|
|
|
|
|
|
injectEngineReferences();
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void Engine::watchdog() {
|
|
|
|
#if EFI_ENGINE_CONTROL
|
|
|
|
if (isRunningPwmTest)
|
|
|
|
return;
|
2021-12-08 13:20:19 -08:00
|
|
|
|
|
|
|
if (module<PrimeController>()->isPriming()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
if (!isSpinning) {
|
2016-11-03 20:02:58 -07:00
|
|
|
if (!isRunningBenchTest() && enginePins.stopPins()) {
|
2016-11-04 19:02:42 -07:00
|
|
|
// todo: make this a firmwareError assuming functional tests would run
|
|
|
|
warning(CUSTOM_ERR_2ND_WATCHDOG, "Some pins were turned off by 2nd pass watchdog");
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2021-03-07 14:11:50 -08:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* todo: better watch dog implementation should be implemented - see
|
|
|
|
* http://sourceforge.net/p/rusefi/tickets/96/
|
|
|
|
*/
|
2022-01-17 18:00:49 -08:00
|
|
|
if (engine->triggerCentral.engineMovedRecently()) {
|
2021-03-07 14:11:50 -08:00
|
|
|
// Engine moved recently, no need to safe pins.
|
2015-07-10 06:01:56 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
isSpinning = false;
|
2016-12-18 07:02:38 -08:00
|
|
|
ignitionEvents.isReady = false;
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
2021-04-19 05:11:59 -07:00
|
|
|
efiPrintf("engine has STOPPED");
|
2015-07-10 06:01:56 -07:00
|
|
|
triggerInfo();
|
|
|
|
#endif
|
|
|
|
|
2016-11-03 20:02:58 -07:00
|
|
|
enginePins.stopPins();
|
2015-07-10 06:01:56 -07:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::checkShutdown() {
|
2019-04-12 19:07:03 -07:00
|
|
|
#if EFI_MAIN_RELAY_CONTROL
|
2020-09-07 11:41:04 -07:00
|
|
|
// if we are already in the "ignition_on" mode, then do nothing
|
|
|
|
if (ignitionOnTimeNt > 0) {
|
|
|
|
return;
|
|
|
|
}
|
2017-06-24 22:35:46 -07:00
|
|
|
|
2020-09-07 11:41:04 -07:00
|
|
|
// here we are in the shutdown (the ignition is off) or initial mode (after the firmware fresh start)
|
|
|
|
const efitick_t engineStopWaitTimeoutUs = 500000LL; // 0.5 sec
|
|
|
|
// in shutdown mode, we need a small cooldown time between the ignition off and on
|
|
|
|
if (stopEngineRequestTimeNt == 0 || (getTimeNowNt() - stopEngineRequestTimeNt) > US2NT(engineStopWaitTimeoutUs)) {
|
|
|
|
// if the ignition key is turned on again,
|
|
|
|
// we cancel the shutdown mode, but only if all shutdown procedures are complete
|
|
|
|
const float vBattThresholdOn = 8.0f;
|
2021-12-01 08:22:13 -08:00
|
|
|
// we fallback into zero instead of VBAT_FALLBACK_VALUE because it's not safe to false-trigger the "ignition on" event,
|
|
|
|
// and we want to turn on the main relay only when 100% sure.
|
|
|
|
if ((Sensor::get(SensorType::BatteryVoltage).value_or(0) > vBattThresholdOn) && !isInShutdownMode()) {
|
2020-09-07 11:41:04 -07:00
|
|
|
ignitionOnTimeNt = getTimeNowNt();
|
2021-10-08 01:58:11 -07:00
|
|
|
efiPrintf("Ignition voltage detected!");
|
|
|
|
if (stopEngineRequestTimeNt != 0) {
|
|
|
|
efiPrintf("Cancel the engine shutdown!");
|
|
|
|
stopEngineRequestTimeNt = 0;
|
|
|
|
}
|
2020-09-07 11:41:04 -07:00
|
|
|
}
|
2017-06-24 22:35:46 -07:00
|
|
|
}
|
|
|
|
#endif /* EFI_MAIN_RELAY_CONTROL */
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
bool Engine::isInMainRelayBench() {
|
2021-01-10 20:46:50 -08:00
|
|
|
if (mainRelayBenchStartNt == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return (getTimeNowNt() - mainRelayBenchStartNt) < NT_PER_SECOND;
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
bool Engine::isInShutdownMode() const {
|
2021-11-24 04:47:51 -08:00
|
|
|
#if EFI_MAIN_RELAY_CONTROL && EFI_PROD_CODE
|
2020-09-07 11:41:04 -07:00
|
|
|
// if we are in "ignition_on" mode and not in shutdown mode
|
|
|
|
if (stopEngineRequestTimeNt == 0 && ignitionOnTimeNt > 0) {
|
|
|
|
const float vBattThresholdOff = 5.0f;
|
|
|
|
// start the shutdown process if the ignition voltage dropped low
|
2021-03-11 19:52:34 -08:00
|
|
|
if (Sensor::get(SensorType::BatteryVoltage).value_or(VBAT_FALLBACK_VALUE) <= vBattThresholdOff) {
|
2020-09-07 11:41:04 -07:00
|
|
|
scheduleStopEngine();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// we are not in the shutdown mode?
|
|
|
|
if (stopEngineRequestTimeNt == 0) {
|
2017-06-24 22:35:46 -07:00
|
|
|
return false;
|
2020-09-07 11:41:04 -07:00
|
|
|
}
|
|
|
|
|
2021-01-10 20:46:50 -08:00
|
|
|
const efitick_t turnOffWaitTimeoutNt = NT_PER_SECOND;
|
2020-09-07 11:41:04 -07:00
|
|
|
// We don't want any transients to step in, so we wait at least 1 second whatever happens.
|
|
|
|
// Also it's good to give the stepper motor some time to start moving to the initial position (or parking)
|
2021-01-10 20:46:50 -08:00
|
|
|
if ((getTimeNowNt() - stopEngineRequestTimeNt) < turnOffWaitTimeoutNt)
|
2020-09-07 11:41:04 -07:00
|
|
|
return true;
|
|
|
|
|
2021-01-10 20:46:50 -08:00
|
|
|
const efitick_t engineSpinningWaitTimeoutNt = 5 * NT_PER_SECOND;
|
2017-06-24 22:35:46 -07:00
|
|
|
// The engine is still spinning! Give it some time to stop (but wait no more than 5 secs)
|
2021-01-10 20:46:50 -08:00
|
|
|
if (isSpinning && (getTimeNowNt() - stopEngineRequestTimeNt) < engineSpinningWaitTimeoutNt)
|
2020-09-07 11:41:04 -07:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// The idle motor valve is still moving! Give it some time to park (but wait no more than 10 secs)
|
|
|
|
// Usually it can move to the initial 'cranking' position or zero 'parking' position.
|
2021-01-10 20:46:50 -08:00
|
|
|
const efitick_t idleMotorWaitTimeoutNt = 10 * NT_PER_SECOND;
|
2021-11-16 01:15:29 -08:00
|
|
|
if (isIdleMotorBusy() && (getTimeNowNt() - stopEngineRequestTimeNt) < idleMotorWaitTimeoutNt)
|
2017-06-24 22:35:46 -07:00
|
|
|
return true;
|
|
|
|
#endif /* EFI_MAIN_RELAY_CONTROL */
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
bool Engine::isMainRelayEnabled() const {
|
2020-09-07 11:41:04 -07:00
|
|
|
#if EFI_MAIN_RELAY_CONTROL
|
|
|
|
return enginePins.mainRelay.getLogicValue();
|
|
|
|
#else
|
|
|
|
// if no main relay control, we assume it's always turned on
|
|
|
|
return true;
|
|
|
|
#endif /* EFI_MAIN_RELAY_CONTROL */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float Engine::getTimeIgnitionSeconds(void) const {
|
|
|
|
// return negative if the ignition is turned off
|
|
|
|
if (ignitionOnTimeNt == 0)
|
|
|
|
return -1;
|
2021-08-09 13:33:06 -07:00
|
|
|
float numSeconds = (float)NT2US(getTimeNowNt() - ignitionOnTimeNt) / US_PER_SECOND_F;
|
2020-09-07 11:41:04 -07:00
|
|
|
return numSeconds;
|
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
injection_mode_e Engine::getCurrentInjectionMode() {
|
2021-11-17 00:54:21 -08:00
|
|
|
return rpmCalculator.isCranking() ? engineConfiguration->crankingInjectionMode : engineConfiguration->injectionMode;
|
2016-11-30 19:06:43 -08:00
|
|
|
}
|
|
|
|
|
2019-08-07 21:19:09 -07:00
|
|
|
// see also in TunerStudio project '[doesTriggerImplyOperationMode] tag
|
|
|
|
static bool doesTriggerImplyOperationMode(trigger_type_e type) {
|
2019-08-08 19:33:52 -07:00
|
|
|
return type != TT_TOOTHED_WHEEL
|
|
|
|
&& type != TT_ONE
|
|
|
|
&& type != TT_ONE_PLUS_ONE
|
|
|
|
&& type != TT_3_1_CAM
|
2021-09-19 14:26:13 -07:00
|
|
|
&& type != TT_36_2_2_2
|
2019-08-08 19:33:52 -07:00
|
|
|
&& type != TT_TOOTHED_WHEEL_60_2
|
|
|
|
&& type != TT_TOOTHED_WHEEL_36_1;
|
2019-08-07 21:19:09 -07:00
|
|
|
}
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
operation_mode_e Engine::getOperationMode() {
|
2019-08-17 19:00:01 -07:00
|
|
|
/**
|
|
|
|
* here we ignore user-provided setting for well known triggers.
|
|
|
|
* For instance for Miata NA, there is no reason to allow user to set FOUR_STROKE_CRANK_SENSOR
|
|
|
|
*/
|
|
|
|
return doesTriggerImplyOperationMode(engineConfiguration->trigger.type) ? triggerCentral.triggerShape.getOperationMode() : engineConfiguration->ambiguousOperationMode;
|
2019-08-07 21:19:09 -07:00
|
|
|
}
|
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* The idea of this method is to execute all heavy calculations in a lower-priority thread,
|
2016-01-01 14:02:49 -08:00
|
|
|
* so that trigger event handler/IO scheduler tasks are faster.
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
2021-11-16 01:15:29 -08:00
|
|
|
void Engine::periodicFastCallback() {
|
2019-10-11 17:43:21 -07:00
|
|
|
ScopePerf pc(PE::EnginePeriodicFastCallback);
|
2016-01-01 14:02:49 -08:00
|
|
|
|
2018-02-06 12:47:19 -08:00
|
|
|
#if EFI_MAP_AVERAGING
|
2021-11-16 01:15:29 -08:00
|
|
|
refreshMapAveragingPreCalc();
|
2018-02-06 12:47:19 -08:00
|
|
|
#endif
|
2016-01-01 14:02:49 -08:00
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
engineState.periodicFastCallback();
|
2020-08-21 12:36:43 -07:00
|
|
|
|
2021-11-01 20:33:59 -07:00
|
|
|
knockController.periodicFastCallback();
|
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
tachSignalCallback();
|
2021-11-17 09:13:19 -08:00
|
|
|
|
2021-11-17 10:45:10 -08:00
|
|
|
engine->engineModules.apply_all([](auto & m) { m.onFastCallback(); });
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
2019-01-19 19:09:37 -08:00
|
|
|
|
2021-11-16 01:15:29 -08:00
|
|
|
void doScheduleStopEngine() {
|
2021-04-19 05:11:59 -07:00
|
|
|
efiPrintf("Starting doScheduleStopEngine");
|
2019-01-19 19:09:37 -08:00
|
|
|
engine->stopEngineRequestTimeNt = getTimeNowNt();
|
2020-09-07 11:41:04 -07:00
|
|
|
engine->ignitionOnTimeNt = 0;
|
|
|
|
// todo: initiate stepper motor parking
|
2020-09-10 18:08:39 -07:00
|
|
|
// make sure we have stored all the info
|
2020-09-10 18:26:21 -07:00
|
|
|
#if EFI_PROD_CODE
|
2020-09-10 19:02:02 -07:00
|
|
|
//todo: FIX kinetis build with this line
|
|
|
|
//backupRamFlush();
|
2020-09-10 18:26:21 -07:00
|
|
|
#endif // EFI_PROD_CODE
|
2019-01-19 19:09:37 -08:00
|
|
|
}
|