faster uniform adc cleanup (#3334)
* dead fast tps * oooooh map avg on hh7 * adc v4 fast support * new fast API * hardware.cpp * adc v2 * warning * guard * no check required * stub cypress/kinetis * kinetis and cypress stubs * cleanup * h7 adc speed * adc skip * configurable oversample
This commit is contained in:
parent
3d7aa1eeb7
commit
abb6513744
|
@ -37,12 +37,7 @@ DDEFS += -DEFI_LOGIC_ANALYZER=FALSE
|
|||
|
||||
TRIGGER_USE_ADC = yes
|
||||
|
||||
# we need fast ADC for software trigger detector
|
||||
#DDEFS += -DEFI_OVERRIDE_FAST_ADC_FOR_STM32H7=TRUE -DADC_FAST_DEVICE=ADCD1 -DADC_SLOW_DEVICE=ADCD3 -DSTM32_ADC_USE_ADC3=TRUE
|
||||
#DDEFS += -DADC_SLOW_DEVICE=ADCD3 -DSTM32_ADC_USE_ADC3=TRUE
|
||||
|
||||
DDEFS += -DEFI_OVERRIDE_FAST_ADC_FOR_STM32H7=TRUE -DADC_FAST_DEVICE=ADCD1 -DEFI_USE_ONLY_FAST_ADC=TRUE -DEFI_FASTER_UNIFORM_ADC=TRUE -DADC_MAX_CHANNELS_COUNT=16 -DADC_BUF_DEPTH_FAST=1 -DADC_BUF_NUM_AVG=1
|
||||
#DDEFS += -DADC_SLOW_DEVICE=ADCD1
|
||||
DDEFS += -DFAST_ADC_SKIP=3 -DH7_ADC_SPEED=20000 -DH7_ADC_OVERSAMPLE=2
|
||||
|
||||
# We are running on Hellen-One hardware!
|
||||
DDEFS += -DHW_HELLEN=1
|
||||
|
|
|
@ -148,53 +148,32 @@ static FastAdcToken triggerSampleIndex;
|
|||
|
||||
extern AdcDevice fastAdc;
|
||||
|
||||
#if EFI_FASTER_UNIFORM_ADC
|
||||
static int adcCallbackCounter = 0;
|
||||
static volatile int averagedSamples[ADC_MAX_CHANNELS_COUNT];
|
||||
static adcsample_t avgBuf[ADC_MAX_CHANNELS_COUNT];
|
||||
#ifdef FAST_ADC_SKIP
|
||||
// No reason to enable if N = 1
|
||||
static_assert(FAST_ADC_SKIP > 1);
|
||||
static size_t fastAdcSkipCount = 0;
|
||||
#endif // FAST_ADC_SKIP
|
||||
|
||||
void onFastAdcCompleteInternal(adcsample_t* samples);
|
||||
/**
|
||||
* This method is not in the adc* lower-level file because it is more business logic then hardware.
|
||||
*/
|
||||
void onFastAdcComplete(adcsample_t*) {
|
||||
ScopePerf perf(PE::AdcCallbackFast);
|
||||
|
||||
void onFastAdcComplete(adcsample_t* samples) {
|
||||
#if HAL_TRIGGER_USE_ADC
|
||||
// we need to call this ASAP, because trigger processing is time-critical
|
||||
triggerAdcCallback(getFastAdc(triggerSampleIndex));
|
||||
#endif /* HAL_TRIGGER_USE_ADC */
|
||||
|
||||
// store the values for averaging
|
||||
for (int i = fastAdc.size() - 1; i >= 0; i--) {
|
||||
averagedSamples[i] += samples[i];
|
||||
#ifdef FAST_ADC_SKIP
|
||||
// If we run the fast ADC _very_ fast for triggerAdcCallback's benefit, we may want to
|
||||
// skip most of the samples for the rest of the callback.
|
||||
if (fastAdcSkipCount++ == FAST_ADC_SKIP) {
|
||||
fastAdcSkipCount = 0;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// if it's time to process the data
|
||||
if (++adcCallbackCounter >= ADC_BUF_NUM_AVG) {
|
||||
// get an average
|
||||
for (int i = fastAdc.size() - 1; i >= 0; i--) {
|
||||
avgBuf[i] = (adcsample_t)(averagedSamples[i] / ADC_BUF_NUM_AVG); // todo: rounding?
|
||||
}
|
||||
|
||||
// call the real callback (see below)
|
||||
onFastAdcCompleteInternal(samples);
|
||||
|
||||
// reset the avg buffer & counter
|
||||
for (int i = fastAdc.size() - 1; i >= 0; i--) {
|
||||
averagedSamples[i] = 0;
|
||||
}
|
||||
adcCallbackCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* EFI_FASTER_UNIFORM_ADC */
|
||||
|
||||
/**
|
||||
* This method is not in the adc* lower-level file because it is more business logic then hardware.
|
||||
*/
|
||||
#if EFI_FASTER_UNIFORM_ADC
|
||||
void onFastAdcCompleteInternal(adcsample_t*) {
|
||||
#else
|
||||
void onFastAdcComplete(adcsample_t*) {
|
||||
#endif
|
||||
ScopePerf perf(PE::AdcCallbackFast);
|
||||
|
||||
/**
|
||||
* this callback is executed 10 000 times a second, it needs to be as fast as possible
|
||||
|
@ -237,13 +216,6 @@ static void adcConfigListener(Engine *engine) {
|
|||
}
|
||||
|
||||
static void turnOnHardware(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||
#if EFI_FASTER_UNIFORM_ADC
|
||||
for (int i = 0; i < ADC_MAX_CHANNELS_COUNT; i++) {
|
||||
averagedSamples[i] = 0;
|
||||
}
|
||||
adcCallbackCounter = 0;
|
||||
#endif /* EFI_FASTER_UNIFORM_ADC */
|
||||
|
||||
#if EFI_PROD_CODE && EFI_SHAFT_POSITION_INPUT
|
||||
turnOnTriggerInputPins(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
#endif /* EFI_SHAFT_POSITION_INPUT */
|
||||
|
|
|
@ -10,6 +10,29 @@
|
|||
#include "mpu_util.h"
|
||||
#include "map_averaging.h"
|
||||
|
||||
#ifndef H7_ADC_SPEED
|
||||
#define H7_ADC_SPEED (10000)
|
||||
#endif
|
||||
|
||||
#ifndef H7_ADC_OVERSAMPLE
|
||||
#define H7_ADC_OVERSAMPLE (4)
|
||||
#endif
|
||||
|
||||
static_assert((H7_ADC_OVERSAMPLE & (H7_ADC_OVERSAMPLE - 1)) == 0, "H7_ADC_OVERSAMPLE must be a power of 2");
|
||||
|
||||
constexpr size_t log2_int(size_t x) {
|
||||
size_t result = 0;
|
||||
while (x >>= 1) result++;
|
||||
return result;
|
||||
}
|
||||
|
||||
// poor man's unit test
|
||||
static_assert(log2_int(4) == 2);
|
||||
static_assert(log2_int(16) == 4);
|
||||
|
||||
// Shift the result by log2(N) bits to divide by N
|
||||
static constexpr int H7_ADC_SHIFT_BITS = log2_int(H7_ADC_OVERSAMPLE);
|
||||
|
||||
void portInitAdc() {
|
||||
// Init slow ADC
|
||||
adcStart(&ADCD1, NULL);
|
||||
|
@ -50,8 +73,8 @@ static constexpr ADCConversionGroup convGroupSlow = {
|
|||
.end_cb = adc_callback,
|
||||
.error_cb = nullptr,
|
||||
.cfgr = ADC_CFGR_EXTEN_0 | (4 << ADC_CFGR_EXTSEL_Pos), // External trigger ch4, rising edge: TIM3 TRGO
|
||||
.cfgr2 = 3 << ADC_CFGR2_OVSR_Pos | // Oversample by 4x (register contains N-1)
|
||||
2 << ADC_CFGR2_OVSS_Pos | // shift the result right 2 bits to make a 16 bit result out of the 18 bit internal sum (4x oversampled)
|
||||
.cfgr2 = (H7_ADC_OVERSAMPLE - 1) << ADC_CFGR2_OVSR_Pos | // Oversample by Nx (register contains N-1)
|
||||
H7_ADC_SHIFT_BITS << ADC_CFGR2_OVSS_Pos | // shift the result right log2(N) bits to make a 16 bit result out of the internal oversample sum
|
||||
ADC_CFGR2_ROVSE, // Enable oversampling
|
||||
.ccr = 0,
|
||||
.pcsel = 0xFFFFFFFF, // enable analog switches on all channels
|
||||
|
@ -119,8 +142,8 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
|||
adcStartConversionI(&ADCD1, &convGroupSlow, convertedSamples, 1);
|
||||
}
|
||||
|
||||
constexpr uint32_t samplingRate = 10000;
|
||||
constexpr uint32_t timerCountFrequency = samplingRate * 100;
|
||||
constexpr uint32_t samplingRate = H7_ADC_SPEED;
|
||||
constexpr uint32_t timerCountFrequency = samplingRate * 10;
|
||||
constexpr uint32_t timerPeriod = timerCountFrequency / samplingRate;
|
||||
|
||||
static constexpr GPTConfig gptCfg = {
|
||||
|
|
Loading…
Reference in New Issue