96 lines
3.3 KiB
Python
96 lines
3.3 KiB
Python
#!/usr/bin/env python
|
|
|
|
|
|
from collections import defaultdict, namedtuple
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../../../tools"))
|
|
import boardgen
|
|
|
|
|
|
# These are the columns of the af.csv as well as the arguments to the PIN()
|
|
# macro in samd_prefix.c.
|
|
AFS = {
|
|
"SAMD21": ["eic", "adc0", "sercom1", "sercom2", "tcc1", "tcc2"],
|
|
"SAMD51": ["eic", "adc0", "adc1", "sercom1", "sercom2", "tc", "tcc1", "tcc2"],
|
|
}
|
|
|
|
|
|
class SamdPin(boardgen.Pin):
|
|
def __init__(self, cpu_pin_name):
|
|
super().__init__(cpu_pin_name)
|
|
|
|
# P<port><num> (already verified by validate_cpu_pin_name).
|
|
self._port = cpu_pin_name[1]
|
|
self._pin = int(cpu_pin_name[2:])
|
|
|
|
# List of uint8 values from the af.csv. Default to 0xff if not
|
|
# present.
|
|
self._afs = defaultdict(lambda: 0xFF)
|
|
|
|
# Called for each AF defined in the csv file for this pin.
|
|
def add_af(self, af_idx, af_name, af):
|
|
# samd-specific: Any pin in the af.csv is implicitly part of the board
|
|
# pins.csv and will therefore be in the Pin.cpu dict. This is
|
|
# equivalent to adding `,Pxy` to the board.csv for every pin in the
|
|
# af.csv.
|
|
self._available = True
|
|
|
|
name = AFS[self._generator.args.mcu][af_idx]
|
|
assert name == af_name.lower()
|
|
if name == "eic" or name.startswith("adc"):
|
|
# eic and adc columns are decimal.
|
|
v = int(af)
|
|
else:
|
|
# hex, high nibble is device number, low nibble is pad number.
|
|
v = int(af, 16)
|
|
self._afs[AFS[self._generator.args.mcu][af_idx]] = v
|
|
|
|
# Use the PIN() macro defined in samd_prefix.c for defining the pin
|
|
# objects.
|
|
def definition(self):
|
|
# SAMD21: PIN(p_name, p_eic, p_adc0, p_sercom1, p_sercom2, p_tcc1, p_tcc2)
|
|
# SAMD51: PIN(p_name, p_eic, p_adc0, p_adc1, p_sercom1, p_sercom2, p_tc, p_tcc1, p_tcc2)
|
|
return "PIN({:s}, {})".format(
|
|
self.name(),
|
|
", ".join("0x{:02x}".format(self._afs[x]) for x in AFS[self._generator.args.mcu]),
|
|
)
|
|
|
|
# Wrap all definitions to ensure that the ASF defines this pin for this
|
|
# particular MCU.
|
|
def enable_macro(self):
|
|
return "defined(PIN_{})".format(self.name())
|
|
|
|
# SAMD cpu names must be "P<port><num>", with zero-prefixed two-digit <num>.
|
|
@staticmethod
|
|
def validate_cpu_pin_name(cpu_pin_name):
|
|
boardgen.Pin.validate_cpu_pin_name(cpu_pin_name)
|
|
|
|
if not re.match("P[A-D][0-9][0-9]$", cpu_pin_name):
|
|
raise boardgen.PinGeneratorError("Invalid cpu pin name '{}'".format(cpu_pin_name))
|
|
|
|
|
|
class SamdPinGenerator(boardgen.PinGenerator):
|
|
def __init__(self):
|
|
# Use custom pin type above, and also enable the --af-csv argument so
|
|
# that add_af gets called on each pin.
|
|
super().__init__(
|
|
pin_type=SamdPin,
|
|
enable_af=True,
|
|
)
|
|
|
|
# Override the default implementation just to change the default arguments
|
|
# (extra header row, skip first column).
|
|
def parse_af_csv(self, filename):
|
|
return super().parse_af_csv(filename, header_rows=1, pin_col=0, af_col=1)
|
|
|
|
# We need to know the mcu to emit the correct AF list.
|
|
def extra_args(self, parser):
|
|
parser.add_argument("--mcu")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
SamdPinGenerator().main()
|