Fast adc API (#3327)

* 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
This commit is contained in:
Matthew Kennedy 2021-10-07 05:29:01 -07:00 committed by GitHub
parent bc40f2c207
commit 31ffb0add4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 36 deletions

View File

@ -2,9 +2,6 @@
#pragma once
#undef EFI_MAP_AVERAGING
#define EFI_MAP_AVERAGING FALSE
#undef EFI_USE_FAST_ADC
// https://github.com/rusefi/rusefi/issues/3301 "H7 is currently actually using fast ADC exclusively - it just needs a bit of plumbing to make it work."
#define EFI_USE_FAST_ADC FALSE

View File

@ -62,11 +62,14 @@ void removeChannel(const char *name, adc_channel_e setting);
#define adcToVoltsDivided(adc) (adcToVolts(adc) * engineConfiguration->analogInputDividerCoefficient)
#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
using FastAdcToken = size_t;
FastAdcToken enableFastAdcChannel(const char* msg, adc_channel_e channel);
adcsample_t getFastAdc(FastAdcToken token);
#endif // HAL_USE_ADC
void printFullAdcReport(void);

View File

@ -137,17 +137,15 @@ SPIDriver * getSpiDevice(spi_device_e spiDevice) {
}
#endif
#define TPS_IS_SLOW -1
#if HAL_USE_ADC
static int fastMapSampleIndex;
static int hipSampleIndex;
static int tpsSampleIndex;
static FastAdcToken fastMapSampleIndex;
static FastAdcToken hipSampleIndex;
#if HAL_TRIGGER_USE_ADC
static int triggerSampleIndex;
static FastAdcToken triggerSampleIndex;
#endif
#if HAL_USE_ADC
extern AdcDevice fastAdc;
#if EFI_FASTER_UNIFORM_ADC
@ -160,8 +158,7 @@ void onFastAdcCompleteInternal(adcsample_t* samples);
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(samples[triggerSampleIndex]);
triggerAdcCallback(getFastAdc(triggerSampleIndex));
#endif /* HAL_TRIGGER_USE_ADC */
// store the values for averaging
@ -193,9 +190,9 @@ void onFastAdcComplete(adcsample_t* samples) {
* 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* buffer) {
void onFastAdcCompleteInternal(adcsample_t*) {
#else
void onFastAdcComplete(adcsample_t* buffer) {
void onFastAdcComplete(adcsample_t*) {
#endif
ScopePerf perf(PE::AdcCallbackFast);
@ -212,32 +209,22 @@ void onFastAdcComplete(adcsample_t* buffer) {
#endif /* EFI_SENSOR_CHART */
#if EFI_MAP_AVERAGING
mapAveragingAdcCallback(buffer[fastMapSampleIndex]);
mapAveragingAdcCallback(getFastAdc(fastMapSampleIndex));
#endif /* EFI_MAP_AVERAGING */
#if EFI_HIP_9011
if (CONFIG(isHip9011Enabled)) {
hipAdcCallback(buffer[hipSampleIndex]);
hipAdcCallback(getFastAdc(hipSampleIndex));
}
#endif /* EFI_HIP_9011 */
// if (tpsSampleIndex != TPS_IS_SLOW) {
// tpsFastAdc = buffer[tpsSampleIndex];
// }
}
#endif /* HAL_USE_ADC */
static void calcFastAdcIndexes(void) {
#if HAL_USE_ADC && EFI_USE_FAST_ADC
fastMapSampleIndex = fastAdc.internalAdcIndexByHardwareIndex[engineConfiguration->map.sensor.hwChannel];
hipSampleIndex =
isAdcChannelValid(engineConfiguration->hipOutputChannel) ?
fastAdc.internalAdcIndexByHardwareIndex[engineConfiguration->hipOutputChannel] : -1;
tpsSampleIndex =
isAdcChannelValid(engineConfiguration->tps1_1AdcChannel) ?
fastAdc.internalAdcIndexByHardwareIndex[engineConfiguration->tps1_1AdcChannel] : TPS_IS_SLOW;
#if HAL_USE_ADC
fastMapSampleIndex = enableFastAdcChannel("Fast MAP", engineConfiguration->map.sensor.hwChannel);
hipSampleIndex = enableFastAdcChannel("HIP9011", engineConfiguration->hipOutputChannel);
#if HAL_TRIGGER_USE_ADC
adc_channel_e triggerChannel = getAdcChannelForTrigger();
triggerSampleIndex = isAdcChannelValid(triggerChannel) ?
fastAdc.internalAdcIndexByHardwareIndex[triggerChannel] : -1;
triggerSampleIndex = enableFastAdcChannel("Trigger ADC", getAdcChannelForTrigger());
#endif /* HAL_TRIGGER_USE_ADC */
#endif/* HAL_USE_ADC */

View File

@ -275,4 +275,24 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
return true;
}
static constexpr FastAdcToken invalidToken = (FastAdcToken)(-1);
FastAdcToken enableFastAdcChannel(const char*, adc_channel_e channel) {
if (!isAdcChannelValid(channel)) {
return invalidToken;
}
// TODO: implement me!
return invalidToken;
}
adcsample_t getFastAdc(FastAdcToken token) {
if (token == invalidToken) {
return 0;
}
// TODO: implement me!
return 0;
}
#endif /* EFI_PROD_CODE */

View File

@ -280,4 +280,24 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
return true;
}
static constexpr FastAdcToken invalidToken = (FastAdcToken)(-1);
FastAdcToken enableFastAdcChannel(const char*, adc_channel_e channel) {
if (!isAdcChannelValid(channel)) {
return invalidToken;
}
// TODO: implement me!
return invalidToken;
}
adcsample_t getFastAdc(FastAdcToken token) {
if (token == invalidToken) {
return 0;
}
// TODO: implement me!
return 0;
}
#endif /* EFI_PROD_CODE */

View File

@ -174,4 +174,30 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
return true;
}
#if EFI_USE_FAST_ADC
#include "AdcConfiguration.h"
extern AdcDevice fastAdc;
static constexpr FastAdcToken invalidToken = (FastAdcToken)(-1);
FastAdcToken enableFastAdcChannel(const char*, adc_channel_e channel) {
if (!isAdcChannelValid(channel)) {
return invalidToken;
}
return fastAdc.internalAdcIndexByHardwareIndex[static_cast<size_t>(channel)];
}
adcsample_t getFastAdc(FastAdcToken token) {
if (token == invalidToken) {
return 0;
}
return fastAdc.samples[token];
}
#endif
#endif // HAL_USE_ADC

View File

@ -8,6 +8,7 @@
#include "pch.h"
#include "mpu_util.h"
#include "map_averaging.h"
void portInitAdc() {
// Init slow ADC
@ -23,6 +24,15 @@ float getMcuTemperature() {
return 0;
}
adcsample_t* fastSampleBuffer;
static void adc_callback(ADCDriver *adcp) {
// State may not be complete if we get a callback for "half done"
if (adcp->state == ADC_COMPLETE) {
onFastAdcComplete(adcp->samples);
}
}
// ADC Clock is 25MHz
// 16.5 sampling + 8.5 conversion = 25 cycles per sample total
// 16 channels * 4x oversample = 64 samples per batch
@ -37,7 +47,7 @@ constexpr size_t slowChannelCount = 16;
static constexpr ADCConversionGroup convGroupSlow = {
.circular = true, // Continuous mode means we will auto re-trigger on every timer event
.num_channels = slowChannelCount,
.end_cb = nullptr,
.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)
@ -101,6 +111,8 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
}
didStart = true;
fastSampleBuffer = convertedSamples;
{
chibios_rt::CriticalSectionLocker csl;
// Oversampling and right-shift happen in hardware, so we can sample directly to the output buffer
@ -125,3 +137,22 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
// Return true if OK
return true;
}
static constexpr FastAdcToken invalidToken = (FastAdcToken)(-1);
FastAdcToken enableFastAdcChannel(const char*, adc_channel_e channel) {
if (!isAdcChannelValid(channel)) {
return invalidToken;
}
// H7 always samples all fast channels, nothing to do here but compute index
return channel - EFI_ADC_0;
}
adcsample_t getFastAdc(FastAdcToken token) {
if (token == invalidToken) {
return 0;
}
return fastSampleBuffer[token];
}