diff --git a/include/libopencm3/stm32/f3/adc.h b/include/libopencm3/stm32/f3/adc.h index 1456aacc..f81793b3 100644 --- a/include/libopencm3/stm32/f3/adc.h +++ b/include/libopencm3/stm32/f3/adc.h @@ -486,6 +486,43 @@ #define ADC_CCR_DELAY_SHIFT 8 /* DUAL[4:0]: Dual ADC mode selection */ +/****************************************************************************/ +/** @defgroup adc_multi_mode ADC Multi mode selection +@ingroup adc_defines + +@{*/ + +/** All ADCs independent */ +#define ADC_CCR_DUAL_INDEPENDENT 0x0 + +/* Dual modes: (ADC1 master + ADC2 slave or ADC3 master + ADC4 slave) */ +/** + * Dual modes combined regular simultaneous + + * injected simultaneous mode. + */ +#define ADC_CCR_DUAL_REG_SIMUL_AND_INJECTED_SIMUL 0x1 +/** + * Dual mode Combined regular simultaneous + + * alternate trigger mode. + */ +#define ADC_CCR_DUAL_REG_SIMUL_AND_ALTERNATE_TRIG 0x2 +/** + * Dual mode Combined interleaved mode + + * injected simultaneous mode. + */ +#define ADC_CCR_DUAL_REG_INTERLEAVED_AND_INJECTED_SIMUL 0x3 + +/** Dual mode Injected simultaneous mode only. */ +#define ADC_CCR_DUAL_INJECTED_SIMUL 0x5 +/** Dual mode Regular simultaneous mode only. */ +#define ADC_CCR_DUAL_REGULAR_SIMUL 0x6 +/** Dual mode Interleaved mode only. */ +#define ADC_CCR_DUAL_INTERLEAVED 0x7 +/** Dual mode Alternate trigger mode only. */ +#define ADC_CCR_DUAL_ALTERNATE_TRIG 0x9 +/**@}*/ + +#define ADC_CCR_DUAL_MASK (0x1f << 0) #define ADC_CCR_DUAL_SHIFT 0 diff --git a/lib/stm32/f3/adc.c b/lib/stm32/f3/adc.c index 7bf67e81..0fba5f5c 100644 --- a/lib/stm32/f3/adc.c +++ b/lib/stm32/f3/adc.c @@ -53,7 +53,7 @@ * adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); * uint8_t channels[] = ADC_CHANNEL0; * adc_set_regular_sequence(ADC1, 1, channels); - * adc_set_multi_mode(ADC_CCR_MULTI_INDEPENDENT); + * adc_set_multi_mode(ADC_CCR_DUAL_INDEPENDENT); * adc_power_on(ADC1); * adc_start_conversion_regular(ADC1); * while (! adc_eoc(ADC1)); @@ -597,10 +597,13 @@ void adc_set_clk_prescale(uint32_t adc, uint32_t prescale) } /*---------------------------------------------------------------------------*/ -/** @brief ADC Set Dual/Triple Mode +/** @brief ADC Set Dual Mode * - * The multiple mode uses ADC1 as master, ADC2 and optionally ADC3 in a slave - * arrangement. This setting is applied to ADC1 only. + * The multiple mode can uses these arrangement: + * - ADC1 as master and ADC2 as slave + * - ADC3 as master and ADC4 as slave + * + * This setting is applied to ADC master only (ADC1 or ADC3). * * The various modes possible are described in the reference manual. * @@ -610,7 +613,8 @@ void adc_set_clk_prescale(uint32_t adc, uint32_t prescale) */ void adc_set_multi_mode(uint32_t adc, uint32_t mode) { - ADC_CCR(adc) |= mode; + ADC_CCR(adc) &= ~ADC_CCR_DUAL_MASK; + ADC_CCR(adc) |= (mode << ADC_CCR_DUAL_SHIFT); } /*---------------------------------------------------------------------------*/