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/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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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) },
|
||||
|
@ -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]);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user