tourel beacon
[aversive.git] / config / gen_headers / gen_regs.py
1 #!/usr/bin/python
2
3 import xml.parsers.expat
4 import sys, re
5
6 not_a_register=["IO_START_ADDR",
7                 "IO_STOP_ADDR",
8                 "EXT_IO_START_ADDR",
9                 "EXT_IO_STOP_ADDR",
10                 "MEM_START_ADDR",
11                 "MEM_STOP_ADDR",
12                 ]
13 curtree=[]
14 curattrtree=[]
15
16
17 ##### timer prescalers
18
19 prescaler_timer_num = -1
20 prescaler_timers = {}
21
22 def prescaler_module():
23     global prescaler_timer_num
24     global prescaler_timers
25
26     if curtree[-1] != "module":
27         return
28     if not curattrtree[-1].has_key("class"):
29         return
30     if not curattrtree[-1]["class"].startswith("TIMER_COUNTER"):
31         return
32     prescaler_timer_num = int(curattrtree[-1]["class"].replace("TIMER_COUNTER_", ""))
33     prescaler_timers[prescaler_timer_num] = []
34
35 def prescaler_clk():
36     global prescaler_timer_num
37     global prescaler_timers
38
39     if curtree[-3:] != ["module", "enumerator", "enum"]:
40         return
41     if not curattrtree[-2].has_key("name"):
42         return
43     if not curattrtree[-2]["name"].startswith("CLK_SEL_"):
44         return
45     if not curattrtree[-3].has_key("class"):
46         return
47     if not curattrtree[-3]["class"].startswith("TIMER_COUNTER"):
48         return
49     val = int(curattrtree[-1]["val"], 16)
50     text = curattrtree[-1]["text"]
51     if text == "No Clock Source (Stopped)":
52         prescaler = 0
53     elif text == "Running, No Prescaling":
54         prescaler = 1
55     elif text.startswith("Running, CLK/"):
56         prescaler = int(text.split("/")[1])
57     elif text == "Running, ExtClk Tx Falling Edge":
58         prescaler = -1
59     elif text == "Running, ExtClk Tx Rising Edge":
60         prescaler = -2
61     else:
62         prescaler = -3
63     prescaler_timers[prescaler_timer_num].append((val,prescaler))
64
65 def prescaler_module_end():
66     global prescaler_timer_num
67     global prescaler_timers
68     
69     if curtree[-1] != "module":
70         return
71     if prescaler_timer_num == -1:
72         return
73     prescaler_timer_num = -1
74
75 def prescaler_print():
76     global prescaler_timers
77     keys = prescaler_timers.keys()
78     keys.sort()
79     for k in keys:
80         print "/* prescalers timer %d */"%(k)
81         for p in prescaler_timers[k]:
82             if p[1] == -1:
83                 txt = "FALL"
84             elif p[1] == -2:
85                 txt = "RISE"
86             else:
87                 txt = str(p[1])
88             txt = "#define TIMER%d_PRESCALER_DIV_%s"%(k, txt)
89             txt = txt.ljust(40)
90             print "%s%d"%(txt, p[0])
91         print
92         for p in prescaler_timers[k]:
93             txt = "#define TIMER%d_PRESCALER_REG_%d"%(k, p[0])
94             txt = txt.ljust(40)
95             print "%s%d"%(txt, p[1])
96         print
97     print
98
99 #####
100
101 # timer intrp 
102
103 timer_dict={}
104 sigtimer_OV_dict={}
105 sigtimer_OC_dict={}
106 sigtimer_IC_dict={}
107
108 def timer_intrp(data):
109     if len(curtree) <= 3:
110         return
111     if curtree[-1] != "SOURCE":
112         return
113     if not curtree[-2].startswith("VECTOR"):
114         return
115     if not data.startswith("TIMER"):
116         return
117     timernum = re.sub("TIMER([0-9]).*", r"\1", data)
118     subtimernum=re.sub("TIMER[0-9].*COMP([A-C])", r"\1", data)
119     if len(subtimernum) != 1:
120         subtimernum=""
121     timerid = timernum+subtimernum
122     if data.find("OVF") != -1:
123         timer_dict[timerid] = 1
124         sigtimer_OV_dict[timerid] = 1
125     elif data.find("COMP") != -1:
126         timer_dict[timerid] = 1
127         sigtimer_OC_dict[timerid] = 1
128     elif data.find("CAPT") != -1:
129         timer_dict[timerid] = 1
130         sigtimer_IC_dict[timerid] = 1
131
132 def timer_intrp_print():
133     l=timer_dict.keys()
134     l.sort()
135     print "/* available timers */"
136     for k in l:
137         print "#define TIMER%s_AVAILABLE"%k
138     print
139
140     l=sigtimer_OV_dict.keys()
141     l.sort()
142     i=0
143     print "/* overflow interrupt number */"
144     for k in l:
145         print "#define SIG_OVERFLOW%s_NUM %d"%(k,i)
146         i+=1
147     print "#define SIG_OVERFLOW_TOTAL_NUM %d"%i
148     print
149     
150     l=sigtimer_OC_dict.keys()
151     l.sort()
152     i=0
153     print "/* output compare interrupt number */"
154     for k in l:
155         print "#define SIG_OUTPUT_COMPARE%s_NUM %d"%(k,i)
156         i+=1
157     print "#define SIG_OUTPUT_COMPARE_TOTAL_NUM %d"%i
158     print
159     
160     i=0
161     print "/* Pwm nums */"
162     for k in l:
163         print "#define PWM%s_NUM %d"%(k,i)
164         i+=1
165     print "#define PWM_TOTAL_NUM %d"%i
166     print
167     
168     l=sigtimer_IC_dict.keys()
169     l.sort()
170     i=0
171     print "/* input capture interrupt number */"
172     for k in l:
173         print "#define SIG_INPUT_CAPTURE%s_NUM %d"%(k,i)
174         i+=1
175     print "#define SIG_INPUT_CAPTURE_TOTAL_NUM %d"%i
176     print
177
178
179 #####
180
181 # regs
182 bits={}
183 regs={}
184
185 def regs_parse():
186     if len(curtree) <= 3:
187         return 
188     if curtree[-1].find("_MASK") == -1:
189         return
190     if curtree[-3] != "IO_MEMORY":
191         return
192     bitname = curtree[-1].replace("_MASK", "_REG")
193     bitname = bitname.replace("-", "_")
194
195     if bits.has_key(bitname) == False:
196         bits[bitname]=[]
197     bits[bitname].append(curtree[-2])
198
199     if regs.has_key(curtree[-2])==False:
200         regs[curtree[-2]]=[]
201     regs[curtree[-2]].append(bitname)
202
203 def regs_print():
204     for r in regs.keys():
205         print 
206         print "/* %s */"%r
207         for b in regs[r]:
208             if len(bits[b]) != 1:
209                 reglist = bits[b][:]
210                 reglist.remove(r)
211                 regliststr = reduce(lambda x, y: x+", "+y, reglist)
212                 print "/* #define %s %s%s */ /* dup in %s */"%(b, " "*(20-len(b)), r, regliststr)
213             else:
214                 print "#define %s %s%s"%(b, " "*(20-len(b)), r)
215     print
216     
217 #####
218
219 # pins
220
221 alt_name = None
222 pin_name = None
223 pins_dict = {}
224
225 def pins_parse(data):
226     global alt_name, pin_name
227
228     if len(curtree) < 4:
229         return
230     if curtree[-1] not in [ "NAME", "ALT_NAME", "PIN_NAME" ]:
231         return
232     if not curtree[-2].startswith("PIN"):
233         return
234     if curtree[-4] != "PACKAGE":
235         return
236     pins = data[1:-1].split(":")
237     if curtree[-1] == "NAME":
238         alt_name = pins[0]
239         pin_name = pins[1:]
240     elif curtree[-1] == "ALT_NAME":
241         alt_name = pins[0]
242     elif curtree[-1] == "PIN_NAME":
243         pin_name = pins
244
245 def pins_end():
246     global alt_name, pin_name
247
248     if len(curtree) < 3:
249         return
250     if not curtree[-1].startswith("PIN"):
251         return
252     if curtree[-3] != "PACKAGE":
253         return
254     if alt_name != None and re.match("P[A-Z][0-7]", alt_name):
255         pins_dict[alt_name[1:]] = pin_name
256     alt_name = None
257     pin_name = None
258
259 def pins_print():
260     keys = pins_dict.keys()
261     keys.sort()
262     print "/* pins mapping */"
263     for k in keys:
264         for p in pins_dict[k]:
265             p = p.replace("'", "")
266             print "#define %s_PORT PORT%s"%(p, k[0])
267             print "#define %s_BIT %s"%(p, k[1])
268         print
269     print
270
271 #####
272
273 def start_element(name, attrs):
274     global state, curtree, sigtimer_list, not_a_register, bits, regs
275
276     curtree.append(name)
277     curattrtree.append(attrs)
278
279     prescaler_module()
280     prescaler_clk()
281
282     regs_parse()
283     
284         
285 def end_element(name):
286     global state, curtree, sigtimer_list, not_a_register
287
288     prescaler_module_end()
289     pins_end()
290
291     curtree.pop()
292     curattrtree.pop()
293
294
295 def char_data(data):
296     timer_intrp(data)
297     pins_parse(data)
298
299
300 print """/*  
301  *  Copyright Droids Corporation, Microb Technology, Eirbot (2009)
302  * 
303  *  This program is free software; you can redistribute it and/or modify
304  *  it under the terms of the GNU General Public License as published by
305  *  the Free Software Foundation; either version 2 of the License, or
306  *  (at your option) any later version.
307  *
308  *  This program is distributed in the hope that it will be useful,
309  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
310  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
311  *  GNU General Public License for more details.
312  *
313  *  You should have received a copy of the GNU General Public License
314  *  along with this program; if not, write to the Free Software
315  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
316  *
317  *  Revision : $Id $
318  *
319  */
320
321 /* WARNING : this file is automatically generated by scripts.
322  * You should not edit it. If you find something wrong in it,
323  * write to zer0@droids-corp.org */
324
325 """
326
327 p = xml.parsers.expat.ParserCreate()
328
329 p.StartElementHandler = start_element
330 p.EndElementHandler = end_element
331 p.CharacterDataHandler = char_data
332
333 f=open(sys.argv[1])
334 p.Parse(f.read(), 1)
335
336 prescaler_print()
337 timer_intrp_print()
338 regs_print()
339 pins_print()
340
341 f.close()