LCOV - code coverage report
Current view: top level - firmware/hw_layer - hardware.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 50 84.0 %
Date: 2024-07-27 03:14:29 Functions: 8 11 72.7 %

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

Generated by: LCOV version 1.14