├── automation ├── tools │ ├── kiplot │ │ ├── src │ │ │ └── kiplot │ │ │ │ ├── __init__.py │ │ │ │ ├── __version__.py │ │ │ │ ├── error.py │ │ │ │ └── __main__.py │ │ ├── tests │ │ │ ├── test_plot │ │ │ │ ├── __init__.py │ │ │ │ └── README.md │ │ │ ├── test_yaml.py │ │ │ ├── conftest.py │ │ │ └── yaml_samples │ │ │ │ └── simple_2layer.kiplot.yaml │ │ ├── setup.cfg │ │ ├── .gitignore │ │ └── setup.py │ ├── ninja │ │ ├── misc │ │ │ ├── afl-fuzz-tokens │ │ │ │ ├── misc_a │ │ │ │ ├── misc_b │ │ │ │ ├── misc_eq │ │ │ │ ├── kw_build │ │ │ │ ├── kw_pool │ │ │ │ ├── kw_rule │ │ │ │ ├── misc_colon │ │ │ │ ├── misc_dollar │ │ │ │ ├── misc_indent │ │ │ │ ├── misc_pipe │ │ │ │ ├── misc_space │ │ │ │ ├── kw_default │ │ │ │ ├── kw_include │ │ │ │ ├── kw_subninja │ │ │ │ ├── misc_cont │ │ │ │ └── misc_pipepipe │ │ │ ├── afl-fuzz │ │ │ │ └── build.ninja │ │ │ ├── inherited-fds.ninja │ │ │ ├── long-slow-build.ninja │ │ │ ├── ci.py │ │ │ ├── packaging │ │ │ │ ├── rpmbuild.sh │ │ │ │ └── ninja.spec │ │ │ ├── measure.py │ │ │ └── bash-completion │ │ ├── .editorconfig │ │ ├── doc │ │ │ ├── dblatex.xsl │ │ │ ├── style.css │ │ │ ├── README.md │ │ │ └── docbook.xsl │ │ ├── .gitignore │ │ ├── src │ │ │ ├── debug_flags.cc │ │ │ ├── exit_status.h │ │ │ ├── load_status.h │ │ │ ├── edit_distance.h │ │ │ ├── debug_flags.h │ │ │ ├── string_piece_util.h │ │ │ ├── version.h │ │ │ ├── browse.h │ │ │ ├── timestamp.h │ │ │ ├── msvc_helper.h │ │ │ ├── win32port.h │ │ │ ├── graphviz.h │ │ │ ├── msvc_helper_test.cc │ │ │ ├── inline.sh │ │ │ ├── depfile_parser.h │ │ │ ├── state_test.cc │ │ │ ├── parser.h │ │ │ ├── dyndep_parser.h │ │ │ ├── includes_normalize.h │ │ │ ├── canon_perftest.cc │ │ │ ├── gen_doxygen_mainpage.sh │ │ │ ├── getopt.h │ │ │ ├── edit_distance_test.cc │ │ │ ├── version.cc │ │ │ ├── parser.cc │ │ │ ├── hash_collision_bench.cc │ │ │ ├── string_piece_util.cc │ │ │ ├── string_piece.h │ │ │ ├── clparser.h │ │ │ └── manifest_parser.h │ │ ├── .travis.yml │ │ ├── .clang-format │ │ ├── .github │ │ │ └── workflows │ │ │ │ ├── windows.yml │ │ │ │ └── macos.yml │ │ ├── README.md │ │ ├── RELEASING │ │ ├── appveyor.yml │ │ └── CONTRIBUTING.md │ ├── InteractiveHtmlBom │ │ ├── InteractiveHtmlBom │ │ │ ├── core │ │ │ │ ├── __init__.py │ │ │ │ └── fontparser.py │ │ │ ├── dialog │ │ │ │ └── __init__.py │ │ │ ├── icon.png │ │ │ ├── errors.py │ │ │ ├── dialog_test.py │ │ │ ├── i18n │ │ │ │ ├── language_zh.bat │ │ │ │ └── language_en.bat │ │ │ ├── ecad │ │ │ │ ├── __init__.py │ │ │ │ └── kicad_extra │ │ │ │ │ ├── sexpressions.py │ │ │ │ │ ├── xmlparser.py │ │ │ │ │ ├── parser_base.py │ │ │ │ │ ├── netlistparser.py │ │ │ │ │ └── __init__.py │ │ │ ├── version.py │ │ │ ├── __init__.py │ │ │ └── web │ │ │ │ └── lz-string.js │ │ ├── __init__.py │ │ ├── icons │ │ │ ├── plugin_icon_big.png │ │ │ ├── stats-36px.svg │ │ │ ├── io-36px.svg │ │ │ ├── copy-48px.svg │ │ │ ├── bom-ungrouped-32px.svg │ │ │ ├── bom-netlist-32px.svg │ │ │ ├── bom-grouped-32px.svg │ │ │ ├── bom-only-32px.svg │ │ │ ├── bom-top-bot-32px.svg │ │ │ ├── baseline-settings-20px.svg │ │ │ └── bom-left-right-32px.svg │ │ ├── .gitignore │ │ ├── LICENSE │ │ └── README.md │ ├── PcbDraw │ │ ├── .gitattributes │ │ ├── examples │ │ │ ├── .gitignore │ │ │ ├── init.sh │ │ │ ├── populate │ │ │ │ ├── remap.json │ │ │ │ ├── source_md.md │ │ │ │ └── source_html.md │ │ │ ├── pcbdraw │ │ │ │ └── remap.json │ │ │ └── readme.md │ │ ├── pcbdraw │ │ │ ├── footprints │ │ │ │ ├── KiCAD-base │ │ │ │ │ ├── yaqwsx_KiCAD_lib │ │ │ │ │ ├── LEDs │ │ │ │ │ │ └── LED-5MM_red.svg │ │ │ │ │ ├── Resistors_SMD │ │ │ │ │ │ ├── R_0603_HandSoldering.svg │ │ │ │ │ │ ├── R_0805_HandSoldering.svg │ │ │ │ │ │ ├── R_1206_HandSoldering.svg │ │ │ │ │ │ └── R_1210_HandSoldering.svg │ │ │ │ │ ├── yaqwsx │ │ │ │ │ │ ├── arduino_uno_small_pads.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x01_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x02_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x03_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x04_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x05_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x06_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x07_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x08_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x09_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x10_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x11_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x12_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x13_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x14_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x15_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x16_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x17_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x18_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x19_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x20_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x21_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x22_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x23_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x24_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x25_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x26_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x27_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x28_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x29_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x30_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x31_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x32_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x33_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x34_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x35_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x36_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x37_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x38_circle.svg │ │ │ │ │ │ ├── Pin_Header_Straight_1x39_circle.svg │ │ │ │ │ │ └── Pin_Header_Straight_1x40_circle.svg │ │ │ │ │ ├── Capacitors_SMD │ │ │ │ │ │ ├── C_0603_HandSoldering.svg │ │ │ │ │ │ └── C_0805_HandSoldering.svg │ │ │ │ │ └── EtherkitKicadLibrary │ │ │ │ │ │ ├── SOT23.svg │ │ │ │ │ │ ├── SOT23-2N7002.svg │ │ │ │ │ │ └── MSOP-10.svg │ │ │ │ └── scrips │ │ │ │ │ ├── resize_canvas.sh │ │ │ │ │ └── generate_pinheaders.py │ │ │ ├── __init__.py │ │ │ ├── styles │ │ │ │ ├── set-blue-cu.json │ │ │ │ ├── set-red-cu.json │ │ │ │ ├── gatema-green.json │ │ │ │ ├── oshpark-purple.json │ │ │ │ ├── set-black-cu.json │ │ │ │ ├── set-black-enig.json │ │ │ │ ├── set-black-hasl.json │ │ │ │ ├── set-blue-enig.json │ │ │ │ ├── set-blue-hasl.json │ │ │ │ ├── set-red-enig.json │ │ │ │ ├── set-red-hasl.json │ │ │ │ ├── set-white-cu.json │ │ │ │ ├── set-white-enig.json │ │ │ │ ├── set-white-hasl.json │ │ │ │ ├── set-yellow-cu.json │ │ │ │ ├── set-yellow-enig.json │ │ │ │ ├── set-yellow-hasl.json │ │ │ │ ├── jlcpcb-green-enig.json │ │ │ │ ├── jlcpcb-green-hasl.json │ │ │ │ ├── mayer-yellow-hasl.json │ │ │ │ └── oshpark-afterdark.json │ │ │ └── templates │ │ │ │ └── simple.handlebars │ │ ├── promo_pcbdraw.png │ │ ├── promo_populate.jpg │ │ ├── setup.cfg │ │ ├── MANIFEST.in │ │ ├── .gitmodules │ │ ├── Makefile │ │ ├── .github │ │ │ └── FUNDING.yml │ │ ├── LICENSE │ │ ├── setup.py │ │ ├── README.md │ │ └── .gitignore │ ├── generate_pos.py │ └── kicad-jlcpcb-bom-plugin │ │ ├── bom_csv_jlcpcb.py │ │ ├── kicad_pos_to_cpl.py │ │ └── README.md ├── ninja.sh ├── run_ibom.sh ├── run_erc.sh ├── Dockerfile └── run_drc.sh ├── pyproject.toml ├── docs ├── ferris_doc_cards.odg ├── ferris_0_2_doc_cards.odg └── assembly_guide.md ├── 0.2 ├── bling │ ├── cases │ │ └── mid_profile │ │ │ ├── fp-lib-table │ │ │ ├── lip.pro │ │ │ ├── template.pro │ │ │ ├── bottom_plate_puck.pro │ │ │ ├── left_switch_plate.pro │ │ │ ├── bottom_plate_no_puck.pro │ │ │ └── right_switch_plate.pro │ ├── fp-lib-table │ ├── readme.md │ └── sym-lib-table ├── compact │ ├── cases │ │ └── low_profile │ │ │ ├── fp-lib-table │ │ │ ├── lip.pro │ │ │ ├── metal_plate.pro │ │ │ └── cork_spacer_and_lip.pro │ ├── fp-lib-table │ ├── readme.md │ └── sym-lib-table ├── high │ ├── fp-lib-table │ ├── readme.md │ └── sym-lib-table ├── mini │ ├── fp-lib-table │ ├── sym-lib-table │ └── readme.md └── readme.md ├── 0.1 ├── low │ ├── fp-lib-table │ ├── sym-lib-table │ └── readme.md ├── base │ ├── fp-lib-table │ ├── readme.md │ └── sym-lib-table ├── high │ ├── fp-lib-table │ ├── readme.md │ └── sym-lib-table ├── compact │ ├── fp-lib-table │ ├── sym-lib-table │ └── readme.md ├── readme.md └── bom.csv ├── fp └── dummy.pretty │ └── dummy.kicad_mod ├── .gitignore ├── .github └── workflows │ ├── black.yml │ ├── ci.yml │ └── release.yml ├── .gitmodules ├── .kiplot.edge_cuts.yml └── .kiplot.yml /automation/tools/kiplot/src/kiplot/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /automation/tools/kiplot/tests/test_plot/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_a: -------------------------------------------------------------------------------- 1 | a -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_b: -------------------------------------------------------------------------------- 1 | b -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_eq: -------------------------------------------------------------------------------- 1 | = -------------------------------------------------------------------------------- /automation/tools/kiplot/setup.cfg: -------------------------------------------------------------------------------- 1 | [aliases] 2 | test=pytest -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/kw_build: -------------------------------------------------------------------------------- 1 | build -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/kw_pool: -------------------------------------------------------------------------------- 1 | pool -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/kw_rule: -------------------------------------------------------------------------------- 1 | rule -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_colon: -------------------------------------------------------------------------------- 1 | : -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_dollar: -------------------------------------------------------------------------------- 1 | $ -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_indent: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_pipe: -------------------------------------------------------------------------------- 1 | | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_space: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/kw_default: -------------------------------------------------------------------------------- 1 | default -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/kw_include: -------------------------------------------------------------------------------- 1 | include -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/kw_subninja: -------------------------------------------------------------------------------- 1 | subninja -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_cont: -------------------------------------------------------------------------------- 1 | $ 2 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz-tokens/misc_pipepipe: -------------------------------------------------------------------------------- 1 | || -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | exclude = 'tools/.*/' 3 | 4 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/.gitattributes: -------------------------------------------------------------------------------- 1 | pcbdraw/_version.py export-subst 2 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/examples/.gitignore: -------------------------------------------------------------------------------- 1 | ArduinoLearningKitStarter 2 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx_KiCAD_lib: -------------------------------------------------------------------------------- 1 | yaqwsx -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/LEDs/LED-5MM_red.svg: -------------------------------------------------------------------------------- 1 | LED-5MM.svg -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/__init__.py: -------------------------------------------------------------------------------- 1 | from .InteractiveHtmlBom import plugin 2 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/Resistors_SMD/R_0603_HandSoldering.svg: -------------------------------------------------------------------------------- 1 | R_0603.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/Resistors_SMD/R_0805_HandSoldering.svg: -------------------------------------------------------------------------------- 1 | R_0805.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/Resistors_SMD/R_1206_HandSoldering.svg: -------------------------------------------------------------------------------- 1 | R_1206.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/Resistors_SMD/R_1210_HandSoldering.svg: -------------------------------------------------------------------------------- 1 | R_1210.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/arduino_uno_small_pads.svg: -------------------------------------------------------------------------------- 1 | arduino_uno.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/Capacitors_SMD/C_0603_HandSoldering.svg: -------------------------------------------------------------------------------- 1 | C_0603.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/Capacitors_SMD/C_0805_HandSoldering.svg: -------------------------------------------------------------------------------- 1 | C_0805.svg -------------------------------------------------------------------------------- /docs/ferris_doc_cards.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierrechevalier83/ferris/HEAD/docs/ferris_doc_cards.odg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/EtherkitKicadLibrary/SOT23.svg: -------------------------------------------------------------------------------- 1 | ../TO_SOT_Packages_SMD/SOT-23.svg -------------------------------------------------------------------------------- /docs/ferris_0_2_doc_cards.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierrechevalier83/ferris/HEAD/docs/ferris_0_2_doc_cards.odg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/EtherkitKicadLibrary/SOT23-2N7002.svg: -------------------------------------------------------------------------------- 1 | ../TO_SOT_Packages_SMD/SOT-23.svg -------------------------------------------------------------------------------- /automation/tools/kiplot/src/kiplot/__version__.py: -------------------------------------------------------------------------------- 1 | VERSION = (0, 1, 0) 2 | 3 | __version__ = '.'.join(map(str, VERSION)) 4 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/EtherkitKicadLibrary/MSOP-10.svg: -------------------------------------------------------------------------------- 1 | ../Housings_SSOP/MSOP-10_3x3mm_Pitch0.5mm.svg -------------------------------------------------------------------------------- /automation/tools/kiplot/src/kiplot/error.py: -------------------------------------------------------------------------------- 1 | """ 2 | KiPlot errors 3 | """ 4 | 5 | 6 | class KiPlotError(Exception): 7 | pass 8 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/dialog/__init__.py: -------------------------------------------------------------------------------- 1 | from .settings_dialog import SettingsDialog, GeneralSettingsPanel 2 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x01_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x01.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x02_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x02.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x03_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x03.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x04_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x04.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x05_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x05.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x06_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x06.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x07_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x07.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x08_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x08.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x09_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x09.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x10_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x10.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x11_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x11.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x12_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x12.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x13_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x13.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x14_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x14.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x15_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x15.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x16_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x16.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x17_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x17.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x18_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x18.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x19_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x19.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x20_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x20.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x21_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x21.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x22_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x22.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x23_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x23.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x24_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x24.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x25_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x25.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x26_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x26.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x27_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x27.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x28_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x28.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x29_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x29.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x30_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x30.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x31_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x31.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x32_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x32.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x33_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x33.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x34_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x34.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x35_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x35.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x36_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x36.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x37_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x37.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x38_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x38.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x39_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x39.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/KiCAD-base/yaqwsx/Pin_Header_Straight_1x40_circle.svg: -------------------------------------------------------------------------------- 1 | ../Pin_Headers/Pin_Header_Straight_1x40.svg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/promo_pcbdraw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierrechevalier83/ferris/HEAD/automation/tools/PcbDraw/promo_pcbdraw.png -------------------------------------------------------------------------------- /automation/tools/PcbDraw/promo_populate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierrechevalier83/ferris/HEAD/automation/tools/PcbDraw/promo_populate.jpg -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from ._version import get_versions 3 | __version__ = get_versions()['version'] 4 | del get_versions 5 | -------------------------------------------------------------------------------- /0.2/bling/cases/mid_profile/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name dummy)(type KiCad)(uri ${KIPRJMOD}/../../../../fp/dummy.pretty)(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/afl-fuzz/build.ninja: -------------------------------------------------------------------------------- 1 | rule b 2 | command = clang -MMD -MF $out.d -o $out -c $in 3 | description = building $out 4 | 5 | build a.o: b a.c 6 | -------------------------------------------------------------------------------- /0.2/compact/cases/low_profile/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name dummy)(type KiCad)(uri /home/pierrec/Documents/code/ferris/fp/dummy.pretty)(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/plugin_icon_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierrechevalier83/ferris/HEAD/automation/tools/InteractiveHtmlBom/icons/plugin_icon_big.png -------------------------------------------------------------------------------- /automation/tools/kiplot/tests/test_yaml.py: -------------------------------------------------------------------------------- 1 | """ 2 | Tests for the YAML parser 3 | """ 4 | 5 | 6 | # content of test_sample.py 7 | def test_numbers_3_4(): 8 | assert 12 == 12 9 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea 3 | .vscode 4 | *.iml 5 | *.bak 6 | test 7 | releases 8 | demo 9 | config.ini 10 | InteractiveHtmlBom/web/user* 11 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pierrechevalier83/ferris/HEAD/automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/icon.png -------------------------------------------------------------------------------- /automation/tools/PcbDraw/setup.cfg: -------------------------------------------------------------------------------- 1 | [versioneer] 2 | VCS = git 3 | style = pep440 4 | versionfile_source = pcbdraw/_version.py 5 | versionfile_build = pcbdraw/_version.py 6 | tag_prefix = v 7 | parentdir_prefix = None -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/stats-36px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include pcbdraw/footprints *.svg 2 | recursive-include pcbdraw/styles *.json 3 | recursive-include pcbdraw/templates *include versioneer.py 4 | include pcbdraw/_version.py 5 | include versioneer.py 6 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/scrips/resize_canvas.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | for i in `find . -name '*.svg'`; do echo "Processing $i"; inkscape --verb=FitCanvasToDrawing --verb=FileSave --verb=FileClose --verb=FileQuit $i ; done -------------------------------------------------------------------------------- /automation/tools/ninja/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | insert_final_newline = true 8 | end_of_line = lf 9 | 10 | [CMakeLists.txt] 11 | indent_style = tab 12 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/examples/init.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Clone example board 4 | rm -rf ArduinoLearningKitStarter 5 | git clone https://github.com/RoboticsBrno/ArduinoLearningKitStarter.git 6 | cd ArduinoLearningKitStarter 7 | git checkout v3.1 8 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/examples/populate/remap.json: -------------------------------------------------------------------------------- 1 | { 2 | "L_G1": "LEDs:LED-5MM_green", 3 | "L_B1": "LEDs:LED-5MM_blue", 4 | "L_Y1": "LEDs:LED-5MM_yellow", 5 | "PHOTO1": "yaqwsx:R_PHOTO_7mm", 6 | "J8": "yaqwsx:Pin_Header_Straight_1x02_circle" 7 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "pcbdraw/PcbDraw-Lib"] 2 | path = pcbdraw/footprints 3 | url = https://github.com/yaqwsx/PcbDraw-Lib.git 4 | [submodule "pcbdraw/footprints"] 5 | path = pcbdraw/footprints 6 | url = https://github.com/yaqwsx/PcbDraw-Lib.git 7 | -------------------------------------------------------------------------------- /0.1/low/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 3 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 4 | ) 5 | -------------------------------------------------------------------------------- /automation/ninja.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ -z "$WORKDIR" ]]; then 3 | export WORKDIR="$(pwd)"; 4 | fi 5 | 6 | docker run --user $(id -u $USER):$(id -g $USER) -e WORKDIR=$WORKDIR -v $WORKDIR:/workdir -v /var/run/docker.sock:/var/run/docker.sock -t pierrechevalier83/ferris_automation ninja $@ 7 | 8 | -------------------------------------------------------------------------------- /fp/dummy.pretty/dummy.kicad_mod: -------------------------------------------------------------------------------- 1 | (module dummy (layer F.Cu) (tedit 604AAE8F) 2 | (fp_text reference dummy (at 0 0.5) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value dummy (at 0 -0.5) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | ) 9 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | .PHONY: package release 4 | 5 | all: package 6 | 7 | package: 8 | rm dist/* 9 | python3 setup.py sdist bdist_wheel 10 | 11 | install: package 12 | pip3 install --no-deps --force dist/*.whl 13 | 14 | release: package 15 | twine upload dist/* 16 | 17 | clean: 18 | rm -rf dist build -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/io-36px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /automation/tools/kiplot/tests/conftest.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test configuration 3 | """ 4 | 5 | 6 | def pytest_addoption(parser): 7 | parser.addoption("--plot_dir", action="store", default=None, 8 | help="the plot dir to use (omit to use a temp dir). " 9 | "If given, plots will _not_ be cleared after testing.") 10 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/copy-48px.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/errors.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | class ExitCodes(): 5 | ERROR_PARSE = 3 6 | ERROR_FILE_NOT_FOUND = 4 7 | ERROR_NO_DISPLAY = 5 8 | 9 | 10 | class ParsingException(Exception): 11 | pass 12 | 13 | 14 | def exit_error(logger, code, err): 15 | logger.error(err) 16 | sys.exit(code) 17 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/examples/pcbdraw/remap.json: -------------------------------------------------------------------------------- 1 | { 2 | "L_G1": "LEDs:LED-5MM_green", 3 | "L_B1": "LEDs:LED-5MM_blue", 4 | "L_Y1": "LEDs:LED-5MM_yellow", 5 | "PHOTO1": "yaqwsx:R_PHOTO_7mm", 6 | "J8": "yaqwsx:Pin_Header_Straight_1x02_circle", 7 | "REF**": "dummy:dummy", 8 | "G***": "dummy:dummy", 9 | "svg2mod": "dummy:dummy" 10 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-blue-cu.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#1b1f44", 3 | "copper": "#00406a", 4 | "silk": "#d5dce4", 5 | "pads": "#d39751", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-red-cu.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#812e2a", 3 | "copper": "#be352b", 4 | "silk": "#d5dce4", 5 | "pads": "#d39751", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/gatema-green.json: -------------------------------------------------------------------------------- 1 | { 2 | "copper": "#417e5a", 3 | "board": "#4ca06c", 4 | "silk": "#f0f0f0", 5 | "pads": "#b5ae30", 6 | "clad": "#9c6b28", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/oshpark-purple.json: -------------------------------------------------------------------------------- 1 | { 2 | "copper": "#451d70", 3 | "board": "#30234a", 4 | "silk": "#d8dae7", 5 | "pads": "#ede8b9", 6 | "clad": "#5d4e44", 7 | "outline": "#000000", 8 | "vcut": "#f0f0f0", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-black-cu.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#1d1918", 3 | "copper": "#2d2522", 4 | "silk": "#d5dce4", 5 | "pads": "#d39751", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-black-enig.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#1d1918", 3 | "copper": "#2d2522", 4 | "silk": "#d5dce4", 5 | "pads": "#cfb96e", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-black-hasl.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#1d1918", 3 | "copper": "#2d2522", 4 | "silk": "#d5dce4", 5 | "pads": "#8b898c", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-blue-enig.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#1b1f44", 3 | "copper": "#00406a", 4 | "silk": "#d5dce4", 5 | "pads": "#cfb96e", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-blue-hasl.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#1b1f44", 3 | "copper": "#00406a", 4 | "silk": "#d5dce4", 5 | "pads": "#8b898c", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-red-enig.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#812e2a", 3 | "copper": "#be352b", 4 | "silk": "#d5dce4", 5 | "pads": "#cfb96e", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-red-hasl.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#812e2a", 3 | "copper": "#be352b", 4 | "silk": "#d5dce4", 5 | "pads": "#8b898c", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-white-cu.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#bdccc7", 3 | "copper": "#b7b7ad", 4 | "silk": "#0b1013", 5 | "pads": "#d39751", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-white-enig.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#bdccc7", 3 | "copper": "#b7b7ad", 4 | "silk": "#0b1013", 5 | "pads": "#cfb96e", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-white-hasl.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#bdccc7", 3 | "copper": "#b7b7ad", 4 | "silk": "#0b1013", 5 | "pads": "#cfcfd7", 6 | "clad": "#72786c", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-yellow-cu.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#73823d", 3 | "copper": "#f79e64", 4 | "silk": "#d5dce4", 5 | "pads": "#d39751", 6 | "clad": "#525341", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-yellow-enig.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#73823d", 3 | "copper": "#f79e64", 4 | "silk": "#d5dce4", 5 | "pads": "#cfb96e", 6 | "clad": "#525341", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/set-yellow-hasl.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#73823d", 3 | "copper": "#f79e64", 4 | "silk": "#d5dce4", 5 | "pads": "#8b898c", 6 | "clad": "#525341", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/jlcpcb-green-enig.json: -------------------------------------------------------------------------------- 1 | { 2 | "copper": "#208b47", 3 | "board": "#285e3a", 4 | "silk": "#f0f0f0", 5 | "pads": "#b5ae30", 6 | "clad": "#9c6b28", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/jlcpcb-green-hasl.json: -------------------------------------------------------------------------------- 1 | { 2 | "copper": "#208b47", 3 | "board": "#285e3a", 4 | "silk": "#f0f0f0", 5 | "pads": "#bfba9e", 6 | "clad": "#9c6b28", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/mayer-yellow-hasl.json: -------------------------------------------------------------------------------- 1 | { 2 | "board": "#6c651d", 3 | "copper": "#f2a756", 4 | "silk": "#d5dce4", 5 | "pads": "#8b898c", 6 | "clad": "#656e5b", 7 | "outline": "#000000", 8 | "vcut": "#bf2600", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/styles/oshpark-afterdark.json: -------------------------------------------------------------------------------- 1 | { 2 | "copper": "#af6640", 3 | "board": "#323232", 4 | "silk": "#d8dae7", 5 | "pads": "#dec500", 6 | "clad": "#5d4e44", 7 | "outline": "#000000", 8 | "vcut": "#f0f0f0", 9 | "highlight-on-top": false, 10 | "highlight-style": "stroke:none;fill:#ff0000;opacity:0.5;", 11 | "highlight-padding": 1.5, 12 | "highlight-offset": 0 13 | } -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/bom-ungrouped-32px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /automation/tools/ninja/doc/dblatex.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 0 6 | 0 7 | 8 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/dialog_test.py: -------------------------------------------------------------------------------- 1 | from dialog.settings_dialog import * 2 | 3 | class MyApp(wx.App): 4 | def OnInit(self): 5 | frame = SettingsDialog(lambda: None, lambda x: None, "Hi", 'test') 6 | if frame.ShowModal() == wx.ID_OK: 7 | print("Should generate bom") 8 | frame.Destroy() 9 | return True 10 | 11 | 12 | app = MyApp() 13 | app.MainLoop() 14 | 15 | print("Done") 16 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/bom-netlist-32px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /automation/tools/kiplot/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | 29 | .pytest_cache 30 | 31 | *.kicad_pcb-bak 32 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/bom-grouped-32px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /automation/tools/kiplot/tests/test_plot/README.md: -------------------------------------------------------------------------------- 1 | This directory contains tests for full testing of KiCad plots. 2 | This tests: 3 | 4 | * KiPlot's config parsing and driving of KiCad 5 | * KiCad's own plotting code 6 | 7 | Generally, boards are drawn from `../board_samples` and configs from 8 | `yaml_samples`. Sometimes, the YAML samples are modified by the test 9 | runners to avoid having hundreds of them! 10 | 11 | Bug that should be tested for: 12 | 13 | * https://bugs.launchpad.net/kicad/+bug/1775037 -------------------------------------------------------------------------------- /0.1/base/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name switches)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/switches.pretty)(options "")(descr "")) 3 | (lib (name panelization)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/panelization.pretty)(options "")(descr "")) 4 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 5 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 6 | ) 7 | -------------------------------------------------------------------------------- /0.1/high/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name switches)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/switches.pretty)(options "")(descr "")) 3 | (lib (name panelization)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/panelization.pretty)(options "")(descr "")) 4 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 5 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 6 | ) 7 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/bom-only-32px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /0.1/compact/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name switches)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/switches.pretty)(options "")(descr "")) 3 | (lib (name panelization)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/panelization.pretty)(options "")(descr "")) 4 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 5 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 6 | ) 7 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/i18n/language_zh.bat: -------------------------------------------------------------------------------- 1 | ::start up echo 2 | set i18n_gitAddr= https://github.com/openscopeproject/InteractiveHtmlBom 3 | set i18n_batScar= Bat 文件: Scarrrr0725 4 | set i18n_thx4using= 感谢使用 InteractiveHtmlBom 5 | 6 | ::convert 7 | set i18n_draghere=请将您的EDA PCB源文件拖移至此 : 8 | set i18n_converting=导出中. . . . . . . . . . 9 | 10 | ::converted 11 | set i18n_again=请问是否转换其他文件 ? 12 | set i18n_converted= 您的EDA源文件已成功导出 Bom ! 13 | -------------------------------------------------------------------------------- /automation/tools/ninja/doc/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 5ex 10ex; 3 | max-width: 80ex; 4 | line-height: 1.5; 5 | font-family: sans-serif; 6 | } 7 | h1, h2, h3 { 8 | font-weight: normal; 9 | } 10 | pre, code { 11 | font-family: x, monospace; 12 | } 13 | pre { 14 | padding: 1ex; 15 | background: #eee; 16 | border: solid 1px #ddd; 17 | min-width: 0; 18 | font-size: 90%; 19 | } 20 | code { 21 | color: #007; 22 | } 23 | div.chapter { 24 | margin-top: 4em; 25 | border-top: solid 2px black; 26 | } 27 | p { 28 | margin-top: 0; 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX thumbnails cache file 2 | .DS_Store 3 | 4 | 5 | # For PCBs designed using KiCad: http://www.kicad-pcb.org/ 6 | # Format documentation: http://kicad-pcb.org/help/file-formats/ 7 | 8 | # Temporary files 9 | *.000 10 | *.bak 11 | *.bck 12 | *.kicad_pcb-bak 13 | *.sch-bak 14 | *~ 15 | *.~lock* 16 | _autosave-* 17 | *.tmp 18 | *-save.pro 19 | *-save.kicad_pcb 20 | *-cache.lib 21 | *-rescue.lib 22 | *-rescue.dcm 23 | fp-info-cache 24 | gerber/ 25 | 26 | # Autorouter files (exported from Pcbnew) 27 | *.dsn 28 | *.ses 29 | 30 | # Build artifacts 31 | build 32 | .ninja_log 33 | .eggs 34 | -------------------------------------------------------------------------------- /docs/assembly_guide.md: -------------------------------------------------------------------------------- 1 | Cursory assembly guide: 2 | ======================= 3 | 4 | The cards below are designed to be printed in A6 and shipped with a Ferris kit so the people receiving a kit can easily have all the information they need at hand. 5 | 6 | ![Greetings](https://i.imgur.com/A0aignA.jpeg) 7 | ![Assembly](https://i.imgur.com/9mO0Vrl.jpeg) 8 | ![BoM](https://i.imgur.com/PUIFOxi.jpeg) 9 | ![Keeb map](https://i.imgur.com/3QpTI6m.jpeg) 10 | ![Diodes](https://i.imgur.com/WgII1Tx.jpeg) 11 | ![Microcontroller](https://i.imgur.com/m1sC2Tc.jpeg) 12 | ![Jacks](https://i.imgur.com/cJ2TTdF.jpeg) 13 | ![Pinout](https://i.imgur.com/aDIN4Sr.jpeg) 14 | -------------------------------------------------------------------------------- /automation/run_ibom.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ -z "$WORKDIR" ]]; then 3 | export WORKDIR="$(pwd)"; 4 | fi 5 | VARIANT=$1 6 | 7 | # Try 5 times as it sometimes fails 8 | for attempt in {0..5} 9 | do 10 | docker run --user $(id -u $USER):$(id -g $USER) -e VARIANT=$VARIANT -v $WORKDIR:/workdir -t pierrechevalier83/ferris_automation bash -c 'echo ${VARIANT} && Xvfb :98 & python3 automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/generate_interactive_bom.py $VARIANT/ferris.kicad_pcb --dest-dir ../../build/$VARIANT --netlist-file $VARIANT/ferris.xml --extra-fields "LCSC Part,Part Name" --dnp-field "DNP" --no-browser' && exit 0 11 | done 12 | exit 1 13 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/i18n/language_en.bat: -------------------------------------------------------------------------------- 1 | ::start up echo 2 | set i18n_gitAddr= https://github.com/openscopeproject/InteractiveHtmlBom 3 | set i18n_batScar= Bat file by Scarrrr0725 4 | set i18n_thx4using= Thankyou For Using Generate Interactive Bom 5 | 6 | ::convert 7 | set i18n_draghere=Please Drag the EasyEDA PCB source file here : 8 | set i18n_converting=Converting . . . . . . 9 | 10 | ::converted 11 | set i18n_again=Do you want to convert another file ? 12 | set i18n_converted= EDA source file is converted to bom successfully! -------------------------------------------------------------------------------- /automation/tools/ninja/doc/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the Ninja manual and support files used in 2 | building it. Here's a brief overview of how it works. 3 | 4 | The source text, `manual.asciidoc`, is written in the AsciiDoc format. 5 | AsciiDoc can generate HTML but it doesn't look great; instead, we use 6 | AsciiDoc to generate the Docbook XML format and then provide our own 7 | Docbook XSL tweaks to produce HTML from that. 8 | 9 | In theory using AsciiDoc and DocBook allows us to produce nice PDF 10 | documentation etc. In reality it's not clear anyone wants that, but the 11 | build rules are in place to generate it if you install dblatex. 12 | -------------------------------------------------------------------------------- /0.2/compact/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name switches)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/switches.pretty)(options "")(descr "")) 3 | (lib (name panelization)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/panelization.pretty)(options "")(descr "")) 4 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 5 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 6 | (lib (name breakout_pins)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/breakout_pins.pretty)(options "")(descr "")) 7 | ) 8 | -------------------------------------------------------------------------------- /0.2/high/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name switches)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/switches.pretty)(options "")(descr "")) 3 | (lib (name panelization)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/panelization.pretty)(options "")(descr "")) 4 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 5 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 6 | (lib (name breakout_pins)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/breakout_pins.pretty)(options "")(descr "")) 7 | ) 8 | -------------------------------------------------------------------------------- /0.2/mini/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name switches)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/switches.pretty)(options "")(descr "")) 3 | (lib (name panelization)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/panelization.pretty)(options "")(descr "")) 4 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 5 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 6 | (lib (name breakout_pins)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/breakout_pins.pretty)(options "")(descr "")) 7 | ) 8 | -------------------------------------------------------------------------------- /.github/workflows/black.yml: -------------------------------------------------------------------------------- 1 | name: Black (Python formatting) 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Set up Python 3.8 15 | uses: actions/setup-python@v2 16 | with: 17 | python-version: 3.8 18 | - name: Install dependencies 19 | run: | 20 | python -m pip install --upgrade pip 21 | pip install black 22 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 23 | - name: Lint with black 24 | run: | 25 | black . 26 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/inherited-fds.ninja: -------------------------------------------------------------------------------- 1 | # This build file prints out a list of open file descriptors in 2 | # Ninja subprocesses, to help verify we don't accidentally leak 3 | # any. 4 | 5 | # Because one fd leak was in the code managing multiple subprocesses, 6 | # this test brings up multiple subprocesses and then dumps the fd 7 | # table of the last one. 8 | 9 | # Use like: ./ninja -f misc/inherited-fds.ninja 10 | 11 | rule sleep 12 | command = sleep 10000 13 | 14 | rule dump 15 | command = sleep 1; ls -l /proc/self/fd; exit 1 16 | 17 | build all: phony a b c d e 18 | 19 | build a: sleep 20 | build b: sleep 21 | build c: sleep 22 | build d: sleep 23 | build e: dump 24 | -------------------------------------------------------------------------------- /0.1/high/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.1 - High 2 | 3 | The Ferris high is designed for people who like a low-profile and "no-frill" keyboard, 4 | but like the feel of MX switches, or the keycaps availability for these more common switches. 5 | 6 | ![Ferris High](https://i.imgur.com/JfCLJa0.jpg) 7 | ![Ferris High silk](https://i.imgur.com/ZjXNqry.jpg) 8 | 9 | ## Specific features: 10 | * MX switches 11 | * Width: 10.9 cm 12 | * Height: 9.6 cm 13 | * Depth: 2.4 cm (from desk to top of keycap with BSP keycaps and 2mm rubber bumper) 14 | 15 | ## Hardware status: 16 | Working boards were produced. 17 | 18 | ## Firmware status: 19 | Supported in [upstream qmk](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ferris/0_1) 20 | -------------------------------------------------------------------------------- /0.1/base/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.1 - Base 2 | 3 | This is the first ever iteration of the Ferris keyboard: a plain pcb with support for choc switches, and the same layout as the Kyria (but limited to 34 keys). 4 | 5 | ![Base variant](https://i.imgur.com/s6nTn0C.jpg) 6 | ![Base variant silk](https://i.imgur.com/Ymlac2A.jpg) 7 | 8 | ## Specific features: 9 | * Choc switches (PG 1350) 10 | * MX Spacing (19x19mm) 11 | * Width: 10.9 cm 12 | * Height: 9.6 cm 13 | * Height: 1.5 cm (from desk to top of keycap with MBK switch and 2mm rubber bumper) 14 | 15 | ## Hardware status: 16 | Working boards were produced. 17 | 18 | ## Firmware status: 19 | Supported in [upstream qmk](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ferris/0_1) 20 | -------------------------------------------------------------------------------- /automation/tools/ninja/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.obj 3 | *.exe 4 | *.pdb 5 | *.ilk 6 | /build*/ 7 | /build.ninja 8 | /ninja 9 | /ninja.bootstrap 10 | /build_log_perftest 11 | /canon_perftest 12 | /clparser_perftest 13 | /depfile_parser_perftest 14 | /hash_collision_bench 15 | /ninja_test 16 | /manifest_parser_perftest 17 | /graph.png 18 | /doc/manual.html 19 | /doc/doxygen 20 | *.patch 21 | .DS_Store 22 | 23 | # Eclipse project files 24 | .project 25 | .cproject 26 | 27 | # SublimeText project files 28 | *.sublime-project 29 | *.sublime-workspace 30 | 31 | # Ninja output 32 | .ninja_deps 33 | .ninja_log 34 | 35 | # Visual Studio Code project files 36 | /.vscode/ 37 | /.ccls-cache/ 38 | 39 | # Qt Creator project files 40 | /CMakeLists.txt.user 41 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: yaqwsx 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /0.2/bling/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name rgb)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/rgb.pretty)(options "")(descr "")) 3 | (lib (name puck)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/puck.pretty)(options "")(descr "")) 4 | (lib (name silkscreens)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/silkscreens.pretty)(options "")(descr "")) 5 | (lib (name copper_pads)(type KiCad)(uri ${KIPRJMOD}/../../fp/ferris_pcb_art/copper_pads.pretty)(options "")(descr "")) 6 | (lib (name panelization)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/panelization.pretty)(options "")(descr "")) 7 | (lib (name breakout_pins)(type KiCad)(uri ${KIPRJMOD}/../../fp/keyboard_footprints/breakout_pins.pretty)(options "")(descr "")) 8 | ) 9 | -------------------------------------------------------------------------------- /automation/run_erc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ -z "$WORKDIR" ]]; then 3 | export WORKDIR="$(pwd)"; 4 | fi 5 | 6 | VARIANT=$1 7 | 8 | ERC_OUTPUT=$(docker run --rm -t -e VARIANT=$VARIANT -e RUST_LOG -v $WORKDIR:/workdir pierrechevalier83/kicad_cli bash -c 'RUSTLOG=$RUSTLOG kicad_cli run-erc $VARIANT --headless') 9 | 10 | if [[ -z "$ERC_OUTPUT" ]]; then 11 | echo -e "\e[1;32mERROR\e[0m" 12 | echo "Missing ERC report line. Something went wrong" 13 | exit 2 14 | else 15 | if [[ "$ERC_OUTPUT" == "ErcOutput { num_errors: 0, num_warnings: 0 }"* ]]; then 16 | touch build/$VARIANT.erc_success 17 | echo -e "\e[1;32mPASS\e[0m" 18 | echo "$ERC_OUTPUT" 19 | exit 0 20 | else 21 | echo -e "\e[1;32mFAIL\e[0m" 22 | echo "$ERC_OUTPUT" 23 | exit 1 24 | fi 25 | fi 26 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/ecad/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def get_parser_by_extension(file_name, config, logger): 5 | ext = os.path.splitext(file_name)[1] 6 | if ext == '.kicad_pcb': 7 | return get_kicad_parser(file_name, config, logger) 8 | elif ext == '.json': 9 | return get_easyeda_parser(file_name, config, logger) 10 | else: 11 | return None 12 | 13 | 14 | def get_kicad_parser(file_name, config, logger, board=None): 15 | from .kicad import PcbnewParser 16 | return PcbnewParser(file_name, config, logger, board) 17 | 18 | 19 | def get_easyeda_parser(file_name, config, logger): 20 | from .easyeda import EasyEdaParser 21 | return EasyEdaParser(file_name, config, logger) 22 | -------------------------------------------------------------------------------- /0.1/base/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 4 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 5 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 6 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 7 | (lib (name MCU_Microchip_ATmega)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_Microchip_ATmega.lib)(options "")(descr "")) 8 | ) 9 | -------------------------------------------------------------------------------- /automation/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM archlinux 2 | 3 | RUN pacman -Syy --noconfirm --noprogress 4 | RUN pacman -Syu --noconfirm --noprogress 5 | 6 | RUN pacman -S docker gcc git openssh ninja kicad xclip python python-pip python-wxpython python-wand python-lxml --noconfirm --noprogress 7 | RUN python -m pip install kicad_netlist_reader numpy 8 | 9 | COPY configure.py /ferris/automation/configure.py 10 | COPY tools/kiplot /ferris/automation/tools/kiplot 11 | COPY tools/ninja /ferris/automation/tools/ninja 12 | WORKDIR ferris 13 | RUN python -m pip install -e automation/tools/kiplot 14 | RUN python ./automation/configure.py 15 | 16 | RUN pacman -S xorg-server-xvfb --noconfirm --noprogress 17 | RUN pacman -S zip --noconfirm --noprogress 18 | 19 | ENV DISPLAY ":98" 20 | 21 | VOLUME /workdir 22 | WORKDIR /workdir 23 | -------------------------------------------------------------------------------- /automation/run_drc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ -z "$WORKDIR" ]]; then 3 | export WORKDIR="$(pwd)"; 4 | fi 5 | 6 | VARIANT=$1 7 | 8 | DRC_OUTPUT=$(docker run -t -e VARIANT=$VARIANT -e RUST_LOG -v $WORKDIR:/workdir pierrechevalier83/kicad_cli bash -c 'kicad_cli run-drc $VARIANT --headless --drc-timeout-in-s 60') 9 | 10 | if [[ -z "$DRC_OUTPUT" ]]; then 11 | echo -e "\e[1;32mERROR\e[0m" 12 | echo "Missing DRC report line. Something went wrong" 13 | echo "$FULL_DRC_OUTPUT" 14 | exit 2 15 | else 16 | if [[ "$DRC_OUTPUT" == "DrcOutput { num_errors: 0, num_unconnected_pads: 0 }"* ]]; then 17 | touch build/$VARIANT.drc_success 18 | echo -e "\e[1;32mPASS\e[0m" 19 | echo "$DRC_OUTPUT" 20 | exit 0 21 | else 22 | echo -e "\e[1;32mFAIL\e[0m" 23 | echo "$DRC_OUTPUT" 24 | exit 1 25 | fi 26 | fi 27 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/bom-top-bot-32px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | F 9 | B 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/baseline-settings-20px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/debug_flags.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | bool g_explaining = false; 16 | 17 | bool g_keep_depfile = false; 18 | 19 | bool g_keep_rsp = false; 20 | 21 | bool g_experimental_statcache = true; 22 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/icons/bom-left-right-32px.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | F 9 | B 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /0.2/bling/cases/mid_profile/lip.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/compact/cases/low_profile/lip.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/bling/cases/mid_profile/template.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/bling/cases/mid_profile/bottom_plate_puck.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/bling/cases/mid_profile/left_switch_plate.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/compact/cases/low_profile/metal_plate.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/bling/cases/mid_profile/bottom_plate_no_puck.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/bling/cases/mid_profile/right_switch_plate.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.2/compact/cases/low_profile/cork_spacer_and_lip.pro: -------------------------------------------------------------------------------- 1 | update=22/05/2015 07:44:53 2 | version=1 3 | last_client=kicad 4 | [general] 5 | version=1 6 | RootSch= 7 | BoardNm= 8 | [pcbnew] 9 | version=1 10 | LastNetListRead= 11 | UseCmpFile=1 12 | PadDrill=0.600000000000 13 | PadDrillOvalY=0.600000000000 14 | PadSizeH=1.500000000000 15 | PadSizeV=1.500000000000 16 | PcbTextSizeV=1.500000000000 17 | PcbTextSizeH=1.500000000000 18 | PcbTextThickness=0.300000000000 19 | ModuleTextSizeV=1.000000000000 20 | ModuleTextSizeH=1.000000000000 21 | ModuleTextSizeThickness=0.150000000000 22 | SolderMaskClearance=0.000000000000 23 | SolderMaskMinWidth=0.000000000000 24 | DrawSegmentWidth=0.200000000000 25 | BoardOutlineThickness=0.100000000000 26 | ModuleOutlineThickness=0.150000000000 27 | [cvpcb] 28 | version=1 29 | NetIExt=net 30 | [eeschema] 31 | version=1 32 | LibDir= 33 | [eeschema/libraries] 34 | -------------------------------------------------------------------------------- /0.1/high/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name ferris-rescue)(type Legacy)(uri ${KIPRJMOD}/ferris-rescue.lib)(options "")(descr "")) 4 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 5 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 6 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 7 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 8 | (lib (name MCU_Microchip_ATmega)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_Microchip_ATmega.lib)(options "")(descr "")) 9 | ) 10 | -------------------------------------------------------------------------------- /0.1/low/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name ferris-rescue)(type Legacy)(uri ${KIPRJMOD}/ferris-rescue.lib)(options "")(descr "")) 4 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 5 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 6 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 7 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 8 | (lib (name MCU_Microchip_ATmega)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_Microchip_ATmega.lib)(options "")(descr "")) 9 | ) 10 | -------------------------------------------------------------------------------- /0.1/compact/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name ferris-rescue)(type Legacy)(uri ${KIPRJMOD}/ferris-rescue.lib)(options "")(descr "")) 4 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 5 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 6 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 7 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 8 | (lib (name MCU_Microchip_ATmega)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_Microchip_ATmega.lib)(options "")(descr "")) 9 | ) 10 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/exit_status.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_EXIT_STATUS_H_ 16 | #define NINJA_EXIT_STATUS_H_ 17 | 18 | enum ExitStatus { 19 | ExitSuccess, 20 | ExitFailure, 21 | ExitInterrupted 22 | }; 23 | 24 | #endif // NINJA_EXIT_STATUS_H_ 25 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/load_status.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_LOAD_STATUS_H_ 16 | #define NINJA_LOAD_STATUS_H_ 17 | 18 | enum LoadStatus { 19 | LOAD_ERROR, 20 | LOAD_SUCCESS, 21 | LOAD_NOT_FOUND, 22 | }; 23 | 24 | #endif // NINJA_LOAD_STATUS_H_ 25 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/version.py: -------------------------------------------------------------------------------- 1 | # Update this when new version is tagged. 2 | LAST_TAG = 'v2.3' 3 | 4 | import os 5 | plugin_path = os.path.realpath(os.path.dirname(__file__)) 6 | plugin_path if not os.path.islink(plugin_path) else os.readlink(plugin_path) 7 | 8 | def _get_git_version(): 9 | import os, subprocess 10 | try: 11 | git_version = subprocess.check_output( 12 | ['git', 'describe', '--tags', '--abbrev=4', '--dirty=-*'], 13 | cwd=plugin_path) 14 | return git_version.decode('utf-8') if isinstance(git_version, bytes) else git_version 15 | except subprocess.CalledProcessError as e: 16 | print('Git version check failed: ' + str(e)) 17 | except Exception as e: 18 | print('Git process cannot be launched: ' + str(e)) 19 | return None 20 | 21 | 22 | version = _get_git_version() or LAST_TAG 23 | -------------------------------------------------------------------------------- /automation/tools/generate_pos.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Generate a minimal pos file to serve as input to the jlc plugin 4 | # 5 | import pcbnew 6 | import sys 7 | 8 | board = pcbnew.LoadBoard(sys.argv[1]) 9 | 10 | MODULE_ATTR_NORMAL = 0 11 | MODULE_ATTR_NORMAL_INSERT = 1 12 | MODULE_ATTR_VIRTUAL = 2 13 | 14 | print("Ref,PosX,PosY,Rot,Side") 15 | for module in board.GetModules(): 16 | if module.GetAttributes() == MODULE_ATTR_NORMAL_INSERT: 17 | (pos_x, pos_y) = module.GetPosition() 18 | side = "top" 19 | if module.IsFlipped(): 20 | side = "bottom" 21 | data = { 22 | "Ref": module.GetReference(), 23 | "PosX": pos_x / 1000000.0, 24 | "PosY": pos_y / 1000000.0, 25 | "Rot": module.GetOrientation() / 10.0, 26 | "Side": side, 27 | } 28 | print('"{0[Ref]}",{0[PosX]},{0[PosY]},{0[Rot]},{0[Side]}'.format(data)) 29 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/long-slow-build.ninja: -------------------------------------------------------------------------------- 1 | # An input file for running a "slow" build. 2 | # Use like: ninja -f misc/long-slow-build.ninja all 3 | 4 | rule sleep 5 | command = sleep 1 6 | description = SLEEP $out 7 | 8 | build 0: sleep README 9 | build 1: sleep README 10 | build 2: sleep README 11 | build 3: sleep README 12 | build 4: sleep README 13 | build 5: sleep README 14 | build 6: sleep README 15 | build 7: sleep README 16 | build 8: sleep README 17 | build 9: sleep README 18 | build 10: sleep 0 19 | build 11: sleep 1 20 | build 12: sleep 2 21 | build 13: sleep 3 22 | build 14: sleep 4 23 | build 15: sleep 5 24 | build 16: sleep 6 25 | build 17: sleep 7 26 | build 18: sleep 8 27 | build 19: sleep 9 28 | build 20: sleep 10 29 | build 21: sleep 11 30 | build 22: sleep 12 31 | build 23: sleep 13 32 | build 24: sleep 14 33 | build 25: sleep 15 34 | build 26: sleep 16 35 | build 27: sleep 17 36 | build 28: sleep 18 37 | build 29: sleep 19 38 | build all: phony 20 21 22 23 24 25 26 27 28 29 39 | -------------------------------------------------------------------------------- /automation/tools/ninja/.travis.yml: -------------------------------------------------------------------------------- 1 | matrix: 2 | include: 3 | - os: linux 4 | dist: precise 5 | compiler: gcc 6 | - os: linux 7 | dist: precise 8 | compiler: clang 9 | - os: linux 10 | dist: trusty 11 | compiler: gcc 12 | - os: linux 13 | dist: trusty 14 | compiler: clang 15 | - os: linux 16 | dist: xenial 17 | compiler: gcc 18 | - os: linux 19 | dist: xenial 20 | compiler: clang 21 | - os: osx 22 | osx_image: xcode10 23 | - os: osx 24 | osx_image: xcode10.1 25 | sudo: false 26 | language: cpp 27 | before_install: 28 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install re2c ; fi 29 | - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install re2c python ; fi 30 | script: 31 | - ./misc/ci.py 32 | - python3 configure.py --bootstrap 33 | - ./ninja all 34 | - ./ninja_test --gtest_filter=-SubprocessTest.SetWithLots 35 | - ./misc/ninja_syntax_test.py 36 | - ./misc/output_test.py 37 | -------------------------------------------------------------------------------- /0.1/compact/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.1 - Compact 2 | 3 | As minimalist as the Ferris 0.1 - base, but featuring choc spacing instead of MX spacing, 4 | resulting in an even smaller keyboard. 5 | 6 | The keycaps availability for choc with choc spacing is less than that of choc switches 7 | with MX spacing, so be sure to pay attention to the switches you are getting. 8 | 9 | The MBK switches (pictured) are recommended as they are widely regarded as the best choc 10 | switches for choc spaced boards. 11 | 12 | ![Ferris Compact](https://i.imgur.com/wcE4eT5.jpg) 13 | ![Ferris Compact silk](https://i.imgur.com/FD1pJfh.jpg) 14 | 15 | ## Specific features: 16 | * Choc switches (PG 1350) 17 | * Choc Spacing (17x18mm) 18 | * Width: 10.4 cm 19 | * Height: 8.8 cm 20 | * Depth: 1.5 cm (from desk to top of keycap with MBK and 2mm rubber bumper) 21 | 22 | ## Hardware status: 23 | Working boards were produced. 24 | 25 | ## Firmware status: 26 | Supported in [upstream qmk](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ferris/0_1) 27 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/footprints/scrips/generate_pinheaders.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """ 4 | Generates pin header in KiCAD style from a single pin model. 5 | Models are generated in current working directory. 6 | """ 7 | 8 | from lxml import etree 9 | from copy import deepcopy 10 | import argparse 11 | 12 | if __name__ == "__main__": 13 | parser = argparse.ArgumentParser() 14 | parser.add_argument("model", help="Single pin header model. Group with id 'pin' has to be present."); 15 | parser.add_argument("file_template", help="Python formatting string for name of the models.") 16 | 17 | args = parser.parse_args() 18 | 19 | document = etree.parse(args.model) 20 | root = document.getroot() 21 | pin = root.find(".//*[@id='pin']") 22 | for i in range(1, 40): 23 | el = deepcopy(pin) 24 | del el.attrib["id"] 25 | el.attrib["transform"] = "translate(0 {})".format(i * 2.54) 26 | root.append(el) 27 | document.write(args.file_template.format(i + 1)) -------------------------------------------------------------------------------- /0.2/compact/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.2 - Compact 2 | 3 | The Ferris 0.2 compact is a straight update from the 0.1 compact, which maintains 4 | the initial minimalist instincts. 5 | 6 | Its form factor is the same as the Ferris Bling, except it gets to save about 2mm 7 | in the `y` dimension as mounting holes are removed. 8 | 9 | ![Ferris 0.2 Compact](https://i.imgur.com/Z1GhXUg.png) 10 | 11 | ## Specific features: 12 | * Choc switches (PG 1350) 13 | * Choc spacing (18x17mm) 14 | * Width: 10.4 cm 15 | * Height: 8.8 cm 16 | * Height: 1.5 cm (from desk to top of keycap with MBK switch and 2mm rubber bumper) 17 | 18 | ## Hardware status: 19 | Working boards are yet to be printed and tested. 20 | 21 | ## Firmware status: 22 | * Support coming to upstream qmk with [this PR](https://github.com/qmk/qmk_firmware/pull/12133) 23 | * Support coming to upstream zmk with [this PR](https://github.com/zmkfirmware/zmk/pull/642) 24 | * Plan to write rust firmware for it eventually tracked in [this issue](https://github.com/pierrechevalier83/ferris/issues/2) 25 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/edit_distance.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_EDIT_DISTANCE_H_ 16 | #define NINJA_EDIT_DISTANCE_H_ 17 | 18 | #include "string_piece.h" 19 | 20 | int EditDistance(const StringPiece& s1, 21 | const StringPiece& s2, 22 | bool allow_replacements = true, 23 | int max_edit_distance = 0); 24 | 25 | #endif // NINJA_EDIT_DISTANCE_H_ 26 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Check Design Rules and Electrical Rules for all variants 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | run-drc: 11 | strategy: 12 | matrix: 13 | variant: [0.1/base, 0.1/compact, 0.1/high, 0.1/low, 0.2/bling, 0.2/compact, 0.2/high, 0.2/mini] 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | with: 18 | submodules: true 19 | - name: Design rules check 20 | run: | 21 | ./automation/ninja.sh build/${{ matrix.variant }}/ferris.kicad_pcb.drc_success 22 | 23 | run-erc: 24 | strategy: 25 | matrix: 26 | variant: [0.1/base, 0.1/compact, 0.1/high, 0.1/low, 0.2/bling, 0.2/compact, 0.2/high, 0.2/mini] 27 | runs-on: ubuntu-latest 28 | steps: 29 | - uses: actions/checkout@v2 30 | with: 31 | submodules: true 32 | - name: Electrical rules check 33 | run: | 34 | ./automation/ninja.sh build/${{ matrix.variant }}/ferris.sch.erc_success 35 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/examples/populate/source_md.md: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | - --remap remap.json 4 | img_name: img/populating_{}.png 5 | type: md 6 | board: ../ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb 7 | libs: kicad-default 8 | ... 9 | 10 | # Demo population manual 11 | 12 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. Vestibulum fermentum tortor id mi. Nulla turpis magna, cursus sit amet, suscipit a, interdum id, felis. 13 | 14 | - [[front | ]] This is the front side of the board we are populating 15 | - [[back | ]] This is the back side of the board we are populating 16 | - [[front | RV1, RV2 ]] First, populate RV1 and RV2. Basically, any description could be here. 17 | - [[front | U2 ]] Let's populate U2! 18 | 19 | You can put a paragraph of text between the population steps. 20 | 21 | - [[back | R24 ]] We can also populate a component on the other side 22 | 23 | And this is the end of the demo. -------------------------------------------------------------------------------- /automation/tools/kiplot/tests/yaml_samples/simple_2layer.kiplot.yaml: -------------------------------------------------------------------------------- 1 | # Example KiPlot config file for a basic 2-layer board 2 | kiplot: 3 | version: 1 4 | 5 | outputs: 6 | 7 | - name: 'gerbers' 8 | comment: "Gerbers for the Gerber god" 9 | type: gerber 10 | dir: gerberdir 11 | options: 12 | # generic layer options 13 | exclude_edge_layer: false 14 | exclude_pads_from_silkscreen: false 15 | use_aux_axis_as_origin: false 16 | plot_sheet_reference: false 17 | plot_footprint_refs: true 18 | plot_footprint_values: true 19 | force_plot_invisible_refs_vals: false 20 | tent_vias: true 21 | check_zone_fills: true 22 | 23 | # gerber options 24 | line_width: 0.15 25 | subtract_mask_from_silk: true 26 | use_protel_extensions: false 27 | gerber_precision: 4.5 28 | create_gerber_job_file: true 29 | use_gerber_x2_attributes: true 30 | use_gerber_net_attributes: false 31 | 32 | layers: 33 | - layer: F.Cu 34 | suffix: F_Cu 35 | - layer: F.SilkS 36 | suffix: F_SilkS -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/kicad_lib_tmk"] 2 | path = lib/kicad_lib_tmk 3 | url = https://github.com/tmk/kicad_lib_tmk.git 4 | [submodule "keyboard_footprints"] 5 | path = fp/keyboard_footprints 6 | url = https://github.com/pierrechevalier83/keyboard_footprints 7 | [submodule "ferris_pcb_art"] 8 | path = fp/ferris_pcb_art 9 | url = https://github.com/pierrechevalier83/ferris_pcb_art 10 | [submodule "kicad_lib_tmk"] 11 | path = sym/kicad_lib_tmk 12 | url = https://github.com/tmk/kicad_lib_tmk 13 | [submodule "tools/kiplot"] 14 | path = tools/kiplot 15 | url = https://github.com/johnbeard/kiplot.git 16 | [submodule "tools/ninja"] 17 | path = tools/ninja 18 | url = https://github.com/ninja-build/ninja.git 19 | [submodule "tools/PcbDraw"] 20 | path = tools/PcbDraw 21 | url = https://github.com/yaqwsx/PcbDraw.git 22 | [submodule "tools/InteractiveHtmlBom"] 23 | path = tools/InteractiveHtmlBom 24 | url = https://github.com/openscopeproject/InteractiveHtmlBom.git 25 | [submodule "tools/kicad-jlcpcb-bom-plugin"] 26 | path = tools/kicad-jlcpcb-bom-plugin 27 | url = https://github.com/wokwi/kicad-jlcpcb-bom-plugin.git 28 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/ecad/kicad_extra/sexpressions.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | term_regex = r'''(?mx) 4 | \s*(?: 5 | (?P\()| 6 | (?P\))| 7 | (?P"(?:\\\\|\\"|[^"])*")| 8 | (?P[^(^)\s]+) 9 | )''' 10 | pattern = re.compile(term_regex) 11 | 12 | 13 | def parse_sexpression(sexpression): 14 | stack = [] 15 | out = [] 16 | for terms in pattern.finditer(sexpression): 17 | term, value = [(t, v) for t, v in terms.groupdict().items() if v][0] 18 | if term == 'open': 19 | stack.append(out) 20 | out = [] 21 | elif term == 'close': 22 | assert stack, "Trouble with nesting of brackets" 23 | tmp, out = out, stack.pop(-1) 24 | out.append(tmp) 25 | elif term == 'sq': 26 | out.append(value[1:-1].replace('\\\\', '\\').replace('\\"', '"')) 27 | elif term == 's': 28 | out.append(value) 29 | else: 30 | raise NotImplementedError("Error: %s, %s" % (term, value)) 31 | assert not stack, "Trouble with nesting of brackets" 32 | return out[0] 33 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jan Mrázek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 qu1ck 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /0.1/low/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.1 - Base 2 | 3 | ![Ferris Low](https://i.imgur.com/MwBP3hJ.jpg) 4 | ![Ferris Low silk](https://i.imgur.com/6oXWj0b.jpg) 5 | 6 | The Ferris low is similar to the 0.1 base variant, but supports choc mini switches, which are even lower profile than choc switches. 7 | 8 | These switches are not commonly available and are more expensive than normal choc switches, but can be acquired from Kailh's store on AliExpress: 9 | * [Listing for choc mini white (clicky) switches](https://www.aliexpress.com/item/32989908397.html?spm=2114.12010612.8148356.16.41f639a68SKHzM) 10 | * [Listing for choc mini brown (tactile) and black (linear) switches](https://www.aliexpress.com/item/4000277394324.html?spm=2114.12010612.8148356.42.194a7aebEvJRzh) 11 | 12 | 13 | ## Specific features: 14 | * Choc mini switches (PG 1232) 15 | * MX Spacing (19x19mm) 16 | * Width: 10.9 cm 17 | * Height: 9.6 cm 18 | * Height: 1.2 cm (from desk to top of keycap with MBK switch and 2mm rubber bumper) 19 | 20 | ## Hardware status: 21 | Working boards were produced. 22 | 23 | ## Firmware status: 24 | Supported in [upstream qmk](https://github.com/qmk/qmk_firmware/tree/master/keyboards/ferris/0_1) 25 | -------------------------------------------------------------------------------- /automation/tools/ninja/.clang-format: -------------------------------------------------------------------------------- 1 | # Copyright 2014 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This isn't meant to be authoritative, but it's good enough to be useful. 16 | # Still use your best judgement for formatting decisions: clang-format 17 | # sometimes makes strange choices. 18 | 19 | BasedOnStyle: Google 20 | AllowShortFunctionsOnASingleLine: Inline 21 | AllowShortIfStatementsOnASingleLine: false 22 | AllowShortLoopsOnASingleLine: false 23 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 24 | Cpp11BracedListStyle: false 25 | IndentCaseLabels: false 26 | DerivePointerBinding: false 27 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/ci.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | 5 | ignores = [ 6 | '.git/', 7 | 'misc/afl-fuzz-tokens/', 8 | 'ninja_deps', 9 | 'src/depfile_parser.cc', 10 | 'src/lexer.cc', 11 | ] 12 | 13 | error_count = 0 14 | 15 | def error(path, msg): 16 | global error_count 17 | error_count += 1 18 | print('\x1b[1;31m{}\x1b[0;31m{}\x1b[0m'.format(path, msg)) 19 | 20 | for root, directory, filenames in os.walk('.'): 21 | for filename in filenames: 22 | path = os.path.join(root, filename)[2:] 23 | if any([path.startswith(x) for x in ignores]): 24 | continue 25 | with open(path, 'rb') as file: 26 | line_nr = 1 27 | try: 28 | for line in [x.decode() for x in file.readlines()]: 29 | if len(line) == 0 or line[-1] != '\n': 30 | error(path, ' missing newline at end of file.') 31 | if len(line) > 1: 32 | if line[-2] == '\r': 33 | error(path, ' has Windows line endings.') 34 | break 35 | if line[-2] == ' ' or line[-2] == '\t': 36 | error(path, ':{} has trailing whitespace.'.format(line_nr)) 37 | line_nr += 1 38 | except UnicodeError: 39 | pass # binary file 40 | 41 | exit(error_count) 42 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/packaging/rpmbuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo Building ninja RPMs.. 4 | GITROOT=$(git rev-parse --show-toplevel) 5 | cd $GITROOT 6 | 7 | VER=1.0 8 | REL=$(git rev-parse --short HEAD)git 9 | RPMTOPDIR=$GITROOT/rpm-build 10 | echo "Ver: $VER, Release: $REL" 11 | 12 | # Create tarball 13 | mkdir -p $RPMTOPDIR/{SOURCES,SPECS} 14 | git archive --format=tar --prefix=ninja-${VER}-${REL}/ HEAD | gzip -c > $RPMTOPDIR/SOURCES/ninja-${VER}-${REL}.tar.gz 15 | 16 | # Convert git log to RPM's ChangeLog format (shown with rpm -qp --changelog ) 17 | sed -e "s/%{ver}/$VER/" -e "s/%{rel}/$REL/" misc/packaging/ninja.spec > $RPMTOPDIR/SPECS/ninja.spec 18 | git log --format="* %cd %aN%n- (%h) %s%d%n" --date=local | sed -r 's/[0-9]+:[0-9]+:[0-9]+ //' >> $RPMTOPDIR/SPECS/ninja.spec 19 | 20 | # Build SRC and binary RPMs 21 | rpmbuild --quiet \ 22 | --define "_topdir $RPMTOPDIR" \ 23 | --define "_rpmdir $PWD" \ 24 | --define "_srcrpmdir $PWD" \ 25 | --define '_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm' \ 26 | -ba $RPMTOPDIR/SPECS/ninja.spec && 27 | 28 | rm -rf $RPMTOPDIR && 29 | echo Done 30 | -------------------------------------------------------------------------------- /0.2/high/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.2 - High 2 | 3 | The Ferris 0.2 High is a simple port from the 0.1 High with a similarly reduced number of features. 4 | It's the Ferris with MX footprints for those who want to use the latest hardware :) 5 | ![Ferris 0.2 Compact](https://i.imgur.com/AIdXMnM.png) 6 | 7 | ## Specific features: 8 | * MX switches 9 | * Width: 10.9 cm 10 | * Height: 9.6 cm 11 | * Depth: 2.4 cm (from desk to top of keycap with BSP keycaps and 2mm rubber bumper) 12 | 13 | ## Hardware status: 14 | Working boards are yet to be printed and tested. 15 | 16 | ## Firmware status: 17 | * Support coming to upstream qmk with [this PR](https://github.com/qmk/qmk_firmware/pull/12133) 18 | * Support coming to upstream zmk with [this PR](https://github.com/zmkfirmware/zmk/pull/642) 19 | * Plan to write rust firmware for it eventually tracked in [this issue](https://github.com/pierrechevalier83/ferris/issues/2) 20 | Support coming to upstream qmk with [this PR](https://github.com/qmk/qmk_firmware/pull/12133) 21 | Support coming to upstream zmk with [this PR](https://github.com/zmkfirmware/zmk/pull/642) 22 | Plan to write rust firmware for it eventually tracked in [this issue](https://github.com/pierrechevalier83/ferris/issues/2) 23 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/debug_flags.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_EXPLAIN_H_ 16 | #define NINJA_EXPLAIN_H_ 17 | 18 | #include 19 | 20 | #define EXPLAIN(fmt, ...) { \ 21 | if (g_explaining) \ 22 | fprintf(stderr, "ninja explain: " fmt "\n", __VA_ARGS__); \ 23 | } 24 | 25 | extern bool g_explaining; 26 | 27 | extern bool g_keep_depfile; 28 | 29 | extern bool g_keep_rsp; 30 | 31 | extern bool g_experimental_statcache; 32 | 33 | #endif // NINJA_EXPLAIN_H_ 34 | -------------------------------------------------------------------------------- /0.1/readme.md: -------------------------------------------------------------------------------- 1 | Ferris 0.1 2 | === 3 | 4 | ![Ferris 0.1 family](https://i.imgur.com/TCjkquR.jpg) 5 | 6 | The 0.1 variants of the Ferris generally share the same underlying PCB design, 7 | with varying functionalities to cater to different tastes. 8 | 9 | The left hand uses an Atmega32u4 chip with an external crystal connected to the 10 | computer via USB-C. 11 | 12 | The right hand is connected to the left hand using a 4 poles TRRS Jack cable. 13 | On the right PCB, there is a passive I/O expander (the MCP23017) which allows to 14 | handle the input from the 5 by 4 switch matrix while only needing 4 pins (for i2c) 15 | between halves. 16 | 17 | Four variants were designed, printed and verified to work: 18 | * [Base variant](base/readme.md) (Choc switches with MX spacing) 19 | * [Ferris Low](low/readme.md) (Choc mini) 20 | * [Ferris High](high/readme.md) (MX switches) 21 | * [Ferris Compact](compact/readme.md) (Choc switches with choc spacing) 22 | 23 | Note that the 0.1 design does not include any protection against electrostatic discharge. 24 | 25 | For that reason, it is recommended to favour the 0.2 designs except if you really prefer 26 | one of the 0.1 variants for some specific reason (for instance, you may have spare 27 | Atmega32u4 chips on hand). 28 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/string_piece_util.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_STRINGPIECE_UTIL_H_ 16 | #define NINJA_STRINGPIECE_UTIL_H_ 17 | 18 | #include 19 | #include 20 | 21 | #include "string_piece.h" 22 | 23 | std::vector SplitStringPiece(StringPiece input, char sep); 24 | 25 | std::string JoinStringPiece(const std::vector& list, char sep); 26 | 27 | inline char ToLowerASCII(char c) { 28 | return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c; 29 | } 30 | 31 | bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b); 32 | 33 | #endif // NINJA_STRINGPIECE_UTIL_H_ 34 | -------------------------------------------------------------------------------- /0.2/bling/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.2 - Bling 2 | 3 | By design, most Ferris variants come with an extremely limited set of features. 4 | "It's just a keyboard" 5 | 6 | The Bling breaks away from this tradition to serve users who like a little bit 7 | of "bling" in their life :) 8 | 9 | ![Ferris Bling](https://i.imgur.com/LwKlmnz.jpg) 10 | ![Ferris Bling Silk](https://media4.giphy.com/media/7GF1Ns1y66IMlpD9lN/giphy.gif) 11 | 12 | ## Specific features: 13 | * Choc switches (PG 1350) 14 | * Choc spacing (18x17mm) 15 | * Width: 10.4 cm 16 | * Height: 9.0 cm 17 | * Height: 1.5 cm (from desk to top of keycap with MBK switch and 2mm rubber bumper) 18 | * Support for case (with mounting holes) 19 | * Support for tenting puck 20 | * RGB underglow 21 | 22 | ## Hardware status: 23 | Working boards were produced. 24 | 25 | ## Firmware status: 26 | * Support coming to upstream qmk with [this PR](https://github.com/qmk/qmk_firmware/pull/12133) 27 | * Support for the underglow feature is missing from this PR, but will come in a subsequent PR. It works for me :) 28 | * Support coming to upstream zmk with [this PR](https://github.com/zmkfirmware/zmk/pull/642) 29 | Plan to write rust firmware for it eventually tracked in [this issue](https://github.com/pierrechevalier83/ferris/issues/2) 30 | -------------------------------------------------------------------------------- /0.2/high/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 4 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 5 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 6 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 7 | (lib (name MCU_ST_STM32F0)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_ST_STM32F0.lib)(options "")(descr "")) 8 | (lib (name Power_Protection)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Power_Protection.lib)(options "")(descr "")) 9 | (lib (name Regulator_Linear)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Regulator_Linear.lib)(options "")(descr "")) 10 | (lib (name Transistor_BJT)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Transistor_BJT.lib)(options "")(descr "")) 11 | (lib (name Diode)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Diode.lib)(options "")(descr "")) 12 | ) 13 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/examples/populate/source_html.md: -------------------------------------------------------------------------------- 1 | --- 2 | params: 3 | - --remap remap.json 4 | img_name: img/populating_{}.png 5 | template: simple 6 | type: html 7 | board: ../ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb 8 | libs: kicad-default 9 | ... 10 | 11 | # Demo population manual 12 | 13 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Itaque earum rerum hic 14 | tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias 15 | consequatur aut perferendis doloribus asperiores repellat. Vestibulum fermentum 16 | tortor id mi. Nulla turpis magna, cursus sit amet, suscipit a, interdum id, 17 | felis. 18 | 19 | - [[front | ]] This is the front side of the board we are populating 20 | - [[back | ]] This is the back side of the board we are populating 21 | - [[front | RV1, RV2 ]] First, populate RV1 and RV2. Basically, any description 22 | could be here. 23 | - [[front | U2 ]] Let's populate U2! 24 | 25 | You can put a paragraph of text between the population steps. Lorem ipsum dolor 26 | sit amet, consectetuer adipiscing elit. Itaque earum rerum hic tenetur a 27 | sapiente. 28 | 29 | - [[back | R24 ]] We can also populate a component on the other side 30 | 31 | ## Conclusion 32 | 33 | This is the end of the demo. -------------------------------------------------------------------------------- /automation/tools/ninja/src/version.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_VERSION_H_ 16 | #define NINJA_VERSION_H_ 17 | 18 | #include 19 | 20 | /// The version number of the current Ninja release. This will always 21 | /// be "git" on trunk. 22 | extern const char* kNinjaVersion; 23 | 24 | /// Parse the major/minor components of a version string. 25 | void ParseVersion(const std::string& version, int* major, int* minor); 26 | 27 | /// Check whether \a version is compatible with the current Ninja version, 28 | /// aborting if not. 29 | void CheckNinjaVersion(const std::string& required_version); 30 | 31 | #endif // NINJA_VERSION_H_ 32 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/browse.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_BROWSE_H_ 16 | #define NINJA_BROWSE_H_ 17 | 18 | struct State; 19 | 20 | /// Run in "browse" mode, which execs a Python webserver. 21 | /// \a ninja_command is the command used to invoke ninja. 22 | /// \a args are the number of arguments to be passed to the Python script. 23 | /// \a argv are arguments to be passed to the Python script. 24 | /// This function does not return if it runs successfully. 25 | void RunBrowsePython(State* state, const char* ninja_command, 26 | const char* input_file, int argc, char* argv[]); 27 | 28 | #endif // NINJA_BROWSE_H_ 29 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/timestamp.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_TIMESTAMP_H_ 16 | #define NINJA_TIMESTAMP_H_ 17 | 18 | #ifdef _WIN32 19 | #include "win32port.h" 20 | #else 21 | #ifndef __STDC_FORMAT_MACROS 22 | #define __STDC_FORMAT_MACROS 23 | #endif 24 | #include 25 | #endif 26 | 27 | // When considering file modification times we only care to compare 28 | // them against one another -- we never convert them to an absolute 29 | // real time. On POSIX we use timespec (seconds&nanoseconds since epoch) 30 | // and on Windows we use a different value. Both fit in an int64. 31 | typedef int64_t TimeStamp; 32 | 33 | #endif // NINJA_TIMESTAMP_H_ 34 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/msvc_helper.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | std::string EscapeForDepfile(const std::string& path); 18 | 19 | /// Wraps a synchronous execution of a CL subprocess. 20 | struct CLWrapper { 21 | CLWrapper() : env_block_(NULL) {} 22 | 23 | /// Set the environment block (as suitable for CreateProcess) to be used 24 | /// by Run(). 25 | void SetEnvBlock(void* env_block) { env_block_ = env_block; } 26 | 27 | /// Start a process and gather its raw output. Returns its exit code. 28 | /// Crashes (calls Fatal()) on error. 29 | int Run(const std::string& command, std::string* output); 30 | 31 | void* env_block_; 32 | }; 33 | -------------------------------------------------------------------------------- /0.1/bom.csv: -------------------------------------------------------------------------------- 1 | Comment,Designator,Footprint,LCSC, LCSC Part # 2 | 22p,"C1,C2",Capacitor_SMD:C_0805_2012Metric_Pad1.15x1.40mm_HandSolder,,C1804 3 | 0.1u,"C3,C4,C5,C6,C9,C10",Capacitor_SMD:C_0805_2012Metric_Pad1.15x1.40mm_HandSolder,,C49678 4 | 4.7u,C7,Capacitor_SMD:C_0805_2012Metric_Pad1.15x1.40mm_HandSolder,,C1779 5 | 1u,C8,Capacitor_SMD:C_0805_2012Metric_Pad1.15x1.40mm_HandSolder,,C28323 6 | D,"D0_0,D1_0,D0_1,D1_1,D0_2,D1_2,D2_0,D2_1,D2_2,D0_3,D1_3,D2_3,D0_4,D1_4,D2_4,D3_3,D3_4,D0_5,D1_5,D0_6,D1_6,D0_7,D1_7,D2_5,D2_6,D2_7,D0_8,D1_8,D2_8,D0_9,D1_9,D2_9,D3_5,D3_6",Diode_SMD:D_SOD-123,,C81598 7 | 500mA,F1,Fuse:Fuse_1206_3216Metric,,C151162 8 | USB C,J1,Connector_USB:USB_C_Receptacle_HRO_TYPE-C-31-M-12,,C165948 9 | TRRS,"Jack1,Jack0",kbd:TRRS-PJ-320A,, 10 | 10k,"R1,R2,R9",Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder,,C17414 11 | 22,"R4,R3",Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder,, C17561 12 | 5.1K,"R5,R6",Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder,,C27834 13 | 4.7k,"R7,R8",Resistor_SMD:R_0805_2012Metric_Pad1.15x1.40mm_HandSolder,,C17673 14 | SW_PUSH,SW1,Button_Switch_SMD:SW_SPST_B3U-1000P,,C231329 15 | ATmega32U4-AU,U1,Package_QFP:TQFP-44_10x10mm_P0.8mm,,C44854 16 | MCP23017_SO,U2,Package_SO:SOIC-28W_7.5x17.9mm_P1.27mm,,C47023 17 | Crystal,Y1,Crystal:Crystal_SMD_3225-4Pin_3.2x2.5mm,,C13738 18 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import setuptools 4 | import versioneer 5 | 6 | with open("README.md", "r") as fh: 7 | long_description = fh.read() 8 | 9 | setuptools.setup( 10 | name="PcbDraw", 11 | version=versioneer.get_version(), 12 | cmdclass=versioneer.get_cmdclass(), 13 | author="Jan Mrázek", 14 | author_email="email@honzamrazek.cz", 15 | description="Utility to produce nice looking drawings of KiCAD boards", 16 | long_description=long_description, 17 | long_description_content_type="text/markdown", 18 | url="https://github.com/yaqwsx/PcbDraw", 19 | packages=setuptools.find_packages(), 20 | classifiers=[ 21 | "Programming Language :: Python :: 3", 22 | "License :: OSI Approved :: MIT License", 23 | "Operating System :: OS Independent", 24 | ], 25 | install_requires=[ 26 | "numpy", 27 | "lxml", 28 | "mistune", 29 | "pybars3", 30 | "wand", 31 | "pyyaml" 32 | ], 33 | setup_requires=[ 34 | "versioneer" 35 | ], 36 | zip_safe=False, 37 | include_package_data=True, 38 | entry_points = { 39 | "console_scripts": [ 40 | "pcbdraw=pcbdraw.pcbdraw:main", 41 | "populate=pcbdraw.populate:main" 42 | ], 43 | } 44 | ) -------------------------------------------------------------------------------- /automation/tools/ninja/src/win32port.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_WIN32PORT_H_ 16 | #define NINJA_WIN32PORT_H_ 17 | 18 | #if defined(__MINGW32__) || defined(__MINGW64__) 19 | #ifndef __STDC_FORMAT_MACROS 20 | #define __STDC_FORMAT_MACROS 21 | #endif 22 | #include 23 | #endif 24 | 25 | typedef signed short int16_t; 26 | typedef unsigned short uint16_t; 27 | /// A 64-bit integer type 28 | typedef signed long long int64_t; 29 | typedef unsigned long long uint64_t; 30 | 31 | // printf format specifier for uint64_t, from C99. 32 | #ifndef PRIu64 33 | #define PRId64 "I64d" 34 | #define PRIu64 "I64u" 35 | #define PRIx64 "I64x" 36 | #endif 37 | 38 | #endif // NINJA_WIN32PORT_H_ 39 | 40 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/graphviz.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_GRAPHVIZ_H_ 16 | #define NINJA_GRAPHVIZ_H_ 17 | 18 | #include 19 | 20 | #include "dyndep.h" 21 | 22 | struct DiskInterface; 23 | struct Node; 24 | struct Edge; 25 | struct State; 26 | 27 | /// Runs the process of creating GraphViz .dot file output. 28 | struct GraphViz { 29 | GraphViz(State* state, DiskInterface* disk_interface) 30 | : dyndep_loader_(state, disk_interface) {} 31 | void Start(); 32 | void AddTarget(Node* node); 33 | void Finish(); 34 | 35 | DyndepLoader dyndep_loader_; 36 | std::set visited_nodes_; 37 | std::set visited_edges_; 38 | }; 39 | 40 | #endif // NINJA_GRAPHVIZ_H_ 41 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/README.md: -------------------------------------------------------------------------------- 1 | # PcbDraw 2 | 3 | Convert your KiCAD boards into nice looking 2D drawings suitable for pinout 4 | diagrams. Never draw them manually again! 5 | 6 | ![example](promo_pcbdraw.png) 7 | 8 | This small Python script takes a KiCAD board (.kicad_pcb file) and produces a 2D 9 | nice looking drawing of the board as an SVG file. This allows you to quickly and 10 | automatically create awesome pinout diagrams for your project. These diagrams 11 | are much easier to read than a labeled photo of a physical board or an actual 12 | KiCAD design. 13 | 14 | You and your users will love them! 15 | 16 | PcbDraw also comes with a small utility called Populate which allows you to 17 | easily specify & maintain nice looking HTML or Markdown population manuals. 18 | 19 | ![example](promo_populate.jpg) 20 | 21 | ## Usage 22 | 23 | There are two separate guides: 24 | 25 | - [usage of PcbDraw](doc/pcbdraw.md) 26 | - [usage of Populate](doc/populate.md) 27 | 28 | There are also examples of usage in the `examples` directory. 29 | 30 | ## Contributing 31 | 32 | Feel free to submit issues and pull requests! 33 | 34 | ## Future Work 35 | 36 | - make reasonably complete module library 37 | - produce nicer SVG file structures (make SVG smaller by including each module 38 | exactly once, treat ids correctly,...) 39 | - support value labels on modules 40 | -------------------------------------------------------------------------------- /0.2/mini/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name ferris-rescue)(type Legacy)(uri ${KIPRJMOD}/ferris-rescue.lib)(options "")(descr "")) 4 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 5 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 6 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 7 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 8 | (lib (name MCU_ST_STM32F0)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_ST_STM32F0.lib)(options "")(descr "")) 9 | (lib (name Power_Protection)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Power_Protection.lib)(options "")(descr "")) 10 | (lib (name Regulator_Linear)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Regulator_Linear.lib)(options "")(descr "")) 11 | (lib (name Transistor_BJT)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Transistor_BJT.lib)(options "")(descr "")) 12 | (lib (name Diode)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Diode.lib)(options "")(descr "")) 13 | ) 14 | -------------------------------------------------------------------------------- /0.2/bling/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 4 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 5 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 6 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 7 | (lib (name MCU_ST_STM32F0)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_ST_STM32F0.lib)(options "")(descr "")) 8 | (lib (name Power_Protection)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Power_Protection.lib)(options "")(descr "")) 9 | (lib (name Driver_LED)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Driver_LED.lib)(options "")(descr "")) 10 | (lib (name Regulator_Linear)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Regulator_Linear.lib)(options "")(descr "")) 11 | (lib (name Transistor_BJT)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Transistor_BJT.lib)(options "")(descr "")) 12 | (lib (name Diode)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Diode.lib)(options "")(descr "")) 13 | ) 14 | -------------------------------------------------------------------------------- /0.2/compact/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (lib (name keyboard_parts)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_lib_tmk/keyboard_parts.lib)(options "")(descr "")) 3 | (lib (name Connector)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Connector.lib)(options "")(descr "")) 4 | (lib (name Device)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Device.lib)(options "")(descr "")) 5 | (lib (name Interface_Expansion)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Interface_Expansion.lib)(options "")(descr "")) 6 | (lib (name power)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/power.lib)(options "")(descr "")) 7 | (lib (name MCU_ST_STM32F0)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/MCU_ST_STM32F0.lib)(options "")(descr "")) 8 | (lib (name Power_Protection)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Power_Protection.lib)(options "")(descr "")) 9 | (lib (name Driver_LED)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Driver_LED.lib)(options "")(descr "")) 10 | (lib (name Regulator_Linear)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Regulator_Linear.lib)(options "")(descr "")) 11 | (lib (name Transistor_BJT)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Transistor_BJT.lib)(options "")(descr "")) 12 | (lib (name Diode)(type Legacy)(uri ${KIPRJMOD}/../../sym/kicad_library/Diode.lib)(options "")(descr "")) 13 | ) 14 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/ecad/kicad_extra/xmlparser.py: -------------------------------------------------------------------------------- 1 | from xml.dom import minidom 2 | 3 | from .parser_base import ParserBase 4 | 5 | 6 | class XmlParser(ParserBase): 7 | @staticmethod 8 | def get_text(nodelist): 9 | rc = [] 10 | for node in nodelist: 11 | if node.nodeType == node.TEXT_NODE: 12 | rc.append(node.data) 13 | return ''.join(rc) 14 | 15 | def get_extra_field_data(self): 16 | xml = minidom.parse(self.file_name) 17 | components = xml.getElementsByTagName('comp') 18 | field_set = set() 19 | comp_dict = {} 20 | for c in components: 21 | ref_fields = comp_dict.setdefault(c.attributes['ref'].value, {}) 22 | datasheet = c.getElementsByTagName('datasheet') 23 | if datasheet: 24 | datasheet = self.get_text(datasheet[0].childNodes) 25 | if datasheet != '~': 26 | field_set.add('datasheet') 27 | ref_fields['datasheet'] = datasheet 28 | for f in c.getElementsByTagName('field'): 29 | name = f.attributes['name'].value 30 | if name not in self.DEFAULT_FIELDS: 31 | field_set.add(name) 32 | ref_fields[name] = self.get_text(f.childNodes) 33 | 34 | return list(field_set), comp_dict 35 | -------------------------------------------------------------------------------- /0.2/readme.md: -------------------------------------------------------------------------------- 1 | Ferris 0.2 2 | === 3 | 4 | ![Ferris Bling](https://i.imgur.com/LwKlmnz.jpg) 5 | ![Ferris Bling Silk](https://media4.giphy.com/media/7GF1Ns1y66IMlpD9lN/giphy.gif) 6 | 7 | The 0.2 variants of the Ferris generally share the same hardware, although the 8 | Ferris bling has additional circuitry to offer RGB underglow. 9 | 10 | Like the 0.1 designs, multiple variants are available to cater for different tastes. 11 | 12 | The left hand uses an arm chip (STM32F072) as well as components to protect the board 13 | against electrostatic discharge. 14 | 15 | The right hand is connected to the left hand using a 4 poles TRRS Jack cable. 16 | On the right PCB, there is a passive I/O expander (the MCP23017) which allows to 17 | handle the input from the 5 by 4 switch matrix while only needing 4 pins (for i2c) 18 | between halves. 19 | 20 | Four variants were designed. Not all were tested yet. See subdirectories for individual 21 | status 22 | * [Ferris Bling](bling/readme.md) (Choc, Choc spacing, packed with features) 23 | * [Ferris Compact](compact/readme.md) (Choc, Choc spacing, as minimalistic as the previous Ferris we all know and love) 24 | * [Ferris High](high/readme.md) (MX switches) 25 | * [Ferris Mini](mini/readme.md) (Choc mini switches with choc spacing) 26 | 27 | If there is a combination of features that you are interested in and none of these variants offer, 28 | feel free to raise an issue or a PR :) 29 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/msvc_helper_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "msvc_helper.h" 16 | 17 | #include "test.h" 18 | #include "util.h" 19 | 20 | using namespace std; 21 | 22 | TEST(EscapeForDepfileTest, SpacesInFilename) { 23 | ASSERT_EQ("sub\\some\\ sdk\\foo.h", 24 | EscapeForDepfile("sub\\some sdk\\foo.h")); 25 | } 26 | 27 | TEST(MSVCHelperTest, EnvBlock) { 28 | char env_block[] = "foo=bar\0"; 29 | CLWrapper cl; 30 | cl.SetEnvBlock(env_block); 31 | string output; 32 | cl.Run("cmd /c \"echo foo is %foo%", &output); 33 | ASSERT_EQ("foo is bar\r\n", output); 34 | } 35 | 36 | TEST(MSVCHelperTest, NoReadOfStderr) { 37 | CLWrapper cl; 38 | string output; 39 | cl.Run("cmd /c \"echo to stdout&& echo to stderr 1>&2", &output); 40 | ASSERT_EQ("to stdout\r\n", output); 41 | } 42 | -------------------------------------------------------------------------------- /automation/tools/ninja/.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | on: 4 | pull_request: 5 | push: 6 | release: 7 | types: published 8 | 9 | jobs: 10 | build: 11 | runs-on: windows-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Install dependencies 17 | run: choco install re2c 18 | 19 | - name: Build ninja 20 | shell: bash 21 | run: | 22 | cmake -DCMAKE_BUILD_TYPE=Release -B build 23 | cmake --build build --parallel --config Release 24 | 25 | - name: Test ninja 26 | run: .\ninja_test.exe 27 | working-directory: build/Release 28 | 29 | - name: Create ninja archive 30 | shell: bash 31 | run: | 32 | mkdir artifact 33 | 7z a artifact/ninja-win.zip ./build/Release/ninja.exe 34 | 35 | # Upload ninja binary archive as an artifact 36 | - name: Upload artifact 37 | uses: actions/upload-artifact@v1 38 | with: 39 | name: ninja-binary-archives 40 | path: artifact 41 | 42 | - name: Upload release asset 43 | if: github.event.action == 'published' 44 | uses: actions/upload-release-asset@v1.0.1 45 | env: 46 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 47 | with: 48 | upload_url: ${{ github.event.release.upload_url }} 49 | asset_path: ./artifact/ninja-win.zip 50 | asset_name: ninja-win.zip 51 | asset_content_type: application/zip 52 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/packaging/ninja.spec: -------------------------------------------------------------------------------- 1 | Summary: Ninja is a small build system with a focus on speed. 2 | Name: ninja 3 | Version: %{ver} 4 | Release: %{rel}%{?dist} 5 | Group: Development/Tools 6 | License: Apache 2.0 7 | URL: https://github.com/ninja-build/ninja 8 | Source0: %{name}-%{version}-%{rel}.tar.gz 9 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{rel} 10 | 11 | BuildRequires: asciidoc 12 | 13 | %description 14 | Ninja is yet another build system. It takes as input the interdependencies of files (typically source code and output executables) and 15 | orchestrates building them, quickly. 16 | 17 | Ninja joins a sea of other build systems. Its distinguishing goal is to be fast. It is born from my work on the Chromium browser project, 18 | which has over 30,000 source files and whose other build systems (including one built from custom non-recursive Makefiles) can take ten 19 | seconds to start building after changing one file. Ninja is under a second. 20 | 21 | %prep 22 | %setup -q -n %{name}-%{version}-%{rel} 23 | 24 | %build 25 | echo Building.. 26 | ./configure.py --bootstrap 27 | ./ninja manual 28 | 29 | %install 30 | mkdir -p %{buildroot}%{_bindir} %{buildroot}%{_docdir} 31 | cp -p ninja %{buildroot}%{_bindir}/ 32 | 33 | %files 34 | %defattr(-, root, root) 35 | %doc COPYING README.md doc/manual.html 36 | %{_bindir}/* 37 | 38 | %clean 39 | rm -rf %{buildroot} 40 | 41 | #The changelog is built automatically from Git history 42 | %changelog 43 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/inline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2001 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This quick script converts a text file into an #include-able header. 18 | # It expects the name of the variable as its first argument, and reads 19 | # stdin and writes stdout. 20 | 21 | varname="$1" 22 | 23 | # 'od' and 'sed' may not be available on all platforms, and may not support the 24 | # flags used here. We must ensure that the script exits with a non-zero exit 25 | # code in those cases. 26 | byte_vals=$(od -t x1 -A n -v) || exit 1 27 | escaped_byte_vals=$(echo "${byte_vals}" \ 28 | | sed -e 's|^[\t ]\{0,\}$||g; s|[\t ]\{1,\}| |g; s| \{1,\}$||g; s| |\\x|g; s|^|"|; s|$|"|') \ 29 | || exit 1 30 | 31 | # Only write output once we have successfully generated the required data 32 | printf "const char %s[] = \n%s;" "${varname}" "${escaped_byte_vals}" 33 | -------------------------------------------------------------------------------- /automation/tools/ninja/.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: macOS 2 | 3 | on: 4 | pull_request: 5 | push: 6 | release: 7 | types: published 8 | 9 | jobs: 10 | build: 11 | runs-on: macOS-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Install dependencies 17 | run: brew install re2c p7zip cmake 18 | 19 | - name: Build ninja 20 | shell: bash 21 | env: 22 | MACOSX_DEPLOYMENT_TARGET: 10.12 23 | run: | 24 | cmake -DCMAKE_BUILD_TYPE=Release -B build 25 | cmake --build build --parallel --config Release 26 | 27 | - name: Test ninja 28 | run: ctest -vv 29 | working-directory: build 30 | 31 | - name: Create ninja archive 32 | shell: bash 33 | run: | 34 | mkdir artifact 35 | 7z a artifact/ninja-mac.zip ./build/ninja 36 | 37 | # Upload ninja binary archive as an artifact 38 | - name: Upload artifact 39 | uses: actions/upload-artifact@v1 40 | with: 41 | name: ninja-binary-archives 42 | path: artifact 43 | 44 | - name: Upload release asset 45 | if: github.event.action == 'published' 46 | uses: actions/upload-release-asset@v1.0.1 47 | env: 48 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 49 | with: 50 | upload_url: ${{ github.event.release.upload_url }} 51 | asset_path: ./artifact/ninja-mac.zip 52 | asset_name: ninja-mac.zip 53 | asset_content_type: application/zip 54 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | # VSCode settings 92 | .vscode -------------------------------------------------------------------------------- /automation/tools/ninja/README.md: -------------------------------------------------------------------------------- 1 | # Ninja 2 | 3 | Ninja is a small build system with a focus on speed. 4 | https://ninja-build.org/ 5 | 6 | See [the manual](https://ninja-build.org/manual.html) or 7 | `doc/manual.asciidoc` included in the distribution for background 8 | and more details. 9 | 10 | Binaries for Linux, Mac, and Windows are available at 11 | [GitHub](https://github.com/ninja-build/ninja/releases). 12 | Run `./ninja -h` for Ninja help. 13 | 14 | Installation is not necessary because the only required file is the 15 | resulting ninja binary. However, to enable features like Bash 16 | completion and Emacs and Vim editing modes, some files in misc/ must be 17 | copied to appropriate locations. 18 | 19 | If you're interested in making changes to Ninja, read 20 | [CONTRIBUTING.md](CONTRIBUTING.md) first. 21 | 22 | ## Building Ninja itself 23 | 24 | You can either build Ninja via the custom generator script written in Python or 25 | via CMake. For more details see 26 | [the wiki](https://github.com/ninja-build/ninja/wiki). 27 | 28 | ### Python 29 | 30 | ``` 31 | ./configure.py --bootstrap 32 | ``` 33 | 34 | This will generate the `ninja` binary and a `build.ninja` file you can now use 35 | to build Ninja with itself. 36 | 37 | ### CMake 38 | 39 | ``` 40 | cmake -Bbuild-cmake -H. 41 | cmake --build build-cmake 42 | ``` 43 | 44 | The `ninja` binary will now be inside the `build-cmake` directory (you can 45 | choose any other name you like). 46 | 47 | To run the unit tests: 48 | 49 | ``` 50 | ./build-cmake/ninja_test 51 | ``` 52 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/depfile_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_DEPFILE_PARSER_H_ 16 | #define NINJA_DEPFILE_PARSER_H_ 17 | 18 | #include 19 | #include 20 | 21 | #include "string_piece.h" 22 | 23 | struct DepfileParserOptions { 24 | DepfileParserOptions() {} 25 | }; 26 | 27 | /// Parser for the dependency information emitted by gcc's -M flags. 28 | struct DepfileParser { 29 | explicit DepfileParser(DepfileParserOptions options = 30 | DepfileParserOptions()); 31 | 32 | /// Parse an input file. Input must be NUL-terminated. 33 | /// Warning: may mutate the content in-place and parsed StringPieces are 34 | /// pointers within it. 35 | bool Parse(std::string* content, std::string* err); 36 | 37 | std::vector outs_; 38 | std::vector ins_; 39 | DepfileParserOptions options_; 40 | }; 41 | 42 | #endif // NINJA_DEPFILE_PARSER_H_ 43 | -------------------------------------------------------------------------------- /automation/tools/ninja/RELEASING: -------------------------------------------------------------------------------- 1 | Notes to myself on all the steps to make for a Ninja release. 2 | 3 | Push new release branch: 4 | 1. Run afl-fuzz for a day or so and run ninja_test 5 | 2. Consider sending a heads-up to the ninja-build mailing list first 6 | 3. Make sure branches 'master' and 'release' are synced up locally 7 | 4. Update src/version.cc with new version (with ".git"), then 8 | git commit -am 'mark this 1.5.0.git' 9 | 5. git checkout release; git merge master 10 | 6. Fix version number in src/version.cc (it will likely conflict in the above) 11 | 7. Fix version in doc/manual.asciidoc (exists only on release branch) 12 | 8. commit, tag, push (don't forget to push --tags) 13 | git commit -am v1.5.0; git push origin release 14 | git tag v1.5.0; git push --tags 15 | # Push the 1.5.0.git change on master too: 16 | git checkout master; git push origin master 17 | 9. Construct release notes from prior notes 18 | credits: git shortlog -s --no-merges REV.. 19 | 20 | Release on github: 21 | 1. https://github.com/blog/1547-release-your-software 22 | Add binaries to https://github.com/ninja-build/ninja/releases 23 | 24 | Make announcement on mailing list: 25 | 1. copy old mail 26 | 27 | Update website: 28 | 1. Make sure your ninja checkout is on the v1.5.0 tag 29 | 2. Clone https://github.com/ninja-build/ninja-build.github.io 30 | 3. In that repo, `./update-docs.sh` 31 | 4. Update index.html with newest version and link to release notes 32 | 5. git commit -m 'run update-docs.sh, 1.5.0 release' 33 | 6. git push origin master 34 | -------------------------------------------------------------------------------- /0.2/mini/readme.md: -------------------------------------------------------------------------------- 1 | # Ferris 0.2 - Mini 2 | 3 | The Ferris 0.2 mini is the tiniest Ferris in all dimensions: 4 | * It uses choc mini switches, like the Ferris 0.1 Low to reduce the keyboard's depth. 5 | * It uses choc spacing between keys, like the Ferris 0.1 and 0.2 compact. 6 | * It has no extra feature needing extra space. 7 | 8 | Reminder that like for the Ferris 0.1 low, this keyboard uses uncommon and less readily 9 | available "choc mini" switches that can be acquired from Kailh's store on AliExpress: 10 | * [Listing for choc mini white (clicky) switches](https://www.aliexpress.com/item/32989908397.html?spm=2114.12010612.8148356.16.41f639a68SKHzM) 11 | * [Listing for choc mini brown (tactile) and black (linear) switches](https://www.aliexpress.com/item/4000277394324.html?spm=2114.12010612.8148356.42.194a7aebEvJRzh) 12 | 13 | ![Ferris 0.2 Mini](https://i.imgur.com/55Awsyf.png) 14 | 15 | ## Specific features: 16 | * Choc mini switches (PG 1232) 17 | * Choc switches (PG 1350) 18 | * Choc spacing (18x17mm) 19 | * Width: 10.4 cm 20 | * Height: 8.8 cm 21 | * Height: 1.2 cm (from desk to top of keycap with MBK switch and 2mm rubber bumper) 22 | 23 | ## Hardware status: 24 | Working boards are yet to be printed and tested. 25 | 26 | ## Firmware status: 27 | * Support coming to upstream qmk with [this PR](https://github.com/qmk/qmk_firmware/pull/12133) 28 | * Support coming to upstream zmk with [this PR](https://github.com/zmkfirmware/zmk/pull/642) 29 | * Plan to write rust firmware for it eventually tracked in [this issue](https://github.com/pierrechevalier83/ferris/issues/2) 30 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/state_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "graph.h" 16 | #include "state.h" 17 | #include "test.h" 18 | 19 | using namespace std; 20 | 21 | namespace { 22 | 23 | TEST(State, Basic) { 24 | State state; 25 | 26 | EvalString command; 27 | command.AddText("cat "); 28 | command.AddSpecial("in"); 29 | command.AddText(" > "); 30 | command.AddSpecial("out"); 31 | 32 | Rule* rule = new Rule("cat"); 33 | rule->AddBinding("command", command); 34 | state.bindings_.AddRule(rule); 35 | 36 | Edge* edge = state.AddEdge(rule); 37 | state.AddIn(edge, "in1", 0); 38 | state.AddIn(edge, "in2", 0); 39 | state.AddOut(edge, "out", 0); 40 | 41 | EXPECT_EQ("cat in1 in2 > out", edge->EvaluateCommand()); 42 | 43 | EXPECT_FALSE(state.GetNode("in1", 0)->dirty()); 44 | EXPECT_FALSE(state.GetNode("in2", 0)->dirty()); 45 | EXPECT_FALSE(state.GetNode("out", 0)->dirty()); 46 | } 47 | 48 | } // namespace 49 | -------------------------------------------------------------------------------- /automation/tools/ninja/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 1.0.{build} 2 | image: 3 | - Visual Studio 2017 4 | - Ubuntu1804 5 | 6 | environment: 7 | CLICOLOR_FORCE: 1 8 | CHERE_INVOKING: 1 # Tell Bash to inherit the current working directory 9 | matrix: 10 | - MSYSTEM: MINGW64 11 | - MSYSTEM: MSVC 12 | - MSYSTEM: LINUX 13 | 14 | matrix: 15 | exclude: 16 | - image: Visual Studio 2017 17 | MSYSTEM: LINUX 18 | - image: Ubuntu1804 19 | MSYSTEM: MINGW64 20 | - image: Ubuntu1804 21 | MSYSTEM: MSVC 22 | 23 | for: 24 | - 25 | matrix: 26 | only: 27 | - MSYSTEM: MINGW64 28 | build_script: 29 | ps: "C:\\msys64\\usr\\bin\\bash -lc @\"\n 30 | pacman -S --quiet --noconfirm --needed re2c 2>&1\n 31 | ./configure.py --bootstrap --platform mingw 2>&1\n 32 | ./ninja all\n 33 | ./ninja_test 2>&1\n 34 | ./misc/ninja_syntax_test.py 2>&1\n\"@" 35 | - 36 | matrix: 37 | only: 38 | - MSYSTEM: MSVC 39 | build_script: 40 | - cmd: >- 41 | call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" 42 | 43 | python configure.py --bootstrap 44 | 45 | ninja.bootstrap.exe all 46 | 47 | ninja_test 48 | 49 | python misc/ninja_syntax_test.py 50 | 51 | - matrix: 52 | only: 53 | - image: Ubuntu1804 54 | build_script: 55 | - ./configure.py --bootstrap 56 | - ./ninja all 57 | - ./ninja_test 58 | - misc/ninja_syntax_test.py 59 | - misc/output_test.py 60 | 61 | test: off 62 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/ecad/kicad_extra/parser_base.py: -------------------------------------------------------------------------------- 1 | class ParserBase: 2 | DEFAULT_FIELDS = [] 3 | 4 | def __init__(self, file_name): 5 | """ 6 | :param file_name: path to file that should be parsed. 7 | """ 8 | self.file_name = file_name 9 | 10 | @staticmethod 11 | def normalize_field_names(data): 12 | field_map = {f.lower(): f for f in reversed(data[0])} 13 | 14 | def remap(ref_fields): 15 | return {field_map[f.lower()]: v for (f, v) in 16 | sorted(ref_fields.items(), reverse=True)} 17 | 18 | field_data = {r: remap(d) for (r, d) in data[1].items()} 19 | return field_map.values(), field_data 20 | 21 | def parse(self, normalize_case): 22 | data = self.get_extra_field_data() 23 | if data is None: 24 | return None 25 | if normalize_case: 26 | data = self.normalize_field_names(data) 27 | return sorted(data[0]), data[1] 28 | 29 | def get_extra_field_data(self): 30 | # type: () -> tuple 31 | """ 32 | Parses the file and returns a extra field data. 33 | :return: tuple of the format 34 | ( 35 | [field_name1, field_name2,... ], 36 | { 37 | ref1: { 38 | field_name1: field_value1, 39 | field_name2: field_value2, 40 | ... 41 | ], 42 | ref2: ... 43 | } 44 | ) 45 | """ 46 | pass 47 | -------------------------------------------------------------------------------- /automation/tools/ninja/doc/docbook.xsl: -------------------------------------------------------------------------------- 1 | 3 | 5 | ]> 6 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 19 | book toc 20 | 21 | 22 | 0 23 | 24 | 25 | 1 26 | 27 | 30 | ul 31 | 32 | 34 | 35 | -------------------------------------------------------------------------------- /.kiplot.edge_cuts.yml: -------------------------------------------------------------------------------- 1 | # Adapted from example KiPlot config file 2 | # at `tools/kiplot/docs/samples/generic_plot.kiplot.yaml` 3 | 4 | kiplot: 5 | version: 1 6 | 7 | preflight: 8 | 9 | # one day.... 10 | check_zone_fills: false 11 | run_drc: false 12 | 13 | outputs: 14 | - name: DXF 15 | comment: "DXF Edge Cuts files" 16 | type: dxf 17 | dir: . 18 | options: 19 | exclude_edge_layer: true 20 | exclude_pads_from_silkscreen: true 21 | use_aux_axis_as_origin: false 22 | plot_sheet_reference: false 23 | plot_footprint_refs: false 24 | plot_footprint_values: false 25 | force_plot_invisible_refs_vals: false 26 | tent_vias: false 27 | check_zone_fills: false 28 | 29 | # PS options 30 | drill_marks: full 31 | sketch_plot: false 32 | use_aux_axis_as_origin: false 33 | polygon_mode: false 34 | layers: 35 | - layer: Edge.Cuts 36 | suffix: Edge_Cuts 37 | 38 | - name: SVG 39 | comment: "SVG files" 40 | type: svg 41 | dir: . 42 | options: 43 | exclude_edge_layer: true 44 | exclude_pads_from_silkscreen: true 45 | use_aux_axis_as_origin: false 46 | plot_sheet_reference: false 47 | plot_footprint_refs: false 48 | plot_footprint_values: false 49 | force_plot_invisible_refs_vals: false 50 | tent_vias: false 51 | check_zone_fills: false 52 | 53 | # SVG options 54 | line_width: 0.1 55 | drill_marks: full 56 | mirror_plot: false 57 | negative_plot: false 58 | layers: 59 | - layer: Edge.Cuts 60 | suffix: Edge_Cuts 61 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/ecad/kicad_extra/netlistparser.py: -------------------------------------------------------------------------------- 1 | import io 2 | 3 | from .parser_base import ParserBase 4 | from .sexpressions import parse_sexpression 5 | 6 | 7 | class NetlistParser(ParserBase): 8 | def get_extra_field_data(self): 9 | with io.open(self.file_name, 'r', encoding='utf-8') as f: 10 | sexpression = parse_sexpression(f.read()) 11 | components = None 12 | for s in sexpression: 13 | if s[0] == 'components': 14 | components = s[1:] 15 | if components is None: 16 | return None 17 | field_set = set() 18 | comp_dict = {} 19 | for c in components: 20 | ref = None 21 | fields = None 22 | datasheet = None 23 | for f in c[1:]: 24 | if f[0] == 'ref': 25 | ref = f[1] 26 | if f[0] == 'fields': 27 | fields = f[1:] 28 | if f[0] == 'datasheet': 29 | datasheet = f[1] 30 | if ref is None: 31 | return None 32 | ref_fields = comp_dict.setdefault(ref, {}) 33 | if datasheet and datasheet != '~': 34 | field_set.add('datasheet') 35 | ref_fields['datasheet'] = datasheet 36 | if fields is None: 37 | continue 38 | for f in fields: 39 | if len(f) > 1: 40 | field_set.add(f[1][1]) 41 | if len(f) > 2: 42 | ref_fields[f[1][1]] = f[2] 43 | 44 | return list(field_set), comp_dict 45 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/parser.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_PARSER_H_ 16 | #define NINJA_PARSER_H_ 17 | 18 | #include 19 | 20 | #include "lexer.h" 21 | 22 | struct FileReader; 23 | struct State; 24 | 25 | /// Base class for parsers. 26 | struct Parser { 27 | Parser(State* state, FileReader* file_reader) 28 | : state_(state), file_reader_(file_reader) {} 29 | 30 | /// Load and parse a file. 31 | bool Load(const std::string& filename, std::string* err, Lexer* parent = NULL); 32 | 33 | protected: 34 | /// If the next token is not \a expected, produce an error string 35 | /// saying "expected foo, got bar". 36 | bool ExpectToken(Lexer::Token expected, std::string* err); 37 | 38 | State* state_; 39 | FileReader* file_reader_; 40 | Lexer lexer_; 41 | 42 | private: 43 | /// Parse a file, given its contents as a string. 44 | virtual bool Parse(const std::string& filename, const std::string& input, 45 | std::string* err) = 0; 46 | }; 47 | 48 | #endif // NINJA_PARSER_H_ 49 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/dyndep_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_DYNDEP_PARSER_H_ 16 | #define NINJA_DYNDEP_PARSER_H_ 17 | 18 | #include "eval_env.h" 19 | #include "parser.h" 20 | 21 | struct DyndepFile; 22 | struct EvalString; 23 | 24 | /// Parses dyndep files. 25 | struct DyndepParser: public Parser { 26 | DyndepParser(State* state, FileReader* file_reader, 27 | DyndepFile* dyndep_file); 28 | 29 | /// Parse a text string of input. Used by tests. 30 | bool ParseTest(const std::string& input, std::string* err) { 31 | return Parse("input", input, err); 32 | } 33 | 34 | private: 35 | /// Parse a file, given its contents as a string. 36 | bool Parse(const std::string& filename, const std::string& input, 37 | std:: string* err); 38 | 39 | bool ParseDyndepVersion(std::string* err); 40 | bool ParseLet(std::string* key, EvalString* val, std::string* err); 41 | bool ParseEdge(std::string* err); 42 | 43 | DyndepFile* dyndep_file_; 44 | BindingEnv env_; 45 | }; 46 | 47 | #endif // NINJA_DYNDEP_PARSER_H_ 48 | -------------------------------------------------------------------------------- /automation/tools/kicad-jlcpcb-bom-plugin/bom_csv_jlcpcb.py: -------------------------------------------------------------------------------- 1 | # 2 | # Example python script to generate a BOM from a KiCad generic netlist 3 | # 4 | # Example: Sorted and Grouped CSV BOM 5 | # 6 | 7 | """ 8 | @package 9 | Generate a CSV BOM for use with JLCSMT service. 10 | Components are sorted by ref and grouped by value with same footprint 11 | Fields are (if exist). 12 | LCSC Part numbers are copied from the "LCSC Part" field, if exists. 13 | It is possible to hide components from the BOM by setting the 14 | "JLCPCB BOM" field to "0" or "false". 15 | 16 | Output fields: 17 | 'Comment', 'Designator', 'Footprint', 'LCSC Part #' 18 | 19 | Command line: 20 | python "pathToFile/bom_csv_jlcsmt.py" "%I" "%O.csv" 21 | """ 22 | 23 | import kicad_netlist_reader 24 | import csv 25 | import sys 26 | 27 | net = kicad_netlist_reader.netlist(sys.argv[1]) 28 | 29 | with open(sys.argv[2], 'w', newline='') as f: 30 | out = csv.writer(f) 31 | out.writerow(['Comment', 'Designator', 'Footprint', 'LCSC Part #']) 32 | 33 | for group in net.groupComponents(): 34 | refs = [] 35 | 36 | lcsc_pn = "" 37 | for component in group: 38 | if component.getField('JLCPCB BOM') in ['0', 'false', 'False', 'FALSE']: 39 | continue 40 | refs.append(component.getRef()) 41 | lcsc_pn = component.getField("LCSC Part") or lcsc_pn 42 | c = component 43 | 44 | if len(refs) == 0: 45 | continue 46 | 47 | # Fill in the component groups common data 48 | out.writerow([c.getValue() + " " + c.getDescription(), ",".join(refs), c.getFootprint().split(':')[1], 49 | lcsc_pn]) 50 | 51 | f.close() 52 | -------------------------------------------------------------------------------- /automation/tools/kicad-jlcpcb-bom-plugin/kicad_pos_to_cpl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf8 3 | 4 | # Converts a KiCad Footprint Position (.pos) File into JLCPCB compatible CPL file 5 | # Copyright (C) 2019, Uri Shaked. Released under the MIT license. 6 | # 7 | # Usage: kicad_pos_to_cpl.py [overrides.json] 8 | # 9 | # The overrides file is a JSON file that contains a single object. The key of that object 10 | # is the reference of the part of override, and the value is the amount of degrees to 11 | # add to the part's rotation. For instance, to rotate U1 by 90 degrees, and Q1 by 180 12 | # degrees, put the following value in the overrides.json file: 13 | # { "U1": 90, "Q1": 180 } 14 | 15 | import sys 16 | import csv 17 | import json 18 | from collections import OrderedDict 19 | 20 | overrides = {} 21 | 22 | if len(sys.argv) == 4: 23 | with open(sys.argv[3], 'r') as overrides_file: 24 | overrides = json.load(overrides_file) 25 | 26 | with open(sys.argv[1], 'r') as in_file, open(sys.argv[2], 'w', newline='') as out_file: 27 | 28 | reader = csv.DictReader(in_file) 29 | ordered_fieldnames = OrderedDict([('Designator',None),('Mid X',None),('Mid Y',None),('Layer',None),('Rotation',None)]) 30 | writer = csv.DictWriter(out_file, fieldnames=ordered_fieldnames) 31 | writer.writeheader() 32 | 33 | for row in reader: 34 | angle_adjustment = overrides.get(row['Ref'], 0) 35 | writer.writerow({ 36 | 'Designator': row['Ref'], 37 | 'Mid X': row['PosX'] + 'mm', 38 | 'Mid Y': row['PosY'] + 'mm', 39 | 'Layer': row['Side'].capitalize(), 40 | 'Rotation': (360 + int(float(row['Rot']) + angle_adjustment)) % 360 41 | }) 42 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Generate artifacts for all variants 2 | 3 | on: 4 | push: 5 | tags: 6 | - '*' 7 | jobs: 8 | generate-artifacts: 9 | strategy: 10 | matrix: 11 | variant: [0.1/base, 0.1/compact, 0.1/high, 0.1/low, 0.2/bling, 0.2/compact, 0.2/high, 0.2/mini] 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | with: 16 | submodules: true 17 | - name: Design rules check 18 | run: | 19 | ./automation/ninja.sh build/${{ matrix.variant }}/ferris.kicad_pcb.drc_success 20 | - name: Electrical rules check 21 | run: | 22 | ./automation/ninja.sh build/${{ matrix.variant }}/ferris.sch.erc_success 23 | - name: Generate artifacts 24 | run: | 25 | ./automation/ninja.sh ${{ matrix.variant }} 26 | - name: Generate release zip 27 | run: | 28 | zip -j \ 29 | build/${{ matrix.variant }}/release.zip \ 30 | build/${{ matrix.variant }}/front.svg \ 31 | build/${{ matrix.variant }}/back.svg \ 32 | build/${{ matrix.variant }}/bom_jlcpcb.csv \ 33 | build/${{ matrix.variant }}/cpl.csv \ 34 | build/${{ matrix.variant }}/pos.csv \ 35 | build/${{ matrix.variant }}/ibom.html \ 36 | build/${{ matrix.variant }}/gerbers.zip 37 | - name: Upload generated files to release 38 | uses: svenstaro/upload-release-action@v2 39 | with: 40 | repo_token: ${{ secrets.GITHUB_TOKEN }} 41 | file: build/${{ matrix.variant }}/release.zip 42 | asset_name: ${{ matrix.variant }}/release.zip 43 | tag: ${{ github.ref }} 44 | body: "Automatically generated files for all ferris variants" 45 | 46 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/pcbdraw/templates/simple.handlebars: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Populating manual 10 | 11 | 12 | 23 | 24 | 25 | 26 |
27 | {{#each items}} 28 |
29 | {{#if this.is_comment}} 30 |
31 | {{{this.content}}} 32 |
33 | {{/if}} 34 | {{#if this.is_step}} 35 | {{#each this.steps}} 36 |
37 |
38 | 39 |
{{{this.comment}}}
40 |
41 |
42 | {{/each}} 43 | {{/if}} 44 |
45 | {{/each}} 46 |
47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/includes_normalize.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | struct StringPiece; 19 | 20 | /// Utility functions for normalizing include paths on Windows. 21 | /// TODO: this likely duplicates functionality of CanonicalizePath; refactor. 22 | struct IncludesNormalize { 23 | /// Normalize path relative to |relative_to|. 24 | IncludesNormalize(const std::string& relative_to); 25 | 26 | // Internal utilities made available for testing, maybe useful otherwise. 27 | static std::string AbsPath(StringPiece s, std::string* err); 28 | static std::string Relativize(StringPiece path, 29 | const std::vector& start_list, 30 | std::string* err); 31 | 32 | /// Normalize by fixing slashes style, fixing redundant .. and . and makes the 33 | /// path |input| relative to |this->relative_to_| and store to |result|. 34 | bool Normalize(const std::string& input, std::string* result, 35 | std::string* err) const; 36 | 37 | private: 38 | std::string relative_to_; 39 | std::vector split_relative_to_; 40 | }; 41 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/ecad/kicad_extra/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from .xmlparser import XmlParser 4 | from .netlistparser import NetlistParser 5 | 6 | PARSERS = { 7 | '.xml': XmlParser, 8 | '.net': NetlistParser 9 | } 10 | 11 | 12 | def parse_schematic_data(file_name, normalize_case): 13 | if not os.path.isfile(file_name): 14 | return None 15 | extension = os.path.splitext(file_name)[1] 16 | if extension not in PARSERS: 17 | return None 18 | else: 19 | parser = PARSERS[extension](file_name) 20 | return parser.parse(normalize_case) 21 | 22 | 23 | def find_latest_schematic_data(base_name, directories): 24 | """ 25 | :param base_name: base name of pcb file 26 | :param directories: list of directories to search 27 | :return: last modified parsable file path or None if not found 28 | """ 29 | files = [] 30 | for d in directories: 31 | files.extend(_find_in_dir(d)) 32 | # sort by decreasing modification time 33 | files = sorted(files, reverse=True) 34 | if files: 35 | # try to find first (last modified) file that has name matching pcb file 36 | for _, f in files: 37 | if os.path.splitext(os.path.basename(f))[0] == base_name: 38 | return f 39 | # if no such file is found just return last modified 40 | return files[0][1] 41 | else: 42 | return None 43 | 44 | 45 | def _find_in_dir(dir): 46 | _, _, files = next(os.walk(dir), (None, None, [])) 47 | # filter out files that we can not parse 48 | files = [f for f in files if os.path.splitext(f)[1] in PARSERS.keys()] 49 | files = [os.path.join(dir, f) for f in files] 50 | # get their modification time and sort in descending order 51 | return [(os.path.getmtime(f), f) for f in files] 52 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/canon_perftest.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | #include "util.h" 19 | #include "metrics.h" 20 | 21 | using namespace std; 22 | 23 | const char kPath[] = 24 | "../../third_party/WebKit/Source/WebCore/" 25 | "platform/leveldb/LevelDBWriteBatch.cpp"; 26 | 27 | int main() { 28 | vector times; 29 | string err; 30 | 31 | char buf[200]; 32 | size_t len = strlen(kPath); 33 | strcpy(buf, kPath); 34 | 35 | for (int j = 0; j < 5; ++j) { 36 | const int kNumRepetitions = 2000000; 37 | int64_t start = GetTimeMillis(); 38 | uint64_t slash_bits; 39 | for (int i = 0; i < kNumRepetitions; ++i) { 40 | CanonicalizePath(buf, &len, &slash_bits, &err); 41 | } 42 | int delta = (int)(GetTimeMillis() - start); 43 | times.push_back(delta); 44 | } 45 | 46 | int min = times[0]; 47 | int max = times[0]; 48 | float total = 0; 49 | for (size_t i = 0; i < times.size(); ++i) { 50 | total += times[i]; 51 | if (times[i] < min) 52 | min = times[i]; 53 | else if (times[i] > max) 54 | max = times[i]; 55 | } 56 | 57 | printf("min %dms max %dms avg %.1fms\n", 58 | min, max, total / times.size()); 59 | } 60 | -------------------------------------------------------------------------------- /automation/tools/ninja/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to successfully make changes to Ninja 2 | 3 | We're very wary of changes that increase the complexity of Ninja (in particular, 4 | new build file syntax or command-line flags) or increase the maintenance burden 5 | of Ninja. Ninja is already successfully used by hundreds of developers for large 6 | projects and it already achieves (most of) the goals we set out for it to do. 7 | It's probably best to discuss new feature ideas on the 8 | [mailing list](https://groups.google.com/forum/#!forum/ninja-build) or in an 9 | issue before creating a PR. 10 | 11 | ## Coding guidelines 12 | 13 | Generally it's the 14 | [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) with 15 | a few additions: 16 | 17 | * Any code merged into the Ninja codebase which will be part of the main 18 | executable must compile as C++03. You may use C++11 features in a test or an 19 | unimportant tool if you guard your code with `#if __cplusplus >= 201103L`. 20 | * We have used `using namespace std;` a lot in the past. For new contributions, 21 | please try to avoid relying on it and instead whenever possible use `std::`. 22 | However, please do not change existing code simply to add `std::` unless your 23 | contribution already needs to change that line of code anyway. 24 | * All source files should have the Google Inc. license header. 25 | * Use `///` for [Doxygen](http://www.doxygen.nl/) (use `\a` to refer to 26 | arguments). 27 | * It's not necessary to document each argument, especially when they're 28 | relatively self-evident (e.g. in 29 | `CanonicalizePath(string* path, string* err)`, the arguments are hopefully 30 | obvious). 31 | 32 | If you're unsure about code formatting, please use 33 | [clang-format](https://clang.llvm.org/docs/ClangFormat.html). However, please do 34 | not format code that is not otherwise part of your contribution. 35 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/gen_doxygen_mainpage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright 2011 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -o errexit 18 | set -o nounset 19 | 20 | STATUS=0 21 | 22 | # Print each of its arguments on stderr (one per line) prefixed by the 23 | # basename of this script. 24 | stderr() 25 | { 26 | local me=$(basename "$0") 27 | local i 28 | for i 29 | do 30 | echo >&2 "$me: $i" 31 | done 32 | } 33 | 34 | # Print each of its arguments on stderr (one per line) prefixed by the 35 | # basename of this script and 'error'. 36 | error() 37 | { 38 | local i 39 | for i 40 | do 41 | stderr "error: $i" 42 | done 43 | STATUS=1 44 | } 45 | 46 | generate_header() 47 | { 48 | cat <&2 "usage: $0 inputs..." 82 | exit 1 83 | fi 84 | 85 | generate_header 86 | for i in "$@" 87 | do 88 | include_file "$i" 89 | done 90 | generate_footer 91 | 92 | exit $STATUS 93 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/core/fontparser.py: -------------------------------------------------------------------------------- 1 | from .newstroke_font import NEWSTROKE_FONT 2 | 3 | 4 | class FontParser: 5 | STROKE_FONT_SCALE = 1.0 / 21.0 6 | FONT_OFFSET = -10 7 | 8 | def __init__(self): 9 | self.parsed_font = {} 10 | 11 | def parse_font_char(self, chr): 12 | lines = [] 13 | line = [] 14 | glyph_x = 0 15 | index = ord(chr) - ord(' ') 16 | if index >= len(NEWSTROKE_FONT): 17 | index = ord('?') - ord(' ') 18 | glyph_str = NEWSTROKE_FONT[index] 19 | for i in range(0, len(glyph_str), 2): 20 | coord = glyph_str[i:i + 2] 21 | 22 | # The first two values contain the width of the char 23 | if i < 2: 24 | glyph_x = (ord(coord[0]) - ord('R')) * self.STROKE_FONT_SCALE 25 | glyph_width = (ord(coord[1]) - ord(coord[0])) * self.STROKE_FONT_SCALE 26 | elif coord[0] == ' ' and coord[1] == 'R': 27 | lines.append(line) 28 | line = [] 29 | else: 30 | line.append([ 31 | (ord(coord[0]) - ord('R')) * self.STROKE_FONT_SCALE - glyph_x, 32 | (ord(coord[1]) - ord('R') + self.FONT_OFFSET) * self.STROKE_FONT_SCALE 33 | ]) 34 | 35 | if len(line) > 0: 36 | lines.append(line) 37 | 38 | return { 39 | 'w': glyph_width, 40 | 'l': lines 41 | } 42 | 43 | def parse_font_for_string(self, s): 44 | for c in s: 45 | if c == '\t' and ' ' not in self.parsed_font: 46 | # tabs rely on space char to calculate offset 47 | self.parsed_font[' '] = self.parse_font_char(' ') 48 | if c not in self.parsed_font and ord(c) >= ord(' '): 49 | self.parsed_font[c] = self.parse_font_char(c) 50 | 51 | def get_parsed_font(self): 52 | return self.parsed_font 53 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/getopt.h: -------------------------------------------------------------------------------- 1 | #ifndef GETOPT_H 2 | #define GETOPT_H 3 | 4 | /* include files needed by this include file */ 5 | 6 | /* macros defined by this include file */ 7 | #define no_argument 0 8 | #define required_argument 1 9 | #define OPTIONAL_ARG 2 10 | 11 | /* types defined by this include file */ 12 | 13 | /* GETOPT_LONG_OPTION_T: The type of long option */ 14 | typedef struct GETOPT_LONG_OPTION_T 15 | { 16 | const char *name; /* the name of the long option */ 17 | int has_arg; /* one of the above macros */ 18 | int *flag; /* determines if getopt_long() returns a 19 | * value for a long option; if it is 20 | * non-NULL, 0 is returned as a function 21 | * value and the value of val is stored in 22 | * the area pointed to by flag. Otherwise, 23 | * val is returned. */ 24 | int val; /* determines the value to return if flag is 25 | * NULL. */ 26 | } GETOPT_LONG_OPTION_T; 27 | 28 | typedef GETOPT_LONG_OPTION_T option; 29 | 30 | #ifdef __cplusplus 31 | extern "C" 32 | { 33 | #endif 34 | 35 | /* externally-defined variables */ 36 | extern char *optarg; 37 | extern int optind; 38 | extern int opterr; 39 | extern int optopt; 40 | 41 | /* function prototypes */ 42 | #ifndef _AIX 43 | int getopt (int argc, char **argv, char *optstring); 44 | #endif 45 | int getopt_long (int argc, char **argv, const char *shortopts, 46 | const GETOPT_LONG_OPTION_T * longopts, int *longind); 47 | int getopt_long_only (int argc, char **argv, const char *shortopts, 48 | const GETOPT_LONG_OPTION_T * longopts, int *longind); 49 | 50 | #ifdef __cplusplus 51 | }; 52 | 53 | #endif 54 | 55 | #endif /* GETOPT_H */ 56 | 57 | /* END OF FILE getopt.h */ 58 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/edit_distance_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "edit_distance.h" 16 | 17 | #include "test.h" 18 | 19 | TEST(EditDistanceTest, TestEmpty) { 20 | EXPECT_EQ(5, EditDistance("", "ninja")); 21 | EXPECT_EQ(5, EditDistance("ninja", "")); 22 | EXPECT_EQ(0, EditDistance("", "")); 23 | } 24 | 25 | TEST(EditDistanceTest, TestMaxDistance) { 26 | const bool allow_replacements = true; 27 | for (int max_distance = 1; max_distance < 7; ++max_distance) { 28 | EXPECT_EQ(max_distance + 1, 29 | EditDistance("abcdefghijklmnop", "ponmlkjihgfedcba", 30 | allow_replacements, max_distance)); 31 | } 32 | } 33 | 34 | TEST(EditDistanceTest, TestAllowReplacements) { 35 | bool allow_replacements = true; 36 | EXPECT_EQ(1, EditDistance("ninja", "njnja", allow_replacements)); 37 | EXPECT_EQ(1, EditDistance("njnja", "ninja", allow_replacements)); 38 | 39 | allow_replacements = false; 40 | EXPECT_EQ(2, EditDistance("ninja", "njnja", allow_replacements)); 41 | EXPECT_EQ(2, EditDistance("njnja", "ninja", allow_replacements)); 42 | } 43 | 44 | TEST(EditDistanceTest, TestBasics) { 45 | EXPECT_EQ(0, EditDistance("browser_tests", "browser_tests")); 46 | EXPECT_EQ(1, EditDistance("browser_test", "browser_tests")); 47 | EXPECT_EQ(1, EditDistance("browser_tests", "browser_test")); 48 | } 49 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/version.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "version.h" 16 | 17 | #include 18 | 19 | #include "util.h" 20 | 21 | using namespace std; 22 | 23 | const char* kNinjaVersion = "1.10.1.git"; 24 | 25 | void ParseVersion(const string& version, int* major, int* minor) { 26 | size_t end = version.find('.'); 27 | *major = atoi(version.substr(0, end).c_str()); 28 | *minor = 0; 29 | if (end != string::npos) { 30 | size_t start = end + 1; 31 | end = version.find('.', start); 32 | *minor = atoi(version.substr(start, end).c_str()); 33 | } 34 | } 35 | 36 | void CheckNinjaVersion(const string& version) { 37 | int bin_major, bin_minor; 38 | ParseVersion(kNinjaVersion, &bin_major, &bin_minor); 39 | int file_major, file_minor; 40 | ParseVersion(version, &file_major, &file_minor); 41 | 42 | if (bin_major > file_major) { 43 | Warning("ninja executable version (%s) greater than build file " 44 | "ninja_required_version (%s); versions may be incompatible.", 45 | kNinjaVersion, version.c_str()); 46 | return; 47 | } 48 | 49 | if ((bin_major == file_major && bin_minor < file_minor) || 50 | bin_major < file_major) { 51 | Fatal("ninja version (%s) incompatible with build file " 52 | "ninja_required_version version (%s).", 53 | kNinjaVersion, version.c_str()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import threading 4 | import time 5 | 6 | import wx 7 | import wx.aui 8 | 9 | 10 | def check_for_bom_button(): 11 | # From Miles McCoo's blog 12 | # https://kicad.mmccoo.com/2017/03/05/adding-your-own-command-buttons-to-the-pcbnew-gui/ 13 | def find_pcbnew_window(): 14 | windows = wx.GetTopLevelWindows() 15 | pcbneww = [w for w in windows if "pcbnew" in w.GetTitle().lower()] 16 | if len(pcbneww) != 1: 17 | return None 18 | return pcbneww[0] 19 | 20 | def callback(_): 21 | plugin.Run() 22 | 23 | path = os.path.dirname(__file__) 24 | while not wx.GetApp(): 25 | time.sleep(1) 26 | bm = wx.Bitmap(path + '/icon.png', wx.BITMAP_TYPE_PNG) 27 | button_wx_item_id = 0 28 | 29 | from pcbnew import ID_H_TOOLBAR 30 | while True: 31 | time.sleep(1) 32 | pcbnew_window = find_pcbnew_window() 33 | if not pcbnew_window: 34 | continue 35 | 36 | top_tb = pcbnew_window.FindWindowById(ID_H_TOOLBAR) 37 | if button_wx_item_id == 0 or not top_tb.FindTool(button_wx_item_id): 38 | top_tb.AddSeparator() 39 | button_wx_item_id = wx.NewId() 40 | top_tb.AddTool(button_wx_item_id, "iBOM", bm, 41 | "Generate interactive BOM", wx.ITEM_NORMAL) 42 | top_tb.Bind(wx.EVT_TOOL, callback, id=button_wx_item_id) 43 | top_tb.Realize() 44 | 45 | 46 | if not os.environ.get('INTERACTIVE_HTML_BOM_CLI_MODE', False): 47 | from .ecad.kicad import InteractiveHtmlBomPlugin 48 | 49 | plugin = InteractiveHtmlBomPlugin() 50 | plugin.register() 51 | 52 | # Add a button the hacky way if plugin button is not supported 53 | # in pcbnew, unless this is linux. 54 | if not plugin.pcbnew_icon_support and not sys.platform.startswith('linux'): 55 | t = threading.Thread(target=check_for_bom_button) 56 | t.daemon = True 57 | t.start() 58 | -------------------------------------------------------------------------------- /.kiplot.yml: -------------------------------------------------------------------------------- 1 | # Adapted from example KiPlot config file 2 | # at `tools/kiplot/docs/samples/generic_plot.kiplot.yaml` 3 | 4 | kiplot: 5 | version: 1 6 | 7 | preflight: 8 | 9 | # one day.... 10 | check_zone_fills: false 11 | run_drc: false 12 | 13 | outputs: 14 | 15 | - name: 'gerbers' 16 | comment: "Gerbers for the board house" 17 | type: gerber 18 | dir: . 19 | options: 20 | # generic layer options 21 | exclude_edge_layer: true 22 | exclude_pads_from_silkscreen: true 23 | use_aux_axis_as_origin: false 24 | plot_sheet_reference: false 25 | plot_footprint_refs: true 26 | plot_footprint_values: false 27 | force_plot_invisible_refs_vals: false 28 | tent_vias: true 29 | check_zone_fills: true 30 | 31 | # gerber options 32 | line_width: 0.1 33 | subtract_mask_from_silk: false 34 | use_protel_extensions: false 35 | gerber_precision: 4.6 36 | create_gerber_job_file: true 37 | use_gerber_x2_attributes: false 38 | use_gerber_net_attributes: false 39 | 40 | layers: 41 | - layer: F.Cu 42 | suffix: F_Cu 43 | - layer: B.Cu 44 | suffix: B_Cu 45 | - layer: F.SilkS 46 | suffix: F_SilkS 47 | - layer: B.SilkS 48 | suffix: B_SilkS 49 | - layer: F.Mask 50 | suffix: F_Mask 51 | - layer: B.Mask 52 | suffix: B_Mask 53 | - layer: F.Paste 54 | suffix: F_Paste 55 | - layer: B.Paste 56 | suffix: B_Paste 57 | - layer: Edge.Cuts 58 | suffix: Edge_Cuts 59 | - layer: F.Fab 60 | suffix: F_Fab 61 | - layer: B.Fab 62 | suffix: B_Fab 63 | 64 | - name: excellon_drill 65 | comment: "Excellon drill files" 66 | type: excellon 67 | dir: . 68 | options: 69 | metric_units: true 70 | pth_and_npth_single_file: false 71 | use_aux_axis_as_origin: false 72 | minimal_header: false 73 | mirror_y_axis: false 74 | map: 75 | type: 'gerber' 76 | 77 | 78 | -------------------------------------------------------------------------------- /automation/tools/PcbDraw/examples/readme.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | To use any of the examples, simply run `./init.sh` in the examples directory. 4 | The script will download a simple demo board by RoboticsBrno. 5 | 6 | 7 | # Example usages of PcbDraw 8 | 9 | All the examples assumes the current directory is the root of the repository. 10 | 11 | To render the board invoke: 12 | 13 | ``` 14 | pcbdraw examples/ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb front.svg 15 | ``` 16 | 17 | To render board, but e.g. change colors of LEDs: 18 | 19 | ``` 20 | pcbdraw --remap examples/pcbdraw/remap.json examples/ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb front.svg 21 | ``` 22 | 23 | To render the back side: 24 | 25 | ``` 26 | pcbdraw -b examples/ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb back.svg 27 | ``` 28 | 29 | To use different style: 30 | 31 | ``` 32 | pcbdraw --style oshpark-purple examples/ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb front.svg 33 | ``` 34 | 35 | To render only the board without components: 36 | 37 | ``` 38 | pcbdraw --filter "" examples/ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb front.svg 39 | ``` 40 | 41 | To render board with only `L_R1` and `L_Y1`: 42 | 43 | ``` 44 | pcbdraw --filter L_R1,L_Y1 examples/ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb front.svg 45 | ``` 46 | 47 | To render board and highlight `L_R1` and `L_Y1`: 48 | 49 | ``` 50 | pcbdraw --highlight L_R1,L_Y1 examples/ArduinoLearningKitStarter/ArduinoLearningKitStarter.kicad_pcb front.svg 51 | ``` 52 | 53 | 54 | ## Populate 55 | 56 | There are two example for the populate - HTML one and a Mardown one. They are 57 | the same and are located in files `source_md.md` and `source_html.md`. To see 58 | the result, run 59 | 60 | ``` 61 | populate examples/populate/source_md.md markdown_demo 62 | ``` 63 | or 64 | ``` 65 | populate examples/populate/source_html.md html_demo 66 | ``` 67 | 68 | You can find results 69 | in the directories `markdown_demo` and `html_demo` respectively. 70 | 71 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/measure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2011 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """measure the runtime of a command by repeatedly running it. 18 | """ 19 | 20 | from __future__ import print_function 21 | 22 | import time 23 | import subprocess 24 | import sys 25 | 26 | devnull = open('/dev/null', 'w') 27 | 28 | def run(cmd, repeat=10): 29 | print('sampling:', end=' ') 30 | sys.stdout.flush() 31 | 32 | samples = [] 33 | for _ in range(repeat): 34 | start = time.time() 35 | subprocess.call(cmd, stdout=devnull, stderr=devnull) 36 | end = time.time() 37 | dt = (end - start) * 1000 38 | print('%dms' % int(dt), end=' ') 39 | sys.stdout.flush() 40 | samples.append(dt) 41 | print() 42 | 43 | # We're interested in the 'pure' runtime of the code, which is 44 | # conceptually the smallest time we'd see if we ran it enough times 45 | # such that it got the perfect time slices / disk cache hits. 46 | best = min(samples) 47 | # Also print how varied the outputs were in an attempt to make it 48 | # more obvious if something has gone terribly wrong. 49 | err = sum(s - best for s in samples) / float(len(samples)) 50 | print('estimate: %dms (mean err %.1fms)' % (best, err)) 51 | 52 | if __name__ == '__main__': 53 | if len(sys.argv) < 2: 54 | print('usage: measure.py command args...') 55 | sys.exit(1) 56 | run(cmd=sys.argv[1:]) 57 | -------------------------------------------------------------------------------- /automation/tools/kiplot/src/kiplot/__main__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import argparse 4 | import logging 5 | import os 6 | import sys 7 | 8 | from . import kiplot 9 | from . import config_reader 10 | 11 | 12 | def main(): 13 | 14 | EXIT_BAD_ARGS = 1 15 | EXIT_BAD_CONFIG = 2 16 | 17 | parser = argparse.ArgumentParser( 18 | description='Command-line Plotting for KiCad') 19 | parser.add_argument('-v', '--verbose', action='store_true', 20 | help='show debugging information') 21 | parser.add_argument('-b', '--board-file', required=True, 22 | help='The PCB .kicad-pcb board file') 23 | parser.add_argument('-c', '--plot-config', required=True, 24 | help='The plotting config file to use') 25 | parser.add_argument('-d', '--out-dir', default='.', 26 | help='The output directory (cwd if not given)') 27 | 28 | args = parser.parse_args() 29 | 30 | log_level = logging.DEBUG if args.verbose else logging.INFO 31 | logging.basicConfig(level=log_level) 32 | 33 | if not os.path.isfile(args.board_file): 34 | logging.error("Board file not found: {}".format(args.board_file)) 35 | 36 | if not os.path.isfile(args.plot_config): 37 | logging.error("Plot config file not found: {}" 38 | .format(args.plot_config)) 39 | sys.exit(EXIT_BAD_ARGS) 40 | 41 | cr = config_reader.CfgYamlReader() 42 | 43 | with open(args.plot_config) as cf_file: 44 | cfg = cr.read(cf_file) 45 | 46 | # relative to CWD (absolute path overrides) 47 | outdir = os.path.join(os.getcwd(), args.out_dir) 48 | cfg.outdir = outdir 49 | 50 | # Finally, once all value are in, check they make sense 51 | errs = cfg.validate() 52 | 53 | if errs: 54 | logging.error('Invalid config:\n\n' + "\n".join(errs)) 55 | sys.exit(EXIT_BAD_CONFIG) 56 | 57 | # Set up the plotter and do it 58 | plotter = kiplot.Plotter(cfg) 59 | plotter.plot(args.board_file) 60 | 61 | 62 | if __name__ == "__main__": 63 | main() 64 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/parser.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "parser.h" 16 | 17 | #include "disk_interface.h" 18 | #include "metrics.h" 19 | 20 | using namespace std; 21 | 22 | bool Parser::Load(const string& filename, string* err, Lexer* parent) { 23 | METRIC_RECORD(".ninja parse"); 24 | string contents; 25 | string read_err; 26 | if (file_reader_->ReadFile(filename, &contents, &read_err) != 27 | FileReader::Okay) { 28 | *err = "loading '" + filename + "': " + read_err; 29 | if (parent) 30 | parent->Error(string(*err), err); 31 | return false; 32 | } 33 | 34 | // The lexer needs a nul byte at the end of its input, to know when it's done. 35 | // It takes a StringPiece, and StringPiece's string constructor uses 36 | // string::data(). data()'s return value isn't guaranteed to be 37 | // null-terminated (although in practice - libc++, libstdc++, msvc's stl -- 38 | // it is, and C++11 demands that too), so add an explicit nul byte. 39 | contents.resize(contents.size() + 1); 40 | 41 | return Parse(filename, contents, err); 42 | } 43 | 44 | bool Parser::ExpectToken(Lexer::Token expected, string* err) { 45 | Lexer::Token token = lexer_.ReadToken(); 46 | if (token != expected) { 47 | string message = string("expected ") + Lexer::TokenName(expected); 48 | message += string(", got ") + Lexer::TokenName(token); 49 | message += Lexer::TokenErrorHint(expected); 50 | return lexer_.Error(message, err); 51 | } 52 | return true; 53 | } 54 | -------------------------------------------------------------------------------- /automation/tools/kicad-jlcpcb-bom-plugin/README.md: -------------------------------------------------------------------------------- 1 | # KiCad JLCPCB BOM Plugin 2 | 3 | Export a JLCPCB Compatible BOM directly from your KiCad schematic! 4 | 5 | ## Installation 6 | 7 | This script requires **Python 3**. If you need a Python 2 version, please get 8 | [kicad-jlcpcb-bom-plugin version 1.0.0](https://github.com/wokwi/kicad-jlcpcb-bom-plugin/releases/tag/1.0.0) instead. 9 | 10 | The script has been tested with KiCad 5.1.4. 11 | 12 | 1. Copy `bom_csv_jlcpcb.py` to your KiCad installation folder under the `bin/scripting/plugins` directory 13 | 2. In Eschema (the Schematics editor) go to "Tools" -> "Generate Bill of Materials", press the "+" button 14 | at the bottom of the screen, and choose the plugin file you have just copied. When asked for a nickname, 15 | go with the default, "bom_csv_jlcpcb". 16 | 17 | ## Usage 18 | 19 | Instructions for exporting JLCPCB BOM from KiCad's Eschema: 20 | 21 | 1. Go to "Tools" -> "Generate Bill of Materials" 22 | 2. Choose "bom_csv_jlcpcb" from the "BOM plugins" list on the left 23 | 3. Make sure the command line ends with "%O.csv" (otherwise, change "%O" into "%O.csv") 24 | 4. Click on "Generate". The BOM file should be created inside your project's directory, as a CSV file. 25 | 26 | ## Custom Fields 27 | 28 | You can customize the script's output by adding the following fields to your components: 29 | 30 | 1. "LCSC Part" - Add this field to include an LCSC Part number in the generated BOM. e.g.: C2286 for a red LED. 31 | 2. "JLCPCB BOM" - Set this field to 0 (or "False") to omit the component from the generated BOM. 32 | 33 | ## Generating a JLCPCB CPL File 34 | 35 | You can use the `kicad_pos_to_cpl.py` script to convert a KiCad Footprint Position (.pos) file into a CPL file 36 | compatible with JLCPCB SMT Assembly service. The `.pos` file can be generated from Pcbnew, by going into 37 | "File" -> "Fabrication Outputs" -> "Footprint Position (.pos) File..." and choosing the following options: 38 | 39 | * Format: CSV 40 | * Units: Millimeters 41 | * Files: Separate files for front and back 42 | 43 | Also, make sure to uncheck "Include footprints with SMD pads even if not marked Surface Mount". 44 | 45 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/hash_collision_bench.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "build_log.h" 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | using namespace std; 23 | 24 | int random(int low, int high) { 25 | return int(low + (rand() / double(RAND_MAX)) * (high - low) + 0.5); 26 | } 27 | 28 | void RandomCommand(char** s) { 29 | int len = random(5, 100); 30 | *s = new char[len]; 31 | for (int i = 0; i < len; ++i) 32 | (*s)[i] = (char)random(32, 127); 33 | } 34 | 35 | int main() { 36 | const int N = 20 * 1000 * 1000; 37 | 38 | // Leak these, else 10% of the runtime is spent destroying strings. 39 | char** commands = new char*[N]; 40 | pair* hashes = new pair[N]; 41 | 42 | srand((int)time(NULL)); 43 | 44 | for (int i = 0; i < N; ++i) { 45 | RandomCommand(&commands[i]); 46 | hashes[i] = make_pair(BuildLog::LogEntry::HashCommand(commands[i]), i); 47 | } 48 | 49 | sort(hashes, hashes + N); 50 | 51 | int collision_count = 0; 52 | for (int i = 1; i < N; ++i) { 53 | if (hashes[i - 1].first == hashes[i].first) { 54 | if (strcmp(commands[hashes[i - 1].second], 55 | commands[hashes[i].second]) != 0) { 56 | printf("collision!\n string 1: '%s'\n string 2: '%s'\n", 57 | commands[hashes[i - 1].second], 58 | commands[hashes[i].second]); 59 | collision_count++; 60 | } 61 | } 62 | } 63 | printf("\n\n%d collisions after %d runs\n", collision_count, N); 64 | } 65 | -------------------------------------------------------------------------------- /automation/tools/ninja/misc/bash-completion: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Add the following to your .bashrc to tab-complete ninja targets 16 | # . path/to/ninja/misc/bash-completion 17 | 18 | _ninja_target() { 19 | local cur prev targets dir line targets_command OPTIND 20 | 21 | # When available, use bash_completion to: 22 | # 1) Complete words when the cursor is in the middle of the word 23 | # 2) Complete paths with files or directories, as appropriate 24 | if _get_comp_words_by_ref cur prev &>/dev/null ; then 25 | case $prev in 26 | -f) 27 | _filedir 28 | return 0 29 | ;; 30 | -C) 31 | _filedir -d 32 | return 0 33 | ;; 34 | esac 35 | else 36 | cur="${COMP_WORDS[COMP_CWORD]}" 37 | fi 38 | 39 | if [[ "$cur" == "--"* ]]; then 40 | # there is currently only one argument that takes -- 41 | COMPREPLY=($(compgen -P '--' -W 'version' -- "${cur:2}")) 42 | else 43 | dir="." 44 | line=$(echo ${COMP_LINE} | cut -d" " -f 2-) 45 | # filter out all non relevant arguments but keep C for dirs 46 | while getopts :C:f:j:l:k:nvd:t: opt $line; do 47 | case $opt in 48 | # eval for tilde expansion 49 | C) eval dir="$OPTARG" ;; 50 | esac 51 | done; 52 | targets_command="eval ninja -C \"${dir}\" -t targets all 2>/dev/null | cut -d: -f1" 53 | COMPREPLY=($(compgen -W '`${targets_command}`' -- "$cur")) 54 | fi 55 | return 56 | } 57 | complete -F _ninja_target ninja 58 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/README.md: -------------------------------------------------------------------------------- 1 | # Interactive HTML BOM plugin for KiCad 2 | ![icon](https://i.imgur.com/js4kDOn.png) 3 | 4 | This plugin generates convenient BOM listing with ability to visually correlate 5 | and easily search for components and their placements on the pcb. 6 | 7 | This is really useful when hand soldering your prototype and you have to find 50 8 | places where 0.1uF cap should be or which of the SOP8 footprints are for the same 9 | micro. Dynamically highlighting all components in the same group on the rendering 10 | of the pcb makes manually populating the board much easier. 11 | 12 | This plugin utilizes Pcbnew python bindings to read pcb data and render 13 | silkscreen, fab layer, footprint pads, text and drawings. Additionally it can 14 | pull data from schematic if you export it through netlist or xml file that 15 | Eeschema can generate from it's internal bom tool. That extra data can be added 16 | as additional columns in the BOM table (for example manufacturer id) or it can be 17 | used to indicate which components should be omitted altogether (dnp field). For 18 | full description of functionality see [wiki](https://github.com/openscopeproject/InteractiveHtmlBom/wiki). 19 | 20 | Generated html page is fully self contained, doesn't need internet connection to work 21 | and can be packaged with documentation of your project or hosted anywhere on the web. 22 | 23 | [Demo is worth a thousand words.](https://openscopeproject.org/InteractiveHtmlBomDemo/) 24 | 25 | ## Installation and Usage 26 | 27 | See [project wiki](https://github.com/openscopeproject/InteractiveHtmlBom/wiki) for instructions. 28 | 29 | ## License and credits 30 | 31 | Plugin code is licensed under MIT license, see `LICENSE` for more info. 32 | 33 | Html page uses [Split.js](https://github.com/nathancahill/Split.js), 34 | [PEP.js](https://github.com/jquery/PEP) and (stripped down) 35 | [lz-string.js](https://github.com/pieroxy/lz-string) libraries that get embedded into 36 | generated bom page. 37 | 38 | `units.py` is borrowed from [KiBom](https://github.com/SchrodingersGat/KiBoM) 39 | plugin (MIT license). 40 | 41 | `svgpath.py` is heavily based on 42 | [svgpathtools](https://github.com/mathandy/svgpathtools) module (MIT license). 43 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/string_piece_util.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "string_piece_util.h" 16 | 17 | #include 18 | #include 19 | #include 20 | using namespace std; 21 | 22 | vector SplitStringPiece(StringPiece input, char sep) { 23 | vector elems; 24 | elems.reserve(count(input.begin(), input.end(), sep) + 1); 25 | 26 | StringPiece::const_iterator pos = input.begin(); 27 | 28 | for (;;) { 29 | const char* next_pos = find(pos, input.end(), sep); 30 | if (next_pos == input.end()) { 31 | elems.push_back(StringPiece(pos, input.end() - pos)); 32 | break; 33 | } 34 | elems.push_back(StringPiece(pos, next_pos - pos)); 35 | pos = next_pos + 1; 36 | } 37 | 38 | return elems; 39 | } 40 | 41 | string JoinStringPiece(const vector& list, char sep) { 42 | if (list.empty()) { 43 | return ""; 44 | } 45 | 46 | string ret; 47 | 48 | { 49 | size_t cap = list.size() - 1; 50 | for (size_t i = 0; i < list.size(); ++i) { 51 | cap += list[i].len_; 52 | } 53 | ret.reserve(cap); 54 | } 55 | 56 | for (size_t i = 0; i < list.size(); ++i) { 57 | if (i != 0) { 58 | ret += sep; 59 | } 60 | ret.append(list[i].str_, list[i].len_); 61 | } 62 | 63 | return ret; 64 | } 65 | 66 | bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) { 67 | if (a.len_ != b.len_) { 68 | return false; 69 | } 70 | 71 | for (size_t i = 0; i < a.len_; ++i) { 72 | if (ToLowerASCII(a.str_[i]) != ToLowerASCII(b.str_[i])) { 73 | return false; 74 | } 75 | } 76 | 77 | return true; 78 | } 79 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/string_piece.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_STRINGPIECE_H_ 16 | #define NINJA_STRINGPIECE_H_ 17 | 18 | #include 19 | 20 | #include 21 | 22 | /// StringPiece represents a slice of a string whose memory is managed 23 | /// externally. It is useful for reducing the number of std::strings 24 | /// we need to allocate. 25 | struct StringPiece { 26 | typedef const char* const_iterator; 27 | 28 | StringPiece() : str_(NULL), len_(0) {} 29 | 30 | /// The constructors intentionally allow for implicit conversions. 31 | StringPiece(const std::string& str) : str_(str.data()), len_(str.size()) {} 32 | StringPiece(const char* str) : str_(str), len_(strlen(str)) {} 33 | 34 | StringPiece(const char* str, size_t len) : str_(str), len_(len) {} 35 | 36 | bool operator==(const StringPiece& other) const { 37 | return len_ == other.len_ && memcmp(str_, other.str_, len_) == 0; 38 | } 39 | 40 | bool operator!=(const StringPiece& other) const { 41 | return !(*this == other); 42 | } 43 | 44 | /// Convert the slice into a full-fledged std::string, copying the 45 | /// data into a new string. 46 | std::string AsString() const { 47 | return len_ ? std::string(str_, len_) : std::string(); 48 | } 49 | 50 | const_iterator begin() const { 51 | return str_; 52 | } 53 | 54 | const_iterator end() const { 55 | return str_ + len_; 56 | } 57 | 58 | char operator[](size_t pos) const { 59 | return str_[pos]; 60 | } 61 | 62 | size_t size() const { 63 | return len_; 64 | } 65 | 66 | const char* str_; 67 | size_t len_; 68 | }; 69 | 70 | #endif // NINJA_STRINGPIECE_H_ 71 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/clparser.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_CLPARSER_H_ 16 | #define NINJA_CLPARSER_H_ 17 | 18 | #include 19 | #include 20 | 21 | /// Visual Studio's cl.exe requires some massaging to work with Ninja; 22 | /// for example, it emits include information on stderr in a funny 23 | /// format when building with /showIncludes. This class parses this 24 | /// output. 25 | struct CLParser { 26 | /// Parse a line of cl.exe output and extract /showIncludes info. 27 | /// If a dependency is extracted, returns a nonempty string. 28 | /// Exposed for testing. 29 | static std::string FilterShowIncludes(const std::string& line, 30 | const std::string& deps_prefix); 31 | 32 | /// Return true if a mentioned include file is a system path. 33 | /// Filtering these out reduces dependency information considerably. 34 | static bool IsSystemInclude(std::string path); 35 | 36 | /// Parse a line of cl.exe output and return true if it looks like 37 | /// it's printing an input filename. This is a heuristic but it appears 38 | /// to be the best we can do. 39 | /// Exposed for testing. 40 | static bool FilterInputFilename(std::string line); 41 | 42 | /// Parse the full output of cl, filling filtered_output with the text that 43 | /// should be printed (if any). Returns true on success, or false with err 44 | /// filled. output must not be the same object as filtered_object. 45 | bool Parse(const std::string& output, const std::string& deps_prefix, 46 | std::string* filtered_output, std::string* err); 47 | 48 | std::set includes_; 49 | }; 50 | 51 | #endif // NINJA_CLPARSER_H_ 52 | -------------------------------------------------------------------------------- /automation/tools/InteractiveHtmlBom/InteractiveHtmlBom/web/lz-string.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Pieroxy 2 | // This work is free. You can redistribute it and/or modify it 3 | // under the terms of the WTFPL, Version 2 4 | // For more information see LICENSE.txt or http://www.wtfpl.net/ 5 | // 6 | // For more information, the home page: 7 | // http://pieroxy.net/blog/pages/lz-string/testing.html 8 | // 9 | // LZ-based compression algorithm, version 1.4.4 10 | var LZString=function(){var o=String.fromCharCode,i={};var n={decompressFromBase64:function(o){return null==o?"":""==o?null:n._decompress(o.length,32,function(n){return function(o,n){if(!i[o]){i[o]={};for(var t=0;t>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 2:return""}for(f[3]=l,e=l,g.push(l);;){if(m.index>i)return"";for(a=0,p=Math.pow(2,h),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(l=a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 2:return g.join("")}if(0==c&&(c=Math.pow(2,h),h++),f[l])v=f[l];else{if(l!==d)return null;v=e+e.charAt(0)}g.push(v),f[d++]=e+v.charAt(0),e=v,0==--c&&(c=Math.pow(2,h),h++)}}};return n}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString}); -------------------------------------------------------------------------------- /automation/tools/kiplot/setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import io 4 | import os 5 | 6 | from setuptools import setup, find_packages 7 | 8 | # Package meta-data. 9 | NAME = 'kiplot' 10 | DESCRIPTION = 'Plotting driver for KiCad' 11 | URL = 'https://github.com/johnbeard/kiplot' 12 | EMAIL = 'john.j.beard@gmail.com' 13 | AUTHOR = 'John Beard' 14 | REQUIRES_PYTHON = '>=2.7.0' 15 | 16 | 17 | # What packages are required for this module to be executed? 18 | REQUIRED = [ 19 | 'pyyaml', 20 | # 'pcbnew' 21 | ] 22 | 23 | here = os.path.abspath(os.path.dirname(__file__)) 24 | 25 | # Import the README and use it as the long-description. 26 | # Note: this will only work if 'README.md' is present in your MANIFEST.in file! 27 | with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f: 28 | long_description = '\n' + f.read() 29 | 30 | 31 | about = {} 32 | with open(os.path.join(here, 'src', NAME, '__version__.py')) as f: 33 | exec(f.read(), about) 34 | 35 | 36 | # Where the magic happens: 37 | setup( 38 | name=NAME, 39 | version=about['__version__'], 40 | description=DESCRIPTION, 41 | long_description=long_description, 42 | long_description_content_type='text/markdown', 43 | author=AUTHOR, 44 | author_email=EMAIL, 45 | python_requires=REQUIRES_PYTHON, 46 | url=URL, 47 | packages=find_packages('src'), 48 | package_dir={'': 'src'}, 49 | # If your package is a single module, use this instead of 'packages': 50 | # py_modules=['mypackage'], 51 | 52 | entry_points={ 53 | 'console_scripts': ['kiplot=kiplot.__main__:main'], 54 | }, 55 | install_requires=REQUIRED, 56 | include_package_data=True, 57 | license='MIT', 58 | classifiers=[ 59 | # Trove classifiers 60 | # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers 61 | 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', 62 | 'Programming Language :: Python', 63 | 'Programming Language :: Python :: 2', 64 | 'Programming Language :: Python :: 2.7', 65 | 'Programming Language :: Python :: Implementation :: CPython', 66 | 'Programming Language :: Python :: Implementation :: PyPy', 67 | 'Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)', 68 | ], 69 | setup_requires=['pytest-runner'], 70 | tests_require=['pytest'], 71 | ) 72 | -------------------------------------------------------------------------------- /automation/tools/ninja/src/manifest_parser.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef NINJA_MANIFEST_PARSER_H_ 16 | #define NINJA_MANIFEST_PARSER_H_ 17 | 18 | #include "parser.h" 19 | 20 | struct BindingEnv; 21 | struct EvalString; 22 | 23 | enum DupeEdgeAction { 24 | kDupeEdgeActionWarn, 25 | kDupeEdgeActionError, 26 | }; 27 | 28 | enum PhonyCycleAction { 29 | kPhonyCycleActionWarn, 30 | kPhonyCycleActionError, 31 | }; 32 | 33 | struct ManifestParserOptions { 34 | ManifestParserOptions() 35 | : dupe_edge_action_(kDupeEdgeActionWarn), 36 | phony_cycle_action_(kPhonyCycleActionWarn) {} 37 | DupeEdgeAction dupe_edge_action_; 38 | PhonyCycleAction phony_cycle_action_; 39 | }; 40 | 41 | /// Parses .ninja files. 42 | struct ManifestParser : public Parser { 43 | ManifestParser(State* state, FileReader* file_reader, 44 | ManifestParserOptions options = ManifestParserOptions()); 45 | 46 | /// Parse a text string of input. Used by tests. 47 | bool ParseTest(const std::string& input, std::string* err) { 48 | quiet_ = true; 49 | return Parse("input", input, err); 50 | } 51 | 52 | private: 53 | /// Parse a file, given its contents as a string. 54 | bool Parse(const std::string& filename, const std::string& input, 55 | std::string* err); 56 | 57 | /// Parse various statement types. 58 | bool ParsePool(std::string* err); 59 | bool ParseRule(std::string* err); 60 | bool ParseLet(std::string* key, EvalString* val, std::string* err); 61 | bool ParseEdge(std::string* err); 62 | bool ParseDefault(std::string* err); 63 | 64 | /// Parse either a 'subninja' or 'include' line. 65 | bool ParseFileInclude(bool new_scope, std::string* err); 66 | 67 | BindingEnv* env_; 68 | ManifestParserOptions options_; 69 | bool quiet_; 70 | }; 71 | 72 | #endif // NINJA_MANIFEST_PARSER_H_ 73 | --------------------------------------------------------------------------------