more trigger_adc & cypress fixes (#3642)

Co-authored-by: Andrei <andreikagit@users.noreply.github.com>
This commit is contained in:
Andreika 2021-12-02 00:26:58 +02:00 committed by GitHub
parent 7db1bb87f5
commit 90c56e8643
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 122 additions and 21 deletions

View File

@ -7,6 +7,8 @@ export EXTRA_PARAMS="-DDUMMY -D__USE_CMSIS\
-DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE\ -DEFI_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_CHECKS=FALSE -DCH_DBG_ENABLE_ASSERTS=FALSE -DCH_DBG_ENABLE_STACK_CHECK=FALSE -DCH_DBG_FILL_THREADS=FALSE -DCH_DBG_THREADS_PROFILING=FALSE\
-DDEFAULT_ENGINE_TYPE=MINIMAL_PINS" -DDEFAULT_ENGINE_TYPE=MINIMAL_PINS"
TRIGGER_USE_ADC = yes
export BUILDDIR="build" export BUILDDIR="build"
export PROJECT_BOARD="hellen/cypress" export PROJECT_BOARD="hellen/cypress"
export PROJECT_CPU="cypress" export PROJECT_CPU="cypress"

View File

@ -14,7 +14,7 @@
#if (EFI_SHAFT_POSITION_INPUT) || defined(__DOXYGEN__) #if (EFI_SHAFT_POSITION_INPUT) || defined(__DOXYGEN__)
#if (HAL_USE_ICU == TRUE) || (HAL_TRIGGER_USE_PAL == TRUE) #if (HAL_USE_ICU == TRUE) || (HAL_TRIGGER_USE_PAL == TRUE) || (HAL_TRIGGER_USE_ADC == TRUE)
#if (HAL_USE_ICU == TRUE) #if (HAL_USE_ICU == TRUE)
void icuTriggerTurnOnInputPins(); void icuTriggerTurnOnInputPins();
@ -48,10 +48,27 @@
#define extiTriggerTurnOffInputPin(brainPin) ((void)0) #define extiTriggerTurnOffInputPin(brainPin) ((void)0)
#endif #endif
#if (HAL_TRIGGER_USE_ADC == TRUE)
void adcTriggerTurnOnInputPins();
int adcTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft);
void adcTriggerTurnOffInputPin(brain_pin_e brainPin);
#else
#define adcTriggerTurnOnInputPins() ((void)0)
int adcTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft) {
UNUSED(msg);
UNUSED(index);
UNUSED(isTriggerShaft);
return -2;
}
#define adcTriggerTurnOffInputPin(brainPin) ((void)0)
#endif
enum triggerType { enum triggerType {
TRIGGER_NONE, TRIGGER_NONE,
TRIGGER_ICU, TRIGGER_ICU,
TRIGGER_EXTI TRIGGER_EXTI,
TRIGGER_ADC,
}; };
static triggerType shaftTriggerType[TRIGGER_SUPPORTED_CHANNELS]; static triggerType shaftTriggerType[TRIGGER_SUPPORTED_CHANNELS];
@ -83,6 +100,18 @@ static int turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft
} }
#endif #endif
/* ... then ADC */
#if HAL_TRIGGER_USE_ADC
if (adcTriggerTurnOnInputPin(msg, index, isTriggerShaft) >= 0) {
if (isTriggerShaft) {
shaftTriggerType[index] = TRIGGER_ADC;
} else {
camTriggerType[index] = TRIGGER_ADC;
}
return 0;
}
#endif
/* ... then EXTI */ /* ... then EXTI */
if (extiTriggerTurnOnInputPin(msg, index, isTriggerShaft) >= 0) { if (extiTriggerTurnOnInputPin(msg, index, isTriggerShaft) >= 0) {
if (isTriggerShaft) { if (isTriggerShaft) {
@ -108,6 +137,10 @@ static void turnOffTriggerInputPin(int index, bool isTriggerShaft) {
icuTriggerTurnOffInputPin(brainPin); icuTriggerTurnOffInputPin(brainPin);
} }
#endif /* EFI_ICU_INPUTS */ #endif /* EFI_ICU_INPUTS */
if (shaftTriggerType[index] == TRIGGER_ADC) {
adcTriggerTurnOffInputPin(brainPin);
}
if (shaftTriggerType[index] == TRIGGER_EXTI) { if (shaftTriggerType[index] == TRIGGER_EXTI) {
extiTriggerTurnOffInputPin(brainPin); extiTriggerTurnOffInputPin(brainPin);
} }
@ -119,6 +152,10 @@ static void turnOffTriggerInputPin(int index, bool isTriggerShaft) {
icuTriggerTurnOffInputPin(brainPin); icuTriggerTurnOffInputPin(brainPin);
} }
#endif /* EFI_ICU_INPUTS */ #endif /* EFI_ICU_INPUTS */
if (camTriggerType[index] == TRIGGER_ADC) {
adcTriggerTurnOffInputPin(brainPin);
}
if (camTriggerType[index] == TRIGGER_EXTI) { if (camTriggerType[index] == TRIGGER_EXTI) {
extiTriggerTurnOffInputPin(brainPin); extiTriggerTurnOffInputPin(brainPin);
} }
@ -169,7 +206,7 @@ void turnOnTriggerInputPins() {
applyNewTriggerInputPins(); applyNewTriggerInputPins();
} }
#endif /* (HAL_USE_ICU == TRUE) || (HAL_TRIGGER_USE_PAL == TRUE) */ #endif /* (HAL_USE_ICU == TRUE) || (HAL_TRIGGER_USE_PAL == TRUE) || (HAL_TRIGGER_USE_ADC == TRUE) */
void stopTriggerDebugPins() { void stopTriggerDebugPins() {

View File

@ -10,14 +10,14 @@
#include "pch.h" #include "pch.h"
#include "trigger_input_adc.h" #include "trigger_input_adc.h"
#define voltsToAdcDivided(volts) (voltsToAdc(volts) / engineConfiguration->analogInputDividerCoefficient)
/*static*/ TriggerAdcDetector trigAdcState; /*static*/ TriggerAdcDetector trigAdcState;
#define DELTA_THRESHOLD_CNT_LOW (GPT_FREQ_FAST / GPT_PERIOD_FAST / 32) // ~1/32 second? #define DELTA_THRESHOLD_CNT_LOW (GPT_FREQ_FAST / GPT_PERIOD_FAST / 32) // ~1/32 second?
#define DELTA_THRESHOLD_CNT_HIGH (GPT_FREQ_FAST / GPT_PERIOD_FAST / 4) // ~1/4 second? #define DELTA_THRESHOLD_CNT_HIGH (GPT_FREQ_FAST / GPT_PERIOD_FAST / 4) // ~1/4 second?
#define triggerVoltsToAdcDivided(volts) (voltsToAdc(volts) / trigAdcState.triggerInputDividerCoefficient)
// hardware-dependent part // hardware-dependent part
#if (EFI_SHAFT_POSITION_INPUT && HAL_TRIGGER_USE_ADC && HAL_USE_ADC) || defined(__DOXYGEN__) #if (EFI_SHAFT_POSITION_INPUT && HAL_TRIGGER_USE_ADC && HAL_USE_ADC) || defined(__DOXYGEN__)
@ -25,11 +25,18 @@
//!!!!!!!!!! //!!!!!!!!!!
#define TRIGGER_ADC_DEBUG_LED TRUE #define TRIGGER_ADC_DEBUG_LED TRUE
//#define DEBUG_OUTPUT_IGN1 TRUE
//#define TRIGGER_ADC_DUMP_BUF TRUE
#ifdef TRIGGER_ADC_DEBUG_LED #ifdef TRIGGER_ADC_DEBUG_LED
#define TRIGGER_ADC_DEBUG_LED1_PORT GPIOH #define TRIGGER_ADC_DEBUG_LED1_PORT GPIOH
#define TRIGGER_ADC_DEBUG_LED1_PIN 9 #define TRIGGER_ADC_DEBUG_LED1_PIN 9
//#define DEBUG_OUTPUT_IGN1
#ifdef TRIGGER_ADC_DUMP_BUF
static const int dumpBufNum = 100;
static triggerAdcSample_t dumpBuf[dumpBufNum];
static int dumpBufCnt = 0;
#endif /* TRIGGER_ADC_DUMP_BUF */
void toggleLed(int led, int mode) { void toggleLed(int led, int mode) {
#if 1 #if 1
@ -60,9 +67,11 @@ static ioportmask_t triggerInputPin;
#endif /* PAL_MODE_EXTINT */ #endif /* PAL_MODE_EXTINT */
void setTriggerAdcMode(triggerAdcMode_t adcMode) { void setTriggerAdcMode(triggerAdcMode_t adcMode) {
trigAdcState.curAdcMode = adcMode;
trigAdcState.modeSwitchCnt++;
palSetPadMode(triggerInputPort, triggerInputPin, palSetPadMode(triggerInputPort, triggerInputPin,
(adcMode == TRIGGER_ADC_ADC) ? PAL_MODE_INPUT_ANALOG : PAL_MODE_EXTINT); (adcMode == TRIGGER_ADC_ADC) ? PAL_MODE_INPUT_ANALOG : PAL_MODE_EXTINT);
trigAdcState.curAdcMode = adcMode;
} }
static void shaft_callback(void *arg, efitick_t stamp) { static void shaft_callback(void *arg, efitick_t stamp) {
@ -82,8 +91,19 @@ void triggerAdcCallback(triggerAdcSample_t value) {
trigAdcState.analogCallback(stamp, value); trigAdcState.analogCallback(stamp, value);
} }
#ifdef TRIGGER_ADC_DUMP_BUF
static void printDumpBuf(void) {
efiPrintf("------");
for (int i = 0; i < dumpBufNum; i++) {
int pos = (dumpBufCnt - i - 1 + dumpBufNum) % dumpBufNum;
triggerAdcSample_t v = dumpBuf[pos];
efiPrintf("[%d] %d", i, v);
}
}
#endif /* TRIGGER_ADC_DUMP_BUF */
static int turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft) {
int adcTriggerTurnOnInputPin(const char *msg, int index, bool isTriggerShaft) {
brain_pin_e brainPin = isTriggerShaft ? brain_pin_e brainPin = isTriggerShaft ?
engineConfiguration->triggerInputPins[index] : engineConfiguration->camInputs[index]; engineConfiguration->triggerInputPins[index] : engineConfiguration->camInputs[index];
@ -110,6 +130,10 @@ static int turnOnTriggerInputPin(const char *msg, int index, bool isTriggerShaft
#endif #endif
#endif /* TRIGGER_ADC_DEBUG_LED */ #endif /* TRIGGER_ADC_DEBUG_LED */
#ifdef TRIGGER_ADC_DUMP_BUF
addConsoleAction("trigger_adc_dump", printDumpBuf);
#endif /* TRIGGER_ADC_DUMP_BUF */
return 0; return 0;
} }
@ -157,26 +181,35 @@ void TriggerAdcDetector::init() {
// todo: move some of these to config // todo: move some of these to config
// 4.7k||5.1k + 4.7k
triggerInputDividerCoefficient = 1.52f; // = analogInputDividerCoefficient
// we need to make at least minNumAdcMeasurementsPerTooth for 1 tooth (i.e. between two consequent events) // we need to make at least minNumAdcMeasurementsPerTooth for 1 tooth (i.e. between two consequent events)
const int minNumAdcMeasurementsPerTooth = 20; const int minNumAdcMeasurementsPerTooth = 10; // for 60-2 wheel: 1/(10*2*60/10000/60) = 500 RPM
minDeltaTimeForStableAdcDetectionNt = US2NT(US_PER_SECOND_LL * minNumAdcMeasurementsPerTooth * GPT_PERIOD_FAST / GPT_FREQ_FAST); minDeltaTimeForStableAdcDetectionNt = US2NT(US_PER_SECOND_LL * minNumAdcMeasurementsPerTooth * GPT_PERIOD_FAST / GPT_FREQ_FAST);
// we assume that the transition occurs somewhere in the middle of the measurement period, so we take the half of it // we assume that the transition occurs somewhere in the middle of the measurement period, so we take the half of it
stampCorrectionForAdc = US2NT(US_PER_SECOND_LL * GPT_PERIOD_FAST / GPT_FREQ_FAST / 2); stampCorrectionForAdc = US2NT(US_PER_SECOND_LL * GPT_PERIOD_FAST / GPT_FREQ_FAST / 2);
// these thresholds allow to switch from ADC mode to EXTI mode, indicating the clamping of the signal analogToDigitalTransitionCnt = 4;
switchingThresholdLow = voltsToAdcDivided(1.0f); digitalToAnalogTransitionCnt = 4;
switchingThresholdHigh = voltsToAdcDivided(4.0f);
// used to filter out low signals // used to filter out low signals
minDeltaThresholdWeakSignal = voltsToAdcDivided(0.05f); // 50mV minDeltaThresholdWeakSignal = triggerVoltsToAdcDivided(0.05f); // 50mV
// we need to shift the default threshold even for strong signals because of the possible loss of the first tooth (after the sync) // we need to shift the default threshold even for strong signals because of the possible loss of the first tooth (after the sync)
minDeltaThresholdStrongSignal = voltsToAdcDivided(0.04f); // 5mV minDeltaThresholdStrongSignal = triggerVoltsToAdcDivided(0.04f); // 5mV
const triggerAdcSample_t adcDeltaThreshold = voltsToAdcDivided(0.25f); const triggerAdcSample_t adcDeltaThreshold = triggerVoltsToAdcDivided(0.25f);
adcDefaultThreshold = voltsToAdcDivided(3.4f); // this corresponds to VREF1 on Hellen boards adcDefaultThreshold = triggerVoltsToAdcDivided(2.5f); // this corresponds to VREF1 on Hellen boards
adcMinThreshold = adcDefaultThreshold - adcDeltaThreshold; adcMinThreshold = adcDefaultThreshold - adcDeltaThreshold;
adcMaxThreshold = adcDefaultThreshold - adcDeltaThreshold; adcMaxThreshold = adcDefaultThreshold - adcDeltaThreshold;
// these thresholds allow to switch from ADC mode to EXTI mode, indicating the clamping of the signal
// they should exceed the MCU schmitt trigger thresholds (usually 0.3*Vdd and 0.7*Vdd)
switchingThresholdLow = triggerVoltsToAdcDivided(1.0f); // = 0.2*Vdd (<0.3*Vdd)
switchingThresholdHigh = triggerVoltsToAdcDivided(4.0f); // = 0.8*Vdd (>0.7*Vdd)
modeSwitchCnt = 0;
reset(); reset();
#endif // EFI_SIMULATOR #endif // EFI_SIMULATOR
} }
@ -214,7 +247,7 @@ void TriggerAdcDetector::digitalCallback(efitick_t stamp, bool isPrimary, bool r
switchingTeethCnt = 0; switchingTeethCnt = 0;
} }
if (switchingCnt > 4) { if (switchingCnt >= digitalToAnalogTransitionCnt) {
switchingCnt = 0; switchingCnt = 0;
// we need at least 3 wide teeth to be certain! // we need at least 3 wide teeth to be certain!
// we don't want to confuse them with a sync.gap // we don't want to confuse them with a sync.gap
@ -234,12 +267,17 @@ void TriggerAdcDetector::analogCallback(efitick_t stamp, triggerAdcSample_t valu
return; return;
} }
#ifdef TRIGGER_ADC_DUMP_BUF
dumpBuf[dumpBufCnt] = value;
dumpBufCnt = (dumpBufCnt + 1) % dumpBufNum;
#endif /* TRIGGER_ADC_DUMP_BUF */
// <1V or >4V? // <1V or >4V?
if (value >= switchingThresholdHigh || value <= switchingThresholdLow) { if (value >= switchingThresholdHigh || value <= switchingThresholdLow) {
switchingCnt++; switchingCnt++;
} else { } else {
switchingCnt = 0; //switchingCnt = 0;
switchingTeethCnt = 0; switchingCnt = maxI(switchingCnt - 1, 0);
} }
int delta = value - adcThreshold; int delta = value - adcThreshold;
@ -328,16 +366,17 @@ void TriggerAdcDetector::analogCallback(efitick_t stamp, triggerAdcSample_t valu
// it should not accumulate too much // it should not accumulate too much
integralSum = 0; integralSum = 0;
#if 0
// update triggerAdcITerm // update triggerAdcITerm
efitime_t deltaTimeUs = NT2US(stamp - prevStamp); efitime_t deltaTimeUs = NT2US(stamp - prevStamp);
if (deltaTimeUs > 200) { // 200 us = ~2500 RPM (we don't need this correction for large RPM) if (deltaTimeUs > 200) { // 200 us = ~2500 RPM (we don't need this correction for large RPM)
triggerAdcITerm = 1.0f / (triggerAdcITermCoef * deltaTimeUs); triggerAdcITerm = 1.0f / (triggerAdcITermCoef * deltaTimeUs);
triggerAdcITerm = maxF(triggerAdcITerm, triggerAdcITermMin); triggerAdcITerm = maxF(triggerAdcITerm, triggerAdcITermMin);
} }
#endif
} }
if (switchingCnt > 4) { if (switchingCnt >= analogToDigitalTransitionCnt) {
switchingCnt = 0; switchingCnt = 0;
// we need at least 3 high-signal teeth to be certain! // we need at least 3 high-signal teeth to be certain!
if (switchingTeethCnt++ > 3) { if (switchingTeethCnt++ > 3) {
@ -349,10 +388,15 @@ void TriggerAdcDetector::analogCallback(efitick_t stamp, triggerAdcSample_t valu
// we want to reset the thresholds on return // we want to reset the thresholds on return
zeroThreshold = minDeltaThresholdStrongSignal; zeroThreshold = minDeltaThresholdStrongSignal;
adcThreshold = adcDefaultThreshold; adcThreshold = adcDefaultThreshold;
// reset integrator
triggerAdcITerm = triggerAdcITermMin;
integralSum = 0; integralSum = 0;
transitionCooldownCnt = 0; transitionCooldownCnt = 0;
return; return;
} }
} else {
// we don't see "big teeth" anymore
switchingTeethCnt = 0;
} }
prevValue = transition; prevValue = transition;
@ -360,3 +404,14 @@ void TriggerAdcDetector::analogCallback(efitick_t stamp, triggerAdcSample_t valu
#endif // EFI_SIMULATOR #endif // EFI_SIMULATOR
} }
triggerAdcMode_t getTriggerAdcMode(void) {
return trigAdcState.curAdcMode;
}
float getTriggerAdcThreshold(void) {
return trigAdcState.adcThreshold;
}
int getTriggerAdcModeCnt(void) {
return trigAdcState.modeSwitchCnt;
}

View File

@ -29,11 +29,16 @@ public:
triggerAdcSample_t adcMinThreshold; triggerAdcSample_t adcMinThreshold;
triggerAdcSample_t adcMaxThreshold; triggerAdcSample_t adcMaxThreshold;
float triggerInputDividerCoefficient;
float triggerAdcITermCoef = 1600.0f; float triggerAdcITermCoef = 1600.0f;
float triggerAdcITermMin = 3.125e-8f; // corresponds to rpm=25 float triggerAdcITermMin = 3.125e-8f; // corresponds to rpm=25
int transitionCooldown = 5; int transitionCooldown = 5;
int analogToDigitalTransitionCnt;
int digitalToAnalogTransitionCnt;
triggerAdcMode_t curAdcMode = TRIGGER_ADC_NONE; triggerAdcMode_t curAdcMode = TRIGGER_ADC_NONE;
float adcThreshold = adcDefaultThreshold; float adcThreshold = adcDefaultThreshold;
float triggerAdcITerm = triggerAdcITermMin; float triggerAdcITerm = triggerAdcITermMin;
@ -57,4 +62,6 @@ public:
int minDeltaThresholdCntPos = 0, minDeltaThresholdCntNeg = 0; int minDeltaThresholdCntPos = 0, minDeltaThresholdCntNeg = 0;
int integralSum = 0; int integralSum = 0;
int transitionCooldownCnt = 0; int transitionCooldownCnt = 0;
int modeSwitchCnt = 0;
}; };