/
limp_manager.h
176 lines (138 loc) · 3.91 KB
/
limp_manager.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#pragma once
#include "shutdown_controller.h"
#include <cstdint>
// Keep this list in sync with fuelIgnCutCodeList in tunerstudio.template.ini!
enum class ClearReason : uint8_t {
None, // 0
Fatal, // 1
Settings, // 2
HardLimit, // 3
FaultRevLimit,
BoostCut, // 5
OilPressure, // 6
StopRequested, // 7
EtbProblem, // 8
LaunchCut, // 9
InjectorDutyCycle, // 10
FloodClear, // 11
EnginePhase, // 12
KickStart, // 13
IgnitionOff, // 14
Lua, // 15
ACR, // 16 - Harley Automatic Compression Release
LambdaProtection, // 17
GdiComms,
PleaseBrake,
// Keep this list in sync with fuelIgnCutCodeList in tunerstudio.template.ini!
// todo: add a code generator between ClearReason and fuelIgnCutCodeList in tunerstudio.template.ini
};
enum class TpsState : uint8_t {
None, // 0
EngineStopped, // 1
TpsError, // 2
PpsError, // 3
IntermittentTps, // 4
PidJitter, // 5
Lua, // 6
Manual, // 7
NotConfigured, // 8
Redundancy, // 9
IntermittentPps, // 10
// keep this list in sync with etbCutCodeList in tunerstudio.template.ini!
};
// Only allows clearing the value, but never resetting it.
class Clearable {
public:
Clearable() : m_value(true) {}
Clearable(bool value) : m_value(value) {
if (!m_value) {
clearReason = ClearReason::Settings;
}
}
void clear(ClearReason p_clearReason) {
if (m_value) {
m_value = false;
clearReason = p_clearReason;
}
}
operator bool() const {
return m_value;
}
ClearReason clearReason = ClearReason::None;
private:
bool m_value = true;
};
struct LimpState {
const bool value;
const ClearReason reason;
// Implicit conversion operator to bool, so you can do things like if (myResult) { ... }
constexpr explicit operator bool() const {
return value;
}
};
class Hysteresis {
public:
// returns true if value > rising, false if value < falling, previous if falling < value < rising.
bool test(float value, float rising, float falling) {
return test(value > rising, value < falling);
}
bool test (bool risingCondition, bool fallingCondition) {
if (risingCondition) {
m_state = true;
} else if (fallingCondition) {
m_state = false;
}
return m_state;
}
private:
bool m_state = false;
};
class LimpManager : public EngineModule {
public:
ShutdownController shutdownController;
// This is called from periodicFastCallback to update internal state
void updateState(int rpm, efitick_t nowNt);
void onFastCallback() override;
void onIgnitionStateChanged(bool ignitionOn) override;
// Other subsystems call these APIs to determine their behavior
bool allowElectronicThrottle() const;
LimpState allowInjection() const;
LimpState allowIgnition() const;
float getTimeSinceAnyCut() const;
bool allowTriggerInput() const;
void updateRevLimit(int rpm);
angle_t getLimitingTimingRetard() const;
float getLimitingFuelCorrection() const;
// Other subsystems call these APIs to indicate a problem has occurred
// void reportEtbProblem();
void fatalError();
Timer gdiComms;
private:
void setFaultRevLimit(int limit);
Hysteresis m_revLimitHysteresis;
Hysteresis m_boostCutHysteresis;
Hysteresis m_injectorDutyCutHysteresis;
// Start with no fault rev limit
int32_t m_faultRevLimit = INT32_MAX;
Clearable m_allowEtb;
Clearable m_allowInjection;
Clearable m_allowIgnition;
Clearable m_allowTriggerInput;
Clearable m_transientAllowInjection = true;
Clearable m_transientAllowIgnition = true;
bool m_hadOilPressureAfterStart = false;
// Ignition switch state
bool m_ignitionOn = false;
angle_t m_timingRetard = 0;
float m_fuelCorrection = 1.0f;
// todo: migrate to engineState->desiredRpmLimit to get this variable logged
float m_revLimit;
float resumeRpm;
// Tracks how long since a cut (ignition or fuel) was active for any reason
Timer m_lastCutTime;
// Tracks how long injector duty has been over the sustained limit
Timer m_injectorDutySustainedTimer;
};
#if EFI_ENGINE_CONTROL
LimpManager * getLimpManager();
#endif // EFI_ENGINE_CONTROL