summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/samd/Makefile26
-rw-r--r--ports/samd/boards/make-pin-table.py (renamed from ports/samd/boards/make-pin-af.py)54
-rw-r--r--ports/samd/boards/make-pins.py128
-rw-r--r--ports/samd/machine_adc.c4
-rw-r--r--ports/samd/machine_led.c27
-rw-r--r--ports/samd/machine_pin.c119
-rw-r--r--ports/samd/machine_pwm.c4
-rw-r--r--ports/samd/modsamd.c60
-rw-r--r--ports/samd/pin_af.c69
-rw-r--r--ports/samd/pin_af.h18
10 files changed, 221 insertions, 288 deletions
diff --git a/ports/samd/Makefile b/ports/samd/Makefile
index e6e592a03..f512fb0b2 100644
--- a/ports/samd/Makefile
+++ b/ports/samd/Makefile
@@ -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
@@ -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))
@@ -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
@@ -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
diff --git a/ports/samd/boards/make-pin-af.py b/ports/samd/boards/make-pin-table.py
index d895ef9dd..327478568 100644
--- a/ports/samd/boards/make-pin-af.py
+++ b/ports/samd/boards/make-pin-table.py
@@ -16,6 +16,7 @@ table_header = """// This file was automatically generated by make-pin-cap.py
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:
@@ -25,17 +26,43 @@ class Pins:
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(
@@ -52,7 +79,15 @@ class Pins:
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(
@@ -67,7 +102,7 @@ class Pins:
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",
)
@@ -75,7 +110,13 @@ def main():
"-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",
@@ -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)
diff --git a/ports/samd/boards/make-pins.py b/ports/samd/boards/make-pins.py
deleted file mode 100644
index 679e2c9d1..000000000
--- a/ports/samd/boards/make-pins.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python
-"""Generates the pins file for the SAMD port."""
-
-from __future__ import print_function
-
-import argparse
-import sys
-import csv
-
-pins_header_prefix = """// This file was automatically generated by make-pins.py
-//
-typedef struct _machine_pin_obj_t {
- mp_obj_base_t base;
- uint32_t id;
- char *name;
-} machine_pin_obj_t;
-
-int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_size);
-
-"""
-
-led_header_prefix = """typedef struct _machine_led_obj_t {
- mp_obj_base_t base;
- uint32_t id;
- char *name;
-} machine_led_obj_t;
-
-"""
-
-
-class Pins:
- def __init__(self):
- self.board_pins = [] # list of pin objects
- self.board_leds = [] # list of led objects
-
- def parse_csv_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:
- if row[0].startswith("PIN_"):
- if len(row) == 1:
- self.board_pins.append([row[0], row[0][4:]])
- else:
- self.board_pins.append([row[0], row[1]])
- elif row[0].startswith("LED_"):
- self.board_leds.append(["PIN_" + row[0][4:], row[1]])
- elif row[0].startswith("-"):
- self.board_pins.append(["-1", ""])
-
- def print_pins(self, pins_filename):
- with open(pins_filename, "wt") as pins_file:
- pins_file.write("// This file was automatically generated by make-pins.py\n")
- pins_file.write("//\n")
- pins_file.write('#include "modmachine.h"\n')
- pins_file.write('#include "sam.h"\n')
- pins_file.write('#include "pins.h"\n\n')
-
- pins_file.write("const machine_pin_obj_t machine_pin_obj[] = {\n")
- for pin in self.board_pins:
- pins_file.write(" {{&machine_pin_type}, ")
- pins_file.write(pin[0] + ', "' + pin[1])
- pins_file.write('"},\n')
- pins_file.write("};\n")
-
- if self.board_leds:
- pins_file.write("\nconst machine_led_obj_t machine_led_obj[] = {\n")
- for pin in self.board_leds:
- pins_file.write(" {{&machine_led_type}, ")
- pins_file.write(pin[0] + ', "' + pin[1])
- pins_file.write('"},\n')
- pins_file.write("};\n")
-
- def print_header(self, hdr_filename):
- with open(hdr_filename, "wt") as hdr_file:
- hdr_file.write(pins_header_prefix)
- if self.board_leds:
- hdr_file.write(led_header_prefix)
- hdr_file.write(
- "extern const machine_pin_obj_t machine_pin_obj[%d];\n" % len(self.board_pins)
- )
- if self.board_leds:
- hdr_file.write(
- "extern const machine_led_obj_t machine_led_obj[%d];\n" % len(self.board_leds)
- )
-
-
-def main():
- parser = argparse.ArgumentParser(
- prog="make-pins.py",
- usage="%(prog)s [options] [command]",
- description="Generate board specific pin file",
- )
- parser.add_argument(
- "-b",
- "--board",
- dest="csv_filename",
- help="Specifies the pins.csv filename",
- )
- parser.add_argument(
- "-p",
- "--pins",
- dest="pins_filename",
- help="Specifies the name of the generated pins.c file",
- )
- parser.add_argument(
- "-i",
- "--inc",
- dest="hdr_filename",
- help="Specifies name of generated pin header file",
- )
- args = parser.parse_args(sys.argv[1:])
-
- pins = Pins()
-
- if args.csv_filename:
- pins.parse_csv_file(args.csv_filename)
-
- if args.pins_filename:
- pins.print_pins(args.pins_filename)
-
- pins.print_header(args.hdr_filename)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ports/samd/machine_adc.c b/ports/samd/machine_adc.c
index 97b6a14f1..efe0f041c 100644
--- a/ports/samd/machine_adc.c
+++ b/ports/samd/machine_adc.c
@@ -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);
}
diff --git a/ports/samd/machine_led.c b/ports/samd/machine_led.c
index 54c2cb18b..c18bc052b 100644
--- a/ports/samd/machine_led.c
+++ b/ports/samd/machine_led.c
@@ -30,7 +30,7 @@
#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;
@@ -38,8 +38,10 @@ 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, ...)
@@ -47,23 +49,16 @@ mp_obj_t mp_led_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw,
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) },
diff --git a/ports/samd/machine_pin.c b/ports/samd/machine_pin.c
index 2dc10f9b4..a7cd86d38 100644
--- a/ports/samd/machine_pin.c
+++ b/ports/samd/machine_pin.c
@@ -34,7 +34,6 @@
#include "extmod/virtpin.h"
#include "modmachine.h"
#include "samd_soc.h"
-#include "pins.h"
#include "pin_af.h"
#include "hal_gpio.h"
@@ -68,17 +67,17 @@ STATIC void machine_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
machine_pin_obj_t *self = self_in;
char *mode_str;
char *pull_str[] = {"PULL_OFF", "PULL_UP", "PULL_DOWN"};
- if (GPIO_IS_OPEN_DRAIN(self->id)) {
+ if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
mode_str = "OPEN_DRAIN";
} else {
- mode_str = (mp_hal_get_pin_direction(self->id) == GPIO_DIRECTION_OUT) ? "OUT" : "IN";
+ mode_str = (mp_hal_get_pin_direction(self->pin_id) == GPIO_DIRECTION_OUT) ? "OUT" : "IN";
}
mp_printf(print, "Pin(\"%s\", mode=%s, pull=%s, GPIO=P%c%02u)",
- self->name,
+ pin_name(self->pin_id),
mode_str,
- pull_str[mp_hal_get_pull_mode(self->id)],
- "ABCD"[self->id / 32], self->id % 32);
+ pull_str[mp_hal_get_pull_mode(self->pin_id)],
+ "ABCD"[self->pin_id / 32], self->pin_id % 32);
}
STATIC void pin_validate_drive(bool strength) {
@@ -87,25 +86,6 @@ STATIC void pin_validate_drive(bool strength) {
}
}
-int pin_find(mp_obj_t pin, const machine_pin_obj_t machine_pin_obj[], int table_size) {
- int wanted_pin = -1;
- if (mp_obj_is_small_int(pin)) {
- // Pin defined by the index of pin table
- wanted_pin = mp_obj_get_int(pin);
- } else if (mp_obj_is_str(pin)) {
- // Search by name
- size_t slen;
- const char *s = mp_obj_str_get_data(pin, &slen);
- for (wanted_pin = 0; wanted_pin < table_size; wanted_pin++) {
- if (slen == strlen(machine_pin_obj[wanted_pin].name) &&
- strncmp(s, machine_pin_obj[wanted_pin].name, slen) == 0) {
- break;
- }
- }
- }
- return wanted_pin;
-}
-
// Pin.init(mode, pull=None, *, value=None, drive=0). No 'alt' yet.
STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_mode, ARG_pull, ARG_value, ARG_drive, ARG_alt };
@@ -120,32 +100,34 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+ // clear any existing mux setting
+ mp_hal_clr_pin_mux(self->pin_id);
// set initial value (do this before configuring mode/pull)
if (args[ARG_value].u_obj != mp_const_none) {
- mp_hal_pin_write(self->id, mp_obj_is_true(args[ARG_value].u_obj));
+ mp_hal_pin_write(self->pin_id, mp_obj_is_true(args[ARG_value].u_obj));
}
// configure mode
if (args[ARG_mode].u_obj != mp_const_none) {
mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj);
if (mode == GPIO_MODE_IN) {
- mp_hal_pin_input(self->id);
+ mp_hal_pin_input(self->pin_id);
} else if (mode == GPIO_MODE_OUT) {
- mp_hal_pin_output(self->id);
+ mp_hal_pin_output(self->pin_id);
} else if (mode == GPIO_MODE_OPEN_DRAIN) {
- mp_hal_pin_open_drain(self->id);
+ mp_hal_pin_open_drain(self->pin_id);
} else {
- mp_hal_pin_input(self->id); // If no args are given, the Pin is 'input'.
+ mp_hal_pin_input(self->pin_id); // If no args are given, the Pin is 'input'.
}
}
// configure pull. Only to be used with IN mode. The function sets the pin to INPUT.
uint32_t pull = 0;
- mp_int_t dir = mp_hal_get_pin_direction(self->id);
+ mp_int_t dir = mp_hal_get_pin_direction(self->pin_id);
if (dir == GPIO_DIRECTION_OUT && args[ARG_pull].u_obj != mp_const_none) {
mp_raise_ValueError(MP_ERROR_TEXT("OUT incompatible with pull"));
} else if (args[ARG_pull].u_obj != mp_const_none) {
pull = mp_obj_get_int(args[ARG_pull].u_obj);
- gpio_set_pin_pull_mode(self->id, pull); // hal_gpio.h
+ gpio_set_pin_pull_mode(self->pin_id, pull); // hal_gpio.h
}
// get the strength
@@ -158,18 +140,10 @@ STATIC mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_
// constructor(id, ...)
mp_obj_t mp_pin_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);
+ const machine_pin_obj_t *self;
// get the wanted pin object
- int wanted_pin = pin_find(args[0], machine_pin_obj, MP_ARRAY_SIZE(machine_pin_obj));
-
- const machine_pin_obj_t *self = NULL;
- if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(machine_pin_obj)) {
- self = (machine_pin_obj_t *)&machine_pin_obj[wanted_pin];
- }
-
- if (self == NULL || self->base.type == NULL) {
- mp_raise_ValueError(MP_ERROR_TEXT("invalid pin"));
- }
+ self = pin_find(args[0], &machine_pin_type);
if (n_args > 1 || n_kw > 0) {
// pin mode given, so configure this GPIO
@@ -187,18 +161,18 @@ mp_obj_t machine_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp
machine_pin_obj_t *self = self_in;
if (n_args == 0) {
// get pin
- return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self->id));
+ return MP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self->pin_id));
} else {
// set pin
bool value = mp_obj_is_true(args[0]);
- if (GPIO_IS_OPEN_DRAIN(self->id)) {
+ if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
if (value == 0) {
- mp_hal_pin_od_low(self->id);
+ mp_hal_pin_od_low(self->pin_id);
} else {
- mp_hal_pin_od_high(self->id);
+ mp_hal_pin_od_high(self->pin_id);
}
} else {
- mp_hal_pin_write(self->id, value);
+ mp_hal_pin_write(self->pin_id, value);
}
return mp_const_none;
}
@@ -219,7 +193,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_pin_value_obj, 1, 2, machine_
// Pin.disable(pin)
STATIC mp_obj_t machine_pin_disable(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- gpio_set_pin_direction(self->id, GPIO_DIRECTION_OFF); // Disables the pin (low power state)
+ gpio_set_pin_direction(self->pin_id, GPIO_DIRECTION_OFF); // Disables the pin (low power state)
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_disable_obj, machine_pin_disable);
@@ -227,10 +201,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_disable_obj, machine_pin_disable);
// Pin.low() Totem-pole (push-pull)
STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- if (GPIO_IS_OPEN_DRAIN(self->id)) {
- mp_hal_pin_od_low(self->id);
+ if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
+ mp_hal_pin_od_low(self->pin_id);
} else {
- mp_hal_pin_low(self->id);
+ mp_hal_pin_low(self->pin_id);
}
return mp_const_none;
}
@@ -239,10 +213,10 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_low_obj, machine_pin_low);
// Pin.high() Totem-pole (push-pull)
STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- if (GPIO_IS_OPEN_DRAIN(self->id)) {
- mp_hal_pin_od_high(self->id);
+ if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
+ mp_hal_pin_od_high(self->pin_id);
} else {
- mp_hal_pin_high(self->id);
+ mp_hal_pin_high(self->pin_id);
}
return mp_const_none;
}
@@ -255,16 +229,16 @@ STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) {
// Determine DIRECTION of PIN.
bool pin_dir;
- if (GPIO_IS_OPEN_DRAIN(self->id)) {
- pin_dir = mp_hal_get_pin_direction(self->id);
+ if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
+ pin_dir = mp_hal_get_pin_direction(self->pin_id);
if (pin_dir) {
// Pin is output, thus low, switch to high
- mp_hal_pin_od_high(self->id);
+ mp_hal_pin_od_high(self->pin_id);
} else {
- mp_hal_pin_od_low(self->id);
+ mp_hal_pin_od_low(self->pin_id);
}
} else {
- gpio_toggle_pin_level(self->id);
+ gpio_toggle_pin_level(self->pin_id);
}
return mp_const_none;
}
@@ -280,8 +254,8 @@ STATIC mp_obj_t machine_pin_drive(size_t n_args, const mp_obj_t *args) {
pin_validate_drive(strength);
// Set the DRVSTR bit (ASF hri/hri_port_dxx.h
hri_port_write_PINCFG_DRVSTR_bit(PORT,
- (enum gpio_port)GPIO_PORT(self->id),
- GPIO_PIN(self->id),
+ (enum gpio_port)GPIO_PORT(self->pin_id),
+ GPIO_PIN(self->pin_id),
strength);
return mp_const_none;
}
@@ -301,9 +275,9 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
// Get the IRQ object.
- uint8_t eic_id = get_pin_af_info(self->id)->eic;
+ uint8_t eic_id = get_pin_obj_ptr(self->pin_id)->eic;
machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]);
- if (irq != NULL && irq->pin_id != self->id) {
+ if (irq != NULL && irq->pin_id != self->pin_id) {
mp_raise_ValueError(MP_ERROR_TEXT("IRQ already used"));
}
@@ -322,7 +296,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
if (n_args > 1 || kw_args->used != 0) {
// set the mux config of the pin.
- mp_hal_set_pin_mux(self->id, ALT_FCT_EIC);
+ mp_hal_set_pin_mux(self->pin_id, ALT_FCT_EIC);
// Configure IRQ.
#if defined(MCU_SAMD21)
@@ -362,7 +336,7 @@ STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_
irq->base.ishard = args[ARG_hard].u_bool;
irq->flags = 0;
irq->trigger = args[ARG_trigger].u_int;
- irq->pin_id = self->id;
+ irq->pin_id = self->pin_id;
// Enable IRQ if a handler is given.
if (args[ARG_handler].u_obj != mp_const_none) {
@@ -457,10 +431,10 @@ STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, i
switch (request) {
case MP_PIN_READ: {
- return mp_hal_pin_read(self->id);
+ return mp_hal_pin_read(self->pin_id);
}
case MP_PIN_WRITE: {
- mp_hal_pin_write(self->id, arg);
+ mp_hal_pin_write(self->pin_id, arg);
return 0;
}
}
@@ -494,7 +468,7 @@ static uint8_t find_eic_id(int pin) {
STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- uint8_t eic_id = find_eic_id(self->id);
+ uint8_t eic_id = find_eic_id(self->pin_id);
if (eic_id != 0xff) {
machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]);
EIC->INTENCLR.reg |= (1 << eic_id);
@@ -507,7 +481,7 @@ STATIC mp_uint_t machine_pin_irq_trigger(mp_obj_t self_in, mp_uint_t new_trigger
STATIC mp_uint_t machine_pin_irq_info(mp_obj_t self_in, mp_uint_t info_type) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
- uint8_t eic_id = find_eic_id(self->id);
+ uint8_t eic_id = find_eic_id(self->pin_id);
if (eic_id != 0xff) {
machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]);
if (info_type == MP_IRQ_INFO_FLAGS) {
@@ -525,11 +499,8 @@ STATIC const mp_irq_methods_t machine_pin_irq_methods = {
};
mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) {
- if (!mp_obj_is_type(obj, &machine_pin_type)) {
- mp_raise_ValueError(MP_ERROR_TEXT("expecting a Pin"));
- }
- machine_pin_obj_t *pin = MP_OBJ_TO_PTR(obj);
- return pin->id;
+ const machine_pin_obj_t *pin = pin_find(obj, &machine_pin_type);
+ return pin->pin_id;
}
MP_REGISTER_ROOT_POINTER(void *machine_pin_irq_objects[16]);
diff --git a/ports/samd/machine_pwm.c b/ports/samd/machine_pwm.c
index d987927d3..91982a6f7 100644
--- a/ports/samd/machine_pwm.c
+++ b/ports/samd/machine_pwm.c
@@ -107,8 +107,8 @@ STATIC void mp_machine_pwm_duty_set_ns(machine_pwm_obj_t *self, mp_int_t duty_ns
STATIC void mp_machine_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_printf(print, "PWM P%c%02u device=%u channel=%u output=%u",
- "ABCD"[self->pin_id / 32], self->pin_id % 32, self->device, self->channel, self->output);
+ mp_printf(print, "PWM %s device=%u channel=%u output=%u",
+ pin_name(self->pin_id), self->device, self->channel, self->output);
}
// PWM(pin)
diff --git a/ports/samd/modsamd.c b/ports/samd/modsamd.c
index 05ed69bad..79e7b4cc3 100644
--- a/ports/samd/modsamd.c
+++ b/ports/samd/modsamd.c
@@ -30,42 +30,40 @@
#include "sam.h"
#include "pin_af.h"
-#include "pins.h"
#include "samd_soc.h"
extern const mp_obj_type_t samd_flash_type;
STATIC mp_obj_t samd_pininfo(mp_obj_t pin_obj) {
- mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_obj);
- const pin_af_t *pin_af = get_pin_af_info(pin);
- const char *name = ((machine_pin_obj_t *)MP_OBJ_TO_PTR(pin_obj))->name;
- if (pin_af) {
- #if defined(MCU_SAMD21)
- mp_obj_t tuple[7] = {
- tuple[0] = mp_obj_new_str(name, strlen(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),
- tuple[4] = mp_obj_new_int(pin_af->sercom2),
- tuple[5] = mp_obj_new_int(pin_af->tcc1),
- tuple[6] = mp_obj_new_int(pin_af->tcc2),
- };
- 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[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),
- tuple[4] = mp_obj_new_int(pin_af->sercom1),
- tuple[5] = mp_obj_new_int(pin_af->sercom2),
- tuple[6] = mp_obj_new_int(pin_af->tc),
- tuple[7] = mp_obj_new_int(pin_af->tcc1),
- tuple[8] = mp_obj_new_int(pin_af->tcc2),
- };
- return mp_obj_new_tuple(9, tuple);
- #endif
- }
+ const machine_pin_obj_t *pin_af = pin_find(pin_obj, NULL);
+ // 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[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),
+ tuple[4] = mp_obj_new_int(pin_af->sercom2),
+ tuple[5] = mp_obj_new_int(pin_af->tcc1),
+ tuple[6] = mp_obj_new_int(pin_af->tcc2),
+ };
+ 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[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),
+ tuple[4] = mp_obj_new_int(pin_af->sercom1),
+ tuple[5] = mp_obj_new_int(pin_af->sercom2),
+ tuple[6] = mp_obj_new_int(pin_af->tc),
+ tuple[7] = mp_obj_new_int(pin_af->tcc1),
+ tuple[8] = mp_obj_new_int(pin_af->tcc2),
+ };
+ return mp_obj_new_tuple(9, tuple);
+ #endif
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(samd_pininfo_obj, samd_pininfo);
diff --git a/ports/samd/pin_af.c b/ports/samd/pin_af.c
index 926c4ae0c..fc2a0f3d5 100644
--- a/ports/samd/pin_af.c
+++ b/ports/samd/pin_af.c
@@ -29,7 +29,9 @@
*/
#include <stdint.h>
+#include "string.h"
+#include "modmachine.h"
#include "py/runtime.h"
#include "py/misc.h"
#include "pin_af.h"
@@ -43,13 +45,65 @@ extern const uint8_t tcc_channel_count[];
// Just look for an table entry for a given pin and raise an error
// in case of no match (which should not happen).
-const pin_af_t *get_pin_af_info(int pin_id) {
+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];
}
}
- mp_raise_ValueError(MP_ERROR_TEXT("wrong pin"));
+ mp_raise_ValueError(MP_ERROR_TEXT("not a Pin"));
+}
+
+const machine_pin_obj_t *pin_find(mp_obj_t pin, const mp_obj_type_t *type) {
+ const machine_pin_obj_t *self = NULL;
+ // Is already a object of the proper type
+ if (mp_obj_is_type(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)) {
+ // Search by name
+ size_t slen;
+ const char *s = mp_obj_str_get_data(pin, &slen);
+ // Check for a string like PA02 or PD12
+ 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);
+ } 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];
+ }
+ }
+ }
+ }
+ if (self != NULL && (type == NULL || mp_obj_is_type(self, type))) {
+ return self;
+ } else {
+ 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;
+ }
+ }
+ }
+ return "-";
}
// Test, wether the given pin is defined and has signals for sercom.
@@ -57,7 +111,7 @@ const pin_af_t *get_pin_af_info(int pin_id) {
// If not, an error will be raised.
sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom_nr) {
- const pin_af_t *pct_ptr = get_pin_af_info(pin_id);
+ const machine_pin_obj_t *pct_ptr = get_pin_obj_ptr(pin_id);
if ((pct_ptr->sercom1 >> 4) == sercom_nr) {
return (sercom_pad_config_t) {ALT_FCT_SERCOM1, pct_ptr->sercom1 & 0x0f};
} else if ((pct_ptr->sercom2 >> 4) == sercom_nr) {
@@ -72,7 +126,12 @@ sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom_nr) {
// If not, an error will be raised.
adc_config_t get_adc_config(int pin_id, int32_t flag) {
- const pin_af_t *pct_ptr = get_pin_af_info(pin_id);
+ const machine_pin_obj_t *pct_ptr = get_pin_obj_ptr(pin_id);
+ #if defined(MCU_SAMD51)
+ if (pct_ptr->adc1 != 0xff && (flag & (1 << (pct_ptr->adc1 + 16))) == 0) {
+ return (adc_config_t) {1, pct_ptr->adc1};
+ } else
+ #endif
if (pct_ptr->adc0 != 0xff && (flag & (1 << pct_ptr->adc0)) == 0) {
return (adc_config_t) {0, pct_ptr->adc0};
#if defined(MUC_SAMD51)
@@ -91,7 +150,7 @@ adc_config_t get_adc_config(int pin_id, int32_t flag) {
// tries to provide an unused device, if available.
pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t device_status[]) {
- const pin_af_t *pct_ptr = get_pin_af_info(pin_id);
+ const machine_pin_obj_t *pct_ptr = get_pin_obj_ptr(pin_id);
uint8_t tcc1 = pct_ptr->tcc1;
uint8_t tcc2 = pct_ptr->tcc2;
diff --git a/ports/samd/pin_af.h b/ports/samd/pin_af.h
index b75f4ddd0..5bb65a098 100644
--- a/ports/samd/pin_af.h
+++ b/ports/samd/pin_af.h
@@ -30,15 +30,17 @@
#if defined(MCU_SAMD21)
-typedef struct {
+typedef struct _machine_pin_obj_t {
+ mp_obj_base_t base;
uint8_t pin_id;
+ char *name;
uint8_t eic;
uint8_t adc0;
uint8_t sercom1;
uint8_t sercom2;
uint8_t tcc1;
uint8_t tcc2;
-} pin_af_t;
+} machine_pin_obj_t;
#define ALT_FCT_TC 4
#define ALT_FCT_TCC1 4
@@ -46,8 +48,10 @@ typedef struct {
#elif defined(MCU_SAMD51)
-typedef struct {
+typedef struct _machine_pin_obj_t {
+ mp_obj_base_t base;
uint8_t pin_id;
+ char *name;
uint8_t eic;
uint8_t adc0;
uint8_t adc1;
@@ -56,7 +60,7 @@ typedef struct {
uint8_t tc;
uint8_t tcc1;
uint8_t tcc2;
-} pin_af_t;
+} machine_pin_obj_t;
#define ALT_FCT_TC 4
#define ALT_FCT_TCC1 5
@@ -85,7 +89,11 @@ typedef struct _pwm_config_t {
#define ALT_FCT_SERCOM1 2
#define ALT_FCT_SERCOM2 3
+extern const machine_pin_obj_t pin_af_table[];
+
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);
pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t used_dev[]);
-const pin_af_t *get_pin_af_info(int pin_id);
+const machine_pin_obj_t *get_pin_obj_ptr(int pin_id);
+const char *pin_name(int id);
+const machine_pin_obj_t *pin_find(mp_obj_t pin, const mp_obj_type_t *type);