diff options
| author | brian cully <bjc@spork.org> | 2026-01-30 10:52:35 -0500 |
|---|---|---|
| committer | brian cully <bjc@spork.org> | 2026-01-30 10:52:35 -0500 |
| commit | 8e66c1b9465d54c4fed1f343f479950cf3833439 (patch) | |
| tree | 82815f7516102f341d00686736c5d928390171f7 | |
| parent | 248585b7f9728b08eea12f2bc73c7d672605c6a6 (diff) | |
| download | Model100-8e66c1b9465d54c4fed1f343f479950cf3833439.tar.gz Model100-8e66c1b9465d54c4fed1f343f479950cf3833439.zip | |
update for recent kaleidoscope/chrysalis
removed a bunch of stuff i wasn't using to simplify, and rebase off
the current default example in the kaleidoscope library.
| -rw-r--r-- | Model100.ino | 908 |
1 files changed, 651 insertions, 257 deletions
diff --git a/Model100.ino b/Model100.ino index e563c9c..274ca45 100644 --- a/Model100.ino +++ b/Model100.ino @@ -1,180 +1,388 @@ // -*- mode: c++ -*- +// Copyright 2016-2022 Keyboardio, inc. <jesse@keyboard.io> +// See "LICENSE" for license details -#ifndef BUILD_INFORMATION -#define BUILD_INFORMATION "locally built" -#endif +/** + * These #include directives pull in the Kaleidoscope firmware core, + * as well as the Kaleidoscope plugins we use in the Model 100's firmware + */ + +// The Kaleidoscope core +#include "Kaleidoscope.h" + +// Support for storing the keymap in EEPROM +#include "Kaleidoscope-EEPROM-Settings.h" +#include "Kaleidoscope-EEPROM-Keymap.h" + +// Support for communicating with the host via a simple Serial protocol +#include "Kaleidoscope-FocusSerial.h" + +// Support for querying the firmware version via Focus +#include "Kaleidoscope-FirmwareVersion.h" + +// Support for keys that move the mouse +#include "Kaleidoscope-MouseKeys.h" + +// Support for macros +#include "Kaleidoscope-Macros.h" + +#include "Kaleidoscope-CharShift.h" + +//#include "Kaleidoscope-Leader.h" + +// Support for controlling the keyboard's LEDs +#include "Kaleidoscope-LEDControl.h" + +// Support for the "Boot greeting" effect, which pulses the 'LED' button for 10s +// when the keyboard is connected to a computer (or that computer is powered on) +#include "Kaleidoscope-LEDEffect-BootGreeting.h" + +// Support for LED modes that set all LEDs to a single color +#include "Kaleidoscope-LEDEffect-SolidColor.h" + +// Support for an LED mode that makes all the LEDs 'breathe' +#include "Kaleidoscope-LEDEffect-Breathe.h" + +// Support for an LED mode that makes a red pixel chase a blue pixel across the keyboard +#include "Kaleidoscope-LEDEffect-Chase.h" + +// Support for LED modes that pulse the keyboard's LED in a rainbow pattern +#include "Kaleidoscope-LEDEffect-Rainbow.h" + +// Support for an LED mode that lights up the keys as you press them +#include "Kaleidoscope-LED-Stalker.h" -#include <Kaleidoscope.h> -#include <Kaleidoscope-CharShift.h> -#include <Kaleidoscope-EEPROM-Keymap.h> -#include <Kaleidoscope-EEPROM-Settings.h> -#include <Kaleidoscope-FocusSerial.h> -#include <Kaleidoscope-HardwareTestMode.h> -#include <Kaleidoscope-HostPowerManagement.h> -#include <Kaleidoscope-Heatmap.h> -#include <Kaleidoscope-HostOS.h> -#include <Kaleidoscope-IdleLEDs.h> -#include <Kaleidoscope-LayerHighlighter.h> -#include <Kaleidoscope-LayerNames.h> -#include <Kaleidoscope-Leader.h> -#include <Kaleidoscope-LEDControl.h> -#include <Kaleidoscope-LEDEffect-BootGreeting.h> -#include <Kaleidoscope-LEDEffect-Breathe.h> -#include <Kaleidoscope-LEDEffect-Rainbow.h> -#include <Kaleidoscope-Macros.h> -#include <Kaleidoscope-MagicCombo.h> -#include <Kaleidoscope-NumPad.h> -#include <Kaleidoscope-OneShot.h> -#include <Kaleidoscope-Qukeys.h> -#include <Kaleidoscope-SpaceCadet.h> -#include <Kaleidoscope-Syster.h> -#include <Kaleidoscope-TapDance.h> -#include <Kaleidoscope-USB-Quirks.h> -#include <Kaleidoscope-Unicode.h> +// Support for an LED mode that prints the keys you press in letters 4px high +#include "Kaleidoscope-LED-AlphaSquare.h" + +// Support for shared palettes for other plugins, like Colormap below +#include "Kaleidoscope-LED-Palette-Theme.h" + +// Support for an LED mode that lets one configure per-layer color maps +#include "Kaleidoscope-Colormap.h" + +// Support for turning the LEDs off after a certain amount of time +#include "Kaleidoscope-IdleLEDs.h" + +// Support for overlaying colors +#include "Kaleidoscope-Colormap-Overlay.h" + +// Support for setting and saving the default LED mode +#include "Kaleidoscope-DefaultLEDModeConfig.h" + +// Support for changing the brightness of the LEDs +#include "Kaleidoscope-LEDBrightnessConfig.h" + +// Support for Keyboardio's internal keyboard testing mode +#include "Kaleidoscope-HardwareTestMode.h" + +// Support for host power management (suspend & wakeup) +#include "Kaleidoscope-HostPowerManagement.h" + +// Support for magic combos (key chords that trigger an action) +#include "Kaleidoscope-MagicCombo.h" + +// Support for USB quirks, like changing the key state report protocol +#include "Kaleidoscope-USB-Quirks.h" + +// Support for secondary actions on keys +#include "Kaleidoscope-Qukeys.h" + +// Support for one-shot modifiers and layer keys +#include "Kaleidoscope-OneShot.h" +#include "Kaleidoscope-Escape-OneShot.h" + +// Support for dynamic, Chrysalis-editable macros +#include "Kaleidoscope-DynamicMacros.h" + +// Support for SpaceCadet keys +#include "Kaleidoscope-SpaceCadet.h" + +// Support for editable layer names +#include "Kaleidoscope-LayerNames.h" + +// Support for the GeminiPR Stenography protocol +#include "Kaleidoscope-Steno.h" + +/** This 'enum' is a list of all the macros used by the Model 100's firmware + * The names aren't particularly important. What is important is that each + * is unique. + * + * These are the names of your macros. They'll be used in two places. + * The first is in your keymap definitions. There, you'll use the syntax + * `M(MACRO_NAME)` to mark a specific keymap position as triggering `MACRO_NAME` + * + * The second usage is in the 'switch' statement in the `macroAction` function. + * That switch statement actually runs the code associated with a macro when + * a macro key is pressed. + */ -// Macros enum { MACRO_VERSION_INFO, MACRO_ANY, - WOW, - SAUCY, - LUL, - ZZZ, - GIVE_PLZ, - TAKE_NRG, - SEEMS_GOOD, - GASM }; -// Layers -enum { ENGRAM, FUNCTION, NUMPAD, MACROS }; -typedef struct { - const uint8_t index; - const char *string; -} emote; +/** The Model 100's key layouts are defined as 'keymaps'. By default, there are three + * keymaps: The standard QWERTY keymap, the "Function layer" keymap and the "Numpad" + * keymap. + * + * Each keymap is defined as a list using the 'KEYMAP_STACKED' macro, built + * of first the left hand's layout, followed by the right hand's layout. + * + * Keymaps typically consist mostly of `Key_` definitions. There are many, many keys + * defined as part of the USB HID Keyboard specification. You can find the names + * (if not yet the explanations) for all the standard `Key_` defintions offered by + * Kaleidoscope in these files: + * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/keyboard.h + * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/consumerctl.h + * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/sysctl.h + * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/keymaps.h + * + * Additional things that should be documented here include + * using ___ to let keypresses fall through to the previously active layer + * using XXX to mark a keyswitch as 'blocked' on this layer + * using ShiftToLayer() and LockLayer() keys to change the active keymap. + * keeping NUM and FN consistent and accessible on all layers + * + * The PROG key is special, since it is how you indicate to the board that you + * want to flash the firmware. However, it can be remapped to a regular key. + * When the keyboard boots, it first looks to see whether the PROG key is held + * down; if it is, it simply awaits further flashing instructions. If it is + * not, it continues loading the rest of the firmware and the keyboard + * functions normally, with whatever binding you have set to PROG. More detail + * here: https://community.keyboard.io/t/how-the-prog-key-gets-you-into-the-bootloader/506/8 + * + * The "keymaps" data structure is a list of the keymaps compiled into the firmware. + * The order of keymaps in the list is important, as the ShiftToLayer(#) and LockLayer(#) + * macros switch to key layers based on this list. + * + * -constexpr char wow[] PROGMEM = "eeriedWow"; -constexpr char saucy[] PROGMEM = "eeriedSaucy"; -constexpr char lul[] PROGMEM = "supert25LUL"; -constexpr char zzz[] PROGMEM = "plasmoWife"; -constexpr char givePLZ[] PROGMEM = "GivePLZ"; -constexpr char takeNRG[] PROGMEM = "TakeNRG"; -constexpr char seemsGood[] PROGMEM = "SeemsGood"; -constexpr char gasm[] PROGMEM = "kdubGasm"; + * A key defined as 'ShiftToLayer(FUNCTION)' will switch to FUNCTION while held. + * Similarly, a key defined as 'LockLayer(NUMPAD)' will switch to NUMPAD when tapped. + */ -static constexpr emote emotes[] = { - { WOW, wow }, - { SAUCY, saucy }, - { LUL, lul }, - { ZZZ, zzz }, - { GIVE_PLZ, givePLZ }, - { TAKE_NRG, takeNRG }, - { SEEMS_GOOD, seemsGood }, - { GASM, gasm } -}; +/** + * Layers are "0-indexed" -- That is the first one is layer 0. The second one is layer 1. + * The third one is layer 2. + * This 'enum' lets us use names like QWERTY, FUNCTION, and NUMPAD in place of + * the numbers 0, 1 and 2. + * + */ -// constexpr auto mapSize = kaleidoscope_internal::device.matrix_rows * kaleidoscope_internal::device.matrix_columns; -// constexpr Key workman[mapSize] = -// KEYMAP_STACKED(Key_Escape, Key_1, Key_2, Key_3, Key_4, Key_5, Key_ScrollLock, -// Key_Backtick, Key_Q, Key_D, Key_R, Key_W, Key_B, Key_Tab, -// MoveToLayer(DVORAK), Key_A, Key_S, Key_H, Key_T, Key_G, -// Key_RightGui, Key_Z, Key_X, Key_M, Key_C, Key_V, Key_LeftGui, -// Key_LeftBracket, Key_Backspace, LSHIFT(Key_LeftBracket), LSHIFT(Key_9), -// ShiftToLayer(FUNCTION), +enum { + PRIMARY, + NUMPAD, + FUNCTION, +}; // layers -// LockLayer(MACROS), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD), -// Key_Enter, Key_J, Key_F, Key_U, Key_P, Key_Semicolon, Key_Minus, -// Key_Y, Key_N, Key_E, Key_O, Key_I, Key_Quote, -// Key_PcApplication, Key_K, Key_L, Key_Comma, Key_Period, Key_Slash, Key_Equals, -// LSHIFT(Key_0), LSHIFT(Key_RightBracket), Key_Spacebar, Key_RightBracket, -// ShiftToLayer(FUNCTION)); -// *INDENT-OFF* +/** + * To change your keyboard's layout from QWERTY to DVORAK or COLEMAK, comment out the line + * + * #define PRIMARY_KEYMAP_QWERTY + * + * by changing it to + * + * // #define PRIMARY_KEYMAP_QWERTY + * + * Then uncomment the line corresponding to the layout you want to use. + * + */ -/* - * Engram layout: https://engram.dev/ - * - * [{ 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 - * +// #define PRIMARY_KEYMAP_QWERTY +// #define PRIMARY_KEYMAP_DVORAK +// #define PRIMARY_KEYMAP_COLEMAK +// #define PRIMARY_KEYMAP_CUSTOM +#define PRIMARY_KEYMAP_ENGRAM + + +/* This comment temporarily turns off astyle's indent enforcement + * so we can make the keymaps actually resemble the physical key layout better */ +// clang-format off + +KEYMAPS( -KEYMAPS([ENGRAM] = KEYMAP_STACKED - (Key_Escape, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LeftBracket, - Key_Backtick, Key_B, Key_Y, Key_O, Key_U, CS(0), Key_Tab, - CS(6), Key_C, Key_I, Key_E, Key_A, CS(1), - Key_RightGui, Key_G, Key_X, Key_J, Key_K, CS(2), Key_LeftGui, - Key_LeftControl, Key_Backspace, Key_LeftAlt, Key_LeftShift, - ShiftToLayer(FUNCTION), +#if defined (PRIMARY_KEYMAP_QWERTY) + [PRIMARY] = KEYMAP_STACKED + (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + ShiftToLayer(FUNCTION), - Key_RightBracket, Key_6, Key_7, Key_8, Key_9, Key_0, LEAD(0), - Key_Enter, CS(3), Key_L, Key_D, Key_W, Key_V, Key_Z, - CS(4), Key_H, Key_T, Key_S, Key_N, Key_Q, - Key_PcApplication, CS(5), Key_R, Key_M, Key_F, Key_P, Key_Equals, - Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, - ShiftToLayer(FUNCTION)), + M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD), + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_RightAlt, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl, + ShiftToLayer(FUNCTION)), - [FUNCTION] = KEYMAP_STACKED - (Key_LEDEffectNext, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, LSHIFT(Key_Comma), - Key_CapsLock, ___, ___, ___, ___, ___, LSHIFT(Key_9), - Key_ScrollLock, ___, ___, ___, ___, ___, - Key_KeypadNumLock, Key_PrintScreen, Key_Insert, Consumer_ScanPreviousTrack, Consumer_ScanNextTrack, Consumer_PlaySlashPause, ___, - ___, Key_Delete, ___, ___, - ___, +#elif defined (PRIMARY_KEYMAP_DVORAK) - LSHIFT(Key_Period), Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11, - LSHIFT(Key_0), Key_PageUp, LCTRL(Key_LeftArrow), Key_UpArrow, LCTRL(Key_RightArrow), Key_End, Key_F12, - Key_PageDown, Key_LeftArrow, Key_DownArrow, Key_RightArrow, Key_Home, ___, - ___, Consumer_Mute, Consumer_VolumeDecrement, Consumer_VolumeIncrement, ___, Key_Backslash, Key_Pipe, - ___, ___, ___, ___, - ___), + [PRIMARY] = KEYMAP_STACKED + (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Quote, Key_Comma, Key_Period, Key_P, Key_Y, Key_Tab, + Key_PageUp, Key_A, Key_O, Key_E, Key_U, Key_I, + Key_PageDown, Key_Semicolon, Key_Q, Key_J, Key_K, Key_X, Key_Escape, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + ShiftToLayer(FUNCTION), - [NUMPAD] = KEYMAP_STACKED - (___, ___, ___, ___, ___, ___, ___, - ___, ___, ___, ___, ___, ___, ___, - ___, ___, ___, ___, ___, ___, - ___, ___, ___, ___, ___, ___, ___, - ___, ___, ___, ___, - ___, + M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD), + Key_Enter, Key_F, Key_G, Key_C, Key_R, Key_L, Key_Slash, + Key_D, Key_H, Key_T, Key_N, Key_S, Key_Minus, + Key_RightAlt, Key_B, Key_M, Key_W, Key_V, Key_Z, Key_Equals, + Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl, + ShiftToLayer(FUNCTION)), - ___, ___, Key_Keypad7, Key_Keypad8, Key_Keypad9, Key_KeypadSubtract, UnlockLayer(NUMPAD), - ___, ___, Key_Keypad4, Key_Keypad5, Key_Keypad6, Key_KeypadAdd, ___, - ___, Key_Keypad1, Key_Keypad2, Key_Keypad3, Key_KeypadEquals, ___, - ___, ___, Key_0, Key_KeypadDot, Key_KeypadMultiply, Key_KeypadDivide, Key_KeypadEnter, - ___, ___, ___, ___, - ___), +#elif defined (PRIMARY_KEYMAP_COLEMAK) + + [PRIMARY] = KEYMAP_STACKED + (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_F, Key_P, Key_B, Key_Tab, + Key_PageUp, Key_A, Key_R, Key_S, Key_T, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_D, Key_V, Key_Escape, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + ShiftToLayer(FUNCTION), + + M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD), + Key_Enter, Key_J, Key_L, Key_U, Key_Y, Key_Semicolon, Key_Equals, + Key_M, Key_N, Key_E, Key_I, Key_O, Key_Quote, + Key_RightAlt, Key_K, Key_H, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl, + ShiftToLayer(FUNCTION)), + +#elif defined (PRIMARY_KEYMAP_CUSTOM) + // Edit this keymap to make a custom layout + [PRIMARY] = KEYMAP_STACKED + (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext, + Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab, + Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G, + Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape, + Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift, + ShiftToLayer(FUNCTION), + + M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD), + Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals, + Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote, + Key_RightAlt, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus, + Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl, + ShiftToLayer(FUNCTION)), + +#elif defined (PRIMARY_KEYMAP_ENGRAM) + [PRIMARY] = KEYMAP_STACKED + (Key_Escape, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LeftBracket, + Key_Backtick, Key_B, Key_Y, Key_O, Key_U, CS(0), Key_Tab, + CS(6), Key_C, Key_I, Key_E, Key_A, CS(1), + Key_RightGui, Key_G, Key_X, Key_J, Key_K, CS(2), Key_LeftGui, + Key_LeftControl, Key_Backspace, Key_LeftAlt, Key_LeftShift, + ShiftToLayer(FUNCTION), + + Key_RightBracket, Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD), + Key_Enter, CS(3), Key_L, Key_D, Key_W, Key_V, Key_Z, + CS(4), Key_H, Key_T, Key_S, Key_N, Key_Q, + Key_PcApplication, CS(5), Key_R, Key_M, Key_F, Key_P, Key_Equals, + Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl, + ShiftToLayer(FUNCTION)), +#else + +#error "No default keymap defined. You should make sure that you have a line like '#define PRIMARY_KEYMAP_QWERTY' in your sketch" + +#endif - [MACROS] = KEYMAP_STACKED - (___, ___, ___, ___, ___, ___, ___, - ___, ___, ___, ___, ___, ___, ___, - ___, ___, ___, ___, ___, M(SEEMS_GOOD), - ___, M(ZZZ), ___, M(GASM), ___, ___, ___, - ___, ___, ___, ___, - ___, - M(MACRO_VERSION_INFO), ___, ___, ___, ___, ___, UnlockLayer(MACROS), - ___, ___, ___, ___, ___, M(WOW), ___, - ___, ___, ___, M(LUL), M(SAUCY), ___, - ___, ___, ___, M(GIVE_PLZ), M(TAKE_NRG), ___, ___, - ___, ___, ___, ___, - ___) - ) -// *INDENT-ON* + [NUMPAD] = KEYMAP_STACKED + (___, ___, ___, ___, ___, ___, ___, + ___, ___, ___, ___, ___, ___, ___, + ___, ___, ___, ___, ___, ___, + ___, ___, ___, ___, ___, ___, ___, + ___, ___, ___, ___, + ___, + + M(MACRO_VERSION_INFO), ___, Key_7, Key_8, Key_9, Key_KeypadSubtract, ___, + ___, ___, Key_4, Key_5, Key_6, Key_KeypadAdd, ___, + ___, Key_1, Key_2, Key_3, Key_Equals, ___, + ___, ___, Key_0, Key_Period, Key_KeypadMultiply, Key_KeypadDivide, Key_Enter, + ___, ___, ___, ___, + ___), + + // [FUNCTION] = KEYMAP_STACKED + // (___, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_CapsLock, + // Key_Tab, ___, Key_mouseUp, ___, Key_mouseBtnR, Key_mouseWarpEnd, Key_mouseWarpNE, + // Key_Home, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseBtnL, Key_mouseWarpNW, + // Key_End, Key_PrintScreen, Key_Insert, ___, Key_mouseBtnM, Key_mouseWarpSW, Key_mouseWarpSE, + // ___, Key_Delete, ___, ___, + // ___, + + // Consumer_ScanPreviousTrack, Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11, + // Consumer_PlaySlashPause, Consumer_ScanNextTrack, Key_LeftCurlyBracket, Key_RightCurlyBracket, Key_LeftBracket, Key_RightBracket, Key_F12, + // Key_LeftArrow, Key_DownArrow, Key_UpArrow, Key_RightArrow, ___, ___, + // Key_PcApplication, Consumer_Mute, Consumer_VolumeDecrement, Consumer_VolumeIncrement, ___, Key_Backslash, Key_Pipe, + // ___, ___, Key_Enter, ___, + // ___) + [FUNCTION] = KEYMAP_STACKED + (Key_LEDEffectNext, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, LSHIFT(Key_Comma), + Key_CapsLock, Key_Cut, Key_Copy, Key_Paste, ___, ___, ___, + Key_ScrollLock, ___, ___, ___, ___, ___, + Key_KeypadNumLock, Key_PrintScreen, Key_Insert, Consumer_ScanPreviousTrack, Consumer_ScanNextTrack, Consumer_PlaySlashPause, ___, + ___, Key_Delete, ___, ___, + ___, + + LSHIFT(Key_Period), Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11, + ___, Key_PageUp, LCTRL(Key_LeftArrow), Key_UpArrow, LCTRL(Key_RightArrow), Key_Home, Key_F12, + Key_PageDown, Key_LeftArrow, Key_DownArrow, Key_RightArrow, Key_End, ___, + ___, Consumer_Mute, Consumer_VolumeDecrement, Consumer_VolumeIncrement, ___, Key_Backslash, Key_Pipe, + ___, ___, ___, ___, + ___), +) // KEYMAPS( + +/* Re-enable astyle's indent enforcement */ +// clang-format on + +#define RGB_UNSET CRGB(0x00, 0x00, 0x00) +#define RGB_RED CRGB(0xff, 0x00, 0x00) + +// Set up a default palette to be use for the Colormap and Colormap-Overlay +// plugins +PALETTE( + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_UNSET, + RGB_RED) // PALETTE( /** versionInfoMacro handles the 'firmware version info' macro * When a key bound to the macro is pressed, this macro * prints out the firmware build information as virtual keystrokes */ -static void versionInfoMacro(uint8_t keyState) { - if (keyToggledOn(keyState)) { - Macros.type(PSTR("Keyboardio Model 100 - Kaleidoscope ")); - Macros.type(PSTR(BUILD_INFORMATION)); - Unicode.type(0x2615); +static void versionInfoMacro(uint8_t key_state) { + if (keyToggledOn(key_state)) { + Macros.type(PSTR("Keyboardio Model 100 - Firmware version ")); + Macros.type(PSTR(KALEIDOSCOPE_FIRMWARE_VERSION)); } } @@ -185,6 +393,7 @@ static void versionInfoMacro(uint8_t keyState) { * keypress event repeating that randomly selected key. * */ + static void anyKeyMacro(KeyEvent &event) { if (keyToggledOn(event.state)) { event.key.setKeyCode(Key_A.getKeyCode() + (uint8_t)(millis() % 36)); @@ -192,16 +401,6 @@ static void anyKeyMacro(KeyEvent &event) { } } -static void emoteMacro(uint8_t macroID, KeyEvent &event) { - if (keyToggledOn(event.state)) { - for (auto e : emotes) { - if (e.index == macroID) { - Macros.type(e.string); - return; - } - } - } -} /** macroAction dispatches keymap events that are tied to a macro to that macro. It takes two uint8_t parameters. @@ -213,10 +412,11 @@ static void emoteMacro(uint8_t macroID, KeyEvent &event) { The 'switch' statement should have a 'case' for each entry of the macro enum. Each 'case' statement should call out to a function to handle the macro in question. -*/ + */ + +const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) { + switch (macro_id) { -const macro_t *macroAction(uint8_t macroID, KeyEvent &event) { - switch (macroID) { case MACRO_VERSION_INFO: versionInfoMacro(event.state); break; @@ -224,26 +424,36 @@ const macro_t *macroAction(uint8_t macroID, KeyEvent &event) { case MACRO_ANY: anyKeyMacro(event); break; - - default: - emoteMacro(macroID, event); } return MACRO_NONE; } + +// These 'solid' color effect definitions define a rainbow of +// LED color modes calibrated to draw 500mA or less on the +// Keyboardio Model 100. + + +static kaleidoscope::plugin::LEDSolidColor solidRed(160, 0, 0); +static kaleidoscope::plugin::LEDSolidColor solidOrange(140, 70, 0); +static kaleidoscope::plugin::LEDSolidColor solidYellow(130, 100, 0); +static kaleidoscope::plugin::LEDSolidColor solidGreen(0, 160, 0); +static kaleidoscope::plugin::LEDSolidColor solidBlue(0, 70, 130); +static kaleidoscope::plugin::LEDSolidColor solidIndigo(0, 0, 170); +static kaleidoscope::plugin::LEDSolidColor solidViolet(130, 0, 120); + /** toggleLedsOnSuspendResume toggles the LEDs off when the host goes to sleep, * and turns them back on when it wakes up. */ void toggleLedsOnSuspendResume(kaleidoscope::plugin::HostPowerManagement::Event event) { switch (event) { case kaleidoscope::plugin::HostPowerManagement::Suspend: + case kaleidoscope::plugin::HostPowerManagement::Sleep: LEDControl.disable(); break; case kaleidoscope::plugin::HostPowerManagement::Resume: LEDControl.enable(); break; - case kaleidoscope::plugin::HostPowerManagement::Sleep: - break; } } @@ -255,7 +465,7 @@ void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement:: toggleLedsOnSuspendResume(event); } -/** This 'enum' is a list of all the magic combos used by the Model 01's +/** This 'enum' is a list of all the magic combos used by the Model 100's * firmware The names aren't particularly important. What is important is that * each is unique. * @@ -281,23 +491,24 @@ static void toggleKeyboardProtocol(uint8_t combo_index) { } /** + * Toggles between using the built-in keymap, and the EEPROM-stored one. + */ +static void toggleKeymapSource(uint8_t combo_index) { + if (Layer.getKey == Layer.getKeyFromPROGMEM) { + Layer.getKey = EEPROMKeymap.getKey; + } else { + Layer.getKey = Layer.getKeyFromPROGMEM; + } +} + +/** * This enters the hardware test mode */ static void enterHardwareTestMode(uint8_t combo_index) { HardwareTestMode.runTests(); } - -/** Magic combo list, a list of key combo and action pairs the firmware should - * recognise. - */ -USE_MAGIC_COMBOS({.action = toggleKeyboardProtocol, - // Left Fn + Esc + Shift - .keys = { R3C6, R2C6, R3C7 }}, - {.action = enterHardwareTestMode, - // Left Fn + Prog + LED - .keys = { R3C6, R0C0, R0C6 }}); - +/* void leaderMacro(uint8_t i) { // auto event = kaleidoscope::KeyEvent(KeyAddr::none(), IS_PRESSED, ShiftToLayer(MACROS)); // OneShot.setPending(event); @@ -310,105 +521,283 @@ void leaderNumpad(uint8_t i) { constexpr kaleidoscope::plugin::Leader::dictionary_t leaderDictionary[] = LEADER_DICT({LEADER_SEQ(LEAD(0), Key_M), leaderMacro}, - {LEADER_SEQ(LEAD(0), Key_N), leaderNumpad}); - -constexpr int charshiftCode(uint8_t index) { - return 53631 + index; -} + {LEADER_SEQ(LEAD(0), Key_N), leaderNumpad}); + */ -void tapDanceAction(uint8_t i, KeyAddr addr, uint8_t count, - kaleidoscope::plugin::TapDance::ActionType action) { - switch (i) { - case 0: - return tapDanceActionKeys(count, action, charshiftCode(0), LSHIFT(Key_Comma)); - case 1: - return tapDanceActionKeys(count, action, charshiftCode(1), Key_LeftBracket); - case 2: - return tapDanceActionKeys(count, action, charshiftCode(2), LSHIFT(Key_LeftBracket)); - case 3: - return tapDanceActionKeys(count, action, charshiftCode(3), LSHIFT(Key_Period)); - case 4: - return tapDanceActionKeys(count, action, charshiftCode(4), Key_RightBracket); - case 5: - return tapDanceActionKeys(count, action, charshiftCode(5), LSHIFT(Key_RightBracket)); - } -} - -static kaleidoscope::plugin::LayerHighlighter macroHighlighter(MACROS); +/** Magic combo list, a list of key combo and action pairs the firmware should + * recognise. + */ +USE_MAGIC_COMBOS({.action = toggleKeyboardProtocol, + // Left Fn + Esc + Shift + .keys = {R3C6, R2C6, R3C7}}, + {.action = enterHardwareTestMode, + // Left Fn + Prog + LED + .keys = {R3C6, R0C0, R0C6}}, + {.action = toggleKeymapSource, + // Left Fn + Prog + Shift + .keys = {R3C6, R0C0, R3C7}}); // First, tell Kaleidoscope which plugins you want to use. // The order can be important. For example, LED effects are // added in the order they're listed here. -KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings, - EEPROMKeymap, - Focus, - FocusSettingsCommand, - FocusEEPROMCommand, - LayerNames, - //HostOS, - Unicode, - Qukeys, - CharShift, - TapDance, - Leader, - // LEDControl provides support for other LED - // modes - LEDControl, - IdleLEDs, - BootGreetingEffect, - LEDRainbowWaveEffect, - LEDBreatheEffect, - HeatmapEffect, +KALEIDOSCOPE_INIT_PLUGINS( + // ---------------------------------------------------------------------- + // Chrysalis plugins - // The numpad plugin is responsible for - // lighting up the 'numpad' mode with a - // custom LED effect - NumPad, - macroHighlighter, + // The EEPROMSettings & EEPROMKeymap plugins make it possible to have an + // editable keymap in EEPROM. + EEPROMSettings, + EEPROMKeymap, - // The macros plugin adds support for macros - Macros, + // Focus allows bi-directional communication with the host, and is the + // interface through which the keymap in EEPROM can be edited. + Focus, - // The HostPowerManagement plugin allows us - // to turn LEDs off when then host goes to - // sleep, and resume them when it wakes up. - //HostPowerManagement, + // FocusSettingsCommand adds a few Focus commands, intended to aid in + // changing some settings of the keyboard, such as the default layer (via the + // `settings.defaultLayer` command) + FocusSettingsCommand, - // The MagicCombo plugin lets you use key - // combinations to trigger custom actions - - // a bit like Macros, but triggered by - // pressing multiple keys at the same time. - MagicCombo, + // FocusEEPROMCommand adds a set of Focus commands, which are very helpful in + // both debugging, and in backing up one's EEPROM contents. + FocusEEPROMCommand, - // The USBQuirks plugin lets you do some - // things with USB that we aren't - // comfortable - or able - to do - // automatically, but can be useful - // nevertheless. Such as toggling the key - // report protocol between Boot (used by - // BIOSes) and Report (NKRO). - USBQuirks); + // The FirmwareVersion plugin lets Chrysalis query the version of the firmware + // programmatically. + FirmwareVersion, -void setup() { - Serial.begin(115200); + // The LayerNames plugin allows Chrysalis to display - and edit - custom layer + // names, to be shown instead of the default indexes. + LayerNames, + + // Enables setting, saving (via Chrysalis), and restoring (on boot) the + // default LED mode. + DefaultLEDModeConfig, + + // Enables controlling (and saving) the brightness of the LEDs via Focus. + LEDBrightnessConfig, + + // ---------------------------------------------------------------------- + // Keystroke-handling plugins + + // The Qukeys plugin enables the "Secondary action" functionality in + // Chrysalis. Keys with secondary actions will have their primary action + // performed when tapped, but the secondary action when held. + Qukeys, + + CharShift, + + // SpaceCadet can turn your shifts into parens on tap, while keeping them as + // Shifts when held. SpaceCadetConfig lets Chrysalis configure some aspects of + // the plugin. + SpaceCadet, + SpaceCadetConfig, + + // Enables the "Sticky" behavior for modifiers, and the "Layer shift when + // held" functionality for layer keys. + OneShot, + OneShotConfig, + EscapeOneShot, + EscapeOneShotConfig, + //Leader, + + // The macros plugin adds support for macros + Macros, + + // Enables dynamic, Chrysalis-editable macros. + DynamicMacros, + + // The MouseKeys plugin lets you add keys to your keymap which move the mouse. + MouseKeys, + MouseKeysConfig, - // Necessary for FreeBSD, as it doesn't support NKRO. - //BootKeyboard.default_protocol = HID_BOOT_PROTOCOL; + // The MagicCombo plugin lets you use key combinations to trigger custom + // actions - a bit like Macros, but triggered by pressing multiple keys at the + // same time. + MagicCombo, + // Enables the GeminiPR Stenography protocol. Unused by default, but with the + // plugin enabled, it becomes configurable - and then usable - via Chrysalis. + GeminiPR, + + // ---------------------------------------------------------------------- + // LED mode plugins + + // The boot greeting effect pulses the LED button for 10 seconds after the + // keyboard is first connected + BootGreetingEffect, + + // LEDControl provides support for other LED modes + LEDControl, + + // We start with the LED effect that turns off all the LEDs. + LEDOff, + + // The rainbow effect changes the color of all of the keyboard's keys at the same time + // running through all the colors of the rainbow. + LEDRainbowEffect, + + // The rainbow wave effect lights up your keyboard with all the colors of a rainbow + // and slowly moves the rainbow across your keyboard + LEDRainbowWaveEffect, + + // The chase effect follows the adventure of a blue pixel which chases a red pixel across + // your keyboard. Spoiler: the blue pixel never catches the red pixel + LEDChaseEffect, + + // These static effects turn your keyboard's LEDs a variety of colors + solidRed, + solidOrange, + solidYellow, + solidGreen, + solidBlue, + solidIndigo, + solidViolet, + + // The breathe effect slowly pulses all of the LEDs on your keyboard + LEDBreatheEffect, + + // The AlphaSquare effect prints each character you type, using your + // keyboard's LEDs as a display + AlphaSquareEffect, + + // The stalker effect lights up the keys you've pressed recently + StalkerEffect, + + // The LED Palette Theme plugin provides a shared palette for other plugins, + // like Colormap below + LEDPaletteTheme, + + // The Colormap effect makes it possible to set up per-layer colormaps + ColormapEffect, + + // The colormap overlay plugin provides a way to set LED colors regardless of + // the active LED effect. This is used for lighting up the keys assigned in + // the factory 'numpad' mode + ColormapOverlay, + + // The HostPowerManagement plugin allows us to turn LEDs off when then host + // goes to sleep, and resume them when it wakes up. + HostPowerManagement, + + // Turns LEDs off after a configurable amount of idle time. + IdleLEDs, + PersistentIdleLEDs, + + // ---------------------------------------------------------------------- + // Miscellaneous plugins + + // The USBQuirks plugin lets you do some things with USB that we aren't + // comfortable - or able - to do automatically, but can be useful + // nevertheless. Such as toggling the key report protocol between Boot (used + // by BIOSes) and Report (NKRO). + USBQuirks, + + // The hardware test mode, which can be invoked by tapping Prog, LED and the + // left Fn button at the same time. + HardwareTestMode //, +); + +/** The 'setup' function is one of the two standard Arduino sketch functions. + * It's called when your keyboard first powers up. This is where you set up + * Kaleidoscope and any plugins. + */ +void setup() { // First, call Kaleidoscope's internal setup function Kaleidoscope.setup(); - LayerNames.reserve_storage(128); - EEPROMKeymap.setup(5); + // Add colormap overlays for all keys of the numpad. This makes sure that + // all keys of the numpad light up once the numpad layer is active. + // + // The call signature is: + // kaleidoscope::plugin::Overlay(<layer>, <key_address>, <palette_index>) + // + // Key address matrix: https://github.com/keyboardio/Kaleidoscope/blob/master/plugins/Kaleidoscope-Hardware-Keyboardio-Model100/src/kaleidoscope/device/keyboardio/Model100.h#L175-L205 + // + // (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) | (0, 9) (0, 10) (0, 11) (0, 12) (0, 13) (0, 14) (0, 15) + // (1, 0) (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) | (1, 9) (1, 10) (1, 11) (1, 12) (1, 13) (1, 14) (1, 15) + // (2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) | (2, 10) (2, 11) (2, 12) (2, 13) (2, 14) (2, 15) + // (3, 0) (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (2, 6) | (2, 9) (3, 10) (3, 11) (3, 12) (3, 13) (3, 14) (3, 15) + // (0, 7) (1, 7) (2, 7) (3, 7) | (3, 8) (2, 8) (1, 8) (0, 8) + // (3, 6) | (3, 9) + COLORMAP_OVERLAYS( + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(0, 11), 23), // 7 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(1, 11), 23), // 4 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(2, 11), 23), // 1 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(3, 11), 23), // 0 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(0, 12), 23), // 8 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(1, 12), 23), // 5 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(2, 12), 23), // 2 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(3, 12), 23), // period + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(0, 13), 23), // 9 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(1, 13), 23), // 6 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(2, 13), 23), // 3 + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(3, 13), 23), // multiply + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(0, 14), 23), // substract + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(1, 14), 23), // add + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(2, 14), 23), // equals + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(3, 14), 23), // divide + kaleidoscope::plugin::Overlay(NUMPAD, KeyAddr(3, 15), 23), // enter + ) // COLORMAP_OVERLAYS( + + // Set the hue of the boot greeting effect to something that will result in a + // nice green color. + BootGreetingEffect.hue = 85; + + // We configure the AlphaSquare effect to use RED letters + AlphaSquare.color = CRGB(255, 0, 0); + + // Set the rainbow effects to be reasonably bright, but low enough + // to mitigate audible noise in some environments. + LEDRainbowEffect.brightness(170); + LEDRainbowWaveEffect.brightness(160); + + // Set the action key the test mode should listen for to Left Fn + HardwareTestMode.setActionKey(R3C6); + + // The LED Stalker mode has a few effects. The one we like is called + // 'BlazingTrail'. For details on other options, see + // https://github.com/keyboardio/Kaleidoscope/blob/master/docs/plugins/LED-Stalker.md + StalkerEffect.variant = STALKER(BlazingTrail); - // While we hope to improve this in the future, the NumPad plugin - // needs to be explicitly told which keymap layer is your numpad layer - NumPad.numPadLayer = NUMPAD; + // To make the keymap editable without flashing new firmware, we store + // additional layers in EEPROM. For now, we reserve space for eight layers. If + // one wants to use these layers, just set the default layer to one in EEPROM, + // by using the `settings.defaultLayer` Focus command, or by using the + // `keymap.onlyCustom` command to use EEPROM layers only. + EEPROMKeymap.setup(8); - Leader.dictionary = leaderDictionary; + // We need to tell the Colormap plugin how many layers we want to have custom + // maps for. To make things simple, we set it to eight layers, which is how + // many editable layers we have (see above). + ColormapEffect.max_layers(8); + DefaultColormap.setup(); + + // For Dynamic Macros, we need to reserve storage space for the editable + // macros. A kilobyte is a reasonable default. + DynamicMacros.reserve_storage(1024); + + // If there's a default layer set in EEPROM, we should set that as the default + // here. + Layer.move(EEPROMSettings.default_layer()); + + // To avoid any surprises, SpaceCadet is turned off by default. However, it + // can be permanently enabled via Chrysalis, so we should only disable it if + // no configuration exists. + SpaceCadetConfig.disableSpaceCadetIfUnconfigured(); + + // Editable layer names are stored in EEPROM too, and we reserve 16 bytes per + // layer for them. We need one extra byte per layer for bookkeeping, so we + // reserve 17 / layer in total. + LayerNames.reserve_storage(17 * 8); + + // Unless configured otherwise with Chrysalis, we want to make sure that the + // firmware starts with LED effects off. This avoids over-taxing devices that + // don't have a lot of power to share with USB devices + DefaultLEDModeConfig.activateLEDModeIfUnconfigured(&LEDRainbowWaveEffect); + + //Leader.dictionary = leaderDictionary; - // Engram modifies the standard shift key behavior on the innermost - // column. CS_KEYS(kaleidoscope::plugin::CharShift::KeyPair(Key_Quote, LSHIFT(Key_9)), kaleidoscope::plugin::CharShift::KeyPair(Key_Comma, Key_Semicolon), kaleidoscope::plugin::CharShift::KeyPair(Key_Minus, LSHIFT(Key_Minus)), @@ -416,10 +805,15 @@ void setup() { kaleidoscope::plugin::CharShift::KeyPair(Key_Period, LSHIFT(Key_Semicolon)), kaleidoscope::plugin::CharShift::KeyPair(LSHIFT(Key_Slash), LSHIFT(Key_1)), kaleidoscope::plugin::CharShift::KeyPair(Key_Slash, Key_Backslash)); - - Qukeys.setOverlapThreshold(25); } +/** loop is the second of the standard Arduino sketch functions. + * As you might expect, it runs in a loop, never exiting. + * + * For Kaleidoscope-based keyboard firmware, you usually just want to + * call Kaleidoscope.loop(); and not do anything custom here. + */ + void loop() { Kaleidoscope.loop(); } |
