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;
567 engine->etbAutoTune = true;
568 return;
570 engine->etbAutoTune = false;
571 #if EFI_TUNER_STUDIO
573 #endif // EFI_TUNER_STUDIO
574 return;
577 return;
578 case TS_EWG_AUTOCAL_0:
579 etbAutocal(DC_Wastegate);
580 return;
582 etbAutocal(DC_Wastegate, false);
583 return;
584#endif // EFI_ELECTRONIC_THROTTLE_BODY
587 // broadcast, for old WBO FWs
589 return;
593 return;
595 return;
596
597#if EFI_PROD_CODE && EFI_FILE_LOGGING
598 case TS_SD_MOUNT_PC:
600 return;
601 case TS_SD_MOUNT_ECU:
603 return;
604 case TS_SD_UNMOUNT:
606 return;
607 case TS_SD_FORMAT:
609 return;
612 return;
613#endif // EFI_FILE_LOGGING
614
615 default:
616 criticalError("Unexpected bench x14 %d", index);
617 }
618}
619
620extern bool rebootForPresetPending;
621
622static void applyPreset(int index) {
623 setEngineType(index);
624#if EFI_TUNER_STUDIO
626#endif // EFI_TUNER_STUDIO
627}
628
629// placeholder to force custom_board_ts_command migration
630void boardTsAction(uint16_t index) { UNUSED(index); }
631
632#if EFI_CAN_SUPPORT
633/**
634 * for example to bench test injector 1
635 * 0x77000C 0x66 0x00 ?? ?? ?? ??
636 * 0x77000C 0x66 0x00 0x14 0x00 0x09 0x00 start/stop engine
637 *
638 * See also more complicated ISO-TP CANBus wrapper of complete TS protocol
639 */
640static void processCanUserControl(const CANRxFrame& frame) {
641 // reserved data8[1]
642 uint16_t subsystem = getTwoBytesLsb(frame, 2);
643 uint16_t index = getTwoBytesLsb(frame, 4);
644 executeTSCommand(subsystem, index);
645}
646
647 union FloatIntBytes {
648 float f;
649 int i;
650 uint8_t bytes[sizeof(float)];
651 };
652
653static void processCanSetCalibration(const CANRxFrame& frame) {
654 // todo allow changes of scalar settings via CANbus
655 UNUSED(frame);
656}
657/**
658 * CANbus protocol to query scalar calibrations using hash keys
659 *
660 * see fields_api.txt for well-known fields
661 * see generated_fields_api_header.h for corresponding hashes
662 */
663static void processCanRequestCalibration(const CANRxFrame& frame) {
664#if EFI_LUA_LOOKUP
665 int hash = getFourBytesLsb(frame, 2);
666 efiPrintf("processCanRequestCalibration=%x", hash);
667 FloatIntBytes fb;
668 fb.f = getConfigValueByHash(hash);
669
670 CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::ECU_GET_CALIBRATION, 8, /*bus*/0, /*isExtended*/true);
671 for (size_t i = 0;i<sizeof(float);i++) {
672 msg[4 + i] = fb.bytes[i];
673 }
674
675 fb.i = hash;
676 // first half of the packed is copy of that hash value so that recipients know what they are processing
677 for (size_t i = 0;i<sizeof(float);i++) {
678 msg[i] = fb.bytes[i];
679 }
680#endif // EFI_LUA_LOOKUP
681}
682
684 if (frame.data8[0] != (int)bench_test_magic_numbers_e::BENCH_HEADER) {
685 return;
686 }
687
688 int eid = CAN_EID(frame);
689 if (eid == (int)bench_test_packet_ids_e::ECU_SET_CALIBRATION) {
691 } else if (eid == (int)bench_test_packet_ids_e::ECU_REQ_CALIBRATION) {
693 } else if (eid == (int)bench_test_packet_ids_e::ECU_CAN_BUS_USER_CONTROL) {
695 }
696}
697
698#endif // EFI_CAN_SUPPORT
699
700std::optional<setup_custom_board_ts_command_override_type> custom_board_ts_command;
701
702void executeTSCommand(uint16_t subsystem, uint16_t index) {
703 efiPrintf("IO test subsystem=%d index=%d", subsystem, index);
704
706
707 switch (subsystem) {
710 break;
711
712 case TS_DEBUG_MODE:
714 break;
715
717 if (!running) {
720 }
721 break;
722
724 if (!running) {
727 }
728 break;
729
731 if (!running) {
732 doRunSolenoidBench(index, 1000.0,
734 }
735 break;
736
738 if (!running) {
739 doRunBenchTestLuaOutput(index, 4.0,
741 }
742 break;
743
744 case TS_X14:
745 handleCommandX14(index);
746 break;
747#if EFI_CAN_SUPPORT
748 case TS_WIDEBAND:
749 setWidebandOffset(0xff, index);
750 break;
752 {
753 uint8_t hwIndex = index >> 8;
754 uint8_t canIndex = index & 0xff;
755
756 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
757 // TODO:
758 hwIndex = hwIndex < 8 ? hwIndex : 0xff;
759 setWidebandOffset(hwIndex, canIndex);
760 }
761 break;
763 {
764 uint8_t hwIndex = index >> 8;
765 uint8_t sensType = index & 0xff;
766
767 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
768 // TODO:
769 hwIndex = hwIndex < 8 ? hwIndex : 0xff;
770 setWidebandSensorType(hwIndex, sensType);
771 }
772 break;
774 pingWideband(index >> 8);
775 break;
776
779 {
780 uint8_t hwIndex = index >> 8;
781
782 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
783 // TODO:
784 widebandUpdateHwId = hwIndex < 8 ? hwIndex : 0xff;
786 }
787 break;
788
791 break;
792
793#endif // EFI_CAN_SUPPORT
795 handleBenchCategory(index);
796 break;
797
799 applyPreset(index);
800 break;
801
802 case TS_BOARD_ACTION:
803 // TODO: use call_board_override
804 if (custom_board_ts_command.has_value()) {
805 custom_board_ts_command.value()(subsystem, index);
806 }
807 break;
808
810 applyPreset((int)DEFAULT_ENGINE_TYPE);
811 break;
812
813 case TS_STOP_ENGINE:
815 break;
816
817 case 0xba:
818#if EFI_PROD_CODE && EFI_DFU_JUMP
820#endif /* EFI_DFU_JUMP */
821 break;
822
823 case REBOOT_COMMAND:
824#if EFI_PROD_CODE
825 rebootNow();
826#endif /* EFI_PROD_CODE */
827 break;
828
829#if EFI_USE_OPENBLT
830 case 0xbc:
831 /* Jump to OpenBLT if present */
833 break;
834#endif
835
836 default:
837 criticalError("Unexpected bench subsystem %d %d", subsystem, index);
838 }
839}
840
842 // default values if configuration was not specified
845 }
846
849 }
850
853 }
854}
855
857 addConsoleAction("fuelpumpbench", fuelPumpBench);
858 addConsoleActionF("fuelpumpbench2", fuelPumpBenchExt);
859
860 addConsoleActionFFF(CMD_FUEL_BENCH, fuelInjBench);
862
863 addConsoleActionFFF(CMD_SPARK_BENCH, sparkBench);
864 addConsoleActionFFFF("sparkbench2", sparkBenchExt);
865
867
868 addConsoleAction(CMD_AC_RELAY_BENCH, acRelayBench);
869
870 addConsoleAction(CMD_FAN_BENCH, fanBench);
871 addConsoleAction(CMD_FAN2_BENCH, fan2Bench);
872 addConsoleActionF("fanbench2", fanBenchExt);
873
874 addConsoleAction("mainrelaybench", mainRelayBench);
875
876#if EFI_CAN_SUPPORT
877#if EFI_WIDEBAND_FIRMWARE_UPDATE
878 addConsoleActionI("update_wideband", [](int hwIndex) { requestWidebandUpdate(hwIndex, false); });
879#endif // EFI_WIDEBAND_FIRMWARE_UPDATE
880 addConsoleActionII("set_wideband_index", [](int hwIndex, int index) { setWidebandOffset(hwIndex, index); });
881#endif // EFI_CAN_SUPPORT
882
883 addConsoleAction(CMD_STARTER_BENCH, starterRelayBench);
884 addConsoleAction(CMD_MIL_BENCH, milBench);
885 addConsoleAction(CMD_HPFP_BENCH, hpfpValveBench);
886
887#if EFI_CAN_SUPPORT
888 addConsoleActionI("ping_wideband", [](int index) {
889 pingWideband(index);
890 });
891#endif // EFI_CAN_SUPPORT
892
893#if EFI_LUA
894 // this commands facilitates TS Lua Button scripts development
895 addConsoleActionI("lua_button", [](int index) {
896 if (index < 0 || index > LUA_BUTTON_COUNT)
897 return;
898 luaCommandCounters[index - 1]++;
899 });
900 addConsoleActionFFFF("luabench2", [](float humanIndex, float onTime, float offTimeMs, float count) {
901 doRunBenchTestLuaOutput((int)humanIndex, onTime, offTimeMs, (int)count);
902 });
903#endif // EFI_LUA
904 instance.start();
906}
907
908#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:678
uint32_t durationsInStateMs[2]
Definition efi_output.h:81
void setValue(const char *msg, int logicValue, bool isForce=false)
Definition efi_gpio.cpp:604
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 etbAutocal(dc_function_e function, bool reportToTs)
static EngineAccessor engine
Definition engine.h:421
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_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