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-04-25 02:23:43 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 "AdcConfiguration.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 "svnversion.h"
      47             : #include "vvt.h"
      48             : #include "trigger_emulator_algo.h"
      49             : #include "boost_control.h"
      50             : #include "software_knock.h"
      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_STORAGE_INT_FLASH == TRUE) || (EFI_STORAGE_MFS == TRUE)
      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 NULL;
     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 NULL;
     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 FastAdcToken fastMapSampleIndex;
     262             : static FastAdcToken hipSampleIndex;
     263             : 
     264             : #if HAL_TRIGGER_USE_ADC
     265             : static FastAdcToken triggerSampleIndex;
     266             : #endif // HAL_TRIGGER_USE_ADC
     267             : 
     268             : extern AdcDevice fastAdc;
     269             : 
     270             : #ifdef FAST_ADC_SKIP
     271             : // No reason to enable if N = 1
     272             : static_assert(FAST_ADC_SKIP > 1);
     273             : static size_t fastAdcSkipCount = 0;
     274             : #endif // FAST_ADC_SKIP
     275             : 
     276             : /**
     277             :  * This method is not in the adc* lower-level file because it is more business logic then hardware.
     278             :  */
     279             : void onFastAdcComplete(adcsample_t*) {
     280             :         ScopePerf perf(PE::AdcCallbackFast);
     281             : 
     282             : #if HAL_TRIGGER_USE_ADC
     283             :         // we need to call this ASAP, because trigger processing is time-critical
     284             :         triggerAdcCallback(getFastAdc(triggerSampleIndex));
     285             : #endif /* HAL_TRIGGER_USE_ADC */
     286             : 
     287             : #ifdef FAST_ADC_SKIP
     288             :         // If we run the fast ADC _very_ fast for triggerAdcCallback's benefit, we may want to
     289             :         // skip most of the samples for the rest of the callback.
     290             :         if (fastAdcSkipCount++ == FAST_ADC_SKIP) {
     291             :                 fastAdcSkipCount = 0;
     292             :         } else {
     293             :                 return;
     294             :         }
     295             : #endif
     296             : 
     297             :         /**
     298             :          * this callback is executed 10 000 times a second, it needs to be as fast as possible
     299             :          */
     300             :         efiAssertVoid(ObdCode::CUSTOM_STACK_ADC, hasLotsOfRemainingStack(), "lowstck#9b");
     301             : 
     302             : #if EFI_SENSOR_CHART && EFI_SHAFT_POSITION_INPUT
     303             :         if (getEngineState()->sensorChartMode == SC_AUX_FAST1) {
     304             :                 float voltage = getAdcValue("fAux1", engineConfiguration->auxFastSensor1_adcChannel);
     305             :                 scAddData(engine->triggerCentral.getCurrentEnginePhase(getTimeNowNt()).value_or(0), voltage);
     306             :         }
     307             : #endif /* EFI_SENSOR_CHART */
     308             : 
     309             : #if EFI_MAP_AVERAGING
     310             :         mapAveragingAdcCallback(adcToVoltsDivided(getFastAdc(fastMapSampleIndex), engineConfiguration->map.sensor.hwChannel));
     311             : #endif /* EFI_MAP_AVERAGING */
     312             : #if EFI_HIP_9011
     313             :         if (engineConfiguration->isHip9011Enabled) {
     314             :                 hipAdcCallback(adcToVoltsDivided(getFastAdc(hipSampleIndex), engineConfiguration->hipOutputChannel));
     315             :         }
     316             : #endif /* EFI_HIP_9011 */
     317             : }
     318             : #endif /* HAL_USE_ADC */
     319             : 
     320         453 : static void calcFastAdcIndexes() {
     321             : #if HAL_USE_ADC
     322             :         fastMapSampleIndex = enableFastAdcChannel("Fast MAP", engineConfiguration->map.sensor.hwChannel);
     323             :         hipSampleIndex = enableFastAdcChannel("HIP9011", engineConfiguration->hipOutputChannel);
     324             : #if HAL_TRIGGER_USE_ADC
     325             :         triggerSampleIndex = enableFastAdcChannel("Trigger ADC", getAdcChannelForTrigger());
     326             : #endif /* HAL_TRIGGER_USE_ADC */
     327             : 
     328             : #endif/* HAL_USE_ADC */
     329         453 : }
     330             : 
     331         147 : static void adcConfigListener() {
     332             :         // todo: something is not right here - looks like should be a callback for each configuration change?
     333         147 :         calcFastAdcIndexes();
     334         147 : }
     335             : 
     336             : /**
     337             :  * this method is NOT currently invoked on ECU start
     338             :  * todo: reduce code duplication by moving more logic into startHardware method
     339             :  */
     340             : 
     341         147 : void applyNewHardwareSettings() {
     342             :     /**
     343             :      * All 'stop' methods need to go before we begin starting pins.
     344             :      *
     345             :      * We take settings from 'activeConfiguration' not 'engineConfiguration' while stopping hardware.
     346             :      * Some hardware is restart unconditionally on change of parameters while for some systems we make extra effort and restart only
     347             :      * relevant settings were changes.
     348             :      *
     349             :      */
     350         147 :         ButtonDebounce::stopConfigurationList();
     351             : 
     352             : #if EFI_PROD_CODE
     353             :         stopSensors();
     354             : #endif // EFI_PROD_CODE
     355             : 
     356             : #if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
     357             :         stopTriggerInputPins();
     358             : #endif /* EFI_SHAFT_POSITION_INPUT */
     359             : 
     360             : #if EFI_SENT_SUPPORT
     361             :         stopSent();
     362             : #endif // EFI_SENT_SUPPORT
     363             : 
     364             : #if EFI_CAN_SUPPORT
     365             :         stopCanPins();
     366             : #endif /* EFI_CAN_SUPPORT */
     367             : 
     368         147 :         stopKLine();
     369             : 
     370             : #if EFI_AUX_SERIAL
     371             :         stopAuxSerialPins();
     372             : #endif /* EFI_AUX_SERIAL */
     373             : 
     374             : #if EFI_HIP_9011
     375             :         stopHip9001_pins();
     376             : #endif /* EFI_HIP_9011 */
     377             : 
     378         147 :         stopHardware();
     379             : 
     380             : #if HAL_USE_SPI
     381             :         stopSpiModules();
     382             : #endif /* HAL_USE_SPI */
     383             : 
     384         147 :         if (isPinOrModeChanged(clutchUpPin, clutchUpPinMode)) {
     385             :                 // bug? duplication with stopSwitchPins?
     386           0 :                 efiSetPadUnused(activeConfiguration.clutchUpPin);
     387             :         }
     388             : 
     389             : #if EFI_SHAFT_POSITION_INPUT
     390         147 :         stopTriggerDebugPins();
     391             : #endif // EFI_SHAFT_POSITION_INPUT
     392             : 
     393         147 :         enginePins.unregisterPins();
     394             : 
     395             : #if EFI_PROD_CODE
     396             :         reconfigureSensors();
     397             : #endif /* EFI_PROD_CODE */
     398             : 
     399         147 :         ButtonDebounce::startConfigurationList();
     400             : 
     401             :         /*******************************************
     402             :          * Start everything back with new settings *
     403             :          ******************************************/
     404         147 :         startHardware();
     405             : 
     406             : #if EFI_PROD_CODE && (BOARD_EXT_GPIOCHIPS > 0)
     407             :         /* TODO: properly restart gpio chips...
     408             :          * This is only workaround for "CS pin lost" bug
     409             :          * see: https://github.com/rusefi/rusefi/issues/2107
     410             :          * We should provide better way to gracefully stop all
     411             :          * gpio chips: set outputs to safe state, release all
     412             :          * on-chip resources (gpios, SPIs, etc) and then restart
     413             :          * with updated settings.
     414             :          * Following code just re-inits CS pins for all external
     415             :          * gpio chips, but does not update CS pin definition in
     416             :          * gpio chips private data/settings. So changing CS pin
     417             :          * on-fly does not work */
     418             :         startSmartCsPins();
     419             : #endif /* (BOARD_EXT_GPIOCHIPS > 0) */
     420             : 
     421             : #if EFI_AUX_SERIAL
     422             :         startAuxSerialPins();
     423             : #endif /* EFI_AUX_SERIAL */
     424             : 
     425         147 :     startKLine();
     426             : 
     427             : 
     428             : #if EFI_HIP_9011
     429             :         startHip9001_pins();
     430             : #endif /* EFI_HIP_9011 */
     431             : 
     432             : 
     433             : #if EFI_PROD_CODE && EFI_IDLE_CONTROL
     434             :         if (isIdleHardwareRestartNeeded()) {
     435             :                  initIdleHardware();
     436             :         }
     437             : #endif
     438             : 
     439             : #if EFI_BOOST_CONTROL
     440         147 :         startBoostPin();
     441             : #endif
     442             : #if EFI_EMULATE_POSITION_SENSORS
     443         147 :         startTriggerEmulatorPins();
     444             : #endif /* EFI_EMULATE_POSITION_SENSORS */
     445             : #if EFI_LOGIC_ANALYZER
     446             :         startLogicAnalyzerPins();
     447             : #endif /* EFI_LOGIC_ANALYZER */
     448             : #if EFI_VVT_PID
     449             :         startVvtControlPins();
     450             : #endif /* EFI_VVT_PID */
     451             : 
     452             : #if EFI_SENT_SUPPORT
     453             :         startSent();
     454             : #endif
     455             : 
     456         147 :         adcConfigListener();
     457         147 : }
     458             : 
     459             : #if EFI_PROD_CODE && EFI_BOR_LEVEL
     460             : void setBor(int borValue) {
     461             :         efiPrintf("setting BOR to %d", borValue);
     462             :         BOR_Set((BOR_Level_t)borValue);
     463             : }
     464             : #endif /* EFI_BOR_LEVEL */
     465             : 
     466             : // This function initializes hardware that can do so before configuration is loaded
     467           0 : void initHardwareNoConfig() {
     468             :         efiAssertVoid(ObdCode::CUSTOM_IH_STACK, hasLotsOfRemainingStack(), "init h");
     469             : 
     470           0 :         efiPrintf("initHardware()");
     471             : 
     472             : #if EFI_PROD_CODE
     473             :         initPinRepository();
     474             : #endif
     475             : 
     476             : #if EFI_HISTOGRAMS
     477             :         /**
     478             :          * histograms is a data structure for CPU monitor, it does not depend on configuration
     479             :          */
     480             :         initHistogramsModule();
     481             : #endif /* EFI_HISTOGRAMS */
     482             : 
     483             : #if EFI_GPIO_HARDWARE
     484             :         /**
     485             :          * We need the LED_ERROR pin even before we read configuration
     486             :          */
     487           0 :         initPrimaryPins();
     488             : #endif // EFI_GPIO_HARDWARE
     489             : 
     490             : #if EFI_PROD_CODE && EFI_SIGNAL_EXECUTOR_ONE_TIMER
     491             :         // it's important to initialize this pretty early in the game before any scheduling usages
     492             :         initSingleTimerExecutorHardware();
     493             : #endif // EFI_PROD_CODE && EFI_SIGNAL_EXECUTOR_ONE_TIMER
     494             : 
     495             : #if EFI_PROD_CODE && EFI_RTC
     496             :         initRtc();
     497             : #endif // EFI_PROD_CODE && EFI_RTC
     498             : 
     499             : #if (EFI_STORAGE_INT_FLASH == TRUE) || (EFI_STORAGE_MFS == TRUE)
     500             :         initFlash();
     501             : #endif
     502             : 
     503             : #if EFI_FILE_LOGGING
     504             :         initEarlyMmcCard();
     505             : #endif // EFI_FILE_LOGGING
     506             : 
     507             : #if HAL_USE_PAL && EFI_PROD_CODE
     508             :         // this should be initialized before detectBoardType()
     509             :         efiExtiInit();
     510             : #endif // HAL_USE_PAL
     511             : }
     512             : 
     513         147 : void stopHardware() {
     514         147 :         stopSwitchPins();
     515             : 
     516             : #if EFI_PROD_CODE && (BOARD_EXT_GPIOCHIPS > 0)
     517             :         stopSmartCsPins();
     518             : #endif /* (BOARD_EXT_GPIOCHIPS > 0) */
     519             : 
     520             : #if EFI_LOGIC_ANALYZER
     521             :         stopLogicAnalyzerPins();
     522             : #endif /* EFI_LOGIC_ANALYZER */
     523             : 
     524             : #if EFI_EMULATE_POSITION_SENSORS
     525         147 :         stopTriggerEmulatorPins();
     526             : #endif /* EFI_EMULATE_POSITION_SENSORS */
     527             : 
     528             : #if EFI_VVT_PID
     529             :         stopVvtControlPins();
     530             : #endif /* EFI_VVT_PID */
     531         147 : }
     532             : 
     533             : /**
     534             :  * This method is invoked both on ECU start and configuration change
     535             :  * At the moment we have too many system which handle ECU start and configuration change separately
     536             :  * TODO: move move hardware code here
     537             :  */
     538         453 : void startHardware() {
     539         453 :         initStartStopButton();
     540             : 
     541             : #if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
     542             :         startTriggerInputPins();
     543             : #endif /* EFI_SHAFT_POSITION_INPUT */
     544             : 
     545             : #if EFI_ENGINE_CONTROL
     546         453 :         enginePins.startPins();
     547             : #endif /* EFI_ENGINE_CONTROL */
     548             : 
     549             : #if EFI_SHAFT_POSITION_INPUT
     550         453 :         validateTriggerInputs();
     551             : 
     552         453 :         startTriggerDebugPins();
     553             : 
     554             : #endif // EFI_SHAFT_POSITION_INPUT
     555             : 
     556         453 :         startSwitchPins();
     557             : 
     558             : #if EFI_CAN_SUPPORT
     559             :         startCanPins();
     560             : #endif /* EFI_CAN_SUPPORT */
     561         453 : }
     562             : 
     563             : // Weak link a stub so that every board doesn't have to implement this function
     564         306 : PUBLIC_API_WEAK void boardInitHardware() { }
     565         306 : PUBLIC_API_WEAK void boardInitHardwareExtra() { }
     566             : 
     567           0 : PUBLIC_API_WEAK void setPinConfigurationOverrides() { }
     568             : 
     569             : #if HAL_USE_I2C
     570             : const I2CConfig i2cfg = {
     571             :     OPMODE_I2C,
     572             :     400000,
     573             :     FAST_DUTY_CYCLE_2,
     574             : };
     575             : #endif
     576             : 
     577         306 : void initHardware() {
     578         306 :         if (hasFirmwareError()) {
     579           0 :                 return;
     580             :         }
     581             : 
     582             : #if EFI_PROD_CODE && STM32_I2C_USE_I2C3
     583             :         if (engineConfiguration->useEeprom) {
     584             :             i2cStart(&EE_U2CD, &i2cfg);
     585             :         }
     586             : #endif // STM32_I2C_USE_I2C3
     587             : 
     588         306 :         boardInitHardware();
     589         306 :         boardInitHardwareExtra();
     590             : 
     591             : #if HAL_USE_ADC
     592             :         initAdcInputs();
     593             : 
     594             :         // wait for first set of ADC values so that we do not produce invalid sensor data
     595             :         waitForSlowAdc(1);
     596             : #endif /* HAL_USE_ADC */
     597             : 
     598             : #if EFI_SOFTWARE_KNOCK
     599             :         initSoftwareKnock();
     600             : #endif /* EFI_SOFTWARE_KNOCK */
     601             : 
     602             : #ifdef TRIGGER_SCOPE
     603             :         initTriggerScope();
     604             : #endif // TRIGGER_SCOPE
     605             : 
     606             : #if HAL_USE_SPI
     607             :         initSpiModules();
     608             : #endif /* HAL_USE_SPI */
     609             : 
     610             : #if (EFI_PROD_CODE && BOARD_EXT_GPIOCHIPS > 0) || EFI_SIMULATOR
     611             :         // initSmartGpio depends on 'initSpiModules'
     612             :         initSmartGpio();
     613             : #endif
     614             : 
     615             :         // output pins potentially depend on 'initSmartGpio'
     616         306 :         initMiscOutputPins();
     617             : 
     618             : #if EFI_MC33816
     619             :         initMc33816();
     620             : #endif /* EFI_MC33816 */
     621             : 
     622             : #if EFI_CAN_SUPPORT
     623             : #if EFI_SIMULATOR
     624             :         // Set CAN device name
     625             :         CAND1.deviceName = "can0";
     626             : #endif
     627             : 
     628             :         initCan();
     629             : #endif /* EFI_CAN_SUPPORT */
     630             : 
     631             : 
     632             : #if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
     633             :         onEcuStartTriggerImplementation();
     634             : #endif /* EFI_SHAFT_POSITION_INPUT */
     635         306 :         onEcuStartDoSomethingTriggerInputPins();
     636             : 
     637             : #if EFI_HIP_9011
     638             :         initHip9011();
     639             : #endif /* EFI_HIP_9011 */
     640             : 
     641             : #if EFI_WS2812
     642             :         initWS2812();
     643             : #endif /* EFI_LED_WS2812 */
     644             : 
     645             : #if EFI_ONBOARD_MEMS
     646             :         initAccelerometer();
     647             : #endif
     648             : 
     649             : #if EFI_BOSCH_YAW
     650             :         initBoschYawRateSensor();
     651             : #endif /* EFI_BOSCH_YAW */
     652             : 
     653             : #if EFI_UART_GPS
     654             :         initGps();
     655             : #endif
     656             : 
     657             : #if EFI_AUX_SERIAL
     658             :         initAuxSerial();
     659             : #endif /* EFI_AUX_SERIAL */
     660             : 
     661             : #if EFI_CAN_SUPPORT
     662             :         initCanVssSupport();
     663             : #endif // EFI_CAN_SUPPORT
     664             : 
     665             : #if EFI_CDM_INTEGRATION
     666             :         cdmIonInit();
     667             : #endif // EFI_CDM_INTEGRATION
     668             : 
     669             : #if EFI_SENT_SUPPORT
     670             :         initSent();
     671             : #endif
     672             : 
     673         306 :         initKLine();
     674             : 
     675             : #if EFI_DAC
     676             :         initDac();
     677             : #endif
     678             : 
     679         306 :         calcFastAdcIndexes();
     680             : 
     681         306 :         startHardware();
     682             : 
     683         306 :         efiPrintf("initHardware() OK!");
     684             : }
     685             : 
     686             : #if HAL_USE_SPI
     687             : // this is F4 implementation but we will keep it here for now for simplicity
     688             : int getSpiPrescaler(spi_speed_e speed, spi_device_e device) {
     689             :         switch (speed) {
     690             :         case _5MHz:
     691             :                 return device == SPI_DEVICE_1 ? SPI_BaudRatePrescaler_16 : SPI_BaudRatePrescaler_8;
     692             :         case _2_5MHz:
     693             :                 return device == SPI_DEVICE_1 ? SPI_BaudRatePrescaler_32 : SPI_BaudRatePrescaler_16;
     694             :         case _1_25MHz:
     695             :                 return device == SPI_DEVICE_1 ? SPI_BaudRatePrescaler_64 : SPI_BaudRatePrescaler_32;
     696             : 
     697             :         case _150KHz:
     698             :                 // SPI1 does not support 150KHz, it would be 300KHz for SPI1
     699             :                 return SPI_BaudRatePrescaler_256;
     700             :         default:
     701             :                 // unexpected
     702             :                 return 0;
     703             :         }
     704             : }
     705             : 
     706             : #endif /* HAL_USE_SPI */
     707             : 
     708           0 : void checkLastResetCause() {
     709             : #if EFI_PROD_CODE
     710             :         Reset_Cause_t cause = getMCUResetCause();
     711             :         const char *causeStr = getMCUResetCause(cause);
     712             :         efiPrintf("Last Reset Cause: %s", causeStr);
     713             : 
     714             :         // if reset by watchdog, signal a fatal error
     715             :         if (cause == Reset_Cause_IWatchdog || cause == Reset_Cause_WWatchdog) {
     716             :                 firmwareError(ObdCode::OBD_PCM_Processor_Fault, "Watchdog Reset");
     717             :         }
     718             : #endif // EFI_PROD_CODE
     719           0 : }

Generated by: LCOV version 1.14