summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2021-07-01 12:04:48 +1000
committerDamien George <damien@micropython.org>2021-07-05 16:03:11 +1000
commit86ef96535295de130185dcf41f0c514cf5192ae4 (patch)
tree9f6540b9a4232b5bc6b7922fd69673f2cda1db34
parent0e11966ce9ea2345458d2e6127ee28486c4cb65d (diff)
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>
-rw-r--r--ports/stm32/adc.c38
-rwxr-xr-xports/stm32/boards/make-pins.py57
2 files changed, 40 insertions, 55 deletions
diff --git a/ports/stm32/adc.c b/ports/stm32/adc.c
index 55dc3083b..09cd3306b 100644
--- a/ports/stm32/adc.c
+++ b/ports/stm32/adc.c
@@ -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);
diff --git a/ports/stm32/boards/make-pins.py b/ports/stm32/boards/make-pins.py
index a19532331..70213de6a 100755
--- a/ports/stm32/boards/make-pins.py
+++ b/ports/stm32/boards/make-pins.py
@@ -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)