aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xfix-layer-4.py111
1 files changed, 111 insertions, 0 deletions
diff --git a/fix-layer-4.py b/fix-layer-4.py
new file mode 100755
index 0000000..59f7a1f
--- /dev/null
+++ b/fix-layer-4.py
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+"""
+
+Layer 4 is a layer with large polygons (GND and Power). In Altium, this was made
+like an inverted layer with drawn lines separating polygons. Issues were with
+line thickness in Kicad, clearance parameters preventing copper to flow in between
+pins under the FPGA and the fact that KiCAD doesn't do inverted layers so the
+lines had to be removed and zone clearances adjusted to create the same result.
+
+Compare with
+
+ $ gerbv 'Cryptech Alpha-In4.Cu.gbr' CrypTech.GP3
+
+"""
+
+import sys
+import pcbnew
+
+
+def remove_tracks(board, layer):
+ """
+ The tracks on Layer four are actually where there *should not* be copper.
+ L4 is an inverted layer, but that information actually isn't in the files -
+ it is specified in an excel sheet sent to the PCB house.
+
+ By removing them and then setting some parameters carefully on the zones
+ on that layer, we get a close-to-perfect (but no longer inverted) result
+ in KiCAD.
+ """
+ for this in [x for x in board.GetTracks() if x.GetLayerName() == layer]:
+ print('Removing track {}'.format(this))
+ board.Delete(this)
+
+#def set_tracks_width(board, layer, width):
+# for this in [x for x in board.GetTracks() if x.GetLayerName() == layer]:
+# this.SetWidth(width)
+#
+#def move_tracks(board, from_layer, to_layer):
+# for this in [x for x in board.GetTracks() if x.GetLayerName() == from_layer]:
+# this.SetLayer(board.GetLayerID(to_layer))
+
+
+def layer_zone_fixes(board, layer):
+ for i in range(board.GetAreaCount()):
+ area = board.GetArea(i)
+ if area.GetLayerName() != layer:
+ continue
+ print('Area {} {}'.format(area, area.GetNetname()))
+ # This makes sharp edges matching Altium Designer
+ # 0.0255 is the minimum KiCad wants in order to allow changes to the zone inside KiCad
+ area.SetMinThickness(int(2 * 0.0255 * 1000000))
+ # 0.25 works better for the distance between zones in the bottom half of layer 4,
+ # but does not allow copper between the vias under the FPGA
+ #area.SetZoneClearance(int(0.25 * 1000000))
+ #
+ # Values below 0.15 or somewhere there does not seem to make a difference at all
+ area.SetZoneClearance(int(0.15 * 1000000))
+ if area.GetNetname() == 'GND':
+ area.SetPriority(50)
+ # 0.25 clearance on the 'background' GND zone keeps the distance to the island
+ # zones in the bottom half of layer 4, matching the clearance between the areas
+ # but creating a bit more clearance around vias in KiCAD plot than in Altium
+ area.SetZoneClearance(int(0.25 * 1000000))
+ area.SetThermalReliefCopperBridge(int(0.5 * 1000000))
+ #help(area)
+
+
+def hide_layers_except(board, layers):
+ """
+ As a convenience when working on getting a particular layer right, hide other layers.
+ """
+ lset = board.GetVisibleLayers()
+ print('Layer set: {} / {}'.format(lset, lset.FmtHex()))
+ #help(lset)
+ mask = 0
+ for x in lset.Seq():
+ name = board.GetLayerName(x)
+ print(' {} {}'.format(x, name))
+ if name in layers:
+ mask |= 1 << x
+ hexset = '{0:013x}'.format(mask)
+ visible_set = pcbnew.LSET()
+ visible_set.ParseHex(hexset, len(hexset))
+ board.SetVisibleLayers(visible_set)
+
+
+def main(in_fn='rev03-KiCad/convert.kicad_pcb', out_fn='rev03-KiCad/Cryptech Alpha.kicad_pcb'):
+ board = pcbnew.LoadBoard(in_fn)
+ pcbnew.SaveBoard(in_fn + '.before-fix-layer-4', board)
+
+ remove_tracks(board, 'In4.Cu')
+ #set_tracks_width(board, 'In4.Cu', int(0.15 * 1000000))
+ #move_tracks(board, 'In4.Cu', 'Eco2.User')
+ layer_zone_fixes(board, 'In4.Cu')
+
+ hide_layers_except(board, ['In4.Cu'])
+
+ # Only show Through Via while working on Layer 4
+ board.SetVisibleElements(0x7FFC0009)
+
+ pcbnew.SaveBoard(out_fn, board)
+ return True
+
+if __name__ == '__main__':
+ try:
+ res = main()
+ if res:
+ sys.exit(0)
+ sys.exit(1)
+ except KeyboardInterrupt:
+ pass