diff options
author | Dave Hylands <dhylands@gmail.com> | 2014-03-11 23:55:41 -0700 |
---|---|---|
committer | Dave Hylands <dhylands@gmail.com> | 2014-03-11 23:55:41 -0700 |
commit | dd38d907244bc0e483c3d760f2ba464a394ec229 (patch) | |
tree | 05869a4757c5a1b11b8baf206595551c7650f6e7 /stmhal/boards/make-pins.py | |
parent | 8bfec2b53822e2b62c4577b32e0beae398a16297 (diff) | |
download | micropython-dd38d907244bc0e483c3d760f2ba464a394ec229.tar.gz micropython-dd38d907244bc0e483c3d760f2ba464a394ec229.zip |
Initial checkin with STM HAL
This compiles and links, but hasn't been tested on a board
yet and even if it was run, it doesn't currently do anything.
Diffstat (limited to 'stmhal/boards/make-pins.py')
-rwxr-xr-x | stmhal/boards/make-pins.py | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/stmhal/boards/make-pins.py b/stmhal/boards/make-pins.py new file mode 100755 index 0000000000..8c1bedbf0c --- /dev/null +++ b/stmhal/boards/make-pins.py @@ -0,0 +1,261 @@ +#!/usr/bin/env python +"""Creates the pin file for the STM32F4xx.""" + +from __future__ import print_function + +import argparse +import sys +import csv + +SUPPORTED_FN = { + 'TIM' : ['CH1', 'CH2', 'CH3', 'CH4', + 'CH1N', 'CH2N', 'CH3N', 'CH1_ETR', 'ETR', 'BKIN'], + 'I2C' : ['SDA', 'SCL'], + 'USART' : ['RX', 'TX', 'CTS', 'RTS', 'CK'], + 'UART' : ['RX', 'TX', 'CTS', 'RTS'], + 'SPI' : ['NSS', 'SCK', 'MISO', 'MOSI'] +} + +def parse_port_pin(name_str): + """Parses a string and returns a (port-num, pin-num) tuple.""" + if len(name_str) < 3: + raise ValueError("Expecting pin name to be at least 3 charcters.") + if name_str[0] != 'P': + raise ValueError("Expecting pin name to start with P") + if name_str[1] < 'A' or name_str[1] > 'J': + raise ValueError("Expecting pin port to be between A and J") + port = ord(name_str[1]) - ord('A') + pin_str = name_str[2:] + if not pin_str.isdigit(): + raise ValueError("Expecting numeric pin number.") + return (port, int(pin_str)) + +def split_name_num(name_num): + num = None + for num_idx in range(len(name_num) - 1, -1, -1): + if not name_num[num_idx].isdigit(): + name = name_num[0:num_idx + 1] + num_str = name_num[num_idx + 1:] + if len(num_str) > 0: + num = int(num_str) + break + return name, num + + +class AlternateFunction(object): + """Holds the information associated with a pins alternate function.""" + + def __init__(self, idx, af_str): + self.idx = idx + self.af_str = af_str + + self.func = '' + self.fn_num = None + self.pin_type = '' + self.supported = False + + af_words = af_str.split('_', 1) + self.func, self.fn_num = split_name_num(af_words[0]) + if len(af_words) > 1: + self.pin_type = af_words[1] + if self.func in SUPPORTED_FN: + pin_types = SUPPORTED_FN[self.func] + if self.pin_type in pin_types: + self.supported = True + + def is_supported(self): + return self.supported + + def ptr(self): + """Returns the numbered function (i.e. USART6) for this AF.""" + if self.fn_num is None: + return self.func + return '{:s}{:d}'.format(self.func, self.fn_num) + + def print(self): + """Prints the C representation of this AF.""" + if self.supported: + print(' AF', end='') + else: + print(' //', end='') + fn_num = self.fn_num + if fn_num is None: + fn_num = 0 + print('({:2d}, {:8s}, {:2d}, {:10s}, {:8s}), // {:s}'.format(self.idx, + self.func, fn_num, self.pin_type, self.ptr(), self.af_str)) + + +class Pin(object): + """Holds the information associated with a pin.""" + + def __init__(self, port, pin): + self.port = port + self.pin = pin + self.alt_fn = [] + self.board_name = None + self.alt_fn_count = 0 + + def port_letter(self): + return chr(self.port + ord('A')) + + def pin_name(self): + return '{:s}{:d}'.format(self.port_letter(), self.pin) + + def parse_af(self, af_idx, af_strs_in): + if len(af_strs_in) == 0: + return + # If there is a slash, then the slash separates 2 aliases for the + # same alternate function. + af_strs = af_strs_in.split('/') + for af_str in af_strs: + alt_fn = AlternateFunction(af_idx, af_str) + self.alt_fn.append(alt_fn) + if alt_fn.is_supported(): + self.alt_fn_count += 1 + + def alt_fn_name(self): + if self.alt_fn_count > 0: + return 'pin_{:s}_af'.format(self.pin_name()) + return 'NULL' + + def print(self): + if self.alt_fn_count == 0: + print("// ", end='') + print('const pin_af_obj_t {:s}[] = {{'.format(self.alt_fn_name())) + for alt_fn in self.alt_fn: + alt_fn.print() + if self.alt_fn_count == 0: + print("// ", end='') + print('};') + print('') + print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:d}, {:s});'.format( + self.pin_name(), self.port_letter(), self.pin, + self.alt_fn_count, self.alt_fn_name())) + print('') + + def print_header(self, hdr_file): + hdr_file.write('extern const pin_obj_t pin_{:s};\n'. + format(self.pin_name())) + if self.alt_fn_count > 0: + hdr_file.write('extern const pin_af_obj_t pin_{:s}_af[];\n'. + format(self.pin_name())) + + +class Pins(object): + + def __init__(self): + self.pins = [] + self.board_pins = [] + + def find_pin(self, port_num, pin_num): + for pin in self.pins: + if pin.port == port_num and pin.pin == pin_num: + return pin + + def parse_af_file(self, filename, pinname_col, af_col): + with open(filename, 'r') as csvfile: + rows = csv.reader(csvfile) + for row in rows: + try: + (port_num, pin_num) = parse_port_pin(row[pinname_col]) + except: + continue + pin = Pin(port_num, pin_num) + for af_idx in range(af_col, len(row)): + pin.parse_af(af_idx - af_col, row[af_idx]) + self.pins.append(pin) + + def parse_board_file(self, filename): + with open(filename, 'r') as csvfile: + rows = csv.reader(csvfile) + for row in rows: + try: + (port_num, pin_num) = parse_port_pin(row[1]) + except: + continue + pin = self.find_pin(port_num, pin_num) + if pin: + pin.board_name = row[0] + self.board_pins.append(pin) + + def print_named(self, label, pins): + print('const pin_named_pin_t pin_{:s}_pins[] = {{'.format(label)) + for pin in pins: + if pin.board_name: + if label == 'board': + pin_name = pin.board_name + else: + pin_name = pin.pin_name() + print(' {{ "{:s}", &pin_{:s} }},'.format(pin_name, pin.pin_name())) + print(' { NULL, NULL }') + print('};') + + def print(self): + for pin in self.pins: + if pin.board_name: + pin.print() + self.print_named('cpu', self.pins) + print('') + self.print_named('board', self.board_pins) + + def print_header(self, hdr_filename): + with open(hdr_filename, 'wt') as hdr_file: + for pin in self.pins: + if pin.board_name: + pin.print_header(hdr_file) + + +def main(): + parser = argparse.ArgumentParser( + prog="make-pins.py", + usage="%(prog)s [options] [command]", + description="Generate board specific pin file" + ) + parser.add_argument( + "-a", "--af", + dest="af_filename", + help="Specifies the alternate function file for the chip", + default="stm32f4xx-af.csv" + ) + parser.add_argument( + "-b", "--board", + dest="board_filename", + help="Specifies the board file", + ) + parser.add_argument( + "-p", "--prefix", + dest="prefix_filename", + help="Specifies beginning portion of generated pins file", + default="stm32f4xx-prefix.c" + ) + parser.add_argument( + "-r", "--hdr", + dest="hdr_filename", + help="Specifies name of generated pin header file", + default="build/pins.h" + ) + args = parser.parse_args(sys.argv[1:]) + + pins = Pins() + + print('// This file was automatically generated by make-pins.py') + print('//') + if args.af_filename: + print('// --af {:s}'.format(args.af_filename)) + pins.parse_af_file(args.af_filename, 1, 2) + + if args.board_filename: + print('// --board {:s}'.format(args.board_filename)) + pins.parse_board_file(args.board_filename) + + if args.prefix_filename: + print('// --prefix {:s}'.format(args.prefix_filename)) + print('') + with open(args.prefix_filename, 'r') as prefix_file: + print(prefix_file.read()) + pins.print() + pins.print_header(args.hdr_filename) + + +if __name__ == "__main__": + main() |