-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmipi-dbi-cmd
executable file
·143 lines (121 loc) · 4.32 KB
/
mipi-dbi-cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: CC0-1.0
#
# Written in 2022 by Noralf Trønnes <[email protected]>
#
# To the extent possible under law, the author(s) have dedicated all copyright and related and
# neighboring rights to this software to the public domain worldwide. This software is
# distributed without any warranty.
#
# You should have received a copy of the CC0 Public Domain Dedication along with this software.
# If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
from __future__ import print_function
import argparse
import sys
def hexstr(buf):
return ' '.join('{:02x}'.format(x) for x in buf)
def parse_binary(buf):
if len(buf) < 18:
raise ValueError('file too short, len=%d' % len(buf))
if buf[:15] != b'MIPI DBI\x00\x00\x00\x00\x00\x00\x00':
raise ValueError('wrong magic: %s' % hexstr(buf[:15]))
if buf[15] != 1:
raise ValueError('wrong version: %d' % (buf[15]))
result = ''
cmds = buf[16:]
i = 0
while i < len(cmds):
try:
pos = i
cmd = cmds[i]
i += 1
num_params = cmds[i]
i += 1
params = cmds[i:i+num_params]
if len(params) != num_params:
raise IndexError()
if cmd == 0x00 and num_params == 1:
s = 'delay %d\n' % params[0]
else:
s = 'command 0x%02x' % cmd
if params:
s += ' '
s += ' '.join('0x{:02x}'.format(x) for x in params)
s += '\n'
except IndexError:
raise ValueError('malformed file at offset %d: %s' % (pos + 16, hexstr(cmds[pos:])))
i += num_params
result += s
return result
def print_file(fn):
with open(args.fw_file, mode='rb') as f:
fw = f.read()
s = parse_binary(bytearray(fw))
print(s)
def parse_values(parts):
vals = []
for x in parts:
try:
val = int(x, 0)
except ValueError:
raise ValueError('not a number: %s' % x)
if val < 0 or val > 255:
raise ValueError('value out of bounds: %s (%d)' % (hex(val), val))
vals.append(val)
return vals
def make_file(fw_file, input_file):
with open(input_file, mode='r') as f:
lines = f.readlines()
buf = bytearray()
buf.extend(b'MIPI DBI\x00\x00\x00\x00\x00\x00\x00') # magic
buf.append(1) # version
for idx, line in enumerate(lines):
# strip off comments and skip empty lines
comment_idx = line.find('#')
if comment_idx >= 0:
line = line[:comment_idx]
line = line.strip()
if not line:
continue
try:
parts = line.split()
if parts[0] == 'command':
vals = parse_values(parts[1:])
buf.append(vals[0])
num_params = len(vals) - 1
buf.append(num_params)
if num_params:
buf.extend(vals[1:])
elif parts[0] == 'delay':
vals = parse_values(parts[1:])
if len(vals) != 1:
raise ValueError('delay takes exactly one argument')
buf.append(0x00)
buf.append(1)
buf.append(vals[0])
else:
raise ValueError('unknown keyword: %s' % parts[0])
except ValueError as e:
raise ValueError('error: %s\nline %d: %s' % (e, idx + 1, line))
with open(fw_file, mode='wb') as f:
f.write(buf)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='MIPI DBI Linux driver firmware tool')
parser.add_argument('fw_file', help='firmware binary file')
parser.add_argument('input', nargs='?', help='Input commands file')
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
parser.add_argument('-d', '--debug', action='store_true', help='Print exception callstack')
args = parser.parse_args()
try:
if args.input:
make_file(args.fw_file, args.input)
if args.verbose:
print_file(args.fw_file)
else:
print_file(args.fw_file)
except Exception as e:
if args.debug:
raise
print(e, file=sys.stderr)
sys.exit(1)