stm32/adc: Simplify and generalise how pin_adcX table is defined.

The ADC_FIRST_GPIO_CHANNEL and ADC_LAST_GPIO_CHANNEL macros are no longer
needed.  Instead the pin_adcX table (X = 1, 2, 3) is now generated to be
the exact size needed for a given MCU, and MP_ARRAY_SIZE(pin_adcX) is used
to determine the upper bound.

This commit also allows CPU pins to be excluded from ADC configuration if
they are hidden by prefixing their name with a "-".

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George 2021-07-01 12:04:48 +10:00
parent 0e11966ce9
commit 86ef965352
2 changed files with 40 additions and 55 deletions

View File

@ -70,8 +70,6 @@
#if defined(STM32F0)
#define ADC_FIRST_GPIO_CHANNEL (0)
#define ADC_LAST_GPIO_CHANNEL (15)
#define ADC_SCALE_V (3.3f)
#define ADC_CAL_ADDRESS (0x1ffff7ba)
#define ADC_CAL1 ((uint16_t *)0x1ffff7b8)
@ -80,8 +78,6 @@
#elif defined(STM32F4)
#define ADC_FIRST_GPIO_CHANNEL (0)
#define ADC_LAST_GPIO_CHANNEL (15)
#define ADC_SCALE_V (3.3f)
#define ADC_CAL_ADDRESS (0x1fff7a2a)
#define ADC_CAL1 ((uint16_t *)(ADC_CAL_ADDRESS + 2))
@ -90,8 +86,6 @@
#elif defined(STM32F7)
#define ADC_FIRST_GPIO_CHANNEL (0)
#define ADC_LAST_GPIO_CHANNEL (15)
#define ADC_SCALE_V (3.3f)
#if defined(STM32F722xx) || defined(STM32F723xx) || \
defined(STM32F732xx) || defined(STM32F733xx)
@ -106,8 +100,6 @@
#elif defined(STM32H7)
#define ADC_FIRST_GPIO_CHANNEL (0)
#define ADC_LAST_GPIO_CHANNEL (16)
#define ADC_SCALE_V (3.3f)
#define ADC_CAL_ADDRESS (0x1FF1E860)
#define ADC_CAL1 ((uint16_t *)(0x1FF1E820))
@ -116,8 +108,6 @@
#elif defined(STM32L4) || defined(STM32WB)
#define ADC_FIRST_GPIO_CHANNEL (1)
#define ADC_LAST_GPIO_CHANNEL (16)
#define ADC_SCALE_V (VREFINT_CAL_VREF / 1000.0f)
#define ADC_CAL_ADDRESS (VREFINT_CAL_ADDR)
#define ADC_CAL1 (TEMPSENSOR_CAL1_ADDR)
@ -179,7 +169,7 @@
typedef struct _pyb_obj_adc_t {
mp_obj_base_t base;
mp_obj_t pin_name;
int channel;
uint32_t channel;
ADC_HandleTypeDef handle;
} pyb_obj_adc_t;
@ -308,13 +298,6 @@ STATIC void adcx_init_periph(ADC_HandleTypeDef *adch, uint32_t resolution) {
}
STATIC void adc_init_single(pyb_obj_adc_t *adc_obj) {
if (ADC_FIRST_GPIO_CHANNEL <= adc_obj->channel && adc_obj->channel <= ADC_LAST_GPIO_CHANNEL) {
// Channels 0-16 correspond to real pins. Configure the GPIO pin in ADC mode.
const pin_obj_t *pin = pin_adc_table[adc_obj->channel];
mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);
}
adc_obj->handle.Instance = ADCx;
adcx_init_periph(&adc_obj->handle, ADC_RESOLUTION_12B);
@ -431,8 +414,8 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
} else {
const pin_obj_t *pin = pin_find(pin_obj);
if ((pin->adc_num & PIN_ADC_MASK) == 0) {
// No ADC1 function on that pin
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("pin %q does not have ADC capabilities"), pin->name);
// 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);
}
channel = pin->adc_channel;
}
@ -441,11 +424,11 @@ STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("not a valid ADC Channel: %d"), channel);
}
if (ADC_FIRST_GPIO_CHANNEL <= channel && channel <= ADC_LAST_GPIO_CHANNEL) {
// these channels correspond to physical GPIO ports so make sure they exist
if (pin_adc_table[channel] == NULL) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("channel %d not available on this board"), channel);
// If this channel corresponds to a pin then configure the pin in ADC mode.
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);
}
}
@ -730,11 +713,10 @@ void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution, uint32_t en_m
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("resolution %d not supported"), resolution);
}
for (uint32_t channel = ADC_FIRST_GPIO_CHANNEL; channel <= ADC_LAST_GPIO_CHANNEL; ++channel) {
for (uint32_t channel = 0; channel < MP_ARRAY_SIZE(pin_adcall_table); ++channel) {
// only initialise those channels that are selected with the en_mask
if (en_mask & (1 << channel)) {
// Channels 0-16 correspond to real pins. Configure the GPIO pin in
// ADC mode.
// If this channel corresponds to a pin then configure the pin in ADC mode.
const pin_obj_t *pin = pin_adcall_table[channel];
if (pin) {
mp_hal_pin_config(pin, MP_HAL_PIN_MODE_ADC, MP_HAL_PIN_PULL_NONE, 0);

View File

@ -287,6 +287,7 @@ class Pins(object):
def __init__(self):
self.cpu_pins = [] # list of NamedPin objects
self.board_pins = [] # list of NamedPin objects
self.adc_table_size = {} # maps ADC number X to size of pin_adcX table
def find_pin(self, port_num, pin_num):
for named_pin in self.cpu_pins:
@ -353,27 +354,27 @@ class Pins(object):
self.print_named("board", self.board_pins)
def print_adc(self, adc_num):
print("")
print("const pin_obj_t * const pin_adc{:d}[] = {{".format(adc_num))
for channel in range(17):
if channel == 16:
print("#if defined(STM32L4)")
adc_found = False
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if (
pin.is_board_pin()
and (pin.adc_num & (1 << (adc_num - 1)))
and (pin.adc_channel == channel)
):
print(" &pin_{:s}_obj, // {:d}".format(pin.cpu_pin_name(), channel))
adc_found = True
break
if not adc_found:
print(" NULL, // {:d}".format(channel))
if channel == 16:
print("#endif")
print("};")
adc_pins = {}
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if (
pin.is_board_pin()
and not named_pin.is_hidden()
and (pin.adc_num & (1 << (adc_num - 1)))
):
adc_pins[pin.adc_channel] = pin
if adc_pins:
table_size = max(adc_pins) + 1
self.adc_table_size[adc_num] = table_size
print("")
print("const pin_obj_t * const pin_adc{:d}[{:d}] = {{".format(adc_num, table_size))
for channel in range(table_size):
if channel in adc_pins:
obj = "&pin_{:s}_obj".format(adc_pins[channel].cpu_pin_name())
else:
obj = "NULL"
print(" [{:d}] = {},".format(channel, obj))
print("};")
def print_header(self, hdr_filename, obj_decls):
with open(hdr_filename, "wt") as hdr_file:
@ -382,9 +383,12 @@ class Pins(object):
pin = named_pin.pin()
if pin.is_board_pin():
pin.print_header(hdr_file)
hdr_file.write("extern const pin_obj_t * const pin_adc1[];\n")
hdr_file.write("extern const pin_obj_t * const pin_adc2[];\n")
hdr_file.write("extern const pin_obj_t * const pin_adc3[];\n")
for adc_num, table_size in self.adc_table_size.items():
hdr_file.write(
"extern const pin_obj_t * const pin_adc{:d}[{:d}];\n".format(
adc_num, table_size
)
)
# provide #define's mapping board to cpu name
for named_pin in self.board_pins:
hdr_file.write(
@ -569,9 +573,8 @@ def main():
with open(args.prefix_filename, "r") as prefix_file:
print(prefix_file.read())
pins.print()
pins.print_adc(1)
pins.print_adc(2)
pins.print_adc(3)
for i in range(1, 4):
pins.print_adc(i)
pins.print_header(args.hdr_filename, args.hdr_obj_decls)
pins.print_qstr(args.qstr_filename)
pins.print_af_hdr(args.af_const_filename)