Beispiel #1
0
 def npth(self, diameter, x, y):
     """put a npth in pcb with given diameter and location"""
     module = pcbnew.FOOTPRINT(self.pcb)
     npth = pcbnew.PAD(module)
     npth.SetAttribute(pcbnew.PAD_ATTRIB_NPTH)
     npth.SetShape(pcbnew.PAD_SHAPE_CIRCLE)
     npth.SetSize(pcbnew.wxSizeMM(diameter, diameter))
     npth.SetDrillShape(pcbnew.PAD_DRILL_SHAPE_CIRCLE)
     npth.SetDrillSize(pcbnew.wxSizeMM(diameter, diameter))
     module.Add(npth)
     self.pcb.Add(module)
     loc = pcbnew.wxPointMM(x, y)
     module.SetPosition(loc)
Beispiel #2
0
def add_text(pos,
             angle,
             string,
             layer='F.SilkS',
             size=(1, 1),
             thick=5,
             hjustify=None,
             vjustify=None):
    text = pcbnew.TEXTE_PCB(pcb)
    text.SetPosition(pnt.to_unit(vec2.round(pos, PointDigits), UnitMM))
    text.SetTextAngle(angle * 10)
    text.SetText(string)
    text.SetLayer(pcb.GetLayerID(layer))
    text.SetTextSize(pcbnew.wxSizeMM(size[0], size[1]))
    text.SetThickness(scalar_to_unit(thick, UnitMM))
    text.SetMirrored(layer[0] == 'B')
    if hjustify != None:
        text.SetHorizJustify(hjustify)
    if vjustify != None:
        text.SetVertJustify(vjustify)
    pcb.Add(text)
    return text
Beispiel #3
0
 def _setVCutLabelStyle(self, label, layer):
     label.SetText("V-CUT")
     label.SetLayer(layer)
     label.SetTextThickness(fromMm(0.4))
     label.SetTextSize(pcbnew.wxSizeMM(2, 2))
     label.SetHorizJustify(EDA_TEXT_HJUSTIFY_T.GR_TEXT_HJUSTIFY_LEFT)
Beispiel #4
0
def _size_mm(x, y):
    """Convert size in mm to internal size"""
    return pcbnew.wxSizeMM(float(x), float(y))
Beispiel #5
0
def _size_mm(x, y):
    """Convert size in mm to internal size"""
    return pcbnew.wxSizeMM(float(x), float(y))
Beispiel #6
0
def main():
    kad.removeDrawings()
    kad.removeTracksAndVias()

    # board type
    filename = pcb.GetFileName()
    boardname = filename[filename.find('Zoea') + 4]
    # print( filename, boardname )
    for bname, btype in [('L', BZL), ('R', BZR), ('T', BZT), ('B', BZB),
                         ('M', BZM)]:
        if boardname == bname:
            board = btype
            if board in [BZL, BZR, BZM]:
                kad.add_text((PCB_Width / 2, 1.5), 0,
                             'Zoea{} by orihikarna 20/09/04'.format(bname),
                             'F.SilkS' if board != BZR else 'B.SilkS', (1, 1),
                             0.15, pcbnew.GR_TEXT_HJUSTIFY_CENTER,
                             pcbnew.GR_TEXT_VJUSTIFY_CENTER)
            break

    drawEdgeCuts(board)

    ### zones
    zones = []
    if board in [BZL, BZR, BZM]:
        add_zone('GND', 'F.Cu', make_rect((PCB_Width, PCB_Height), (0, 0)),
                 zones)
        add_zone('GND', 'B.Cu', make_rect((PCB_Width, PCB_Height), (0, 0)),
                 zones)

    ###
    ### Set key positios
    ###
    sw_pos_angles = []
    for idx, key in enumerate(keys):
        _, x, y, angle = key
        name = get_key_postfix(idx)
        if idx == 4:  # SWB1
            px = x * KeyUnit
            py = PCB_Height - y * KeyUnit
        else:
            px = (x - 0.5) * KeyUnit - 2.5 + PCB_Width
            py = (y + 0.5) * KeyUnit + 2.5
        if board == BZR:
            angle += 180  # back side
        sw_pos = (px, py)
        sw_pos_angles.append((sw_pos, angle))

        # SW & LED & Diode
        if board in [BZL, BZR]:
            sign = [+1, -1][board]
            ## SW
            kad.set_mod_pos_angle('SW' + name, sw_pos, 180 - angle)
            ## LED
            pos = vec2.scale(4.93, vec2.rotate(90 * sign + angle), sw_pos)
            kad.set_mod_pos_angle('L' + name, pos, -angle)
            if True:  # LED holes
                corners = []
                for i in range(4):
                    deg = i * 90 + angle
                    pt = vec2.scale([3.6, 3.2][i % 2] / 2.0, vec2.rotate(deg),
                                    pos)
                    corners.append([(pt, deg + 90), BezierRound, [0.2]])
                kad.draw_closed_corners(corners, 'Edge.Cuts', 0.1)
            # wire LED GND to SW's fixed pin
            kad.wire_mods([('L' + name, '3', 'SW' + name, '3', 0.6,
                            (Dird, 0, 90, -1), ['F.Cu', 'B.Cu'][board])])
            # LED pass caps
            pos = vec2.mult(mat2.rotate(-angle), (0, 7.5 * sign), sw_pos)
            kad.set_mod_pos_angle('CL' + name, pos, -angle)
            kad.wire_mods([
                ('CL' + name, '1', 'L' + name, '1', 0.6, (Dird, 0, 90, -0.6)),
                ('CL' + name, '2', 'SW' + name, '3', 0.6, (Dird, ([(0.5, -45)],
                                                                  0), 90, -1)),
            ])
            ## Diode
            Dx = 8.6 * sign
            Dy = 0.6 * sign
            if (board == BZL and idx < 2) or (board == BZR and idx < 3):
                pos = vec2.mult(mat2.rotate(-angle), (-Dx, Dy), sw_pos)
                kad.set_mod_pos_angle('D' + name, pos, -90 * sign - angle)
                # wire to SW
                kad.wire_mods([('D' + name, '1', 'SW' + name, '2', 0.5,
                                (Dird, 0, 0, -1))])
            elif idx < 4:
                pos = vec2.mult(mat2.rotate(-angle), (+Dx, Dy), sw_pos)
                kad.set_mod_pos_angle('D' + name, pos, -90 * sign - angle)
                # wire to SW
                kad.wire_mods([('D' + name, '1', 'SW' + name, '2', 0.5,
                                (Dird, 0, 0, -1))])

    if board in [BZT, BZB]:
        draw_top_bottom(board, sw_pos_angles)

    ###
    ### Set mod positios
    ###
    if board == BZL:
        kad.move_mods(
            (0, 0),
            0,
            [
                # mcu
                (
                    None,
                    (PCB_Width / 2, 28),
                    0,
                    [
                        ('U1', (0, 0), 0),
                        # pass caps
                        (None, (-5.8, -4.2), 0, [
                            ('C3', (0, -0.2), 0),
                            ('C5', (-2.9, 0), 90),
                        ]),
                        # C4 & regulators
                        (None, (6.8, 3.3), -90, [
                            ('C4', (0, 0), 0),
                            (None, (0, -4.7), 0, [
                                ('C1', (0, -2.7), 0),
                                ('U2', (-0.25, 0), 0),
                                ('C2', (0, +2.7), 0),
                            ]),
                        ]),
                        # NRST
                        ('C6', (-7.5, 4.2), 180),
                        # R1
                        ('R1', (-7.5, 2.2), 180),
                        # USB DM/DP
                        ('R4', (8.5, +0.2), 180),
                        ('R5', (8.5, -1.8), 180),
                    ]),
                # I2C pull-ups
                (None, (2.62, PCB_Height / 2), 0, [
                    ('R2', (12, -1.9), +90),
                    ('R3', (12, +1.9), -90),
                ]),
                # USB (PC) connector
                (None, (PCB_Width - 2.62, J2_y), 0, [
                    ('J2', (0, 0), 90),
                    ('R8', (-7.5, +5.2), 0),
                    ('R9', (-7.5, -5.2), 0),
                    ('F1', (-12, -3), 90),
                    ('L1', (-14, -3), 90),
                ]),
                # Pin headers
                ('J3', (J3_x, PCB_Height * 2 / 3 - 1.27), 90),
                # D0
                ('D0', (73, 25.4), 180),
            ])
    elif board == BZR:
        kad.move_mods(
            (PCB_Width / 2, 28.5),
            0,
            [
                # expander
                ('U1', (0, 0), -90),
                ('C1', (6.5, -2.8), 90),
                # R1
                ('R1', (-7.5, 3.2), 0),
            ])
        kad.move_mods(
            (0, 0),
            0,
            [
                # Pin headers
                ('J3', (J3_x + 1.27, PCB_Height * 2 / 3 - 1.27), 90),
            ])
    if board in [BZL, BZR]:
        # Debounce
        pos, angle = kad.get_mod_pos_angle('SW14')
        kad.move_mods(pos, angle + [0, 180][board], [
            (None, (+9.6, 3.9), 0, [
                ('C11', (0, -2), 0),
                ('R11', (0, 0), 0),
                ('R12', (0, +2), 0),
            ]),
        ])
        pos, angle = kad.get_mod_pos_angle('SWB1')
        kad.move_mods(pos, angle + [0, 180][board], [
            (None, (-9.6, 5.9), 0, [
                ('CB1', (0, -2), 180),
                ('RB1', (0, 0), 180),
                ('RB2', (0, +2), 180),
            ]),
        ])
        # Split (USB) connector
        sign = [+1, -1][board]
        kad.move_mods((0, J1_y), 0, [
            (None, (2.62, 0), 0, [
                ('J1', (0, 0), -90 * sign),
                ('R6', (7.5, -5.2 * sign), 180),
                ('R7', (7.5, +5.2 * sign), 180),
            ]),
        ])
        # D1
        kad.move_mods((0, 0), 0, [
            ('D1', (D1_x, PCB_Height * 2 / 3 - 1.2), 180),
        ])

    ###
    ### Wire mods
    ###
    # COL lines
    if board in [BZL, BZR]:
        kad.wire_mods([
            ('SW14', '1', 'SW13', '1', 0.5, (Dird, 0, 0, -5)),
            ('SW13', '1', 'SW12', '1', 0.5, (Dird, 0, 90, -1)),
            ('SW12', '1', 'SW11', '1', 0.5, (Dird, 0, 90, -9)),
        ])
    # ROW lines
    if board == BZL:
        kad.wire_mods([
            ('D11', '2', 'U1', '26', 0.5, (Dird, ([(2, -90)], 45),
                                           ([(1.4, 90)], 0), -0.8)),
            ('D12', '2', 'U1', '27', 0.5, (Dird, 0, ([(2.2, 90)], 0), -1.4)),
            ('D13', '2', 'U1', '28', 0.5, (Dird, 0, ([(3.0, 90)], 0), -1.4)),
            ('D14', '2', 'U1', '29', 0.5, (Dird, 0, ([(3.1, 90)], 0), -1.4)),
            ('C11', '2', 'U1', '30', 0.5, (Dird, 90, ([(2.3, 90), (12.0, 180),
                                                       (3, -135)], 0), -0.8)),
        ])
    elif board == BZR:
        kad.wire_mods([
            ('D11', '2', 'U1', '5', 0.45, (Dird, ([(6, 0), (14, 90)], -45),
                                           ([(2.2, 180)], -90), -1)),
            ('D12', '2', 'U1', '4', 0.45, (Dird, 0, ([(3.0, 180)], 90), -1.6)),
            ('D13', '2', 'U1', '3', 0.45, (Dird, 0, ([(3.0, 180)], 90), -1.6)),
            ('D14', '2', 'U1', '2', 0.45, (Dird, 0, ([(2.2, 180)], 90), -1.0)),
            ('RB1', '2', 'U1', '22', 0.45, (Dird, 0, ([(2.0, 180)], 90),
                                            -0.8)),
        ])
    # Split (USB) connector
    if board in [BZL, BZR]:
        via_splt_vba = kad.add_via_relative('J1', 'A4', (-0.4, -5.8),
                                            VIA_Size[1])
        via_splt_vbb = kad.add_via_relative('J1', 'B4', (+0.4, -5.8),
                                            VIA_Size[1])
        via_splt_cc1 = kad.add_via_relative('J1', 'A5', (-0.15, -2.4),
                                            VIA_Size[3])
        via_splt_cc2 = kad.add_via_relative('J1', 'B5', (+0.15, -3.2),
                                            VIA_Size[3])
        via_splt_dpa = kad.add_via_relative('J1', 'A6', (-0.5, -4.8),
                                            VIA_Size[3])
        via_splt_dpb = kad.add_via_relative('J1', 'B6', (+0.15, -4.8),
                                            VIA_Size[3])
        via_splt_dma = kad.add_via_relative('J1', 'A7', (+0.15, -4.0),
                                            VIA_Size[3])
        via_splt_dmb = kad.add_via_relative('J1', 'B7', (-0.15, -4.1),
                                            VIA_Size[3])
        via_splt_sb1 = kad.add_via_relative('J1', 'A8', (+0.15, -2.4),
                                            VIA_Size[3])
        via_splt_sb2 = kad.add_via_relative('J1', 'B8', (-0.15, -3.2),
                                            VIA_Size[3])
        via_r6_cc1 = kad.add_via_relative('R6', '1', (0, -1.4), VIA_Size[3])
        via_r7_cc2 = kad.add_via_relative('R7', '1', (0, +1.4), VIA_Size[3])
        kad.wire_mods([
            # gnd
            ('J1', 'S1', 'J1', 'S2', 0.8, (Dird, ([(0.8, 45)], 0), -45), 'Opp'
             ),
            # vbus
            ('J1', via_splt_vba, 'J1', 'A4', 0.8, (Dird, +60, ([(1.6, 90),
                                                                (0.5, 135)],
                                                               90))),
            ('J1', via_splt_vbb, 'J1', 'B4', 0.8, (Dird, -60, ([(1.6, 90),
                                                                (0.5, 45)],
                                                               90))),
            ('J1', via_splt_vba, 'J1', via_splt_vbb, 0.8, (Strt), 'Opp'),
            # dm/dp = I2C
            ('J1', via_splt_dpa, 'J1', 'A6', 0.3, (Dird, 90, ([(3.52, 90)],
                                                              -45), -0.1)),
            ('J1', via_splt_dpb, 'J1', 'B6', 0.3, (Dird, 0, 90)),
            ('J1', via_splt_dpa, 'J1', via_splt_dpb, 0.4, (Strt), 'Opp'),
            ('J1', via_splt_dma, 'J1', 'A7', 0.3, (Dird, 0, 90)),
            ('J1', via_splt_dmb, 'J1', 'B7', 0.3, (Dird, 0, 90)),
            ('J1', via_splt_dma, 'J1', via_splt_dmb, 0.4, (Dird, 0, -45, -0.6),
             'Opp'),
            # cc1/2
            ('J1', via_splt_cc1, 'J1', 'A5', 0.3, (Dird, 0, 90)),
            ('J1', via_splt_cc2, 'J1', 'B5', 0.3, (Dird, 0, 90)),
            ('J1', via_splt_cc1, 'J1', via_r6_cc1, 0.4, (Dird, -45, 0, -0.6),
             'Opp'),
            ('J1', via_splt_cc2, 'J1', via_r7_cc2, 0.4, (Dird, +45, 0, -0.6),
             'Opp'),
            ('J1', via_r6_cc1, 'R6', '1', 0.4, (Dird, 45, 90)),
            ('J1', via_r7_cc2, 'R7', '1', 0.4, (Dird, 45, 90)),
            ('R6', '2', 'J1', 'A1', 0.8, (Dird, 90, ([(1.1, 90)], -45))),
            ('R7', '2', 'J1', 'B1', 0.8, (Dird, 90, ([(1.1, 90)], +45))),
            ('R6', '2', 'J1', 'S1', 0.8, (Dird, 90, 90)),
            ('R7', '2', 'J1', 'S2', 0.8, (Dird, 90, 90)),
            # sbu = LED
            ('J1', via_splt_sb1, 'J1', 'A8', 0.3, (Dird, 0, 90)),
            ('J1', via_splt_sb2, 'J1', 'B8', 0.3, (Dird, 0, 90)),
            ('J1', via_splt_sb1, 'J1', via_splt_sb2, 0.4, (Dird, 0, -45, -0.6),
             'Opp'),
        ])
    if board == BZL:
        # USB (PC) connector
        via_usb_vba = kad.add_via_relative('J2', 'A4', (+0.5, -5.0),
                                           VIA_Size[1])
        via_usb_vbb = kad.add_via_relative('J2', 'B4', (-0.5, -5.0),
                                           VIA_Size[1])
        via_usb_cc1 = kad.add_via_relative('J2', 'A5', (-0.15, -2.4),
                                           VIA_Size[3])
        via_usb_cc2 = kad.add_via_relative('J2', 'B5', (+0.15, -2.4),
                                           VIA_Size[3])
        via_usb_dpa = kad.add_via_relative('J2', 'A6', (-0.5, -4.0),
                                           VIA_Size[3])
        via_usb_dpb = kad.add_via_relative('J2', 'B6', (+0.15, -4.0),
                                           VIA_Size[3])
        via_usb_dma = kad.add_via_relative('J2', 'A7', (+0.15, -3.2),
                                           VIA_Size[3])
        via_usb_dmb = kad.add_via_relative('J2', 'B7', (-0.15, -3.2),
                                           VIA_Size[3])
        via_r8_cc1 = kad.add_via_relative('R8', '1', (0, -1.4), VIA_Size[3])
        via_r9_cc2 = kad.add_via_relative('R9', '1', (0, +1.4), VIA_Size[3])
        kad.wire_mods([
            # vbus
            ('J2', via_usb_vba, 'J2', 'A4', 0.8, (Dird, +60, ([(1.6, 90),
                                                               (0.5, 135)],
                                                              90))),
            ('J2', via_usb_vbb, 'J2', 'B4', 0.8, (Dird, -60, ([(1.6, 90),
                                                               (0.5, 45)],
                                                              90))),
            ('J2', via_usb_vba, 'J2', via_usb_vbb, 0.8, (Strt), 'Opp'),
            # dm/dp
            ('J2', via_usb_dpa, 'J2', 'A6', 0.3, (Dird, 90, ([(2.4, 90)], -45),
                                                  -0.2)),
            ('J2', via_usb_dpb, 'J2', 'B6', 0.3, (Dird, 0, 90)),
            ('J2', via_usb_dpa, 'J2', via_usb_dpb, 0.4, (Strt), 'Opp'),
            ('J2', via_usb_dma, 'J2', 'A7', 0.3, (Dird, 0, 90)),
            ('J2', via_usb_dmb, 'J2', 'B7', 0.3, (Dird, 0, 90)),
            ('J2', via_usb_dma, 'J2', via_usb_dmb, 0.4, (Dird, 90, 0), 'Opp'),
            ('J2', via_usb_dpb, 'R5', '1', 0.5,
             (Dird, ([(7.0, 90)], 45), ([(-1, 0), (-0.8, -45)], 0), -0.3)),
            ('J2', via_usb_dmb, 'R4', '1', 0.5,
             (Dird, ([(8.2, 90)], 45), ([(-1, 0), (-0.8, +45)], 0), -0.3)),
            # cc1/2
            ('J2', via_usb_cc1, 'J2', 'A5', 0.3, (Dird, 0, 90)),
            ('J2', via_usb_cc2, 'J2', 'B5', 0.3, (Dird, 0, 90)),
            ('J2', via_usb_cc1, 'J2', via_r8_cc1, 0.4, (Dird, -45, 0, -0.6),
             'Opp'),
            ('J2', via_usb_cc2, 'J2', via_r9_cc2, 0.4, (Dird, +45, 0, -0.6),
             'Opp'),
            ('J2', via_r8_cc1, 'R8', '1', 0.4, (Dird, 45, 90)),
            ('J2', via_r9_cc2, 'R9', '1', 0.4, (Dird, 45, 90)),
            ('R8', '2', 'J2', 'A1', 0.8, (Dird, 90, ([(1.1, 90)], -45))),
            ('R9', '2', 'J2', 'B1', 0.8, (Dird, 90, ([(1.1, 90)], +45))),
            ('R8', '2', 'J2', 'S1', 0.8, (Dird, 90, 90)),
            ('R9', '2', 'J2', 'S2', 0.8, (Dird, 90, 90)),
        ])
    # J1/J2
    if board == BZL:
        kad.wire_mods([
            # I2C pull-ups
            ('J1', via_splt_vba, 'R2', '2', 0.8, (Dird, -45, 90)),
            ('J1', via_splt_vbb, 'R3', '2', 0.8, (Dird, +45, 90)),
            ('J1', via_splt_dmb, 'R2', '1', 0.4, (Dird, 90, ([(1.2, +90)],
                                                             -45), -0.6)),
            ('J1', via_splt_dpb, 'R3', '1', 0.4, (Dird, 90, ([(1.2, -90)],
                                                             +45), -0.6)),
            # VBUS
            ('F1', '1', 'J2', via_usb_vbb, 0.6, (Dird, 0, 90)),
            ('F1', '2', 'L1', '2', 0.6, (Dird, 0, 90)),
        ])
    elif board == BZR:
        via_scl = kad.add_via_relative('U1', '12', (2.8 - 0.2, -0.2),
                                       VIA_Size[3])
        via_sda = kad.add_via_relative('U1', '13', (3.6 - 0.2, -0.2),
                                       VIA_Size[3])
        kad.wire_mods([
            # 5v
            ('J1', via_splt_vbb, 'C11', '1', 0.5, (Dird, ([(9, 90)], 0), 90,
                                                   -0.8)),
            ('J1', via_splt_vbb, 'C11', '1', 0.5, (Dird, ([(11, 90), (-2, 90)],
                                                          0), 90, -0.8)),
            ('J1', via_splt_vba, 'SWB1', '2', 0.6, (Dird, 90, 90, -1)),
            # dm/dp = I2C
            ('U1', via_sda, 'U1', '13', 0.45, (Dird, 45, 0, -1)),
            ('U1', via_scl, 'U1', '12', 0.45, (Dird, 45, 0, -1)),
            ('J1', via_splt_dmb, 'U1',
             via_sda, 0.45, (Dird, ([(2, 90)], 45), ([(0.2, 0), (19.4, 90),
                                                      (1.2, 135)], 90), -1)),
            ('J1', via_splt_dpb, 'U1',
             via_scl, 0.45, (Dird, ([(1, 90)], 45), ([(0.2, 0), (18.4, 90),
                                                      (1.2, 135)], 90), -1)),
        ])
    # J3 Gnd
    if board in [BZL, BZR]:
        via_gnd = kad.add_via_relative('J3', '1', (0, -4), VIA_Size[3])
        kad.wire_mods([
            # J3 GND
            ('J3', '1', 'J3', via_gnd, 0.5, (Strt), ['B.Cu', 'F.Cu'][board]),
        ])
        pcb.Delete(via_gnd)
    if board == BZL:
        # mcu
        via_vcca1 = kad.add_via_relative('U1', '1', (-3.0, -0.15), VIA_Size[2])
        via_vcca5 = kad.add_via_relative('U1', '5', (-3.0, +0.0), VIA_Size[2])
        via_nrst = kad.add_via_relative('U1', '4', (-1.6, 0), VIA_Size[3])
        via_swdio = kad.add_via_relative('U1', '23', (-4.0, 0.8), VIA_Size[3])
        via_swclk = kad.add_via_relative('U1', '24', (-4.8, 0.8), VIA_Size[3])
        VCC = pcb.FindNet('VCC')
        via_u1_ctr = kad.add_via(
            kad.get_mod_pos_angle('U1')[0], VCC, VIA_Size[1])
        kad.wire_mods([
            # pass caps
            ('C4', '1', 'U1', '17', 0.5, (ZgZg, 90, 45)),
            ('C4', '2', 'U1', '16', 0.5, (Dird, 90, 90, -1)),
            ('C3', '1', 'U1', '1', 0.5, (Dird, -45, 0, -0.6)),
            ('C3', '2', 'U1', '32', 0.5, (Dird, 0, 90, -1)),
            ('C3', '2', 'C5', '2', 0.5, (Dird, ([(1.25, 90)], 0), -45, -1)),
            # regulator
            ('U2', '1', 'C1', '1', 0.6, (ZgZg, 90, 30)),  # 5V
            ('U2', '3', 'C1', '2', 0.6, (ZgZg, 90, 30, -1)),  # Gnd
            ('U2', '3', 'C2', '2', 0.6, (ZgZg, 90, 30, -1)),  # Gnd
            ('U2', '2', 'C2', '1', 0.6, (ZgZg, 90, 30)),  # Vcc
            #
            ('C4', '1', 'C2', '1', 0.6, (Dird, 0, 90)),  # Vcc
            ('C4', '2', 'C2', '2', 0.6, (Dird, 0, 90)),  # Gnd
            # VCC
            ('U1', '1', None, via_u1_ctr, 0.5, (Dird, 0, -45, -0.4)),
            ('U1', '17', None, via_u1_ctr, 0.5, (Dird, 0, -45, -0.4)),
            ('U1', '5', None, via_u1_ctr, 0.5, (Dird, 0, -45)),
            # VCCA
            ('U1', '5', None, via_vcca5, 0.5, (Strt)),
            ('C5', '1', None, via_vcca1, 0.5, (Dird, 45, 90)),
            ('U1', via_vcca1, None, via_vcca5, 0.6, (Strt), 'B.Cu'),
            # USB
            ('U1', '21', 'R4', '2', 0.5, (Dird, 0, ([(1, 0)], -45), -0.3)),
            ('U1', '22', 'R5', '2', 0.5, (Dird, 0, ([(1, 0)], +45), -0.3)),
            # I2C pull-up's
            ('U1', '2', 'R2', '1', 0.5, (Dird, 180, ([(-2, 90), (1.4, -45),
                                                      (-12.5, 90)], -45), -0.8)
             ),
            ('U1', '3', 'R3', '1', 0.5, (Dird, 180, ([(+2, 90), (2.4, 135),
                                                      (+12, 90)], -45), -0.8)),
            # NRST
            ('U1', '4', None, via_nrst, 0.4, (Strt)),
            ('J3', '2', None, via_nrst, 0.4, (Dird, ([(1.4, 0)], 90), 0, -1),
             'B.Cu'),
            ('J3', '2', 'C6', '1', 0.4, (Dird, ([(1.4, 0)], 90), 90, -1)),
            # SWCLK/DIO
            ('U1', '23', None, via_swdio, 0.4, (Dird, 0, 45, -0.4)),
            ('U1', '24', None, via_swclk, 0.4, (Dird, 0, 45, -0.4)),
            ('J3', '3', 'U1', via_swclk, 0.4,
             (Dird, ([(2.2, 0)], 90), ([(2.0, -135)], 90), -1), 'B.Cu'),
            ('J3', '4', 'U1', via_swdio, 0.4,
             (Dird, ([(3.0, 0)], 90), ([(1.6, -135)], 90), -1), 'B.Cu'),
            # TX/RX
            ('J3', '5', 'U1', '8', 0.4, (Dird, ([(2.2, 0)], 90), 90, -1)),
            ('J3', '6', 'U1', '9', 0.4, (Dird, ([(3.0, 0)], 90), 90, -1)),
            # D1
            ('U1', '7', 'R1', '1', 0.5, (Dird, 0, 90, -1)),
            ('R1', '2', 'D1', '2', 0.5, (Dird, 0, 90, -1)),
            ('J3', '1', 'D1', '1', 0.5, (Dird, 0, 0, -1)),
        ])
        pcb.Delete(via_u1_ctr)
    elif board == BZR:
        # mcp23017
        via_u1_vcc = kad.add_via_relative('U1', '9', (1.8, 0), VIA_Size[2])
        via_u1_vcc2 = kad.add_via_relative('U1', '9', (1.8, 4), VIA_Size[2])
        via_u1_nrst = kad.add_via_relative('U1', '9', (4.5, 0), VIA_Size[3])
        via_led_u1 = kad.add_via_relative('U1', '1', (0, -2), VIA_Size[2])
        via_led_d1 = kad.add_via_relative('D1', '2', (0, -5), VIA_Size[2])
        kad.wire_mods([
            # Gnd
            ('U1', '15', 'U1', '17', 0.45, (Strt)),
            # pass caps
            ('U1', via_u1_vcc2, 'C1', '1', 0.45, (Dird, 90, 0)),
            ('U1', '10', 'C1', '2', 0.45, (Dird, ([(1.4, 180)], 90), 0, -0.4)),
            # NRST
            ('U1', via_u1_nrst, 'U1', '18', 0.4, (Dird, -45, 0, -0.4)),
            ('U1', via_u1_vcc, 'U1', '9', 0.45, (Dird, -45, 0, -0.2)),
            ('U1', via_u1_vcc, 'U1', via_u1_vcc2, 0.5, (Strt), 'Opp'),
            ('U1', via_u1_vcc, 'U1', via_u1_nrst, 0.4, (Dird, 0, 90, -0.6),
             'Opp'),
            # Vcc
            ('U1', via_u1_vcc, 'J1', via_splt_vbb, 0.5,
             (Dird, ([(0.2, 0)], 90), ([(21, 90)], -45), -1)),
            # D1
            ('R1', '1', 'D1', '1', 0.5, (ZgZg, 90, 45, -0.8)),
            ('U1', '1', 'U1', via_led_u1, 0.45, (Dird, 90, 0)),
            ('D1', '2', 'D1', via_led_d1, 0.45, (Dird, 90, 0)),
            ('U1', via_led_u1, 'D1', via_led_d1, 0.5, (Dird, 90, 90, -0.8),
             'Opp'),
            # J3
            ('J3', '3', 'U1', via_scl, 0.45, (Dird, -45, ([(0.4, 45)], 0), -1)
             ),
            ('J3', '4', 'U1', via_sda, 0.45, (Dird, 45, 0, -1)),
            ('J3', '5', 'U1', via_u1_vcc2, 0.5, (ZgZg, 0, 45, -1)),
        ])
    # Debounce (common, internal)
    if board in [BZL, BZR]:
        kad.wire_mods([
            # COL1
            ('R11', '1', 'R12', '1', 0.5, (Strt)),
            ('R11', '2', 'C11', '2', 0.5, (Strt)),
            # BOOT0
            ('RB1', '1', 'RB2', '1', 0.5, (Strt)),
            ('RB1', '2', 'CB1', '2', 0.5, (Strt)),
            # SW14
            ('R12', '1', 'SW14', '1', 0.5, (Dird, 0, 90)),
            # SWB1
            ('RB1', '1', 'SWB1', '1', 0.5, (Dird, 0, 90)),
            ('CB1', '1', 'SWB1', '2', 0.6, (Dird, 90, 0, -1)),
        ])
    # Debounce
    if board == BZL:
        via_vcc_col1 = kad.add_via_relative('C11', '1', (0, -2), VIA_Size[1])
        kad.wire_mods([
            # Vcc
            ('C11', '1', None, via_vcc_col1, 0.5, (Strt)),
            ('SWB1', '2', 'J1', via_vcc_col1, 0.5, (Dird, 0, 0, -1)),
        ])
        via_bt01 = kad.add_via_relative('U1', '31', (-1.6, -1.4), VIA_Size[2])
        via_bt02 = kad.add_via_relative('RB1', '2', (16, 0), VIA_Size[2])
        kad.wire_mods([
            # Vcc
            ('U1', via_bt01, 'RB1', via_bt02, 0.5, (Dird, ([(7, 180)], 90), 0,
                                                    -1), 'B.Cu'),
            ('CB1', '1', 'U1', '5', 0.5, (Dird, ([(1.5, -90), (3.4, 0),
                                                  (2.6, 90)], 0), 0, -1)),
            # boot0
            ('U1', '31', 'U1', via_bt01, 0.5, (Dird, 90, 0, -0.8)),
            ('RB1', '2', 'RB1', via_bt02, 0.5, (Dird, 0, 90, -1)),
        ])
    elif board == BZR:
        pos_u1, net = kad.get_pad_pos_net('U1', '21')
        pos_c11 = kad.get_pad_pos('C11', '2')
        via_col1_u1 = kad.add_via((pos_c11[0] + 1, pos_u1[1] - 3.2), net,
                                  VIA_Size[1])
        via_col1_c11 = kad.add_via_relative('C11', '2', (0, 5), VIA_Size[2])
        kad.wire_mods([
            ('U1', '21', 'U1', via_col1_u1, 0.45, (Dird, ([(2.8, 180),
                                                           (16.6, 90),
                                                           (1.2, 135)], 90),
                                                   45, -1)),
            ('C11', '2', 'C11', via_col1_c11, 0.45, (Dird, 90, 0)),
            ('U1', via_col1_u1, 'C11', via_col1_c11, 0.45, (Dird, 0, 90, -1),
             'Opp'),
        ])
    # LED
    via_led_dos = {}
    via_led_dis = {}
    via_led_5vs = {}
    if board == BZL:
        # LED vias
        for idx in range(5):
            mod_led = 'L' + get_key_postfix(idx)
            via_led_dos[mod_led] = kad.add_via_relative(
                mod_led, '2', (-1.6, 0), VIA_Size[2])
            via_led_dis[mod_led] = kad.add_via_relative(
                mod_led, '4', (+0.6, -1.2), VIA_Size[2])
            kad.wire_mods([(mod_led, '2', mod_led, via_led_dos[mod_led], 0.5,
                            (Strt), 'F.Cu')])
            kad.wire_mods([(mod_led, '4', mod_led, via_led_dis[mod_led], 0.5,
                            (Dird, 90, 0, -0.8), 'F.Cu')])
            if mod_led != 'L11':
                via_led_5vs[mod_led] = kad.add_via_relative(
                    mod_led, '1', (-1.6, 0), VIA_Size[1])
                kad.wire_mods([(mod_led, '1', mod_led, via_led_5vs[mod_led],
                                0.6, (Strt), 'F.Cu')])

        via_ldi = kad.add_via_relative('U1', '12', (1.6, -1.4), VIA_Size[3])
        via_lb1_5v = kad.add_via_relative('R2', '2', (0, 11.6), VIA_Size[1])
        via_lb1_di = kad.add_via_relative('R2', '2', (0, 10.3), VIA_Size[2])
        kad.wire_mods([
            # 5V
            ('LB1', via_led_5vs['LB1'], 'J1', via_lb1_5v, 0.6,
             (Dird, ([(2.4, 90), (11.2, 0)], -45), 0, -1)),
            ('J1', via_lb1_5v, 'L14', via_led_5vs['L14'], 0.6, (Dird, 0, 90,
                                                                -1), 'B.Cu'),
            ('L14', via_led_5vs['L14'], 'L13', via_led_5vs['L13'], 0.6,
             (Dird, ([(2.4, 90), (11.2, 0)], -45), 0, -1)),
            ('L13', via_led_5vs['L13'], 'L12', via_led_5vs['L12'], 0.6,
             (Dird, ([(2.4, 90), (11.2, 0)], -45), 0, -1)),
            # DI <-- DO
            ('J1', via_splt_sb1, 'LB1', via_led_dos['LB1'], 0.5,
             (Dird, 0, ([(5, -135), (5, -90)], -45), -1), 'B.Cu'),
            ('LB1', via_led_dis['LB1'], 'J1', via_lb1_di, 0.5,
             (Dird, ([(0.3, 90), (3.3, 0)], -45), 0, -1)),
            ('J1', via_lb1_di, 'L14', via_led_dos['L14'], 0.5,
             (Dird, 0, ([(1.4, 180)], 90), -1), 'B.Cu'),
            ('L14', via_led_dis['L14'], 'L13', via_led_dos['L13'], 0.5,
             (Dird, ([(0.3, 90), (3.3, 0)], -45), 0, -1)),
            ('L13', via_led_dis['L13'], 'L12', via_led_dos['L12'], 0.5,
             (Dird, ([(0.3, 90), (3.3, 0)], -45), 0, -1)),
            ('L12', via_led_dis['L12'], 'L11', via_led_dos['L11'], 0.5,
             (Dird, ([(0.3, 90)], 0), 45, -1)),
            ('L11', via_led_dis['L11'], 'U1', via_ldi, 0.4,
             (Dird, 90, ([(10, 0), (3, -45), (13, 0), (3, +45)], 0), -0.6)),
            ('U1', '12', 'U1', via_ldi, 0.4, (Dird, 90, 0, -0.6)),
            #
            ('R2', '2', 'J1', via_lb1_5v, 0.6, (Dird, 90, 0)),
        ])
        pcb.Delete(via_lb1_di)

        # D0
        pos_c1_1 = kad.get_pad_pos('C1', '1')
        pos_d0_2 = kad.get_pad_pos('D0', '2')
        via_vcc_l12 = kad.add_via_relative('C1', '1',
                                           (pos_d0_2[1] - pos_c1_1[1], 0),
                                           VIA_Size[0])
        via_vcc_c1 = kad.add_via_relative('C1', '1', (-1.5, 0), VIA_Size[0])
        kad.wire_mods([
            ('C1', '1', None, via_vcc_c1, 0.6, (Dird, 90, 0, -1)),
            ('L12', via_led_5vs['L12'], None, via_vcc_l12, 0.6, (ZgZg, 90, 45,
                                                                 -1)),
            ('L12', via_vcc_l12, 'L12', via_vcc_c1, 0.6, (ZgZg, 90, 60),
             'B.Cu'),
            ('D0', '1', 'L11', '1', 0.6, (Dird, ([(3, 180)], -30), 0, -1)),
            ('D0', '2', 'L12', via_vcc_l12, 0.6, (Dird, 0, 90)),
            ('D0', '2', 'L1', '1', 0.6, (Dird, 90, ([(1.4, 90)], 45), -0.4)),
        ])
    elif board == BZR:
        # LED vias
        for idx in range(5):
            mod_led = 'L' + get_key_postfix(idx)
            if mod_led != 'L11':
                via_led_dos[mod_led] = kad.add_via_relative(
                    mod_led, '2', (-1.6, 0), VIA_Size[2])
                kad.wire_mods([(mod_led, '2', mod_led, via_led_dos[mod_led],
                                0.5, (Strt), 'B.Cu')])
            via_led_dis[mod_led] = kad.add_via_relative(
                mod_led, '4', (+0.6, -1.2), VIA_Size[2])
            kad.wire_mods([(mod_led, '4', mod_led, via_led_dis[mod_led], 0.5,
                            (Dird, 90, 0, -0.8), 'B.Cu')])
            via_led_5vs[mod_led] = kad.add_via_relative(
                mod_led, '1', (-1.6, 0), VIA_Size[1])
            kad.wire_mods([(mod_led, '1', mod_led, via_led_5vs[mod_led], 0.6,
                            (Strt), 'B.Cu')])
        via_l14_5v = kad.add_via_relative('J1', 'B4', (0, -18), VIA_Size[0])
        via_l14_di = kad.add_via_relative('J1', 'B4', (0, -17), VIA_Size[0])
        kad.wire_mods([
            # 5V
            ('SWB1', '2', mod_led, via_led_5vs[mod_led], 0.6,
             (Dird, ([(0.5, 0)], 90), 0, -1), 'B.Cu'),
            ('LB1', via_led_5vs['LB1'], 'J1', via_l14_5v, 0.6, (Dird, 0, 0,
                                                                -1)),
            ('J1', via_l14_5v, 'L14', via_led_5vs['L14'], 0.6,
             (Dird, 0, ([(2.4, 90)], 0), -1), 'F.Cu'),
            ('L14', via_led_5vs['L14'], 'L13', via_led_5vs['L13'], 0.6,
             (Dird, 0, ([(2.4, 90), (11.3, 0)], -45), -1)),
            ('L13', via_led_5vs['L13'], 'L12', via_led_5vs['L12'], 0.6,
             (Dird, 0, ([(2.4, 90), (11.3, 0)], -45), -1)),
            ('L12', via_led_5vs['L12'], 'L11', via_led_5vs['L11'], 0.6,
             (Dird, 90, ([(2.4, 90), (11.3, 0)], -45), -1)),
            # DO --> DI
            ('L12', via_led_dos['L12'], 'L11', via_led_dis['L11'], 0.5,
             (Dird, ([(1.2, 180)], 90), ([(0.3, 90), (3.3, 0)], -45), -1)),
            ('L13', via_led_dos['L13'], 'L12', via_led_dis['L12'], 0.5,
             (Dird, 0, ([(0.3, 90), (3.3, 0)], -45), -1)),
            ('L14', via_led_dos['L14'], 'L13', via_led_dis['L13'], 0.5,
             (Dird, 0, ([(0.3, 90), (3.3, 0)], -45), -1)),
            ('J1', via_l14_di, 'L14', via_led_dis['L14'], 0.5,
             (Dird, 0, ([(0.3, 90)], 0), -1), 'F.Cu'),
            ('LB1', via_led_dos['LB1'], 'J1', via_l14_di, 0.5, (Dird, 0, 0,
                                                                -1)),
            ('J1', via_splt_sb1, 'LB1', via_led_dis['LB1'], 0.5, (Dird, ([
                (2, 180), (1.4, -135)
            ], 0), ([(0.3, 90), (3.3, 0)], -45), -1), 'Opp'),
            # J3
            ('J3', '2', 'LB1', via_led_dis['LB1'], 0.45,
             (Dird, ([(2, 0), (16, 90)], -30), ([(0.3, 90)], 0), -1)),
        ])
        pcb.Delete(via_l14_5v)
        pcb.Delete(via_l14_di)

    ###
    ### Ref
    ###
    if board == BZL:
        refs = [
            (3, 135, 0, ['U1']),
            (2.8, 0, 90, ['U2']),
            (2.5, 0, 90, ['C1', 'C2', 'C4']),
            (1.8, 90, 0, ['C3', 'C5']),
            (3, 0, 180, ['C6', 'R1', 'D1']),
            (3.3, 0, 180, ['C11', 'R11', 'R12']),
            (3.3, 180, 0, ['CB1', 'RB1', 'RB2']),
            (1.8, -90, 0, ['R2']),
            (1.8, +90, 180, ['R3']),
            (3, 180, 180, ['R4', 'R5', 'R6', 'R7']),
            (3, 180, 0, ['R8', 'R9', 'L1', 'F1']),
            (4.0, 145, 0, ['LB1', 'L11', 'L12', 'L13', 'L14']),
            (4, 0, 0, ['CLB1', 'CL11', 'CL12', 'CL13', 'CL14']),
            (4.5, 0, 180, ['D0']),
            (4.5, 0, 0, ['D11', 'D12', 'D13', 'D14']),
            (7, 0, +90, ['J1']),
            (7, 180, -90, ['J2']),
            (15, -90, -90, ['J3']),
        ]
    elif board == BZR:
        refs = [
            (4, -110, 90, ['U1']),
            (1.8, -90, 0, ['C1']),
            (3.3, 180, 0, ['R1']),
            (3.3, 0, 180, ['D1']),
            (3.3, 180, 180, ['C11', 'R11', 'R12']),
            (3.3, 0, 0, ['CB1', 'RB1', 'RB2']),
            (3, 180, 180, ['R6', 'R7']),
            (4.0, -145, 180, ['LB1', 'L11', 'L12', 'L13', 'L14']),
            (4, 0, 180, ['CLB1', 'CL11', 'CL12', 'CL13', 'CL14']),
            (4.5, 0, 180, ['D11', 'D12', 'D13', 'D14']),
            (7, 0, -90, ['J1']),
            (13, -90, -90, ['J3']),
        ]
    else:
        refs = [(0, 0, None, ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'])]
    for offset_length, offset_angle, text_angle, mod_names in refs:
        for mod_name in mod_names:
            mod = kad.get_mod(mod_name)
            if mod == None:
                continue
            pos, angle = kad.get_mod_pos_angle(mod_name)
            ref = mod.Reference()
            if text_angle == None:
                ref.SetVisible(False)
            else:
                ref.SetTextSize(pcbnew.wxSizeMM(1, 1))
                ref.SetThickness(pcbnew.FromMM(0.15))
                pos_ref = vec2.scale(offset_length,
                                     vec2.rotate(-(offset_angle + angle)), pos)
                ref.SetPosition(pnt.to_unit(vec2.round(pos_ref, 3), True))
                ref.SetTextAngle(text_angle * 10)
                ref.SetKeepUpright(False)
    # J3
    if board == BZL:
        pads = ['GND', 'nRST', 'CLK', 'DIO', 'TX', 'RX']
    elif board == BZR:
        pads = ['GND', 'LDI', 'SCL', 'SDA', '5V']
    else:
        pads = []
    for idx, text in enumerate(pads):
        pos = kad.get_pad_pos('J3', '{}'.format(idx + 1))
        pos = vec2.scale(2, vec2.rotate(-90), pos)
        kad.add_text(pos, 0, text, ['F.SilkS', 'B.SilkS'][board], (0.9, 0.9),
                     0.15, pcbnew.GR_TEXT_HJUSTIFY_CENTER,
                     pcbnew.GR_TEXT_VJUSTIFY_CENTER)

    pcbnew.Refresh()
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()