fast adc callback (#3031)

* fast adc callback

* guard

* missed one

* now cypress will be happy
This commit is contained in:
Matthew Kennedy 2021-07-23 11:19:59 -07:00 committed by GitHub
parent a59179396f
commit 09192cfc4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 53 deletions

View File

@ -45,7 +45,7 @@ enum class PE : uint8_t {
GetSpeedDensityFuel, GetSpeedDensityFuel,
WallFuelAdjust, WallFuelAdjust,
MapAveragingTriggerCallback, MapAveragingTriggerCallback,
AdcCallbackFastComplete, Unused1,
SingleTimerExecutorScheduleByTimestamp, SingleTimerExecutorScheduleByTimestamp,
GetTimeNowUs, GetTimeNowUs,
EventQueueExecuteCallback, EventQueueExecuteCallback,

View File

@ -114,7 +114,12 @@ static adcsample_t getAvgAdcValue(int index, adcsample_t *samples, int bufDepth,
#define ADC_SAMPLING_FAST ADC_SAMPLE_28 #define ADC_SAMPLING_FAST ADC_SAMPLE_28
#if EFI_USE_FAST_ADC #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 = { static ADCConversionGroup adcgrpcfgFast = {
.circular = FALSE, .circular = FALSE,

View File

@ -65,3 +65,8 @@ void removeChannel(const char *name, adc_channel_e setting);
#endif /* HAL_USE_ADC */ #endif /* HAL_USE_ADC */
void printFullAdcReport(void); 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

View File

@ -155,40 +155,35 @@ static int adcCallbackCounter = 0;
static volatile int averagedSamples[ADC_MAX_CHANNELS_COUNT]; static volatile int averagedSamples[ADC_MAX_CHANNELS_COUNT];
static adcsample_t avgBuf[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) { void onFastAdcComplete(adcsample_t* samples) {
adcsample_t *buffer = adcp->samples;
//size_t n = adcp->depth;
if (adcp->state == ADC_COMPLETE) {
#if HAL_TRIGGER_USE_ADC #if HAL_TRIGGER_USE_ADC
// we need to call this ASAP, because trigger processing is time-critical // we need to call this ASAP, because trigger processing is time-critical
if (triggerSampleIndex >= 0) if (triggerSampleIndex >= 0)
triggerAdcCallback(buffer[triggerSampleIndex]); triggerAdcCallback(samples[triggerSampleIndex]);
#endif /* HAL_TRIGGER_USE_ADC */ #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--) { 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 // call the real callback (see below)
if (++adcCallbackCounter >= ADC_BUF_NUM_AVG) { onFastAdcCompleteInternal(samples);
// 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) // reset the avg buffer & counter
adc_callback_fast_internal(adcp); for (int i = fastAdc.size() - 1; i >= 0; i--) {
averagedSamples[i] = 0;
// reset the avg buffer & counter
for (int i = fastAdc.size() - 1; i >= 0; i--) {
averagedSamples[i] = 0;
}
adcCallbackCounter = 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. * This method is not in the adc* lower-level file because it is more business logic then hardware.
*/ */
#if EFI_FASTER_UNIFORM_ADC #if EFI_FASTER_UNIFORM_ADC
void adc_callback_fast_internal(ADCDriver *adcp) { void onFastAdcCompleteInternal(adcsample_t* buffer) {
#else #else
void adc_callback_fast(ADCDriver *adcp) { void onFastAdcComplete(adcsample_t* buffer) {
#endif #endif
adcsample_t *buffer = adcp->samples;
size_t n = adcp->depth;
(void) buffer;
(void) n;
ScopePerf perf(PE::AdcCallbackFast); ScopePerf perf(PE::AdcCallbackFast);
/** /**
* Note, only in the ADC_COMPLETE state because the ADC driver fires an * this callback is executed 10 000 times a second, it needs to be as fast as possible
* intermediate callback when the buffer is half full. */
* */ efiAssertVoid(CUSTOM_ERR_6676, getCurrentRemainingStack() > 128, "lowstck#9b");
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");
#if EFI_SENSOR_CHART && EFI_SHAFT_POSITION_INPUT #if EFI_SENSOR_CHART && EFI_SHAFT_POSITION_INPUT
if (ENGINE(sensorChartMode) == SC_AUX_FAST1) { if (ENGINE(sensorChartMode) == SC_AUX_FAST1) {
float voltage = getAdcValue("fAux1", engineConfiguration->auxFastSensor1_adcChannel); float voltage = getAdcValue("fAux1", engineConfiguration->auxFastSensor1_adcChannel);
scAddData(getCrankshaftAngleNt(getTimeNowNt() PASS_ENGINE_PARAMETER_SUFFIX), voltage); scAddData(getCrankshaftAngleNt(getTimeNowNt() PASS_ENGINE_PARAMETER_SUFFIX), voltage);
} }
#endif /* EFI_SENSOR_CHART */ #endif /* EFI_SENSOR_CHART */
#if EFI_MAP_AVERAGING #if EFI_MAP_AVERAGING
mapAveragingAdcCallback(buffer[fastMapSampleIndex]); mapAveragingAdcCallback(buffer[fastMapSampleIndex]);
#endif /* EFI_MAP_AVERAGING */ #endif /* EFI_MAP_AVERAGING */
#if EFI_HIP_9011 #if EFI_HIP_9011
if (CONFIG(isHip9011Enabled)) { if (CONFIG(isHip9011Enabled)) {
hipAdcCallback(buffer[hipSampleIndex]); hipAdcCallback(buffer[hipSampleIndex]);
} }
#endif /* EFI_HIP_9011 */ #endif /* EFI_HIP_9011 */
// if (tpsSampleIndex != TPS_IS_SLOW) { // if (tpsSampleIndex != TPS_IS_SLOW) {
// tpsFastAdc = buffer[tpsSampleIndex]; // tpsFastAdc = buffer[tpsSampleIndex];
// } // }
}
} }
#endif /* HAL_USE_ADC */ #endif /* HAL_USE_ADC */