mirror of https://github.com/rusefi/rusefi-1.git
ADC cleanup, enable oversampling on H7 (#2437)
* cleanup v2 adc * simplify * oversample on h7 * output 16b result * port-ify ADC_MAX_VALUE * simplify include * guard for cypress * make sim/tests happy * 16x oversample + comment * this check is uesless Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
parent
b4f1fedc9e
commit
96a14fd649
|
@ -38,7 +38,12 @@
|
|||
#include "perf_trace.h"
|
||||
#include "thread_priority.h"
|
||||
|
||||
static adcsample_t slowAdcSamples[ADC_MAX_CHANNELS_COUNT];
|
||||
/* Depth of the conversion buffer, channels are sampled X times each.*/
|
||||
#ifndef ADC_BUF_DEPTH_FAST
|
||||
#define ADC_BUF_DEPTH_FAST 4
|
||||
#endif
|
||||
|
||||
static NO_CACHE adcsample_t slowAdcSamples[ADC_MAX_CHANNELS_COUNT];
|
||||
static NO_CACHE adcsample_t fastAdcSampleBuf[ADC_BUF_DEPTH_FAST * ADC_MAX_CHANNELS_COUNT];
|
||||
|
||||
static adc_channel_mode_e adcHwChannelEnabled[HW_MAX_ADC_INDEX];
|
||||
|
@ -217,11 +222,6 @@ int getInternalAdcValue(const char *msg, adc_channel_e hwChannel) {
|
|||
}
|
||||
#endif // EFI_USE_FAST_ADC
|
||||
|
||||
if (adcHwChannelEnabled[hwChannel] != ADC_SLOW) {
|
||||
// todo: make this not happen during hardware continuous integration
|
||||
warning(CUSTOM_OBD_WRONG_ADC_MODE, "ADC is off [%s] index=%d", msg, hwChannel);
|
||||
}
|
||||
|
||||
return slowAdcSamples[hwChannel - 1];
|
||||
}
|
||||
|
||||
|
@ -517,10 +517,6 @@ static SlowAdcController slowAdcController;
|
|||
|
||||
void initAdcInputs() {
|
||||
scheduleMsg(&logger, "initAdcInputs()");
|
||||
if (ADC_BUF_DEPTH_FAST > MAX_ADC_GRP_BUF_DEPTH)
|
||||
firmwareError(CUSTOM_ERR_ADC_DEPTH_FAST, "ADC_BUF_DEPTH_FAST too high");
|
||||
if (ADC_BUF_DEPTH_SLOW > MAX_ADC_GRP_BUF_DEPTH)
|
||||
firmwareError(CUSTOM_ERR_ADC_DEPTH_SLOW, "ADC_BUF_DEPTH_SLOW too high");
|
||||
|
||||
configureInputs();
|
||||
|
||||
|
|
|
@ -56,19 +56,6 @@ float getMCUInternalTemperature(void);
|
|||
void addChannel(const char *name, adc_channel_e setting, adc_channel_mode_e mode);
|
||||
void removeChannel(const char *name, adc_channel_e setting);
|
||||
|
||||
/* Depth of the conversion buffer, channels are sampled X times each.*/
|
||||
#ifndef ADC_BUF_DEPTH_SLOW
|
||||
#define ADC_BUF_DEPTH_SLOW 8
|
||||
#endif /* ADC_BUF_DEPTH_SLOW */
|
||||
|
||||
#ifndef ADC_BUF_DEPTH_FAST
|
||||
#define ADC_BUF_DEPTH_FAST 4
|
||||
#endif /* ADC_BUF_DEPTH_FAST */
|
||||
|
||||
// todo: preprocessor way of doing 'max'?
|
||||
// max(ADC_BUF_DEPTH_SLOW, ADC_BUF_DEPTH_FAST)
|
||||
#define MAX_ADC_GRP_BUF_DEPTH 8
|
||||
|
||||
#define getAdcValue(msg, hwChannel) getInternalAdcValue(msg, hwChannel)
|
||||
|
||||
#define adcToVoltsDivided(adc) (adcToVolts(adc) * engineConfiguration->analogInputDividerCoefficient)
|
||||
|
|
|
@ -10,8 +10,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "engine_configuration.h"
|
||||
#if EFI_PROD_CODE
|
||||
#include "port_mpu_util.h"
|
||||
#include "rusefi_hw_enums.h"
|
||||
#else // not EFI_PROD_CODE
|
||||
#define ADC_MAX_VALUE 4095
|
||||
#endif
|
||||
|
||||
#define adcToVolts(adc) ((engineConfiguration->adcVcc) / ADC_MAX_VALUE * (adc))
|
||||
|
||||
|
|
|
@ -46,3 +46,5 @@ typedef enum {
|
|||
// TODO
|
||||
#define SPI_CR1_24BIT_MODE 0
|
||||
#define SPI_CR2_24BIT_MODE 0
|
||||
|
||||
#define ADC_MAX_VALUE 4095
|
||||
|
|
|
@ -34,3 +34,5 @@ typedef enum {
|
|||
// TODO
|
||||
#define SPI_CR1_24BIT_MODE 0
|
||||
#define SPI_CR2_24BIT_MODE 0
|
||||
|
||||
#define ADC_MAX_VALUE 4095
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
EXTERN_CONFIG;
|
||||
|
||||
/* Depth of the conversion buffer, channels are sampled X times each.*/
|
||||
#ifndef ADC_BUF_DEPTH_SLOW
|
||||
#define ADC_BUF_DEPTH_SLOW 8
|
||||
#endif /* ADC_BUF_DEPTH_SLOW */
|
||||
#define SLOW_ADC_OVERSAMPLE 8
|
||||
|
||||
void portInitAdc() {
|
||||
// Init slow ADC
|
||||
|
@ -150,13 +148,13 @@ static constexpr ADCConversionGroup convGroupSlow = {
|
|||
.sqr3 = ADC_SQR3_SQ1_N(0) | ADC_SQR3_SQ2_N(1) | ADC_SQR3_SQ3_N(2) | ADC_SQR3_SQ4_N(3) | ADC_SQR3_SQ5_N(4) | ADC_SQR3_SQ6_N(5), // Conversion group sequence 1...6
|
||||
};
|
||||
|
||||
static NO_CACHE adcsample_t slowSampleBuffer[ADC_BUF_DEPTH_SLOW * slowChannelCount];
|
||||
static NO_CACHE adcsample_t slowSampleBuffer[SLOW_ADC_OVERSAMPLE * slowChannelCount];
|
||||
|
||||
bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
||||
msg_t result = adcConvert(&ADCD1, &convGroupSlow, slowSampleBuffer, ADC_BUF_DEPTH_SLOW);
|
||||
msg_t result = adcConvert(&ADCD1, &convGroupSlow, slowSampleBuffer, SLOW_ADC_OVERSAMPLE);
|
||||
|
||||
// If something went wrong - try again later
|
||||
if (result == MSG_RESET || result == MSG_TIMEOUT) {
|
||||
if (result != MSG_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -164,12 +162,12 @@ bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
|||
for (int i = 0; i < slowChannelCount; i++) {
|
||||
uint32_t sum = 0;
|
||||
size_t index = i;
|
||||
for (size_t j = 0; j < ADC_BUF_DEPTH_SLOW; j++) {
|
||||
for (size_t j = 0; j < SLOW_ADC_OVERSAMPLE; j++) {
|
||||
sum += slowSampleBuffer[index];
|
||||
index += slowChannelCount;
|
||||
}
|
||||
|
||||
adcsample_t value = static_cast<adcsample_t>(sum / ADC_BUF_DEPTH_SLOW);
|
||||
adcsample_t value = static_cast<adcsample_t>(sum / SLOW_ADC_OVERSAMPLE);
|
||||
convertedSamples[i] = value;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,11 @@ float getMcuTemperature() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO: use a define instead of magic number
|
||||
#define ADC_SAMPLING_SLOW (7)
|
||||
// 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
|
||||
|
||||
// Sample the 16 channels that line up with the STM32F4/F7
|
||||
constexpr size_t slowChannelCount = 16;
|
||||
|
@ -38,7 +41,9 @@ static constexpr ADCConversionGroup convGroupSlow = {
|
|||
.end_cb = nullptr,
|
||||
.error_cb = nullptr,
|
||||
.cfgr = 0,
|
||||
.cfgr2 = 0, // no oversampling (yet)
|
||||
.cfgr2 = 16 << ADC_CFGR2_OVSR_Pos | // Oversample by 16x
|
||||
4 << ADC_CFGR2_OVSS_Pos | // shift the result right 4 bits to make a 16 bit result
|
||||
ADC_CFGR2_ROVSE, // Enable oversampling
|
||||
.ccr = 0,
|
||||
.pcsel = 0xFFFFFFFF, // enable analog switches on all channels
|
||||
// Thresholds aren't used
|
||||
|
@ -88,21 +93,10 @@ static constexpr ADCConversionGroup convGroupSlow = {
|
|||
},
|
||||
};
|
||||
|
||||
static NO_CACHE adcsample_t slowSampleBuffer[slowChannelCount];
|
||||
|
||||
bool readSlowAnalogInputs(adcsample_t* convertedSamples) {
|
||||
msg_t result = adcConvert(&ADCD1, &convGroupSlow, slowSampleBuffer, 1);
|
||||
// Oversampling and right-shift happen in hardware, so we can sample directly to the output buffer
|
||||
msg_t result = adcConvert(&ADCD1, &convGroupSlow, convertedSamples, 1);
|
||||
|
||||
// If something went wrong - try again later
|
||||
if (result != MSG_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// V4 ADC can oversample in hardware, so no need to oversample in software
|
||||
for (int i = 0; i < slowChannelCount; i++) {
|
||||
// Convert from 16b result to 12b result
|
||||
convertedSamples[i] = slowSampleBuffer[i] >> 4;
|
||||
}
|
||||
|
||||
return true;
|
||||
// Return true if OK
|
||||
return result == MSG_OK;
|
||||
}
|
||||
|
|
|
@ -21,3 +21,4 @@
|
|||
#define SPI_CR1_24BIT_MODE 0
|
||||
#define SPI_CR2_24BIT_MODE 0
|
||||
|
||||
#define ADC_MAX_VALUE 4095
|
||||
|
|
|
@ -20,3 +20,5 @@
|
|||
/* 3 x 8-bit transfer */
|
||||
#define SPI_CR1_24BIT_MODE 0
|
||||
#define SPI_CR2_24BIT_MODE SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0
|
||||
|
||||
#define ADC_MAX_VALUE 4095
|
||||
|
|
|
@ -12,3 +12,5 @@
|
|||
#define MCU_SERIAL_NUMBER_LOCATION (uint8_t*)(0x1FF1E800)
|
||||
|
||||
// todo SPI! #2284
|
||||
|
||||
#define ADC_MAX_VALUE 65535
|
||||
|
|
Loading…
Reference in New Issue