|
| 1 | +# Helper script for CH552 44 PCB |
| 2 | +# to be used with Kicad scripting console. |
| 3 | +# |
| 4 | +# Use with: |
| 5 | +# import sys |
| 6 | +# sys.path.append('/home/rgoulter/github/keyboard-labs/scripts') |
| 7 | +# import ch552_44 |
| 8 | + |
| 9 | +# pcbnew.GetBoard().FindFootprintByReference("J2").SetPosition(pcbnew.VECTOR2I_MM(100, 100)) |
| 10 | + |
| 11 | +import pcbnew |
| 12 | +from pcbnew import wxPoint, VECTOR2I_MM |
| 13 | +from pcbnew import VECTOR2I_MM |
| 14 | + |
| 15 | +logical_rows = [r for r in range(1, 7 + 1)] |
| 16 | +logical_cols = [r for r in range(1, 7 + 1)] |
| 17 | + |
| 18 | +rows = [r for r in range(1, 4 + 1)] |
| 19 | +cols = [c for c in range(1, 12 + 1)] |
| 20 | + |
| 21 | +logical_7x7_rc = [(r, c) for r in logical_rows for c in logical_cols] |
| 22 | +ortho_4x12_rc = [(r, c) for r in rows for c in cols] |
| 23 | + |
| 24 | +def suffix(p): |
| 25 | + (r, c) = p |
| 26 | + return "_{r}_{c}".format(r=r, c=c) |
| 27 | + |
| 28 | +def with_rc(f): |
| 29 | + return [f(p) for p in logical_7x7_rc] |
| 30 | + |
| 31 | +SWs = with_rc(lambda p: "SW{suf}".format(suf=suffix(p))) |
| 32 | +Ds = with_rc(lambda p: "D{suf}".format(suf=suffix(p))) |
| 33 | + |
| 34 | +def footprints(): |
| 35 | + return pcbnew.GetBoard().Footprints() |
| 36 | + |
| 37 | +def footprint_ref(fp): |
| 38 | + return fp.Reference().GetText() |
| 39 | + |
| 40 | +def lock(refs): |
| 41 | + all_fps = footprints() |
| 42 | + fps = [f for f in all_fps if footprint_ref(f) in refs] |
| 43 | + for f in fps: |
| 44 | + f.SetLocked(True) |
| 45 | + pcbnew.Refresh() |
| 46 | + |
| 47 | +def unlock(refs): |
| 48 | + all_fps = footprints() |
| 49 | + fps = [f for f in all_fps if footprint_ref(f) in refs] |
| 50 | + for f in fps: |
| 51 | + f.SetLocked(False) |
| 52 | + pcbnew.Refresh() |
| 53 | + |
| 54 | +def unlock_all(): |
| 55 | + fps = footprints() |
| 56 | + for f in fps: |
| 57 | + f.SetLocked(False) |
| 58 | + pcbnew.Refresh() |
| 59 | + |
| 60 | +# the logical grid is 7 rows and 7 columns. |
| 61 | +# the keyboard is 4 rows and 12 columns. |
| 62 | +def keyboard_coord_to_logical_coord(coord): |
| 63 | + (r, c) = coord |
| 64 | + idx = (c - 1) * 4 + (r - 1) |
| 65 | + return (idx % 7 + 1, int(idx / 7) + 1) |
| 66 | + |
| 67 | +def logical_coord_to_keyboard_coord(coord): |
| 68 | + (r, c) = coord |
| 69 | + idx = (c - 1) * 7 + (r - 1) |
| 70 | + return (idx % 4 + 1, int(idx / 4) + 1) |
| 71 | + |
| 72 | +def position_offset_for_keyboard_coord(coord): |
| 73 | + (r, c) = coord |
| 74 | + return VECTOR2I_MM(19.05 * (c - 1), 19.05 * (r - 1)) |
| 75 | + |
| 76 | +# position the SWs |
| 77 | +# |
| 78 | +# SWs are spaced apart by 19.05mm in rows and columns |
| 79 | +# starting from where SW_1_1 is placed. |
| 80 | +def position_SWs(): |
| 81 | + # Get position footprint by ref SW_1_1 |
| 82 | + sw_1_1 = pcbnew.GetBoard().FindFootprintByReference("SW_1_1") |
| 83 | + sw_1_1_pos = sw_1_1.GetPosition() |
| 84 | + |
| 85 | + # set position of all SWs relative to SW_1_1 |
| 86 | + for p in logical_7x7_rc: |
| 87 | + (r, c) = p |
| 88 | + fp = pcbnew.GetBoard().FindFootprintByReference("SW_{r}_{c}".format(r=r, c=c)) |
| 89 | + if fp is None: |
| 90 | + continue |
| 91 | + keyboard_coord = logical_coord_to_keyboard_coord(p) |
| 92 | + fp.SetPosition(sw_1_1_pos + position_offset_for_keyboard_coord(keyboard_coord)) |
| 93 | + |
| 94 | + # and set to 0 degrees |
| 95 | + fp.SetOrientationDegrees(0) |
| 96 | + |
| 97 | +# position the Ds |
| 98 | +# |
| 99 | +# Ds are spaced apart by 19.05mm in rows and columns |
| 100 | +# starting from where D_1_1 and D_1_2 are placed. |
| 101 | +def position_Ds(): |
| 102 | + # Get position footprint by ref D_1_1 and D_1_2. |
| 103 | + d_1_1 = pcbnew.GetBoard().FindFootprintByReference("D_1_1") |
| 104 | + (lr, lc) = keyboard_coord_to_logical_coord((1, 2)) |
| 105 | + d_1_2 = pcbnew.GetBoard().FindFootprintByReference("D_{r}_{c}".format(r=lr, c=lc)) |
| 106 | + d_1_1_pos = d_1_1.GetPosition() |
| 107 | + d_1_2_pos = d_1_2.GetPosition() |
| 108 | + |
| 109 | + # set position of all Ds relative to D_1_1 and D_1_2. |
| 110 | + # Odd columns are relative to D_1_1, even columns are relative to D_1_2. |
| 111 | + for p in logical_7x7_rc: |
| 112 | + (r, c) = p |
| 113 | + fp = pcbnew.GetBoard().FindFootprintByReference("D_{r}_{c}".format(r=r, c=c)) |
| 114 | + if fp is None: |
| 115 | + continue |
| 116 | + (kr, kc) = logical_coord_to_keyboard_coord(p) |
| 117 | + if kc % 2 == 1: |
| 118 | + fp.SetPosition(d_1_1_pos + position_offset_for_keyboard_coord((kr, kc))) |
| 119 | + |
| 120 | + else: |
| 121 | + fp.SetPosition(d_1_2_pos + position_offset_for_keyboard_coord((kr, kc - 1))) |
| 122 | + |
| 123 | + # and set to 270 degrees |
| 124 | + fp.SetOrientationDegrees(270) |
| 125 | + |
| 126 | +# position U1 |
| 127 | +# so its x position is halfway between the |
| 128 | +# x of SW_1_1 and SW_1_12 |
| 129 | +def position_U1(): |
| 130 | + sw_1_1 = pcbnew.GetBoard().FindFootprintByReference("SW_1_1") |
| 131 | + (lr, lc) = keyboard_coord_to_logical_coord((1, 12)) |
| 132 | + sw_1_12 = pcbnew.GetBoard().FindFootprintByReference("SW_{r}_{c}".format(r=lr, c=lc)) |
| 133 | + sw_1_1_pos = sw_1_1.GetPosition() |
| 134 | + sw_1_12_pos = sw_1_12.GetPosition() |
| 135 | + |
| 136 | + u1 = pcbnew.GetBoard().FindFootprintByReference("U1") |
| 137 | + u1_pos = u1.GetPosition() |
| 138 | + |
| 139 | + board_middle_x_offset = 15.24 / 2 |
| 140 | + u1.SetPosition(pcbnew.VECTOR2I(int((sw_1_1_pos.x + sw_1_12_pos.x ) / 2), u1_pos.y) - VECTOR2I_MM(board_middle_x_offset, 0)) |
| 141 | + |
| 142 | +def position_Hs(): |
| 143 | + # Get position footprint by ref SW_1_1 |
| 144 | + sw_1_1 = pcbnew.GetBoard().FindFootprintByReference("SW_1_1") |
| 145 | + sw_1_1_pos = sw_1_1.GetPosition() |
| 146 | + |
| 147 | + U = 19.05 |
| 148 | + C = 12 |
| 149 | + R = 4 |
| 150 | + |
| 151 | + # Hs aren't a consistent grid, |
| 152 | + # but some are similar. |
| 153 | + |
| 154 | + # H1 - H5, the JJ40 mount hole positions |
| 155 | + pcbnew.GetBoard().FindFootprintByReference("H1").SetPosition( |
| 156 | + sw_1_1_pos + VECTOR2I_MM(0.5 * U, 0.5 * U) |
| 157 | + ) |
| 158 | + pcbnew.GetBoard().FindFootprintByReference("H2").SetPosition( |
| 159 | + sw_1_1_pos + VECTOR2I_MM(0.5 * U, (R - 1.5) * U) |
| 160 | + ) |
| 161 | + pcbnew.GetBoard().FindFootprintByReference("H3").SetPosition( |
| 162 | + sw_1_1_pos + VECTOR2I_MM((C - 1.5) * U, (R - 1.5) * U) |
| 163 | + ) |
| 164 | + pcbnew.GetBoard().FindFootprintByReference("H4").SetPosition( |
| 165 | + sw_1_1_pos + VECTOR2I_MM((C - 1.5) * U, 0.5 * U) |
| 166 | + ) |
| 167 | + pcbnew.GetBoard().FindFootprintByReference("H5").SetPosition( |
| 168 | + sw_1_1_pos + VECTOR2I_MM((C - 1) / 2 * U, (R - 1) / 2 * U) |
| 169 | + ) |
| 170 | + |
| 171 | + # H7 - H10: mount holes for cover plate over dev board |
| 172 | + m = 3 |
| 173 | + pcbnew.GetBoard().FindFootprintByReference("H7").SetPosition( |
| 174 | + sw_1_1_pos + VECTOR2I_MM(4.5 * U + m, -7 + 3) |
| 175 | + ) |
| 176 | + pcbnew.GetBoard().FindFootprintByReference("H8").SetPosition( |
| 177 | + sw_1_1_pos + VECTOR2I_MM(4.5 * U + m, 1.5 * U - 3) |
| 178 | + ) |
| 179 | + pcbnew.GetBoard().FindFootprintByReference("H9").SetPosition( |
| 180 | + sw_1_1_pos + VECTOR2I_MM(6.5 * U - m, 1.5 * U - 3) |
| 181 | + ) |
| 182 | + pcbnew.GetBoard().FindFootprintByReference("H10").SetPosition( |
| 183 | + sw_1_1_pos + VECTOR2I_MM(6.5 * U - m, -7 + 3) |
| 184 | + ) |
| 185 | + |
| 186 | +def position_all(): |
| 187 | + position_SWs() |
| 188 | + position_Ds() |
| 189 | + position_U1() |
| 190 | + position_Hs() |
| 191 | + pcbnew.Refresh() |
| 192 | + |
| 193 | +def hide_d_labels(): |
| 194 | + for d in Ds: |
| 195 | + f = pcbnew.GetBoard().FindFootprintByReference(d) |
| 196 | + if f is None: |
| 197 | + continue |
| 198 | + f.Reference().SetVisible(False) |
| 199 | + pcbnew.Refresh() |
| 200 | + |
| 201 | +def hide_sw_labels(): |
| 202 | + for sw in SWs: |
| 203 | + f = pcbnew.GetBoard().FindFootprintByReference(sw) |
| 204 | + if f is None: |
| 205 | + continue |
| 206 | + # Get the text items in the footprint |
| 207 | + # and hide them if they're on silkscreen layers |
| 208 | + for t in f.GraphicalItems(): |
| 209 | + if isinstance(t, pcbnew.FP_TEXT) and t.GetLayerName() in ["F.Silkscreen"]: |
| 210 | + t.SetVisible(False) |
| 211 | + pcbnew.Refresh() |
| 212 | + |
| 213 | +def hide_u1_labels(): |
| 214 | + u1 = pcbnew.GetBoard().FindFootprintByReference("U1") |
| 215 | + # Get the text items in the footprint |
| 216 | + # and hide them if they're on silkscreen layers |
| 217 | + for t in u1.GraphicalItems(): |
| 218 | + if isinstance(t, pcbnew.FP_TEXT) and t.GetLayerName() in ["F.Silkscreen", "B.Silkscreen"]: |
| 219 | + t.SetVisible(False) |
| 220 | + pcbnew.Refresh() |
| 221 | + |
| 222 | +# H1-5 |
| 223 | +def hide_h_labels(): |
| 224 | + for h in ["H1", "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "H10", "H11", "H12", "H13", "H14", "H15"]: |
| 225 | + f = pcbnew.GetBoard().FindFootprintByReference(h) |
| 226 | + if f is None: |
| 227 | + continue |
| 228 | + f.Reference().SetVisible(False) |
| 229 | + pcbnew.Refresh() |
| 230 | + |
| 231 | +def hide_labels(): |
| 232 | + hide_d_labels() |
| 233 | + hide_sw_labels() |
| 234 | + hide_u1_labels() |
| 235 | + hide_h_labels() |
| 236 | + |
| 237 | +def fixup(): |
| 238 | + position_all() |
| 239 | + hide_labels() |
0 commit comments