Skip to content

Commit 57ae8fa

Browse files
committed
scripts/mtl_ecspy_to_c.py: Convert data to C code
Signed-off-by: Filip Gołaś <filip.golas@3mdeb.com>
1 parent 4b884cf commit 57ae8fa

File tree

1 file changed

+158
-42
lines changed

1 file changed

+158
-42
lines changed

scripts/mtl_ecspy_to_c.py

+158-42
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,167 @@
22
import sys
33
import re
44

5-
# get the log from ecspy
6-
# parse the gpio control register values
75

8-
args = sys.argv
9-
ecspy_log = args[1]
10-
lines = open(ecspy_log).readlines()
11-
gpio_data = {}
6+
gpcr_control_pin_mode_to_c_define = {
7+
"00": "GPIO_ALT1",
8+
"01": "GPIO_OUT",
9+
"10": "GPIO_IN",
10+
}
11+
12+
13+
# parses the log file given as a list of lines
14+
# returns two dicts
15+
# - GCR register values: {GCR_number(int):
16+
# value(list of '1' positions in binary form)
17+
# }
18+
# - GP registers: {letter(str): {
19+
# number(int): {
20+
# data(int),
21+
# mirror(int),
22+
# pot(int),
23+
# control: (list of '1' positions in binary form
24+
# }
25+
# }
26+
def parse_ecspy_log(lines: list[str]) -> tuple[dict, dict]:
27+
gpr_line_re = re.compile(r"([A-M])(\d): data (\d) mirror (\d) pot (\d) control ([0-9A-Fa-f]{2})")
28+
gcr_line_re = re.compile(r"GCR(\d?): 0x([0-9A-Fa-f]{2})")
29+
gpr_grouped = {}
30+
gcr_grouped = {}
31+
for line in lines:
32+
match_gpr = gpr_line_re.match(line)
33+
match_gcr = gcr_line_re.match(line)
34+
if match_gpr:
35+
gpr = {}
36+
gpr['letter'] = match_gpr.group(1)
37+
gpr['number'] = int(match_gpr.group(2))
38+
gpr['data'] = int(match_gpr.group(3))
39+
gpr['mirror'] = int(match_gpr.group(4))
40+
gpr['pot'] = int(match_gpr.group(5))
41+
gpr['control'] = int_to_bit_positions(int(match_gpr.group(6), 16))
42+
43+
if gpr['letter'] not in gpr_grouped:
44+
gpr_grouped[gpr['letter']] = {}
45+
gpr_grouped[gpr['letter']][gpr['number']] = gpr
46+
47+
if match_gcr:
48+
gcr = {}
49+
gcr['number'] = match_gcr.group(1)
50+
gcr['value'] = int_to_bit_positions(int(match_gcr.group(2), 16))
51+
if gcr['number'] not in gcr_grouped:
52+
gcr_grouped[gcr['number']] = gcr
53+
return gpr_grouped, gcr_grouped
54+
55+
def bit_positions_to_hex(positions: list[int]) -> str:
56+
return hex(sum([1 << i for i in positions]))
57+
58+
# returns a string defining the GPCR register value
59+
# using #defines for the bit positions
60+
def gpcr_control_bit_positions_to_c(positions: list[int]) -> str:
61+
macros = []
62+
pimmode = ("1" if 6 in positions else "0") + ("1" if 7 in positions else "0")
63+
macros.append(gpcr_control_pin_mode_to_c_define[pimmode])
64+
if 2 in positions:
65+
macros.append("GPIO_UP")
66+
if 1 in positions:
67+
macros.append("GPIO_DOWN")
68+
[print(f"WARNING: undefined GPCR control bit position: {pos} in {bit_positions_to_hex(positions)}") \
69+
for pos in positions if pos not in [1, 2, 6, 7]]
70+
output = " | ".join(macros)
71+
return output
1272

1373
# returns a list of positions of bits set to 1 in the integer
14-
def int_to_bits(n):
74+
# e.g. 5(0b101) -> [0, 2]
75+
def int_to_bit_positions(n: int) -> list[int]:
1576
return [i for i in range(n.bit_length()) if n & (1 << i)]
1677

17-
# Regular expression to parse each line
18-
gpr_line_re = re.compile(r"([A-M]\d): data (\d) mirror (\d) pot (\d) control ([0-9A-Fa-f]{2})")
19-
gcr_line_re = re.compile(r"GCR(\d): 0x([0-9A-Fa-f]{2})")
20-
gpr_grouped = {}
21-
gcr_grouped = {}
22-
for line in lines:
23-
match_gpr = gpr_line_re.match(line)
24-
match_gcr = gcr_line_re.match(line)
25-
if match_gpr:
26-
gpr = {}
27-
gpr['pin'] = match_gpr.group(1)
28-
gpr['data'] = int(match_gpr.group(2))
29-
gpr['mirror'] = int(match_gpr.group(3))
30-
gpr['pot'] = int(match_gpr.group(4))
31-
gpr['control'] = int(match_gpr.group(5), 16)
32-
33-
port = gpr['pin'][0]
34-
port_number = int(gpr['pin'][1])
35-
36-
if port not in gpr_grouped:
37-
gpr_grouped[port] = {}
38-
gpr_grouped[port][port_number] = gpr
39-
if match_gcr:
40-
gcr = {}
41-
gcr['number'] = int(match_gcr.group(1))
42-
gcr['value'] = int(match_gcr.group(2), 16)
43-
if gcr['number'] not in gcr_grouped:
44-
gcr_grouped[gcr['number']] = gcr
45-
46-
print("GPR:")
47-
for group in gpr_grouped:
48-
print(f"\n{group}: {gpr_grouped[group]}")
49-
print("\n\nGCR:")
50-
for group in gcr_grouped:
51-
print(f"\n{group}: {gcr_grouped[group]}")
78+
# converts a list of bit positions to a string defining setting the bits
79+
# using BIT() macro
80+
# e.g. [0, 2] -> "BIT(2) | BIT(0)"
81+
def bit_positions_to_macros(positions: list[int]) -> str:
82+
positions.sort(reverse=True)
83+
macros = [f"BIT({pos})" for pos in positions]
84+
macros_joined = " | ".join(macros)
85+
return macros_joined
86+
87+
# converts a dictionary of gpdr letter group
88+
# data to a list of bit positions
89+
# where the data is set to 1
90+
# e.g. {
91+
# 0: {'data': 1, (...)}
92+
# 1: {'data': 0, (...)}
93+
# 2: {'data': 1, (...)}
94+
# } -> [0,2]
95+
def gpdr_letter_group_data_to_bit_positions(gpdrs: dict) -> list[int]:
96+
bit_positions = []
97+
for number in gpdrs:
98+
if gpdrs[number]['data'] == 1:
99+
bit_positions.append(number)
100+
return bit_positions
101+
102+
# converts a dictionary of gcr values to a string
103+
# defining the gcr values in c using BIT() macro
104+
def gcr_grouped_to_c(gcr_grouped: dict) -> str:
105+
converted_output = "\n\n//GCR\n\n"
106+
for number in gcr_grouped:
107+
gcr = gcr_grouped[number]
108+
if gcr['value']:
109+
macros = bit_positions_to_macros(gcr['value'])
110+
converted_output += f"GCR{gcr['number']} = {macros};\n"
111+
else:
112+
converted_output += f"GCR{gcr['number']} = 0;\n"
113+
return converted_output
114+
115+
# converts a dictionary of gpr values to a string
116+
# defining the gpr values in c using BIT() macro
117+
# and GPCR values using GPIO defines
118+
def gpr_grouped_to_c(gpr_grouped: dict) -> str:
119+
converted_output = "\n\n//GPDR\n\n"
120+
for letter in gpr_grouped:
121+
data_value = ""
122+
bit_positions = gpdr_letter_group_data_to_bit_positions(gpr_grouped[letter])
123+
data_value = bit_positions_to_macros(bit_positions)
124+
if data_value == "":
125+
data_value = "0"
126+
converted_output += f"GPDR{letter} = {data_value};\n"
127+
converted_output += "\n\n//GPCR\n\n"
128+
for letter in gpr_grouped:
129+
for number in gpr_grouped[letter]:
130+
gpr = gpr_grouped[letter][number]
131+
macros = gpcr_control_bit_positions_to_c(gpr['control'])
132+
if macros != "":
133+
converted_output += f"GPCR{letter}{number} = {macros};\n"
134+
else:
135+
print(f"WARNING: GPR{letter}{number}: {gpr} undefined control value: {gpr['control']}")
136+
exit(1)
137+
return converted_output
138+
139+
args = sys.argv
140+
141+
def usage():
142+
print(f"Usage: {args[0]} <ecspy_log_file>")
143+
exit(1)
144+
145+
if __name__ == "__main__":
146+
if len(args) != 2:
147+
usage()
148+
ecspy_log = args[1]
149+
150+
try:
151+
lines = open(ecspy_log).readlines()
152+
except FileNotFoundError:
153+
print(f"File {ecspy_log} not found")
154+
exit(1)
155+
156+
gpr_grouped, gcr_grouped = parse_ecspy_log(lines)
157+
158+
# print("GPR:")
159+
# for group in gpr_grouped:
160+
# print(f"\n{group}: {gpr_grouped[group]}")
161+
# print("\n\nGCR:")
162+
# for group in gcr_grouped:
163+
# print(f"\n{group}: {gcr_grouped[group]}")
164+
165+
output = gcr_grouped_to_c(gcr_grouped)
166+
output += gpr_grouped_to_c(gpr_grouped)
52167

168+
print(output)

0 commit comments

Comments
 (0)