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>
This commit is contained in:
Rene Straub 2023-08-05 14:21:41 +02:00 committed by Damien George
parent 13cc280eae
commit 8f9bba0a1a

View File

@ -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);
}