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
9565425bdc
commit
a4998ab7a8
|
@ -2,9 +2,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#undef EFI_MAP_AVERAGING
|
|
||||||
#define EFI_MAP_AVERAGING FALSE
|
|
||||||
|
|
||||||
#undef EFI_USE_FAST_ADC
|
#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."
|
// 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
|
#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)
|
#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
|
// This callback is called by the ADC driver when a new fast ADC sample is ready
|
||||||
void onFastAdcComplete(adcsample_t* samples);
|
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
|
#endif
|
||||||
|
|
||||||
#define TPS_IS_SLOW -1
|
#if HAL_USE_ADC
|
||||||
|
|
||||||
static int fastMapSampleIndex;
|
static FastAdcToken fastMapSampleIndex;
|
||||||
static int hipSampleIndex;
|
static FastAdcToken hipSampleIndex;
|
||||||
static int tpsSampleIndex;
|
|
||||||
|
|
||||||
#if HAL_TRIGGER_USE_ADC
|
#if HAL_TRIGGER_USE_ADC
|
||||||
static int triggerSampleIndex;
|
static FastAdcToken triggerSampleIndex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAL_USE_ADC
|
|
||||||
extern AdcDevice fastAdc;
|
extern AdcDevice fastAdc;
|
||||||
|
|
||||||
#if EFI_FASTER_UNIFORM_ADC
|
#if EFI_FASTER_UNIFORM_ADC
|
||||||
|
@ -160,8 +158,7 @@ void onFastAdcCompleteInternal(adcsample_t* samples);
|
||||||
void onFastAdcComplete(adcsample_t* samples) {
|
void onFastAdcComplete(adcsample_t* samples) {
|
||||||
#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)
|
triggerAdcCallback(getFastAdc(triggerSampleIndex));
|
||||||
triggerAdcCallback(samples[triggerSampleIndex]);
|
|
||||||
#endif /* HAL_TRIGGER_USE_ADC */
|
#endif /* HAL_TRIGGER_USE_ADC */
|
||||||
|
|
||||||
// store the values for averaging
|
// 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.
|
* 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 onFastAdcCompleteInternal(adcsample_t* buffer) {
|
void onFastAdcCompleteInternal(adcsample_t*) {
|
||||||
#else
|
#else
|
||||||
void onFastAdcComplete(adcsample_t* buffer) {
|
void onFastAdcComplete(adcsample_t*) {
|
||||||
#endif
|
#endif
|
||||||
ScopePerf perf(PE::AdcCallbackFast);
|
ScopePerf perf(PE::AdcCallbackFast);
|
||||||
|
|
||||||
|
@ -212,32 +209,22 @@ void onFastAdcComplete(adcsample_t* buffer) {
|
||||||
#endif /* EFI_SENSOR_CHART */
|
#endif /* EFI_SENSOR_CHART */
|
||||||
|
|
||||||
#if EFI_MAP_AVERAGING
|
#if EFI_MAP_AVERAGING
|
||||||
mapAveragingAdcCallback(buffer[fastMapSampleIndex]);
|
mapAveragingAdcCallback(getFastAdc(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(getFastAdc(hipSampleIndex));
|
||||||
}
|
}
|
||||||
#endif /* EFI_HIP_9011 */
|
#endif /* EFI_HIP_9011 */
|
||||||
// if (tpsSampleIndex != TPS_IS_SLOW) {
|
|
||||||
// tpsFastAdc = buffer[tpsSampleIndex];
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
#endif /* HAL_USE_ADC */
|
#endif /* HAL_USE_ADC */
|
||||||
|
|
||||||
static void calcFastAdcIndexes(void) {
|
static void calcFastAdcIndexes(void) {
|
||||||
#if HAL_USE_ADC && EFI_USE_FAST_ADC
|
#if HAL_USE_ADC
|
||||||
fastMapSampleIndex = fastAdc.internalAdcIndexByHardwareIndex[engineConfiguration->map.sensor.hwChannel];
|
fastMapSampleIndex = enableFastAdcChannel("Fast MAP", engineConfiguration->map.sensor.hwChannel);
|
||||||
hipSampleIndex =
|
hipSampleIndex = enableFastAdcChannel("HIP9011", engineConfiguration->hipOutputChannel);
|
||||||
isAdcChannelValid(engineConfiguration->hipOutputChannel) ?
|
|
||||||
fastAdc.internalAdcIndexByHardwareIndex[engineConfiguration->hipOutputChannel] : -1;
|
|
||||||
tpsSampleIndex =
|
|
||||||
isAdcChannelValid(engineConfiguration->tps1_1AdcChannel) ?
|
|
||||||
fastAdc.internalAdcIndexByHardwareIndex[engineConfiguration->tps1_1AdcChannel] : TPS_IS_SLOW;
|
|
||||||
#if HAL_TRIGGER_USE_ADC
|
#if HAL_TRIGGER_USE_ADC
|
||||||
adc_channel_e triggerChannel = getAdcChannelForTrigger();
|
triggerSampleIndex = enableFastAdcChannel("Trigger ADC", getAdcChannelForTrigger());
|
||||||
triggerSampleIndex = isAdcChannelValid(triggerChannel) ?
|
|
||||||
fastAdc.internalAdcIndexByHardwareIndex[triggerChannel] : -1;
|
|
||||||
#endif /* HAL_TRIGGER_USE_ADC */
|
#endif /* HAL_TRIGGER_USE_ADC */
|
||||||
|
|
||||||
#endif/* HAL_USE_ADC */
|
#endif/* HAL_USE_ADC */
|
||||||
|
|
|
@ -275,4 +275,24 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
||||||
return true;
|
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 */
|
#endif /* EFI_PROD_CODE */
|
||||||
|
|
|
@ -280,4 +280,24 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
||||||
return true;
|
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 */
|
#endif /* EFI_PROD_CODE */
|
||||||
|
|
|
@ -174,4 +174,30 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
||||||
return true;
|
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
|
#endif // HAL_USE_ADC
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "mpu_util.h"
|
#include "mpu_util.h"
|
||||||
|
#include "map_averaging.h"
|
||||||
|
|
||||||
void portInitAdc() {
|
void portInitAdc() {
|
||||||
// Init slow ADC
|
// Init slow ADC
|
||||||
|
@ -23,6 +24,15 @@ float getMcuTemperature() {
|
||||||
return 0;
|
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
|
// ADC Clock is 25MHz
|
||||||
// 16.5 sampling + 8.5 conversion = 25 cycles per sample total
|
// 16.5 sampling + 8.5 conversion = 25 cycles per sample total
|
||||||
// 16 channels * 4x oversample = 64 samples per batch
|
// 16 channels * 4x oversample = 64 samples per batch
|
||||||
|
@ -37,7 +47,7 @@ constexpr size_t slowChannelCount = 16;
|
||||||
static constexpr ADCConversionGroup convGroupSlow = {
|
static constexpr ADCConversionGroup convGroupSlow = {
|
||||||
.circular = true, // Continuous mode means we will auto re-trigger on every timer event
|
.circular = true, // Continuous mode means we will auto re-trigger on every timer event
|
||||||
.num_channels = slowChannelCount,
|
.num_channels = slowChannelCount,
|
||||||
.end_cb = nullptr,
|
.end_cb = adc_callback,
|
||||||
.error_cb = nullptr,
|
.error_cb = nullptr,
|
||||||
.cfgr = ADC_CFGR_EXTEN_0 | (4 << ADC_CFGR_EXTSEL_Pos), // External trigger ch4, rising edge: TIM3 TRGO
|
.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)
|
.cfgr2 = 3 << ADC_CFGR2_OVSR_Pos | // Oversample by 4x (register contains N-1)
|
||||||
|
@ -101,6 +111,8 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
||||||
}
|
}
|
||||||
didStart = true;
|
didStart = true;
|
||||||
|
|
||||||
|
fastSampleBuffer = convertedSamples;
|
||||||
|
|
||||||
{
|
{
|
||||||
chibios_rt::CriticalSectionLocker csl;
|
chibios_rt::CriticalSectionLocker csl;
|
||||||
// Oversampling and right-shift happen in hardware, so we can sample directly to the output buffer
|
// 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 if OK
|
||||||
return true;
|
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