From a2fdc1128e1fcb696cf0961f2f17460331642760 Mon Sep 17 00:00:00 2001 From: dron0gus Date: Tue, 7 Jan 2020 11:42:08 +0300 Subject: [PATCH] triggers: fix coexistence of ICU and EXTI trigger drivers (#1085) --- firmware/hw_layer/digital_input_icu.cpp | 3 +- firmware/hw_layer/trigger_input.cpp | 127 ++++++++++++++++++++++- firmware/hw_layer/trigger_input.h | 3 - firmware/hw_layer/trigger_input_exti.cpp | 26 +++-- firmware/hw_layer/trigger_input_icu.cpp | 28 ++--- 5 files changed, 156 insertions(+), 31 deletions(-) diff --git a/firmware/hw_layer/digital_input_icu.cpp b/firmware/hw_layer/digital_input_icu.cpp index 2a9cf68578..ed28125fd5 100644 --- a/firmware/hw_layer/digital_input_icu.cpp +++ b/firmware/hw_layer/digital_input_icu.cpp @@ -156,6 +156,8 @@ icuchannel_t getInputCaptureChannel(brain_pin_e hwPin) { */ //Nullable ICUDriver * getInputCaptureDriver(const char *msg, brain_pin_e hwPin) { + UNUSED(msg); + if (hwPin == GPIO_UNASSIGNED || hwPin == GPIO_INVALID) { return NULL; } @@ -199,7 +201,6 @@ ICUDriver * getInputCaptureDriver(const char *msg, brain_pin_e hwPin) { return &ICUD9; } #endif - firmwareError(CUSTOM_ERR_NOT_INPUT_PIN, "%s: Not input pin %s", msg, hwPortname(hwPin)); return (ICUDriver *) NULL; } diff --git a/firmware/hw_layer/trigger_input.cpp b/firmware/hw_layer/trigger_input.cpp index 476d7b9b1e..db74c4a4e6 100644 --- a/firmware/hw_layer/trigger_input.cpp +++ b/firmware/hw_layer/trigger_input.cpp @@ -8,20 +8,130 @@ #include "global.h" #include "trigger_input.h" +/* TODO: + * - merge comparator trigger + */ + #if (EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT) || defined(__DOXYGEN__) EXTERN_ENGINE; #if (HAL_USE_ICU == TRUE) || (HAL_TRIGGER_USE_PAL == TRUE) + +#if (HAL_USE_ICU == TRUE) + void icuTriggerTurnOnInputPins(Logging *sharedLogger); + int icuTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft); + void icuTriggerTurnOffInputPin(brain_pin_e brainPin); + void icuTriggerSetPrimaryChannel(brain_pin_e brainPin); +#else + #define icuTriggerTurnOnInputPins(sharedLogger) ((void)0) + int icuTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft) { + UNUSED(msg); + UNUSED(index); + UNUSED(isTriggerShaft); + + return -2; + } + #define icuTriggerTurnOffInputPin(brainPin) ((void)0) + #define icuTriggerSetPrimaryChannel(brainPin) ((void)0) +#endif + +#if (HAL_TRIGGER_USE_PAL == TRUE) + void extiTriggerTurnOnInputPins(Logging *sharedLogger); + int extiTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft); + void extiTriggerTurnOffInputPin(brain_pin_e brainPin); + void extiTriggerSetPrimaryChannel(brain_pin_e brainPin); +#else + #define extiTriggerTurnOnInputPins(sharedLogger) ((void)0) + int extiTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft) { + UNUSED(msg); + UNUSED(index); + UNUSED(isTriggerShaft); + + return -2; + } + #define extiTriggerTurnOffInputPin(brainPin) ((void)0) + #define extiTriggerSetPrimaryChannel(brainPin) ((void)0) +#endif + +enum triggerType { + TRIGGER_NONE, + TRIGGER_ICU, + TRIGGER_EXTI +}; + +static triggerType shaftTriggerType[TRIGGER_SUPPORTED_CHANNELS]; +static triggerType camTriggerType[CAM_INPUTS_COUNT]; + +static int turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft) { + brain_pin_e brainPin = isTriggerShaft ? + CONFIG(triggerInputPins)[index] : engineConfiguration->camInputs[index]; + + if (isTriggerShaft) + shaftTriggerType[index] = TRIGGER_NONE; + else + camTriggerType[index] = TRIGGER_NONE; + + if (brainPin == GPIO_UNASSIGNED) + return 0; + + /* try ICU first */ + if (icuTriggerTurnOnInputPin(msg, index, isTriggerShaft) >= 0) { + if (isTriggerShaft) + shaftTriggerType[index] = TRIGGER_ICU; + else + camTriggerType[index] = TRIGGER_ICU; + return 0; + } + + /* ... then EXTI */ + if (extiTriggerTurnOnInputPin(msg, index, isTriggerShaft) >= 0) { + if (isTriggerShaft) + shaftTriggerType[index] = TRIGGER_EXTI; + else + camTriggerType[index] = TRIGGER_EXTI; + return 0; + } + + firmwareError(CUSTOM_ERR_NOT_INPUT_PIN, "%s: Not input pin %s", msg, hwPortname(brainPin)); + + return -1; +} + +static void turnOffTriggerInputPin(int index, bool isTriggerShaft) { + brain_pin_e brainPin = isTriggerShaft ? + activeConfiguration.triggerInputPins[index] : activeConfiguration.camInputs[index]; + + if (isTriggerShaft) { + if (shaftTriggerType[index] == TRIGGER_ICU) + icuTriggerTurnOffInputPin(brainPin); + if (shaftTriggerType[index] == TRIGGER_EXTI) + extiTriggerTurnOffInputPin(brainPin); + + shaftTriggerType[index] = TRIGGER_NONE; + } else { + if (camTriggerType[index] == TRIGGER_ICU) + icuTriggerTurnOffInputPin(brainPin); + if (camTriggerType[index] == TRIGGER_EXTI) + extiTriggerTurnOffInputPin(brainPin); + + camTriggerType[index] = TRIGGER_NONE; + } +} + +/*==========================================================================*/ +/* Exported functions. */ +/*==========================================================================*/ + void stopTriggerInputPins(void) { for (int i = 0; i < TRIGGER_SUPPORTED_CHANNELS; i++) { if (isConfigurationChanged(triggerInputPins[i])) { - turnOffTriggerInputPin(activeConfiguration.triggerInputPins[i]); + turnOffTriggerInputPin(i, true); } } for (int i = 0; i < CAM_INPUTS_COUNT; i++) { if (isConfigurationChanged(camInputs[i])) { - turnOffTriggerInputPin(activeConfiguration.camInputs[i]); + turnOffTriggerInputPin(i, false); } } } @@ -40,10 +150,19 @@ void startTriggerInputPins(void) { } } - setPrimaryChannel(CONFIG(triggerInputPins)[0]); + icuTriggerSetPrimaryChannel(CONFIG(triggerInputPins)[0]); + extiTriggerSetPrimaryChannel(CONFIG(triggerInputPins)[0]); } -#endif +void turnOnTriggerInputPins(Logging *sharedLogger) { + /* init all trigger HW available */ + icuTriggerTurnOnInputPins(sharedLogger); + extiTriggerTurnOnInputPins(sharedLogger); + + applyNewTriggerInputPins(); +} + +#endif /* (HAL_USE_ICU == TRUE) || (HAL_TRIGGER_USE_PAL == TRUE) */ void applyNewTriggerInputPins(void) { // first we will turn off all the changed pins diff --git a/firmware/hw_layer/trigger_input.h b/firmware/hw_layer/trigger_input.h index c6094f61c7..852c88ddca 100644 --- a/firmware/hw_layer/trigger_input.h +++ b/firmware/hw_layer/trigger_input.h @@ -20,8 +20,5 @@ 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); -void turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft); #endif /* CRANK_INPUT_H_ */ diff --git a/firmware/hw_layer/trigger_input_exti.cpp b/firmware/hw_layer/trigger_input_exti.cpp index 9fd75b6289..1028790b00 100644 --- a/firmware/hw_layer/trigger_input_exti.cpp +++ b/firmware/hw_layer/trigger_input_exti.cpp @@ -12,11 +12,15 @@ #include "global.h" -#if EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE) && (HAL_USE_COMP == FALSE) +#if EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE) #include "trigger_input.h" #include "digital_input_exti.h" +#if (PAL_USE_CALLBACKS == FALSE) + #error "PAL_USE_CALLBACKS should be enabled to use HAL_TRIGGER_USE_PAL" +#endif + extern bool hasFirmwareErrorFlag; static Logging *logger; @@ -64,30 +68,34 @@ static void cam_callback(void *arg) { } } -void turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft) { +/*==========================================================================*/ +/* Exported functions. */ +/*==========================================================================*/ + +int extiTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft) { brain_pin_e brainPin = isTriggerShaft ? CONFIG(triggerInputPins)[index] : engineConfiguration->camInputs[index]; - scheduleMsg(logger, "turnOnTriggerInputPin(PAL) %s %s", msg, hwPortname(brainPin)); + scheduleMsg(logger, "extiTriggerTurnOnInputPin %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)); efiExtiEnablePin(msg, brainPin, PAL_EVENT_MODE_BOTH_EDGES, isTriggerShaft ? shaft_callback : cam_callback, (void *)pal_line); + + return 0; } -void turnOffTriggerInputPin(brain_pin_e brainPin) { +void extiTriggerTurnOffInputPin(brain_pin_e brainPin) { efiExtiDisablePin(brainPin); } -void setPrimaryChannel(brain_pin_e brainPin) { +void extiTriggerSetPrimaryChannel(brain_pin_e brainPin) { primary_line = PAL_LINE(getHwPort("trg", brainPin), getHwPin("trg", brainPin)); } -void turnOnTriggerInputPins(Logging *sharedLogger) { +void extiTriggerTurnOnInputPins(Logging *sharedLogger) { logger = sharedLogger; - - applyNewTriggerInputPins(); } -#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE) && (HAL_USE_COMP == FALSE)) */ +#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE)) */ diff --git a/firmware/hw_layer/trigger_input_icu.cpp b/firmware/hw_layer/trigger_input_icu.cpp index 22589b6092..3639155857 100644 --- a/firmware/hw_layer/trigger_input_icu.cpp +++ b/firmware/hw_layer/trigger_input_icu.cpp @@ -17,7 +17,7 @@ volatile int icuWidthCallbackCounter = 0; volatile int icuWidthPeriodCounter = 0; -#if EFI_SHAFT_POSITION_INPUT && (HAL_USE_ICU == TRUE) && (HAL_USE_COMP == FALSE) +#if EFI_SHAFT_POSITION_INPUT && (HAL_USE_ICU == TRUE) #include "trigger_input.h" #include "digital_input_icu.h" @@ -79,17 +79,21 @@ static void shaftPeriodCallback(bool isPrimary) { hwHandleShaftSignal(signal); } -void turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft) { +/*==========================================================================*/ +/* Exported functions. */ +/*==========================================================================*/ + +int icuTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft) { (void)msg; brain_pin_e brainPin = isTriggerShaft ? CONFIG(triggerInputPins)[index] : engineConfiguration->camInputs[index]; if (brainPin == GPIO_UNASSIGNED) { - return; + return -1; } digital_input_s* input = startDigitalCapture("trigger", brainPin, true); if (input == NULL) { /* error already reported */ - return; + return -1; } if (isTriggerShaft) { @@ -100,24 +104,20 @@ void turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft) { input->setWidthCallback((VoidInt)(void*)vvtWidthCallback, NULL); input->setPeriodCallback((VoidInt)(void*)vvtPeriodCallback, NULL); } + + return 0; } -void turnOffTriggerInputPin(brain_pin_e brainPin) { +void icuTriggerTurnOffInputPin(brain_pin_e brainPin) { stopDigitalCapture("trigger", brainPin); } -void setPrimaryChannel(brain_pin_e brainPin) { +void icuTriggerSetPrimaryChannel(brain_pin_e brainPin) { (void)brainPin; } -/*==========================================================================*/ -/* Exported functions. */ -/*==========================================================================*/ - -void turnOnTriggerInputPins(Logging *sharedLogger) { +void icuTriggerTurnOnInputPins(Logging *sharedLogger) { logger = sharedLogger; - - applyNewTriggerInputPins(); } -#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_USE_ICU == TRUE) && (HAL_USE_COMP == FALSE)) */ +#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_USE_ICU == TRUE)) */