Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | /** | |||
2 | * @file status_loop.cpp | |||
3 | * @brief Human-readable protocol status messages | |||
4 | * | |||
5 | * http://rusefi.com/forum/viewtopic.php?t=263 rusEfi console overview | |||
6 | * http://rusefi.com/forum/viewtopic.php?t=210 Commands overview | |||
7 | * | |||
8 | * | |||
9 | * @date Mar 15, 2013 | |||
10 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
11 | * | |||
12 | * This file is part of rusEfi - see http://rusefi.com | |||
13 | * | |||
14 | * rusEfi is free software; you can redistribute it and/or modify it under the terms of | |||
15 | * the GNU General Public License as published by the Free Software Foundation; either | |||
16 | * version 3 of the License, or (at your option) any later version. | |||
17 | * | |||
18 | * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without | |||
19 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
20 | * GNU General Public License for more details. | |||
21 | * | |||
22 | * You should have received a copy of the GNU General Public License along with this program. | |||
23 | * If not, see <http://www.gnu.org/licenses/>. | |||
24 | * | |||
25 | */ | |||
26 | ||||
27 | #include "pch.h" | |||
28 | #include "status_loop.h" | |||
29 | #include "electronic_throttle.h" | |||
30 | ||||
31 | #if EFI_LOGIC_ANALYZER | |||
32 | #include "logic_analyzer.h" | |||
33 | #endif /* EFI_LOGIC_ANALYZER */ | |||
34 | ||||
35 | #include "trigger_central.h" | |||
36 | #include "sensor_reader.h" | |||
37 | #include "mmc_card.h" | |||
38 | #include "console_io.h" | |||
39 | #include "malfunction_central.h" | |||
40 | #include "speed_density.h" | |||
41 | ||||
42 | #include "tunerstudio.h" | |||
43 | #include "tunerstudio_calibration_channel.h" | |||
44 | #include "fuel_math.h" | |||
45 | #include "main_trigger_callback.h" | |||
46 | #include "spark_logic.h" | |||
47 | #include "idle_thread.h" | |||
48 | #include "can_hw.h" | |||
49 | #include "periodic_thread_controller.h" | |||
50 | #include "cdm_ion_sense.h" | |||
51 | #include "binary_mlg_logging.h" | |||
52 | #include "buffered_writer.h" | |||
53 | #include "dynoview.h" | |||
54 | #include "frequency_sensor.h" | |||
55 | #include "digital_input_exti.h" | |||
56 | #include "dc_motors.h" | |||
57 | ||||
58 | #if EFI_PROD_CODE | |||
59 | // todo: move this logic to algo folder! | |||
60 | #include "rtc_helper.h" | |||
61 | #include "rusefi.h" | |||
62 | #include "pin_repository.h" | |||
63 | #include "max3185x.h" | |||
64 | #include "single_timer_executor.h" | |||
65 | #include "periodic_task.h" | |||
66 | #endif /* EFI_PROD_CODE */ | |||
67 | ||||
68 | #if EFI_CONFIGURATION_STORAGE | |||
69 | #include "storage.h" | |||
70 | #include "flash_main.h" | |||
71 | #endif | |||
72 | ||||
73 | #if EFI_MAP_AVERAGING && defined (MODULE_MAP_AVERAGING) | |||
74 | #include "map_averaging.h" | |||
75 | #endif | |||
76 | ||||
77 | #if (BOARD_TLE8888_COUNT > 0) | |||
78 | #include "tle8888.h" | |||
79 | #endif /* BOARD_TLE8888_COUNT */ | |||
80 | ||||
81 | #if EFI_ENGINE_SNIFFER | |||
82 | #include "engine_sniffer.h" | |||
83 | extern WaveChart waveChart; | |||
84 | #endif /* EFI_ENGINE_SNIFFER */ | |||
85 | ||||
86 | extern int maxTriggerReentrant; | |||
87 | extern uint32_t maxLockedDuration; | |||
88 | ||||
89 | /** | |||
90 | * Time when the firmware version was last reported | |||
91 | * TODO: implement a request/response instead of just constantly sending this out | |||
92 | */ | |||
93 | static Timer printVersionTimer; | |||
94 | ||||
95 | // todo: unify with handleGetVersion? | |||
96 | ✗ | static void printVersionForConsole(const char *engineTypeName, const char *firmwareBuildId) { | ||
97 | // VersionChecker in rusEFI console is parsing these version string, please follow the expected format | |||
98 | ✗ | efiPrintfProto(PROTOCOL_VERSION_TAG, "%d@%u %s %s %ld", | ||
99 | getRusEfiVersion(), /*do we have a working way to print 64 bit values?!*/(unsigned int)SIGNATURE_HASH, | |||
100 | firmwareBuildId, | |||
101 | engineTypeName, | |||
102 | (uint32_t)getTimeNowS()); | |||
103 | ✗ | } | ||
104 | ||||
105 | #if EFI_PROD_CODE | |||
106 | // Inform the console about the mapping between a pin's logical name (for example, injector 3) | |||
107 | // and the physical MCU pin backing that function (for example, PE3) | |||
108 | static void printOutPin(const char *pinName, brain_pin_e hwPin) { | |||
109 | if (hwPin == Gpio::Unassigned || hwPin == Gpio::Invalid) { | |||
110 | return; | |||
111 | } | |||
112 | const char *hwPinName; | |||
113 | if (isBrainPinValid(hwPin)) { | |||
114 | hwPinName = hwPortname(hwPin); | |||
115 | } else { | |||
116 | hwPinName = "smart"; | |||
117 | } | |||
118 | ||||
119 | efiPrintfProto(PROTOCOL_OUTPIN, "%s@%s", pinName, hwPinName); | |||
120 | } | |||
121 | #endif // EFI_PROD_CODE | |||
122 | ||||
123 | // Print out the current mapping between logical and physical pins that | |||
124 | // the engine sniffer cares about, so we can display a physical pin | |||
125 | // in each engine sniffer row | |||
126 | ✗ | static void printEngineSnifferPinMappings() { | ||
127 | #if EFI_PROD_CODE | |||
128 | printOutPin(PROTOCOL_CRANK1, engineConfiguration->triggerInputPins[0]); | |||
129 | printOutPin(PROTOCOL_CRANK2, engineConfiguration->triggerInputPins[1]); | |||
130 | for (int i = 0;i<CAM_INPUTS_COUNT;i++) { | |||
131 | extern const char *vvtNames[]; | |||
132 | printOutPin(vvtNames[i], engineConfiguration->camInputs[i]); | |||
133 | } | |||
134 | ||||
135 | int cylCount = minI(engineConfiguration->cylindersCount, MAX_CYLINDER_COUNT); | |||
136 | for (int i = 0; i < cylCount; i++) { | |||
137 | printOutPin(enginePins.coils[i].getShortName(), engineConfiguration->ignitionPins[i]); | |||
138 | printOutPin(enginePins.trailingCoils[i].getShortName(), engineConfiguration->trailingCoilPins[i]); | |||
139 | printOutPin(enginePins.injectors[i].getShortName(), engineConfiguration->injectionPins[i]); | |||
140 | printOutPin(enginePins.injectorsStage2[i].getShortName(), engineConfiguration->injectionPinsStage2[i]); | |||
141 | } | |||
142 | #endif /* EFI_PROD_CODE */ | |||
143 | ✗ | } | ||
144 | ||||
145 | ✗ | void printOverallStatus() { | ||
146 | #if EFI_ENGINE_SNIFFER | |||
147 | ✗ | waveChart.publishIfFull(); | ||
148 | #endif /* EFI_ENGINE_SNIFFER */ | |||
149 | ||||
150 | ||||
151 | /** | |||
152 | * we report the version every second - this way the console does not need to | |||
153 | * request it and we will display it pretty soon | |||
154 | */ | |||
155 | ✗ | if (printVersionTimer.hasElapsedSec(1)) { | ||
156 | // we're sending, reset the timer | |||
157 | ✗ | printVersionTimer.reset(); | ||
158 | ||||
159 | // Output the firmware version, board type, git hash, uptime in seconds, etc for rusEFI console | |||
160 | ✗ | printVersionForConsole(getEngine_type_e(engineConfiguration->engineType), FIRMWARE_ID); | ||
161 | ||||
162 | // Output the current engine sniffer pin mappings | |||
163 | ✗ | printEngineSnifferPinMappings(); | ||
164 | } | |||
165 | ✗ | } | ||
166 | ||||
167 | #if !defined(LOGIC_ANALYZER_BUFFER_SIZE) | |||
168 | // TODO: how small can this be? | |||
169 | #define LOGIC_ANALYZER_BUFFER_SIZE 1000 | |||
170 | #endif /* LOGIC_ANALYZER_BUFFER_SIZE */ | |||
171 | ||||
172 | #if EFI_LOGIC_ANALYZER | |||
173 | static char logicAnalyzerBuffer[LOGIC_ANALYZER_BUFFER_SIZE]; | |||
174 | static Logging logicAnalyzerLogger("logic analyzer", logicAnalyzerBuffer, sizeof(logicAnalyzerBuffer)); | |||
175 | #endif // EFI_LOGIC_ANALYZER | |||
176 | ||||
177 | /** | |||
178 | * @brief Sends all pending data to rusEfi console | |||
179 | * | |||
180 | * This method is periodically invoked by the main loop | |||
181 | * todo: is this mostly dead code? | |||
182 | */ | |||
183 | ✗ | void updateDevConsoleState() { | ||
184 | #if EFI_PROD_CODE | |||
185 | // todo: unify with simulator! | |||
186 | if (hasFirmwareError()) { | |||
187 | efiPrintf("%s error: %s", CRITICAL_PREFIX, getCriticalErrorMessage()); | |||
188 | return; | |||
189 | } | |||
190 | #endif /* EFI_PROD_CODE */ | |||
191 | ||||
192 | #if EFI_RTC | |||
193 | engine->outputChannels.rtcUnixEpochTime = getEpochTime(); | |||
194 | #endif | |||
195 | ||||
196 | #if HAL_USE_ADC | |||
197 | printFullAdcReportIfNeeded(); | |||
198 | #endif /* HAL_USE_ADC */ | |||
199 | ||||
200 | #if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT | |||
201 | ✗ | int currentCkpEventCounter = engine->triggerCentral.triggerState.getTotalEventCounter(); | ||
202 | ✗ | systime_t nowSeconds = getTimeNowS(); | ||
203 | static int prevCkpEventCounter = -1; | |||
204 | static systime_t timeOfPreviousReport = (systime_t) -1; | |||
205 | ✗ | if (prevCkpEventCounter == currentCkpEventCounter && timeOfPreviousReport == nowSeconds) { | ||
206 | ✗ | return; | ||
207 | } | |||
208 | ✗ | timeOfPreviousReport = nowSeconds; | ||
209 | ||||
210 | ✗ | prevCkpEventCounter = currentCkpEventCounter; | ||
211 | #else | |||
212 | chThdSleepMilliseconds(200); | |||
213 | #endif | |||
214 | ||||
215 | #if EFI_LOGIC_ANALYZER | |||
216 | printWave(&logicAnalyzerLogger); | |||
217 | scheduleLogging(&logicAnalyzerLogger); | |||
218 | #endif /* EFI_LOGIC_ANALYZER */ | |||
219 | } | |||
220 | ||||
221 | #if EFI_PROD_CODE | |||
222 | static OutputPin* leds[] = { &enginePins.warningLedPin, &enginePins.runningLedPin, | |||
223 | &enginePins.errorLedPin, &enginePins.communicationLedPin, &enginePins.checkEnginePin }; | |||
224 | #endif // EFI_PROD_CODE | |||
225 | ||||
226 | ✗ | void initWarningRunningPins() { | ||
227 | #if EFI_PROD_CODE | |||
228 | // open question if we need warningLedPin and runningLedPin at all! | |||
229 | enginePins.warningLedPin.initPin("led: warning status", getWarningLedPin(), LED_PIN_MODE, true); | |||
230 | enginePins.runningLedPin.initPin("led: running status", getRunningLedPin(), LED_PIN_MODE, true); | |||
231 | #endif /* EFI_PROD_CODE */ | |||
232 | ✗ | } | ||
233 | ||||
234 | #if EFI_PROD_CODE | |||
235 | static void initStatusLeds() { | |||
236 | enginePins.communicationLedPin.initPin("led: comm status", getCommsLedPin(), LED_PIN_MODE, true); | |||
237 | // checkEnginePin is already initialized by the time we get here | |||
238 | } | |||
239 | ||||
240 | static bool isTriggerErrorNow() { | |||
241 | #if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT | |||
242 | bool justHadError = engine->triggerCentral.triggerState.someSortOfTriggerError(); | |||
243 | return justHadError || engine->triggerCentral.isTriggerDecoderError(); | |||
244 | #else | |||
245 | return false; | |||
246 | #endif /* EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT */ | |||
247 | } | |||
248 | ||||
249 | extern bool consoleByteArrived; | |||
250 | ||||
251 | class CommunicationBlinkingTask : public PeriodicTimerController { | |||
252 | ||||
253 | int getPeriodMs() override { | |||
254 | return counter % 2 == 0 ? onTimeMs : offTimeMs; | |||
255 | } | |||
256 | ||||
257 | void setAllLeds(int value) { | |||
258 | // make sure we do not turn the critical LED off if already have | |||
259 | // critical error by now | |||
260 | for (size_t i = 0; !hasFirmwareError() && i < efi::size(leds); i++) { | |||
261 | leds[i]->setValue(value, /*force*/true); | |||
262 | } | |||
263 | } | |||
264 | ||||
265 | void PeriodicTask() override { | |||
266 | counter++; | |||
267 | ||||
268 | if (counter == 1) { | |||
269 | // first invocation of BlinkingTask | |||
270 | setAllLeds(1); | |||
271 | } else if (counter == 2) { | |||
272 | // second invocation of BlinkingTask | |||
273 | setAllLeds(0); | |||
274 | } else if (counter % 2 == 0) { | |||
275 | enginePins.communicationLedPin.setValue(0, /*force*/true); | |||
276 | ||||
277 | #if EFI_FILE_LOGGING | |||
278 | extern bool needErrorReportFile; | |||
279 | #else | |||
280 | #define needErrorReportFile false | |||
281 | #endif // EFI_FILE_LOGGING | |||
282 | // todo: properly encapsulate warning LED logic! | |||
283 | if (!needErrorReportFile) { | |||
284 | enginePins.warningLedPin.setValue(0); | |||
285 | } | |||
286 | } else { | |||
287 | #define BLINKING_PERIOD_MS 33 | |||
288 | ||||
289 | if (hasFirmwareError()) { | |||
290 | // special behavior in case of critical error - not equal on/off time | |||
291 | // this special behavior helps to notice that something is not right, also | |||
292 | // differentiates software firmware error from critical interrupt error with CPU halt. | |||
293 | offTimeMs = 50; | |||
294 | onTimeMs = 450; | |||
295 | } else if (consoleByteArrived) { | |||
296 | offTimeMs = 100; | |||
297 | onTimeMs = 33; | |||
298 | #if EFI_CONFIGURATION_STORAGE | |||
299 | } else if (getNeedToWriteConfiguration()) { | |||
300 | offTimeMs = onTimeMs = 500; | |||
301 | #endif /* EFI_CONFIGURATION_STORAGE */ | |||
302 | } else { | |||
303 | onTimeMs = | |||
304 | #if EFI_USB_SERIAL | |||
305 | is_usb_serial_ready() ? 3 * BLINKING_PERIOD_MS : | |||
306 | #endif // EFI_USB_SERIAL | |||
307 | BLINKING_PERIOD_MS; | |||
308 | offTimeMs = 0.6 * onTimeMs; | |||
309 | } | |||
310 | ||||
311 | enginePins.communicationLedPin.setValue(1, /*force*/true); | |||
312 | ||||
313 | #if EFI_ENGINE_CONTROL | |||
314 | if (isTriggerErrorNow()) { | |||
315 | // todo: at the moment warning codes do not affect warning LED?! | |||
316 | enginePins.warningLedPin.setValue(1); | |||
317 | } | |||
318 | #endif /* EFI_ENGINE_CONTROL */ | |||
319 | } | |||
320 | } | |||
321 | ||||
322 | private: | |||
323 | int counter = 0; | |||
324 | int onTimeMs = 100; | |||
325 | int offTimeMs = 100; | |||
326 | }; | |||
327 | ||||
328 | static CommunicationBlinkingTask communicationsBlinkingTask; | |||
329 | ||||
330 | #endif /* EFI_PROD_CODE */ | |||
331 | ||||
332 | ||||
333 | #if EFI_TUNER_STUDIO | |||
334 | ||||
335 | /** | |||
336 | * This is useful if we are changing engine mode dynamically | |||
337 | * For example http://rusefi.com/forum/viewtopic.php?f=5&t=1085 | |||
338 | */ | |||
339 | 522954 | static int packEngineMode() { | ||
340 | 522954 | return (Enum2Underlying(engineConfiguration->fuelAlgorithm) << 4) + | ||
341 | 522954 | (engineConfiguration->injectionMode << 2) + | ||
342 | 522954 | engineConfiguration->ignitionMode; | ||
343 | } | |||
344 | ||||
345 | 522954 | static void updateTempSensors() { | ||
346 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult clt = Sensor::get(SensorType::Clt); | |
347 | 522954 | engine->outputChannels.coolant = clt.value_or(0); | ||
348 | 522954 | engine->outputChannels.isCltError = !clt.Valid; | ||
349 | ||||
350 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult iat = Sensor::get(SensorType::Iat); | |
351 | 522954 | engine->outputChannels.intake = iat.value_or(0); | ||
352 | 522954 | engine->outputChannels.isIatError = !iat.Valid; | ||
353 | ||||
354 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult auxTemp1 = Sensor::get(SensorType::AuxTemp1); | |
355 | 522954 | engine->outputChannels.auxTemp1 = auxTemp1.value_or(0); | ||
356 | ||||
357 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult auxTemp2 = Sensor::get(SensorType::AuxTemp2); | |
358 | 522954 | engine->outputChannels.auxTemp2 = auxTemp2.value_or(0); | ||
359 | ||||
360 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult oilTemp = Sensor::get(SensorType::OilTemperature); | |
361 | 522954 | engine->outputChannels.oilTemp = oilTemp.value_or(0); | ||
362 | ||||
363 | // see also updateFuelSensors() | |||
364 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult fuelTemp = Sensor::get(SensorType::FuelTemperature); | |
365 | 522954 | engine->outputChannels.fuelTemp = fuelTemp.value_or(0); | ||
366 | ||||
367 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult ambientTemp = Sensor::get(SensorType::AmbientTemperature); | |
368 | 522954 | engine->outputChannels.ambientTemp = ambientTemp.value_or(0); | ||
369 | ||||
370 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult compressorDischargeTemp = Sensor::get(SensorType::CompressorDischargeTemperature); | |
371 | 522954 | engine->outputChannels.compressorDischargeTemp = compressorDischargeTemp.value_or(0); | ||
372 | 522954 | } | ||
373 | ||||
374 | void updateUnfilteredRawPedal(); | |||
375 | ||||
376 | 522954 | static void updateThrottles() { | ||
377 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult tps1 = Sensor::get(SensorType::Tps1); | |
378 | 522954 | engine->outputChannels.TPSValue = tps1.value_or(0); | ||
379 |
2/3✓ Branch 1 taken 522954 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 522954 times.
|
522954 | engine->outputChannels.isTpsError = Sensor::hasSensor(SensorType::Tps1) ? !tps1.Valid : false; | |
380 |
1/1✓ Branch 1 taken 522954 times.
|
522954 | engine->outputChannels.tpsADC = convertVoltageTo10bitADC(Sensor::getRaw(SensorType::Tps1Primary)); | |
381 | ||||
382 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult tps2 = Sensor::get(SensorType::Tps2); | |
383 | 522954 | engine->outputChannels.TPS2Value = tps2.value_or(0); | ||
384 | // If we don't have a TPS2 at all, don't turn on the failure light | |||
385 |
2/3✓ Branch 1 taken 522954 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 522954 times.
|
522954 | engine->outputChannels.isTps2Error = Sensor::hasSensor(SensorType::Tps2Primary) ? !tps2.Valid : false; | |
386 | ||||
387 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | SensorResult pedal = Sensor::get(SensorType::AcceleratorPedal); | |
388 | 522954 | engine->outputChannels.throttlePedalPosition = pedal.value_or(0); | ||
389 | // Only report fail if you have one (many people don't) | |||
390 |
2/3✓ Branch 1 taken 522954 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 522954 times.
|
522954 | engine->outputChannels.isPedalError = Sensor::hasSensor(SensorType::AcceleratorPedal) ? !pedal.Valid : false; | |
391 | ||||
392 | // TPS 1 pri/sec split | |||
393 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 5 taken 522954 times.
|
522954 | engine->outputChannels.tps1Split = Sensor::getOrZero(SensorType::Tps1Primary) - Sensor::getOrZero(SensorType::Tps1Secondary); | |
394 | // TPS 2 pri/sec split | |||
395 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 5 taken 522954 times.
|
522954 | engine->outputChannels.tps2Split = Sensor::getOrZero(SensorType::Tps2Primary) - Sensor::getOrZero(SensorType::Tps2Secondary); | |
396 | // TPS1 - TPS2 split | |||
397 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 5 taken 522954 times.
|
522954 | engine->outputChannels.tps12Split = Sensor::getOrZero(SensorType::Tps1) - Sensor::getOrZero(SensorType::Tps2); | |
398 | // Pedal pri/sec split | |||
399 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 5 taken 522954 times.
|
522954 | engine->outputChannels.accPedalSplit = Sensor::getOrZero(SensorType::AcceleratorPedalPrimary) - Sensor::getOrZero(SensorType::AcceleratorPedalSecondary); | |
400 | ||||
401 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.accPedalUnfiltered = Sensor::getOrZero(SensorType::AcceleratorPedalUnfiltered); | |
402 |
1/1✓ Branch 1 taken 522954 times.
|
522954 | updateUnfilteredRawPedal(); | |
403 | 522954 | } | ||
404 | ||||
405 | 522954 | static void updateLambda() { | ||
406 | 522954 | float lambdaValue = Sensor::getOrZero(SensorType::Lambda1); | ||
407 | 522954 | engine->outputChannels.lambdaValue = lambdaValue; | ||
408 | 522954 | engine->outputChannels.AFRValue = lambdaValue * engine->fuelComputer.stoichiometricRatio; | ||
409 | // TODO: this can be calculated on PC side! | |||
410 | 522954 | engine->outputChannels.afrGasolineScale = lambdaValue * STOICH_RATIO; | ||
411 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.SmoothedAFRValue = Sensor::getOrZero(SensorType::SmoothedLambda1); | |
412 | ||||
413 | 522954 | float lambda2Value = Sensor::getOrZero(SensorType::Lambda2); | ||
414 | 522954 | engine->outputChannels.lambdaValue2 = lambda2Value; | ||
415 | 522954 | engine->outputChannels.AFRValue2 = lambda2Value * engine->fuelComputer.stoichiometricRatio; | ||
416 | // TODO: this can be calculated on PC side! | |||
417 | 522954 | engine->outputChannels.afr2GasolineScale = lambda2Value * STOICH_RATIO; | ||
418 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.SmoothedAFRValue2 = Sensor::getOrZero(SensorType::SmoothedLambda2); | |
419 | 522954 | } | ||
420 | ||||
421 | 522954 | static void updateFuelSensors() { | ||
422 | // Low pressure is directly in kpa | |||
423 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.lowFuelPressure = Sensor::getOrZero(SensorType::FuelPressureLow); | |
424 | // High pressure is in bar, aka 100 kpa | |||
425 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.highFuelPressure = KPA2BAR(Sensor::getOrZero(SensorType::FuelPressureHigh)); | |
426 | ||||
427 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.flexPercent = Sensor::getOrZero(SensorType::FuelEthanolPercent); | |
428 | ||||
429 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.fuelTankLevel = Sensor::getOrZero(SensorType::FuelLevel); | |
430 | 522954 | } | ||
431 | ||||
432 | 522954 | static void updateEgtSensors() { | ||
433 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[0] = Sensor::getOrZero(SensorType::EGT1); | |
434 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[1] = Sensor::getOrZero(SensorType::EGT2); | |
435 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[2] = Sensor::getOrZero(SensorType::EGT3); | |
436 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[3] = Sensor::getOrZero(SensorType::EGT4); | |
437 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[4] = Sensor::getOrZero(SensorType::EGT5); | |
438 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[5] = Sensor::getOrZero(SensorType::EGT6); | |
439 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[6] = Sensor::getOrZero(SensorType::EGT7); | |
440 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.egt[7] = Sensor::getOrZero(SensorType::EGT8); | |
441 | 522954 | } | ||
442 | ||||
443 | 522954 | static void updateVvtSensors() { | ||
444 | #if EFI_SHAFT_POSITION_INPUT | |||
445 | // 248 | |||
446 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.vvtPositionB1I = engine->triggerCentral.getVVTPosition(/*bankIndex*/0, /*camIndex*/0); | |
447 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.vvtPositionB1E = engine->triggerCentral.getVVTPosition(/*bankIndex*/0, /*camIndex*/1); | |
448 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.vvtPositionB2I = engine->triggerCentral.getVVTPosition(/*bankIndex*/1, /*camIndex*/0); | |
449 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.vvtPositionB2E = engine->triggerCentral.getVVTPosition(/*bankIndex*/1, /*camIndex*/1); | |
450 | #endif | |||
451 | 522954 | } | ||
452 | ||||
453 | 522954 | static void updateVehicleSpeed() { | ||
454 | #if EFI_VEHICLE_SPEED | |||
455 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.vehicleSpeedKph = Sensor::getOrZero(SensorType::VehicleSpeed); | |
456 | 522954 | engine->outputChannels.wheelSlipRatio = Sensor::getOrZero(SensorType::WheelSlipRatio); | ||
457 | #ifdef MODULE_GEAR_DETECTOR | |||
458 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 6 taken 522954 times.
|
522954 | engine->outputChannels.speedToRpmRatio = engine->module<GearDetector>()->getGearboxRatio(); | |
459 | 522954 | engine->outputChannels.detectedGear = Sensor::getOrZero(SensorType::DetectedGear); | ||
460 | #endif | |||
461 | #endif /* EFI_VEHICLE_SPEED */ | |||
462 | 522954 | } | ||
463 | ||||
464 | static SensorType luaGaugeTypes[] = { | |||
465 | SensorType::LuaGauge1, | |||
466 | SensorType::LuaGauge2, | |||
467 | SensorType::LuaGauge3, | |||
468 | SensorType::LuaGauge4, | |||
469 | SensorType::LuaGauge5, | |||
470 | SensorType::LuaGauge6, | |||
471 | SensorType::LuaGauge7, | |||
472 | SensorType::LuaGauge8 | |||
473 | }; | |||
474 | ||||
475 | 522954 | static void updateRawSensors() { | ||
476 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawTps1Primary = Sensor::getRaw(SensorType::Tps1Primary); | |
477 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawTps1Secondary = Sensor::getRaw(SensorType::Tps1Secondary); | |
478 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawTps2Primary = Sensor::getRaw(SensorType::Tps2Primary); | |
479 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawTps2Secondary = Sensor::getRaw(SensorType::Tps2Secondary); | |
480 | 522954 | engine->outputChannels.rawPpsPrimary = Sensor::getRaw(SensorType::AcceleratorPedalPrimary); | ||
481 | 522954 | engine->outputChannels.rawPpsSecondary = Sensor::getRaw(SensorType::AcceleratorPedalSecondary); | ||
482 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawBattery = Sensor::getRaw(SensorType::BatteryVoltage); | |
483 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawClt = Sensor::getRaw(SensorType::Clt); | |
484 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawIat = Sensor::getRaw(SensorType::Iat); | |
485 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAuxTemp1 = Sensor::getRaw(SensorType::AuxTemp1); | |
486 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAuxTemp2 = Sensor::getRaw(SensorType::AuxTemp2); | |
487 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAmbientTemp = Sensor::getRaw(SensorType::AmbientTemperature); | |
488 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawOilPressure = Sensor::getRaw(SensorType::OilPressure); | |
489 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawFuelLevel = Sensor::getRaw(SensorType::FuelLevel); | |
490 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAcPressure = Sensor::getRaw(SensorType::AcPressure); | |
491 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawLowFuelPressure = Sensor::getRaw(SensorType::FuelPressureLow); | |
492 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawHighFuelPressure = Sensor::getRaw(SensorType::FuelPressureHigh); | |
493 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawMaf = Sensor::getRaw(SensorType::Maf); | |
494 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawMaf2 = Sensor::getRaw(SensorType::Maf2); | |
495 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawMap = Sensor::getRaw(SensorType::MapSlow); | |
496 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawWastegatePosition = Sensor::getRaw(SensorType::WastegatePosition); | |
497 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawIdlePositionSensor = Sensor::getRaw(SensorType::IdlePosition); | |
498 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAuxAnalog1 = Sensor::getRaw(SensorType::AuxAnalog1); | |
499 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAuxAnalog2 = Sensor::getRaw(SensorType::AuxAnalog2); | |
500 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAuxAnalog3 = Sensor::getRaw(SensorType::AuxAnalog3); | |
501 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.rawAuxAnalog4 = Sensor::getRaw(SensorType::AuxAnalog4); | |
502 | ||||
503 |
2/2✓ Branch 0 taken 4183632 times.
✓ Branch 1 taken 522954 times.
|
2/2✓ Decision 'true' taken 4183632 times.
✓ Decision 'false' taken 522954 times.
|
4706586 | for (size_t i = 0;i<LUA_GAUGE_COUNT;i++) { |
504 | 4183632 | engine->outputChannels.luaGauges[i] = Sensor::getOrZero(luaGaugeTypes[i]); | ||
505 | } | |||
506 | ||||
507 |
2/2✓ Branch 0 taken 4183632 times.
✓ Branch 1 taken 522954 times.
|
2/2✓ Decision 'true' taken 4183632 times.
✓ Decision 'false' taken 522954 times.
|
4706586 | for (int i = 0; i < LUA_ANALOG_INPUT_COUNT; i++) { |
508 | 4183632 | adc_channel_e channel = engineConfiguration->auxAnalogInputs[i]; | ||
509 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4183632 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 4183632 times.
|
4183632 | if (isAdcChannelValid(channel)) { |
510 | ✗ | engine->outputChannels.rawAnalogInput[i] = adcGetScaledVoltage("raw aux", channel).value_or(0); | ||
511 | } | |||
512 | } | |||
513 | ||||
514 | // TODO: transition AFR to new sensor model | |||
515 |
5/7✓ Branch 1 taken 195464 times.
✓ Branch 2 taken 327490 times.
✓ Branch 5 taken 195464 times.
✓ Branch 9 taken 195464 times.
✓ Branch 10 taken 327490 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
|
522954 | engine->outputChannels.rawAfr = (engineConfiguration->afr.hwChannel == EFI_ADC_NONE) ? 0 : adcGetScaledVoltage("ego", engineConfiguration->afr.hwChannel).value_or(0); | |
516 | 522954 | } | ||
517 | 522954 | static void updatePressures() { | ||
518 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.baroPressure = Sensor::getOrZero(SensorType::BarometricPressure); | |
519 | // instantMAPValue is injected in a very different way | |||
520 | 522954 | float mapValue = Sensor::getOrZero(SensorType::Map); | ||
521 | 522954 | engine->outputChannels.MAPValue = mapValue; | ||
522 | ||||
523 | 522954 | engine->outputChannels.mapFast = Sensor::getOrZero(SensorType::MapFast); | ||
524 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.oilPressure = Sensor::getOrZero(SensorType::OilPressure); | |
525 | 522954 | engine->outputChannels.acPressure = Sensor::getOrZero(SensorType::AcPressure); | ||
526 | ||||
527 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.compressorDischargePressure = Sensor::getOrZero(SensorType::CompressorDischargePressure); | |
528 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.throttleInletPressure = Sensor::getOrZero(SensorType::ThrottleInletPressure); | |
529 | 522954 | engine->outputChannels.throttlePressureRatio = getThrottlePressureRatio(mapValue); | ||
530 | ||||
531 | 522954 | engine->outputChannels.auxLinear1 = Sensor::getOrZero(SensorType::AuxLinear1); | ||
532 | 522954 | engine->outputChannels.auxLinear2 = Sensor::getOrZero(SensorType::AuxLinear2); | ||
533 | 522954 | engine->outputChannels.auxLinear3 = Sensor::getOrZero(SensorType::AuxLinear3); | ||
534 | 522954 | engine->outputChannels.auxLinear4 = Sensor::getOrZero(SensorType::AuxLinear4); | ||
535 | 522954 | } | ||
536 | ||||
537 | 522954 | static void updateMiscSensors() { | ||
538 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.VBatt = Sensor::getOrZero(SensorType::BatteryVoltage); | |
539 | ||||
540 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.idlePositionSensor = Sensor::getOrZero(SensorType::IdlePosition); | |
541 | ||||
542 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.wastegatePositionSensor = Sensor::getOrZero(SensorType::WastegatePosition); | |
543 | ||||
544 | 522954 | engine->outputChannels.ISSValue = Sensor::getOrZero(SensorType::InputShaftSpeed); | ||
545 | 522954 | engine->outputChannels.auxSpeed1 = Sensor::getOrZero(SensorType::AuxSpeed1); | ||
546 | 522954 | engine->outputChannels.auxSpeed2 = Sensor::getOrZero(SensorType::AuxSpeed2); | ||
547 | ||||
548 | #if HAL_USE_ADC | |||
549 | engine->outputChannels.internalMcuTemperature = getMCUInternalTemperature(); | |||
550 | engine->outputChannels.internalVref = getMCUVref(); | |||
551 | #endif /* HAL_USE_ADC */ | |||
552 | 522954 | } | ||
553 | ||||
554 | 522954 | static void updateSensors() { | ||
555 | 522954 | updateTempSensors(); | ||
556 | 522954 | updateThrottles(); | ||
557 | 522954 | updateRawSensors(); | ||
558 | 522954 | updateLambda(); | ||
559 | 522954 | updateFuelSensors(); | ||
560 | 522954 | updateEgtSensors(); | ||
561 | 522954 | updateVvtSensors(); | ||
562 | 522954 | updateVehicleSpeed(); | ||
563 | 522954 | updatePressures(); | ||
564 | 522954 | updateMiscSensors(); | ||
565 | 522954 | } | ||
566 | ||||
567 | 522954 | static void updateFuelCorrections() { | ||
568 | 522954 | engine->outputChannels.Gego = 100.0f * engine->engineState.stftCorrection[0]; | ||
569 | 522954 | } | ||
570 | ||||
571 | 522954 | static void updateFuelResults() { | ||
572 | #if EFI_VEHICLE_SPEED && defined (MODULE_ODOMETER) | |||
573 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 6 taken 522954 times.
|
522954 | engine->outputChannels.fuelFlowRate = engine->module<TripOdometer>()->getConsumptionGramPerSecond(); | |
574 | 522954 | engine->outputChannels.totalFuelConsumption = engine->module<TripOdometer>()->getConsumedGrams(); | ||
575 | 522954 | engine->outputChannels.ignitionOnTime = engine->module<TripOdometer>()->getIgnitionOnTime(); | ||
576 | 522954 | engine->outputChannels.engineRunTime = engine->module<TripOdometer>()->getEngineRunTime(); | ||
577 | ||||
578 | // output channel in km | |||
579 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 6 taken 522954 times.
|
522954 | engine->outputChannels.distanceTraveled = 0.001f * engine->module<TripOdometer>()->getDistanceMeters(); | |
580 | #endif // EFI_VEHICLE_SPEED MODULE_ODOMETER | |||
581 | 522954 | } | ||
582 | ||||
583 | 522954 | static void updateFuelInfo() { | ||
584 | 522954 | updateFuelCorrections(); | ||
585 | 522954 | updateFuelResults(); | ||
586 | #if EFI_ENGINE_CONTROL | |||
587 | 522954 | const auto& wallFuel = engine->injectionEvents.elements[0].getWallFuel(); | ||
588 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.wallFuelAmount = wallFuel.getWallFuel() * 1000; // Convert grams to mg | |
589 | 522954 | engine->outputChannels.wallFuelCorrectionValue = wallFuel.wallFuelCorrection * 1000; // Convert grams to mg | ||
590 | ||||
591 | 522954 | engine->outputChannels.veValue = engine->engineState.currentVe; | ||
592 | #endif // EFI_ENGINE_CONTROL | |||
593 | 522954 | } | ||
594 | ||||
595 | 522954 | static void updateIgnition(float rpm) { | ||
596 | #if EFI_ENGINE_CONTROL | |||
597 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | engine->outputChannels.coilDutyCycle = getCoilDutyCycle(rpm); | |
598 | #endif // EFI_ENGINE_CONTROL | |||
599 | 522954 | } | ||
600 | ||||
601 | 522954 | static void updateFlags() { | ||
602 | 522954 | engine->outputChannels.isO2HeaterOn = enginePins.o2heater.getLogicValue(); | ||
603 | // todo: eliminate state copy logic by giving DfcoController it's owm xxx.txt and leveraging LiveData | |||
604 | 522954 | engine->outputChannels.dfcoActive = engine->module<DfcoController>()->cutFuel(); | ||
605 | ||||
606 | #if EFI_LAUNCH_CONTROL | |||
607 | 522954 | engine->outputChannels.launchTriggered = engine->launchController.isLaunchCondition; | ||
608 | #endif | |||
609 | ||||
610 | #if EFI_PROD_CODE | |||
611 | engine->outputChannels.isTriggerError = isTriggerErrorNow(); | |||
612 | #endif // EFI_PROD_CODE | |||
613 | ||||
614 | #if EFI_CONFIGURATION_STORAGE | |||
615 | engine->outputChannels.needBurn = getNeedToWriteConfiguration(); | |||
616 | #endif /* EFI_CONFIGURATION_STORAGE */ | |||
617 | #if EFI_FILE_LOGGING | |||
618 | updateSdCardLiveFlags(); | |||
619 | #endif | |||
620 | 522954 | } | ||
621 | ||||
622 | // sensor state for EFI Analytics Tuner Studio | |||
623 | // todo: the 'let's copy internal state for external consumers' approach is DEPRECATED | |||
624 | // As of 2022 it's preferred to leverage LiveData where all state is exposed | |||
625 | // this method is invoked ONLY if we SD card log or have serial connection with some frontend app | |||
626 | 522954 | void updateTunerStudioState() { | ||
627 | 522954 | TunerStudioOutputChannels *tsOutputChannels = &engine->outputChannels; | ||
628 | #if EFI_USB_SERIAL | |||
629 | // pretty much SD card logs know if specifically USB serial is active | |||
630 | engine->outputChannels.isUsbConnected = is_usb_serial_ready(); | |||
631 | #endif // EFI_USB_SERIAL | |||
632 | ||||
633 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | float rpm = Sensor::get(SensorType::Rpm).value_or(0); | |
634 | ||||
635 | ||||
636 | static Timer blinkIndicatorsTimer; | |||
637 | 522954 | constexpr float blinkHalfPeriod = 0.3; | ||
638 | 522954 | bool isBlinkPhase = blinkIndicatorsTimer.hasElapsedSec(blinkHalfPeriod); | ||
639 | #if EFI_ELECTRONIC_THROTTLE_BODY | |||
640 | 522954 | blinkEtbErrorCodes(isBlinkPhase); | ||
641 | #endif // EFI_ELECTRONIC_THROTTLE_BODY | |||
642 |
2/2✓ Branch 0 taken 259331 times.
✓ Branch 1 taken 263623 times.
|
2/2✓ Decision 'true' taken 259331 times.
✓ Decision 'false' taken 263623 times.
|
522954 | if (isBlinkPhase) { |
643 | 259331 | engine->outputChannels.sparkCutReasonBlinker = 0; | ||
644 | 259331 | engine->outputChannels.fuelCutReasonBlinker = 0; | ||
645 | ||||
646 |
2/2✓ Branch 1 taken 1644 times.
✓ Branch 2 taken 257687 times.
|
2/2✓ Decision 'true' taken 1644 times.
✓ Decision 'false' taken 257687 times.
|
259331 | if (blinkIndicatorsTimer.hasElapsedSec(2 * blinkHalfPeriod)) { |
647 | 1644 | blinkIndicatorsTimer.reset(); | ||
648 | } | |||
649 | } else { | |||
650 | 263623 | engine->outputChannels.sparkCutReasonBlinker = engine->outputChannels.sparkCutReason; | ||
651 | 263623 | engine->outputChannels.fuelCutReasonBlinker = engine->outputChannels.fuelCutReason; | ||
652 | } | |||
653 | ||||
654 | ||||
655 | #if EFI_PROD_CODE | |||
656 | executorStatistics(); | |||
657 | #endif /* EFI_PROD_CODE */ | |||
658 | ||||
659 | 522954 | DcHardware *dc = getPrimaryDCHardwareForLogging(); | ||
660 | 522954 | engine->dc_motors.dcOutput0 = dc->dcMotor.get(); | ||
661 | 522954 | engine->dc_motors.isEnabled0_int = dc->msg() == nullptr; | ||
662 | ||||
663 | 522954 | tsOutputChannels->RPMValue = rpm; | ||
664 | #if EFI_SHAFT_POSITION_INPUT | |||
665 | 522954 | tsOutputChannels->instantRpm = engine->triggerCentral.instantRpm.getInstantRpm(); | ||
666 | 522954 | tsOutputChannels->totalTriggerErrorCounter = engine->triggerCentral.triggerState.totalTriggerErrorCounter; | ||
667 | 522954 | tsOutputChannels->rpmAcceleration = engine->rpmCalculator.getRpmAcceleration(); | ||
668 | ||||
669 | 522954 | tsOutputChannels->orderingErrorCounter = engine->triggerCentral.triggerState.orderingErrorCounter; | ||
670 | #endif // EFI_SHAFT_POSITION_INPUT | |||
671 | ||||
672 | 522954 | updateSensors(); | ||
673 | 522954 | updateFuelInfo(); | ||
674 | 522954 | updateIgnition(rpm); | ||
675 | 522954 | updateFlags(); | ||
676 | // update calibration channel, reset to None state after timeout | |||
677 | 522954 | tsCalibrationIsIdle(); | ||
678 | ||||
679 | // Output both the estimated air flow, and measured air flow (if available) | |||
680 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | tsOutputChannels->mafMeasured = Sensor::getOrZero(SensorType::Maf); | |
681 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | tsOutputChannels->mafMeasured2 = Sensor::getOrZero(SensorType::Maf2); | |
682 | 522954 | tsOutputChannels->mafEstimate = engine->engineState.airflowEstimate; | ||
683 | ||||
684 | #if EFI_ENGINE_CONTROL | |||
685 |
2/2✓ Branch 2 taken 522954 times.
✓ Branch 5 taken 522954 times.
|
522954 | tsOutputChannels->injectorDutyCycle = minF(/*let's avoid scaled "uint8_t, 2" overflow*/127, getInjectorDutyCycle(rpm)); | |
686 |
1/1✓ Branch 2 taken 522954 times.
|
522954 | tsOutputChannels->injectorDutyCycleStage2 = getInjectorDutyCycleStage2(rpm); | |
687 | #endif | |||
688 | ||||
689 | 522954 | tsOutputChannels->seconds = getTimeNowS(); | ||
690 | ||||
691 | 522954 | tsOutputChannels->engineMode = packEngineMode(); | ||
692 | 522954 | tsOutputChannels->firmwareVersion = getRusEfiVersion(); | ||
693 | ||||
694 | 522954 | tsOutputChannels->accelerationLat = engine->sensors.accelerometer.lat; | ||
695 | 522954 | tsOutputChannels->accelerationLon = engine->sensors.accelerometer.lon; | ||
696 | 522954 | tsOutputChannels->accelerationVert = engine->sensors.accelerometer.vert; | ||
697 | 522954 | tsOutputChannels->gyroYaw = engine->sensors.accelerometer.yawRate; | ||
698 | ||||
699 | #if EFI_DYNO_VIEW | |||
700 | 522954 | tsOutputChannels->hp = getDynoviewHP(); | ||
701 | 522954 | tsOutputChannels->torque = getDynoviewTorque(); | ||
702 | #else | |||
703 | tsOutputChannels->hp = -1; | |||
704 | tsOutputChannels->torque = -1; | |||
705 | #endif | |||
706 | ||||
707 | 522954 | tsOutputChannels->turboSpeed = Sensor::getOrZero(SensorType::TurbochargerSpeed); | ||
708 | extern FrequencySensor inputShaftSpeedSensor; | |||
709 | 522954 | tsOutputChannels->issEdgeCounter = inputShaftSpeedSensor.eventCounter; | ||
710 | extern FrequencySensor vehicleSpeedSensor; | |||
711 | 522954 | tsOutputChannels->vssEdgeCounter = vehicleSpeedSensor.eventCounter; | ||
712 | ||||
713 |
3/6✓ Branch 0 taken 522954 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 522954 times.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 522954 times.
|
522954 | tsOutputChannels->hasCriticalError = hasFirmwareError() || hasConfigError() || engine->engineState.warnings.hasWarningMessage(); | |
714 | 522954 | tsOutputChannels->hasFaultReportFile = hasErrorReportFile(); | ||
715 |
2/4✓ Branch 1 taken 522954 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 522954 times.
|
522954 | tsOutputChannels->triggerPageRefreshFlag = needToTriggerTsRefresh() || ltftNeedVeRefresh(); | |
716 | ||||
717 | 522954 | tsOutputChannels->isWarnNow = engine->engineState.warnings.isWarningNow(); | ||
718 | ||||
719 | 522954 | tsOutputChannels->tpsAccelFuel = engine->engineState.tpsAccelEnrich; | ||
720 | ||||
721 | 522954 | tsOutputChannels->checkEngine = hasErrorCodes(); | ||
722 | ||||
723 | 522954 | engine->engineState.warnings.refreshTs(); | ||
724 | ||||
725 | 522954 | tsOutputChannels->starterState = enginePins.starterControl.getLogicValue(); | ||
726 | 522954 | tsOutputChannels->starterRelayDisable = enginePins.starterRelayDisable.getLogicValue(); | ||
727 | ||||
728 | ||||
729 | 522954 | tsOutputChannels->revolutionCounterSinceStart = engine->rpmCalculator.getRevolutionCounterSinceStart(); | ||
730 | ||||
731 | #if EFI_CLOCK_LOCKS | |||
732 | tsOutputChannels->maxLockedDuration = NT2US(maxLockedDuration); | |||
733 | #endif /* EFI_CLOCK_LOCKS */ | |||
734 | ||||
735 | #if EFI_SHAFT_POSITION_INPUT | |||
736 | 522954 | tsOutputChannels->maxTriggerReentrant = maxTriggerReentrant; | ||
737 | 522954 | tsOutputChannels->triggerPrimaryFall = engine->triggerCentral.getHwEventCounter((int)SHAFT_PRIMARY_FALLING); | ||
738 | 522954 | tsOutputChannels->triggerPrimaryRise = engine->triggerCentral.getHwEventCounter((int)SHAFT_PRIMARY_RISING); | ||
739 | ||||
740 | 522954 | tsOutputChannels->triggerSecondaryFall = engine->triggerCentral.getHwEventCounter((int)SHAFT_SECONDARY_FALLING); | ||
741 | 522954 | tsOutputChannels->triggerSecondaryRise = engine->triggerCentral.getHwEventCounter((int)SHAFT_SECONDARY_RISING); | ||
742 | ||||
743 | #endif // EFI_SHAFT_POSITION_INPUT | |||
744 | ||||
745 | #if HAL_USE_PAL && EFI_PROD_CODE | |||
746 | tsOutputChannels->extiOverflowCount = getExtiOverflowCounter(); | |||
747 | #endif | |||
748 | ||||
749 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 522954 times.
|
522954 | switch (engineConfiguration->debugMode) { | |
750 | ✗ | case DBG_LOGIC_ANALYZER: | ||
751 | #if EFI_LOGIC_ANALYZER | |||
752 | // used by HW CI | |||
753 | reportLogicAnalyzerToTS(); | |||
754 | #endif /* EFI_LOGIC_ANALYZER */ | |||
755 | ✗ | break; | ||
756 |
1/1✓ Decision 'true' taken 522954 times.
|
522954 | default: | |
757 | ; | |||
758 | } | |||
759 | 522954 | } | ||
760 | ||||
761 | #endif /* EFI_TUNER_STUDIO */ | |||
762 | ||||
763 | ✗ | void startStatusThreads() { | ||
764 | // todo: refactoring needed, this file should probably be split into pieces | |||
765 | #if EFI_PROD_CODE | |||
766 | initStatusLeds(); | |||
767 | communicationsBlinkingTask.start(); | |||
768 | #endif /* EFI_PROD_CODE */ | |||
769 | ✗ | } | ||
770 |