diff options
| author | Rene Straub <rene@see5.ch> | 2023-08-05 14:21:41 +0200 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2023-09-27 16:28:15 +1000 |
| commit | 8f9bba0a1a36caf3afd86b27b1e860225f85cc6a (patch) | |
| tree | ce9772edfbb33c42fb3f8404cad4916cb93256c3 | |
| parent | 13cc280eaeb2f01aa78631019057f6ff22d33384 (diff) | |
stm32/adc: Add support for STM32H5 ADC2 inputs.
Select ADC instance based on pin information to support ADC2 inputs.
Display ADC instance number similar to machine_adc (STM32H5 only):
<ADC2 on Pin(Pin.cpu.F14, mode=Pin.ANALOG) channel=6>
Signed-off-by: Rene Straub <rene@see5.ch>
| -rw-r--r-- | ports/stm32/adc.c | 47 |
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); } |
