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:
parent
0e11966ce9
commit
86ef965352
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue