GCC Code Coverage Report


Directory: ./
File: firmware/config/engines/custom_engine.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 22.3% 55 0 247
Functions: 11.1% 2 0 18
Branches: 0.0% 0 0 2
Decisions: 0.0% 0 - 2

Line Branch Decision Exec Source
1 /**
2 * @file custom_engine.cpp
3 *
4 *
5 * set engine_type 49
6 * FRANKENSO_QA_ENGINE
7 * See also DEFAULT_ENGINE_TYPE
8 * Frankenso QA 12 cylinder engine
9 *
10 * @date Jan 18, 2015
11 * @author Andrey Belomutskiy, (c) 2012-2020
12 */
13
14 #include "pch.h"
15
16 #include "custom_engine.h"
17 #include "mre_meta.h"
18 #include "proteus_meta.h"
19 #include "hellen_meta.h"
20 #include "odometer.h"
21 #include "defaults.h"
22 #if EFI_PROD_CODE
23 #include "drivers/gpio/mc33810.h"
24 #endif /* EFI_PROD_CODE */
25
26 #if EFI_ELECTRONIC_THROTTLE_BODY
27 #include "electronic_throttle.h"
28 #endif
29
30 #if EFI_PROD_CODE
31 #include "can_hw.h"
32 #include "scheduler.h"
33 #endif /* EFI_PROD_CODE */
34
35 void setDiscoveryPdm() {
36 }
37
38 #if defined(HW_NUCLEO_F767) || defined(HW_NUCLEO_H743) || defined(HW_FRANKENSO)
39
40 /**
41 * set engine_type 59
42 */
43 void setDiscovery33810Test() {
44 // spi3mosiPin = Gpio::B5 grey
45 // spi3misoPin = Gpio::B4; vio
46 // spi3sckPin = Gpio::B3; blue
47 // CS PC5 white
48 // EN PA6 yellow
49
50 engineConfiguration->map.sensor.hwChannel = EFI_ADC_NONE;
51 engineConfiguration->clt.adcChannel = EFI_ADC_NONE;
52 engineConfiguration->triggerSimulatorPins[0] = Gpio::Unassigned;
53 engineConfiguration->triggerSimulatorPins[1] = Gpio::Unassigned;
54
55 engineConfiguration->mc33810_cs[0] = Gpio::C5;
56
57 engineConfiguration->injectionPins[0] = Gpio::MC33810_0_OUT_0;
58 engineConfiguration->injectionPins[1] = Gpio::MC33810_0_OUT_1;
59 engineConfiguration->injectionPins[2] = Gpio::Unassigned;
60 engineConfiguration->injectionPins[3] = Gpio::Unassigned;
61
62 engineConfiguration->ignitionPins[0] = Gpio::MC33810_0_GD_0;
63 engineConfiguration->ignitionPins[1] = Gpio::MC33810_0_GD_1;
64 engineConfiguration->ignitionPins[2] = Gpio::MC33810_0_GD_2;
65 engineConfiguration->ignitionPins[3] = Gpio::MC33810_0_GD_3;
66
67 engineConfiguration->cylindersCount = 2;
68 engineConfiguration->firingOrder = FO_1_2;
69 }
70 #endif // HW_FRANKENSO
71
72 // todo: should this be part of more default configurations?
73 12 void setFrankensoConfiguration() {
74 #ifdef HW_FRANKENSO
75 12 engineConfiguration->trigger.type = trigger_type_e::TT_ONE_PLUS_ONE;
76
77 12 commonFrankensoAnalogInputs();
78
79 /**
80 * Frankenso analog #1 PC2 ADC12 CLT
81 * Frankenso analog #2 PC1 ADC11 IAT
82 * Frankenso analog #3 PA0 ADC0 MAP
83 * Frankenso analog #4 PC3 ADC13 WBO / O2
84 * Frankenso analog #5 PA2 ADC2 TPS
85 * Frankenso analog #6 PA1 ADC1
86 * Frankenso analog #7 PA4 ADC4
87 * Frankenso analog #8 PA3 ADC3
88 * Frankenso analog #9 PA7 ADC7
89 * Frankenso analog #10 PA6 ADC6
90 * Frankenso analog #11 PC5 ADC15
91 * Frankenso analog #12 PC4 ADC14 VBatt
92 */
93 12 engineConfiguration->tps1_1AdcChannel = EFI_ADC_2; // PA2
94
95 12 engineConfiguration->map.sensor.hwChannel = EFI_ADC_0;
96
97 12 engineConfiguration->clt.adcChannel = EFI_ADC_12;
98 12 engineConfiguration->iat.adcChannel = EFI_ADC_11;
99 12 engineConfiguration->afr.hwChannel = EFI_ADC_13;
100
101 // Frankenso hardware
102 12 engineConfiguration->clt.config.bias_resistor = 2700;
103 12 engineConfiguration->iat.config.bias_resistor = 2700;
104
105 /**
106 * http://rusefi.com/wiki/index.php?title=Manual:Hardware_Frankenso_board
107 */
108 // Frankenso low out #1: PE6
109 // Frankenso low out #2: PE5
110 // Frankenso low out #3: PD7 Main Relay
111 // Frankenso low out #4: PC13 Idle valve solenoid
112 // Frankenso low out #5: PE3
113 // Frankenso low out #6: PE4 fuel pump relay
114 // Frankenso low out #7: PE1 (do not use with discovery!)
115 // Frankenso low out #8: PE2 injector #2
116 // Frankenso low out #9: PB9 injector #1
117 // Frankenso low out #10: PE0 (do not use with discovery!)
118 // Frankenso low out #11: PB8 injector #3
119 // Frankenso low out #12: PB7 injector #4
120
121 12 engineConfiguration->fuelPumpPin = Gpio::E4;
122 12 engineConfiguration->mainRelayPin = Gpio::D7;
123 12 engineConfiguration->idle.solenoidPin = Gpio::C13;
124
125 12 engineConfiguration->fanPin = Gpio::E5;
126
127 12 engineConfiguration->injectionPins[0] = Gpio::B9; // #1
128 12 engineConfiguration->injectionPins[1] = Gpio::E2; // #2
129 12 engineConfiguration->injectionPins[2] = Gpio::B8; // #3
130 #ifndef EFI_INJECTOR_PIN3
131 12 engineConfiguration->injectionPins[3] = Gpio::B7; // #4
132 #else /* EFI_INJECTOR_PIN3 */
133 engineConfiguration->injectionPins[3] = EFI_INJECTOR_PIN3; // #4
134 #endif /* EFI_INJECTOR_PIN3 */
135
136 12 setAlgorithm(engine_load_mode_e::LM_SPEED_DENSITY);
137
138 12 engineConfiguration->injectionPins[4] = Gpio::Unassigned;
139 12 engineConfiguration->injectionPins[5] = Gpio::Unassigned;
140 12 engineConfiguration->injectionPins[6] = Gpio::Unassigned;
141 12 engineConfiguration->injectionPins[7] = Gpio::Unassigned;
142 12 engineConfiguration->injectionPins[8] = Gpio::Unassigned;
143 12 engineConfiguration->injectionPins[9] = Gpio::Unassigned;
144 12 engineConfiguration->injectionPins[10] = Gpio::Unassigned;
145 12 engineConfiguration->injectionPins[11] = Gpio::Unassigned;
146
147 12 engineConfiguration->ignitionPins[0] = Gpio::E14;
148 12 engineConfiguration->ignitionPins[1] = Gpio::C7;
149 12 engineConfiguration->ignitionPins[2] = Gpio::C9;
150 // set_ignition_pin 4 PE10
151 12 engineConfiguration->ignitionPins[3] = Gpio::E10;
152
153 // todo: 8.2 or 10k?
154 12 engineConfiguration->vbattDividerCoeff = ((float) (10 + 33)) / 10 * 2;
155 #endif // HW_FRANKENSO
156 12 }
157
158 // ETB_BENCH_ENGINE
159 // set engine_type 58
160 void setEtbTestConfiguration() {
161 // VAG test ETB
162 engineConfiguration->tpsMin = 54;
163 // by the way this ETB has default position of ADC=74 which is about 4%
164 engineConfiguration->tpsMax = 540;
165
166 // yes, 30K - that's a test configuration
167 engineConfiguration->rpmHardLimit = 30000;
168
169 setCrankOperationMode();
170 engineConfiguration->trigger.type = trigger_type_e::TT_TOOTHED_WHEEL_60_2;
171
172
173 engineConfiguration->ignitionPins[0] = Gpio::Unassigned;
174 engineConfiguration->ignitionPins[1] = Gpio::Unassigned;
175 engineConfiguration->ignitionPins[2] = Gpio::Unassigned;
176 engineConfiguration->ignitionPins[3] = Gpio::Unassigned;
177 /**
178 * remember that some H-bridges require 5v control lines, not just 3v logic outputs we have on stm32
179 */
180 engineConfiguration->etbIo[0].directionPin1 = Gpio::C7; // Frankenso high-side in order to get 5v control
181 engineConfiguration->etbIo[0].directionPin2 = Gpio::C9;
182 engineConfiguration->etbIo[0].controlPin = Gpio::E14;
183
184 #if EFI_ELECTRONIC_THROTTLE_BODY
185 setBoschVNH2SP30Curve();
186 #endif /* EFI_ELECTRONIC_THROTTLE_BODY */
187
188 engineConfiguration->tps1_1AdcChannel = EFI_ADC_2; // PA2
189 engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_9; // PB1
190
191 // turning off other PWMs to simplify debugging
192 engineConfiguration->triggerSimulatorRpm = 0;
193 engineConfiguration->stepperEnablePin = Gpio::Unassigned;
194 engineConfiguration->idle.stepperStepPin = Gpio::Unassigned;
195 engineConfiguration->idle.stepperDirectionPin = Gpio::Unassigned;
196 engineConfiguration->useStepperIdle = true;
197
198 // no analog dividers - all sensors with 3v supply, naked discovery bench setup
199 engineConfiguration->analogInputDividerCoefficient = 1;
200
201 // see also setDefaultEtbBiasCurve
202 }
203
204 #if defined(HW_FRANKENSO) && EFI_PROD_CODE && HAL_USE_EEPROM
205
206 // todo: page_size + 2
207 // todo: CC_SECTION(".nocache")
208 static uint8_t write_buf[EE_PAGE_SIZE + 10];
209
210
211 #define EEPROM_WRITE_TIME_MS 10 /* time to write one page in ms. Consult datasheet! */
212
213 /**
214 * https://www.onsemi.com/pdf/datasheet/cat24c32-d.pdf
215 * CAT24C32
216 */
217 static const I2CEepromFileConfig i2cee = {
218 .barrier_low = 0,
219 .barrier_hi = EE_SIZE - 1,
220 .size = EE_SIZE,
221 .pagesize = EE_PAGE_SIZE,
222 .write_time = TIME_MS2I(EEPROM_WRITE_TIME_MS),
223 .i2cp = &EE_U2CD,
224 .addr = 0x50,
225 .write_buf = write_buf
226 };
227
228 extern EepromDevice eepdev_24xx;
229 static I2CEepromFileStream ifile;
230
231 /**
232 * set engine_type 61
233 */
234 void setEepromTestConfiguration() {
235 engineConfiguration->useEeprom = true;
236 engineConfiguration->ignitionPins[2] = Gpio::Unassigned;
237 // dirty hack
238 brain_pin_markUnused(Gpio::C9);
239 efiSetPadMode("I2C", Gpio::A8, PAL_MODE_ALTERNATE(4));
240 efiSetPadMode("I2C", Gpio::C9, PAL_MODE_ALTERNATE(4));
241
242
243 addConsoleActionI("ee_read",
244 [](int value) {
245 if (ifile.vmt != eepdev_24xx.efsvmt) {
246 EepromFileOpen((EepromFileStream *)&ifile, (EepromFileConfig *)&i2cee, &eepdev_24xx);
247 }
248
249 ifile.vmt->setposition(&ifile, 0);
250 // chFileStreamSeek(&ifile, 0);
251 int v2;
252 streamRead(&ifile, (uint8_t *)&v2, 4);
253 efiPrintf("EE has %d", v2);
254
255 v2 += 3;
256 ifile.vmt->setposition(&ifile, 0);
257 streamWrite(&ifile, (uint8_t *)&v2, 4);
258
259
260 });
261 }
262 #endif //HW_FRANKENSO
263
264 // F407 discovery
265 void setL9779TestConfiguration() {
266 // enable_spi 3
267 engineConfiguration->is_enabled_spi_3 = true;
268 // Wire up spi3
269 // green
270 engineConfiguration->spi3mosiPin = Gpio::B5;
271 // blue
272 engineConfiguration->spi3misoPin = Gpio::B4;
273 // white
274 engineConfiguration->spi3sckPin = Gpio::B3;
275
276 engineConfiguration->l9779spiDevice = SPI_DEVICE_3;
277 // orange
278 engineConfiguration->l9779_cs = Gpio::D5;
279 }
280
281 #if HW_PROTEUS
282 /*
283 * set engine_type 96
284 */
285
286 void proteusDcWastegateTest() {
287 engineConfiguration->isBoostControlEnabled = true;
288 engineConfiguration->etbFunctions[0] = DC_Wastegate;
289 engineConfiguration->etbFunctions[1] = DC_None;
290 engineConfiguration->map.sensor.hwChannel = EFI_ADC_NONE;
291
292 engineConfiguration->tps1_1AdcChannel = EFI_ADC_10;
293 setTPS1Calibration(98, 926, 891, 69);
294
295 engineConfiguration->wastegatePositionSensor = EFI_ADC_6;
296 engineConfiguration->wastegatePositionClosedVoltage = 0.7;
297 engineConfiguration->wastegatePositionOpenedVoltage = 4.0;
298
299 strncpy(config->luaScript, R"(
300
301 mapSensor = Sensor.new("map")
302 mapSensor : setTimeout(3000)
303
304 function onTick()
305 local tps = getSensor("TPS1")
306 tps = (tps == nil and 0 or tps)
307 mapSensor : set(tps)
308 end
309
310 )", efi::size(config->luaScript));
311 }
312
313 #endif // HW_PROTEUS
314
315 static void setBasicNotECUmode() {
316 engineConfiguration->trigger.type = trigger_type_e::TT_HALF_MOON;
317
318 // todo: shall we disable map averaging?
319
320 engineConfiguration->wwaeTau = 0.0;
321 engineConfiguration->wwaeBeta = 0.0;
322
323 engineConfiguration->fanPin = Gpio::Unassigned;
324 engineConfiguration->triggerInputPins[0] = Gpio::Unassigned;
325
326 engineConfiguration->tps1_1AdcChannel = EFI_ADC_NONE;
327 engineConfiguration->tps2_1AdcChannel = EFI_ADC_NONE;
328 engineConfiguration->throttlePedalPositionAdcChannel = EFI_ADC_NONE;
329 engineConfiguration->throttlePedalPositionSecondAdcChannel = EFI_ADC_NONE;
330 engineConfiguration->vehicleSpeedSensorInputPin = Gpio::Unassigned;
331 engineConfiguration->clt.adcChannel = EFI_ADC_NONE;
332 engineConfiguration->iat.adcChannel = EFI_ADC_NONE;
333 engineConfiguration->map.sensor.hwChannel = EFI_ADC_NONE;
334 }
335
336 void setBodyControlUnit() {
337 for (int i = 0; i < MAX_CYLINDER_COUNT;i++) {
338 engineConfiguration->ignitionPins[i] = Gpio::Unassigned;
339 engineConfiguration->injectionPins[i] = Gpio::Unassigned;
340 }
341 setBasicNotECUmode();
342 }
343
344 void mreSecondaryCan() {
345 setBodyControlUnit();
346
347 engineConfiguration->auxAnalogInputs[0] = MRE_IN_TPS;
348 engineConfiguration->auxAnalogInputs[1] = MRE_IN_MAP;
349 engineConfiguration->auxAnalogInputs[2] = MRE_IN_CLT;
350 engineConfiguration->auxAnalogInputs[3] = MRE_IN_IAT;
351 // engineConfiguration->auxAnalogInputs[0] =
352
353
354 // EFI_ADC_14: "32 - AN volt 6"
355 // engineConfiguration->afr.hwChannel = EFI_ADC_14;
356
357
358 strncpy(config->luaScript, R"(
359 txPayload = {}
360 function onTick()
361 auxV = getAuxAnalog(0)
362 print('Hello analog ' .. auxV )
363 -- first byte: integer part, would be autoboxed to int
364 txPayload[1] = auxV
365 -- second byte: fractional part, would be autoboxed to int, overflow would be ignored
366 txPayload[2] = auxV * 256;
367 auxV = getAuxAnalog(1)
368 print('Hello analog ' .. auxV )
369 txPayload[3] = auxV
370 txPayload[4] = auxV * 256;
371 auxV = getAuxAnalog(2)
372 print('Hello analog ' .. auxV )
373 txPayload[5] = auxV
374 txPayload[6] = auxV * 256;
375 txCan(1, 0x600, 1, txPayload)
376 end
377 )", efi::size(config->luaScript));
378
379 }
380
381 void mreBCM() {
382 mreSecondaryCan();
383 // maybe time to kill this feature is pretty soon?
384 engineConfiguration->consumeObdSensors = true;
385 }
386
387 586 void setBoschHDEV_5_injectors() {
388 #if HPFP_LOBE_PROFILE_SIZE == 16
389 static const float hardCodedHpfpLobeProfileQuantityBins[16] = {0.0, 1.0, 4.5, 9.5,
390 16.5, 25.0, 34.5, 45.0 ,
391 55.0, 65.5, 75.0, 83.5,
392 90.5, 95.5, 99.0, 100.0};
393 586 copyArray(config->hpfpLobeProfileQuantityBins, hardCodedHpfpLobeProfileQuantityBins);
394 #endif // HPFP_LOBE_PROFILE_SIZE
395 586 setHpfpLobeProfileAngle(3);
396 586 setLinearCurve(config->hpfpDeadtimeVoltsBins, 8, 16, 0.5);
397
398 586 setRpmTableBin(config->hpfpCompensationRpmBins);
399 586 setLinearCurve(config->hpfpCompensationLoadBins, 0.005, 0.120, 0.001);
400
401 // This is the configuration for bosch HDEV 5 injectors
402 // all times in microseconds/us
403 586 engineConfiguration->mc33_hvolt = 65;
404 586 engineConfiguration->mc33_i_boost = 13000;
405 586 engineConfiguration->mc33_i_peak = 9400;
406 586 engineConfiguration->mc33_i_hold = 3700;
407 586 engineConfiguration->mc33_t_min_boost = 100;
408 586 engineConfiguration->mc33_t_max_boost = 400;
409 586 engineConfiguration->mc33_t_peak_off = 10;
410 586 engineConfiguration->mc33_t_peak_tot = 700;
411 586 engineConfiguration->mc33_t_bypass = 10;
412 586 engineConfiguration->mc33_t_hold_off = 60;
413 586 engineConfiguration->mc33_t_hold_tot = 10000;
414
415 586 engineConfiguration->mc33_hpfp_i_peak = 5; // A not mA like above
416 586 engineConfiguration->mc33_hpfp_i_hold = 3;
417 586 engineConfiguration->mc33_hpfp_i_hold_off = 10; // us
418 586 engineConfiguration->mc33_hpfp_max_hold = 10; // this value in ms not us
419
420 586 }
421
422 /**
423 * set engine_type 107
424 */
425 void setRotary() {
426 engineConfiguration->cylindersCount = 2;
427 engineConfiguration->firingOrder = FO_1_2;
428
429 engineConfiguration->trigger.type = trigger_type_e::TT_36_2_2_2;
430 engineConfiguration->twoStroke = true;
431
432 strcpy(engineConfiguration->engineMake, ENGINE_MAKE_MAZDA);
433 strcpy(engineConfiguration->engineCode, "13B");
434 strcpy(engineConfiguration->vehicleName, "test");
435
436 engineConfiguration->ignitionMode = IM_INDIVIDUAL_COILS;
437 engineConfiguration->injectionPins[2] = Gpio::Unassigned; // injector in default pinout
438 engineConfiguration->injectionPins[3] = Gpio::Unassigned;
439
440 engineConfiguration->enableTrailingSparks = true;
441 engineConfiguration->trailingCoilPins[0] = Gpio::C9;
442 engineConfiguration->trailingCoilPins[1] = Gpio::E10;
443 }
444
445 /**
446 * set engine_type 103
447 */
448 void setTest33816EngineConfiguration() {
449
450 // grey
451 // default spi3mosiPin PB5
452 // white
453 // default spi3misoPin PB4
454 // violet
455 // default spi3sckPin PB3
456
457
458 engineConfiguration->triggerSimulatorPins[0] = Gpio::Unassigned;
459 engineConfiguration->triggerSimulatorPins[1] = Gpio::Unassigned;
460
461 engineConfiguration->injectionPins[0] = Gpio::B9; // #1
462 engineConfiguration->injectionPins[1] = Gpio::E2; // #2
463 engineConfiguration->injectionPins[2] = Gpio::B8; // #3
464 engineConfiguration->injectionPins[3] = Gpio::B7; // #4
465
466
467 // blue
468 engineConfiguration->mc33816_cs = Gpio::D7;
469 // green
470 engineConfiguration->mc33816_rstb = Gpio::D4;
471 engineConfiguration->sdCardCsPin = Gpio::Unassigned;
472 // yellow
473 engineConfiguration->mc33816_driven = Gpio::D6;
474
475 engineConfiguration->mc33816_flag0 = Gpio::D3;
476
477 // enable_spi 3
478 engineConfiguration->is_enabled_spi_3 = true;
479 // Wire up spi3
480 engineConfiguration->spi3mosiPin = Gpio::B5;
481 engineConfiguration->spi3misoPin = Gpio::B4;
482 engineConfiguration->spi3sckPin = Gpio::B3;
483
484 engineConfiguration->isSdCardEnabled = false;
485
486 engineConfiguration->mc33816spiDevice = SPI_DEVICE_3;
487 }
488
489 void proteusLuaDemo() {
490 #if HW_PROTEUS
491 engineConfiguration->tpsMin = 889;
492 engineConfiguration->tpsMax = 67;
493
494 engineConfiguration->tps1SecondaryMin = 105;
495 engineConfiguration->tps1SecondaryMax = 933;
496
497 strcpy(engineConfiguration->scriptCurveName[2 - 1], "rateofchange");
498
499 strcpy(engineConfiguration->scriptCurveName[3 - 1], "bias");
500
501 /**
502 * for this demo I use ETB just a sample object to control with PID. No reasonable person should consider actually using
503 * Lua for actual intake ETB control while driving around the racing track - hard-coded ETB control is way smarter!
504 */
505 static const float defaultBiasBins[] = {
506 0, 1, 2, 4, 7, 98, 99, 100
507 };
508 static const float defaultBiasValues[] = {
509 -20, -18, -17, 0, 20, 21, 22, 25
510 };
511
512 engineConfiguration->luaOutputPins[0] = Gpio::D12;
513 engineConfiguration->luaOutputPins[1] = Gpio::D10;
514 engineConfiguration->luaOutputPins[2] = Gpio::D11;
515
516 setLinearCurve(config->scriptCurve2Bins, 0, 8000, 1);
517 setLinearCurve(config->scriptCurve2, 0, 100, 1);
518
519 copyArray(config->scriptCurve3Bins, defaultBiasBins);
520 copyArray(config->scriptCurve3, defaultBiasValues);
521
522 engineConfiguration->auxAnalogInputs[0] = PROTEUS_IN_ANALOG_VOLT_10;
523 engineConfiguration->afr.hwChannel = EFI_ADC_NONE;
524
525
526 // ETB direction #1 PD10
527 engineConfiguration->etbIo[0].directionPin1 = Gpio::Unassigned;
528 // ETB control PD12
529 engineConfiguration->etbIo[0].controlPin = Gpio::Unassigned;
530 // ETB disable PD11
531 engineConfiguration->etbIo[0].disablePin = Gpio::Unassigned;
532
533 /**
534 controlIndex = 0
535 directionIndex = 1
536
537 print('pid output ' .. output)
538 print('')
539
540
541
542 local duty = (bias + output) / 100
543
544 -- isPositive = duty > 0;
545 -- pwmValue = isPositive and duty or -duty
546 -- setPwmDuty(controlIndex, pwmValue)
547
548 -- dirValue = isPositive and 1 or 0;
549 -- setPwmDuty(directionIndex, dirValue)
550
551 -- print('pwm ' .. pwmValue .. ' dir ' .. dirValue)
552
553 *
554 */
555
556 auto script = R"(
557
558 startPwm(0, 800, 0.1)
559 -- direction
560 startPwm(1, 80, 1.0)
561 -- disable
562 startPwm(2, 80, 0.0)
563
564 pid = Pid.new(2, 0, 0, -100, 100)
565
566 biasCurveIndex = findCurveIndex("bias")
567
568 voltageFromCan = nil
569 canRxAdd(0x600)
570
571 function onCanRx(bus, id, dlc, data)
572 print('got CAN id=' .. id .. ' dlc=' .. dlc)
573 voltageFromCan = data[2] / 256.0 + data[1]
574 end
575
576 function onTick()
577 local targetVoltage = getAuxAnalog(0)
578
579 -- local target = interpolate(1, 0, 3.5, 100, targetVoltage)
580 local target = interpolate(1, 0, 3.5, 100, voltageFromCan)
581 -- clamp 0 to 100
582 target = math.max(0, target)
583 target = math.min(100, target)
584
585 print('Decoded target: ' .. target)
586
587 local tps = getSensor("TPS1")
588 tps = (tps == nil and 'invalid TPS' or tps)
589 print('Tps ' .. tps)
590
591 local output = pid:get(target, tps)
592
593 local bias = curve(biasCurveIndex, target)
594 print('bias ' .. bias)
595
596 local duty = (bias + output) / 100
597 isPositive = duty > 0;
598 pwmValue = isPositive and duty or -duty
599 setPwmDuty(0, pwmValue)
600
601 dirValue = isPositive and 1 or 0;
602 setPwmDuty(1, dirValue)
603
604 print('pwm ' .. pwmValue .. ' dir ' .. dirValue)
605 print('')
606 end
607 )";
608 strncpy(config->luaScript, script, efi::size(config->luaScript));
609 #endif
610 }
611
612 void detectBoardType() {
613 #if HW_HELLEN && EFI_PROD_CODE
614 detectHellenBoardType();
615 #endif //HW_HELLEN EFI_PROD_CODE
616 // todo: add board ID detection?
617 // see hellen128 which has/had alternative i2c board id?
618 }
619
620 // set engine_type 15
621 void fuelBenchMode() {
622 engineConfiguration->cranking.rpm = 12000;
623 #if EFI_ENGINE_CONTROL
624 setFlatInjectorLag(0);
625 #endif // EFI_ENGINE_CONTROL
626 setTable(config->postCrankingFactor, 1.0f);
627 setArrayValues(config->crankingFuelCoef, 1.0f);
628 setTable(config->crankingCycleBaseFuel, 1.0f);
629 setBasicNotECUmode();
630 }
631
632 #if HW_PROTEUS
633 // PROTEUS_STIM_QC
634 // set engine_type 73
635 void proteusStimQc() {
636 engineConfiguration->trigger.type = trigger_type_e::TT_ONE_PLUS_ONE;
637 engineConfiguration->vvtMode[0] = VVT_SINGLE_TOOTH;
638 engineConfiguration->vvtMode[1] = VVT_SINGLE_TOOTH;
639
640 engineConfiguration->triggerInputPins[0] = PROTEUS_DIGITAL_1;
641 engineConfiguration->triggerInputPins[1] = PROTEUS_DIGITAL_2;
642 engineConfiguration->camInputs[0] = PROTEUS_DIGITAL_3;
643 engineConfiguration->camInputs[1] = PROTEUS_DIGITAL_4;
644 engineConfiguration->vehicleSpeedSensorInputPin = PROTEUS_DIGITAL_5;
645 engineConfiguration->brakePedalPin = PROTEUS_DIGITAL_6;
646
647 setProteusEtbIO();
648 // EFI_ADC_13: "Analog Volt 4"
649 engineConfiguration->tps2_1AdcChannel = PROTEUS_IN_TPS2_1;
650 // EFI_ADC_0: "Analog Volt 5"
651 engineConfiguration->tps2_2AdcChannel = PROTEUS_IN_ANALOG_VOLT_5;
652 engineConfiguration->oilPressure.hwChannel = PROTEUS_IN_ANALOG_VOLT_6;
653 // pps2 volt 7
654
655 // pps1 volt 9
656 // afr volt 10
657 engineConfiguration->oilTempSensor.adcChannel = PROTEUS_IN_ANALOG_VOLT_11;
658 setCommonNTCSensor(&engineConfiguration->oilTempSensor, 2700);
659
660
661 engineConfiguration->auxLinear1.hwChannel = PROTEUS_IN_ANALOG_TEMP_1;
662 engineConfiguration->auxLinear2.hwChannel = PROTEUS_IN_ANALOG_TEMP_4;
663
664 // engineConfiguration->fan2Pin = Gpio::PROTEUS_LS_9;
665 // engineConfiguration->malfunctionIndicatorPin = Gpio::PROTEUS_LS_13;
666 // engineConfiguration->tachOutputPin = Gpio::PROTEUS_LS_14;
667 //
668 // engineConfiguration->vvtPins[0] = Gpio::PROTEUS_LS_15;
669 // engineConfiguration->vvtPins[1] = Gpio::PROTEUS_LS_16;
670 }
671 #endif // HW_PROTEUS
672
673 // set engine_type 93
674 void testEngine6451() {
675 #ifdef HW_FRANKENSO
676 setFrankensoConfiguration();
677 #endif
678 engineConfiguration->trigger.type = trigger_type_e::TT_NARROW_SINGLE_TOOTH;
679
680 setWholeTimingTable(30);
681 setTable(config->ignitionIatCorrTable, 0);
682 engineConfiguration->cylindersCount = 6;
683 engineConfiguration->firingOrder = FO_1_5_3_6_2_4;
684 engineConfiguration->ignitionMode = IM_INDIVIDUAL_COILS;
685 engineConfiguration->triggerSimulatorRpm = 4800;
686 }
687
688