use space-indentor function
[pinmux.git] / src / bsv / peripheral_gen / base.py
1 import types
2
3 def li(txt, indent):
4 indent = ' ' * indent
5 istxt = False
6 if isinstance(txt, str):
7 istxt = True
8 txt = txt.split('\n')
9 res = []
10 for line in txt:
11 line = line.split('\n')
12 res += line
13 txt = res
14 res = []
15 for line in txt:
16 res.append(indent + line)
17 if istxt:
18 res = '\n'.join(res)
19 return res
20
21
22 class PBase(object):
23 def __init__(self, name):
24 self.name = name
25
26 def extifdecl(self, name, count):
27 sname = self.get_iname(count)
28 return "interface PeripheralSide%s %s;" % (name.upper(), sname)
29
30 def has_axi_master(self):
31 return False
32
33 def irq_name(self):
34 return ""
35
36 def mk_dma_irq(self, name, count):
37 if not self.irq_name():
38 return ''
39 sname = self.get_iname(count)
40 return "{0}_interrupt".format(sname)
41
42 def mk_dma_rule(self, name, count):
43 irqname = self.mk_dma_irq(name, count)
44 if not irqname:
45 return ''
46 pirqname = self.irq_name().format(count)
47 template = " {0}_interrupt.send(\n" + \
48 " slow_peripherals.{1});"
49 return template.format(irqname, pirqname)
50
51 def get_clock_reset(self, name, count):
52 return "slow_clock,slow_reset"
53
54 def mk_dma_sync(self, name, count):
55 irqname = self.mk_dma_irq(name, count)
56 if not irqname:
57 return ''
58 sname = self.peripheral.iname().format(count)
59 template = "SyncBitIfc#(Bit#(1)) {0} <-\n" + \
60 " <-mkSyncBitToCC({1});"
61 return template.format(irqname, self.get_clock_reset(name, count))
62
63 def mk_dma_connect(self, name, count):
64 irqname = self.mk_dma_irq(name, count)
65 if not irqname:
66 return ''
67 return "{0}.read".format(irqname)
68
69 def fastifdecl(self, name, count):
70 return ''
71
72 def slowifdeclmux(self, name, count):
73 return ''
74
75 def slowimport(self):
76 return ''
77
78 def num_axi_regs32(self):
79 return 0
80
81 def slowifdecl(self):
82 return ''
83
84 def get_iname(self, inum):
85 return "{0}{1}".format(self.name, self.mksuffix(self.name, inum))
86
87 def axibase(self, name, ifacenum):
88 name = name.upper()
89 return "%(name)s%(ifacenum)dBase" % locals()
90
91 def axiend(self, name, ifacenum):
92 name = name.upper()
93 return "%(name)s%(ifacenum)dEnd" % locals()
94
95 def axi_reg_def(self, start, name, ifacenum):
96 name = name.upper()
97 offs = self.num_axi_regs32() * 4 * 16
98 if offs == 0:
99 return ('', 0)
100 end = start + offs - 1
101 bname = self.axibase(name, ifacenum)
102 bend = self.axiend(name, ifacenum)
103 comment = "%d 32-bit regs" % self.num_axi_regs32()
104 return (" `define %(bname)s 'h%(start)08X\n"
105 " `define %(bend)s 'h%(end)08X // %(comment)s" % locals(),
106 offs)
107
108 def axi_master_name(self, name, ifacenum, typ=''):
109 name = name.upper()
110 return "{0}{1}_master_num".format(name, ifacenum)
111
112 def axi_slave_name(self, name, ifacenum, typ=''):
113 name = name.upper()
114 return "{0}{1}_{2}slave_num".format(name, ifacenum, typ)
115
116 def axi_master_idx(self, idx, name, ifacenum, typ):
117 name = self.axi_master_name(name, ifacenum, typ)
118 return ("typedef {0} {1};".format(idx, name), 1)
119
120 def axi_slave_idx(self, idx, name, ifacenum, typ):
121 name = self.axi_slave_name(name, ifacenum, typ)
122 return ("typedef {0} {1};".format(idx, name), 1)
123
124 def axi_addr_map(self, name, ifacenum):
125 bname = self.axibase(name, ifacenum)
126 bend = self.axiend(name, ifacenum)
127 name = self.axi_slave_name(name, ifacenum)
128 return """\
129 if(addr>=`{0} && addr<=`{1})
130 return tuple2(True,fromInteger(valueOf({2})));
131 else""".format(bname, bend, name)
132
133 def mk_pincon(self, name, count):
134 # TODO: really should be using bsv.interface_decl.Interfaces
135 # pin-naming rules.... logic here is hard-coded to duplicate
136 # it (see Interface.__init__ outen)
137 ret = []
138 for p in self.peripheral.pinspecs:
139 typ = p['type']
140 pname = p['name']
141 #n = "{0}{1}".format(self.name, self.mksuffix(name, count))
142 n = name # "{0}{1}".format(self.name, self.mksuffix(name, count))
143 ret.append(" //%s %s" % (n, str(p)))
144 sname = self.peripheral.iname().format(count)
145 sname = "{0}.{1}".format(sname, pname)
146 ps = "pinmux.peripheral_side.%s" % sname
147 if typ == 'out' or typ == 'inout':
148 fname = self.pinname_out(pname)
149 if not n.startswith('gpio'): # XXX EURGH! horrible hack
150 n_ = "{0}{1}".format(n, count)
151 else:
152 n_ = n
153 if fname:
154 if p.get('outen'):
155 ps_ = ps + '_out'
156 else:
157 ps_ = ps
158 ret.append("mkConnection({0},\n\t\t\t{1}.{2});"
159 .format(ps_, n_, fname))
160 fname = None
161 if p.get('outen'):
162 fname = self.pinname_outen(pname)
163 if fname:
164 if isinstance(fname, str):
165 fname = "{0}.{1}".format(n_, fname)
166 fname = self.pinname_tweak(pname, 'outen', fname)
167 ret.append("mkConnection({0}_outen,\n\t\t\t{1});"
168 .format(ps, fname))
169 if typ == 'in' or typ == 'inout':
170 fname = self.pinname_in(pname)
171 if fname:
172 if p.get('outen'):
173 ps_ = ps + '_in'
174 else:
175 ps_ = ps
176 n_ = "{0}{1}".format(n, count)
177 n_ = '{0}.{1}'.format(n_, fname)
178 n_ = self.ifname_tweak(pname, 'in', n_)
179 ret.append("mkConnection({1}, {0});".format(ps_, n_))
180 return '\n'.join(li(ret, 6))
181
182 def mk_cellconn(self, *args):
183 return ''
184
185 def mkfast_peripheral(self, size=0):
186 return ''
187
188 def mkslow_peripheral(self, size=0):
189 return ''
190
191 def mksuffix(self, name, i):
192 return i
193
194 def __mk_connection(self, con, aname, fabricname):
195 txt = "mkConnection ({2}.v_to_slaves\n" + \
196 " [fromInteger(valueOf({1}))],\n" + \
197 " {0});"
198
199 print "PBase __mk_connection", self.name, aname
200 if not con:
201 return ''
202 return li(txt.format(con, aname, fabricname), 8)
203
204 def __mk_master_connection(self, con, aname):
205 txt = "mkConnection (slow_fabric.v_to_slaves\n" + \
206 " [fromInteger(valueOf({1}))],\n" + \
207 " {0});"
208
209 print "PBase __mk_connection", self.name, aname
210 if not con:
211 return ''
212 return li(txt.format(con, aname), 8)
213
214 def mk_connection(self, count, fabricname, typ, name=None):
215 if name is None:
216 name = self.name
217 print "PBase mk_conn", self.name, count
218 aname = self.axi_slave_name(name, count, typ)
219 #dname = self.mksuffix(name, count)
220 #dname = "{0}{1}".format(name, dname)
221 con = self._mk_connection(name, count).format(count, aname)
222 return self.__mk_connection(con, aname, fabricname)
223
224 def _mk_connection(self, name=None, count=0):
225 return ''
226
227 def pinname_out(self, pname):
228 return ''
229
230 def pinname_in(self, pname):
231 return ''
232
233 def pinname_outen(self, pname):
234 return ''
235
236 def ifname_tweak(self, pname, typ, txt):
237 return txt
238
239 def pinname_tweak(self, pname, typ, txt):
240 return txt
241
242 def num_irqs(self):
243 return 0
244
245 def mk_plic(self, inum, irq_offs):
246 res = []
247 print "mk_plic", self.name, inum, irq_offs
248 niq = self.num_irqs()
249 if niq == 0:
250 return ('', irq_offs)
251 name = self.get_iname(inum)
252 res.append("// PLIC rules for {0}".format(name))
253 for idx in range(niq):
254 plic_obj = self.plic_object(name, idx)
255 print "plic_obj", name, idx, plic_obj
256 plic = mkplic_rule.format(name, plic_obj, irq_offs)
257 res.append(plic)
258 irq_offs += 1 # increment to next irq
259 return ('\n'.join(li(res, 5)), irq_offs)
260
261 def mk_ext_ifacedef(self, iname, inum):
262 return ''
263
264 def extfastifinstance(self, name, count):
265 return ''
266
267 def _extifinstance(self, name, count, suffix, prefix, samename=False):
268 pname = self.get_iname(count)
269 if samename:
270 sname = pname
271 else:
272 sname = self.peripheral.iname().format(count)
273 template = " interface {0}{3} = {2}{1};"
274 return template.format(pname, sname, prefix, suffix)
275
276 def extifinstance(self, name, count):
277 return self._extifinstance(name, count, "",
278 "pinmux.peripheral_side.")
279
280
281 mkplic_rule = """\
282 rule rl_connect_{0}_to_plic_{2};
283 if({1} == 1'b1) begin
284 ff_gateway_queue[{2}].enq(1);
285 plic.ifc_external_irq[{2}].irq_frm_gateway(True);
286 end
287 endrule
288 """
289
290 axi_master_declarations= """\
291 typedef 0 Dmem_master_num;
292 typedef 1 Imem_master_num;
293 {0}
294 typedef TAdd#(LastGen_master_num, `ifdef Debug 1 `else 0 `endif )
295 Debug_master_num;
296 typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif )
297 DMA_master_num;
298 typedef TAdd#(DMA_master_num,1)
299 Num_Masters;
300 """
301
302 axi_fastslave_declarations = """\
303 {0}
304 typedef TAdd#(LastGen_fastslave_num,1) Sdram_cfg_slave_num;
305 typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif )
306 Sdram_cfg_slave_num;
307 typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif )
308 BootRom_slave_num ;
309 typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif )
310 Debug_slave_num ;
311 typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif )
312 TCM_slave_num;
313 typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif )
314 Dma_slave_num;
315 typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
316 typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif )
317 VME_slave_num;
318 typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif )
319 FlexBus_slave_num;
320 typedef TAdd#(FlexBus_slave_num,1)
321 Num_Slaves;
322
323 """
324
325 axi_slave_declarations = """\
326 typedef 0 SlowMaster;
327 {0}
328 typedef TAdd#(LastGen_slave_num,`ifdef CLINT 1 `else 0 `endif )
329 CLINT_slave_num;
330 typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
331 Plic_slave_num;
332 typedef TAdd#(Plic_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
333 AxiExp1_slave_num;
334 typedef TAdd#(AxiExp1_slave_num,1) Num_Slow_Slaves;
335 """
336
337 pinmux_cellrule = """\
338 rule connect_select_lines_pinmux;
339 {0}
340 endrule
341 """
342
343
344 class CallFn(object):
345 def __init__(self, peripheral, name):
346 self.peripheral = peripheral
347 self.name = name
348
349 def __call__(self, *args):
350 #print "__call__", self.name, self.peripheral.slow, args
351 if not self.peripheral.slow:
352 return ''
353 return getattr(self.peripheral.slow, self.name)(*args[1:])
354
355
356 class PeripheralIface(object):
357 def __init__(self, ifacename):
358 self.slow = None
359 slow = slowfactory.getcls(ifacename)
360 print "Iface", ifacename, slow
361 if slow:
362 self.slow = slow(ifacename)
363 self.slow.peripheral = self
364 for fname in ['slowimport',
365 'extfastifinstance', 'extifinstance', 'extifdecl',
366 'slowifdecl', 'slowifdeclmux',
367 'fastifdecl',
368 'mkslow_peripheral',
369 'mk_dma_sync', 'mk_dma_connect', 'mk_dma_rule',
370 'mkfast_peripheral',
371 'mk_plic', 'mk_ext_ifacedef',
372 'mk_connection', 'mk_cellconn', 'mk_pincon']:
373 fn = CallFn(self, fname)
374 setattr(self, fname, types.MethodType(fn, self))
375
376 #print "PeripheralIface"
377 #print dir(self)
378
379 def mksuffix(self, name, i):
380 if self.slow is None:
381 return i
382 return self.slow.mksuffix(name, i)
383
384 def axi_reg_def(self, start, count):
385 if not self.slow:
386 return ('', 0)
387 return self.slow.axi_reg_def(start, self.ifacename, count)
388
389 def axi_master_idx(self, start, count, typ):
390 if not self.slow or not self.slow.has_axi_master():
391 return ('', 0)
392 return self.slow.axi_master_idx(start, self.ifacename, count, typ)
393
394 def axi_slave_idx(self, start, count, typ):
395 if not self.slow:
396 return ('', 0)
397 return self.slow.axi_slave_idx(start, self.ifacename, count, typ)
398
399 def axi_addr_map(self, count):
400 if not self.slow:
401 return ''
402 return self.slow.axi_addr_map(self.ifacename, count)
403
404
405 class PeripheralInterfaces(object):
406 def __init__(self):
407 self.fastbusmode = False
408
409 def slowimport(self, *args):
410 ret = []
411 for (name, count) in self.ifacecount:
412 #print "slowimport", name, self.data[name].slowimport
413 ret.append(self.data[name].slowimport())
414 return '\n'.join(list(filter(None, ret)))
415
416 def extfastifinstance(self, *args):
417 ret = []
418 for (name, count) in self.ifacecount:
419 for i in range(count):
420 iname = self.data[name].iname().format(i)
421 print "extfast", iname, self.is_on_fastbus(name, i)
422 if self.is_on_fastbus(name, i):
423 continue
424 ret.append(self.data[name].extfastifinstance(name, i))
425 return '\n'.join(list(filter(None, ret)))
426
427 def extifinstance(self, *args):
428 ret = []
429 for (name, count) in self.ifacecount:
430 for i in range(count):
431 iname = self.data[name].iname().format(i)
432 if not self.is_on_fastbus(name, i):
433 continue
434 ret.append(self.data[name].extifinstance(name, i))
435 return '\n'.join(list(filter(None, ret)))
436
437 def extifdecl(self, *args):
438 ret = []
439 for (name, count) in self.ifacecount:
440 for i in range(count):
441 if not self.is_on_fastbus(name, i):
442 continue
443 ret.append(self.data[name].extifdecl(name, i))
444 return '\n'.join(li(list(filter(None, ret)), 8))
445
446 def slowifdeclmux(self, *args):
447 ret = []
448 for (name, count) in self.ifacecount:
449 for i in range(count):
450 ret.append(self.data[name].slowifdeclmux(name, i))
451 return '\n'.join(list(filter(None, ret)))
452
453 def fastifdecl(self, *args):
454 ret = []
455 for (name, count) in self.ifacecount:
456 for i in range(count):
457 print "fastifdecl", name, i, self.is_on_fastbus(name, i)
458 if self.is_on_fastbus(name, i):
459 continue
460 ret.append(self.data[name].fastifdecl(name, i))
461 return '\n'.join(list(filter(None, ret)))
462
463 def slowifdecl(self, *args):
464 ret = []
465 for (name, count) in self.ifacecount:
466 for i in range(count):
467 if self.is_on_fastbus(name, i):
468 continue
469 ret.append(self.data[name].slowifdecl().format(i, name))
470 return '\n'.join(list(filter(None, ret)))
471
472 def axi_reg_def(self, *args):
473 ret = []
474 start = 0x00011100 # start of AXI peripherals address
475 for (name, count) in self.ifacecount:
476 for i in range(count):
477 if self.is_on_fastbus(name, i):
478 continue
479 x = self.data[name].axi_reg_def(start, i)
480 #print ("ifc", name, x)
481 (rdef, offs) = x
482 ret.append(rdef)
483 start += offs
484 return '\n'.join(list(filter(None, ret)))
485
486 def _axi_num_idx(self, start, template, typ, idxtype, *args):
487 ret = []
488 for (name, count) in self.ifacecount:
489 for i in range(count):
490 if self.is_on_fastbus(name, i):
491 continue
492 if typ == 'master':
493 fn = self.data[name].axi_master_idx
494 else:
495 fn = self.data[name].axi_slave_idx
496 (rdef, offs) = fn(start, i, idxtype)
497 #print ("ifc", name, rdef, offs)
498 ret.append(rdef)
499 start += offs
500 ret.append("typedef %d LastGen_%s_num;" % (start - 1, typ))
501 decls = '\n'.join(list(filter(None, ret)))
502 return template.format(decls)
503
504 def axi_slave_idx(self, *args):
505 return self._axi_num_idx(0, axi_slave_declarations, 'slave',
506 '', *args)
507
508 def axi_fastslave_idx(self, *args):
509 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
510 'fast', *args)
511
512 def axi_master_idx(self, *args):
513 return self._axi_num_idx(2, axi_master_declarations, 'master',
514 'master', *args)
515
516 def axi_fastslave_idx(self, *args):
517 return self._axi_num_idx(0, axi_fastslave_declarations, 'fastslave',
518 'fast', *args)
519
520 def axi_addr_map(self, *args):
521 ret = []
522 for (name, count) in self.ifacecount:
523 for i in range(count):
524 if self.is_on_fastbus(name, i):
525 continue
526 ret.append(self.data[name].axi_addr_map(i))
527 return '\n'.join(list(filter(None, ret)))
528
529 def mkfast_peripheral(self, *args):
530 ret = []
531 for (name, count) in self.ifacecount:
532 for i in range(count):
533 if self.is_on_fastbus(name, i):
534 continue
535 #print "mkfast", name, count
536 x = self.data[name].mkfast_peripheral()
537 print name, count, x
538 suffix = self.data[name].mksuffix(name, i)
539 ret.append(x.format(suffix))
540 return '\n'.join(list(filter(None, ret)))
541
542 def mkslow_peripheral(self, *args):
543 ret = []
544 for (name, count) in self.ifacecount:
545 for i in range(count):
546 if self.is_on_fastbus(name, i):
547 continue
548 #print "mkslow", name, count
549 x = self.data[name].mkslow_peripheral()
550 print name, count, x
551 suffix = self.data[name].mksuffix(name, i)
552 ret.append(x.format(suffix))
553 return '\n'.join(list(filter(None, ret)))
554
555 def mk_fast_connection(self, *args):
556 ret = []
557 for (name, count) in self.ifacecount:
558 for i in range(count):
559 if self.is_on_fastbus(name, i):
560 continue
561 txt = self.data[name].mk_connection(i, "fabric", "fast")
562 if name == 'gpioa':
563 print "txt", txt
564 print self.data[name].mk_connection
565 ret.append(txt)
566 return '\n'.join(list(filter(None, ret)))
567
568 def mk_connection(self, *args):
569 ret = []
570 for (name, count) in self.ifacecount:
571 for i in range(count):
572 if self.is_on_fastbus(name, i):
573 continue
574 txt = self.data[name].mk_connection(i, "slow_fabric", "")
575 if name == 'gpioa':
576 print "txt", txt
577 print self.data[name].mk_connection
578 ret.append(txt)
579 return '\n'.join(list(filter(None, ret)))
580
581 def mk_cellconn(self):
582 ret = []
583 cellcount = 0
584 for (name, count) in self.ifacecount:
585 for i in range(count):
586 if self.is_on_fastbus(name, i):
587 continue
588 res = self.data[name].mk_cellconn(cellcount, name, i)
589 if not res:
590 continue
591 (txt, cellcount) = res
592 ret.append(txt)
593 ret = '\n'.join(list(filter(None, ret)))
594 return pinmux_cellrule.format(ret)
595
596 def mk_pincon(self):
597 ret = []
598 for (name, count) in self.ifacecount:
599 for i in range(count):
600 if self.is_on_fastbus(name, i):
601 continue
602 txt = self.data[name].mk_pincon(name, i)
603 ret.append(txt)
604 return '\n'.join(list(filter(None, ret)))
605
606 def mk_dma_irq(self):
607 ret = []
608 sync = []
609 rules = []
610 cnct = []
611
612 self.dma_count = 0
613
614 for (name, count) in self.ifacecount:
615 ifacerules = []
616 for i in range(count):
617 if not self.is_on_fastbus(name, i):
618 continue
619 txt = self.data[name].mk_dma_sync(name, i)
620 if txt:
621 self.dma_count += 1
622 sync.append(txt)
623 txt = self.data[name].mk_dma_rule(name, i)
624 ifacerules.append(txt)
625 txt = self.data[name].mk_dma_connect(name, i)
626 cnct.append(txt)
627 ifacerules = list(filter(None, ifacerules))
628 if ifacerules:
629 txt = "rule synchronize_%s_interrupts;" % name
630 rules.append(txt)
631 rules += ifacerules
632 rules.append("endrule")
633
634 cnct = list(filter(None, cnct))
635 ct = self.dma_count
636 _cnct = ["rule rl_connect_interrupt_to_DMA;",
637 " Bit #(%d) lv_interrupt_to_DMA={" % ct]
638 spc = " "
639 spcsep = ",\n" + spc
640 cnct = _cnct + [spc + spcsep.join(cnct)]
641 cnct.append(" };")
642 cnct.append(" dma.interrupt_from_peripherals(\n" + \
643 " lv_interrupt_to_DMA);")
644 cnct.append("endrule;")
645
646 ret = list(filter(None, sync + rules + cnct))
647 ret = li(ret, 15)
648 return '\n'.join(ret)
649
650 def num_dmachannels(self):
651 return "`define NUM_DMACHANNELS {0}".format(self.dma_count)
652
653 def mk_ext_ifacedef(self):
654 ret = []
655 for (name, count) in self.ifacecount:
656 for i in range(count):
657 if self.is_on_fastbus(name, i):
658 continue
659 txt = self.data[name].mk_ext_ifacedef(name, i)
660 ret.append(txt)
661 return '\n'.join(list(filter(None, ret)))
662
663 def mk_plic(self):
664 ret = []
665 irq_offs = 8 # XXX: DMA scovers 0-7?
666 for (name, count) in self.ifacecount:
667 for i in range(count):
668 if self.is_on_fastbus(name, i):
669 continue
670 res = self.data[name].mk_plic(i, irq_offs)
671 if not res:
672 continue
673 (txt, irq_offs) = res
674 ret.append(txt)
675 self.num_slow_irqs = irq_offs
676 return '\n'.join(list(filter(None, ret)))
677
678 def mk_sloirqsdef(self):
679 return " `define NUM_SLOW_IRQS {0}".format(self.num_slow_irqs)
680
681 def is_on_fastbus(self, name, i):
682 #print "fastbus mode", self.fastbusmode, name, i
683 iname = self.data[name].iname().format(i)
684 if self.fastbusmode:
685 return iname not in self.fastbus
686 return iname in self.fastbus
687
688
689 class PFactory(object):
690 def getcls(self, name):
691 from uart import uart
692 from quart import quart
693 from sdmmc import sdmmc
694 from pwm import pwm
695 from eint import eint
696 from rs232 import rs232
697 from twi import twi
698 from eint import eint
699 from jtag import jtag
700 from spi import spi, mspi
701 from qspi import qspi, mqspi
702 from gpio import gpio
703 from rgbttl import rgbttl
704
705 for k, v in {'uart': uart,
706 'rs232': rs232,
707 'twi': twi,
708 'quart': quart,
709 'mqspi': mqspi,
710 'mspi': mspi,
711 'qspi': qspi,
712 'spi': spi,
713 'pwm': pwm,
714 'eint': eint,
715 'sd': sdmmc,
716 'jtag': jtag,
717 'lcd': rgbttl,
718 'gpio': gpio
719 }.items():
720 if name.startswith(k):
721 return v
722 return None
723
724
725 slowfactory = PFactory()
726
727 if __name__ == '__main__':
728 p = uart('uart')
729 print p.slowimport()
730 print p.slowifdecl()
731 i = PeripheralIface('uart')
732 print i, i.slow
733 i = PeripheralIface('gpioa')
734 print i, i.slow