Skip to content

Commit

Permalink
samd/machine_pin: Change the pin handling and naming/numbering.
Browse files Browse the repository at this point in the history
Pin numbers are now the MCU port numbers in the range:

    PA0..PA31:  0..31
    PB0..PB31: 32..63
    PC0..PC31: 64..95
    PD0..PD31: 96..127

Pins can be denoted by the GPIO port number, the name as defined in
pins.csv or a string in the form Pxnn, like "PA16" or "PD03".

The pins.c and pins.h files are now obsolete.  The pin objects are part of
the AF table.

As result of a simplification, the code now supports using pin names or
numbers instead of pin objects for modules like UART, SPI, PWM, I2C, ADC,
pininfo.
  • Loading branch information
robert-hh authored and dpgeorge committed Oct 25, 2022
1 parent e7aa970 commit e5cf3fa
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 288 deletions.
26 changes: 6 additions & 20 deletions ports/samd/Makefile
Expand Up @@ -47,14 +47,10 @@ INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include
INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include/pio
INC += -I$(TOP)/lib/tinyusb/src

MAKE_PIN_AF = boards/make-pin-af.py
MAKE_PIN_AF = boards/make-pin-table.py
PIN_AF_TABLE_CSV = mcu/$(MCU_SERIES_LOWER)/pin-af-table.csv
GEN_PIN_AF = pin_af_table.c

MAKE_PINS = boards/make-pins.py
BOARD_PINS = $(BOARD_DIR)/pins.csv
GEN_PINS_SRC = $(BUILD)/pins.c
GEN_PINS_HDR = $(BUILD)/pins.h
GEN_PIN_AF = pin_af_table.c

CFLAGS_MCU_SAMD21 = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float
CFLAGS_MCU_SAMD51 = -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
Expand Down Expand Up @@ -150,7 +146,7 @@ DRIVERS_SRC_C += \
drivers/bus/softspi.c \

# List of sources for qstr extraction
SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(SRC_CXX) $(GEN_PINS_SRC)
SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(SRC_CXX)

OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
Expand All @@ -161,7 +157,6 @@ OBJ += $(addprefix $(BUILD)/, $(ASF4_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(LIBM_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(TINYUSB_SRC_C:.c=.o))
OBJ += $(GEN_PINS_SRC:.c=.o)

ifneq ($(FROZEN_MANIFEST),)
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
Expand All @@ -182,19 +177,10 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf
$(BUILD)/firmware.uf2: $(BUILD)/firmware.bin
$(Q)$(PYTHON) $(UF2CONV) -b $(TEXT0) -c -o $@ $<

pin_af.c: $(BUILD)/$(GEN_PIN_AF)
pin_af.c: $(BUILD)/$(GEN_PIN_AF) | $(HEADER_BUILD)

$(BUILD)/$(GEN_PIN_AF): $(PIN_AF_TABLE_CSV) | $(HEADER_BUILD)
$(BUILD)/$(GEN_PIN_AF): $(PIN_AF_TABLE_CSV) $(BOARD_PINS) | $(HEADER_BUILD)
$(ECHO) "Create $@"
$(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --table $(BUILD)/$(GEN_PIN_AF) --mcu $(MCU_SERIES)

machine_led.c machine_pin.c modsamd.c: $(GEN_PINS_HDR)

$(GEN_PINS_SRC) $(GEN_PINS_HDR): $(BOARD_PINS) | $(HEADER_BUILD)
$(ECHO) "Create $@"
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --pins $(GEN_PINS_SRC) --inc $(GEN_PINS_HDR)

$(GEN_PINS_SRC:.c=.o): $(GEN_PINS_SRC)
$(call compile_c)
$(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --board $(BOARD_PINS) --table $(BUILD)/$(GEN_PIN_AF) --mcu $(MCU_SERIES)

include $(TOP)/py/mkrules.mk
Expand Up @@ -16,6 +16,7 @@
class Pins:
def __init__(self):
self.board_pins = [] # list of pin objects
self.pin_names = {}

def parse_csv_file(self, filename):
with open(filename, "r") as csvfile:
Expand All @@ -25,17 +26,43 @@ def parse_csv_file(self, filename):
if len(row) > 0 and row[0].strip().upper()[:2] in ("PA", "PB", "PC", "PD"):
self.board_pins.append(row)

def parse_pin_file(self, filename):
with open(filename, "r") as csvfile:
rows = csv.reader(csvfile, skipinitialspace=True)
for row in rows:
# Pin numbers must start with "PIN_"
# LED numbers must start with "LED_"
if len(row) > 0:
# for compatibility, map LED_ to PIN_
if row[0].startswith("LED_"):
row[0] = "PIN_" + row[0][4:]
if len(row) == 1:
self.pin_names[row[0]] = (row[0][4:], "{&machine_led_type}")
else:
self.pin_names[row[0]] = (row[1], "{&machine_led_type}")
elif row[0].startswith("PIN_"):
if len(row) == 1:
self.pin_names[row[0]] = (row[0][4:], "{&machine_pin_type}")
else:
self.pin_names[row[0]] = (row[1], "{&machine_pin_type}")

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 pin_af_t pin_af_table[] = {\n")
table_file.write("const machine_pin_obj_t pin_af_table[] = {\n")
if mcu_name == "SAMD21":
for row in self.board_pins:
pin = "PIN_" + row[0].upper()
table_file.write(" #ifdef " + pin + "\n")
eic = row[1] if row[1] else "0xff"
adc = row[2] if row[2] else "0xff"
table_file.write(" {%s, %s, %s" % (pin, eic, adc))
if pin in self.pin_names:
name = '"%s"' % self.pin_names[pin][0]
type = self.pin_names[pin][1]
else:
name = '"-"'
type = "{&machine_pin_type}"
table_file.write(" {%s, %s, %s, %s, %s" % (type, pin, name, eic, adc))
for cell in row[3:]:
if cell:
table_file.write(
Expand All @@ -52,7 +79,15 @@ def print_table(self, table_filename, mcu_name):
eic = row[1] if row[1] else "0xff"
adc0 = row[2] if row[2] else "0xff"
adc1 = row[3] if row[3] else "0xff"
table_file.write(" {%s, %s, %s, %s" % (pin, eic, adc0, adc1))
if pin in self.pin_names:
name = '"%s"' % self.pin_names[pin][0]
type = self.pin_names[pin][1]
else:
name = '"-"'
type = "{&machine_pin_type}"
table_file.write(
" {%s, %s, %s, %s, %s, %s" % (type, pin, name, eic, adc0, adc1)
)
for cell in row[4:]:
if cell:
table_file.write(
Expand All @@ -67,15 +102,21 @@ def print_table(self, table_filename, mcu_name):

def main():
parser = argparse.ArgumentParser(
prog="make-pin-cap.py",
prog="make-pin-af.py",
usage="%(prog)s [options] [command]",
description="Generate MCU-specific pin cap table file",
)
parser.add_argument(
"-c",
"--csv",
dest="csv_filename",
help="Specifies the pin-mux-xxxx.csv filename",
help="Specifies the pin-af-table.csv filename",
)
parser.add_argument(
"-b",
"--board",
dest="pin_filename",
help="Specifies the pins.csv filename",
)
parser.add_argument(
"-t",
Expand All @@ -96,6 +137,9 @@ def main():
if args.csv_filename:
pins.parse_csv_file(args.csv_filename)

if args.pin_filename:
pins.parse_pin_file(args.pin_filename)

if args.table_filename:
pins.print_table(args.table_filename, args.mcu_name)

Expand Down
128 changes: 0 additions & 128 deletions ports/samd/boards/make-pins.py

This file was deleted.

4 changes: 2 additions & 2 deletions ports/samd/machine_adc.c
Expand Up @@ -66,8 +66,8 @@ STATIC void adc_obj_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t k
(void)kind;
machine_adc_obj_t *self = MP_OBJ_TO_PTR(o);

mp_printf(print, "ADC(P%c%02u, ADC%u, channel=%u, bits=%u, average=%u)",
"ABCD"[self->id / 32], self->id % 32, self->adc_config.device,
mp_printf(print, "ADC(%s, ADC%u, channel=%u, bits=%u, average=%u)",
pin_name(self->id), self->adc_config.device,
self->adc_config.channel, self->bits, 1 << self->avg);
}

Expand Down
27 changes: 11 additions & 16 deletions ports/samd/machine_led.c
Expand Up @@ -30,40 +30,35 @@
#include "py/mphal.h"
#include "extmod/virtpin.h"
#include "modmachine.h"
#include "pins.h"
#include "pin_af.h"

extern mp_obj_t machine_pin_low_obj;
extern mp_obj_t machine_pin_high_obj;
extern mp_obj_t machine_pin_toggle_obj;
extern mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args);

STATIC void machine_led_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_led_obj_t *self = self_in;
mp_printf(print, "LED(\"%s\")", self->name);
machine_pin_obj_t *self = self_in;
mp_printf(print, "LED(\"%s\", GPIO=P%c%02u)",
pin_name(self->pin_id),
"ABCD"[self->pin_id / 32], self->pin_id % 32);
}

// constructor(id, ...)
mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);

// get the wanted LED object
int wanted_led = pin_find(args[0], (const machine_pin_obj_t *)machine_led_obj, MP_ARRAY_SIZE(machine_led_obj));
const machine_led_obj_t *self = NULL;
if (0 <= wanted_led && wanted_led < MP_ARRAY_SIZE(machine_led_obj)) {
self = (machine_led_obj_t *)&machine_led_obj[wanted_led];
}
// the array could be padded with 'nulls' (see other Ports).
// Will also error if the asked for LED (index) is greater than the array row size.
if (self == NULL || self->base.type == NULL) {
mp_raise_ValueError(MP_ERROR_TEXT("invalid LED"));
}
mp_hal_pin_output(self->id);
mp_hal_pin_low(self->id);
const machine_pin_obj_t *self;

self = pin_find(args[0], &machine_led_type);

mp_hal_pin_output(self->pin_id);
mp_hal_pin_low(self->pin_id);

return MP_OBJ_FROM_PTR(self);
}


STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = {
// instance methods
{ MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) },
Expand Down

0 comments on commit e5cf3fa

Please sign in to comment.