summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.gitmodules4
-rw-r--r--builddefs/bootloader.mk6
-rw-r--r--builddefs/common_features.mk3
-rw-r--r--builddefs/mcu_selection.mk36
-rw-r--r--data/schemas/keyboard.jsonschema5
-rw-r--r--keyboards/voyager/.DS_Storebin0 -> 8196 bytes
-rw-r--r--keyboards/voyager/chconf.h14
-rw-r--r--keyboards/voyager/config.h140
-rw-r--r--keyboards/voyager/gd32/config.h4
-rw-r--r--keyboards/voyager/gd32/info.json227
-rw-r--r--keyboards/voyager/gd32/rules.mk32
-rw-r--r--keyboards/voyager/halconf.h22
-rw-r--r--keyboards/voyager/info.json227
-rw-r--r--keyboards/voyager/keymaps/.DS_Storebin0 -> 8196 bytes
-rw-r--r--keyboards/voyager/keymaps/default/config.h15
-rw-r--r--keyboards/voyager/keymaps/default/keymap.c196
-rw-r--r--keyboards/voyager/keymaps/default/rules.mk12
-rw-r--r--keyboards/voyager/ld/IGNITION.ld85
-rw-r--r--keyboards/voyager/matrix.c241
-rw-r--r--keyboards/voyager/mcuconf.h39
-rw-r--r--keyboards/voyager/readme.md58
-rw-r--r--keyboards/voyager/rgb_matrix_kb.inc32
-rw-r--r--keyboards/voyager/rules.mk33
-rw-r--r--keyboards/voyager/voyager.c386
-rw-r--r--keyboards/voyager/voyager.h74
m---------lib/chibios-contrib0
-rw-r--r--lib/python/qmk/constants.py2
-rw-r--r--platforms/chibios/boards/GD32F303C_EVAL/board/board.c58
-rw-r--r--platforms/chibios/boards/GD32F303C_EVAL/board/board.mk11
-rw-r--r--platforms/chibios/boards/GD32F303C_EVAL/configs/board.h169
-rw-r--r--platforms/chibios/boards/GD32F303C_EVAL/configs/config.h9
-rw-r--r--platforms/chibios/boards/GD32F303C_EVAL/configs/mcuconf.h211
-rw-r--r--platforms/chibios/bootloaders/ignition.c54
-rw-r--r--quantum/action_layer.c8
-rw-r--r--quantum/oryx.c70
-rw-r--r--quantum/oryx.h5
37 files changed, 2477 insertions, 14 deletions
diff --git a/.gitignore b/.gitignore
index 7ccdefa656..b9bf041143 100644
--- a/.gitignore
+++ b/.gitignore
@@ -93,9 +93,6 @@ user_song_list.h
/users/
/layouts/
/keyboards/*
-!/keyboards/ergodox_ez/
-!/keyboards/planck/
-!/keyboards/moonlander/
# clangd
compile_commands.json
diff --git a/.gitmodules b/.gitmodules
index 48c7035afa..0950f9e5e7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,8 +4,8 @@
branch = master
[submodule "lib/chibios-contrib"]
path = lib/chibios-contrib
- url = https://github.com/qmk/ChibiOS-Contrib
- branch = master
+ url = https://github.com/zsa/ChibiOS-Contrib
+ branch = main
[submodule "lib/googletest"]
path = lib/googletest
url = https://github.com/qmk/googletest
diff --git a/builddefs/bootloader.mk b/builddefs/bootloader.mk
index 9f55536423..c6574dadbe 100644
--- a/builddefs/bootloader.mk
+++ b/builddefs/bootloader.mk
@@ -217,6 +217,12 @@ ifeq ($(strip $(BOOTLOADER)), wb32-dfu)
OPT_DEFS += -DBOOTLOADER_WB32_DFU
BOOTLOADER_TYPE = wb32_dfu
endif
+ifeq ($(strip $(BOOTLOADER)), ignition)
+ OPT_DEFS += -DBOOTLOADER_IGNITION
+ BOOTLOADER_TYPE = ignition
+ MCU_LDSCRIPT = IGNITION
+endif
+
ifeq ($(strip $(BOOTLOADER_TYPE)),)
$(call CATASTROPHIC_ERROR,Invalid BOOTLOADER,No bootloader specified. Please set an appropriate 'BOOTLOADER' in your keyboard's 'rules.mk' file.)
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 5ec047a6e8..19779405df 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -212,7 +212,7 @@ else
ifeq ($(PLATFORM),AVR)
# Automatically provided by avr-libc, nothing required
else ifeq ($(PLATFORM),CHIBIOS)
- ifneq ($(filter STM32F3xx_% STM32F1xx_% %_STM32F401xC %_STM32F401xE %_STM32F405xG %_STM32F411xE %_STM32F072xB %_STM32F042x6 %_GD32VF103xB %_GD32VF103x8, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
+ ifneq ($(filter STM32F3xx_% STM32F1xx_% %_STM32F401xC %_STM32F401xE %_STM32F405xG %_STM32F411xE %_STM32F072xB %_STM32F042x6 %_GD32VF103xB %_GD32VF103x8 %_GD32F303x6, $(MCU_SERIES)_$(MCU_LDSCRIPT)),)
# Emulated EEPROM
OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_FLASH_EMULATED
COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/flash
@@ -296,6 +296,7 @@ ifneq ($(strip $(FLASH_DRIVER)), none)
endif
endif
+
RGBLIGHT_ENABLE ?= no
VALID_RGBLIGHT_TYPES := WS2812 APA102 custom
diff --git a/builddefs/mcu_selection.mk b/builddefs/mcu_selection.mk
index 0ea9630d59..1c45d375de 100644
--- a/builddefs/mcu_selection.mk
+++ b/builddefs/mcu_selection.mk
@@ -815,6 +815,40 @@ ifneq ($(findstring GD32VF103, $(MCU)),)
USE_FPU ?= no
endif
+ifneq ($(findstring GD32F303, $(MCU)),)
+ # Cortex version
+ MCU = cortex-m4
+
+ # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
+ ARMV = 7
+
+ ## chip/board settings
+ # - the next two should match the directories in
+ # <chibios[-contrib]>/os/hal/ports/$(MCU_PORT_NAME)/$(MCU_SERIES)
+ # OR
+ # <chibios[-contrib]>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
+ MCU_PORT_NAME = GD
+ MCU_FAMILY = GD32F
+ MCU_SERIES = GD32F303
+
+ # Linker script to use
+ # - it should exist either in <chibios>/os/common/startup/ARMCMx/compilers/GCC/ld/
+ # or <keyboard_dir>/ld/
+ MCU_LDSCRIPT ?= GD32F303x6
+
+ # Startup code to use
+ # - it should exist in <chibios>/os/common/startup/ARMCMx/compilers/GCC/mk/
+ MCU_STARTUP ?= gd32f30x
+
+ # Board: it should exist either in <chibios>/os/hal/boards/,
+ # <keyboard_dir>/boards/, or drivers/boards/
+ BOARD ?= GD32F303C_EVAL
+
+ STM32_BOOTLOADER_ADDRESS ?= 0x08002000
+
+ USE_FPU ?= no
+endif
+
ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287))
PROTOCOL = LUFA
@@ -909,4 +943,4 @@ ifneq (,$(filter $(MCU),attiny85))
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
# automatically to create a 32-bit value in your source code.
F_CPU ?= 16500000
-endif
+endif \ No newline at end of file
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema
index 4c785a968a..de1b901a1d 100644
--- a/data/schemas/keyboard.jsonschema
+++ b/data/schemas/keyboard.jsonschema
@@ -42,7 +42,7 @@
},
"processor": {
"type": "string",
- "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK64FX512", "MK66FX1M0", "RP2040", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L442", "STM32L443", "GD32VF103", "WB32F3G71", "WB32FQ95", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
+ "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK64FX512", "MK66FX1M0", "RP2040", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L442", "STM32L443", "GD32VF103", "WB32F3G71", "WB32FQ95", "GD32F303", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"]
},
"audio": {
"type": "object",
@@ -107,7 +107,8 @@
"unknown",
"usbasploader",
"USBasp",
- "wb32-dfu"
+ "wb32-dfu",
+ "ignition"
]
},
"bootloader_instructions": {
diff --git a/keyboards/voyager/.DS_Store b/keyboards/voyager/.DS_Store
new file mode 100644
index 0000000000..46b234f95f
--- /dev/null
+++ b/keyboards/voyager/.DS_Store
Binary files differ
diff --git a/keyboards/voyager/chconf.h b/keyboards/voyager/chconf.h
new file mode 100644
index 0000000000..5abb622086
--- /dev/null
+++ b/keyboards/voyager/chconf.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#define CH_CFG_ST_RESOLUTION 16
+
+#define CH_CFG_ST_FREQUENCY 2000
+
+#define CH_CFG_INTERVALS_SIZE 32
+
+#define CH_CFG_TIME_TYPES_SIZE 32
+
+#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE
+
+#include_next <chconf.h>
+
diff --git a/keyboards/voyager/config.h b/keyboards/voyager/config.h
new file mode 100644
index 0000000000..311310fff4
--- /dev/null
+++ b/keyboards/voyager/config.h
@@ -0,0 +1,140 @@
+/* Copyright 2020 ZSA Technology Labs, Inc <@zsa>
+ * Copyright 2020 Jack Humbert <jack.humb@gmail.com>
+ * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "config_common.h"
+
+/* key matrix size */
+#define MATRIX_ROWS 12
+#define MATRIX_COLS 7
+
+/* PCB default pin-out */
+// #define MATRIX_ROW_PINS { B10, B11, B12, B13, B14, B15 }
+// #define MATRIX_COL_PINS { A0, A1, A2, A3, A6, A7, B0 }
+
+// #define MCP23_ROW_PINS { GPB5, GBP4, GBP3, GBP2, GBP1, GBP0 }
+// #define MCP23_COL_PINS { GPA0, GBA1, GBA2, GBA3, GBA4, GBA5, GBA6 }
+
+// #define MCP23_LED_R GPB7
+// #define MCP23_LED_G GPB6
+// #define MCP23_LED_B GPA7
+
+// Not needed, is default address:
+// #define EXTERNAL_EEPROM_I2C_BASE_ADDRESS 0b10100000
+
+/* COL2ROW or ROW2COL */
+#define DIODE_DIRECTION ROW2COL
+
+/* Set 0 if debouncing isn't needed */
+#ifndef DEBOUNCE
+# define DEBOUNCE 5
+#endif
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+/*
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ */
+
+/* disable debug print */
+// #define NO_DEBUG
+
+#define DRIVER_ADDR_1 0b1110100
+#define DRIVER_ADDR_2 0b1110111
+
+#define DRIVER_COUNT 2
+#define DRIVER_1_LED_TOTAL 36
+#define DRIVER_2_LED_TOTAL 36
+#define DRIVER_LED_TOTAL (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
+#define RGB_MATRIX_CENTER \
+ { 125, 26 }
+#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 175
+#define RGB_MATRIX_FRAMEBUFFER_EFFECTS
+#define RGB_MATRIX_KEYPRESSES
+#define RGB_DISABLE_WHEN_USB_SUSPENDED
+// RGB Matrix Animation modes. Explicitly enabled
+// For full list of effects, see:
+// https://docs.qmk.fm/#/feature_rgb_matrix?id=rgb-matrix-effects
+#define ENABLE_RGB_MATRIX_ALPHAS_MODS
+#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN
+#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT
+#define ENABLE_RGB_MATRIX_BREATHING
+#define ENABLE_RGB_MATRIX_BAND_SAT
+#define ENABLE_RGB_MATRIX_BAND_VAL
+#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT
+#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL
+#define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT
+#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL
+#define ENABLE_RGB_MATRIX_CYCLE_ALL
+#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
+#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN
+#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
+#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN
+#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL
+#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL
+#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL
+#define ENABLE_RGB_MATRIX_DUAL_BEACON
+#define ENABLE_RGB_MATRIX_RAINBOW_BEACON
+#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS
+#define ENABLE_RGB_MATRIX_RAINDROPS
+#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
+#define ENABLE_RGB_MATRIX_HUE_BREATHING
+#define ENABLE_RGB_MATRIX_HUE_PENDULUM
+#define ENABLE_RGB_MATRIX_HUE_WAVE
+#define ENABLE_RGB_MATRIX_PIXEL_RAIN
+#define ENABLE_RGB_MATRIX_PIXEL_FLOW
+#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL
+// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined
+#define ENABLE_RGB_MATRIX_TYPING_HEATMAP
+#define ENABLE_RGB_MATRIX_DIGITAL_RAIN
+// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS
+#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS
+#define ENABLE_RGB_MATRIX_SPLASH
+#define ENABLE_RGB_MATRIX_MULTISPLASH
+#define ENABLE_RGB_MATRIX_SOLID_SPLASH
+#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH
+
+#ifndef ISSI_TIMEOUT
+# define ISSI_TIMEOUT 5
+#endif
+
+#define MOUSEKEY_INTERVAL 20
+#define MOUSEKEY_DELAY 0
+#define MOUSEKEY_TIME_TO_MAX 60
+#define MOUSEKEY_MAX_SPEED 7
+#define MOUSEKEY_WHEEL_DELAY 400
+#define MOUSEKEY_WHEEL_INTERVAL MOUSEKEY_INTERVAL
+#define MOUSEKEY_WHEEL_MAX_SPEED MOUSEKEY_MAX_SPEED
+#define MOUSEKEY_WHEEL_TIME_TO_MAX MOUSEKEY_TIME_TO_MAX
+
+#define TAPPING_TOGGLE 1
+
+// Delay between each i2c io expander ops (in MCU cycles)
+#define IO_EXPANDER_OP_DELAY 500 \ No newline at end of file
diff --git a/keyboards/voyager/gd32/config.h b/keyboards/voyager/gd32/config.h
new file mode 100644
index 0000000000..86c3985db2
--- /dev/null
+++ b/keyboards/voyager/gd32/config.h
@@ -0,0 +1,4 @@
+#define GD32
+#define FEE_PAGE_SIZE 0x400
+#define FEE_PAGE_COUNT 2
+#define FEE_MCU_FLASH_SIZE 256 \ No newline at end of file
diff --git a/keyboards/voyager/gd32/info.json b/keyboards/voyager/gd32/info.json
new file mode 100644
index 0000000000..4ac2636296
--- /dev/null
+++ b/keyboards/voyager/gd32/info.json
@@ -0,0 +1,227 @@
+{
+ "keyboard_name": "Voyager",
+ "manufacturer": "ZSA Technology Labs",
+ "url": "zsa.io/voyager",
+ "maintainer": "ZSA Technology Labs",
+ "usb": {
+ "vid": "0x3297",
+ "pid": "0x1978",
+ "device_version": "0.0.1"
+ },
+ "layouts": {
+ "LAYOUT_voyager": {
+ "layout": [
+ {
+ "x": 3,
+ "y": 0
+ },
+ {
+ "x": 12,
+ "y": 0
+ },
+ {
+ "x": 2,
+ "y": 0.25
+ },
+ {
+ "x": 4,
+ "y": 0.25
+ },
+ {
+ "x": 11,
+ "y": 0.25
+ },
+ {
+ "x": 13,
+ "y": 0.25
+ },
+ {
+ "x": 0,
+ "y": 0.5
+ },
+ {
+ "x": 1,
+ "y": 0.5
+ },
+ {
+ "x": 5,
+ "y": 0.5
+ },
+ {
+ "x": 10,
+ "y": 0.5
+ },
+ {
+ "x": 14,
+ "y": 0.5
+ },
+ {
+ "x": 15,
+ "y": 0.5
+ },
+ {
+ "x": 3,
+ "y": 1
+ },
+ {
+ "x": 12,
+ "y": 1
+ },
+ {
+ "x": 2,
+ "y": 1.25
+ },
+ {
+ "x": 4,
+ "y": 1.25
+ },
+ {
+ "x": 11,
+ "y": 1.25
+ },
+ {
+ "x": 13,
+ "y": 1.25
+ },
+ {
+ "x": 0,
+ "y": 1.5
+ },
+ {
+ "x": 1,
+ "y": 1.5
+ },
+ {
+ "x": 5,
+ "y": 1.5
+ },
+ {
+ "x": 10,
+ "y": 1.5
+ },
+ {
+ "x": 14,
+ "y": 1.5
+ },
+ {
+ "x": 15,
+ "y": 1.5
+ },
+ {
+ "x": 3,
+ "y": 2
+ },
+ {
+ "x": 12,
+ "y": 2
+ },
+ {
+ "x": 2,
+ "y": 2.25
+ },
+ {
+ "x": 4,
+ "y": 2.25
+ },
+ {
+ "x": 11,
+ "y": 2.25
+ },
+ {
+ "x": 13,
+ "y": 2.25
+ },
+ {
+ "x": 0,
+ "y": 2.5
+ },
+ {
+ "x": 1,
+ "y": 2.5
+ },
+ {
+ "x": 5,
+ "y": 2.5
+ },
+ {
+ "x": 10,
+ "y": 2.5
+ },
+ {
+ "x": 14,
+ "y": 2.5
+ },
+ {
+ "x": 15,
+ "y": 2.5
+ },
+ {
+ "x": 3,
+ "y": 3
+ },
+ {
+ "x": 12,
+ "y": 3
+ },
+ {
+ "x": 2,
+ "y": 3.25
+ },
+ {
+ "x": 4,
+ "y": 3.25
+ },
+ {
+ "x": 11,
+ "y": 3.25
+ },
+ {
+ "x": 13,
+ "y": 3.25
+ },
+ {
+ "x": 0,
+ "y": 3.5
+ },
+ {
+ "x": 1,
+ "y": 3.5
+ },
+ {
+ "x": 5,
+ "y": 3.5
+ },
+ {
+ "x": 10,
+ "y": 3.5
+ },
+ {
+ "x": 14,
+ "y": 3.5
+ },
+ {
+ "x": 15,
+ "y": 3.5
+ },
+ {
+ "x": 0,
+ "y": 4.5
+ },
+ {
+ "x": 1,
+ "y": 4.5,
+ "h": 1.75
+ },
+ {
+ "x": -0.75,
+ "y": 4.75,
+ "h": 1.75
+ },
+ {
+ "x": 0.25,
+ "y": 4.75
+ }
+ ]
+ }
+ }
+}
diff --git a/keyboards/voyager/gd32/rules.mk b/keyboards/voyager/gd32/rules.mk
new file mode 100644
index 0000000000..7b4ff0f14d
--- /dev/null
+++ b/keyboards/voyager/gd32/rules.mk
@@ -0,0 +1,32 @@
+# MCU name
+MCU = GD32F303
+
+# Bootloader selection
+BOOTLOADER = ignition
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # Commands for debug and configuration
+NKRO_ENABLE = yes # Enable N-Key Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+AUDIO_ENABLE = no # Audio output
+CUSTOM_MATRIX = lite
+SWAP_HANDS_ENABLE = yes
+RGB_MATRIX_ENABLE = yes
+RGB_MATRIX_DRIVER = IS31FL3731
+EEPROM_DRIVER = vendor
+MOUSE_SHARED_EP = no
+LTO_ENABLE = no
+DFU_SUFFIX_ARGS = -v 3297 -p 1791
+
+#project specific files
+SRC += matrix.c
+QUANTUM_LIB_SRC += i2c_master.c
+
+MOUSE_SHARED_EP = no \ No newline at end of file
diff --git a/keyboards/voyager/halconf.h b/keyboards/voyager/halconf.h
new file mode 100644
index 0000000000..46b53b1a7f
--- /dev/null
+++ b/keyboards/voyager/halconf.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#define HAL_USE_I2C TRUE
+#define HAL_USE_GPT TRUE
+#define HAL_USE_DAC TRUE
+
+#include_next <halconf.h>
diff --git a/keyboards/voyager/info.json b/keyboards/voyager/info.json
new file mode 100644
index 0000000000..340a527e9d
--- /dev/null
+++ b/keyboards/voyager/info.json
@@ -0,0 +1,227 @@
+{
+ "keyboard_name": "Voyager",
+ "manufacturer": "ZSA Technology Labs",
+ "url": "zsa.io/voyager",
+ "maintainer": "ZSA Technology Labs",
+ "usb": {
+ "vid": "0x3297",
+ "pid": "0x1977",
+ "device_version": "0.0.1"
+ },
+ "layouts": {
+ "LAYOUT_voyager": {
+ "layout": [
+ {
+ "x": 3,
+ "y": 0
+ },
+ {
+ "x": 12,
+ "y": 0
+ },
+ {
+ "x": 2,
+ "y": 0.25
+ },
+ {
+ "x": 4,
+ "y": 0.25
+ },
+ {
+ "x": 11,
+ "y": 0.25
+ },
+ {
+ "x": 13,
+ "y": 0.25
+ },
+ {
+ "x": 0,
+ "y": 0.5
+ },
+ {
+ "x": 1,
+ "y": 0.5
+ },
+ {
+ "x": 5,
+ "y": 0.5
+ },
+ {
+ "x": 10,
+ "y": 0.5
+ },
+ {
+ "x": 14,
+ "y": 0.5
+ },
+ {
+ "x": 15,
+ "y": 0.5
+ },
+ {
+ "x": 3,
+ "y": 1
+ },
+ {
+ "x": 12,
+ "y": 1
+ },
+ {
+ "x": 2,
+ "y": 1.25
+ },
+ {
+ "x": 4,
+ "y": 1.25
+ },
+ {
+ "x": 11,
+ "y": 1.25
+ },
+ {
+ "x": 13,
+ "y": 1.25
+ },
+ {
+ "x": 0,
+ "y": 1.5
+ },
+ {
+ "x": 1,
+ "y": 1.5
+ },
+ {
+ "x": 5,
+ "y": 1.5
+ },
+ {
+ "x": 10,
+ "y": 1.5
+ },
+ {
+ "x": 14,
+ "y": 1.5
+ },
+ {
+ "x": 15,
+ "y": 1.5
+ },
+ {
+ "x": 3,
+ "y": 2
+ },
+ {
+ "x": 12,
+ "y": 2
+ },
+ {
+ "x": 2,
+ "y": 2.25
+ },
+ {
+ "x": 4,
+ "y": 2.25
+ },
+ {
+ "x": 11,
+ "y": 2.25
+ },
+ {
+ "x": 13,
+ "y": 2.25
+ },
+ {
+ "x": 0,
+ "y": 2.5
+ },
+ {
+ "x": 1,
+ "y": 2.5
+ },
+ {
+ "x": 5,
+ "y": 2.5
+ },
+ {
+ "x": 10,
+ "y": 2.5
+ },
+ {
+ "x": 14,
+ "y": 2.5
+ },
+ {
+ "x": 15,
+ "y": 2.5
+ },
+ {
+ "x": 3,
+ "y": 3
+ },
+ {
+ "x": 12,
+ "y": 3
+ },
+ {
+ "x": 2,
+ "y": 3.25
+ },
+ {
+ "x": 4,
+ "y": 3.25
+ },
+ {
+ "x": 11,
+ "y": 3.25
+ },
+ {
+ "x": 13,
+ "y": 3.25
+ },
+ {
+ "x": 0,
+ "y": 3.5
+ },
+ {
+ "x": 1,
+ "y": 3.5
+ },
+ {
+ "x": 5,
+ "y": 3.5
+ },
+ {
+ "x": 10,
+ "y": 3.5
+ },
+ {
+ "x": 14,
+ "y": 3.5
+ },
+ {
+ "x": 15,
+ "y": 3.5
+ },
+ {
+ "x": 0,
+ "y": 4.5
+ },
+ {
+ "x": 1,
+ "y": 4.5,
+ "h": 1.75
+ },
+ {
+ "x": -0.75,
+ "y": 4.75,
+ "h": 1.75
+ },
+ {
+ "x": 0.25,
+ "y": 4.75
+ }
+ ]
+ }
+ }
+}
diff --git a/keyboards/voyager/keymaps/.DS_Store b/keyboards/voyager/keymaps/.DS_Store
new file mode 100644
index 0000000000..50a04ea7b9
--- /dev/null
+++ b/keyboards/voyager/keymaps/.DS_Store
Binary files differ
diff --git a/keyboards/voyager/keymaps/default/config.h b/keyboards/voyager/keymaps/default/config.h
new file mode 100644
index 0000000000..235b8a10a1
--- /dev/null
+++ b/keyboards/voyager/keymaps/default/config.h
@@ -0,0 +1,15 @@
+/*
+ Set any config.h overrides for your specific keymap here.
+ See config.h options at https://docs.qmk.fm/#/config_options?id=the-configh-file
+*/
+#define ORYX_CONFIGURATOR
+#define USB_SUSPEND_WAKEUP_DELAY 0
+#define IGNORE_MOD_TAP_INTERRUPT
+#define FIRMWARE_VERSION u8"dAA/M7l"
+#define RAW_USAGE_PAGE 0xFF60
+#define RAW_USAGE_ID 0x61
+#define LAYER_STATE_8BIT
+#define COMBO_COUNT 1
+
+#define RGB_MATRIX_STARTUP_SPD 60
+
diff --git a/keyboards/voyager/keymaps/default/keymap.c b/keyboards/voyager/keymaps/default/keymap.c
new file mode 100644
index 0000000000..b96185d304
--- /dev/null
+++ b/keyboards/voyager/keymaps/default/keymap.c
@@ -0,0 +1,196 @@
+#include QMK_KEYBOARD_H
+#include "version.h"
+#include "keymap_german.h"
+#include "keymap_nordic.h"
+#include "keymap_french.h"
+#include "keymap_spanish.h"
+#include "keymap_hungarian.h"
+#include "keymap_swedish.h"
+#include "keymap_br_abnt2.h"
+#include "keymap_canadian_multilingual.h"
+#include "keymap_german_ch.h"
+#include "keymap_jp.h"
+#include "keymap_korean.h"
+#include "keymap_bepo.h"
+#include "keymap_italian.h"
+#include "keymap_slovenian.h"
+#include "keymap_lithuanian_azerty.h"
+#include "keymap_danish.h"
+#include "keymap_norwegian.h"
+#include "keymap_portuguese.h"
+#include "keymap_contributions.h"
+#include "keymap_czech.h"
+#include "keymap_romanian.h"
+#include "keymap_russian.h"
+#include "keymap_uk.h"
+#include "keymap_estonian.h"
+#include "keymap_belgian.h"
+#include "keymap_us_international.h"
+#include "keymap_croatian.h"
+#include "keymap_turkish_q.h"
+#include "keymap_slovak.h"
+
+#define KC_MAC_UNDO LGUI(KC_Z)
+#define KC_MAC_CUT LGUI(KC_X)
+#define KC_MAC_COPY LGUI(KC_C)
+#define KC_MAC_PASTE LGUI(KC_V)
+#define KC_PC_UNDO LCTL(KC_Z)
+#define KC_PC_CUT LCTL(KC_X)
+#define KC_PC_COPY LCTL(KC_C)
+#define KC_PC_PASTE LCTL(KC_V)
+#define ES_LESS_MAC KC_GRAVE
+#define ES_GRTR_MAC LSFT(KC_GRAVE)
+#define ES_BSLS_MAC ALGR(KC_6)
+#define NO_PIPE_ALT KC_GRAVE
+#define NO_BSLS_ALT KC_EQUAL
+#define LSA_T(kc) MT(MOD_LSFT | MOD_LALT, kc)
+#define BP_NDSH_MAC ALGR(KC_8)
+#define SE_SECT_MAC ALGR(KC_6)
+#define MOON_LED_LEVEL LED_LEVEL
+
+enum custom_keycodes {
+ RGB_SLD = ML_SAFE_RANGE,
+ HSV_0_255_255,
+ HSV_74_255_255,
+ HSV_169_255_255,
+};
+
+
+
+enum tap_dance_codes {
+ DANCE_0,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT_voyager(
+ TD(DANCE_0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINUS,
+ CAPS_WORD, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLASH,
+ MT(MOD_LSFT, KC_BSPACE),KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCOLON, MT(MOD_RSFT, KC_QUOTE),
+ KC_LGUI, MT(MOD_LALT, KC_Z),KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, MT(MOD_RALT, KC_SLASH),KC_RCTRL,
+ LT(1,KC_ENTER), MT(MOD_LCTL, KC_TAB), MT(MOD_LSFT, KC_BSPACE),LT(2,KC_SPACE)
+ ),
+ [1] = LAYOUT_voyager(
+ KC_ESCAPE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_GRAVE, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_7, KC_8, KC_9, KC_MINUS, KC_SLASH, KC_F12,
+ KC_TRANSPARENT, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_4, KC_5, KC_6, KC_PLUS, KC_ASTR, KC_BSPACE,
+ KC_TRANSPARENT, KC_TRANSPARENT, KC_LBRACKET, KC_RBRACKET, KC_LCBR, KC_RCBR, KC_1, KC_2, KC_3, KC_DOT, KC_EQUAL, KC_ENTER,
+ KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_0
+ ),
+ [2] = LAYOUT_voyager(
+ RGB_TOG, TOGGLE_LAYER_COLOR,RGB_MOD, RGB_SLD, RGB_VAD, RGB_VAI, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT,
+ KC_TRANSPARENT, KC_TRANSPARENT, KC_AUDIO_VOL_DOWN,KC_AUDIO_VOL_UP,KC_AUDIO_MUTE, KC_TRANSPARENT, KC_PGUP, KC_HOME, KC_UP, KC_END, KC_TRANSPARENT, KC_TRANSPARENT,
+ KC_TRANSPARENT, KC_MEDIA_PREV_TRACK,KC_MEDIA_NEXT_TRACK,KC_MEDIA_STOP, KC_MEDIA_PLAY_PAUSE,KC_TRANSPARENT, KC_PGDOWN, KC_LEFT, KC_DOWN, KC_RIGHT, KC_TRANSPARENT, KC_TRANSPARENT,
+ KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, HSV_0_255_255, HSV_74_255_255, HSV_169_255_255, KC_TRANSPARENT, LCTL(LSFT(KC_TAB)),LCTL(KC_TAB), KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT,
+ KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT
+ ),
+};
+
+const uint16_t PROGMEM combo0[] = { MT(MOD_RSFT, KC_QUOTE), MT(MOD_LSFT, KC_BSPACE), COMBO_END};
+
+combo_t key_combos[COMBO_COUNT] = {
+ COMBO(combo0, KC_CAPSLOCK),
+};
+
+
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+
+ case RGB_SLD:
+ if (record->event.pressed) {
+ rgblight_mode(1);
+ }
+ return false;
+ case HSV_0_255_255:
+ if (record->event.pressed) {
+ rgblight_mode(1);
+ rgblight_sethsv(0,255,255);
+ }
+ return false;
+ case HSV_74_255_255:
+ if (record->event.pressed) {
+ rgblight_mode(1);
+ rgblight_sethsv(74,255,255);
+ }
+ return false;
+ case HSV_169_255_255:
+ if (record->event.pressed) {
+ rgblight_mode(1);
+ rgblight_sethsv(169,255,255);
+ }
+ return false;
+ }
+ return true;
+}
+
+
+typedef struct {
+ bool is_press_action;
+ uint8_t step;
+} tap;
+
+enum {
+ SINGLE_TAP = 1,
+ SINGLE_HOLD,
+ DOUBLE_TAP,
+ DOUBLE_HOLD,
+ DOUBLE_SINGLE_TAP,
+ MORE_TAPS
+};
+
+static tap dance_state[1];
+
+uint8_t dance_step(qk_tap_dance_state_t *state);
+
+uint8_t dance_step(qk_tap_dance_state_t *state) {
+ if (state->count == 1) {
+ if (state->interrupted || !state->pressed) return SINGLE_TAP;
+ else return SINGLE_HOLD;
+ } else if (state->count == 2) {
+ if (state->interrupted) return DOUBLE_SINGLE_TAP;
+ else if (state->pressed) return DOUBLE_HOLD;
+ else return DOUBLE_TAP;
+ }
+ return MORE_TAPS;
+}
+
+
+void on_dance_0(qk_tap_dance_state_t *state, void *user_data);
+void dance_0_finished(qk_tap_dance_state_t *state, void *user_data);
+void dance_0_reset(qk_tap_dance_state_t *state, void *user_data);
+
+void on_dance_0(qk_tap_dance_state_t *state, void *user_data) {
+ if(state->count == 3) {
+ tap_code16(KC_EQUAL);
+ tap_code16(KC_EQUAL);
+ tap_code16(KC_EQUAL);
+ }
+ if(state->count > 3) {
+ tap_code16(KC_EQUAL);
+ }
+}
+
+void dance_0_finished(qk_tap_dance_state_t *state, void *user_data) {
+ dance_state[0].step = dance_step(state);
+ switch (dance_state[0].step) {
+ case SINGLE_TAP: register_code16(KC_EQUAL); break;
+ case SINGLE_HOLD: register_code16(KC_ESCAPE); break;
+ case DOUBLE_TAP: register_code16(KC_EQUAL); register_code16(KC_EQUAL); break;
+ case DOUBLE_SINGLE_TAP: tap_code16(KC_EQUAL); register_code16(KC_EQUAL);
+ }
+}
+
+void dance_0_reset(qk_tap_dance_state_t *state, void *user_data) {
+ wait_ms(10);
+ switch (dance_state[0].step) {
+ case SINGLE_TAP: unregister_code16(KC_EQUAL); break;
+ case SINGLE_HOLD: unregister_code16(KC_ESCAPE); break;
+ case DOUBLE_TAP: unregister_code16(KC_EQUAL); break;
+ case DOUBLE_SINGLE_TAP: unregister_code16(KC_EQUAL); break;
+ }
+ dance_state[0].step = 0;
+}
+
+qk_tap_dance_action_t tap_dance_actions[] = {
+ [DANCE_0] = ACTION_TAP_DANCE_FN_ADVANCED(on_dance_0, dance_0_finished, dance_0_reset),
+};
diff --git a/keyboards/voyager/keymaps/default/rules.mk b/keyboards/voyager/keymaps/default/rules.mk
new file mode 100644
index 0000000000..df7ed84338
--- /dev/null
+++ b/keyboards/voyager/keymaps/default/rules.mk
@@ -0,0 +1,12 @@
+# Set any rules.mk overrides for your specific keymap here.
+# See rules at https://docs.qmk.fm/#/config_options?id=the-rulesmk-file
+CONSOLE_ENABLE = yes
+COMMAND_ENABLE = no
+MOUSEKEY_ENABLE = no
+ORYX_ENABLE = yes
+RGB_MATRIX_CUSTOM_KB = yes
+TAP_DANCE_ENABLE = yes
+SPACE_CADET_ENABLE = no
+CAPS_WORD_ENABLE = yes
+COMBO_ENABLE = yes
+SRC = matrix.c
diff --git a/keyboards/voyager/ld/IGNITION.ld b/keyboards/voyager/ld/IGNITION.ld
new file mode 100644
index 0000000000..0619983beb
--- /dev/null
+++ b/keyboards/voyager/ld/IGNITION.ld
@@ -0,0 +1,85 @@
+/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/*
+ * STM32F303xC memory setup.
+ */
+MEMORY
+{
+ flash0 (rx) : org = 0x08002000, len = 256k - 0x2000
+ flash1 (rx) : org = 0x00000000, len = 0
+ flash2 (rx) : org = 0x00000000, len = 0
+ flash3 (rx) : org = 0x00000000, len = 0
+ flash4 (rx) : org = 0x00000000, len = 0
+ flash5 (rx) : org = 0x00000000, len = 0
+ flash6 (rx) : org = 0x00000000, len = 0
+ flash7 (rx) : org = 0x00000000, len = 0
+ ram0 (wx) : org = 0x20000000, len = 40k
+ ram1 (wx) : org = 0x00000000, len = 0
+ ram2 (wx) : org = 0x00000000, len = 0
+ ram3 (wx) : org = 0x00000000, len = 0
+ ram4 (wx) : org = 0x10000000, len = 8k
+ ram5 (wx) : org = 0x00000000, len = 0
+ ram6 (wx) : org = 0x00000000, len = 0
+ ram7 (wx) : org = 0x00000000, len = 0
+}
+
+/* For each data/text section two region are defined, a virtual region
+ and a load region (_LMA suffix).*/
+
+/* Flash region to be used for exception vectors.*/
+REGION_ALIAS("VECTORS_FLASH", flash0);
+REGION_ALIAS("VECTORS_FLASH_LMA", flash0);
+
+/* Flash region to be used for constructors and destructors.*/
+REGION_ALIAS("XTORS_FLASH", flash0);
+REGION_ALIAS("XTORS_FLASH_LMA", flash0);
+
+/* Flash region to be used for code text.*/
+REGION_ALIAS("TEXT_FLASH", flash0);
+REGION_ALIAS("TEXT_FLASH_LMA", flash0);
+
+/* Flash region to be used for read only data.*/
+REGION_ALIAS("RODATA_FLASH", flash0);
+REGION_ALIAS("RODATA_FLASH_LMA", flash0);
+
+/* Flash region to be used for various.*/
+REGION_ALIAS("VARIOUS_FLASH", flash0);
+REGION_ALIAS("VARIOUS_FLASH_LMA", flash0);
+
+/* Flash region to be used for RAM(n) initialization data.*/
+REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0);
+
+/* RAM region to be used for Main stack. This stack accommodates the processing
+ of all exceptions and interrupts.*/
+REGION_ALIAS("MAIN_STACK_RAM", ram0);
+
+/* RAM region to be used for the process stack. This is the stack used by
+ the main() function.*/
+REGION_ALIAS("PROCESS_STACK_RAM", ram0);
+
+/* RAM region to be used for data segment.*/
+REGION_ALIAS("DATA_RAM", ram0);
+REGION_ALIAS("DATA_RAM_LMA", flash0);
+
+/* RAM region to be used for BSS segment.*/
+REGION_ALIAS("BSS_RAM", ram0);
+
+/* RAM region to be used for the default heap.*/
+REGION_ALIAS("HEAP_RAM", ram0);
+
+/* Generic rules inclusion.*/
+INCLUDE rules.ld \ No newline at end of file
diff --git a/keyboards/voyager/matrix.c b/keyboards/voyager/matrix.c
new file mode 100644
index 0000000000..4de3ed860d
--- /dev/null
+++ b/keyboards/voyager/matrix.c
@@ -0,0 +1,241 @@
+/* Copyright 2020 ZSA Technology Labs, Inc <@zsa>
+ * Copyright 2020 Jack Humbert <jack.humb@gmail.com>
+ * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "voyager.h"
+#include "is31fl3731.h"
+#include "i2c_master.h"
+
+extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values
+extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
+static matrix_row_t raw_matrix_right[MATRIX_COLS];
+
+#define ROWS_PER_HAND (MATRIX_ROWS / 2)
+#ifndef VOYAGER_I2C_TIMEOUT
+# define VOYAGER_I2C_TIMEOUT 100
+#endif
+
+extern bool mcp23018_leds[3];
+extern bool is_launching;
+
+bool mcp23018_initd = false;
+// extern bool IS31FL3731_initd;
+static uint8_t mcp23018_reset_loop;
+// static uint8_t is31fl3731_reset_loop;
+
+uint8_t mcp23018_tx[3];
+uint8_t mcp23018_rx[1];
+
+void mcp23018_init(void) {
+ i2c_init();
+
+ mcp23018_tx[0] = 0x00; // IODIRA
+ mcp23018_tx[1] = 0b00000000; // A is output
+ mcp23018_tx[2] = 0b00111111; // B is inputs
+
+ if (MSG_OK == i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, VOYAGER_I2C_TIMEOUT)) {
+ mcp23018_tx[0] = 0x0C; // GPPUA
+ mcp23018_tx[1] = 0b10000000; // A is not pulled-up
+ mcp23018_tx[2] = 0b11111111; // B is pulled-up
+ wait_ms(5);
+
+ if (MSG_OK == i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, VOYAGER_I2C_TIMEOUT)) {
+ wait_ms(5);
+ mcp23018_initd = is_launching = true;
+ }
+ }
+}
+
+bool io_expander_ready(void) {
+ uint8_t tx[1] = {0x13};
+ if (MSG_OK == i2c_readReg(MCP23018_DEFAULT_ADDRESS << 1, tx[0], &tx[0], 1, VOYAGER_I2C_TIMEOUT)) {
+ return true;
+ }
+ return false;
+}
+
+void matrix_init_custom(void) {
+ // outputs
+ setPinOutput(B10);
+ setPinOutput(B11);
+ setPinOutput(B12);
+ setPinOutput(B13);
+ setPinOutput(B14);
+ setPinOutput(B15);
+
+ // inputs
+ setPinInputLow(A0);
+ setPinInputLow(A1);
+ setPinInputLow(A2);
+ setPinInputLow(A3);
+ setPinInputLow(A6);
+ setPinInputLow(A7);
+ setPinInputLow(B0);
+
+ mcp23018_init();
+}
+
+bool matrix_scan_custom(matrix_row_t current_matrix[]) {
+ bool changed = false;
+ // Attempt to reset the mcp23018 if it's not initialized
+ if (!mcp23018_initd) {
+ if (++mcp23018_reset_loop == 0) {
+ // Since mcp23018_reset_loop is 8 bit - we'll try to reset once in 255 matrix scans. This will be approx bit more frequent than once per second.
+ if (io_expander_ready()) {
+ // If we managed to initialize the mcp23018 - we need to reinitialize the matrix / layer state. During an electric discharge the i2c peripherals might be in a weird state. Giving a delay and resetting the MCU allows to recover from this.
+ wait_ms(200);
+ mcu_reset();
+ }
+ }
+ }
+
+ // Scanning left and right side of the keyboard for key presses.
+ // Left side is scanned by reading the gpio pins directly, right side is scanned by reading the mcp23018 registers.
+
+ matrix_row_t data = 0;
+ for (uint8_t row = 0; row <= ROWS_PER_HAND; row++) {
+ // strobe row
+ switch (row) {
+ case 0:
+ writePinHigh(B10);
+ break;
+ case 1:
+ writePinHigh(B11);
+ break;
+ case 2:
+ writePinHigh(B12);
+ break;
+ case 3:
+ writePinHigh(B13);
+ break;
+ case 4:
+ writePinHigh(B14);
+ break;
+ case 5:
+ writePinHigh(B15);
+ break;
+ case 6:
+ break; // Left hand has 6 rows
+ }
+
+ // Selecting the row on the right side of the keyboard.
+ if (mcp23018_initd) {
+ // select row
+ mcp23018_tx[0] = 0x12; // GPIOA
+ mcp23018_tx[1] = (0b01111111 & ~(1 << (row))) | ((uint8_t)!mcp23018_leds[2] << 7); // activate row
+ mcp23018_tx[2] = ((uint8_t)!mcp23018_leds[1] << 6) | ((uint8_t)!mcp23018_leds[0] << 7); // activate row
+
+ if (MSG_OK != i2c_transmit(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx, 3, VOYAGER_I2C_TIMEOUT)) {
+ mcp23018_initd = false;
+ }
+ }
+ // Reading the left side of the keyboard.
+ if (row < ROWS_PER_HAND) {
+ // i2c comm incur enough wait time
+ if (!mcp23018_initd) {
+ // need wait to settle pin state
+ matrix_io_delay();
+ }
+ // read col data
+ data = ((readPin(A0) << 0) | (readPin(A1) << 1) | (readPin(A2) << 2) | (readPin(A3) << 3) | (readPin(A6) << 4) | (readPin(A7) << 5) | (readPin(B0) << 6));
+ // unstrobe row
+ switch (row) {
+ case 0:
+ writePinLow(B10);
+ break;
+ case 1:
+ writePinLow(B11);
+ break;
+ case 2:
+ writePinLow(B12);
+ break;
+ case 3:
+ writePinLow(B13);
+ break;
+ case 4:
+ writePinLow(B14);
+ break;
+ case 5:
+ writePinLow(B15);
+ break;
+ case 6:
+ break;
+ }
+
+ if (current_matrix[row] != data) {
+ current_matrix[row] = data;
+ changed = true;
+ }
+ }
+
+ // Reading the right side of the keyboard.
+ if (mcp23018_initd) {
+ for (uint16_t i = 0; i < IO_EXPANDER_OP_DELAY; i++) {
+ __asm__("nop");
+ }
+
+ mcp23018_tx[0] = 0x13; // GPIOB
+ if (MSG_OK != i2c_readReg(MCP23018_DEFAULT_ADDRESS << 1, mcp23018_tx[0], &mcp23018_rx[0], 1, VOYAGER_I2C_TIMEOUT)) {
+ mcp23018_initd = false;
+ }
+ data = ~(mcp23018_rx[0] & 0b00111111);
+ for (uint16_t i = 0; i < IO_EXPANDER_OP_DELAY; i++) {
+ __asm__("nop");
+ }
+ } else {
+ data = 0;
+ }
+
+ if (raw_matrix_right[row] != data) {
+ raw_matrix_right[row] = data;
+ changed = true;
+ }
+ }
+
+ for (uint8_t row = 0; row < ROWS_PER_HAND; row++) {
+ current_matrix[11 - row] = 0;
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+ current_matrix[11 - row] |= ((raw_matrix_right[6 - col] & (1 << row) ? 1 : 0) << col);
+ }
+ }
+ return changed;
+}
+
+// DO NOT REMOVE
+// Needed for proper wake/sleep
+void matrix_power_up(void) {
+ bool temp_launching = is_launching;
+
+ matrix_init_custom();
+
+ is_launching = temp_launching;
+ if (!temp_launching) {
+ STATUS_LED_1(false);
+ STATUS_LED_2(false);
+ STATUS_LED_3(false);
+ STATUS_LED_4(false);
+ }
+
+ // initialize matrix state: all keys off
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ matrix[i] = 0;
+ }
+}
+
+bool is_transport_connected(void) {
+ return mcp23018_initd;
+} \ No newline at end of file
diff --git a/keyboards/voyager/mcuconf.h b/keyboards/voyager/mcuconf.h
new file mode 100644
index 0000000000..69f458a937
--- /dev/null
+++ b/keyboards/voyager/mcuconf.h
@@ -0,0 +1,39 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include_next "mcuconf.h"
+
+// for i2c expander, and ISSI
+#undef STM32_I2C_USE_I2C1
+#define STM32_I2C_USE_I2C1 TRUE
+
+// for future hardwar
+#undef STM32_I2C_USE_I2C2
+#define STM32_I2C_USE_I2C2 TRUE
+
+// for audio
+#undef STM32_DAC_USE_DAC1_CH1
+#define STM32_DAC_USE_DAC1_CH1 TRUE
+#undef STM32_DAC_USE_DAC1_CH2
+#define STM32_DAC_USE_DAC1_CH2 TRUE
+#undef STM32_GPT_USE_TIM6
+#define STM32_GPT_USE_TIM6 TRUE
+#undef STM32_GPT_USE_TIM7
+#define STM32_GPT_USE_TIM7 TRUE
+#undef STM32_GPT_USE_TIM8
+#define STM32_GPT_USE_TIM8 TRUE
diff --git a/keyboards/voyager/readme.md b/keyboards/voyager/readme.md
new file mode 100644
index 0000000000..2758f6d60a
--- /dev/null
+++ b/keyboards/voyager/readme.md
@@ -0,0 +1,58 @@
+# Voyager
+
+![Voyager](https://zsa.io/static/gallery-white-case-7a2ef555f8f7f4ce1b9030477b16e517.png)
+
+A next-gen split, ergonomic keyboard with an active left side, USB type C, integrated wrist rest, and a thumb cluster that can move.
+
+
+* Keyboard Maintainer: [drashna](https://github.com/drashna), [ZSA](https://github.com/zsa/)
+* Hardware Supported: Voyager (STM32F303xC)
+* Hardware Availability: [ZSA Store](https://zsa.io/voyager/)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make voyager:default
+
+Flashing example for this keyboard:
+
+ make voyager:default:flash
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+
+## Voyager Customization
+
+### Indicator LEDs
+
+There are 6 functions for enabling and disabling the LEDs on the top of the boards. The functions are `ML_LED_1(bool)` through `ML_LED_6(bool)`, with the first LED being the left most LED on the left hand, and the sixth LED being the right most LED on the right side.
+
+By default, the Indicator LEDs are used to indicate the layer state for the keyboard. If you wish to change this (and indicate caps/num/scroll lock status instead), then define `VOYAGER_USER_LEDS` in your `config.h` file.
+
+
+### Oryx Configuration
+
+To enable the features from Oryx (ZSA's Configurator), either compile the `default` keymap, or add `#define ORYX_CONFIGURATOR` to your `config.h` file.
+
+This enables the front Indicator LEDs, and the `TOGGLE_LAYER_COLOR` keycode. The `TOGGLE_LAYER_COLOR` keycode toggles the customized LED map configured on Oryx.
+
+### RGB Matrix Features
+
+If you're using the Smart LED (layer indication) feature from the Oryx Configurator, you want to make sure that you enable these options by adding `#define ORYX_CONFIGURATOR` to your keymap's `config.h`.
+
+This changes the `RGB_TOG` keycode so that it will toggle the lights on and off, in a way that will allow the Smart LEDs to continue to work, even with the rest of the LEDs turned off.
+
+Additionally, a new keycode has been added to toggle the Smart LEDs. Use `TOGGLE_LAYER_COLOR`, if you aren't already.
+
+### Detecting split / Gaming mode
+
+To make it extra gaming friendly, you can configure what happens when you disconnect the right half. This is especially useful when using gaming unfriendly layers or layouts (e.g. home row mods, dvorak, colemak).
+
+Example for enabling a specific layer while right side is disconnected:
+
+```
+void housekeeping_task_user(void) {
+ if (!is_transport_connected()) {
+ // set layer
+ }
+}
+```
diff --git a/keyboards/voyager/rgb_matrix_kb.inc b/keyboards/voyager/rgb_matrix_kb.inc
new file mode 100644
index 0000000000..18cf39dfac
--- /dev/null
+++ b/keyboards/voyager/rgb_matrix_kb.inc
@@ -0,0 +1,32 @@
+#ifdef RGB_MATRIX_ENABLE
+RGB_MATRIX_EFFECT(oryx_webhid_effect)
+# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
+
+static void oryx_webhid_effect_init(void) {
+ // Paint it black
+ for (uint8_t i = 0; i < DRIVER_LED_TOTAL; ++i) {
+ webhid_leds[i] = (RGB){0, 0, 0};
+ }
+}
+
+static bool oryx_webhid_effect_run(effect_params_t* params) {
+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
+ uint8_t val = rgb_matrix_get_val() * 100 / 175;
+ if(val == 0) {
+ rgb_matrix_set_color_all(0, 0, 0);
+ }
+ else {
+ for (uint8_t i = led_min; i < led_max; ++i) {
+ rgb_matrix_set_color(i, webhid_leds[i].r * val / 100, webhid_leds[i].g * val / 100, webhid_leds[i].b * val / 100);
+ }
+ }
+ return rgb_matrix_check_finished_leds(led_max);
+}
+
+static bool oryx_webhid_effect(effect_params_t* params) {
+ if (params->init) oryx_webhid_effect_init();
+ return oryx_webhid_effect_run(params);
+}
+
+# endif
+#endif
diff --git a/keyboards/voyager/rules.mk b/keyboards/voyager/rules.mk
new file mode 100644
index 0000000000..27c275a9e9
--- /dev/null
+++ b/keyboards/voyager/rules.mk
@@ -0,0 +1,33 @@
+# MCU name
+MCU = STM32F303
+
+# Bootloader selection
+BOOTLOADER = ignition
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite
+MOUSEKEY_ENABLE = yes # Mouse keys
+EXTRAKEY_ENABLE = yes # Audio control and System control
+CONSOLE_ENABLE = no # Console for debug
+COMMAND_ENABLE = no # Commands for debug and configuration
+NKRO_ENABLE = yes # Enable N-Key Rollover
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
+AUDIO_ENABLE = no # Audio output
+CUSTOM_MATRIX = lite
+SWAP_HANDS_ENABLE = yes
+RGB_MATRIX_ENABLE = yes
+RGB_MATRIX_DRIVER = IS31FL3731
+EEPROM_DRIVER = vendor
+MOUSE_SHARED_EP = no
+LTO_ENABLE = no
+DFU_SUFFIX_ARGS = -v 3297 -p 0791
+DEBUG_ENABLE = yes
+
+#project specific files
+SRC += matrix.c
+QUANTUM_LIB_SRC += i2c_master.c
+
+MOUSE_SHARED_EP = no \ No newline at end of file
diff --git a/keyboards/voyager/voyager.c b/keyboards/voyager/voyager.c
new file mode 100644
index 0000000000..f31dce2924
--- /dev/null
+++ b/keyboards/voyager/voyager.c
@@ -0,0 +1,386 @@
+/* Copyright 2020 ZSA Technology Labs, Inc <@zsa>
+ * Copyright 2020 Jack Humbert <jack.humb@gmail.com>
+ * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "voyager.h"
+#include "raw_hid.h"
+
+keyboard_config_t keyboard_config;
+
+bool mcp23018_leds[2] = {0, 0};
+bool is_launching = false;
+
+#ifdef DYNAMIC_MACRO_ENABLE
+static bool is_dynamic_recording = false;
+
+void dynamic_macro_record_start_user(void) {
+ is_dynamic_recording = true;
+}
+
+void dynamic_macro_record_end_user(int8_t direction) {
+ is_dynamic_recording = false;
+ STATUS_LED_3(false);
+}
+#endif
+
+void voyager_led_task(void) {
+ if (rawhid_state.rgb_control) return;
+ if (is_launching) {
+ STATUS_LED_1(false);
+ STATUS_LED_2(false);
+ STATUS_LED_3(false);
+ STATUS_LED_4(false);
+
+ STATUS_LED_1(true);
+ wait_ms(250);
+ STATUS_LED_2(true);
+ wait_ms(250);
+ STATUS_LED_3(true);
+ wait_ms(250);
+ STATUS_LED_4(true);
+ wait_ms(250);
+ STATUS_LED_1(false);
+ wait_ms(250);
+ STATUS_LED_2(false);
+ wait_ms(250);
+ STATUS_LED_3(false);
+ wait_ms(250);
+ STATUS_LED_4(false);
+ wait_ms(250);
+ is_launching = false;
+ layer_state_set_kb(layer_state);
+ }
+#ifdef DYNAMIC_MACRO_ENABLE
+ else if (is_dynamic_recording) {
+ STATUS_LED_3(true);
+ wait_ms(100);
+ STATUS_LED_3(false);
+ wait_ms(155);
+ }
+#endif
+#if !defined(VOYAGER_USER_LEDS)
+ else {
+ layer_state_set_kb(layer_state);
+ }
+#endif
+}
+
+static THD_WORKING_AREA(waLEDThread, 128);
+static THD_FUNCTION(LEDThread, arg) {
+ (void)arg;
+ chRegSetThreadName("LEDThread");
+ while (true) {
+ voyager_led_task();
+ }
+}
+
+void keyboard_pre_init_kb(void) {
+ // Initialize Reset pins
+ setPinInput(A8);
+ setPinOutput(A9);
+ writePinLow(A9);
+
+ setPinOutput(B5);
+ setPinOutput(B4);
+ setPinOutput(B3);
+
+ writePinLow(B5);
+ writePinLow(B4);
+ writePinLow(B3);
+
+ chThdCreateStatic(waLEDThread, sizeof(waLEDThread), NORMALPRIO - 16, LEDThread, NULL);
+ keyboard_pre_init_user();
+}
+
+#if !defined(VOYAGER_USER_LEDS)
+layer_state_t layer_state_set_kb(layer_state_t state) {
+ state = layer_state_set_user(state);
+ if (is_launching || !keyboard_config.led_level || rawhid_state.rgb_control) return state;
+ bool LED_1 = false;
+ bool LED_2 = false;
+ bool LED_3 = false;
+# if !defined(CAPS_LOCK_STATUS)
+ bool LED_4 = false;
+# endif
+
+ uint8_t layer = get_highest_layer(state);
+ switch (layer) {
+ case 1:
+ LED_1 = true;
+ break;
+ case 2:
+ LED_2 = true;
+ break;
+ case 3:
+ LED_3 = true;
+ break;
+ case 4:
+# if !defined(CAPS_LOCK_STATUS)
+ LED_4 = true;
+# endif
+ break;
+ case 5:
+ LED_1 = true;
+ LED_2 = true;
+ break;
+ case 6:
+ LED_1 = true;
+ LED_2 = true;
+ LED_3 = true;
+ break;
+ case 7:
+ LED_1 = true;
+ LED_2 = true;
+ LED_3 = true;
+# if !defined(CAPS_LOCK_STATUS)
+ LED_4 = true;
+# endif
+ break;
+ default:
+ break;
+ }
+
+ STATUS_LED_1(LED_1);
+ STATUS_LED_2(LED_2);
+ STATUS_LED_3(LED_3);
+# if !defined(CAPS_LOCK_STATUS)
+ STATUS_LED_4(LED_4);
+# endif
+ return state;
+}
+#endif
+
+#ifdef RGB_MATRIX_ENABLE
+// clang-format off
+const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL] = {
+/* Refer to IS31 manual for these locations
+ * driver
+ * | R location
+ * | | G location
+ * | | | B location
+ * | | | | */
+ {0, C2_2, C1_2, C4_3},
+ {0, C2_3, C1_3, C3_3},
+ {0, C2_4, C1_4, C3_4},
+ {0, C2_5, C1_5, C3_5},
+ {0, C2_6, C1_6, C3_6},
+ {0, C2_7, C1_7, C3_7},
+ {0, C2_8, C1_8, C3_8},
+ {0, C8_1, C7_1, C9_1},
+ {0, C8_2, C7_2, C9_2},
+ {0, C8_3, C7_3, C9_3},
+ {0, C8_4, C7_4, C9_4},
+ {0, C8_5, C7_5, C9_5},
+ {0, C8_6, C7_6, C9_6},
+ {0, C2_10, C1_10, C4_11},
+ {0, C2_11, C1_11, C3_11},
+ {0, C2_12, C1_12, C3_12},
+ {0, C2_13, C1_13, C3_13},
+ {0, C2_14, C1_14, C3_14},
+ {0, C2_15, C1_15, C3_15},
+ {0, C2_16, C1_16, C3_16},
+ {0, C8_9, C7_9, C9_9},
+ {0, C8_10, C7_10, C9_10},
+ {0, C8_11, C7_11, C9_11},
+ {0, C8_12, C7_12, C9_12},
+ {0, C8_13, C7_13, C9_13},
+ {0, C8_14, C7_14, C9_14},
+
+ {1, C2_7, C1_7, C3_7},
+ {1, C2_6, C1_6, C3_6},
+ {1, C2_5, C1_5, C3_5},
+ {1, C2_4, C1_4, C3_4},
+ {1, C2_3, C1_3, C3_3},
+ {1, C2_2, C1_2, C4_3},
+
+ {1, C8_5, C7_5, C9_5},
+ {1, C8_4, C7_4, C9_4},
+ {1, C8_3, C7_3, C9_3},
+ {1, C8_2, C7_2, C9_2},
+ {1, C8_1, C7_1, C9_1},
+ {1, C2_8, C1_8, C3_8},
+
+ {1, C2_14, C1_14, C3_14},
+ {1, C2_13, C1_13, C3_13},
+ {1, C2_12, C1_12, C3_12},
+ {1, C2_11, C1_11, C3_11},
+ {1, C2_10, C1_10, C4_11},
+ {1, C8_6, C7_6, C9_6},
+
+ {1, C8_12, C7_12, C9_12},
+ {1, C8_11, C7_11, C9_11},
+ {1, C8_10, C7_10, C9_10},
+ {1, C8_9, C7_9, C9_9},
+ {1, C2_16, C1_16, C3_16},
+ {1, C2_15, C1_15, C3_15},
+
+ {1, C8_14, C7_14, C9_14},
+ {1, C8_13, C7_13, C9_13},
+};
+
+led_config_t g_led_config = { {
+ { NO_LED, 0, 5, 10, 15, 20, 25 },
+ { NO_LED, 1, 6, 11, 16, 21, 26 },
+ { NO_LED, 2, 7, 12, 17, 22, 27 },
+ { NO_LED, 3, 8, 13, 18, 23, NO_LED },
+ { NO_LED, NO_LED, NO_LED, NO_LED, 24, NO_LED, NO_LED },
+ { 32, 33, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED },
+ { 41, 46, 51, 56, 61, 65, NO_LED },
+
+ { 66, 62, 57, 52, 47, 42, NO_LED },
+ { 67, 63, 58, 53, 48, 43, NO_LED },
+ { NO_LED, 64, 59, 54, 49, 44, NO_LED },
+ { NO_LED, NO_LED, 60, NO_LED, NO_LED, NO_LED, NO_LED },
+ { NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, 69, 68 },
+}, {
+ { 0, 4}, { 0, 20}, { 0, 36}, { 0, 52}, { 0, 68},
+ { 16, 3}, { 16, 19}, { 16, 35}, { 16, 51}, { 16, 67},
+ { 32, 1}, { 32, 17}, { 32, 33}, { 32, 49}, { 32, 65},
+ { 48, 0}, { 48, 16}, { 48, 32}, { 48, 48}, { 48, 64},
+ { 64, 1}, { 64, 17}, { 64, 33}, { 64, 49}, { 64, 65},
+ { 80, 3}, { 80, 19}, { 80, 35}, { 80, 51}, { 96, 4},
+ { 96, 20}, { 96, 36}, { 88, 69}, {100, 80}, {112, 91},
+ {108, 69},
+
+ {240, 4}, {240, 20}, {240, 36}, {240, 52}, {240, 68},
+ {224, 3}, {224, 19}, {224, 35}, {224, 51}, {224, 67},
+ {208, 1}, {208, 17}, {208, 33}, {208, 49}, {208, 65},
+ {192, 0}, {192, 16}, {192, 32}, {192, 48}, {192, 64},
+ {176, 1}, {176, 17}, {176, 33}, {176, 49}, {176, 65},
+ {160, 3}, {160, 19}, {160, 35}, {160, 51}, {144, 4},
+ {144, 20}, {144, 36}, {152, 69}, {140, 80}, {128, 91},
+ {132, 69}
+
+}, {
+ 1, 1, 1, 1, 1, 4,
+ 4, 4, 4, 1, 4, 4,
+ 4, 4, 1, 4, 4, 4,
+ 4, 1, 4, 4, 4, 4,
+ 1, 4, 4, 4, 4, 4,
+ 4, 4, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 4,
+ 4, 4, 4, 1, 4, 4,
+ 4, 4, 1, 4, 4, 4,
+ 4, 1, 4, 4, 4, 4,
+ 1, 4, 4, 4, 4, 4,
+ 4, 4, 1, 1, 1, 1
+} };
+// clang-format on
+
+#endif
+
+#ifdef SWAP_HANDS_ENABLE
+// swap-hands action needs a matrix to define the swap
+// clang-format off
+const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
+ /* Left hand, matrix positions */
+ {{6,6}, {5,6}, {4,6}, {3,6}, {2,6}, {1,6},{0,6}},
+ {{6,7}, {5,7}, {4,7}, {3,7}, {2,7}, {1,7},{0,7}},
+ {{6,8}, {5,8}, {4,8}, {3,8}, {2,8}, {1,8},{0,8}},
+ {{6,9}, {5,9}, {4,9}, {3,9}, {2,9}, {1,9},{0,9}},
+ {{6,10},{5,10},{4,10},{3,10},{2,10},{1,10},{0,10}},
+ {{6,11},{5,11},{4,11},{3,11},{2,11},{1,11},{0,11}},
+ /* Right hand, matrix positions */
+ {{6,0}, {5,0}, {4,0}, {3,0}, {2,0}, {1,0},{0,0}},
+ {{6,1}, {5,1}, {4,1}, {3,1}, {2,1}, {1,1},{0,1}},
+ {{6,2}, {5,2}, {4,2}, {3,2}, {2,2}, {1,2},{0,2}},
+ {{6,3}, {5,3}, {4,3}, {3,3}, {2,3}, {1,3},{0,3}},
+ {{6,4}, {5,4}, {4,4}, {3,4}, {2,4}, {1,4},{0,4}},
+ {{6,5}, {5,5}, {4,5}, {3,5}, {2,5}, {1,5},{0,5}},
+};
+// clang-format on
+
+void keyboard_post_init_kb(void) {
+ rgb_matrix_enable_noeeprom();
+ keyboard_post_init_user();
+}
+#endif
+
+#ifdef CAPS_LOCK_STATUS
+bool led_update_kb(led_t led_state) {
+ bool res = led_update_user(led_state);
+ if (res) {
+ STATUS_LED_4(led_state.caps_lock);
+ }
+ return res;
+}
+#endif
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+ if (!process_record_user(keycode, record)) {
+ return false;
+ }
+ switch (keycode) {
+#if !defined(VOYAGER_USER_LEDS)
+ case LED_LEVEL:
+ if (record->event.pressed) {
+ keyboard_config.led_level ^= 1;
+ eeconfig_update_kb(keyboard_config.raw);
+ if (keyboard_config.led_level) {
+ layer_state_set_kb(layer_state);
+ } else {
+ STATUS_LED_1(false);
+ STATUS_LED_2(false);
+ STATUS_LED_3(false);
+ STATUS_LED_4(false);
+ }
+ }
+ break;
+#endif
+#ifdef RGB_MATRIX_ENABLE
+ case TOGGLE_LAYER_COLOR:
+ if (record->event.pressed) {
+ keyboard_config.disable_layer_led ^= 1;
+ if (keyboard_config.disable_layer_led) rgb_matrix_set_color_all(0, 0, 0);
+ }
+ break;
+ case RGB_TOG:
+ if (record->event.pressed) {
+ switch (rgb_matrix_get_flags()) {
+ case LED_FLAG_ALL: {
+ rgb_matrix_set_flags(LED_FLAG_NONE);
+ rgb_matrix_set_color_all(0, 0, 0);
+ } break;
+ default: {
+ rgb_matrix_set_flags(LED_FLAG_ALL);
+ } break;
+ }
+ }
+ return false;
+#endif
+ }
+ return true;
+}
+
+void matrix_init_kb(void) {
+ keyboard_config.raw = eeconfig_read_kb();
+
+ if (!keyboard_config.led_level && !keyboard_config.led_level_res) {
+ keyboard_config.led_level = true;
+ keyboard_config.led_level_res = 0b11;
+ eeconfig_update_kb(keyboard_config.raw);
+ }
+ matrix_init_user();
+}
+
+void eeconfig_init_kb(void) { // EEPROM is getting reset!
+ keyboard_config.raw = 0;
+ keyboard_config.led_level = true;
+ keyboard_config.led_level_res = 0b11;
+ eeconfig_update_kb(keyboard_config.raw);
+ eeconfig_init_user();
+}
diff --git a/keyboards/voyager/voyager.h b/keyboards/voyager/voyager.h
new file mode 100644
index 0000000000..a9fa3169aa
--- /dev/null
+++ b/keyboards/voyager/voyager.h
@@ -0,0 +1,74 @@
+/* Copyright 2020 ZSA Technology Labs, Inc <@zsa>
+ * Copyright 2020 Jack Humbert <jack.humb@gmail.com>
+ * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+extern bool mcp23018_leds[];
+
+#define MCP23018_DEFAULT_ADDRESS 0b0100000
+
+#define STATUS_LED_1(status) writePin(B5, (bool)status)
+#define STATUS_LED_2(status) writePin(B4, (bool)status)
+#define STATUS_LED_3(status) mcp23018_leds[0] = (bool)status
+#define STATUS_LED_4(status) mcp23018_leds[1] = (bool)status
+
+// clang-format off
+#define LAYOUT_voyager( \
+ k00, k01, k02, k03, k04, k05, k26, k27, k28, k29, k30, k31, \
+ k06, k07, k08, k09, k10, k11, k32, k33, k34, k35, k36, k37, \
+ k12, k13, k14, k15, k16, k17, k38, k39, k40, k41, k42, k43, \
+ k18, k19, k20, k21, k22, k23, k44, k45, k46, k47, k48, k49, \
+ k24, k25, k50, k51 \
+)\
+{ \
+ { KC_NO, k00, k01, k02, k03, k04, k05 }, \
+ { KC_NO, k06, k07, k08, k09, k10, k11 }, \
+ { KC_NO, k12, k13, k14, k15, k16, k17 }, \
+ { KC_NO, k18, k19, k20, k21, k22, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, k23, KC_NO, KC_NO }, \
+ { k24, k25, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+\
+ { k26, k27, k28, k29, k30, k31, KC_NO }, \
+ { k32, k33, k34, k35, k36, k37, KC_NO }, \
+ { k38, k39, k40, k41, k42, k43, KC_NO }, \
+ { KC_NO, k45, k46, k47, k48, k49, KC_NO }, \
+ { KC_NO, KC_NO, k44, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, k50, k51 }, \
+}
+// clang-format on
+enum voyager_keycodes {
+ TOGGLE_LAYER_COLOR = SAFE_RANGE,
+ LED_LEVEL,
+ ML_SAFE_RANGE,
+};
+
+typedef union {
+ uint32_t raw;
+ struct {
+ bool disable_layer_led : 1;
+ bool placeholder : 1;
+ bool led_level : 1;
+ uint8_t led_level_res : 2; // DO NOT REMOVE
+ };
+} keyboard_config_t;
+
+extern keyboard_config_t keyboard_config;
+
+bool is_transport_connected(void);
diff --git a/lib/chibios-contrib b/lib/chibios-contrib
-Subproject d03aa9cc2f76468e431c71421015102956dd6ad
+Subproject 209d7d335922ffb17a40e52b31f71a3a1a8f240
diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py
index 8a13029a8a..2493df2e5d 100644
--- a/lib/python/qmk/constants.py
+++ b/lib/python/qmk/constants.py
@@ -14,7 +14,7 @@ QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware'
MAX_KEYBOARD_SUBFOLDERS = 5
# Supported processor types
-CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK64FX512', 'MK66FX1M0', 'RP2040', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95'
+CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK64FX512', 'MK66FX1M0', 'RP2040', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F405', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L442', 'STM32L443', 'GD32VF103', 'WB32F3G71', 'WB32FQ95', 'GD32F303'
LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None
VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85'
diff --git a/platforms/chibios/boards/GD32F303C_EVAL/board/board.c b/platforms/chibios/boards/GD32F303C_EVAL/board/board.c
new file mode 100644
index 0000000000..e82e1d37ce
--- /dev/null
+++ b/platforms/chibios/boards/GD32F303C_EVAL/board/board.c
@@ -0,0 +1,58 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#include <hal.h>
+
+/**
+ * @brief PAL setup.
+ * @details Digital I/O ports static configuration as defined in @p board.h.
+ * This variable is used by the HAL when initializing the PAL driver.
+ */
+#if HAL_USE_PAL || defined(__DOXYGEN__)
+const PALConfig pal_default_config =
+{
+ {VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
+ {VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
+ {VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH},
+ {VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH},
+# if STM32_HAS_GPIOE
+ {VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH},
+# endif
+};
+#endif
+
+__attribute__((weak)) void enter_bootloader_mode_if_requested(void) {}
+
+/*
+ * Early initialization code.
+ * This initialization must be performed just after stack setup and before
+ * any other initialization.
+ */
+void __early_init(void) {
+ enter_bootloader_mode_if_requested();
+
+ stm32_clock_init();
+}
+
+/*
+ * Board-specific initialization code.
+ */
+void boardInit(void) {
+ //JTAG-DP Disabled and SW-DP Enabled
+ AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
+ //Set backup register DR10 to enter bootloader on reset
+ BKP->DR10 = RTC_BOOTLOADER_FLAG;
+}
diff --git a/platforms/chibios/boards/GD32F303C_EVAL/board/board.mk b/platforms/chibios/boards/GD32F303C_EVAL/board/board.mk
new file mode 100644
index 0000000000..b9a48f105b
--- /dev/null
+++ b/platforms/chibios/boards/GD32F303C_EVAL/board/board.mk
@@ -0,0 +1,11 @@
+# List of all the board related files.
+$(info $(BOARD_PATH))
+BOARDSRC = $(BOARD_PATH)/board/board.c
+
+# Required include directories
+BOARDINC = $(BOARD_PATH)/board
+
+# Shared variables
+ALLCSRC += $(BOARDSRC)
+ALLINC += $(BOARDINC)
+
diff --git a/platforms/chibios/boards/GD32F303C_EVAL/configs/board.h b/platforms/chibios/boards/GD32F303C_EVAL/configs/board.h
new file mode 100644
index 0000000000..69028bbe9e
--- /dev/null
+++ b/platforms/chibios/boards/GD32F303C_EVAL/configs/board.h
@@ -0,0 +1,169 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+/*
+ * Setup for a Generic STM32F103 board.
+ */
+
+/*
+ * Board identifier.
+ */
+#define BOARD_GD32EVAL
+#define BOARD_NAME "GENERIC GD32F303 board - ignition bootloader"
+
+/*
+ * Board frequencies.
+ */
+#define STM32_LSECLK 32768
+//#define STM32_HSECLK 8000000
+#define STM32_HSECLK 10800000 // ~ 98Mhz
+
+/*
+ * MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h.
+ */
+#define STM32F103xE
+
+/*
+ * IO pins assignments
+ */
+
+/* on-board */
+
+#define GPIOA_LED 8
+#define GPIOD_OSC_IN 0
+#define GPIOD_OSC_OUT 1
+
+/* In case your board has a "USB enable" hardware
+ controlled by a pin, define it here. (It could be just
+ a 1.5k resistor connected to D+ line.)
+*/
+/*
+#define GPIOB_USB_DISC 10
+*/
+
+/*
+ * I/O ports initial setup, this configuration is established soon after reset
+ * in the initialization code.
+ *
+ * The digits have the following meaning:
+ * 0 - Analog input.
+ * 1 - Push Pull output 10MHz.
+ * 2 - Push Pull output 2MHz.
+ * 3 - Push Pull output 50MHz.
+ * 4 - Digital input.
+ * 5 - Open Drain output 10MHz.
+ * 6 - Open Drain output 2MHz.
+ * 7 - Open Drain output 50MHz.
+ * 8 - Digital input with PullUp or PullDown resistor depending on ODR.
+ * 9 - Alternate Push Pull output 10MHz.
+ * A - Alternate Push Pull output 2MHz.
+ * B - Alternate Push Pull output 50MHz.
+ * C - Reserved.
+ * D - Alternate Open Drain output 10MHz.
+ * E - Alternate Open Drain output 2MHz.
+ * F - Alternate Open Drain output 50MHz.
+ * Please refer to the STM32 Reference Manual for details.
+ */
+
+/*
+ * Port A setup.
+ * Everything input with pull-up except:
+ * PA2 - Alternate output (USART2 TX).
+ * PA3 - Normal input (USART2 RX).
+ * PA9 - Alternate output (USART1 TX).
+ * PA10 - Normal input (USART1 RX).
+ */
+#define VAL_GPIOACRL 0x88884B88 /* PA7...PA0 */
+#define VAL_GPIOACRH 0x888884B8 /* PA15...PA8 */
+#define VAL_GPIOAODR 0xFFFFFFFF
+
+/*
+ * Port B setup.
+ * Everything input with pull-up except:
+ * PB10 - Push Pull output (USB switch).
+ */
+#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
+#define VAL_GPIOBCRH 0x88888388 /* PB15...PB8 */
+#define VAL_GPIOBODR 0xFFFFFFFF
+
+/*
+ * Port C setup.
+ * Everything input with pull-up except:
+ * PC13 - Push Pull output (LED).
+ */
+#define VAL_GPIOCCRL 0x88888888 /* PC7...PC0 */
+#define VAL_GPIOCCRH 0x88388888 /* PC15...PC8 */
+#define VAL_GPIOCODR 0xFFFFFFFF
+
+/*
+ * Port D setup.
+ * Everything input with pull-up except:
+ * PD0 - Normal input (XTAL).
+ * PD1 - Normal input (XTAL).
+ */
+#define VAL_GPIODCRL 0x88888844 /* PD7...PD0 */
+#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
+#define VAL_GPIODODR 0xFFFFFFFF
+
+/*
+ * Port E setup.
+ * Everything input with pull-up except:
+ */
+#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */
+#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
+#define VAL_GPIOEODR 0xFFFFFFFF
+
+/*
+ * USB bus activation macro, required by the USB driver.
+ */
+/* The point is that most of the generic STM32F103* boards
+ have a 1.5k resistor connected on one end to the D+ line
+ and on the other end to some pin. Or even a slightly more
+ complicated "USB enable" circuit, controlled by a pin.
+ That should go here.
+
+ However on some boards (e.g. one that I have), there's no
+ such hardware. In which case it's better to not do anything.
+*/
+/*
+#define usb_lld_connect_bus(usbp) palClearPad(GPIOB, GPIOB_USB_DISC)
+*/
+#define usb_lld_connect_bus(usbp) palSetPadMode(GPIOA, 12, PAL_MODE_INPUT);
+
+/*
+ * USB bus de-activation macro, required by the USB driver.
+ */
+/*
+#define usb_lld_disconnect_bus(usbp) palSetPad(GPIOB, GPIOB_USB_DISC)
+*/
+#define usb_lld_disconnect_bus(usbp) \
+ palSetPadMode(GPIOA, 12, PAL_MODE_OUTPUT_PUSHPULL); \
+ palClearPad(GPIOA, 12);
+
+#if !defined(_FROM_ASM_)
+# ifdef __cplusplus
+extern "C" {
+# endif
+void boardInit(void);
+# ifdef __cplusplus
+}
+# endif
+#endif /* _FROM_ASM_ */
+
+#endif /* _BOARD_H_ */
diff --git a/platforms/chibios/boards/GD32F303C_EVAL/configs/config.h b/platforms/chibios/boards/GD32F303C_EVAL/configs/config.h
new file mode 100644
index 0000000000..ef22c6a1ee
--- /dev/null
+++ b/platforms/chibios/boards/GD32F303C_EVAL/configs/config.h
@@ -0,0 +1,9 @@
+// Copyright 2022 Nick Brassel (@tzarc)
+// SPDX-License-Identifier: GPL-2.0-or-later
+#pragma once
+
+// Value to place in RTC backup register 10 for persistent bootloader mode
+#define RTC_BOOTLOADER_FLAG 0x424C
+
+// Value to place in RTC backup register 10 for instant reboot mode
+#define RTC_BOOTLOADER_JUST_UPLOADED 0x424D \ No newline at end of file
diff --git a/platforms/chibios/boards/GD32F303C_EVAL/configs/mcuconf.h b/platforms/chibios/boards/GD32F303C_EVAL/configs/mcuconf.h
new file mode 100644
index 0000000000..c6e31e91af
--- /dev/null
+++ b/platforms/chibios/boards/GD32F303C_EVAL/configs/mcuconf.h
@@ -0,0 +1,211 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/* The GD32F303 is pretty much an STM32F103 in disguise. It requires a patch for i2c that needs to be available in CHIBIOS-CONTRIB */
+#ifndef _MCUCONF_H_
+#define _MCUCONF_H_
+
+#define MCU_STM32
+#define STM32F103_MCUCONF
+
+/*
+ * STM32F103 drivers configuration.
+ * The following settings override the default settings present in
+ * the various device driver implementation headers.
+ * Note that the settings for each driver only have effect if the whole
+ * driver is enabled in halconf.h.
+ *
+ * IRQ priorities:
+ * 15...0 Lowest...Highest.
+ *
+ * DMA priorities:
+ * 0...3 Lowest...Highest.
+ */
+
+/*
+ * HAL driver system settings.
+ */
+#define STM32_NO_INIT FALSE
+#define STM32_HSI_ENABLED TRUE
+#define STM32_LSI_ENABLED FALSE
+#define STM32_HSE_ENABLED TRUE
+#define STM32_LSE_ENABLED FALSE
+#define STM32_SW STM32_SW_PLL
+#define STM32_PLLSRC STM32_PLLSRC_HSE
+#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
+#define STM32_PLLMUL_VALUE 9
+#define STM32_HPRE STM32_HPRE_DIV1
+#define STM32_PPRE1 STM32_PPRE1_DIV2
+#define STM32_PPRE2 STM32_PPRE2_DIV2
+#define STM32_ADCPRE STM32_ADCPRE_DIV4
+#define STM32_USB_CLOCK_REQUIRED TRUE
+#define STM32_USBPRE STM32_USBPRE_DIV1P5
+#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
+#define STM32_RTCSEL STM32_RTCSEL_HSEDIV
+#define STM32_PVD_ENABLE FALSE
+#define STM32_PLS STM32_PLS_LEV0
+
+/*
+ * ADC driver system settings.
+ */
+#define STM32_ADC_USE_ADC1 FALSE
+#define STM32_ADC_ADC1_DMA_PRIORITY 2
+#define STM32_ADC_ADC1_IRQ_PRIORITY 6
+
+/*
+ * CAN driver system settings.
+ */
+#define STM32_CAN_USE_CAN1 FALSE
+#define STM32_CAN_CAN1_IRQ_PRIORITY 11
+
+/*
+ * EXT driver system settings.
+ */
+#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI17_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
+#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
+
+/*
+ * GPT driver system settings.
+ */
+#define STM32_GPT_USE_TIM1 FALSE
+#define STM32_GPT_USE_TIM2 FALSE
+#define STM32_GPT_USE_TIM3 FALSE
+#define STM32_GPT_USE_TIM4 FALSE
+#define STM32_GPT_USE_TIM5 FALSE
+#define STM32_GPT_USE_TIM8 FALSE
+#define STM32_GPT_TIM1_IRQ_PRIORITY 7
+#define STM32_GPT_TIM2_IRQ_PRIORITY 7
+#define STM32_GPT_TIM3_IRQ_PRIORITY 7
+#define STM32_GPT_TIM4_IRQ_PRIORITY 7
+#define STM32_GPT_TIM5_IRQ_PRIORITY 7
+#define STM32_GPT_TIM8_IRQ_PRIORITY 7
+
+/*
+ * I2C driver system settings.
+ */
+#define STM32_I2C_USE_I2C1 FALSE
+#define STM32_I2C_USE_I2C2 FALSE
+#define STM32_I2C_BUSY_TIMEOUT 50
+#define STM32_I2C_I2C1_IRQ_PRIORITY 5
+#define STM32_I2C_I2C2_IRQ_PRIORITY 5
+#define STM32_I2C_I2C1_DMA_PRIORITY 3
+#define STM32_I2C_I2C2_DMA_PRIORITY 3
+#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
+
+/*
+ * ICU driver system settings.
+ */
+#define STM32_ICU_USE_TIM1 FALSE
+#define STM32_ICU_USE_TIM2 FALSE
+#define STM32_ICU_USE_TIM3 FALSE
+#define STM32_ICU_USE_TIM4 FALSE
+#define STM32_ICU_USE_TIM5 FALSE
+#define STM32_ICU_USE_TIM8 FALSE
+#define STM32_ICU_TIM1_IRQ_PRIORITY 7
+#define STM32_ICU_TIM2_IRQ_PRIORITY 7
+#define STM32_ICU_TIM3_IRQ_PRIORITY 7
+#define STM32_ICU_TIM4_IRQ_PRIORITY 7
+#define STM32_ICU_TIM5_IRQ_PRIORITY 7
+#define STM32_ICU_TIM8_IRQ_PRIORITY 7
+
+/*
+ * PWM driver system settings.
+ */
+#define STM32_PWM_USE_ADVANCED FALSE
+#define STM32_PWM_USE_TIM1 FALSE
+#define STM32_PWM_USE_TIM2 FALSE
+#define STM32_PWM_USE_TIM3 FALSE
+#define STM32_PWM_USE_TIM4 FALSE
+#define STM32_PWM_USE_TIM5 FALSE
+#define STM32_PWM_USE_TIM8 FALSE
+#define STM32_PWM_TIM1_IRQ_PRIORITY 7
+#define STM32_PWM_TIM2_IRQ_PRIORITY 7
+#define STM32_PWM_TIM3_IRQ_PRIORITY 7
+#define STM32_PWM_TIM4_IRQ_PRIORITY 7
+#define STM32_PWM_TIM5_IRQ_PRIORITY 7
+#define STM32_PWM_TIM8_IRQ_PRIORITY 7
+
+/*
+ * RTC driver system settings.
+ */
+#define STM32_RTC_IRQ_PRIORITY 15
+
+/*
+ * SERIAL driver system settings.
+ */
+#define STM32_SERIAL_USE_USART1 FALSE
+#define STM32_SERIAL_USE_USART2 FALSE
+#define STM32_SERIAL_USE_USART3 FALSE
+#define STM32_SERIAL_USE_UART4 FALSE
+#define STM32_SERIAL_USE_UART5 FALSE
+#define STM32_SERIAL_USART1_PRIORITY 12
+#define STM32_SERIAL_USART2_PRIORITY 12
+#define STM32_SERIAL_USART3_PRIORITY 12
+#define STM32_SERIAL_UART4_PRIORITY 12
+#define STM32_SERIAL_UART5_PRIORITY 12
+
+/*
+ * SPI driver system settings.
+ */
+#define STM32_SPI_USE_SPI1 FALSE
+#define STM32_SPI_USE_SPI2 TRUE
+#define STM32_SPI_USE_SPI3 FALSE
+#define STM32_SPI_SPI1_DMA_PRIORITY 1
+#define STM32_SPI_SPI2_DMA_PRIORITY 1
+#define STM32_SPI_SPI3_DMA_PRIORITY 1
+#define STM32_SPI_SPI1_IRQ_PRIORITY 10
+#define STM32_SPI_SPI2_IRQ_PRIORITY 10
+#define STM32_SPI_SPI3_IRQ_PRIORITY 10
+#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
+
+/*
+ * ST driver system settings.
+ */
+#define STM32_ST_IRQ_PRIORITY 8
+#define STM32_ST_USE_TIMER 2
+
+/*
+ * UART driver system settings.
+ */
+#define STM32_UART_USE_USART1 FALSE
+#define STM32_UART_USE_USART2 FALSE
+#define STM32_UART_USE_USART3 FALSE
+#define STM32_UART_USART1_IRQ_PRIORITY 12
+#define STM32_UART_USART2_IRQ_PRIORITY 12
+#define STM32_UART_USART3_IRQ_PRIORITY 12
+#define STM32_UART_USART1_DMA_PRIORITY 0
+#define STM32_UART_USART2_DMA_PRIORITY 0
+#define STM32_UART_USART3_DMA_PRIORITY 0
+#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
+
+/*
+ * USB driver system settings.
+ */
+#define STM32_USB_USE_USB1 TRUE
+#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
+#define STM32_USB_USB1_HP_IRQ_PRIORITY 13
+#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
+
+#endif /* _MCUCONF_H_ */
diff --git a/platforms/chibios/bootloaders/ignition.c b/platforms/chibios/bootloaders/ignition.c
new file mode 100644
index 0000000000..00d55db2b8
--- /dev/null
+++ b/platforms/chibios/bootloaders/ignition.c
@@ -0,0 +1,54 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+#include <ch.h>
+#include <hal.h>
+#include "wait.h"
+#include "gpio.h"
+
+#define APP_ADDRESS 0x08002000
+
+__attribute__((weak)) void bootloader_jump(void) {
+ // The ignition bootloader is checking for a high signal on A8 for 100ms when powering on the board.
+ // Setting both A8 and A9 high will charge the capacitor quickly.
+ // Setting A9 low before reset will cause the capacitor to discharge
+ // thus making the bootloder unlikely to trigger twice between power cycles.
+ setPinOutputPushPull(A9);
+ setPinOutputPushPull(A8);
+ writePinHigh(A9);
+ writePinHigh(A8);
+ wait_ms(500);
+ writePinLow(A9);
+
+ NVIC_SystemReset();
+}
+
+__attribute__((weak)) void mcu_reset(void) {
+ // When resetting the MCU, we want to jump to the application.
+ SCB->AIRCR = APP_ADDRESS & 0xFFFF;
+
+ // Set the stack pointer to the applications stack pointer
+ __asm__ volatile("msr msp, %0" ::"g"(*(volatile uint32_t *)APP_ADDRESS));
+
+ // Jump to the application
+ (*(void (**)())(APP_ADDRESS + 4))();
+ while (1)
+ ;
+}
+
+__attribute__((weak)) void enter_bootloader_mode_if_requested(void) {} \ No newline at end of file
diff --git a/quantum/action_layer.c b/quantum/action_layer.c
index 5cc1ac9b34..edb5d777ce 100644
--- a/quantum/action_layer.c
+++ b/quantum/action_layer.c
@@ -59,7 +59,7 @@ static void default_layer_state_set(layer_state_t state) {
* Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit.
*/
void default_layer_debug(void) {
- dprintf("%08lX(%u)", default_layer_state, get_highest_layer(default_layer_state));
+ // dprintf("%08lX(%u)", default_layer_state, get_highest_layer(default_layer_state));
}
/** \brief Default Layer Set
@@ -121,9 +121,9 @@ __attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) {
*/
void layer_state_set(layer_state_t state) {
state = layer_state_set_kb(state);
-#ifdef ORYX_ENABLE
+# ifdef ORYX_ENABLE
layer_state_set_oryx(state);
-#endif
+# endif
dprint("layer_state: ");
layer_debug();
dprint(" to ");
@@ -223,7 +223,7 @@ void layer_xor(layer_state_t state) {
* Print out the hex value of the 32-bit layer state, as well as the value of the highest bit.
*/
void layer_debug(void) {
- dprintf("%08lX(%u)", layer_state, get_highest_layer(layer_state));
+ // dprintf("%08lX(%u)", layer_state, get_highest_layer(layer_state));
}
#endif
diff --git a/quantum/oryx.c b/quantum/oryx.c
index f3172c3e07..ebcf36ab21 100644
--- a/quantum/oryx.c
+++ b/quantum/oryx.c
@@ -1,6 +1,9 @@
#include <string.h>
#include "oryx.h"
#include "eeprom.h"
+#ifdef KEYBOARD_voyager
+# include "voyager.h"
+#endif
rawhid_state_t rawhid_state = {.pairing = false, .paired = false};
@@ -67,6 +70,10 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
rgb_matrix_mode_noeeprom(RGB_MATRIX_CUSTOM_oryx_webhid_effect);
rawhid_state.rgb_control = true;
}
+ uint8_t event[RAW_EPSIZE];
+ event[0] = ORYX_EVT_RGB_CONTROL;
+ event[1] = rawhid_state.rgb_control;
+ raw_hid_send(event, RAW_EPSIZE);
#else
oryx_error(ORYX_ERR_RGB_MATRIX_NOT_ENABLED);
#endif
@@ -79,6 +86,69 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
oryx_error(ORYX_ERR_RGB_MATRIX_NOT_ENABLED);
#endif
break;
+ case ORYX_SET_STATUS_LED:
+ switch (param[0]) {
+ case 0:
+#ifdef STATUS_LED_1
+ STATUS_LED_1(param[1]);
+#else
+ oryx_error(ORYX_ERR_STATUS_LED_OUT_OF_RANGE);
+#endif
+ break;
+ case 1:
+#ifdef STATUS_LED_2
+ STATUS_LED_2(param[1]);
+#else
+ oryx_error(ORYX_ERR_STATUS_LED_OUT_OF_RANGE);
+#endif
+ break;
+ case 2:
+#ifdef STATUS_LED_3
+ STATUS_LED_3(param[1]);
+#else
+ oryx_error(ORYX_ERR_STATUS_LED_OUT_OF_RANGE);
+#endif
+ break;
+ case 3:
+#ifdef STATUS_LED_4
+ STATUS_LED_4(param[1]);
+#else
+ oryx_error(ORYX_ERR_STATUS_LED_OUT_OF_RANGE);
+#endif
+ break;
+ case 4:
+#ifdef STATUS_LED_5
+ STATUS_LED_5(param[1]);
+#else
+ oryx_error(ORYX_ERR_STATUS_LED_OUT_OF_RANGE);
+#endif
+ break;
+ case 5:
+#ifdef STATUS_LED_6
+ STATUS_LED_6(param[1]);
+#else
+ oryx_error(ORYX_ERR_STATUS_LED_OUT_OF_RANGE);
+#endif
+ break;
+
+ default:
+ oryx_error(ORYX_ERR_STATUS_LED_OUT_OF_RANGE);
+ break;
+ }
+ break;
+ case ORYX_UPDATE_BRIGHTNESS:
+#if defined(RGB_MATRIX_ENABLE) && !defined(KEYBOARD_ergodox_ez_glow)
+ if (param[0]) {
+ rgb_matrix_increase_val_noeeprom();
+ } else {
+ rgb_matrix_decrease_val_noeeprom();
+ }
+#else
+ oryx_error(ORYX_ERR_RGB_MATRIX_NOT_ENABLED);
+#endif
+ break;
+ default:
+ oryx_error(ORYX_ERR_UNKNOWN_COMMAND);
}
}
diff --git a/quantum/oryx.h b/quantum/oryx.h
index 25deb74f55..063353468e 100644
--- a/quantum/oryx.h
+++ b/quantum/oryx.h
@@ -37,6 +37,8 @@ enum Oryx_Command_Code {
ORYX_SET_LAYER,
ORYX_RGB_CONTROL,
ORYX_SET_RGB_LED,
+ ORYX_SET_STATUS_LED,
+ ORYX_UPDATE_BRIGHTNESS,
ORYX_GET_PROTOCOL_VERSION = 0xFE,
};
@@ -49,6 +51,7 @@ enum Oryx_Event_Code {
ORYX_EVT_LAYER,
ORYX_EVT_KEYDOWN,
ORYX_EVT_KEYUP,
+ ORYX_EVT_RGB_CONTROL,
ORYX_EVT_GET_PROTOCOL_VERSION = 0XFE,
ORYX_EVT_ERROR = 0xFF,
};
@@ -59,6 +62,8 @@ enum Oryx_Error_Code {
ORYX_ERR_PAIRING_KEY_INPUT_FAILED,
ORYX_ERR_PAIRING_FAILED,
ORYX_ERR_RGB_MATRIX_NOT_ENABLED,
+ ORYX_ERR_STATUS_LED_OUT_OF_RANGE,
+ ORYX_ERR_UNKNOWN_COMMAND = 0xFF,
};
extern bool oryx_state_live_training_enabled;