Line data Source code
1 : /**
2 : * @file hardware.cpp
3 : * @brief Hardware package entry point
4 : *
5 : * @date May 27, 2013
6 : * @author Andrey Belomutskiy, (c) 2012-2020
7 : */
8 :
9 : #include "pch.h"
10 :
11 :
12 : #include "trigger_input.h"
13 : #include "can_hw.h"
14 : #include "hardware.h"
15 : #include "rtc_helper.h"
16 : #include "bench_test.h"
17 : #include "yaw_rate_sensor.h"
18 : #include "pin_repository.h"
19 : #include "logic_analyzer.h"
20 : #include "smart_gpio.h"
21 : #include "accelerometer.h"
22 : #include "eficonsole.h"
23 : #include "console_io.h"
24 : #include "sensor_chart.h"
25 : #include "idle_thread.h"
26 : #include "odometer.h"
27 : #include "kline.h"
28 : #include "dac.h"
29 :
30 : #if EFI_PROD_CODE
31 : #include "mpu_util.h"
32 : #endif /* EFI_PROD_CODE */
33 :
34 : #include "mmc_card.h"
35 :
36 : #include "AdcDevice.h"
37 : #include "idle_hardware.h"
38 : #include "mcp3208.h"
39 : #include "hip9011.h"
40 : #include "histogram.h"
41 : #include "gps_uart.h"
42 : #include "sent.h"
43 : #include "cdm_ion_sense.h"
44 : #include "trigger_central.h"
45 : #include "vvt.h"
46 : #include "trigger_emulator_algo.h"
47 : #include "boost_control.h"
48 : #if EFI_SOFTWARE_KNOCK
49 : #include "software_knock.h"
50 : #endif
51 : #include "trigger_scope.h"
52 : #include "init.h"
53 : #if EFI_MC33816
54 : #include "mc33816.h"
55 : #endif /* EFI_MC33816 */
56 : #if EFI_WS2812
57 : #include "WS2812.h"
58 : #endif /* EFI_WS2812 */
59 :
60 : #if EFI_MAP_AVERAGING
61 : #include "map_averaging.h"
62 : #endif
63 :
64 : #if EFI_CONFIGURATION_STORAGE
65 : #include "flash_main.h"
66 : #endif
67 :
68 : #if HAL_USE_PAL && EFI_PROD_CODE
69 : #include "digital_input_exti.h"
70 : #endif // HAL_USE_PAL
71 :
72 : #if EFI_CAN_SUPPORT
73 : #include "can_vss.h"
74 : #endif
75 :
76 : #if HAL_USE_SPI
77 : /* zero index is SPI_NONE */
78 : extern bool isSpiInitialized[SPI_TOTAL_COUNT + 1];
79 :
80 : /* these are common adapters for engineConfiguration access, move to some common file? */
81 : brain_pin_e getMisoPin(spi_device_e device) {
82 : switch(device) {
83 : case SPI_DEVICE_1:
84 : return engineConfiguration->spi1misoPin;
85 : case SPI_DEVICE_2:
86 : return engineConfiguration->spi2misoPin;
87 : case SPI_DEVICE_3:
88 : return engineConfiguration->spi3misoPin;
89 : case SPI_DEVICE_4:
90 : return engineConfiguration->spi4misoPin;
91 : case SPI_DEVICE_5:
92 : return engineConfiguration->spi5misoPin;
93 : case SPI_DEVICE_6:
94 : return engineConfiguration->spi6misoPin;
95 : default:
96 : break;
97 : }
98 : return Gpio::Unassigned;
99 : }
100 :
101 : brain_pin_e getMosiPin(spi_device_e device) {
102 : switch(device) {
103 : case SPI_DEVICE_1:
104 : return engineConfiguration->spi1mosiPin;
105 : case SPI_DEVICE_2:
106 : return engineConfiguration->spi2mosiPin;
107 : case SPI_DEVICE_3:
108 : return engineConfiguration->spi3mosiPin;
109 : case SPI_DEVICE_4:
110 : return engineConfiguration->spi4mosiPin;
111 : case SPI_DEVICE_5:
112 : return engineConfiguration->spi5mosiPin;
113 : case SPI_DEVICE_6:
114 : return engineConfiguration->spi6mosiPin;
115 : default:
116 : break;
117 : }
118 : return Gpio::Unassigned;
119 : }
120 :
121 : brain_pin_e getSckPin(spi_device_e device) {
122 : switch(device) {
123 : case SPI_DEVICE_1:
124 : return engineConfiguration->spi1sckPin;
125 : case SPI_DEVICE_2:
126 : return engineConfiguration->spi2sckPin;
127 : case SPI_DEVICE_3:
128 : return engineConfiguration->spi3sckPin;
129 : case SPI_DEVICE_4:
130 : return engineConfiguration->spi4sckPin;
131 : case SPI_DEVICE_5:
132 : return engineConfiguration->spi5sckPin;
133 : case SPI_DEVICE_6:
134 : return engineConfiguration->spi6sckPin;
135 : default:
136 : break;
137 : }
138 : return Gpio::Unassigned;
139 : }
140 :
141 : /**
142 : * @return NULL if SPI device not specified
143 : */
144 : SPIDriver * getSpiDevice(spi_device_e spiDevice) {
145 : if (spiDevice == SPI_NONE) {
146 : return nullptr;
147 : }
148 : #if STM32_SPI_USE_SPI1
149 : if (spiDevice == SPI_DEVICE_1) {
150 : return &SPID1;
151 : }
152 : #endif
153 : #if STM32_SPI_USE_SPI2
154 : if (spiDevice == SPI_DEVICE_2) {
155 : return &SPID2;
156 : }
157 : #endif
158 : #if STM32_SPI_USE_SPI3
159 : if (spiDevice == SPI_DEVICE_3) {
160 : return &SPID3;
161 : }
162 : #endif
163 : #if STM32_SPI_USE_SPI4
164 : if (spiDevice == SPI_DEVICE_4) {
165 : return &SPID4;
166 : }
167 : #endif
168 : #if STM32_SPI_USE_SPI5
169 : if (spiDevice == SPI_DEVICE_5) {
170 : return &SPID5;
171 : }
172 : #endif
173 : #if STM32_SPI_USE_SPI6
174 : if (spiDevice == SPI_DEVICE_6) {
175 : return &SPID6;
176 : }
177 : #endif
178 : firmwareError(ObdCode::CUSTOM_ERR_UNEXPECTED_SPI, "Unexpected SPI device: %d", spiDevice);
179 : return nullptr;
180 : }
181 :
182 : /**
183 : * Only one consumer can use SPI bus at a given time
184 : */
185 : void lockSpi(spi_device_e device) {
186 : efiAssertVoid(ObdCode::CUSTOM_STACK_SPI, hasLotsOfRemainingStack(), "lockSpi");
187 : spiAcquireBus(getSpiDevice(device));
188 : }
189 :
190 : void unlockSpi(spi_device_e device) {
191 : spiReleaseBus(getSpiDevice(device));
192 : }
193 :
194 : static void initSpiModules() {
195 : if (engineConfiguration->is_enabled_spi_1) {
196 : turnOnSpi(SPI_DEVICE_1);
197 : }
198 : if (engineConfiguration->is_enabled_spi_2) {
199 : turnOnSpi(SPI_DEVICE_2);
200 : }
201 : if (engineConfiguration->is_enabled_spi_3) {
202 : turnOnSpi(SPI_DEVICE_3);
203 : }
204 : if (engineConfiguration->is_enabled_spi_4) {
205 : turnOnSpi(SPI_DEVICE_4);
206 : }
207 : if (engineConfiguration->is_enabled_spi_5) {
208 : turnOnSpi(SPI_DEVICE_5);
209 : }
210 : if (engineConfiguration->is_enabled_spi_6) {
211 : turnOnSpi(SPI_DEVICE_6);
212 : }
213 : }
214 :
215 : void stopSpi(spi_device_e device) {
216 : if (!isSpiInitialized[device]) {
217 : return; // not turned on
218 : }
219 : isSpiInitialized[device] = false;
220 : efiSetPadUnused(getSckPin(device));
221 : efiSetPadUnused(getMisoPin(device));
222 : efiSetPadUnused(getMosiPin(device));
223 : }
224 :
225 : static void stopSpiModules() {
226 : if (isConfigurationChanged(is_enabled_spi_1)) {
227 : stopSpi(SPI_DEVICE_1);
228 : }
229 :
230 : if (isConfigurationChanged(is_enabled_spi_2)) {
231 : stopSpi(SPI_DEVICE_2);
232 : }
233 :
234 : if (isConfigurationChanged(is_enabled_spi_3)) {
235 : stopSpi(SPI_DEVICE_3);
236 : }
237 :
238 : if (isConfigurationChanged(is_enabled_spi_4)) {
239 : stopSpi(SPI_DEVICE_4);
240 : }
241 :
242 : if (isConfigurationChanged(is_enabled_spi_5)) {
243 : stopSpi(SPI_DEVICE_5);
244 : }
245 :
246 : if (isConfigurationChanged(is_enabled_spi_6)) {
247 : stopSpi(SPI_DEVICE_6);
248 : }
249 : }
250 :
251 : void printSpiConfig(const char *msg, spi_device_e device) {
252 : efiPrintf("%s %s mosi=%s", msg, getSpi_device_e(device), hwPortname(getMosiPin(device)));
253 : efiPrintf("%s %s miso=%s", msg, getSpi_device_e(device), hwPortname(getMisoPin(device)));
254 : efiPrintf("%s %s sck=%s", msg, getSpi_device_e(device), hwPortname(getSckPin(device)));
255 : }
256 :
257 : #endif // HAL_USE_SPI
258 :
259 : #if HAL_USE_ADC
260 :
261 : static AdcToken fastMapSampleIndex;
262 : static AdcToken hipSampleIndex;
263 :
264 : #if HAL_TRIGGER_USE_ADC
265 : static AdcToken triggerSampleIndex;
266 : #endif // HAL_TRIGGER_USE_ADC
267 :
268 : /**
269 : * This method is not in the adc* lower-level file because it is more business logic then hardware.
270 : */
271 : void onFastAdcComplete(adcsample_t*) {
272 : ScopePerf perf(PE::AdcCallbackFast);
273 :
274 : #if HAL_TRIGGER_USE_ADC
275 : // we need to call this ASAP, because trigger processing is time-critical
276 : triggerAdcCallback(getFastAdc(triggerSampleIndex));
277 : #endif /* HAL_TRIGGER_USE_ADC */
278 :
279 : /**
280 : * this callback is executed 10 000 times a second, it needs to be as fast as possible
281 : */
282 : efiAssertVoid(ObdCode::CUSTOM_STACK_ADC, hasLotsOfRemainingStack(), "lowstck#9b");
283 :
284 : #if EFI_SENSOR_CHART && EFI_SHAFT_POSITION_INPUT
285 : if (getEngineState()->sensorChartMode == SC_AUX_FAST1) {
286 : /* Why we use raw value here? */
287 : float voltage = adcGetRawValue("fAux1", engineConfiguration->auxFastSensor1_adcChannel);
288 : scAddData(engine->triggerCentral.getCurrentEnginePhase(getTimeNowNt()).value_or(0), voltage);
289 : }
290 : #endif /* EFI_SENSOR_CHART */
291 :
292 : #if EFI_MAP_AVERAGING
293 : mapAveragingAdcCallback(adcRawValueToScaledVoltage(getFastAdc(fastMapSampleIndex), engineConfiguration->map.sensor.hwChannel));
294 : #endif /* EFI_MAP_AVERAGING */
295 : #if EFI_HIP_9011
296 : if (engineConfiguration->isHip9011Enabled) {
297 : hipAdcCallback(adcRawValueToScaledVoltage(getFastAdc(hipSampleIndex), engineConfiguration->hipOutputChannel));
298 : }
299 : #endif /* EFI_HIP_9011 */
300 : }
301 : #endif /* HAL_USE_ADC */
302 :
303 672 : static void calcFastAdcIndexes() {
304 : #if HAL_USE_ADC
305 : fastMapSampleIndex = enableFastAdcChannel("Fast MAP", engineConfiguration->map.sensor.hwChannel);
306 : hipSampleIndex = enableFastAdcChannel("HIP9011", engineConfiguration->hipOutputChannel);
307 : #if HAL_TRIGGER_USE_ADC
308 : triggerSampleIndex = enableFastAdcChannel("Trigger ADC", getAdcChannelForTrigger());
309 : #endif /* HAL_TRIGGER_USE_ADC */
310 :
311 : #endif/* HAL_USE_ADC */
312 672 : }
313 :
314 175 : static void adcConfigListener() {
315 : // todo: something is not right here - looks like should be a callback for each configuration change?
316 175 : calcFastAdcIndexes();
317 175 : }
318 :
319 : /**
320 : * this method is NOT currently invoked on ECU start
321 : * todo: reduce code duplication by moving more logic into startHardware method
322 : */
323 :
324 175 : void applyNewHardwareSettings() {
325 : /**
326 : * All 'stop' methods need to go before we begin starting pins.
327 : *
328 : * We take settings from 'activeConfiguration' not 'engineConfiguration' while stopping hardware.
329 : * Some hardware is restart unconditionally on change of parameters while for some systems we make extra effort and restart only
330 : * relevant settings were changes.
331 : *
332 : */
333 175 : ButtonDebounce::stopConfigurationList();
334 :
335 : #if EFI_PROD_CODE
336 : stopSensors();
337 : #endif // EFI_PROD_CODE
338 :
339 : #if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
340 : stopTriggerInputPins();
341 : #endif /* EFI_SHAFT_POSITION_INPUT */
342 :
343 : #if EFI_PROD_CODE && EFI_SENT_SUPPORT
344 : stopSent();
345 : #endif // EFI_SENT_SUPPORT
346 :
347 : #if EFI_CAN_SUPPORT
348 : stopCanPins();
349 : #endif /* EFI_CAN_SUPPORT */
350 :
351 175 : stopKLine();
352 :
353 : #if EFI_HIP_9011
354 : stopHip9011_pins();
355 : #endif /* EFI_HIP_9011 */
356 :
357 175 : stopHardware();
358 :
359 : #if HAL_USE_SPI
360 : stopSpiModules();
361 : #endif /* HAL_USE_SPI */
362 :
363 175 : if (isPinOrModeChanged(clutchUpPin, clutchUpPinMode)) {
364 : // bug? duplication with stopSwitchPins?
365 0 : efiSetPadUnused(activeConfiguration.clutchUpPin);
366 : }
367 :
368 : #if EFI_SHAFT_POSITION_INPUT
369 175 : stopTriggerDebugPins();
370 : #endif // EFI_SHAFT_POSITION_INPUT
371 :
372 175 : enginePins.unregisterPins();
373 :
374 : #if EFI_PROD_CODE
375 : reconfigureSensors();
376 : #endif /* EFI_PROD_CODE */
377 :
378 175 : ButtonDebounce::startConfigurationList();
379 :
380 : /*******************************************
381 : * Start everything back with new settings *
382 : ******************************************/
383 175 : startHardware();
384 :
385 : #if EFI_PROD_CODE && (BOARD_EXT_GPIOCHIPS > 0)
386 : /* TODO: properly restart gpio chips...
387 : * This is only workaround for "CS pin lost" bug
388 : * see: https://github.com/rusefi/rusefi/issues/2107
389 : * We should provide better way to gracefully stop all
390 : * gpio chips: set outputs to safe state, release all
391 : * on-chip resources (gpios, SPIs, etc) and then restart
392 : * with updated settings.
393 : * Following code just re-inits CS pins for all external
394 : * gpio chips, but does not update CS pin definition in
395 : * gpio chips private data/settings. So changing CS pin
396 : * on-fly does not work */
397 : startSmartCsPins();
398 : #endif /* (BOARD_EXT_GPIOCHIPS > 0) */
399 :
400 175 : startKLine();
401 :
402 : #if EFI_HIP_9011
403 : startHip9011_pins();
404 : #endif /* EFI_HIP_9011 */
405 :
406 :
407 : #if EFI_PROD_CODE && EFI_IDLE_CONTROL
408 : if (isIdleHardwareRestartNeeded()) {
409 : initIdleHardware();
410 : }
411 : #endif
412 :
413 : #if EFI_BOOST_CONTROL
414 175 : startBoostPin();
415 : #endif
416 : #if EFI_EMULATE_POSITION_SENSORS
417 175 : startTriggerEmulatorPins();
418 : #endif /* EFI_EMULATE_POSITION_SENSORS */
419 : #if EFI_LOGIC_ANALYZER
420 : startLogicAnalyzerPins();
421 : #endif /* EFI_LOGIC_ANALYZER */
422 : #if EFI_VVT_PID
423 : startVvtControlPins();
424 : #endif /* EFI_VVT_PID */
425 :
426 : #if EFI_PROD_CODE && EFI_SENT_SUPPORT
427 : startSent();
428 : #endif
429 :
430 175 : adcConfigListener();
431 175 : }
432 :
433 : #if EFI_PROD_CODE && EFI_BOR_LEVEL
434 : void setBor(int borValue) {
435 : efiPrintf("setting BOR to %d", borValue);
436 : BOR_Set((BOR_Level_t)borValue);
437 : }
438 : #endif /* EFI_BOR_LEVEL */
439 :
440 : // This function initializes hardware that can do so before configuration is loaded
441 0 : void initHardwareNoConfig() {
442 : efiAssertVoid(ObdCode::CUSTOM_IH_STACK, hasLotsOfRemainingStack(), "init h");
443 :
444 0 : efiPrintf("initHardware()");
445 :
446 : #if EFI_PROD_CODE
447 : initPinRepository();
448 : #endif
449 :
450 : #if EFI_HISTOGRAMS
451 : /**
452 : * histograms is a data structure for CPU monitor, it does not depend on configuration
453 : */
454 : initHistogramsModule();
455 : #endif /* EFI_HISTOGRAMS */
456 :
457 : #if EFI_GPIO_HARDWARE
458 : /**
459 : * We need the LED_ERROR pin even before we read configuration
460 : */
461 0 : initPrimaryPins();
462 : #endif // EFI_GPIO_HARDWARE
463 :
464 : #if EFI_PROD_CODE && EFI_SIGNAL_EXECUTOR_ONE_TIMER
465 : // it's important to initialize this pretty early in the game before any scheduling usages
466 : initSingleTimerExecutorHardware();
467 : #endif // EFI_PROD_CODE && EFI_SIGNAL_EXECUTOR_ONE_TIMER
468 :
469 : #if EFI_PROD_CODE && EFI_RTC
470 : initRtc();
471 : #endif // EFI_PROD_CODE && EFI_RTC
472 :
473 : #if EFI_CONFIGURATION_STORAGE
474 : initFlash();
475 : #endif
476 :
477 : #if EFI_FILE_LOGGING
478 : initEarlyMmcCard();
479 : #endif // EFI_FILE_LOGGING
480 :
481 : #if HAL_USE_PAL && EFI_PROD_CODE
482 : // this should be initialized before detectBoardType()
483 : efiExtiInit();
484 : #endif // HAL_USE_PAL
485 : }
486 :
487 175 : void stopHardware() {
488 175 : stopSwitchPins();
489 :
490 : #if EFI_PROD_CODE && (BOARD_EXT_GPIOCHIPS > 0)
491 : stopSmartCsPins();
492 : #endif /* (BOARD_EXT_GPIOCHIPS > 0) */
493 :
494 : #if EFI_LOGIC_ANALYZER
495 : stopLogicAnalyzerPins();
496 : #endif /* EFI_LOGIC_ANALYZER */
497 :
498 : #if EFI_EMULATE_POSITION_SENSORS
499 175 : stopTriggerEmulatorPins();
500 : #endif /* EFI_EMULATE_POSITION_SENSORS */
501 :
502 : #if EFI_VVT_PID
503 : stopVvtControlPins();
504 : #endif /* EFI_VVT_PID */
505 175 : }
506 :
507 : /**
508 : * This method is invoked both on ECU start and configuration change
509 : * At the moment we have too many system which handle ECU start and configuration change separately
510 : * TODO: move move hardware code here
511 : */
512 672 : void startHardware() {
513 : #if EFI_SHAFT_POSITION_INPUT
514 672 : initStartStopButton();
515 : #endif
516 :
517 : #if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
518 : startTriggerInputPins();
519 : #endif /* EFI_SHAFT_POSITION_INPUT */
520 :
521 : #if EFI_ENGINE_CONTROL
522 672 : enginePins.startPins();
523 : #endif /* EFI_ENGINE_CONTROL */
524 :
525 : #if EFI_SHAFT_POSITION_INPUT
526 672 : validateTriggerInputs();
527 :
528 672 : startTriggerDebugPins();
529 :
530 : #endif // EFI_SHAFT_POSITION_INPUT
531 :
532 672 : startSwitchPins();
533 :
534 : #if EFI_CAN_SUPPORT
535 : startCanPins();
536 : #endif /* EFI_CAN_SUPPORT */
537 672 : }
538 :
539 : // Weak link a stub so that every board doesn't have to implement this function
540 497 : PUBLIC_API_WEAK void boardInitHardware() { }
541 497 : PUBLIC_API_WEAK void boardInitHardwareExtra() { }
542 :
543 0 : PUBLIC_API_WEAK void setPinConfigurationOverrides() { }
544 :
545 : #if HAL_USE_I2C
546 : const I2CConfig i2cfg = {
547 : OPMODE_I2C,
548 : 400000,
549 : FAST_DUTY_CYCLE_2,
550 : };
551 : #endif
552 :
553 497 : void initHardware() {
554 497 : if (hasFirmwareError()) {
555 0 : return;
556 : }
557 :
558 : #if EFI_PROD_CODE && STM32_I2C_USE_I2C3
559 : if (engineConfiguration->useEeprom) {
560 : i2cStart(&EE_U2CD, &i2cfg);
561 : }
562 : #endif // STM32_I2C_USE_I2C3
563 :
564 497 : boardInitHardware();
565 497 : boardInitHardwareExtra();
566 :
567 : #if HAL_USE_ADC
568 : initAdcInputs();
569 :
570 : // wait for first set of ADC values so that we do not produce invalid sensor data
571 : waitForSlowAdc();
572 : #endif /* HAL_USE_ADC */
573 :
574 : #if EFI_SOFTWARE_KNOCK
575 : initSoftwareKnock();
576 : #endif /* EFI_SOFTWARE_KNOCK */
577 :
578 : #ifdef TRIGGER_SCOPE
579 : initTriggerScope();
580 : #endif // TRIGGER_SCOPE
581 :
582 : #if HAL_USE_SPI
583 : initSpiModules();
584 : #endif /* HAL_USE_SPI */
585 :
586 : #if (EFI_PROD_CODE && BOARD_EXT_GPIOCHIPS > 0) || EFI_SIMULATOR
587 : // initSmartGpio depends on 'initSpiModules'
588 : initSmartGpio();
589 : #endif
590 :
591 : // output pins potentially depend on 'initSmartGpio'
592 497 : initMiscOutputPins();
593 :
594 : #if EFI_MC33816
595 : initMc33816();
596 : #endif /* EFI_MC33816 */
597 :
598 : #if EFI_CAN_SUPPORT
599 : #if EFI_SIMULATOR
600 : // Set CAN device name
601 : CAND1.deviceName = "can0";
602 : #endif
603 :
604 : initCan();
605 : #endif /* EFI_CAN_SUPPORT */
606 :
607 :
608 : #if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
609 : onEcuStartTriggerImplementation();
610 : #endif /* EFI_SHAFT_POSITION_INPUT */
611 497 : onEcuStartDoSomethingTriggerInputPins();
612 :
613 : #if EFI_HIP_9011
614 : initHip9011();
615 : #endif /* EFI_HIP_9011 */
616 :
617 : #if EFI_WS2812
618 : initWS2812();
619 : #endif /* EFI_LED_WS2812 */
620 :
621 : #if EFI_ONBOARD_MEMS
622 : initAccelerometer();
623 : #endif
624 :
625 : #if EFI_BOSCH_YAW
626 : initBoschYawRateSensor();
627 : #endif /* EFI_BOSCH_YAW */
628 :
629 : #if EFI_UART_GPS
630 : initGps();
631 : #endif
632 :
633 : #if EFI_CAN_SUPPORT
634 : initCanVssSupport();
635 : #endif // EFI_CAN_SUPPORT
636 :
637 : #if EFI_CDM_INTEGRATION
638 : cdmIonInit();
639 : #endif // EFI_CDM_INTEGRATION
640 :
641 : #if EFI_PROD_CODE && EFI_SENT_SUPPORT
642 : initSent();
643 : #endif
644 :
645 497 : initKLine();
646 :
647 : #if EFI_DAC
648 : initDac();
649 : #endif
650 :
651 497 : calcFastAdcIndexes();
652 :
653 497 : startHardware();
654 :
655 497 : efiPrintf("initHardware() OK!");
656 : }
657 :
658 : #if HAL_USE_SPI
659 : // this is F4 implementation but we will keep it here for now for simplicity
660 : int getSpiPrescaler(spi_speed_e speed, spi_device_e device) {
661 : switch (speed) {
662 : case _5MHz:
663 : return device == SPI_DEVICE_1 ? SPI_BaudRatePrescaler_16 : SPI_BaudRatePrescaler_8;
664 : case _2_5MHz:
665 : return device == SPI_DEVICE_1 ? SPI_BaudRatePrescaler_32 : SPI_BaudRatePrescaler_16;
666 : case _1_25MHz:
667 : return device == SPI_DEVICE_1 ? SPI_BaudRatePrescaler_64 : SPI_BaudRatePrescaler_32;
668 :
669 : case _150KHz:
670 : // SPI1 does not support 150KHz, it would be 300KHz for SPI1
671 : return SPI_BaudRatePrescaler_256;
672 : default:
673 : // unexpected
674 : return 0;
675 : }
676 : }
677 :
678 : #endif /* HAL_USE_SPI */
679 :
680 0 : void checkLastResetCause() {
681 : #if EFI_PROD_CODE
682 : Reset_Cause_t cause = getMCUResetCause();
683 : const char *causeStr = getMCUResetCause(cause);
684 : efiPrintf("Last Reset Cause: %s", causeStr);
685 :
686 : // if reset by watchdog, signal a fatal error
687 : if (cause == Reset_Cause_IWatchdog || cause == Reset_Cause_WWatchdog) {
688 : firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Watchdog Reset");
689 : }
690 : #endif // EFI_PROD_CODE
691 0 : }
|