├── FAK-Firmware ├── .envrc ├── .gitignore ├── ncl │ ├── examples │ │ ├── zilpzalp │ │ │ ├── config.ncl │ │ │ ├── keyboard.ncl │ │ │ ├── README.md │ │ │ ├── keymap.ncl │ │ │ └── layouts.ncl │ │ ├── cheapis │ │ │ ├── cheapis_fak.jpg │ │ │ ├── README.md │ │ │ ├── keyboard.ncl │ │ │ └── keymap.ncl │ │ └── 3x3_macropad │ │ │ ├── README.md │ │ │ ├── keyboard.ncl │ │ │ └── keymap.ncl │ ├── fak │ │ ├── constants.ncl │ │ ├── gen_meson_options.ncl │ │ ├── mcus.ncl │ │ ├── util_types.ncl │ │ ├── main.ncl │ │ ├── keyboard.ncl │ │ ├── util_functions.ncl │ │ ├── hid_codes.ncl │ │ ├── keycode.ncl │ │ ├── gen_code.ncl │ │ └── keymap.ncl │ ├── keyboard.ncl │ └── keymap.ncl ├── meson.options ├── src │ ├── bootloader.h │ ├── mouse.h │ ├── time.h │ ├── split_peripheral.h │ ├── bootloader.c │ ├── tap_dance.h │ ├── keyboard.h │ ├── combo.h │ ├── macro.h │ ├── caps_word.h │ ├── usb.h │ ├── key_event_queue.h │ ├── main.c │ ├── split_peripheral.c │ ├── macro.c │ ├── time.c │ ├── caps_word.c │ ├── tap_dance.c │ ├── split_central.h │ ├── mouse.c │ ├── hold_tap.h │ ├── keymap.h │ ├── key_event_queue.c │ ├── keymap.c │ └── combo.c ├── flake.nix ├── meson.build └── fak.py ├── PIP ├── ch55p34-bottom-pos.csv └── ch55p34-top-pos.csv ├── .gitattributes ├── ch55p34.jpg ├── gerber ├── gerber.zip ├── ch55p34-Edge_Cuts.gbr ├── ch55p34-job.gbrjob ├── ch55p34-PTH.drl ├── ch55p34-B_Paste.gbr ├── ch55p34-NPTH.drl └── ch55p34-F_Paste.gbr ├── Case Files ├── Case.stl ├── plate.stl └── midplate.stl ├── ch55p34 ├── ch55p34-backups │ └── ch55p34-2024-01-05_175440.zip ├── fp-lib-table ├── sym-lib-table ├── ch55p34.kicad_prl └── fp-info-cache ├── components-and-pretty ├── ProjectLocal.dcm ├── ProjectLocal.pretty │ ├── Bumpon_3M_F0502.kicad_mod │ ├── H_M2_Spacer_Hole.kicad_mod │ ├── Mini_DC_Motor.kicad_mod │ ├── H_M2_GH60_MountingHole.kicad_mod │ ├── Graphic_Mask_HalfHole.kicad_mod │ ├── SW_Push_SPST_3x6mm.kicad_mod │ ├── SK6812-MINI-E_Reversible.kicad_mod │ ├── SW_Push_SPST_3x6mm_Reversible.kicad_mod │ ├── Resistor-Hybrid.kicad_mod │ ├── SK6812-MINI-E.kicad_mod │ ├── SOT-23_Handsoldering_Reversible.kicad_mod │ ├── SOT-23-6_Handsoldering_Reversible.kicad_mod │ ├── SW_MX_PG1350_NoLed.kicad_mod │ ├── LED_SK6812_PLCC4_5.0x5.0mm_P3.2mm_Reversible.kicad_mod │ ├── C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual_Reversible.kicad_mod │ ├── C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual.kicad_mod │ ├── LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm.kicad_mod │ ├── RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm_Reversible.kicad_mod │ ├── Diode-dual.kicad_mod │ ├── Resistor-Hybrid_Reversible.kicad_mod │ ├── SW_Cherry_MX_PCB_1.00u_BSilkRef.kicad_mod │ ├── SW_Hotswap_Kailh.kicad_mod │ └── DIP-20_W15.24mm.kicad_mod ├── sym-lib-table ├── shell.nix ├── ProjectLocal.lib └── MCU_RaspberryPi_RP2040.lib ├── BOM └── BOMJLC.csv └── README.md /FAK-Firmware/.envrc: -------------------------------------------------------------------------------- 1 | use flake . 2 | -------------------------------------------------------------------------------- /FAK-Firmware/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | .direnv/ 3 | .main.ncl.json 4 | -------------------------------------------------------------------------------- /PIP/ch55p34-bottom-pos.csv: -------------------------------------------------------------------------------- 1 | Ref,Val,Package,PosX,PosY,Rot,Side 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /ch55p34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doesntfazer/Ch55p34-keyboard/HEAD/ch55p34.jpg -------------------------------------------------------------------------------- /gerber/gerber.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doesntfazer/Ch55p34-keyboard/HEAD/gerber/gerber.zip -------------------------------------------------------------------------------- /Case Files/Case.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doesntfazer/Ch55p34-keyboard/HEAD/Case Files/Case.stl -------------------------------------------------------------------------------- /Case Files/plate.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doesntfazer/Ch55p34-keyboard/HEAD/Case Files/plate.stl -------------------------------------------------------------------------------- /Case Files/midplate.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doesntfazer/Ch55p34-keyboard/HEAD/Case Files/midplate.stl -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/zilpzalp/config.ncl: -------------------------------------------------------------------------------- 1 | { 2 | layout = "aptmak", 3 | combo_timeout_ms = 50, 4 | } 5 | -------------------------------------------------------------------------------- /FAK-Firmware/meson.options: -------------------------------------------------------------------------------- 1 | option('split', type : 'boolean', value : true) 2 | option('extra_sources', type : 'string', value : '') 3 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/constants.ncl: -------------------------------------------------------------------------------- 1 | { 2 | MAX_LAYER_COUNT = 32, 3 | MAX_USB_STRING_LENGTH = 126, 4 | DEFAULT_DEBOUNCE_MS = 5, 5 | } 6 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/cheapis/cheapis_fak.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doesntfazer/Ch55p34-keyboard/HEAD/FAK-Firmware/ncl/examples/cheapis/cheapis_fak.jpg -------------------------------------------------------------------------------- /ch55p34/ch55p34-backups/ch55p34-2024-01-05_175440.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/doesntfazer/Ch55p34-keyboard/HEAD/ch55p34/ch55p34-backups/ch55p34-2024-01-05_175440.zip -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/3x3_macropad/README.md: -------------------------------------------------------------------------------- 1 | **Level: Beginner 😁** 2 | 3 | - The basics! 4 | - Demonstrates direct pin keys, tap dance, combos, basic hold-tap, and basic keycodes. 5 | -------------------------------------------------------------------------------- /ch55p34/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (version 7) 3 | (lib (name "ProjectLocal")(type "KiCad")(uri "D:/KiCad Projects/Ch55p34/components-and-pretty/ProjectLocal.pretty")(options "")(descr "")) 4 | ) 5 | -------------------------------------------------------------------------------- /FAK-Firmware/src/bootloader.h: -------------------------------------------------------------------------------- 1 | #ifndef __BOOTLOADER_H__ 2 | #define __BOOTLOADER_H__ 3 | 4 | #define BOOT_ADDR 0x3800 5 | 6 | inline void bootloader(); 7 | inline void sw_reset(); 8 | 9 | #endif // __BOOTLOADER_H__ 10 | -------------------------------------------------------------------------------- /FAK-Firmware/src/mouse.h: -------------------------------------------------------------------------------- 1 | #ifndef __MOUSE_H__ 2 | #define __MOUSE_H__ 3 | 4 | #include 5 | 6 | void mouse_handle_key(uint16_t custom_code, uint8_t down); 7 | void mouse_process(); 8 | 9 | #endif // __MOUSE_H__ 10 | -------------------------------------------------------------------------------- /FAK-Firmware/src/time.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIME_H__ 2 | #define __TIME_H__ 3 | 4 | void delay(uint16_t ms); 5 | uint16_t get_timer(); 6 | 7 | void CLK_init(); 8 | 9 | void TMR0_interrupt(); 10 | void TMR0_init(); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP BluePill_or_MiniF4_DIP40 4 | D Symbol for DIP40, with labels for Bluepill/MiniF4. 5 | K module black pill STM32 dip40 bluepill blackpill 6 | $ENDCMP 7 | # 8 | #End Doc Library 9 | -------------------------------------------------------------------------------- /FAK-Firmware/src/split_peripheral.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPLIT_PERIPHERAL_H__ 2 | #define __SPLIT_PERIPHERAL_H__ 3 | 4 | #include 5 | 6 | void key_state_inform(uint8_t key_idx, uint8_t down); 7 | 8 | void keyboard_init(); 9 | void keyboard_scan(); 10 | 11 | #endif // __SPLIT_PERIPHERAL_H__ 12 | -------------------------------------------------------------------------------- /ch55p34/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (version 7) 3 | (lib (name "MCU_RaspberryPi_RP2040")(type "KiCad")(uri "D:/KiCad Projects/Ch55p34/components-and-pretty/MCU_RaspberryPi_RP2040.kicad_sym")(options "")(descr "")) 4 | (lib (name "ProjectLocal")(type "KiCad")(uri "D:/KiCad Projects/Ch55p34/components-and-pretty/ProjectLocal.kicad_sym")(options "")(descr "")) 5 | ) 6 | -------------------------------------------------------------------------------- /FAK-Firmware/src/bootloader.c: -------------------------------------------------------------------------------- 1 | #include "bootloader.h" 2 | #include "ch552.h" 3 | #include "time.h" 4 | 5 | inline void bootloader() { 6 | USB_CTRL = 0; 7 | EA = 0; 8 | delay(1); 9 | ((void (*__data)(void)) BOOT_ADDR)(); 10 | } 11 | 12 | inline void sw_reset() { 13 | SAFE_MOD = 0x55; 14 | SAFE_MOD = 0xAA; 15 | GLOBAL_CFG |= bSW_RESET; 16 | } 17 | -------------------------------------------------------------------------------- /FAK-Firmware/src/tap_dance.h: -------------------------------------------------------------------------------- 1 | #ifndef __TAP_DANCE_H__ 2 | #define __TAP_DANCE_H__ 3 | 4 | #include "keyboard.h" 5 | 6 | #include 7 | 8 | uint8_t is_future_type_tap_dance(uint32_t key_code); 9 | 10 | uint8_t tap_dance_handle_event(fak_key_state_t *ks, uint8_t handle_ev, int16_t delta); 11 | 12 | extern __code uint32_t tap_dance_bindings[]; 13 | 14 | #endif // __TAP_DANCE_H__ 15 | -------------------------------------------------------------------------------- /FAK-Firmware/src/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYBOARD_H__ 2 | #define __KEYBOARD_H__ 3 | 4 | #ifdef SPLIT_ENABLE 5 | #define SPLIT_MSG_REQUEST_KEYS 69 6 | #define SPLIT_KEY_COUNT_BYTES (((SPLIT_PERIPH_KEY_COUNT - 1) / 8) + 1) 7 | #endif 8 | 9 | #ifdef SPLIT_SIDE_CENTRAL 10 | #include "split_central.h" 11 | #endif 12 | 13 | #ifdef SPLIT_SIDE_PERIPHERAL 14 | #include "split_peripheral.h" 15 | #endif 16 | 17 | #endif // __KEYBOARD_H__ 18 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/Bumpon_3M_F0502.kicad_mod: -------------------------------------------------------------------------------- 1 | (module Bumpon_3M_F0502 (layer F.Cu) (tedit 60C0EBD2) 2 | (fp_text reference REF** (at 0 0) (layer F.SilkS) hide 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value Bumpon_3M_F0502 (at -0.127 -3.429) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_circle (center 0 0) (end 2.5 0) (layer Dwgs.User) (width 0.12)) 9 | ) 10 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/H_M2_Spacer_Hole.kicad_mod: -------------------------------------------------------------------------------- 1 | (module H_M2_Spacer_Hole (layer F.Cu) (tedit 602F83BF) 2 | (fp_text reference REF** (at 0 0) (layer F.SilkS) hide 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value H_M2_Spacer_Hole (at 0 -0.5) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (pad "" np_thru_hole circle (at 0 0) (size 4.3 4.3) (drill 4.3) (layers *.Cu *.Mask)) 9 | ) 10 | -------------------------------------------------------------------------------- /BOM/BOMJLC.csv: -------------------------------------------------------------------------------- 1 | Comment,Designator,Footprint,LCSC Part # 2 | 1N4148W,"D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31, D32, D33, D34",D_SOD-123, C25133 3 | 5.1k,"R1, R2",R_0805_2012Metric,C27834 4 | 330R,R3,R_0805_2012Metric,C17630 5 | 10K,R4,R_0805_2012Metric,C17414 6 | 100n,"C1, C2, C3",C_0805_2012Metric,C49678 7 | CH552T,U1,TSSOP-20_4.4x6.5mm_P0.65mm,C111367 8 | Type-C,J1,USB_C_Receptacle_HRO_TYPE-C-31-M-12,C165948 9 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/3x3_macropad/keyboard.ncl: -------------------------------------------------------------------------------- 1 | let { DirectPinKey, .. } = import "../../fak/keyboard.ncl" in 2 | let { CH552T, .. } = import "../../fak/mcus.ncl" in 3 | 4 | { 5 | mcu = CH552T, 6 | usb_dev = { 7 | vendor_id = 51966, # 0xCAFE 8 | product_id = 47806, # 0xBABE 9 | product_ver = 256, # 0x0100 10 | }, 11 | keys = 12 | let D = DirectPinKey in 13 | [ 14 | D 10, D 11, D 12, 15 | D 14, D 15, D 16, 16 | D 32, D 34, D 30, 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /components-and-pretty/sym-lib-table: -------------------------------------------------------------------------------- 1 | (sym_lib_table 2 | (version 7) 3 | (lib (name "keebio")(type "KiCad")(uri "${KIPRJMOD}/keebio-components/keebio.kicad_sym")(options "")(descr "")) 4 | (lib (name "MCU_RaspberryPi_RP2040")(type "KiCad")(uri "${KIPRJMOD}/MCU_RaspberryPi_RP2040.kicad_sym")(options "")(descr "")) 5 | (lib (name "ProjectLocal")(type "KiCad")(uri "${KIPRJMOD}/ProjectLocal.kicad_sym")(options "")(descr "")) 6 | (lib (name "MCU_RaspberryPi_and_Boards")(type "KiCad")(uri "${KIPRJMOD}/KiCad-RP-Pico/RP-Pico Libraries/MCU_RaspberryPi_and_Boards.kicad_sym")(options "")(descr "")) 7 | ) 8 | -------------------------------------------------------------------------------- /FAK-Firmware/src/combo.h: -------------------------------------------------------------------------------- 1 | #ifndef __COMBO_H__ 2 | #define __COMBO_H__ 3 | 4 | #include 5 | 6 | #define COMBO_FLAGS_KEY_COUNT_MASK 0x07 7 | #define COMBO_FLAGS_SLOW_RELEASE_MASK 0x08 8 | 9 | typedef struct { 10 | uint8_t flags; 11 | uint8_t timeout_ms; 12 | #ifdef COMBO_REQUIRE_PRIOR_IDLE_MS_ENABLE 13 | uint16_t require_prior_idle_ms; 14 | #endif 15 | uint8_t key_indices[COMBO_MAX_KEY_COUNT]; 16 | } fak_combo_def_t; 17 | 18 | void combo_push_key_event(uint8_t key_idx, uint8_t pressed); 19 | void combo_handle(); 20 | void combo_init(); 21 | 22 | #endif // __COMBO_H__ 23 | -------------------------------------------------------------------------------- /FAK-Firmware/src/macro.h: -------------------------------------------------------------------------------- 1 | #ifndef __MACRO_H__ 2 | #define __MACRO_H__ 3 | 4 | #include 5 | 6 | #define MACRO_INST_HALT 0 7 | #define MACRO_INST_PRESS 1 8 | #define MACRO_INST_RELEASE 2 9 | #define MACRO_INST_TAP 3 10 | #define MACRO_INST_WAIT 4 11 | 12 | typedef struct { 13 | uint8_t inst; 14 | #if MACRO_STEP_ARG_COUNT > 256 15 | uint16_t arg_idx; 16 | #else 17 | uint8_t arg_idx; 18 | #endif 19 | } fak_macro_step_t; 20 | 21 | void macro_handle_key(uint16_t custom_code, uint8_t down); 22 | 23 | extern __code fak_macro_step_t macro_steps[]; 24 | extern __code uint32_t macro_step_args[]; 25 | 26 | #endif // __MACRO_H__ 27 | -------------------------------------------------------------------------------- /FAK-Firmware/src/caps_word.h: -------------------------------------------------------------------------------- 1 | #ifndef CAPS_WORD_H_ 2 | #define CAPS_WORD_H_ 3 | 4 | #include 5 | 6 | #include "ch552.h" 7 | 8 | void caps_word_on(); 9 | void caps_word_off(); 10 | void caps_word_toggle(); 11 | 12 | __bit caps_word_active(); 13 | 14 | // Process the logic for caps word for the given key. 15 | // 16 | // If keys other than A-Z, 0-9, -, _, backspace, delete are pressed, 17 | // exit caps word mode. 18 | // 19 | // Does nothing if caps word word is not active. 20 | // 21 | // Returns 1 if the needs to press shift key for the key, 0 otherwise. 22 | __bit caps_word_handle_key(uint8_t code, uint8_t shift_pressed); 23 | 24 | #endif // CAPS_WORD_H_ 25 | -------------------------------------------------------------------------------- /FAK-Firmware/src/usb.h: -------------------------------------------------------------------------------- 1 | #ifndef __USB_H__ 2 | #define __USB_H__ 3 | 4 | #include 5 | 6 | uint8_t USB_EP1I_read(uint8_t idx); 7 | void USB_EP1I_write(uint8_t idx, uint8_t value); 8 | inline void USB_EP1I_ready_send(); 9 | inline void USB_EP1I_send_now(); 10 | 11 | #ifdef CONSUMER_KEYS_ENABLE 12 | void USB_EP2I_write_now(uint8_t idx, uint16_t value); 13 | #endif 14 | 15 | #ifdef MOUSE_KEYS_ENABLE 16 | uint8_t USB_EP3I_read(uint8_t idx); 17 | void USB_EP3I_write(uint8_t idx, uint8_t value); 18 | inline void USB_EP3I_ready_send(); 19 | inline void USB_EP3I_send_now(); 20 | #endif 21 | 22 | void USB_interrupt(); 23 | void USB_init(); 24 | 25 | #endif // __USB_H__ 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ch55p34 2 | ![Ch55p34](ch55p34.jpg) 3 | keyboard based on the ch552t Chip. 4 | 5 | Runs on [FAK firmware](https://github.com/semickolon/fak). I named it the Ch55p34 because it's "Ch55p." It is hot-swappable. 6 | 7 | I forgot to add mounting holes, and because of this, I had to find a way to mount the plate to the case. 8 | 9 | You can use it without a case, or you can use the 3d printable case and plate that I designed. 10 | 11 | Four m2x10mm screws hold the plate in place. from the side. 12 | 13 | An unintended side effect is that it is about 7mm thinner than any other keyboard I've made with a case. 14 | 15 | I may do this for the rest of my keyboards! 16 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/gen_meson_options.ncl: -------------------------------------------------------------------------------- 1 | let util = import "util_functions.ncl" in 2 | 3 | fun ir => 4 | 5 | { 6 | split = ir.defines.SPLIT_ENABLE, 7 | extra_sources = 8 | { 9 | "src/hold_tap.c" = ir.defines.HOLD_TAP_ENABLE, 10 | "src/tap_dance.c" = ir.defines.TAP_DANCE_ENABLE, 11 | "src/combo.c" = ir.defines.COMBO_COUNT > 0, 12 | "src/mouse.c" = ir.defines.MOUSE_KEYS_ENABLE, 13 | "src/macro.c" = ir.defines.MACRO_KEYS_ENABLE, 14 | "src/caps_word.c" = ir.defines.CAPS_WORD_ENABLE, 15 | } 16 | |> std.record.filter (fun _k pred => pred) 17 | |> std.record.to_array 18 | |> std.array.map (fun e => e.field) 19 | |> util.array.join ",", 20 | } 21 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/zilpzalp/keyboard.ncl: -------------------------------------------------------------------------------- 1 | let { MatrixKey, .. } = import "../../fak/keyboard.ncl" in 2 | let { CH552T, .. } = import "../../fak/mcus.ncl" in 3 | 4 | { 5 | mcu = CH552T, 6 | matrix = { 7 | cols = [30, 31, 32, 33], 8 | rows = [10, 11, 12, 13, 14, 15, 16] 9 | }, 10 | usb_dev = { 11 | vendor_id = 43962, # 0xABBA 12 | product_id = 1, 13 | product_ver = 256, # 0x0100 14 | }, 15 | keys = 16 | let M = MatrixKey in 17 | [ 18 | M 0 0, M 1 0, M 2 0, M 3 0, M 3 6, M 2 6, M 1 6, M 0 6, 19 | M 0 2, M 0 1, M 1 1, M 2 1, M 3 1, M 3 5, M 2 5, M 1 5, M 0 5, M 0 4, 20 | M 1 2, M 2 2, M 3 2, M 3 4, M 2 4, M 1 4, 21 | M 1 3, M 3 3, M 2 3, M 0 3, 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/keyboard.ncl: -------------------------------------------------------------------------------- 1 | let { MatrixKey, .. } = import "../ncl/fak/keyboard.ncl" in 2 | let { CH552T, .. } = import "../ncl/fak/mcus.ncl" in 3 | 4 | { 5 | mcu = CH552T, 6 | matrix = { 7 | cols = [31, 11, 10, 13, 17, 30, 33, 34, 35, 12], 8 | rows = [32, 14, 15, 16] 9 | }, 10 | usb_dev = { 11 | vendor_id = 43962, # 0xABBA 12 | product_id = 1, 13 | product_ver = 256, # 0x0100 14 | }, 15 | keys = 16 | let M = MatrixKey in 17 | [ 18 | M 0 0, M 1 0, M 2 0, M 3 0, M 4 0, M 5 0, M 6 0, M 7 0, M 8 0, M 9 0, 19 | M 0 1, M 1 1, M 2 1, M 3 1, M 4 1, M 5 1, M 6 1, M 7 1, M 8 1, M 9 1, 20 | M 0 2, M 1 2, M 2 2, M 3 2, M 4 2, M 5 2, M 6 2, M 7 2, M 8 2, M 9 2, 21 | M 3 3, M 4 3, M 5 3, M 6 3, 22 | ] 23 | } -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/Mini_DC_Motor.kicad_mod: -------------------------------------------------------------------------------- 1 | (module Mini_DC_Motor (layer F.Cu) (tedit 60B8D20D) 2 | (fp_text reference REF** (at 0 -5.9 180) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value Mini_DC_Motor (at 0.762 -15.486) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_circle (center 0 0) (end 5 0) (layer B.SilkS) (width 0.12)) 9 | (fp_circle (center 0 0) (end 5 0) (layer F.SilkS) (width 0.12)) 10 | (fp_text user %R (at 0 -5.9) (layer B.SilkS) 11 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 12 | ) 13 | (pad 1 thru_hole rect (at -9 -2) (size 2 2) (drill 1) (layers *.Cu *.Mask)) 14 | (pad 2 thru_hole rect (at -9 2) (size 2 2) (drill 1) (layers *.Cu *.Mask)) 15 | ) 16 | -------------------------------------------------------------------------------- /FAK-Firmware/src/key_event_queue.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEY_EVENT_QUEUE_H__ 2 | #define __KEY_EVENT_QUEUE_H__ 3 | 4 | #include 5 | 6 | typedef struct { 7 | uint8_t pressed; 8 | uint8_t mapped; // TODO: Wasteful. Merge with pressed as bit flags 9 | uint8_t key_idx; 10 | uint16_t timestamp; 11 | } fak_key_event_t; 12 | 13 | inline uint8_t key_event_queue_get_size(); 14 | inline uint8_t key_event_queue_get_bsize(); 15 | inline uint8_t* key_event_queue_state(); 16 | inline fak_key_event_t* key_event_queue_front(); 17 | inline fak_key_event_t* key_event_queue_bfront(); 18 | 19 | void key_event_queue_push(); 20 | void key_event_queue_pop(); 21 | void key_event_queue_bpush(fak_key_event_t *ev); 22 | void key_event_queue_bpop(); 23 | void key_event_queue_breset(); 24 | 25 | void key_event_queue_init(); 26 | 27 | #endif // __KEY_EVENT_QUEUE_H__ 28 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/mcus.ncl: -------------------------------------------------------------------------------- 1 | { 2 | CH552T = { 3 | gpios = [ 4 | 10, 11, 12, 13, 14, 15, 16, 17, 5 | 30, 31, 32, 33, 34, 35, 6 | ], 7 | features = { 8 | uart_30_31 = { 9 | type = 'uart, 10 | keys = ["uart0", "uart00"], 11 | pins = [30, 31], 12 | }, 13 | uart_12_13 = { 14 | type = 'uart, 15 | keys = ["uart0", "uart01"], 16 | pins = [12, 13], 17 | }, 18 | }, 19 | }, 20 | 21 | CH552G = { 22 | gpios = [ 23 | 11, 14, 15, 16, 17, 24 | 30, 31, 32, 33, 34, 25 | ], 26 | features = { 27 | uart_30_31 = { 28 | type = 'uart, 29 | keys = ["uart0", "uart00"], 30 | pins = [30, 31], 31 | }, 32 | }, 33 | }, 34 | 35 | CH552E = { 36 | gpios = [ 37 | 14, 15, 16, 17, 38 | ], 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/H_M2_GH60_MountingHole.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "H_M2_GH60_MountingHole" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 62DCD941) 4 | (property "Description" "GH-60 Case Mounting Hole") 5 | (property "Sheetfile" "keyboard-x2-lumberjack-arm-fancy.kicad_sch") 6 | (property "Sheetname" "") 7 | (attr through_hole) 8 | (fp_text reference "H5" (at 0 0) (layer "F.SilkS") 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | (tstamp 0ab0ef08-facb-4705-8b82-cfaf7e133261) 11 | ) 12 | (fp_text value "~" (at 0 -0.5) (layer "F.Fab") 13 | (effects (font (size 1 1) (thickness 0.15))) 14 | (tstamp 99eee47b-e281-45a6-a52c-e4d3ca1ed974) 15 | ) 16 | (pad "" np_thru_hole circle (at 0 0) (size 5 5) (drill oval 4.2 2.2) (layers F&B.Cu *.Mask) (tstamp 7fa03dc1-7e80-4f9b-a3f2-286a7532fc9d)) 17 | ) 18 | -------------------------------------------------------------------------------- /FAK-Firmware/src/main.c: -------------------------------------------------------------------------------- 1 | #include "ch552.h" 2 | #include "keyboard.h" 3 | #include "time.h" 4 | 5 | #ifdef SPLIT_SIDE_CENTRAL 6 | #include "usb.h" 7 | 8 | void USB_interrupt(); 9 | void USB_ISR() __interrupt(INT_NO_USB) { 10 | USB_interrupt(); 11 | } 12 | #endif 13 | 14 | void TMR0_interrupt(); 15 | void TMR0_ISR() __interrupt(INT_NO_TMR0) { 16 | TMR0_interrupt(); 17 | } 18 | 19 | #if defined(SPLIT_ENABLE) && defined(SPLIT_SIDE_PERIPHERAL) 20 | void UART_interrupt(); 21 | void UART_ISR() __interrupt(INT_NO_UART0) { 22 | UART_interrupt(); 23 | } 24 | #endif 25 | 26 | void main() { 27 | CLK_init(); 28 | #ifdef SPLIT_SIDE_CENTRAL 29 | TMR0_init(); 30 | USB_init(); 31 | #endif 32 | keyboard_init(); 33 | 34 | #ifdef UART0_ALT 35 | PIN_FUNC |= bUART0_PIN_X; 36 | #endif 37 | #ifdef UART1_ALT 38 | PIN_FUNC |= bUART1_PIN_X; 39 | #endif 40 | 41 | EA = 1; 42 | 43 | while (1) { 44 | keyboard_scan(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /FAK-Firmware/src/split_peripheral.c: -------------------------------------------------------------------------------- 1 | #include "split_peripheral.h" 2 | #include "ch552.h" 3 | #include "time.h" 4 | 5 | uint8_t key_bits[SPLIT_KEY_COUNT_BYTES]; 6 | 7 | void key_state_inform(uint8_t key_idx, uint8_t down) { 8 | uint8_t shift = key_idx % 8; 9 | ES = 0; 10 | key_bits[key_idx / 8] = (key_bits[key_idx / 8] & ~(1 << shift)) | (down << shift); 11 | ES = 1; 12 | } 13 | 14 | void keyboard_init() { 15 | for (uint8_t i = SPLIT_KEY_COUNT_BYTES; i;) { 16 | key_bits[--i] = 0; 17 | } 18 | 19 | SM0 = 1; 20 | SM1 = 0; 21 | SM2 = 0; 22 | REN = 1; 23 | ES = 1; 24 | 25 | keyboard_init_user(); 26 | } 27 | 28 | void keyboard_scan() { 29 | keyboard_scan_user(); 30 | } 31 | 32 | void UART_interrupt() { 33 | if (!RI) return; 34 | RI = 0; 35 | REN = 0; 36 | TB8 = 0; 37 | 38 | for (uint8_t i = 0; i < SPLIT_KEY_COUNT_BYTES; i++) { 39 | SBUF = key_bits[i]; 40 | while (!TI); 41 | TI = 0; 42 | } 43 | 44 | REN = 1; 45 | } 46 | -------------------------------------------------------------------------------- /FAK-Firmware/src/macro.c: -------------------------------------------------------------------------------- 1 | #include "macro.h" 2 | #include "keyboard.h" 3 | #include "time.h" 4 | #include "usb.h" 5 | 6 | // TODO: Macro processing should be non-blocking 7 | 8 | void macro_handle_key(uint16_t step_idx, uint8_t down) { 9 | if (!down) return; 10 | 11 | fak_macro_step_t step; 12 | uint32_t arg; 13 | 14 | while (1) { 15 | step = macro_steps[step_idx++]; 16 | if (step.inst == MACRO_INST_HALT) return; 17 | 18 | arg = macro_step_args[step.arg_idx]; 19 | 20 | switch (step.inst) { 21 | case MACRO_INST_PRESS: 22 | handle_non_future(arg, 1); 23 | USB_EP1I_send_now(); 24 | break; 25 | case MACRO_INST_RELEASE: 26 | handle_non_future(arg, 0); 27 | USB_EP1I_send_now(); 28 | break; 29 | case MACRO_INST_TAP: 30 | tap_non_future(arg); 31 | break; 32 | case MACRO_INST_WAIT: 33 | delay(arg); 34 | break; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/util_types.ncl: -------------------------------------------------------------------------------- 1 | let { array, .. } = import "util_functions.ncl" in 2 | 3 | { 4 | Uint = (fun bits => 5 | std.contract.from_predicate (fun value => 6 | std.is_number value 7 | && std.number.is_integer value 8 | && value >= 0 9 | && value < (std.number.pow 2 bits)) 10 | ), 11 | Uint8 = Uint 8, 12 | Uint16 = Uint 16, 13 | Uint32 = Uint 32, 14 | 15 | BoundedInt = (fun lower_inclusive upper_exclusive => 16 | std.contract.from_predicate (fun n => 17 | std.is_number n 18 | && std.number.is_integer n 19 | && n >= lower_inclusive 20 | && n < upper_exclusive) 21 | ), 22 | 23 | Set = fun t => 24 | let UniqueItems = std.contract.from_predicate (fun arr => 25 | std.is_array arr 26 | && (array.unique arr) == arr 27 | ) in 28 | std.contract.Sequence [ Array t, UniqueItems ], 29 | 30 | ElementOf = fun list => std.contract.from_predicate 31 | (match { 32 | '"Array" => fun e => std.array.elem e list, 33 | 'Record => fun e => std.array.elem e (std.record.values list), 34 | } (std.typeof list)), 35 | } 36 | -------------------------------------------------------------------------------- /FAK-Firmware/src/time.c: -------------------------------------------------------------------------------- 1 | #include "ch552.h" 2 | #include "time.h" 3 | 4 | __idata volatile uint16_t timer_1ms; 5 | 6 | void delay(uint16_t ms) { 7 | while (ms) { 8 | while ((TKEY_CTRL & bTKC_IF) == 0); 9 | while (TKEY_CTRL & bTKC_IF); 10 | ms--; 11 | } 12 | } 13 | 14 | uint16_t get_timer() { 15 | uint16_t ret; 16 | ET0 = 0; 17 | ret = timer_1ms; 18 | ET0 = 1; 19 | return ret; 20 | } 21 | 22 | static inline void enter_safe_mode() { 23 | SAFE_MOD = 0x55; 24 | SAFE_MOD = 0xAA; 25 | } 26 | 27 | static inline void exit_safe_mode() { 28 | SAFE_MOD = 0x00; 29 | } 30 | 31 | void CLK_init() { 32 | // Internal clock @ 24MHz 33 | enter_safe_mode(); 34 | CLOCK_CFG = (CLOCK_CFG & ~MASK_SYS_CK_SEL) | 0b110; 35 | exit_safe_mode(); 36 | } 37 | 38 | #pragma save 39 | #pragma nooverlay 40 | void TMR0_interrupt() { 41 | TL0 = 0x30; 42 | TH0 = 0xF8; // 65536 - 2000 = 63536 43 | timer_1ms++; 44 | } 45 | #pragma restore 46 | 47 | void TMR0_init() { 48 | TL0 = 0x30; 49 | TH0 = 0xF8; // 65536 - 2000 = 63536 50 | TMOD = bT0_M0; 51 | 52 | timer_1ms = 0; 53 | 54 | ET0 = 1; 55 | TR0 = 1; 56 | } 57 | -------------------------------------------------------------------------------- /FAK-Firmware/src/caps_word.c: -------------------------------------------------------------------------------- 1 | #include "caps_word.h" 2 | 3 | #include "ch552.h" 4 | 5 | #include "time.h" 6 | #include "split_central.h" 7 | 8 | __bit caps_word_state = 0; 9 | 10 | void caps_word_on() { 11 | caps_word_state = 1; 12 | } 13 | 14 | void caps_word_off() { 15 | caps_word_state = 0; 16 | } 17 | 18 | void caps_word_toggle() { 19 | caps_word_state = !caps_word_state; 20 | } 21 | 22 | __bit caps_word_active() { 23 | return caps_word_state; 24 | } 25 | 26 | __bit caps_word_handle_key(uint8_t code, uint8_t shift_pressed) { 27 | if (caps_word_state == 0) { 28 | return 0; 29 | } 30 | 31 | // check hasn't timed out 32 | if ((get_timer() - get_last_tap_timestamp()) > 5000) { 33 | caps_word_state = 0; 34 | return 0; 35 | } 36 | 37 | // this assumes US layout on the host OS. 38 | if ((code >= 0x04) && code < (0x04 + 26)) { 39 | // A..Z 40 | return 1; 41 | } else if (!shift_pressed && (code >= 0x04 + 26) && code < (0x04 + 26 + 10)) { // 1..0 42 | } else if (code == 0x2A) { // backspace 43 | } else if (code == 0x2D) { // minus 44 | return 1; 45 | } else if (code == 0x4C) { // delete 46 | } else { 47 | // otherwise: not an accepted key; disable caps word 48 | caps_word_state = 0; 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /FAK-Firmware/src/tap_dance.c: -------------------------------------------------------------------------------- 1 | #include "tap_dance.h" 2 | #include "keymap.h" 3 | 4 | __xdata __at(XADDR_TAP_COUNT) uint8_t tap_count = 1; 5 | 6 | uint8_t is_future_type_tap_dance(uint32_t key_code) { 7 | return (key_code >> 24) == 0xE0; 8 | } 9 | 10 | uint8_t tap_dance_handle_event(fak_key_state_t *ks, uint8_t handle_ev, int16_t delta) { 11 | fak_key_event_t *ev_front = key_event_queue_front(); 12 | 13 | if (handle_ev == HANDLE_EVENT_QUEUED && !ev_front->pressed) { 14 | return HANDLE_RESULT_COMPLETED; 15 | } 16 | 17 | uint8_t max_taps = (ks->key_code >> 20) & 0xF; 18 | uint16_t tapping_term_ms = (ks->key_code >> 8) & 0xFFF; 19 | 20 | if (tap_count < max_taps && delta < tapping_term_ms) { 21 | if (handle_ev != HANDLE_EVENT_INCOMING_EVENT) { 22 | return 0; 23 | } 24 | 25 | fak_key_event_t *ev_in = key_event_queue_bfront(); 26 | 27 | if (ev_front->key_idx == ev_in->key_idx) { 28 | if (!ev_in->pressed) return 0; 29 | tap_count++; 30 | return HANDLE_RESULT_COMPLETED; 31 | } 32 | } 33 | 34 | uint8_t binding_start = ks->key_code & 0xFF; 35 | ks->key_code = tap_dance_bindings[binding_start + tap_count - 1]; 36 | tap_count = 1; 37 | 38 | return HANDLE_RESULT_MAPPED; 39 | } 40 | -------------------------------------------------------------------------------- /FAK-Firmware/flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "fak"; 3 | 4 | inputs = { 5 | nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11"; 6 | nickel.url = "github:tweag/nickel/1.3.0"; 7 | naersk.url = "github:nix-community/naersk"; 8 | }; 9 | 10 | outputs = { self, nixpkgs, ... }@inputs: 11 | let 12 | system = "x86_64-linux"; 13 | pkgs = import nixpkgs { inherit system; }; 14 | nickel = inputs.nickel.packages.${system}.default; 15 | naersk = pkgs.callPackage inputs.naersk {}; 16 | in 17 | { 18 | devShells.${system}.default = pkgs.mkShell { 19 | packages = 20 | let 21 | wchisp = naersk.buildPackage rec { 22 | pname = "wchisp"; 23 | version = "0.3-git"; 24 | src = pkgs.fetchFromGitHub { 25 | owner = "ch32-rs"; 26 | repo = pname; 27 | rev = "4b4787243ef9bc87cbbb0d95c7482b4f7c9838f1"; 28 | hash = "sha256-Ju2DBv3R4O48o8Fk/AFXOBIsvGMK9hJ8Ogxk47f7gcU="; 29 | }; 30 | }; 31 | in 32 | with pkgs; [ 33 | sdcc 34 | nickel 35 | nls 36 | meson 37 | python311 38 | ninja 39 | wchisp 40 | ]; 41 | }; 42 | }; 43 | } 44 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/Graphic_Mask_HalfHole.kicad_mod: -------------------------------------------------------------------------------- 1 | (module Graphic_Mask_HalfHole (layer F.Cu) (tedit 61C826D5) 2 | (fp_text reference REF** (at 4.318 -2.54) (layer F.SilkS) hide 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value Graphic_Mask_HalfHole (at 0 3.429) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_arc (start 0 0) (end 0 1.875) (angle -180) (layer F.Mask) (width 1.25)) 9 | (fp_arc (start 0 0) (end 0 1.875) (angle -180) (layer F.Cu) (width 1.25)) 10 | (fp_arc (start 0 0) (end 0 1.875) (angle -180) (layer B.Cu) (width 1.25)) 11 | (fp_arc (start 0 0) (end 0 1.875) (angle -180) (layer B.Mask) (width 1.25)) 12 | (fp_line (start 0 -1.875) (end -3.7089 -1.875) (layer F.Mask) (width 1.25)) 13 | (fp_line (start -3.7089 1.875) (end 0 1.875) (layer F.Mask) (width 1.25)) 14 | (fp_line (start 0 -1.875) (end -3.7089 -1.875) (layer F.Cu) (width 1.25)) 15 | (fp_line (start 0 -1.875) (end -3.7089 -1.875) (layer B.Cu) (width 1.25)) 16 | (fp_line (start 0 -1.875) (end -3.7089 -1.875) (layer B.Mask) (width 1.25)) 17 | (fp_line (start -3.7089 1.875) (end 0 1.875) (layer F.Cu) (width 1.25)) 18 | (fp_line (start -3.7089 1.875) (end 0 1.875) (layer B.Cu) (width 1.25)) 19 | (fp_line (start -3.7089 1.875) (end 0 1.875) (layer B.Mask) (width 1.25)) 20 | ) 21 | -------------------------------------------------------------------------------- /FAK-Firmware/src/split_central.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPLIT_CENTRAL_H__ 2 | #define __SPLIT_CENTRAL_H__ 3 | 4 | #include "key_event_queue.h" 5 | #include "ch552.h" 6 | 7 | #include 8 | 9 | #define KEY_STATUS_DOWN 0x01 10 | #define KEY_STATUS_DEBOUNCE 0x02 11 | #define KEY_STATUS_RESOLVED 0x04 12 | 13 | #define HANDLE_RESULT_MAPPED 0x01 14 | #define HANDLE_RESULT_COMPLETED 0x02 15 | #define HANDLE_RESULT_CONSUMED_EVENT 0x04 16 | 17 | #define HANDLE_EVENT_QUEUED 0 18 | #define HANDLE_EVENT_PRE_SCAN 1 19 | #define HANDLE_EVENT_INCOMING_EVENT 2 20 | 21 | #define FUTURE_TYPE_NONE 0 22 | #define FUTURE_TYPE_HOLD_TAP 1 23 | #define FUTURE_TYPE_TAP_DANCE 2 24 | 25 | typedef struct { 26 | uint8_t status; 27 | uint32_t key_code; 28 | } fak_key_state_t; 29 | 30 | typedef struct { 31 | uint8_t type; 32 | union { 33 | fak_key_event_t* ev_in; 34 | }; 35 | } fak_handle_event_t; 36 | 37 | void push_key_event(uint8_t key_idx, uint8_t pressed); 38 | void handle_non_future(uint32_t key_code, uint8_t down); 39 | void tap_non_future(uint32_t key_code); 40 | uint32_t get_real_key_code(uint8_t key_idx); 41 | uint8_t get_future_type(uint32_t key_code); 42 | uint16_t get_last_tap_timestamp(); 43 | void key_state_inform(uint8_t key_idx, uint8_t down); 44 | 45 | void keyboard_init(); 46 | void keyboard_scan(); 47 | 48 | #endif // __SPLIT_CENTRAL_H__ 49 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SW_Push_SPST_3x6mm.kicad_mod: -------------------------------------------------------------------------------- 1 | (module SW_Push_SPST_3x6mm (layer F.Cu) (tedit 61B6AF94) 2 | (fp_text reference REF** (at 4.00812 -2.48158 180) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value SW_Push (at -2.25552 -3.93192 -180) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_line (start 0.775 1.75) (end 6.775 1.75) (layer F.SilkS) (width 0.12)) 9 | (fp_line (start 0.775 -1.75) (end 6.775 -1.75) (layer F.SilkS) (width 0.12)) 10 | (fp_line (start 0.775 -1.75) (end 0.775 1.75) (layer F.SilkS) (width 0.12)) 11 | (fp_line (start 6.775 -1.75) (end 6.775 1.75) (layer F.SilkS) (width 0.12)) 12 | (fp_line (start 2.425 -0.675) (end 5.125 -0.675) (layer F.SilkS) (width 0.12)) 13 | (fp_line (start 2.425 0.675) (end 5.125 0.675) (layer F.SilkS) (width 0.12)) 14 | (fp_line (start 2.425 -0.675) (end 2.425 0.675) (layer F.SilkS) (width 0.12)) 15 | (fp_line (start 5.125 -0.675) (end 5.125 0.675) (layer F.SilkS) (width 0.12)) 16 | (pad 2 smd rect (at 7.55 0) (size 1.5 2) (layers F.Cu F.Paste F.Mask)) 17 | (pad 1 smd rect (at 0 0) (size 1.5 2) (layers F.Cu F.Paste F.Mask)) 18 | (model ${KISYS3DMOD}/Button_Switch_SMD.3dshapes/SW_SPST_FSMSM.wrl 19 | (offset (xyz 3.75 0 0)) 20 | (scale (xyz 0.9 0.9 0.9)) 21 | (rotate (xyz 0 0 0)) 22 | ) 23 | ) 24 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/cheapis/README.md: -------------------------------------------------------------------------------- 1 | **Level: Intermediate 😅** 2 | 3 | ![My development cheapis split](./cheapis_fak.jpg) 4 | 5 | This is what I use for development! 6 | 7 | Check out dotleon's cheapis here: https://github.com/dotleon/cheapis 8 | 9 | - This is an example of a true split keyboard. That is, there are two MCUs and not just a matrix carried over to the other side (e.g., [Cheapino](https://github.com/tompi/cheapino), not be confused with Cheapis). 10 | - The base layout is parameterized (as a string! `QWERTYUI..`) and can be easily swapped. 11 | - The hold-tap behavior for the key that activates the media layer is automatically generated based on the contents of the media layer itself, so that the key would act as a hold only if the next pressed key is a non-empty keycode (`XXXX`). This avoids unnecessarily activating the media layer if the next pressed key would be useless anyway. 12 | - Home-row mod behaviors are automatically generated, allowing for bilateral combinations and combining more than one mod. The `eager_decision` property is set to `'hold` for all mods except `lalt`, which allows for Gui/Ctrl/Shift + external mouse click, without having to wait for the timeout. For operating systems that react to Gui being tapped (like Windows), you might want to exclude `lgui` from `eager_decision` assignment too. My OS doesn't react to Gui tap so I'm cool with it. 13 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/zilpzalp/README.md: -------------------------------------------------------------------------------- 1 | **Level: Advanced 🥵** 2 | 3 | Based on kilipan's zilpzalp example keymaps: https://github.com/kilipan/zilpzalp/tree/main/example_keymaps 4 | 5 | - Three highly modularized base layouts: Qwerty, Colemak, and Aptmak. More layouts can be easily added. 6 | - Code is reused as much as possible. Common traits between all layouts are shared. 7 | - Home row mod behaviors are automatically generated based on its side (left/right half) and location on the keyboard. It automatically configures bilateral combinations and allows for combining more than one mod. The way it's configured also allows for flexibility, such as reassigning where the home row mods are (e.g., top/bottom row mods) and the order of mods (e.g., GACS, CSAG) while being completely decoupled to the base layout. 8 | - Combo definition is simplified in `layouts.ncl` and `keymap.ncl` does all the heavy lifting. The auto home row mod behaviors even assign the correct key interrupt for combos (tap on press if all combo keys are on the same side, hold on release if all combo keys are on the other side, no interrupt if combo keys are on both sides). 9 | - This is an example of how you can reuse and share code across layouts, keymaps, and even keyboards. Heck, you can even develop this further to a fully-fledged FAK userspace library. Like [QMK userspaces](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_userspace.md) but on functional programming steroids. 10 | -------------------------------------------------------------------------------- /FAK-Firmware/src/mouse.c: -------------------------------------------------------------------------------- 1 | #include "mouse.h" 2 | #include "usb.h" 3 | #include "time.h" 4 | 5 | // TODO: Convert to __xdata 6 | int8_t scroll_direction = 0; 7 | uint16_t scroll_at_time = 0; 8 | 9 | void mouse_handle_key(uint16_t custom_code, uint8_t down) { 10 | if (custom_code < 8) { 11 | uint8_t buttons = USB_EP3I_read(0); 12 | buttons = (buttons & ~(1 << custom_code)) | (down << custom_code); 13 | return USB_EP3I_write(0, buttons); 14 | } 15 | 16 | switch (custom_code) { 17 | case 8: USB_EP3I_write(1, down * MOUSE_MOVE_SPEED); break; // Right 18 | case 9: USB_EP3I_write(1, -down * MOUSE_MOVE_SPEED); break; // Left 19 | case 10: USB_EP3I_write(2, down * MOUSE_MOVE_SPEED); break; // Down 20 | case 11: USB_EP3I_write(2, -down * MOUSE_MOVE_SPEED); break; // Up 21 | case 12: // Wheel up 22 | case 13: // Wheel down 23 | scroll_direction = custom_code == 12 ? down : -down; 24 | scroll_at_time = get_timer(); 25 | break; 26 | } 27 | } 28 | 29 | void mouse_process() { 30 | if (scroll_direction != 0) { 31 | if (get_timer() >= scroll_at_time) { 32 | USB_EP3I_write(3, scroll_direction); 33 | USB_EP3I_send_now(); 34 | USB_EP3I_write(3, 0); 35 | scroll_at_time = get_timer() + MOUSE_SCROLL_INTERVAL_MS; 36 | } 37 | } else { 38 | USB_EP3I_write(3, 0); 39 | } 40 | 41 | USB_EP3I_send_now(); 42 | } 43 | -------------------------------------------------------------------------------- /ch55p34/ch55p34.kicad_prl: -------------------------------------------------------------------------------- 1 | { 2 | "board": { 3 | "active_layer": 31, 4 | "active_layer_preset": "All Layers", 5 | "auto_track_width": true, 6 | "hidden_netclasses": [], 7 | "hidden_nets": [], 8 | "high_contrast_mode": 0, 9 | "net_color_mode": 1, 10 | "opacity": { 11 | "images": 0.6, 12 | "pads": 1.0, 13 | "tracks": 1.0, 14 | "vias": 1.0, 15 | "zones": 0.6 16 | }, 17 | "selection_filter": { 18 | "dimensions": true, 19 | "footprints": true, 20 | "graphics": true, 21 | "keepouts": true, 22 | "lockedItems": false, 23 | "otherItems": true, 24 | "pads": true, 25 | "text": true, 26 | "tracks": true, 27 | "vias": true, 28 | "zones": true 29 | }, 30 | "visible_items": [ 31 | 0, 32 | 1, 33 | 2, 34 | 3, 35 | 4, 36 | 5, 37 | 8, 38 | 9, 39 | 10, 40 | 11, 41 | 12, 42 | 13, 43 | 15, 44 | 16, 45 | 17, 46 | 18, 47 | 19, 48 | 20, 49 | 21, 50 | 22, 51 | 23, 52 | 24, 53 | 25, 54 | 26, 55 | 27, 56 | 28, 57 | 29, 58 | 30, 59 | 32, 60 | 33, 61 | 34, 62 | 35, 63 | 36, 64 | 39, 65 | 40 66 | ], 67 | "visible_layers": "fffffff_ffffffff", 68 | "zone_display_mode": 0 69 | }, 70 | "meta": { 71 | "filename": "ch55p34.kicad_prl", 72 | "version": 3 73 | }, 74 | "project": { 75 | "files": [] 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/cheapis/keyboard.ncl: -------------------------------------------------------------------------------- 1 | let { DirectPinKey, MatrixKey, PeripheralSideKey, .. } = import "../../fak/keyboard.ncl" in 2 | let { CH552T, .. } = import "../../fak/mcus.ncl" in 3 | 4 | let side_central = { 5 | mcu = CH552T, 6 | matrix = { 7 | cols = [14, 15, 16, 17, 10], 8 | rows = [35, 34, 33, 32] 9 | }, 10 | split.channel = CH552T.features.uart_12_13, 11 | } in 12 | 13 | let side_periph = { 14 | mcu = CH552T, 15 | matrix = { 16 | cols = [10, 17, 16, 15, 14], 17 | rows = [35, 34, 33, 32] 18 | }, 19 | split.channel = CH552T.features.uart_30_31, 20 | keys = 21 | let M = MatrixKey in 22 | [ 23 | M 0 0, M 1 0, M 2 0, M 3 0, M 4 0, 24 | M 0 1, M 1 1, M 2 1, M 3 1, M 4 1, 25 | M 0 2, M 1 2, M 2 2, M 3 2, M 4 2, 26 | M 0 3, M 1 3, 27 | ] 28 | } in 29 | 30 | side_central & { 31 | usb_dev = { 32 | vendor_id = 65535, 33 | product_id = 0, 34 | product_ver = 42069, 35 | # FIXME: There is a known issue with strings making USB connection slow 36 | # manufacturer = "dotleon", 37 | # product = "cheapis", 38 | }, 39 | split.peripheral = side_periph, 40 | keys = 41 | let D = DirectPinKey in 42 | let M = MatrixKey in 43 | let S = PeripheralSideKey in 44 | [ 45 | M 0 0, M 1 0, M 2 0, M 3 0, M 4 0, S 0, S 1, S 2, S 3, S 4, 46 | M 0 1, M 1 1, M 2 1, M 3 1, M 4 1, S 5, S 6, S 7, S 8, S 9, 47 | M 0 2, M 1 2, M 2 2, M 3 2, M 4 2, S 10, S 11, S 12, S 13, S 14, 48 | M 3 3, M 4 3, S 15, S 16, 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /gerber/ch55p34-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,7.0.1*% 2 | %TF.CreationDate,2024-01-05T17:15:02-05:00*% 3 | %TF.ProjectId,ch55p34,63683535-7033-4342-9e6b-696361645f70,rev?*% 4 | %TF.SameCoordinates,Original*% 5 | %TF.FileFunction,Profile,NP*% 6 | %FSLAX46Y46*% 7 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 8 | G04 Created by KiCad (PCBNEW 7.0.1) date 2024-01-05 17:15:02* 9 | %MOMM*% 10 | %LPD*% 11 | G01* 12 | G04 APERTURE LIST* 13 | %TA.AperFunction,Profile*% 14 | %ADD10C,0.100000*% 15 | %TD*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X160650000Y-35050000D02* 19 | X196480000Y-28120000D01* 20 | X151260000Y-35050000D02* 21 | X160650000Y-35050000D01* 22 | X115190000Y-28110000D02* 23 | X151260000Y-35050000D01* 24 | X76800000Y-24140000D02* 25 | X55310000Y-30750000D01* 26 | X96790000Y-23180000D02* 27 | X76800000Y-24140000D01* 28 | X115190000Y-28110000D02* 29 | X96790000Y-23180000D01* 30 | X214870000Y-23180000D02* 31 | X196480000Y-28120000D01* 32 | X234870000Y-24150000D02* 33 | X214870000Y-23180000D01* 34 | X256350000Y-30740000D02* 35 | X234870000Y-24150000D01* 36 | X271140000Y-85960000D02* 37 | X256350000Y-30740000D01* 38 | X223300000Y-118550000D02* 39 | X271140000Y-85960000D01* 40 | X206020000Y-126600000D02* 41 | X223300000Y-118550000D01* 42 | X185860000Y-132670000D02* 43 | X206020000Y-126600000D01* 44 | X125800000Y-132660000D02* 45 | X185860000Y-132670000D01* 46 | X105630000Y-126580000D02* 47 | X125800000Y-132660000D01* 48 | X88300000Y-118520000D02* 49 | X105630000Y-126580000D01* 50 | X40530000Y-85940000D02* 51 | X88300000Y-118520000D01* 52 | X55310000Y-30750000D02* 53 | X40530000Y-85940000D01* 54 | M02* 55 | -------------------------------------------------------------------------------- /FAK-Firmware/src/hold_tap.h: -------------------------------------------------------------------------------- 1 | #ifndef __HOLD_TAP_H__ 2 | #define __HOLD_TAP_H__ 3 | 4 | #include "keyboard.h" 5 | #include "keymap.h" 6 | 7 | #include 8 | 9 | #define HOLD_TAP_KEY_INTERRUPT_ENABLE 0x01 10 | #define HOLD_TAP_KEY_INTERRUPT_DECIDE_HOLD 0x02 11 | #define HOLD_TAP_KEY_INTERRUPT_DECIDE_TAP 0x00 12 | #define HOLD_TAP_KEY_INTERRUPT_ON_PRESS 0x04 13 | #define HOLD_TAP_KEY_INTERRUPT_ON_RELEASE 0x00 14 | 15 | #define HOLD_TAP_FLAGS_TIMEOUT_DECISION_MASK 0x01 16 | #define HOLD_TAP_FLAGS_TIMEOUT_DECISION_TAP 0x00 17 | #define HOLD_TAP_FLAGS_TIMEOUT_DECISION_HOLD 0x01 18 | 19 | #ifdef HOLD_TAP_EAGER_ENABLE 20 | #define HOLD_TAP_FLAGS_EAGER_MASK 0x06 21 | #define HOLD_TAP_FLAGS_EAGER_NONE 0x00 22 | #define HOLD_TAP_FLAGS_EAGER_HOLD 0x02 23 | #define HOLD_TAP_FLAGS_EAGER_TAP 0x04 24 | #endif 25 | 26 | #ifdef HOLD_TAP_GLOBAL_QUICK_TAP_IGNORE_CONSECUTIVE_ENABLE 27 | #define HOLD_TAP_FLAGS_GLOBAL_QUICK_TAP_IGNORE_CONSECUTIVE 0x08 28 | #endif 29 | 30 | uint8_t is_future_type_hold_tap(uint32_t key_code); 31 | 32 | uint8_t hold_tap_handle_event(fak_key_state_t *ks, uint8_t handle_ev, int16_t delta); 33 | 34 | typedef struct { 35 | uint8_t flags; 36 | uint16_t timeout_ms; 37 | uint8_t key_interrupts[(KEY_COUNT + 1) / 2]; 38 | #ifdef HOLD_TAP_QUICK_TAP_ENABLE 39 | uint8_t quick_tap_ms; 40 | #ifdef HOLD_TAP_QUICK_TAP_INTERRUPT_ENABLE 41 | uint16_t quick_tap_interrupt_ms; 42 | #endif 43 | #endif 44 | #ifdef HOLD_TAP_GLOBAL_QUICK_TAP_ENABLE 45 | uint16_t global_quick_tap_ms; 46 | #endif 47 | } fak_hold_tap_behavior_t; 48 | 49 | extern __code fak_hold_tap_behavior_t hold_tap_behaviors[]; 50 | 51 | #endif // __HOLD_TAP_H__ 52 | -------------------------------------------------------------------------------- /FAK-Firmware/src/keymap.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYMAP_H__ 2 | #define __KEYMAP_H__ 3 | 4 | #include 5 | 6 | #define KEY_CODE_HOLD_MASK 0xFFFF0000 7 | #define KEY_CODE_HOLD_LAYER_BEHAVIOR_MASK 0xE0000000 8 | #define KEY_CODE_HOLD_LAYER_IDX_MASK 0x1F000000 9 | #define KEY_CODE_HOLD_MODS_MASK 0xFF0000 10 | #define KEY_CODE_TAP_MASK 0xFFFF 11 | #define KEY_CODE_TAP_MODS_MASK 0xFF00 12 | #define KEY_CODE_TAP_CODE_MASK 0xFF 13 | 14 | #define KEY_CODE_HOLD_NO_OP 0x1FFF0000 15 | 16 | #if LAYER_COUNT == 1 17 | extern __code uint32_t key_map[KEY_COUNT]; 18 | 19 | #else 20 | 21 | #if LAYER_COUNT <= 8 22 | typedef uint8_t fak_layer_state_t; 23 | #elif LAYER_COUNT <= 16 24 | typedef uint16_t fak_layer_state_t; 25 | #else 26 | typedef uint32_t fak_layer_state_t; 27 | #endif 28 | 29 | extern __code uint32_t key_map[LAYER_COUNT][KEY_COUNT]; 30 | 31 | #if CONDITIONAL_LAYER_COUNT > 0 32 | typedef struct { 33 | uint8_t then_layer; 34 | fak_layer_state_t if_layers; 35 | } fak_conditional_layer_def_t; 36 | 37 | extern __code fak_conditional_layer_def_t conditional_layers[CONDITIONAL_LAYER_COUNT]; 38 | #endif 39 | 40 | uint8_t get_highest_layer_idx(); 41 | uint8_t get_default_layer_idx(); 42 | void set_default_layer_idx(uint8_t layer_idx); 43 | 44 | void set_layer_state(fak_layer_state_t state); 45 | void layer_state_on(uint8_t layer_idx); 46 | void layer_state_off(uint8_t layer_idx); 47 | void layer_state_toggle(uint8_t layer_idx); 48 | 49 | void set_persistent_layer_state(fak_layer_state_t state); 50 | void persistent_layer_state_on(uint8_t layer_idx); 51 | void persistent_layer_state_off(uint8_t layer_idx); 52 | 53 | uint8_t is_layer_on(uint8_t layer_idx); 54 | uint8_t is_layer_off(uint8_t layer_idx); 55 | 56 | #endif 57 | 58 | uint32_t get_real_key_code(uint8_t key_idx); 59 | 60 | #endif // __KEYMAP_H__ 61 | -------------------------------------------------------------------------------- /components-and-pretty/shell.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs ? import {}, 3 | on-nixos ? true, 4 | interactive-html-bom ? pkgs.callPackage ../nix/pkgs/interactive-html-bom {}, 5 | # Kludge: on NixOS desktop, need virtualgl for the pcbnew 6 | # to be able to show 3D preview. 7 | kibot ? pkgs.callPackage ../nix/pkgs/kibot {}, 8 | pcbdraw ? pkgs.callPackage ../nix/pkgs/pcbdraw {}, 9 | recordmydesktop ? pkgs.callPackage ../nix/pkgs/recordmydesktop {}, 10 | }: 11 | pkgs.mkShell { 12 | # The environment variables KiBot uses for its 13 | # 3D preview are in ~/.config/kicad/kicad_common, for Kicad 5. 14 | # /nix/store/niapxda5vc2mpyys5bn07zs30jwd2qi7-kicad-symbols-7d4cbbddce/share/kicad/library 15 | KICAD_SYMBOL_DIR = "${pkgs.kicad.libraries.symbols}/share/kicad/library"; 16 | # /nix/store/f4raka5s0z9cqwpqbw2954v774kiqb90-kicad-packages3d-be0ba9377b/share/kicad/modules/packages3d/ 17 | KISYS3DMOD = "${pkgs.kicad.libraries.packages3d}/share/kicad/modules/packages3d"; 18 | # /nix/store/p0j7z9ld18mqiipqlihyy691v3ma0qmr-kicad-footprints-e53d53ac4a/share/kicad/modules 19 | KISYSMOD = "${pkgs.kicad.libraries.footprints}/share/kicad/modules"; 20 | 21 | # Couldn't get KiAuto's interposer to work. 22 | KIAUTO_INTERPOSER_DISABLE = "1"; 23 | 24 | shellHook = '' 25 | KICAD_COMMON_CONFIG="$HOME/.config/kicad/kicad_common" 26 | if ! grep -q KISYS3DMOD "$KICAD_COMMON_CONFIG"; then 27 | echo "KISYS3DMOD=$KISYS3DMOD" >> "$KICAD_COMMON_CONFIG" 28 | fi 29 | ''; 30 | 31 | LD_LIBRARY_PATH = 32 | if on-nixos 33 | then 34 | # c.f. https://nixos.wiki/wiki/OpenGL 35 | "/run/opengl-driver/lib:/run/opengl-driver-32/lib" 36 | else ""; 37 | 38 | buildInputs = with pkgs; [ 39 | fluxbox 40 | interactive-html-bom 41 | kibot 42 | pcbdraw 43 | recordmydesktop 44 | turbovnc 45 | virtualgl 46 | wmctrl 47 | x11vnc 48 | xclip 49 | xdotool 50 | xorg.xkbcomp 51 | ]; 52 | } 53 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/main.ncl: -------------------------------------------------------------------------------- 1 | let util = import "util_functions.ncl" in 2 | 3 | let { Keyboard, .. } = import "keyboard.ncl" in 4 | let kb | Keyboard = import "../keyboard.ncl" in 5 | 6 | let _km = import "../keymap.ncl" in 7 | let { Keymap, .. } = (import "keymap.ncl") kb _km in 8 | let km | Keymap = _km in 9 | 10 | let gen_ir = import "gen_ir.ncl" in 11 | let gen_code = import "gen_code.ncl" in 12 | let gen_meson_options = import "gen_meson_options.ncl" in 13 | 14 | let is_split = std.record.has_field "split" kb in 15 | 16 | if is_split then 17 | # This preprocessing transformation is necessary in order to: 18 | # - Eliminate unused peripheral side keys 19 | # - Detect invalid peripheral side keys (e.g., S 9 assuming peripheral of 5 keys) 20 | # - Ensure both sides are on the same page about the order of key pressed bits 21 | 22 | let periph_key_indices = kb.keys 23 | |> std.array.filter (fun k => k.type == 'peripheral) 24 | |> std.array.map (fun k => k.data) 25 | in 26 | 27 | let transformed_periph_keys = periph_key_indices 28 | |> std.array.map (fun key_idx => std.array.at key_idx kb.split.peripheral.keys) 29 | in 30 | 31 | let transformed_central_keys = kb.keys 32 | |> std.array.map (fun k => 33 | if k.type != 'peripheral then k else 34 | k & {data | force = util.array.index_of k.data periph_key_indices} 35 | ) 36 | in 37 | 38 | let transformed_kb = kb & { 39 | keys | force = transformed_central_keys, 40 | split.peripheral.keys | force = transformed_periph_keys, 41 | } in 42 | 43 | let central_ir = gen_ir transformed_kb km 'central in 44 | let peripheral_ir = gen_ir transformed_kb.split.peripheral {} 'peripheral in 45 | 46 | { 47 | central = central_ir |> gen_code, 48 | peripheral = peripheral_ir |> gen_code, 49 | meson_options = central_ir |> gen_meson_options, 50 | } 51 | 52 | else 53 | let ir = gen_ir kb km 'self in 54 | { 55 | central = ir |> gen_code, 56 | meson_options = ir |> gen_meson_options, 57 | } -------------------------------------------------------------------------------- /FAK-Firmware/src/key_event_queue.c: -------------------------------------------------------------------------------- 1 | #include "key_event_queue.h" 2 | #include "keymap.h" 3 | 4 | typedef struct { 5 | fak_key_event_t q[KEY_EVENT_QUEUE_LEN]; 6 | uint8_t size; 7 | uint8_t bsize; 8 | uint8_t state; 9 | } fak_key_event_queue_t; 10 | 11 | __xdata __at(XADDR_KEY_EVENT_QUEUE) fak_key_event_queue_t key_event_queue; 12 | 13 | inline uint8_t key_event_queue_get_size() { 14 | return key_event_queue.size; 15 | } 16 | 17 | inline uint8_t key_event_queue_get_bsize() { 18 | return key_event_queue.bsize; 19 | } 20 | 21 | inline uint8_t* key_event_queue_state() { 22 | return &key_event_queue.state; 23 | } 24 | 25 | inline fak_key_event_t* key_event_queue_front() { 26 | return &key_event_queue.q[0]; 27 | } 28 | 29 | inline fak_key_event_t* key_event_queue_bfront() { 30 | return &key_event_queue.q[key_event_queue.size]; 31 | } 32 | 33 | void key_event_queue_push() { 34 | if (!key_event_queue.bsize) return; 35 | key_event_queue.size++; 36 | key_event_queue.bsize--; 37 | } 38 | 39 | void key_event_queue_pop() { 40 | if (!key_event_queue.size) return; 41 | 42 | for (uint8_t i = 0; i < (key_event_queue.size + key_event_queue.bsize - 1); i++) { 43 | key_event_queue.q[i] = key_event_queue.q[i + 1]; 44 | } 45 | 46 | key_event_queue.bsize += key_event_queue.size - 1; 47 | key_event_queue.size = 0; 48 | } 49 | 50 | void key_event_queue_bpush(fak_key_event_t *ev) { 51 | key_event_queue.q[key_event_queue.size + key_event_queue.bsize] = *ev; 52 | key_event_queue.bsize++; 53 | } 54 | 55 | void key_event_queue_bpop() { 56 | if (!key_event_queue.bsize) return; 57 | 58 | for (uint8_t i = 0; i < key_event_queue.bsize - 1; i++) { 59 | key_event_queue.q[key_event_queue.size + i] = key_event_queue.q[key_event_queue.size + i + 1]; 60 | } 61 | key_event_queue.bsize--; 62 | } 63 | 64 | void key_event_queue_breset() { 65 | key_event_queue.bsize += key_event_queue.size; 66 | key_event_queue.size = 0; 67 | } 68 | 69 | void key_event_queue_init() { 70 | key_event_queue.size = 0; 71 | key_event_queue.bsize = 0; 72 | key_event_queue.state = 0; 73 | } 74 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.4 2 | #encoding utf-8 3 | # 4 | # BluePill_or_MiniF4_DIP40 5 | # 6 | DEF BluePill_or_MiniF4_DIP40 U 0 40 Y Y 1 F N 7 | F0 "U" -500 1100 50 H V C CNN 8 | F1 "BluePill_or_MiniF4_DIP40" -100 50 50 V V C CNN 9 | F2 "ProjectLocal:WeAct_MiniF4" 500 1150 50 H I C CNN 10 | F3 "" 650 -850 50 V I C CNN 11 | DRAW 12 | T 0 -400 200 24 0 0 0 "USB DN" Normal 0 L C 13 | T 0 -400 100 24 0 0 0 "USB DP" Normal 0 L C 14 | S -600 1000 600 -1100 0 1 0 f 15 | X B12 1 -800 900 200 R 50 50 1 1 B 16 | X A15 10 -800 0 200 R 50 50 1 1 B 17 | X B3 11 -800 -100 200 R 50 50 1 1 B 18 | X B4 12 -800 -200 200 R 50 50 1 1 B 19 | X B5 13 -800 -300 200 R 50 50 1 1 B 20 | X B6 14 -800 -400 200 R 50 50 1 1 B 21 | X B7 15 -800 -500 200 R 50 50 1 1 B 22 | X B8 16 -800 -600 200 R 50 50 1 1 B 23 | X B9 17 -800 -700 200 R 50 50 1 1 B 24 | X 5V 18 -800 -800 200 R 50 50 1 1 w 25 | X GND 19 -800 -900 200 R 50 50 1 1 w 26 | X B13 2 -800 800 200 R 50 50 1 1 B 27 | X 3V3 20 -800 -1000 200 R 50 50 1 1 w 28 | X VBAT 21 800 -1000 200 L 50 50 1 1 w 29 | X C13 22 800 -900 200 L 50 50 1 1 B 30 | X C14 23 800 -800 200 L 50 50 1 1 B 31 | X C15 24 800 -700 200 L 50 50 1 1 B 32 | X A0_or_RST 25 800 -600 200 L 50 50 1 1 I 33 | X A1_or_A0 26 800 -500 200 L 50 50 1 1 B 34 | X A2_or_A1 27 800 -400 200 L 50 50 1 1 B 35 | X A3_or_A2 28 800 -300 200 L 50 50 1 1 B 36 | X A4_or_A3 29 800 -200 200 L 50 50 1 1 B 37 | X B14 3 -800 700 200 R 50 50 1 1 B 38 | X A5_or_A4 30 800 -100 200 L 50 50 1 1 B 39 | X A6_or_A5 31 800 0 200 L 50 50 1 1 B 40 | X A7_or_A6 32 800 100 200 L 50 50 1 1 B 41 | X B0_or_A7 33 800 200 200 L 50 50 1 1 B 42 | X B1_or_B0 34 800 300 200 L 50 50 1 1 B 43 | X B10_or_B1 35 800 400 200 L 50 50 1 1 B 44 | X B11_or_B2 36 800 500 200 L 50 50 1 1 B 45 | X RST_or_B10 37 800 600 200 L 50 50 1 1 B 46 | X 3V3 38 800 700 200 L 50 50 1 1 w 47 | X GND 39 800 800 200 L 50 50 1 1 w 48 | X B15 4 -800 600 200 R 50 50 1 1 B 49 | X GND_or_5V 40 800 900 200 L 50 50 1 1 w 50 | X A8 5 -800 500 200 R 50 50 1 1 B 51 | X A9 6 -800 400 200 R 50 50 1 1 B 52 | X A10 7 -800 300 200 R 50 50 1 1 B 53 | X A11 8 -800 200 200 R 50 50 1 1 B 54 | X A12 9 -800 100 200 R 50 50 1 1 B 55 | ENDDRAW 56 | ENDDEF 57 | # 58 | #End Library 59 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SK6812-MINI-E_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module SK6812-MINI-E_Reversible (layer F.Cu) (tedit 5FD78D81) 2 | (fp_text reference REF** (at 0 2.1 unlocked) (layer F.SilkS) 3 | (effects (font (size 0.7 0.7) (thickness 0.15))) 4 | ) 5 | (fp_text value SK6812-MINI-E_Reversible (at 0 -3.81 unlocked) (layer Dwgs.User) hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_poly (pts (xy 2.8 1.27) (xy 2.2 1.27) (xy 2.2 1.87)) (layer B.SilkS) (width 0.1)) 9 | (fp_poly (pts (xy 2.8 -1.4) (xy 2.2 -1.4) (xy 2.2 -2)) (layer F.SilkS) (width 0.1)) 10 | (fp_line (start 1.6 -1.4) (end 1.6 1.4) (layer Cmts.User) (width 0.12)) 11 | (fp_line (start 1.6 1.4) (end -1.6 1.4) (layer Cmts.User) (width 0.12)) 12 | (fp_line (start -1.6 1.4) (end -1.6 -1.4) (layer Cmts.User) (width 0.12)) 13 | (fp_line (start -1.6 -1.4) (end 1.6 -1.4) (layer Cmts.User) (width 0.12)) 14 | (fp_line (start 1.7 -1.5) (end 1.7 1.5) (layer Edge.Cuts) (width 0.12)) 15 | (fp_line (start 1.7 1.5) (end -1.7 1.5) (layer Edge.Cuts) (width 0.12)) 16 | (fp_line (start -1.7 1.5) (end -1.7 -1.5) (layer Edge.Cuts) (width 0.12)) 17 | (fp_line (start -1.7 -1.5) (end 1.7 -1.5) (layer Edge.Cuts) (width 0.12)) 18 | (fp_text user %R (at 0 2.1) (layer B.SilkS) 19 | (effects (font (size 0.7 0.7) (thickness 0.15)) (justify mirror)) 20 | ) 21 | (pad 1 smd rect (at -2.55 0.75) (size 1.7 0.82) (layers F.Cu F.Paste F.Mask)) 22 | (pad 2 smd rect (at -2.55 -0.75) (size 1.7 0.82) (layers F.Cu F.Paste F.Mask)) 23 | (pad 4 smd rect (at 2.55 0.75) (size 1.7 0.82) (layers F.Cu F.Paste F.Mask)) 24 | (pad 3 smd roundrect (at 2.55 -0.75) (size 1.7 0.82) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)) 25 | (pad 1 smd rect (at -2.55 -0.75) (size 1.7 0.82) (layers B.Cu B.Paste B.Mask)) 26 | (pad 3 smd roundrect (at 2.55 0.75) (size 1.7 0.82) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)) 27 | (pad 2 smd rect (at -2.55 0.75) (size 1.7 0.82) (layers B.Cu B.Paste B.Mask)) 28 | (pad 4 smd rect (at 2.55 -0.75) (size 1.7 0.82) (layers B.Cu B.Paste B.Mask)) 29 | (model "${KIPRJMOD}/Keebio-Parts.pretty/3dmodels/SK6812MINI-E v1.step" 30 | (at (xyz 0 0 0)) 31 | (scale (xyz 1 1 1)) 32 | (rotate (xyz 90 0 0)) 33 | ) 34 | ) 35 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SW_Push_SPST_3x6mm_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module SW_Push_SPST_3x6mm_Reversible (layer F.Cu) (tedit 61B6AF7C) 2 | (fp_text reference REF** (at 4.00812 -2.48158 180) (layer F.SilkS) 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value SW_Push (at -2.25552 -3.93192 -180) (layer F.Fab) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_line (start 0.775 1.75) (end 6.775 1.75) (layer B.SilkS) (width 0.12)) 9 | (fp_line (start 6.775 1.75) (end 6.775 -1.75) (layer B.SilkS) (width 0.12)) 10 | (fp_line (start 2.425 0.675) (end 2.425 -0.675) (layer B.SilkS) (width 0.12)) 11 | (fp_line (start 0.775 -1.75) (end 6.775 -1.75) (layer B.SilkS) (width 0.12)) 12 | (fp_line (start 0.775 1.75) (end 0.775 -1.75) (layer B.SilkS) (width 0.12)) 13 | (fp_line (start 2.425 0.675) (end 5.125 0.675) (layer B.SilkS) (width 0.12)) 14 | (fp_line (start 5.125 0.675) (end 5.125 -0.675) (layer B.SilkS) (width 0.12)) 15 | (fp_line (start 2.425 -0.675) (end 5.125 -0.675) (layer B.SilkS) (width 0.12)) 16 | (fp_line (start 0.775 1.75) (end 6.775 1.75) (layer F.SilkS) (width 0.12)) 17 | (fp_line (start 0.775 -1.75) (end 6.775 -1.75) (layer F.SilkS) (width 0.12)) 18 | (fp_line (start 0.775 -1.75) (end 0.775 1.75) (layer F.SilkS) (width 0.12)) 19 | (fp_line (start 6.775 -1.75) (end 6.775 1.75) (layer F.SilkS) (width 0.12)) 20 | (fp_line (start 2.425 -0.675) (end 5.125 -0.675) (layer F.SilkS) (width 0.12)) 21 | (fp_line (start 2.425 0.675) (end 5.125 0.675) (layer F.SilkS) (width 0.12)) 22 | (fp_line (start 2.425 -0.675) (end 2.425 0.675) (layer F.SilkS) (width 0.12)) 23 | (fp_line (start 5.125 -0.675) (end 5.125 0.675) (layer F.SilkS) (width 0.12)) 24 | (fp_text user %R (at 4.00812 -2.48158 -180) (layer B.SilkS) 25 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 26 | ) 27 | (pad 2 smd rect (at 7.55 -0.00508) (size 1.5 2) (layers B.Cu B.Paste B.Mask)) 28 | (pad 1 smd rect (at 0 -0.00508) (size 1.5 2) (layers B.Cu B.Paste B.Mask)) 29 | (pad 2 smd rect (at 7.55 0) (size 1.5 2) (layers F.Cu F.Paste F.Mask)) 30 | (pad 1 smd rect (at 0 0) (size 1.5 2) (layers F.Cu F.Paste F.Mask)) 31 | (model ${KISYS3DMOD}/Button_Switch_SMD.3dshapes/SW_SPST_FSMSM.wrl 32 | (offset (xyz 3.75 0 0)) 33 | (scale (xyz 0.9 0.9 0.9)) 34 | (rotate (xyz 0 0 0)) 35 | ) 36 | ) 37 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/Resistor-Hybrid.kicad_mod: -------------------------------------------------------------------------------- 1 | (module Resistor-Hybrid (layer F.Cu) (tedit 61B5F662) 2 | (attr smd) 3 | (fp_text reference R** (at -0.0254 1.5) (layer F.SilkS) 4 | (effects (font (size 0.8 0.8) (thickness 0.15))) 5 | ) 6 | (fp_text value R (at 0 -1.925) (layer F.SilkS) hide 7 | (effects (font (size 0.8 0.8) (thickness 0.15))) 8 | ) 9 | (fp_line (start -2.794 -0.762) (end -2.54 -1.016) (layer F.SilkS) (width 0.15)) 10 | (fp_line (start -2.54 -1.016) (end -2.286 -1.016) (layer F.SilkS) (width 0.15)) 11 | (fp_line (start -2.286 -1.016) (end -2.032 -0.762) (layer F.SilkS) (width 0.15)) 12 | (fp_line (start -2.032 -0.762) (end 2.032 -0.762) (layer F.SilkS) (width 0.15)) 13 | (fp_line (start 2.032 -0.762) (end 2.286 -1.016) (layer F.SilkS) (width 0.15)) 14 | (fp_line (start 2.286 -1.016) (end 2.54 -1.016) (layer F.SilkS) (width 0.15)) 15 | (fp_line (start 2.54 -1.016) (end 2.794 -0.762) (layer F.SilkS) (width 0.15)) 16 | (fp_line (start 2.794 -0.762) (end 2.794 0.762) (layer F.SilkS) (width 0.15)) 17 | (fp_line (start 2.794 0.762) (end 2.54 1.016) (layer F.SilkS) (width 0.15)) 18 | (fp_line (start 2.54 1.016) (end 2.286 1.016) (layer F.SilkS) (width 0.15)) 19 | (fp_line (start 2.286 1.016) (end 2.032 0.762) (layer F.SilkS) (width 0.15)) 20 | (fp_line (start 2.032 0.762) (end -2.032 0.762) (layer F.SilkS) (width 0.15)) 21 | (fp_line (start -2.032 0.762) (end -2.286 1.016) (layer F.SilkS) (width 0.15)) 22 | (fp_line (start -2.286 1.016) (end -2.54 1.016) (layer F.SilkS) (width 0.15)) 23 | (fp_line (start -2.54 1.016) (end -2.794 0.762) (layer F.SilkS) (width 0.15)) 24 | (fp_line (start -2.794 0.762) (end -2.794 -0.762) (layer F.SilkS) (width 0.15)) 25 | (fp_line (start -3.302 0) (end -2.794 0) (layer F.SilkS) (width 0.15)) 26 | (fp_line (start 2.794 0) (end 3.302 0) (layer F.SilkS) (width 0.15)) 27 | (pad 1 smd rect (at 1.35 0) (size 1.5 1.2) (layers F.Cu F.Paste F.Mask)) 28 | (pad 2 smd rect (at -1.35 0) (size 1.5 1.2) (layers F.Cu F.Paste F.Mask)) 29 | (pad 2 thru_hole circle (at -3.9 0) (size 1.6 1.6) (drill 1) (layers *.Cu *.Mask F.SilkS)) 30 | (pad 1 thru_hole circle (at 3.9 0) (size 1.6 1.6) (drill 1) (layers *.Cu *.Mask)) 31 | (pad 2 smd rect (at -2.5 0) (size 2.9 0.5) (layers F.Cu) 32 | (solder_mask_margin -999)) 33 | (pad 1 smd rect (at 2.5 0) (size 2.9 0.5) (layers F.Cu) 34 | (solder_mask_margin -999)) 35 | (model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl 36 | (at (xyz 0 0 0)) 37 | (scale (xyz 1 1 1)) 38 | (rotate (xyz 0 0 0)) 39 | ) 40 | ) 41 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/3x3_macropad/keymap.ncl: -------------------------------------------------------------------------------- 1 | let { tap, hold, td, combo, .. } = import "../../fak/keycode.ncl" in 2 | 3 | # We alias commonly used stuff, so we don't end up repeating them over and over. 4 | let kc = tap.reg.kc in 5 | let me = tap.custom.media in 6 | let XXXX = tap.none & hold.none in 7 | let TTTT = tap.trans & hold.trans in 8 | 9 | # "cu" for custom keys. This is just a name, so it can be whatever you want. 10 | let cu = { 11 | # Again, these are just names. They don't have to be 4-letter or capitalized. 12 | COPY = tap.reg.mod.lctl & kc.C, 13 | PSTE = tap.reg.mod.lctl & kc.V, 14 | CUT = tap.reg.mod.lctl & kc.X, 15 | CLOS = tap.reg.mod.lalt & kc.F4, 16 | 17 | # Yep. Such names are possible in Nickel. 18 | ":P" = tap.reg.mod.lctl & tap.reg.mod.lalt & kc.DEL, 19 | 20 | # Screenshot 21 | SCSH = tap.reg.mod.lgui & tap.reg.mod.lsft & kc.S, 22 | } in 23 | 24 | # 1 tap = play/pause. 2 taps = next track. 3 taps = prev track. 25 | let my_playback_tap_dance = td.make 200 [ 26 | me.PLAY, 27 | me.NEXT, 28 | me.PREV, 29 | # Reminder: These can be hold-taps for more complex behavior. 30 | # These can even be tap dances... for nested tap dances... but uh... why though? 31 | ] in 32 | 33 | # The following keycode is a hold-tap, since it has a tap and a hold portion 34 | # Important: All hold-taps need to have a behavior bound with `hold.reg.behavior` 35 | 36 | let ctrl_if_held_and_space_if_tapped = 37 | tap.reg.kc.SPC 38 | & hold.reg.mod.lctl 39 | & hold.reg.behavior { 40 | timeout_ms = 300 41 | # This will resolve as a hold after 300ms regardless of other keys pressed. 42 | # However, if released before the 300ms is up, it will resolve as a tap. 43 | } 44 | in 45 | 46 | # Keymap definition 47 | { 48 | virtual_keys = [ 49 | # Combo activated by the first and second physical keys 50 | combo.make 42 [0, 1], 51 | 52 | # Combo activated by the third, fourth, and fifth physical keys 53 | combo.make 69 [2, 3, 4], 54 | ], 55 | 56 | layers = [ 57 | [ # Layer 0 58 | cu.COPY, cu.PSTE, cu.CUT, 59 | me.VOLU, me.VOLD, me.MUTE, 60 | cu.SCSH, cu.CLOS, cu.":P", 61 | 62 | # Combos start here in the same order we defined them above 63 | hold.reg.layer 1, 64 | hold.reg.layer 2, 65 | ], 66 | [ # Layer 1 67 | kc.A, kc.B, kc.C, 68 | kc.D, kc.E, kc.F, 69 | kc.G, kc.H, kc.I, 70 | 71 | TTTT, 72 | my_playback_tap_dance, 73 | ], 74 | [ # Layer 2 75 | kc.N7, kc.N8, kc.N9, 76 | kc.N4, kc.N5, kc.N6, 77 | kc.N1, kc.N2, kc.N3, 78 | 79 | ctrl_if_held_and_space_if_tapped, 80 | TTTT, 81 | ], 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /FAK-Firmware/meson.build: -------------------------------------------------------------------------------- 1 | project('fak', 'c') 2 | 3 | cc_args = ['--opt-code-size'] 4 | inc_dirs = ['src', 'src/inc'] 5 | 6 | sources_common = [ 7 | 'src/main.c', 8 | 'src/time.c', 9 | 'src/bootloader.c', 10 | ] 11 | 12 | sources_central = [ 13 | 'src/usb.c', 14 | 'src/split_central.c', 15 | 'src/keymap.c', 16 | 'src/key_event_queue.c', 17 | ] 18 | 19 | sources_peripheral = [ 20 | 'src/split_peripheral.c', 21 | ] 22 | 23 | ### 24 | 25 | cc = find_program('sdcc', required : true) 26 | nickel = find_program('nickel', required : true) 27 | python = find_program('python', required : true) 28 | wchisp = find_program('wchisp', required : false) 29 | 30 | sides = ['central'] 31 | if get_option('split') 32 | sides += ['peripheral'] 33 | endif 34 | 35 | foreach side : sides 36 | side_h = custom_target(side + '.h', 37 | input : 'fak.py', 38 | output : side + '.h', 39 | capture : true, 40 | command : [python, '@INPUT@', 'query_ncl', side + '.h'], 41 | depend_files : ['.main.ncl.json'], 42 | ) 43 | 44 | side_c = custom_target(side + '.c', 45 | input : 'fak.py', 46 | output : side + '.c', 47 | capture : true, 48 | command : [python, '@INPUT@', 'query_ncl', side + '.c'], 49 | depend_files : ['.main.ncl.json'], 50 | ) 51 | 52 | dir_base = meson.current_source_dir() 53 | cc_incs = ['--include', side_h.full_path()] 54 | 55 | foreach dir : inc_dirs 56 | cc_incs += '-I' + join_paths(dir_base, dir) 57 | endforeach 58 | 59 | compiler = generator(cc, 60 | output : '@BASENAME@.rel', 61 | arguments : cc_args + cc_incs + ['-c', '@INPUT@', '-o', '@OUTPUT@'], 62 | depends : [side_c, side_h], 63 | ) 64 | 65 | sources = sources_common + [side_c] 66 | 67 | if side == 'central' 68 | sources += sources_central 69 | 70 | extra_sources = get_option('extra_sources').strip() 71 | if extra_sources != '' 72 | sources += extra_sources.split(',') 73 | endif 74 | elif side == 'peripheral' 75 | sources += sources_peripheral 76 | endif 77 | 78 | rel = compiler.process(sources) 79 | 80 | ihx = custom_target(side + '.ihx', 81 | input : rel, 82 | output : side + '.ihx', 83 | install : true, 84 | install_dir : 'firmware', 85 | command : [cc, cc_args, '-o', '@OUTPUT@', '@INPUT@'], 86 | ) 87 | 88 | flash = run_target('flash_' + side, 89 | command : [wchisp, 'flash', ihx.full_path()], 90 | depends : ihx, 91 | ) 92 | endforeach 93 | 94 | wchisp_info = run_target('wchisp_info', 95 | command : [wchisp, 'info'], 96 | ) 97 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/keyboard.ncl: -------------------------------------------------------------------------------- 1 | let { MAX_USB_STRING_LENGTH, DEFAULT_DEBOUNCE_MS, .. } = import "constants.ncl" in 2 | let { Uint8, Uint16, BoundedInt, Set, ElementOf, .. } = import "util_types.ncl" in 3 | 4 | let GpioPin = std.contract.from_predicate (fun value => 5 | std.is_number value 6 | && std.number.is_integer value 7 | && value >= 10 8 | && value <= 47 9 | && value % 10 < 8) in 10 | 11 | let UsbString = std.contract.from_predicate (fun value => 12 | std.is_string value 13 | && std.string.length value <= MAX_USB_STRING_LENGTH 14 | ) in 15 | 16 | let McuFeature = fun gpios => { 17 | type | [| 'uart |], 18 | keys | Set String, 19 | pins | Set (ElementOf gpios), 20 | } in 21 | 22 | let Mcu = { 23 | gpios | Set GpioPin, 24 | features | { _ : McuFeature gpios } | default = {}, 25 | } in 26 | 27 | let MatrixCol = fun matrix => BoundedInt 0 (std.array.length matrix.cols) in 28 | let MatrixRow = fun matrix => BoundedInt 0 (std.array.length matrix.rows) in 29 | 30 | let UsbDev = { 31 | vendor_id | Uint16, 32 | product_id | Uint16, 33 | product_ver | Uint16, 34 | manufacturer | UsbString | default = "", 35 | product | UsbString | default = "", 36 | serial_number | UsbString | default = "", 37 | } in 38 | 39 | let Matrix = fun mcu => { 40 | cols | Array (ElementOf mcu.gpios) | default = [], 41 | rows | Array (ElementOf mcu.gpios) | default = [], 42 | } in 43 | 44 | let PhysicalKey = fun mcu matrix => { 45 | type | [| 'direct, 'matrix, 'peripheral |], 46 | data | match { 47 | 'direct => ElementOf mcu.gpios, 48 | 'matrix => { 49 | col | MatrixCol matrix, 50 | row | MatrixRow matrix, 51 | }, 52 | # Index validity check is performed in main.ncl 53 | 'peripheral => Uint8, 54 | } type 55 | } in 56 | 57 | let KeyboardPeripheralSide = { 58 | mcu | Mcu, 59 | matrix | Matrix mcu | default = {}, 60 | keys | Set (PhysicalKey mcu matrix), 61 | # TODO: Check that this is a UART feature 62 | split.channel | ElementOf mcu.features, 63 | } in 64 | 65 | let KeyboardCentralSide = { 66 | mcu | Mcu, 67 | matrix | Matrix mcu | default = {}, 68 | keys | Set (PhysicalKey mcu matrix), 69 | usb_dev | UsbDev, 70 | debounce_ms | Uint8 | default = DEFAULT_DEBOUNCE_MS, 71 | split | { 72 | # TODO: Check that this is a UART feature 73 | channel | ElementOf mcu.features, 74 | peripheral | KeyboardPeripheralSide, 75 | } | optional, 76 | } in 77 | 78 | { 79 | DirectPinKey = fun pin => { 80 | type = 'direct, 81 | data = pin 82 | }, 83 | MatrixKey = fun col_pin row_pin => { 84 | type = 'matrix, 85 | data.col = col_pin, 86 | data.row = row_pin, 87 | }, 88 | PeripheralSideKey = fun periph_key_idx => { 89 | type = 'peripheral, 90 | data = periph_key_idx, 91 | }, 92 | Keyboard = KeyboardCentralSide, 93 | } 94 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/util_functions.ncl: -------------------------------------------------------------------------------- 1 | let rec _number = { 2 | ceil = fun n => if std.number.fract n == 0 then n else std.number.floor (n + 1), 3 | } in 4 | 5 | let rec _array = { 6 | unique = fun arr => std.array.fold_left (fun acc e => 7 | if std.array.elem e acc then acc else acc @ [e] 8 | ) [] arr, 9 | 10 | enumerate = fun arr => std.array.fold_left (fun acc e => acc @ [{ 11 | index = std.array.length acc, 12 | value = e 13 | }] ) [] arr, 14 | 15 | index_of = fun e arr => 16 | let matches = std.array.filter (fun { index, value } => value == e) (enumerate arr) in 17 | (std.array.first matches).index, 18 | 19 | join = fun sep arr => std.array.fold_left (++) "" (std.array.intersperse sep arr), 20 | 21 | chunk = fun size arr => 22 | let arr_len = std.array.length arr in 23 | if arr_len > size then 24 | std.array.generate (fun i => 25 | let start = i * size in 26 | let end = std.number.min (start + size) arr_len in 27 | std.array.slice start end arr 28 | ) (_number.ceil (arr_len / size)) 29 | else 30 | [arr], 31 | 32 | at_or = fun i default_value arr => 33 | if i < std.array.length arr then 34 | std.array.at i arr 35 | else 36 | default_value, 37 | 38 | sort_num | Array Number -> Array Number = fun arr => 39 | arr |> std.array.sort (fun x y => 40 | if x < y then 41 | 'Lesser 42 | else if (x == y) then 43 | 'Equal 44 | else 45 | 'Greater), 46 | 47 | min | Array Number -> Number = fun arr => 48 | arr |> sort_num |> std.array.first, 49 | 50 | max | Array Number -> Number = fun arr => 51 | arr |> sort_num |> std.array.last, 52 | 53 | first_or = at_or 0, 54 | 55 | last_or = fun default_value arr => 56 | if std.array.length arr > 0 then 57 | std.array.last arr 58 | else 59 | default_value, 60 | 61 | to_string | Array std.string.Stringable -> String = fun arr => 62 | let contents = arr |> std.array.map std.to_string |> join ", " in 63 | "[%{contents}]", 64 | } in 65 | 66 | let Integer = std.number.Integer in 67 | let rec _bit = { 68 | shift | Integer -> Integer -> Integer = fun n shift => ( 69 | if shift >= 0 then 70 | n * (std.number.pow 2 shift) 71 | else 72 | std.number.truncate (n / (std.number.pow 2 (-shift))) 73 | ), 74 | } in 75 | 76 | let rec _record = { 77 | only_if | Bool -> Dyn -> Dyn = 78 | fun cond record => if cond then record else {}, 79 | 80 | at_or | Dyn -> String -> Dyn -> Dyn = 81 | fun record field default_value => 82 | if std.record.has_field field record then 83 | record."%{field}" 84 | else 85 | default_value, 86 | } in 87 | 88 | { 89 | number = _number, 90 | array = _array, 91 | bit = _bit, 92 | record = _record, 93 | } 94 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SK6812-MINI-E.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "SK6812-MINI-E" (version 20221018) (generator pcbnew) 2 | (layer "F.Cu") 3 | (attr smd) 4 | (fp_text reference "REF**" (at 0 2.1 unlocked) (layer "F.SilkS") 5 | (effects (font (size 0.7 0.7) (thickness 0.15))) 6 | (tstamp 41ad4736-f2de-40a4-80f6-8b4d812696d8) 7 | ) 8 | (fp_text value "SK6812-MINI-E" (at 0 -0.5 unlocked) (layer "F.SilkS") hide 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | (tstamp bcd18c4c-2a60-4c73-9a71-563606ec68f2) 11 | ) 12 | (fp_circle (center -2.54 1.397) (end -2.4892 1.4478) 13 | (stroke (width 0.1) (type default)) (fill none) (layer "F.SilkS") (tstamp e66dcd1e-74a6-4cc2-84e3-680df0588c64)) 14 | (fp_poly 15 | (pts 16 | (xy 2.8 -1.4) 17 | (xy 2.2 -1.4) 18 | (xy 2.2 -2) 19 | ) 20 | 21 | (stroke (width 0.1) (type solid)) (fill solid) (layer "F.SilkS") (tstamp ff3e3ce1-2541-4890-a2f0-3bfa07d5023b)) 22 | (fp_line (start -1.6 -1.4) (end 1.6 -1.4) 23 | (stroke (width 0.12) (type solid)) (layer "Cmts.User") (tstamp afabd9a3-ced4-40e5-b565-8e6962c63f2e)) 24 | (fp_line (start -1.6 1.4) (end -1.6 -1.4) 25 | (stroke (width 0.12) (type solid)) (layer "Cmts.User") (tstamp 2cf864c4-34ee-49ef-ba97-23b2fa3ac33f)) 26 | (fp_line (start 1.6 -1.4) (end 1.6 1.4) 27 | (stroke (width 0.12) (type solid)) (layer "Cmts.User") (tstamp 2e0199ee-3dd8-4679-8bce-29d215d4eab6)) 28 | (fp_line (start 1.6 1.4) (end -1.6 1.4) 29 | (stroke (width 0.12) (type solid)) (layer "Cmts.User") (tstamp 2fa635fe-6afb-4a5d-95b3-dc8dcd88b104)) 30 | (fp_line (start -1.7 -1.5) (end 1.7 -1.5) 31 | (stroke (width 0.12) (type solid)) (layer "Edge.Cuts") (tstamp 8b3d2cc0-95de-47a6-ae17-41bca078aa3a)) 32 | (fp_line (start -1.7 1.5) (end -1.7 -1.5) 33 | (stroke (width 0.12) (type solid)) (layer "Edge.Cuts") (tstamp 9a3a3bfa-6ee7-43cc-9618-95a0059688ea)) 34 | (fp_line (start 1.7 -1.5) (end 1.7 1.5) 35 | (stroke (width 0.12) (type solid)) (layer "Edge.Cuts") (tstamp 401c5423-2420-4b05-b0f7-af0d1951f944)) 36 | (fp_line (start 1.7 1.5) (end -1.7 1.5) 37 | (stroke (width 0.12) (type solid)) (layer "Edge.Cuts") (tstamp 281ce8f0-71aa-4a8f-9075-faacb2237f96)) 38 | (pad "1" smd rect (at -2.65 0.75) (size 1.5 0.82) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 1a11ec2d-17e2-4117-ab6e-a9fcec9d3b74)) 39 | (pad "2" smd rect (at -2.65 -0.75) (size 1.5 0.82) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 3fe8bc8d-2293-49ed-a1ae-5fb0cde11b3a)) 40 | (pad "3" smd roundrect (at 2.65 -0.75) (size 1.5 0.82) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.25) (tstamp ccbb8988-775f-4bdd-a684-5e7d31a50b82)) 41 | (pad "4" smd rect (at 2.65 0.75) (size 1.5 0.82) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 9c4b0429-2291-4757-8e52-71cb04ed2d06)) 42 | (model "${KIPRJMOD}/Keebio-Parts.pretty/3dmodels/SK6812MINI-E v1.step" 43 | (offset (xyz 0 0 0)) 44 | (scale (xyz 1 1 1)) 45 | (rotate (xyz 90 0 0)) 46 | ) 47 | ) 48 | -------------------------------------------------------------------------------- /components-and-pretty/MCU_RaspberryPi_RP2040.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.4 2 | #encoding utf-8 3 | # 4 | # RP2040 5 | # 6 | DEF RP2040 U 0 40 Y Y 1 F N 7 | F0 "U" -1150 1950 50 H V C CNN 8 | F1 "RP2040" 950 -1950 50 H V C CNN 9 | F2 "RP2040_minimal:RP2040-QFN-56" -750 0 50 H I C CNN 10 | F3 "" -750 0 50 H I C CNN 11 | DRAW 12 | T 0 0 200 100 0 0 0 "Raspberry Pi" Normal 0 C C 13 | T 0 0 0 100 0 0 0 RP2040 Normal 0 C C 14 | S 1150 1900 -1150 -1900 0 1 10 f 15 | X IOVDD 1 350 2000 100 D 50 50 1 1 W 16 | X IOVDD 10 250 2000 100 D 50 50 1 1 W 17 | X GPIO8 11 1250 500 100 L 50 50 1 1 B 18 | X GPIO9 12 1250 400 100 L 50 50 1 1 B 19 | X GPIO10 13 1250 300 100 L 50 50 1 1 B 20 | X GPIO11 14 1250 200 100 L 50 50 1 1 B 21 | X GPIO12 15 1250 100 100 L 50 50 1 1 B 22 | X GPIO13 16 1250 0 100 L 50 50 1 1 B 23 | X GPIO14 17 1250 -100 100 L 50 50 1 1 B 24 | X GPIO15 18 1250 -200 100 L 50 50 1 1 B 25 | X TESTEN 19 -500 -2000 100 U 50 50 1 1 P 26 | X GPIO0 2 1250 1300 100 L 50 50 1 1 B 27 | X XIN 20 -1250 -100 100 R 50 50 1 1 I 28 | X XOUT 21 -1250 -300 100 R 50 50 1 1 P 29 | X IOVDD 22 150 2000 100 D 50 50 1 1 W 30 | X DVDD 23 -700 2000 100 D 50 50 1 1 W 31 | X SWCLK 24 -1250 -1250 100 R 50 50 1 1 O 32 | X SWD 25 -1250 -1350 100 R 50 50 1 1 B 33 | X RUN 26 -1250 -800 100 R 50 50 1 1 I 34 | X GPIO16 27 1250 -300 100 L 50 50 1 1 B 35 | X GPIO17 28 1250 -400 100 L 50 50 1 1 B 36 | X GPIO18 29 1250 -500 100 L 50 50 1 1 B 37 | X GPIO1 3 1250 1200 100 L 50 50 1 1 B 38 | X GPIO19 30 1250 -600 100 L 50 50 1 1 B 39 | X GPIO20 31 1250 -700 100 L 50 50 1 1 B 40 | X GPIO21 32 1250 -800 100 L 50 50 1 1 B 41 | X IOVDD 33 50 2000 100 D 50 50 1 1 W 42 | X GPIO22 34 1250 -900 100 L 50 50 1 1 B 43 | X GPIO23 35 1250 -1000 100 L 50 50 1 1 B 44 | X GPIO24 36 1250 -1100 100 L 50 50 1 1 B 45 | X GPIO25 37 1250 -1200 100 L 50 50 1 1 B 46 | X GPIO26_ADC0 38 1250 -1400 100 L 50 50 1 1 B 47 | X GPIO27_ADC1 39 1250 -1500 100 L 50 50 1 1 B 48 | X GPIO2 4 1250 1100 100 L 50 50 1 1 B 49 | X GPIO28_ADC2 40 1250 -1600 100 L 50 50 1 1 B 50 | X GPIO29_ADC3 41 1250 -1700 100 L 50 50 1 1 B 51 | X IOVDD 42 -50 2000 100 D 50 50 1 1 W 52 | X ADC_AVDD 43 650 2000 100 D 50 50 1 1 W 53 | X VREG_IN 44 -350 2000 100 D 50 50 1 1 W 54 | X VREG_VOUT 45 -500 2000 100 D 50 50 1 1 w 55 | X USB_DM 46 1250 1600 100 L 50 50 1 1 B 56 | X USB_DP 47 1250 1700 100 L 50 50 1 1 B 57 | X USB_VDD 48 500 2000 100 D 50 50 1 1 W 58 | X IOVDD 49 -150 2000 100 D 50 50 1 1 W 59 | X GPIO3 5 1250 1000 100 L 50 50 1 1 B 60 | X DVDD 50 -800 2000 100 D 50 50 1 1 W 61 | X QSPI_SD3 51 -1250 800 100 R 50 50 1 1 B 62 | X QSPI_SCLK 52 -1250 650 100 R 50 50 1 1 O 63 | X QSPI_SD0 53 -1250 1100 100 R 50 50 1 1 B 64 | X QSPI_SD2 54 -1250 900 100 R 50 50 1 1 B 65 | X QSPI_SD1 55 -1250 1000 100 R 50 50 1 1 B 66 | X QSPI_SS 56 -1250 1250 100 R 50 50 1 1 B 67 | X GND 57 0 -2000 100 U 50 50 1 1 W 68 | X GPIO4 6 1250 900 100 L 50 50 1 1 B 69 | X GPIO5 7 1250 800 100 L 50 50 1 1 B 70 | X GPIO6 8 1250 700 100 L 50 50 1 1 B 71 | X GPIO7 9 1250 600 100 L 50 50 1 1 B 72 | ENDDRAW 73 | ENDDEF 74 | # 75 | #End Library 76 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/keymap.ncl: -------------------------------------------------------------------------------- 1 | let { tap, hold, td, combo, .. } = import "../ncl/fak/keycode.ncl" in 2 | let util = import "../ncl/fak/util_functions.ncl" in 3 | let kc = tap.reg.kc in 4 | let mo = hold.reg.layer in 5 | let md = hold.reg.mod in 6 | let ks = tap.reg.ks in 7 | let TRNS = tap.trans in 8 | 9 | let ki = { 10 | hp = { decision = 'hold, trigger_on = 'press }, 11 | tp = { decision = 'tap, trigger_on = 'press }, 12 | hr = { decision = 'hold, trigger_on = 'release }, 13 | tr = { decision = 'tap, trigger_on = 'release }, 14 | xx = { decision = 'none }, 15 | } in 16 | 17 | let zsftbehavior = { 18 | timeout_ms = 200, 19 | key_interrupts = [ 20 | ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, 21 | ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, 22 | ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, ki.hp, 23 | ki.hp, ki.hp, ki.hp, ki.hp, 24 | ], 25 | } in 26 | 27 | let shift = fun k => tap.reg.mod.lsft & k in 28 | let ctla = tap.reg.kc.A & tap.reg.mod.lctl in 29 | let zsft = tap.reg.kc.Z & hold.reg.mod.lsft & hold.reg.behavior zsftbehavior in 30 | let actl = tap.reg.kc.A & hold.reg.mod.lctl & hold.reg.behavior { } in 31 | let slsft = tap.reg.kc.SLASH & hold.reg.mod.lsft & hold.reg.behavior zsftbehavior in 32 | let cad = tap.reg.mod.lctl & tap.reg.mod.lalt & kc.DEL in 33 | { 34 | conditional_layers = { 35 | "3" = [1, 2], 36 | }, 37 | layers = [ 38 | [ # Layer 0 39 | kc.Q, kc.W, kc.F, kc.P, kc.G, kc.J, kc.L, kc.U, kc.Y, kc.QUOTE, 40 | actl, kc.R, kc.S, kc.T, kc.D, kc.H, kc.N, kc.E, kc.I, kc.O, 41 | zsft, kc.X, kc.C, kc.V, kc.B, kc.K, kc.M, kc.COMMA, kc.DOT, slsft, 42 | mo 1, kc.SPACE, kc.BACKSPACE, mo 2, 43 | ], 44 | [ # Layer 1 45 | kc.N1, kc.N2, kc.N3, kc.N4, kc.N5, kc.N6, kc.N7, kc.N8, kc.N9, kc.N0, 46 | kc.TAB, kc.LEFT, kc.DOWN, kc.UP, kc.RIGHT, TRNS, kc.MINS, kc.EQL, kc.LBRC, kc.RBRC, 47 | md.lctl, kc.GRV, md.lgui, md.lalt, TRNS, TRNS, TRNS, TRNS, kc.BACKSLASH, kc.SEMICOLON, 48 | mo 1, kc.SPACE, kc.ENTER, mo 2, 49 | ], 50 | [ # Layer 2 51 | ks.EXLM, shift kc.N2, shift kc.N3, shift kc.N4, shift kc.N5, shift kc.N6, shift kc.N7, shift kc.N8, shift kc.N9, shift kc.N0, 52 | kc.ESC, kc.DEL, ctla, TRNS, TRNS, TRNS, shift kc.MINS, shift kc.EQL, shift kc.LBRC, shift kc.RBRC, 53 | kc.CAPS, shift kc.GRV, kc.PGDN, kc.PGUP, TRNS, TRNS, TRNS, TRNS, shift kc.BACKSLASH, shift kc.SEMICOLON, 54 | mo 1, kc.SPACE, kc.ENTER, mo 2, 55 | ], 56 | [ # Layer 3 57 | kc.F1, kc. F2, kc.F3, kc.F4, kc.F5, kc.F6, kc.F7, kc.F8, kc.F9, kc.F10, 58 | kc.F11, kc.F12, TRNS, TRNS, TRNS, TRNS, TRNS, cad, TRNS, TRNS, 59 | TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, 60 | mo 1, tap.custom.fak.BOOT, kc.BACKSPACE, mo 2, 61 | ], 62 | ] 63 | } -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SOT-23_Handsoldering_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module SOT-23_Handsoldering_Reversible (layer F.Cu) (tedit 61B5F6C5) 2 | (descr "6-pin SOT-23 package, Handsoldering") 3 | (tags "SOT-23-6 Handsoldering") 4 | (attr smd) 5 | (fp_text reference REF** (at 0 -2.9) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value SOT-23_Handsoldering_Reversible (at 0 2.9) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start -0.9 0.9) (end -0.25 1.55) (layer B.Fab) (width 0.1)) 12 | (fp_line (start 0.9 1.55) (end -0.25 1.55) (layer B.Fab) (width 0.1)) 13 | (fp_line (start 0.9 -1.55) (end -0.9 -1.55) (layer B.Fab) (width 0.1)) 14 | (fp_line (start 0.9 1.55) (end 0.9 -1.55) (layer B.Fab) (width 0.1)) 15 | (fp_line (start -2.4 1.8) (end 2.4 1.8) (layer B.CrtYd) (width 0.05)) 16 | (fp_line (start 0.9 1.61) (end -2.05 1.61) (layer B.SilkS) (width 0.12)) 17 | (fp_line (start -0.9 0.9) (end -0.9 -1.55) (layer B.Fab) (width 0.1)) 18 | (fp_line (start 2.4 1.8) (end 2.4 -1.8) (layer B.CrtYd) (width 0.05)) 19 | (fp_line (start 2.4 -1.8) (end -2.4 -1.8) (layer B.CrtYd) (width 0.05)) 20 | (fp_line (start -2.4 -1.8) (end -2.4 1.8) (layer B.CrtYd) (width 0.05)) 21 | (fp_line (start -0.9 -1.61) (end 0.9 -1.61) (layer B.SilkS) (width 0.12)) 22 | (fp_line (start 0.9 -1.55) (end 0.9 1.55) (layer F.Fab) (width 0.1)) 23 | (fp_line (start 0.9 1.55) (end -0.9 1.55) (layer F.Fab) (width 0.1)) 24 | (fp_line (start -0.9 -0.9) (end -0.9 1.55) (layer F.Fab) (width 0.1)) 25 | (fp_line (start 0.9 -1.55) (end -0.25 -1.55) (layer F.Fab) (width 0.1)) 26 | (fp_line (start -0.9 -0.9) (end -0.25 -1.55) (layer F.Fab) (width 0.1)) 27 | (fp_line (start -2.4 -1.8) (end 2.4 -1.8) (layer F.CrtYd) (width 0.05)) 28 | (fp_line (start 2.4 -1.8) (end 2.4 1.8) (layer F.CrtYd) (width 0.05)) 29 | (fp_line (start 2.4 1.8) (end -2.4 1.8) (layer F.CrtYd) (width 0.05)) 30 | (fp_line (start -2.4 1.8) (end -2.4 -1.8) (layer F.CrtYd) (width 0.05)) 31 | (fp_line (start 0.9 -1.61) (end -2.05 -1.61) (layer F.SilkS) (width 0.12)) 32 | (fp_line (start -0.9 1.61) (end 0.9 1.61) (layer F.SilkS) (width 0.12)) 33 | (fp_text user %R (at 0 0 90) (layer F.Fab) 34 | (effects (font (size 0.5 0.5) (thickness 0.075))) 35 | ) 36 | (fp_text user %R (at 0 0 270) (layer B.Fab) 37 | (effects (font (size 0.5 0.5) (thickness 0.075)) (justify mirror)) 38 | ) 39 | (fp_text user %R (at 0.127 -2.921) (layer B.SilkS) 40 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 41 | ) 42 | (pad 1 smd rect (at -1.35 -0.95) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 43 | (pad 2 smd rect (at -1.35 0.95) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 44 | (pad 3 smd rect (at 1.35 0) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 45 | (pad 3 smd rect (at 1.35 0) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 46 | (pad 1 smd rect (at -1.35 0.95) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 47 | (pad 2 smd rect (at -1.35 -0.95) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 48 | (model ${KISYS3DMOD}/Package_TO_SOT_SMD.3dshapes/SOT-23.wrl 49 | (at (xyz 0 0 0)) 50 | (scale (xyz 1 1 1)) 51 | (rotate (xyz 0 0 0)) 52 | ) 53 | ) 54 | -------------------------------------------------------------------------------- /ch55p34/fp-info-cache: -------------------------------------------------------------------------------- 1 | 33639141008405 2 | keyswitches 3 | Kailh_socket_MX 4 | MX-style keyswitch with Kailh socket mount 5 | MX,cherry,gateron,kailh,pg1511,socket 6 | 0 7 | 2 8 | 2 9 | keyswitches 10 | Kailh_socket_MX_4fab 11 | MX-style keyswitch with Kailh socket mount 12 | MX,cherry,gateron,kailh,pg1511,socket 13 | 0 14 | 2 15 | 2 16 | keyswitches 17 | Kailh_socket_MX_optional 18 | MX-style keyswitch with support for optional Kailh socket 19 | MX,cherry,gateron,kailh,pg1511,socket 20 | 0 21 | 4 22 | 2 23 | keyswitches 24 | Kailh_socket_MX_optional_platemount 25 | MX-style keyswitch with support for optional Kailh socket 26 | MX,cherry,gateron,kailh,pg1511,socket 27 | 0 28 | 4 29 | 2 30 | keyswitches 31 | Kailh_socket_MX_optional_reversible 32 | MX-style keyswitch with support for reversible optional Kailh socket 33 | MX,cherry,gateron,kailh,pg1511,socket 34 | 0 35 | 8 36 | 2 37 | keyswitches 38 | Kailh_socket_MX_optional_reversible_platemount 39 | MX-style keyswitch with support for reversible optional Kailh socket 40 | MX,cherry,gateron,kailh,pg1511,socket 41 | 0 42 | 8 43 | 2 44 | keyswitches 45 | Kailh_socket_MX_platemount 46 | MX-style keyswitch with Kailh socket mount 47 | MX,cherry,gateron,kailh,pg1511,socket 48 | 0 49 | 2 50 | 2 51 | keyswitches 52 | Kailh_socket_MX_reversible 53 | MX-style keyswitch with reversible Kailh socket mount 54 | MX,cherry,gateron,kailh,pg1511,socket 55 | 0 56 | 4 57 | 2 58 | keyswitches 59 | Kailh_socket_MX_reversible_platemount 60 | MX-style keyswitch with reversible Kailh socket mount 61 | MX,cherry,gateron,kailh,pg1511,socket 62 | 0 63 | 4 64 | 2 65 | keyswitches 66 | Kailh_socket_PG1350 67 | Kailh "Choc" PG1350 keyswitch socket mount 68 | kailh,choc 69 | 0 70 | 2 71 | 2 72 | keyswitches 73 | Kailh_socket_PG1350_optional 74 | Kailh "Choc" PG1350 keyswitch with optional socket mount 75 | kailh,choc 76 | 0 77 | 4 78 | 2 79 | keyswitches 80 | Kailh_socket_PG1350_optional_reversible 81 | Kailh "Choc" PG1350 keyswitch with optional socket mount, reversible 82 | kailh,choc 83 | 0 84 | 7 85 | 2 86 | keyswitches 87 | Kailh_socket_PG1350_reversible 88 | Kailh "Choc" PG1350 keyswitch reversible socket mount 89 | kailh,choc 90 | 0 91 | 4 92 | 2 93 | keyswitches 94 | SW_MX 95 | MX-style keyswitch 96 | MX,cherry,gateron,kailh 97 | 0 98 | 2 99 | 2 100 | keyswitches 101 | SW_MX_reversible 102 | MX-style keyswitch, reversible 103 | MX,cherry,gateron,kailh 104 | 0 105 | 4 106 | 2 107 | keyswitches 108 | SW_MX_reversible_minimal 109 | MX-style keyswitch, reversible, without pcb-mount holes 110 | MX,cherry,gateron,kailh 111 | 0 112 | 4 113 | 2 114 | keyswitches 115 | SW_PG1350 116 | Kailh "Choc" PG1350 keyswitch 117 | kailh,choc 118 | 0 119 | 2 120 | 2 121 | keyswitches 122 | SW_PG1350_reversible 123 | Kailh "Choc" PG1350 keyswitch, able to be mounted on front or back of PCB 124 | kailh,choc 125 | 0 126 | 3 127 | 2 128 | keyswitches 129 | SW_PG1350_reversible_rotatable 130 | Kailh "Choc" PG1350 keyswitch, able to be mounted on front or back of PCB and/or rotated 90 degrees (see README) 131 | kailh,choc 132 | 0 133 | 6 134 | 2 135 | keyswitches 136 | Stabilizer_MX_2u 137 | MX-style stabilizer mount 138 | MX,cherry,gateron,kailh,pg1511,stabilizer,stab 139 | 0 140 | 0 141 | 0 142 | -------------------------------------------------------------------------------- /gerber/ch55p34-job.gbrjob: -------------------------------------------------------------------------------- 1 | { 2 | "Header": { 3 | "GenerationSoftware": { 4 | "Vendor": "KiCad", 5 | "Application": "Pcbnew", 6 | "Version": "7.0.1" 7 | }, 8 | "CreationDate": "2024-01-05T17:15:02-05:00" 9 | }, 10 | "GeneralSpecs": { 11 | "ProjectId": { 12 | "Name": "ch55p34", 13 | "GUID": "63683535-7033-4342-9e6b-696361645f70", 14 | "Revision": "rev?" 15 | }, 16 | "Size": { 17 | "X": 230.71, 18 | "Y": 109.59 19 | }, 20 | "LayerNumber": 2, 21 | "BoardThickness": 1.6, 22 | "Finish": "None" 23 | }, 24 | "DesignRules": [ 25 | { 26 | "Layers": "Outer", 27 | "PadToPad": 0.2, 28 | "PadToTrack": 0.2, 29 | "TrackToTrack": 0.2, 30 | "MinLineWidth": 0.2, 31 | "TrackToRegion": 0.5, 32 | "RegionToRegion": 0.5 33 | } 34 | ], 35 | "FilesAttributes": [ 36 | { 37 | "Path": "ch55p34-F_Cu.gbr", 38 | "FileFunction": "Copper,L1,Top", 39 | "FilePolarity": "Positive" 40 | }, 41 | { 42 | "Path": "ch55p34-B_Cu.gbr", 43 | "FileFunction": "Copper,L2,Bot", 44 | "FilePolarity": "Positive" 45 | }, 46 | { 47 | "Path": "ch55p34-F_Paste.gbr", 48 | "FileFunction": "SolderPaste,Top", 49 | "FilePolarity": "Positive" 50 | }, 51 | { 52 | "Path": "ch55p34-B_Paste.gbr", 53 | "FileFunction": "SolderPaste,Bot", 54 | "FilePolarity": "Positive" 55 | }, 56 | { 57 | "Path": "ch55p34-F_Silkscreen.gbr", 58 | "FileFunction": "Legend,Top", 59 | "FilePolarity": "Positive" 60 | }, 61 | { 62 | "Path": "ch55p34-B_Silkscreen.gbr", 63 | "FileFunction": "Legend,Bot", 64 | "FilePolarity": "Positive" 65 | }, 66 | { 67 | "Path": "ch55p34-F_Mask.gbr", 68 | "FileFunction": "SolderMask,Top", 69 | "FilePolarity": "Negative" 70 | }, 71 | { 72 | "Path": "ch55p34-B_Mask.gbr", 73 | "FileFunction": "SolderMask,Bot", 74 | "FilePolarity": "Negative" 75 | }, 76 | { 77 | "Path": "ch55p34-Edge_Cuts.gbr", 78 | "FileFunction": "Profile", 79 | "FilePolarity": "Positive" 80 | } 81 | ], 82 | "MaterialStackup": [ 83 | { 84 | "Type": "Legend", 85 | "Name": "Top Silk Screen" 86 | }, 87 | { 88 | "Type": "SolderPaste", 89 | "Name": "Top Solder Paste" 90 | }, 91 | { 92 | "Type": "SolderMask", 93 | "Thickness": 0.01, 94 | "Name": "Top Solder Mask" 95 | }, 96 | { 97 | "Type": "Copper", 98 | "Thickness": 0.035, 99 | "Name": "F.Cu" 100 | }, 101 | { 102 | "Type": "Dielectric", 103 | "Thickness": 1.51, 104 | "Material": "FR4", 105 | "Name": "F.Cu/B.Cu", 106 | "Notes": "Type: dielectric layer 1 (from F.Cu to B.Cu)" 107 | }, 108 | { 109 | "Type": "Copper", 110 | "Thickness": 0.035, 111 | "Name": "B.Cu" 112 | }, 113 | { 114 | "Type": "SolderMask", 115 | "Thickness": 0.01, 116 | "Name": "Bottom Solder Mask" 117 | }, 118 | { 119 | "Type": "SolderPaste", 120 | "Name": "Bottom Solder Paste" 121 | }, 122 | { 123 | "Type": "Legend", 124 | "Name": "Bottom Silk Screen" 125 | } 126 | ] 127 | } 128 | -------------------------------------------------------------------------------- /gerber/ch55p34-PTH.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad 7.0.1} date Fri Jan 5 17:15:05 2024 3 | ; FORMAT={-:-/ absolute / metric / decimal} 4 | ; #@! TF.CreationDate,2024-01-05T17:15:05-05:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,7.0.1 6 | ; #@! TF.FileFunction,Plated,1,2,PTH 7 | FMAT,2 8 | METRIC 9 | ; #@! TA.AperFunction,Plated,PTH,ViaDrill 10 | T1C0.400 11 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 12 | T2C0.600 13 | ; #@! TA.AperFunction,Plated,PTH,ComponentDrill 14 | T3C1.000 15 | % 16 | G90 17 | G05 18 | T1 19 | X62.02Y-76.65 20 | X68.11Y-57.65 21 | X72.21Y-39.13 22 | X84.0Y-66.08 23 | X88.85Y-50.78 24 | X91.27Y-39.2 25 | X92.82Y-33.25 26 | X93.67Y-38.89 27 | X97.576Y-40.44 28 | X97.76Y-38.74 29 | X103.07Y-69.29 30 | X109.58Y-50.55 31 | X110.75Y-45.75 32 | X110.78Y-43.73 33 | X111.87Y-109.65 34 | X112.79Y-33.51 35 | X112.79Y-49.652 36 | X112.8Y-46.73 37 | X112.96Y-44.98 38 | X121.39Y-79.49 39 | X126.28Y-61.16 40 | X127.52Y-54.33 41 | X127.57Y-52.92 42 | X128.68Y-43.97 43 | X129.13Y-54.91 44 | X129.16Y-53.69 45 | X129.38Y-47.77 46 | X129.66Y-52.44 47 | X131.83Y-116.87 48 | X133.415Y-61.583 49 | X137.48Y-86.74 50 | X141.05Y-84.29 51 | X141.21Y-61.91 52 | X141.21Y-71.8 53 | X142.03Y-100.59 54 | X143.14Y-66.66 55 | X143.15Y-97.45 56 | X143.16Y-87.52 57 | X144.42Y-77.08 58 | X144.46Y-102.35 59 | X144.52Y-83.358 60 | X144.56Y-70.45 61 | X145.48Y-62.929 62 | X145.53Y-52.41 63 | X145.94Y-64.38 64 | X146.6Y-62.929 65 | X146.75Y-82.957 66 | X146.97Y-69.95 67 | X147.16Y-95.83 68 | X148.13Y-66.269 69 | X149.31Y-82.85 70 | X149.352Y-70.978 71 | X149.5Y-95.37 72 | X149.62Y-66.918 73 | X150.32Y-64.87 74 | X150.663Y-63.918 75 | X151.804Y-45.974 76 | X151.94Y-70.92 77 | X152.07Y-105.472 78 | X152.15Y-83.17 79 | X152.17Y-95.59 80 | X152.654Y-52.226 81 | X152.654Y-56.388 82 | X153.504Y-47.752 83 | X154.433Y-51.799 84 | X154.5Y-60.63 85 | X154.55Y-83.0 86 | X154.59Y-105.79 87 | X154.66Y-96.05 88 | X154.74Y-70.91 89 | X155.111Y-49.022 90 | X156.303Y-51.816 91 | X156.809Y-63.094 92 | X157.153Y-54.61 93 | X157.44Y-105.79 94 | X157.48Y-83.07 95 | X157.546Y-64.044 96 | X157.94Y-94.61 97 | X158.662Y-45.974 98 | X158.662Y-48.768 99 | X158.705Y-56.985 100 | X159.7Y-95.4 101 | X160.03Y-83.03 102 | X160.362Y-45.974 103 | X160.69Y-70.9 104 | X161.35Y-104.27 105 | X162.12Y-95.695 106 | X162.18Y-82.98 107 | X163.71Y-70.59 108 | X164.33Y-96.203 109 | X164.97Y-83.358 110 | X165.32Y-70.492 111 | X165.5Y-69.093 112 | X168.251Y-70.171 113 | X170.08Y-84.32 114 | X170.92Y-97.25 115 | X179.8Y-57.15 116 | X179.87Y-58.74 117 | X180.67Y-47.14 118 | X180.806Y-59.275 119 | X183.35Y-58.19 120 | X183.395Y-56.197 121 | X183.445Y-57.195 122 | X185.6Y-63.08 123 | X188.89Y-80.98 124 | X191.92Y-93.84 125 | X193.63Y-110.3 126 | X197.64Y-49.67 127 | X197.69Y-50.74 128 | X198.39Y-40.59 129 | X199.28Y-48.92 130 | X199.477Y-49.98 131 | X203.24Y-56.46 132 | X206.37Y-72.42 133 | X214.433Y-40.043 134 | X215.35Y-30.33 135 | X215.5Y-104.78 136 | X216.049Y-38.427 137 | X220.44Y-49.28 138 | X222.58Y-62.23 139 | X237.06Y-40.51 140 | X240.23Y-50.6 141 | X242.94Y-63.69 142 | X252.46Y-33.29 143 | T3 144 | X145.029Y-43.942 145 | X147.569Y-43.942 146 | X164.851Y-44.196 147 | X167.391Y-44.196 148 | T2 149 | X151.634Y-36.76G85X151.634Y-36.16 150 | G05 151 | X151.634Y-41.19G85X151.634Y-40.09 152 | G05 153 | X160.274Y-36.76G85X160.274Y-36.16 154 | G05 155 | X160.274Y-41.19G85X160.274Y-40.09 156 | G05 157 | T0 158 | M30 159 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SOT-23-6_Handsoldering_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module SOT-23-6_Handsoldering_Reversible (layer F.Cu) (tedit 603EF1F4) 2 | (descr "6-pin SOT-23 package, Handsoldering") 3 | (tags "SOT-23-6 Handsoldering") 4 | (attr smd) 5 | (fp_text reference REF** (at 0 -2.9) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value SOT-23-6_Handsoldering_Reversible (at 0 2.9) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start -0.9 1.61) (end 0.9 1.61) (layer F.SilkS) (width 0.12)) 12 | (fp_line (start 0.9 -1.61) (end -2.05 -1.61) (layer F.SilkS) (width 0.12)) 13 | (fp_line (start -2.4 1.8) (end -2.4 -1.8) (layer F.CrtYd) (width 0.05)) 14 | (fp_line (start 2.4 1.8) (end -2.4 1.8) (layer F.CrtYd) (width 0.05)) 15 | (fp_line (start 2.4 -1.8) (end 2.4 1.8) (layer F.CrtYd) (width 0.05)) 16 | (fp_line (start -2.4 -1.8) (end 2.4 -1.8) (layer F.CrtYd) (width 0.05)) 17 | (fp_line (start -0.9 -0.9) (end -0.25 -1.55) (layer F.Fab) (width 0.1)) 18 | (fp_line (start 0.9 -1.55) (end -0.25 -1.55) (layer F.Fab) (width 0.1)) 19 | (fp_line (start -0.9 -0.9) (end -0.9 1.55) (layer F.Fab) (width 0.1)) 20 | (fp_line (start 0.9 1.55) (end -0.9 1.55) (layer F.Fab) (width 0.1)) 21 | (fp_line (start 0.9 -1.55) (end 0.9 1.55) (layer F.Fab) (width 0.1)) 22 | (fp_text user %R (at 0 0 90) (layer F.Fab) 23 | (effects (font (size 0.5 0.5) (thickness 0.075))) 24 | ) 25 | (fp_text user %R (at 0 0 270) (layer B.Fab) 26 | (effects (font (size 0.5 0.5) (thickness 0.075)) (justify mirror)) 27 | ) 28 | (fp_line (start -0.9 -1.61) (end 0.9 -1.61) (layer B.SilkS) (width 0.12)) 29 | (fp_line (start -2.4 -1.8) (end -2.4 1.8) (layer B.CrtYd) (width 0.05)) 30 | (fp_line (start 2.4 -1.8) (end -2.4 -1.8) (layer B.CrtYd) (width 0.05)) 31 | (fp_line (start 2.4 1.8) (end 2.4 -1.8) (layer B.CrtYd) (width 0.05)) 32 | (fp_line (start -0.9 0.9) (end -0.9 -1.55) (layer B.Fab) (width 0.1)) 33 | (fp_line (start 0.9 1.61) (end -2.05 1.61) (layer B.SilkS) (width 0.12)) 34 | (fp_line (start -2.4 1.8) (end 2.4 1.8) (layer B.CrtYd) (width 0.05)) 35 | (fp_line (start 0.9 1.55) (end 0.9 -1.55) (layer B.Fab) (width 0.1)) 36 | (fp_line (start 0.9 -1.55) (end -0.9 -1.55) (layer B.Fab) (width 0.1)) 37 | (fp_line (start 0.9 1.55) (end -0.25 1.55) (layer B.Fab) (width 0.1)) 38 | (fp_line (start -0.9 0.9) (end -0.25 1.55) (layer B.Fab) (width 0.1)) 39 | (fp_text user %R (at 0.127 -2.921) (layer B.SilkS) 40 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 41 | ) 42 | (pad 1 smd rect (at -1.35 -0.95) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 43 | (pad 2 smd rect (at -1.35 0) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 44 | (pad 3 smd rect (at -1.35 0.95) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 45 | (pad 4 smd rect (at 1.35 0.95) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 46 | (pad 6 smd rect (at 1.35 -0.95) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 47 | (pad 5 smd rect (at 1.35 0) (size 1.56 0.65) (layers F.Cu F.Paste F.Mask)) 48 | (pad 4 smd rect (at 1.35 -0.95) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 49 | (pad 5 smd rect (at 1.35 0) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 50 | (pad 6 smd rect (at 1.35 0.95) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 51 | (pad 2 smd rect (at -1.35 0) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 52 | (pad 1 smd rect (at -1.35 0.95) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 53 | (pad 3 smd rect (at -1.35 -0.95) (size 1.56 0.65) (layers B.Cu B.Paste B.Mask)) 54 | (model ${KISYS3DMOD}/Package_TO_SOT_SMD.3dshapes/SOT-23-6.wrl 55 | (at (xyz 0 0 0)) 56 | (scale (xyz 1 1 1)) 57 | (rotate (xyz 0 0 0)) 58 | ) 59 | ) 60 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SW_MX_PG1350_NoLed.kicad_mod: -------------------------------------------------------------------------------- 1 | (module SW_MX_PG1350_NoLed (layer F.Cu) (tedit 61B5F70A) 2 | (descr "Kailh \"Choc\" PG1350 keyswitch, able to be mounted on front or back of PCB") 3 | (tags kailh,choc) 4 | (fp_text reference REF** (at 0 -7.62) (layer F.SilkS) 5 | (effects (font (size 1 1) (thickness 0.15))) 6 | ) 7 | (fp_text value SW_MX_PG1350_NoLed (at 0 8.255) (layer F.Fab) 8 | (effects (font (size 1 1) (thickness 0.15))) 9 | ) 10 | (fp_line (start 6 -7) (end 7 -7) (layer F.SilkS) (width 0.15)) 11 | (fp_line (start 7 -7) (end 7 -6) (layer F.SilkS) (width 0.15)) 12 | (fp_line (start 7 6) (end 7 7) (layer F.SilkS) (width 0.15)) 13 | (fp_line (start 7 7) (end 6 7) (layer F.SilkS) (width 0.15)) 14 | (fp_line (start -6 7) (end -7 7) (layer F.SilkS) (width 0.15)) 15 | (fp_line (start -7 7) (end -7 6) (layer F.SilkS) (width 0.15)) 16 | (fp_line (start -7 -6) (end -7 -7) (layer F.SilkS) (width 0.15)) 17 | (fp_line (start -7 -7) (end -6 -7) (layer F.SilkS) (width 0.15)) 18 | (fp_line (start -6.9 6.9) (end 6.9 6.9) (layer Eco2.User) (width 0.15)) 19 | (fp_line (start 6.9 -6.9) (end -6.9 -6.9) (layer Eco2.User) (width 0.15)) 20 | (fp_line (start 6.9 -6.9) (end 6.9 6.9) (layer Eco2.User) (width 0.15)) 21 | (fp_line (start -6.9 6.9) (end -6.9 -6.9) (layer Eco2.User) (width 0.15)) 22 | (fp_line (start -7.5 -7.5) (end 7.5 -7.5) (layer B.Fab) (width 0.15)) 23 | (fp_line (start 7.5 -7.5) (end 7.5 7.5) (layer B.Fab) (width 0.15)) 24 | (fp_line (start 7.5 7.5) (end -7.5 7.5) (layer B.Fab) (width 0.15)) 25 | (fp_line (start -7.5 7.5) (end -7.5 -7.5) (layer B.Fab) (width 0.15)) 26 | (fp_line (start -7.5 -7.5) (end 7.5 -7.5) (layer F.Fab) (width 0.15)) 27 | (fp_line (start 7.5 7.5) (end -7.5 7.5) (layer F.Fab) (width 0.15)) 28 | (fp_line (start 7.5 -7.5) (end 7.5 7.5) (layer F.Fab) (width 0.15)) 29 | (fp_line (start -7.5 7.5) (end -7.5 -7.5) (layer F.Fab) (width 0.15)) 30 | (fp_text user %R (at -0.127 0 180) (layer B.Fab) 31 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 32 | ) 33 | (fp_text user %R (at -0.127 0 180) (layer F.Fab) 34 | (effects (font (size 1 1) (thickness 0.15))) 35 | ) 36 | (fp_text user %R (at 0 0) (layer B.Fab) 37 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 38 | ) 39 | (fp_text user %R (at 0 0) (layer F.Fab) 40 | (effects (font (size 1 1) (thickness 0.15))) 41 | ) 42 | (fp_text user %V (at 0 8.255) (layer B.Fab) 43 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 44 | ) 45 | (fp_text user %R (at 0 -7.62) (layer B.SilkS) 46 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 47 | ) 48 | (pad 2 thru_hole circle (at -2.54 5.08 180) (size 2.286 2.286) (drill 1.5) (layers *.Cu *.Mask)) 49 | (pad "" np_thru_hole circle (at -5.08 0 180) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask)) 50 | (pad "" np_thru_hole circle (at 0 0 180) (size 3.9878 3.9878) (drill 3.9878) (layers *.Cu *.Mask)) 51 | (pad 1 thru_hole circle (at 3.81 2.54 225) (size 2.54 2.54) (drill 1.5) (layers *.Cu *.Mask)) 52 | (pad "" np_thru_hole circle (at 5.08 0 180) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask)) 53 | (pad "" np_thru_hole circle (at -5.5 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask)) 54 | (pad "" np_thru_hole circle (at 5.5 0) (size 1.7018 1.7018) (drill 1.7018) (layers *.Cu *.Mask)) 55 | (pad 1 thru_hole circle (at 0 5.9) (size 2.032 2.032) (drill 1.27) (layers *.Cu *.Mask)) 56 | (pad 2 thru_hole circle (at -5.1 3.9 315) (size 2.2 2.2) (drill 1.2) (layers *.Cu *.Mask)) 57 | (model ${KIPRJMOD}/Switch_Keyboard/packages3d/Switch_Keyboard_Kailh.3dshapes/SW_Kailh_Choc_V1.wrl 58 | (at (xyz 0 0 0)) 59 | (scale (xyz 1 1 1)) 60 | (rotate (xyz 0 0 180)) 61 | ) 62 | ) 63 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/hid_codes.ncl: -------------------------------------------------------------------------------- 1 | [ 2 | [], # 0x00 3 | [], 4 | [], 5 | [], 6 | ["A"], # 0x04 7 | ["B", "BUTTER_DOG"], 8 | ["C"], 9 | ["D", "DEEZ"], 10 | ["E"], 11 | ["F"], 12 | ["G"], 13 | ["H"], 14 | ["I"], 15 | ["J"], 16 | ["K"], 17 | ["L"], 18 | ["M"], 19 | ["N"], 20 | ["O"], 21 | ["P"], 22 | ["Q"], 23 | ["R"], 24 | ["S"], 25 | ["T"], 26 | ["U"], 27 | ["V"], 28 | ["W"], 29 | ["X"], 30 | ["Y"], 31 | ["Z"], 32 | ["N1", "1"], 33 | ["N2", "2"], 34 | ["N3", "3"], 35 | ["N4", "4"], 36 | ["N5", "5"], 37 | ["N6", "6"], 38 | ["N7", "7"], 39 | ["N8", "8"], 40 | ["N9", "9"], 41 | ["N0", "0"], 42 | ["ENTER", "ENT", "\n"], 43 | ["ESCAPE", "ESC"], 44 | ["BACKSPACE", "BSPC"], 45 | ["TAB", "\t"], 46 | ["SPACE", "SPC", " "], 47 | ["MINUS", "MINS", "-"], 48 | ["EQUAL", "EQL", "="], 49 | ["LEFT_BRACKET", "LBRC", "["], 50 | ["RIGHT_BRACKET", "RBRC", "]"], 51 | ["BACKSLASH", "BSLS", "\\"], 52 | ["NONUS_HASH", "NUHS", "#"], 53 | ["SEMICOLON", "SCLN", ";"], 54 | ["QUOTE", "QUOT", "'"], 55 | ["GRAVE", "GRV", "`"], 56 | ["COMMA", "COMM", ","], 57 | ["DOT", "."], 58 | ["SLASH", "SLSH", "/"], 59 | ["CAPS_LOCK", "CAPS"], 60 | ["F1"], 61 | ["F2"], 62 | ["F3"], 63 | ["F4"], 64 | ["F5"], 65 | ["F6"], 66 | ["F7"], 67 | ["F8"], 68 | ["F9"], 69 | ["F10"], 70 | ["F11"], 71 | ["F12"], 72 | ["PRINT_SCREEN", "PSCR"], 73 | ["SCROLL_LOCK", "SCRL", "BRMD"], 74 | ["PAUSE", "PAUS", "BRK", "BRMU"], 75 | ["INSERT", "INS"], 76 | ["HOME"], 77 | ["PAGE_UP", "PGUP"], 78 | ["DELETE", "DEL"], 79 | ["END"], 80 | ["PAGE_DOWN", "PGDN"], 81 | ["RIGHT", "RGHT"], 82 | ["LEFT"], 83 | ["DOWN"], 84 | ["UP"], 85 | ["NUM_LOCK", "NUM"], 86 | ["KP_SLASH", "PSLS"], 87 | ["KP_ASTERISK", "PAST"], 88 | ["KP_MINUS", "PMNS"], 89 | ["KP_PLUS", "PPLS"], 90 | ["KP_ENTER", "PENT"], 91 | ["KP_1", "P1"], 92 | ["KP_2", "P2"], 93 | ["KP_3", "P3"], 94 | ["KP_4", "P4"], 95 | ["KP_5", "P5"], 96 | ["KP_6", "P6"], 97 | ["KP_7", "P7"], 98 | ["KP_8", "P8"], 99 | ["KP_9", "P9"], 100 | ["KP_0", "P0"], 101 | ["KP_DOT", "PDOT"], 102 | ["NONUS_BACKSLASH", "NUBS"], 103 | ["APPLICATION", "APP"], 104 | ["KB_POWER"], 105 | ["KP_EQUAL", "PEQL"], 106 | ["F13"], 107 | ["F14"], 108 | ["F15"], 109 | ["F16"], 110 | ["F17"], 111 | ["F18"], 112 | ["F19"], 113 | ["F20"], 114 | ["F21"], 115 | ["F22"], 116 | ["F23"], 117 | ["F24"], 118 | ["EXECUTE", "EXEC"], 119 | ["HELP"], 120 | ["MENU"], 121 | ["SELECT", "SLCT"], 122 | ["STOP"], 123 | ["AGAIN", "AGIN"], 124 | ["UNDO"], 125 | ["CUT"], 126 | ["COPY"], 127 | ["PASTE"], 128 | ["FIND"], 129 | ["KB_MUTE"], 130 | ["KB_VOLUME_UP"], 131 | ["KB_VOLUME_DOWN"], 132 | ["LOCKING_CAPS_LOCK", "LCAP"], 133 | ["LOCKING_NUM_LOCK", "LNUM"], 134 | ["LOCKING_SCROLL_LOCK", "LSCR"], 135 | ["KP_COMMA", "PCMM"], 136 | ["KP_EQUAL_AS400"], 137 | ["INTERNATIONAL_1", "INT1"], 138 | ["INTERNATIONAL_2", "INT2"], 139 | ["INTERNATIONAL_3", "INT3"], 140 | ["INTERNATIONAL_4", "INT4"], 141 | ["INTERNATIONAL_5", "INT5"], 142 | ["INTERNATIONAL_6", "INT6"], 143 | ["INTERNATIONAL_7", "INT7"], 144 | ["INTERNATIONAL_8", "INT8"], 145 | ["INTERNATIONAL_9", "INT9"], 146 | ["LANGUAGE_1", "LNG1"], 147 | ["LANGUAGE_2", "LNG2"], 148 | ["LANGUAGE_3", "LNG3"], 149 | ["LANGUAGE_4", "LNG4"], 150 | ["LANGUAGE_5", "LNG5"], 151 | ["LANGUAGE_6", "LNG6"], 152 | ["LANGUAGE_7", "LNG7"], 153 | ["LANGUAGE_8", "LNG8"], 154 | ["LANGUAGE_9", "LNG9"], 155 | ["ALTERNATE_ERASE", "ERAS"], 156 | ["SYSTEM_REQUEST", "SYRQ"], 157 | ["CANCEL", "CNCL"], 158 | ["CLEAR", "CLR"], 159 | ["PRIOR", "PRIR"], 160 | ["RETURN", "RETN"], 161 | ["SEPARATOR", "SEPR"], # 0x9F 162 | ] 163 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/LED_SK6812_PLCC4_5.0x5.0mm_P3.2mm_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module LED_SK6812_PLCC4_5.0x5.0mm_P3.2mm_Reversible (layer F.Cu) (tedit 60C0EF92) 2 | (descr https://cdn-shop.adafruit.com/product-files/1138/SK6812+LED+datasheet+.pdf) 3 | (tags "LED RGB NeoPixel") 4 | (attr smd) 5 | (fp_text reference REF** (at 0 -3.5) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value LED_SK6812_PLCC4_5.0x5.0mm_P3.2mm_Reversible (at 0 4) (layer F.Fab) 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start 3.45 -2.75) (end 3.45 2.75) (layer B.CrtYd) (width 0.05)) 12 | (fp_line (start 2.5 -1.5) (end 1.5 -2.5) (layer B.Fab) (width 0.1)) 13 | (fp_line (start 3.65 -2.75) (end 3.65 -1.6) (layer B.SilkS) (width 0.12)) 14 | (fp_line (start 2.5 -2.5) (end 2.5 2.5) (layer B.Fab) (width 0.1)) 15 | (fp_circle (center 0 0) (end 0 2) (layer B.Fab) (width 0.1)) 16 | (fp_line (start 3.45 2.75) (end -3.45 2.75) (layer B.CrtYd) (width 0.05)) 17 | (fp_line (start 2.5 2.5) (end -2.5 2.5) (layer B.Fab) (width 0.1)) 18 | (fp_line (start -3.65 -2.75) (end 3.65 -2.75) (layer B.SilkS) (width 0.12)) 19 | (fp_line (start -2.5 2.5) (end -2.5 -2.5) (layer B.Fab) (width 0.1)) 20 | (fp_line (start -3.65 2.75) (end 3.65 2.75) (layer B.SilkS) (width 0.12)) 21 | (fp_line (start -2.5 -2.5) (end 2.5 -2.5) (layer B.Fab) (width 0.1)) 22 | (fp_line (start -3.45 2.75) (end -3.45 -2.75) (layer B.CrtYd) (width 0.05)) 23 | (fp_line (start -3.45 -2.75) (end 3.45 -2.75) (layer B.CrtYd) (width 0.05)) 24 | (fp_line (start 3.45 -2.75) (end -3.45 -2.75) (layer F.CrtYd) (width 0.05)) 25 | (fp_line (start 3.45 2.75) (end 3.45 -2.75) (layer F.CrtYd) (width 0.05)) 26 | (fp_line (start -3.45 2.75) (end 3.45 2.75) (layer F.CrtYd) (width 0.05)) 27 | (fp_line (start -3.45 -2.75) (end -3.45 2.75) (layer F.CrtYd) (width 0.05)) 28 | (fp_line (start 2.5 1.5) (end 1.5 2.5) (layer F.Fab) (width 0.1)) 29 | (fp_line (start -2.5 -2.5) (end -2.5 2.5) (layer F.Fab) (width 0.1)) 30 | (fp_line (start -2.5 2.5) (end 2.5 2.5) (layer F.Fab) (width 0.1)) 31 | (fp_line (start 2.5 2.5) (end 2.5 -2.5) (layer F.Fab) (width 0.1)) 32 | (fp_line (start 2.5 -2.5) (end -2.5 -2.5) (layer F.Fab) (width 0.1)) 33 | (fp_line (start -3.65 -2.75) (end 3.65 -2.75) (layer F.SilkS) (width 0.12)) 34 | (fp_line (start -3.65 2.75) (end 3.65 2.75) (layer F.SilkS) (width 0.12)) 35 | (fp_line (start 3.65 2.75) (end 3.65 1.6) (layer F.SilkS) (width 0.12)) 36 | (fp_circle (center 0 0) (end 0 -2) (layer F.Fab) (width 0.1)) 37 | (fp_text user %R (at 0 0) (layer F.Fab) 38 | (effects (font (size 0.8 0.8) (thickness 0.15))) 39 | ) 40 | (fp_text user %R (at 0 0) (layer B.Fab) 41 | (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)) 42 | ) 43 | (fp_text user %R (at 0 -3.5) (layer B.SilkS) 44 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 45 | ) 46 | (fp_poly (pts (xy 3.65 2.75) (xy 2.6416 2.7432) (xy 3.65 1.6)) (layer F.SilkS) (width 0.1)) 47 | (fp_poly (pts (xy 3.65 -2.75) (xy 2.6416 -2.7432) (xy 3.65 -1.6)) (layer B.SilkS) (width 0.1)) 48 | (pad 1 smd rect (at 2.45 1.6) (size 1.5 1) (layers F.Cu F.Paste F.Mask)) 49 | (pad 2 smd rect (at 2.45 -1.6) (size 1.5 1) (layers F.Cu F.Paste F.Mask)) 50 | (pad 4 smd rect (at -2.45 1.6) (size 1.5 1) (layers F.Cu F.Paste F.Mask)) 51 | (pad 3 smd rect (at -2.45 -1.6) (size 1.5 1) (layers F.Cu F.Paste F.Mask)) 52 | (pad 4 smd rect (at -2.45 -1.6) (size 1.5 1) (layers B.Cu B.Paste B.Mask)) 53 | (pad 2 smd rect (at 2.45 1.6) (size 1.5 1) (layers B.Cu B.Paste B.Mask)) 54 | (pad 1 smd rect (at 2.45 -1.6) (size 1.5 1) (layers B.Cu B.Paste B.Mask)) 55 | (pad 3 smd rect (at -2.45 1.6) (size 1.5 1) (layers B.Cu B.Paste B.Mask)) 56 | (model ${KISYS3DMOD}/LED_SMD.3dshapes/LED_SK6812_PLCC4_5.0x5.0mm_P3.2mm.wrl 57 | (at (xyz 0 0 0)) 58 | (scale (xyz 1 1 1)) 59 | (rotate (xyz 0 0 0)) 60 | ) 61 | ) 62 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual_Reversible (layer F.Cu) (tedit 5FD8C752) 2 | (descr "Capacitor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf, https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator") 3 | (tags "capacitor handsolder") 4 | (attr smd) 5 | (fp_text reference REF** (at 0 -1.68) (layer F.SilkS) 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text value C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual_Reversible (at 0 3.81) (layer F.Fab) hide 9 | (effects (font (size 1 1) (thickness 0.15))) 10 | ) 11 | (fp_line (start 1.88 0.98) (end -1.88 0.98) (layer F.CrtYd) (width 0.05)) 12 | (fp_line (start 1.88 -0.98) (end 1.88 0.98) (layer F.CrtYd) (width 0.05)) 13 | (fp_line (start -1.88 -0.98) (end 1.88 -0.98) (layer F.CrtYd) (width 0.05)) 14 | (fp_line (start -1.88 0.98) (end -1.88 -0.98) (layer F.CrtYd) (width 0.05)) 15 | (fp_line (start -0.261252 0.735) (end 0.261252 0.735) (layer F.SilkS) (width 0.12)) 16 | (fp_line (start -0.261252 -0.735) (end 0.261252 -0.735) (layer F.SilkS) (width 0.12)) 17 | (fp_line (start 1 0.625) (end -1 0.625) (layer F.Fab) (width 0.1)) 18 | (fp_line (start 1 -0.625) (end 1 0.625) (layer F.Fab) (width 0.1)) 19 | (fp_line (start -1 -0.625) (end 1 -0.625) (layer F.Fab) (width 0.1)) 20 | (fp_line (start -1 0.625) (end -1 -0.625) (layer F.Fab) (width 0.1)) 21 | (fp_line (start 1.88 -0.98) (end 1.88 0.98) (layer B.CrtYd) (width 0.05)) 22 | (fp_line (start -1.88 0.98) (end 1.88 0.98) (layer B.CrtYd) (width 0.05)) 23 | (fp_line (start -1.88 0.98) (end -1.88 -0.98) (layer B.CrtYd) (width 0.05)) 24 | (fp_line (start -0.261252 -0.735) (end 0.261252 -0.735) (layer B.SilkS) (width 0.12)) 25 | (fp_line (start -0.261252 0.735) (end 0.261252 0.735) (layer B.SilkS) (width 0.12)) 26 | (fp_line (start 1 0.625) (end -1 0.625) (layer B.Fab) (width 0.1)) 27 | (fp_line (start 1 -0.625) (end 1 0.625) (layer B.Fab) (width 0.1)) 28 | (fp_line (start -1 -0.625) (end 1 -0.625) (layer B.Fab) (width 0.1)) 29 | (fp_line (start -1 0.625) (end -1 -0.625) (layer B.Fab) (width 0.1)) 30 | (fp_line (start 1.88 -0.98) (end -1.88 -0.98) (layer B.CrtYd) (width 0.05)) 31 | (fp_text user %R (at 0 0) (layer F.Fab) 32 | (effects (font (size 0.5 0.5) (thickness 0.08))) 33 | ) 34 | (fp_text user %R (at 0 0) (layer B.Fab) 35 | (effects (font (size 0.5 0.5) (thickness 0.08))) 36 | ) 37 | (fp_text user %R (at 0 -1.651) (layer B.SilkS) 38 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 39 | ) 40 | (pad 1 smd roundrect (at -1.0375 0) (size 1.175 1.45) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.212766)) 41 | (pad 2 smd roundrect (at 1.0375 0) (size 1.175 1.45) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.212766)) 42 | (pad 2 smd roundrect (at 1.0375 0) (size 1.175 1.45) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.212766)) 43 | (pad 1 smd roundrect (at -1.0375 0) (size 1.175 1.45) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.212766)) 44 | (pad 2 thru_hole roundrect (at 2.54 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (roundrect_rratio 0.25)) 45 | (pad 1 thru_hole roundrect (at -2.54 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (roundrect_rratio 0.25)) 46 | (pad 1 smd rect (at -1.8 0 180) (size 1.6 0.5) (layers F.Cu)) 47 | (pad 2 smd rect (at 1.8 0 180) (size 1.6 0.5) (layers B.Cu)) 48 | (pad 2 smd rect (at 1.8 0 180) (size 1.6 0.5) (layers F.Cu)) 49 | (pad 1 smd rect (at -1.8 0 180) (size 1.6 0.5) (layers B.Cu)) 50 | (model ${KISYS3DMOD}/Capacitor_SMD.3dshapes/C_0805_2012Metric.wrl 51 | (at (xyz 0 0 0)) 52 | (scale (xyz 1 1 1)) 53 | (rotate (xyz 0 0 0)) 54 | ) 55 | ) 56 | -------------------------------------------------------------------------------- /FAK-Firmware/src/keymap.c: -------------------------------------------------------------------------------- 1 | #include "keymap.h" 2 | 3 | #if LAYER_COUNT > 1 4 | __xdata __at(XADDR_LAYER_STATE) fak_layer_state_t layer_state = 0; 5 | __xdata __at(XADDR_PERSISTENT_LAYER_STATE) fak_layer_state_t persistent_layer_state = 1; 6 | #endif 7 | 8 | uint32_t get_real_key_code(uint8_t key_idx) { 9 | #if LAYER_COUNT == 1 10 | return key_map[key_idx]; 11 | #else 12 | 13 | #ifdef LAYER_TRANSPARENCY_ENABLE 14 | #define IS_HOLD_TRANS (hold == 0xFFFF) 15 | #define IS_TAP_TRANS (tap == 0xFFFF) 16 | uint16_t hold = 0xFFFF; 17 | uint16_t tap = 0xFFFF; 18 | uint8_t layer_idx = LAYER_COUNT - 1; 19 | 20 | do { 21 | if (!is_layer_on(layer_idx)) 22 | continue; 23 | 24 | uint32_t key_code = key_map[layer_idx][key_idx]; 25 | 26 | // Bail out if this keycode is not a hold-tap (e.g. tap dance) 27 | // and if either hold or tap, but not both, is still transparent. 28 | if ((key_code >> 28) == 0xE && (IS_HOLD_TRANS ^ IS_TAP_TRANS)) { 29 | return 0; 30 | } 31 | 32 | if (IS_HOLD_TRANS) hold = key_code >> 16; 33 | if (IS_TAP_TRANS) tap = key_code & 0xFFFF; 34 | } while (layer_idx-- && (IS_HOLD_TRANS || IS_TAP_TRANS)); 35 | 36 | if (hold == 0xFFFF) hold = 0; 37 | if (tap == 0xFFFF) tap = 0; 38 | return ((uint32_t) hold << 16) | tap; 39 | #else 40 | return key_map[get_highest_layer_idx()][key_idx]; 41 | #endif 42 | 43 | #endif 44 | } 45 | 46 | #if LAYER_COUNT > 1 47 | 48 | uint8_t get_highest_layer_idx() { 49 | for (uint8_t layer_idx = LAYER_COUNT - 1; layer_idx; layer_idx--) { 50 | if (is_layer_on(layer_idx)) 51 | return layer_idx; 52 | } 53 | return 0; 54 | } 55 | 56 | uint8_t get_default_layer_idx() { 57 | for (uint8_t layer_idx = 0; layer_idx < LAYER_COUNT; layer_idx++) { 58 | if (persistent_layer_state & (1 << layer_idx)) 59 | return layer_idx; 60 | } 61 | return 0; 62 | } 63 | 64 | static void on_layer_state_change() { 65 | #if CONDITIONAL_LAYER_COUNT > 0 66 | for (uint8_t i = 0; i < CONDITIONAL_LAYER_COUNT; i++) { 67 | __code fak_conditional_layer_def_t *cl = &conditional_layers[i]; 68 | 69 | if (((layer_state | persistent_layer_state) & cl->if_layers) == cl->if_layers) { 70 | layer_state |= (1 << cl->then_layer); 71 | } else { 72 | layer_state &= ~(1 << cl->then_layer); 73 | } 74 | } 75 | #endif 76 | } 77 | 78 | void set_default_layer_idx(uint8_t layer_idx) { 79 | set_persistent_layer_state(1 << layer_idx); 80 | } 81 | 82 | void set_layer_state(fak_layer_state_t state) { 83 | layer_state = state; 84 | on_layer_state_change(); 85 | } 86 | 87 | void layer_state_on(uint8_t layer_idx) { 88 | layer_state |= (1 << layer_idx); 89 | on_layer_state_change(); 90 | } 91 | 92 | void layer_state_off(uint8_t layer_idx) { 93 | layer_state &= ~(1 << layer_idx); 94 | on_layer_state_change(); 95 | } 96 | 97 | void layer_state_toggle(uint8_t layer_idx) { 98 | if (is_layer_off(layer_idx)) { 99 | layer_state_on(layer_idx); 100 | } else { 101 | layer_state_off(layer_idx); 102 | } 103 | } 104 | 105 | void set_persistent_layer_state(fak_layer_state_t state) { 106 | persistent_layer_state = state; 107 | on_layer_state_change(); 108 | } 109 | 110 | void persistent_layer_state_on(uint8_t layer_idx) { 111 | persistent_layer_state |= (1 << layer_idx); 112 | on_layer_state_change(); 113 | } 114 | 115 | void persistent_layer_state_off(uint8_t layer_idx) { 116 | persistent_layer_state &= ~(1 << layer_idx); 117 | on_layer_state_change(); 118 | } 119 | 120 | uint8_t is_layer_on(uint8_t layer_idx) { 121 | return ((layer_state | persistent_layer_state) & (1 << layer_idx)) != 0; 122 | } 123 | 124 | uint8_t is_layer_off(uint8_t layer_idx) { 125 | return ((layer_state | persistent_layer_state) & (1 << layer_idx)) == 0; 126 | } 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 62C7A525) 4 | (descr "Capacitor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal with elongated pad for handsoldering. (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf, https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator") 5 | (tags "capacitor handsolder") 6 | (attr smd) 7 | (fp_text reference "REF**" (at 0 -1.68) (layer "F.SilkS") 8 | (effects (font (size 0.8 0.8) (thickness 0.15))) 9 | (tstamp e49538a4-3810-41b5-a3b6-eb8629aa6422) 10 | ) 11 | (fp_text value "C_0805_2012Metric_Pad1.18x1.45mm_HandSolder_Dual" (at 0 3.81) (layer "F.Fab") hide 12 | (effects (font (size 1 1) (thickness 0.15))) 13 | (tstamp 2870aa09-efba-46fc-b234-78ff4bc63a0e) 14 | ) 15 | (fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab") 16 | (effects (font (size 0.5 0.5) (thickness 0.08))) 17 | (tstamp 989161fd-3ef3-401e-a81e-f99362f6c81a) 18 | ) 19 | (fp_line (start -0.261252 0.735) (end 0.261252 0.735) (layer "F.SilkS") (width 0.12) (tstamp 7e3bc9c6-d780-4f04-b3b9-a2e254b1064d)) 20 | (fp_line (start -0.261252 -0.735) (end 0.261252 -0.735) (layer "F.SilkS") (width 0.12) (tstamp c2f2337d-95f2-47ff-8f66-c627a316ce20)) 21 | (fp_line (start -1.88 -0.98) (end 1.88 -0.98) (layer "F.CrtYd") (width 0.05) (tstamp 09ef31da-8126-4111-863a-ca46c6c72b30)) 22 | (fp_line (start 1.88 0.98) (end -1.88 0.98) (layer "F.CrtYd") (width 0.05) (tstamp 4e89b1da-f6cc-42f6-be5a-8892f43bc444)) 23 | (fp_line (start -1.88 0.98) (end -1.88 -0.98) (layer "F.CrtYd") (width 0.05) (tstamp 6fe4dc6f-1b63-4844-8354-9c22bf03a674)) 24 | (fp_line (start 1.88 -0.98) (end 1.88 0.98) (layer "F.CrtYd") (width 0.05) (tstamp a9603cbb-e7e4-42c3-bc5c-041b296fc98f)) 25 | (fp_line (start 1 0.625) (end -1 0.625) (layer "B.Fab") (width 0.1) (tstamp 3f324d1f-900d-4ee8-a0ac-3bcd23add899)) 26 | (fp_line (start -1 -0.625) (end 1 -0.625) (layer "B.Fab") (width 0.1) (tstamp 88ad4e45-dd46-4e84-a796-7866cb537b9a)) 27 | (fp_line (start 1 -0.625) (end 1 0.625) (layer "B.Fab") (width 0.1) (tstamp 9956d2ce-ae8e-4b82-b21c-0fc392d7827f)) 28 | (fp_line (start -1 0.625) (end -1 -0.625) (layer "B.Fab") (width 0.1) (tstamp f707362e-dd2b-4e1e-8af5-8004c7870c5e)) 29 | (fp_line (start 1 -0.625) (end 1 0.625) (layer "F.Fab") (width 0.1) (tstamp 4715ba48-db4f-4adc-b81a-603168918b66)) 30 | (fp_line (start -1 -0.625) (end 1 -0.625) (layer "F.Fab") (width 0.1) (tstamp 48370d7f-008e-4461-8764-a468f8ae0afd)) 31 | (fp_line (start -1 0.625) (end -1 -0.625) (layer "F.Fab") (width 0.1) (tstamp 9c37c411-d00c-4108-afb9-adac0bbcb91d)) 32 | (fp_line (start 1 0.625) (end -1 0.625) (layer "F.Fab") (width 0.1) (tstamp 9d72dbb4-cb89-4d85-9c25-6c845343b1a7)) 33 | (pad "1" smd rect (at -1.8 0 180) (size 1.6 0.5) (layers "F.Cu") (tstamp 0225955b-50b5-4e9e-ab8f-2f4f9d0b286f)) 34 | (pad "1" thru_hole roundrect (at -2.54 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (roundrect_rratio 0.25) (tstamp 16164215-14a1-45bc-9613-daf837bbdccb)) 35 | (pad "1" smd roundrect (at -1.0375 0) (size 1.175 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.212766) (tstamp 39380cac-13e4-4fd8-bf29-6d7adad646f0)) 36 | (pad "2" smd rect (at 1.8 0 180) (size 1.6 0.5) (layers "F.Cu") (tstamp 08639269-e50e-4f90-90cc-a6117ad8aedb)) 37 | (pad "2" smd roundrect (at 1.0375 0) (size 1.175 1.45) (layers "F.Cu" "F.Paste" "F.Mask") (roundrect_rratio 0.212766) (tstamp 6c1281f8-da61-4139-9df2-30630006e0b8)) 38 | (pad "2" thru_hole roundrect (at 2.54 0) (size 1.524 1.524) (drill 0.762) (layers *.Cu *.Mask) (roundrect_rratio 0.25) (tstamp 8899ab45-5f22-46dc-837f-a43c2924259a)) 39 | (model "${KISYS3DMOD}/Capacitor_SMD.3dshapes/C_0805_2012Metric.wrl" 40 | (offset (xyz 0 0 0)) 41 | (scale (xyz 1 1 1)) 42 | (rotate (xyz 0 0 0)) 43 | ) 44 | ) 45 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/zilpzalp/keymap.ncl: -------------------------------------------------------------------------------- 1 | let { tap, hold, td, combo, .. } = import "../../fak/keycode.ncl" in 2 | let util = import "../../fak/util_functions.ncl" in 3 | 4 | let config = import "config.ncl" in 5 | let layout = (import "layouts.ncl")."%{config.layout}" in 6 | 7 | let ki = { 8 | hp = { decision = 'hold, trigger_on = 'press }, 9 | tp = { decision = 'tap, trigger_on = 'press }, 10 | hr = { decision = 'hold, trigger_on = 'release }, 11 | tr = { decision = 'tap, trigger_on = 'release }, 12 | xx = { decision = 'none }, 13 | } in 14 | 15 | let combos = layout.combos in 16 | 17 | let virtual_keys' = 18 | combos |> std.array.map (fun c => 19 | combo.make config.combo_timeout_ms (std.array.split_at 1 c).right) 20 | in 21 | 22 | let physical_key_count = 28 in 23 | let virtual_key_count = std.array.length virtual_keys' in 24 | let key_count = physical_key_count + virtual_key_count in 25 | 26 | let rec get_side_of_key_idx = fun key_idx => 27 | if key_idx < physical_key_count then 28 | let right_indices = [4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 26, 27] in 29 | if std.array.elem key_idx right_indices then 'right else 'left 30 | else 31 | let c = std.array.at (key_idx - physical_key_count) combos in 32 | let unique_sides = (std.array.split_at 1 c).right 33 | |> std.array.map get_side_of_key_idx 34 | |> util.array.unique in 35 | if std.array.length unique_sides > 1 then 36 | 'both 37 | else 38 | std.array.first unique_sides 39 | in 40 | 41 | let make_hrm = fun key_idx => 42 | let hrm_mods = 43 | let md = hold.reg.mod 44 | in [ 45 | md.lctl, md.lalt, md.lgui, md.lsft, md.ralt, 46 | md.ralt, md.rsft, md.rgui, md.lalt, md.rctl, 47 | ] in 48 | 49 | let hrm_key_indices = [ 50 | 16, 8, 9, 10, 11, 51 | 12, 13, 14, 15, 23, 52 | ] in 53 | 54 | let htb_hrm_base = { 55 | timeout_ms = 200, 56 | quick_tap_ms = 150, 57 | quick_tap_interrupt_ms = 500, 58 | global_quick_tap_ms = 100, 59 | } in 60 | 61 | let htb_hrm = fun side => htb_hrm_base & { 62 | key_interrupts = 63 | let hrm_key_indices_on_side = hrm_key_indices |> 64 | std.array.filter (fun i => get_side_of_key_idx i == side) in 65 | 66 | std.array.generate (fun key_idx => 67 | let side_of_key_idx = get_side_of_key_idx key_idx in 68 | if side_of_key_idx == 'both then 69 | ki.xx 70 | else if side_of_key_idx != side then 71 | ki.hr 72 | else if std.array.elem key_idx hrm_key_indices_on_side then 73 | ki.tr 74 | else 75 | ki.tp 76 | ) key_count 77 | } in 78 | 79 | if std.array.elem key_idx hrm_key_indices then 80 | let mod_idx = util.array.index_of key_idx hrm_key_indices in 81 | let mod = std.array.at mod_idx hrm_mods in 82 | let side = get_side_of_key_idx key_idx in 83 | mod & hold.reg.behavior (htb_hrm side) 84 | else 85 | {} 86 | in 87 | 88 | let XXXX = tap.none & hold.none in 89 | let virtual_base = combos |> std.array.map std.array.first in 90 | let virtual_filler = combos |> std.array.map (fun c => XXXX) in 91 | 92 | let layer_default = 93 | let base_keycodes = layout.base_layout 94 | |> std.string.characters 95 | |> util.array.enumerate 96 | |> std.array.map (fun { index, value } => tap.reg.kc."%{value}" & make_hrm index) 97 | in 98 | 99 | let thumb_keycodes = 100 | let htb_thumb = { 101 | timeout_ms = 200, 102 | quick_tap_ms = 150, 103 | quick_tap_interrupt_ms = 500, 104 | key_interrupts = std.array.replicate key_count ki.hr, 105 | } in 106 | 107 | layout.thumbs 108 | |> util.array.enumerate 109 | |> std.array.map (fun { index, value } => 110 | value 111 | & hold.reg.layer (index + 1) 112 | & hold.reg.behavior htb_thumb) 113 | in 114 | 115 | base_keycodes @ thumb_keycodes @ virtual_base 116 | in 117 | 118 | { 119 | virtual_keys = virtual_keys', 120 | layers = [layer_default] @ ( 121 | ["NUM", "NAV", "SYM", "FUN"] 122 | |> std.array.map (fun name => layout.layers."%{name}") 123 | |> std.array.map (fun layer => layer @ virtual_filler) 124 | ) 125 | } 126 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm" (version 20221018) (generator pcbnew) 2 | (layer "F.Cu") 3 | (descr "5.0mm x 5.0mm Addressable RGB LED NeoPixel, https://cdn-shop.adafruit.com/datasheets/WS2812B.pdf") 4 | (tags "LED RGB NeoPixel PLCC-4 5050") 5 | (attr smd) 6 | (fp_text reference "REF**" (at 0 -3.5) (layer "F.SilkS") 7 | (effects (font (size 1 1) (thickness 0.15))) 8 | (tstamp 29976fa0-918e-48c1-ba81-319324267df7) 9 | ) 10 | (fp_text value "LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm" (at 0 4) (layer "F.Fab") 11 | (effects (font (size 1 1) (thickness 0.15))) 12 | (tstamp 11f34c85-b80f-46bd-b71d-beeef7ef25a2) 13 | ) 14 | (fp_text user "1" (at -4.15 -1.6) (layer "F.SilkS") 15 | (effects (font (size 1 1) (thickness 0.15))) 16 | (tstamp d09dbb95-d0d6-4d24-828b-5464671de2a8) 17 | ) 18 | (fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab") 19 | (effects (font (size 0.8 0.8) (thickness 0.15))) 20 | (tstamp c5756b5f-7ccc-4d42-872b-98775daca562) 21 | ) 22 | (fp_line (start -3.65 -2.75) (end 3.65 -2.75) 23 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 6ed77aa4-f296-4996-819b-3cc749559f49)) 24 | (fp_line (start -3.65 2.75) (end 3.65 2.75) 25 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp ca1d06bb-c27e-4859-b633-e45a2345f320)) 26 | (fp_line (start 3.65 2.75) (end 3.65 1.6) 27 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp e860fd23-f087-40be-9473-9d8e25d5ffe3)) 28 | (fp_circle (center -3.4036 -2.3876) (end -3.3528 -2.3368) 29 | (stroke (width 0.1) (type default)) (fill none) (layer "F.SilkS") (tstamp 2ec0b752-c3c5-410a-9dfd-f75d168a5542)) 30 | (fp_poly 31 | (pts 32 | (xy 3.624428 2.745298) 33 | (xy 2.616028 2.738498) 34 | (xy 3.624428 1.595298) 35 | ) 36 | 37 | (stroke (width 0.1) (type solid)) (fill solid) (layer "F.SilkS") (tstamp cde96cd3-6c3b-4ce7-9c8e-e4b24cae905e)) 38 | (fp_line (start -3.45 -2.75) (end -3.45 2.75) 39 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp e698f4d4-65a5-4d0f-a8ed-5745b8f0d483)) 40 | (fp_line (start -3.45 2.75) (end 3.45 2.75) 41 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 2d2813ac-2cb3-426c-9318-d6eb3fef0d3b)) 42 | (fp_line (start 3.45 -2.75) (end -3.45 -2.75) 43 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 3ed360c1-b7ac-408f-ae9c-5f158b031e9b)) 44 | (fp_line (start 3.45 2.75) (end 3.45 -2.75) 45 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 62f632c6-6884-46e9-ac67-40d4696553e0)) 46 | (fp_line (start -2.5 -2.5) (end -2.5 2.5) 47 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c0c389f3-e39a-48d8-966d-313f4224879e)) 48 | (fp_line (start -2.5 2.5) (end 2.5 2.5) 49 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e4c74574-4660-4fc6-b56a-3f019923dc9c)) 50 | (fp_line (start 2.5 -2.5) (end -2.5 -2.5) 51 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp e2bf95a5-2ab1-44b7-8a52-0c672195a1d4)) 52 | (fp_line (start 2.5 1.5) (end 1.5 2.5) 53 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp bfb2b50f-e0ce-4bd4-b9e6-cca37d8e1b12)) 54 | (fp_line (start 2.5 2.5) (end 2.5 -2.5) 55 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 90c3ef5b-455e-4d2f-aa38-e0f89bf4bf0c)) 56 | (fp_circle (center 0 0) (end 0 -2) 57 | (stroke (width 0.1) (type solid)) (fill none) (layer "F.Fab") (tstamp 83b9b0b3-69d5-4d55-b734-61b11225d74a)) 58 | (pad "1" smd rect (at -2.45 -1.65) (size 1.5 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 303fa036-5e50-4d6d-bb86-5cdfd4b88a9f)) 59 | (pad "2" smd rect (at -2.45 1.65) (size 1.5 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 19ff1e90-56ef-461a-889c-61ffea674474)) 60 | (pad "3" smd rect (at 2.45 1.65) (size 1.5 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp abc776f0-6816-4443-a596-fad8645d4ac8)) 61 | (pad "4" smd rect (at 2.45 -1.65) (size 1.5 0.9) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp e6e3b1bc-4064-4031-9b80-d1df61337d0a)) 62 | (model "${KICAD7_3DMODEL_DIR}/LED_SMD.3dshapes/LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm.wrl" 63 | (offset (xyz 0 0 0)) 64 | (scale (xyz 1 1 1)) 65 | (rotate (xyz 0 0 0)) 66 | ) 67 | ) 68 | -------------------------------------------------------------------------------- /FAK-Firmware/fak.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import subprocess 3 | import json 4 | import glob 5 | import hashlib 6 | import os 7 | import sys 8 | import time 9 | 10 | os.chdir(sys.path[0]) 11 | 12 | EVAL_PATH = '.main.ncl.json' 13 | BUILD_DIR = 'build' 14 | SUBCOMMAND = sys.argv[1] 15 | 16 | 17 | def compute_hash_sig(): 18 | h = hashlib.sha256() 19 | 20 | for filepath in glob.glob('ncl/**/*.ncl', recursive=True): 21 | with open(filepath, 'r') as f: 22 | h.update(f.read().encode('utf-8')) 23 | 24 | return h.hexdigest() 25 | 26 | 27 | def save_evaluation(hash_sig): 28 | completed_proc = subprocess.run( 29 | ['nickel', 'export', '--format', 'json', 'ncl/fak/main.ncl'], 30 | capture_output=True, 31 | text=True, 32 | ) 33 | 34 | if completed_proc.returncode != 0: 35 | print(completed_proc.stderr) 36 | sys.exit(1) 37 | 38 | raw_result = completed_proc.stdout 39 | result = json.loads(raw_result) 40 | result['__hash__'] = hash_sig 41 | 42 | with open(EVAL_PATH, 'w') as f: 43 | f.write(json.dumps(result, indent=2)) 44 | 45 | return result 46 | 47 | 48 | def load_evaluation(hash_sig): 49 | if not os.path.isfile(EVAL_PATH): 50 | return None 51 | 52 | with open(EVAL_PATH, 'r') as f: 53 | result = json.loads(f.read()) 54 | 55 | if result['__hash__'] == hash_sig: 56 | return result 57 | 58 | return None 59 | 60 | 61 | def evaluate_ncl(): 62 | hash_sig = compute_hash_sig() 63 | result = load_evaluation(hash_sig) 64 | 65 | if result is None: 66 | result = save_evaluation(hash_sig) 67 | 68 | return result 69 | 70 | 71 | def subcmd_query_ncl(): 72 | result = evaluate_ncl() 73 | selector = sys.argv[2] 74 | 75 | for key in selector.split('.'): 76 | result = result[key] 77 | 78 | print(result, end='') 79 | 80 | 81 | def meson_configure(): 82 | if not os.path.isdir(BUILD_DIR): 83 | subprocess.run(['meson', 'setup', BUILD_DIR], check=True) 84 | 85 | print("Evaluating Nickel files...") 86 | result = evaluate_ncl() 87 | 88 | for key, value in result['meson_options'].items(): 89 | subprocess.run(['meson', 'configure', f'-D{key}={value}'], check=True, cwd=BUILD_DIR) 90 | 91 | return result 92 | 93 | 94 | def subcmd_compile(): 95 | meson_configure() 96 | subprocess.run(['meson', 'compile'], check=True, cwd=BUILD_DIR) 97 | 98 | 99 | def wait_for_device(): 100 | attempts = 0 101 | while attempts < 16: 102 | try: 103 | subprocess.run(['meson', 'compile', 'wchisp_info'], check=True, cwd=BUILD_DIR, capture_output=True) 104 | return 105 | except subprocess.CalledProcessError: 106 | if attempts == 0: 107 | print("Device not available!") 108 | print("Waiting for bootloader...", end="", flush=True) 109 | else: 110 | print(".", end="", flush=True) 111 | 112 | time.sleep(1) 113 | attempts += 1 114 | 115 | 116 | # TODO: Implement better flashing experience 117 | # - Automatically flash whatever side(s) needs to reflash 118 | def subcmd_flash_central(): 119 | subcmd_compile() 120 | wait_for_device() 121 | subprocess.run(['meson', 'compile', 'flash_central'], check=True, cwd=BUILD_DIR) 122 | 123 | 124 | def subcmd_flash_peripheral(): 125 | result = meson_configure() 126 | 127 | if 'peripheral' not in result: 128 | print("Error: Can't flash peripheral. The keyboard is not a split.") 129 | sys.exit(1) 130 | 131 | subcmd_compile() 132 | wait_for_device() 133 | subprocess.run(['meson', 'compile', 'flash_peripheral'], check=True, cwd=BUILD_DIR) 134 | 135 | # TODO: Use argparse 136 | 137 | if SUBCOMMAND == 'query_ncl': 138 | subcmd_query_ncl() 139 | elif SUBCOMMAND == 'compile': 140 | subcmd_compile() 141 | elif SUBCOMMAND in ['flash', 'flash_c', 'flash_central']: 142 | subcmd_flash_central() 143 | elif SUBCOMMAND in ['flash_p', 'flash_peripheral']: 144 | subcmd_flash_peripheral() 145 | else: 146 | print("Error: Unknown subcommand") 147 | sys.exit(1) 148 | -------------------------------------------------------------------------------- /gerber/ch55p34-B_Paste.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,7.0.1*% 2 | %TF.CreationDate,2024-01-05T17:15:01-05:00*% 3 | %TF.ProjectId,ch55p34,63683535-7033-4342-9e6b-696361645f70,rev?*% 4 | %TF.SameCoordinates,Original*% 5 | %TF.FileFunction,Paste,Bot*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 7.0.1) date 2024-01-05 17:15:01* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 Aperture macros list* 15 | %AMRotRect* 16 | 0 Rectangle, with rotation* 17 | 0 The origin of the aperture is its center* 18 | 0 $1 length* 19 | 0 $2 width* 20 | 0 $3 Rotation angle, in degrees counterclockwise* 21 | 0 Add horizontal line* 22 | 21,1,$1,$2,0,0,$3*% 23 | G04 Aperture macros list end* 24 | %ADD10RotRect,2.550000X2.500000X25.000000*% 25 | %ADD11RotRect,2.550000X2.500000X30.000000*% 26 | %ADD12RotRect,2.550000X2.500000X330.000000*% 27 | %ADD13RotRect,2.550000X2.500000X335.000000*% 28 | %ADD14RotRect,2.550000X2.500000X15.000000*% 29 | %ADD15RotRect,2.550000X2.500000X345.000000*% 30 | G04 APERTURE END LIST* 31 | D10* 32 | %TO.C,SW34*% 33 | X214194952Y-106673460D03* 34 | X202716040Y-114828744D03* 35 | %TD*% 36 | D11* 37 | %TO.C,SW33*% 38 | X192249812Y-112098323D03* 39 | X181525360Y-121223027D03* 40 | %TD*% 41 | D12* 42 | %TO.C,SW32*% 43 | X130302788Y-118388323D03* 44 | X117038336Y-113663027D03* 45 | %TD*% 46 | D13* 47 | %TO.C,SW31*% 48 | X108864400Y-111989998D03* 49 | X95238587Y-108438757D03* 50 | %TD*% 51 | D14* 52 | %TO.C,SW30*% 53 | X264227914Y-72674563D03* 54 | X251507241Y-78712658D03* 55 | %TD*% 56 | %TO.C,SW29*% 57 | X242737245Y-66073843D03* 58 | X230016572Y-72111938D03* 59 | %TD*% 60 | %TO.C,SW28*% 61 | X222758597Y-65116062D03* 62 | X210037924Y-71154157D03* 63 | %TD*% 64 | %TO.C,SW27*% 65 | X205672511Y-74953468D03* 66 | X192951838Y-80991563D03* 67 | %TD*% 68 | %TO.C,SW26*% 69 | X188257725Y-83564148D03* 70 | X175537052Y-89602243D03* 71 | %TD*% 72 | D15* 73 | %TO.C,SW25*% 74 | X135551622Y-86820092D03* 75 | X121516149Y-85688899D03* 76 | %TD*% 77 | %TO.C,SW24*% 78 | X118136836Y-78209412D03* 79 | X104101363Y-77078219D03* 80 | %TD*% 81 | %TO.C,SW23*% 82 | X101050750Y-68372006D03* 83 | X87015277Y-67240813D03* 84 | %TD*% 85 | %TO.C,SW22*% 86 | X81072102Y-69329787D03* 87 | X67036629Y-68198594D03* 88 | %TD*% 89 | %TO.C,SW21*% 90 | X59581433Y-75930507D03* 91 | X45545960Y-74799314D03* 92 | %TD*% 93 | D14* 94 | %TO.C,SW20*% 95 | X259297411Y-54273676D03* 96 | X246576738Y-60311771D03* 97 | %TD*% 98 | %TO.C,SW19*% 99 | X237806742Y-47672956D03* 100 | X225086069Y-53711051D03* 101 | %TD*% 102 | %TO.C,SW18*% 103 | X217828095Y-46715175D03* 104 | X205107422Y-52753270D03* 105 | %TD*% 106 | %TO.C,SW17*% 107 | X200742008Y-56552581D03* 108 | X188021335Y-62590676D03* 109 | %TD*% 110 | %TO.C,SW16*% 111 | X183327222Y-65163261D03* 112 | X170606549Y-71201356D03* 113 | %TD*% 114 | D15* 115 | %TO.C,SW15*% 116 | X140482125Y-68419205D03* 117 | X126446652Y-67288012D03* 118 | %TD*% 119 | %TO.C,SW14*% 120 | X123067339Y-59808525D03* 121 | X109031866Y-58677332D03* 122 | %TD*% 123 | %TO.C,SW13*% 124 | X105981252Y-49971119D03* 125 | X91945779Y-48839926D03* 126 | %TD*% 127 | %TO.C,SW12*% 128 | X86002604Y-50928900D03* 129 | X71967131Y-49797707D03* 130 | %TD*% 131 | %TO.C,SW11*% 132 | X64511936Y-57529620D03* 133 | X50476463Y-56398427D03* 134 | %TD*% 135 | D14* 136 | %TO.C,SW10*% 137 | X254366908Y-35872789D03* 138 | X241646235Y-41910884D03* 139 | %TD*% 140 | %TO.C,SW9*% 141 | X232876240Y-29272069D03* 142 | X220155567Y-35310164D03* 143 | %TD*% 144 | %TO.C,SW8*% 145 | X212897592Y-28314288D03* 146 | X200176919Y-34352383D03* 147 | %TD*% 148 | %TO.C,SW7*% 149 | X195811506Y-38151694D03* 150 | X183090833Y-44189789D03* 151 | %TD*% 152 | %TO.C,SW6*% 153 | X178396719Y-46762374D03* 154 | X165676046Y-52800469D03* 155 | %TD*% 156 | D15* 157 | %TO.C,SW5*% 158 | X145412628Y-50018318D03* 159 | X131377155Y-48887125D03* 160 | %TD*% 161 | %TO.C,SW4*% 162 | X127997841Y-41407638D03* 163 | X113962368Y-40276445D03* 164 | %TD*% 165 | %TO.C,SW3*% 166 | X110911755Y-31570232D03* 167 | X96876282Y-30439039D03* 168 | %TD*% 169 | %TO.C,SW2*% 170 | X90933107Y-32528013D03* 171 | X76897634Y-31396820D03* 172 | %TD*% 173 | %TO.C,SW1*% 174 | X69442439Y-39128733D03* 175 | X55406966Y-37997540D03* 176 | %TD*% 177 | M02* 178 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm_Reversible locked (layer F.Cu) (tedit 6074427E) 2 | (descr "Alps rotary encoder, EC12E... with switch, vertical shaft, http://www.alps.com/prod/info/E/HTML/Encoder/Incremental/EC11/EC11E15204A3.html") 3 | (tags "rotary encoder") 4 | (fp_text reference SW_RE1 (at 2.8 -4.7) (layer F.SilkS) 5 | (effects (font (size 1 1) (thickness 0.15))) 6 | ) 7 | (fp_text value Rotary_Encoder_Switch (at 7.5 10.4) (layer F.Fab) 8 | (effects (font (size 1 1) (thickness 0.15))) 9 | ) 10 | (fp_circle (center 7.5 2.5) (end 10.5 2.5) (layer F.Fab) (width 0.12)) 11 | (fp_circle (center 7.5 2.5) (end 10.5 2.5) (layer F.SilkS) (width 0.12)) 12 | (fp_line (start 16 9.6) (end -1.5 9.6) (layer F.CrtYd) (width 0.05)) 13 | (fp_line (start 16 9.6) (end 16 -4.6) (layer F.CrtYd) (width 0.05)) 14 | (fp_line (start -1.5 -4.6) (end -1.5 9.6) (layer F.CrtYd) (width 0.05)) 15 | (fp_line (start -1.5 -4.6) (end 16 -4.6) (layer F.CrtYd) (width 0.05)) 16 | (fp_line (start 2.5 -3.3) (end 13.5 -3.3) (layer F.Fab) (width 0.12)) 17 | (fp_line (start 13.5 -3.3) (end 13.5 8.3) (layer F.Fab) (width 0.12)) 18 | (fp_line (start 13.5 8.3) (end 1.5 8.3) (layer F.Fab) (width 0.12)) 19 | (fp_line (start 1.5 8.3) (end 1.5 -2.2) (layer F.Fab) (width 0.12)) 20 | (fp_line (start 1.5 -2.2) (end 2.5 -3.3) (layer F.Fab) (width 0.12)) 21 | (fp_line (start 9.5 -3.4) (end 13.6 -3.4) (layer F.SilkS) (width 0.12)) 22 | (fp_line (start 13.6 8.4) (end 9.5 8.4) (layer F.SilkS) (width 0.12)) 23 | (fp_line (start 5.5 8.4) (end 1.4 8.4) (layer F.SilkS) (width 0.12)) 24 | (fp_line (start 5.5 -3.4) (end 1.4 -3.4) (layer F.SilkS) (width 0.12)) 25 | (fp_line (start 1.4 -3.4) (end 1.4 8.4) (layer F.SilkS) (width 0.12)) 26 | (fp_line (start 7.5 -0.5) (end 7.5 5.5) (layer F.Fab) (width 0.12)) 27 | (fp_line (start 4.5 2.5) (end 10.5 2.5) (layer F.Fab) (width 0.12)) 28 | (fp_line (start 13.6 -3.4) (end 13.6 -1) (layer F.SilkS) (width 0.12)) 29 | (fp_line (start 13.6 1.2) (end 13.6 3.8) (layer F.SilkS) (width 0.12)) 30 | (fp_line (start 13.6 6) (end 13.6 8.4) (layer F.SilkS) (width 0.12)) 31 | (fp_line (start 7.5 2) (end 7.5 3) (layer F.SilkS) (width 0.12)) 32 | (fp_line (start 7 2.5) (end 8 2.5) (layer F.SilkS) (width 0.12)) 33 | (fp_text user %R (at 11.1 6.3) (layer F.Fab) 34 | (effects (font (size 1 1) (thickness 0.15))) 35 | ) 36 | (fp_circle (center 7.50254 2.49872) (end 10.50254 2.49872) (layer B.SilkS) (width 0.12)) 37 | (fp_line (start 9.50254 8.39872) (end 13.60254 8.39872) (layer B.SilkS) (width 0.12)) 38 | (fp_line (start 13.60254 -3.40128) (end 9.50254 -3.40128) (layer B.SilkS) (width 0.12)) 39 | (fp_line (start 5.50254 -3.40128) (end 1.40254 -3.40128) (layer B.SilkS) (width 0.12)) 40 | (fp_line (start 5.50254 8.39872) (end 1.40254 8.39872) (layer B.SilkS) (width 0.12)) 41 | (fp_line (start 1.40254 8.39872) (end 1.40254 -3.40128) (layer B.SilkS) (width 0.12)) 42 | (fp_line (start 13.60254 8.39872) (end 13.60254 5.99872) (layer B.SilkS) (width 0.12)) 43 | (fp_line (start 13.60254 3.79872) (end 13.60254 1.19872) (layer B.SilkS) (width 0.12)) 44 | (fp_line (start 13.60254 -1.00128) (end 13.60254 -3.40128) (layer B.SilkS) (width 0.12)) 45 | (fp_line (start 7.50254 2.99872) (end 7.50254 1.99872) (layer B.SilkS) (width 0.12)) 46 | (fp_line (start 7.00254 2.49872) (end 8.00254 2.49872) (layer B.SilkS) (width 0.12)) 47 | (fp_text user %R (at 2.85242 -4.70154) (layer B.SilkS) 48 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 49 | ) 50 | (pad A thru_hole circle (at 0 0) (size 2 2) (drill 1) (layers *.Cu *.Mask)) 51 | (pad C thru_hole circle (at 0 2.5) (size 2 2) (drill 1) (layers *.Cu *.Mask)) 52 | (pad B thru_hole circle (at 0 5) (size 2 2) (drill 1) (layers *.Cu *.Mask)) 53 | (pad MP thru_hole rect (at 7.5 -3.1) (size 3.2 2) (drill oval 2.8 1.5) (layers *.Cu *.Mask)) 54 | (pad MP thru_hole rect (at 7.5 8.1) (size 3.2 2) (drill oval 2.8 1.5) (layers *.Cu *.Mask)) 55 | (pad S2 thru_hole circle (at 14.5 0) (size 2 2) (drill 1) (layers *.Cu *.Mask)) 56 | (pad S1 thru_hole circle (at 14.5 5) (size 2 2) (drill 1) (layers *.Cu *.Mask)) 57 | (model ${KISYS3DMOD}/Rotary_Encoder.3dshapes/RotaryEncoder_Alps_EC11E-Switch_Vertical_H20mm.wrl 58 | (at (xyz 0 0 0)) 59 | (scale (xyz 1 1 1)) 60 | (rotate (xyz 0 0 0)) 61 | ) 62 | ) 63 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/Diode-dual.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "Diode-dual" (version 20221018) (generator pcbnew) 2 | (layer "F.Cu") 3 | (attr smd) 4 | (fp_text reference "D**" (at -0.0254 1.4) (layer "F.SilkS") 5 | (effects (font (size 0.8 0.8) (thickness 0.15))) 6 | (tstamp 89e9beaa-84ee-40e8-8d92-eaf98b38a9dd) 7 | ) 8 | (fp_text value "D" (at 0 -1.925) (layer "F.SilkS") hide 9 | (effects (font (size 0.8 0.8) (thickness 0.15))) 10 | (tstamp 070c6ac3-9fa5-4850-b4ba-cc61c625abb8) 11 | ) 12 | (fp_line (start -2.286 -0.762) (end -2.286 0.762) 13 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp e421fba9-c9c2-4df7-90fc-dd86a3cd1504)) 14 | (fp_line (start -2.286 0.762) (end -2.032 0.762) 15 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 0d251e07-71ac-4ae3-a0f7-94ec4accabe1)) 16 | (fp_line (start -2.159 0.762) (end 2.921 0.762) 17 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp abf3028d-7209-432b-b7bb-a0b7eaa79757)) 18 | (fp_line (start -0.2952 -0.373) (end 0.3048 0.027) 19 | (stroke (width 0.2) (type solid)) (layer "F.SilkS") (tstamp 3a0f06cc-f046-4fd6-85aa-45df8856f311)) 20 | (fp_line (start -0.2952 0.027) (end -0.5952 0.027) 21 | (stroke (width 0.2) (type solid)) (layer "F.SilkS") (tstamp 1ca19d03-7316-48c0-87a9-2eb0432eed7d)) 22 | (fp_line (start -0.2952 0.377) (end -0.2952 -0.373) 23 | (stroke (width 0.2) (type solid)) (layer "F.SilkS") (tstamp 29f55586-2097-4a0a-b426-47840b12c8fc)) 24 | (fp_line (start 0.3048 0.027) (end -0.2952 0.377) 25 | (stroke (width 0.2) (type solid)) (layer "F.SilkS") (tstamp 301d3d14-70aa-4b42-b7f6-a0d1fceeab56)) 26 | (fp_line (start 0.3048 0.027) (end 0.6048 0.027) 27 | (stroke (width 0.2) (type solid)) (layer "F.SilkS") (tstamp bc236164-5f58-4605-8b27-3452e541cada)) 28 | (fp_line (start 0.3048 0.377) (end 0.3048 -0.373) 29 | (stroke (width 0.2) (type solid)) (layer "F.SilkS") (tstamp c0a29a05-357f-43d1-9a34-a834ad3ed0c8)) 30 | (fp_line (start 2.286 0.762) (end 2.286 -0.762) 31 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 64eba968-9d48-4557-a188-a228a6458787)) 32 | (fp_line (start 2.413 -0.762) (end 2.413 0.762) 33 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 97fd7d31-678b-44f7-94b3-a6dbc8e2f182)) 34 | (fp_line (start 2.54 0.762) (end 2.54 -0.762) 35 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 0c6fec6c-34dd-47ec-a6bd-46a2bbbf10aa)) 36 | (fp_line (start 2.667 -0.762) (end 2.667 0.762) 37 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 109a4694-154b-4660-b557-a9872a22bcf1)) 38 | (fp_line (start 2.794 0.762) (end 2.794 -0.762) 39 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp ae329257-37d5-43c3-9759-ce77b26ddd44)) 40 | (fp_line (start 2.921 -0.762) (end -2.286 -0.762) 41 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 79bc4e25-69ec-493f-bdf4-592f01af9f21)) 42 | (fp_line (start 2.921 0.762) (end 2.921 -0.762) 43 | (stroke (width 0.15) (type solid)) (layer "F.SilkS") (tstamp 0f7a212b-a487-46e3-8a9a-73aa78b3787f)) 44 | (pad "1" smd rect (at 1.4 0) (size 1.6 1.2) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp f37c6185-8568-41f3-8bd0-abae3551a6ad)) 45 | (pad "1" smd rect (at 2.5 0) (size 2.9 0.5) (layers "F.Cu") (tstamp 2f6ac8f8-0dac-4b3a-ac6c-ea098d585e18)) 46 | (pad "1" thru_hole rect (at 3.9 0) (size 1.6 1.6) (drill 1) (layers "*.Cu" "*.Mask") (tstamp 2027144f-771f-46c3-b6ca-52c6c8df2d36)) 47 | (pad "2" thru_hole circle (at -3.9 0) (size 1.6 1.6) (drill 1) (layers "*.Cu" "*.Mask") (tstamp a8001b0a-90f4-41c0-9e90-7de61cb33a20)) 48 | (pad "2" smd rect (at -2.5 0) (size 2.9 0.5) (layers "F.Cu") (tstamp 01d4e3ad-61fc-4426-affa-e230f9fb216f)) 49 | (pad "2" smd rect (at -1.4 0) (size 1.6 1.2) (layers "F.Cu" "F.Paste" "F.Mask") (tstamp 667fee13-a73e-466d-9065-50dae901870f)) 50 | (group "" (id 99aa8e96-7622-4087-ae23-388a4bd424e6) 51 | (members 52 | 1ca19d03-7316-48c0-87a9-2eb0432eed7d 53 | 29f55586-2097-4a0a-b426-47840b12c8fc 54 | 301d3d14-70aa-4b42-b7f6-a0d1fceeab56 55 | 3a0f06cc-f046-4fd6-85aa-45df8856f311 56 | bc236164-5f58-4605-8b27-3452e541cada 57 | c0a29a05-357f-43d1-9a34-a834ad3ed0c8 58 | ) 59 | ) 60 | (model "${KICAD6_3DMODEL_DIR}/Diode_THT.3dshapes/D_DO-35_SOD27_P7.62mm_Horizontal.wrl" 61 | (offset (xyz 3.81 0 -0.4)) 62 | (scale (xyz 1 1 1)) 63 | (rotate (xyz 0 0 180)) 64 | ) 65 | ) 66 | -------------------------------------------------------------------------------- /gerber/ch55p34-NPTH.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ; DRILL file {KiCad 7.0.1} date Fri Jan 5 17:15:05 2024 3 | ; FORMAT={-:-/ absolute / metric / decimal} 4 | ; #@! TF.CreationDate,2024-01-05T17:15:05-05:00 5 | ; #@! TF.GenerationSoftware,Kicad,Pcbnew,7.0.1 6 | ; #@! TF.FileFunction,NonPlated,1,2,NPTH 7 | FMAT,2 8 | METRIC 9 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 10 | T1C0.650 11 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 12 | T2C1.702 13 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 14 | T3C3.000 15 | ; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill 16 | T4C3.988 17 | % 18 | G90 19 | G05 20 | T1 21 | X153.064Y-40.11 22 | X158.844Y-40.11 23 | T2 24 | X47.284Y-77.895 25 | X52.215Y-59.494 26 | X57.098Y-80.524 27 | X57.145Y-41.093 28 | X62.028Y-62.123 29 | X66.959Y-43.722 30 | X68.775Y-71.294 31 | X73.705Y-52.893 32 | X78.589Y-73.924 33 | X78.636Y-34.492 34 | X83.519Y-55.523 35 | X88.45Y-37.122 36 | X88.753Y-70.336 37 | X93.684Y-51.935 38 | X96.413Y-111.789 39 | X98.567Y-72.966 40 | X98.614Y-33.534 41 | X103.498Y-54.565 42 | X105.621Y-116.083 43 | X105.839Y-80.174 44 | X108.428Y-36.164 45 | X110.77Y-61.773 46 | X115.653Y-82.803 47 | X115.7Y-43.372 48 | X117.916Y-117.103 49 | X120.584Y-64.402 50 | X123.254Y-88.784 51 | X125.514Y-46.001 52 | X126.715Y-122.183 53 | X128.185Y-70.383 54 | X133.068Y-91.414 55 | X133.115Y-51.982 56 | X137.999Y-73.013 57 | X142.929Y-54.612 58 | X168.729Y-54.612 59 | X173.659Y-73.013 60 | X178.543Y-51.982 61 | X178.59Y-91.414 62 | X183.473Y-70.383 63 | X184.943Y-122.183 64 | X186.144Y-46.001 65 | X188.404Y-88.784 66 | X191.074Y-64.402 67 | X193.742Y-117.103 68 | X195.958Y-43.372 69 | X196.005Y-82.803 70 | X200.888Y-61.773 71 | X203.23Y-36.164 72 | X205.819Y-80.174 73 | X206.037Y-116.083 74 | X208.16Y-54.565 75 | X213.044Y-33.534 76 | X213.091Y-72.966 77 | X215.245Y-111.789 78 | X217.974Y-51.935 79 | X222.905Y-70.336 80 | X223.208Y-37.122 81 | X228.139Y-55.523 82 | X233.022Y-34.492 83 | X233.069Y-73.924 84 | X237.953Y-52.893 85 | X242.883Y-71.294 86 | X244.699Y-43.722 87 | X249.63Y-62.123 88 | X254.513Y-41.093 89 | X254.56Y-80.524 90 | X259.443Y-59.494 91 | X264.374Y-77.895 92 | T3 93 | X49.168Y-75.77 94 | X54.099Y-57.369 95 | X55.959Y-74.96 96 | X59.029Y-38.968 97 | X60.89Y-56.559 98 | X65.82Y-38.158 99 | X70.659Y-69.169 100 | X75.589Y-50.768 101 | X77.45Y-68.359 102 | X80.52Y-32.367 103 | X82.38Y-49.958 104 | X87.311Y-31.557 105 | X90.637Y-68.211 106 | X95.568Y-49.81 107 | X97.429Y-67.401 108 | X98.637Y-110.024 109 | X100.499Y-31.41 110 | X102.359Y-49.001 111 | X105.466Y-110.405 112 | X107.29Y-30.6 113 | X107.724Y-78.049 114 | X112.654Y-59.648 115 | X114.515Y-77.239 116 | X117.585Y-41.247 117 | X119.445Y-58.838 118 | X120.286Y-115.538 119 | X124.376Y-40.437 120 | X125.138Y-86.659 121 | X127.055Y-116.513 122 | X130.069Y-68.259 123 | X131.929Y-85.85 124 | X134.999Y-49.858 125 | X136.86Y-67.449 126 | X141.79Y-49.048 127 | X169.298Y-51.83 128 | X174.229Y-70.231 129 | X174.774Y-47.733 130 | X179.159Y-88.632 131 | X179.705Y-66.134 132 | X184.636Y-84.535 133 | X184.773Y-119.348 134 | X186.713Y-43.219 135 | X189.002Y-113.973 136 | X191.644Y-61.62 137 | X192.189Y-39.122 138 | X196.574Y-80.021 139 | X197.12Y-57.523 140 | X202.05Y-75.924 141 | X203.799Y-33.382 142 | X206.115Y-113.244 143 | X208.73Y-51.783 144 | X209.275Y-29.285 145 | X210.796Y-108.258 146 | X213.66Y-70.184 147 | X214.206Y-47.686 148 | X219.136Y-66.087 149 | X223.778Y-34.34 150 | X228.708Y-52.74 151 | X229.254Y-30.243 152 | X233.639Y-71.141 153 | X234.185Y-48.644 154 | X239.115Y-67.044 155 | X245.268Y-40.94 156 | X250.199Y-59.341 157 | X250.745Y-36.843 158 | X255.129Y-77.742 159 | X255.675Y-55.244 160 | X260.606Y-73.645 161 | T4 162 | X52.191Y-79.209 163 | X57.121Y-60.809 164 | X62.052Y-42.408 165 | X73.682Y-72.609 166 | X78.612Y-54.208 167 | X83.543Y-35.807 168 | X93.66Y-71.651 169 | X98.591Y-53.25 170 | X101.017Y-113.936 171 | X103.521Y-34.849 172 | X110.746Y-81.488 173 | X115.677Y-63.087 174 | X120.607Y-44.687 175 | X122.315Y-119.643 176 | X128.161Y-90.099 177 | X133.092Y-71.698 178 | X138.022Y-53.297 179 | X173.636Y-53.297 180 | X178.566Y-71.698 181 | X183.497Y-90.099 182 | X189.343Y-119.643 183 | X191.051Y-44.687 184 | X195.981Y-63.087 185 | X200.912Y-81.488 186 | X208.137Y-34.849 187 | X210.641Y-113.936 188 | X213.067Y-53.25 189 | X217.998Y-71.651 190 | X228.115Y-35.807 191 | X233.046Y-54.208 192 | X237.976Y-72.609 193 | X249.606Y-42.408 194 | X254.537Y-60.809 195 | X259.467Y-79.209 196 | T0 197 | M30 198 | -------------------------------------------------------------------------------- /PIP/ch55p34-top-pos.csv: -------------------------------------------------------------------------------- 1 | Designator,Val,Package,Mid X,Mid Y,Rotation,Layer 2 | C1,100n,C_0805_2012Metric,153.924,-53.848,-90,top 3 | C2,100n,C_0805_2012Metric,157.226,-57.658,-90,top 4 | C3,100n,C_0805_2012Metric,153.924,-57.658,-90,top 5 | D1,1N4448W,D_SOD-123,144.526,-73.786,90,top 6 | D2,1N4448W,D_SOD-123,147.066,-73.786,90,top 7 | D3,1N4448W,D_SOD-123,149.606,-73.786,90,top 8 | D4,1N4448W,D_SOD-123,152.146,-73.786,90,top 9 | D5,1N4448W,D_SOD-123,154.686,-73.786,90,top 10 | D6,1N4448W,D_SOD-123,157.226,-73.786,90,top 11 | D7,1N4448W,D_SOD-123,159.766,-73.786,90,top 12 | D8,1N4448W,D_SOD-123,162.306,-73.786,90,top 13 | D9,1N4448W,D_SOD-123,164.846,-73.786,90,top 14 | D10,1N4448W,D_SOD-123,167.386,-73.786,90,top 15 | D11,1N4448W,D_SOD-123,144.526,-85.978,90,top 16 | D12,1N4448W,D_SOD-123,147.066,-85.978,90,top 17 | D13,1N4448W,D_SOD-123,149.606,-85.978,90,top 18 | D14,1N4448W,D_SOD-123,152.146,-85.978,90,top 19 | D15,1N4448W,D_SOD-123,154.686,-85.978,90,top 20 | D16,1N4448W,D_SOD-123,157.226,-85.978,90,top 21 | D17,1N4448W,D_SOD-123,159.766,-85.978,90,top 22 | D18,1N4448W,D_SOD-123,162.306,-85.978,90,top 23 | D19,1N4448W,D_SOD-123,164.846,-85.978,90,top 24 | D20,1N4448W,D_SOD-123,167.386,-85.978,90,top 25 | D21,1N4448W,D_SOD-123,144.526,-98.934,90,top 26 | D22,1N4448W,D_SOD-123,147.066,-98.934,90,top 27 | D23,1N4448W,D_SOD-123,149.606,-98.934,90,top 28 | D24,1N4448W,D_SOD-123,152.146,-98.934,90,top 29 | D25,1N4448W,D_SOD-123,154.686,-98.934,90,top 30 | D26,1N4448W,D_SOD-123,157.226,-98.934,90,top 31 | D27,1N4448W,D_SOD-123,159.766,-98.934,90,top 32 | D28,1N4448W,D_SOD-123,162.306,-98.934,90,top 33 | D29,1N4448W,D_SOD-123,164.846,-98.934,90,top 34 | D30,1N4448W,D_SOD-123,167.386,-98.934,90,top 35 | D31,1N4448W,D_SOD-123,152.146,-105.918,90,top 36 | D32,1N4448W,D_SOD-123,154.686,-105.918,90,top 37 | D33,1N4448W,D_SOD-123,157.226,-105.918,90,top 38 | D34,1N4448W,D_SOD-123,159.766,-105.918,90,top 39 | J1,USB_C_Receptacle_USB2.0,USB_C_Receptacle_HRO_TYPE-C-31-M-12,155.954,-37.51,180,top 40 | J2,Conn_01x02_Pin,PinHeader_1x02_P2.54mm_Vertical,167.391,-44.196,-90,top 41 | J3,Conn_01x02_Pin,PinHeader_1x02_P2.54mm_Vertical,145.029,-43.942,90,top 42 | R1,5.1k,R_0805_2012Metric,153.924,-45.974,-90,top 43 | R2,5.1k,R_0805_2012Metric,157.226,-45.974,-90,top 44 | R3,330R,R_0805_2012Metric,153.924,-49.784,-90,top 45 | R4,10K,R_0805_2012Metric,157.226,-49.784,-90,top 46 | SW1,SW_PUSH,Kailh_socket_MX,62.051965,-42.407664,-15,top 47 | SW2,SW_PUSH,Kailh_socket_MX,83.542633,-35.806944,-15,top 48 | SW3,SW_PUSH,Kailh_socket_MX,103.521281,-34.849163,-15,top 49 | SW4,SW_PUSH,Kailh_socket_MX,120.607367,-44.686569,-15,top 50 | SW5,SW_PUSH,Kailh_socket_MX,138.022154,-53.297249,-15,top 51 | SW6,SW_PUSH,Kailh_socket_MX,173.635846,-53.297249,15,top 52 | SW7,SW_PUSH,Kailh_socket_MX,191.050633,-44.686569,15,top 53 | SW8,SW_PUSH,Kailh_socket_MX,208.136719,-34.849163,15,top 54 | SW9,SW_PUSH,Kailh_socket_MX,228.115367,-35.806944,15,top 55 | SW10,SW_PUSH,Kailh_socket_MX,249.606035,-42.407664,15,top 56 | SW11,SW_PUSH,Kailh_socket_MX,57.121462,-60.808551,-15,top 57 | SW12,SW_PUSH,Kailh_socket_MX,78.61213,-54.207831,-15,top 58 | SW13,SW_PUSH,Kailh_socket_MX,98.590778,-53.25005,-15,top 59 | SW14,SW_PUSH,Kailh_socket_MX,115.676865,-63.087456,-15,top 60 | SW15,SW_PUSH,Kailh_socket_MX,133.091651,-71.698136,-15,top 61 | SW16,SW_PUSH,Kailh_socket_MX,178.566349,-71.698136,15,top 62 | SW17,SW_PUSH,Kailh_socket_MX,195.981135,-63.087456,15,top 63 | SW18,SW_PUSH,Kailh_socket_MX,213.067222,-53.25005,15,top 64 | SW19,SW_PUSH,Kailh_socket_MX,233.045869,-54.207831,15,top 65 | SW20,SW_PUSH,Kailh_socket_MX,254.536538,-60.808551,15,top 66 | SW21,SW_PUSH,Kailh_socket_MX,52.190959,-79.209438,-15,top 67 | SW22,SW_PUSH,Kailh_socket_MX,73.681628,-72.608718,-15,top 68 | SW23,SW_PUSH,Kailh_socket_MX,93.660276,-71.650937,-15,top 69 | SW24,SW_PUSH,Kailh_socket_MX,110.746362,-81.488343,-15,top 70 | SW25,SW_PUSH,Kailh_socket_MX,128.161148,-90.099023,-15,top 71 | SW26,SW_PUSH,Kailh_socket_MX,183.496852,-90.099023,15,top 72 | SW27,SW_PUSH,Kailh_socket_MX,200.911638,-81.488343,15,top 73 | SW28,SW_PUSH,Kailh_socket_MX,217.997724,-71.650937,15,top 74 | SW29,SW_PUSH,Kailh_socket_MX,237.976372,-72.608718,15,top 75 | SW30,SW_PUSH,Kailh_socket_MX,259.467041,-79.209438,15,top 76 | SW31,SW_PUSH,Kailh_socket_MX,101.016823,-113.935773,-25,top 77 | SW32,SW_PUSH,Kailh_socket_MX,122.315488,-119.642732,-30,top 78 | SW33,SW_PUSH,Kailh_socket_MX,189.342512,-119.642732,30,top 79 | SW34,SW_PUSH,Kailh_socket_MX,210.641177,-113.935772,25,top 80 | U1,CH552T,TSSOP-20_4.4x6.5mm_P0.65mm,156.178,-64.594,0,top 81 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/Resistor-Hybrid_Reversible.kicad_mod: -------------------------------------------------------------------------------- 1 | (module Resistor-Hybrid_Reversible (layer F.Cu) (tedit 61B5F676) 2 | (attr smd) 3 | (fp_text reference R** (at -0.0254 1.5) (layer F.SilkS) 4 | (effects (font (size 0.8 0.8) (thickness 0.15))) 5 | ) 6 | (fp_text value R (at 0 -1.925) (layer F.SilkS) hide 7 | (effects (font (size 0.8 0.8) (thickness 0.15))) 8 | ) 9 | (fp_line (start -2.794 -0.762) (end -2.54 -1.016) (layer F.SilkS) (width 0.15)) 10 | (fp_line (start -2.54 -1.016) (end -2.286 -1.016) (layer F.SilkS) (width 0.15)) 11 | (fp_line (start -2.286 -1.016) (end -2.032 -0.762) (layer F.SilkS) (width 0.15)) 12 | (fp_line (start -2.032 -0.762) (end 2.032 -0.762) (layer F.SilkS) (width 0.15)) 13 | (fp_line (start 2.032 -0.762) (end 2.286 -1.016) (layer F.SilkS) (width 0.15)) 14 | (fp_line (start 2.286 -1.016) (end 2.54 -1.016) (layer F.SilkS) (width 0.15)) 15 | (fp_line (start 2.54 -1.016) (end 2.794 -0.762) (layer F.SilkS) (width 0.15)) 16 | (fp_line (start 2.794 -0.762) (end 2.794 0.762) (layer F.SilkS) (width 0.15)) 17 | (fp_line (start 2.794 0.762) (end 2.54 1.016) (layer F.SilkS) (width 0.15)) 18 | (fp_line (start 2.54 1.016) (end 2.286 1.016) (layer F.SilkS) (width 0.15)) 19 | (fp_line (start 2.286 1.016) (end 2.032 0.762) (layer F.SilkS) (width 0.15)) 20 | (fp_line (start 2.032 0.762) (end -2.032 0.762) (layer F.SilkS) (width 0.15)) 21 | (fp_line (start -2.032 0.762) (end -2.286 1.016) (layer F.SilkS) (width 0.15)) 22 | (fp_line (start -2.286 1.016) (end -2.54 1.016) (layer F.SilkS) (width 0.15)) 23 | (fp_line (start -2.54 1.016) (end -2.794 0.762) (layer F.SilkS) (width 0.15)) 24 | (fp_line (start -2.794 0.762) (end -2.794 -0.762) (layer F.SilkS) (width 0.15)) 25 | (fp_line (start -3.302 0) (end -2.794 0) (layer F.SilkS) (width 0.15)) 26 | (fp_line (start 2.794 0) (end 3.302 0) (layer F.SilkS) (width 0.15)) 27 | (fp_line (start 2.032 0.762) (end 2.286 1.016) (layer B.SilkS) (width 0.15)) 28 | (fp_line (start 2.794 0) (end 3.302 0) (layer B.SilkS) (width 0.15)) 29 | (fp_line (start 2.032 -0.762) (end -2.032 -0.762) (layer B.SilkS) (width 0.15)) 30 | (fp_line (start -2.54 1.016) (end -2.286 1.016) (layer B.SilkS) (width 0.15)) 31 | (fp_line (start 2.794 -0.762) (end 2.54 -1.016) (layer B.SilkS) (width 0.15)) 32 | (fp_line (start 2.286 1.016) (end 2.54 1.016) (layer B.SilkS) (width 0.15)) 33 | (fp_line (start 2.54 1.016) (end 2.794 0.762) (layer B.SilkS) (width 0.15)) 34 | (fp_line (start -2.032 -0.762) (end -2.286 -1.016) (layer B.SilkS) (width 0.15)) 35 | (fp_line (start 2.54 -1.016) (end 2.286 -1.016) (layer B.SilkS) (width 0.15)) 36 | (fp_line (start -2.54 -1.016) (end -2.794 -0.762) (layer B.SilkS) (width 0.15)) 37 | (fp_line (start 2.794 0.762) (end 2.794 -0.762) (layer B.SilkS) (width 0.15)) 38 | (fp_line (start -2.286 1.016) (end -2.032 0.762) (layer B.SilkS) (width 0.15)) 39 | (fp_line (start -3.302 0) (end -2.794 0) (layer B.SilkS) (width 0.15)) 40 | (fp_line (start -2.286 -1.016) (end -2.54 -1.016) (layer B.SilkS) (width 0.15)) 41 | (fp_line (start -2.794 0.762) (end -2.54 1.016) (layer B.SilkS) (width 0.15)) 42 | (fp_line (start -2.032 0.762) (end 2.032 0.762) (layer B.SilkS) (width 0.15)) 43 | (fp_line (start 2.286 -1.016) (end 2.032 -0.762) (layer B.SilkS) (width 0.15)) 44 | (fp_line (start -2.794 -0.762) (end -2.794 0.762) (layer B.SilkS) (width 0.15)) 45 | (fp_text user %R (at 0 1.524) (layer B.SilkS) 46 | (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)) 47 | ) 48 | (pad 2 smd rect (at -2.5 0) (size 2.9 0.5) (layers B.Cu) 49 | (solder_mask_margin -999)) 50 | (pad 2 smd rect (at -1.35 0) (size 1.5 1.2) (layers B.Cu B.Paste B.Mask)) 51 | (pad 1 smd rect (at 1.35 0) (size 1.5 1.2) (layers B.Cu B.Paste B.Mask)) 52 | (pad 1 smd rect (at 2.5 0) (size 2.9 0.5) (layers B.Cu) 53 | (solder_mask_margin -999)) 54 | (pad 1 smd rect (at 1.35 0) (size 1.5 1.2) (layers F.Cu F.Paste F.Mask)) 55 | (pad 2 smd rect (at -1.35 0) (size 1.5 1.2) (layers F.Cu F.Paste F.Mask)) 56 | (pad 2 thru_hole circle (at -3.9 0) (size 1.6 1.6) (drill 1) (layers *.Cu *.Mask F.SilkS)) 57 | (pad 1 thru_hole circle (at 3.9 0) (size 1.6 1.6) (drill 1) (layers *.Cu *.Mask)) 58 | (pad 2 smd rect (at -2.5 0) (size 2.9 0.5) (layers F.Cu) 59 | (solder_mask_margin -999)) 60 | (pad 1 smd rect (at 2.5 0) (size 2.9 0.5) (layers F.Cu) 61 | (solder_mask_margin -999)) 62 | (model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl 63 | (at (xyz 0 0 0)) 64 | (scale (xyz 1 1 1)) 65 | (rotate (xyz 0 0 0)) 66 | ) 67 | ) 68 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/keycode.ncl: -------------------------------------------------------------------------------- 1 | let util = import "util_functions.ncl" in 2 | let hid_codes = import "hid_codes.ncl" in 3 | 4 | let mod_ = fun K => let K = fun mod => K { mods."%{mod}" = true } in { 5 | lctl = K "left_ctrl", 6 | lsft = K "left_shift", 7 | lalt = K "left_alt", 8 | lgui = K "left_gui", 9 | rctl = K "right_ctrl", 10 | rsft = K "right_shift", 11 | ralt = K "right_alt", 12 | rgui = K "right_gui", 13 | } in 14 | 15 | { 16 | tap = let 17 | K = fun t d => { type = 'hold_tap, data.tap = { type = t, data = d } } 18 | in { 19 | none = K 'none {}, 20 | reg = { 21 | kc = let _K = fun x => K 'regular { hid_code = x } in 22 | hid_codes 23 | |> util.array.enumerate 24 | |> std.array.flat_map (fun { index, value } => 25 | value 26 | |> std.array.map (fun v => { "%{v}" = _K index }) 27 | ) 28 | |> std.array.reduce_left (&), 29 | mod = mod_ (K 'regular), 30 | ks = { 31 | CIRC = kc.N6, 32 | DLR = kc.N4, 33 | TILD = kc.GRV, 34 | PIPE = kc.BSLS, 35 | PERC = kc.N5, 36 | AMPR = kc.N7, 37 | ASTR = kc.N8, 38 | HASH = kc.N3, 39 | AT = kc.N2, 40 | DQUO = kc.QUOT, 41 | LCBR = kc.LBRC, 42 | RCBR = kc.RBRC, 43 | LPRN = kc.N9, 44 | RPRN = kc.N0, 45 | LABK = kc.COMM, 46 | RABK = kc.DOT, 47 | QUES = kc.SLSH, 48 | UNDS = kc.MINS, 49 | PLUS = kc.EQL, 50 | COLN = kc.SCLN, 51 | EXLM = kc.N1, 52 | } 53 | |> std.record.map_values ((&) mod.lsft), 54 | }, 55 | sticky = { 56 | mod = mod_ (K 'sticky), 57 | }, 58 | layer = let K = fun i op => K 'layer { layer = i, operation = op } in { 59 | DF = fun i => K i 'df, 60 | TG = fun i => K i 'tog, 61 | TO = fun i => K i 'to, 62 | }, 63 | custom = let K = fun t c => K 'custom { type = t, data.code = c } in { 64 | fak = let K = fun code => K 'fak code in { 65 | RESET = K 0, 66 | BOOT = K 1, 67 | CWON = K 2, 68 | CWOFF = K 3, 69 | CWTG = K 4, 70 | }, 71 | media = let K = fun code => K 'consumer code in { 72 | PLAY = K 205, 73 | MUTE = K 226, 74 | VOLU = K 233, 75 | VOLD = K 234, 76 | NEXT = K 181, 77 | PREV = K 182, 78 | }, 79 | mouse = let K = fun code => K 'mouse code in { 80 | BTN1 = K 0, 81 | BTN2 = K 1, 82 | BTN3 = K 2, 83 | BTN4 = K 3, 84 | BTN5 = K 4, 85 | BTN6 = K 5, 86 | BTN7 = K 6, 87 | BTN8 = K 7, 88 | RGHT = K 8, 89 | LEFT = K 9, 90 | DOWN = K 10, 91 | UP = K 11, 92 | WH_U = K 12, 93 | WH_D = K 13, 94 | }, 95 | }, 96 | trans = K 'transparent {}, 97 | }, 98 | 99 | hold = let 100 | K = fun t d => { type = 'hold_tap, data.hold = { type = t, data = d } } 101 | in { 102 | none = K 'none {}, 103 | reg = { 104 | behavior = fun b => K 'regular { behavior = b }, 105 | layer = fun i => K 'regular { layer = i }, 106 | mod = mod_ (K 'regular), 107 | }, 108 | nop = fun b => K 'nop { behavior = b }, 109 | trans = K 'transparent {} 110 | }, 111 | 112 | td = { 113 | make = fun t b => { 114 | type = 'tap_dance, 115 | data = { 116 | tapping_term_ms = t, 117 | bindings = b 118 | } 119 | } 120 | }, 121 | 122 | combo = { 123 | make = fun t k => { 124 | type = 'combo, 125 | data = { 126 | timeout_ms = t, 127 | key_indices = k, 128 | }, 129 | }, 130 | slow_release = { data.slow_release = true }, 131 | require_prior_idle_ms = fun ms => { data.require_prior_idle_ms = ms }, 132 | }, 133 | 134 | macro = { 135 | make = fun steps => { 136 | type = 'hold_tap, 137 | data.tap = { 138 | type = 'custom, 139 | data = { 140 | type = 'macro, 141 | data.steps = steps, 142 | }, 143 | }, 144 | }, 145 | press = fun kc => { inst = 'press, arg.keycode = kc }, 146 | release = fun kc => { inst = 'release, arg.keycode = kc }, 147 | tap = fun kc => { inst = 'tap, arg.keycode = kc }, 148 | wait = fun ms => { inst = 'wait, arg.duration_ms = ms }, 149 | }, 150 | 151 | MO = fun i => hold.reg.layer i, 152 | LT = fun b i tap => hold.reg.behavior b & hold.reg.layer i & tap, 153 | LM = fun b i mods tap => LT b i tap, 154 | DF = fun i => tap.layer.DF i, 155 | TG = fun i => tap.layer.TG i, 156 | TO = fun i => tap.layer.TO i, 157 | CTL_T = fun b tap => hold.reg.behavior b & hold.reg.mod.lctl & tap, 158 | } 159 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/zilpzalp/layouts.ncl: -------------------------------------------------------------------------------- 1 | let { tap, hold, .. } = import "../../fak/keycode.ncl" in 2 | let util = import "../../fak/util_functions.ncl" in 3 | 4 | let kc = tap.reg.kc in 5 | let ks = tap.reg.ks in 6 | let md = hold.reg.mod in 7 | let tm = tap.reg.mod in 8 | let me = tap.custom.media in 9 | let XXXX = tap.none & hold.none in 10 | 11 | let shared_layers = { 12 | NUM0 = [ 13 | XXXX, XXXX, XXXX, XXXX, ks.PLUS, kc.N7, kc.N8, kc.N9, 14 | md.lalt, md.lgui, md.lsft, XXXX, kc.MINS, kc.N4, kc.N5, kc.N6, 15 | md.lctl, XXXX, XXXX, XXXX, kc.N1, kc.N2, kc.N3, kc.SLSH, 16 | XXXX, XXXX, kc.E, kc.N0, 17 | ], 18 | NAV0 = [ 19 | XXXX, XXXX, XXXX, me.VOLD, me.VOLU, kc.BSPC, kc.DEL, kc.INS, 20 | md.lalt, md.lgui, md.lsft, me.MUTE, kc.LEFT, kc.DOWN, kc.UP, kc.RGHT, 21 | md.lctl, XXXX, XXXX, XXXX, kc.HOME, XXXX, kc.END, kc.TAB, 22 | XXXX, XXXX, XXXX, XXXX, 23 | ], 24 | NUM1 = [ 25 | kc.N9, kc.N8, kc.N7, ks.ASTR, ks.PLUS, kc.N7, kc.N8, kc.N9, 26 | kc.N6, kc.N5, kc.N4, kc.SLSH, kc.MINS, kc.N4, kc.N5, kc.N6, 27 | kc.N0, kc.N3, kc.N2, kc.N1, kc.N1, kc.N2, kc.N3, kc.DOT, 28 | XXXX, XXXX, kc.E, kc.N0, 29 | ], 30 | NAV1 = [ 31 | kc.INS, kc.UP, kc.BSPC, me.VOLD, me.VOLU, kc.BSPC, kc.DEL, kc.INS, 32 | kc.LEFT, kc.DOWN, kc.RGHT, me.MUTE, kc.LEFT, kc.DOWN, kc.UP, kc.RGHT, 33 | md.lctl, kc.HOME, kc.PGDN, kc.END, kc.HOME, kc.PGUP, kc.END, kc.TAB, 34 | XXXX, XXXX, XXXX, XXXX, 35 | ], 36 | SYM = [ 37 | kc.GRV, ks.DQUO, kc.DOT, kc.LBRC, kc.RBRC, kc.BSLS, ks.PIPE, kc.SLSH, 38 | ks.AT, ks.HASH, ks.DLR, ks.LPRN, ks.RPRN, ks.AMPR, ks.ASTR, ks.PERC, 39 | ks.EXLM, ks.TILD, kc.QUOT, ks.UNDS, kc.MINS, ks.PLUS, kc.EQL, kc.TAB, 40 | ks.LCBR, ks.RCBR, XXXX, XXXX, 41 | ], 42 | FUN = [ 43 | XXXX, XXXX, XXXX, XXXX, kc.F12, kc.F7, kc.F8, kc.F9, 44 | XXXX, XXXX, XXXX, XXXX, kc.F11, kc.F4, kc.F5, kc.F6, 45 | XXXX, XXXX, XXXX, XXXX, kc.F1, kc.F2, kc.F3, kc.F10, 46 | XXXX, XXXX, XXXX, XXXX, 47 | ], 48 | } in 49 | 50 | let both_side_combos = [ 51 | [kc.CAPS, 0, 7], 52 | # Caps word combo here once supported 53 | # [CW, 10, 13], 54 | ] in 55 | 56 | { 57 | qwerty = { 58 | base_layout = "WERTYUIOSDFGHJKLAXCVM,.P", 59 | thumbs = [kc.ESC, kc.SPC, kc.N, kc.ENT], 60 | combos = [ 61 | # Left 62 | [kc.Q, 0, 1], 63 | [kc.Z, 17, 18], [kc.B, 18, 19], 64 | # Right 65 | [kc.QUOT, 5, 6], [kc.SCLN, 6, 7], 66 | [kc.MINS, 20, 21], [kc.SLSH, 21, 22], 67 | ] @ both_side_combos, 68 | layers = { 69 | NUM = shared_layers.NUM0, 70 | NAV = shared_layers.NAV0, 71 | SYM = shared_layers.SYM, 72 | FUN = shared_layers.FUN, 73 | } 74 | }, 75 | 76 | colemak = { 77 | base_layout = "WFPKJLUYRSTGMNEIAXCDH,.O", 78 | thumbs = [kc.ESC, kc.SPC, kc.ENT, kc.BSPC], 79 | combos = [ 80 | # Left 81 | [kc.Q, 0, 1], [kc.B, 1, 2], 82 | [kc.Z, 17, 18], [kc.V, 18, 19], 83 | # Right 84 | [kc.QUOT, 5, 6], [kc.SCLN, 6, 7], 85 | [kc.MINS, 20, 21], [kc.SLSH, 21, 22], 86 | ] @ both_side_combos, 87 | layers = { 88 | NUM = shared_layers.NUM0, 89 | NAV = shared_layers.NAV0, 90 | SYM = shared_layers.SYM, 91 | FUN = shared_layers.FUN, 92 | } 93 | }, 94 | 95 | aptmak = { 96 | base_layout = "WFPBJLUYSTHKXNAIRCGDM,.O", 97 | thumbs = [kc.QUOT, kc.SPC, kc.E, kc.ENT], 98 | combos = [ 99 | # Left 100 | [kc.V, 0, 1], [kc.Q, 1, 2], 101 | [ks.LCBR, 0, 8], [kc.LBRC, 1, 9], [ks.LPRN, 2, 10], [ks.LABK, 3, 11], 102 | [kc.Z, 17, 18], [kc.ESC, 18, 19], 103 | # Right 104 | [tm.lctl & kc.BSPC, 5, 7], 105 | [kc.BSPC, 5, 6], [kc.DEL, 6, 7], 106 | [ks.RABK, 4, 12], [ks.RPRN, 5, 13], [kc.RBRC, 6, 14], [ks.RCBR, 7, 15], 107 | [kc.MINS, 20, 21], [kc.SLSH, 21, 22], 108 | ] @ both_side_combos, 109 | layers = { 110 | NUM = shared_layers.NUM1, 111 | NAV = shared_layers.NAV1, 112 | SYM = shared_layers.SYM, 113 | FUN = shared_layers.FUN, 114 | }, 115 | }, 116 | } 117 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SW_Cherry_MX_PCB_1.00u_BSilkRef.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "SW_Cherry_MX_PCB_1.00u_BSilkRef" (version 20221018) (generator pcbnew) 2 | (layer "F.Cu") 3 | (descr "Cherry MX keyswitch PCB Mount with 1.00u keycap") 4 | (tags "Cherry MX Keyboard Keyswitch Switch PCB Cutout 1.00u") 5 | (attr through_hole) 6 | (fp_text reference "REF**" (at 0 6) (layer "B.SilkS") 7 | (effects (font (size 0.8 0.8) (thickness 0.15)) (justify mirror)) 8 | (tstamp 6dd8e5c7-47e7-41c6-bdfe-e2177ff58bf4) 9 | ) 10 | (fp_text value "SW_Cherry_MX_PCB_1.00u_BSilkRef" (at 0 8) (layer "F.Fab") 11 | (effects (font (size 1 1) (thickness 0.15))) 12 | (tstamp 755beab4-e3bc-4d7c-a4f3-0a216c86aaa4) 13 | ) 14 | (fp_text user "${REFERENCE}" (at 0 0) (layer "F.Fab") 15 | (effects (font (size 1 1) (thickness 0.15))) 16 | (tstamp f8a30e99-62bd-4ea7-be3d-426eac3d393c) 17 | ) 18 | (fp_line (start -7.1 -7.1) (end -7.1 7.1) 19 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp bc2e35dc-b0e2-4395-97b8-157ef14fb963)) 20 | (fp_line (start -7.1 7.1) (end 7.1 7.1) 21 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 71afee85-7ead-4ae8-b1b7-71d4c2712a54)) 22 | (fp_line (start 7.1 -7.1) (end -7.1 -7.1) 23 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp d8bca9a0-285d-4af0-b0ab-0a3dfac19d48)) 24 | (fp_line (start 7.1 7.1) (end 7.1 -7.1) 25 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 2680acb7-b835-4496-82e3-653ce0ff0fae)) 26 | (fp_line (start -9.525 -9.525) (end -9.525 9.525) 27 | (stroke (width 0.1) (type solid)) (layer "Dwgs.User") (tstamp 9880dae4-687e-49fa-9b94-0ad4965bf2e9)) 28 | (fp_line (start -9.525 9.525) (end 9.525 9.525) 29 | (stroke (width 0.1) (type solid)) (layer "Dwgs.User") (tstamp bb208b15-69ff-4806-b50f-c3445277a8c7)) 30 | (fp_line (start 9.525 -9.525) (end -9.525 -9.525) 31 | (stroke (width 0.1) (type solid)) (layer "Dwgs.User") (tstamp 8b5db2b5-aac5-4845-8bda-8780abcd28d7)) 32 | (fp_line (start 9.525 9.525) (end 9.525 -9.525) 33 | (stroke (width 0.1) (type solid)) (layer "Dwgs.User") (tstamp 53f8f977-b80e-4d3e-b89a-fe0793f8d7b8)) 34 | (fp_line (start -7 -7) (end -7 7) 35 | (stroke (width 0.1) (type solid)) (layer "Eco1.User") (tstamp 26a15a41-e498-411b-a6b8-16db8e624bf5)) 36 | (fp_line (start -7 7) (end 7 7) 37 | (stroke (width 0.1) (type solid)) (layer "Eco1.User") (tstamp 4d15a077-6b67-4ea1-8184-ce6f8bea2627)) 38 | (fp_line (start 7 -7) (end -7 -7) 39 | (stroke (width 0.1) (type solid)) (layer "Eco1.User") (tstamp 448d53c7-10b4-4f89-a0c0-62e69270897c)) 40 | (fp_line (start 7 7) (end 7 -7) 41 | (stroke (width 0.1) (type solid)) (layer "Eco1.User") (tstamp a321ba94-d605-41ca-92a9-1f57a8c2f735)) 42 | (fp_line (start -7.25 -7.25) (end -7.25 7.25) 43 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp d9f7e0a9-496f-4d10-aaf4-71e95a39480d)) 44 | (fp_line (start -7.25 7.25) (end 7.25 7.25) 45 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 6e796982-7a12-478c-b43e-c63834beef37)) 46 | (fp_line (start 7.25 -7.25) (end -7.25 -7.25) 47 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 1276cc19-80fa-44fd-9912-d55ea79f20d9)) 48 | (fp_line (start 7.25 7.25) (end 7.25 -7.25) 49 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 7051e5b8-6ef8-429f-a7e0-8bdd3c592557)) 50 | (fp_line (start -7 -7) (end -7 7) 51 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp c80f07fa-19b5-4dad-8973-6f1cd5a50967)) 52 | (fp_line (start -7 7) (end 7 7) 53 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 108ab74d-1dda-467d-8a67-824cd91232b6)) 54 | (fp_line (start 7 -7) (end -7 -7) 55 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 268aca84-269a-48d4-8ebd-314e24696743)) 56 | (fp_line (start 7 7) (end 7 -7) 57 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 9d594acc-a768-4bd6-9050-43c88773356b)) 58 | (pad "" np_thru_hole circle (at -5.08 0) (size 1.75 1.75) (drill 1.75) (layers "*.Cu" "*.Mask") (tstamp e91bbcac-8dfe-4967-a267-22842ecfc510)) 59 | (pad "" smd circle (at -3.81 -2.54) (size 1.55 1.55) (layers "F.Mask") (tstamp ee93b531-66e0-409c-a60f-fd88b1152f7a)) 60 | (pad "" np_thru_hole circle (at 0 0) (size 4 4) (drill 4) (layers "*.Cu" "*.Mask") (tstamp f02373d5-99f0-4c67-b61d-cbc2fb7c1e61)) 61 | (pad "" smd circle (at 2.54 -5.08) (size 1.55 1.55) (layers "F.Mask") (tstamp 39e1f04f-9d1f-42c5-9d7f-6f2b8c228975)) 62 | (pad "" np_thru_hole circle (at 5.08 0) (size 1.75 1.75) (drill 1.75) (layers "*.Cu" "*.Mask") (tstamp 37b638fc-29e4-4832-acb1-83911e225f71)) 63 | (pad "1" thru_hole circle (at -3.81 -2.54) (size 2.5 2.5) (drill 1.5) (layers "*.Cu" "B.Mask") (tstamp 86d648ea-bd9b-487c-b206-03d0f90e93d8)) 64 | (pad "2" thru_hole circle (at 2.54 -5.08) (size 2.5 2.5) (drill 1.5) (layers "*.Cu" "B.Mask") (tstamp 1497c46c-4ac3-4229-978c-a2b40ff14145)) 65 | (model "${KIPRJMOD}/Switch_Keyboard/library/3dmodels/3d-library.3dshapes/SW_Cherry_MX_PCB.stp" 66 | (offset (xyz 0 0 0)) 67 | (scale (xyz 1 1 1)) 68 | (rotate (xyz 0 0 0)) 69 | ) 70 | ) 71 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/SW_Hotswap_Kailh.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "SW_Hotswap_Kailh" (version 20211014) (generator pcbnew) 2 | (layer "F.Cu") 3 | (tedit 62C7A812) 4 | (descr "Kailh keyswitch Hotswap Socket, ") 5 | (tags "Kailh Keyboard Keyswitch Switch Hotswap Socket") 6 | (attr smd) 7 | (fp_text reference "REF**" (at 0 -8) (layer "B.SilkS") 8 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 9 | (tstamp 5c738e6a-1cc9-4233-94c4-fbb3c6b5f798) 10 | ) 11 | (fp_text value "SW_Hotswap_Kailh" (at 0 0) (layer "B.Fab") 12 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 13 | (tstamp cb6766bd-94ae-4689-881d-0f421fda5966) 14 | ) 15 | (fp_text user "${REFERENCE}" (at 0 -4.75) (layer "B.Fab") 16 | (effects (font (size 1 1) (thickness 0.15)) (justify mirror)) 17 | (tstamp 2853758b-d7f5-4541-8d61-ec33f76a7baf) 18 | ) 19 | (fp_line (start -4.1 -6.9) (end 1 -6.9) (layer "B.SilkS") (width 0.12) (tstamp 0688165c-0667-40a9-8ccc-62b6ebba9fb5)) 20 | (fp_line (start -0.2 -2.7) (end 4.9 -2.7) (layer "B.SilkS") (width 0.12) (tstamp 3a536ef2-1104-4f34-b878-8f419296e242)) 21 | (fp_arc (start -2.2 -0.7) (mid -1.614214 -2.114214) (end -0.2 -2.7) (layer "B.SilkS") (width 0.12) (tstamp fdc04b8f-0ffd-4f7a-bdef-df2055dec38c)) 22 | (fp_arc (start -6.1 -4.9) (mid -5.514214 -6.314214) (end -4.1 -6.9) (layer "B.SilkS") (width 0.12) (tstamp fde38b97-ec2b-4dae-9258-83994cfb2855)) 23 | (fp_line (start -7.1 6.1) (end -7.1 7.1) (layer "F.SilkS") (width 0.12) (tstamp 0242b431-d86c-4fb1-a95a-69cfa12b6098)) 24 | (fp_line (start 7.1 7.1) (end 7.1 6.1) (layer "F.SilkS") (width 0.12) (tstamp 2eee146c-c203-4cdf-9226-cec02828455b)) 25 | (fp_line (start -6.1 7.1) (end -7.1 7.1) (layer "F.SilkS") (width 0.12) (tstamp 38da6768-fe2f-4f1d-9952-6e1e46c625e5)) 26 | (fp_line (start 7.1 -7.1) (end 7.1 -6.1) (layer "F.SilkS") (width 0.12) (tstamp 3d1da087-c7db-4a60-8eef-30998becd615)) 27 | (fp_line (start -7.1 -7.1) (end -7.1 -6.1) (layer "F.SilkS") (width 0.12) (tstamp 5830e5ae-ff6d-4410-994f-efe6833fcbeb)) 28 | (fp_line (start 6.1 -7.1) (end 7.1 -7.1) (layer "F.SilkS") (width 0.12) (tstamp a9c5139a-8fe0-42dd-a0a1-6e6c48eec862)) 29 | (fp_line (start 6.1 7.1) (end 7.1 7.1) (layer "F.SilkS") (width 0.12) (tstamp b617ff8f-d972-46f0-b2a7-bcdc2121587d)) 30 | (fp_line (start -6.1 -7.1) (end -7.1 -7.1) (layer "F.SilkS") (width 0.12) (tstamp f0e3b0fe-24de-40a0-9f8a-eb835160b0a4)) 31 | (fp_line (start 7.37 -0.55) (end 7.37 -7.05) (layer "B.CrtYd") (width 0.05) (tstamp 2c98fd5a-189c-4ab0-b50a-9c6c95a702d0)) 32 | (fp_line (start 7.37 -7.05) (end -8.61 -7.05) (layer "B.CrtYd") (width 0.05) (tstamp 61f14c1a-2973-472e-b28d-aaa23218a80b)) 33 | (fp_line (start -8.61 -0.55) (end 7.37 -0.55) (layer "B.CrtYd") (width 0.05) (tstamp 88f6c12c-e2f1-4962-b0d6-25dfbfdec1b1)) 34 | (fp_line (start -8.61 -7.05) (end -8.61 -0.55) (layer "B.CrtYd") (width 0.05) (tstamp 96e19753-cbff-44b9-8dba-28b6bb6ba969)) 35 | (fp_line (start -7.25 -7.25) (end -7.25 7.25) (layer "F.CrtYd") (width 0.05) (tstamp 05df103a-f39d-4178-b536-ac66a58cf533)) 36 | (fp_line (start 7.25 7.25) (end 7.25 -7.25) (layer "F.CrtYd") (width 0.05) (tstamp 3b202aaf-1b03-4546-855b-7a4354e1b6a0)) 37 | (fp_line (start 7.25 -7.25) (end -7.25 -7.25) (layer "F.CrtYd") (width 0.05) (tstamp 9ee5ee0a-cfec-4d97-8074-8a995bc7a938)) 38 | (fp_line (start -7.25 7.25) (end 7.25 7.25) (layer "F.CrtYd") (width 0.05) (tstamp d2ebe1a1-e39c-4660-a151-bddd7ea8056a)) 39 | (fp_line (start 4.8 -6.8) (end 4.8 -2.8) (layer "B.Fab") (width 0.12) (tstamp 697aef9e-14a8-47c9-a388-9e39ef217db7)) 40 | (fp_line (start -0.3 -2.8) (end 4.8 -2.8) (layer "B.Fab") (width 0.12) (tstamp a2f0480b-cd2d-4101-986e-ef65bb186094)) 41 | (fp_line (start -4 -6.8) (end 4.8 -6.8) (layer "B.Fab") (width 0.12) (tstamp a3931d16-fa6c-4dd7-841b-2cebf0c1f5ce)) 42 | (fp_line (start -6 -0.8) (end -6 -4.8) (layer "B.Fab") (width 0.12) (tstamp d2294368-54f2-49e9-8d56-eab722e1b007)) 43 | (fp_line (start -6 -0.8) (end -2.3 -0.8) (layer "B.Fab") (width 0.12) (tstamp e1493ac3-749b-46a8-9352-9c9a17ba592e)) 44 | (fp_arc (start -2.3 -0.8) (mid -1.714214 -2.214214) (end -0.3 -2.8) (layer "B.Fab") (width 0.12) (tstamp abc1d56c-60b6-4fb6-96d6-e2774297691a)) 45 | (fp_arc (start -6 -4.8) (mid -5.414214 -6.214214) (end -4 -6.8) (layer "B.Fab") (width 0.12) (tstamp c7705619-41bf-44b7-8301-7d37ff8f877a)) 46 | (fp_line (start -7 7) (end 7 7) (layer "F.Fab") (width 0.1) (tstamp 7239a413-52fa-4ae5-8bba-acfa94642ec8)) 47 | (fp_line (start 7 -7) (end -7 -7) (layer "F.Fab") (width 0.1) (tstamp a8cd2b31-d600-4560-9e7d-b765246818a8)) 48 | (fp_line (start -7 -7) (end -7 7) (layer "F.Fab") (width 0.1) (tstamp cc0b6a38-0622-4675-b50b-22e81e558b74)) 49 | (fp_line (start 7 7) (end 7 -7) (layer "F.Fab") (width 0.1) (tstamp f040f10c-430a-4974-8b2b-08bd0df051a3)) 50 | (pad "" np_thru_hole circle (at 5.08 0) (size 1.75 1.75) (drill 1.75) (layers *.Cu *.Mask) (tstamp 2e01d60c-5ffd-4105-be5c-28526b9e94f3)) 51 | (pad "" np_thru_hole circle (at -3.81 -2.54) (size 3 3) (drill 3) (layers *.Cu *.Mask) (tstamp 61fa8287-788e-46bc-9c1f-c6fe5286fecb)) 52 | (pad "" np_thru_hole circle (at 0 0) (size 4 4) (drill 4) (layers *.Cu *.Mask) (tstamp b8f1d0dd-7328-4161-afb9-c343b389599b)) 53 | (pad "" np_thru_hole circle (at -5.08 0) (size 1.75 1.75) (drill 1.75) (layers *.Cu *.Mask) (tstamp cca7d9f0-931b-487d-b1d9-8df79da1576a)) 54 | (pad "" np_thru_hole circle (at 2.54 -5.08) (size 3 3) (drill 3) (layers *.Cu *.Mask) (tstamp d0a21e27-3415-470d-b3c1-a4a0fff56f06)) 55 | (pad "1" smd rect (at -7.085 -2.54) (size 2.55 2.5) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp a1d18ed7-8f0c-417c-a723-dfd224496e94)) 56 | (pad "2" smd rect (at 5.842 -5.08) (size 2.55 2.5) (layers "B.Cu" "B.Paste" "B.Mask") (tstamp eff259d8-ff80-4654-bc5b-96d73a2a066c)) 57 | (model "${KIPRJMOD}/Switch_Keyboard/packages3d/Switch_Keyboard_Kailh.3dshapes/SW_Hotswap_Kailh.wrl" 58 | (offset (xyz 0 0 0)) 59 | (scale (xyz 1 1 1)) 60 | (rotate (xyz 0 0 0)) 61 | ) 62 | ) 63 | -------------------------------------------------------------------------------- /components-and-pretty/ProjectLocal.pretty/DIP-20_W15.24mm.kicad_mod: -------------------------------------------------------------------------------- 1 | (footprint "DIP-20_W15.24mm" (version 20221018) (generator pcbnew) 2 | (layer "F.Cu") 3 | (descr "24-lead though-hole mounted DIP package, row spacing 15.24 mm (600 mils)") 4 | (tags "THT DIP DIL PDIP 2.54mm 15.24mm 600mil") 5 | (attr through_hole) 6 | (fp_text reference "REF**" (at 7.62 -2.33) (layer "F.SilkS") 7 | (effects (font (size 1 1) (thickness 0.15))) 8 | (tstamp 47bd9a61-2a33-47a9-ada2-a05dee9a175b) 9 | ) 10 | (fp_text value "DIP-20_W15.24mm" (at 7.62 25.4) (layer "F.Fab") 11 | (effects (font (size 1 1) (thickness 0.15))) 12 | (tstamp 78144ba6-ea69-4438-bc9a-081c2c5e5bfb) 13 | ) 14 | (fp_text user "${REFERENCE}" (at 7.62 13.97) (layer "F.Fab") 15 | (effects (font (size 1 1) (thickness 0.15))) 16 | (tstamp bfd2f4b2-6383-4644-9773-44bc0454136d) 17 | ) 18 | (fp_line (start 1.16 -1.33) (end 1.16 24.13) 19 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0ae6af42-5372-46ae-909e-0e8f7b01d431)) 20 | (fp_line (start 1.16 24.13) (end 14.08 24.13) 21 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 06446477-8049-4a50-8874-f45493a37e51)) 22 | (fp_line (start 6.62 -1.33) (end 1.16 -1.33) 23 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 3232eaf4-1260-4ab5-9587-7266cefcefea)) 24 | (fp_line (start 14.08 -1.33) (end 8.62 -1.33) 25 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 0aeb00fe-a983-4377-85d3-6958f6ea251b)) 26 | (fp_line (start 14.08 24.13) (end 14.08 -1.33) 27 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp 5e04c1b2-08a9-43b4-853c-bcdb14580737)) 28 | (fp_arc (start 8.62 -1.33) (mid 7.62 -0.33) (end 6.62 -1.33) 29 | (stroke (width 0.12) (type solid)) (layer "F.SilkS") (tstamp f30d70ab-10cd-4d3c-8212-ac4cebea99fc)) 30 | (fp_line (start -1.055 24.13) (end 16.295 24.13) 31 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp c06b1d17-62f6-427a-a57a-51ad7803eb9f)) 32 | (fp_line (start -1.05 -1.55) (end -1.055 24.13) 33 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp bb2a1712-098d-4b1a-95a5-0fd7e427baaa)) 34 | (fp_line (start 16.295 24.13) (end 16.3 -1.55) 35 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 92e2dd27-bf28-4dd8-9233-1f00dfa4e6c3)) 36 | (fp_line (start 16.3 -1.55) (end -1.05 -1.55) 37 | (stroke (width 0.05) (type solid)) (layer "F.CrtYd") (tstamp 57091eeb-6d15-48d1-bdce-8753971bca90)) 38 | (fp_line (start 0.255 -0.27) (end 1.255 -1.27) 39 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp cff0ac41-d4c1-4e79-b888-6a79d678960e)) 40 | (fp_line (start 0.255 24.13) (end 0.255 -0.27) 41 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp f3f4b5ad-55bf-4a96-bfea-b77221b729fb)) 42 | (fp_line (start 1.255 -1.27) (end 14.985 -1.27) 43 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3a022399-d86f-4d63-828a-d16d8d7d9154)) 44 | (fp_line (start 14.985 -1.27) (end 14.985 24.13) 45 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 3b21466a-b64c-4004-aafb-313d5be4879f)) 46 | (fp_line (start 14.985 24.13) (end 0.255 24.13) 47 | (stroke (width 0.1) (type solid)) (layer "F.Fab") (tstamp 490aae59-f96e-4349-af0c-72922b3c9fc8)) 48 | (pad "1" thru_hole rect (at 0 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 1871a227-79c6-4dbd-8970-bc398da19cfe)) 49 | (pad "2" thru_hole oval (at 0 2.54) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp f3b9e1ef-9146-4808-94d0-a2226514c72b)) 50 | (pad "3" thru_hole oval (at 0 5.08) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 50feec52-e843-4132-921d-18b1267cfad0)) 51 | (pad "4" thru_hole oval (at 0 7.62) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 8690528a-0abd-4e76-9810-ea6589e38334)) 52 | (pad "5" thru_hole oval (at 0 10.16) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 72986864-bb7c-47c3-b580-2e238830806b)) 53 | (pad "6" thru_hole oval (at 0 12.7) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 06551a43-6be7-4fd9-8a4b-9e0278cd12e0)) 54 | (pad "7" thru_hole oval (at 0 15.24) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 5ca47d78-d769-4697-a1ab-0042e71abaf5)) 55 | (pad "8" thru_hole oval (at 0 17.78) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 17313b45-c1da-4a07-92c1-1c63787e75d3)) 56 | (pad "9" thru_hole oval (at 0 20.32) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 0976d798-2e1d-40e6-8077-b5c7244cf0c1)) 57 | (pad "10" thru_hole oval (at 0 22.86) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp da6dbfa5-7fdc-41e6-a7f1-5c9af6aff9aa)) 58 | (pad "11" thru_hole oval (at 15.24 22.86) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 8eb3ab2a-9274-4742-9253-588c06f6c10c)) 59 | (pad "12" thru_hole oval (at 15.24 20.32) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 4ca33d97-1ecd-4e50-9ae4-a40527c2dbc7)) 60 | (pad "13" thru_hole oval (at 15.24 17.78) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 3dde83fd-9141-469f-81d5-4666c8ace51a)) 61 | (pad "14" thru_hole oval (at 15.24 15.24) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 3310e537-4734-49d6-8738-deb8bf801678)) 62 | (pad "15" thru_hole oval (at 15.24 12.7) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp e19404d6-e2c2-484b-97f2-ff0aeb9442bb)) 63 | (pad "16" thru_hole oval (at 15.24 10.16) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 1acdd0ee-7de8-4016-a857-211f768d66f6)) 64 | (pad "17" thru_hole oval (at 15.24 7.62) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 314546cb-cb17-4993-9b95-9ac3c0cb8b97)) 65 | (pad "18" thru_hole oval (at 15.24 5.08) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 3d95cc17-f42f-4be8-bb81-7c1db1c14c51)) 66 | (pad "19" thru_hole oval (at 15.24 2.54) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 740fb463-3add-4679-bacd-2c3268aab88a)) 67 | (pad "20" thru_hole oval (at 15.24 0) (size 1.6 1.6) (drill 0.8) (layers "*.Cu" "*.Mask") (tstamp 7642f18b-04b6-4704-9b6e-ab4dfdc9ca73)) 68 | (model "${KICAD6_3DMODEL_DIR}/Package_DIP.3dshapes/DIP-24_W15.24mm.wrl" 69 | (offset (xyz 0 0 0)) 70 | (scale (xyz 1 1 1)) 71 | (rotate (xyz 0 0 0)) 72 | ) 73 | ) 74 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/gen_code.ncl: -------------------------------------------------------------------------------- 1 | let util = import "util_functions.ncl" in 2 | 3 | fun ir => 4 | 5 | let layer_count = std.array.length ir.key_map in 6 | 7 | let rec codegen = { 8 | val = { 9 | auto = fun value => 10 | if std.is_record value then 11 | struct value 12 | else if std.is_array value then 13 | array value 14 | else 15 | std.to_string value, 16 | struct = fun record => 17 | "{\n" ++ util.array.join "\n" ( 18 | record 19 | |> std.record.to_array 20 | |> std.array.map (fun { field, value } => ".%{field} = %{auto value},") 21 | ) ++ "\n}", 22 | array = fun arr => "{ %{util.array.join ", " (std.array.map auto arr)} }" 23 | }, 24 | 25 | defines = fun defines => 26 | let codegen_define = fun { field, value } => if value == false then "" else "#define %{field} %{ 27 | if value == true then "" else std.to_string value 28 | }" in 29 | defines 30 | |> std.record.to_array 31 | |> std.array.map codegen_define 32 | |> std.array.filter (fun s => s != "") 33 | |> util.array.join "\n", 34 | 35 | pin_def = fun i pin out => 36 | let prefix = if out then "OUT" else "IN" in 37 | let port = std.to_string (std.number.truncate (pin / 10)) in 38 | let port_idx = std.to_string (pin % 10) in 39 | m%" 40 | #define %{prefix}%{std.to_string i}_PIN %{port_idx} 41 | SBIT(%{prefix}%{std.to_string i}, P%{port}_ADDR, %{prefix}%{std.to_string i}_PIN); 42 | "%, 43 | } in 44 | 45 | let h_file = m%" 46 | %{codegen.defines ir.defines} 47 | 48 | #include "keyboard.h" 49 | 50 | void keyboard_init_user(); 51 | void keyboard_scan_user(); 52 | "% in 53 | 54 | let side_central_defs = 55 | m%" 56 | %{ 57 | if layer_count == 0 then 58 | "// (No layers. This must be peripheral side.)" 59 | else if layer_count == 1 then 60 | "__code uint32_t key_map[KEY_COUNT] = %{codegen.val.array (std.array.at 0 ir.key_map)};" 61 | else 62 | "__code uint32_t key_map[LAYER_COUNT][KEY_COUNT] = %{codegen.val.array ir.key_map};" 63 | } 64 | 65 | %{ 66 | if std.array.length ir.hold_tap_behaviors > 0 then 67 | m%" 68 | #include "hold_tap.h" 69 | __code fak_hold_tap_behavior_t hold_tap_behaviors[] = %{codegen.val.array ir.hold_tap_behaviors}; 70 | "% 71 | else 72 | "// (No hold tap behaviors)" 73 | } 74 | 75 | %{ 76 | if std.array.length ir.tap_dance_bindings > 0 then 77 | "__code uint32_t tap_dance_bindings[] = %{codegen.val.array ir.tap_dance_bindings};" 78 | else 79 | "// (No tap dance bindings)" 80 | } 81 | 82 | %{ 83 | if std.array.length ir.split_periph_key_indices > 0 then 84 | "__code uint8_t split_periph_key_indices[SPLIT_PERIPH_KEY_COUNT] = %{codegen.val.array ir.split_periph_key_indices};" 85 | else 86 | "// (No split periph key indices)" 87 | } 88 | 89 | %{ 90 | if std.array.length ir.combo_defs > 0 then 91 | m%" 92 | #include "combo.h" 93 | __code fak_combo_def_t combo_defs[COMBO_COUNT] = %{codegen.val.array ir.combo_defs}; 94 | "% 95 | else 96 | "// (No combo defs)" 97 | } 98 | 99 | %{ 100 | if std.array.length ir.conditional_layers > 0 then 101 | m%" 102 | __code fak_conditional_layer_def_t conditional_layers[CONDITIONAL_LAYER_COUNT] = %{codegen.val.array ir.conditional_layers}; 103 | "% 104 | else 105 | "// (No conditional layers)" 106 | } 107 | 108 | %{ 109 | if std.array.length ir.macro_steps > 0 then 110 | m%" 111 | #include "macro.h" 112 | __code fak_macro_step_t macro_steps[] = %{codegen.val.array ir.macro_steps}; 113 | __code uint32_t macro_step_args[MACRO_STEP_ARG_COUNT] = %{codegen.val.array ir.macro_step_args}; 114 | "% 115 | else 116 | "// (No macros)" 117 | } 118 | "% in 119 | 120 | let c_file = 121 | let key_state_inform = fun key_idx in_pin_idx => 122 | "key_state_inform(%{std.to_string key_idx}, !IN%{std.to_string in_pin_idx});" in 123 | let set_out_pin = fun high out_pin_idx => 124 | "OUT%{std.to_string out_pin_idx} = %{if high then "1" else "0"};" in 125 | m%" 126 | #include "ch552.h" 127 | 128 | %{side_central_defs} 129 | 130 | %{ 131 | ir.kscan.ins 132 | |> util.array.enumerate 133 | |> std.array.map (fun { index, value } => codegen.pin_def index value false) 134 | |> util.array.join "\n" 135 | } 136 | 137 | %{ 138 | ir.kscan.outs 139 | |> util.array.enumerate 140 | |> std.array.map (fun { index, value } => codegen.pin_def index value true) 141 | |> util.array.join "\n" 142 | } 143 | 144 | void keyboard_init_user() { 145 | %{ 146 | ir.kscan.outs 147 | |> std.array.length 148 | |> std.array.generate (fun i => set_out_pin true i) 149 | |> util.array.join "\n" 150 | } 151 | } 152 | 153 | static void row_switch_delay() { 154 | for (uint8_t i = 16; i; i--) { 155 | __asm__ ("nop"); 156 | } 157 | } 158 | 159 | void keyboard_scan_user() { 160 | // Direct pins 161 | %{ 162 | ir.kscan.direct 163 | |> std.array.map (fun { in_idx, key_idx } => key_state_inform key_idx in_idx) 164 | |> util.array.join "\n" 165 | } 166 | 167 | // Matrix 168 | %{ 169 | let matrix_row_scan = fun out_pin_idx row_mapping => 170 | row_mapping 171 | |> util.array.enumerate 172 | |> std.array.filter (fun { index, value } => value >= 0) 173 | |> std.array.map (fun { index, value } => 174 | let in_pin_idx = std.array.at index ir.kscan.matrix.ins in 175 | let key_idx = value in 176 | key_state_inform key_idx in_pin_idx 177 | ) 178 | |> std.array.prepend "row_switch_delay();" 179 | |> std.array.prepend (set_out_pin false out_pin_idx) 180 | |> std.array.append (set_out_pin true out_pin_idx) 181 | |> util.array.join "\n" 182 | in 183 | 184 | ir.kscan.matrix.mapping 185 | |> util.array.enumerate 186 | |> std.array.map (fun { index, value } => 187 | matrix_row_scan (std.array.at index ir.kscan.matrix.outs) value 188 | ) 189 | |> util.array.join "\n\n" 190 | } 191 | } 192 | "% in 193 | 194 | { 195 | h = h_file, 196 | c = c_file, 197 | } 198 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/fak/keymap.ncl: -------------------------------------------------------------------------------- 1 | let { MAX_LAYER_COUNT, .. } = import "constants.ncl" in 2 | let { Uint, Uint8, Uint16, BoundedInt, Set, .. } = import "util_types.ncl" in 3 | let util = import "util_functions.ncl" in 4 | 5 | let Uint13 = Uint 13 in 6 | 7 | fun kb km => 8 | 9 | let Modifiers = { 10 | left_ctrl | Bool | default = false, 11 | left_shift | Bool | default = false, 12 | left_alt | Bool | default = false, 13 | left_gui | Bool | default = false, 14 | right_ctrl | Bool | default = false, 15 | right_shift | Bool | default = false, 16 | right_alt | Bool | default = false, 17 | right_gui | Bool | default = false, 18 | } in 19 | 20 | let physical_key_count = std.array.length kb.keys in 21 | let virtual_key_count = std.array.length (util.record.at_or km "virtual_keys" []) in 22 | let key_count = physical_key_count + virtual_key_count in 23 | 24 | let LayerIndex = BoundedInt 0 (std.array.length km.layers) in 25 | let PhysicalKeyIndex = BoundedInt 0 physical_key_count in 26 | 27 | let NonConditionalLayerIndex = 28 | let ValidIndex = std.contract.from_predicate (fun i => 29 | let conditional_layer_indices = 30 | util.record.at_or km "conditional_layers" {} 31 | |> std.record.fields 32 | |> std.array.map std.string.to_number 33 | in 34 | !(std.array.elem i conditional_layer_indices) 35 | ) in 36 | std.contract.Sequence [ LayerIndex, ValidIndex ] 37 | in 38 | 39 | let HoldTapKeyInterrupt = { 40 | decision | [| 'none, 'hold, 'tap |] | default = 'none, 41 | trigger_on | [| 'press, 'release |] | default = 'press 42 | } in 43 | 44 | let HoldTapKeyInterrupts = ( 45 | let ValidLength = std.contract.from_predicate (fun ints => 46 | (std.array.length ints) == key_count 47 | ) in 48 | std.contract.Sequence [ Array HoldTapKeyInterrupt, ValidLength ] 49 | ) in 50 | 51 | let HoldTapBehavior = let 52 | default_key_interrupts = std.array.replicate key_count {} 53 | in { 54 | timeout_decision | [| 'hold, 'tap |] | default = 'hold, 55 | timeout_ms | Uint16 | default = 200, 56 | eager_decision | [| 'none, 'hold, 'tap |] | default = 'none, 57 | key_interrupts | HoldTapKeyInterrupts | default = default_key_interrupts, 58 | quick_tap_ms | Uint8 | default = 0, 59 | quick_tap_interrupt_ms 60 | | (if quick_tap_ms > 0 then Uint16 else std.contract.Equal 0) 61 | | default = 0, 62 | global_quick_tap_ms | Uint16 | default = 0, 63 | global_quick_tap_ignore_consecutive 64 | | (if global_quick_tap_ms > 0 then Bool else std.contract.Equal false) 65 | | default = false, 66 | } in 67 | 68 | let rec Keycode = 69 | let Holdable = { 70 | type | [| 'none, 'regular, 'nop, 'transparent |], 71 | data | (match { 72 | 'none => {}, 73 | 'regular => { 74 | behavior | HoldTapBehavior, 75 | layer | NonConditionalLayerIndex | default = 0, 76 | mods | Modifiers | default = {} 77 | }, 78 | 'nop => { 79 | behavior | HoldTapBehavior, 80 | }, 81 | 'transparent => {} 82 | }) type 83 | } in 84 | 85 | let Tappable = { 86 | type | [| 'none, 'regular, 'sticky, 'layer, 'custom, 'transparent |], 87 | data | (match { 88 | 'none => {}, 89 | 'regular => { 90 | hid_code | Uint8 | default = 0, 91 | mods | Modifiers | default = {} 92 | }, 93 | 'sticky => { 94 | mods | Modifiers | default = {}, 95 | }, 96 | 'layer => { 97 | operation | [| 'df, 'tog, 'to |], 98 | layer | NonConditionalLayerIndex 99 | }, 100 | 'custom => { 101 | type | [| 'fak, 'consumer, 'user, 'mouse, 'macro |], 102 | data | (match { 103 | 'macro => 104 | let MacroStep = { 105 | inst | [| 'press, 'release, 'tap, 'wait |], 106 | arg | (match { 107 | 'wait => { duration_ms | Uint16 }, 108 | _ => { keycode | Keycode }, 109 | }) inst 110 | } in 111 | { steps | Array MacroStep }, 112 | _ => { code | Uint 10 }, 113 | }) type 114 | }, 115 | 'transparent => {} 116 | }) type 117 | } in 118 | 119 | { 120 | type | [| 'hold_tap, 'tap_dance |], 121 | data | (match { 122 | 'hold_tap => { 123 | hold | Holdable | default = { type = 'none, data = {} }, 124 | tap | Tappable | default = { type = 'none, data = {} } 125 | }, 126 | 'tap_dance => { 127 | tapping_term_ms | Uint 12 | default = 200, 128 | bindings | Array Keycode, 129 | max_taps | std.contract.Sequence [ 130 | BoundedInt 2 17, 131 | std.contract.Equal (std.array.length bindings) 132 | ] | default = (std.array.length bindings) 133 | } 134 | }) type 135 | } in 136 | 137 | let Layer = ( 138 | let ValidLength = std.contract.from_predicate (fun layer => 139 | (std.array.length layer) == key_count 140 | ) in 141 | std.contract.Sequence [ Array Keycode, ValidLength ] 142 | ) in 143 | 144 | let Layers = 145 | let ValidLength = std.contract.from_predicate (fun layers => 146 | let len = std.array.length layers in len > 0 && len <= MAX_LAYER_COUNT 147 | ) in 148 | std.contract.Sequence [ Array Layer, ValidLength ] 149 | in 150 | 151 | let ConditionalLayers = std.contract.from_predicate (fun cl => cl 152 | |> std.record.to_array 153 | |> std.array.all (fun { field, value } => 154 | let then_layer | LayerIndex = std.string.to_number field in 155 | let if_layers | Set NonConditionalLayerIndex = value in 156 | !(std.array.elem then_layer if_layers) 157 | ) 158 | ) in 159 | 160 | let ComboKeyIndices = 161 | let ValidLength = std.contract.from_predicate (fun key_indices => 162 | let len = std.array.length key_indices in len >= 2 && len <= 9 163 | ) in 164 | std.contract.Sequence [ Set PhysicalKeyIndex, ValidLength ] 165 | in 166 | 167 | let VirtualKey = { 168 | type | [| 'combo |], 169 | data | (match { 170 | 'combo => { 171 | timeout_ms | Uint8 | default = 50, 172 | key_indices | ComboKeyIndices, 173 | slow_release | Bool | default = false, 174 | require_prior_idle_ms | Uint16 | default = 0, 175 | } 176 | }) type 177 | } in 178 | 179 | { 180 | Keymap = { 181 | layers | Layers, 182 | conditional_layers | ConditionalLayers | default = {}, 183 | virtual_keys | Set VirtualKey | default = [], 184 | mouse = { 185 | move_speed | Uint8 | default = 4, 186 | scroll_interval_ms | Uint16 | default = 20, 187 | }, 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /gerber/ch55p34-F_Paste.gbr: -------------------------------------------------------------------------------- 1 | %TF.GenerationSoftware,KiCad,Pcbnew,7.0.1*% 2 | %TF.CreationDate,2024-01-05T17:15:01-05:00*% 3 | %TF.ProjectId,ch55p34,63683535-7033-4342-9e6b-696361645f70,rev?*% 4 | %TF.SameCoordinates,Original*% 5 | %TF.FileFunction,Paste,Top*% 6 | %TF.FilePolarity,Positive*% 7 | %FSLAX46Y46*% 8 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 9 | G04 Created by KiCad (PCBNEW 7.0.1) date 2024-01-05 17:15:01* 10 | %MOMM*% 11 | %LPD*% 12 | G01* 13 | G04 APERTURE LIST* 14 | G04 Aperture macros list* 15 | %AMRoundRect* 16 | 0 Rectangle with rounded corners* 17 | 0 $1 Rounding radius* 18 | 0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners* 19 | 0 Add a 4 corners polygon primitive as box body* 20 | 4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0* 21 | 0 Add four circle primitives for the rounded corners* 22 | 1,1,$1+$1,$2,$3* 23 | 1,1,$1+$1,$4,$5* 24 | 1,1,$1+$1,$6,$7* 25 | 1,1,$1+$1,$8,$9* 26 | 0 Add four rect primitives between the rounded corners* 27 | 20,1,$1+$1,$2,$3,$4,$5,0* 28 | 20,1,$1+$1,$4,$5,$6,$7,0* 29 | 20,1,$1+$1,$6,$7,$8,$9,0* 30 | 20,1,$1+$1,$8,$9,$2,$3,0*% 31 | G04 Aperture macros list end* 32 | %ADD10RoundRect,0.100000X-0.637500X-0.100000X0.637500X-0.100000X0.637500X0.100000X-0.637500X0.100000X0*% 33 | %ADD11RoundRect,0.250000X-0.450000X0.262500X-0.450000X-0.262500X0.450000X-0.262500X0.450000X0.262500X0*% 34 | %ADD12R,0.600000X1.450000*% 35 | %ADD13R,0.300000X1.450000*% 36 | %ADD14RoundRect,0.225000X0.375000X-0.225000X0.375000X0.225000X-0.375000X0.225000X-0.375000X-0.225000X0*% 37 | %ADD15RoundRect,0.250000X-0.475000X0.250000X-0.475000X-0.250000X0.475000X-0.250000X0.475000X0.250000X0*% 38 | G04 APERTURE END LIST* 39 | D10* 40 | %TO.C,U1*% 41 | X153315500Y-61669000D03* 42 | X153315500Y-62319000D03* 43 | X153315500Y-62969000D03* 44 | X153315500Y-63619000D03* 45 | X153315500Y-64269000D03* 46 | X153315500Y-64919000D03* 47 | X153315500Y-65569000D03* 48 | X153315500Y-66219000D03* 49 | X153315500Y-66869000D03* 50 | X153315500Y-67519000D03* 51 | X159040500Y-67519000D03* 52 | X159040500Y-66869000D03* 53 | X159040500Y-66219000D03* 54 | X159040500Y-65569000D03* 55 | X159040500Y-64919000D03* 56 | X159040500Y-64269000D03* 57 | X159040500Y-63619000D03* 58 | X159040500Y-62969000D03* 59 | X159040500Y-62319000D03* 60 | X159040500Y-61669000D03* 61 | %TD*% 62 | D11* 63 | %TO.C,R4*% 64 | X157226000Y-50696500D03* 65 | X157226000Y-48871500D03* 66 | %TD*% 67 | %TO.C,R3*% 68 | X153924000Y-50696500D03* 69 | X153924000Y-48871500D03* 70 | %TD*% 71 | %TO.C,R2*% 72 | X157226000Y-46886500D03* 73 | X157226000Y-45061500D03* 74 | %TD*% 75 | %TO.C,R1*% 76 | X153924000Y-46886500D03* 77 | X153924000Y-45061500D03* 78 | %TD*% 79 | D12* 80 | %TO.C,J1*% 81 | X159204000Y-41555000D03* 82 | X158404000Y-41555000D03* 83 | D13* 84 | X157704000Y-41555000D03* 85 | X156704000Y-41555000D03* 86 | X155204000Y-41555000D03* 87 | X154204000Y-41555000D03* 88 | D12* 89 | X153504000Y-41555000D03* 90 | X152704000Y-41555000D03* 91 | X152704000Y-41555000D03* 92 | X153504000Y-41555000D03* 93 | D13* 94 | X154704000Y-41555000D03* 95 | X155704000Y-41555000D03* 96 | X156204000Y-41555000D03* 97 | X157204000Y-41555000D03* 98 | D12* 99 | X158404000Y-41555000D03* 100 | X159204000Y-41555000D03* 101 | %TD*% 102 | D14* 103 | %TO.C,D34*% 104 | X159766000Y-107568000D03* 105 | X159766000Y-104268000D03* 106 | %TD*% 107 | %TO.C,D33*% 108 | X157226000Y-107568000D03* 109 | X157226000Y-104268000D03* 110 | %TD*% 111 | %TO.C,D32*% 112 | X154686000Y-107568000D03* 113 | X154686000Y-104268000D03* 114 | %TD*% 115 | %TO.C,D31*% 116 | X152146000Y-107568000D03* 117 | X152146000Y-104268000D03* 118 | %TD*% 119 | %TO.C,D30*% 120 | X167386000Y-100584000D03* 121 | X167386000Y-97284000D03* 122 | %TD*% 123 | %TO.C,D29*% 124 | X164846000Y-100584000D03* 125 | X164846000Y-97284000D03* 126 | %TD*% 127 | %TO.C,D28*% 128 | X162306000Y-100584000D03* 129 | X162306000Y-97284000D03* 130 | %TD*% 131 | %TO.C,D27*% 132 | X159766000Y-100584000D03* 133 | X159766000Y-97284000D03* 134 | %TD*% 135 | %TO.C,D26*% 136 | X157226000Y-97284000D03* 137 | X157226000Y-100584000D03* 138 | %TD*% 139 | %TO.C,D25*% 140 | X154686000Y-97284000D03* 141 | X154686000Y-100584000D03* 142 | %TD*% 143 | %TO.C,D24*% 144 | X152146000Y-97284000D03* 145 | X152146000Y-100584000D03* 146 | %TD*% 147 | %TO.C,D23*% 148 | X149606000Y-97284000D03* 149 | X149606000Y-100584000D03* 150 | %TD*% 151 | %TO.C,D22*% 152 | X147066000Y-97284000D03* 153 | X147066000Y-100584000D03* 154 | %TD*% 155 | %TO.C,D21*% 156 | X144526000Y-97284000D03* 157 | X144526000Y-100584000D03* 158 | %TD*% 159 | %TO.C,D20*% 160 | X167386000Y-84328000D03* 161 | X167386000Y-87628000D03* 162 | %TD*% 163 | %TO.C,D19*% 164 | X164846000Y-84328000D03* 165 | X164846000Y-87628000D03* 166 | %TD*% 167 | %TO.C,D18*% 168 | X162306000Y-84328000D03* 169 | X162306000Y-87628000D03* 170 | %TD*% 171 | %TO.C,D17*% 172 | X159766000Y-84328000D03* 173 | X159766000Y-87628000D03* 174 | %TD*% 175 | %TO.C,D16*% 176 | X157226000Y-84328000D03* 177 | X157226000Y-87628000D03* 178 | %TD*% 179 | %TO.C,D15*% 180 | X154686000Y-84328000D03* 181 | X154686000Y-87628000D03* 182 | %TD*% 183 | %TO.C,D14*% 184 | X152146000Y-84328000D03* 185 | X152146000Y-87628000D03* 186 | %TD*% 187 | %TO.C,D13*% 188 | X149606000Y-84328000D03* 189 | X149606000Y-87628000D03* 190 | %TD*% 191 | %TO.C,D12*% 192 | X147066000Y-84328000D03* 193 | X147066000Y-87628000D03* 194 | %TD*% 195 | %TO.C,D11*% 196 | X144526000Y-84328000D03* 197 | X144526000Y-87628000D03* 198 | %TD*% 199 | %TO.C,D10*% 200 | X167386000Y-75436000D03* 201 | X167386000Y-72136000D03* 202 | %TD*% 203 | %TO.C,D9*% 204 | X164846000Y-75436000D03* 205 | X164846000Y-72136000D03* 206 | %TD*% 207 | %TO.C,D8*% 208 | X162306000Y-75436000D03* 209 | X162306000Y-72136000D03* 210 | %TD*% 211 | %TO.C,D7*% 212 | X159766000Y-75436000D03* 213 | X159766000Y-72136000D03* 214 | %TD*% 215 | %TO.C,D6*% 216 | X157226000Y-75436000D03* 217 | X157226000Y-72136000D03* 218 | %TD*% 219 | %TO.C,D5*% 220 | X154686000Y-75436000D03* 221 | X154686000Y-72136000D03* 222 | %TD*% 223 | %TO.C,D4*% 224 | X152146000Y-75436000D03* 225 | X152146000Y-72136000D03* 226 | %TD*% 227 | %TO.C,D3*% 228 | X149606000Y-72136000D03* 229 | X149606000Y-75436000D03* 230 | %TD*% 231 | %TO.C,D2*% 232 | X147066000Y-72136000D03* 233 | X147066000Y-75436000D03* 234 | %TD*% 235 | %TO.C,D1*% 236 | X144526000Y-72136000D03* 237 | X144526000Y-75436000D03* 238 | %TD*% 239 | D15* 240 | %TO.C,C3*% 241 | X153924000Y-58608000D03* 242 | X153924000Y-56708000D03* 243 | %TD*% 244 | %TO.C,C2*% 245 | X157226000Y-58608000D03* 246 | X157226000Y-56708000D03* 247 | %TD*% 248 | %TO.C,C1*% 249 | X153924000Y-54798000D03* 250 | X153924000Y-52898000D03* 251 | %TD*% 252 | M02* 253 | -------------------------------------------------------------------------------- /FAK-Firmware/ncl/examples/cheapis/keymap.ncl: -------------------------------------------------------------------------------- 1 | let { tap, hold, td, combo, .. } = import "../../fak/keycode.ncl" in 2 | let util = import "../../fak/util_functions.ncl" in 3 | 4 | let virtual_keys' = [ 5 | combo.make 30 [12, 13], 6 | ] in 7 | 8 | let key_count = 34 + std.array.length virtual_keys' in 9 | 10 | let kc = tap.reg.kc in 11 | let ks = tap.reg.ks in 12 | let md = hold.reg.mod in 13 | let tm = tap.reg.mod in 14 | let me = tap.custom.media in 15 | let MO = hold.reg.layer in 16 | 17 | let ki = { 18 | hp = { decision = 'hold, trigger_on = 'press }, 19 | tp = { decision = 'tap, trigger_on = 'press }, 20 | hr = { decision = 'hold, trigger_on = 'release }, 21 | tr = { decision = 'tap, trigger_on = 'release }, 22 | xx = { decision = 'none }, 23 | } in 24 | 25 | let layouts = { 26 | QWERTY = "QWERTYUIOPASDFGHJKL;ZXCVBNM,./", 27 | DVORAK = "',.PYFGCRLAOEUIDHTNS;QJKXBMWVZ", 28 | COLEMAK = "QWFPGJLUY;ARSTDHNEIOZXCVBKM,./", 29 | } in 30 | 31 | let make_hrm = fun key_idx => 32 | let htb_hrm_base = fun eager => { 33 | timeout_ms = 200, 34 | quick_tap_ms = 150, 35 | quick_tap_interrupt_ms = 500, 36 | global_quick_tap_ms = 80, 37 | eager_decision = eager, 38 | } in 39 | 40 | let htb_hrm_left = fun eager => htb_hrm_base eager & { 41 | key_interrupts = [ 42 | ki.tp, ki.tp, ki.tp, ki.tp, ki.tp, ki.hr, ki.hr, ki.hr, ki.hr, ki.hr, 43 | ki.tr, ki.tr, ki.tr, ki.tr, ki.tp, ki.hr, ki.hr, ki.hr, ki.hr, ki.hr, 44 | ki.tp, ki.tp, ki.tp, ki.tp, ki.tp, ki.hr, ki.hr, ki.hr, ki.hr, ki.hr, 45 | ki.hp, ki.hp, ki.hp, ki.hp, 46 | ki.xx, 47 | ] 48 | } in 49 | 50 | let htb_hrm_right = fun eager => htb_hrm_base eager & { 51 | key_interrupts = [ 52 | ki.hr, ki.hr, ki.hr, ki.hr, ki.hr, ki.tp, ki.tp, ki.tp, ki.tp, ki.tp, 53 | ki.hr, ki.hr, ki.hr, ki.hr, ki.hr, ki.tp, ki.tr, ki.tr, ki.tr, ki.tr, 54 | ki.hr, ki.hr, ki.hr, ki.hr, ki.hr, ki.tp, ki.tp, ki.tp, ki.tp, ki.tp, 55 | ki.hp, ki.hp, ki.hp, ki.hp, 56 | ki.xx, 57 | ] 58 | } in 59 | 60 | let hrm_mods = 61 | let m = [md.lgui, md.lalt, md.lctl, md.lsft] in 62 | m @ std.array.reverse m 63 | in 64 | 65 | let hrm_key_indices = [10, 11, 12, 13, 16, 17, 18, 19] in 66 | 67 | if std.array.elem key_idx hrm_key_indices then 68 | let mod_idx = util.array.index_of key_idx hrm_key_indices in 69 | let side = if mod_idx < (std.array.length hrm_mods / 2) then 'left else 'right in 70 | let mod = std.array.at mod_idx hrm_mods in 71 | 72 | mod & hold.reg.behavior ( 73 | (if side == 'left then htb_hrm_left else htb_hrm_right) 74 | (if mod == md.lalt then 'none else 'hold) 75 | ) 76 | else 77 | {} 78 | in 79 | 80 | let XXXX = tap.none & hold.none in 81 | 82 | let L' = fun layer => 83 | let filler = std.array.replicate (key_count - std.array.length layer) XXXX in 84 | layer @ filler 85 | in 86 | 87 | let layer_media = 88 | let MNP = td.make 200 [ me.NEXT, me.PREV ] in 89 | L' [ 90 | XXXX, me.MUTE, me.VOLD, me.VOLU, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, 91 | XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, 92 | XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, 93 | me.PLAY, MNP, XXXX, XXXX, 94 | ] 95 | in 96 | 97 | let htb_media = { 98 | timeout_ms = 250, 99 | timeout_decision = 'tap, 100 | global_quick_tap_ms = 80, 101 | key_interrupts = layer_media 102 | |> std.array.map (fun kc => if kc == XXXX then ki.tp else ki.hr) 103 | } in 104 | 105 | let alphas = fun layout => layout 106 | |> std.string.characters 107 | |> util.array.enumerate 108 | |> std.array.map (fun { index, value } => kc."%{value}" 109 | & (if index == 0 then 110 | MO 2 & hold.reg.behavior htb_media 111 | else 112 | make_hrm index) 113 | ) 114 | in 115 | 116 | let cu = { 117 | SCSH = tm.lgui & tm.lsft & kc.S, 118 | PWSP = tm.lgui & kc.PGDN, 119 | NWSP = tm.lgui & kc.PGUP, 120 | CT = tm.lctl & kc.TAB, 121 | CST = tm.lctl & tm.lsft & kc.TAB, 122 | BOOT = tap.custom.fak.BOOT, 123 | } in 124 | 125 | let thumb = fun i => 126 | let htb_generic = { 127 | timeout_ms = 200, 128 | quick_tap_ms = 150, 129 | key_interrupts = std.array.replicate key_count ki.hr, 130 | } in 131 | [ 132 | kc.DEL & MO 3 & hold.reg.behavior htb_generic, 133 | kc.BSPC & MO 5 & hold.reg.behavior htb_generic, 134 | kc.SPC & MO 1 & hold.reg.behavior htb_generic, 135 | kc.ESC & MO 4 & hold.reg.behavior htb_generic, 136 | ] 137 | |> std.array.at i 138 | in 139 | 140 | let keymap = { 141 | virtual_keys = virtual_keys', 142 | layers = [ 143 | let base = fun key_idx => (alphas layouts.COLEMAK) |> std.array.at key_idx in 144 | [ 145 | base 0, base 1, base 2, base 3, base 4, base 5, base 6, base 7, base 8, base 9, 146 | base 10, base 11, base 12, base 13, base 14, base 15, base 16, base 17, base 18, base 19, 147 | base 20, base 21, base 22, base 23, base 24, base 25, base 26, base 27, base 28, base 29, 148 | thumb 0, thumb 1, thumb 2, thumb 3, 149 | # Combo [12, 13] 150 | td.make 200 [MO 3, cu.BOOT], 151 | ], 152 | L' [ 153 | XXXX, XXXX, XXXX, XXXX, XXXX, cu.PWSP, cu.CT, cu.CST, cu.NWSP, XXXX, 154 | md.lgui, md.lalt, md.lctl, md.lsft, cu.SCSH, kc.LEFT, kc.DOWN, kc.UP, kc.RGHT, XXXX, 155 | XXXX, XXXX, XXXX, XXXX, XXXX, kc.HOME, kc.PGDN, kc.PGUP, kc.END, XXXX, 156 | XXXX, kc.ENT, XXXX, XXXX, 157 | ], 158 | layer_media, 159 | L' [ 160 | XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, kc.N7, kc.N8, kc.N9, XXXX, 161 | XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, kc.N4, kc.N5, kc.N6, XXXX, 162 | XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, kc.N1, kc.N2, kc.N3, XXXX, 163 | XXXX, XXXX, kc.N0, kc.".", 164 | ], 165 | L' [ 166 | XXXX, XXXX, XXXX, kc.F11, XXXX, XXXX, kc.F12, XXXX, XXXX, XXXX, 167 | kc.F7, kc.F5, kc.F3, kc.F1, XXXX, kc.F8, kc.F10, kc.F2, kc.F4, kc.F6, 168 | XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, XXXX, 169 | ], 170 | L' [ 171 | ks.CIRC, ks.DLR, ks.TILD, ks.PIPE, ks.PERC, ks.AMPR, ks.ASTR, kc.SLSH, ks.HASH, ks.AT, 172 | ks.DQUO, kc.LBRC, ks.LCBR, ks.LPRN, ks.LABK, kc.GRV, ks.UNDS, kc.EQL, ks.COLN, kc.QUOT, 173 | kc.BSLS, kc.RBRC, ks.RCBR, ks.RPRN, ks.RABK, ks.QUES, ks.PLUS, kc.SCLN, ks.EXLM, kc.MINS, 174 | ], 175 | ] 176 | } in 177 | 178 | keymap 179 | -------------------------------------------------------------------------------- /FAK-Firmware/src/combo.c: -------------------------------------------------------------------------------- 1 | #include "combo.h" 2 | #include "time.h" 3 | #include "split_central.h" 4 | 5 | #define REF_COUNT_OWNED 255 6 | 7 | #define COMBO_KEY_COUNT(combo_def) ((combo_def.flags & COMBO_FLAGS_KEY_COUNT_MASK) + 2) 8 | 9 | typedef struct { 10 | uint8_t state; 11 | uint16_t timestamp; 12 | } fak_combo_state_t; 13 | 14 | typedef struct { 15 | uint8_t key_idx; 16 | uint8_t ref_count; 17 | } fak_combo_key_queue_entry_t; 18 | 19 | typedef struct { 20 | uint8_t size; 21 | fak_combo_key_queue_entry_t q[COMBO_KEY_QUEUE_LEN]; 22 | } fak_combo_key_queue_t; 23 | 24 | extern __code fak_combo_def_t combo_defs[COMBO_COUNT]; 25 | 26 | __xdata __at(XADDR_COMBO_STATES) fak_combo_state_t combo_states[COMBO_COUNT]; 27 | __xdata __at(XADDR_COMBO_KEY_QUEUE) fak_combo_key_queue_t combo_key_queue; 28 | 29 | static void combo_key_queue_remove(uint8_t idx) { 30 | for (uint8_t i = idx; i < combo_key_queue.size - 1; i++) { 31 | combo_key_queue.q[i] = combo_key_queue.q[i + 1]; 32 | } 33 | combo_key_queue.size--; 34 | } 35 | 36 | void combo_push_key_event(uint8_t key_idx, uint8_t pressed) { 37 | if (pressed) { 38 | #ifdef COMBO_REQUIRE_PRIOR_IDLE_MS_ENABLE 39 | uint16_t last_tap_delta = get_timer() - get_last_tap_timestamp(); 40 | #endif 41 | 42 | // Add to combo key queue if key is in any (handle-able) combo 43 | for (uint8_t i = COMBO_COUNT; i;) { 44 | i--; 45 | 46 | #ifdef COMBO_REQUIRE_PRIOR_IDLE_MS_ENABLE 47 | // Do not handle combo if it requires prior idle time 48 | uint16_t require_prior_idle_ms = combo_defs[i].require_prior_idle_ms; 49 | 50 | if (require_prior_idle_ms && require_prior_idle_ms > last_tap_delta) { 51 | continue; 52 | } 53 | #endif 54 | 55 | for (uint8_t j = COMBO_KEY_COUNT(combo_defs[i]); j;) { 56 | if (combo_defs[i].key_indices[--j] != key_idx) 57 | continue; 58 | 59 | fak_combo_key_queue_entry_t e = { .key_idx = key_idx }; 60 | combo_key_queue.q[combo_key_queue.size++] = e; 61 | return combo_handle(); 62 | } 63 | } 64 | 65 | // Otherwise, we have a non-combo key 66 | // Press all unowned combo keys, removing them all from the queue 67 | for (uint8_t i = 0; i < combo_key_queue.size; i++) { 68 | if (combo_key_queue.q[i].ref_count != REF_COUNT_OWNED) { 69 | push_key_event(combo_key_queue.q[i].key_idx, 1); 70 | combo_key_queue_remove(i); 71 | } 72 | } 73 | 74 | // Then press the non-combo key itself 75 | return push_key_event(key_idx, 1); 76 | } 77 | 78 | // On release, we check if this key is in the queue 79 | for (uint8_t i = 0; i < combo_key_queue.size; i++) { 80 | if (key_idx != combo_key_queue.q[i].key_idx) 81 | continue; 82 | 83 | // If it's owned, we let the combo processor handle it 84 | __bit owned = combo_key_queue.q[i].ref_count == REF_COUNT_OWNED; 85 | combo_key_queue_remove(i); 86 | 87 | if (owned) { 88 | return combo_handle(); 89 | } 90 | 91 | // Otherwise, we press all unowned combo keys *up until* the combo key removed just now 92 | // All these keys are also removed from the queue 93 | // This is done to preserve the keypress order 94 | uint8_t k = 0; 95 | 96 | for (uint8_t j = 0; j < i; j++) { 97 | if (combo_key_queue.q[j].ref_count == REF_COUNT_OWNED) { 98 | k++; 99 | continue; 100 | } 101 | 102 | push_key_event(combo_key_queue.q[k].key_idx, 1); 103 | combo_key_queue_remove(k); 104 | } 105 | 106 | // Tap the combo key removed just now 107 | push_key_event(key_idx, 1); 108 | break; 109 | } 110 | 111 | push_key_event(key_idx, 0); 112 | } 113 | 114 | void combo_handle() { 115 | // Reset ref counters except owned 116 | for (uint8_t i = combo_key_queue.size; i;) { 117 | uint8_t *ref_count = &combo_key_queue.q[--i].ref_count; 118 | if (*ref_count != REF_COUNT_OWNED) *ref_count = 0; 119 | } 120 | 121 | for (uint8_t i = 0; i < COMBO_COUNT; i++) { 122 | uint8_t pressed_keys = 0; 123 | uint8_t combo_key_count = COMBO_KEY_COUNT(combo_defs[i]); 124 | 125 | #define combo_def (combo_defs[i]) 126 | #define combo_state (combo_states[i]) 127 | #define all_pressed_keys ((1 << combo_key_count) - 1) 128 | 129 | // Enumerate pressed keys 130 | for (uint8_t j = 0; j < combo_key_count; j++) { 131 | for (uint8_t k = 0; k < combo_key_queue.size; k++) { 132 | if (combo_def.key_indices[j] != combo_key_queue.q[k].key_idx) 133 | continue; 134 | 135 | // Bail out if we see an owned key, which means this combo is impossible to trigger for now 136 | // This only applies to inactive combos 137 | if (combo_state.state != 2 && combo_key_queue.q[k].ref_count == REF_COUNT_OWNED) { 138 | combo_state.state = 0; 139 | goto exit_outer; 140 | } 141 | 142 | pressed_keys |= (1 << j); 143 | break; 144 | } 145 | } 146 | 147 | // Check for combo deprivation or timeout 148 | __bit will_own = 0; 149 | 150 | if (combo_state.state == 1) { 151 | if (pressed_keys == 0) { 152 | combo_state.state = 0; 153 | continue; 154 | } else if ((get_timer() - combo_state.timestamp) >= combo_def.timeout_ms) { 155 | continue; 156 | } else if (pressed_keys == all_pressed_keys) { 157 | will_own = 1; 158 | } 159 | } 160 | 161 | // Populate ref counters, only if this is an inactive combo 162 | if (combo_state.state != 2) { 163 | for (uint8_t j = 0; j < combo_key_count; j++) { 164 | if (!(pressed_keys & (1 << j))) 165 | continue; 166 | 167 | for (uint8_t k = 0; k < combo_key_queue.size; k++) { 168 | if (combo_def.key_indices[j] != combo_key_queue.q[k].key_idx) 169 | continue; 170 | 171 | if (will_own) { 172 | combo_key_queue.q[k].ref_count = REF_COUNT_OWNED; 173 | } else { 174 | combo_key_queue.q[k].ref_count++; 175 | } 176 | 177 | break; 178 | } 179 | } 180 | } 181 | 182 | if (combo_state.state == 0 && pressed_keys) { 183 | combo_state.state = 1; 184 | combo_state.timestamp = get_timer(); 185 | } else if (combo_state.state == 1 && will_own) { 186 | combo_state.state = 2; 187 | push_key_event(COMBO_KEY_IDX_START + i, 1); 188 | } else if (combo_state.state == 2) { 189 | uint8_t release = 0; 190 | 191 | if (combo_def.flags & COMBO_FLAGS_SLOW_RELEASE_MASK) { 192 | release = pressed_keys == 0; 193 | } else { 194 | release = pressed_keys != all_pressed_keys; 195 | } 196 | 197 | if (release) { 198 | combo_state.state = 0; 199 | push_key_event(COMBO_KEY_IDX_START + i, 0); 200 | } 201 | } 202 | exit_outer: 203 | } 204 | 205 | // If no combo cares about a key anymore, press it then remove from queue 206 | for (uint8_t i = 0; i < combo_key_queue.size;) { 207 | uint8_t ref_count = combo_key_queue.q[i].ref_count; 208 | 209 | if (ref_count == REF_COUNT_OWNED) { 210 | i++; 211 | continue; 212 | } else if (ref_count != 0) { 213 | // We only do this until we see a key that combos still do care about 214 | // This is done to preserve the keypress order 215 | break; 216 | } 217 | 218 | push_key_event(combo_key_queue.q[i].key_idx, 1); 219 | combo_key_queue_remove(i); 220 | } 221 | } 222 | 223 | void combo_init() { 224 | for (uint8_t i = COMBO_COUNT; i;) { 225 | combo_states[--i].state = 0; 226 | } 227 | 228 | combo_key_queue.size = 0; 229 | } 230 | --------------------------------------------------------------------------------