circuitpython/ports/esp32/boards/make-pins.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

186 lines
5.8 KiB
Python
Raw Normal View History

#!/usr/bin/env python
import argparse
import sys
import csv
import re
MAX_CPU_PINS = 49
def parse_pin(name_str):
"""Parses a string and returns a pin number."""
if len(name_str) < 2:
raise ValueError("Expecting pin name to be at least 2 characters.")
if not name_str.startswith("GPIO"):
raise ValueError("Expecting pin name to start with GPIO")
return int(re.findall(r"\d+$", name_str)[0])
class Pin:
def __init__(self, pin):
self.pin = pin
self.is_board = False
def cpu_pin_name(self):
return "GPIO{:d}".format(self.pin)
def is_board_pin(self):
return self.is_board
def set_is_board_pin(self):
self.is_board = True
class NamedPin:
def __init__(self, name, pin):
self._name = name
self._pin = pin
def pin(self):
return self._pin
def name(self):
return self._name
class Pins:
def __init__(self):
self.cpu_pins = [] # list of NamedPin objects
self.board_pins = [] # list of NamedPin objects
def find_pin(self, pin_name):
for pin in self.cpu_pins:
if pin.name() == pin_name:
return pin.pin()
def create_pins(self):
for pin_num in range(MAX_CPU_PINS):
pin = Pin(pin_num)
self.cpu_pins.append(NamedPin(pin.cpu_pin_name(), pin))
def parse_board_file(self, filename):
with open(filename, "r") as csvfile:
rows = csv.reader(csvfile)
for row in rows:
if len(row) == 0 or row[0].startswith("#"):
# Skip empty lines, and lines starting with "#"
continue
if len(row) != 2:
raise ValueError("Expecting two entries in a row")
cpu_pin_name = row[1]
parse_pin(cpu_pin_name)
pin = self.find_pin(cpu_pin_name)
if not pin:
raise ValueError("Unknown pin {}".format(cpu_pin_name))
pin.set_is_board_pin()
if row[0]: # Only add board pins that have a name
self.board_pins.append(NamedPin(row[0], pin))
def print_table(self, label, named_pins, out_source):
print("", file=out_source)
print(
"const machine_{}_obj_t machine_{}_obj_table[GPIO_NUM_MAX] = {{".format(label, label),
file=out_source,
)
for pin in named_pins:
print(" #if MICROPY_HW_ENABLE_{}".format(pin.name()), file=out_source)
print(
" [GPIO_NUM_{}] = {{ .base = {{ .type = &machine_{}_type }} }},".format(
pin.pin().pin, label
),
file=out_source,
)
print(" #endif", file=out_source)
print("};", file=out_source)
def print_named(self, label, named_pins, out_source):
print("", file=out_source)
print(
"STATIC const mp_rom_map_elem_t machine_pin_{:s}_pins_locals_dict_table[] = {{".format(
label
),
file=out_source,
)
for named_pin in named_pins:
pin = named_pin.pin()
print(
" {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},".format(
named_pin.name(), pin.cpu_pin_name()
),
file=out_source,
)
print("};", file=out_source)
print(
"MP_DEFINE_CONST_DICT(machine_pin_{:s}_pins_locals_dict, machine_pin_{:s}_pins_locals_dict_table);".format(
label, label
),
file=out_source,
)
def print_tables(self, out_source):
self.print_table("pin", self.cpu_pins, out_source)
self.print_table("pin_irq", self.cpu_pins, out_source)
self.print_named("board", self.board_pins, out_source)
def print_header(self, out_header):
# Provide #defines for each cpu pin.
for named_pin in self.cpu_pins:
pin = named_pin.pin()
n = pin.cpu_pin_name()
print("#if MICROPY_HW_ENABLE_{}".format(n), file=out_header)
print(
"#define pin_{:s} (machine_pin_obj_table[{}])".format(n, pin.pin),
file=out_header,
)
print("#endif", file=out_header)
# Provide #define's mapping board to cpu name.
for named_pin in self.board_pins:
if named_pin.pin().is_board_pin():
print(
"#define pin_{:s} pin_{:s}".format(
named_pin.name(), named_pin.pin().cpu_pin_name()
),
file=out_header,
)
def main():
parser = argparse.ArgumentParser(description="Generate board specific pin file")
parser.add_argument("--board-csv")
parser.add_argument("--prefix")
parser.add_argument("--output-source")
parser.add_argument("--output-header")
args = parser.parse_args(sys.argv[1:])
pins = Pins()
pins.create_pins()
if args.board_csv:
pins.parse_board_file(args.board_csv)
with open(args.output_source, "w") as out_source:
print("// This file was automatically generated by make-pins.py", file=out_source)
print("//", file=out_source)
if args.board_csv:
print("// --board-csv {:s}".format(args.board_csv), file=out_source)
if args.prefix:
print("// --prefix {:s}".format(args.prefix), file=out_source)
print("", file=out_source)
with open(args.prefix, "r") as prefix_file:
print(prefix_file.read(), end="", file=out_source)
pins.print_tables(out_source)
with open(args.output_header, "w") as out_header:
pins.print_header(out_header)
if __name__ == "__main__":
main()