From 09192cfc4d3064936519d7dbd0f8cd31ce208f15 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Fri, 23 Jul 2021 11:19:59 -0700 Subject: [PATCH] fast adc callback (#3031) * fast adc callback * guard * missed one * now cypress will be happy --- firmware/development/perf_trace.h | 2 +- firmware/hw_layer/adc/adc_inputs.cpp | 7 ++- firmware/hw_layer/adc/adc_inputs.h | 5 ++ firmware/hw_layer/hardware.cpp | 84 +++++++++++----------------- 4 files changed, 45 insertions(+), 53 deletions(-) diff --git a/firmware/development/perf_trace.h b/firmware/development/perf_trace.h index 323ef8de15..c591c0aafa 100644 --- a/firmware/development/perf_trace.h +++ b/firmware/development/perf_trace.h @@ -45,7 +45,7 @@ enum class PE : uint8_t { GetSpeedDensityFuel, WallFuelAdjust, MapAveragingTriggerCallback, - AdcCallbackFastComplete, + Unused1, SingleTimerExecutorScheduleByTimestamp, GetTimeNowUs, EventQueueExecuteCallback, diff --git a/firmware/hw_layer/adc/adc_inputs.cpp b/firmware/hw_layer/adc/adc_inputs.cpp index c9a54cd15b..78243c8aeb 100644 --- a/firmware/hw_layer/adc/adc_inputs.cpp +++ b/firmware/hw_layer/adc/adc_inputs.cpp @@ -114,7 +114,12 @@ static adcsample_t getAvgAdcValue(int index, adcsample_t *samples, int bufDepth, #define ADC_SAMPLING_FAST ADC_SAMPLE_28 #if EFI_USE_FAST_ADC -void adc_callback_fast(ADCDriver *adcp); +static void adc_callback_fast(ADCDriver *adcp) { + // State may not be complete if we get a callback for "half done" + if (adcp->state == ADC_COMPLETE) { + onFastAdcComplete(adcp->samples); + } +} static ADCConversionGroup adcgrpcfgFast = { .circular = FALSE, diff --git a/firmware/hw_layer/adc/adc_inputs.h b/firmware/hw_layer/adc/adc_inputs.h index 1c8dee9d27..b3a35f58ef 100644 --- a/firmware/hw_layer/adc/adc_inputs.h +++ b/firmware/hw_layer/adc/adc_inputs.h @@ -65,3 +65,8 @@ void removeChannel(const char *name, adc_channel_e setting); #endif /* HAL_USE_ADC */ void printFullAdcReport(void); + +#if HAL_USE_ADC +// This callback is called by the ADC driver when a new fast ADC sample is ready +void onFastAdcComplete(adcsample_t* samples); +#endif diff --git a/firmware/hw_layer/hardware.cpp b/firmware/hw_layer/hardware.cpp index 4ed5eaddac..c3b0580ac1 100644 --- a/firmware/hw_layer/hardware.cpp +++ b/firmware/hw_layer/hardware.cpp @@ -155,40 +155,35 @@ static int adcCallbackCounter = 0; static volatile int averagedSamples[ADC_MAX_CHANNELS_COUNT]; static adcsample_t avgBuf[ADC_MAX_CHANNELS_COUNT]; -void adc_callback_fast_internal(ADCDriver *adcp); +void onFastAdcCompleteInternal(adcsample_t* samples); -void adc_callback_fast(ADCDriver *adcp) { - adcsample_t *buffer = adcp->samples; - //size_t n = adcp->depth; - - if (adcp->state == ADC_COMPLETE) { +void onFastAdcComplete(adcsample_t* samples) { #if HAL_TRIGGER_USE_ADC - // we need to call this ASAP, because trigger processing is time-critical - if (triggerSampleIndex >= 0) - triggerAdcCallback(buffer[triggerSampleIndex]); + // we need to call this ASAP, because trigger processing is time-critical + if (triggerSampleIndex >= 0) + triggerAdcCallback(samples[triggerSampleIndex]); #endif /* HAL_TRIGGER_USE_ADC */ - // store the values for averaging + // store the values for averaging + for (int i = fastAdc.size() - 1; i >= 0; i--) { + averagedSamples[i] += samples[i]; + } + + // 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--) { - averagedSamples[i] += fastAdc.samples[i]; + avgBuf[i] = (adcsample_t)(averagedSamples[i] / ADC_BUF_NUM_AVG); // todo: rounding? } - // 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); - // call the real callback (see below) - adc_callback_fast_internal(adcp); - - // reset the avg buffer & counter - for (int i = fastAdc.size() - 1; i >= 0; i--) { - averagedSamples[i] = 0; - } - adcCallbackCounter = 0; + // reset the avg buffer & counter + for (int i = fastAdc.size() - 1; i >= 0; i--) { + averagedSamples[i] = 0; } + adcCallbackCounter = 0; } } @@ -198,48 +193,35 @@ void adc_callback_fast(ADCDriver *adcp) { * This method is not in the adc* lower-level file because it is more business logic then hardware. */ #if EFI_FASTER_UNIFORM_ADC -void adc_callback_fast_internal(ADCDriver *adcp) { +void onFastAdcCompleteInternal(adcsample_t* buffer) { #else -void adc_callback_fast(ADCDriver *adcp) { +void onFastAdcComplete(adcsample_t* buffer) { #endif - adcsample_t *buffer = adcp->samples; - size_t n = adcp->depth; - (void) buffer; - (void) n; - ScopePerf perf(PE::AdcCallbackFast); /** - * Note, only in the ADC_COMPLETE state because the ADC driver fires an - * intermediate callback when the buffer is half full. - * */ - if (adcp->state == ADC_COMPLETE) { - ScopePerf perf(PE::AdcCallbackFastComplete); - - /** - * this callback is executed 10 000 times a second, it needs to be as fast as possible - */ - efiAssertVoid(CUSTOM_ERR_6676, getCurrentRemainingStack() > 128, "lowstck#9b"); + * this callback is executed 10 000 times a second, it needs to be as fast as possible + */ + efiAssertVoid(CUSTOM_ERR_6676, getCurrentRemainingStack() > 128, "lowstck#9b"); #if EFI_SENSOR_CHART && EFI_SHAFT_POSITION_INPUT - if (ENGINE(sensorChartMode) == SC_AUX_FAST1) { - float voltage = getAdcValue("fAux1", engineConfiguration->auxFastSensor1_adcChannel); - scAddData(getCrankshaftAngleNt(getTimeNowNt() PASS_ENGINE_PARAMETER_SUFFIX), voltage); - } + if (ENGINE(sensorChartMode) == SC_AUX_FAST1) { + float voltage = getAdcValue("fAux1", engineConfiguration->auxFastSensor1_adcChannel); + scAddData(getCrankshaftAngleNt(getTimeNowNt() PASS_ENGINE_PARAMETER_SUFFIX), voltage); + } #endif /* EFI_SENSOR_CHART */ #if EFI_MAP_AVERAGING - mapAveragingAdcCallback(buffer[fastMapSampleIndex]); + mapAveragingAdcCallback(buffer[fastMapSampleIndex]); #endif /* EFI_MAP_AVERAGING */ #if EFI_HIP_9011 - if (CONFIG(isHip9011Enabled)) { - hipAdcCallback(buffer[hipSampleIndex]); - } + if (CONFIG(isHip9011Enabled)) { + hipAdcCallback(buffer[hipSampleIndex]); + } #endif /* EFI_HIP_9011 */ // if (tpsSampleIndex != TPS_IS_SLOW) { // tpsFastAdc = buffer[tpsSampleIndex]; // } - } } #endif /* HAL_USE_ADC */