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:
parent
bc40f2c207
commit
31ffb0add4
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue