From 555749ef5dde558f745f0dc6d00a168d3b3e9d58 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sun, 1 Aug 2021 18:53:09 -0400 Subject: 8x oversample; other fixes --- source/periph/adc.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'source/periph/adc.cpp') diff --git a/source/periph/adc.cpp b/source/periph/adc.cpp index 00438f2..4667307 100644 --- a/source/periph/adc.cpp +++ b/source/periph/adc.cpp @@ -39,7 +39,7 @@ ADCConversionGroup ADC::m_group_config = { .end_cb = ADC::conversionCallback, .error_cb = nullptr, .cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13), /* TIM6_TRGO */ - .cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x + .cfgr2 = 0,//ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x #if defined(TARGET_PLATFORM_H7) .ccr = 0, .pcsel = 0, @@ -73,7 +73,7 @@ ADCConversionGroup ADC::m_group_config2 = { .end_cb = readAltCallback, .error_cb = nullptr, .cfgr = ADC_CFGR_EXTEN_RISING | ADC_CFGR_EXTSEL_SRC(13), /* TIM6_TRGO */ - .cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x + .cfgr2 = 0,//ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_1 | ADC_CFGR2_OVSS_0, // Oversampling 2x #if defined(TARGET_PLATFORM_H7) .ccr = 0, .pcsel = 0, @@ -182,13 +182,29 @@ void ADC::setRate(SClock::Rate rate) adcStart(m_driver, &m_config); #elif defined(TARGET_PLATFORM_L4) std::array, 6> m_rate_presets = {{ + // PLLSAI2 sources MSI of 4MHz, divided by PLLM of /1 = 4MHz. + // 4MHz is then multiplied by PLLSAI2N (x8 to x86), with result + // between 64 and 344 MHz. + // + // SAI2N MUST BE AT LEAST 16 TO MAKE 64MHz MINIMUM. + // + // That is then divided by PLLSAI2R: + // R of 0 = /2; 1 = /4, 2 = /6, 3 = /8. + // PLLSAI2 then feeds into the ADC, which has a prescaler of /10. + // Finally, the ADC's SMP value produces the desired sample rate. + // + // 4MHz * N / R / 10 / SMP = sample rate. + // + // With oversampling, must create faster clock + // (x2 oversampling requires x2 sample rate clock). + // // Rate PLLSAI2N R SMPR - {/* 8k */ 8, 1, ADC_SMPR_SMP_12P5}, - {/* 16k */ 16, 1, ADC_SMPR_SMP_12P5}, - {/* 20k */ 20, 1, ADC_SMPR_SMP_12P5}, - {/* 32k */ 32, 1, ADC_SMPR_SMP_12P5}, - {/* 48k */ 24, 0, ADC_SMPR_SMP_12P5}, - {/* 96k */ 73, 1, ADC_SMPR_SMP_6P5} // Technically 96.05263kS/s + {/* 8k */ 16, 1, ADC_SMPR_SMP_12P5}, // R3=32k (min), R1=64k + {/* 16k */ 16, 0, ADC_SMPR_SMP_12P5}, + {/* 20k */ 20, 0, ADC_SMPR_SMP_12P5}, + {/* 32k */ 32, 0, ADC_SMPR_SMP_12P5}, + {/* 48k */ 48, 0, ADC_SMPR_SMP_12P5}, + {/* 96k */ 73, 0, ADC_SMPR_SMP_6P5} // Technically 96.05263kS/s }}; auto& preset = m_rate_presets[static_cast(rate)]; @@ -205,9 +221,9 @@ void ADC::setRate(SClock::Rate rate) m_group_config.smpr[0] = ADC_SMPR1_SMP_AN5(smpr); - // Set 2x oversampling - m_group_config.cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1; - m_group_config2.cfgr2 = ADC_CFGR2_ROVSE | ADC_CFGR2_OVSR_0 | ADC_CFGR2_OVSS_1; + // 8x oversample + m_group_config.cfgr2 = ADC_CFGR2_ROVSE | (2 << ADC_CFGR2_OVSR_Pos) | (3 << ADC_CFGR2_OVSS_Pos); + m_group_config2.cfgr2 = ADC_CFGR2_ROVSE | (2 << ADC_CFGR2_OVSR_Pos) | (3 << ADC_CFGR2_OVSS_Pos); #endif } -- cgit v1.2.3