From 19a36f254fe1007827d6e83a90250d625bb7ae2e Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Mon, 25 Sep 2017 15:10:51 +0200 Subject: fix more layers --- convert.sh | 2 +- fix-layer-4.py | 114 ---------------------------------------- fix-pcb.py | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 115 deletions(-) delete mode 100755 fix-layer-4.py create mode 100755 fix-pcb.py diff --git a/convert.sh b/convert.sh index 7bc1a4f..b5538ec 100755 --- a/convert.sh +++ b/convert.sh @@ -73,7 +73,7 @@ done # Make a copy used as input file in fix-layer-4.py cp "Cryptech Alpha.kicad_pcb" "convert.kicad_pcb" -../fix-layer-4.py "convert.kicad_pcb" "Cryptech Alpha.kicad_pcb" +../fix-pcb.py "convert.kicad_pcb" "Cryptech Alpha.kicad_pcb" echo "" diff --git a/fix-layer-4.py b/fix-layer-4.py deleted file mode 100755 index 78f851c..0000000 --- a/fix-layer-4.py +++ /dev/null @@ -1,114 +0,0 @@ -#!/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 'rev03-KiCad/GerberOutput/Cryptech Alpha-In4.Cu.gbr' /path/to/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: - if len(sys.argv) != 3: - sys.stderr.write('Syntax: fix-layer-4.py infile.kicad_pcb outfile.kicad_pcb\n') - sys.exit(1) - res = main(sys.argv[1], sys.argv[2]) - if res: - sys.exit(0) - sys.exit(1) - except KeyboardInterrupt: - pass diff --git a/fix-pcb.py b/fix-pcb.py new file mode 100755 index 0000000..d04d7a5 --- /dev/null +++ b/fix-pcb.py @@ -0,0 +1,160 @@ +#!/usr/bin/python + +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 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 layer_zone_fixes(board, layer, gnd_clearance=0.25): + 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(gnd_clearance * 1000000)) + area.SetThermalReliefCopperBridge(int(0.5 * 1000000)) + #help(area) + + +def fix_layer_4(board): + """ + + 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 + vias 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 'rev03-KiCad/GerberOutput/Cryptech Alpha-In4.Cu.gbr' /path/to/CrypTech.GP3 + """ + 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', gnd_clearance=0.25) + + +def fix_layer_6(board): + """ + Layer 6 has a GND polygon that needs a little less clearance in order to fill in between + the vias of the FPGA. + + Compare with + + $ gerbv 'rev03-KiCad/GerberOutput/Cryptech Alpha-In6.Cu.gbr' /path/to/CrypTech.GP4 + """ + layer_zone_fixes(board, 'In6.Cu', gnd_clearance=0.15) + + +def fix_layer_bottom(board): + """ + There is one small segment that ends up on Net 1 instead of GND (Net 7) for some reason: + + #Tracks#3898: 200C000500FFFFFFFFFFFFFFFF41A799058A60450341A7990561AE4803E50106000000000000000000FFFF0001 + - (segment (start 38.75 -74.875) (end 38.75 -75.425) (width 1) (layer B.Cu) (net 1)) + + (segment (start 38.75 -74.875) (end 38.75 -75.425) (width 1) (layer B.Cu) (net 7)) + + I'm guessing the surrounding GND polygon somehow has priority in Altium so this small + bug is not visible there. This is a segment connected to one of the seven stiching vias + for the GND polygon under and to the right of U14 (bottom left one of the four grouped together). + + The OSHW logo is lost, but I think we can live with that. + + The copper print saying PCB rev.03 is messed up, but I don't think we can expect the fonts + to be similar in Altium and KiCAD anyways, so might as well just redo that. + + Compare with + + $ gerbv 'rev03-KiCad/GerberOutput/Cryptech Alpha-B.Cu.gbr' /path/to/CrypTech.GBL + """ + for this in [x for x in board.GetTracks() if x.GetLayerName() == 'B.Cu']: + if tuple(this.GetStart()) == (38750000, -74875000): + print('Moving track to net GND: {}'.format(this)) + this.SetNet(board.FindNet('GND')) + + layer_zone_fixes(board, 'B.Cu', gnd_clearance=0.15) + + +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) + + fix_layer_4(board) + fix_layer_6(board) + fix_layer_bottom(board) + + hide_layers_except(board, ['B.Cu']) + + # Only show Through Via while working on Layer 4 + board.SetVisibleElements(0x7FFC0009) + + pcbnew.SaveBoard(out_fn, board) + return True + +if __name__ == '__main__': + try: + if len(sys.argv) != 3: + sys.stderr.write('Syntax: fix-layer-4.py infile.kicad_pcb outfile.kicad_pcb\n') + sys.exit(1) + res = main(sys.argv[1], sys.argv[2]) + if res: + sys.exit(0) + sys.exit(1) + except KeyboardInterrupt: + pass -- cgit v1.2.3