rusefi/firmware/controllers/algo/engine.h

326 lines
9.0 KiB
C
Raw Normal View History

2015-07-10 06:01:56 -07:00
/**
* @file engine.h
*
* @date May 21, 2014
* @author Andrey Belomutskiy, (c) 2012-2019
2015-07-10 06:01:56 -07:00
*/
2019-09-19 21:17:00 -07:00
#pragma once
2015-07-10 06:01:56 -07:00
2019-01-27 21:44:30 -08:00
#include "globalaccess.h"
2019-05-27 16:05:59 -07:00
#include "engine_state.h"
2015-07-10 06:01:56 -07:00
#include "rpm_calculator.h"
#include "event_registry.h"
#include "table_helper.h"
#include "listener_array.h"
#include "accel_enrichment.h"
2015-09-13 14:02:44 -07:00
#include "trigger_central.h"
#include "local_version_holder.h"
2015-07-10 06:01:56 -07:00
#if EFI_SIGNAL_EXECUTOR_ONE_TIMER
// PROD real firmware uses this implementation
2019-03-29 06:11:13 -07:00
#include "single_timer_executor.h"
#endif /* EFI_SIGNAL_EXECUTOR_ONE_TIMER */
#if EFI_SIGNAL_EXECUTOR_SLEEP
#include "signal_executor_sleep.h"
#endif /* EFI_SIGNAL_EXECUTOR_SLEEP */
#if EFI_UNIT_TEST
#include "global_execution_queue.h"
#endif /* EFI_UNIT_TEST */
#define FAST_CALLBACK_PERIOD_MS 5
2016-11-30 19:06:43 -08:00
2015-07-10 06:01:56 -07:00
class RpmCalculator;
#define MAF_DECODING_CACHE_SIZE 256
#define MAF_DECODING_CACHE_MULT (MAF_DECODING_CACHE_SIZE / 5.0)
/**
* I am not sure if this needs to be configurable.
*
* Also technically the whole feature might be implemented as cranking fuel coefficient curve by TPS.
*/
// todo: not great location for these
#define CLEANUP_MODE_TPS 90
#define STEPPER_PARKING_TPS CLEANUP_MODE_TPS
2019-11-23 19:55:21 -08:00
#define CYCLE_ALTERNATION 2
class IEtbController;
class Engine : public TriggerStateListener {
2015-07-10 06:01:56 -07:00
public:
explicit Engine(persistent_config_s *config);
2016-12-18 07:02:38 -08:00
Engine();
IEtbController *etbControllers[ETB_COUNT];
void OnTriggerStateDecodingError() override;
void OnTriggerStateProperState(efitick_t nowNt) override;
2016-12-18 07:02:38 -08:00
void setConfig(persistent_config_s *config);
2017-05-15 20:33:22 -07:00
injection_mode_e getCurrentInjectionMode(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2016-12-18 07:02:38 -08:00
LocalVersionHolder versionForConfigurationListeners;
LocalVersionHolder auxParametersVersion;
operation_mode_e getOperationMode(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2019-12-02 21:29:12 -08:00
AuxActor auxValves[AUX_DIGITAL_VALVE_COUNT][2];
2019-11-23 19:55:21 -08:00
bool needTdcCallback = true;
/**
* if 2nd TPS is not configured we do not run 2nd ETB
*/
int etbActualCount = 0;
2019-11-23 19:55:21 -08:00
2019-10-07 22:36:03 -07:00
/**
* By the way 32-bit value should hold at least 400 hours of events at 6K RPM x 12 events per revolution
*/
int globalSparkIdCounter = 0;
2019-11-11 19:19:35 -08:00
// this is useful at least for real hardware integration testing - maybe a proper solution would be to simply
// GND input pins instead of leaving them floating
bool hwTriggerInputEnabled = true;
#if !EFI_PROD_CODE
float mockMapValue = 0;
// for historical reasons we have options to mock TPS on different layers :(
int mockTpsAdcValue = 0;
float mockTpsValue = NAN;
#endif
int getGlobalConfigurationVersion(void) const;
/**
* true if a recent configuration change has changed any of the trigger settings which
* we have not adjusted for yet
*/
bool isTriggerConfigChanged = false;
LocalVersionHolder triggerVersion;
// a pointer with interface type would make this code nicer but would carry extra runtime
// cost to resolve pointer, we use instances as a micro optimization
#if EFI_SIGNAL_EXECUTOR_ONE_TIMER
SingleTimerExecutor executor;
#endif
#if EFI_SIGNAL_EXECUTOR_SLEEP
SleepExecutor executor;
#endif
#if EFI_UNIT_TEST
TestExecutor executor;
#endif
2016-01-25 09:01:30 -08:00
2019-04-12 19:07:03 -07:00
#if EFI_ENGINE_CONTROL
2016-12-18 09:03:48 -08:00
FuelSchedule injectionEvents;
IgnitionEventList ignitionEvents;
2016-12-18 09:03:48 -08:00
#endif /* EFI_ENGINE_CONTROL */
2016-02-06 07:01:34 -08:00
2019-10-16 21:06:54 -07:00
WallFuel wallFuel[INJECTION_PIN_COUNT];
bool needToStopEngine(efitick_t nowNt) const;
2019-01-19 19:31:55 -08:00
bool etbAutoTune = false;
2016-01-26 20:01:44 -08:00
/**
* That's the linked list of pending events scheduled in relation to trigger
* At the moment we iterate over the whole list while looking for events for specific trigger index
* We can make it an array of lists per trigger index, but that would take some RAM and probably not needed yet.
2016-01-26 20:01:44 -08:00
*/
AngleBasedEvent *angleBasedEventsHead = nullptr;
2016-01-30 19:03:36 -08:00
/**
* this is based on isEngineChartEnabled and engineSnifferRpmThreshold settings
*/
2019-01-19 19:31:55 -08:00
bool isEngineChartEnabled = false;
2016-01-30 19:03:36 -08:00
/**
* this is based on sensorChartMode and sensorSnifferRpmThreshold settings
*/
2019-01-19 19:31:55 -08:00
sensor_chart_e sensorChartMode = SC_OFF;
2016-01-31 16:01:34 -08:00
/**
* based on current RPM and isAlternatorControlEnabled setting
*/
2019-01-19 19:31:55 -08:00
bool isAlternatorControlEnabled = false;
2016-01-26 20:01:44 -08:00
2019-01-19 19:31:55 -08:00
bool isCltBroken = false;
bool slowCallBackWasInvoked = false;
2017-05-11 05:32:08 -07:00
2017-05-01 19:33:20 -07:00
// floatms_t callToPitEndTime;
/**
2017-05-04 14:03:23 -07:00
* remote telemetry: if not zero, time to stop flashing 'CALL FROM PIT STOP' light
2017-05-01 19:33:20 -07:00
*/
2019-01-19 19:31:55 -08:00
efitime_t callFromPitStopEndTime = 0;
2017-07-26 17:27:08 -07:00
// timestamp of most recent time RPM hard limit was triggered
2019-01-19 19:31:55 -08:00
efitime_t rpmHardLimitTimestamp = 0;
2017-05-01 19:33:20 -07:00
2017-02-24 16:20:33 -08:00
/**
* This flag indicated a big enough problem that engine control would be
* prohibited if this flag is set to true.
*/
2019-01-19 19:31:55 -08:00
bool withError = false;
2017-02-24 16:20:33 -08:00
2015-07-10 06:01:56 -07:00
RpmCalculator rpmCalculator;
2019-09-22 05:22:35 -07:00
persistent_config_s *config = nullptr;
/**
* we use funny unique name to make sure that compiler is not confused between global variable and class member
* todo: this variable is probably a sign of some problem, should we even have it?
*/
2019-09-22 05:22:35 -07:00
engine_configuration_s *engineConfigurationPtr = nullptr;
2015-07-10 06:01:56 -07:00
/**
* this is about 'stopengine' command
*/
2019-01-19 19:31:55 -08:00
efitick_t stopEngineRequestTimeNt = 0;
2015-07-10 06:01:56 -07:00
/**
2019-05-02 14:52:48 -07:00
* This counter is incremented every time user adjusts ECU parameters online (either via rusEfi console or other
* tuning software)
*/
volatile int globalConfigurationVersion = 0;
2016-01-30 19:03:36 -08:00
/**
* always 360 or 720, never zero
*/
2016-01-14 21:01:42 -08:00
angle_t engineCycle;
LoadAccelEnrichment engineLoadAccelEnrichment;
TpsAccelEnrichment tpsAccelEnrichment;
2015-07-10 06:01:56 -07:00
2015-09-13 14:02:44 -07:00
TriggerCentral triggerCentral;
2015-07-10 06:01:56 -07:00
/**
2016-10-12 22:02:02 -07:00
* Each individual fuel injection duration for current engine cycle, without wall wetting
* including everything including injector lag, both cranking and running
2017-11-06 19:29:39 -08:00
* @see getInjectionDuration()
2015-07-10 06:01:56 -07:00
*/
2019-01-19 19:31:55 -08:00
floatms_t injectionDuration = 0;
2015-07-10 06:01:56 -07:00
2015-08-23 20:02:37 -07:00
/**
* This one with wall wetting accounted for, used for logging.
*/
2019-01-19 19:31:55 -08:00
floatms_t actualLastInjection = 0;
2015-08-23 20:02:37 -07:00
2017-05-15 20:33:22 -07:00
void periodicFastCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void periodicSlowCallback(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2017-05-15 20:33:22 -07:00
void updateSlowSensors(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void initializeTriggerWaveform(Logging *logger DECLARE_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
2019-01-19 19:31:55 -08:00
bool clutchUpState = false;
bool clutchDownState = false;
bool brakePedalState = false;
2019-09-08 18:05:03 -07:00
// todo: extract some helper which would contain boolean state and most recent toggle time?
bool acSwitchState = false;
2019-09-08 18:05:03 -07:00
efitimeus_t acSwitchLastChangeTime = 0;
2015-07-10 06:01:56 -07:00
2019-01-19 19:31:55 -08:00
bool isRunningPwmTest = false;
2015-07-10 06:01:56 -07:00
2018-03-18 09:15:51 -07:00
FsioState fsioState;
2015-07-10 06:01:56 -07:00
/**
* Are we experiencing knock right now?
*/
2019-01-19 19:31:55 -08:00
bool knockNow = false;
2015-07-10 06:01:56 -07:00
/**
* Have we experienced knock since engine was started?
*/
2019-01-19 19:31:55 -08:00
bool knockEver = false;
2015-07-10 06:01:56 -07:00
/**
* KnockCount is directly proportional to the degrees of ignition
* advance removed
*/
2019-01-19 19:31:55 -08:00
int knockCount = 0;
2015-07-10 06:01:56 -07:00
2019-01-19 19:31:55 -08:00
float knockVolts = 0;
2015-07-11 13:01:31 -07:00
2019-01-19 19:31:55 -08:00
bool knockDebug = false;
2015-07-10 06:01:56 -07:00
2019-01-19 19:31:55 -08:00
efitimeus_t timeOfLastKnockEvent = 0;
2015-07-10 06:01:56 -07:00
/**
* are we running any kind of functional test? this affect
* some areas
*/
2019-01-19 19:31:55 -08:00
bool isTestMode = false;
2019-12-21 17:43:11 -08:00
void resetEngineSnifferIfInTestMode();
2015-07-10 06:01:56 -07:00
/**
* pre-calculated offset for given sequence index within engine cycle
* (not cylinder ID)
*/
2018-07-24 17:40:44 -07:00
angle_t ignitionPositionWithinEngineCycle[IGNITION_PIN_COUNT];
2015-07-10 06:01:56 -07:00
/**
* pre-calculated reference to which output pin should be used for
* given sequence index within engine cycle
2016-01-16 14:02:38 -08:00
* todo: update documentation
2015-07-10 06:01:56 -07:00
*/
2016-01-16 14:02:38 -08:00
int ignitionPin[IGNITION_PIN_COUNT];
2015-07-10 06:01:56 -07:00
2019-01-27 23:29:13 -08:00
// Store current ignition mode for prepareIgnitionPinIndices()
ignition_mode_e ignitionModeForPinIndices = Force_4_bytes_size_ignition_mode;
2017-11-20 12:01:48 -08:00
/**
* this is invoked each time we register a trigger tooth signal
*/
void onTriggerSignalEvent(efitick_t nowNt);
2015-07-10 06:01:56 -07:00
EngineState engineState;
SensorsState sensors;
2019-01-19 19:31:55 -08:00
efitick_t lastTriggerToothEventTimeNt = 0;
2015-07-10 06:01:56 -07:00
/**
* This coefficient translates ADC value directly into voltage adjusted according to
2018-11-03 06:44:34 -07:00
* voltage divider configuration with just one multiplication. This is a future (?) performance optimization.
2015-07-10 06:01:56 -07:00
*/
2019-01-19 19:31:55 -08:00
float adcToVoltageInputDividerCoefficient = NAN;
2015-07-10 06:01:56 -07:00
/**
* This field is true if we are in 'cylinder cleanup' state right now
* see isCylinderCleanupEnabled
*/
2019-01-19 19:31:55 -08:00
bool isCylinderCleanupMode = false;
2015-07-10 06:01:56 -07:00
/**
* value of 'triggerShape.getLength()'
* pre-calculating this value is a performance optimization
*/
2019-01-19 19:31:55 -08:00
uint32_t engineCycleEventCount = 0;
2015-07-10 06:01:56 -07:00
void preCalculate(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2015-07-10 06:01:56 -07:00
void watchdog();
/**
* Needed by EFI_MAIN_RELAY_CONTROL to shut down the engine correctly.
*/
void checkShutdown();
/**
* Allows to finish some long-term shutdown procedures (stepper motor parking etc.)
Returns true if some operations are in progress on background.
*/
bool isInShutdownMode() const;
2015-07-10 06:01:56 -07:00
monitoring_timestamps_s m;
void knockLogic(float knockVolts DECLARE_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
void printKnockState(void);
private:
/**
* By the way:
* 'cranking' means engine is not stopped and the rpm are below crankingRpm
* 'running' means RPM are above crankingRpm
* 'spinning' means the engine is not stopped
*/
2019-01-19 19:31:55 -08:00
bool isSpinning = false;
void reset();
2015-07-10 06:01:56 -07:00
};
2017-05-15 20:33:22 -07:00
void prepareShapes(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void applyNonPersistentConfiguration(Logging * logger DECLARE_ENGINE_PARAMETER_SUFFIX);
void prepareOutputSignals(DECLARE_ENGINE_PARAMETER_SIGNATURE);
2018-02-03 07:48:35 -08:00
2017-08-31 04:53:41 -07:00
void validateConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE);
void doScheduleStopEngine(DECLARE_ENGINE_PARAMETER_SIGNATURE);