def add_zone(net_name, layer_name, rect, zones): layer = pcb.GetLayerID(layer_name) zone, poly = kad.add_zone(rect, layer, len(zones), net_name) zone.SetZoneClearance(pcbnew.FromMils(20)) zone.SetMinThickness(pcbnew.FromMils(16)) #zone.SetThermalReliefGap( pcbnew.FromMils( 12 ) ) #zone.SetThermalReliefCopperBridge( pcbnew.FromMils( 24 ) ) zone.Hatch() # zones.append(zone)
def Run(self): SCALE = 1000000.0 msg = "Loading Board\n" board = pcbnew.GetBoard() gndnet = find_net("GND", board) set_all_pads_to_net(gndnet, board) pcboutline = find_pcb_outline_bbox(board) pcboutline.Inflate(-1 * pcbnew.FromMils(10)) leftside = pcboutline.GetLeft() rightside = pcboutline.GetRight() bottomside = pcboutline.GetBottom() topside = pcboutline.GetTop() print "Creating copper pour on GND: top={} bottom={} left={} right={}".format( topside / SCALE, bottomside / SCALE, leftside / SCALE, rightside / SCALE) zone_container = board.InsertArea(gndnet.GetNet(), 0, pcbnew.B_Cu, leftside, topside, pcbnew.ZONE_CONTAINER.DIAGONAL_EDGE) shape_poly_set = zone_container.Outline() shape_poly_set.Append(leftside, bottomside) shape_poly_set.Append(rightside, bottomside) shape_poly_set.Append(rightside, topside) zone_container.SetPadConnection(pcbnew.PAD_ZONE_CONN_FULL) zone_container.Hatch() msg += "\n" msg += "You may need to refresh the display now. Select Legacy mode, then Modern mode" + "\n"
def AddParam(self, section, param, unit, default, hint=''): """ Add a parameter with some properties. TODO: Hints are not supported, as there is as yet nowhere to put them in the KiCAD interface """ error = "" val = None if unit == self.uMM: val = pcbnew.FromMM(default) elif unit == self.uMils: val = pcbnew.FromMils(default) elif unit == self.uNatural: val = default elif unit == self.uString: val = str(default) elif unit == self.uBool: val = "True" if default else "False" # ugly stringing else: error = "Warning: Unknown unit type: %s" % unit return error if unit in [self.uNatural, self.uBool, self.uString]: param = "*%s" % param # star prefix for natural if section not in self.parameters: self.parameters[section] = {} self.parameters[section][param] = val return error
def Run( self ): SCALE = 1000000.0 msg="Loading Board\n" board = pcbnew.GetBoard() gndnet = find_net("GND", board) if gndnet == None: return #TODO: create a new net set_all_pads_to_net(gndnet, board) pcboutline = find_pcb_outline_bbox(board) pcboutline.Inflate(-1 * pcbnew.FromMils(10)) leftside = pcboutline.GetLeft() rightside = pcboutline.GetRight() bottomside = pcboutline.GetBottom() topside = pcboutline.GetTop() msg+="Creating copper pour on GND: top={} bottom={} left={} right={}".format(topside/SCALE, bottomside/SCALE, leftside/SCALE, rightside/SCALE) #brd.AddArea(aNewZonesList: 'PICKED_ITEMS_LIST *', aNetcode: 'int', aLayer: 'PCB_LAYER_ID', aStartPointPosition: 'wxPoint', aHatch: 'ZONE_BORDER_DISPLAY_STYLE') -> 'ZONE *) zone_container = board.AddArea(None, gndnet.GetNetCode(), pcbnew.B_Cu, pcbnew.wxPoint(leftside, topside), pcbnew.ZONE_FILL_MODE_POLYGONS) shape_poly_set = zone_container.Outline() shape_poly_set.Append(leftside, bottomside) shape_poly_set.Append(rightside, bottomside) shape_poly_set.Append(rightside, topside) zone_container.SetPadConnection(pcbnew.ZONE_CONNECTION_FULL) #zone_container.Hatch() msg+="\n" msg+="You may need to refresh the display now. Select Legacy mode, then Modern mode" + "\n"
def PutOnGridMils(self, value, gridSizeMil=2): """ Round the value (in KiCAD internal units 1nm) according to the provided gridSize in mil. """ thresh = pcbnew.FromMils(gridSizeMil) res = round(value / thresh) * thresh return res
def set_trace_widths(board, target_widths): board.BuildListOfNets() # required so 'board' contains valid netclass data # build list with copper layer names copper_layer_count = board.GetCopperLayerCount() layer_names = [ board.GetLayerName(layer_id) for layer_id in range(board.GetCopperLayerCount() - 1) ] + [board.GetLayerName(31)] # check the target widths structure for nc, width_map in target_widths.items(): # TODO check for valid net class (API only available in kicad 5) # nc = board.GetAllNetClasses() for layer_name in width_map.keys(): if layer_name != 'Default' and layer_name not in layer_names: raise Exception('Invalid layer name: %s' % layer_name) # initialize counters for changes count = collections.OrderedDict() for layer_name in layer_names: count.setdefault(layer_name, 0) for track in board.GetTracks(): for nc, width_map in target_widths.items(): default_width = width_map['Default'] if type(track) == pcbnew.TRACK and track.GetNet().GetClassName( ) == nc: layer_name = track.GetLayerName() if layer_name in width_map: track.SetWidth(pcbnew.FromMils(width_map[layer_name])) else: if default_width <= 0: pos = track.GetPosition() x = pcbnew.ToMM(pos.x) y = pcbnew.ToMM(pos.y) raise Exception( 'Found track on net %s on unexpected layer: %s at position %.2fx%.2f mm' % (track.GetNetname(), layer_name, x, y)) else: track.SetWidth(pcbnew.FromMils(default_width)) count[layer_name] += 1 return count
def add_line_rawunit(a, b, layer='Edge.Cuts', width=2): if a[0] == b[0] and a[1] == b[1]: print("add_line_rawunit: identical", a) return None line = pcbnew.DRAWSEGMENT() line.SetStart(a) line.SetEnd(b) line.SetLayer(pcb.GetLayerID(layer)) line.SetWidth(pcbnew.FromMils(width)) pcb.Add(line) return line
def scalar_to_unit(v, mm_or_mils): if mm_or_mils: return pcbnew.FromMM(v) else: return pcbnew.FromMils(v)
import os.path import sys import time CPU_REF = 'U7' # CPU reference designator # four SDRAM memory chips: DDR_LF = 'U15' # left front DRAM DDR_RF = 'U17' # right front DRAM DDR_LB = 'U16' # left back DRAM DDR_RB = 'U18' # right back DRAM # Length of SDRAM clock, it sets the maximum or equal needed for other traces CLOCK_LEN = pcbnew.FromMils( 2.25 * 1000 ) def addr_line_netname(line_no): """From an address line number, return the netname""" netname = '/DDR3/DRAM_A' + str(line_no) return netname # Establish GOALS which are LENs, TOLERANCEs and NETs for each group of nets. # Net Group: ADDR_AND_CMD ADDR_AND_CMD_LEN = pcbnew.FromMils( 2.22 * 1000 ) ADDR_AND_CMD_TOLERANCE = pcbnew.FromMils( 25 ) / 2 ADDR_AND_CMD_NETS = [addr_line_netname(a) for a in range(0,16)] ADDR_AND_CMD_NETS += [ '/DDR3/DRAM_SDBA0', '/DDR3/DRAM_SDBA1',
def FromInch(a): if isinstance(a, pcbnew.wxPoint): return pcbnew.wxPoint(pcbnew.FromMils(a.x * 1000.0), pcbnew.FromMils(a.y * 1000.0)) else: return pcbnew.FromMils(a * 1000.0)
def generate_gerbers(args): """ Generates Gerber output files from a Kicad PCB design. Uses the arguments constructed elsewhere in this script. """ pcb_file = sanitize(args.pcb_file) output_dir = sanitize(args.output_dir) board = pcbnew.LoadBoard(pcb_file) plotter = pcbnew.PLOT_CONTROLLER(board) options = plotter.GetPlotOptions() options.SetPlotFrameRef(False) options.SetPlotPadsOnSilkLayer(False) options.SetPlotValue(True) options.SetPlotReference(True) options.SetPlotInvisibleText(False) options.SetPlotViaOnMaskLayer(False) options.SetPlotPadsOnSilkLayer(False) options.SetExcludeEdgeLayer(True) options.SetUseAuxOrigin(True) options.SetUseGerberProtelExtensions(False) options.SetUseGerberAttributes(False) options.SetSubtractMaskFromSilk(True) options.SetLineWidth(pcbnew.FromMils(4)) options.SetGerberPrecision(6) # At the time of this writing, KiCAD appears to have some kind of bug # that prevents SetOutputDirectory() from accepting absolute paths. # As a result, this script creates a relative path to args.tempdir, # and uses that instead. path_components = [] result = os.path.split(args.pcb_file) while result[1] != "": path_components.append(result[1]) result = os.path.split(result[0]) rel_root = (os.path.pardir + os.path.sep) * (len(path_components) - 1) rel_root = rel_root[:-1 * len(os.path.sep)] tempdir = rel_root + args.tempdir options.SetOutputDirectory(tempdir) plot_plan = [ ("CuTop", pcbnew.F_Cu, "Top layer"), ("CuBottom", pcbnew.B_Cu, "Bottom layer"), ("PasteBottom", pcbnew.B_Paste, "Paste Bottom"), ("PasteTop", pcbnew.F_Paste, "Paste top"), ("SilkTop", pcbnew.F_SilkS, "Silk top"), ("SilkBottom", pcbnew.B_SilkS, "Silk top"), ("MaskBottom", pcbnew.B_Mask, "Mask bottom"), ("MaskTop", pcbnew.F_Mask, "Mask top"), ("EdgeCuts", pcbnew.Edge_Cuts, "Edges"), ("FabTop", pcbnew.F_Fab, "Fab drawing top"), ("FabBottom", pcbnew.B_Fab, "Fab drawing bottom"), ] for layer_info in plot_plan: plotter.SetLayer(layer_info[1]) plotter.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER, layer_info[2]) plotter.PlotLayer() if not os.path.isdir(output_dir): try: os.mkdir(output_dir) except OSError: err_msg = "Error: Couldn't make output directory [%s]" % output_dir sys.stderr.write(err_msg + "\n") return 1 for filename in os.listdir(args.tempdir): filename = os.path.join(args.tempdir, filename) if os.path.getsize(filename) != 0: shutil.copy(filename, output_dir) return 0
if (d.GetLayerName() != "Edge.Cuts"): continue if (boundingbox == None): boundingbox = d.GetBoundingBox() else: boundingbox.Merge(d.GetBoundingBox()) boundingbox.Inflate(-150000) #assume a 0.15mm line width return boundingbox gndnet = find_net("GND") set_all_pads_to_net(gndnet) pcboutline = find_pcb_outline_bbox() pcboutline.Inflate(-1 * pcbnew.FromMils(10)) leftside = pcboutline.GetLeft() rightside = pcboutline.GetRight() bottomside = pcboutline.GetBottom() topside = pcboutline.GetTop() print "Creating copper pour on GND: top={} bottom={} left={} right={}".format( topside / SCALE, bottomside / SCALE, leftside / SCALE, rightside / SCALE) zone_container = board.InsertArea(gndnet.GetNet(), 0, pcbnew.B_Cu, leftside, topside, pcbnew.CPolyLine.DIAGONAL_EDGE) shape_poly_set = zone_container.Outline() shape_poly_set.Append(leftside, bottomside) shape_poly_set.Append(rightside, bottomside) shape_poly_set.Append(rightside, topside) zone_container.SetPadConnection(pcbnew.PAD_ZONE_CONN_FULL)
raise IOError('Too many matches') return matches[0] return filename parser = argparse.ArgumentParser(description="""\ Modify kicad pcb file to place footprints like in the schematic. Your project needs to have a .kicad-pcb file with loaded netlist and footprint associations.""") parser.add_argument('project', nargs='?', help='Kicad project') parser.add_argument('--schematic', help='Input .sch file') parser.add_argument('--pcb', help='Input .kicad_pcb file') parser.add_argument( '--scale', type=float, default=pcbnew.FromMils(1), help='Distance scale factor from schematic to PCB (default 1)') args = parser.parse_args() if args.schematic and args.pcb: schfile = args.schematic pcbfile = args.pcb else: if os.path.isfile(args.project): # If the user passed the .pro file, extract the directory directory = os.path.dirname(args.project) project_name = os.path.basename(args.project) project_name = project_name[:project_name.rindex('.')] else: directory = args.project try:
def main(): kad.removeDrawings() kad.removeTracksAndVias() #PCB_Rect = map( lambda pt: (PCB_Width * pt[0], PCB_Height * pt[1]), FourCorners ) #kad.drawRect( PCB_Rect, 'Edge.Cuts', R = 40 ) drawEdgeCuts() zones = [] add_zone( 'GND', 'F.Cu', make_rect( (PCB_Width - 100, PCB_Height), (100, 0) ), zones ) add_zone( 'GND', 'B.Cu', make_rect( (PCB_Width - 500, PCB_Height), (500, 0)), zones ) add_zone( 'VCC', 'B.Cu', make_rect( (300, 100), (110, 110)), zones ) kad.add_text( (440, 405), 0, ' STM32\n F042K6\n tiny\n orihikarna\n200904', 'F.SilkS', (0.9, 0.9), 6, pcbnew.GR_TEXT_HJUSTIFY_LEFT, pcbnew.GR_TEXT_VJUSTIFY_CENTER ) ### ### Set mod positios ### kad.move_mods( (300, 350), 0, [ # Pin headers ('J1', (-250, +300), 90), ('J2', (-250, -300), 90), ('J3', (-250, -200), 0), # USB connector (None, (550, -5), 0, [ ('J4', (0, 0), -90), (None, (-40, -25), 0, [ ('R3', (0, -75), 0),# BOOT0 pull-down ('R8', (0, 0), 0), ('R9', (0, +75), 0), ] ), ] ), # BOOT0 (SW1) ('SW1', (525, -275), -90), # D1/D2 (None, (575, 230), 0, [ (None, (0, 0), 180, [ ('D1', (0, 0), 0), ('R1', (0, 0), 0) ] ), (None, (0, 75), 180, [ ('D2', (0, 0), 0), ('R2', (0, 0), 0) ] ), ] ), # mcu (None, (15, 0), 0, [ ('U1', (0, 0), -90), # pass caps (None, ( 235, -155), -90, [ ('C3', (0, 0), 0), ('C4', (0, 0), 0) ] ), (None, (-235, 155), +90, [ ('C5', (0, 0), 0), ('C6', (0, 0), 0) ] ), # Vcca pass caps (None, ( 90, -115), 0, [ ('C7', (0, 0), 0), ('C8', (0, -75), 0) ] ), ] ), # D3 ('D3', (-280, 150), 0), # NRST ('C9', (-100, -125), 180), # USB DM/DP (None, (164, 112.5), 0, [ ('R6', (0, 0), 180), ('R7', (-10, 75), 180) ] ), # I2C pull-up's (None, (-80, 155), 0, [ ('R4', (0, 0), 90), ('R5', (75, 0), 90) ] ), # regulators (None, (-40, 0), 0, [ ('U2', ( 0, 6), 90), ('C1', ( 104, 0), 90), ('C2', (-104, 0), 90), ('L1', ( 215, +37.5), 0), ('F1', ( 225, -37.5), 180), ] ), ] ) ### ### Wire mods ### # regulator via_reggnd1 = kad.add_via_relative( 'U2', '3', (-15, -48), VIA_Size[1] ) via_reggnd2 = kad.add_via_relative( 'U2', '3', (-15, +48), VIA_Size[1] ) kad.wire_mods( [ ('F1', '2', 'L1', '2', 24, (ZgZg, 0, 70, -20)), ('C1', '1', 'L1', '1', 24, (Strt)), ('U2', '1', 'C1', '1', 24, (Dird, 90, 0)),# 5V ('U2', '3', 'C1', '2', 24, (Dird, 90, 0)),# Gnd ('U2', '3', 'C2', '2', 24, (Dird, 90, 0)),# Gnd ('U2', '2', 'C2', '1', 24, (Dird, 90, 0)),# Vcc # Gnd (None, via_reggnd1, 'U2', '3', 24, (Dird, 0, 90)), (None, via_reggnd2, 'U2', '3', 24, (Dird, 0, 90)), (None, via_reggnd1, 'U2', '3', 24, (Dird, ([(35, 180)], 90), ([(50, 180)], 0), -32)), (None, via_reggnd2, 'U2', '3', 24, (Dird, ([(35, 180)], 90), ([(50, 180)], 0), -32)), ] ) # mcu via_vcca = kad.add_via_relative( 'U1', '5', (-65, 10), VIA_Size[0] ) kad.wire_mods( [ # mcu <--> Vcc x 2 ('U1', '1', 'C3', '1', 24, (ZgZg, 90, 45, -20)),# Vcc ('U1','32', 'C3', '2', 24, (Dird, 90, 0)),# Gnd ('U1','17', 'C5', '1', 24, (ZgZg, 90, 45, -20)),# Vcc ('U1','16', 'C5', '2', 24, (Dird, 90, 0)),# Gnd # Vcc <--> Vcc ('U1', '1', 'U1', '17', 20, (Dird, ([(33, 0), (80, -45), (80, -90)], 135), ([(33, 180), (80, 135)], 180), -16)),# Vcc # Vcca ('U1', '5', None, via_vcca, 24, (Dird, 0, 90)), ('C8', '1', None, via_vcca, 24, (Dird, 0, 90)), ('C7', '1', 'C8', '1', 24, (Strt)), ('C7', '2', 'C8', '2', 24, (Strt)), # Gnd ('C4', '2', 'C7', '2', 24, (Dird, 0, 0)), ('U1', via_reggnd1, 'U1', '32', 20, (Dird, 90, ([(33, -90)], 135), -16)), ('U1', via_reggnd2, 'U1', '16', 20, (Dird, 0, ([(33, +90)], -45), -16)), ] ) via_pads = [ ('C3', '1'), ('C3', '2'), ('C5', '1'), ('C5', '2'), ] for mod_name, pad_name in via_pads: kad.add_via_on_pad( mod_name, pad_name, VIA_Size[1] ) ## pin headers [(80, 45), (56, 90)] is a basic shape # J1 kad.wire_mods( [ # left B.Cu ('R4', '1', 'J1', '2', 20, (Dird, 0, -45, -16)),# PA9 ('R5', '1', 'J1', '3', 20, (Dird, 0, -45, -16)),# PA10 # left F.Cu ('U1','19', 'J1', '2', 20, (Dird, 0, ([(80, -45), (40, -90)], -45), -16)),# PA9 ('U1','20', 'J1', '3', 20, (Dird, 0, -45, -16)),# PA10 ('U1','23', 'J1', '4', 20, (Dird, 0, -45, -16)),# PA13 ('U1','24', 'J1', '5', 20, (Dird, 0, +45, -16)),# PA14 # right (separation = 30 mils, 30 * sin(22.5) = 11.48, (30 - 11.5) x 1.414 ~ 26.2) ('U1','26', 'J1', '6', 20, (Dird, ([(40, 90), (12, 45)], 0), 45, -16)),# PB3 ('U1','27', 'J1', '7', 20, (Dird, ([(40+11.5, 90), (12+26.2, 45)], 0), 45, -16)),# PB4 ('U1','28', 'J1', '8', 20, (Dird, ([(40+23.0, 90), (12+52.4, 45)], 0), ([(80, 45), (56, 90)], 45), -16)),# PB5 ] ) # J2 kad.wire_mods( [ ('U1', '9', 'J2', '1', 20, (Dird, 0, +45, -16)),# PA3 ('U1', '8', 'J2', '2', 20, (Dird, 0, +45, -16)),# PA2 (None, via_vcca, 'J2', '3', 24, (Dird, 45, 0), 'F.Cu'), (None, via_vcca, 'J2', '3', 24, (Dird, 90, 0), 'B.Cu'), ('U1', '4', 'J2', '4', 20, (ZgZg, 0, 25, -16)),# NRST ('U1', '3', 'J2', '5', 20, (Dird, 0, -45, -16)),# PF1 ('U1', '2', 'J2', '6', 20, (Dird, 0, ([(80, 135), (56, 90)], -45), -16)),# PF0 ] ) # J3 kad.wire_mods( [ ('U1', '13', 'J3', '3', 20, (Dird, -90, -45, -16)),# PA7 ('U1', '12', 'J3', '2', 20, (Dird, -90, ([(27, -90)], -45), -16)),# PA6 ('U1', '11', 'J3', '1', 20, (Dird, ([(33, -90)], 45), ([(25, -90), (75, -45)], -90), -16)),# PA5 ] ) # J4 (USB) via_cc1 = kad.add_via_relative( 'J4', 'A5', (+22, +70), VIA_Size[2] ) via_cc2 = kad.add_via_relative( 'J4', 'B5', (-22, +70), VIA_Size[2] ) kad.wire_mods( [ # VBUS A4 <--> B4 # ('J4', 'A4', 'J4', 'B4', 12.4, (Strt2, # [(-3.1, 0), (15, 90), (24, 60), (40, 90), (40, 45)], # [(+3.1, 0), (15, 90), (24, 120), (40, 90), (40, 135)], 5)), ('J4', 'A4', 'J4', 'B4', 20, (Strt2, [(-1.75, 0), (30, -90), (20, -62), (65, -90)], [(+1.75, 0), (30, -90), (20, -118), (65, -90)], -32)), # Vcc <--> D1 ('D1', '2', 'J4', 'B4', 20, (Dird, ([(100, 45)], 90), ([(+1.75, 0), (30, -90), (20, -118)], -90), -32)), # Gnd Shield ('J4', 'A1', 'J4', 'S1', 23.5, (Dird, 0, +45)), ('J4', 'B1', 'J4', 'S2', 23.5, (Dird, 0, -45)), ('J4', 'A1', 'J4', 'S1', 23.5, (Dird, ([(55, 90)], 0), 90, -20)), ('J4', 'B1', 'J4', 'S2', 23.5, (Dird, ([(55, 90)], 0), 90, -20)), ('J4', 'S1', 'J4', 'S4', 24, (Strt), 'B.Cu'), ('J4', 'S2', 'J4', 'S3', 24, (Strt), 'F.Cu'), ('C3', '2', 'J4', 'S1', 24, (Dird, 90, 45, -20), 'F.Cu'), ('J2', '7', 'J4', 'S1', 24, (Dird, 0, -45, -20), 'B.Cu'), ('R3', '2', 'J4', 'S4', 24, (Dird, 0, 0), 'F.Cu'), ('R9', '2', 'J4', 'S3', 24, (Dird, 0, 0), 'F.Cu'), ('R1', '2', 'J4', 'S3', 24, (Dird, 90, 90), 'F.Cu'), # DM/DP ('J4', 'A7', 'J4', 'B7', 11.72, (Strt2, [(50, +90)], [(50, +90)], -16)),# DM ('J4', 'A7', 'J4', 'B7', 11.72, (Strt2, [(50+30, +90), (-30, +90)], [(50, +90)], -16)),# DM ('J4', 'A6', 'J4', 'B6', 11.72, (Strt2, [(50, -90)], [(50, -90)], -16)),# DP # DM/DP <--> R6, R7 ('J4', 'A7', 'R6', '1', 11.72, (Dird, -90, ([(26, -90), (40, 180), (45, 90), (28, 135)], 90), -16)),# DM ('J4', 'B6', 'R7', '1', 11.72, (Dird, -90, ([(26, +90), (72, 180), (55, 90), (28, 135)], 90), -16)),# DP # Gnd: CC1/CC2/BOOT0 ('R8', '2', 'R9', '2', 20, (Strt)), ('R8', '2', 'R3', '2', 20, (Strt)), # CC1/CC2 (None, via_cc1, 'J4', 'A5', 11.72, (Dird, -90, ([(50, -90)], +135), -20)), (None, via_cc1, 'R8', '1', 16, (Dird, 0, 90, 25)), (None, via_cc2, 'J4', 'B5', 11.72, (Dird, -90, ([(50, -90)], -135), -20)), (None, via_cc2, 'R9', '1', 16, (Dird, 0, 90, 25)), ] ) # Vcc rounting kad.wire_mods( [ # C4 <--> C8 ('C4', '1', 'C8', '1', 24, (Dird, ([(46, 180)], 90), 90, -20)), # C2 <--> C6 ('C2', '1', 'C6', '1', 24, (Dird, ([(25, -90)], 0), -90, -20)), # C2 <--> C4 ('C4', '1', 'C2', '1', 24, (Dird, ([(46, 180)], 90), ([(50, -90)], 0), -20)),# Vcc ] ) # 5V routing kad.wire_mods( [ # regulator <--> I2C ('R5', '2', 'U2', '1', 24, (Dird, 0, 90)), # I2C pull-up's ('R4', '2', 'R5', '2', 24, (Strt)), # I2C <--> J1 ('R4', '2', 'J1', '1', 24, (Dird, ([(50, -90)], 180), ([(80, -45), (40, -90)], -45), -20), 'B.Cu'),# 5V ] ) # USB DM/DP <--> mcu via_dm = kad.add_via_relative( 'U1', '21', (-55, -26), VIA_Size[2] ) via_dp = kad.add_via_relative( 'U1', '22', ( 55, 4), VIA_Size[2] ) kad.wire_mods( [ (None, via_dm, 'U1', '21', 20, (Dird, 90, 0, -16)), (None, via_dp, 'U1', '22', 20, (Dird, 90, 0, -16)), (None, via_dm, 'R6', '2', 20, (Dird, 0, 90, -16)), (None, via_dp, 'R7', '2', 20, (Dird, 90, 0, -16)), ] ) # connections kad.wire_mods( [ # VBUS: J4 <--> Regulator/F1 ('J4', 'A4', 'F1', '1', 23.5, (Dird, ([(55, 90)], 0), ([(45, 180)], -45), -20)), # Gnd: J4/A1 <--> mcu/C4 ('J4', 'A1', 'C4', '2', 23.5, (Dird, 90, -45, -20)), # Gnd: Regulator/C1 <--> Vdda/C7 ('C1', '2', 'C7', '2', 24, (ZgZg, 90, 55, -20)), # BOOT0: mcu/PB8 <--> R3 ('U1', '31', 'R3', '1', 16, (Dird, ([(36, 90), (14, 45), (50, 90), (24, 135)], 90), 90, -12)), ] ) # NRST via_nrst = kad.add_via_relative( 'U1', '4', (55, 30), VIA_Size[2] ) kad.wire_mods( [ ('U1', '4', None, via_nrst, 16, (Dird, 0, 90, -12)), ('C9', '1', None, via_nrst, 16, (Dird, 90, 0)), # Gnd: C9 <--> Regulator/C2 ('C9', '2', 'C2', '2', 16, (Dird, 0, 0)), ] ) # BOOT0 via_sw1 = kad.add_via_relative( 'SW1', '1', (50, -40), VIA_Size[2] ) via_boot0 = kad.add_via_relative( 'SW1', '2', (0, -125), VIA_Size[2] ) kad.wire_mods( [ (None, via_boot0, 'SW1', '2', 16, (Dird, 90, 0, -12)), (None, via_boot0, 'R3', '1', 16, (ZgZg, 90, 45, -12)), (None, via_sw1, 'SW1', '1', 16, (Dird, 90, 0, -12)),# Vcc (None, via_sw1, 'C3', '1', 16, (ZgZg, 90, 60, -12)),# Vcc ] ) # D1/D2 via_pads = [ ('R1', '1'), ('R2', '1') ] for mod_name, pad_name in via_pads: kad.add_via_on_pad( mod_name, pad_name, VIA_Size[1] ) # D2 via_d2 = kad.add_via_relative( 'U1', '25', (135, 0), VIA_Size[1] ) kad.wire_mods( [ ('R1', '2', 'R2', '2', 20, (Strt)), (None, via_d2, 'U1', '25', 20, (Dird, 90, 0)),# PA15 (None, via_d2, 'D2', '2', 20, (Dird, 0, 45, -16)), ] ) # D3 via_d3 = kad.add_via_relative( 'D3', '3', (40, 62), VIA_Size[2] ) kad.wire_mods( [ ('D3', '4', 'J1', '1', 20, (Dird, ([(10, 0)], 90), 45, -16), 'B.Cu'),# 5V ('D3', '2', 'C5', '2', 20, (Dird, ([(10, 0)], 90), 90), 'F.Cu'),# Gnd (None, via_d3, 'D3', '3', 16, (Dird, 0, ([(10, 0)], 90), -16)), (None, via_d3, 'U1', '15', 16, (ZgZg, 90, 45, -16)), ] ) ### ### Ref ### refs = [ ('C1', 90, +40, 90), ('C2', 90, -40, 90), ('C3', -60, 70, 180), ('C4', 60,120, 180), ('C5', -60, 70, 180), ('C6', 60,-60, 180), ('C7', 90, 0, 90), ('C8', 90, 0, 90), ('C9', -90, 0, -90), ('R1', -15, 0, 0), ('R2', -15, 0, 0), ('R4', 60,120, 180), ('R5', -60, 60, 180), ('R6', -100, 0, -90), ('R7', -100, 0, -90), ('L1', 100, 0, 90), ('F1', -100, 0, -90), ('R3', 100, 0, 90), ('R8', 100, 0, 90), ('R9', 100, 0, 90), ('U1', 120, 135, 0), ('U2', 0, 0, -90), ('D1', 15, 0, 0), ('D2', 15, 0, 0), ('D3', 50, 90, -90), ('SW1', 0, 0, -90), ('J1', 0, 0, None), ('J2', 0, 0, None), ('J3', 0, 0, None), ] for mod_name, offset_length, offset_angle, text_angle in refs: mod = kad.get_mod( mod_name ) pos, angle = kad.get_mod_pos_angle( mod_name ) ref = mod.Reference() if text_angle == None: ref.SetVisible( False ) else: ref.SetTextSize( pcbnew.wxSizeMM( 0.9, 0.9 ) ) ref.SetThickness( pcbnew.FromMils( 7 ) ) pos_ref = vec2.scale( offset_length, vec2.rotate( - (offset_angle + angle) ), pos ) ref.SetPosition( pnt.mils2unit( vec2.round( pos_ref ) ) ) ref.SetTextAngle( text_angle * 10 ) ref.SetKeepUpright( False ) refs = [ ('J3', (0, 90), (90, 0), [ ('1', 'A5', 'SCK'), ('2', 'A6', 'MISO'), ('3', 'A7', 'MOSI'), ] ), ('J2', (90, 0), (0, 90), [ ('1', 'A3', 'RX'), ('2', 'A2', 'TX'), ('3', 'nRST', 'nRST'), ('4', 'F1', 'F1'), ('5', 'F0', 'F0'), ('6', 'GND', 'GND'), ('7', '3V3', '3V3'), ] ), ('J1', (-90, 180), (0, -90), [ ('1', '5V', '5V'), ('2', 'A9', 'SCL'), ('3', 'A10', 'SDA'), ('4', 'A13', 'DIO'), ('5', 'A14', 'CLK'), ('6', 'B3', 'SCK'), ('7', 'B4', 'MISO'), ('8', 'B5', 'MOSI'), ] ), ] for mod, angles1, angles2, pads in refs: for pad, text1, text2 in pads: pos = kad.get_pad_pos( mod, pad ) angle_pos1, angle_text1 = angles1 angle_pos2, angle_text2 = angles2 for idx, layer in enumerate( ['F.SilkS', 'B.SilkS'] ): pos1 = vec2.scale( [65, 65][idx], vec2.rotate( angle_pos1 ), pos ) pos2 = vec2.scale( 50, vec2.rotate( angle_pos2 ), pos ) kad.add_text( pos1, angle_text1, text1, layer, (0.7, 0.7), 6, pcbnew.GR_TEXT_HJUSTIFY_CENTER, pcbnew.GR_TEXT_VJUSTIFY_CENTER ) kad.add_text( pos2, angle_text2, text2, layer, (0.7, 0.7), 6, pcbnew.GR_TEXT_HJUSTIFY_CENTER, pcbnew.GR_TEXT_VJUSTIFY_CENTER ) pos, angle = kad.get_mod_pos_angle( 'SW1' ) kad.add_text( pos, angle + 90, 'BOOT0', 'F.SilkS', (0.85, 0.65), 6, pcbnew.GR_TEXT_HJUSTIFY_CENTER, pcbnew.GR_TEXT_VJUSTIFY_CENTER ) pcbnew.Refresh()