Example #1
0
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)
Example #2
0
    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')
Example #3
0
    """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()
Example #4
0
    # 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()
Example #5
0
def generate_netlist():
    skidl.ERC()
    name, ext = os.path.splitext(sys.argv[1])
    skidl.generate_netlist(file_=name + '.net')
Example #6
0
    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()
Example #7
0
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])
Example #8
0
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