Line |
Branch |
Decision |
Exec |
Source |
1 |
|
|
|
/** |
2 |
|
|
|
* @file settings.cpp |
3 |
|
|
|
* @brief This file is about configuring engine via the human-readable protocol |
4 |
|
|
|
* |
5 |
|
|
|
* @date Dec 30, 2012 |
6 |
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020 |
7 |
|
|
|
*/ |
8 |
|
|
|
|
9 |
|
|
|
#include "pch.h" |
10 |
|
|
|
|
11 |
|
|
|
#if ! EFI_UNIT_TEST |
12 |
|
|
|
|
13 |
|
|
|
#include "eficonsole.h" |
14 |
|
|
|
#include "trigger_decoder.h" |
15 |
|
|
|
#include "console_io.h" |
16 |
|
|
|
#include "idle_thread.h" |
17 |
|
|
|
#include "alternator_controller.h" |
18 |
|
|
|
#include "trigger_emulator_algo.h" |
19 |
|
|
|
#include "value_lookup.h" |
20 |
|
|
|
#if EFI_RTC |
21 |
|
|
|
#include "rtc_helper.h" |
22 |
|
|
|
#endif // EFI_RTC |
23 |
|
|
|
|
24 |
|
|
|
#if EFI_PROD_CODE |
25 |
|
|
|
#include "can_hw.h" |
26 |
|
|
|
#include "rusefi.h" |
27 |
|
|
|
#include "hardware.h" |
28 |
|
|
|
#endif // EFI_PROD_CODE |
29 |
|
|
|
|
30 |
|
|
|
#if EFI_ELECTRONIC_THROTTLE_BODY |
31 |
|
|
|
#include "electronic_throttle.h" |
32 |
|
|
|
#endif // EFI_ELECTRONIC_THROTTLE_BODY |
33 |
|
|
|
|
34 |
|
|
|
#if EFI_CONFIGURATION_STORAGE |
35 |
|
|
|
#include "flash_main.h" |
36 |
|
|
|
#endif // EFI_CONFIGURATION_STORAGE |
37 |
|
|
|
|
38 |
|
|
|
#if EFI_ENGINE_SNIFFER |
39 |
|
|
|
#include "engine_sniffer.h" |
40 |
|
|
|
extern int waveChartUsedSize; |
41 |
|
|
|
extern WaveChart waveChart; |
42 |
|
|
|
#endif // EFI_ENGINE_SNIFFER |
43 |
|
|
|
|
44 |
|
|
|
using namespace rusefi::stringutil; |
45 |
|
|
|
|
46 |
|
|
|
void printSpiState() { |
47 |
|
|
|
efiPrintf("spi 1=%s/2=%s/3=%s/4=%s", |
48 |
|
|
|
boolToString(engineConfiguration->is_enabled_spi_1), |
49 |
|
|
|
boolToString(engineConfiguration->is_enabled_spi_2), |
50 |
|
|
|
boolToString(engineConfiguration->is_enabled_spi_3), |
51 |
|
|
|
boolToString(engineConfiguration->is_enabled_spi_4)); |
52 |
|
|
|
} |
53 |
|
|
|
|
54 |
|
|
|
/** |
55 |
|
|
|
* @brief Prints current engine configuration to human-readable console. |
56 |
|
|
|
*/ |
57 |
|
|
|
void printConfiguration() { |
58 |
|
|
|
|
59 |
|
|
|
efiPrintf("Template %s/%d trigger %s/%s/%d", getEngine_type_e(engineConfiguration->engineType), |
60 |
|
|
|
(int)engineConfiguration->engineType, |
61 |
|
|
|
getTrigger_type_e(engineConfiguration->trigger.type), |
62 |
|
|
|
Enum2String(engineConfiguration->fuelAlgorithm), (int)engineConfiguration->fuelAlgorithm); |
63 |
|
|
|
|
64 |
|
|
|
efiPrintf("configurationVersion=%d", engine->getGlobalConfigurationVersion()); |
65 |
|
|
|
|
66 |
|
|
|
#if EFI_PROD_CODE |
67 |
|
|
|
printSpiState(); |
68 |
|
|
|
#endif // EFI_PROD_CODE |
69 |
|
|
|
} |
70 |
|
|
|
|
71 |
|
|
|
#if EFI_ENGINE_CONTROL |
72 |
|
|
|
static void setIdleSolenoidFrequency(int value) { |
73 |
|
|
|
engineConfiguration->idle.solenoidFrequency = value; |
74 |
|
|
|
incrementGlobalConfigurationVersion(); |
75 |
|
|
|
} |
76 |
|
|
|
#endif // EFI_ENGINE_CONTROL |
77 |
|
|
|
|
78 |
|
|
|
#if EFI_ENGINE_CONTROL |
79 |
|
|
|
static void setCrankingRpm(int value) { |
80 |
|
|
|
engineConfiguration->cranking.rpm = value; |
81 |
|
|
|
printConfiguration(); |
82 |
|
|
|
} |
83 |
|
|
|
|
84 |
|
|
|
/** |
85 |
|
|
|
* this method is used in console - it also prints current configuration |
86 |
|
|
|
*/ |
87 |
|
|
|
static void setAlgorithmInt(int value) { |
88 |
|
|
|
setAlgorithm((engine_load_mode_e) value); |
89 |
|
|
|
printConfiguration(); |
90 |
|
|
|
} |
91 |
|
|
|
|
92 |
|
|
|
static void setFiringOrder(int value) { |
93 |
|
|
|
engineConfiguration->firingOrder = (firing_order_e) value; |
94 |
|
|
|
printConfiguration(); |
95 |
|
|
|
} |
96 |
|
|
|
|
97 |
|
|
|
static void setRpmHardLimit(int value) { |
98 |
|
|
|
engineConfiguration->rpmHardLimit = value; |
99 |
|
|
|
printConfiguration(); |
100 |
|
|
|
} |
101 |
|
|
|
|
102 |
|
|
|
static void setCrankingIACExtra(float percent) { |
103 |
|
|
|
for (uint8_t i = 0; i < CLT_CRANKING_CURVE_SIZE; i++) { |
104 |
|
|
|
config->cltCrankingCorr[i] = percent; |
105 |
|
|
|
} |
106 |
|
|
|
efiPrintf("cranking_iac %.2f", percent); |
107 |
|
|
|
} |
108 |
|
|
|
|
109 |
|
|
|
static void setCrankingFuel(float fuelMilligram) { |
110 |
|
|
|
setTable(config->crankingCycleBaseFuel, fuelMilligram); |
111 |
|
|
|
efiPrintf("cranking_fuel %.2f", fuelMilligram); |
112 |
|
|
|
} |
113 |
|
|
|
|
114 |
|
|
|
static void setGlobalTriggerAngleOffset(float value) { |
115 |
|
|
|
engineConfiguration->globalTriggerAngleOffset = value; |
116 |
|
|
|
incrementGlobalConfigurationVersion(); |
117 |
|
|
|
printConfiguration(); |
118 |
|
|
|
} |
119 |
|
|
|
|
120 |
|
|
|
static void setCrankingTimingAngle(float value) { |
121 |
|
|
|
engineConfiguration->crankingTimingAngle = value; |
122 |
|
|
|
incrementGlobalConfigurationVersion(); |
123 |
|
|
|
printConfiguration(); |
124 |
|
|
|
} |
125 |
|
|
|
|
126 |
|
|
|
static void setCrankingInjectionMode(int value) { |
127 |
|
|
|
engineConfiguration->crankingInjectionMode = (injection_mode_e) value; |
128 |
|
|
|
incrementGlobalConfigurationVersion(); |
129 |
|
|
|
printConfiguration(); |
130 |
|
|
|
} |
131 |
|
|
|
|
132 |
|
|
|
static void setInjectionMode(int value) { |
133 |
|
|
|
engineConfiguration->injectionMode = (injection_mode_e) value; |
134 |
|
|
|
incrementGlobalConfigurationVersion(); |
135 |
|
|
|
printConfiguration(); |
136 |
|
|
|
} |
137 |
|
|
|
|
138 |
|
|
|
static void setIgnitionMode(int value) { |
139 |
|
|
|
#if EFI_ENGINE_CONTROL |
140 |
|
|
|
engineConfiguration->ignitionMode = (ignition_mode_e) value; |
141 |
|
|
|
incrementGlobalConfigurationVersion(); |
142 |
|
|
|
prepareOutputSignals(); |
143 |
|
|
|
#endif // EFI_ENGINE_CONTROL |
144 |
|
|
|
} |
145 |
|
|
|
|
146 |
|
|
|
static void setIndividualCoilsIgnition() { |
147 |
|
|
|
setIgnitionMode((int)IM_INDIVIDUAL_COILS); |
148 |
|
|
|
} |
149 |
|
|
|
|
150 |
|
|
|
static void setTriggerType(int value) { |
151 |
|
|
|
engineConfiguration->trigger.type = (trigger_type_e) value; |
152 |
|
|
|
incrementGlobalConfigurationVersion(); |
153 |
|
|
|
printConfiguration(); |
154 |
|
|
|
efiPrintf("Do you need to also invoke set operation_mode X?"); |
155 |
|
|
|
engine->resetEngineSnifferIfInTestMode(); |
156 |
|
|
|
} |
157 |
|
|
|
|
158 |
|
|
|
static void setDebugMode(int value) { |
159 |
|
|
|
engineConfiguration->debugMode = (debug_mode_e) value; |
160 |
|
|
|
} |
161 |
|
|
|
|
162 |
|
|
|
static void setWholeTimingMap(float value) { |
163 |
|
|
|
setTable(config->ignitionTable, value); |
164 |
|
|
|
} |
165 |
|
|
|
|
166 |
|
|
|
static void setWholeTimingMapCmd(float value) { |
167 |
|
|
|
efiPrintf("Setting whole timing advance map to %.2f", value); |
168 |
|
|
|
setWholeTimingMap(value); |
169 |
|
|
|
engine->resetEngineSnifferIfInTestMode(); |
170 |
|
|
|
} |
171 |
|
|
|
|
172 |
|
|
|
#endif // EFI_ENGINE_CONTROL |
173 |
|
|
|
|
174 |
|
|
|
#if EFI_PROD_CODE |
175 |
|
|
|
|
176 |
|
|
|
static brain_pin_e parseBrainPinWithErrorMessage(const char *pinName) { |
177 |
|
|
|
brain_pin_e pin = parseBrainPin(pinName); |
178 |
|
|
|
if (pin == Gpio::Invalid) { |
179 |
|
|
|
efiPrintf("invalid pin name [%s]", pinName); |
180 |
|
|
|
} |
181 |
|
|
|
return pin; |
182 |
|
|
|
} |
183 |
|
|
|
|
184 |
|
|
|
/** |
185 |
|
|
|
* For example: |
186 |
|
|
|
* set_ignition_pin 1 PD7 |
187 |
|
|
|
* todo: this method counts index from 1 while at least 'set_trigger_input_pin' counts from 0. |
188 |
|
|
|
* todo: make things consistent |
189 |
|
|
|
*/ |
190 |
|
|
|
static void setIgnitionPin(const char *indexStr, const char *pinName) { |
191 |
|
|
|
int index = atoi(indexStr) - 1; // convert from human index into software index |
192 |
|
|
|
if (index < 0 || index >= MAX_CYLINDER_COUNT) |
193 |
|
|
|
return; |
194 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
195 |
|
|
|
if (pin == Gpio::Invalid) { |
196 |
|
|
|
return; |
197 |
|
|
|
} |
198 |
|
|
|
efiPrintf("setting ignition pin[%d] to %s please save&restart", index, hwPortname(pin)); |
199 |
|
|
|
engineConfiguration->ignitionPins[index] = pin; |
200 |
|
|
|
incrementGlobalConfigurationVersion(); |
201 |
|
|
|
} |
202 |
|
|
|
|
203 |
|
|
|
// this method is useful for desperate time debugging |
204 |
|
|
|
// readpin PA0 |
205 |
|
|
|
void readPin(const char *pinName) { |
206 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
207 |
|
|
|
if (pin == Gpio::Invalid) { |
208 |
|
|
|
return; |
209 |
|
|
|
} |
210 |
|
|
|
int physicalValue = palReadPad(getHwPort("read", pin), getHwPin("read", pin)); |
211 |
|
|
|
efiPrintf("pin %s value %d", hwPortname(pin), physicalValue); |
212 |
|
|
|
} |
213 |
|
|
|
|
214 |
|
|
|
// this method is useful for desperate time debugging or hardware validation |
215 |
|
|
|
static void benchSetPinValue(const char *pinName, int bit) { |
216 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
217 |
|
|
|
if (pin == Gpio::Invalid) { |
218 |
|
|
|
return; |
219 |
|
|
|
} |
220 |
|
|
|
efiSetPadModeWithoutOwnershipAcquisition("bench_pin_test", pin, PAL_MODE_OUTPUT_PUSHPULL); |
221 |
|
|
|
// low-level API which does not care about 'qcDirectPinControlMode' |
222 |
|
|
|
palWritePad(getHwPort("write", pin), getHwPin("write", pin), bit); |
223 |
|
|
|
efiPrintf("pin %s set value", hwPortname(pin)); |
224 |
|
|
|
readPin(pinName); |
225 |
|
|
|
} |
226 |
|
|
|
|
227 |
|
|
|
static void benchClearPin(const char *pinName) { |
228 |
|
|
|
benchSetPinValue(pinName, 0); |
229 |
|
|
|
} |
230 |
|
|
|
|
231 |
|
|
|
static void benchSetPin(const char *pinName) { |
232 |
|
|
|
benchSetPinValue(pinName, 1); |
233 |
|
|
|
} |
234 |
|
|
|
|
235 |
|
|
|
static void setIndividualPin(const char *pinName, brain_pin_e *targetPin, const char *name) { |
236 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
237 |
|
|
|
if (pin == Gpio::Invalid) { |
238 |
|
|
|
return; |
239 |
|
|
|
} |
240 |
|
|
|
efiPrintf("setting %s pin to %s please save&restart", name, hwPortname(pin)); |
241 |
|
|
|
*targetPin = pin; |
242 |
|
|
|
incrementGlobalConfigurationVersion(); |
243 |
|
|
|
} |
244 |
|
|
|
|
245 |
|
|
|
// set vss_pin |
246 |
|
|
|
static void setVssPin(const char *pinName) { |
247 |
|
|
|
setIndividualPin(pinName, &engineConfiguration->vehicleSpeedSensorInputPin, "VSS"); |
248 |
|
|
|
} |
249 |
|
|
|
|
250 |
|
|
|
// set_idle_pin none |
251 |
|
|
|
static void setIdlePin(const char *pinName) { |
252 |
|
|
|
setIndividualPin(pinName, &engineConfiguration->idle.solenoidPin, "idle"); |
253 |
|
|
|
} |
254 |
|
|
|
|
255 |
|
|
|
static void setAlternatorPin(const char *pinName) { |
256 |
|
|
|
setIndividualPin(pinName, &engineConfiguration->alternatorControlPin, "alternator"); |
257 |
|
|
|
} |
258 |
|
|
|
|
259 |
|
|
|
/** |
260 |
|
|
|
* For example: |
261 |
|
|
|
* set_trigger_input_pin 0 PA5 |
262 |
|
|
|
* todo: this method counts index from 0 while at least 'set_ignition_pin' counts from 1. |
263 |
|
|
|
* todo: make things consistent |
264 |
|
|
|
*/ |
265 |
|
|
|
static void setTriggerInputPin(const char *indexStr, const char *pinName) { |
266 |
|
|
|
int index = atoi(indexStr); |
267 |
|
|
|
if (index < 0 || index > 2) |
268 |
|
|
|
return; |
269 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
270 |
|
|
|
if (pin == Gpio::Invalid) { |
271 |
|
|
|
return; |
272 |
|
|
|
} |
273 |
|
|
|
efiPrintf("setting trigger pin[%d] to %s please save&restart", index, hwPortname(pin)); |
274 |
|
|
|
engineConfiguration->triggerInputPins[index] = pin; |
275 |
|
|
|
incrementGlobalConfigurationVersion(); |
276 |
|
|
|
} |
277 |
|
|
|
|
278 |
|
|
|
static void setTriggerSimulatorPin(const char *indexStr, const char *pinName) { |
279 |
|
|
|
int index = atoi(indexStr); |
280 |
|
|
|
if (index < 0 || index >= TRIGGER_SIMULATOR_PIN_COUNT) |
281 |
|
|
|
return; |
282 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
283 |
|
|
|
if (pin == Gpio::Invalid) { |
284 |
|
|
|
return; |
285 |
|
|
|
} |
286 |
|
|
|
efiPrintf("setting trigger simulator pin[%d] to %s please save&restart", index, hwPortname(pin)); |
287 |
|
|
|
engineConfiguration->triggerSimulatorPins[index] = pin; |
288 |
|
|
|
incrementGlobalConfigurationVersion(); |
289 |
|
|
|
} |
290 |
|
|
|
|
291 |
|
|
|
#if HAL_USE_ADC |
292 |
|
|
|
// set_analog_input_pin pps pa4 |
293 |
|
|
|
// set_analog_input_pin afr none |
294 |
|
|
|
static void setAnalogInputPin(const char *sensorStr, const char *pinName) { |
295 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
296 |
|
|
|
if (pin == Gpio::Invalid) { |
297 |
|
|
|
return; |
298 |
|
|
|
} |
299 |
|
|
|
adc_channel_e channel = getAdcChannel(pin); |
300 |
|
|
|
if (channel == EFI_ADC_ERROR) { |
301 |
|
|
|
efiPrintf("Error with [%s]", pinName); |
302 |
|
|
|
return; |
303 |
|
|
|
} |
304 |
|
|
|
if (strEqual("map", sensorStr)) { |
305 |
|
|
|
engineConfiguration->map.sensor.hwChannel = channel; |
306 |
|
|
|
efiPrintf("setting MAP to %s/%d", pinName, channel); |
307 |
|
|
|
} else if (strEqual("pps", sensorStr)) { |
308 |
|
|
|
engineConfiguration->throttlePedalPositionAdcChannel = channel; |
309 |
|
|
|
efiPrintf("setting PPS to %s/%d", pinName, channel); |
310 |
|
|
|
} else if (strEqual("afr", sensorStr)) { |
311 |
|
|
|
engineConfiguration->afr.hwChannel = channel; |
312 |
|
|
|
efiPrintf("setting AFR to %s/%d", pinName, channel); |
313 |
|
|
|
} else if (strEqual("clt", sensorStr)) { |
314 |
|
|
|
engineConfiguration->clt.adcChannel = channel; |
315 |
|
|
|
efiPrintf("setting CLT to %s/%d", pinName, channel); |
316 |
|
|
|
} else if (strEqual("iat", sensorStr)) { |
317 |
|
|
|
engineConfiguration->iat.adcChannel = channel; |
318 |
|
|
|
efiPrintf("setting IAT to %s/%d", pinName, channel); |
319 |
|
|
|
} else if (strEqual("tps", sensorStr)) { |
320 |
|
|
|
engineConfiguration->tps1_1AdcChannel = channel; |
321 |
|
|
|
efiPrintf("setting TPS1 to %s/%d", pinName, channel); |
322 |
|
|
|
} else if (strEqual("tps2", sensorStr)) { |
323 |
|
|
|
engineConfiguration->tps2_1AdcChannel = channel; |
324 |
|
|
|
efiPrintf("setting TPS2 to %s/%d", pinName, channel); |
325 |
|
|
|
} |
326 |
|
|
|
incrementGlobalConfigurationVersion(); |
327 |
|
|
|
} |
328 |
|
|
|
#endif // HAL_USE_ADC |
329 |
|
|
|
|
330 |
|
|
|
static void setLogicInputPin(const char *indexStr, const char *pinName) { |
331 |
|
|
|
int index = atoi(indexStr); |
332 |
|
|
|
if (index < 0 || index > 2) { |
333 |
|
|
|
return; |
334 |
|
|
|
} |
335 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
336 |
|
|
|
if (pin == Gpio::Invalid) { |
337 |
|
|
|
return; |
338 |
|
|
|
} |
339 |
|
|
|
efiPrintf("setting logic input pin[%d] to %s please save&restart", index, hwPortname(pin)); |
340 |
|
|
|
engineConfiguration->logicAnalyzerPins[index] = pin; |
341 |
|
|
|
incrementGlobalConfigurationVersion(); |
342 |
|
|
|
} |
343 |
|
|
|
|
344 |
|
|
|
#endif // EFI_PROD_CODE |
345 |
|
|
|
|
346 |
|
|
|
static void setSpiMode(int index, bool mode) { |
347 |
|
|
|
switch (index) { |
348 |
|
|
|
case 1: |
349 |
|
|
|
engineConfiguration->is_enabled_spi_1 = mode; |
350 |
|
|
|
break; |
351 |
|
|
|
case 2: |
352 |
|
|
|
engineConfiguration->is_enabled_spi_2 = mode; |
353 |
|
|
|
break; |
354 |
|
|
|
case 3: |
355 |
|
|
|
engineConfiguration->is_enabled_spi_3 = mode; |
356 |
|
|
|
break; |
357 |
|
|
|
default: |
358 |
|
|
|
efiPrintf("invalid spi index %d", index); |
359 |
|
|
|
return; |
360 |
|
|
|
} |
361 |
|
|
|
printSpiState(); |
362 |
|
|
|
} |
363 |
|
|
|
|
364 |
|
|
|
bool verboseRxCan = false; |
365 |
|
|
|
|
366 |
|
|
|
static void enableOrDisable(const char *param, bool isEnabled) { |
367 |
|
|
|
if (strEqualCaseInsensitive(param, "useTLE8888_cranking_hack")) { |
368 |
|
|
|
engineConfiguration->useTLE8888_cranking_hack = isEnabled; |
369 |
|
|
|
#if EFI_SHAFT_POSITION_INPUT |
370 |
|
|
|
} else if (strEqualCaseInsensitive(param, CMD_TRIGGER_HW_INPUT)) { |
371 |
|
|
|
getTriggerCentral()->hwTriggerInputEnabled = isEnabled; |
372 |
|
|
|
#endif // EFI_SHAFT_POSITION_INPUT |
373 |
|
|
|
} else if (strEqualCaseInsensitive(param, "verboseTLE8888")) { |
374 |
|
|
|
engineConfiguration->verboseTLE8888 = isEnabled; |
375 |
|
|
|
} else if (strEqualCaseInsensitive(param, "verboseRxCan")) { |
376 |
|
|
|
verboseRxCan = isEnabled; |
377 |
|
|
|
} else if (strEqualCaseInsensitive(param, "verboseCan")) { |
378 |
|
|
|
engineConfiguration->verboseCan = isEnabled; |
379 |
|
|
|
} else if (strEqualCaseInsensitive(param, "verboseCan2")) { |
380 |
|
|
|
engineConfiguration->verboseCan2 = isEnabled; |
381 |
|
|
|
} else if (strEqualCaseInsensitive(param, "verboseIsoTp")) { |
382 |
|
|
|
engineConfiguration->verboseIsoTp = isEnabled; |
383 |
|
|
|
} else if (strEqualCaseInsensitive(param, "artificialMisfire")) { |
384 |
|
|
|
engineConfiguration->artificialTestMisfire = isEnabled; |
385 |
|
|
|
} else if (strEqualCaseInsensitive(param, "logic_level_trigger")) { |
386 |
|
|
|
engineConfiguration->displayLogicLevelsInEngineSniffer = isEnabled; |
387 |
|
|
|
} else if (strEqualCaseInsensitive(param, "can_broadcast")) { |
388 |
|
|
|
engineConfiguration->enableVerboseCanTx = isEnabled; |
389 |
|
|
|
// } else if (strEqualCaseInsensitive(param, "etb_auto")) { |
390 |
|
|
|
// engine->etbAutoTune = isEnabled; |
391 |
|
|
|
} else if (strEqualCaseInsensitive(param, "verboseKLine")) { |
392 |
|
|
|
engineConfiguration->verboseKLine = isEnabled; |
393 |
|
|
|
} else if (strEqualCaseInsensitive(param, "stepperidle")) { |
394 |
|
|
|
engineConfiguration->useStepperIdle = isEnabled; |
395 |
|
|
|
} else if (strEqualCaseInsensitive(param, "two_wire_wasted_spark")) { |
396 |
|
|
|
engineConfiguration->twoWireBatchIgnition = isEnabled; |
397 |
|
|
|
incrementGlobalConfigurationVersion(); |
398 |
|
|
|
} else if (strEqualCaseInsensitive(param, "altcontrol")) { |
399 |
|
|
|
engineConfiguration->isAlternatorControlEnabled = isEnabled; |
400 |
|
|
|
} else if (strEqualCaseInsensitive(param, "sd")) { |
401 |
|
|
|
engineConfiguration->isSdCardEnabled = isEnabled; |
402 |
|
|
|
} else if (strEqualCaseInsensitive(param, CMD_FUNCTIONAL_TEST_MODE)) { |
403 |
|
|
|
engine->isFunctionalTestMode = isEnabled; |
404 |
|
|
|
} else if (strEqualCaseInsensitive(param, "can_read")) { |
405 |
|
|
|
engineConfiguration->canReadEnabled = isEnabled; |
406 |
|
|
|
} else if (strEqualCaseInsensitive(param, "can_write")) { |
407 |
|
|
|
engineConfiguration->canWriteEnabled = isEnabled; |
408 |
|
|
|
} else if (strEqualCaseInsensitive(param, CMD_INJECTION)) { |
409 |
|
|
|
engineConfiguration->isInjectionEnabled = isEnabled; |
410 |
|
|
|
} else if (strEqualCaseInsensitive(param, CMD_PWM)) { |
411 |
|
|
|
engine->isPwmEnabled = isEnabled; |
412 |
|
|
|
} else if (strEqualCaseInsensitive(param, "trigger_details")) { |
413 |
|
|
|
engineConfiguration->verboseTriggerSynchDetails = isEnabled; |
414 |
|
|
|
} else if (strEqualCaseInsensitive(param, "vvt_details")) { |
415 |
|
|
|
engineConfiguration->verboseVVTDecoding = isEnabled; |
416 |
|
|
|
} else if (strEqualCaseInsensitive(param, "invertCamVVTSignal")) { |
417 |
|
|
|
engineConfiguration->invertCamVVTSignal = isEnabled; |
418 |
|
|
|
} else if (strEqualCaseInsensitive(param, CMD_IGNITION)) { |
419 |
|
|
|
engineConfiguration->isIgnitionEnabled = isEnabled; |
420 |
|
|
|
#if EFI_EMULATE_POSITION_SENSORS |
421 |
|
|
|
} else if (strEqualCaseInsensitive(param, CMD_SELF_STIMULATION)) { |
422 |
|
|
|
if (isEnabled) { |
423 |
|
|
|
enableTriggerStimulator(); |
424 |
|
|
|
} else { |
425 |
|
|
|
disableTriggerStimulator(); |
426 |
|
|
|
} |
427 |
|
|
|
} else if (strEqualCaseInsensitive(param, CMD_EXTERNAL_STIMULATION)) { |
428 |
|
|
|
if (isEnabled) { |
429 |
|
|
|
enableExternalTriggerStimulator(); |
430 |
|
|
|
} else { |
431 |
|
|
|
disableTriggerStimulator(); |
432 |
|
|
|
} |
433 |
|
|
|
#endif // EFI_EMULATE_POSITION_SENSORS |
434 |
|
|
|
} else { |
435 |
|
|
|
efiPrintf("unexpected [%s]", param); |
436 |
|
|
|
return; // well, MISRA would not like this 'return' here :( |
437 |
|
|
|
} |
438 |
|
|
|
efiPrintf("[%s] %s", param, isEnabled ? "enabled" : "disabled"); |
439 |
|
|
|
} |
440 |
|
|
|
|
441 |
|
|
|
static void enable(const char *param) { |
442 |
|
|
|
enableOrDisable(param, true); |
443 |
|
|
|
} |
444 |
|
|
|
|
445 |
|
|
|
static void disable(const char *param) { |
446 |
|
|
|
enableOrDisable(param, false); |
447 |
|
|
|
} |
448 |
|
|
|
|
449 |
|
|
|
static void enableSpi(int index) { |
450 |
|
|
|
setSpiMode(index, true); |
451 |
|
|
|
} |
452 |
|
|
|
|
453 |
|
|
|
static void disableSpi(int index) { |
454 |
|
|
|
setSpiMode(index, false); |
455 |
|
|
|
} |
456 |
|
|
|
|
457 |
|
|
|
/** |
458 |
|
|
|
* See 'LimpManager::isEngineStop' for code which actually stops engine |
459 |
|
|
|
*/ |
460 |
|
|
|
static void scheduleStopEngine() { |
461 |
|
|
|
doScheduleStopEngine(StopRequestedReason::Console); |
462 |
|
|
|
} |
463 |
|
|
|
|
464 |
|
|
|
static void getValue(const char *paramStr) { |
465 |
|
|
|
|
466 |
|
|
|
{ |
467 |
|
|
|
float value = getConfigValueByName(paramStr); |
468 |
|
|
|
if (value != EFI_ERROR_CODE) { |
469 |
|
|
|
efiPrintf("%s value: %.2f", paramStr, value); |
470 |
|
|
|
return; |
471 |
|
|
|
} |
472 |
|
|
|
} |
473 |
|
|
|
|
474 |
|
|
|
if (strEqualCaseInsensitive(paramStr, "tps_min")) { |
475 |
|
|
|
efiPrintf("tps_min=%d", engineConfiguration->tpsMin); |
476 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "tps_max")) { |
477 |
|
|
|
efiPrintf("tps_max=%d", engineConfiguration->tpsMax); |
478 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "global_trigger_offset_angle")) { |
479 |
|
|
|
efiPrintf("global_trigger_offset=%.2f", engineConfiguration->globalTriggerAngleOffset); |
480 |
|
|
|
#if EFI_SHAFT_POSITION_INPUT |
481 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "trigger_hw_input")) { |
482 |
|
|
|
efiPrintf("trigger_hw_input=%s", boolToString(getTriggerCentral()->hwTriggerInputEnabled)); |
483 |
|
|
|
#endif // EFI_SHAFT_POSITION_INPUT |
484 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, CMD_DATE)) { |
485 |
|
|
|
printDateTime(); |
486 |
|
|
|
} else { |
487 |
|
|
|
efiPrintf("Invalid Parameter: %s", paramStr); |
488 |
|
|
|
} |
489 |
|
|
|
} |
490 |
|
|
|
|
491 |
|
|
|
static void setScriptCurve1Value(float value) { |
492 |
|
|
|
setLinearCurve(config->scriptCurve1, value, value, 1); |
493 |
|
|
|
} |
494 |
|
|
|
|
495 |
|
|
|
static void setScriptCurve2Value(float value) { |
496 |
|
|
|
setLinearCurve(config->scriptCurve2, value, value, 1); |
497 |
|
|
|
} |
498 |
|
|
|
|
499 |
|
|
|
struct command_i_s { |
500 |
|
|
|
const char *token; |
501 |
|
|
|
VoidInt callback; |
502 |
|
|
|
}; |
503 |
|
|
|
|
504 |
|
|
|
struct command_f_s { |
505 |
|
|
|
const char *token; |
506 |
|
|
|
VoidFloat callback; |
507 |
|
|
|
}; |
508 |
|
|
|
|
509 |
|
|
|
const command_f_s commandsF[] = { |
510 |
|
|
|
#if EFI_ENGINE_CONTROL |
511 |
|
|
|
{"global_trigger_offset_angle", setGlobalTriggerAngleOffset}, |
512 |
|
|
|
{"cranking_fuel", setCrankingFuel}, |
513 |
|
|
|
{"cranking_iac", setCrankingIACExtra}, |
514 |
|
|
|
{"cranking_timing_angle", setCrankingTimingAngle}, |
515 |
|
|
|
{"flat_injector_lag", setFlatInjectorLag}, |
516 |
|
|
|
#endif // EFI_ENGINE_CONTROL |
517 |
|
|
|
{"script_curve_1_value", setScriptCurve1Value}, |
518 |
|
|
|
{"script_curve_2_value", setScriptCurve2Value}, |
519 |
|
|
|
}; |
520 |
|
|
|
|
521 |
|
|
|
const command_i_s commandsI[] = { |
522 |
|
|
|
#if EFI_ENGINE_CONTROL |
523 |
|
|
|
{"ignition_mode", setIgnitionMode}, |
524 |
|
|
|
{"driveWheelRevPerKm", [](int value) { |
525 |
|
|
|
engineConfiguration->driveWheelRevPerKm = value; |
526 |
|
|
|
}}, |
527 |
|
|
|
{"cranking_rpm", setCrankingRpm}, |
528 |
|
|
|
{"cranking_injection_mode", setCrankingInjectionMode}, |
529 |
|
|
|
{"injection_mode", setInjectionMode}, |
530 |
|
|
|
{CMD_ENGINE_TYPE, setEngineTypeAndSave}, |
531 |
|
|
|
{"rpm_hard_limit", setRpmHardLimit}, |
532 |
|
|
|
{"firing_order", setFiringOrder}, |
533 |
|
|
|
{"algorithm", setAlgorithmInt}, |
534 |
|
|
|
{"debug_mode", setDebugMode}, |
535 |
|
|
|
{"trigger_type", setTriggerType}, |
536 |
|
|
|
// used by HW CI |
537 |
|
|
|
{"idle_solenoid_freq", setIdleSolenoidFrequency}, |
538 |
|
|
|
#endif // EFI_ENGINE_CONTROL |
539 |
|
|
|
#if EFI_PROD_CODE |
540 |
|
|
|
#if EFI_BOR_LEVEL |
541 |
|
|
|
{"bor", setBor}, |
542 |
|
|
|
#endif // EFI_BOR_LEVEL |
543 |
|
|
|
#if EFI_CAN_SUPPORT |
544 |
|
|
|
{"can_mode", setCanType}, |
545 |
|
|
|
{"can_vss", setCanVss}, |
546 |
|
|
|
#endif // EFI_CAN_SUPPORT |
547 |
|
|
|
#if EFI_IDLE_CONTROL |
548 |
|
|
|
{"idle_position", setManualIdleValvePosition}, |
549 |
|
|
|
{"idle_rpm", setTargetIdleRpm}, |
550 |
|
|
|
#endif // EFI_IDLE_CONTROL |
551 |
|
|
|
#endif // EFI_PROD_CODE |
552 |
|
|
|
|
553 |
|
|
|
// {"", }, |
554 |
|
|
|
// {"", }, |
555 |
|
|
|
}; |
556 |
|
|
|
|
557 |
|
|
|
static void setValue(const char *paramStr, const char *valueStr) { |
558 |
|
|
|
float valueF = atoff(valueStr); |
559 |
|
|
|
int valueI = atoi(valueStr); |
560 |
|
|
|
|
561 |
|
|
|
const command_f_s *currentF = &commandsF[0]; |
562 |
|
|
|
while (currentF < commandsF + sizeof(commandsF)/sizeof(commandsF[0])) { |
563 |
|
|
|
if (strEqualCaseInsensitive(paramStr, currentF->token)) { |
564 |
|
|
|
currentF->callback(valueF); |
565 |
|
|
|
return; |
566 |
|
|
|
} |
567 |
|
|
|
currentF++; |
568 |
|
|
|
} |
569 |
|
|
|
|
570 |
|
|
|
const command_i_s *currentI = &commandsI[0]; |
571 |
|
|
|
while (currentI < commandsI + sizeof(commandsI)/sizeof(commandsI[0])) { |
572 |
|
|
|
if (strEqualCaseInsensitive(paramStr, currentI->token)) { |
573 |
|
|
|
currentI->callback(valueI); |
574 |
|
|
|
return; |
575 |
|
|
|
} |
576 |
|
|
|
currentI++; |
577 |
|
|
|
} |
578 |
|
|
|
|
579 |
|
|
|
|
580 |
|
|
|
if (strEqualCaseInsensitive(paramStr, "warning_period")) { |
581 |
|
|
|
engineConfiguration->warningPeriod = valueI; |
582 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "dwell")) { |
583 |
|
|
|
setConstantDwell(valueF); |
584 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, CMD_ENGINESNIFFERRPMTHRESHOLD)) { |
585 |
|
|
|
engineConfiguration->engineSnifferRpmThreshold = valueI; |
586 |
|
|
|
#if EFI_EMULATE_POSITION_SENSORS |
587 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, CMD_RPM)) { |
588 |
|
|
|
setTriggerEmulatorRPM(valueI); |
589 |
|
|
|
#endif // EFI_EMULATE_POSITION_SENSORS |
590 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "mc33_hvolt")) { |
591 |
|
|
|
engineConfiguration->mc33_hvolt = valueI; |
592 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "mc33_i_peak")) { |
593 |
|
|
|
engineConfiguration->mc33_i_peak = valueI; |
594 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "mc33_i_hold")) { |
595 |
|
|
|
engineConfiguration->mc33_i_hold = valueI; |
596 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "mc33_t_max_boost")) { |
597 |
|
|
|
engineConfiguration->mc33_t_max_boost = valueI; |
598 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "mc33_t_peak_off")) { |
599 |
|
|
|
engineConfiguration->mc33_t_peak_off = valueI; |
600 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "vvt_offset")) { |
601 |
|
|
|
engineConfiguration->vvtOffsets[0] = valueF; |
602 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "vvt_mode")) { |
603 |
|
|
|
engineConfiguration->vvtMode[0] = (vvt_mode_e)valueI; |
604 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "wwaeTau")) { |
605 |
|
|
|
engineConfiguration->wwaeTau = valueF; |
606 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "wwaeBeta")) { |
607 |
|
|
|
engineConfiguration->wwaeBeta = valueF; |
608 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "benchTestOffTime")) { |
609 |
|
|
|
engineConfiguration->benchTestOffTime = valueI; |
610 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "benchTestCount")) { |
611 |
|
|
|
engineConfiguration->benchTestCount = valueI; |
612 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "cranking_dwell")) { |
613 |
|
|
|
engineConfiguration->ignitionDwellForCrankingMs = valueF; |
614 |
|
|
|
#if EFI_PROD_CODE |
615 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, CMD_VSS_PIN)) { |
616 |
|
|
|
setVssPin(valueStr); |
617 |
|
|
|
#endif // EFI_PROD_CODE |
618 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, "targetvbatt")) { |
619 |
|
|
|
setTable(config->alternatorVoltageTargetTable, valueF); |
620 |
|
|
|
} else if (strEqualCaseInsensitive(paramStr, CMD_DATE)) { |
621 |
|
|
|
// rusEfi console invokes this method with timestamp in local timezone |
622 |
|
|
|
setDateTime(valueStr); |
623 |
|
|
|
} |
624 |
|
|
|
|
625 |
|
|
|
bool isGoodName = setConfigValueByName(paramStr, valueF); |
626 |
|
|
|
if (isGoodName) { |
627 |
|
|
|
efiPrintf("Settings: applying [%s][%f]", paramStr, valueF); |
628 |
|
|
|
} |
629 |
|
|
|
|
630 |
|
|
|
engine->resetEngineSnifferIfInTestMode(); |
631 |
|
|
|
} |
632 |
|
|
|
|
633 |
|
|
|
void initSettings() { |
634 |
|
|
|
#if EFI_SIMULATOR |
635 |
|
|
|
printf("initSettings\n"); |
636 |
|
|
|
#endif // EFI_SIMULATOR |
637 |
|
|
|
|
638 |
|
|
|
// todo: start saving values into flash right away? |
639 |
|
|
|
|
640 |
|
|
|
#if EFI_ENGINE_CONTROL |
641 |
|
|
|
// used by HW CI |
642 |
|
|
|
addConsoleAction(CMD_INDIVIDUAL_INJECTION, setIndividualCoilsIgnition); |
643 |
|
|
|
addConsoleAction("showconfig", printConfiguration); |
644 |
|
|
|
addConsoleActionF("set_whole_timing_map", setWholeTimingMapCmd); |
645 |
|
|
|
#endif // EFI_ENGINE_CONTROL |
646 |
|
|
|
|
647 |
|
|
|
addConsoleAction("stopengine", (Void) scheduleStopEngine); |
648 |
|
|
|
|
649 |
|
|
|
// todo: refactor this - looks like all boolean flags should be controlled with less code duplication |
650 |
|
|
|
addConsoleActionI("enable_spi", enableSpi); |
651 |
|
|
|
addConsoleActionI("disable_spi", disableSpi); |
652 |
|
|
|
|
653 |
|
|
|
addConsoleActionS(CMD_ENABLE, enable); |
654 |
|
|
|
addConsoleActionS(CMD_DISABLE, disable); |
655 |
|
|
|
|
656 |
|
|
|
addConsoleActionSS(CMD_SET, setValue); |
657 |
|
|
|
addConsoleActionS(CMD_GET, getValue); |
658 |
|
|
|
|
659 |
|
|
|
#if EFI_PROD_CODE |
660 |
|
|
|
addConsoleActionSS(CMD_IGNITION_PIN, setIgnitionPin); |
661 |
|
|
|
addConsoleActionSS(CMD_TRIGGER_PIN, setTriggerInputPin); |
662 |
|
|
|
addConsoleActionSS(CMD_TRIGGER_SIMULATOR_PIN, setTriggerSimulatorPin); |
663 |
|
|
|
|
664 |
|
|
|
addConsoleActionI(CMD_ECU_UNLOCK, unlockEcu); |
665 |
|
|
|
|
666 |
|
|
|
addConsoleActionS(CMD_ALTERNATOR_PIN, setAlternatorPin); |
667 |
|
|
|
addConsoleActionS(CMD_IDLE_PIN, setIdlePin); |
668 |
|
|
|
|
669 |
|
|
|
addConsoleActionS("bench_clearpin", benchClearPin); |
670 |
|
|
|
addConsoleActionS("bench_setpin", benchSetPin); |
671 |
|
|
|
addConsoleActionS("readpin", readPin); |
672 |
|
|
|
addConsoleAction("hw_qc_mode", [](){ |
673 |
|
|
|
setHwQcMode(); |
674 |
|
|
|
}); |
675 |
|
|
|
addConsoleActionS("bench_set_output_mode", [](const char *pinName){ |
676 |
|
|
|
brain_pin_e pin = parseBrainPinWithErrorMessage(pinName); |
677 |
|
|
|
if (pin == Gpio::Invalid) { |
678 |
|
|
|
return; |
679 |
|
|
|
} |
680 |
|
|
|
efiSetPadModeWithoutOwnershipAcquisition("manual-mode", pin, PAL_MODE_OUTPUT_PUSHPULL); |
681 |
|
|
|
}); |
682 |
|
|
|
|
683 |
|
|
|
#if HAL_USE_ADC |
684 |
|
|
|
addConsoleAction("adc_report", printFullAdcReport); |
685 |
|
|
|
addConsoleActionSS("set_analog_input_pin", setAnalogInputPin); |
686 |
|
|
|
#endif // HAL_USE_ADC |
687 |
|
|
|
addConsoleActionSS(CMD_LOGIC_PIN, setLogicInputPin); |
688 |
|
|
|
#endif // EFI_PROD_CODE |
689 |
|
|
|
} |
690 |
|
|
|
|
691 |
|
|
|
void printDateTime() { |
692 |
|
|
|
#if EFI_RTC |
693 |
|
|
|
printRtcDateTime(); |
694 |
|
|
|
#else // EFI_RTC |
695 |
|
|
|
efiPrintf("Cannot print time: RTC not supported"); |
696 |
|
|
|
#endif // EFI_RTC |
697 |
|
|
|
} |
698 |
|
|
|
|
699 |
|
|
|
void setDateTime(const char * const isoDateTime) { |
700 |
|
|
|
#if EFI_RTC |
701 |
|
|
|
printRtcDateTime(); |
702 |
|
|
|
if (strlen(isoDateTime) >= 19 && isoDateTime[10] == 'T') { |
703 |
|
|
|
efidatetime_t dateTime; |
704 |
|
|
|
dateTime.year = atoi(isoDateTime); |
705 |
|
|
|
dateTime.month = atoi(isoDateTime + 5); |
706 |
|
|
|
dateTime.day = atoi(isoDateTime + 8); |
707 |
|
|
|
dateTime.hour = atoi(isoDateTime + 11); |
708 |
|
|
|
dateTime.minute = atoi(isoDateTime + 14); |
709 |
|
|
|
dateTime.second = atoi(isoDateTime + 17); |
710 |
|
|
|
if (dateTime.year != ATOI_ERROR_CODE && |
711 |
|
|
|
dateTime.month >= 1 && dateTime.month <= 12 && |
712 |
|
|
|
dateTime.day >= 1 && dateTime.day <= 31 && |
713 |
|
|
|
dateTime.hour <= 23 && |
714 |
|
|
|
dateTime.minute <= 59 && |
715 |
|
|
|
dateTime.second <= 59) { |
716 |
|
|
|
// doesn't concern about leap years or seconds; ChibiOS doesn't support (added) leap seconds anyway |
717 |
|
|
|
setRtcDateTime(&dateTime); |
718 |
|
|
|
efiPrintf("Time is changed to"); |
719 |
|
|
|
printRtcDateTime(); |
720 |
|
|
|
return; |
721 |
|
|
|
} |
722 |
|
|
|
} |
723 |
|
|
|
efiPrintf("date_set Date parameter %s is wrong", isoDateTime); |
724 |
|
|
|
#else // EFI_RTC |
725 |
|
|
|
efiPrintf("Cannot set time: RTC not supported"); |
726 |
|
|
|
#endif // EFI_RTC |
727 |
|
|
|
} |
728 |
|
|
|
|
729 |
|
|
|
#endif // ! EFI_UNIT_TEST |
730 |
|
|
|
|
731 |
|
|
✗ |
void setEngineTypeAndSave(int value) { |
732 |
|
|
✗ |
setEngineType(value, true); |
733 |
|
|
✗ |
} |
734 |
|
|
|
|
735 |
|
|
1 |
void setEngineType(int value, bool isWriteToFlash) { |
736 |
|
|
|
{ |
737 |
|
|
|
#if EFI_PROD_CODE |
738 |
|
|
|
chibios_rt::CriticalSectionLocker csl; |
739 |
|
|
|
#endif // EFI_PROD_CODE |
740 |
|
|
|
|
741 |
|
|
1 |
engineConfiguration->engineType = (engine_type_e)value; |
742 |
|
|
1 |
resetConfigurationExt((engine_type_e)value); |
743 |
|
|
1 |
engine->resetEngineSnifferIfInTestMode(); |
744 |
|
|
|
|
745 |
|
|
|
#if EFI_CONFIGURATION_STORAGE |
746 |
|
|
|
if (isWriteToFlash) { |
747 |
|
|
|
writeToFlashNow(); |
748 |
|
|
|
} |
749 |
|
|
|
#endif /* EFI_CONFIGURATION_STORAGE */ |
750 |
|
|
|
} |
751 |
|
|
1 |
incrementGlobalConfigurationVersion("engineType"); |
752 |
|
|
|
#if EFI_ENGINE_CONTROL && ! EFI_UNIT_TEST |
753 |
|
|
|
printConfiguration(); |
754 |
|
|
|
#endif // ! EFI_UNIT_TEST |
755 |
|
|
1 |
} |
756 |
|
|
|
|