rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
bench_test.cpp
Go to the documentation of this file.
1/**
2 * @file bench_test.cpp
3 * @brief Utility methods related to bench testing.
4 *
5 *
6 * @date Sep 8, 2013
7 * @author Andrey Belomutskiy, (c) 2012-2020
8 *
9 * This file is part of rusEfi - see http://rusefi.com
10 *
11 * rusEfi is free software; you can redistribute it and/or modify it under the terms of
12 * the GNU General Public License as published by the Free Software Foundation; either
13 * version 3 of the License, or (at your option) any later version.
14 *
15 * rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
16 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along with this program.
20 * If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include "pch.h"
24#include "tunerstudio.h"
26#include "long_term_fuel_trim.h"
27#include "can_common.h"
28#include "can_rx.h"
29#include "torque_estimator.h"
30#include "value_lookup.h"
31#include "can_msg_tx.h"
32#include "gm_sbc.h" // setStepperHw
33
34#include "fw_configuration.h"
35#include "board_overrides.h"
36
37static bool isRunningBench = false;
39
41 return isRunningBench;
42}
43
47
48#if !EFI_UNIT_TEST
49
50#include "flash_main.h"
51#include "bench_test.h"
54#include "electronic_throttle.h"
56#include "malfunction_central.h"
58#include "vvt.h"
59#include "microsecond_timer.h"
60#include "rusefi_wideband.h"
61
62#if EFI_PROD_CODE
63#include "rusefi.h"
64#include "mpu_util.h"
65#endif /* EFI_PROD_CODE */
66
67#if (BOARD_TLE8888_COUNT > 0)
68#include "gpio/tle8888.h"
69#endif // BOARD_TLE8888_COUNT
70
71#if EFI_FILE_LOGGING
72#include "mmc_card.h"
73#endif
74
77
78#if EFI_SIMULATOR
79static int savedPinToggleCounter = 0;
80static uint32_t savedDurationsInStateMs[2] = { 0, 0 };
81#endif // EFI_SIMULATOR
82
83
84#define BENCH_MSG "bench"
85
86static void benchOn(OutputPin* output) {
87 output->setValue(BENCH_MSG, true, /*isForce*/ true);
88}
89
90static void benchOff(OutputPin* output) {
91#if EFI_PROD_CODE && (BOARD_EXT_GPIOCHIPS > 0)
92 static char pin_error[64];
93
94 brain_pin_diag_e diag = output->getDiag();
95 if (diag == PIN_UNKNOWN) {
96 efiPrintf("No Diag on this pin");
97 } else {
98 pinDiag2string(pin_error, sizeof(pin_error), diag);
99 efiPrintf("Diag says %s", pin_error);
100 }
101#endif // EFI_PROD_CODE
102 output->setValue(BENCH_MSG, false, /*isForce*/ true);
103}
104
105static void runBench(OutputPin *output, float onTimeMs, float offTimeMs, int count, bool swapOnOff) {
106 int onTimeUs = MS2US(std::max(0.1f, onTimeMs));
107 int offTimeUs = MS2US(std::max(0.1f, offTimeMs));
108
109 if (onTimeUs > TOO_FAR_INTO_FUTURE_US) {
110 firmwareError(ObdCode::CUSTOM_ERR_BENCH_PARAM, "onTime above limit %dus", TOO_FAR_INTO_FUTURE_US);
111 return;
112 }
113
114 efiPrintf("Running bench: ON_TIME=%d us OFF_TIME=%d us Counter=%d", onTimeUs, offTimeUs, count);
115 efiPrintf("output on %s", hwPortname(output->brainPin));
116
117 isRunningBench = true;
118 outputOnTheBenchTest = output;
119
120 for (int i = 0; isRunningBench && i < count; i++) {
122 efitick_t nowNt = getTimeNowNt();
123 // start in a short time so the scheduler can precisely schedule the start event
124 efitick_t startTime = nowNt + US2NT(50);
125 efitick_t endTime = startTime + US2NT(onTimeUs);
126
127 auto const bstartAction{ swapOnOff ? action_s::make<benchOff>(output) : action_s::make<benchOn>(output) };
128 auto const bendAction{ swapOnOff ? action_s::make<benchOn>(output) : action_s::make<benchOff>(output) };
129
130 // Schedule both events
131 engine->scheduler.schedule("bstart", &benchSchedStart, startTime, bstartAction);
132 engine->scheduler.schedule("bend", &benchSchedEnd, endTime, bendAction);
133
134 // Wait one full cycle time for the event + delay to happen
135 chThdSleepMicroseconds(onTimeUs + offTimeUs);
136 }
137 /* last */
139
140#if EFI_SIMULATOR
141 // save the current counters and durations after the test while the pin is still controlled
145#endif // EFI_SIMULATOR
146
147 efiPrintf("Done!");
148 outputOnTheBenchTest = nullptr;
149 isRunningBench = false;
150}
151
152// todo: migrate to smarter getOutputOnTheBenchTest() approach?
153static volatile bool isBenchTestPending = false;
154static bool widebandUpdatePending = false;
155static bool widebandUpdateFromFile = false;
156static uint8_t widebandUpdateHwId = 0;
157static float globalOnTimeMs;
158static float globalOffTimeMs;
159static int globalCount;
161static bool swapOnOff = false;
162
163static chibios_rt::CounterSemaphore benchSemaphore(0);
164
165static void pinbench(float ontimeMs, float offtimeMs, int iterations,
166 OutputPin* pinParam, bool p_swapOnOff = false)
167{
168 globalOnTimeMs = ontimeMs;
169 globalOffTimeMs = offtimeMs;
170#if EFI_SIMULATOR
171 globalCount = maxI(2, iterations);
172#else
173 globalCount = iterations;
174#endif // EFI_SIMULATOR
175 pinX = pinParam;
176 swapOnOff = p_swapOnOff;
177 // let's signal bench thread to wake up
178 isBenchTestPending = true;
179 benchSemaphore.signal();
180}
181
182static void cancelBenchTest() {
183 isRunningBench = false;
184}
185
186static void doRunFuelInjBench(size_t humanIndex, float onTimeMs, float offTimeMs, int count) {
187 if (humanIndex < 1 || humanIndex > engineConfiguration->cylindersCount) {
188 efiPrintf("Invalid index: %d", humanIndex);
189 return;
190 }
191 pinbench(onTimeMs, offTimeMs, count,
192 &enginePins.injectors[humanIndex - 1]);
193}
194
195static void doRunSparkBench(size_t humanIndex, float onTime, float offTime, int count) {
196 if (humanIndex < 1 || humanIndex > engineConfiguration->cylindersCount) {
197 efiPrintf("Invalid index: %d", humanIndex);
198 return;
199 }
200 pinbench(onTime, offTime, count, &enginePins.coils[humanIndex - 1]);
201}
202
203static void doRunSolenoidBench(size_t humanIndex, float onTime, float offTime, int count) {
204 if (humanIndex < 1 || humanIndex > TCU_SOLENOID_COUNT) {
205 efiPrintf("Invalid index: %d", humanIndex);
206 return;
207 }
208 pinbench(onTime, offTime, count, &enginePins.tcuSolenoids[humanIndex - 1]);
209}
210
211static void doRunBenchTestLuaOutput(size_t humanIndex, float onTimeMs, float offTimeMs, int count) {
212 if (humanIndex < 1 || humanIndex > LUA_PWM_COUNT) {
213 efiPrintf("Invalid index: %d", humanIndex);
214 return;
215 }
216 pinbench(onTimeMs, offTimeMs, count,
217 &enginePins.luaOutputPins[humanIndex - 1]);
218}
219
220/**
221 * cylinder #2, 5ms ON, 1000ms OFF, repeat 3 times
222 * fuelInjBenchExt 2 5 1000 3
223 */
224static void fuelInjBenchExt(float humanIndex, float onTimeMs, float offTimeMs, float count) {
225 doRunFuelInjBench((int)humanIndex, onTimeMs, offTimeMs, (int)count);
226}
227
228/**
229 * fuelbench 5 1000 2
230 */
231static void fuelInjBench(float onTimeMs, float offTimeMs, float count) {
232 fuelInjBenchExt(1, onTimeMs, offTimeMs, count);
233}
234
235/**
236 * sparkbench2 1 5 1000 2
237 */
238static void sparkBenchExt(float humanIndex, float onTime, float offTimeMs, float count) {
239 doRunSparkBench((int)humanIndex, onTime, offTimeMs, (int)count);
240}
241
242/**
243 * sparkbench 5 400 2
244 * 5 ms ON, 400 ms OFF, two times
245 */
246static void sparkBench(float onTime, float offTimeMs, float count) {
247 sparkBenchExt(1, onTime, offTimeMs, count);
248}
249
250/**
251 * solenoid #2, 1000ms ON, 1000ms OFF, repeat 3 times
252 * tcusolbench 2 1000 1000 3
253 */
254static void tcuSolenoidBench(float humanIndex, float onTime, float offTimeMs, float count) {
255 doRunSolenoidBench((int)humanIndex, onTime, offTimeMs, (int)count);
256}
257
258static void fanBenchExt(float onTimeMs) {
259 pinbench(onTimeMs, 100.0, 1, &enginePins.fanRelay);
260}
261
262void fanBench() {
263 fanBenchExt(BENCH_FAN_DURATION);
264}
265
266void fan2Bench() {
267 pinbench(3000.0, 100.0, 1, &enginePins.fanRelay2);
268}
269
270/**
271 * we are blinking for 16 seconds so that one can click the button and walk around to see the light blinking
272 */
273void milBench() {
274 pinbench(500.0, 500.0, 16, &enginePins.checkEnginePin);
275}
276
278 pinbench(BENCH_STARTER_DURATION, 100.0, 1, &enginePins.starterControl);
279}
280
281static void fuelPumpBenchExt(float durationMs) {
282 pinbench(durationMs, 100.0, 1,
284}
285
287 pinbench(BENCH_AC_RELAY_DURATION, 100.0, 1, &enginePins.acRelay);
288}
289
290static void mainRelayBench() {
291 pinbench(BENCH_MAIN_RELAY_DURATION, 100.0, 1, &enginePins.mainRelay, true);
292}
293
298
300 fuelPumpBenchExt(BENCH_FUEL_PUMP_DURATION);
301}
302
303static void vvtValveBench(int vvtIndex) {
304#if EFI_VVT_PID
305 pinbench(BENCH_VVT_DURATION, 100.0, 1, getVvtOutputPin(vvtIndex));
306#endif // EFI_VVT_PID
307}
308
309static void requestWidebandUpdate(int hwIndex, bool fromFile)
310{
311 widebandUpdateHwId = hwIndex;
312 widebandUpdateFromFile = fromFile;
314 benchSemaphore.signal();
315}
316
317class BenchController : public ThreadController<4 * UTILITY_THREAD_STACK_SIZE> {
318public:
319 BenchController() : ThreadController("BenchTest", PRIO_BENCH_TEST) { }
320private:
321 void ThreadTask() override {
322 while (true) {
323 benchSemaphore.wait();
324
325 assertStackVoid("Bench", ObdCode::STACK_USAGE_MISC, EXPECTED_REMAINING_STACK);
326
327 if (isBenchTestPending) {
328 isBenchTestPending = false;
330 }
331
333 #if EFI_WIDEBAND_FIRMWARE_UPDATE && EFI_CAN_SUPPORT
335 #if EFI_PROD_CODE
337 #endif
338 } else {
340 }
341 #endif
342 widebandUpdatePending = false;
343 }
344 }
345 }
346};
347
348static BenchController instance;
349
350static void auxOutBench(int index) {
351 // todo!
352 UNUSED(index);
353}
354
355#if EFI_HD_ACR
356static void hdAcrBench(int index) {
358 pinbench(BENCH_AC_RELAY_DURATION, 100.0, 1, pin);
359}
360#endif // EFI_HD_ACR
361
362int luaCommandCounters[LUA_BUTTON_COUNT] = {};
363
364void handleBenchCategory(uint16_t index) {
365 switch(index) {
366 case BENCH_VVT0_VALVE:
367 vvtValveBench(0);
368 return;
369 case BENCH_VVT1_VALVE:
370 vvtValveBench(1);
371 return;
372 case BENCH_VVT2_VALVE:
373 vvtValveBench(2);
374 return;
375 case BENCH_VVT3_VALVE:
376 vvtValveBench(3);
377 return;
378 case BENCH_AUXOUT0:
379 auxOutBench(0);
380 return;
381 case BENCH_AUXOUT1:
382 auxOutBench(1);
383 return;
384 case BENCH_AUXOUT2:
385 auxOutBench(2);
386 return;
387 case BENCH_AUXOUT3:
388 auxOutBench(3);
389 return;
390 case BENCH_AUXOUT4:
391 auxOutBench(4);
392 return;
393 case BENCH_AUXOUT5:
394 auxOutBench(5);
395 return;
396 case BENCH_AUXOUT6:
397 auxOutBench(6);
398 return;
399 case BENCH_AUXOUT7:
400 auxOutBench(7);
401 return;
402 case LUA_COMMAND_1:
404 return;
405 case LUA_COMMAND_2:
407 return;
408 case LUA_COMMAND_3:
410 return;
411 case LUA_COMMAND_4:
413 return;
414#if EFI_LTFT_CONTROL
415 case LTFT_RESET:
417 return;
418 case LTFT_APPLY_TO_VE:
420 return;
421 case LTFT_DEV_POKE:
423 return;
424#endif // EFI_LTFT_CONTROL
425#if EFI_HD_ACR
426 case HD_ACR:
427 hdAcrBench(0);
428 return;
429 case HD_ACR2:
430 hdAcrBench(1);
431 return;
432#endif // EFI_HD_ACR
433 case BENCH_HPFP_VALVE:
435 return;
436 case BENCH_FUEL_PUMP:
437 // cmd_test_fuel_pump
439 return;
440 case BENCH_MAIN_RELAY:
442 return;
445 return;
447 // cmd_test_check_engine_light
448 milBench();
449 return;
451 acRelayBench();
452 return;
453 case BENCH_FAN_RELAY:
454 fanBench();
455 return;
456 case BENCH_IDLE_VALVE:
457 // cmd_test_idle_valve
458#if EFI_IDLE_CONTROL
460#endif /* EFI_IDLE_CONTROL */
461 return;
463 fan2Bench();
464 return;
465 case BENCH_CANCEL:
467 return;
468 default:
469 criticalError("Unexpected bench function %d", index);
470 }
471}
472
473int getSavedBenchTestPinStates(uint32_t durationsInStateMs[2]) {
474#if EFI_SIMULATOR
475 durationsInStateMs[0] = savedDurationsInStateMs[0];
476 durationsInStateMs[1] = savedDurationsInStateMs[1];
478#else
479 UNUSED(durationsInStateMs);
480 return 0;
481#endif // EFI_SIMULATOR
482}
483
484static void handleCommandX14(uint16_t index) {
485 switch (index) {
487 setStepperHw();
489 return;
490 case TS_GRAB_PEDAL_UP:
492 return;
495 return;
498 return;
499 case TS_GRAB_TPS_OPEN:
501 return;
502 case TS_RESET_TLE8888:
503 #if (BOARD_TLE8888_COUNT > 0)
505 #endif
506 return;
509 // do nothing, we are catching with Lua
510 // this is temporary uaDASH API
511 return;
512 case TS_RESET_MC33810:
513 #if EFI_PROD_CODE && (BOARD_MC33810_COUNT > 0)
515 #endif
516 return;
517#if EFI_SHAFT_POSITION_INPUT
519 // this is different from starter relay bench test!
521 return;
522#endif // EFI_SHAFT_POSITION_INPUT
523 case TS_WRITE_FLASH:
524 // cmd_write_config
525 #if EFI_CONFIGURATION_STORAGE
527 #endif /* EFI_CONFIGURATION_STORAGE */
528 return;
530 #if EFI_EMULATE_POSITION_SENSORS == TRUE
532 #endif /* EFI_EMULATE_POSITION_SENSORS == TRUE */
533 return;
535 #if EFI_EMULATE_POSITION_SENSORS == TRUE
537 #endif /* EFI_EMULATE_POSITION_SENSORS == TRUE */
538 return;
540 #if EFI_EMULATE_POSITION_SENSORS == TRUE
542 #endif /* EFI_EMULATE_POSITION_SENSORS == TRUE */
543 return;
544/*
545 case TS_ETB_RESET:
546 #if EFI_ELECTRONIC_THROTTLE_BODY == TRUE
547 #if EFI_PROD_CODE
548 etbPidReset();
549 #endif
550 #endif // EFI_ELECTRONIC_THROTTLE_BODY
551 return;
552*/
553#if EFI_ELECTRONIC_THROTTLE_BODY
554 case TS_ETB_AUTOCAL_0:
555 etbAutocal(DC_Throttle1);
556 return;
557 case TS_ETB_AUTOCAL_1:
558 etbAutocal(DC_Throttle2);
559 return;
561 etbAutocal(DC_Throttle1, false);
562 return;
564 etbAutocal(DC_Throttle2, false);
565 return;
568 return;
571 return;
573 engine->etbAutoTune = true;
574 return;
576 engine->etbAutoTune = false;
577 #if EFI_TUNER_STUDIO
579 #endif // EFI_TUNER_STUDIO
580 return;
583 return;
584 case TS_EWG_AUTOCAL_0:
585 etbAutocal(DC_Wastegate);
586 return;
588 etbAutocal(DC_Wastegate, false);
589 return;
590#endif // EFI_ELECTRONIC_THROTTLE_BODY
593 // broadcast, for old WBO FWs
595 return;
599 return;
601 return;
602
603#if EFI_PROD_CODE && EFI_FILE_LOGGING
604 case TS_SD_MOUNT_PC:
606 return;
607 case TS_SD_MOUNT_ECU:
609 return;
610 case TS_SD_UNMOUNT:
612 return;
613 case TS_SD_FORMAT:
615 return;
618 return;
619#endif // EFI_FILE_LOGGING
620
621 default:
622 criticalError("Unexpected bench x14 %d", index);
623 }
624}
625
626extern bool rebootForPresetPending;
627
628static void applyPreset(int index) {
629 setEngineType(index);
630#if EFI_TUNER_STUDIO
632#endif // EFI_TUNER_STUDIO
633}
634
635// placeholder to force custom_board_ts_command migration
636void boardTsAction(uint16_t index) { UNUSED(index); }
637
638#if EFI_CAN_SUPPORT
639/**
640 * for example to bench test injector 1
641 * 0x77000C 0x66 0x00 ?? ?? ?? ??
642 * 0x77000C 0x66 0x00 0x14 0x00 0x09 0x00 start/stop engine
643 *
644 * See also more complicated ISO-TP CANBus wrapper of complete TS protocol
645 */
646static void processCanUserControl(const CANRxFrame& frame) {
647 // reserved data8[1]
648 uint16_t subsystem = getTwoBytesLsb(frame, 2);
649 uint16_t index = getTwoBytesLsb(frame, 4);
650 executeTSCommand(subsystem, index);
651}
652
653 union FloatIntBytes {
654 float f;
655 int i;
656 uint8_t bytes[sizeof(float)];
657 };
658
659static void processCanSetCalibration(const CANRxFrame& frame) {
660 // todo allow changes of scalar settings via CANbus
661 UNUSED(frame);
662}
663/**
664 * CANbus protocol to query scalar calibrations using hash keys
665 *
666 * see fields_api.txt for well-known fields
667 * see generated_fields_api_header.h for corresponding hashes
668 */
669static void processCanRequestCalibration(const CANRxFrame& frame) {
670#if EFI_LUA_LOOKUP
671 int hash = getFourBytesLsb(frame, 2);
672 efiPrintf("processCanRequestCalibration=%x", hash);
673 FloatIntBytes fb;
674 fb.f = getConfigValueByHash(hash);
675
676 CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::ECU_GET_CALIBRATION, 8, /*bus*/0, /*isExtended*/true);
677 for (size_t i = 0;i<sizeof(float);i++) {
678 msg[4 + i] = fb.bytes[i];
679 }
680
681 fb.i = hash;
682 // first half of the packed is copy of that hash value so that recipients know what they are processing
683 for (size_t i = 0;i<sizeof(float);i++) {
684 msg[i] = fb.bytes[i];
685 }
686#endif // EFI_LUA_LOOKUP
687}
688
690 if (frame.data8[0] != (int)bench_test_magic_numbers_e::BENCH_HEADER) {
691 return;
692 }
693
694 int eid = CAN_EID(frame);
695 if (eid == (int)bench_test_packet_ids_e::ECU_SET_CALIBRATION) {
697 } else if (eid == (int)bench_test_packet_ids_e::ECU_REQ_CALIBRATION) {
699 } else if (eid == (int)bench_test_packet_ids_e::ECU_CAN_BUS_USER_CONTROL) {
701 }
702}
703
704#endif // EFI_CAN_SUPPORT
705
706std::optional<setup_custom_board_ts_command_override_type> custom_board_ts_command;
707
708void executeTSCommand(uint16_t subsystem, uint16_t index) {
709 efiPrintf("IO test subsystem=%d index=%d", subsystem, index);
710
712
713 switch (subsystem) {
716 break;
717
718 case TS_DEBUG_MODE:
720 break;
721
723 if (!running) {
726 }
727 break;
728
730 if (!running) {
733 }
734 break;
735
737 if (!running) {
738 doRunSolenoidBench(index, 1000.0,
740 }
741 break;
742
744 if (!running) {
745 doRunBenchTestLuaOutput(index, 4.0,
747 }
748 break;
749
750 case TS_X14:
751 handleCommandX14(index);
752 break;
753#if EFI_CAN_SUPPORT
754 case TS_WIDEBAND:
755 setWidebandOffset(0xff, index);
756 break;
758 {
759 uint8_t hwIndex = index >> 8;
760 uint8_t canIndex = index & 0xff;
761
762 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
763 // TODO:
764 hwIndex = hwIndex < 8 ? hwIndex : 0xff;
765 setWidebandOffset(hwIndex, canIndex);
766 }
767 break;
769 {
770 uint8_t hwIndex = index >> 8;
771 uint8_t sensType = index & 0xff;
772
773 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
774 // TODO:
775 hwIndex = hwIndex < 8 ? hwIndex : 0xff;
776 setWidebandSensorType(hwIndex, sensType);
777 }
778 break;
780 pingWideband(index >> 8);
781 break;
782
785 {
786 uint8_t hwIndex = index >> 8;
787
788 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
789 // TODO:
790 widebandUpdateHwId = hwIndex < 8 ? hwIndex : 0xff;
792 }
793 break;
794
797 break;
798
799#endif // EFI_CAN_SUPPORT
801 handleBenchCategory(index);
802 break;
803
805 applyPreset(index);
806 break;
807
808 case TS_BOARD_ACTION:
809 // TODO: use call_board_override
810 if (custom_board_ts_command.has_value()) {
811 custom_board_ts_command.value()(subsystem, index);
812 }
813 break;
814
816 applyPreset((int)DEFAULT_ENGINE_TYPE);
817 break;
818
819 case TS_STOP_ENGINE:
821 break;
822
823 case 0xba:
824#if EFI_PROD_CODE && EFI_DFU_JUMP
826#endif /* EFI_DFU_JUMP */
827 break;
828
829 case REBOOT_COMMAND:
830#if EFI_PROD_CODE
831 rebootNow();
832#endif /* EFI_PROD_CODE */
833 break;
834
835#if EFI_USE_OPENBLT
836 case 0xbc:
837 /* Jump to OpenBLT if present */
839 break;
840#endif
841
842 default:
843 criticalError("Unexpected bench subsystem %d %d", subsystem, index);
844 }
845}
846
848 // default values if configuration was not specified
851 }
852
855 }
856
859 }
860}
861
863 addConsoleAction("fuelpumpbench", fuelPumpBench);
864 addConsoleActionF("fuelpumpbench2", fuelPumpBenchExt);
865
866 addConsoleActionFFF(CMD_FUEL_BENCH, fuelInjBench);
868
869 addConsoleActionFFF(CMD_SPARK_BENCH, sparkBench);
870 addConsoleActionFFFF("sparkbench2", sparkBenchExt);
871
873
874 addConsoleAction(CMD_AC_RELAY_BENCH, acRelayBench);
875
876 addConsoleAction(CMD_FAN_BENCH, fanBench);
877 addConsoleAction(CMD_FAN2_BENCH, fan2Bench);
878 addConsoleActionF("fanbench2", fanBenchExt);
879
880 addConsoleAction("mainrelaybench", mainRelayBench);
881
882#if EFI_CAN_SUPPORT
883#if EFI_WIDEBAND_FIRMWARE_UPDATE
884 addConsoleActionI("update_wideband", [](int hwIndex) { requestWidebandUpdate(hwIndex, false); });
885#endif // EFI_WIDEBAND_FIRMWARE_UPDATE
886 addConsoleActionII("set_wideband_index", [](int hwIndex, int index) { setWidebandOffset(hwIndex, index); });
887#endif // EFI_CAN_SUPPORT
888
889 addConsoleAction(CMD_STARTER_BENCH, starterRelayBench);
890 addConsoleAction(CMD_MIL_BENCH, milBench);
891 addConsoleAction(CMD_HPFP_BENCH, hpfpValveBench);
892
893#if EFI_CAN_SUPPORT
894 addConsoleActionI("ping_wideband", [](int index) {
895 pingWideband(index);
896 });
897#endif // EFI_CAN_SUPPORT
898
899#if EFI_LUA
900 // this commands facilitates TS Lua Button scripts development
901 addConsoleActionI("lua_button", [](int index) {
902 if (index < 0 || index > LUA_BUTTON_COUNT)
903 return;
904 luaCommandCounters[index - 1]++;
905 });
906 addConsoleActionFFFF("luabench2", [](float humanIndex, float onTime, float offTimeMs, float count) {
907 doRunBenchTestLuaOutput((int)humanIndex, onTime, offTimeMs, (int)count);
908 });
909#endif // EFI_LUA
910 instance.start();
912}
913
914#endif /* EFI_UNIT_TEST */
void jump_to_openblt()
void jump_to_bootloader()
int luaCommandCounters[LUA_BUTTON_COUNT]
static void processCanRequestCalibration(const CANRxFrame &frame)
static int globalCount
static float globalOnTimeMs
static scheduling_s benchSchedStart
void executeTSCommand(uint16_t subsystem, uint16_t index)
static void runBench(OutputPin *output, float onTimeMs, float offTimeMs, int count, bool swapOnOff)
static void sparkBenchExt(float humanIndex, float onTime, float offTimeMs, float count)
static volatile bool isBenchTestPending
int getSavedBenchTestPinStates(uint32_t durationsInStateMs[2])
void fanBench()
static void benchOff(OutputPin *output)
static void doRunFuelInjBench(size_t humanIndex, float onTimeMs, float offTimeMs, int count)
void milBench()
static bool widebandUpdateFromFile
static void handleCommandX14(uint16_t index)
static void doRunSolenoidBench(size_t humanIndex, float onTime, float offTime, int count)
static void sparkBench(float onTime, float offTimeMs, float count)
void processCanEcuControl(const CANRxFrame &frame)
std::optional< setup_custom_board_ts_command_override_type > custom_board_ts_command
static void processCanSetCalibration(const CANRxFrame &frame)
static void cancelBenchTest()
static void fanBenchExt(float onTimeMs)
static void doRunSparkBench(size_t humanIndex, float onTime, float offTime, int count)
static uint8_t widebandUpdateHwId
static void pinbench(float ontimeMs, float offtimeMs, int iterations, OutputPin *pinParam, bool p_swapOnOff=false)
void starterRelayBench()
void initBenchTest()
static bool isRunningBench
static chibios_rt::CounterSemaphore benchSemaphore(0)
static void hdAcrBench(int index)
static void hpfpValveBench()
void boardTsAction(uint16_t index)
void onConfigurationChangeBenchTest()
static float globalOffTimeMs
bool isRunningBenchTest()
static void mainRelayBench()
static void doRunBenchTestLuaOutput(size_t humanIndex, float onTimeMs, float offTimeMs, int count)
static uint32_t savedDurationsInStateMs[2]
static void auxOutBench(int index)
static OutputPin * outputOnTheBenchTest
bool rebootForPresetPending
const OutputPin * getOutputOnTheBenchTest()
void fan2Bench()
static bool widebandUpdatePending
static void fuelInjBench(float onTimeMs, float offTimeMs, float count)
void fuelPumpBench()
static bool swapOnOff
static void processCanUserControl(const CANRxFrame &frame)
static void fuelInjBenchExt(float humanIndex, float onTimeMs, float offTimeMs, float count)
void acRelayBench()
void handleBenchCategory(uint16_t index)
static OutputPin * pinX
static int savedPinToggleCounter
static void requestWidebandUpdate(int hwIndex, bool fromFile)
static scheduling_s benchSchedEnd
static void vvtValveBench(int vvtIndex)
static void tcuSolenoidBench(float humanIndex, float onTime, float offTimeMs, float count)
static void benchOn(OutputPin *output)
static BenchController instance
static void fuelPumpBenchExt(float durationMs)
static void applyPreset(int index)
Utility methods related to bench testing.
uint16_t getTwoBytesLsb(const CANRxFrame &frame, int offset)
Definition can_rx.cpp:150
uint32_t getFourBytesLsb(const CANRxFrame &frame, int offset)
Definition can_rx.cpp:143
bool etbAutoTune
Definition engine.h:304
bool etbIgnoreJamProtection
Definition engine.h:305
SingleTimerExecutor scheduler
Definition engine.h:279
RpmCalculator rpmCalculator
Definition engine.h:314
TunerStudioOutputChannels outputChannels
Definition engine.h:113
RegisteredOutputPin harleyAcr2
Definition efi_gpio.h:96
RegisteredNamedOutputPin harleyAcr
Definition efi_gpio.h:95
RegisteredOutputPin mainRelay
Definition efi_gpio.h:76
OutputPin tcuSolenoids[TCU_SOLENOID_COUNT]
Definition efi_gpio.h:132
RegisteredOutputPin fanRelay
Definition efi_gpio.h:86
RegisteredOutputPin starterControl
Definition efi_gpio.h:82
OutputPin luaOutputPins[LUA_PWM_COUNT]
Definition efi_gpio.h:100
RegisteredOutputPin fanRelay2
Definition efi_gpio.h:87
InjectorOutputPin injectors[MAX_CYLINDER_COUNT]
Definition efi_gpio.h:127
RegisteredOutputPin fuelPumpRelay
Definition efi_gpio.h:91
RegisteredOutputPin acRelay
Definition efi_gpio.h:90
IgnitionOutputPin coils[MAX_CYLINDER_COUNT]
Definition efi_gpio.h:129
RegisteredOutputPin checkEnginePin
Definition efi_gpio.h:118
RegisteredNamedOutputPin hpfpValve
Definition efi_gpio.h:80
Single output pin reference and state.
Definition efi_output.h:49
brain_pin_diag_e getDiag() const
Definition efi_gpio.cpp:679
uint32_t durationsInStateMs[2]
Definition efi_output.h:81
void setValue(const char *msg, int logicValue, bool isForce=false)
Definition efi_gpio.cpp:605
int pinToggleCounter
Definition efi_output.h:76
brain_pin_e brainPin
Definition efi_output.h:86
bool isStopped() const override
void schedule(const char *msg, scheduling_s *scheduling, efitick_t timeNt, action_s const &action) override
Schedule an action to be executed in the future.
A base class for a controller that requires its own thread.
virtual void ThreadTask()=0
void addConsoleActionF(const char *token, VoidFloat callback)
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
void addConsoleActionII(const char *token, VoidIntInt callback)
Register a console command with two Integer parameters.
void addConsoleActionI(const char *token, VoidInt callback)
Register a console command with one Integer parameter.
void addConsoleActionFFFF(const char *token, VoidFloatFloatFloatFloat callback)
void addConsoleActionFFF(const char *token, VoidFloatFloatFloat callback)
EnginePins enginePins
Definition efi_gpio.cpp:24
efitick_t getTimeNowNt()
Definition efitime.cpp:19
void etbBenchTestStart(size_t throttleIndex)
void etbAutocal(dc_function_e function, bool reportToTs)
static EngineAccessor engine
Definition engine.h:415
static constexpr engine_configuration_s * engineConfiguration
debug_mode_e
@ TS_GRAB_TPS_CLOSED
@ TS_TRIGGER_STIMULATOR_ENABLE
@ TS_ETB_STOP_AUTOTUNE
@ TS_WRITE_FLASH
@ TS_ETB_DISABLE_JAM_DETECT
@ TS_SD_FORMAT
@ TS_ESTIMATE_TORQUE_TABLE
@ TS_SD_MOUNT_PC
@ TS_WIDEBAND_UPDATE_FILE
@ TS_GRAB_PEDAL_UP
@ TS_ETB_AUTOCAL_0_FAST
@ TS_START_STOP_ENGINE
@ TS_SD_UNMOUNT
@ TS_ETB_AUTOCAL_0
@ TS_RESET_TLE8888
@ TS_ETB_AUTOCAL_1
@ TS_TCU_UPSHIFT_REQUEST
@ TS_TRIGGER_STIMULATOR_DISABLE
@ TS_SD_MOUNT_ECU
@ TS_RESET_MC33810
@ TS_ETB_BENCH_TEST_1
@ TS_ETB_BENCH_TEST_0
@ TS_EWG_AUTOCAL_0_FAST
@ TS_TCU_DOWNSHIFT_REQUEST
@ TS_EWG_AUTOCAL_0
@ TS_ETB_START_AUTOTUNE
@ TS_GRAB_PEDAL_WOT
@ TS_GRAB_TPS_OPEN
@ TS_SD_DELETE_REPORTS
@ COMMAND_X14_UNUSED_15
@ TS_ETB_AUTOCAL_1_FAST
@ TS_SET_STEPPER_IDLE
@ TS_EXTERNAL_TRIGGER_STIMULATOR_ENABLE
@ TS_WIDEBAND_UPDATE
@ LUA_COMMAND_3
@ BENCH_AC_COMPRESSOR_RELAY
@ LUA_COMMAND_2
@ BENCH_FAN_RELAY
@ BENCH_CANCEL
@ BENCH_VVT0_VALVE
@ BENCH_AUXOUT4
@ BENCH_AUXOUT2
@ LUA_COMMAND_1
@ BENCH_MAIN_RELAY
@ BENCH_AUXOUT7
@ HD_ACR2
@ BENCH_IDLE_VALVE
@ LTFT_APPLY_TO_VE
@ LTFT_DEV_POKE
@ HD_ACR
@ BENCH_AUXOUT3
@ BENCH_CHECK_ENGINE_LIGHT
@ BENCH_VVT3_VALVE
@ BENCH_AUXOUT5
@ LUA_COMMAND_4
@ BENCH_AUXOUT1
@ BENCH_VVT1_VALVE
@ BENCH_AUXOUT0
@ BENCH_FAN_RELAY_2
@ LTFT_RESET
@ BENCH_HPFP_VALVE
@ BENCH_FUEL_PUMP
@ BENCH_AUXOUT6
@ BENCH_STARTER_ENABLE_RELAY
@ BENCH_VVT2_VALVE
@ TS_WIDEBAND_SET_IDX_BY_ID
@ TS_WIDEBAND
@ TS_CLEAR_WARNINGS
@ TS_BOARD_ACTION
@ TS_SOLENOID_CATEGORY
@ TS_LUA_OUTPUT_CATEGORY
@ TS_DEBUG_MODE
@ TS_WIDEBAND_RESTART
@ TS_WIDEBAND_FLASH_BY_ID_FILE
@ TS_SET_ENGINE_TYPE
@ TS_X14
@ TS_IGNITION_CATEGORY
@ TS_BENCH_CATEGORY
@ TS_WIDEBAND_SET_SENS_BY_ID
@ TS_WIDEBAND_PING_BY_ID
@ TS_WIDEBAND_FLASH_BY_ID
@ TS_SET_DEFAULT_ENGINE
@ TS_INJECTOR_CATEGORY
@ TS_STOP_ENGINE
void firmwareError(ObdCode code, const char *fmt,...)
void writeToFlashNow()
void setStepperHw()
Definition gm_sbc.cpp:15
void startIdleBench(void)
UNUSED(samplingTimeSeconds)
void applyLongTermFuelTrimToVe()
void resetLongTermFuelTrim()
void devPokeLongTermFuelTrim()
Main logic header.
void clearWarnings(void)
This data structure holds current malfunction codes.
void mc33810_req_init()
Definition mc33810.cpp:999
void sdCardRemoveReportFiles()
void sdCardRequestMode(SD_MODE mode)
@ SD_MODE_UNMOUNT
Definition mmc_card.h:21
@ SD_MODE_PC
Definition mmc_card.h:20
@ SD_MODE_ECU
Definition mmc_card.h:19
@ SD_MODE_FORMAT
Definition mmc_card.h:22
@ STACK_USAGE_MISC
@ CUSTOM_ERR_BENCH_PARAM
void pinDiag2string(char *buffer, size_t size, brain_pin_diag_e pin_diag)
const char * hwPortname(brain_pin_e brainPin)
void rebootNow()
Definition rusefi.cpp:150
brain_pin_diag_e
void updateWidebandFirmwareFromFile(uint8_t hwIndex)
void setWidebandSensorType(uint8_t hwIndex, uint8_t type)
void pingWideband(uint8_t hwIndex)
void setWidebandOffset(uint8_t hwIndex, uint8_t index)
void restartWideband()
void updateWidebandFirmware(uint8_t hwIndex)
running("running", SensorCategory.SENSOR_INPUTS, FieldType.INT, 888, 1.0, -1.0, -1.0, "")
void setEngineType(int value, bool isWriteToFlash)
Definition settings.cpp:739
void doScheduleStopEngine(StopRequestedReason reason)
void startStopButtonToggle()
brain_pin_e pin
Definition stm32_adc.cpp:15
uint8_t data8[8]
Frame data.
Definition can_mocks.h:55
void tle8888_req_init()
Definition tle8888.cpp:1272
void estimateTorqueTable()
void grabPedalIsUp()
Definition tps.cpp:31
void grapTps1PrimaryIsClosed()
Definition tps.cpp:45
void grapTps1PrimaryIsOpen()
Definition tps.cpp:50
void grabPedalIsWideOpen()
Definition tps.cpp:39
void disableTriggerStimulator()
void enableExternalTriggerStimulator()
void enableTriggerStimulator(bool incGlobalConfiguration)
void onApplyPreset()
uint16_t count
Definition tunerstudio.h:1
maintainConstantValue implementation header
float getConfigValueByHash(const int hash)
OutputPin * getVvtOutputPin(int index)
Definition vvt.cpp:153