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 "value_lookup.h"
30#include "can_msg_tx.h"
31#include "gm_sbc.h" // setStepperHw
32
33#include "fw_configuration.h"
34#include "board_overrides.h"
35
36static bool isRunningBench = false;
38
40 return isRunningBench;
41}
42
46
47#if !EFI_UNIT_TEST
48
49#include "flash_main.h"
50#include "bench_test.h"
53#include "electronic_throttle.h"
55#include "malfunction_central.h"
57#include "vvt.h"
58#include "microsecond_timer.h"
59#include "rusefi_wideband.h"
60
61#if EFI_PROD_CODE
62#include "rusefi.h"
63#include "mpu_util.h"
64#endif /* EFI_PROD_CODE */
65
66#if (BOARD_TLE8888_COUNT > 0)
67#include "gpio/tle8888.h"
68#endif // BOARD_TLE8888_COUNT
69
70#if EFI_FILE_LOGGING
71#include "mmc_card.h"
72#endif
73
76
77#if EFI_SIMULATOR
78static int savedPinToggleCounter = 0;
79static uint32_t savedDurationsInStateMs[2] = { 0, 0 };
80#endif // EFI_SIMULATOR
81
82
83#define BENCH_MSG "bench"
84
85static void benchOn(OutputPin* output) {
86 output->setValue(BENCH_MSG, true, /*isForce*/ true);
87}
88
89static void benchOff(OutputPin* output) {
90#if EFI_PROD_CODE && (BOARD_EXT_GPIOCHIPS > 0)
91 static char pin_error[64];
92
93 brain_pin_diag_e diag = output->getDiag();
94 if (diag == PIN_UNKNOWN) {
95 efiPrintf("No Diag on this pin");
96 } else {
97 pinDiag2string(pin_error, sizeof(pin_error), diag);
98 efiPrintf("Diag says %s", pin_error);
99 }
100#endif // EFI_PROD_CODE
101 output->setValue(BENCH_MSG, false, /*isForce*/ true);
102}
103
104static void runBench(OutputPin *output, float onTimeMs, float offTimeMs, int count, bool swapOnOff) {
105 int onTimeUs = MS2US(std::max(0.1f, onTimeMs));
106 int offTimeUs = MS2US(std::max(0.1f, offTimeMs));
107
108 if (onTimeUs > TOO_FAR_INTO_FUTURE_US) {
109 firmwareError(ObdCode::CUSTOM_ERR_BENCH_PARAM, "onTime above limit %dus", TOO_FAR_INTO_FUTURE_US);
110 return;
111 }
112
113 efiPrintf("Running bench: ON_TIME=%d us OFF_TIME=%d us Counter=%d", onTimeUs, offTimeUs, count);
114 efiPrintf("output on %s", hwPortname(output->brainPin));
115
116 isRunningBench = true;
117 outputOnTheBenchTest = output;
118
119 for (int i = 0; isRunningBench && i < count; i++) {
121 efitick_t nowNt = getTimeNowNt();
122 // start in a short time so the scheduler can precisely schedule the start event
123 efitick_t startTime = nowNt + US2NT(50);
124 efitick_t endTime = startTime + US2NT(onTimeUs);
125
126 auto const bstartAction{ swapOnOff ? action_s::make<benchOff>(output) : action_s::make<benchOn>(output) };
127 auto const bendAction{ swapOnOff ? action_s::make<benchOn>(output) : action_s::make<benchOff>(output) };
128
129 // Schedule both events
130 engine->scheduler.schedule("bstart", &benchSchedStart, startTime, bstartAction);
131 engine->scheduler.schedule("bend", &benchSchedEnd, endTime, bendAction);
132
133 // Wait one full cycle time for the event + delay to happen
134 chThdSleepMicroseconds(onTimeUs + offTimeUs);
135 }
136 /* last */
138
139#if EFI_SIMULATOR
140 // save the current counters and durations after the test while the pin is still controlled
144#endif // EFI_SIMULATOR
145
146 efiPrintf("Done!");
147 outputOnTheBenchTest = nullptr;
148 isRunningBench = false;
149}
150
151// todo: migrate to smarter getOutputOnTheBenchTest() approach?
152static volatile bool isBenchTestPending = false;
153static bool widebandUpdatePending = false;
154static bool widebandUpdateFromFile = false;
155static uint8_t widebandUpdateHwId = 0;
156static float globalOnTimeMs;
157static float globalOffTimeMs;
158static int globalCount;
160static bool swapOnOff = false;
161
162static chibios_rt::CounterSemaphore benchSemaphore(0);
163
164static void pinbench(float ontimeMs, float offtimeMs, int iterations,
165 OutputPin* pinParam, bool p_swapOnOff = false)
166{
167 globalOnTimeMs = ontimeMs;
168 globalOffTimeMs = offtimeMs;
169#if EFI_SIMULATOR
170 globalCount = maxI(2, iterations);
171#else
172 globalCount = iterations;
173#endif // EFI_SIMULATOR
174 pinX = pinParam;
175 swapOnOff = p_swapOnOff;
176 // let's signal bench thread to wake up
177 isBenchTestPending = true;
178 benchSemaphore.signal();
179}
180
181static void cancelBenchTest() {
182 isRunningBench = false;
183}
184
185static void doRunFuelInjBench(size_t humanIndex, float onTimeMs, float offTimeMs, int count) {
186 if (humanIndex < 1 || humanIndex > engineConfiguration->cylindersCount) {
187 efiPrintf("Invalid index: %d", humanIndex);
188 return;
189 }
190 pinbench(onTimeMs, offTimeMs, count,
191 &enginePins.injectors[humanIndex - 1]);
192}
193
194static void doRunSparkBench(size_t humanIndex, float onTime, float offTime, int count) {
195 if (humanIndex < 1 || humanIndex > engineConfiguration->cylindersCount) {
196 efiPrintf("Invalid index: %d", humanIndex);
197 return;
198 }
199 pinbench(onTime, offTime, count, &enginePins.coils[humanIndex - 1]);
200}
201
202static void doRunSolenoidBench(size_t humanIndex, float onTime, float offTime, int count) {
203 if (humanIndex < 1 || humanIndex > TCU_SOLENOID_COUNT) {
204 efiPrintf("Invalid index: %d", humanIndex);
205 return;
206 }
207 pinbench(onTime, offTime, count, &enginePins.tcuSolenoids[humanIndex - 1]);
208}
209
210static void doRunBenchTestLuaOutput(size_t humanIndex, float onTimeMs, float offTimeMs, int count) {
211 if (humanIndex < 1 || humanIndex > LUA_PWM_COUNT) {
212 efiPrintf("Invalid index: %d", humanIndex);
213 return;
214 }
215 pinbench(onTimeMs, offTimeMs, count,
216 &enginePins.luaOutputPins[humanIndex - 1]);
217}
218
219/**
220 * cylinder #2, 5ms ON, 1000ms OFF, repeat 3 times
221 * fuelInjBenchExt 2 5 1000 3
222 */
223static void fuelInjBenchExt(float humanIndex, float onTimeMs, float offTimeMs, float count) {
224 doRunFuelInjBench((int)humanIndex, onTimeMs, offTimeMs, (int)count);
225}
226
227/**
228 * fuelbench 5 1000 2
229 */
230static void fuelInjBench(float onTimeMs, float offTimeMs, float count) {
231 fuelInjBenchExt(1, onTimeMs, offTimeMs, count);
232}
233
234/**
235 * sparkbench2 1 5 1000 2
236 */
237static void sparkBenchExt(float humanIndex, float onTime, float offTimeMs, float count) {
238 doRunSparkBench((int)humanIndex, onTime, offTimeMs, (int)count);
239}
240
241/**
242 * sparkbench 5 400 2
243 * 5 ms ON, 400 ms OFF, two times
244 */
245static void sparkBench(float onTime, float offTimeMs, float count) {
246 sparkBenchExt(1, onTime, offTimeMs, count);
247}
248
249/**
250 * solenoid #2, 1000ms ON, 1000ms OFF, repeat 3 times
251 * tcusolbench 2 1000 1000 3
252 */
253static void tcuSolenoidBench(float humanIndex, float onTime, float offTimeMs, float count) {
254 doRunSolenoidBench((int)humanIndex, onTime, offTimeMs, (int)count);
255}
256
257static void fanBenchExt(float onTimeMs) {
258 pinbench(onTimeMs, 100.0, 1, &enginePins.fanRelay);
259}
260
261void fanBench() {
262 fanBenchExt(BENCH_FAN_DURATION);
263}
264
265void fan2Bench() {
266 pinbench(3000.0, 100.0, 1, &enginePins.fanRelay2);
267}
268
269/**
270 * we are blinking for 16 seconds so that one can click the button and walk around to see the light blinking
271 */
272void milBench() {
273 pinbench(500.0, 500.0, 16, &enginePins.checkEnginePin);
274}
275
277 pinbench(BENCH_STARTER_DURATION, 100.0, 1, &enginePins.starterControl);
278}
279
280static void fuelPumpBenchExt(float durationMs) {
281 pinbench(durationMs, 100.0, 1,
283}
284
286 pinbench(BENCH_AC_RELAY_DURATION, 100.0, 1, &enginePins.acRelay);
287}
288
289static void mainRelayBench() {
290 pinbench(BENCH_MAIN_RELAY_DURATION, 100.0, 1, &enginePins.mainRelay, true);
291}
292
297
299 fuelPumpBenchExt(BENCH_FUEL_PUMP_DURATION);
300}
301
302static void vvtValveBench(int vvtIndex) {
303#if EFI_VVT_PID
304 pinbench(BENCH_VVT_DURATION, 100.0, 1, getVvtOutputPin(vvtIndex));
305#endif // EFI_VVT_PID
306}
307
308static void requestWidebandUpdate(int hwIndex, bool fromFile)
309{
310 widebandUpdateHwId = hwIndex;
311 widebandUpdateFromFile = fromFile;
313 benchSemaphore.signal();
314}
315
316class BenchController : public ThreadController<4 * UTILITY_THREAD_STACK_SIZE> {
317public:
318 BenchController() : ThreadController("BenchTest", PRIO_BENCH_TEST) { }
319private:
320 void ThreadTask() override {
321 while (true) {
322 benchSemaphore.wait();
323
324 assertStackVoid("Bench", ObdCode::STACK_USAGE_MISC, EXPECTED_REMAINING_STACK);
325
326 if (isBenchTestPending) {
327 isBenchTestPending = false;
329 }
330
332 #if EFI_WIDEBAND_FIRMWARE_UPDATE && EFI_CAN_SUPPORT
334 #if EFI_PROD_CODE
336 #endif
337 } else {
339 }
340 #endif
341 widebandUpdatePending = false;
342 }
343 }
344 }
345};
346
347static BenchController instance;
348
349static void auxOutBench(int index) {
350 // todo!
351 UNUSED(index);
352}
353
354#if EFI_HD_ACR
355static void hdAcrBench(int index) {
357 pinbench(BENCH_AC_RELAY_DURATION, 100.0, 1, pin);
358}
359#endif // EFI_HD_ACR
360
361int luaCommandCounters[LUA_BUTTON_COUNT] = {};
362
363void handleBenchCategory(uint16_t index) {
364 switch(index) {
365 case BENCH_VVT0_VALVE:
366 vvtValveBench(0);
367 return;
368 case BENCH_VVT1_VALVE:
369 vvtValveBench(1);
370 return;
371 case BENCH_VVT2_VALVE:
372 vvtValveBench(2);
373 return;
374 case BENCH_VVT3_VALVE:
375 vvtValveBench(3);
376 return;
377 case BENCH_AUXOUT0:
378 auxOutBench(0);
379 return;
380 case BENCH_AUXOUT1:
381 auxOutBench(1);
382 return;
383 case BENCH_AUXOUT2:
384 auxOutBench(2);
385 return;
386 case BENCH_AUXOUT3:
387 auxOutBench(3);
388 return;
389 case BENCH_AUXOUT4:
390 auxOutBench(4);
391 return;
392 case BENCH_AUXOUT5:
393 auxOutBench(5);
394 return;
395 case BENCH_AUXOUT6:
396 auxOutBench(6);
397 return;
398 case BENCH_AUXOUT7:
399 auxOutBench(7);
400 return;
401 case LUA_COMMAND_1:
403 return;
404 case LUA_COMMAND_2:
406 return;
407 case LUA_COMMAND_3:
409 return;
410 case LUA_COMMAND_4:
412 return;
413#if EFI_LTFT_CONTROL
414 case LTFT_RESET:
416 return;
417 case LTFT_APPLY_TO_VE:
419 return;
420 case LTFT_DEV_POKE:
422 return;
423#endif // EFI_LTFT_CONTROL
424#if EFI_HD_ACR
425 case HD_ACR:
426 hdAcrBench(0);
427 return;
428 case HD_ACR2:
429 hdAcrBench(1);
430 return;
431#endif // EFI_HD_ACR
432 case BENCH_HPFP_VALVE:
434 return;
435 case BENCH_FUEL_PUMP:
436 // cmd_test_fuel_pump
438 return;
439 case BENCH_MAIN_RELAY:
441 return;
444 return;
446 // cmd_test_check_engine_light
447 milBench();
448 return;
450 acRelayBench();
451 return;
452 case BENCH_FAN_RELAY:
453 fanBench();
454 return;
455 case BENCH_IDLE_VALVE:
456 // cmd_test_idle_valve
457#if EFI_IDLE_CONTROL
459#endif /* EFI_IDLE_CONTROL */
460 return;
462 fan2Bench();
463 return;
464 case BENCH_CANCEL:
466 return;
467 default:
468 criticalError("Unexpected bench function %d", index);
469 }
470}
471
472int getSavedBenchTestPinStates(uint32_t durationsInStateMs[2]) {
473#if EFI_SIMULATOR
474 durationsInStateMs[0] = savedDurationsInStateMs[0];
475 durationsInStateMs[1] = savedDurationsInStateMs[1];
477#else
478 UNUSED(durationsInStateMs);
479 return 0;
480#endif // EFI_SIMULATOR
481}
482
483static void handleCommandX14(uint16_t index) {
484 switch (index) {
486 setStepperHw();
488 return;
489 case TS_GRAB_PEDAL_UP:
491 return;
494 return;
497 return;
498 case TS_GRAB_TPS_OPEN:
500 return;
501 case TS_RESET_TLE8888:
502 #if (BOARD_TLE8888_COUNT > 0)
504 #endif
505 return;
508 // do nothing, we are catching with Lua
509 // this is temporary uaDASH API
510 return;
511 case TS_RESET_MC33810:
512 #if EFI_PROD_CODE && (BOARD_MC33810_COUNT > 0)
514 #endif
515 return;
516#if EFI_SHAFT_POSITION_INPUT
518 // this is different from starter relay bench test!
520 return;
521#endif // EFI_SHAFT_POSITION_INPUT
522 case TS_WRITE_FLASH:
523 // cmd_write_config
524 #if EFI_CONFIGURATION_STORAGE
526 #endif /* EFI_CONFIGURATION_STORAGE */
527 return;
529 #if EFI_EMULATE_POSITION_SENSORS == TRUE
531 #endif /* EFI_EMULATE_POSITION_SENSORS == TRUE */
532 return;
534 #if EFI_EMULATE_POSITION_SENSORS == TRUE
536 #endif /* EFI_EMULATE_POSITION_SENSORS == TRUE */
537 return;
539 #if EFI_EMULATE_POSITION_SENSORS == TRUE
541 #endif /* EFI_EMULATE_POSITION_SENSORS == TRUE */
542 return;
543/*
544 case TS_ETB_RESET:
545 #if EFI_ELECTRONIC_THROTTLE_BODY == TRUE
546 #if EFI_PROD_CODE
547 etbPidReset();
548 #endif
549 #endif // EFI_ELECTRONIC_THROTTLE_BODY
550 return;
551*/
552#if EFI_ELECTRONIC_THROTTLE_BODY
553 case TS_ETB_AUTOCAL_0:
554 etbAutocal(DC_Throttle1);
555 return;
556 case TS_ETB_AUTOCAL_1:
557 etbAutocal(DC_Throttle2);
558 return;
560 etbAutocal(DC_Throttle1, false);
561 return;
563 etbAutocal(DC_Throttle2, false);
564 return;
566 engine->etbAutoTune = true;
567 return;
569 engine->etbAutoTune = false;
570 #if EFI_TUNER_STUDIO
572 #endif // EFI_TUNER_STUDIO
573 return;
576 return;
577 case TS_EWG_AUTOCAL_0:
578 etbAutocal(DC_Wastegate);
579 return;
581 etbAutocal(DC_Wastegate, false);
582 return;
583#endif // EFI_ELECTRONIC_THROTTLE_BODY
586 // broadcast, for old WBO FWs
588 return;
590 return;
591
592#if EFI_PROD_CODE && EFI_FILE_LOGGING
593 case TS_SD_MOUNT_PC:
595 return;
596 case TS_SD_MOUNT_ECU:
598 return;
599 case TS_SD_UNMOUNT:
601 return;
602 case TS_SD_FORMAT:
604 return;
607 return;
608#endif // EFI_FILE_LOGGING
609
610 default:
611 criticalError("Unexpected bench x14 %d", index);
612 }
613}
614
615extern bool rebootForPresetPending;
616
617static void applyPreset(int index) {
618 setEngineType(index);
619#if EFI_TUNER_STUDIO
621#endif // EFI_TUNER_STUDIO
622}
623
624// placeholder to force custom_board_ts_command migration
625void boardTsAction(uint16_t index) { UNUSED(index); }
626
627#if EFI_CAN_SUPPORT
628/**
629 * for example to bench test injector 1
630 * 0x77000C 0x66 0x00 ?? ?? ?? ??
631 * 0x77000C 0x66 0x00 0x14 0x00 0x09 0x00 start/stop engine
632 *
633 * See also more complicated ISO-TP CANBus wrapper of complete TS protocol
634 */
635static void processCanUserControl(const CANRxFrame& frame) {
636 // reserved data8[1]
637 uint16_t subsystem = getTwoBytesLsb(frame, 2);
638 uint16_t index = getTwoBytesLsb(frame, 4);
639 executeTSCommand(subsystem, index);
640}
641
642 union FloatIntBytes {
643 float f;
644 int i;
645 uint8_t bytes[sizeof(float)];
646 };
647
648static void processCanSetCalibration(const CANRxFrame& frame) {
649 // todo allow changes of scalar settings via CANbus
650 UNUSED(frame);
651}
652/**
653 * CANbus protocol to query scalar calibrations using hash keys
654 *
655 * see fields_api.txt for well-known fields
656 * see generated_fields_api_header.h for corresponding hashes
657 */
658static void processCanRequestCalibration(const CANRxFrame& frame) {
659#if EFI_LUA_LOOKUP
660 int hash = getFourBytesLsb(frame, 2);
661 efiPrintf("processCanRequestCalibration=%x", hash);
662 FloatIntBytes fb;
663 fb.f = getConfigValueByHash(hash);
664
665 CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::ECU_GET_CALIBRATION, 8, /*bus*/0, /*isExtended*/true);
666 for (size_t i = 0;i<sizeof(float);i++) {
667 msg[4 + i] = fb.bytes[i];
668 }
669
670 fb.i = hash;
671 // first half of the packed is copy of that hash value so that recipients know what they are processing
672 for (size_t i = 0;i<sizeof(float);i++) {
673 msg[i] = fb.bytes[i];
674 }
675#endif // EFI_LUA_LOOKUP
676}
677
679 if (frame.data8[0] != (int)bench_test_magic_numbers_e::BENCH_HEADER) {
680 return;
681 }
682
683 int eid = CAN_EID(frame);
684 if (eid == (int)bench_test_packet_ids_e::ECU_SET_CALIBRATION) {
686 } else if (eid == (int)bench_test_packet_ids_e::ECU_REQ_CALIBRATION) {
688 } else if (eid == (int)bench_test_packet_ids_e::ECU_CAN_BUS_USER_CONTROL) {
690 }
691}
692
693#endif // EFI_CAN_SUPPORT
694
695std::optional<setup_custom_board_ts_command_override_type> custom_board_ts_command;
696
697void executeTSCommand(uint16_t subsystem, uint16_t index) {
698 efiPrintf("IO test subsystem=%d index=%d", subsystem, index);
699
701
702 switch (subsystem) {
705 break;
706
707 case TS_DEBUG_MODE:
709 break;
710
712 if (!running) {
715 }
716 break;
717
719 if (!running) {
722 }
723 break;
724
726 if (!running) {
727 doRunSolenoidBench(index, 1000.0,
729 }
730 break;
731
733 if (!running) {
734 doRunBenchTestLuaOutput(index, 4.0,
736 }
737 break;
738
739 case TS_X14:
740 handleCommandX14(index);
741 break;
742#if EFI_CAN_SUPPORT
743 case TS_WIDEBAND:
744 setWidebandOffset(0xff, index);
745 break;
747 {
748 uint8_t hwIndex = index >> 8;
749 uint8_t canIndex = index & 0xff;
750
751 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
752 // TODO:
753 hwIndex = hwIndex < 8 ? hwIndex : 0xff;
754 setWidebandOffset(hwIndex, canIndex);
755 }
756 break;
758 {
759 uint8_t hwIndex = index >> 8;
760 uint8_t sensType = index & 0xff;
761
762 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
763 // TODO:
764 hwIndex = hwIndex < 8 ? hwIndex : 0xff;
765 setWidebandSensorType(hwIndex, sensType);
766 }
767 break;
769 pingWideband(index >> 8);
770 break;
771
774 {
775 uint8_t hwIndex = index >> 8;
776
777 // Hack until we fix canReWidebandHwIndex and set "Broadcast" to 0xff
778 // TODO:
779 widebandUpdateHwId = hwIndex < 8 ? hwIndex : 0xff;
781 }
782 break;
783#endif // EFI_CAN_SUPPORT
785 handleBenchCategory(index);
786 break;
787
789 applyPreset(index);
790 break;
791
792 case TS_BOARD_ACTION:
793 // TODO: use call_board_override
794 if (custom_board_ts_command.has_value()) {
795 custom_board_ts_command.value()(subsystem, index);
796 }
797 break;
798
800 applyPreset((int)DEFAULT_ENGINE_TYPE);
801 break;
802
803 case TS_STOP_ENGINE:
805 break;
806
807 case 0xba:
808#if EFI_PROD_CODE && EFI_DFU_JUMP
810#endif /* EFI_DFU_JUMP */
811 break;
812
813 case REBOOT_COMMAND:
814#if EFI_PROD_CODE
815 rebootNow();
816#endif /* EFI_PROD_CODE */
817 break;
818
819#if EFI_USE_OPENBLT
820 case 0xbc:
821 /* Jump to OpenBLT if present */
823 break;
824#endif
825
826 default:
827 criticalError("Unexpected bench subsystem %d %d", subsystem, index);
828 }
829}
830
832 // default values if configuration was not specified
835 }
836
839 }
840
843 }
844}
845
847 addConsoleAction("fuelpumpbench", fuelPumpBench);
848 addConsoleActionF("fuelpumpbench2", fuelPumpBenchExt);
849
850 addConsoleActionFFF(CMD_FUEL_BENCH, fuelInjBench);
852
853 addConsoleActionFFF(CMD_SPARK_BENCH, sparkBench);
854 addConsoleActionFFFF("sparkbench2", sparkBenchExt);
855
857
858 addConsoleAction(CMD_AC_RELAY_BENCH, acRelayBench);
859
860 addConsoleAction(CMD_FAN_BENCH, fanBench);
861 addConsoleAction(CMD_FAN2_BENCH, fan2Bench);
862 addConsoleActionF("fanbench2", fanBenchExt);
863
864 addConsoleAction("mainrelaybench", mainRelayBench);
865
866#if EFI_CAN_SUPPORT
867#if EFI_WIDEBAND_FIRMWARE_UPDATE
868 addConsoleActionI("update_wideband", [](int hwIndex) { requestWidebandUpdate(hwIndex, false); });
869#endif // EFI_WIDEBAND_FIRMWARE_UPDATE
870 addConsoleActionII("set_wideband_index", [](int hwIndex, int index) { setWidebandOffset(hwIndex, index); });
871#endif // EFI_CAN_SUPPORT
872
873 addConsoleAction(CMD_STARTER_BENCH, starterRelayBench);
874 addConsoleAction(CMD_MIL_BENCH, milBench);
875 addConsoleAction(CMD_HPFP_BENCH, hpfpValveBench);
876
877#if EFI_CAN_SUPPORT
878 addConsoleActionI("ping_wideband", [](int index) {
879 pingWideband(index);
880 });
881#endif // EFI_CAN_SUPPORT
882
883#if EFI_LUA
884 // this commands facilitates TS Lua Button scripts development
885 addConsoleActionI("lua_button", [](int index) {
886 if (index < 0 || index > LUA_BUTTON_COUNT)
887 return;
888 luaCommandCounters[index - 1]++;
889 });
890 addConsoleActionFFFF("luabench2", [](float humanIndex, float onTime, float offTimeMs, float count) {
891 doRunBenchTestLuaOutput((int)humanIndex, onTime, offTimeMs, (int)count);
892 });
893#endif // EFI_LUA
894 instance.start();
896}
897
898#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:296
bool etbIgnoreJamProtection
Definition engine.h:297
SingleTimerExecutor scheduler
Definition engine.h:271
RpmCalculator rpmCalculator
Definition engine.h:306
TunerStudioOutputChannels outputChannels
Definition engine.h:109
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:413
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_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_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:20
@ SD_MODE_PC
Definition mmc_card.h:19
@ SD_MODE_ECU
Definition mmc_card.h:18
@ SD_MODE_FORMAT
Definition mmc_card.h:21
@ 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 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 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