def main(): if len(sys.argv) < 2: # read from stdin layout_json = sys.stdin.read() netlist_file = "keyboard.net" layout_output = "keyboard.layout" else: # read from file f_name = sys.argv[1] # TODO evaluate if this is appropriate behaviour... f_name_root = f_name if f_name.endswith(".json"): f_name_root = f_name.replace(".json", "") netlist_file = f_name_root + ".net" layout_output = f_name_root + ".layout" with open(f_name) as f: layout_json = f.read() original_layout = json_to_layout(layout_json) layout = min_pin_assignment(original_layout) with open(layout_output, 'w') as l_out_file: print(layout.to_json(), file=l_out_file) skidl_setup() row_nets = [Net('row{}'.format(i)) for i in range(layout.rows)] col_nets = [Net('col{}'.format(j)) for j in range(layout.cols)] for key in layout.keys: get_key_module(key.row, key.col, row_nets, col_nets) connect_microcontroller(row_nets, col_nets) generate_netlist(file_=netlist_file)
def save(self, filename): ''' called after all of the parts have been placed and all of the nets have been connected. This walks through the model and populates a fresh instance of the pcbnew board model ''' for net in self.circuit.nets: if net == self.circuit.NC: continue self.pcb.net(net.name) self.pcb.save(filename + '.kicad_pcb') skidl.generate_netlist(file_=filename + '.net')
"""Creates default resistor footprint""" return Part('Device', 'R', value=value, footprint='Resistor_SMD:R_1206_3216Metric') @subcircuit def generate_esp(): """Generate ESP-module code to circuit""" global U1 U1 = Part('RF_Module', 'ESP-12E', footprint='RF_Module:ESP-12E') U1['VCC'] += Net.fetch('+VBatt') U1['GND'] += Net.fetch('GND') U1['EN'] & R('10k') & Net.fetch('+VBatt') U1['GPIO15'] & R('4k7') & Net.fetch('GND') @subcircuit def generate_power_led(): """Generate led connected to ESP GPI0 that is on after boot""" led = Part('Device', 'LED', footprint='LED_SMD:LED_1206_3216Metric') U1['GPIO0'] & (R('1k') & led & Net.fetch('+VBatt')) generate_power_led() generate_esp() generate_netlist()
# ISP Connector parts["P3"] = Part('/Users/swilson/dev/kicad-library/library/conn.lib', 'CONN_02X03', ref="P3", footprint='Connectors_JST:JST_SH_SM06B-SRSS-TB_06x1.00mm_Angled') nets["+5v"] += parts["P3"][2] nets["GND"] += parts["P3"][6] nets["RESET"] += parts["P3"][5] parts["P3"][1] += parts["U1"]["MISO"] parts["P3"][3] += parts["U1"]["SCLK"] parts["P3"][4] += parts["U1"]["MOSI"] # USB Connector parts["P4"] = Part('/Users/swilson/dev/kicad-library/library/conn.lib', 'CONN_01X03', ref="P4", footprint='Connectors_JST:JST_SH_SM03B-SRSS-TB_03x1.00mm_Angled') nets["+5v"] += parts["P4"][2] nets["GND"] += parts["P4"][1] parts["P4"][3] += parts["U1"]["PC6"] # # Layer LED # parts["U1"]["PB5"] += parts["R6"][1] # parts["U1"]["PB6"] += parts["R7"][1] # parts["U1"]["PB7"] += parts["R8"][1] # nets["+5v"] += parts["RGB33"][1] # parts["RGB33"]["R"] += parts["R6"][2] # parts["RGB33"]["G"] += parts["R7"][2] # parts["RGB33"]["B"] += parts["R8"][2] add_controller() connect_switch_matrix() set_name_names() validate_switches() generate_netlist()
def generate_netlist(): skidl.ERC() name, ext = os.path.splitext(sys.argv[1]) skidl.generate_netlist(file_=name + '.net')
leds[i]['VCC'] += vcc # connect input to previous output if 0 < i: leds[i - 1]['SDO'] += sdi[i] leds[i - 1]['CKO'] += cki[i] # don't connect the output of the last LED leds[-1]['SDO'] += NC leds[-1]['CKO'] += NC # connect the input of the first LED to a pin header header = skidl.Part('conn', 'CONN_01X04', footprint='gsg-modules:HEADER-1x4') header[1] += gnd header[2] += vcc header[3] += cki[0] header[4] += sdi[0] # assume that power is applied to pin header header[1].net.drive = skidl.POWER header[2].net.drive = skidl.POWER decoupling_caps = [] decoupling_caps.append(skidl.Part('device', 'C', footprint='gsg-modules:0805')) decoupling_caps.append(skidl.Part('device', 'C', footprint='gsg-modules:0603')) for i in range(2): decoupling_caps[i][1] += vcc decoupling_caps[i][2] += gnd skidl.ERC() skidl.generate_netlist()
def main(): arg_parser = argparse.ArgumentParser( description= "Generate keyboard manufacturing files from www.keyboard-layout-editor.com JSON." ) arg_parser.add_argument("kle_json_filename", help="KLE JSON filename") arg_parser.add_argument("--descriptors_filename", help="JSON file containing keyboard description") arg_parser.add_argument("--position_json_filename", help="kinjector-format overrides of positions") arg_parser.add_argument("--output_prefix", help="prefix for output filenames", default="my-keyboard") arg_parser.add_argument("--out_dir", help="directory to place output files", default="output") arg_parser.add_argument("--add_pro_micro", help="whether to add Pro Micro to board", action="store_true") arg_parser.add_argument("--add_blue_pill", help="whether to add Blue Pill to board", action="store_true") arg_parser.add_argument( "--add_per_key_rgb", help="whether to add an RGB LED for each keyswitch", action="store_true") arg_parser.add_argument( "--use_pg1350", help="whether to use Kailh Choc PG1350 instead of Cherry MX", action="store_true") arg_parser.add_argument( "--no_hotswap", help="whether to use soldered sockets instead of Kailh hotswap sockets", action="store_true") args = arg_parser.parse_args() kbd_dict = { "args": str(args), } if args.descriptors_filename: with open(args.descriptors_filename, "r") as f: descriptors = json.loads(f.read()) print(descriptors) else: descriptors = { "family_id": "keycad", "identifier": "generic_keyboard", "usb_vid": "0xFEED", "usb_pid": "0x0001", "usb_manufacturer": "Generic", "usb_product": "Generic", "usb_description": "A keyboard" } kbd_dict["descriptors"] = descriptors if args.use_pg1350: key_width = 18 key_height = 17 else: key_width = 19.05 key_height = 19.05 pcb = Pcb(key_width, key_height) kbd_dict["keyswitch_width_mm"] = key_width kbd_dict["keyswitch_height_mm"] = key_height if args.position_json_filename is not None: pcb.read_positions(args.position_json_filename) if args.out_dir is not None: out_dir = args.out_dir os.makedirs(out_dir, exist_ok=True) else: out_dir = os.getcwd() pcb_filename = os.path.join(out_dir, args.output_prefix + PCB_FILENAME_SUFFIX) pcb_sandwich_bottom_filename = os.path.join( out_dir, args.output_prefix + "-bottom" + PCB_FILENAME_SUFFIX) pcb_sandwich_plate_filename = os.path.join( out_dir, args.output_prefix + "-top" + PCB_FILENAME_SUFFIX) netlist_filename = os.path.join( out_dir, args.output_prefix + NETLIST_FILENAME_SUFFIX) user_guide_filename = os.path.join(out_dir, args.output_prefix + USER_GUIDE_SUFFIX) partstore = PartStore() schematic = Schematic(partstore, pcb, not args.use_pg1350, not args.no_hotswap) parser = Parser() parser.load(args.kle_json_filename) builder = BoardBuilder(parser, schematic) builder.build(add_pro_micro=args.add_pro_micro, add_blue_pill=args.add_blue_pill, add_per_key_rgb=args.add_per_key_rgb) kbd_dict["matrix_pins"] = schematic.get_legend_dict() kbd_dict["kle"] = parser kbd_dict["key_matrix_keys"] = schematic.key_matrix_keys kbd_dict["has_per_key_led"] = True if schematic.led_data_pin_name is not None: kbd_dict["led_data_pin"] = schematic.led_data_pin_name kbd_dict["led_count"] = parser.key_count with open(netlist_filename, "w") as f: generate_netlist(file_=f) pcb.write_kinjector_file(os.path.join(out_dir, KINJECTOR_JSON_FILENAME)) generate_kicad_pcb(netlist_filename, os.path.join(out_dir, KINJECTOR_JSON_FILENAME), pcb_filename) board_width = parser.board_right - parser.board_left board_height = parser.board_bottom - parser.board_top pcb_width_mm = board_width * key_width pcb_height_mm = board_height * key_height kbd_dict["pcb_width_mm"] = pcb_width_mm kbd_dict["pcb_height_mm"] = pcb_height_mm if args.add_blue_pill: KC_TO_MM = 1000000 # J1 is a magic ref that means the USB-C connector position = pcb.get_part_position("J1") if position: usb_cutout_position = position["x"] / KC_TO_MM # Korean Hroparts TYPE-C-31-M-14 usb_cutout_width = 4.7 * 2 else: usb_cutout_position = -1 usb_cutout_width = -1 add_outline_to_board(pcb_filename, -key_width / 2, -key_height / 2, pcb_width_mm, pcb_height_mm, usb_cutout_position=usb_cutout_position, usb_cutout_width=usb_cutout_width) add_keepout_to_board(pcb_filename, usb_cutout_position - usb_cutout_width / 2, -9.525, usb_cutout_width, 6.1) add_outline_to_board(pcb_sandwich_bottom_filename, -key_width / 2, -key_height / 2, pcb_width_mm, pcb_height_mm, modify_existing=False, margin_mm=5, corner_radius_mm=5) add_outline_to_board(pcb_sandwich_plate_filename, -key_width / 2, -key_height / 2, pcb_width_mm, pcb_height_mm, modify_existing=False, margin_mm=5, corner_radius_mm=5) labels = [] for key in parser.keys: labels.append(key.get_rowcol_label_dict(key_width, key_height)) labels.append({ "text": schematic.get_legend_text(), "x_mm": pcb_width_mm / 2, "y_mm": pcb_height_mm - key_height / 2 - 1 }) add_labels_to_board(pcb_filename, labels) os.unlink(os.path.join(out_dir, KINJECTOR_JSON_FILENAME)) kbd_dict["bom"] = partstore.get_bom() manual = Manual(kbd_dict) manual.generate(user_guide_filename) subprocess.call(["xdg-open", pcb_filename])
def make_board(text, rules): print('Making board for:', text) print('') info = {} # Convert to Morse mark/space sequence. text = text.upper() info['text'] = text try: seqs = sequence.text_to_bit_sequence(text, rules['type']) except: logging.error('Error generating bit sequence', exc_info=sys.exc_info()) return print('Bit sequence:') info['sequence'] = [] for seq in seqs: s = sequence.to_string(seq) print(' ', s) info['sequence'].append(s) nseqs = len(seqs) print('') # Padding: either a fixed padding or to next power of two. length = len(seqs[0]) if length > 256: print('Sequence too long: maximum length is 256') sys.exit(1) length = util.next_power_of_two(length) npadding = length - len(seqs[0]) print('Length:', len(seqs[0]), '->', length) for i in range(npadding): for j in range(nseqs): seqs[j].append(sequence.SPACE) print('Padded bit sequence:') info['padded_sequence'] = [] for seq in seqs: s = sequence.to_string(seq) print(' ', s) info['padded_sequence'].append(s) print('') # Convert to Espresso format. try: esp = espresso.espresso(seqs) except: logging.error('Error running Espresso', exc_info=sys.exc_info()) return p = placement.place(esp, rules) print(p) c, a = placement.assign(p['gates'], info) print('') netlist.skidl_build(nseqs, length, c, a, rules) skidl.ERC() skidl.generate_netlist() bom.make_bom() return info