···11+# This makefile for a Kaleidoscope sketch pulls in all the targets
22+# required to build the example
33+44+55+66+77+ifneq ($(KALEIDOSCOPE_DIR),)
88+search_path += $(KALEIDOSCOPE_DIR)
99+endif
1010+1111+ifneq ($(ARDUINO_DIRECTORIES_USER),)
1212+search_path += $(ARDUINO_DIRECTORIES_USER)/hardware/keyboardio/avr/libraries/Kaleidoscope
1313+endif
1414+1515+ifeq ($(shell uname -s),Darwin)
1616+search_path += $(HOME)/Documents/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
1717+else
1818+search_path += $(HOME)/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
1919+endif
2020+2121+sketch_makefile := etc/makefiles/sketch.mk
2222+2323+$(foreach candidate, $(search_path), $(if $(wildcard $(candidate)/$(sketch_makefile)), $(eval ks_dir ?= $(candidate))))
2424+2525+ifneq ($(ks_dir),)
2626+2727+$(info Using Kaleidoscope from $(ks_dir))
2828+2929+export KALEIDOSCOPE_DIR := $(ks_dir)
3030+include $(ks_dir)/$(sketch_makefile)
3131+3232+else
3333+3434+$(info I can't find your Kaleidoscope installation.)
3535+$(info )
3636+$(info I tried looking in:)
3737+$(info )
3838+$(foreach candidate, $(search_path), $(info $(candidate)))
3939+$(info )
4040+$(info The easiest way to fix this is to set the 'KALEIDOSCOPE_DIR' environment)
4141+$(info variable to the location of your Kaleidoscope directory.)
4242+4343+endif
4444+4545+4646+null-target:
4747+ $(info You should never see this message)
4848+ @:
+769
keyboard/model100/firmware_sharparam.ino
···11+// -*- mode: c++ -*-
22+// Copyright 2016-2022 Keyboardio, inc. <jesse@keyboard.io>
33+// See "LICENSE" for license details
44+55+#ifndef BUILD_INFORMATION
66+#define BUILD_INFORMATION "local build on " __DATE__ " at " __TIME__
77+#endif
88+99+/**
1010+ * These #include directives pull in the Kaleidoscope firmware core,
1111+ * as well as the Kaleidoscope plugins we use in the Model 100's firmware
1212+ */
1313+1414+// The Kaleidoscope core
1515+#include "Kaleidoscope.h"
1616+1717+// Support for storing the keymap in EEPROM
1818+#include "Kaleidoscope-EEPROM-Settings.h"
1919+#include "Kaleidoscope-EEPROM-Keymap.h"
2020+2121+// Support for communicating with the host via a simple Serial protocol
2222+#include "Kaleidoscope-FocusSerial.h"
2323+2424+// Support for querying the firmware version via Focus
2525+#include "Kaleidoscope-FirmwareVersion.h"
2626+2727+// Support for keys that move the mouse
2828+#include "Kaleidoscope-MouseKeys.h"
2929+3030+// Support for macros
3131+#include "Kaleidoscope-Macros.h"
3232+3333+// Support for controlling the keyboard's LEDs
3434+#include "Kaleidoscope-LEDControl.h"
3535+3636+// Support for "Numpad" mode, which is mostly just the Numpad specific LED mode
3737+//#include "Kaleidoscope-NumPad.h"
3838+3939+// Support for the "Boot greeting" effect, which pulses the 'LED' button for 10s
4040+// when the keyboard is connected to a computer (or that computer is powered on)
4141+#include "Kaleidoscope-LEDEffect-BootGreeting.h"
4242+4343+// Support for LED modes that set all LEDs to a single color
4444+//#include "Kaleidoscope-LEDEffect-SolidColor.h"
4545+4646+// Support for an LED mode that makes all the LEDs 'breathe'
4747+//#include "Kaleidoscope-LEDEffect-Breathe.h"
4848+4949+// Support for an LED mode that makes a red pixel chase a blue pixel across the keyboard
5050+//#include "Kaleidoscope-LEDEffect-Chase.h"
5151+5252+// Support for LED modes that pulse the keyboard's LED in a rainbow pattern
5353+//#include "Kaleidoscope-LEDEffect-Rainbow.h"
5454+5555+// Support for an LED mode that lights up the keys as you press them
5656+#include "Kaleidoscope-LED-Stalker.h"
5757+5858+// Support for an LED mode that prints the keys you press in letters 4px high
5959+#include "Kaleidoscope-LED-AlphaSquare.h"
6060+6161+// Support for shared palettes for other plugins, like Colormap below
6262+#include "Kaleidoscope-LED-Palette-Theme.h"
6363+6464+// Support for an LED mode that lets one configure per-layer color maps
6565+#include "Kaleidoscope-Colormap.h"
6666+6767+// Support for turning the LEDs off after a certain amount of time
6868+#include "Kaleidoscope-IdleLEDs.h"
6969+7070+// Support for setting and saving the default LED mode
7171+#include "Kaleidoscope-DefaultLEDModeConfig.h"
7272+7373+// Support for changing the brightness of the LEDs
7474+#include "Kaleidoscope-LEDBrightnessConfig.h"
7575+7676+// Support for Keyboardio's internal keyboard testing mode
7777+#include "Kaleidoscope-HardwareTestMode.h"
7878+7979+// Support for host power management (suspend & wakeup)
8080+#include "Kaleidoscope-HostPowerManagement.h"
8181+8282+// Support for magic combos (key chords that trigger an action)
8383+#include "Kaleidoscope-MagicCombo.h"
8484+8585+// Support for USB quirks, like changing the key state report protocol
8686+#include "Kaleidoscope-USB-Quirks.h"
8787+8888+// Support for secondary actions on keys
8989+#include "Kaleidoscope-Qukeys.h"
9090+9191+// Support for one-shot modifiers and layer keys
9292+#include "Kaleidoscope-OneShot.h"
9393+#include "Kaleidoscope-Escape-OneShot.h"
9494+9595+// Support for dynamic, Chrysalis-editable macros
9696+#include "Kaleidoscope-DynamicMacros.h"
9797+9898+// Support for SpaceCadet keys
9999+//#include "Kaleidoscope-SpaceCadet.h"
100100+101101+// Support for editable layer names
102102+#include "Kaleidoscope-LayerNames.h"
103103+104104+// Support for the GeminiPR Stenography protocol
105105+#include "Kaleidoscope-Steno.h"
106106+107107+/** This 'enum' is a list of all the macros used by the Model 100's firmware
108108+ * The names aren't particularly important. What is important is that each
109109+ * is unique.
110110+ *
111111+ * These are the names of your macros. They'll be used in two places.
112112+ * The first is in your keymap definitions. There, you'll use the syntax
113113+ * `M(MACRO_NAME)` to mark a specific keymap position as triggering `MACRO_NAME`
114114+ *
115115+ * The second usage is in the 'switch' statement in the `macroAction` function.
116116+ * That switch statement actually runs the code associated with a macro when
117117+ * a macro key is pressed.
118118+ */
119119+120120+enum {
121121+ MACRO_VERSION_INFO,
122122+ MACRO_ANY,
123123+ MACRO_TOGGLE_QUKEYS,
124124+ MACRO_MOVETO_BASE_LAYER,
125125+ MACRO_SWITCHTO_QWERTY,
126126+ MACRO_SWITCHTO_DVORAK,
127127+ MACRO_SWITCHTO_COLEMAK_DH
128128+};
129129+130130+131131+/** The Model 100's key layouts are defined as 'keymaps'. By default, there are three
132132+ * keymaps: The standard QWERTY keymap, the "Function layer" keymap and the "Numpad"
133133+ * keymap.
134134+ *
135135+ * Each keymap is defined as a list using the 'KEYMAP_STACKED' macro, built
136136+ * of first the left hand's layout, followed by the right hand's layout.
137137+ *
138138+ * Keymaps typically consist mostly of `Key_` definitions. There are many, many keys
139139+ * defined as part of the USB HID Keyboard specification. You can find the names
140140+ * (if not yet the explanations) for all the standard `Key_` defintions offered by
141141+ * Kaleidoscope in these files:
142142+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/keyboard.h
143143+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/consumerctl.h
144144+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/sysctl.h
145145+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/keymaps.h
146146+ *
147147+ * Additional things that should be documented here include
148148+ * using ___ to let keypresses fall through to the previously active layer
149149+ * using XXX to mark a keyswitch as 'blocked' on this layer
150150+ * using ShiftToLayer() and LockLayer() keys to change the active keymap.
151151+ * keeping NUM and FN consistent and accessible on all layers
152152+ *
153153+ * The PROG key is special, since it is how you indicate to the board that you
154154+ * want to flash the firmware. However, it can be remapped to a regular key.
155155+ * When the keyboard boots, it first looks to see whether the PROG key is held
156156+ * down; if it is, it simply awaits further flashing instructions. If it is
157157+ * not, it continues loading the rest of the firmware and the keyboard
158158+ * functions normally, with whatever binding you have set to PROG. More detail
159159+ * here: https://community.keyboard.io/t/how-the-prog-key-gets-you-into-the-bootloader/506/8
160160+ *
161161+ * The "keymaps" data structure is a list of the keymaps compiled into the firmware.
162162+ * The order of keymaps in the list is important, as the ShiftToLayer(#) and LockLayer(#)
163163+ * macros switch to key layers based on this list.
164164+ *
165165+ *
166166+167167+ * A key defined as 'ShiftToLayer(FUNCTION)' will switch to FUNCTION while held.
168168+ * Similarly, a key defined as 'LockLayer(NUMPAD)' will switch to NUMPAD when tapped.
169169+ */
170170+171171+/**
172172+ * Layers are "0-indexed" -- That is the first one is layer 0. The second one is layer 1.
173173+ * The third one is layer 2.
174174+ * This 'enum' lets us use names like QWERTY, FUNCTION, and NUMPAD in place of
175175+ * the numbers 0, 1 and 2.
176176+ *
177177+ */
178178+179179+enum {
180180+ PRIMARY,
181181+ NUMPAD,
182182+ FUNCTION,
183183+ MOUSE
184184+}; // layers
185185+186186+187187+/**
188188+ * To change your keyboard's layout from QWERTY to DVORAK or COLEMAK, comment out the line
189189+ *
190190+ * #define PRIMARY_KEYMAP_QWERTY
191191+ *
192192+ * by changing it to
193193+ *
194194+ * // #define PRIMARY_KEYMAP_QWERTY
195195+ *
196196+ * Then uncomment the line corresponding to the layout you want to use.
197197+ *
198198+ */
199199+200200+#define PRIMARY_KEYMAP_QWERTY
201201+// #define PRIMARY_KEYMAP_DVORAK
202202+// #define PRIMARY_KEYMAP_COLEMAK
203203+// #define PRIMARY_KEYMAP_CUSTOM
204204+205205+206206+/* This comment temporarily turns off astyle's indent enforcement
207207+ * so we can make the keymaps actually resemble the physical key layout better
208208+ */
209209+// clang-format off
210210+211211+KEYMAPS(
212212+213213+#if defined (PRIMARY_KEYMAP_QWERTY)
214214+ [PRIMARY] = KEYMAP_STACKED
215215+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
216216+ Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
217217+ Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
218218+ Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
219219+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
220220+ ShiftToLayer(FUNCTION),
221221+222222+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
223223+ Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
224224+ Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
225225+ Key_RightAlt, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
226226+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
227227+ ShiftToLayer(FUNCTION)),
228228+229229+#elif defined (PRIMARY_KEYMAP_DVORAK)
230230+231231+ [PRIMARY] = KEYMAP_STACKED
232232+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
233233+ Key_Backtick, Key_Quote, Key_Comma, Key_Period, Key_P, Key_Y, Key_Tab,
234234+ Key_PageUp, Key_A, Key_O, Key_E, Key_U, Key_I,
235235+ Key_PageDown, Key_Semicolon, Key_Q, Key_J, Key_K, Key_X, Key_Escape,
236236+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
237237+ ShiftToLayer(FUNCTION),
238238+239239+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
240240+ Key_Enter, Key_F, Key_G, Key_C, Key_R, Key_L, Key_Slash,
241241+ Key_D, Key_H, Key_T, Key_N, Key_S, Key_Minus,
242242+ Key_RightAlt, Key_B, Key_M, Key_W, Key_V, Key_Z, Key_Equals,
243243+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
244244+ ShiftToLayer(FUNCTION)),
245245+246246+#elif defined (PRIMARY_KEYMAP_COLEMAK)
247247+248248+ [PRIMARY] = KEYMAP_STACKED
249249+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
250250+ Key_Backtick, Key_Q, Key_W, Key_F, Key_P, Key_B, Key_Tab,
251251+ Key_PageUp, Key_A, Key_R, Key_S, Key_T, Key_G,
252252+ Key_PageDown, Key_Z, Key_X, Key_C, Key_D, Key_V, Key_Escape,
253253+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
254254+ ShiftToLayer(FUNCTION),
255255+256256+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
257257+ Key_Enter, Key_J, Key_L, Key_U, Key_Y, Key_Semicolon, Key_Equals,
258258+ Key_M, Key_N, Key_E, Key_I, Key_O, Key_Quote,
259259+ Key_RightAlt, Key_K, Key_H, Key_Comma, Key_Period, Key_Slash, Key_Minus,
260260+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
261261+ ShiftToLayer(FUNCTION)),
262262+263263+#elif defined (PRIMARY_KEYMAP_CUSTOM)
264264+ // Edit this keymap to make a custom layout
265265+ [PRIMARY] = KEYMAP_STACKED
266266+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
267267+ Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
268268+ Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
269269+ Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
270270+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
271271+ ShiftToLayer(FUNCTION),
272272+273273+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
274274+ Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
275275+ Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
276276+ Key_RightAlt, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
277277+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
278278+ ShiftToLayer(FUNCTION)),
279279+280280+#else
281281+282282+#error "No default keymap defined. You should make sure that you have a line like '#define PRIMARY_KEYMAP_QWERTY' in your sketch"
283283+284284+#endif
285285+286286+287287+288288+ [NUMPAD] = KEYMAP_STACKED
289289+ (___, ___, ___, ___, ___, ___, ___,
290290+ ___, ___, ___, ___, ___, ___, ___,
291291+ ___, ___, ___, ___, ___, ___,
292292+ ___, ___, ___, ___, ___, ___, ___,
293293+ ___, ___, ___, ___,
294294+ ___,
295295+296296+ M(MACRO_VERSION_INFO), ___, Key_7, Key_8, Key_9, Key_KeypadSubtract, ___,
297297+ ___, ___, Key_4, Key_5, Key_6, Key_KeypadAdd, ___,
298298+ ___, Key_1, Key_2, Key_3, Key_Equals, ___,
299299+ ___, ___, Key_0, Key_Period, Key_KeypadMultiply, Key_KeypadDivide, Key_Enter,
300300+ ___, ___, ___, ___,
301301+ ___),
302302+303303+ [FUNCTION] = KEYMAP_STACKED
304304+ (___, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_CapsLock,
305305+ Key_Tab, ___, Key_mouseUp, ___, Key_mouseBtnR, Key_mouseWarpEnd, Key_mouseWarpNE,
306306+ Key_Home, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseBtnL, Key_mouseWarpNW,
307307+ Key_End, Key_PrintScreen, Key_Insert, ___, Key_mouseBtnM, Key_mouseWarpSW, Key_mouseWarpSE,
308308+ ___, Key_Delete, ___, ___,
309309+ ___,
310310+311311+ Consumer_ScanPreviousTrack, Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11,
312312+ Consumer_PlaySlashPause, Consumer_ScanNextTrack, Key_LeftCurlyBracket, Key_RightCurlyBracket, Key_LeftBracket, Key_RightBracket, Key_F12,
313313+ Key_LeftArrow, Key_DownArrow, Key_UpArrow, Key_RightArrow, ___, ___,
314314+ Key_PcApplication, Consumer_Mute, Consumer_VolumeDecrement, Consumer_VolumeIncrement, ___, Key_Backslash, Key_Pipe,
315315+ ___, ___, Key_Enter, ___,
316316+ ___)
317317+) // KEYMAPS(
318318+319319+/* Re-enable astyle's indent enforcement */
320320+// clang-format on
321321+322322+/** versionInfoMacro handles the 'firmware version info' macro
323323+ * When a key bound to the macro is pressed, this macro
324324+ * prints out the firmware build information as virtual keystrokes
325325+ */
326326+327327+static void versionInfoMacro(uint8_t key_state) {
328328+ if (keyToggledOn(key_state)) {
329329+ Macros.type(PSTR("Keyboardio Model 100 - Firmware version "));
330330+ Macros.type(PSTR(KALEIDOSCOPE_FIRMWARE_VERSION));
331331+ }
332332+}
333333+334334+/** anyKeyMacro is used to provide the functionality of the 'Any' key.
335335+ *
336336+ * When the 'any key' macro is toggled on, a random alphanumeric key is
337337+ * selected. While the key is held, the function generates a synthetic
338338+ * keypress event repeating that randomly selected key.
339339+ *
340340+ */
341341+342342+static void anyKeyMacro(KeyEvent &event) {
343343+ if (keyToggledOn(event.state)) {
344344+ event.key.setKeyCode(Key_A.getKeyCode() + (uint8_t)(millis() % 36));
345345+ event.key.setFlags(0);
346346+ }
347347+}
348348+349349+static uint8_t baseLayerIndex = 0;
350350+351351+static void moveToBaseLayer(KeyEvent &event) {
352352+ if (!keyToggledOn(event.state)) {
353353+ return;
354354+ }
355355+356356+ Layer.move(baseLayerIndex);
357357+}
358358+359359+static void switchToQwerty(KeyEvent &event) {
360360+ if (!keyToggledOn(event.state)) {
361361+ return;
362362+ }
363363+364364+ baseLayerIndex = 0;
365365+ Layer.move(baseLayerIndex);
366366+}
367367+368368+static void switchToDvorak(KeyEvent &event) {
369369+ if (!keyToggledOn(event.state)) {
370370+ return;
371371+ }
372372+373373+ baseLayerIndex = 3;
374374+ Layer.move(baseLayerIndex);
375375+}
376376+377377+static void switchToColemakDh(KeyEvent &event) {
378378+ if (!keyToggledOn(event.state)) {
379379+ return;
380380+ }
381381+382382+ baseLayerIndex = 7;
383383+ Layer.move(baseLayerIndex);
384384+}
385385+386386+387387+/** macroAction dispatches keymap events that are tied to a macro
388388+ to that macro. It takes two uint8_t parameters.
389389+390390+ The first is the macro being called (the entry in the 'enum' earlier in this file).
391391+ The second is the state of the keyswitch. You can use the keyswitch state to figure out
392392+ if the key has just been toggled on, is currently pressed or if it's just been released.
393393+394394+ The 'switch' statement should have a 'case' for each entry of the macro enum.
395395+ Each 'case' statement should call out to a function to handle the macro in question.
396396+397397+ */
398398+399399+const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
400400+ switch (macro_id) {
401401+402402+ case MACRO_VERSION_INFO:
403403+ versionInfoMacro(event.state);
404404+ break;
405405+406406+ case MACRO_ANY:
407407+ anyKeyMacro(event);
408408+ break;
409409+410410+ case MACRO_TOGGLE_QUKEYS:
411411+ if (keyToggledOn(event.state)) {
412412+ Qukeys.toggle();
413413+ }
414414+ break;
415415+416416+ case MACRO_MOVETO_BASE_LAYER:
417417+ moveToBaseLayer(event);
418418+ break;
419419+ case MACRO_SWITCHTO_QWERTY:
420420+ switchToQwerty(event);
421421+ break;
422422+ case MACRO_SWITCHTO_DVORAK:
423423+ switchToDvorak(event);
424424+ break;
425425+ case MACRO_SWITCHTO_COLEMAK_DH:
426426+ switchToColemakDh(event);
427427+ break;
428428+ }
429429+ return MACRO_NONE;
430430+}
431431+432432+433433+// These 'solid' color effect definitions define a rainbow of
434434+// LED color modes calibrated to draw 500mA or less on the
435435+// Keyboardio Model 100.
436436+437437+438438+//static kaleidoscope::plugin::LEDSolidColor solidRed(160, 0, 0);
439439+//static kaleidoscope::plugin::LEDSolidColor solidOrange(140, 70, 0);
440440+//static kaleidoscope::plugin::LEDSolidColor solidYellow(130, 100, 0);
441441+//static kaleidoscope::plugin::LEDSolidColor solidGreen(0, 160, 0);
442442+//static kaleidoscope::plugin::LEDSolidColor solidBlue(0, 70, 130);
443443+//static kaleidoscope::plugin::LEDSolidColor solidIndigo(0, 0, 170);
444444+//static kaleidoscope::plugin::LEDSolidColor solidViolet(130, 0, 120);
445445+446446+/** toggleLedsOnSuspendResume toggles the LEDs off when the host goes to sleep,
447447+ * and turns them back on when it wakes up.
448448+ */
449449+void toggleLedsOnSuspendResume(kaleidoscope::plugin::HostPowerManagement::Event event) {
450450+ switch (event) {
451451+ case kaleidoscope::plugin::HostPowerManagement::Suspend:
452452+ case kaleidoscope::plugin::HostPowerManagement::Sleep:
453453+ LEDControl.disable();
454454+ break;
455455+ case kaleidoscope::plugin::HostPowerManagement::Resume:
456456+ LEDControl.enable();
457457+ break;
458458+ }
459459+}
460460+461461+/** hostPowerManagementEventHandler dispatches power management events (suspend,
462462+ * resume, and sleep) to other functions that perform action based on these
463463+ * events.
464464+ */
465465+void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement::Event event) {
466466+ toggleLedsOnSuspendResume(event);
467467+}
468468+469469+/** This 'enum' is a list of all the magic combos used by the Model 100's
470470+ * firmware The names aren't particularly important. What is important is that
471471+ * each is unique.
472472+ *
473473+ * These are the names of your magic combos. They will be used by the
474474+ * `USE_MAGIC_COMBOS` call below.
475475+ */
476476+enum {
477477+ // Toggle between Boot (6-key rollover; for BIOSes and early boot) and NKRO
478478+ // mode.
479479+ COMBO_TOGGLE_NKRO_MODE,
480480+ // Enter test mode
481481+ COMBO_ENTER_TEST_MODE
482482+};
483483+484484+/** Wrappers, to be used by MagicCombo. **/
485485+486486+/**
487487+ * This simply toggles the keyboard protocol via USBQuirks, and wraps it within
488488+ * a function with an unused argument, to match what MagicCombo expects.
489489+ */
490490+static void toggleKeyboardProtocol(uint8_t combo_index) {
491491+ USBQuirks.toggleKeyboardProtocol();
492492+}
493493+494494+/**
495495+ * Toggles between using the built-in keymap, and the EEPROM-stored one.
496496+ */
497497+static void toggleKeymapSource(uint8_t combo_index) {
498498+ if (Layer.getKey == Layer.getKeyFromPROGMEM) {
499499+ Layer.getKey = EEPROMKeymap.getKey;
500500+ } else {
501501+ Layer.getKey = Layer.getKeyFromPROGMEM;
502502+ }
503503+}
504504+505505+/**
506506+ * This enters the hardware test mode
507507+ */
508508+static void enterHardwareTestMode(uint8_t combo_index) {
509509+ HardwareTestMode.runTests();
510510+}
511511+512512+513513+/** Magic combo list, a list of key combo and action pairs the firmware should
514514+ * recognise.
515515+ */
516516+USE_MAGIC_COMBOS({.action = toggleKeyboardProtocol,
517517+ // Left Fn + Esc + Shift
518518+ .keys = {R3C6, R2C6, R3C7}},
519519+ {.action = enterHardwareTestMode,
520520+ // Left Fn + Prog + LED
521521+ .keys = {R3C6, R0C0, R0C6}},
522522+ {.action = toggleKeymapSource,
523523+ // Left Fn + Prog + Shift
524524+ .keys = {R3C6, R0C0, R3C7}});
525525+526526+// First, tell Kaleidoscope which plugins you want to use.
527527+// The order can be important. For example, LED effects are
528528+// added in the order they're listed here.
529529+KALEIDOSCOPE_INIT_PLUGINS(
530530+ // ----------------------------------------------------------------------
531531+ // Chrysalis plugins
532532+533533+ // The EEPROMSettings & EEPROMKeymap plugins make it possible to have an
534534+ // editable keymap in EEPROM.
535535+ EEPROMSettings,
536536+ EEPROMKeymap,
537537+538538+ // Focus allows bi-directional communication with the host, and is the
539539+ // interface through which the keymap in EEPROM can be edited.
540540+ Focus,
541541+542542+ // FocusSettingsCommand adds a few Focus commands, intended to aid in
543543+ // changing some settings of the keyboard, such as the default layer (via the
544544+ // `settings.defaultLayer` command)
545545+ FocusSettingsCommand,
546546+547547+ // FocusEEPROMCommand adds a set of Focus commands, which are very helpful in
548548+ // both debugging, and in backing up one's EEPROM contents.
549549+ FocusEEPROMCommand,
550550+551551+ // The FirmwareVersion plugin lets Chrysalis query the version of the firmware
552552+ // programmatically.
553553+ FirmwareVersion,
554554+555555+ // The LayerNames plugin allows Chrysalis to display - and edit - custom layer
556556+ // names, to be shown instead of the default indexes.
557557+ LayerNames,
558558+559559+ // Enables setting, saving (via Chrysalis), and restoring (on boot) the
560560+ // default LED mode.
561561+ DefaultLEDModeConfig,
562562+563563+ // Enables controlling (and saving) the brightness of the LEDs via Focus.
564564+ LEDBrightnessConfig,
565565+566566+ // ----------------------------------------------------------------------
567567+ // Keystroke-handling plugins
568568+569569+ // The Qukeys plugin enables the "Secondary action" functionality in
570570+ // Chrysalis. Keys with secondary actions will have their primary action
571571+ // performed when tapped, but the secondary action when held.
572572+ Qukeys,
573573+574574+ // SpaceCadet can turn your shifts into parens on tap, while keeping them as
575575+ // Shifts when held. SpaceCadetConfig lets Chrysalis configure some aspects of
576576+ // the plugin.
577577+ //SpaceCadet,
578578+ //SpaceCadetConfig,
579579+580580+ // Enables the "Sticky" behavior for modifiers, and the "Layer shift when
581581+ // held" functionality for layer keys.
582582+ OneShot,
583583+ OneShotConfig,
584584+ EscapeOneShot,
585585+ EscapeOneShotConfig,
586586+587587+ // The macros plugin adds support for macros
588588+ Macros,
589589+590590+ // Enables dynamic, Chrysalis-editable macros.
591591+ DynamicMacros,
592592+593593+ // The MouseKeys plugin lets you add keys to your keymap which move the mouse.
594594+ MouseKeys,
595595+ MouseKeysConfig,
596596+597597+ // The MagicCombo plugin lets you use key combinations to trigger custom
598598+ // actions - a bit like Macros, but triggered by pressing multiple keys at the
599599+ // same time.
600600+ MagicCombo,
601601+602602+ // Enables the GeminiPR Stenography protocol. Unused by default, but with the
603603+ // plugin enabled, it becomes configurable - and then usable - via Chrysalis.
604604+ GeminiPR,
605605+606606+ // ----------------------------------------------------------------------
607607+ // LED mode plugins
608608+609609+ // The boot greeting effect pulses the LED button for 10 seconds after the
610610+ // keyboard is first connected
611611+ BootGreetingEffect,
612612+613613+ // LEDControl provides support for other LED modes
614614+ LEDControl,
615615+616616+ // We start with the LED effect that turns off all the LEDs.
617617+ LEDOff,
618618+619619+ // The rainbow effect changes the color of all of the keyboard's keys at the same time
620620+ // running through all the colors of the rainbow.
621621+ //LEDRainbowEffect,
622622+623623+ // The rainbow wave effect lights up your keyboard with all the colors of a rainbow
624624+ // and slowly moves the rainbow across your keyboard
625625+ //LEDRainbowWaveEffect,
626626+627627+ // The chase effect follows the adventure of a blue pixel which chases a red pixel across
628628+ // your keyboard. Spoiler: the blue pixel never catches the red pixel
629629+ //LEDChaseEffect,
630630+631631+ // These static effects turn your keyboard's LEDs a variety of colors
632632+ //solidRed,
633633+ //solidOrange,
634634+ //solidYellow,
635635+ //solidGreen,
636636+ //solidBlue,
637637+ //solidIndigo,
638638+ //solidViolet,
639639+640640+ // The breathe effect slowly pulses all of the LEDs on your keyboard
641641+ //LEDBreatheEffect,
642642+643643+ // The AlphaSquare effect prints each character you type, using your
644644+ // keyboard's LEDs as a display
645645+ AlphaSquareEffect,
646646+647647+ // The stalker effect lights up the keys you've pressed recently
648648+ StalkerEffect,
649649+650650+ // The LED Palette Theme plugin provides a shared palette for other plugins,
651651+ // like Colormap below
652652+ LEDPaletteTheme,
653653+654654+ // The Colormap effect makes it possible to set up per-layer colormaps
655655+ ColormapEffect,
656656+657657+ // The numpad plugin is responsible for lighting up the 'numpad' mode
658658+ // with a custom LED effect
659659+ //NumPad,
660660+661661+ // The HostPowerManagement plugin allows us to turn LEDs off when then host
662662+ // goes to sleep, and resume them when it wakes up.
663663+ HostPowerManagement,
664664+665665+ // Turns LEDs off after a configurable amount of idle time.
666666+ IdleLEDs,
667667+ PersistentIdleLEDs,
668668+669669+ // ----------------------------------------------------------------------
670670+ // Miscellaneous plugins
671671+672672+ // The USBQuirks plugin lets you do some things with USB that we aren't
673673+ // comfortable - or able - to do automatically, but can be useful
674674+ // nevertheless. Such as toggling the key report protocol between Boot (used
675675+ // by BIOSes) and Report (NKRO).
676676+ USBQuirks,
677677+678678+ // The hardware test mode, which can be invoked by tapping Prog, LED and the
679679+ // left Fn button at the same time.
680680+ HardwareTestMode //,
681681+);
682682+683683+/** The 'setup' function is one of the two standard Arduino sketch functions.
684684+ * It's called when your keyboard first powers up. This is where you set up
685685+ * Kaleidoscope and any plugins.
686686+ */
687687+void setup() {
688688+ // QUKEYS(
689689+ // kaleidoscope::plugin::Qukey(kaleidoscope::plugin::Qukeys::layer_wildcard, KeyAddr(3, 7), LSHIFT(Key_9)),
690690+ // kaleidoscope::plugin::Qukey(kaleidoscope::plugin::Qukeys::layer_wildcard, KeyAddr(3, 8), LSHIFT(Key_0))
691691+ // )
692692+693693+ // First, call Kaleidoscope's internal setup function
694694+ Kaleidoscope.setup();
695695+696696+ // Set the hue of the boot greeting effect to something that will result in a
697697+ // nice green color.
698698+ BootGreetingEffect.hue = 85;
699699+700700+ // While we hope to improve this in the future, the NumPad plugin
701701+ // needs to be explicitly told which keymap layer is your numpad layer
702702+ //NumPad.numPadLayer = NUMPAD;
703703+704704+ // We configure the AlphaSquare effect to use RED letters
705705+ AlphaSquare.color = CRGB(255, 0, 0);
706706+707707+ // Set the rainbow effects to be reasonably bright, but low enough
708708+ // to mitigate audible noise in some environments.
709709+ //LEDRainbowEffect.brightness(170);
710710+ //LEDRainbowWaveEffect.brightness(160);
711711+712712+ // Set the action key the test mode should listen for to Left Fn
713713+ HardwareTestMode.setActionKey(R3C6);
714714+715715+ // The LED Stalker mode has a few effects. The one we like is called
716716+ // 'BlazingTrail'. For details on other options, see
717717+ // https://github.com/keyboardio/Kaleidoscope/blob/master/docs/plugins/LED-Stalker.md
718718+ StalkerEffect.variant = STALKER(BlazingTrail);
719719+720720+ // To make the keymap editable without flashing new firmware, we store
721721+ // additional layers in EEPROM. For now, we reserve space for eight layers. If
722722+ // one wants to use these layers, just set the default layer to one in EEPROM,
723723+ // by using the `settings.defaultLayer` Focus command, or by using the
724724+ // `keymap.onlyCustom` command to use EEPROM layers only.
725725+ EEPROMKeymap.setup(8);
726726+727727+ // We need to tell the Colormap plugin how many layers we want to have custom
728728+ // maps for. To make things simple, we set it to eight layers, which is how
729729+ // many editable layers we have (see above).
730730+ ColormapEffect.max_layers(8);
731731+732732+ // For Dynamic Macros, we need to reserve storage space for the editable
733733+ // macros. A kilobyte is a reasonable default.
734734+ DynamicMacros.reserve_storage(1024);
735735+736736+ // If there's a default layer set in EEPROM, we should set that as the default
737737+ // here.
738738+ Layer.move(EEPROMSettings.default_layer());
739739+740740+ // To avoid any surprises, SpaceCadet is turned off by default. However, it
741741+ // can be permanently enabled via Chrysalis, so we should only disable it if
742742+ // no configuration exists.
743743+ //SpaceCadetConfig.disableSpaceCadetIfUnconfigured();
744744+745745+ // Editable layer names are stored in EEPROM too, and we reserve 16 bytes per
746746+ // layer for them. We need one extra byte per layer for bookkeeping, so we
747747+ // reserve 17 / layer in total.
748748+ LayerNames.reserve_storage(17 * 8);
749749+750750+ // Unless configured otherwise with Chrysalis, we want to make sure that the
751751+ // firmware starts with LED effects off. This avoids over-taxing devices that
752752+ // don't have a lot of power to share with USB devices
753753+ DefaultLEDModeConfig.activateLEDModeIfUnconfigured(&LEDOff);
754754+755755+ // Qukeys config
756756+ Qukeys.setOverlapThreshold(90);
757757+ Qukeys.setMinimumHoldTime(100);
758758+}
759759+760760+/** loop is the second of the standard Arduino sketch functions.
761761+ * As you might expect, it runs in a loop, never exiting.
762762+ *
763763+ * For Kaleidoscope-based keyboard firmware, you usually just want to
764764+ * call Kaleidoscope.loop(); and not do anything custom here.
765765+ */
766766+767767+void loop() {
768768+ Kaleidoscope.loop();
769769+}
+704
keyboard/model100/firmware_sharparam.ino.bak
···11+// -*- mode: c++ -*-
22+// Copyright 2016-2022 Keyboardio, inc. <jesse@keyboard.io>
33+// See "LICENSE" for license details
44+55+#ifndef BUILD_INFORMATION
66+#define BUILD_INFORMATION "local build on " __DATE__ " at " __TIME__
77+#endif
88+99+/**
1010+ * These #include directives pull in the Kaleidoscope firmware core,
1111+ * as well as the Kaleidoscope plugins we use in the Model 100's firmware
1212+ */
1313+1414+// The Kaleidoscope core
1515+#include "Kaleidoscope.h"
1616+1717+// Support for storing the keymap in EEPROM
1818+#include "Kaleidoscope-EEPROM-Settings.h"
1919+#include "Kaleidoscope-EEPROM-Keymap.h"
2020+2121+// Support for communicating with the host via a simple Serial protocol
2222+#include "Kaleidoscope-FocusSerial.h"
2323+2424+// Support for querying the firmware version via Focus
2525+#include "Kaleidoscope-FirmwareVersion.h"
2626+2727+// Support for keys that move the mouse
2828+#include "Kaleidoscope-MouseKeys.h"
2929+3030+// Support for macros
3131+#include "Kaleidoscope-Macros.h"
3232+3333+// Support for controlling the keyboard's LEDs
3434+#include "Kaleidoscope-LEDControl.h"
3535+3636+// Support for "Numpad" mode, which is mostly just the Numpad specific LED mode
3737+//#include "Kaleidoscope-NumPad.h"
3838+3939+// Support for the "Boot greeting" effect, which pulses the 'LED' button for 10s
4040+// when the keyboard is connected to a computer (or that computer is powered on)
4141+#include "Kaleidoscope-LEDEffect-BootGreeting.h"
4242+4343+// Support for LED modes that set all LEDs to a single color
4444+//#include "Kaleidoscope-LEDEffect-SolidColor.h"
4545+4646+// Support for an LED mode that makes all the LEDs 'breathe'
4747+//#include "Kaleidoscope-LEDEffect-Breathe.h"
4848+4949+// Support for an LED mode that makes a red pixel chase a blue pixel across the keyboard
5050+//#include "Kaleidoscope-LEDEffect-Chase.h"
5151+5252+// Support for LED modes that pulse the keyboard's LED in a rainbow pattern
5353+//#include "Kaleidoscope-LEDEffect-Rainbow.h"
5454+5555+// Support for an LED mode that lights up the keys as you press them
5656+#include "Kaleidoscope-LED-Stalker.h"
5757+5858+// Support for an LED mode that prints the keys you press in letters 4px high
5959+#include "Kaleidoscope-LED-AlphaSquare.h"
6060+6161+// Support for shared palettes for other plugins, like Colormap below
6262+#include "Kaleidoscope-LED-Palette-Theme.h"
6363+6464+// Support for an LED mode that lets one configure per-layer color maps
6565+#include "Kaleidoscope-Colormap.h"
6666+6767+// Support for turning the LEDs off after a certain amount of time
6868+#include "Kaleidoscope-IdleLEDs.h"
6969+7070+// Support for setting and saving the default LED mode
7171+#include "Kaleidoscope-DefaultLEDModeConfig.h"
7272+7373+// Support for changing the brightness of the LEDs
7474+#include "Kaleidoscope-LEDBrightnessConfig.h"
7575+7676+// Support for Keyboardio's internal keyboard testing mode
7777+#include "Kaleidoscope-HardwareTestMode.h"
7878+7979+// Support for host power management (suspend & wakeup)
8080+#include "Kaleidoscope-HostPowerManagement.h"
8181+8282+// Support for magic combos (key chords that trigger an action)
8383+#include "Kaleidoscope-MagicCombo.h"
8484+8585+// Support for USB quirks, like changing the key state report protocol
8686+#include "Kaleidoscope-USB-Quirks.h"
8787+8888+// Support for secondary actions on keys
8989+#include "Kaleidoscope-Qukeys.h"
9090+9191+// Support for one-shot modifiers and layer keys
9292+#include "Kaleidoscope-OneShot.h"
9393+#include "Kaleidoscope-Escape-OneShot.h"
9494+9595+// Support for dynamic, Chrysalis-editable macros
9696+#include "Kaleidoscope-DynamicMacros.h"
9797+9898+// Support for SpaceCadet keys
9999+//#include "Kaleidoscope-SpaceCadet.h"
100100+101101+// Support for editable layer names
102102+#include "Kaleidoscope-LayerNames.h"
103103+104104+// Support for the GeminiPR Stenography protocol
105105+#include "Kaleidoscope-Steno.h"
106106+107107+/** This 'enum' is a list of all the macros used by the Model 100's firmware
108108+ * The names aren't particularly important. What is important is that each
109109+ * is unique.
110110+ *
111111+ * These are the names of your macros. They'll be used in two places.
112112+ * The first is in your keymap definitions. There, you'll use the syntax
113113+ * `M(MACRO_NAME)` to mark a specific keymap position as triggering `MACRO_NAME`
114114+ *
115115+ * The second usage is in the 'switch' statement in the `macroAction` function.
116116+ * That switch statement actually runs the code associated with a macro when
117117+ * a macro key is pressed.
118118+ */
119119+120120+enum {
121121+ MACRO_VERSION_INFO,
122122+ MACRO_ANY,
123123+ MACRO_TOGGLE_QUKEYS
124124+};
125125+126126+127127+/** The Model 100's key layouts are defined as 'keymaps'. By default, there are three
128128+ * keymaps: The standard QWERTY keymap, the "Function layer" keymap and the "Numpad"
129129+ * keymap.
130130+ *
131131+ * Each keymap is defined as a list using the 'KEYMAP_STACKED' macro, built
132132+ * of first the left hand's layout, followed by the right hand's layout.
133133+ *
134134+ * Keymaps typically consist mostly of `Key_` definitions. There are many, many keys
135135+ * defined as part of the USB HID Keyboard specification. You can find the names
136136+ * (if not yet the explanations) for all the standard `Key_` defintions offered by
137137+ * Kaleidoscope in these files:
138138+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/keyboard.h
139139+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/consumerctl.h
140140+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/sysctl.h
141141+ * https://github.com/keyboardio/Kaleidoscope/blob/master/src/kaleidoscope/key_defs/keymaps.h
142142+ *
143143+ * Additional things that should be documented here include
144144+ * using ___ to let keypresses fall through to the previously active layer
145145+ * using XXX to mark a keyswitch as 'blocked' on this layer
146146+ * using ShiftToLayer() and LockLayer() keys to change the active keymap.
147147+ * keeping NUM and FN consistent and accessible on all layers
148148+ *
149149+ * The PROG key is special, since it is how you indicate to the board that you
150150+ * want to flash the firmware. However, it can be remapped to a regular key.
151151+ * When the keyboard boots, it first looks to see whether the PROG key is held
152152+ * down; if it is, it simply awaits further flashing instructions. If it is
153153+ * not, it continues loading the rest of the firmware and the keyboard
154154+ * functions normally, with whatever binding you have set to PROG. More detail
155155+ * here: https://community.keyboard.io/t/how-the-prog-key-gets-you-into-the-bootloader/506/8
156156+ *
157157+ * The "keymaps" data structure is a list of the keymaps compiled into the firmware.
158158+ * The order of keymaps in the list is important, as the ShiftToLayer(#) and LockLayer(#)
159159+ * macros switch to key layers based on this list.
160160+ *
161161+ *
162162+163163+ * A key defined as 'ShiftToLayer(FUNCTION)' will switch to FUNCTION while held.
164164+ * Similarly, a key defined as 'LockLayer(NUMPAD)' will switch to NUMPAD when tapped.
165165+ */
166166+167167+/**
168168+ * Layers are "0-indexed" -- That is the first one is layer 0. The second one is layer 1.
169169+ * The third one is layer 2.
170170+ * This 'enum' lets us use names like QWERTY, FUNCTION, and NUMPAD in place of
171171+ * the numbers 0, 1 and 2.
172172+ *
173173+ */
174174+175175+enum {
176176+ PRIMARY,
177177+ NUMPAD,
178178+ FUNCTION,
179179+ MOUSE
180180+}; // layers
181181+182182+183183+/**
184184+ * To change your keyboard's layout from QWERTY to DVORAK or COLEMAK, comment out the line
185185+ *
186186+ * #define PRIMARY_KEYMAP_QWERTY
187187+ *
188188+ * by changing it to
189189+ *
190190+ * // #define PRIMARY_KEYMAP_QWERTY
191191+ *
192192+ * Then uncomment the line corresponding to the layout you want to use.
193193+ *
194194+ */
195195+196196+#define PRIMARY_KEYMAP_QWERTY
197197+// #define PRIMARY_KEYMAP_DVORAK
198198+// #define PRIMARY_KEYMAP_COLEMAK
199199+// #define PRIMARY_KEYMAP_CUSTOM
200200+201201+202202+/* This comment temporarily turns off astyle's indent enforcement
203203+ * so we can make the keymaps actually resemble the physical key layout better
204204+ */
205205+// clang-format off
206206+207207+KEYMAPS(
208208+209209+#if defined (PRIMARY_KEYMAP_QWERTY)
210210+ [PRIMARY] = KEYMAP_STACKED
211211+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
212212+ Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
213213+ Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
214214+ Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
215215+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
216216+ ShiftToLayer(FUNCTION),
217217+218218+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
219219+ Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
220220+ Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
221221+ Key_RightAlt, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
222222+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
223223+ ShiftToLayer(FUNCTION)),
224224+225225+#elif defined (PRIMARY_KEYMAP_DVORAK)
226226+227227+ [PRIMARY] = KEYMAP_STACKED
228228+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
229229+ Key_Backtick, Key_Quote, Key_Comma, Key_Period, Key_P, Key_Y, Key_Tab,
230230+ Key_PageUp, Key_A, Key_O, Key_E, Key_U, Key_I,
231231+ Key_PageDown, Key_Semicolon, Key_Q, Key_J, Key_K, Key_X, Key_Escape,
232232+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
233233+ ShiftToLayer(FUNCTION),
234234+235235+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
236236+ Key_Enter, Key_F, Key_G, Key_C, Key_R, Key_L, Key_Slash,
237237+ Key_D, Key_H, Key_T, Key_N, Key_S, Key_Minus,
238238+ Key_RightAlt, Key_B, Key_M, Key_W, Key_V, Key_Z, Key_Equals,
239239+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
240240+ ShiftToLayer(FUNCTION)),
241241+242242+#elif defined (PRIMARY_KEYMAP_COLEMAK)
243243+244244+ [PRIMARY] = KEYMAP_STACKED
245245+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
246246+ Key_Backtick, Key_Q, Key_W, Key_F, Key_P, Key_B, Key_Tab,
247247+ Key_PageUp, Key_A, Key_R, Key_S, Key_T, Key_G,
248248+ Key_PageDown, Key_Z, Key_X, Key_C, Key_D, Key_V, Key_Escape,
249249+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
250250+ ShiftToLayer(FUNCTION),
251251+252252+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
253253+ Key_Enter, Key_J, Key_L, Key_U, Key_Y, Key_Semicolon, Key_Equals,
254254+ Key_M, Key_N, Key_E, Key_I, Key_O, Key_Quote,
255255+ Key_RightAlt, Key_K, Key_H, Key_Comma, Key_Period, Key_Slash, Key_Minus,
256256+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
257257+ ShiftToLayer(FUNCTION)),
258258+259259+#elif defined (PRIMARY_KEYMAP_CUSTOM)
260260+ // Edit this keymap to make a custom layout
261261+ [PRIMARY] = KEYMAP_STACKED
262262+ (___, Key_1, Key_2, Key_3, Key_4, Key_5, Key_LEDEffectNext,
263263+ Key_Backtick, Key_Q, Key_W, Key_E, Key_R, Key_T, Key_Tab,
264264+ Key_PageUp, Key_A, Key_S, Key_D, Key_F, Key_G,
265265+ Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
266266+ Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
267267+ ShiftToLayer(FUNCTION),
268268+269269+ M(MACRO_ANY), Key_6, Key_7, Key_8, Key_9, Key_0, LockLayer(NUMPAD),
270270+ Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
271271+ Key_H, Key_J, Key_K, Key_L, Key_Semicolon, Key_Quote,
272272+ Key_RightAlt, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
273273+ Key_RightShift, Key_LeftAlt, Key_Spacebar, Key_RightControl,
274274+ ShiftToLayer(FUNCTION)),
275275+276276+#else
277277+278278+#error "No default keymap defined. You should make sure that you have a line like '#define PRIMARY_KEYMAP_QWERTY' in your sketch"
279279+280280+#endif
281281+282282+283283+284284+ [NUMPAD] = KEYMAP_STACKED
285285+ (___, ___, ___, ___, ___, ___, ___,
286286+ ___, ___, ___, ___, ___, ___, ___,
287287+ ___, ___, ___, ___, ___, ___,
288288+ ___, ___, ___, ___, ___, ___, ___,
289289+ ___, ___, ___, ___,
290290+ ___,
291291+292292+ M(MACRO_VERSION_INFO), ___, Key_7, Key_8, Key_9, Key_KeypadSubtract, ___,
293293+ ___, ___, Key_4, Key_5, Key_6, Key_KeypadAdd, ___,
294294+ ___, Key_1, Key_2, Key_3, Key_Equals, ___,
295295+ ___, ___, Key_0, Key_Period, Key_KeypadMultiply, Key_KeypadDivide, Key_Enter,
296296+ ___, ___, ___, ___,
297297+ ___),
298298+299299+ [FUNCTION] = KEYMAP_STACKED
300300+ (___, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, Key_CapsLock,
301301+ Key_Tab, ___, Key_mouseUp, ___, Key_mouseBtnR, Key_mouseWarpEnd, Key_mouseWarpNE,
302302+ Key_Home, Key_mouseL, Key_mouseDn, Key_mouseR, Key_mouseBtnL, Key_mouseWarpNW,
303303+ Key_End, Key_PrintScreen, Key_Insert, ___, Key_mouseBtnM, Key_mouseWarpSW, Key_mouseWarpSE,
304304+ ___, Key_Delete, ___, ___,
305305+ ___,
306306+307307+ Consumer_ScanPreviousTrack, Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11,
308308+ Consumer_PlaySlashPause, Consumer_ScanNextTrack, Key_LeftCurlyBracket, Key_RightCurlyBracket, Key_LeftBracket, Key_RightBracket, Key_F12,
309309+ Key_LeftArrow, Key_DownArrow, Key_UpArrow, Key_RightArrow, ___, ___,
310310+ Key_PcApplication, Consumer_Mute, Consumer_VolumeDecrement, Consumer_VolumeIncrement, ___, Key_Backslash, Key_Pipe,
311311+ ___, ___, Key_Enter, ___,
312312+ ___)
313313+) // KEYMAPS(
314314+315315+/* Re-enable astyle's indent enforcement */
316316+// clang-format on
317317+318318+/** versionInfoMacro handles the 'firmware version info' macro
319319+ * When a key bound to the macro is pressed, this macro
320320+ * prints out the firmware build information as virtual keystrokes
321321+ */
322322+323323+static void versionInfoMacro(uint8_t key_state) {
324324+ if (keyToggledOn(key_state)) {
325325+ Macros.type(PSTR("Keyboardio Model 100 - Firmware version "));
326326+ Macros.type(PSTR(KALEIDOSCOPE_FIRMWARE_VERSION));
327327+ }
328328+}
329329+330330+/** anyKeyMacro is used to provide the functionality of the 'Any' key.
331331+ *
332332+ * When the 'any key' macro is toggled on, a random alphanumeric key is
333333+ * selected. While the key is held, the function generates a synthetic
334334+ * keypress event repeating that randomly selected key.
335335+ *
336336+ */
337337+338338+static void anyKeyMacro(KeyEvent &event) {
339339+ if (keyToggledOn(event.state)) {
340340+ event.key.setKeyCode(Key_A.getKeyCode() + (uint8_t)(millis() % 36));
341341+ event.key.setFlags(0);
342342+ }
343343+}
344344+345345+346346+/** macroAction dispatches keymap events that are tied to a macro
347347+ to that macro. It takes two uint8_t parameters.
348348+349349+ The first is the macro being called (the entry in the 'enum' earlier in this file).
350350+ The second is the state of the keyswitch. You can use the keyswitch state to figure out
351351+ if the key has just been toggled on, is currently pressed or if it's just been released.
352352+353353+ The 'switch' statement should have a 'case' for each entry of the macro enum.
354354+ Each 'case' statement should call out to a function to handle the macro in question.
355355+356356+ */
357357+358358+const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
359359+ switch (macro_id) {
360360+361361+ case MACRO_VERSION_INFO:
362362+ versionInfoMacro(event.state);
363363+ break;
364364+365365+ case MACRO_ANY:
366366+ anyKeyMacro(event);
367367+ break;
368368+369369+ case MACRO_TOGGLE_QUKEYS:
370370+ if (keyToggledOn(event.state)) {
371371+ Qukeys.toggle();
372372+ }
373373+ break;
374374+ }
375375+ return MACRO_NONE;
376376+}
377377+378378+379379+// These 'solid' color effect definitions define a rainbow of
380380+// LED color modes calibrated to draw 500mA or less on the
381381+// Keyboardio Model 100.
382382+383383+384384+//static kaleidoscope::plugin::LEDSolidColor solidRed(160, 0, 0);
385385+//static kaleidoscope::plugin::LEDSolidColor solidOrange(140, 70, 0);
386386+//static kaleidoscope::plugin::LEDSolidColor solidYellow(130, 100, 0);
387387+//static kaleidoscope::plugin::LEDSolidColor solidGreen(0, 160, 0);
388388+//static kaleidoscope::plugin::LEDSolidColor solidBlue(0, 70, 130);
389389+//static kaleidoscope::plugin::LEDSolidColor solidIndigo(0, 0, 170);
390390+//static kaleidoscope::plugin::LEDSolidColor solidViolet(130, 0, 120);
391391+392392+/** toggleLedsOnSuspendResume toggles the LEDs off when the host goes to sleep,
393393+ * and turns them back on when it wakes up.
394394+ */
395395+void toggleLedsOnSuspendResume(kaleidoscope::plugin::HostPowerManagement::Event event) {
396396+ switch (event) {
397397+ case kaleidoscope::plugin::HostPowerManagement::Suspend:
398398+ case kaleidoscope::plugin::HostPowerManagement::Sleep:
399399+ LEDControl.disable();
400400+ break;
401401+ case kaleidoscope::plugin::HostPowerManagement::Resume:
402402+ LEDControl.enable();
403403+ break;
404404+ }
405405+}
406406+407407+/** hostPowerManagementEventHandler dispatches power management events (suspend,
408408+ * resume, and sleep) to other functions that perform action based on these
409409+ * events.
410410+ */
411411+void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement::Event event) {
412412+ toggleLedsOnSuspendResume(event);
413413+}
414414+415415+/** This 'enum' is a list of all the magic combos used by the Model 100's
416416+ * firmware The names aren't particularly important. What is important is that
417417+ * each is unique.
418418+ *
419419+ * These are the names of your magic combos. They will be used by the
420420+ * `USE_MAGIC_COMBOS` call below.
421421+ */
422422+enum {
423423+ // Toggle between Boot (6-key rollover; for BIOSes and early boot) and NKRO
424424+ // mode.
425425+ COMBO_TOGGLE_NKRO_MODE,
426426+ // Enter test mode
427427+ COMBO_ENTER_TEST_MODE
428428+};
429429+430430+/** Wrappers, to be used by MagicCombo. **/
431431+432432+/**
433433+ * This simply toggles the keyboard protocol via USBQuirks, and wraps it within
434434+ * a function with an unused argument, to match what MagicCombo expects.
435435+ */
436436+static void toggleKeyboardProtocol(uint8_t combo_index) {
437437+ USBQuirks.toggleKeyboardProtocol();
438438+}
439439+440440+/**
441441+ * Toggles between using the built-in keymap, and the EEPROM-stored one.
442442+ */
443443+static void toggleKeymapSource(uint8_t combo_index) {
444444+ if (Layer.getKey == Layer.getKeyFromPROGMEM) {
445445+ Layer.getKey = EEPROMKeymap.getKey;
446446+ } else {
447447+ Layer.getKey = Layer.getKeyFromPROGMEM;
448448+ }
449449+}
450450+451451+/**
452452+ * This enters the hardware test mode
453453+ */
454454+static void enterHardwareTestMode(uint8_t combo_index) {
455455+ HardwareTestMode.runTests();
456456+}
457457+458458+459459+/** Magic combo list, a list of key combo and action pairs the firmware should
460460+ * recognise.
461461+ */
462462+USE_MAGIC_COMBOS({.action = toggleKeyboardProtocol,
463463+ // Left Fn + Esc + Shift
464464+ .keys = {R3C6, R2C6, R3C7}},
465465+ {.action = enterHardwareTestMode,
466466+ // Left Fn + Prog + LED
467467+ .keys = {R3C6, R0C0, R0C6}},
468468+ {.action = toggleKeymapSource,
469469+ // Left Fn + Prog + Shift
470470+ .keys = {R3C6, R0C0, R3C7}});
471471+472472+// First, tell Kaleidoscope which plugins you want to use.
473473+// The order can be important. For example, LED effects are
474474+// added in the order they're listed here.
475475+KALEIDOSCOPE_INIT_PLUGINS(
476476+ // The EEPROMSettings & EEPROMKeymap plugins make it possible to have an
477477+ // editable keymap in EEPROM.
478478+ EEPROMSettings,
479479+ EEPROMKeymap,
480480+481481+ // SpaceCadet can turn your shifts into parens on tap, while keeping them as
482482+ // Shifts when held. SpaceCadetConfig lets Chrysalis configure some aspects of
483483+ // the plugin.
484484+ //SpaceCadet,
485485+ //SpaceCadetConfig,
486486+487487+ // Focus allows bi-directional communication with the host, and is the
488488+ // interface through which the keymap in EEPROM can be edited.
489489+ Focus,
490490+491491+ // FocusSettingsCommand adds a few Focus commands, intended to aid in
492492+ // changing some settings of the keyboard, such as the default layer (via the
493493+ // `settings.defaultLayer` command)
494494+ FocusSettingsCommand,
495495+496496+ // FocusEEPROMCommand adds a set of Focus commands, which are very helpful in
497497+ // both debugging, and in backing up one's EEPROM contents.
498498+ FocusEEPROMCommand,
499499+500500+ // The boot greeting effect pulses the LED button for 10 seconds after the
501501+ // keyboard is first connected
502502+ BootGreetingEffect,
503503+504504+ // The hardware test mode, which can be invoked by tapping Prog, LED and the
505505+ // left Fn button at the same time.
506506+ HardwareTestMode,
507507+508508+ // The Qukeys plugin enables the "Secondary action" functionality in
509509+ // Chrysalis. Keys with secondary actions will have their primary action
510510+ // performed when tapped, but the secondary action when held.
511511+ Qukeys,
512512+513513+ // LEDControl provides support for other LED modes
514514+ LEDControl,
515515+516516+ // We start with the LED effect that turns off all the LEDs.
517517+ LEDOff,
518518+519519+ // The rainbow effect changes the color of all of the keyboard's keys at the same time
520520+ // running through all the colors of the rainbow.
521521+ //LEDRainbowEffect,
522522+523523+ // The rainbow wave effect lights up your keyboard with all the colors of a rainbow
524524+ // and slowly moves the rainbow across your keyboard
525525+ //LEDRainbowWaveEffect,
526526+527527+ // The chase effect follows the adventure of a blue pixel which chases a red pixel across
528528+ // your keyboard. Spoiler: the blue pixel never catches the red pixel
529529+ //LEDChaseEffect,
530530+531531+ // These static effects turn your keyboard's LEDs a variety of colors
532532+ //solidRed,
533533+ //solidOrange,
534534+ //solidYellow,
535535+ //solidGreen,
536536+ //solidBlue,
537537+ //solidIndigo,
538538+ //solidViolet,
539539+540540+ // The breathe effect slowly pulses all of the LEDs on your keyboard
541541+ //LEDBreatheEffect,
542542+543543+ // The AlphaSquare effect prints each character you type, using your
544544+ // keyboard's LEDs as a display
545545+ AlphaSquareEffect,
546546+547547+ // The stalker effect lights up the keys you've pressed recently
548548+ StalkerEffect,
549549+550550+ // The LED Palette Theme plugin provides a shared palette for other plugins,
551551+ // like Colormap below
552552+ LEDPaletteTheme,
553553+554554+ // The Colormap effect makes it possible to set up per-layer colormaps
555555+ ColormapEffect,
556556+557557+ // The numpad plugin is responsible for lighting up the 'numpad' mode
558558+ // with a custom LED effect
559559+ //NumPad,
560560+561561+ // The macros plugin adds support for macros
562562+ Macros,
563563+564564+ // The MouseKeys plugin lets you add keys to your keymap which move the mouse.
565565+ // The MouseKeysConfig plugin lets Chrysalis configure some aspects of the
566566+ // plugin.
567567+ MouseKeys,
568568+ MouseKeysConfig,
569569+570570+ // The HostPowerManagement plugin allows us to turn LEDs off when then host
571571+ // goes to sleep, and resume them when it wakes up.
572572+ HostPowerManagement,
573573+574574+ // The MagicCombo plugin lets you use key combinations to trigger custom
575575+ // actions - a bit like Macros, but triggered by pressing multiple keys at the
576576+ // same time.
577577+ MagicCombo,
578578+579579+ // The USBQuirks plugin lets you do some things with USB that we aren't
580580+ // comfortable - or able - to do automatically, but can be useful
581581+ // nevertheless. Such as toggling the key report protocol between Boot (used
582582+ // by BIOSes) and Report (NKRO).
583583+ USBQuirks,
584584+585585+ // Enables the "Sticky" behavior for modifiers, and the "Layer shift when
586586+ // held" functionality for layer keys.
587587+ OneShot,
588588+ OneShotConfig,
589589+ EscapeOneShot,
590590+ EscapeOneShotConfig,
591591+592592+ // Turns LEDs off after a configurable amount of idle time.
593593+ IdleLEDs,
594594+ PersistentIdleLEDs,
595595+596596+ // Enables dynamic, Chrysalis-editable macros.
597597+ DynamicMacros,
598598+599599+ // The FirmwareVersion plugin lets Chrysalis query the version of the firmware
600600+ // programmatically.
601601+ FirmwareVersion,
602602+603603+ // The LayerNames plugin allows Chrysalis to display - and edit - custom layer
604604+ // names, to be shown instead of the default indexes.
605605+ LayerNames,
606606+607607+ // Enables setting, saving (via Chrysalis), and restoring (on boot) the
608608+ // default LED mode.
609609+ DefaultLEDModeConfig,
610610+611611+ // Enables controlling (and saving) the brightness of the LEDs via Focus.
612612+ LEDBrightnessConfig,
613613+614614+ // Enables the GeminiPR Stenography protocol. Unused by default, but with the
615615+ // plugin enabled, it becomes configurable - and then usable - via Chrysalis.
616616+ GeminiPR);
617617+618618+/** The 'setup' function is one of the two standard Arduino sketch functions.
619619+ * It's called when your keyboard first powers up. This is where you set up
620620+ * Kaleidoscope and any plugins.
621621+ */
622622+void setup() {
623623+ QUKEYS(
624624+ kaleidoscope::plugin::Qukey(kaleidoscope::plugin::Qukeys::layer_wildcard, KeyAddr(3, 7), LSHIFT(Key_9)),
625625+ kaleidoscope::plugin::Qukey(kaleidoscope::plugin::Qukeys::layer_wildcard, KeyAddr(3, 8), LSHIFT(Key_0))
626626+ )
627627+628628+ // First, call Kaleidoscope's internal setup function
629629+ Kaleidoscope.setup();
630630+631631+ // Set the hue of the boot greeting effect to something that will result in a
632632+ // nice green color.
633633+ BootGreetingEffect.hue = 85;
634634+635635+ // While we hope to improve this in the future, the NumPad plugin
636636+ // needs to be explicitly told which keymap layer is your numpad layer
637637+ //NumPad.numPadLayer = NUMPAD;
638638+639639+ // We configure the AlphaSquare effect to use RED letters
640640+ AlphaSquare.color = CRGB(255, 0, 0);
641641+642642+ // Set the rainbow effects to be reasonably bright, but low enough
643643+ // to mitigate audible noise in some environments.
644644+ //LEDRainbowEffect.brightness(170);
645645+ //LEDRainbowWaveEffect.brightness(160);
646646+647647+ // Set the action key the test mode should listen for to Left Fn
648648+ HardwareTestMode.setActionKey(R3C6);
649649+650650+ // The LED Stalker mode has a few effects. The one we like is called
651651+ // 'BlazingTrail'. For details on other options, see
652652+ // https://github.com/keyboardio/Kaleidoscope/blob/master/docs/plugins/LED-Stalker.md
653653+ StalkerEffect.variant = STALKER(BlazingTrail);
654654+655655+ // To make the keymap editable without flashing new firmware, we store
656656+ // additional layers in EEPROM. For now, we reserve space for eight layers. If
657657+ // one wants to use these layers, just set the default layer to one in EEPROM,
658658+ // by using the `settings.defaultLayer` Focus command, or by using the
659659+ // `keymap.onlyCustom` command to use EEPROM layers only.
660660+ EEPROMKeymap.setup(8);
661661+662662+ // We need to tell the Colormap plugin how many layers we want to have custom
663663+ // maps for. To make things simple, we set it to eight layers, which is how
664664+ // many editable layers we have (see above).
665665+ ColormapEffect.max_layers(8);
666666+667667+ // For Dynamic Macros, we need to reserve storage space for the editable
668668+ // macros. A kilobyte is a reasonable default.
669669+ DynamicMacros.reserve_storage(1024);
670670+671671+ // If there's a default layer set in EEPROM, we should set that as the default
672672+ // here.
673673+ Layer.move(EEPROMSettings.default_layer());
674674+675675+ // To avoid any surprises, SpaceCadet is turned off by default. However, it
676676+ // can be permanently enabled via Chrysalis, so we should only disable it if
677677+ // no configuration exists.
678678+ //SpaceCadetConfig.disableSpaceCadetIfUnconfigured();
679679+680680+ // Editable layer names are stored in EEPROM too, and we reserve 16 bytes per
681681+ // layer for them. We need one extra byte per layer for bookkeeping, so we
682682+ // reserve 17 / layer in total.
683683+ LayerNames.reserve_storage(17 * 8);
684684+685685+ // Unless configured otherwise with Chrysalis, we want to make sure that the
686686+ // firmware starts with LED effects off. This avoids over-taxing devices that
687687+ // don't have a lot of power to share with USB devices
688688+ DefaultLEDModeConfig.activateLEDModeIfUnconfigured(&LEDOff);
689689+690690+ // Qukeys config
691691+ Qukeys.setOverlapThreshold(90);
692692+ Qukeys.setMinimumHoldTime(100);
693693+}
694694+695695+/** loop is the second of the standard Arduino sketch functions.
696696+ * As you might expect, it runs in a loop, never exiting.
697697+ *
698698+ * For Kaleidoscope-based keyboard firmware, you usually just want to
699699+ * call Kaleidoscope.loop(); and not do anything custom here.
700700+ */
701701+702702+void loop() {
703703+ Kaleidoscope.loop();
704704+}