import csv
import os
import pprint
import subprocess
from base import Write
SCRIPT = os.path.relpath(__file__, os.getcwd()).replace("\\", "/")
def match_filter(filter: str, name: str) -> bool:
if filter == "UART":
return name.startswith("UART") or name.startswith("USART")
return name.startswith(filter)
FUNC_TABLE = {
"TX": "Tx",
"RX": "Rx",
}
TEMPLATE = """impl DmaBind{func}<pac::{peri}> for {dma}::{ch} {{}}
"""
def write_item(dma: str, ch: str, func: str, w: Write) -> None:
ch = ch.replace("ch", "C")
(peri, func) = func.split("_", 1)
func = FUNC_TABLE.get(func, "")
w.write(TEMPLATE.format(func=func, peri=peri, dma=dma, ch=ch))
def write_table(d: dict, filter: str, w: Write) -> None:
w.write("\n")
for dma, ch_table in sorted(d.items()):
for ch, func_list in sorted(ch_table.items()):
for func in sorted(func_list):
if match_filter(filter, func):
write_item(dma, ch, func, w)
def parse_dma_info(row: list[str], ret_d: dict) -> None:
dma = row[0]
channel = row[1]
func_list: list[str] = []
for func in row[2:]:
if func:
func_list.append(func)
p = ret_d.setdefault(dma, {})
p[channel] = func_list
def csv_to_code(csv_file: str, show: bool = False) -> None:
print(csv_file)
d: dict = {}
with open(csv_file, newline="", encoding="utf-8") as f:
reader = csv.reader(f, delimiter=",", quotechar='"')
for row in reader:
if row[0]:
parse_dma_info(row, d)
if show:
pprint.pprint(d)
target_file = "src/dma.rs"
with open(target_file, "r", encoding="utf-8") as f:
code = f.read()
i = code.find("// table") + len("// table")
before = code[:i]
code = code[i:]
w = Write(target_file)
w.write(before)
w.write("\n// Do NOT manually modify the code.\n")
w.write(
f"// It's generated by {SCRIPT} from {csv_file}\n",
)
write_table(d, "UART", w)
write_table(d, "SPI", w)
write_table(d, "I2C", w)
w.close()
subprocess.run(["rustfmt", target_file])
if __name__ == "__main__":
csv_to_code("scripts/table/stm32f1_dma_table.csv")