samd/machine_pin: Change the pin handling and naming/numbering.
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.
This commit is contained in:
parent
e7aa9700ca
commit
e5cf3fab95
@ -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/asf4/$(MCU_SERIES_LOWER)/include/pio
|
||||||
INC += -I$(TOP)/lib/tinyusb/src
|
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
|
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
|
BOARD_PINS = $(BOARD_DIR)/pins.csv
|
||||||
GEN_PINS_SRC = $(BUILD)/pins.c
|
GEN_PIN_AF = pin_af_table.c
|
||||||
GEN_PINS_HDR = $(BUILD)/pins.h
|
|
||||||
|
|
||||||
CFLAGS_MCU_SAMD21 = -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float
|
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
|
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 \
|
drivers/bus/softspi.c \
|
||||||
|
|
||||||
# List of sources for qstr extraction
|
# 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 += $(PY_O)
|
||||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.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)/, $(LIBM_SRC_C:.c=.o))
|
||||||
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
|
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
|
||||||
OBJ += $(addprefix $(BUILD)/, $(TINYUSB_SRC_C:.c=.o))
|
OBJ += $(addprefix $(BUILD)/, $(TINYUSB_SRC_C:.c=.o))
|
||||||
OBJ += $(GEN_PINS_SRC:.c=.o)
|
|
||||||
|
|
||||||
ifneq ($(FROZEN_MANIFEST),)
|
ifneq ($(FROZEN_MANIFEST),)
|
||||||
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
|
CFLAGS += -DMICROPY_MODULE_FROZEN_MPY
|
||||||
@ -182,19 +177,10 @@ $(BUILD)/firmware.bin: $(BUILD)/firmware.elf
|
|||||||
$(BUILD)/firmware.uf2: $(BUILD)/firmware.bin
|
$(BUILD)/firmware.uf2: $(BUILD)/firmware.bin
|
||||||
$(Q)$(PYTHON) $(UF2CONV) -b $(TEXT0) -c -o $@ $<
|
$(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 $@"
|
$(ECHO) "Create $@"
|
||||||
$(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --table $(BUILD)/$(GEN_PIN_AF) --mcu $(MCU_SERIES)
|
$(Q)$(PYTHON) $(MAKE_PIN_AF) --csv $(PIN_AF_TABLE_CSV) --board $(BOARD_PINS) --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)
|
|
||||||
|
|
||||||
include $(TOP)/py/mkrules.mk
|
include $(TOP)/py/mkrules.mk
|
||||||
|
@ -16,6 +16,7 @@ table_header = """// This file was automatically generated by make-pin-cap.py
|
|||||||
class Pins:
|
class Pins:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.board_pins = [] # list of pin objects
|
self.board_pins = [] # list of pin objects
|
||||||
|
self.pin_names = {}
|
||||||
|
|
||||||
def parse_csv_file(self, filename):
|
def parse_csv_file(self, filename):
|
||||||
with open(filename, "r") as csvfile:
|
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"):
|
if len(row) > 0 and row[0].strip().upper()[:2] in ("PA", "PB", "PC", "PD"):
|
||||||
self.board_pins.append(row)
|
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):
|
def print_table(self, table_filename, mcu_name):
|
||||||
with open(table_filename, "wt") as table_file:
|
with open(table_filename, "wt") as table_file:
|
||||||
table_file.write(table_header)
|
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":
|
if mcu_name == "SAMD21":
|
||||||
for row in self.board_pins:
|
for row in self.board_pins:
|
||||||
pin = "PIN_" + row[0].upper()
|
pin = "PIN_" + row[0].upper()
|
||||||
table_file.write(" #ifdef " + pin + "\n")
|
table_file.write(" #ifdef " + pin + "\n")
|
||||||
eic = row[1] if row[1] else "0xff"
|
eic = row[1] if row[1] else "0xff"
|
||||||
adc = row[2] if row[2] 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:]:
|
for cell in row[3:]:
|
||||||
if cell:
|
if cell:
|
||||||
table_file.write(
|
table_file.write(
|
||||||
@ -52,7 +79,15 @@ class Pins:
|
|||||||
eic = row[1] if row[1] else "0xff"
|
eic = row[1] if row[1] else "0xff"
|
||||||
adc0 = row[2] if row[2] else "0xff"
|
adc0 = row[2] if row[2] else "0xff"
|
||||||
adc1 = row[3] if row[3] 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:]:
|
for cell in row[4:]:
|
||||||
if cell:
|
if cell:
|
||||||
table_file.write(
|
table_file.write(
|
||||||
@ -67,7 +102,7 @@ class Pins:
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog="make-pin-cap.py",
|
prog="make-pin-af.py",
|
||||||
usage="%(prog)s [options] [command]",
|
usage="%(prog)s [options] [command]",
|
||||||
description="Generate MCU-specific pin cap table file",
|
description="Generate MCU-specific pin cap table file",
|
||||||
)
|
)
|
||||||
@ -75,7 +110,13 @@ def main():
|
|||||||
"-c",
|
"-c",
|
||||||
"--csv",
|
"--csv",
|
||||||
dest="csv_filename",
|
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(
|
parser.add_argument(
|
||||||
"-t",
|
"-t",
|
||||||
@ -96,6 +137,9 @@ def main():
|
|||||||
if args.csv_filename:
|
if args.csv_filename:
|
||||||
pins.parse_csv_file(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:
|
if args.table_filename:
|
||||||
pins.print_table(args.table_filename, args.mcu_name)
|
pins.print_table(args.table_filename, args.mcu_name)
|
||||||
|
|
@ -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()
|
|
@ -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;
|
(void)kind;
|
||||||
machine_adc_obj_t *self = MP_OBJ_TO_PTR(o);
|
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)",
|
mp_printf(print, "ADC(%s, ADC%u, channel=%u, bits=%u, average=%u)",
|
||||||
"ABCD"[self->id / 32], self->id % 32, self->adc_config.device,
|
pin_name(self->id), self->adc_config.device,
|
||||||
self->adc_config.channel, self->bits, 1 << self->avg);
|
self->adc_config.channel, self->bits, 1 << self->avg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "extmod/virtpin.h"
|
#include "extmod/virtpin.h"
|
||||||
#include "modmachine.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_low_obj;
|
||||||
extern mp_obj_t machine_pin_high_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);
|
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) {
|
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;
|
machine_pin_obj_t *self = self_in;
|
||||||
mp_printf(print, "LED(\"%s\")", self->name);
|
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, ...)
|
// 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);
|
mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
|
||||||
|
|
||||||
// get the wanted LED object
|
// 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_pin_obj_t *self;
|
||||||
const machine_led_obj_t *self = NULL;
|
|
||||||
if (0 <= wanted_led && wanted_led < MP_ARRAY_SIZE(machine_led_obj)) {
|
self = pin_find(args[0], &machine_led_type);
|
||||||
self = (machine_led_obj_t *)&machine_led_obj[wanted_led];
|
|
||||||
}
|
mp_hal_pin_output(self->pin_id);
|
||||||
// the array could be padded with 'nulls' (see other Ports).
|
mp_hal_pin_low(self->pin_id);
|
||||||
// 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);
|
|
||||||
|
|
||||||
return MP_OBJ_FROM_PTR(self);
|
return MP_OBJ_FROM_PTR(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = {
|
STATIC const mp_rom_map_elem_t machine_led_locals_dict_table[] = {
|
||||||
// instance methods
|
// instance methods
|
||||||
{ MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&machine_pin_low_obj) },
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include "extmod/virtpin.h"
|
#include "extmod/virtpin.h"
|
||||||
#include "modmachine.h"
|
#include "modmachine.h"
|
||||||
#include "samd_soc.h"
|
#include "samd_soc.h"
|
||||||
#include "pins.h"
|
|
||||||
#include "pin_af.h"
|
#include "pin_af.h"
|
||||||
|
|
||||||
#include "hal_gpio.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;
|
machine_pin_obj_t *self = self_in;
|
||||||
char *mode_str;
|
char *mode_str;
|
||||||
char *pull_str[] = {"PULL_OFF", "PULL_UP", "PULL_DOWN"};
|
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";
|
mode_str = "OPEN_DRAIN";
|
||||||
} else {
|
} 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)",
|
mp_printf(print, "Pin(\"%s\", mode=%s, pull=%s, GPIO=P%c%02u)",
|
||||||
self->name,
|
pin_name(self->pin_id),
|
||||||
mode_str,
|
mode_str,
|
||||||
pull_str[mp_hal_get_pull_mode(self->id)],
|
pull_str[mp_hal_get_pull_mode(self->pin_id)],
|
||||||
"ABCD"[self->id / 32], self->id % 32);
|
"ABCD"[self->pin_id / 32], self->pin_id % 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void pin_validate_drive(bool strength) {
|
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.
|
// 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) {
|
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 };
|
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_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);
|
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)
|
// set initial value (do this before configuring mode/pull)
|
||||||
if (args[ARG_value].u_obj != mp_const_none) {
|
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
|
// configure mode
|
||||||
if (args[ARG_mode].u_obj != mp_const_none) {
|
if (args[ARG_mode].u_obj != mp_const_none) {
|
||||||
mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj);
|
mp_int_t mode = mp_obj_get_int(args[ARG_mode].u_obj);
|
||||||
if (mode == GPIO_MODE_IN) {
|
if (mode == GPIO_MODE_IN) {
|
||||||
mp_hal_pin_input(self->id);
|
mp_hal_pin_input(self->pin_id);
|
||||||
} else if (mode == GPIO_MODE_OUT) {
|
} 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) {
|
} else if (mode == GPIO_MODE_OPEN_DRAIN) {
|
||||||
mp_hal_pin_open_drain(self->id);
|
mp_hal_pin_open_drain(self->pin_id);
|
||||||
} else {
|
} 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.
|
// configure pull. Only to be used with IN mode. The function sets the pin to INPUT.
|
||||||
uint32_t pull = 0;
|
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) {
|
if (dir == GPIO_DIRECTION_OUT && args[ARG_pull].u_obj != mp_const_none) {
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("OUT incompatible with pull"));
|
mp_raise_ValueError(MP_ERROR_TEXT("OUT incompatible with pull"));
|
||||||
} else if (args[ARG_pull].u_obj != mp_const_none) {
|
} else if (args[ARG_pull].u_obj != mp_const_none) {
|
||||||
pull = mp_obj_get_int(args[ARG_pull].u_obj);
|
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
|
// 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, ...)
|
// 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_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);
|
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
|
// get the wanted pin object
|
||||||
int wanted_pin = pin_find(args[0], machine_pin_obj, MP_ARRAY_SIZE(machine_pin_obj));
|
self = pin_find(args[0], &machine_pin_type);
|
||||||
|
|
||||||
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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n_args > 1 || n_kw > 0) {
|
if (n_args > 1 || n_kw > 0) {
|
||||||
// pin mode given, so configure this GPIO
|
// 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;
|
machine_pin_obj_t *self = self_in;
|
||||||
if (n_args == 0) {
|
if (n_args == 0) {
|
||||||
// get pin
|
// 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 {
|
} else {
|
||||||
// set pin
|
// set pin
|
||||||
bool value = mp_obj_is_true(args[0]);
|
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) {
|
if (value == 0) {
|
||||||
mp_hal_pin_od_low(self->id);
|
mp_hal_pin_od_low(self->pin_id);
|
||||||
} else {
|
} else {
|
||||||
mp_hal_pin_od_high(self->id);
|
mp_hal_pin_od_high(self->pin_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
mp_hal_pin_write(self->id, value);
|
mp_hal_pin_write(self->pin_id, value);
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
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)
|
// Pin.disable(pin)
|
||||||
STATIC mp_obj_t machine_pin_disable(mp_obj_t self_in) {
|
STATIC mp_obj_t machine_pin_disable(mp_obj_t self_in) {
|
||||||
machine_pin_obj_t *self = MP_OBJ_TO_PTR(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;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_disable_obj, machine_pin_disable);
|
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)
|
// Pin.low() Totem-pole (push-pull)
|
||||||
STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) {
|
STATIC mp_obj_t machine_pin_low(mp_obj_t self_in) {
|
||||||
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
if (GPIO_IS_OPEN_DRAIN(self->id)) {
|
if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
|
||||||
mp_hal_pin_od_low(self->id);
|
mp_hal_pin_od_low(self->pin_id);
|
||||||
} else {
|
} else {
|
||||||
mp_hal_pin_low(self->id);
|
mp_hal_pin_low(self->pin_id);
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
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)
|
// Pin.high() Totem-pole (push-pull)
|
||||||
STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) {
|
STATIC mp_obj_t machine_pin_high(mp_obj_t self_in) {
|
||||||
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
if (GPIO_IS_OPEN_DRAIN(self->id)) {
|
if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
|
||||||
mp_hal_pin_od_high(self->id);
|
mp_hal_pin_od_high(self->pin_id);
|
||||||
} else {
|
} else {
|
||||||
mp_hal_pin_high(self->id);
|
mp_hal_pin_high(self->pin_id);
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
@ -255,16 +229,16 @@ STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) {
|
|||||||
// Determine DIRECTION of PIN.
|
// Determine DIRECTION of PIN.
|
||||||
bool pin_dir;
|
bool pin_dir;
|
||||||
|
|
||||||
if (GPIO_IS_OPEN_DRAIN(self->id)) {
|
if (GPIO_IS_OPEN_DRAIN(self->pin_id)) {
|
||||||
pin_dir = mp_hal_get_pin_direction(self->id);
|
pin_dir = mp_hal_get_pin_direction(self->pin_id);
|
||||||
if (pin_dir) {
|
if (pin_dir) {
|
||||||
// Pin is output, thus low, switch to high
|
// Pin is output, thus low, switch to high
|
||||||
mp_hal_pin_od_high(self->id);
|
mp_hal_pin_od_high(self->pin_id);
|
||||||
} else {
|
} else {
|
||||||
mp_hal_pin_od_low(self->id);
|
mp_hal_pin_od_low(self->pin_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gpio_toggle_pin_level(self->id);
|
gpio_toggle_pin_level(self->pin_id);
|
||||||
}
|
}
|
||||||
return mp_const_none;
|
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);
|
pin_validate_drive(strength);
|
||||||
// Set the DRVSTR bit (ASF hri/hri_port_dxx.h
|
// Set the DRVSTR bit (ASF hri/hri_port_dxx.h
|
||||||
hri_port_write_PINCFG_DRVSTR_bit(PORT,
|
hri_port_write_PINCFG_DRVSTR_bit(PORT,
|
||||||
(enum gpio_port)GPIO_PORT(self->id),
|
(enum gpio_port)GPIO_PORT(self->pin_id),
|
||||||
GPIO_PIN(self->id),
|
GPIO_PIN(self->pin_id),
|
||||||
strength);
|
strength);
|
||||||
return mp_const_none;
|
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);
|
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||||
|
|
||||||
// Get the IRQ object.
|
// 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]);
|
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"));
|
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) {
|
if (n_args > 1 || kw_args->used != 0) {
|
||||||
|
|
||||||
// set the mux config of the pin.
|
// 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.
|
// Configure IRQ.
|
||||||
#if defined(MCU_SAMD21)
|
#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->base.ishard = args[ARG_hard].u_bool;
|
||||||
irq->flags = 0;
|
irq->flags = 0;
|
||||||
irq->trigger = args[ARG_trigger].u_int;
|
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.
|
// Enable IRQ if a handler is given.
|
||||||
if (args[ARG_handler].u_obj != mp_const_none) {
|
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) {
|
switch (request) {
|
||||||
case MP_PIN_READ: {
|
case MP_PIN_READ: {
|
||||||
return mp_hal_pin_read(self->id);
|
return mp_hal_pin_read(self->pin_id);
|
||||||
}
|
}
|
||||||
case MP_PIN_WRITE: {
|
case MP_PIN_WRITE: {
|
||||||
mp_hal_pin_write(self->id, arg);
|
mp_hal_pin_write(self->pin_id, arg);
|
||||||
return 0;
|
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) {
|
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);
|
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) {
|
if (eic_id != 0xff) {
|
||||||
machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]);
|
machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]);
|
||||||
EIC->INTENCLR.reg |= (1 << 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) {
|
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);
|
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) {
|
if (eic_id != 0xff) {
|
||||||
machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]);
|
machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_objects[eic_id]);
|
||||||
if (info_type == MP_IRQ_INFO_FLAGS) {
|
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) {
|
mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t obj) {
|
||||||
if (!mp_obj_is_type(obj, &machine_pin_type)) {
|
const machine_pin_obj_t *pin = pin_find(obj, &machine_pin_type);
|
||||||
mp_raise_ValueError(MP_ERROR_TEXT("expecting a Pin"));
|
return pin->pin_id;
|
||||||
}
|
|
||||||
machine_pin_obj_t *pin = MP_OBJ_TO_PTR(obj);
|
|
||||||
return pin->id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MP_REGISTER_ROOT_POINTER(void *machine_pin_irq_objects[16]);
|
MP_REGISTER_ROOT_POINTER(void *machine_pin_irq_objects[16]);
|
||||||
|
@ -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) {
|
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);
|
machine_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||||
mp_printf(print, "PWM P%c%02u device=%u channel=%u output=%u",
|
mp_printf(print, "PWM %s device=%u channel=%u output=%u",
|
||||||
"ABCD"[self->pin_id / 32], self->pin_id % 32, self->device, self->channel, self->output);
|
pin_name(self->pin_id), self->device, self->channel, self->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PWM(pin)
|
// PWM(pin)
|
||||||
|
@ -30,42 +30,40 @@
|
|||||||
|
|
||||||
#include "sam.h"
|
#include "sam.h"
|
||||||
#include "pin_af.h"
|
#include "pin_af.h"
|
||||||
#include "pins.h"
|
|
||||||
#include "samd_soc.h"
|
#include "samd_soc.h"
|
||||||
|
|
||||||
extern const mp_obj_type_t samd_flash_type;
|
extern const mp_obj_type_t samd_flash_type;
|
||||||
|
|
||||||
STATIC mp_obj_t samd_pininfo(mp_obj_t pin_obj) {
|
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 machine_pin_obj_t *pin_af = pin_find(pin_obj, NULL);
|
||||||
const pin_af_t *pin_af = get_pin_af_info(pin);
|
// Get the name, now that it is not in the pin object
|
||||||
const char *name = ((machine_pin_obj_t *)MP_OBJ_TO_PTR(pin_obj))->name;
|
const char *name = pin_af->name;
|
||||||
if (pin_af) {
|
|
||||||
#if defined(MCU_SAMD21)
|
#if defined(MCU_SAMD21)
|
||||||
mp_obj_t tuple[7] = {
|
mp_obj_t tuple[7] = {
|
||||||
tuple[0] = mp_obj_new_str(name, strlen(name)),
|
tuple[0] = mp_obj_new_str(name, strlen(name)),
|
||||||
tuple[1] = mp_obj_new_int(pin_af->eic),
|
tuple[1] = mp_obj_new_int(pin_af->eic),
|
||||||
tuple[2] = mp_obj_new_int(pin_af->adc0),
|
tuple[2] = mp_obj_new_int(pin_af->adc0),
|
||||||
tuple[3] = mp_obj_new_int(pin_af->sercom1),
|
tuple[3] = mp_obj_new_int(pin_af->sercom1),
|
||||||
tuple[4] = mp_obj_new_int(pin_af->sercom2),
|
tuple[4] = mp_obj_new_int(pin_af->sercom2),
|
||||||
tuple[5] = mp_obj_new_int(pin_af->tcc1),
|
tuple[5] = mp_obj_new_int(pin_af->tcc1),
|
||||||
tuple[6] = mp_obj_new_int(pin_af->tcc2),
|
tuple[6] = mp_obj_new_int(pin_af->tcc2),
|
||||||
};
|
};
|
||||||
return mp_obj_new_tuple(7, tuple);
|
return mp_obj_new_tuple(7, tuple);
|
||||||
#elif defined(MCU_SAMD51)
|
#elif defined(MCU_SAMD51)
|
||||||
mp_obj_t tuple[9] = {
|
mp_obj_t tuple[9] = {
|
||||||
tuple[0] = mp_obj_new_str(name, strlen(name)),
|
tuple[0] = mp_obj_new_str(name, strlen(name)),
|
||||||
tuple[1] = mp_obj_new_int(pin_af->eic),
|
tuple[1] = mp_obj_new_int(pin_af->eic),
|
||||||
tuple[2] = mp_obj_new_int(pin_af->adc0),
|
tuple[2] = mp_obj_new_int(pin_af->adc0),
|
||||||
tuple[3] = mp_obj_new_int(pin_af->adc1),
|
tuple[3] = mp_obj_new_int(pin_af->adc1),
|
||||||
tuple[4] = mp_obj_new_int(pin_af->sercom1),
|
tuple[4] = mp_obj_new_int(pin_af->sercom1),
|
||||||
tuple[5] = mp_obj_new_int(pin_af->sercom2),
|
tuple[5] = mp_obj_new_int(pin_af->sercom2),
|
||||||
tuple[6] = mp_obj_new_int(pin_af->tc),
|
tuple[6] = mp_obj_new_int(pin_af->tc),
|
||||||
tuple[7] = mp_obj_new_int(pin_af->tcc1),
|
tuple[7] = mp_obj_new_int(pin_af->tcc1),
|
||||||
tuple[8] = mp_obj_new_int(pin_af->tcc2),
|
tuple[8] = mp_obj_new_int(pin_af->tcc2),
|
||||||
};
|
};
|
||||||
return mp_obj_new_tuple(9, tuple);
|
return mp_obj_new_tuple(9, tuple);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(samd_pininfo_obj, samd_pininfo);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(samd_pininfo_obj, samd_pininfo);
|
||||||
|
@ -29,7 +29,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
#include "modmachine.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/misc.h"
|
#include "py/misc.h"
|
||||||
#include "pin_af.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
|
// Just look for an table entry for a given pin and raise an error
|
||||||
// in case of no match (which should not happen).
|
// 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++) {
|
for (int i = 0; i < MP_ARRAY_SIZE(pin_af_table); i++) {
|
||||||
if (pin_af_table[i].pin_id == pin_id) { // Pin match
|
if (pin_af_table[i].pin_id == pin_id) { // Pin match
|
||||||
return &pin_af_table[i];
|
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.
|
// 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.
|
// If not, an error will be raised.
|
||||||
|
|
||||||
sercom_pad_config_t get_sercom_config(int pin_id, uint8_t sercom_nr) {
|
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) {
|
if ((pct_ptr->sercom1 >> 4) == sercom_nr) {
|
||||||
return (sercom_pad_config_t) {ALT_FCT_SERCOM1, pct_ptr->sercom1 & 0x0f};
|
return (sercom_pad_config_t) {ALT_FCT_SERCOM1, pct_ptr->sercom1 & 0x0f};
|
||||||
} else if ((pct_ptr->sercom2 >> 4) == sercom_nr) {
|
} 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.
|
// If not, an error will be raised.
|
||||||
|
|
||||||
adc_config_t get_adc_config(int pin_id, int32_t flag) {
|
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) {
|
if (pct_ptr->adc0 != 0xff && (flag & (1 << pct_ptr->adc0)) == 0) {
|
||||||
return (adc_config_t) {0, pct_ptr->adc0};
|
return (adc_config_t) {0, pct_ptr->adc0};
|
||||||
#if defined(MUC_SAMD51)
|
#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.
|
// tries to provide an unused device, if available.
|
||||||
|
|
||||||
pwm_config_t get_pwm_config(int pin_id, int wanted_dev, uint8_t device_status[]) {
|
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 tcc1 = pct_ptr->tcc1;
|
||||||
uint8_t tcc2 = pct_ptr->tcc2;
|
uint8_t tcc2 = pct_ptr->tcc2;
|
||||||
|
|
||||||
|
@ -30,15 +30,17 @@
|
|||||||
|
|
||||||
#if defined(MCU_SAMD21)
|
#if defined(MCU_SAMD21)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct _machine_pin_obj_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
uint8_t pin_id;
|
uint8_t pin_id;
|
||||||
|
char *name;
|
||||||
uint8_t eic;
|
uint8_t eic;
|
||||||
uint8_t adc0;
|
uint8_t adc0;
|
||||||
uint8_t sercom1;
|
uint8_t sercom1;
|
||||||
uint8_t sercom2;
|
uint8_t sercom2;
|
||||||
uint8_t tcc1;
|
uint8_t tcc1;
|
||||||
uint8_t tcc2;
|
uint8_t tcc2;
|
||||||
} pin_af_t;
|
} machine_pin_obj_t;
|
||||||
|
|
||||||
#define ALT_FCT_TC 4
|
#define ALT_FCT_TC 4
|
||||||
#define ALT_FCT_TCC1 4
|
#define ALT_FCT_TCC1 4
|
||||||
@ -46,8 +48,10 @@ typedef struct {
|
|||||||
|
|
||||||
#elif defined(MCU_SAMD51)
|
#elif defined(MCU_SAMD51)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct _machine_pin_obj_t {
|
||||||
|
mp_obj_base_t base;
|
||||||
uint8_t pin_id;
|
uint8_t pin_id;
|
||||||
|
char *name;
|
||||||
uint8_t eic;
|
uint8_t eic;
|
||||||
uint8_t adc0;
|
uint8_t adc0;
|
||||||
uint8_t adc1;
|
uint8_t adc1;
|
||||||
@ -56,7 +60,7 @@ typedef struct {
|
|||||||
uint8_t tc;
|
uint8_t tc;
|
||||||
uint8_t tcc1;
|
uint8_t tcc1;
|
||||||
uint8_t tcc2;
|
uint8_t tcc2;
|
||||||
} pin_af_t;
|
} machine_pin_obj_t;
|
||||||
|
|
||||||
#define ALT_FCT_TC 4
|
#define ALT_FCT_TC 4
|
||||||
#define ALT_FCT_TCC1 5
|
#define ALT_FCT_TCC1 5
|
||||||
@ -85,7 +89,11 @@ typedef struct _pwm_config_t {
|
|||||||
#define ALT_FCT_SERCOM1 2
|
#define ALT_FCT_SERCOM1 2
|
||||||
#define ALT_FCT_SERCOM2 3
|
#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);
|
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);
|
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[]);
|
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user