Skip to content

Commit ff7be31

Browse files
iabdalkaderdpgeorge
authored andcommitted
stm32/adc: Allow using ADC12 and ADC3 for H7.
* Modify common functions in adc.c to accept ADC handle. * Most external channels are connected to ADC12 which is used by default. * For ADCAll (internal channels) ADC3 is used instead. * Issue adafruit#4435 is possibly related (at least partially fixed).
1 parent d1decdf commit ff7be31

File tree

1 file changed

+40
-28
lines changed

1 file changed

+40
-28
lines changed

ports/stm32/adc.c

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,9 @@
5151
/// val = adc.read_core_vref() # read MCU VREF
5252

5353
/* ADC defintions */
54-
55-
#if defined(STM32H7)
56-
#define ADCx (ADC3)
57-
#define PIN_ADC_MASK PIN_ADC3
58-
#define pin_adc_table pin_adc3
59-
#else
6054
#define ADCx (ADC1)
6155
#define PIN_ADC_MASK PIN_ADC1
6256
#define pin_adc_table pin_adc1
63-
#endif
6457

6558
#define ADCx_CLK_ENABLE __HAL_RCC_ADC1_CLK_ENABLE
6659

@@ -142,7 +135,7 @@
142135
defined(STM32F746xx) || defined(STM32F765xx) || \
143136
defined(STM32F767xx) || defined(STM32F769xx)
144137
#define VBAT_DIV (4)
145-
#elif defined(STM32H743xx)
138+
#elif defined(STM32H743xx) || defined(STM32H747xx)
146139
#define VBAT_DIV (4)
147140
#elif defined(STM32L432xx) || \
148141
defined(STM32L451xx) || defined(STM32L452xx) || \
@@ -214,12 +207,12 @@ STATIC bool is_adcx_channel(int channel) {
214207
#endif
215208
}
216209

217-
STATIC void adc_wait_for_eoc_or_timeout(int32_t timeout) {
210+
STATIC void adc_wait_for_eoc_or_timeout(ADC_HandleTypeDef *adcHandle, int32_t timeout) {
218211
uint32_t tickstart = HAL_GetTick();
219212
#if defined(STM32F4) || defined(STM32F7)
220-
while ((ADCx->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
213+
while ((adcHandle->Instance->SR & ADC_FLAG_EOC) != ADC_FLAG_EOC) {
221214
#elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
222-
while (READ_BIT(ADCx->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {
215+
while (READ_BIT(adcHandle->Instance->ISR, ADC_FLAG_EOC) != ADC_FLAG_EOC) {
223216
#else
224217
#error Unsupported processor
225218
#endif
@@ -229,11 +222,15 @@ STATIC void adc_wait_for_eoc_or_timeout(int32_t timeout) {
229222
}
230223
}
231224

232-
STATIC void adcx_clock_enable(void) {
225+
STATIC void adcx_clock_enable(ADC_HandleTypeDef *adch) {
233226
#if defined(STM32F0) || defined(STM32F4) || defined(STM32F7)
234227
ADCx_CLK_ENABLE();
235228
#elif defined(STM32H7)
236-
__HAL_RCC_ADC3_CLK_ENABLE();
229+
if (adch->Instance == ADC3) {
230+
__HAL_RCC_ADC3_CLK_ENABLE();
231+
} else {
232+
__HAL_RCC_ADC12_CLK_ENABLE();
233+
}
237234
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP);
238235
#elif defined(STM32L4) || defined(STM32WB)
239236
if (__HAL_RCC_GET_ADC_SOURCE() == RCC_ADCCLKSOURCE_NONE) {
@@ -246,9 +243,8 @@ STATIC void adcx_clock_enable(void) {
246243
}
247244

248245
STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
249-
adcx_clock_enable();
246+
adcx_clock_enable(adch);
250247

251-
adch->Instance = ADCx;
252248
adch->Init.Resolution = resolution;
253249
adch->Init.ContinuousConvMode = DISABLE;
254250
adch->Init.DiscontinuousConvMode = DISABLE;
@@ -308,6 +304,7 @@ STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
308304
mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);
309305
}
310306

307+
adc_obj->handle.Instance = ADCx;
311308
adcx_init_periph(&adc_obj->handle, ADC_RESOLUTION_12B);
312309

313310
#if defined(STM32L4) && defined(ADC_DUALMODE_REGSIMULT_INJECSIMULT)
@@ -335,7 +332,11 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
335332
#if defined(STM32F0)
336333
sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
337334
#elif defined(STM32F4) || defined(STM32F7)
338-
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
335+
if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) {
336+
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
337+
} else {
338+
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
339+
}
339340
#elif defined(STM32H7)
340341
if (__HAL_ADC_IS_CHANNEL_INTERNAL(channel)) {
341342
sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;
@@ -370,8 +371,8 @@ STATIC void adc_config_channel(ADC_HandleTypeDef *adc_handle, uint32_t channel)
370371

371372
STATIC uint32_t adc_read_channel(ADC_HandleTypeDef *adcHandle) {
372373
HAL_ADC_Start(adcHandle);
373-
adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
374-
uint32_t value = ADCx->DR;
374+
adc_wait_for_eoc_or_timeout(adcHandle, EOC_TIMEOUT);
375+
uint32_t value = adcHandle->Instance->DR;
375376
HAL_ADC_Stop(adcHandle);
376377
return value;
377378
}
@@ -529,19 +530,19 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_
529530
} else {
530531
// for subsequent samples we can just set the "start sample" bit
531532
#if defined(STM32F4) || defined(STM32F7)
532-
ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
533+
self->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
533534
#elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
534-
SET_BIT(ADCx->CR, ADC_CR_ADSTART);
535+
SET_BIT(self->handle.Instance->CR, ADC_CR_ADSTART);
535536
#else
536537
#error Unsupported processor
537538
#endif
538539
}
539540

540541
// wait for sample to complete
541-
adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
542+
adc_wait_for_eoc_or_timeout(&self->handle, EOC_TIMEOUT);
542543

543544
// read value
544-
uint value = ADCx->DR;
545+
uint value = self->handle.Instance->DR;
545546

546547
// store value in buffer
547548
if (typesize == 1) {
@@ -608,9 +609,9 @@ STATIC mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i
608609
adc_config_channel(&adc0->handle, adc0->channel);
609610
HAL_ADC_Start(&adc0->handle);
610611
// Wait for sample to complete and discard
611-
adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
612+
adc_wait_for_eoc_or_timeout(&adc0->handle, EOC_TIMEOUT);
612613
// Read (and discard) value
613-
uint value = ADCx->DR;
614+
uint value = adc0->handle.Instance->DR;
614615

615616
// Ensure first sample is on a timer tick
616617
__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);
@@ -639,17 +640,17 @@ STATIC mp_obj_t adc_read_timed_multi(mp_obj_t adc_array_in, mp_obj_t buf_array_i
639640
// for the first sample we need to turn the ADC on
640641
// ADC is started: set the "start sample" bit
641642
#if defined(STM32F4) || defined(STM32F7)
642-
ADCx->CR2 |= (uint32_t)ADC_CR2_SWSTART;
643+
adc->handle.Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
643644
#elif defined(STM32F0) || defined(STM32H7) || defined(STM32L4) || defined(STM32WB)
644-
SET_BIT(ADCx->CR, ADC_CR_ADSTART);
645+
SET_BIT(adc->handle.Instance->CR, ADC_CR_ADSTART);
645646
#else
646647
#error Unsupported processor
647648
#endif
648649
// wait for sample to complete
649-
adc_wait_for_eoc_or_timeout(EOC_TIMEOUT);
650+
adc_wait_for_eoc_or_timeout(&adc->handle, EOC_TIMEOUT);
650651

651652
// read value
652-
value = ADCx->DR;
653+
value = adc->handle.Instance->DR;
653654

654655
// store values in buffer
655656
if (typesize == 1) {
@@ -723,13 +724,24 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m
723724
if (en_mask & (1 << channel)) {
724725
// Channels 0-16 correspond to real pins. Configure the GPIO pin in
725726
// ADC mode.
727+
#if defined(STM32H7)
728+
const pin_obj_t *pin = pin_adc3[channel];
729+
#else
726730
const pin_obj_t *pin = pin_adc_table[channel];
731+
#endif
727732
if (pin) {
728733
mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);
729734
}
730735
}
731736
}
732737

738+
#if defined(STM32H7)
739+
// On the H7 the internal channels are connected to ADC3. To read internal channels
740+
// with ADCAll, ADC3 must be used here, and ADC12 is used to read the GPIO channels.
741+
adc_all->handle.Instance = ADC3;
742+
#else
743+
adc_all->handle.Instance = ADCx;
744+
#endif
733745
adcx_init_periph(&adc_all->handle, resolution);
734746
}
735747

0 commit comments

Comments
 (0)