H7 ADC triggered by hardware timer (#3028)
* config * allow changing adc speed * timer triggered ADC * ICU on nucleo * turn that off too * 10khz * make those default for all h7 * I can't type
This commit is contained in:
parent
09192cfc4d
commit
f70c844c60
|
@ -34,3 +34,18 @@
|
|||
|
||||
#undef ENABLE_PERF_TRACE
|
||||
#define ENABLE_PERF_TRACE TRUE
|
||||
|
||||
// H7 runs faster "slow" ADC to make up for reduced oversampling
|
||||
#define SLOW_ADC_RATE 1000
|
||||
|
||||
#undef EFI_ICU_INPUTS
|
||||
#define EFI_ICU_INPUTS FALSE
|
||||
|
||||
#undef HAL_TRIGGER_USE_PAL
|
||||
#define HAL_TRIGGER_USE_PAL TRUE
|
||||
|
||||
#undef EFI_LOGIC_ANALYZER
|
||||
#define EFI_LOGIC_ANALYZER FALSE
|
||||
|
||||
#undef HAL_VSS_USE_PAL
|
||||
#define HAL_VSS_USE_PAL TRUE
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
#include "global.h"
|
||||
#include "adc_math.h"
|
||||
|
||||
#ifndef SLOW_ADC_RATE
|
||||
#define SLOW_ADC_RATE 500
|
||||
#endif
|
||||
|
||||
static inline bool isAdcChannelValid(adc_channel_e hwChannel) {
|
||||
if (hwChannel <= EFI_ADC_NONE) {
|
||||
|
|
|
@ -25,10 +25,10 @@ float getMcuTemperature() {
|
|||
}
|
||||
|
||||
// ADC Clock is 25MHz
|
||||
// 32.5 sampling + 8.5 conversion = 41 cycles per sample total
|
||||
// 16 channels * 16x oversample = 256 samples per batch
|
||||
// (41 * 256) / 25MHz -> 419 microseconds to sample all channels
|
||||
#define ADC_SAMPLING_SLOW ADC_SMPR_SMP_32P5
|
||||
// 16.5 sampling + 8.5 conversion = 25 cycles per sample total
|
||||
// 16 channels * 4x oversample = 64 samples per batch
|
||||
// (25 * 64) / 25MHz -> 64 microseconds to sample all channels
|
||||
#define ADC_SAMPLING_SLOW ADC_SMPR_SMP_16P5
|
||||
|
||||
// Sample the 16 channels that line up with the STM32F4/F7
|
||||
constexpr size_t slowChannelCount = 16;
|
||||
|
@ -36,13 +36,13 @@ constexpr size_t slowChannelCount = 16;
|
|||
// Conversion group for slow channels
|
||||
// This simply samples every channel in sequence
|
||||
static constexpr ADCConversionGroup convGroupSlow = {
|
||||
.circular = FALSE,
|
||||
.circular = true, // Continuous mode means we will auto re-trigger on every timer event
|
||||
.num_channels = slowChannelCount,
|
||||
.end_cb = nullptr,
|
||||
.error_cb = nullptr,
|
||||
.cfgr = 0,
|
||||
.cfgr2 = 15 << ADC_CFGR2_OVSR_Pos | // Oversample by 16x (register contains N-1)
|
||||
4 << ADC_CFGR2_OVSS_Pos | // shift the result right 4 bits to make a 16 bit result
|
||||
.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)
|
||||
2 << ADC_CFGR2_OVSS_Pos | // shift the result right 2 bits to make a 16 bit result out of the 18 bit internal sum (4x oversampled)
|
||||
ADC_CFGR2_ROVSE, // Enable oversampling
|
||||
.ccr = 0,
|
||||
.pcsel = 0xFFFFFFFF, // enable analog switches on all channels
|
||||
|
@ -93,10 +93,36 @@ static constexpr ADCConversionGroup convGroupSlow = {
|
|||
},
|
||||
};
|
||||
|
||||
static bool didStart = false;
|
||||
|
||||
bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
||||
// Oversampling and right-shift happen in hardware, so we can sample directly to the output buffer
|
||||
msg_t result = adcConvert(&ADCD1, &convGroupSlow, convertedSamples, 1);
|
||||
// This only needs to happen once, as the timer will continue firing the ADC and writing to the buffer without our help
|
||||
if (didStart) {
|
||||
return true;
|
||||
}
|
||||
didStart = true;
|
||||
|
||||
{
|
||||
chibios_rt::CriticalSectionLocker csl;
|
||||
// Oversampling and right-shift happen in hardware, so we can sample directly to the output buffer
|
||||
adcStartConversionI(&ADCD1, &convGroupSlow, convertedSamples, 1);
|
||||
}
|
||||
|
||||
constexpr uint32_t samplingRate = 10000;
|
||||
constexpr uint32_t timerCountFrequency = samplingRate * 100;
|
||||
constexpr uint32_t timerPeriod = timerCountFrequency / samplingRate;
|
||||
|
||||
static constexpr GPTConfig gptCfg = {
|
||||
timerCountFrequency,
|
||||
nullptr,
|
||||
TIM_CR2_MMS_1, // TRGO on update event
|
||||
0
|
||||
};
|
||||
|
||||
// Start timer
|
||||
gptStart(&GPTD3, &gptCfg);
|
||||
gptStartContinuous(&GPTD3, timerPeriod);
|
||||
|
||||
// Return true if OK
|
||||
return result == MSG_OK;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
* @brief Enables the ICU subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ICU TRUE
|
||||
#define HAL_USE_ICU FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -264,7 +264,7 @@
|
|||
*/
|
||||
#define STM32_GPT_USE_TIM1 FALSE
|
||||
#define STM32_GPT_USE_TIM2 FALSE
|
||||
#define STM32_GPT_USE_TIM3 FALSE
|
||||
#define STM32_GPT_USE_TIM3 TRUE
|
||||
#define STM32_GPT_USE_TIM4 FALSE
|
||||
#define STM32_GPT_USE_TIM5 FALSE
|
||||
#define STM32_GPT_USE_TIM6 TRUE
|
||||
|
@ -306,9 +306,9 @@
|
|||
/*
|
||||
* ICU driver system settings.
|
||||
*/
|
||||
#define STM32_ICU_USE_TIM1 TRUE
|
||||
#define STM32_ICU_USE_TIM2 TRUE
|
||||
#define STM32_ICU_USE_TIM3 TRUE
|
||||
#define STM32_ICU_USE_TIM1 FALSE
|
||||
#define STM32_ICU_USE_TIM2 FALSE
|
||||
#define STM32_ICU_USE_TIM3 FALSE
|
||||
#define STM32_ICU_USE_TIM4 FALSE
|
||||
#define STM32_ICU_USE_TIM5 FALSE
|
||||
#define STM32_ICU_USE_TIM8 FALSE
|
||||
|
|
Loading…
Reference in New Issue