summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/adc.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c
index 7680ecbef..d153f547d 100644
--- a/ports/stm32/adc.c
+++ b/ports/stm32/adc.c
@@ -51,9 +51,14 @@
/// val = adc.read_core_vref() # read MCU VREF
/* ADC definitions */
+#if defined(STM32H5)
+// STM32H5 features two ADC instances, ADCx and pin_adc_table are set dynamically
+#define PIN_ADC_MASK (PIN_ADC1 | PIN_ADC2)
+#else
#define ADCx (ADC1)
#define PIN_ADC_MASK PIN_ADC1
#define pin_adc_table pin_adc1
+#endif
#if defined(STM32H7A3xx) || defined(STM32H7A3xxQ) || \
defined(STM32H7B3xx) || defined(STM32H7B3xxQ)
@@ -379,8 +384,8 @@ STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
#endif
}
-STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
- adc_obj->handle.Instance = ADCx;
+STATIC void adc_init_single(pyb_obj_adc_t *adc_obj, ADC_TypeDef *adc) {
+ adc_obj->handle.Instance = adc;
adcx_init_periph(&adc_obj->handle, ADC_RESOLUTION_12B);
#if (defined(STM32G4) || defined(STM32L4)) && defined(ADC_DUALMODE_REGSIMULT_INJECSIMULT)
@@ -495,7 +500,15 @@ STATIC uint32_t adc_config_and_read_channel(ADC_HandleTypeDef *adcHandle, uint32
STATIC void adc_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_obj_adc_t *self = MP_OBJ_TO_PTR(self_in);
+ #if defined STM32H5
+ unsigned adc_id = 1;
+ if (self->handle.Instance == ADC2) {
+ adc_id = 2;
+ }
+ mp_printf(print, "<ADC%u on ", adc_id);
+ #else
mp_print_str(print, "<ADC on ");
+ #endif
mp_obj_print_helper(print, self->pin_name, PRINT_STR);
mp_printf(print, " channel=%u>", self->channel);
}
@@ -510,6 +523,13 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
// 1st argument is the pin name
mp_obj_t pin_obj = args[0];
+ #if defined(STM32H5)
+ // STM32H5 has two ADC instances where some pins are only available on ADC1 or ADC2 (but not both).
+ // Assume we're using a channel of ADC1. Can be overridden for ADC2 later in this function.
+ ADC_TypeDef *adc = ADC1;
+ const pin_obj_t *const *pin_adc_table = pin_adc1;
+ uint32_t num_adc_pins = MP_ARRAY_SIZE(pin_adc1);
+ #endif
uint32_t channel;
if (mp_obj_is_int(pin_obj)) {
@@ -520,6 +540,13 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
// No ADC function on the given pin.
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin(%q) doesn't have ADC capabilities"), pin->name);
}
+ #if defined(STM32H5)
+ if ((pin->adc_num & PIN_ADC2) == PIN_ADC2) {
+ adc = ADC2;
+ pin_adc_table = pin_adc2;
+ num_adc_pins = MP_ARRAY_SIZE(pin_adc2);
+ }
+ #endif
channel = pin->adc_channel;
}
@@ -528,20 +555,32 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
}
// If this channel corresponds to a pin then configure the pin in ADC mode.
+ #if defined(STM32H5)
+ if (channel < num_adc_pins) {
+ const pin_obj_t *pin = pin_adc_table[channel];
+ if (pin != NULL) {
+ mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);
+ }
+ }
+ #else
if (channel < MP_ARRAY_SIZE(pin_adc_table)) {
const pin_obj_t *pin = pin_adc_table[channel];
if (pin != NULL) {
mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);
}
}
+ #endif
pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t);
memset(o, 0, sizeof(*o));
o->base.type = &pyb_adc_type;
o->pin_name = pin_obj;
o->channel = channel;
- adc_init_single(o);
-
+ #if defined(STM32H5)
+ adc_init_single(o, adc);
+ #else
+ adc_init_single(o, ADCx);
+ #endif
return MP_OBJ_FROM_PTR(o);
}