From 8227244e06c5bb6ff8d696d2ce33d91c2eed7942 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Tue, 11 Nov 2025 10:20:51 -0600 Subject: [PATCH] initial commit --- config.h | 30 +++++++++++ flake.lock | 131 +++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 35 ++++++++++++ keymap.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++ nixcaps.nix | 62 ++++++++++++++++++++++ rules.mk | 8 +++ 6 files changed, 416 insertions(+) create mode 100644 config.h create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 keymap.c create mode 100644 nixcaps.nix create mode 100644 rules.mk diff --git a/config.h b/config.h new file mode 100644 index 0000000000..0bfae4d254 --- /dev/null +++ b/config.h @@ -0,0 +1,30 @@ +/* +Copyright 2023 Chris Cochrun + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once +#define RGBLIGHT_LAYERS +/* #define RGBLIGHT_EFFECT_BREATHING */ +/* #define RGBLIGHT_EFFECT_RAINBOW_MOOD */ +/* #define RGBLIGHT_EFFECT_RAINBOW_SWIRL */ +/* #define RGBLIGHT_EFFECT_SNAKE */ +/* #define RGBLIGHT_EFFECT_KNIGHT */ +/* #define RGBLIGHT_EFFECT_CHRISTMAS */ +/* #define RGBLIGHT_EFFECT_STATIC_GRADIENT */ +/* #define RGBLIGHT_EFFECT_RGB_TEST */ +/* #define RGBLIGHT_EFFECT_ALTERNATING */ +/* #define RGBLIGHT_EFFECT_TWINKLE */ +/* #define RGBLIGHT_SLEEP */ diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000000..6e1c63570c --- /dev/null +++ b/flake.lock @@ -0,0 +1,131 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixcaps": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1758698037, + "narHash": "sha256-HTPAR5fXzIB2dvm+4lxdGakvenogAtCrcNC9PBuviyQ=", + "owner": "agustinmista", + "repo": "nixcaps", + "rev": "a5623c741a29b60581517040cf62996b5648de1f", + "type": "github" + }, + "original": { + "owner": "agustinmista", + "ref": "main", + "repo": "nixcaps", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1757745802, + "narHash": "sha256-hLEO2TPj55KcUFUU1vgtHE9UEIOjRcH/4QbmfHNF820=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "c23193b943c6c689d70ee98ce3128239ed9e32d1", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1762596750, + "narHash": "sha256-rXXuz51Bq7DHBlfIjN7jO8Bu3du5TV+3DSADBX7/9YQ=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "b6a8526db03f735b89dd5ff348f53f752e7ddc8e", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixcaps": "nixcaps", + "nixpkgs": "nixpkgs_2" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000000..1041c4f353 --- /dev/null +++ b/flake.nix @@ -0,0 +1,35 @@ +{ + description = "QMK firmware builder for my keyboard"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + nixcaps.url = "github:agustinmista/nixcaps/main"; + }; + + outputs = + { + nixpkgs, + flake-utils, + nixcaps, + ... + }: + flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + compile = nixcaps.packages.${system}.compile; + in + { + packages.default = compile { + keyboard = "keebio/iris"; + variant = "rev6"; + src = ./.; + flash = fw: '' + echo "Flashing ${fw}.hex ..." + ${pkgs.teensy-loader-cli}/bin/teensy-loader-cli -mmcu=atmega32u4 -v -w ${fw}.hex + ''; + }; + } + ); +} diff --git a/keymap.c b/keymap.c new file mode 100644 index 0000000000..ad73a560f0 --- /dev/null +++ b/keymap.c @@ -0,0 +1,150 @@ +// Copyright 2023 Danny Nguyen (@nooges) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +// Layouts +enum layer_names { + _ENGRAM, + _QWERTY, + _GAMING, + _LOWER, + _RAISE, +}; + +enum custom_keycodes { + EMAIL = SAFE_RANGE, + KILL, +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [_QWERTY] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_DEL, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LALT, KC_A, KC_S, KC_D, KC_F, LT(_LOWER, KC_G), LT(_LOWER, KC_H), KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, _______, KC_RALT, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + //└────────┴────────┴────────┴───┬────┴───┬────┴───┬────┴───┬────┘ └───┬────┴───┬────┴───┬────┴───┬────┴────────┴────────┴────────┘ + TG(_QWERTY), KC_LCTL, KC_LGUI, LT(_RAISE, KC_SPC), KC_ENT, KILL + // └────────┴────────┴────────┘ └────────┴────────┴────────┘ + ), + + [_ENGRAM] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_TAB, KC_B, KC_Y, KC_O, KC_U, KC_QUOT, KC_SCLN, KC_L, KC_D, KC_W, KC_V, KC_Z, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LALT, KC_C, KC_I, KC_E, LALT_T(KC_A), LT(_LOWER, KC_COMM), LT(_LOWER, KC_DOT), RALT_T(KC_H), KC_T, KC_S, KC_N, KC_Q, + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LSFT, KC_G, KC_X, KC_J, KC_K, KC_UNDS, _______, KC_RALT, KC_SLSH, KC_R, KC_M, KC_F, KC_P, EMAIL, + //└────────┴────────┴────────┴───┬────┴───┬────┴───┬────┴───┬────┘ └───┬────┴───┬────┴───┬────┴───┬────┴────────┴────────┴────────┘ + TG(_QWERTY), LCTL_T(KC_TAB), KC_LGUI, LT(_RAISE, KC_SPC), LSFT_T(KC_ENT), KILL + // └────────┴────────┴────────┘ └────────┴────────┴────────┘ + ), + + // Engram +/* `~ 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) [{ ]} */ +/* bB yY oO uU '" ;: lL dD wW vV zZ =+ \| */ +/* cC iI eE aA ,< .> hH tT sS nN qQ */ +/* gG xX jJ kK -_ /? rR mM fF pP */ + + [_LOWER] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + KC_GRV, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + QK_BOOT, KC_1, KC_HOME, KC_UP, KC_END, KC_LPRN, KC_RPRN, KC_7, KC_8, KC_9, KC_0, TG(_GAMING), + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_DEL, KILL, KC_LEFT, KC_DOWN, KC_RGHT, KC_LBRC, KC_RBRC, KC_4, KC_5, KC_6, KC_PLUS, KC_PIPE, + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + BL_STEP, _______, _______, _______, KC_MINS, KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_1, KC_2, KC_3, KC_MINS, _______, + //└────────┴────────┴────────┴───┬────┴───┬────┴───┬────┴───┬────┘ └───┬────┴───┬────┴───┬────┴───┬────┴────────┴────────┴────────┘ + _______, _______, KC_DEL, KC_DEL, _______, KC_0 + // └────────┴────────┴────────┘ └────────┴────────┴────────┘ + ), + + [_RAISE] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + KC_F12, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + UG_TOGG, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + UG_NEXT, KC_MPRV, KC_BRIU, KC_VOLU, KC_BSPC, KC_UNDS, KC_EQL, KC_HOME, UG_HUEU, UG_SATU, UG_VALU, KC_BSLS, + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + KC_MUTE, KC_MPLY, KC_BRID, KC_VOLD, KC_DEL, KC_MINS, KC_LPRN, _______, KC_PLUS, KC_END, UG_HUED, UG_SATD, UG_VALD, _______, + //└────────┴────────┴────────┴───┬────┴───┬────┴───┬────┴───┬────┘ └───┬────┴───┬────┴───┬────┴───┬────┴────────┴────────┴────────┘ + _______, _______, KC_ESC, _______, _______, _______ + // └────────┴────────┴────────┘ └────────┴────────┴────────┘ + ), + + [_GAMING] = LAYOUT( + //┌────────┬────────┬────────┬────────┬────────┬────────┐ ┌────────┬────────┬────────┬────────┬────────┬────────┐ + QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_TAB, KC_Z, KC_Q, KC_W, KC_E, KC_R, KC_Y, KC_U, KC_I, KC_O, KC_P, TG(_GAMING), + //├────────┼────────┼────────┼────────┼────────┼────────┤ ├────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LALT, LSFT_T(KC_G), KC_A, KC_S, KC_D, KC_F, LT(_LOWER, KC_H), KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + //├────────┼────────┼────────┼────────┼────────┼────────┼────────┐ ┌────────┼────────┼────────┼────────┼────────┼────────┼────────┤ + KC_LSFT, KC_B, KC_Z, KC_X, KC_C, KC_V, KC_HOME, KC_END, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + //└────────┴────────┴────────┴───┬────┴───┬────┴───┬────┴───┬────┘ └───┬────┴───┬────┴───┬────┴───┬────┴────────┴────────┴────────┘ + KC_LGUI, KC_LCTL, KC_SPC, LT(_RAISE, KC_SPC), KC_ENT, KC_RALT + // └────────┴────────┴────────┘ └────────┴────────┴────────┘ + ), +}; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case EMAIL: + if (record->event.pressed) { + SEND_STRING("chris@tfcconnection.org"); + } + return false; + break; + case KILL: + if (record->event.pressed) { + SEND_STRING(SS_LGUI("c")); + } + return false; + break; + } + return true; +} + +layer_state_t layer_state_set_user(layer_state_t state) { + switch (get_highest_layer(state)) { + case _GAMING: + rgblight_sethsv_noeeprom(HSV_RED); + break; + default: // for any other layers, or the default layer + rgblight_sethsv_noeeprom(HSV_SPRINGGREEN); + break; + } + return state; +} + + + + + +/* const rgblight_segment_t PROGMEM gaming_layer[] = UGLIGHT_LAYER_SEGMENTS( */ +/* {9, 2, HSV_CYAN} */ +/* ); */ +/* const rgblight_segment_t* const PROGMEM my_rgb_layers[] = UGLIGHT_LAYERS_LIST( */ +/* gaming_layer, // Overrides caps lock layer */ +/* ); */ + +/* void keyboard_post_init_user(void) { */ +/* rgblight_layers = my_rgb_layers; */ +/* } */ + + +/* layer_state_t layer_state_set_user(layer_state_t state) { */ + +/* rgblight_set_layer_state(0, layer_state_cmp(state, _GAMING)); */ + +/* return state; */ +/* } */ diff --git a/nixcaps.nix b/nixcaps.nix new file mode 100644 index 0000000000..747a460095 --- /dev/null +++ b/nixcaps.nix @@ -0,0 +1,62 @@ +{ + qmk, + fetchFromGitHub, + stdenv, + lib, +}: +rec { + qmk_firmware = fetchFromGitHub { + owner = "qmk"; + repo = "qmk_firmware"; + rev = "0.30.3"; + sha256 = "sha256-lM5B9xl7sSxGhI/fbS0ys22t5oVUp8aMLI4pzICEKHk="; + fetchSubmodules = true; + }; + compile = + { + keyboard, + src, + variant ? null, + flash ? null, + target ? "fw", + ... + }: + let + buildDir = "build"; + keyboardDir = "keyboards/${keyboard}"; + keyboardVariant = if builtins.isNull variant then "${keyboard}" else "${keyboard}/${variant}"; + keymapName = "nixcaps"; + keymapDir = "${keyboardDir}/keymaps/${keymapName}"; + in + stdenv.mkDerivation { + name = "nixcaps-compile"; + src = qmk_firmware; + buildInputs = [ qmk ]; + postPatch = '' + mkdir -p ${keymapDir} + cp -r ${src}/* ${keymapDir}/ + ''; + buildPhase = '' + qmk compile \ + --env SKIP_GIT=true \ + --env BUILD_DIR=${buildDir} \ + --env TARGET=${target} \ + --keyboard ${keyboardVariant} \ + --keymap ${keymapName} + ''; + installPhase = '' + mkdir -p $out/bin + cp ${buildDir}/*.{hex,bin,elf,dfu,uf2,eep} $out/bin + + ${lib.optionalString (!builtins.isNull flash) '' + cat > $out/bin/flash <