3 from copy
import deepcopy
4 from collections
import OrderedDict
9 cwd
= os
.path
.split(os
.path
.abspath(__file__
))[0]
10 lead_drawing
= cwd
+ "/greatek_qfp_128L.png"
11 pack_drawing
= cwd
+ "/greatek_qfp_128_fp.png"
12 c4m_drawing
= cwd
+ "/c4mlogo.png"
13 ls180_drawing
= cwd
+ "/ls180-img.png"
15 def bond_int_to_ext(pin
, bank
):
16 """ note that internal numbering is 0-31 whereas the DISPLAY internal
17 numbering is 1-32. this uses the INTERNAL numbering.
21 outer ring numbers: the python list order of the outer pads
22 middle numbers: the package number wires (plus side they are on)
23 inner numbers: the IO pad *python internal (0-31)* numbers plus side
26 N102 N101 N100 99 N 68 N67 N66 N65
27 W29 W30 W31 N0 N N31 E29 E30 E31
33 W2 W1 W0 S0 S S31 E0 E1 E2
34 S1 S2 S3 4 S 35 S36 S37 S38
38 # returns side, order-on-the-side, pin number
40 return 'N', pin
+3, 99-pin
42 return 'S', pin
+3, 4+pin
44 if pin
>= 29: # 29, 30, 31
45 return 'N', pin
-29, 100+(31-pin
)
46 if pin
<= 2: # 0, 1, 2
47 return 'S', 2-pin
, 3-pin
48 return 'W', 28-pin
, 103+(28-pin
)
51 return 'N', 35+(31-pin
), 67-(31-pin
)
53 return 'S', pin
+35, 36+pin
54 return 'E', 28-pin
, 39+(pin
-3)
57 def create_sv(fname
, pins
):
58 """unsophisticated drawer of an SVG
64 print ("WARNING, no SVG image, not producing image %s" % fname
)
67 # create internal to external map
68 bondmap
= {'N': {}, 'S': {}, 'E': {}, 'W': {} }
69 padside
= {'pads.north': 'N', 'pads.east': 'E', 'pads.south': 'S',
72 for pinpad
, bank
in padside
.items():
73 sidepad
[bank
] = pinpad
74 for ipin
in range(len(pins
[pinpad
])):
75 eside
, enum
, epinnum
= bond_int_to_ext(ipin
, bank
)
76 bondmap
[eside
][enum
] = (epinnum
, ipin
, bank
)
77 with
open("/tmp/bondmap.txt", "w") as f
:
78 for k
,v
in bondmap
.items():
80 for enum
, (epinnum
, ipin
, bank
) in v
.items():
81 f
.write(" %d %d -> %s %d\n" % (enum
, epinnum
, bank
, ipin
))
84 outerscale
= scale
* 2.0
86 width
= len(pins
['pads.north']) * scale
87 height
= len(pins
['pads.east']) * scale
88 woffs
= scale
*40#-width/2
89 hoffs
= scale
*40#-height/2
91 nepads
= list(bondmap
['N'].keys())
93 wepads
= list(bondmap
['W'].keys())
95 eepads
= list(bondmap
['E'].keys())
97 sepads
= list(bondmap
['S'].keys())
100 owoffs
= woffs
+ (width
/2) - len(nepads
)/2 * outerscale
101 ohoffs
= hoffs
+ (height
/2) - len(wepads
)/2 * outerscale
103 dwg
= svgwrite
.Drawing(fname
, profile
='full',
104 size
=(width
+scale
*85, height
+scale
*80))
107 dwg
.add(dwg
.rect((owoffs
-scale
*2.5, ohoffs
-scale
*4.5),
108 (len(nepads
)*outerscale
+scale
*9,
109 len(wepads
)*outerscale
+scale
*13),
111 stroke
=svgwrite
.rgb(0, 128, 0, '%'),
112 stroke_width
=scale
/5.0))
115 dwg
.add(dwg
.rect((woffs
-scale
*2, hoffs
-scale
*2),
116 (width
+scale
*6, height
+scale
*6),
117 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
118 stroke_width
=scale
/10.0))
120 # record the inner line (iopad) position so that the outer one can
122 innerpos
= {'N': {}, 'S': {}, 'E': {}, 'W': {} }
124 # create the inner diagram
125 for i
, pin
in enumerate(pins
['pads.west']):
126 ht
= hoffs
+ height
- (i
* scale
) + scale
*0.5
127 endline
= (woffs
-scale
*4.5, ht
-scale
*0.5)
128 innerpos
['W'][i
] = endline
129 dwg
.add(dwg
.line((woffs
-scale
*2, ht
-scale
*0.5),
131 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
132 stroke_width
=scale
/10.0))
133 dwg
.add(dwg
.text(pin
.upper(), insert
=(woffs
-scale
*12, ht
),
135 dwg
.add(dwg
.text("W%d" % (i
+1), insert
=(woffs
-scale
*1.5, ht
),
138 for i
, pin
in enumerate(pins
['pads.east']):
139 ht
= hoffs
+ height
- (i
* scale
) + scale
*0.5
140 wd
= width
+ woffs
+ scale
*2
141 endline
= (wd
+scale
*4.5, ht
-scale
*0.5)
142 innerpos
['E'][i
] = endline
143 dwg
.add(dwg
.line((wd
+scale
*2, ht
-scale
*0.5),
145 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
146 stroke_width
=scale
/10.0))
147 dwg
.add(dwg
.text(pin
.upper(), insert
=(wd
+scale
*5, ht
-scale
*0.25),
149 dwg
.add(dwg
.text("E%d" % (i
+1), insert
=(wd
, ht
-scale
*0.25),
152 for i
, pin
in enumerate(pins
['pads.north']):
153 wd
= woffs
+ i
* scale
+ scale
*1.5
154 endline
= (wd
, hoffs
-scale
*4.5)
155 innerpos
['N'][i
] = endline
156 dwg
.add(dwg
.line((wd
, hoffs
-scale
*2),
158 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
159 stroke_width
=scale
/10.0))
160 pos
=(wd
, hoffs
-scale
*5.0)
161 txt
= dwg
.text(pin
.upper(), insert
=pos
, fill
='black')
164 pos
=(wd
+scale
*0.25, hoffs
-scale
*0.25)
165 txt
= dwg
.text("N%d" % (i
+1), insert
=pos
, fill
='white')
169 for i
, pin
in enumerate(pins
['pads.south']):
170 wd
= woffs
+ i
* scale
+ scale
*1.5
171 ht
= hoffs
+ height
+ scale
*2
172 endline
= (wd
, ht
+scale
*4.5)
173 innerpos
['S'][i
] = endline
174 dwg
.add(dwg
.line((wd
, ht
+scale
*2),
176 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
177 stroke_width
=scale
/10.0))
178 pos
=(wd
-scale
*0.25, ht
+scale
*5.0)
179 txt
= dwg
.text(pin
.upper(), insert
=pos
, fill
='black')
182 pos
=(wd
-scale
*0.25, ht
+scale
*0.25)
183 txt
= dwg
.text("S%d" % (i
+1), insert
=pos
, fill
='white')
189 (epinnum
, ipin
, bank
) = pad
= bondmap
['N'][i
]
190 wd
= owoffs
+ i
* outerscale
+ outerscale
*1.5
191 endline
= (wd
, ohoffs
-outerscale
*2)
192 startline
= innerpos
[bank
][ipin
]
193 dwg
.add(dwg
.line(startline
,
195 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
196 stroke_width
=scale
/10.0))
197 pin
= pins
[sidepad
[bank
]][ipin
]
198 pos
=(wd
, ohoffs
-outerscale
*4.0)
199 txt
= dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
200 insert
=pos
, fill
='black')
203 pos
=(wd
, ohoffs
-outerscale
*2.5)
204 txt
= dwg
.text("%d N" % epinnum
, insert
=pos
, fill
='blue')
210 (epinnum
, ipin
, bank
) = pad
= bondmap
['W'][i
]
211 ht
= ohoffs
+ (i
* outerscale
) + outerscale
*1.5
212 endline
= (owoffs
+outerscale
*0.5, ht
)
213 startline
= innerpos
[bank
][ipin
]
214 dwg
.add(dwg
.line(startline
,
216 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
217 stroke_width
=scale
/10.0))
218 pin
= pins
[sidepad
[bank
]][ipin
]
219 pos
= (owoffs
-outerscale
*6.0, ht
)
220 dwg
.add(dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
223 pos
= (owoffs
-outerscale
*1.0, ht
)
224 dwg
.add(dwg
.text("%d W" % epinnum
, insert
=pos
,
229 (epinnum
, ipin
, bank
) = pad
= bondmap
['S'][i
]
230 wd
= owoffs
+ i
* outerscale
+ outerscale
*1.5
231 ht
= ohoffs
+ len(wepads
)*outerscale
+ outerscale
*4
233 startline
= innerpos
[bank
][ipin
]
234 dwg
.add(dwg
.line(startline
,
236 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
237 stroke_width
=scale
/10.0))
238 pin
= pins
[sidepad
[bank
]][ipin
]
239 pos
=(wd
-outerscale
*0.25, ht
+outerscale
*1.5)
240 txt
= dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
241 insert
=pos
, fill
='black')
244 pos
=(wd
-outerscale
*0.25, ht
+outerscale
*0.5)
245 txt
= dwg
.text("%d S" % epinnum
, insert
=pos
, fill
='blue')
251 (epinnum
, ipin
, bank
) = pad
= bondmap
['E'][i
]
252 ht
= ohoffs
+ (i
* outerscale
) + outerscale
*1.5
253 wd
= owoffs
+len(nepads
)*outerscale
+ outerscale
*1
254 endline
= (wd
+outerscale
*0.5, ht
)
255 startline
= innerpos
[bank
][ipin
]
256 dwg
.add(dwg
.line(startline
,
258 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
259 stroke_width
=scale
/10.0))
260 pin
= pins
[sidepad
[bank
]][ipin
]
261 pos
= (wd
+outerscale
*2.5, ht
)
262 dwg
.add(dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
265 pos
= (wd
+outerscale
*1.0, ht
)
266 dwg
.add(dwg
.text("%d E" % epinnum
, insert
=pos
,
270 image_data
= open(ls180_drawing
, "rb").read()
271 encoded
= base64
.b64encode(image_data
).decode()
272 data
= 'data:image/png;base64,{}'.format(encoded
)
273 pos
=(width
/2+woffs
-225, height
/2+hoffs
-225)
274 leads
= svgwrite
.image
.Image(data
, pos
,
278 # add QFP pack image in top-right
279 image_data
= open(pack_drawing
, "rb").read()
280 encoded
= base64
.b64encode(image_data
).decode()
281 data
= 'data:image/png;base64,{}'.format(encoded
)
283 leads
= svgwrite
.image
.Image(data
, pos
,
286 dwg
.add(dwg
.text("GREATEK QFP128L",
290 dwg
.add(dwg
.text("D/W J1-03128-001",
296 # add QFP lead image in centre
298 image_data
= open(lead_drawing
, "rb").read()
299 encoded
= base64
.b64encode(image_data
).decode()
300 data
= 'data:image/png;base64,{}'.format(encoded
)
301 pos
=(woffs
+width
+scale
*23.5, 0)
302 leads
= svgwrite
.image
.Image(data
, pos
,
304 leads
.rotate(-90, (pos
[0]+sz
/2, pos
[1]+sz
/2))
307 dwg
.add(dwg
.text("GREATEK ELECTRONICS INC.",
308 insert
=(woffs
+width
+scale
*29, scale
*8),
310 dwg
.add(dwg
.text("INNER LEAD DRAWING",
311 insert
=(woffs
+width
+scale
*29, scale
*9),
313 dwg
.add(dwg
.text("QFP 128L OPEN STAMPING",
314 insert
=(woffs
+width
+scale
*29, scale
*10),
316 dwg
.add(dwg
.text("BODY 14x20x2.75mm",
317 insert
=(woffs
+width
+scale
*29, scale
*11),
319 dwg
.add(dwg
.text("L/F PAD SIZE 236x236mil^2",
320 insert
=(woffs
+width
+scale
*29, scale
*12),
324 image_data
= open(c4m_drawing
, "rb").read()
325 encoded
= base64
.b64encode(image_data
).decode()
326 data
= 'data:image/png;base64,{}'.format(encoded
)
327 pos
=(woffs
+scale
*5.0, hoffs
+height
-scale
*5.0)
328 leads
= svgwrite
.image
.Image(data
, pos
,
335 dwg
.add(dwg
.rect((woffs
+scale
+75*i
, hoffs
+scale
),
338 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
339 stroke_width
=scale
/10.0))
341 dwg
.add(dwg
.rect((woffs
+width
-scale
, hoffs
+scale
),
344 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
345 stroke_width
=scale
/10.0))
348 dwg
.add(dwg
.text("Libre-SOC ls180 QFP-128",
349 insert
=(woffs
+width
/2-scale
*5, scale
*4),
351 dwg
.add(dwg
.text("In collaboration with LIP6.fr",
352 insert
=(woffs
+width
/2-scale
*5, scale
*5),
354 dwg
.add(dwg
.text("Cell Libraries by Chips4Makers",
355 insert
=(woffs
+width
/2-scale
*5, scale
*6),
357 dwg
.add(dwg
.text("IMEC TSMC 180nm",
358 insert
=(woffs
+width
/2-scale
*5, scale
*7),
360 dwg
.add(dwg
.text("RED Semiconductor",
361 insert
=(woffs
+width
/2-scale
*5, scale
*8),
364 # add package marking circles
365 pos
= (owoffs
-outerscale
*0, ohoffs
+len(wepads
)*outerscale
+outerscale
*2.5)
366 dwg
.add(dwg
.circle(pos
, scale
*2,
368 stroke
=svgwrite
.rgb(16, 16, 16, '%'),
369 stroke_width
=scale
/5.0))
370 dwg
.add(dwg
.circle(pos
, scale
*1,
372 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
373 stroke_width
=scale
/5.0))
374 pos
= (owoffs
+len(nepads
)*outerscale
+outerscale
*2, ohoffs
-outerscale
*0.5)
375 dwg
.add(dwg
.circle(pos
, scale
*2,
377 stroke
=svgwrite
.rgb(16, 16, 16, '%'),
378 stroke_width
=scale
/5.0))
383 def temp_create_sv(fname
, pins
):
384 """unsophisticated drawer of an SVG
390 print ("WARNING, no SVG image, not producing image %s" % fname
)
393 # create internal to external map
394 bondmap
= {'N': {}, 'S': {}, 'E': {}, 'W': {} }
395 padside
= {'pads.north': 'N', 'pads.east': 'E', 'pads.south': 'S',
398 for pinpad
, bank
in padside
.items():
399 sidepad
[bank
] = pinpad
400 for ipin
in range(len(pins
[pinpad
])):
401 eside
, enum
, epinnum
= bond_int_to_ext(ipin
, bank
)
402 bondmap
[eside
][enum
] = (epinnum
, ipin
, bank
)
403 with
open("/tmp/bondmap.txt", "w") as f
:
404 for k
,v
in bondmap
.items():
406 for enum
, (epinnum
, ipin
, bank
) in v
.items():
407 f
.write(" %d %d -> %s %d\n" % (enum
, epinnum
, bank
, ipin
))
410 outerscale
= scale
* 2.0
412 width
= len(pins
['pads.north']) * scale
413 height
= len(pins
['pads.east']) * scale
414 woffs
= scale
*40#-width/2
415 hoffs
= scale
*40#-height/2
417 nepads
= list(bondmap
['N'].keys())
419 wepads
= list(bondmap
['W'].keys())
421 eepads
= list(bondmap
['E'].keys())
423 sepads
= list(bondmap
['S'].keys())
426 owoffs
= woffs
+ (width
/2) - len(nepads
)/2 * outerscale
427 ohoffs
= hoffs
+ (height
/2) - len(wepads
)/2 * outerscale
429 dwg
= svgwrite
.Drawing(fname
, profile
='full',
430 size
=(width
+scale
*85, height
+scale
*80))
433 # dwg.add(dwg.rect((owoffs-scale*2.5, ohoffs-scale*4.5),
434 dwg
.add(dwg
.rect((owoffs
-scale
*2.5, ohoffs
-scale
*4.5),
435 (len(nepads
)*outerscale
+scale
*9,
436 len(wepads
)*outerscale
+scale
*13),
438 stroke
=svgwrite
.rgb(0, 128, 0, '%'),
439 stroke_width
=scale
/5.0))
442 dwg
.add(dwg
.rect((woffs
-scale
*2, hoffs
-scale
*2),
443 (width
+scale
*6, height
+scale
*6),
444 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
445 stroke_width
=scale
/10.0))
447 # record the inner line (iopad) position so that the outer one can
449 innerpos
= {'N': {}, 'S': {}, 'E': {}, 'W': {} }
451 # create the inner diagram
452 for i
, pin
in enumerate(pins
['pads.west']):
453 ht
= hoffs
+ height
- (i
* scale
) + scale
*0.5
454 endline
= (woffs
-scale
*4.5, ht
-scale
*0.5)
455 innerpos
['W'][i
] = endline
456 dwg
.add(dwg
.line((woffs
-scale
*2, ht
-scale
*0.5),
458 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
459 stroke_width
=scale
/10.0))
460 dwg
.add(dwg
.text(pin
.upper(), insert
=(woffs
-scale
*12, ht
),
462 dwg
.add(dwg
.text("W%d" % (i
+1), insert
=(woffs
-scale
*1.5, ht
),
465 for i
, pin
in enumerate(pins
['pads.east']):
466 ht
= hoffs
+ height
- (i
* scale
) + scale
*0.5
467 wd
= width
+ woffs
+ scale
*2
468 endline
= (wd
+scale
*4.5, ht
-scale
*0.5)
469 innerpos
['E'][i
] = endline
470 dwg
.add(dwg
.line((wd
+scale
*2, ht
-scale
*0.5),
472 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
473 stroke_width
=scale
/10.0))
474 dwg
.add(dwg
.text(pin
.upper(), insert
=(wd
+scale
*5, ht
-scale
*0.25),
476 dwg
.add(dwg
.text("E%d" % (i
+1), insert
=(wd
, ht
-scale
*0.25),
479 for i
, pin
in enumerate(pins
['pads.north']):
480 wd
= woffs
+ i
* scale
+ scale
*1.5
481 endline
= (wd
, hoffs
-scale
*4.5)
482 innerpos
['N'][i
] = endline
483 dwg
.add(dwg
.line((wd
, hoffs
-scale
*2),
485 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
486 stroke_width
=scale
/10.0))
487 pos
=(wd
, hoffs
-scale
*5.0)
488 txt
= dwg
.text(pin
.upper(), insert
=pos
, fill
='black')
491 pos
=(wd
+scale
*0.25, hoffs
-scale
*0.25)
492 txt
= dwg
.text("N%d" % (i
+1), insert
=pos
, fill
='white')
496 for i
, pin
in enumerate(pins
['pads.south']):
497 wd
= woffs
+ i
* scale
+ scale
*1.5
498 ht
= hoffs
+ height
+ scale
*2
499 endline
= (wd
, ht
+scale
*4.5)
500 innerpos
['S'][i
] = endline
501 dwg
.add(dwg
.line((wd
, ht
+scale
*2),
503 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
504 stroke_width
=scale
/10.0))
505 pos
=(wd
-scale
*0.25, ht
+scale
*5.0)
506 txt
= dwg
.text(pin
.upper(), insert
=pos
, fill
='black')
509 pos
=(wd
-scale
*0.25, ht
+scale
*0.25)
510 txt
= dwg
.text("S%d" % (i
+1), insert
=pos
, fill
='white')
516 (epinnum
, ipin
, bank
) = pad
= bondmap
['N'][i
]
517 wd
= owoffs
+ i
* outerscale
+ outerscale
*1.5
518 endline
= (wd
, ohoffs
-outerscale
*2)
519 startline
= innerpos
[bank
][ipin
]
520 dwg
.add(dwg
.line(startline
,
522 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
523 stroke_width
=scale
/10.0))
524 pin
= pins
[sidepad
[bank
]][ipin
]
525 pos
=(wd
, ohoffs
-outerscale
*4.0)
526 txt
= dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
527 insert
=pos
, fill
='black')
530 pos
=(wd
, ohoffs
-outerscale
*2.5)
531 txt
= dwg
.text("%d N" % epinnum
, insert
=pos
, fill
='blue')
537 (epinnum
, ipin
, bank
) = pad
= bondmap
['W'][i
]
538 ht
= ohoffs
+ (i
* outerscale
) + outerscale
*1.5
539 endline
= (owoffs
+outerscale
*0.5, ht
)
540 startline
= innerpos
[bank
][ipin
]
541 dwg
.add(dwg
.line(startline
,
543 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
544 stroke_width
=scale
/10.0))
545 pin
= pins
[sidepad
[bank
]][ipin
]
546 pos
= (owoffs
-outerscale
*6.0, ht
)
547 dwg
.add(dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
550 pos
= (owoffs
-outerscale
*1.0, ht
)
551 dwg
.add(dwg
.text("%d W" % epinnum
, insert
=pos
,
556 (epinnum
, ipin
, bank
) = pad
= bondmap
['S'][i
]
557 wd
= owoffs
+ i
* outerscale
+ outerscale
*1.5
558 ht
= ohoffs
+ len(wepads
)*outerscale
+ outerscale
*4
560 startline
= innerpos
[bank
][ipin
]
561 dwg
.add(dwg
.line(startline
,
563 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
564 stroke_width
=scale
/10.0))
565 pin
= pins
[sidepad
[bank
]][ipin
]
566 pos
=(wd
-outerscale
*0.25, ht
+outerscale
*1.5)
567 txt
= dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
568 insert
=pos
, fill
='black')
571 pos
=(wd
-outerscale
*0.25, ht
+outerscale
*0.5)
572 txt
= dwg
.text("%d S" % epinnum
, insert
=pos
, fill
='blue')
578 (epinnum
, ipin
, bank
) = pad
= bondmap
['E'][i
]
579 ht
= ohoffs
+ (i
* outerscale
) + outerscale
*1.5
580 wd
= owoffs
+len(nepads
)*outerscale
+ outerscale
*1
581 endline
= (wd
+outerscale
*0.5, ht
)
582 startline
= innerpos
[bank
][ipin
]
583 dwg
.add(dwg
.line(startline
,
585 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
586 stroke_width
=scale
/10.0))
587 pin
= pins
[sidepad
[bank
]][ipin
]
588 pos
= (wd
+outerscale
*2.5, ht
)
589 dwg
.add(dwg
.text("%s (%s%d)" % (pin
.upper(), bank
, ipin
+1),
592 pos
= (wd
+outerscale
*1.0, ht
)
593 dwg
.add(dwg
.text("%d E" % epinnum
, insert
=pos
,
597 image_data
= open(ls180_drawing
, "rb").read()
598 encoded
= base64
.b64encode(image_data
).decode()
599 data
= 'data:image/png;base64,{}'.format(encoded
)
600 pos
=(width
/2+woffs
-225, height
/2+hoffs
-225)
601 leads
= svgwrite
.image
.Image(data
, pos
,
605 # add QFP pack image in top-right
606 image_data
= open(pack_drawing
, "rb").read()
607 encoded
= base64
.b64encode(image_data
).decode()
608 data
= 'data:image/png;base64,{}'.format(encoded
)
610 leads
= svgwrite
.image
.Image(data
, pos
,
613 dwg
.add(dwg
.text("GREATEK QFP128L",
617 dwg
.add(dwg
.text("D/W J1-03128-001",
623 # add QFP lead image in centre
625 image_data
= open(lead_drawing
, "rb").read()
626 encoded
= base64
.b64encode(image_data
).decode()
627 data
= 'data:image/png;base64,{}'.format(encoded
)
628 pos
=(woffs
+width
+scale
*23.5, 0)
629 leads
= svgwrite
.image
.Image(data
, pos
,
631 leads
.rotate(-90, (pos
[0]+sz
/2, pos
[1]+sz
/2))
634 dwg
.add(dwg
.text("GREATEK ELECTRONICS INC.",
635 insert
=(woffs
+width
+scale
*29, scale
*8),
637 dwg
.add(dwg
.text("INNER LEAD DRAWING",
638 insert
=(woffs
+width
+scale
*29, scale
*9),
640 dwg
.add(dwg
.text("QFP 128L OPEN STAMPING",
641 insert
=(woffs
+width
+scale
*29, scale
*10),
643 dwg
.add(dwg
.text("BODY 14x20x2.75mm",
644 insert
=(woffs
+width
+scale
*29, scale
*11),
646 dwg
.add(dwg
.text("L/F PAD SIZE 236x236mil^2",
647 insert
=(woffs
+width
+scale
*29, scale
*12),
651 image_data
= open(c4m_drawing
, "rb").read()
652 encoded
= base64
.b64encode(image_data
).decode()
653 data
= 'data:image/png;base64,{}'.format(encoded
)
654 pos
=(woffs
+scale
*5.0, hoffs
+height
-scale
*5.0)
655 leads
= svgwrite
.image
.Image(data
, pos
,
662 dwg
.add(dwg
.rect((woffs
+scale
+75*i
, hoffs
+scale
),
665 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
666 stroke_width
=scale
/10.0))
668 dwg
.add(dwg
.rect((woffs
+width
-scale
, hoffs
+scale
),
671 stroke
=svgwrite
.rgb(16, 255, 16, '%'),
672 stroke_width
=scale
/10.0))
675 dwg
.add(dwg
.text("Libre-SOC ls180 QFP-128",
676 insert
=(woffs
+width
/2-scale
*5, scale
*4),
678 dwg
.add(dwg
.text("In collaboration with LIP6.fr",
679 insert
=(woffs
+width
/2-scale
*5, scale
*5),
681 dwg
.add(dwg
.text("Cell Libraries by Chips4Makers",
682 insert
=(woffs
+width
/2-scale
*5, scale
*6),
684 dwg
.add(dwg
.text("IMEC TSMC 180nm",
685 insert
=(woffs
+width
/2-scale
*5, scale
*7),
687 dwg
.add(dwg
.text("RED Semiconductor",
688 insert
=(woffs
+width
/2-scale
*5, scale
*8),
691 # add package marking circles
692 pos
= (owoffs
-outerscale
*0, ohoffs
+len(wepads
)*outerscale
+outerscale
*2.5)
693 dwg
.add(dwg
.circle(pos
, scale
*2,
695 stroke
=svgwrite
.rgb(16, 16, 16, '%'),
696 stroke_width
=scale
/5.0))
697 dwg
.add(dwg
.circle(pos
, scale
*1,
699 stroke
=svgwrite
.rgb(255, 16, 16, '%'),
700 stroke_width
=scale
/5.0))
701 pos
= (owoffs
+len(nepads
)*outerscale
+outerscale
*2, ohoffs
-outerscale
*0.5)
702 dwg
.add(dwg
.circle(pos
, scale
*2,
704 stroke
=svgwrite
.rgb(16, 16, 16, '%'),
705 stroke_width
=scale
/5.0))
711 def display(of
, pins
, banksel
=None, muxwidth
=4):
713 | Pin | Mux0 | Mux1 | Mux2 | Mux3 |
714 | --- | ----------- | ----------- | ----------- | ----------- |
716 pinidx
= sorted(pins
.keys())
718 pdata
= pins
.get(pin
)
721 for mux
in range(muxwidth
):
724 name
, bank
= pdata
[mux
]
729 res
= '| %3d |' % pin
730 for mux
in range(muxwidth
):
734 name
, bank
= pdata
[mux
]
735 res
+= " %s %-9s |" % (bank
, name
)
736 of
.write("%s\n" % res
)
742 if not f
.startswith('FB_'):
746 return f2
[0], int(f2
[1])
749 while f
and not f
[0].isdigit():
752 return a
, int(f
) if f
else None
764 def find_fn(fname
, names
):
766 if fname
.startswith(n
):
769 def map_name(pinmap
, fn
, fblower
, pin
, rename
):
771 if pin
[:-1].isdigit():
772 print ("map name digit", pin
, fn
, fblower
)
773 if fn
in ['PWM', 'EINT', 'VDD', 'VSS']:
774 return fn
.lower() + pin
.lower()
776 return 'gpio' + pin
[1:].lower()
780 pk
= '%s%s_%s' % (fblower
, pin
[0], pin
[:-1])
781 elif pin
[:-1].isdigit() and fn
!= 'EINT':
782 pk
= '%s%s_out' % (fblower
, pin
[:-1])
784 pk
= '%s_%s' % (fblower
, pin
[:-1])
785 print ("map name", pk
, fblower
, pk
in pinmap
)
788 remapped
= pinmap
[pk
]
789 uscore
= remapped
.find('_')
792 fn
, pin
= remapped
[:uscore
], remapped
[uscore
+1:] + pin
[-1]
795 def python_pindict(of
, pinmap
, pins
, function_names
, dname
, remap
):
798 of
.write("\n%s = OrderedDict()\n" % dname
)
800 for k
, pingroup
in pins
.byspec
.items():
801 (a
, n
) = k
.split(":")
805 of
.write("%s['%s'] = [ " % (dname
, fblower
))
808 for i
, p
in enumerate(pingroup
):
809 name
= map_name(pinmap
, k
[0], fblower
, p
, remap
)
810 res
[fblower
].append(name
)
811 of
.write("'%s', " % name
)
813 if count
== 4 and i
!= len(pingroup
)-1:
817 print (" dict %s" % dname
, a
, n
, pingroup
)
821 def python_dict_fns(of
, pinmap
, pins
, function_names
):
822 of
.write("# auto-generated by Libre-SOC pinmux program: do not edit\n")
823 of
.write("# python src/pinmux_generator.py -v -s {spec} -o {output}\n")
824 of
.write("# use OrderedDict to fix stable order for JTAG Boundary Scan\n")
825 of
.write("from collections import OrderedDict\n")
827 fn_names
= function_names
.keys()
830 fnidx
= list(fns
.keys())
831 fnidx
.sort(key
=fnsplit
)
833 print ("python fnames", function_names
)
834 print ("python speckeys", pins
.byspec
.keys())
835 print ("python dict fns", dir(pins
.gpio
))
836 print (pins
.gpio
.pinfn('', ''))
837 print (pins
.pwm
.pinfn('', ''))
838 print (pins
.sdmmc
.pinfn('', ''))
839 print ("by spec", pins
.byspec
)
842 pd
= python_pindict(of
, {}, pins
, function_names
, 'pindict', False)
843 ld
= python_pindict(of
, pinmap
, pins
, function_names
, 'litexdict', True)
847 # process results and create name map
848 litexmap
= OrderedDict()
852 for pname
, lname
in zip(pl
, ll
):
853 pname
= "%s_%s" % (k
, pname
[:-1]) # strip direction +/-/*
854 lname
= lname
[:-1] # strip direction +/-/*
855 if k
in ['eint', 'pwm', 'gpio', 'vdd', 'vss']: # sigh
856 lname
= "%s_%s" % (k
, lname
)
857 litexmap
[pname
] = lname
858 print ("litexmap", litexmap
)
859 of
.write("litexmap = {\n")
860 for k
, v
in litexmap
.items():
861 of
.write("\t'%s': '%s',\n" % (k
, v
))
866 def display_fns(of
, bankspec
, pins
, function_names
):
867 fn_names
= function_names
.keys()
869 for (pin
, pdata
) in pins
.items():
870 for mux
in range(0, 4): # skip GPIO for now
873 name
, bank
= pdata
[mux
]
874 assert name
is not None, str(bank
)
877 fns
[name
].append((pin
- bankspec
[bank
], mux
, bank
))
879 fnidx
= list(fns
.keys())
880 fnidx
.sort(key
=fnsplit
)
883 fnbase
= find_fn(fname
, fn_names
)
884 #fblower = fnbase.lower()
885 assert fnbase
in function_names
, "fn %s not in descriptions %s" % \
886 (fname
, str(function_names
.keys()))
887 #print "name", fname, fnbase
888 if fnbase
!= current_fn
:
889 if current_fn
is not None:
891 of
.write("## %s\n\n%s\n\n" % (fnbase
, function_names
[fnbase
]))
893 of
.write("* %-9s :" % fname
)
894 for (pin
, mux
, bank
) in fns
[fname
]:
895 of
.write(" %s%d/%d" % (bank
, pin
, mux
))
901 def check_functions(of
, title
, bankspec
, fns
, pins
, required
, eint
, pwm
,
904 pins
= deepcopy(pins
)
905 if descriptions
is None:
912 of
.write("# Pinmap for %s\n\n" % title
)
914 print ("fn_idx", fnidx
)
916 print ("fnspec", pins
.fnspec
.keys())
917 print ("required", required
)
918 for name
in required
:
919 of
.write("## %s\n\n" % name
)
920 if descriptions
and name
in descriptions
:
921 of
.write("%s\n\n" % descriptions
[name
])
923 name
= name
.split(':')
925 findbank
= name
[0][0]
926 findmux
= int(name
[0][1:])
932 name
= name
.split('/')
943 if not fname
.startswith(name
):
945 for k
in pins
.fnspec
.keys():
946 if fname
.startswith(k
):
947 fk
= list(pins
.fnspec
[k
].keys())
950 #print fname, fn, dir(fn)
952 count
= len(fn
.pingroup
)
953 for pin
, mux
, bank
in fns
[fname
]:
954 if findbank
is not None:
959 pin_
= pin
+ bankspec
[bank
]
961 pinfound
[pin_
] = (fname
, pin_
, bank
, pin
, mux
)
963 pinidx
= sorted(pinfound
.keys())
967 print ("pinidx", pinidx
)
969 fname
, pin_
, bank
, pin
, mux
= pinfound
[pin_
]
973 if len(found
) > count
:
977 of
.write("* %s %d %s%d/%d\n" % (fname
, pin_
, bank
, pin
, mux
))
980 if removedcount
!= count
:
982 print ("no match between required and available pins")
984 print ("not all found", name
, removedcount
, count
, title
, found
,
986 print ("pins found", pinfound
)
993 for name
in descriptions
.keys():
994 if not name
.startswith('GPIO'):
1002 of
.write("## GPIO\n\n")
1008 if descriptions
and fname
in descriptions
:
1009 desc
= ': %s' % descriptions
[fname
]
1011 pin
= int(fname
[7:])
1012 pin_
= pin
+ bankspec
[bank
]
1013 if pin_
not in pins
:
1017 of
.write("* %-8s %d %s%-2d %s\n" % (fname
, pin_
, bank
, pin
, desc
))
1021 display_group(of
, bankspec
, "EINT", eint
, fns
, pins
, descriptions
)
1023 display_group(of
, bankspec
, "PWM", pwm
, fns
, pins
, descriptions
)
1025 of
.write("## Unused Pinouts (spare as GPIO) for '%s'\n\n" % title
)
1026 if descriptions
and 'GPIO' in descriptions
:
1027 of
.write("%s\n\n" % descriptions
['GPIO'])
1031 return pins
# unused
1034 def display_group(of
, bankspec
, title
, todisplay
, fns
, pins
, descriptions
):
1035 of
.write("## %s\n\n" % title
)
1038 for fname
in todisplay
:
1040 if descriptions
and fname
in descriptions
:
1041 desc
= ': %s' % descriptions
[fname
]
1042 fname
= fname
.split(':')
1044 findbank
= fname
[0][0]
1045 findmux
= int(fname
[0][1:])
1051 for (pin
, mux
, bank
) in fns
[fname
]:
1052 if findbank
is not None:
1053 if findbank
!= bank
:
1059 pin_
= pin
+ bankspec
[bank
]
1060 if pin_
not in pins
:
1064 of
.write("* %s %d %s%d/%d %s\n" %
1065 (fname
, pin_
, bank
, pin
, mux
, desc
))
1069 def display_fixed(of
, fixed
, offs
):
1071 fkeys
= sorted(fixed
.keys())
1074 for pin
, k
in enumerate(fkeys
):
1075 of
.write("## %s\n\n" % k
)
1078 for name
in fixed
[k
]:
1082 if prevname
[:2] == name
[:2] and linecount
!= 0:
1083 of
.write(" %s" % name
)
1088 of
.write("* %d: %d %s" % (pin_
, pin
, name
))
1090 res
.append((pin_
, name
))