Currently, I can really only ADC1 work reliably. Once I switch to dual mode (for ADC2) I'm getting garbage data in my buffer. Switching to dual mode also messes with ADC3 readings.
I'm trying to read a total of 13 channels:
ADC1: 4 channels
ADC2: 2 channels
ADC3: 7 channels
Code: Select all
#if CACHE_LINE_SIZE > 0
CC_ALIGN_DATA(CACHE_LINE_SIZE)
#endif
CC_SECTION(".nocache") adcsample_t adcBuffer[ADC12_GRP_NUM_CHANNELS * ADC_OVERSAMPLE];
// ADC3 uses BDMA, which only has RAM4 access
CC_SECTION(".ram4_clear") adcsample_t adc3Buffer[CACHE_SIZE_ALIGN(adcsample_t, ADC3_GRP_NUM_CHANNELS * ADC_OVERSAMPLE)];
const ADCConfig adccfg = {.difsel = 0U, .calibration = 0U};
static constexpr ADCConversionGroup adc12grpcfg = {
.circular = false,
.num_channels = ADC12_GRP_NUM_CHANNELS,
.end_cb = nullptr,
.error_cb = nullptr,
.cfgr = ADC_CFGR_CONT,
.cfgr2 = 0U,
.ccr = ADC_CCR_DUAL_REG_INTERL,
.pcsel = ADC_SELMASK_IN2 | ADC_SELMASK_IN3 | ADC_SELMASK_IN5 | ADC_SELMASK_IN6 | ADC_SELMASK_IN9 | ADC_SELMASK_IN15,
.ltr1 = 0U,
.htr1 = 0U,
.ltr2 = 0U,
.htr2 = 0U,
.ltr3 = 0U,
.htr3 = 0U,
.awd2cr = 0U,
.awd3cr = 0U,
.smpr = { ADC_SMPR1_SMP_AN3(ADC_SMPR_SMP_32P5) | ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_32P5) |
ADC_SMPR1_SMP_AN9(ADC_SMPR_SMP_32P5),
ADC_SMPR2_SMP_AN15(ADC_SMPR_SMP_32P5)},
.sqr = { ADC_SQR1_SQ1_N(ADC_CHANNEL_IN3) | ADC_SQR1_SQ2_N(ADC_CHANNEL_IN5) |
ADC_SQR1_SQ3_N(ADC_CHANNEL_IN9) | ADC_SQR1_SQ4_N(ADC_CHANNEL_IN15),
0U,
0U,
0U},
.ssmpr = { ADC_SMPR1_SMP_AN2(ADC_SMPR_SMP_32P5) | ADC_SMPR1_SMP_AN6(ADC_SMPR_SMP_32P5),
0U},
.ssqr = { ADC_SQR1_SQ1_N(ADC_CHANNEL_IN2) | ADC_SQR1_SQ2_N(ADC_CHANNEL_IN6),
0U,
0U,
0U}
};
static const ADCConversionGroup adc3grpcfg = {
.circular = false,
.num_channels = ADC3_GRP_NUM_CHANNELS,
.end_cb = nullptr,
.error_cb = nullptr,
.cfgr = ADC_CFGR_CONT,
.cfgr2 = 0U,
.ccr = ADC_CCR_DUAL_INDEPENDENT,
.pcsel = ADC_SELMASK_IN0 | ADC_SELMASK_IN3 | ADC_SELMASK_IN4 | ADC_SELMASK_IN5 | ADC_SELMASK_IN6 | ADC_SELMASK_IN8 |
ADC_SELMASK_IN9,
.ltr1 = 0U,
.htr1 = 0U,
.ltr2 = 0U,
.htr2 = 0U,
.ltr3 = 0U,
.htr3 = 0U,
.awd2cr = 0U,
.awd3cr = 0U,
.smpr = { ADC_SMPR1_SMP_AN0(ADC_SMPR_SMP_810P5) | ADC_SMPR1_SMP_AN3(ADC_SMPR_SMP_810P5) |
ADC_SMPR1_SMP_AN4(ADC_SMPR_SMP_810P5) | ADC_SMPR1_SMP_AN5(ADC_SMPR_SMP_810P5) |
ADC_SMPR1_SMP_AN6(ADC_SMPR_SMP_810P5) | ADC_SMPR1_SMP_AN8(ADC_SMPR_SMP_810P5) |
ADC_SMPR1_SMP_AN9(ADC_SMPR_SMP_810P5),
0U},
.sqr = { ADC_SQR1_SQ1_N(ADC_CHANNEL_IN0) | ADC_SQR1_SQ2_N(ADC_CHANNEL_IN3) | ADC_SQR1_SQ3_N(ADC_CHANNEL_IN4) |
ADC_SQR1_SQ4_N(ADC_CHANNEL_IN5),
ADC_SQR2_SQ5_N(ADC_CHANNEL_IN6) | ADC_SQR2_SQ6_N(ADC_CHANNEL_IN8) | ADC_SQR2_SQ7_N(ADC_CHANNEL_IN9),
0U,
0U},
.ssmpr = {0U, 0U},
.ssqr = {0U, 0U, 0U, 0U}
};
mcuconf.h:
Code: Select all
/*
* ADC driver system settings.
*/
#define STM32_ADC_DUAL_MODE TRUE
#define STM32_ADC_SAMPLES_SIZE 32
#define STM32_ADC_USE_ADC12 TRUE
#define STM32_ADC_ADC12_DMA_STREAM STM32_DMA_STREAM_ID_ANY
#define STM32_ADC_ADC12_DMA_PRIORITY 2
#define STM32_ADC_ADC12_IRQ_PRIORITY 5
#define STM32_ADC_ADC12_CLOCK_MODE ADC_CCR_CKMODE_ADCCK
#define STM32_ADC_USE_ADC3 TRUE
#define STM32_ADC_ADC3_BDMA_STREAM STM32_BDMA_STREAM_ID_ANY
#define STM32_ADC_ADC3_BDMA_PRIORITY 2
#define STM32_ADC_ADC3_IRQ_PRIORITY 5
#define STM32_ADC_ADC3_CLOCK_MODE ADC_CCR_CKMODE_ADCCK
Doing this in a loop at around 500hz:
Code: Select all
adcConvert(&ADCD1, &adc12grpcfg, adcBuffer, ADC_OVERSAMPLE);
adcConvert(&ADCD3, &adc3grpcfg, adc3Buffer, ADC_OVERSAMPLE);
cacheBufferInvalidate(adc3Buffer, sizeof (adc3Buffer) / sizeof (adcsample_t));