diff --git a/CHANGELOG.md b/CHANGELOG.md index 28dc2781..142d5ce5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +- New outputs: + - KiCad netlist generation + - IPC-D-356 netlist generation ## [1.0.0] - 2022-05-10 ### Added diff --git a/README.md b/README.md index f4d6da53..6385fc97 100644 --- a/README.md +++ b/README.md @@ -1817,6 +1817,28 @@ Next time you need this list just use an alias, like this: - `output_id`: [string=''] Text to use for the %I expansion content. To differentiate variations of this output. - `run_by_default`: [boolean=true] When enabled this output will be created when no specific outputs are requested. +* Netlist + * Type: `netlist` + * Description: Generates the list of connections for the project. + The netlist can be generated in the classic format and in IPC-D-356 format, + useful for board testing + * Valid keys: + - `comment`: [string=''] A comment for documentation purposes. + - `dir`: [string='./'] Output directory for the generated files. If it starts with `+` the rest is concatenated to the default dir. + - `disable_run_by_default`: [string|boolean] Use it to disable the `run_by_default` status of other output. + Useful when this output extends another and you don't want to generate the original. + Use the boolean true value to disable the output you are extending. + - `extends`: [string=''] Copy the `options` section from the indicated output. + - `name`: [string=''] Used to identify this particular output definition. + - `options`: [dict] Options for the `netlist` output. + * Valid keys: + - `format`: [string='classic'] [classic,ipc] The `classic` format is the KiCad internal format, and is generated + from the schematic. The `ipc` format is the IPC-D-356 format, useful for PCB + testing, is generated from the PCB. + - `output`: [string='%f-%i%I%v.%x'] Filename for the output (%i=netlist/IPC-D-356, %x=net/d356). Affected by global options. + - `output_id`: [string=''] Text to use for the %I expansion content. To differentiate variations of this output. + - `run_by_default`: [boolean=true] When enabled this output will be created when no specific outputs are requested. + * PCB Print * Type: `pcb_print` * Description: Prints the PCB using a mechanism that is more flexible than `pdf_pcb_print` and `svg_pcb_print`. diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 0295d359..72883e09 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -957,6 +957,20 @@ outputs: # [string=''] Board variant to apply. # Don't use the `kicost_variant` when using internal variants/filters variant: '' + # Netlist: + # The netlist can be generated in the classic format and in IPC-D-356 format, + # useful for board testing + - name: 'netlist_example' + comment: 'Generates the list of connections for the project.' + type: 'netlist' + dir: 'Example/netlist_dir' + options: + # [string='classic'] [classic,ipc] The `classic` format is the KiCad internal format, and is generated + # from the schematic. The `ipc` format is the IPC-D-356 format, useful for PCB + # testing, is generated from the PCB + format: 'classic' + # [string='%f-%i%I%v.%x'] Filename for the output (%i=netlist/IPC-D-356, %x=net/d356). Affected by global options + output: '%f-%i%I%v.%x' # PCB Print: # Supports PDF, SVG, PNG, EPS and PS formats. # KiCad 5: including the frame is slow. diff --git a/kibot/misc.py b/kibot/misc.py index 26121e73..8fd73898 100644 --- a/kibot/misc.py +++ b/kibot/misc.py @@ -77,6 +77,8 @@ CMD_PCBNEW_3D = CMD_PCBNEW_RUN_DRC URL_PCBNEW_3D = URL_EESCHEMA_DO CMD_PCBNEW_GENCAD = CMD_PCBNEW_RUN_DRC URL_PCBNEW_GENCAD = URL_EESCHEMA_DO +CMD_PCBNEW_IPC_NETLIST = CMD_PCBNEW_RUN_DRC +URL_PCBNEW_IPC_NETLIST = URL_EESCHEMA_DO CMD_KIBOM = 'KiBOM_CLI.py' URL_KIBOM = 'https://github.com/INTI-CMNB/KiBoM' CMD_IBOM = 'generate_interactive_bom.py' diff --git a/kibot/out_netlist.py b/kibot/out_netlist.py new file mode 100644 index 00000000..6d48695e --- /dev/null +++ b/kibot/out_netlist.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Salvador E. Tropea +# Copyright (c) 2022 Instituto Nacional de TecnologĂ­a Industrial +# License: GPL-3.0 +# Project: KiBot (formerly KiPlot) +import os +from .gs import GS +from .optionable import BaseOptions +from .misc import CMD_PCBNEW_IPC_NETLIST, URL_PCBNEW_IPC_NETLIST, CMD_EESCHEMA_DO, URL_EESCHEMA_DO, FAILED_EXECUTE +from .kiplot import check_script, exec_with_retry, add_extra_options +from .macros import macros, document, output_class # noqa: F401 +from . import log + +logger = log.get_logger() + + +class NetlistOptions(BaseOptions): + def __init__(self): + with document: + self.output = GS.def_global_output + """ Filename for the output (%i=netlist/IPC-D-356, %x=net/d356) """ + self.format = 'classic' + """ [classic,ipc] The `classic` format is the KiCad internal format, and is generated + from the schematic. The `ipc` format is the IPC-D-356 format, useful for PCB + testing, is generated from the PCB """ + super().__init__() + + def config(self, parent): + super().config(parent) + if self.format == 'classic': + self._expand_id = 'netlist' + self._expand_ext = 'net' + else: + self._expand_id = 'IPC-D-356' + self._expand_ext = 'd356' + + def run(self, name): + if self.format == 'ipc': + command = CMD_PCBNEW_IPC_NETLIST + url = URL_PCBNEW_IPC_NETLIST + subcommand = 'ipc_netlist' + extra = ['--output_name', name] + file = GS.pcb_file + else: + command = CMD_EESCHEMA_DO + url = URL_EESCHEMA_DO + subcommand = 'netlist' + extra = [] + file = GS.sch_file + output_dir = os.path.dirname(name) + check_script(command, url, '1.6.11') + # Output file name + cmd = [command, subcommand]+extra+[file, output_dir] + cmd, video_remove = add_extra_options(cmd) + # Execute it + ret = exec_with_retry(cmd) + if ret: + logger.error(command+' returned %d', ret) + exit(FAILED_EXECUTE) + # Rename the output if needed + if not extra: + cur = self._parent.expand_filename(output_dir, '%f.%x') + logger.debug('Moving '+cur+' -> '+name) + os.rename(cur, name) + # Remove the video if needed + if video_remove: + video_name = os.path.join(self.expand_filename_pcb(GS.out_dir), command[:-3]+'_'+subcommand+'_screencast.ogv') + if os.path.isfile(video_name): + os.remove(video_name) + + +@output_class +class Netlist(BaseOutput): # noqa: F821 + """ Netlist + Generates the list of connections for the project. + The netlist can be generated in the classic format and in IPC-D-356 format, + useful for board testing """ + def __init__(self): + super().__init__() + with document: + self.options = NetlistOptions + """ [dict] Options for the `netlist` output """ + + @staticmethod + def get_conf_examples(name, layers, templates): + gb1 = {} + gb1['name'] = 'classic_'+name + gb1['comment'] = 'Schematic netlist in KiCad format' + gb1['type'] = name + gb1['dir'] = 'Export' + gb2 = {} + gb2['name'] = 'ipc_'+name + gb2['comment'] = 'IPC-D-356 netlist for testing' + gb2['type'] = name + gb2['dir'] = 'Export' + gb2['options'] = {'format': 'ipc'} + return [gb1, gb2]