rusEFI
The most advanced open source ECU
can_bench_test.cpp
Go to the documentation of this file.
1 
2 #include "pch.h"
3 #include "bench_test.h"
4 #include "board_id.h"
5 #include "can_bench_test.h"
6 #include "can_msg_tx.h"
7 #include "can_common.h"
8 #include "frequency_sensor.h"
9 #include "settings.h"
10 #include "gpio/gpio_ext.h"
11 
12 #define TRUNCATE_TO_BYTE(i) ((i) & 0xff)
13 // raw values are 0..5V, convert it to 8-bit (0..255)
14 #define RAW_TO_BYTE(v) TRUNCATE_TO_BYTE((int)(v * 255.0 / 5.0))
15 
16 /**
17  * QC direct output control API is used by https://github.com/rusefi/stim test device
18  * quite different from bench testing user functionality: QC direct should never be engaged on a real vehicle
19  * Once QC direct control mode is activated the only way out is to reboot the unit!
20  */
22 
23 static void directWritePad(Gpio pin, int value) {
24 #if EFI_GPIO_HARDWARE && EFI_PROD_CODE
25  if (brain_pin_is_onchip(pin)) {
26  palWritePad(getHwPort("can_write", pin), getHwPin("can_write", pin), value);
27  } else {
28 #if (BOARD_EXT_GPIOCHIPS > 0)
29  gpiochips_writePad(pin, value);
30 #endif
31  }
32 #endif // EFI_GPIO_HARDWARE && EFI_PROD_CODE
33 }
34 
35 static void qcSetEtbState(uint8_t dcIndex, uint8_t direction) {
37  const dc_io *io = &engineConfiguration->etbIo[dcIndex];
38  Gpio controlPin = io->controlPin;
39  directWritePad(controlPin, 1);
40  efiSetPadModeWithoutOwnershipAcquisition("QC_ETB", controlPin, PAL_MODE_OUTPUT_PUSHPULL);
41  directWritePad(io->directionPin1, direction);
42  directWritePad(io->disablePin, 0); // disable pin is inverted - here we ENABLE. direct pin access due to qcDirectPinControlMode
43 }
44 
45 #if EFI_CAN_SUPPORT
46 
47 static void setPin(const CANRxFrame& frame, int value) {
48  int outputIndex = frame.data8[2];
49  if (outputIndex >= getBoardMetaOutputsCount()) {
50  criticalError("QC pin index %d", outputIndex);
51  return;
52  }
53 #if EFI_GPIO_HARDWARE && EFI_PROD_CODE
54  Gpio* boardOutputs = getBoardMetaOutputs();
55  criticalAssertVoid(boardOutputs != nullptr, "outputs not defined");
56  Gpio pin = boardOutputs[outputIndex];
57 
58  int hwIndex = brainPin_to_index(pin);
59  if (engine->pinRepository.getBrainUsedPin(hwIndex) == nullptr) {
60  // if pin is assigned we better configure it
61  efiSetPadModeWithoutOwnershipAcquisition("QC_SET", pin, PAL_MODE_OUTPUT_PUSHPULL);
62  }
63 
64  directWritePad(pin, value);
65 #endif // EFI_GPIO_HARDWARE && EFI_PROD_CODE
66 }
67 
69 #if EFI_SHAFT_POSITION_INPUT
70  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::EVENT_COUNTERS, 8, /*bus*/0, /*isExtended*/true);
71 
76 
77  msg[0] = TRUNCATE_TO_BYTE(primaryRise + primaryFall);
78  msg[1] = TRUNCATE_TO_BYTE(secondaryRise + secondaryFall);
79 
80  for (int camIdx = 0; camIdx < 4; camIdx++) {
81  int vvtRise = 0, vvtFall = 0;
82  if (camIdx < CAM_INPUTS_COUNT) {
83  vvtRise = engine->triggerCentral.vvtEventRiseCounter[camIdx];
84  vvtFall = engine->triggerCentral.vvtEventFallCounter[camIdx];
85  }
86 
87  msg[2 + camIdx] = TRUNCATE_TO_BYTE(vvtRise + vvtFall);
88  }
89 
91  msg[6] = TRUNCATE_TO_BYTE(vehicleSpeedSensor.eventCounter);
92 #endif // EFI_SHAFT_POSITION_INPUT
93 }
94 
96  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::BUTTON_COUNTERS, 8, /*bus*/0, /*isExtended*/true);
97  msg[0] = TRUNCATE_TO_BYTE(engine->brakePedalSwitchedState.getCounter());
98  msg[1] = TRUNCATE_TO_BYTE(engine->clutchUpSwitchedState.getCounter());
99  msg[2] = TRUNCATE_TO_BYTE(engine->acButtonSwitchedState.getCounter());
100  // todo: start button
101 }
102 
104  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::BUTTON_COUNTERS, 8, /*bus*/0, /*isExtended*/true);
105  for (int i =0;i<LUA_DIGITAL_INPUT_COUNT;i++) {
106  msg[i] = TRUNCATE_TO_BYTE(engine->luaDigitalInputState[i].state.getCounter());
107  }
108 }
109 
111  const float values_1[] = {
120  };
121 
122  const float values_2[] = {
131  };
132  static_assert(efi::size(values_1) <= 8);
133  static_assert(efi::size(values_2) <= 8);
134 
135 
136  // send the first packet
137  {
138  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::RAW_ANALOG_1, 8, /*bus*/0, /*isExtended*/true);
139  for (size_t valueIdx = 0; valueIdx < efi::size(values_1); valueIdx++) {
140  msg[valueIdx] = RAW_TO_BYTE(values_1[valueIdx]);
141  }
142  }
143  {
144  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::RAW_ANALOG_2, 8, /*bus*/0, /*isExtended*/true);
145  for (size_t valueIdx = 0; valueIdx < efi::size(values_2); valueIdx++) {
146  msg[valueIdx] = RAW_TO_BYTE(values_2[valueIdx]);
147  }
148  }
149 }
150 
151 static void sendOutBoardMeta() {
152 #if EFI_PROD_CODE
153  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::IO_META_INFO, 8, /*bus*/0, /*isExtended*/true);
154  msg[0] = (int)bench_test_magic_numbers_e::BENCH_HEADER;
155  msg[1] = 0;
156  msg[2] = getBoardMetaOutputsCount();
158  msg[4] = getBoardMetaDcOutputsCount();
159 #endif // EFI_PROD_CODE
160 }
161 
163 #if EFI_PROD_CODE
164  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::BOARD_STATUS, 8, /*bus*/0, /*isExtended*/true);
165 
166  int boardId = getBoardId();
167  msg[0] = TRUNCATE_TO_BYTE(boardId >> 8);
168  msg[1] = TRUNCATE_TO_BYTE(boardId);
169 
170  int numSecondsSinceReset = getTimeNowS();
171  msg[2] = TRUNCATE_TO_BYTE(numSecondsSinceReset >> 16);
172  msg[3] = TRUNCATE_TO_BYTE(numSecondsSinceReset >> 8);
173  msg[4] = TRUNCATE_TO_BYTE(numSecondsSinceReset);
174 
175  int engineType = (int) engineConfiguration->engineType;
176  msg[5] = engineType >> 8;
177  msg[6] = engineType;
179 #endif // EFI_PROD_CODE
180 }
181 
182 static void sendPinStatePackets(int pinToggleCounter, uint32_t durationsInStateMs[2]) {
183  CanTxMessage msg(CanCategory::BENCH_TEST, (int)bench_test_packet_ids_e::PIN_STATE, 8, /*bus*/0, /*isExtended*/true);
184  msg[0] = TRUNCATE_TO_BYTE(pinToggleCounter >> 8);
185  msg[1] = TRUNCATE_TO_BYTE(pinToggleCounter);
186 
187  for (int i = 0, mIdx = 2; i < 2; i++) {
188  msg[mIdx++] = TRUNCATE_TO_BYTE(durationsInStateMs[i] >> 16);
189  msg[mIdx++] = TRUNCATE_TO_BYTE(durationsInStateMs[i] >> 8);
190  msg[mIdx++] = TRUNCATE_TO_BYTE(durationsInStateMs[i]);
191  }
192 }
193 
194 // bench test fuel pump pin #5603
195 static void sendPinStatePackets(bench_mode_e benchModePinIdx) {
196  OutputPin *pin = enginePins.getOutputPinForBenchMode(benchModePinIdx);
197  if (pin == nullptr)
198  return;
199 #if EFI_SIMULATOR
200  sendPinStatePackets(pin->pinToggleCounter, pin->durationsInStateMs);
201 #endif // EFI_SIMULATOR
202 }
203 
205  uint32_t savedDurationsInStateMs[2];
208 }
209 
210 static void resetPinStats(bench_mode_e benchModePinIdx) {
211  OutputPin *pin = enginePins.getOutputPinForBenchMode(benchModePinIdx);
212 
213  if (pin == nullptr)
214  return;
215 
216 #if EFI_SIMULATOR
217  pin->resetToggleStats();
218 #endif // EFI_SIMULATOR
219 }
220 
221 /*board public API*/bool withHwQcActivity = false;
222 
223 void processCanQcBenchTest(const CANRxFrame& frame) {
224  if (CAN_EID(frame) != (int)bench_test_packet_ids_e::IO_CONTROL) {
225  return;
226  }
227  if (frame.data8[0] != (int)bench_test_magic_numbers_e::BENCH_HEADER) {
228  return;
229  }
230  withHwQcActivity = true;
231  bench_test_io_control_e command = (bench_test_io_control_e)frame.data8[1];
232  if (command == bench_test_io_control_e::CAN_BENCH_GET_COUNT) {
234  } else if (command == bench_test_io_control_e::CAN_QC_OUTPUT_CONTROL_SET) {
235  qcDirectPinControlMode = true;
236  setPin(frame, 1);
237  } else if (command == bench_test_io_control_e::CAN_QC_OUTPUT_CONTROL_CLEAR) {
238  qcDirectPinControlMode = true;
239  setPin(frame, 0);
240  } else if (command == bench_test_io_control_e::CAN_QC_ETB) {
241  uint8_t dcIndex = frame.data8[2];
242  uint8_t direction = frame.data8[3];
243  qcSetEtbState(dcIndex, direction);
244  } else if (command == bench_test_io_control_e::CAN_BENCH_SET_ENGINE_TYPE) {
245  int eType = frame.data8[2];
246  // todo: fix firmware for 'false' to be possible - i.e. more of properties should be applied on the fly
247  setEngineType(eType, true);
248 #if EFI_PROD_CODE
249  scheduleReboot();
250 #endif // EFI_PROD_CODE
251 } else if (command == bench_test_io_control_e::CAN_BENCH_START_PIN_TEST) {
252  bench_mode_e benchModePinIdx = (bench_mode_e)frame.data8[2];
253  // ignore previous pin state and stats
254  resetPinStats(benchModePinIdx);
255  } else if (command == bench_test_io_control_e::CAN_BENCH_END_PIN_TEST) {
257  } else if (command == bench_test_io_control_e::CAN_BENCH_EXECUTE_BENCH_TEST) {
258  int benchCommandIdx = frame.data8[2];
259  handleBenchCategory(benchCommandIdx);
260  } else if (command == bench_test_io_control_e::CAN_BENCH_QUERY_PIN_STATE) {
261  bench_mode_e benchModePinIdx = (bench_mode_e)frame.data8[2];
262  sendPinStatePackets(benchModePinIdx);
263  }
264 }
265 #endif // EFI_CAN_SUPPORT
266 
268  addConsoleActionII("qc_etb", [](int index, int direction) {
269  qcSetEtbState(index, direction);
270  });
271 }
int getSavedBenchTestPinStates(uint32_t durationsInStateMs[2])
Definition: bench_test.cpp:426
static uint32_t savedDurationsInStateMs[2]
Definition: bench_test.cpp:67
void handleBenchCategory(uint16_t index)
Definition: bench_test.cpp:340
static int savedPinToggleCounter
Definition: bench_test.cpp:66
Utility methods related to bench testing.
board_id_t getBoardId()
Definition: board_id.cpp:14
void sendQcBenchButtonCounters()
static void setPin(const CANRxFrame &frame, int value)
void processCanQcBenchTest(const CANRxFrame &frame)
static void qcSetEtbState(uint8_t dcIndex, uint8_t direction)
void sendQcBenchBoardStatus()
void sendQcBenchRawAnalogValues()
bool qcDirectPinControlMode
static void sendSavedBenchStatePackets()
void initQcBenchControls()
static void directWritePad(Gpio pin, int value)
static void sendOutBoardMeta()
bool withHwQcActivity
static void resetPinStats(bench_mode_e benchModePinIdx)
void sendQcBenchAuxDigitalCounters()
static void sendPinStatePackets(int pinToggleCounter, uint32_t durationsInStateMs[2])
void sendQcBenchEventCounters()
TriggerCentral triggerCentral
Definition: engine.h:286
SwitchedState brakePedalSwitchedState
Definition: engine.h:187
SwitchedState clutchUpSwitchedState
Definition: engine.h:186
SwitchedState acButtonSwitchedState
Definition: engine.h:188
SimpleSwitchedState luaDigitalInputState[LUA_DIGITAL_INPUT_COUNT]
Definition: engine.h:189
PinRepository pinRepository
Definition: engine.h:116
OutputPin * getOutputPinForBenchMode(bench_mode_e idx)
Definition: efi_gpio.cpp:350
Single output pin reference and state.
Definition: efi_output.h:50
const char *& getBrainUsedPin(size_t idx)
virtual float getRaw() const
Definition: sensor.h:162
SwitchedState state
Definition: efi_output.h:37
uint16_t getCounter()
Definition: efi_output.cpp:19
int getHwEventCounter(int index) const
int vvtEventFallCounter[CAM_INPUTS_COUNT]
int vvtEventRiseCounter[CAM_INPUTS_COUNT]
void addConsoleActionII(const char *token, VoidIntInt callback)
Register a console command with two Integer parameters.
Gpio
int gpiochips_writePad(brain_pin_e pin, int value)
Set value to gpio of gpiochip.
Definition: core.cpp:335
EnginePins enginePins
Definition: efi_gpio.cpp:24
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin)
ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin)
efitimesec_t getTimeNowS()
Current system time in seconds (32 bits)
Definition: efitime.cpp:42
void scheduleReboot()
Definition: rusefi.cpp:158
Engine * engine
bench_mode_e
Definition: engine_types.h:490
int getBoardMetaOutputsCount()
Gpio * getBoardMetaOutputs()
int getBoardMetaDcOutputsCount()
int getBoardMetaLowSideOutputsCount()
FrequencySensor vehicleSpeedSensor(SensorType::VehicleSpeed, MS2NT(500))
void efiSetPadModeWithoutOwnershipAcquisition(const char *msg, brain_pin_e brainPin, iomode_t mode)
Definition: io_pins.cpp:61
engine_configuration_s * engineConfiguration
int brainPin_to_index(Gpio brainPin)
bool brain_pin_is_onchip(brain_pin_e brainPin)
@ AcceleratorPedalPrimary
@ AcceleratorPedalSecondary
void setEngineType(int value, bool isWriteToFlash)
Definition: settings.cpp:944
This file is about configuring engine via the human-readable protocol.
@ SHAFT_SECONDARY_RISING
@ SHAFT_SECONDARY_FALLING
@ SHAFT_PRIMARY_FALLING
@ SHAFT_PRIMARY_RISING
brain_pin_e pin
Definition: stm32_adc.cpp:15
uint8_t data8[8]
Frame data.
Definition: can_mocks.h:55
composite packet size