Blame view
tools/rkmux.py
5.96 KB
94b13bbae host-tools: use p... |
1 |
#!/usr/bin/env python2 |
002c634c1 rockchip: Add a s... |
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 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# Script to create enums from datasheet register tables # # Usage: # # First, create a text file from the datasheet: # pdftotext -layout /path/to/rockchip-3288-trm.pdf /tmp/asc # # Then use this script to output the #defines for a particular register: # ./tools/rkmux.py GRF_GPIO4C_IOMUX # # It will create output suitable for putting in a header file, with SHIFT and # MASK values for each bitfield in the register. # # Note: this tool is not perfect and you may need to edit the resulting code. # But it should speed up the process. import csv import re import sys tab_to_col = 3 class RegField: def __init__(self, cols=None): if cols: self.bits, self.attr, self.reset_val, self.desc = ( [x.strip() for x in cols]) self.desc = [self.desc] else: self.bits = '' self.attr = '' self.reset_val = '' self.desc = [] def Setup(self, cols): self.bits, self.attr, self.reset_val = cols[0:3] if len(cols) > 3: self.desc.append(cols[3]) def AddDesc(self, desc): self.desc.append(desc) def Show(self): print self print self.__init__() def __str__(self): return '%s,%s,%s,%s' % (self.bits, self.attr, self.reset_val, ' '.join(self.desc)) class Printer: def __init__(self, name): self.first = True self.name = name self.re_sel = re.compile("[1-9]'b([01]+): (.*)") def __enter__(self): return self def __exit__(self, type, value, traceback): if not self.first: self.output_footer() def output_header(self): print '/* %s */' % self.name print 'enum {' def output_footer(self): print '};'; def output_regfield(self, regfield): lines = regfield.desc field = lines[0] #print 'field:', field if field in ['reserved', 'reserve', 'write_enable', 'write_mask']: return if field.endswith('_sel') or field.endswith('_con'): field = field[:-4] elif field.endswith(' iomux'): field = field[:-6] elif field.endswith('_mode') or field.endswith('_mask'): field = field[:-5] #else: #print 'bad field %s' % field #return field = field.upper() if ':' in regfield.bits: bit_high, bit_low = [int(x) for x in regfield.bits.split(':')] else: bit_high = bit_low = int(regfield.bits) bit_width = bit_high - bit_low + 1 mask = (1 << bit_width) - 1 if self.first: self.first = False self.output_header() else: print out_enum(field, 'shift', bit_low) out_enum(field, 'mask', mask) next_val = -1 #print 'lines: %s', lines for line in lines: m = self.re_sel.match(line) if m: val, enum = int(m.group(1), 2), m.group(2) if enum not in ['reserved', 'reserve']: out_enum(field, enum, val, val == next_val) next_val = val + 1 def process_file(name, fd): field = RegField() reg = '' fields = [] def add_it(field): if field.bits: if reg == name: fields.append(field) field = RegField() return field def is_field_start(line): if '=' in line or '+' in line: return False if (line.startswith('gpio') or line.startswith('peri_') or line.endswith('_sel') or line.endswith('_con')): return True if not ' ' in line: # and '_' in line: return True return False for line in fd: line = line.rstrip() if line[:4] in ['GRF_', 'PMU_', 'CRU_']: field = add_it(field) reg = line do_this = name == reg elif not line or not line.startswith(' '): continue line = line.replace('\xe2\x80\x99', "'") leading = len(line) - len(line.lstrip()) line = line.lstrip() cols = re.split(' *', line, 3) if leading > 15 or (len(cols) > 3 and is_field_start(cols[3])): if is_field_start(line): field = add_it(field) field.AddDesc(line) else: if cols[0] == 'Bit' or len(cols) < 3: continue #print #print field field = add_it(field) field.Setup(cols) field = add_it(field) with Printer(name) as printer: for field in fields: #print field printer.output_regfield(field) #print def out_enum(field, suffix, value, skip_val=False): str = '%s_%s' % (field.upper(), suffix.upper()) if not skip_val: tabs = tab_to_col - len(str) / 8 if value > 9: val_str = '%#x' % value else: val_str = '%d' % value str += '%s= %s' % ('\t' * tabs, val_str) print '\t%s,' % str # Process a CSV file, e.g. from tabula def process_csv(name, fd): reader = csv.reader(fd) rows = [] field = RegField() for row in reader: #print field.desc if not row[0]: field.desc.append(row[3]) continue if field.bits: if field.bits != 'Bit': rows.append(field) #print row field = RegField(row) with Printer(name) as printer: for row in rows: #print field printer.output_regfield(row) #print fname = sys.argv[1] name = sys.argv[2] # Read output from pdftotext -layout if 1: with open(fname, 'r') as fd: process_file(name, fd) # Use tabula # It seems to be better at outputting text for an entire cell in one cell. # But it does not always work. E.g. GRF_GPIO7CH_IOMUX. # So there is no point in using it. if 0: with open(fname, 'r') as fd: process_csv(name, fd) |