different take on #971
This commit is contained in:
parent
1a78b994b2
commit
f3b8fba38a
|
@ -24,6 +24,8 @@ HW_LAYER_EMS_CPP = $(HW_LAYER_EGT_CPP) \
|
|||
$(PROJECT_DIR)/hw_layer/adc_subscription.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/pwm_generator.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/trigger_input.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/trigger_input_icu.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/trigger_input_exti.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/hip9011.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/mc33816.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/hip9011_logic.cpp \
|
||||
|
|
|
@ -1,290 +1,14 @@
|
|||
/**
|
||||
/*
|
||||
* @file trigger_input.cpp
|
||||
* @brief Position sensor hardware layer (ICU and PAL drivers)
|
||||
*
|
||||
* 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
|
||||
* todo: VVT implementation is a nasty copy-paste :(
|
||||
*
|
||||
* see digital_input_hw.cp
|
||||
*
|
||||
* @date Dec 30, 2012
|
||||
* @author Andrey Belomutskiy, (c) 2012-2018
|
||||
* @date Nov 11, 2019
|
||||
* @author Andrey Belomutskiy, (c) 2012-2019
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
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)
|
||||
|
||||
#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"
|
||||
|
||||
#define TRIGGER_SUPPORTED_CHANNELS 2
|
||||
|
||||
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) {
|
||||
(void)icup;
|
||||
hwHandleVvtCamSignal(TV_RISE);
|
||||
}
|
||||
|
||||
static void cam_icu_period_callback(ICUDriver *icup) {
|
||||
(void)icup;
|
||||
hwHandleVvtCamSignal(TV_FALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* that's hardware timer input capture IRQ entry point
|
||||
* 'width' events happens before the 'period' event
|
||||
*/
|
||||
static void shaft_icu_width_callback(ICUDriver *icup) {
|
||||
if (!hwTriggerInputEnabled) {
|
||||
return;
|
||||
}
|
||||
icuWidthCallbackCounter++;
|
||||
// todo: support for 3rd trigger input channel
|
||||
// todo: start using real event time from HW event, not just software timer?
|
||||
if (hasFirmwareErrorFlag)
|
||||
return;
|
||||
int isPrimary = icup == primaryCrankDriver;
|
||||
if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) {
|
||||
return;
|
||||
}
|
||||
// icucnt_t last_width = icuGetWidth(icup); so far we are fine with system time
|
||||
// todo: add support for 3rd channel
|
||||
trigger_event_e signal = isPrimary ? (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_FALLING : SHAFT_PRIMARY_RISING) : (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_FALLING : SHAFT_SECONDARY_RISING);
|
||||
|
||||
hwHandleShaftSignal(signal);
|
||||
}
|
||||
|
||||
static void shaft_icu_period_callback(ICUDriver *icup) {
|
||||
if (!hwTriggerInputEnabled) {
|
||||
return;
|
||||
}
|
||||
icuWidthPeriodCounter++;
|
||||
if (hasFirmwareErrorFlag)
|
||||
return;
|
||||
int isPrimary = icup == primaryCrankDriver;
|
||||
if (!isPrimary && !TRIGGER_SHAPE(needSecondTriggerInput)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo: add support for 3rd channel
|
||||
// icucnt_t last_period = icuGetPeriod(icup); so far we are fine with system time
|
||||
trigger_event_e signal =
|
||||
isPrimary ? (engineConfiguration->invertPrimaryTriggerSignal ? SHAFT_PRIMARY_RISING : SHAFT_PRIMARY_FALLING) : (engineConfiguration->invertSecondaryTriggerSignal ? SHAFT_SECONDARY_RISING : SHAFT_SECONDARY_FALLING);
|
||||
hwHandleShaftSignal(signal);
|
||||
}
|
||||
|
||||
/**
|
||||
* the main purpose of this configuration structure is to specify the input interrupt callbacks
|
||||
*/
|
||||
static ICUConfig shaft_icucfg = { ICU_INPUT_ACTIVE_LOW,
|
||||
100000, /* 100kHz ICU clock frequency. */
|
||||
shaft_icu_width_callback,
|
||||
shaft_icu_period_callback,
|
||||
NULL,
|
||||
ICU_CHANNEL_1,
|
||||
0};
|
||||
|
||||
/**
|
||||
* this is about VTTi and stuff kind of cam sensor
|
||||
*/
|
||||
static ICUConfig cam_icucfg = { ICU_INPUT_ACTIVE_LOW,
|
||||
100000, /* 100kHz ICU clock frequency. */
|
||||
cam_icu_width_callback,
|
||||
cam_icu_period_callback,
|
||||
NULL,
|
||||
ICU_CHANNEL_1,
|
||||
0};
|
||||
|
||||
static int turnOnTriggerInputPin(const char *msg, brain_pin_e brainPin, bool is_shaft) {
|
||||
ICUConfig *icucfg;
|
||||
|
||||
if (brainPin == GPIO_UNASSIGNED) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_shaft) {
|
||||
icucfg = &shaft_icucfg;
|
||||
} else {
|
||||
icucfg = &cam_icucfg;
|
||||
}
|
||||
|
||||
// configure pin
|
||||
turnOnCapturePin(msg, brainPin);
|
||||
icucfg->channel = getInputCaptureChannel(brainPin);
|
||||
|
||||
ICUDriver *driver = getInputCaptureDriver(msg, brainPin);
|
||||
scheduleMsg(logger, "turnOnTriggerInputPin %s", hwPortname(brainPin));
|
||||
// todo: reuse 'setWaveReaderMode' method here?
|
||||
if (driver != NULL) {
|
||||
// todo: once http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1757 is fixed
|
||||
// bool needWidthCallback = !CONFIG(useOnlyRisingEdgeForTrigger) || TRIGGER_SHAPE(useRiseEdge);
|
||||
// shaft_icucfg.width_cb = needWidthCallback ? shaft_icu_width_callback : NULL;
|
||||
|
||||
// bool needPeriodCallback = !CONFIG(useOnlyRisingEdgeForTrigger) || !TRIGGER_SHAPE(useRiseEdge);
|
||||
// shaft_icucfg.period_cb = needPeriodCallback ? shaft_icu_period_callback : NULL;
|
||||
|
||||
efiIcuStart(msg, driver, icucfg);
|
||||
if (driver->state == ICU_READY) {
|
||||
efiAssert(CUSTOM_ERR_ASSERT, driver != NULL, "ti: driver is NULL", -1);
|
||||
efiAssert(CUSTOM_ERR_ASSERT, driver->state == ICU_READY, "ti: driver not ready", -1);
|
||||
icuStartCapture(driver); // this would change state from READY to WAITING
|
||||
icuEnableNotifications(driver);
|
||||
} else {
|
||||
// we would be here for example if same pin is used for multiple input capture purposes
|
||||
firmwareError(CUSTOM_ERR_ICU_STATE, "ICU unexpected state [%s]", hwPortname(brainPin));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void turnOffTriggerInputPin(brain_pin_e brainPin) {
|
||||
ICUDriver *driver = getInputCaptureDriver("trigger_off", brainPin);
|
||||
if (driver != NULL) {
|
||||
icuDisableNotifications(driver);
|
||||
icuStopCapture(driver);
|
||||
icuStop(driver);
|
||||
scheduleMsg(logger, "turnOffTriggerInputPin %s", hwPortname(brainPin));
|
||||
turnOffCapturePin(brainPin);
|
||||
}
|
||||
}
|
||||
|
||||
static void setPrimaryChannel(brain_pin_e brainPin) {
|
||||
primaryCrankDriver = getInputCaptureDriver("primary", brainPin);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_ICU */
|
||||
#endif /* EFI_PROD_CODE */
|
||||
|
||||
/*==========================================================================*/
|
||||
/* Exported functions. */
|
||||
/*==========================================================================*/
|
||||
|
||||
void turnOnTriggerInputPins(Logging *sharedLogger) {
|
||||
logger = 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 */
|
||||
}
|
||||
#if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
|
||||
|
||||
void applyNewTriggerInputPins(void) {
|
||||
// first we will turn off all the changed pins
|
||||
|
@ -293,4 +17,4 @@ void applyNewTriggerInputPins(void) {
|
|||
startTriggerInputPins();
|
||||
}
|
||||
|
||||
#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE || HAL_USE_ICU == TRUE) && (HAL_USE_COMP == FALSE)) */
|
||||
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include "engine.h"
|
||||
|
||||
#define TRIGGER_SUPPORTED_CHANNELS 2
|
||||
|
||||
void turnOnTriggerInputPins(Logging *sharedLogger);
|
||||
void applyNewTriggerInputPins(void);
|
||||
void startTriggerInputPins(void);
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include "trigger_central.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
#define TRIGGER_SUPPORTED_CHANNELS 2
|
||||
|
||||
extern bool hasFirmwareErrorFlag;
|
||||
|
||||
EXTERN_ENGINE
|
||||
|
@ -119,11 +117,4 @@ void stopTriggerInputPins(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void applyNewTriggerInputPins(void) {
|
||||
// first we will turn off all the changed pins
|
||||
stopTriggerInputPins();
|
||||
// then we will enable all the changed pins
|
||||
startTriggerInputPins();
|
||||
}
|
||||
|
||||
#endif /* EFI_SHAFT_POSITION_INPUT && HAL_USE_COMP */
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @file trigger_input_exti.cpp
|
||||
* @brief Position sensor hardware layer - PAL version
|
||||
*
|
||||
* todo: VVT implementation is a nasty copy-paste :(
|
||||
*
|
||||
* see digital_input_hw.cp
|
||||
*
|
||||
* @date Dec 30, 2012
|
||||
* @author Andrey Belomutskiy, (c) 2012-2019
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#if EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE) && (HAL_USE_COMP == FALSE)
|
||||
|
||||
#endif /* (EFI_SHAFT_POSITION_INPUT && (HAL_TRIGGER_USE_PAL == TRUE) && (HAL_USE_COMP == FALSE)) */
|
Loading…
Reference in New Issue