From 4598b89ce9bd171dde92480e86050f6ceb3cfc83 Mon Sep 17 00:00:00 2001 From: robert-hh Date: Fri, 3 Feb 2023 17:03:31 +0100 Subject: [PATCH] samd: Add Pin.board and Pin.cpu classes to Pin. For compatibility with other ports. Code increase up to ~1250 bytes for SAMD21. The feature is configurable via MICROPY_PY_MACHINE_PIN_BOARD_CPU in case flash memory is tight. --- ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv | 2 +- ports/samd/boards/make-pin-table.py | 81 ++++++++++++++++--- ports/samd/machine_pin.c | 23 ++++++ ports/samd/mcu/samd21/mpconfigmcu.h | 4 + ports/samd/mcu/samd51/mpconfigmcu.h | 4 + ports/samd/modsamd.c | 7 +- ports/samd/pin_af.c | 65 +++++++++------ ports/samd/pin_af.h | 9 ++- 8 files changed, 149 insertions(+), 46 deletions(-) diff --git a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv index 4a3d9e21ae..4db71cc4c1 100644 --- a/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv +++ b/ports/samd/boards/SEEED_WIO_TERMINAL/pins.csv @@ -51,7 +51,7 @@ PIN_PB19,LCD_MOSI PIN_PB20,LCD_SCK PIN_PB21,LCD_CS PIN_PC05,LCD_BACKLIGHT -PIN_PC06,LCD_D/C +PIN_PC06,LCD_D_C PIN_PC07,LCD_RESET PIN_PC10,LCD_XL PIN_PC11,LCD_YU diff --git a/ports/samd/boards/make-pin-table.py b/ports/samd/boards/make-pin-table.py index 40bcd166dd..a187f2a711 100644 --- a/ports/samd/boards/make-pin-table.py +++ b/ports/samd/boards/make-pin-table.py @@ -10,6 +10,8 @@ import csv table_header = """// This file was automatically generated by make-pin-cap.py // +// The Pin objects which are available on a board + """ @@ -45,20 +47,23 @@ class Pins: def print_table(self, table_filename, mcu_name): with open(table_filename, "wt") as table_file: table_file.write(table_header) - table_file.write("const machine_pin_obj_t pin_af_table[] = {\n") + + # Create the Pin objects + if mcu_name == "SAMD21": for row in self.board_pins: pin = "PIN_" + row[0].upper() - table_file.write(" #ifdef " + pin + "\n") + table_file.write("#ifdef " + pin + "\n") + table_file.write("static const machine_pin_obj_t %s_obj = " % pin) eic = row[1] if row[1] else "0xff" adc = row[2] if row[2] else "0xff" if pin in self.pin_names: - name = '"%s"' % self.pin_names[pin][0] + name = "MP_QSTR_%s" % self.pin_names[pin][0] type = self.pin_names[pin][1] else: - name = '"-"' + name = "MP_QSTR_" type = "{&machine_pin_type}" - table_file.write(" {%s, %s, %s, %s, %s" % (type, pin, name, eic, adc)) + table_file.write("{%s, %s, %s, %s, %s" % (type, pin, name, eic, adc)) for cell in row[3:]: if cell: table_file.write( @@ -66,23 +71,24 @@ class Pins: ) else: table_file.write(", 0xff") - table_file.write("},\n") - table_file.write(" #endif\n") + table_file.write("};\n") + table_file.write("#endif\n") else: for row in self.board_pins: pin = "PIN_" + row[0].upper() - table_file.write(" #ifdef " + pin + "\n") + table_file.write("#ifdef " + pin + "\n") + table_file.write("const machine_pin_obj_t %s_obj = " % pin) eic = row[1] if row[1] else "0xff" adc0 = row[2] if row[2] else "0xff" adc1 = row[3] if row[3] else "0xff" if pin in self.pin_names: - name = '"%s"' % self.pin_names[pin][0] + name = "MP_QSTR_%s" % self.pin_names[pin][0] type = self.pin_names[pin][1] else: - name = '"-"' + name = "MP_QSTR_" type = "{&machine_pin_type}" table_file.write( - " {%s, %s, %s, %s, %s, %s" % (type, pin, name, eic, adc0, adc1) + "{%s, %s, %s, %s, %s, %s" % (type, pin, name, eic, adc0, adc1) ) for cell in row[4:]: if cell: @@ -91,9 +97,60 @@ class Pins: ) else: table_file.write(", 0xff") - table_file.write("},\n") + table_file.write("};\n") + table_file.write("#endif\n") + + # Create the Pin table + + table_file.write("\n// The table of references to the pin objects.\n\n") + table_file.write("static const machine_pin_obj_t *pin_af_table[] = {\n") + for row in self.board_pins: + pin = "PIN_" + row[0].upper() + table_file.write(" #ifdef " + pin + "\n") + table_file.write(" &%s_obj,\n" % pin) + table_file.write(" #endif\n") + table_file.write("};\n") + + # Create the CPU pins dictionary table + + table_file.write("\n#if MICROPY_PY_MACHINE_PIN_BOARD_CPU\n") + table_file.write("\n// The cpu pins dictionary\n\n") + table_file.write( + "STATIC const mp_rom_map_elem_t pin_cpu_pins_locals_dict_table[] = {\n" + ) + for row in self.board_pins: + pin = "PIN_" + row[0].upper() + table_file.write(" #ifdef " + pin + "\n") + table_file.write( + " { MP_ROM_QSTR(MP_QSTR_%s), MP_ROM_PTR(&%s_obj) },\n" + % (row[0].upper(), pin) + ) + table_file.write(" #endif\n") + table_file.write("};\n") + table_file.write( + "MP_DEFINE_CONST_DICT(machine_pin_cpu_pins_locals_dict, pin_cpu_pins_locals_dict_table);\n" + ) + + # Create the board pins dictionary table + + table_file.write("\n// The board pins dictionary\n\n") + table_file.write( + "STATIC const mp_rom_map_elem_t pin_board_pins_locals_dict_table[] = {\n" + ) + for row in self.board_pins: + pin = "PIN_" + row[0].upper() + if pin in self.pin_names: + table_file.write(" #ifdef " + pin + "\n") + table_file.write( + " { MP_ROM_QSTR(MP_QSTR_%s), MP_ROM_PTR(&%s_obj) },\n" + % (self.pin_names[pin][0], pin) + ) table_file.write(" #endif\n") table_file.write("};\n") + table_file.write( + "MP_DEFINE_CONST_DICT(machine_pin_board_pins_locals_dict, pin_board_pins_locals_dict_table);\n" + ) + table_file.write("#endif\n") def main(): diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c index 8768485832..f8e1b96280 100644 --- a/ports/samd/machine_pin.c +++ b/ports/samd/machine_pin.c @@ -54,6 +54,23 @@ typedef struct _machine_pin_irq_obj_t { uint8_t pin_id; } machine_pin_irq_obj_t; +#if MICROPY_PY_MACHINE_PIN_BOARD_CPU +// Pin mapping dictionaries +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_cpu_pins_obj_type, + MP_QSTR_cpu, + MP_TYPE_FLAG_NONE, + locals_dict, &machine_pin_cpu_pins_locals_dict + ); + +MP_DEFINE_CONST_OBJ_TYPE( + machine_pin_board_pins_obj_type, + MP_QSTR_board, + MP_TYPE_FLAG_NONE, + locals_dict, &machine_pin_board_pins_locals_dict + ); +#endif // MICROPY_PY_MACHINE_PIN_BOARD_CPU + STATIC const mp_irq_methods_t machine_pin_irq_methods; bool EIC_occured; @@ -411,6 +428,12 @@ STATIC const mp_rom_map_elem_t machine_pin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_drive), MP_ROM_PTR(&machine_pin_drive_obj) }, { MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_pin_irq_obj) }, + #if MICROPY_PY_MACHINE_PIN_BOARD_CPU + // class attributes + { MP_ROM_QSTR(MP_QSTR_board), MP_ROM_PTR(&machine_pin_board_pins_obj_type) }, + { MP_ROM_QSTR(MP_QSTR_cpu), MP_ROM_PTR(&machine_pin_cpu_pins_obj_type) }, + #endif // MICROPY_PY_MACHINE_PIN_BOARD_CPU + // class constants { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_IN) }, { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUT) }, diff --git a/ports/samd/mcu/samd21/mpconfigmcu.h b/ports/samd/mcu/samd21/mpconfigmcu.h index 331df8e213..fd6f524d7f 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.h +++ b/ports/samd/mcu/samd21/mpconfigmcu.h @@ -34,6 +34,10 @@ #endif #endif +#ifndef MICROPY_PY_MACHINE_PIN_BOARD_CPU +#define MICROPY_PY_MACHINE_PIN_BOARD_CPU (1) +#endif + #define CPU_FREQ (48000000) #define DFLL48M_FREQ (48000000) #define MAX_CPU_FREQ (48000000) diff --git a/ports/samd/mcu/samd51/mpconfigmcu.h b/ports/samd/mcu/samd51/mpconfigmcu.h index 16b2c101f0..64261951ba 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.h +++ b/ports/samd/mcu/samd51/mpconfigmcu.h @@ -34,6 +34,10 @@ unsigned long trng_random_u32(void); #endif #endif +#ifndef MICROPY_PY_MACHINE_PIN_BOARD_CPU +#define MICROPY_PY_MACHINE_PIN_BOARD_CPU (1) +#endif + // fatfs configuration used in ffconf.h #define MICROPY_FATFS_ENABLE_LFN (1) #define MICROPY_FATFS_RPATH (2) diff --git a/ports/samd/modsamd.c b/ports/samd/modsamd.c index 5a2cf4616d..7593a7bb0d 100644 --- a/ports/samd/modsamd.c +++ b/ports/samd/modsamd.c @@ -36,12 +36,9 @@ extern const mp_obj_type_t samd_flash_type; STATIC mp_obj_t samd_pininfo(mp_obj_t pin_obj) { const machine_pin_obj_t *pin_af = pin_find(pin_obj); - // Get the name, now that it is not in the pin object - const char *name = pin_af->name; - #if defined(MCU_SAMD21) mp_obj_t tuple[7] = { - tuple[0] = mp_obj_new_str(name, strlen(name)), + tuple[0] = MP_OBJ_NEW_QSTR(pin_af->name), tuple[1] = mp_obj_new_int(pin_af->eic), tuple[2] = mp_obj_new_int(pin_af->adc0), tuple[3] = mp_obj_new_int(pin_af->sercom1), @@ -52,7 +49,7 @@ STATIC mp_obj_t samd_pininfo(mp_obj_t pin_obj) { return mp_obj_new_tuple(7, tuple); #elif defined(MCU_SAMD51) mp_obj_t tuple[9] = { - tuple[0] = mp_obj_new_str(name, strlen(name)), + tuple[0] = MP_OBJ_NEW_QSTR(pin_af->name), tuple[1] = mp_obj_new_int(pin_af->eic), tuple[2] = mp_obj_new_int(pin_af->adc0), tuple[3] = mp_obj_new_int(pin_af->adc1), diff --git a/ports/samd/pin_af.c b/ports/samd/pin_af.c index a7a72ac96a..d92a62b700 100644 --- a/ports/samd/pin_af.c +++ b/ports/samd/pin_af.c @@ -47,23 +47,48 @@ extern const uint8_t tcc_channel_count[]; const machine_pin_obj_t *get_pin_obj_ptr(int pin_id) { for (int i = 0; i < MP_ARRAY_SIZE(pin_af_table); i++) { - if (pin_af_table[i].pin_id == pin_id) { // Pin match - return &pin_af_table[i]; + if (pin_af_table[i]->pin_id == pin_id) { // Pin match + return pin_af_table[i]; } } mp_raise_ValueError(MP_ERROR_TEXT("not a Pin")); } +#if MICROPY_PY_MACHINE_PIN_BOARD_CPU +STATIC const machine_pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) { + mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins); + mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP); + if (named_elem != NULL && named_elem->value != NULL) { + return named_elem->value; + } + return NULL; +} +#endif + const machine_pin_obj_t *pin_find(mp_obj_t pin) { - const machine_pin_obj_t *self = NULL; // Is already a object of the proper type if (mp_obj_is_type(pin, &machine_pin_type)) { return pin; } if (mp_obj_is_small_int(pin)) { // Pin defined by pin number for PAnn, PBnn, etc. - self = get_pin_obj_ptr(mp_obj_get_int(pin)); - } else if (mp_obj_is_str(pin)) { + return get_pin_obj_ptr(mp_obj_get_int(pin)); + } + + #if MICROPY_PY_MACHINE_PIN_BOARD_CPU + const machine_pin_obj_t *self = NULL; + // See if the pin name matches a board pin + self = pin_find_named_pin(&machine_pin_board_pins_locals_dict, pin); + if (self != NULL) { + return self; + } + // See if the pin name matches a cpu pin + self = pin_find_named_pin(&machine_pin_cpu_pins_locals_dict, pin); + if (self != NULL) { + return self; + } + #else + if (mp_obj_is_str(pin)) { // Search by name size_t slen; const char *s = mp_obj_str_get_data(pin, &slen); @@ -71,36 +96,26 @@ const machine_pin_obj_t *pin_find(mp_obj_t pin) { if (slen == 4 && s[0] == 'P' && strchr("ABCD", s[1]) != NULL && strchr("0123456789", s[2]) != NULL && strchr("0123456789", s[2]) != NULL) { int num = (s[1] - 'A') * 32 + (s[2] - '0') * 10 + (s[3] - '0'); - self = get_pin_obj_ptr(num); + return get_pin_obj_ptr(num); } else { for (int i = 0; i < MP_ARRAY_SIZE(pin_af_table); i++) { - if (slen == strlen(pin_af_table[i].name) && - strncmp(s, pin_af_table[i].name, slen) == 0) { - self = &pin_af_table[i]; + size_t len; + const char *name = (char *)qstr_data(pin_af_table[i]->name, &len); + if (slen == len && strncmp(s, name, slen) == 0) { + return pin_af_table[i]; } } } } - if (self != NULL) { - return self; - } else { - mp_raise_ValueError(MP_ERROR_TEXT("not a Pin")); - } + #endif // MICROPY_PY_MACHINE_PIN_BOARD_CPU + + mp_raise_ValueError(MP_ERROR_TEXT("not a Pin")); } const char *pin_name(int id) { - static char board_name[5] = "Pxnn"; for (int i = 0; i < sizeof(pin_af_table); i++) { - if (pin_af_table[i].pin_id == id) { - if (pin_af_table[i].name[0] != '-') { - return pin_af_table[i].name; - } else { - board_name[1] = "ABCD"[id / 32]; - id %= 32; - board_name[2] = '0' + id / 10; - board_name[3] = '0' + id % 10; - return board_name; - } + if (pin_af_table[i]->pin_id == id) { + return qstr_str(pin_af_table[i]->name); } } return "-"; diff --git a/ports/samd/pin_af.h b/ports/samd/pin_af.h index 4b0c80250c..edab72aaed 100644 --- a/ports/samd/pin_af.h +++ b/ports/samd/pin_af.h @@ -33,7 +33,7 @@ typedef struct _machine_pin_obj_t { mp_obj_base_t base; uint8_t pin_id; - char *name; + qstr name; uint8_t eic; uint8_t adc0; uint8_t sercom1; @@ -51,7 +51,7 @@ typedef struct _machine_pin_obj_t { typedef struct _machine_pin_obj_t { mp_obj_base_t base; uint8_t pin_id; - char *name; + qstr name; uint8_t eic; uint8_t adc0; uint8_t adc1; @@ -89,7 +89,10 @@ typedef struct _pwm_config_t { #define ALT_FCT_SERCOM1 2 #define ALT_FCT_SERCOM2 3 -extern const machine_pin_obj_t pin_af_table[]; +#if MICROPY_PY_MACHINE_PIN_BOARD_CPU +extern const mp_obj_dict_t machine_pin_cpu_pins_locals_dict; +extern const mp_obj_dict_t machine_pin_board_pins_locals_dict; +#endif sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom); adc_config_t get_adc_config(int pin_id, int32_t flag);