diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index d122aa81b4..920c0c916a 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -937,7 +937,7 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ tsOutputChannels->debugIntField1 = engine->triggerCentral.getHwEventCounter((int)SHAFT_PRIMARY_FALLING); tsOutputChannels->debugIntField2 = engine->triggerCentral.getHwEventCounter((int)SHAFT_SECONDARY_FALLING); tsOutputChannels->debugIntField3 = engine->triggerCentral.getHwEventCounter((int)SHAFT_3RD_FALLING); -#if EFI_PROD_CODE +#if EFI_PROD_CODE && HAL_USE_ICU == TRUE tsOutputChannels->debugIntField4 = engine->triggerCentral.vvtEventRiseCounter; tsOutputChannels->debugIntField5 = engine->triggerCentral.vvtEventFallCounter; tsOutputChannels->debugFloatField5 = icuWidthCallbackCounter + icuWidthPeriodCounter; diff --git a/firmware/controllers/algo/engine.h b/firmware/controllers/algo/engine.h index f2c69a408b..7f8693f9e0 100644 --- a/firmware/controllers/algo/engine.h +++ b/firmware/controllers/algo/engine.h @@ -62,6 +62,11 @@ public: */ int globalSparkIdCounter = 0; + // this is useful at least for real hardware integration testing - maybe a proper solution would be to simply + // GND input pins instead of leaving them floating + bool hwTriggerInputEnabled = true; + + #if !EFI_PROD_CODE float mockMapValue = 0; // for historical reasons we have options to mock TPS on different layers :( diff --git a/firmware/controllers/settings.cpp b/firmware/controllers/settings.cpp index 96e14acd65..98cca9c5e6 100644 --- a/firmware/controllers/settings.cpp +++ b/firmware/controllers/settings.cpp @@ -887,13 +887,11 @@ static void setSpiMode(int index, bool mode) { printSpiState(&logger, boardConfiguration); } -extern bool hwTriggerInputEnabled; - static void enableOrDisable(const char *param, bool isEnabled) { if (strEqualCaseInsensitive(param, "fastadc")) { boardConfiguration->isFastAdcEnabled = isEnabled; } else if (strEqualCaseInsensitive(param, CMD_TRIGGER_HW_INPUT)) { - hwTriggerInputEnabled = isEnabled; + engine->hwTriggerInputEnabled = isEnabled; } else if (strEqualCaseInsensitive(param, "etb_auto")) { engine->etbAutoTune = isEnabled; } else if (strEqualCaseInsensitive(param, "cranking_constant_dwell")) { diff --git a/firmware/controllers/trigger/trigger_central.cpp b/firmware/controllers/trigger/trigger_central.cpp index 4545925e4f..3374fd0d1b 100644 --- a/firmware/controllers/trigger/trigger_central.cpp +++ b/firmware/controllers/trigger/trigger_central.cpp @@ -511,7 +511,6 @@ extern int perSecondIrqCounter; #if EFI_PROD_CODE extern uint32_t maxPrecisionCallbackDuration; -extern bool hwTriggerInputEnabled; #endif /* EFI_PROD_CODE */ extern uint32_t maxSchedulingPrecisionLoss; @@ -545,11 +544,11 @@ void triggerInfo(void) { #if (HAL_TRIGGER_USE_PAL == TRUE) && (PAL_USE_CALLBACKS == TRUE) - scheduleMsg(logger, "trigger PAL mode %d", hwTriggerInputEnabled); + scheduleMsg(logger, "trigger PAL mode %d", engine->hwTriggerInputEnabled); #else #if HAL_USE_ICU == TRUE - scheduleMsg(logger, "trigger ICU hw: %d %d %d", icuWidthCallbackCounter, icuWidthPeriodCounter, hwTriggerInputEnabled); + scheduleMsg(logger, "trigger ICU hw: %d %d %d", icuWidthCallbackCounter, icuWidthPeriodCounter, engine->hwTriggerInputEnabled); #endif /* HAL_USE_ICU */ #endif /* HAL_TRIGGER_USE_PAL */ diff --git a/firmware/hw_layer/trigger_input.cpp b/firmware/hw_layer/trigger_input.cpp index 11bcf46c99..ec10a36a03 100644 --- a/firmware/hw_layer/trigger_input.cpp +++ b/firmware/hw_layer/trigger_input.cpp @@ -10,6 +10,41 @@ #if (EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT) || defined(__DOXYGEN__) +EXTERN_ENGINE; + +#if (HAL_USE_ICU == TRUE) || (HAL_TRIGGER_USE_PAL == TRUE) +void stopTriggerInputPins(void) { + for (int i = 0; i < TRIGGER_SUPPORTED_CHANNELS; i++) { + if (isConfigurationChanged(bc.triggerInputPins[i])) { + turnOffTriggerInputPin(activeConfiguration.bc.triggerInputPins[i]); + } + } + for (int i = 0; i < CAM_INPUTS_COUNT; i++) { + if (isConfigurationChanged(camInputs[i])) { + turnOffTriggerInputPin(activeConfiguration.camInputs[i]); + } + } +} + +void startTriggerInputPins(void) { + for (int i = 0; i < TRIGGER_SUPPORTED_CHANNELS; i++) { + if (isConfigurationChanged(bc.triggerInputPins[i])) { + const char * msg = (i == 0 ? "trigger#1" : (i == 1 ? "trigger#2" : "trigger#3")); + turnOnTriggerInputPin(msg, CONFIGB(triggerInputPins)[i], true); + } + } + + for (int i = 0; i < CAM_INPUTS_COUNT; i++) { + if (isConfigurationChanged(camInputs[i])) { + turnOnTriggerInputPin("cam", engineConfiguration->camInputs[i], false); + } + } + + setPrimaryChannel(CONFIGB(triggerInputPins)[0]); +} +#endif + + void applyNewTriggerInputPins(void) { // first we will turn off all the changed pins stopTriggerInputPins(); diff --git a/firmware/hw_layer/trigger_input.h b/firmware/hw_layer/trigger_input.h index aacdcd6132..cf7c44422c 100644 --- a/firmware/hw_layer/trigger_input.h +++ b/firmware/hw_layer/trigger_input.h @@ -3,13 +3,16 @@ * @brief Position sensor hardware layer * * @date Dec 30, 2012 - * @author Andrey Belomutskiy, (c) 2012-2017 + * @author Andrey Belomutskiy, (c) 2012-2019 */ #ifndef CRANK_INPUT_H_ #define CRANK_INPUT_H_ #include "engine.h" +#include "pin_repository.h" +#include "trigger_structure.h" +#include "trigger_central.h" #define TRIGGER_SUPPORTED_CHANNELS 2 @@ -17,5 +20,8 @@ void turnOnTriggerInputPins(Logging *sharedLogger); void applyNewTriggerInputPins(void); void startTriggerInputPins(void); void stopTriggerInputPins(void); +void setPrimaryChannel(brain_pin_e brainPin); +void turnOffTriggerInputPin(brain_pin_e brainPin); +int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool isVvtShaft); #endif /* CRANK_INPUT_H_ */ diff --git a/firmware/hw_layer/trigger_input_comp.cpp b/firmware/hw_layer/trigger_input_comp.cpp index 048f528829..c032d9e3f6 100644 --- a/firmware/hw_layer/trigger_input_comp.cpp +++ b/firmware/hw_layer/trigger_input_comp.cpp @@ -15,10 +15,7 @@ #include "trigger_input.h" #include "digital_input_hw.h" -#include "pin_repository.h" -#include "trigger_structure.h" -#include "trigger_central.h" -#include "engine_configuration.h" + extern bool hasFirmwareErrorFlag; diff --git a/firmware/hw_layer/trigger_input_exti.cpp b/firmware/hw_layer/trigger_input_exti.cpp index 521fa61a52..92e8032097 100644 --- a/firmware/hw_layer/trigger_input_exti.cpp +++ b/firmware/hw_layer/trigger_input_exti.cpp @@ -14,4 +14,78 @@ #if EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE) && (HAL_USE_COMP == FALSE) +#include "trigger_input.h" +#include "digital_input_exti.h" + +extern bool hasFirmwareErrorFlag; + +static Logging *logger; + +EXTERN_ENGINE; +static ioline_t primary_line; + +static void shaft_callback(void *arg) { + ioline_t pal_line = (ioline_t)arg; + // todo: support for 3rd trigger input channel + // todo: start using real event time from HW event, not just software timer? + if (hasFirmwareErrorFlag) + return; + + bool isPrimary = pal_line == primary_line; + if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) { + return; + } + + bool rise = (palReadLine(pal_line) == PAL_HIGH); + trigger_event_e signal; + // todo: add support for 3rd channel + if (rise) { + signal = isPrimary ? + (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_FALLING : SHAFT_PRIMARY_RISING) : + (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_FALLING : SHAFT_SECONDARY_RISING); + } else { + signal = isPrimary ? + (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_RISING : SHAFT_PRIMARY_FALLING) : + (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_RISING : SHAFT_SECONDARY_FALLING); + } + + hwHandleShaftSignal(signal); +} + +static void cam_callback(void *arg) { + ioline_t pal_line = (ioline_t)arg; + + bool rise = (palReadLine(pal_line) == PAL_HIGH); + + if (rise) { + hwHandleVvtCamSignal(TV_RISE); + } else { + hwHandleVvtCamSignal(TV_FALL); + } +} + +int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool isVvtShaft) { + scheduleMsg(logger, "turnOnTriggerInputPin(PAL) %s %s", msg, hwPortname(brainPin)); + + /* TODO: + * * do not set to both edges if we need only one + * * simplify callback in case of one edge */ + ioline_t pal_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin)); + return efiExtiEnablePin(msg, brainPin, PAL_EVENT_MODE_BOTH_EDGES, isVvtShaft ? shaft_callback : cam_callback, (void *)pal_line); +} + +void turnOffTriggerInputPin(brain_pin_e brainPin) { + efiExtiDisablePin(brainPin); +} + +void setPrimaryChannel(brain_pin_e brainPin) { + primary_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin)); +} + +void turnOnTriggerInputPins(Logging *sharedLogger) { + logger = sharedLogger; + + applyNewTriggerInputPins(); +} + #endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE) && (HAL_USE_COMP == FALSE)) */ diff --git a/firmware/hw_layer/trigger_input_icu.cpp b/firmware/hw_layer/trigger_input_icu.cpp index b1a00ec102..9992b87a8e 100644 --- a/firmware/hw_layer/trigger_input_icu.cpp +++ b/firmware/hw_layer/trigger_input_icu.cpp @@ -1,6 +1,6 @@ /** * @file trigger_input_icu.cpp - * @brief Position sensor hardware layer (ICU and PAL drivers) + * @brief Position sensor hardware layer - ICU version * * todo: code reuse with digital_input_hw.cpp was never finished * todo: at the moment due to half-done code reuse we already depend on EFI_ICU_INPUTS but still have custom code @@ -16,93 +16,18 @@ volatile int icuWidthCallbackCounter = 0; volatile int icuWidthPeriodCounter = 0; -bool hwTriggerInputEnabled = true; // this is useful at least for real hardware integration testing -#if EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE || HAL_USE_ICU == TRUE) && (HAL_USE_COMP == FALSE) +#if EFI_SHAFT_POSITION_INPUT && (HAL_USE_ICU == TRUE) && (HAL_USE_COMP == FALSE) #include "trigger_input.h" #include "digital_input_hw.h" -#include "digital_input_exti.h" -#include "pin_repository.h" -#include "trigger_structure.h" -#include "trigger_central.h" -#include "engine_configuration.h" + +EXTERN_ENGINE; extern bool hasFirmwareErrorFlag; -EXTERN_ENGINE -; static Logging *logger; -#if EFI_PROD_CODE -/* PAL based implementation */ -#if (HAL_TRIGGER_USE_PAL == TRUE) && (PAL_USE_CALLBACKS == TRUE) - -/* static variables for PAL implementation */ -static ioline_t primary_line; - -static void shaft_callback(void *arg) { - ioline_t pal_line = (ioline_t)arg; - // todo: support for 3rd trigger input channel - // todo: start using real event time from HW event, not just software timer? - if (hasFirmwareErrorFlag) - return; - - bool isPrimary = pal_line == primary_line; - if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) { - return; - } - - bool rise = (palReadLine(pal_line) == PAL_HIGH); - trigger_event_e signal; - // todo: add support for 3rd channel - if (rise) { - signal = isPrimary ? - (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_FALLING : SHAFT_PRIMARY_RISING) : - (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_FALLING : SHAFT_SECONDARY_RISING); - } else { - signal = isPrimary ? - (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_RISING : SHAFT_PRIMARY_FALLING) : - (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_RISING : SHAFT_SECONDARY_FALLING); - } - - hwHandleShaftSignal(signal); -} - -static void cam_callback(void *arg) { - ioline_t pal_line = (ioline_t)arg; - - bool rise = (palReadLine(pal_line) == PAL_HIGH); - - if (rise) { - hwHandleVvtCamSignal(TV_RISE); - } else { - hwHandleVvtCamSignal(TV_FALL); - } -} - -static int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool is_shaft) { - scheduleMsg(logger, "turnOnTriggerInputPin(PAL) %s %s", msg, hwPortname(brainPin)); - - /* TODO: - * * do not set to both edges if we need only one - * * simplify callback in case of one edge */ - ioline_t pal_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin)); - return efiExtiEnablePin(msg, brainPin, PAL_EVENT_MODE_BOTH_EDGES, is_shaft ? shaft_callback : cam_callback, (void *)pal_line); -} - -static void turnOffTriggerInputPin(brain_pin_e brainPin) { - efiExtiDisablePin(brainPin); -} - -static void setPrimaryChannel(brain_pin_e brainPin) { - primary_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin)); -} - -/* ICU based implementation */ -#elif (HAL_USE_ICU) - -/* static vars for ICU implementation */ static ICUDriver *primaryCrankDriver; static void cam_icu_width_callback(ICUDriver *icup) { @@ -120,7 +45,7 @@ static void cam_icu_period_callback(ICUDriver *icup) { * 'width' events happens before the 'period' event */ static void shaft_icu_width_callback(ICUDriver *icup) { - if (!hwTriggerInputEnabled) { + if (!engine->hwTriggerInputEnabled) { return; } icuWidthCallbackCounter++; @@ -140,7 +65,7 @@ static void shaft_icu_width_callback(ICUDriver *icup) { } static void shaft_icu_period_callback(ICUDriver *icup) { - if (!hwTriggerInputEnabled) { + if (!engine->hwTriggerInputEnabled) { return; } icuWidthPeriodCounter++; @@ -180,14 +105,14 @@ static ICUConfig cam_icucfg = { ICU_INPUT_ACTIVE_LOW, ICU_CHANNEL_1, 0}; -static int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool is_shaft) { +int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool isVvtShaft) { ICUConfig *icucfg; if (brainPin == GPIO_UNASSIGNED) { return -1; } - if (is_shaft) { + if (isVvtShaft) { icucfg = &shaft_icucfg; } else { icucfg = &cam_icucfg; @@ -222,7 +147,7 @@ static int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool is_ return 0; } -static void turnOffTriggerInputPin(brain_pin_e brainPin) { +void turnOffTriggerInputPin(brain_pin_e brainPin) { ICUDriver *driver = getInputCaptureDriver("trigger_off", brainPin); if (driver != NULL) { icuDisableNotifications(driver); @@ -233,13 +158,10 @@ static void turnOffTriggerInputPin(brain_pin_e brainPin) { } } -static void setPrimaryChannel(brain_pin_e brainPin) { +void setPrimaryChannel(brain_pin_e brainPin) { primaryCrankDriver = getInputCaptureDriver("primary", brainPin); } -#endif /* HAL_USE_ICU */ -#endif /* EFI_PROD_CODE */ - /*==========================================================================*/ /* Exported functions. */ /*==========================================================================*/ @@ -249,39 +171,4 @@ void turnOnTriggerInputPins(Logging *sharedLogger) { applyNewTriggerInputPins(); } - -void stopTriggerInputPins(void) { -#if EFI_PROD_CODE - for (int i = 0; i < TRIGGER_SUPPORTED_CHANNELS; i++) { - if (isConfigurationChanged(bc.triggerInputPins[i])) { - turnOffTriggerInputPin(activeConfiguration.bc.triggerInputPins[i]); - } - } - for (int i = 0; i < CAM_INPUTS_COUNT; i++) { - if (isConfigurationChanged(camInputs[i])) { - turnOffTriggerInputPin(activeConfiguration.camInputs[i]); - } - } -#endif /* EFI_PROD_CODE */ -} - -void startTriggerInputPins(void) { -#if EFI_PROD_CODE - for (int i = 0; i < TRIGGER_SUPPORTED_CHANNELS; i++) { - if (isConfigurationChanged(bc.triggerInputPins[i])) { - const char * msg = (i == 0 ? "trigger#1" : (i == 1 ? "trigger#2" : "trigger#3")); - turnOnTriggerInputPin(msg, CONFIGB(triggerInputPins)[i], true); - } - } - - for (int i = 0; i < CAM_INPUTS_COUNT; i++) { - if (isConfigurationChanged(camInputs[i])) { - turnOnTriggerInputPin("cam", engineConfiguration->camInputs[i], false); - } - } - - setPrimaryChannel(CONFIGB(triggerInputPins)[0]); -#endif /* EFI_PROD_CODE */ -} - -#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE || HAL_USE_ICU == TRUE) && (HAL_USE_COMP == FALSE)) */ +#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_USE_ICU == TRUE) && (HAL_USE_COMP == FALSE)) */