circuitpython/ports/samd/boards/make-pin-table.py
robert-hh e5cf3fab95 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.
2022-10-25 23:34:07 +11:00

149 lines
5.3 KiB
Python

#!/usr/bin/env python
"""Generates the pin_cap table file for the SAMD port."""
from __future__ import print_function
import argparse
import sys
import csv
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:
rows = csv.reader(csvfile)
for row in rows:
# Pin numbers must start with "PA", "PB", "PC" or "PD"
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 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"
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(
", 0x%s" % cell if len(cell) == 2 else ", 0x0%s" % cell
)
else:
table_file.write(", 0xff")
table_file.write("},\n")
table_file.write(" #endif\n")
else:
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"
adc0 = row[2] if row[2] else "0xff"
adc1 = row[3] if row[3] else "0xff"
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(
", 0x%s" % cell if len(cell) == 2 else ", 0x0%s" % cell
)
else:
table_file.write(", 0xff")
table_file.write("},\n")
table_file.write(" #endif\n")
table_file.write("};\n")
def main():
parser = argparse.ArgumentParser(
prog="make-pin-af.py",
usage="%(prog)s [options] [command]",
description="Generate MCU-specific pin cap table file",
)
parser.add_argument(
"-c",
"--csv",
dest="csv_filename",
help="Specifies the pin-af-table.csv filename",
)
parser.add_argument(
"-b",
"--board",
dest="pin_filename",
help="Specifies the pins.csv filename",
)
parser.add_argument(
"-t",
"--table",
dest="table_filename",
help="Specifies the name of the generated pin cap table file",
)
parser.add_argument(
"-m",
"--mcu",
dest="mcu_name",
help="Specifies type of the MCU (SAMD21 or SAMD51)",
)
args = parser.parse_args(sys.argv[1:])
pins = Pins()
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)
if __name__ == "__main__":
main()