circuitpython/ports/stm/tools/parse_af_csv.py

138 lines
5.3 KiB
Python
Raw Normal View History

# This file is part of the MicroPython project, http://micropython.org/
#
# The MIT License (MIT)
#
# Copyright (c) 2020 Lucian Copeland for Adafruit Industries
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import csv
import sys
# Use: parse_af_csf.py Filename.csv -pins-only
# Designed for use with .csv files from Micropython, or in identical format
# created via Datasheet peripheral tables with a Sheets program.
#
# See examples/stm32f405.csv for example formatting.
# Most peripherals (SPI, I2C) output 3 values:
# peripheral index, alt function, pin string
def evaluate_periph(inper, inlist, periph, subtype, altfn, pin):
# ex) SPI1_SCK,SPI3_SCK/I2S3_CK
# Clean anything after a '\' due to SPI/I2S mixing
if not inper.find('/') == -1:
inper = inper[:inper.find('/')]
if inper[:len(periph)] == periph and inper[-len(subtype):] == subtype:
inlist.append([inper[len(periph):len(periph)+1], altfn, pin])
# Timers (TIM) are a special case with 4 values
# timer index, alt function, channel, pin string
def evaluate_tim(inper, inlist, altfn, pin):
# ex) TIM2_CH1/TIM2_ETR, TIM5_CH1
# Clean anything after a '\' to filter ETR
if not inper.find('/') == -1:
inper = inper[:inper.find('/')]
if inper[:3] == "TIM" and inper[5:7] == "CH" and inper[-1:] != 'N':
inlist.append([inper[3:4],altfn,inper[-1:],pin])
# Open target file
with open(sys.argv[1]) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
line_count = 0
if sys.argv[2] != "-pins-only":
# List of peripheral pin types to read
todo = [
["I2C","SDA"],
["I2C","SCL"],
["SPI","SCK"],
["SPI","MOSI"],
["SPI","MISO"],
["UART","TX"],
["UART","RX"]]
# Make a list of empty lists to populate
outlist = []
for items in todo:
empty = []
outlist.append(empty)
# TIM
empty = []
outlist.append(empty)
# Each line is a list of strings
for row in csv_reader:
altfn = 0
pin = row[1]
if len(pin) < 4:
pin = pin[:2] + '0' + pin[2:]
for col in row:
array_index = 0
# Evaluate the string for every possible todo entry
for item in todo:
evaluate_periph(col, outlist[array_index], item[0], item[1], altfn - 2, pin)
# UART special case, run again for USART variant
if item[0] == "UART":
evaluate_periph(col, outlist[array_index], "USART", item[1], altfn - 2, pin)
array_index += 1
# TIM special case
evaluate_tim(col, outlist[-1], altfn - 2, pin)
altfn += 1
line_count += 1
# Print formatted output
for i in range(len(todo)):
ins = (todo[i][0]).lower() + '_' + (todo[i][1]).lower() + '_'
# const mcu_i2c_sda_obj_t mcu_i2c_sda_list[4] = {
2020-04-02 11:47:16 -04:00
print("const mcu_periph_obj_t mcu_" + ins + "list[" + str(len(outlist[i])) + "] = {")
for row in outlist[i]:
print(" PERIPH(" + row[0] + ", " + str(row[1]) + ", &pin_" + row[2] + "),")
print("};")
# Timer special case:
print("const mcu_tim_pin_obj_t mcu_tim_pin_list[" + str(len(outlist[-1])) + "] = {")
for row in outlist[-1]:
print(" TIM(" + row[0] + ", " + str(row[1]) + ", " + str(row[2]) + ", &pin_" + row[3] + "),")
print("};")
else:
# Format all viable pins listed
# ex) const mcu_pin_obj_t pin_PE02 = PIN(4, 2, NO_ADC);
# ex 2) extern const mcu_pin_obj_t pin_PE02;
# TODO: add ADC detection
outlist = []
for row in csv_reader:
altfn = 0
pin = row[1]
if len(pin) < 4:
pin = pin[:2] + '0' + pin[2:]
outlist.append([pin, str(ord(row[1][1:2]) - 65), row[1][2:4]])
line_count += 1
for line in outlist:
print("const mcu_pin_obj_t pin_" + line[0] + " = PIN(" + line[1] + ", " + line[2] + ", NO_ADC);")
for line in outlist:
print("extern const mcu_pin_obj_t pin_" + line[0] + ";")
print(f'Processed {line_count} lines.')