forked from odurc/kicad-utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fix-pins.py
executable file
·253 lines (211 loc) · 9.63 KB
/
fix-pins.py
1
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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from schlib import *
# cases covered by this script:
# (1) pins with posx wrong if component has pins with L direction but not R direction
# (2) pins with posx wrong if component has pins with R direction but not L direction
# (3) pins with posy wrong if component has pins with U direction but not D direction
# (4) pins with posy wrong if component has pins with D direction but not U direction
# (5) pins with posx wrong if component has at least one pin wrong in each of the following direction: L, R
# (6) pins with posy wrong if component has at least one pin wrong in each of the following direction: U, D
# (7) tries to move the pin with L or R direction up or down keeping it 100mil away from another pin or of the rectangle symbol bounds
# (8) tries to move the pin with U or D direction to left or right keeping it 100mil away from another pin or of the rectangle symbol bounds
def fix_component(component):
pinsL = component.filterPins(direction='L')
pinsL_count = len(pinsL)
pinsR = component.filterPins(direction='R')
pinsR_count = len(pinsR)
pinsU = component.filterPins(direction='U')
pinsU_count = len(pinsU)
pinsD = component.filterPins(direction='D')
pinsD_count = len(pinsD)
print component.name
# case (1)
# assuming that all L pins have same length
if pinsL_count > 0 and pinsR_count == 0:
for pin in pinsL:
posx = int(pin['posx'])
length = int(pin['length'])
old_posx = posx
if ((posx % 100) != 0) and ((posx % 50) == 0):
if length <= 100:
length += 50
posx += 50
elif length >= 150:
length -= 50
posx -= 50
pin['posx'] = str(posx)
pin['length'] = str(length)
print ' * fixing posx of %s: %i -> %i' % (pin['name'], old_posx, posx)
# case (2)
# assuming that all R pins have same length
if pinsR_count > 0 and pinsL_count == 0:
for pin in pinsR:
posx = int(pin['posx'])
length = int(pin['length'])
old_posx = posx
if ((posx % 100) != 0) and ((posx % 50) == 0):
if length <= 100:
length += 50
posx -= 50
elif length >= 150:
length -= 50
posx += 50
pin['posx'] = str(posx)
pin['length'] = str(length)
print ' * fixing posx of %s: %i -> %i' % (pin['name'], old_posx, posx)
# case (3)
# assuming that all U pins have same length
if pinsU_count > 0 and pinsD_count == 0:
for pin in pinsU:
posy = int(pin['posy'])
length = int(pin['length'])
old_posy = posy
if ((posy % 100) != 0) and ((posy % 50) == 0):
if length <= 100:
length += 50
posy -= 50
elif length >= 150:
length -= 50
posy += 50
pin['posy'] = str(posy)
pin['length'] = str(length)
print ' * fixing posy of %s: %i -> %i' % (pin['name'], old_posy, posy)
# case (4)
# assuming that all D pins have same length
if pinsD_count > 0 and pinsU_count == 0:
for pin in pinsD:
posy = int(pin['posy'])
length = int(pin['length'])
old_posy = posy
if ((posy % 100) != 0) and ((posy % 50) == 0):
if length <= 100:
length += 50
posy += 50
elif length >= 150:
length -= 50
posy -= 50
pin['posy'] = str(posy)
pin['length'] = str(length)
print ' * fixing posy of %s: %i -> %i' % (pin['name'], old_posy, posy)
# case (5)
if pinsL_count > 0 and pinsR_count > 0:
# check if at least one pin is wrong in L direction
need_fix_L = False
for pin in pinsL:
posx = int(pin['posx'])
if ((posx % 100) != 0) and ((posx % 50) == 0):
need_fix_L = True
break
# check if at least one pin is wrong in R direction
need_fix_R = False
for pin in pinsR:
posx = int(pin['posx'])
if ((posx % 100) != 0) and ((posx % 50) == 0):
need_fix_R = True
break
if need_fix_L and need_fix_R:
for pin in (pinsL + pinsR):
posx = int(pin['posx'])
length = int(pin['length'])
old_posx = posx
if length <= 100:
length += 50
posx += 50 if posx > 0 else -50
elif length >= 150:
length -= 50
posx += -50 if posx > 0 else 50
pin['posx'] = str(posx)
pin['length'] = str(length)
print ' * fixing posx of %s: %i -> %i' % (pin['name'], old_posx, posx)
# case (6)
if pinsU_count > 0 and pinsD_count > 0:
# check if at least one pin is wrong in L direction
need_fix_U = False
for pin in pinsU:
posy = int(pin['posy'])
if ((posy % 100) != 0) and ((posy % 50) == 0):
need_fix_U = True
break
# check if at least one pin is wrong in R direction
need_fix_D = False
for pin in pinsD:
posy = int(pin['posy'])
if ((posy % 100) != 0) and ((posy % 50) == 0):
need_fix_D = True
break
if need_fix_U and need_fix_D:
for pin in (pinsU + pinsD):
posy = int(pin['posy'])
length = int(pin['length'])
old_posy = posy
if length <= 100:
length += 50
posy += 50 if posy > 0 else -50
elif length >= 150:
length -= 50
posy += -50 if posy > 0 else 50
pin['posy'] = str(posy)
pin['length'] = str(length)
print ' * fixing posy of %s: %i -> %i' % (pin['name'], old_posy, posy)
# case (7)
if len(component.draw['rectangles']) == 1:
min_posy = int(component.draw['rectangles'][0]['endy'])
max_posy = int(component.draw['rectangles'][0]['starty'])
for d in ['L', 'R']:
for n in range(2):
pins = component.filterPins(direction=d)
if n == 0:
pins = sorted(pins, key=lambda e: int(e['posy']))
else:
pins = sorted(pins, key=lambda e: int(e['posy']), reverse=True)
for i, pin in enumerate(pins):
posy = int(pin['posy'])
prev_posy = int(pins[i-1]['posy']) if i > 0 else None
next_posy = int(pins[i+1]['posy']) if i < (len(pins)-1) else None
if ((posy % 100) != 0) and ((posy % 50) == 0):
if abs((posy + 50) - max_posy) >= 100:
if next_posy == None or (next_posy != None and abs((posy + 50) - next_posy) >= 100):
pin['posy'] = str(posy + 50)
print ' * fixing posy of %s: %i -> %i' % (pin['name'], posy, posy+50)
continue
if abs((posy - 50) - min_posy) >= 100:
if prev_posy == None or (prev_posy != None and abs((posy - 50) - prev_posy) >= 100):
pin['posy'] = str(posy - 50)
print ' * fixing posy of %s: %i -> %i' % (pin['name'], posy, posy-50)
continue
# case (8)
if len(component.draw['rectangles']) == 1:
min_posx = int(component.draw['rectangles'][0]['startx'])
max_posx = int(component.draw['rectangles'][0]['endx'])
for d in ['U', 'D']:
for n in range(2):
pins = component.filterPins(direction=d)
if n == 0:
pins = sorted(pins, key=lambda e: int(e['posx']))
else:
pins = sorted(pins, key=lambda e: int(e['posx']), reverse=True)
for i, pin in enumerate(pins):
posx = int(pin['posx'])
prev_posx = int(pins[i-1]['posx']) if i > 0 else None
next_posx = int(pins[i+1]['posx']) if i < (len(pins)-1) else None
if ((posx % 100) != 0) and ((posx % 50) == 0):
if abs((posx + 50) - max_posx) >= 100:
if next_posx == None or (next_posx != None and abs((posx + 50) - next_posx) >= 100):
pin['posx'] = str(posx + 50)
print ' * fixing posx of %s: %i -> %i' % (pin['name'], posx, posx+50)
continue
if abs((posx - 50) - min_posx) >= 100:
if prev_posx == None or (prev_posx != None and abs((posx - 50) - prev_posx) >= 100):
pin['posx'] = str(posx - 50)
print ' * fixing posx of %s: %i -> %i' % (pin['name'], posx, posx-50)
continue
if len(sys.argv) < 2:
print 'Usage: %s <file1.lib> [file2.lib file3.lib file4.lib ...]' % sys.argv[0]
exit(1)
for f in sys.argv[1:]:
lib = SchLib(f)
print '---', f, '---'
for component in lib.components:
fix_component(component)
lib.save()