rusEFI
The most advanced open source ECU
engine2.cpp
Go to the documentation of this file.
1 /*
2  * engine2.cpp
3  *
4  * @date Jan 5, 2019
5  * @author Andrey Belomutskiy, (c) 2012-2020
6  */
7 
8 // todo: move this code to more proper locations
9 
10 #include "pch.h"
11 
12 
13 #include "speed_density.h"
14 #include "fuel_math.h"
15 #include "advance_map.h"
16 #include "aux_valves.h"
17 #include "closed_loop_fuel.h"
18 #include "launch_control.h"
19 #include "injector_model.h"
20 #include "tunerstudio.h"
21 
22 #if EFI_PROD_CODE
23 #include "svnversion.h"
24 #endif
25 
26 #if ! EFI_UNIT_TEST
27 #include "status_loop.h"
28 #endif
29 
31  clear();
32 }
33 
35  warningCounter = 0;
38 }
39 
43 
44  warning_t* existing = recentWarnings.find(code);
45 
46  if (!existing) {
47  chibios_rt::CriticalSectionLocker csl;
48 
49  // Add the code to the list
50  existing = recentWarnings.add(warning_t(code));
51  }
52 
53  if (existing) {
54  // Reset the timer on the code to now
55  existing->LastTriggered.reset();
56  }
57 
58  // Reset the "any warning" timer too
59  timeSinceLastWarning.reset();
60 }
61 
62 /**
63  * @param forIndicator if we want to retrieving value for TS indicator, this case a minimal period is applued
64  */
66  int period = maxI(3, engineConfiguration->warningPeriod);
67 
68  return !timeSinceLastWarning.hasElapsedSec(period);
69 }
70 
71 // Check whether a particular warning is active
74 
75  // No warning found at all
76  if (!warn) {
77  return false;
78  }
79 
80  // If the warning is old, it is not active
81  return !warn->LastTriggered.hasElapsedSec(maxI(3, engineConfiguration->warningPeriod));
82 }
83 
86 }
87 
89 }
90 
92 #if EFI_LAUNCH_CONTROL
95 #endif // EFI_LAUNCH_CONTROL
96 }
97 
98 #define MAKE_HUMAN_READABLE_ADVANCE(advance) (advance > getEngineState()->engineCycle / 2 ? advance - getEngineState()->engineCycle : advance)
99 
102 
103 #if EFI_SHAFT_POSITION_INPUT
105  warning(ObdCode::CUSTOM_SLOW_NOT_INVOKED, "Slow not invoked yet");
106  }
107  efitick_t nowNt = getTimeNowNt();
108 
110  crankingTimer.reset(nowNt);
111  }
112 
114 
116 
119  engine->ignitionState.dwellDurationAngle = cisnan(rpm) ? NAN : engine->ignitionState.sparkDwell / getOneDegreeTimeMs(rpm);
120 
121  // todo: move this into slow callback, no reason for IAT corr to be here
123  // todo: move this into slow callback, no reason for CLT corr to be here
125 
126  engine->module<DfcoController>()->update();
127  // should be called before getInjectionMass() and getLimitingTimingRetard()
129 
130  // post-cranking fuel enrichment.
131  float m_postCrankingFactor = interpolate3d(
135  );
136  // for compatibility reasons, apply only if the factor is greater than unity (only allow adding fuel)
137  // if the engine run time is past the last bin, disable ASE in case the table is filled with values more than 1.0, helps with compatibility
139  m_postCrankingFactor = 1.0f;
140  }
141  engine->fuelComputer.running.postCrankingFuelCorrection = m_postCrankingFactor;
142 
144 
146 
147  auto tps = Sensor::get(SensorType::Tps1);
148  updateTChargeK(rpm, tps.value_or(0));
149 
150  float untrimmedInjectionMass = getInjectionMass(rpm) * engine->engineState.lua.fuelMult + engine->engineState.lua.fuelAdd;
151  auto clResult = fuelClosedLoopCorrection();
152 
154  float stage2InjectionMass = untrimmedInjectionMass * injectionStage2Fraction;
155  float stage1InjectionMass = untrimmedInjectionMass - stage2InjectionMass;
156 
157  // Store the pre-wall wetting injection duration for scheduling purposes only, not the actual injection duration
158  engine->engineState.injectionDuration = engine->module<InjectorModelPrimary>()->getInjectionDuration(stage1InjectionMass);
161  ? engine->module<InjectorModelSecondary>()->getInjectionDuration(stage2InjectionMass)
162  : 0;
163 
164  float fuelLoad = getFuelingLoad();
165  injectionOffset = getInjectionOffset(rpm, fuelLoad);
166  engine->lambdaMonitor.update(rpm, fuelLoad);
167 
168  float l_ignitionLoad = getIgnitionLoad();
169  float baseAdvance = getAdvance(rpm, l_ignitionLoad) * engine->ignitionState.luaTimingMult + engine->ignitionState.luaTimingAdd;
170  float correctedIgnitionAdvance = baseAdvance
171  // Pull any extra timing for knock retard
172  - engine->module<KnockController>()->getKnockRetard()
173  // Degrees of timing REMOVED from actual timing during soft RPM limit window
175  // these fields are scaled_channel so let's only use for observability, with a local variables holding value while it matters locally
176  engine->ignitionState.baseIgnitionAdvance = MAKE_HUMAN_READABLE_ADVANCE(baseAdvance);
178 
179 
180  // compute per-bank fueling
181  for (size_t i = 0; i < STFT_BANK_COUNT; i++) {
182  float corr = clResult.banks[i];
183  engine->stftCorrection[i] = corr;
184  }
185 
186  // Now apply that to per-cylinder fueling and timing
187  for (size_t i = 0; i < engineConfiguration->cylindersCount; i++) {
188  uint8_t bankIndex = engineConfiguration->cylinderBankSelect[i];
189  auto bankTrim = engine->stftCorrection[bankIndex];
190  auto cylinderTrim = getCylinderFuelTrim(i, rpm, fuelLoad);
191 
192  // Apply both per-bank and per-cylinder trims
193  engine->engineState.injectionMass[i] = untrimmedInjectionMass * bankTrim * cylinderTrim;
194 
195  timingAdvance[i] = correctedIgnitionAdvance + getCylinderIgnitionTrim(i, rpm, l_ignitionLoad);
196  }
197 
199 
200  // TODO: calculate me from a table!
202 
204 
205 #if EFI_LAUNCH_CONTROL
207 #endif //EFI_LAUNCH_CONTROL
208 
209 #if EFI_ANTILAG_SYSTEM
211 #endif //EFI_ANTILAG_SYSTEM
212 #endif // EFI_SHAFT_POSITION_INPUT
213 }
214 
215 #if EFI_ENGINE_CONTROL
216 void EngineState::updateTChargeK(int rpm, float tps) {
217  float newTCharge = engine->fuelComputer.getTCharge(rpm, tps);
218  // convert to microsecs and then to seconds
219  efitick_t curTime = getTimeNowNt();
220  float secsPassed = (float)NT2US(curTime - timeSinceLastTChargeK) / US_PER_SECOND_F;
221  if (!cisnan(newTCharge)) {
222  // control the rate of change or just fill with the initial value
224  sd.tChargeK = convertCelsiusToKelvin(sd.tCharge);
225  timeSinceLastTChargeK = curTime;
226  }
227 }
228 #endif
229 
230 #if EFI_SIMULATOR
231 #define VCS_VERSION "123"
232 #endif
233 
236  TriggerType = getType();
237 }
238 
241 }
242 
245 }
246 
248  // Convert from VVT type to trigger_config_s
250 }
251 
254 }
255 
258  bool isLocked = lock > 0;
259  if (isLocked) {
260  criticalError("Tune is password protected. Please use console to unlock tune.");
261  }
262  return isLocked;
263 }
264 
265 void unlockEcu(int password) {
266  if (password != engineConfiguration->tuneHidingKey) {
267  efiPrintf("Nope rebooting...");
268 #if EFI_PROD_CODE
269  scheduleReboot();
270 #endif // EFI_PROD_CODE
271  } else {
272  efiPrintf("Unlocked! Burning...");
274  requestBurn();
275  }
276 }
angle_t getAdvance(int rpm, float engineLoad)
size_t getMultiSparkCount(int rpm)
angle_t getCylinderIgnitionTrim(size_t cylinderNumber, int rpm, float ignitionLoad)
void recalculateAuxValveTiming()
Definition: aux_valves.cpp:79
uint8_t code
Definition: bluetooth.cpp:39
FuelComputer fuelComputer
Definition: engine.h:118
SoftSparkLimiter softSparkLimiter
Definition: engine.h:190
IgnitionState ignitionState
Definition: engine.h:207
float stftCorrection[STFT_BANK_COUNT]
Definition: engine.h:279
bool slowCallBackWasInvoked
Definition: engine.h:260
LaunchControlBase launchController
Definition: engine.h:189
EngineState engineState
Definition: engine.h:304
RpmCalculator rpmCalculator
Definition: engine.h:262
constexpr auto & module()
Definition: engine.h:174
AntilagSystemBase antilagController
Definition: engine.h:196
LambdaMonitor lambdaMonitor
Definition: engine.h:204
SoftSparkLimiter hardSparkLimiter
Definition: engine.h:192
angle_t injectionOffset
Definition: engine_state.h:85
void updateTChargeK(int rpm, float tps)
Definition: engine2.cpp:216
efitick_t timeSinceLastTChargeK
Definition: engine_state.h:63
Timer crankingTimer
Definition: engine_state.h:39
void updateSlowSensors()
Definition: engine2.cpp:88
float injectionMass[MAX_CYLINDER_COUNT]
Definition: engine_state.h:35
void periodicFastCallback()
Definition: engine2.cpp:100
bool shouldUpdateInjectionTiming
Definition: engine_state.h:89
void updateSparkSkip()
Definition: engine2.cpp:91
angle_t trailingSparkAngle
Definition: engine_state.h:61
floatms_t injectionDuration
Definition: engine_state.h:82
floatms_t injectionDurationStage2
Definition: engine_state.h:83
float injectionStage2Fraction
Definition: engine_state.h:37
multispark_state multispark
Definition: engine_state.h:87
angle_t timingAdvance[MAX_CYLINDER_COUNT]
Definition: engine_state.h:58
floatms_t getSparkDwell(int rpm)
Definition: engine_math.cpp:77
void updateRevLimit(int rpm)
angle_t getLimitingTimingRetard() const
trigger_config_s getType() const override
Definition: engine2.cpp:239
bool isVerboseTriggerSynchDetails() const override
Definition: engine2.cpp:243
bool isCranking() const override
uint32_t getRevolutionCounterSinceStart(void) const
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition: sensor.h:92
void setTargetSkipRatio(float targetSkipRatio)
virtual bool isVerboseTriggerSynchDetails() const =0
trigger_config_s TriggerType
virtual trigger_config_s getType() const =0
trigger_config_s getType() const override
Definition: engine2.cpp:247
bool isVerboseTriggerSynchDetails() const override
Definition: engine2.cpp:252
warningBuffer_t recentWarnings
Definition: engine_parts.h:68
ObdCode lastErrorCode
Definition: engine_parts.h:63
void addWarningCode(ObdCode code)
Definition: engine2.cpp:40
bool isWarningNow() const
Definition: engine2.cpp:65
Timer timeSinceLastWarning
Definition: engine_parts.h:65
ClosedLoopFuelResult fuelClosedLoopCorrection()
float limitRateOfChange(float newValue, float oldValue, float incrLimitPerSec, float decrLimitPerSec, float secsPassed)
Definition: efilib.cpp:189
efitick_t getTimeNowNt()
Definition: efitime.cpp:19
void unlockEcu(int password)
Definition: engine2.cpp:265
bool isLockedFromUser()
Definition: engine2.cpp:256
LimpManager * getLimpManager()
Definition: engine.cpp:595
trigger_type_e getVvtTriggerType(vvt_mode_e vvtMode)
Definition: engine.cpp:69
void scheduleReboot()
Definition: rusefi.cpp:158
Engine * engine
float getFuelingLoad()
Definition: engine_math.cpp:47
float getIgnitionLoad()
Definition: engine_math.cpp:51
bool warning(ObdCode code, const char *fmt,...)
float getCylinderFuelTrim(size_t cylinderNumber, int rpm, float fuelLoad)
Definition: fuel_math.cpp:441
float getStage2InjectionFraction(int rpm, float load)
Definition: fuel_math.cpp:455
angle_t getCltTimingCorrection()
Definition: fuel_math.cpp:362
angle_t getInjectionOffset(float rpm, float load)
Definition: fuel_math.cpp:208
float getIatFuelCorrection()
Definition: fuel_math.cpp:371
percent_t getInjectorDutyCycle(int rpm)
Definition: fuel_math.cpp:279
float getBaroCorrection()
Definition: fuel_math.cpp:380
float getCltFuelCorrection()
Engine warm-up fuel correction.
Definition: fuel_math.cpp:353
float getInjectionMass(int rpm)
Definition: fuel_math.cpp:303
static bool isLocked
Definition: flash_int.cpp:22
ObdCode
@ CUSTOM_SLOW_NOT_INVOKED
@ EngineStatePeriodicFastCallback
engine_configuration_s * engineConfiguration
correctedIgnitionAdvance("Timing: ignition", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 896, 0.02, 0.0, 0.0, "deg")
temperature_t getTCharge(int rpm, float tps)
void update(float rpm, float load)
float postCrankingFactor[CRANKING_ENRICH_COUNT][CRANKING_ENRICH_COUNT]
scaled_channel< uint16_t, 100, 1 > afrTableYAxis
scaled_channel< int16_t, 50, 1 > baseIgnitionAdvance
scaled_channel< int16_t, 100, 1 > cltTimingCorrection
scaled_channel< int16_t, 50, 1 > correctedIgnitionAdvance
scaled_channel< int16_t, 100, 1 > tCharge
T * find(const TSearch &search) const
Definition: static_vector.h:11
T * add(const T &value)
Definition: static_vector.h:21
Timer LastTriggered
Definition: engine_parts.h:32
composite packet size
void requestBurn()