3 # Script to create enums from datasheet register tables
7 # First, create a text file from the datasheet:
8 # pdftotext -layout /path/to/rockchip-3288-trm.pdf /tmp/asc
10 # Then use this script to output the #defines for a particular register:
11 # ./tools/rkmux.py GRF_GPIO4C_IOMUX
13 # It will create output suitable for putting in a header file, with SHIFT and
14 # MASK values for each bitfield in the register.
16 # Note: this tool is not perfect and you may need to edit the resulting code.
17 # But it should speed up the process.
26 def __init__(self, cols=None):
28 self.bits, self.attr, self.reset_val, self.desc = (
29 [x.strip() for x in cols])
30 self.desc = [self.desc]
37 def Setup(self, cols):
38 self.bits, self.attr, self.reset_val = cols[0:3]
40 self.desc.append(cols[3])
42 def AddDesc(self, desc):
43 self.desc.append(desc)
51 return '%s,%s,%s,%s' % (self.bits, self.attr, self.reset_val,
55 def __init__(self, name):
58 self.re_sel = re.compile("[1-9]'b([01]+): (.*)")
63 def __exit__(self, type, value, traceback):
67 def output_header(self):
68 print '/* %s */' % self.name
71 def output_footer(self):
74 def output_regfield(self, regfield):
77 #print 'field:', field
78 if field in ['reserved', 'reserve', 'write_enable', 'write_mask']:
80 if field.endswith('_sel') or field.endswith('_con'):
82 elif field.endswith(' iomux'):
84 elif field.endswith('_mode') or field.endswith('_mask'):
87 #print 'bad field %s' % field
90 if ':' in regfield.bits:
91 bit_high, bit_low = [int(x) for x in regfield.bits.split(':')]
93 bit_high = bit_low = int(regfield.bits)
94 bit_width = bit_high - bit_low + 1
95 mask = (1 << bit_width) - 1
101 out_enum(field, 'shift', bit_low)
102 out_enum(field, 'mask', mask)
104 #print 'lines: %s', lines
106 m = self.re_sel.match(line)
108 val, enum = int(m.group(1), 2), m.group(2)
109 if enum not in ['reserved', 'reserve']:
110 out_enum(field, enum, val, val == next_val)
114 def process_file(name, fd):
127 def is_field_start(line):
128 if '=' in line or '+' in line:
130 if (line.startswith('gpio') or line.startswith('peri_') or
131 line.endswith('_sel') or line.endswith('_con')):
133 if not ' ' in line: # and '_' in line:
139 if line[:4] in ['GRF_', 'PMU_', 'CRU_']:
140 field = add_it(field)
142 do_this = name == reg
143 elif not line or not line.startswith(' '):
145 line = line.replace('\xe2\x80\x99', "'")
146 leading = len(line) - len(line.lstrip())
148 cols = re.split(' *', line, 3)
149 if leading > 15 or (len(cols) > 3 and is_field_start(cols[3])):
150 if is_field_start(line):
151 field = add_it(field)
154 if cols[0] == 'Bit' or len(cols) < 3:
158 field = add_it(field)
160 field = add_it(field)
162 with Printer(name) as printer:
165 printer.output_regfield(field)
168 def out_enum(field, suffix, value, skip_val=False):
169 str = '%s_%s' % (field.upper(), suffix.upper())
171 tabs = tab_to_col - len(str) / 8
173 val_str = '%#x' % value
175 val_str = '%d' % value
177 str += '%s= %s' % ('\t' * tabs, val_str)
180 # Process a CSV file, e.g. from tabula
181 def process_csv(name, fd):
182 reader = csv.reader(fd)
190 field.desc.append(row[3])
193 if field.bits != 'Bit':
196 field = RegField(row)
198 with Printer(name) as printer:
201 printer.output_regfield(row)
207 # Read output from pdftotext -layout
209 with open(fname, 'r') as fd:
210 process_file(name, fd)
213 # It seems to be better at outputting text for an entire cell in one cell.
214 # But it does not always work. E.g. GRF_GPIO7CH_IOMUX.
215 # So there is no point in using it.
217 with open(fname, 'r') as fd:
218 process_csv(name, fd)