Last active
July 11, 2022 13:18
-
-
Save elfmimi/fefc4bf55cfed8ecea6ca37b1177b9b3 to your computer and use it in GitHub Desktop.
Port of ruby script convert_matrix_config.rb in python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Copyright 2022 Takeshi Ishii (@mtei) | |
# Copyright 2022 Ein Terakawa (a_p_u_r_o@elfmimi) | |
# SPDX-License-Identifier: GPL-2.0-or-later | |
import sys | |
import re | |
import json | |
import subprocess | |
if len(sys.argv) != 2: | |
print(f"usage: python3 {sys.argv[0]} <config_file or info.json>") | |
exit(1) | |
col_pins = None | |
col_pins_right = None | |
col_pins_ext = None | |
col_pins_ext_right = None | |
row_pins = None | |
row_pins_right = None | |
row_pins_ext = None | |
row_pins_ext_right = None | |
input_port_pin = None | |
output_port_pin = None | |
input_port_pin_right = None | |
output_port_pin_right = None | |
def main(): | |
read_configuration(sys.argv[1]) | |
build_all_port_pin_lists() | |
print_all_port_pin_lists() | |
def read_configuration(file): | |
if re.match('^.*info.json', file): | |
read_configuration_from_info_json(file) | |
else: | |
read_configuration_from_config_h(file) | |
def build_all_port_pin_lists(): | |
global input_port_pin, output_port_pin, input_port_pin_right, output_port_pin_right | |
input_port_pin = build_port_pin_list(col_pins) if col_pins else input_port_pin | |
# p input_port_pin | |
input_port_pin = build_port_pin_list_ext(col_pins_ext) if col_pins_ext else input_port_pin | |
# p input_port_pin | |
output_port_pin = build_port_pin_list(row_pins) if row_pins else output_port_pin | |
# p output_port_pin | |
output_port_pin = build_port_pin_list_ext(row_pins_ext) if row_pins_ext else output_port_pin | |
# p output_port_pin | |
input_port_pin_right = build_port_pin_list(col_pins_right) if col_pins_right else input_port_pin_right | |
# p input_port_pin_right | |
input_port_pin_right = build_port_pin_list_ext(col_pins_ext_right) if col_pins_ext_right else input_port_pin_right | |
# p input_port_pin_right | |
output_port_pin_right = build_port_pin_list(row_pins_right) if row_pins_right else output_port_pin_right | |
# p output_port_pin_right | |
output_port_pin_right = build_port_pin_list_ext(row_pins_ext_right) if row_pins_ext_right else output_port_pin_right | |
# p output_port_pin_right | |
def print_all_port_pin_lists(): | |
print("#pragma once") | |
if input_port_pin: | |
if col_pins_ext: | |
print(f" /* #define EXTENDED_MATRIX_COL_PINS {col_pins_ext} */") | |
else: | |
print(f" /* #define MATRIX_COL_PINS {{{col_pins}}} */") | |
print("#undef MATRIX_COL_PINS") | |
print("#define SWITCH_MATRIX_INPUT_0 \\") | |
print_port(input_port_pin[0]) | |
print_pin(input_port_pin[1], True) | |
print("") | |
if output_port_pin: | |
if row_pins_ext: | |
print(f" /* #define EXTENDED_MATRIX_ROW_PINS {row_pins_ext} */") | |
else: | |
print(f" /* #define MATRIX_ROW_PINS {{{row_pins}}} */") | |
print("#undef MATRIX_ROW_PINS") | |
print("#define SWITCH_MATRIX_OUTPUT_0 \\") | |
print_port(output_port_pin[0]) | |
print_pin(output_port_pin[1]) | |
print("") | |
if input_port_pin_right: | |
if col_pins_ext_right: | |
print(f" /* #define EXTENDED_MATRIX_COL_PINS_RIGHT {{{col_pins_ext_right}}} */") | |
else: | |
print(f" /* #define MATRIX_COL_PINS_RIGHT {{{col_pins_right}}} */") | |
print("#undef MATRIX_COL_PINS_RIGHT") | |
print("#define SWITCH_MATRIX_INPUT_1 \\") | |
print_port(input_port_pin_right[0]) | |
print_pin(input_port_pin_right[1], True) | |
print("") | |
if output_port_pin_right: | |
if row_pins_ext_right: | |
print(f" /* #define EXTENDED_MATRIX_ROW_PINS_RIGHT {row_pins_ext_right} */") | |
else: | |
print(f" /* #define MATRIX_ROW_PINS_RIGHT {{{row_pins_right}}} */") | |
print("#undef MATRIX_ROW_PINS_RIGHT") | |
print("#define SWITCH_MATRIX_OUTPUT_1 \\") | |
print_port(output_port_pin_right[0]) | |
print_pin(output_port_pin_right[1]) | |
print("") | |
def read_configuration_from_config_h(file): | |
global col_pins, col_pins_right, col_pins_ext, col_pins_ext_right | |
global row_pins, row_pins_right, row_pins_ext, row_pins_ext_right | |
gcc = "gcc" | |
conf = [] | |
with subprocess.Popen([gcc, "-dM", "-E", "-xc", file], stdout=subprocess.PIPE) as p: | |
for line in p.stdout: | |
if b"define MATRIX_" in line or b"define EXTENDED_MATRIX_" in line: | |
conf.append(line.rstrip().decode()) | |
for c in conf: | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* MATRIX_COL_PINS[ \t]+{(.*)}', c) | |
col_pins = m[1] if m else col_pins | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* MATRIX_COL_PINS_RIGHT[ \t]+{(.*)}', c) | |
col_pins_right = m[1] if m else col_pins_right | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* EXTENDED_MATRIX_COL_PINS[ \t]+(.*)', c) | |
col_pins_ext = m[1] if m else col_pins_ext | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* EXTENDED_MATRIX_COL_PINS_RIGHT[ \t]+(.*)', c) | |
col_pins_ext_right = m[1] if m else col_pins_ext_right | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* MATRIX_ROW_PINS[ \t]+{(.*)}', c) | |
row_pins = m[1] if m else row_pins | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* MATRIX_ROW_PINS_RIGHT[ \t]+{(.*)}', c) | |
row_pins_right = m[1] if m else row_pins_right | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* EXTENDED_MATRIX_ROW_PINS[ \t]+(.*)', c) | |
row_pins_ext = m[1] if m else row_pins_ext | |
m = re.match('^[ \t]*#[ \t]*define[ \t]* EXTENDED_MATRIX_ROW_PINS_RIGHT[ \t]+(.*)', c) | |
row_pins_ext_right = m[1] if m else row_pins_ext_right | |
def read_configuration_from_info_json(file): | |
global col_pins, row_pins | |
with open(file) as f: | |
info = json.load(f) | |
if "matrix_pins" in info: | |
col_pins = ",".join(info["matrix_pins"]["cols"]) | |
row_pins = ",".join(info["matrix_pins"]["rows"]) | |
else: | |
print(f"ERROR: {file} does not contain matrix_pins information.") | |
exit(1) | |
def build_port_pin_list(pins): | |
# p pins | |
# if source data is '#define MATRIX_COL_PINS { F4, F5, F6, F7, B1, B3, B2 }' | |
# example: pins = " F4, F5, F6, F7, B1, B3, B2 " | |
pin_number = 0 | |
raw_list = [] | |
for pin in [pin.strip() for pin in pins.split(",")]: | |
pin_number += 1 | |
if pin == "NO_PIN": | |
port = "NO_PIN" | |
mask = 0 | |
raw_list.append(["NO_DEVICE", port, mask, 0]) | |
else: | |
m = re.match('([A-Z])([0-9]*)', pin) | |
port = m[1]+"0" | |
mask = (1<<int(m[2])) | |
raw_list.append(["MCU_GPIO", port, mask, (1<<(pin_number - 1))]) | |
# p raw_list | |
# example: raw_list = [["MCU_GPIO", "F0", 16, 1], ["MCU_GPIO", "F0", 32, 2], ["MCU_GPIO", "F0", 64, 4], ["MCU_GPIO", "F0", 128, 8], ["MCU_GPIO", "B0", 2, 16], ["MCU_GPIO", "B0", 8, 32], ["MCU_GPIO", "B0", 4, 64]] | |
return build_port_pin_list_sub(raw_list) | |
def build_port_pin_list_ext(pins): | |
# p pins | |
# if source data is | |
# '#define EXTENDED_MATRIX_COL_PINS \ | |
# (MCU_GPIO, F0, 4), (MCU_GPIO, F0,5 ), (MCU_GPIO, F0,6 ), \ | |
# (MCU_GPIO, F0, 7), (MCU_GPIO, B0, 1), (MCU_GPIO, B0, 3), (MCU_GPIO, B0, 2)' | |
# example: pins = "(MCU_GPIO, F0, 4), (MCU_GPIO, F0,5 ), (MCU_GPIO, F0,6 ), (MCU_GPIO, F0, 7), (MCU_GPIO, B0, 1), (MCU_GPIO, B0, 3), (MCU_GPIO, B0, 2)" | |
pin_number = 0 | |
raw_list = [] | |
sepalate_pins = re.split('\s*\)\s*,\s*\(\s*', re.sub('^\s*\(\s*|\s*\)\s*$', '', pins)) | |
for pin in sepalate_pins: | |
pin = re.split('\s*,\s*', pin) | |
dev = pin[0] | |
port = pin[1] | |
pin_number += 1 | |
if dev == "NO_DEVICE" or port == "NO_PIN": | |
raw_list.append(["NO_DEVICE", "NO_PIN", 0, 0]) | |
else: | |
mask = (1<<int(pin[2])) | |
raw_list.append([dev, port, mask, (1<<(pin_number - 1))]) | |
# p raw_list | |
# example: raw_list = [["MCU_GPIO", "F0", 16, 1], ["MCU_GPIO", "F0", 32, 2], ["MCU_GPIO", "F0", 64, 4], ["MCU_GPIO", "F0", 128, 8], ["MCU_GPIO", "B0", 2, 16], ["MCU_GPIO", "B0", 8, 32], ["MCU_GPIO", "B0", 4, 64]] | |
return build_port_pin_list_sub(raw_list) | |
def build_port_pin_list_sub(raw_list): | |
#### build ports list #### | |
port_num = 0 | |
ports = {} | |
for pin in raw_list: | |
key = tuple(pin[0:2]) | |
if key != tuple(["NO_DEVICE", "NO_PIN"]): | |
if key not in ports: | |
ports[key] = [ port_num, 0 ] | |
port_num += 1 | |
ports[key][1] |= pin[2] # build port mask | |
# p ports | |
# example: ports = {("MCU_GPIO", "F0"): [0, 240], ("MCU_GPIO", "B0"): [1, 14]} | |
for v in ports.values(): | |
v[1] = '0x%02x' % v[1] | |
# p ports | |
# example: ports = {("MCU_GPIO", "F0"): [0, "0xf0"], ("MCU_GPIO", "B0"): [1, "0x0e"]} | |
#### build pins list #### | |
pins = [] | |
for pin in raw_list: | |
key = tuple(pin[0:2]) | |
if key in ports: | |
port_index = ports[key][0] | |
else: | |
port_index = "NO_PIN" | |
pins.append([ port_index, '0x%02x' % pin[2], '0x%02x' % pin[3] ]) | |
# p pins | |
# example: pins = [[0, "0x10", "0x1"], [0, "0x20", "0x2"], [0, "0x40", "0x4"], [0, "0x80", "0x8"], [1, "0x2", "0x10"], [1, "0x8", "0x20"], [1, "0x4", "0x40"]] | |
return [ [ [ port[0][1], port[1][1], port[0][0] ] for port in ports.items() ], pins ] | |
def print_port(ports): | |
print(" /* ( ( <port>, <mask>, <dev> ), ... ) */ \\") | |
print(" ( ", end='') | |
print(", \\\n ".join([f"({port[0]}, {port[1]}, {port[2]})" for port in ports]), end='') | |
print(" ),\\") | |
def print_pin(pins, is_input = False): | |
if is_input: | |
pins = [pin for pin in pins if pin[0] != "NO_PIN"] | |
else: | |
pins = [[0 if pin[0] == "NO_PIN" else pin[0], *pin[1:]] for pin in pins] | |
print(" /* ( ( <port_index>, <port_mask>, <matrix_row_mask> ), ... ) */ \\") | |
print(" ( ", end='') | |
print(", \\\n ".join([f"({pin[0]}, {pin[1]}, {pin[2]})" for pin in pins]), end='') | |
print(" )") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment