summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Cully <bjc@kublai.com>2022-09-24 14:35:14 -0400
committerBrian Cully <bjc@kublai.com>2022-09-24 14:35:14 -0400
commit6054e32b278d35cf89df990d9a23290d49e379f7 (patch)
tree96f73c87427d2c0ad52ac5b3c1e251dbcdcfce51
downloadModel100-6054e32b278d35cf89df990d9a23290d49e379f7.tar.gz
Model100-6054e32b278d35cf89df990d9a23290d49e379f7.zip
initial firmware for model 100, based on my model 01 sketch.
-rw-r--r--.gitignore2
-rw-r--r--Makefile64
-rw-r--r--Model100.ino424
-rwxr-xr-xflash8
-rw-r--r--gdbinit.container11
-rw-r--r--sketch.json6
6 files changed, 515 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..43f0aa8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.bin
+*.elf
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..9d997a4
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,64 @@
+# This makefile for a Kaleidoscope sketch pulls in all the targets
+# required to build the example
+
+#" /home/bjc/src/Kaleidoscope/.arduino/data/packages/keyboardio/tools/dfu-util/0.10.0-arduino1/dfu-util" --device 0x3496:0x0005 -D /tmp/kaleidoscope-bjc/output/3606415822-Model100.ino/Model100.ino.bin -R
+
+# arduino-cli compile --fqbn keyboardio:gd32:keyboardio_model_100 --show-properties Model100.ino
+
+_ARDUINO_CLI_COMPILE_CUSTOM_FLAGS=--build-property "runtime.tools.xpack-arm-none-eabi-gcc-9.3.1-1.3.path=/usr" --build-property "runtime.tools.dfu-util.path=/usr/sbin"
+ARDUINO_DIRECTORIES_USER=$(HOME)/Arduino/
+# ARDUINO_DIRECTORIES_DATA=
+KALEIDOSCOPE_DIR=$(HOME)/Arduino/libraries/Kaleidoscope
+#KALEIDOSCOPE_DIR=/tmp/Kaleidoscope
+
+
+ifneq ($(KALEIDOSCOPE_DIR),)
+search_path += $(KALEIDOSCOPE_DIR)
+endif
+
+ifneq ($(ARDUINO_DIRECTORIES_USER),)
+search_path += $(ARDUINO_DIRECTORIES_USER)/hardware/keyboardio/avr/libraries/Kaleidoscope
+endif
+
+ifeq ($(shell uname -s),Darwin)
+search_path += $(HOME)/Documents/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
+else
+search_path += $(HOME)/Arduino/hardware/keyboardio/avr/libraries/Kaleidoscope
+endif
+
+sketch_makefile := etc/makefiles/sketch.mk
+
+$(foreach candidate, $(search_path), $(if $(wildcard $(candidate)/$(sketch_makefile)), $(eval ks_dir ?= $(candidate))))
+
+ifneq ($(ks_dir),)
+
+$(info Using Kaleidoscope from $(ks_dir))
+
+export KALEIDOSCOPE_DIR := $(ks_dir)
+include $(ks_dir)/$(sketch_makefile)
+
+else
+
+$(info I can't find your Kaleidoscope installation.)
+$(info )
+$(info I tried looking in:)
+$(info )
+$(foreach candidate, $(search_path), $(info $(candidate)))
+$(info )
+$(info The easiest way to fix this is to set the 'KALEIDOSCOPE_DIR' environment)
+$(info variable to the location of your Kaleidoscope directory.)
+
+endif
+
+gdb: ${ELF_FILE_PATH}
+ arm-none-eabi-gdb -x gdbinit.container ${ELF_FILE_PATH}
+
+cp-elf: ${ELF_FILE_PATH}
+ cp ${ELF_FILE_PATH} .
+
+cp-bin: ${BIN_FILE_PATH}
+ cp ${BIN_FILE_PATH} .
+
+null-target:
+ $(info You should never see this message)
+ @:
diff --git a/Model100.ino b/Model100.ino
new file mode 100644
index 0000000..0813fcb
--- /dev/null
+++ b/Model100.ino
@@ -0,0 +1,424 @@
+// -*- mode: c++ -*-
+
+#ifndef BUILD_INFORMATION
+#define BUILD_INFORMATION "locally built"
+#endif
+
+#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>
+
+// 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;
+
+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";
+
+static constexpr emote emotes[] = {
+ { WOW, wow },
+ { SAUCY, saucy },
+ { LUL, lul },
+ { ZZZ, zzz },
+ { GIVE_PLZ, givePLZ },
+ { TAKE_NRG, takeNRG },
+ { SEEMS_GOOD, seemsGood },
+ { GASM, gasm }
+};
+
+// 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),
+
+// 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*
+
+/*
+ * 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
+ *
+ */
+
+KEYMAPS([ENGRAM] = KEYMAP_STACKED
+ (Key_Escape, Key_1, Key_2, Key_3, Key_4, Key_5, XXX,
+ Key_Backtick, Key_B, Key_Y, Key_O, Key_U, TD(0), Key_Tab,
+ Key_Slash, Key_C, Key_I, Key_E, Key_A, TD(1),
+ Key_RightGui, Key_G, Key_X, Key_J, Key_K, TD(2), Key_LeftGui,
+ Key_LeftControl, Key_Backspace, Key_LeftAlt, Key_LeftShift,
+ ShiftToLayer(FUNCTION),
+
+ XXX, Key_6, Key_7, Key_8, Key_9, Key_0, LEAD(0),
+ Key_Enter, TD(3), Key_L, Key_D, Key_W, Key_V, Key_Z,
+ TD(4), Key_H, Key_T, Key_S, Key_N, Key_Q,
+ Key_PcApplication, TD(5), Key_R, Key_M, Key_F, Key_P, Key_Equals,
+ Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
+ ShiftToLayer(FUNCTION)),
+
+ [FUNCTION] = KEYMAP_STACKED
+ (Key_LEDEffectNext, Key_F1, Key_F2, Key_F3, Key_F4, Key_F5, XXX,
+ ___, ___, ___, ___, ___, ___, Key_CapsLock,
+ Key_Copy, ___, LSHIFT(Key_LeftBracket), LSHIFT(Key_9), Key_LeftBracket, ___,
+ Key_Paste, Key_PrintScreen, Key_Insert, Consumer_ScanPreviousTrack, Consumer_ScanNextTrack, Consumer_PlaySlashPause, ___,
+ ___, Key_Delete, ___, ___,
+ ___,
+
+ XXX, Key_F6, Key_F7, Key_F8, Key_F9, Key_F10, Key_F11,
+ ___, 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,
+ ___, ___, ___, ___,
+ ___),
+
+ [NUMPAD] = KEYMAP_STACKED
+ (___, ___, ___, ___, ___, ___, ___,
+ ___, ___, ___, ___, ___, ___, ___,
+ ___, ___, ___, ___, ___, ___,
+ ___, ___, ___, ___, ___, ___, ___,
+ ___, ___, ___, ___,
+ ___,
+
+ ___, ___, Key_7, Key_8, Key_9, Key_KeypadSubtract, UnlockLayer(NUMPAD),
+ ___, ___, 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,
+ ___, ___, ___, ___,
+ ___),
+
+ [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*
+
+/** 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);
+ }
+}
+
+/** anyKeyMacro is used to provide the functionality of the 'Any' key.
+ *
+ * When the 'any key' macro is toggled on, a random alphanumeric key is
+ * selected. While the key is held, the function generates a synthetic
+ * 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));
+ event.key.setFlags(0);
+ }
+}
+
+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.
+
+ The first is the macro being called (the entry in the 'enum' earlier in this file).
+ The second is the state of the keyswitch. You can use the keyswitch state to figure out
+ if the key has just been toggled on, is currently pressed or if it's just been released.
+
+ 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 macroID, KeyEvent &event) {
+ switch (macroID) {
+ case MACRO_VERSION_INFO:
+ versionInfoMacro(event.state);
+ break;
+
+ case MACRO_ANY:
+ anyKeyMacro(event);
+ break;
+
+ default:
+ emoteMacro(macroID, event);
+ }
+ return MACRO_NONE;
+}
+
+/** 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:
+ LEDControl.disable();
+ break;
+ case kaleidoscope::plugin::HostPowerManagement::Resume:
+ LEDControl.enable();
+ break;
+ case kaleidoscope::plugin::HostPowerManagement::Sleep:
+ break;
+ }
+}
+
+/** hostPowerManagementEventHandler dispatches power management events (suspend,
+ * resume, and sleep) to other functions that perform action based on these
+ * events.
+ */
+void hostPowerManagementEventHandler(kaleidoscope::plugin::HostPowerManagement::Event event) {
+ toggleLedsOnSuspendResume(event);
+}
+
+/** This 'enum' is a list of all the magic combos used by the Model 01's
+ * firmware The names aren't particularly important. What is important is that
+ * each is unique.
+ *
+ * These are the names of your magic combos. They will be used by the
+ * `USE_MAGIC_COMBOS` call below.
+ */
+enum {
+ // Toggle between Boot (6-key rollover; for BIOSes and early boot) and NKRO
+ // mode.
+ COMBO_TOGGLE_NKRO_MODE,
+ // Enter test mode
+ COMBO_ENTER_TEST_MODE
+};
+
+/** Wrappers, to be used by MagicCombo. **/
+
+/**
+ * This simply toggles the keyboard protocol via USBQuirks, and wraps it within
+ * a function with an unused argument, to match what MagicCombo expects.
+ */
+static void toggleKeyboardProtocol(uint8_t combo_index) {
+ USBQuirks.toggleKeyboardProtocol();
+}
+
+/**
+ * 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);
+ Layer.activate(MACROS);
+}
+
+void leaderNumpad(uint8_t i) {
+ Layer.activate(NUMPAD);
+}
+
+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;
+}
+
+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);
+
+// 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,
+
+ // The numpad plugin is responsible for
+ // lighting up the 'numpad' mode with a
+ // custom LED effect
+ NumPad,
+ macroHighlighter,
+
+ // The macros plugin adds support for macros
+ Macros,
+
+ // The HostPowerManagement plugin allows us
+ // to turn LEDs off when then host goes to
+ // sleep, and resume them when it wakes up.
+ //HostPowerManagement,
+
+ // 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,
+
+ // 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);
+
+void setup() {
+ Serial.begin(115200);
+
+ // Necessary for FreeBSD, as it doesn't support NKRO.
+ //BootKeyboard.default_protocol = HID_BOOT_PROTOCOL;
+
+ // First, call Kaleidoscope's internal setup function
+ Kaleidoscope.setup();
+
+ LayerNames.reserve_storage(128);
+ EEPROMKeymap.setup(5);
+
+ // 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;
+
+ 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)),
+ kaleidoscope::plugin::CharShift::KeyPair(LSHIFT(Key_Quote), LSHIFT(Key_0)),
+ kaleidoscope::plugin::CharShift::KeyPair(Key_Period, LSHIFT(Key_Semicolon)),
+ kaleidoscope::plugin::CharShift::KeyPair(LSHIFT(Key_Slash), LSHIFT(Key_1)));
+
+ Qukeys.setOverlapThreshold(25);
+}
+
+void loop() {
+ Kaleidoscope.loop();
+}
diff --git a/flash b/flash
new file mode 100755
index 0000000..770e600
--- /dev/null
+++ b/flash
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 firmware.bin" >&2
+ exit 1
+fi
+
+dfu-util --device 0x3496:0x0005 -R -D $1
diff --git a/gdbinit.container b/gdbinit.container
new file mode 100644
index 0000000..695822f
--- /dev/null
+++ b/gdbinit.container
@@ -0,0 +1,11 @@
+define hook-quit
+ set confirm off
+end
+
+# print demangled symbols by default
+set print asm-demangle on
+
+# OpenOCD
+set remote hardware-breakpoint-limit 4
+set remote hardware-watchpoint-limit 2
+target extended-remote psyduck:3333
diff --git a/sketch.json b/sketch.json
new file mode 100644
index 0000000..e00344e
--- /dev/null
+++ b/sketch.json
@@ -0,0 +1,6 @@
+{
+ "cpu": {
+ "fqbn": "keyboardio:gd32:keyboardio_model_100",
+ "port": ""
+ }
+}