From 30680c6eb396a2bb06928afd69edae9908ac84fb Mon Sep 17 00:00:00 2001
From: patrickmt <40182064+patrickmt@users.noreply.github.com>
Date: Wed, 29 Aug 2018 15:07:52 -0400
Subject: Massdrop keyboard support (#3780)
* Massdrop SAMD51
Massdrop SAMD51 keyboards initial project upload
* Removing relocated files
Removing files that were relocated and not deleted from previous location
* LED queue fix and cleaning
Cleaned some white space or comments.
Fix for LED I2C command queue.
Cleaned up interrupts.
Added debug function for printing numbers to scope through m15 line.
* Factory programmed serial usage
Ability to use factory programmed serial in hub and keyboard usb descriptors
* USB serial number and bugfix
Added support for factory programmed serial and usage.
Incorporated bootloader's conditional compiling to align project closer.
Fixed issue when USB device attempted to send before enabled.
General white space and comment cleanup.
* Project cleanup
Cleaned up project in terms of white space, commented code, and unecessary files.
NKRO keyboard is now using correct setreport although KBD was fine to use.
Fixed broken linkage to __xprintf for serial debug statements.
* Fix for extra keys
Fixed possible USB hang on extra keys report set missing
* I2C cleanup
I2C cleanup and file renames necessary for master branch merge
* Boot tracing and clocks cleanup
Added optional boot debug trace mode through debug LED codes.
General clock code cleanup.
* Relocate ARM/Atmel headers
Moved ARM/Atmel header folder from drivers to lib and made necessary makefile changes.
* Pull request changes
Pull request changes
* Keymap and compile flag fix
Keymap fix for momentary layer.
Potential compile flag fix for Travis CI failure.
* va_list include fix
Fix for va_list compile failure
* Include file case fixes
Fixes for include files with incorrect case
* ctrl and alt67 keyboard readme
Added ctrl and alt67 keyboard readme files
---
tmk_core/common/arm_atsam/bootloader.c | 19 +++++++
tmk_core/common/arm_atsam/eeprom.c | 98 ++++++++++++++++++++++++++++++++++
tmk_core/common/arm_atsam/printf.h | 8 +++
tmk_core/common/arm_atsam/suspend.c | 17 ++++++
tmk_core/common/arm_atsam/timer.c | 59 ++++++++++++++++++++
tmk_core/common/print.h | 30 ++++++++++-
tmk_core/common/report.h | 5 ++
7 files changed, 235 insertions(+), 1 deletion(-)
create mode 100644 tmk_core/common/arm_atsam/bootloader.c
create mode 100644 tmk_core/common/arm_atsam/eeprom.c
create mode 100644 tmk_core/common/arm_atsam/printf.h
create mode 100644 tmk_core/common/arm_atsam/suspend.c
create mode 100644 tmk_core/common/arm_atsam/timer.c
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/arm_atsam/bootloader.c b/tmk_core/common/arm_atsam/bootloader.c
new file mode 100644
index 000000000..5155d9ff0
--- /dev/null
+++ b/tmk_core/common/arm_atsam/bootloader.c
@@ -0,0 +1,19 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 .
+ */
+
+#include "bootloader.h"
+
+void bootloader_jump(void) {}
diff --git a/tmk_core/common/arm_atsam/eeprom.c b/tmk_core/common/arm_atsam/eeprom.c
new file mode 100644
index 000000000..61cc039ef
--- /dev/null
+++ b/tmk_core/common/arm_atsam/eeprom.c
@@ -0,0 +1,98 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 .
+ */
+
+#include "eeprom.h"
+
+#define EEPROM_SIZE 32
+
+static uint8_t buffer[EEPROM_SIZE];
+
+uint8_t eeprom_read_byte(const uint8_t *addr) {
+ uintptr_t offset = (uintptr_t)addr;
+ return buffer[offset];
+}
+
+void eeprom_write_byte(uint8_t *addr, uint8_t value) {
+ uintptr_t offset = (uintptr_t)addr;
+ buffer[offset] = value;
+}
+
+uint16_t eeprom_read_word(const uint16_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
+}
+
+uint32_t eeprom_read_dword(const uint32_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
+ | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
+}
+
+void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
+ const uint8_t *p = (const uint8_t *)addr;
+ uint8_t *dest = (uint8_t *)buf;
+ while (len--) {
+ *dest++ = eeprom_read_byte(p++);
+ }
+}
+
+void eeprom_write_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_write_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
+
+void eeprom_update_byte(uint8_t *addr, uint8_t value) {
+ eeprom_write_byte(addr, value);
+}
+
+void eeprom_update_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_update_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
diff --git a/tmk_core/common/arm_atsam/printf.h b/tmk_core/common/arm_atsam/printf.h
new file mode 100644
index 000000000..582c83bf5
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.h
@@ -0,0 +1,8 @@
+#ifndef _PRINTF_H_
+#define _PRINTF_H_
+
+#define __xprintf dpf
+int dpf(const char *_Format, ...);
+
+#endif //_PRINTF_H_
+
diff --git a/tmk_core/common/arm_atsam/suspend.c b/tmk_core/common/arm_atsam/suspend.c
new file mode 100644
index 000000000..01d1930ea
--- /dev/null
+++ b/tmk_core/common/arm_atsam/suspend.c
@@ -0,0 +1,17 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 .
+ */
+
+
diff --git a/tmk_core/common/arm_atsam/timer.c b/tmk_core/common/arm_atsam/timer.c
new file mode 100644
index 000000000..bcfe5002c
--- /dev/null
+++ b/tmk_core/common/arm_atsam/timer.c
@@ -0,0 +1,59 @@
+#include "samd51j18a.h"
+#include "timer.h"
+#include "tmk_core/protocol/arm_atsam/clks.h"
+
+void set_time(uint64_t tset)
+{
+ ms_clk = tset;
+}
+
+void timer_init(void)
+{
+ ms_clk = 0;
+}
+
+uint16_t timer_read(void)
+{
+ return (uint16_t)ms_clk;
+}
+
+uint32_t timer_read32(void)
+{
+ return (uint32_t)ms_clk;
+}
+
+uint64_t timer_read64(void)
+{
+ return ms_clk;
+}
+
+uint16_t timer_elapsed(uint16_t tlast)
+{
+ return TIMER_DIFF_16(timer_read(), tlast);
+}
+
+uint32_t timer_elapsed32(uint32_t tlast)
+{
+ return TIMER_DIFF_32(timer_read32(), tlast);
+}
+
+uint32_t timer_elapsed64(uint32_t tlast)
+{
+ uint64_t tnow = timer_read64();
+ return (tnow >= tlast ? tnow - tlast : UINT64_MAX - tlast + tnow);
+}
+
+void timer_clear(void)
+{
+ ms_clk = 0;
+}
+
+void wait_ms(uint64_t msec)
+{
+ CLK_delay_ms(msec);
+}
+
+void wait_us(uint16_t usec)
+{
+ CLK_delay_us(usec);
+}
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index 8836c0fc7..9cbe67bad 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -99,6 +99,34 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
# endif /* USER_PRINT / NORMAL PRINT */
+#elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */
+
+# include "arm_atsam/printf.h"
+
+# ifdef USER_PRINT /* USER_PRINT */
+
+// Remove normal print defines
+# define print(s)
+# define println(s)
+# define xprintf(fmt, ...)
+
+// Create user print defines
+# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
+# define uprint(s) xprintf(s)
+# define uprintln(s) xprintf(s "\r\n")
+
+# else /* NORMAL PRINT */
+
+// Create user & normal print defines
+# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
+# define print(s) xprintf(s)
+# define println(s) xprintf(s "\r\n")
+# define uprint(s) print(s)
+# define uprintln(s) println(s)
+# define uprintf(fmt, ...) xprintf(fmt, ...)
+
+# endif /* USER_PRINT / NORMAL PRINT */
+
#elif defined(__arm__) /* __arm__ */
# include "mbed/xprintf.h"
@@ -130,7 +158,7 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
/* TODO: to select output destinations: UART/USBSerial */
# define print_set_sendchar(func)
-#endif /* __AVR__ / PROTOCOL_CHIBIOS / __arm__ */
+#endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM / __arm__ */
// User print disables the normal print messages in the body of QMK/TMK code and
// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 6c27eb9dc..167f38275 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -84,6 +84,11 @@ along with this program. If not, see .
#define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
#define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
#define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
+ #elif defined(PROTOCOL_ARM_ATSAM)
+ #include "protocol/arm_atsam/usb/udi_device_epsize.h"
+ #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
+ #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
+ #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
#else
#error "NKRO not supported with this protocol"
#endif
--
cgit v1.2.3-70-g09d2
From 621ce29a53e9e94e085fbd86c0b7134e9df4bfe5 Mon Sep 17 00:00:00 2001
From: yiancar
Date: Wed, 29 Aug 2018 23:14:49 +0300
Subject: STM32 EEPROM Emulation (#3741)
* STM32 EEPROM Emulation
- Added EEPROM emulation libaries from libmaple and Arduino_STM32. https://github.com/rogerclarkmelbourne/Arduino_STM32 and https://github.com/leaflabs/libmaple.
- Renamed teensy EEPROM library and added conditional selection of library.
- Remapped EEPROM memory map for 16 byte blocks (as is with STM32f3xx MCUs).
- Added EEPROM initialization in main.c of Chibios.
- Added EEPROM format to clear the emulated pages when EEPROM is marked as invalid.
* Fixed ifdef
---
tmk_core/common.mk | 7 +-
tmk_core/common/chibios/eeprom.c | 632 ------------------------------
tmk_core/common/chibios/eeprom_stm32.c | 673 ++++++++++++++++++++++++++++++++
tmk_core/common/chibios/eeprom_stm32.h | 89 +++++
tmk_core/common/chibios/eeprom_teensy.c | 632 ++++++++++++++++++++++++++++++
tmk_core/common/chibios/flash_stm32.c | 180 +++++++++
tmk_core/common/chibios/flash_stm32.h | 53 +++
tmk_core/common/eeconfig.c | 11 +
tmk_core/common/eeconfig.h | 16 +
tmk_core/protocol/chibios/main.c | 7 +
10 files changed, 1667 insertions(+), 633 deletions(-)
delete mode 100644 tmk_core/common/chibios/eeprom.c
create mode 100755 tmk_core/common/chibios/eeprom_stm32.c
create mode 100755 tmk_core/common/chibios/eeprom_stm32.h
create mode 100644 tmk_core/common/chibios/eeprom_teensy.c
create mode 100755 tmk_core/common/chibios/flash_stm32.c
create mode 100755 tmk_core/common/chibios/flash_stm32.h
(limited to 'tmk_core/common')
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index fd91d29dc..319d196ae 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -31,7 +31,12 @@ endif
ifeq ($(PLATFORM),CHIBIOS)
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
- TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
+ ifeq ($(MCU_SERIES), STM32F3xx)
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
+ else
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
+endif
ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
TMK_COMMON_SRC += $(CHIBIOS)/os/various/syscalls.c
endif
diff --git a/tmk_core/common/chibios/eeprom.c b/tmk_core/common/chibios/eeprom.c
deleted file mode 100644
index 9061b790c..000000000
--- a/tmk_core/common/chibios/eeprom.c
+++ /dev/null
@@ -1,632 +0,0 @@
-#include "ch.h"
-#include "hal.h"
-
-#include "eeconfig.h"
-
-/*************************************/
-/* Hardware backend */
-/* */
-/* Code from PJRC/Teensyduino */
-/*************************************/
-
-/* Teensyduino Core Library
- * http://www.pjrc.com/teensy/
- * Copyright (c) 2013 PJRC.COM, LLC.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * 1. The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * 2. If the Software is incorporated into a build system that allows
- * selection among a list of target devices, then similar target
- * devices manufactured by PJRC.COM must be included in the list of
- * target devices and selectable in the same manner.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-
-#if defined(K20x) /* chip selection */
-/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */
-
-// The EEPROM is really RAM with a hardware-based backup system to
-// flash memory. Selecting a smaller size EEPROM allows more wear
-// leveling, for higher write endurance. If you edit this file,
-// set this to the smallest size your application can use. Also,
-// due to Freescale's implementation, writing 16 or 32 bit words
-// (aligned to 2 or 4 byte boundaries) has twice the endurance
-// compared to writing 8 bit bytes.
-//
-#define EEPROM_SIZE 32
-
-// Writing unaligned 16 or 32 bit data is handled automatically when
-// this is defined, but at a cost of extra code size. Without this,
-// any unaligned write will cause a hard fault exception! If you're
-// absolutely sure all 16 and 32 bit writes will be aligned, you can
-// remove the extra unnecessary code.
-//
-#define HANDLE_UNALIGNED_WRITES
-
-// Minimum EEPROM Endurance
-// ------------------------
-#if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
- #define EEESIZE 0x33
-#elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
- #define EEESIZE 0x34
-#elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
- #define EEESIZE 0x35
-#elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
- #define EEESIZE 0x36
-#elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
- #define EEESIZE 0x37
-#elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
- #define EEESIZE 0x38
-#elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
- #define EEESIZE 0x39
-#endif
-
-/** \brief eeprom initialization
- *
- * FIXME: needs doc
- */
-void eeprom_initialize(void)
-{
- uint32_t count=0;
- uint16_t do_flash_cmd[] = {
- 0xf06f, 0x037f, 0x7003, 0x7803,
- 0xf013, 0x0f80, 0xd0fb, 0x4770};
- uint8_t status;
-
- if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) {
- // FlexRAM is configured as traditional RAM
- // We need to reconfigure for EEPROM usage
- FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command
- FTFL->FCCOB4 = EEESIZE; // EEPROM Size
- FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup
- __disable_irq();
- // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
- (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT));
- __enable_irq();
- status = FTFL->FSTAT;
- if (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)) {
- FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL));
- return; // error
- }
- }
- // wait for eeprom to become ready (is this really necessary?)
- while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
- if (++count > 20000) break;
- }
-}
-
-#define FlexRAM ((uint8_t *)0x14000000)
-
-/** \brief eeprom read byte
- *
- * FIXME: needs doc
- */
-uint8_t eeprom_read_byte(const uint8_t *addr)
-{
- uint32_t offset = (uint32_t)addr;
- if (offset >= EEPROM_SIZE) return 0;
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- return FlexRAM[offset];
-}
-
-/** \brief eeprom read word
- *
- * FIXME: needs doc
- */
-uint16_t eeprom_read_word(const uint16_t *addr)
-{
- uint32_t offset = (uint32_t)addr;
- if (offset >= EEPROM_SIZE-1) return 0;
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- return *(uint16_t *)(&FlexRAM[offset]);
-}
-
-/** \brief eeprom read dword
- *
- * FIXME: needs doc
- */
-uint32_t eeprom_read_dword(const uint32_t *addr)
-{
- uint32_t offset = (uint32_t)addr;
- if (offset >= EEPROM_SIZE-3) return 0;
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- return *(uint32_t *)(&FlexRAM[offset]);
-}
-
-/** \brief eeprom read block
- *
- * FIXME: needs doc
- */
-void eeprom_read_block(void *buf, const void *addr, uint32_t len)
-{
- uint32_t offset = (uint32_t)addr;
- uint8_t *dest = (uint8_t *)buf;
- uint32_t end = offset + len;
-
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- if (end > EEPROM_SIZE) end = EEPROM_SIZE;
- while (offset < end) {
- *dest++ = FlexRAM[offset++];
- }
-}
-
-/** \brief eeprom is ready
- *
- * FIXME: needs doc
- */
-int eeprom_is_ready(void)
-{
- return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0;
-}
-
-/** \brief flexram wait
- *
- * FIXME: needs doc
- */
-static void flexram_wait(void)
-{
- while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
- // TODO: timeout
- }
-}
-
-/** \brief eeprom_write_byte
- *
- * FIXME: needs doc
- */
-void eeprom_write_byte(uint8_t *addr, uint8_t value)
-{
- uint32_t offset = (uint32_t)addr;
-
- if (offset >= EEPROM_SIZE) return;
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- if (FlexRAM[offset] != value) {
- FlexRAM[offset] = value;
- flexram_wait();
- }
-}
-
-/** \brief eeprom write word
- *
- * FIXME: needs doc
- */
-void eeprom_write_word(uint16_t *addr, uint16_t value)
-{
- uint32_t offset = (uint32_t)addr;
-
- if (offset >= EEPROM_SIZE-1) return;
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
-#ifdef HANDLE_UNALIGNED_WRITES
- if ((offset & 1) == 0) {
-#endif
- if (*(uint16_t *)(&FlexRAM[offset]) != value) {
- *(uint16_t *)(&FlexRAM[offset]) = value;
- flexram_wait();
- }
-#ifdef HANDLE_UNALIGNED_WRITES
- } else {
- if (FlexRAM[offset] != value) {
- FlexRAM[offset] = value;
- flexram_wait();
- }
- if (FlexRAM[offset + 1] != (value >> 8)) {
- FlexRAM[offset + 1] = value >> 8;
- flexram_wait();
- }
- }
-#endif
-}
-
-/** \brief eeprom write dword
- *
- * FIXME: needs doc
- */
-void eeprom_write_dword(uint32_t *addr, uint32_t value)
-{
- uint32_t offset = (uint32_t)addr;
-
- if (offset >= EEPROM_SIZE-3) return;
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
-#ifdef HANDLE_UNALIGNED_WRITES
- switch (offset & 3) {
- case 0:
-#endif
- if (*(uint32_t *)(&FlexRAM[offset]) != value) {
- *(uint32_t *)(&FlexRAM[offset]) = value;
- flexram_wait();
- }
- return;
-#ifdef HANDLE_UNALIGNED_WRITES
- case 2:
- if (*(uint16_t *)(&FlexRAM[offset]) != value) {
- *(uint16_t *)(&FlexRAM[offset]) = value;
- flexram_wait();
- }
- if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
- *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
- flexram_wait();
- }
- return;
- default:
- if (FlexRAM[offset] != value) {
- FlexRAM[offset] = value;
- flexram_wait();
- }
- if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
- *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
- flexram_wait();
- }
- if (FlexRAM[offset + 3] != (value >> 24)) {
- FlexRAM[offset + 3] = value >> 24;
- flexram_wait();
- }
- }
-#endif
-}
-
-/** \brief eeprom write block
- *
- * FIXME: needs doc
- */
-void eeprom_write_block(const void *buf, void *addr, uint32_t len)
-{
- uint32_t offset = (uint32_t)addr;
- const uint8_t *src = (const uint8_t *)buf;
-
- if (offset >= EEPROM_SIZE) return;
- if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
- if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
- if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
- while (len > 0) {
- uint32_t lsb = offset & 3;
- if (lsb == 0 && len >= 4) {
- // write aligned 32 bits
- uint32_t val32;
- val32 = *src++;
- val32 |= (*src++ << 8);
- val32 |= (*src++ << 16);
- val32 |= (*src++ << 24);
- if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
- *(uint32_t *)(&FlexRAM[offset]) = val32;
- flexram_wait();
- }
- offset += 4;
- len -= 4;
- } else if ((lsb == 0 || lsb == 2) && len >= 2) {
- // write aligned 16 bits
- uint16_t val16;
- val16 = *src++;
- val16 |= (*src++ << 8);
- if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
- *(uint16_t *)(&FlexRAM[offset]) = val16;
- flexram_wait();
- }
- offset += 2;
- len -= 2;
- } else {
- // write 8 bits
- uint8_t val8 = *src++;
- if (FlexRAM[offset] != val8) {
- FlexRAM[offset] = val8;
- flexram_wait();
- }
- offset++;
- len--;
- }
- }
-}
-
-/*
-void do_flash_cmd(volatile uint8_t *fstat)
-{
- *fstat = 0x80;
- while ((*fstat & 0x80) == 0) ; // wait
-}
-00000000 :
- 0: f06f 037f mvn.w r3, #127 ; 0x7f
- 4: 7003 strb r3, [r0, #0]
- 6: 7803 ldrb r3, [r0, #0]
- 8: f013 0f80 tst.w r3, #128 ; 0x80
- c: d0fb beq.n 6
- e: 4770 bx lr
-*/
-
-#elif defined(KL2x) /* chip selection */
-/* Teensy LC (emulated) */
-
-#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
-
-extern uint32_t __eeprom_workarea_start__;
-extern uint32_t __eeprom_workarea_end__;
-
-#define EEPROM_SIZE 128
-
-static uint32_t flashend = 0;
-
-void eeprom_initialize(void)
-{
- const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
-
- do {
- if (*p++ == 0xFFFF) {
- flashend = (uint32_t)(p - 2);
- return;
- }
- } while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__));
- flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1);
-}
-
-uint8_t eeprom_read_byte(const uint8_t *addr)
-{
- uint32_t offset = (uint32_t)addr;
- const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
- const uint16_t *end = (const uint16_t *)((uint32_t)flashend);
- uint16_t val;
- uint8_t data=0xFF;
-
- if (!end) {
- eeprom_initialize();
- end = (const uint16_t *)((uint32_t)flashend);
- }
- if (offset < EEPROM_SIZE) {
- while (p <= end) {
- val = *p++;
- if ((val & 255) == offset) data = val >> 8;
- }
- }
- return data;
-}
-
-static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data)
-{
- // with great power comes great responsibility....
- uint32_t stat;
- *(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC);
- *(uint32_t *)&(FTFA->FCCOB7) = data;
- __disable_irq();
- (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT));
- __enable_irq();
- stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);
- if (stat) {
- FTFA->FSTAT = stat;
- }
- MCM->PLACR |= MCM_PLACR_CFCC;
-}
-
-void eeprom_write_byte(uint8_t *addr, uint8_t data)
-{
- uint32_t offset = (uint32_t)addr;
- const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend);
- uint32_t i, val, flashaddr;
- uint16_t do_flash_cmd[] = {
- 0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770};
- uint8_t buf[EEPROM_SIZE];
-
- if (offset >= EEPROM_SIZE) return;
- if (!end) {
- eeprom_initialize();
- end = (const uint16_t *)((uint32_t)flashend);
- }
- if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) {
- val = (data << 8) | offset;
- flashaddr = (uint32_t)end;
- flashend = flashaddr;
- if ((flashaddr & 2) == 0) {
- val |= 0xFFFF0000;
- } else {
- val <<= 16;
- val |= 0x0000FFFF;
- }
- flash_write(do_flash_cmd, flashaddr, val);
- } else {
- for (i=0; i < EEPROM_SIZE; i++) {
- buf[i] = 0xFF;
- }
- val = 0;
- for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) {
- val = *p;
- if ((val & 255) < EEPROM_SIZE) {
- buf[val & 255] = val >> 8;
- }
- }
- buf[offset] = data;
- for (flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) {
- *(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr;
- __disable_irq();
- (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT));
- __enable_irq();
- val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);;
- if (val) FTFA->FSTAT = val;
- MCM->PLACR |= MCM_PLACR_CFCC;
- }
- flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__);
- for (i=0; i < EEPROM_SIZE; i++) {
- if (buf[i] == 0xFF) continue;
- if ((flashaddr & 2) == 0) {
- val = (buf[i] << 8) | i;
- } else {
- val = val | (buf[i] << 24) | (i << 16);
- flash_write(do_flash_cmd, flashaddr, val);
- }
- flashaddr += 2;
- }
- flashend = flashaddr;
- if ((flashaddr & 2)) {
- val |= 0xFFFF0000;
- flash_write(do_flash_cmd, flashaddr, val);
- }
- }
-}
-
-/*
-void do_flash_cmd(volatile uint8_t *fstat)
-{
- *fstat = 0x80;
- while ((*fstat & 0x80) == 0) ; // wait
-}
-00000000 :
- 0: 2380 movs r3, #128 ; 0x80
- 2: 7003 strb r3, [r0, #0]
- 4: 7803 ldrb r3, [r0, #0]
- 6: b25b sxtb r3, r3
- 8: 2b00 cmp r3, #0
- a: dafb bge.n 4
- c: 4770 bx lr
-*/
-
-
-uint16_t eeprom_read_word(const uint16_t *addr)
-{
- const uint8_t *p = (const uint8_t *)addr;
- return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
-}
-
-uint32_t eeprom_read_dword(const uint32_t *addr)
-{
- const uint8_t *p = (const uint8_t *)addr;
- return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
- | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
-}
-
-void eeprom_read_block(void *buf, const void *addr, uint32_t len)
-{
- const uint8_t *p = (const uint8_t *)addr;
- uint8_t *dest = (uint8_t *)buf;
- while (len--) {
- *dest++ = eeprom_read_byte(p++);
- }
-}
-
-int eeprom_is_ready(void)
-{
- return 1;
-}
-
-void eeprom_write_word(uint16_t *addr, uint16_t value)
-{
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p, value >> 8);
-}
-
-void eeprom_write_dword(uint32_t *addr, uint32_t value)
-{
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p++, value >> 8);
- eeprom_write_byte(p++, value >> 16);
- eeprom_write_byte(p, value >> 24);
-}
-
-void eeprom_write_block(const void *buf, void *addr, uint32_t len)
-{
- uint8_t *p = (uint8_t *)addr;
- const uint8_t *src = (const uint8_t *)buf;
- while (len--) {
- eeprom_write_byte(p++, *src++);
- }
-}
-
-#else
-// No EEPROM supported, so emulate it
-
-#define EEPROM_SIZE 32
-static uint8_t buffer[EEPROM_SIZE];
-
-uint8_t eeprom_read_byte(const uint8_t *addr) {
- uint32_t offset = (uint32_t)addr;
- return buffer[offset];
-}
-
-void eeprom_write_byte(uint8_t *addr, uint8_t value) {
- uint32_t offset = (uint32_t)addr;
- buffer[offset] = value;
-}
-
-uint16_t eeprom_read_word(const uint16_t *addr) {
- const uint8_t *p = (const uint8_t *)addr;
- return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
-}
-
-uint32_t eeprom_read_dword(const uint32_t *addr) {
- const uint8_t *p = (const uint8_t *)addr;
- return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
- | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
-}
-
-void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
- const uint8_t *p = (const uint8_t *)addr;
- uint8_t *dest = (uint8_t *)buf;
- while (len--) {
- *dest++ = eeprom_read_byte(p++);
- }
-}
-
-void eeprom_write_word(uint16_t *addr, uint16_t value) {
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p, value >> 8);
-}
-
-void eeprom_write_dword(uint32_t *addr, uint32_t value) {
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p++, value >> 8);
- eeprom_write_byte(p++, value >> 16);
- eeprom_write_byte(p, value >> 24);
-}
-
-void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
- uint8_t *p = (uint8_t *)addr;
- const uint8_t *src = (const uint8_t *)buf;
- while (len--) {
- eeprom_write_byte(p++, *src++);
- }
-}
-
-#endif /* chip selection */
-// The update functions just calls write for now, but could probably be optimized
-
-void eeprom_update_byte(uint8_t *addr, uint8_t value) {
- eeprom_write_byte(addr, value);
-}
-
-void eeprom_update_word(uint16_t *addr, uint16_t value) {
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p, value >> 8);
-}
-
-void eeprom_update_dword(uint32_t *addr, uint32_t value) {
- uint8_t *p = (uint8_t *)addr;
- eeprom_write_byte(p++, value);
- eeprom_write_byte(p++, value >> 8);
- eeprom_write_byte(p++, value >> 16);
- eeprom_write_byte(p, value >> 24);
-}
-
-void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
- uint8_t *p = (uint8_t *)addr;
- const uint8_t *src = (const uint8_t *)buf;
- while (len--) {
- eeprom_write_byte(p++, *src++);
- }
-}
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
new file mode 100755
index 000000000..3c1945122
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -0,0 +1,673 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * https://github.com/leaflabs/libmaple
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ */
+
+#include "eeprom_stm32.h"
+
+ FLASH_Status EE_ErasePage(uint32_t);
+
+ uint16_t EE_CheckPage(uint32_t, uint16_t);
+ uint16_t EE_CheckErasePage(uint32_t, uint16_t);
+ uint16_t EE_Format(void);
+ uint32_t EE_FindValidPage(void);
+ uint16_t EE_GetVariablesCount(uint32_t, uint16_t);
+ uint16_t EE_PageTransfer(uint32_t, uint32_t, uint16_t);
+ uint16_t EE_VerifyPageFullWriteVariable(uint16_t, uint16_t);
+
+ uint32_t PageBase0 = EEPROM_PAGE0_BASE;
+ uint32_t PageBase1 = EEPROM_PAGE1_BASE;
+ uint32_t PageSize = EEPROM_PAGE_SIZE;
+ uint16_t Status = EEPROM_NOT_INIT;
+
+// See http://www.st.com/web/en/resource/technical/document/application_note/CD00165693.pdf
+
+/**
+ * @brief Check page for blank
+ * @param page base address
+ * @retval Success or error
+ * EEPROM_BAD_FLASH: page not empty after erase
+ * EEPROM_OK: page blank
+ */
+uint16_t EE_CheckPage(uint32_t pageBase, uint16_t status)
+{
+ uint32_t pageEnd = pageBase + (uint32_t)PageSize;
+
+ // Page Status not EEPROM_ERASED and not a "state"
+ if ((*(__IO uint16_t*)pageBase) != EEPROM_ERASED && (*(__IO uint16_t*)pageBase) != status)
+ return EEPROM_BAD_FLASH;
+ for(pageBase += 4; pageBase < pageEnd; pageBase += 4)
+ if ((*(__IO uint32_t*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty
+ return EEPROM_BAD_FLASH;
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Erase page with increment erase counter (page + 2)
+ * @param page base address
+ * @retval Success or error
+ * FLASH_COMPLETE: success erase
+ * - Flash error code: on write Flash error
+ */
+FLASH_Status EE_ErasePage(uint32_t pageBase)
+{
+ FLASH_Status FlashStatus;
+ uint16_t data = (*(__IO uint16_t*)(pageBase));
+ if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA))
+ data = (*(__IO uint16_t*)(pageBase + 2)) + 1;
+ else
+ data = 0;
+
+ FlashStatus = FLASH_ErasePage(pageBase);
+ if (FlashStatus == FLASH_COMPLETE)
+ FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data);
+
+ return FlashStatus;
+}
+
+/**
+ * @brief Check page for blank and erase it
+ * @param page base address
+ * @retval Success or error
+ * - Flash error code: on write Flash error
+ * - EEPROM_BAD_FLASH: page not empty after erase
+ * - EEPROM_OK: page blank
+ */
+uint16_t EE_CheckErasePage(uint32_t pageBase, uint16_t status)
+{
+ uint16_t FlashStatus;
+ if (EE_CheckPage(pageBase, status) != EEPROM_OK)
+ {
+ FlashStatus = EE_ErasePage(pageBase);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+ return EE_CheckPage(pageBase, status);
+ }
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Find valid Page for write or read operation
+ * @param Page0: Page0 base address
+ * Page1: Page1 base address
+ * @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found
+ */
+uint32_t EE_FindValidPage(void)
+{
+ uint16_t status0 = (*(__IO uint16_t*)PageBase0); // Get Page0 actual status
+ uint16_t status1 = (*(__IO uint16_t*)PageBase1); // Get Page1 actual status
+
+ if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED)
+ return PageBase0;
+ if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED)
+ return PageBase1;
+
+ return 0;
+}
+
+/**
+ * @brief Calculate unique variables in EEPROM
+ * @param start: address of first slot to check (page + 4)
+ * @param end: page end address
+ * @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF)
+ * @retval count of variables
+ */
+uint16_t EE_GetVariablesCount(uint32_t pageBase, uint16_t skipAddress)
+{
+ uint16_t varAddress, nextAddress;
+ uint32_t idx;
+ uint32_t pageEnd = pageBase + (uint32_t)PageSize;
+ uint16_t count = 0;
+
+ for (pageBase += 6; pageBase < pageEnd; pageBase += 4)
+ {
+ varAddress = (*(__IO uint16_t*)pageBase);
+ if (varAddress == 0xFFFF || varAddress == skipAddress)
+ continue;
+
+ count++;
+ for(idx = pageBase + 4; idx < pageEnd; idx += 4)
+ {
+ nextAddress = (*(__IO uint16_t*)idx);
+ if (nextAddress == varAddress)
+ {
+ count--;
+ break;
+ }
+ }
+ }
+ return count;
+}
+
+/**
+ * @brief Transfers last updated variables data from the full Page to an empty one.
+ * @param newPage: new page base address
+ * @param oldPage: old page base address
+ * @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF)
+ * @retval Success or error status:
+ * - FLASH_COMPLETE: on success
+ * - EEPROM_OUT_SIZE: if valid new page is full
+ * - Flash error code: on write Flash error
+ */
+uint16_t EE_PageTransfer(uint32_t newPage, uint32_t oldPage, uint16_t SkipAddress)
+{
+ uint32_t oldEnd, newEnd;
+ uint32_t oldIdx, newIdx, idx;
+ uint16_t address, data, found;
+ FLASH_Status FlashStatus;
+
+ // Transfer process: transfer variables from old to the new active page
+ newEnd = newPage + ((uint32_t)PageSize);
+
+ // Find first free element in new page
+ for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4)
+ if ((*(__IO uint32_t*)newIdx) == 0xFFFFFFFF) // Verify if element
+ break; // contents are 0xFFFFFFFF
+ if (newIdx >= newEnd)
+ return EEPROM_OUT_SIZE;
+
+ oldEnd = oldPage + 4;
+ oldIdx = oldPage + (uint32_t)(PageSize - 2);
+
+ for (; oldIdx > oldEnd; oldIdx -= 4)
+ {
+ address = *(__IO uint16_t*)oldIdx;
+ if (address == 0xFFFF || address == SkipAddress)
+ continue; // it's means that power off after write data
+
+ found = 0;
+ for (idx = newPage + 6; idx < newIdx; idx += 4)
+ if ((*(__IO uint16_t*)(idx)) == address)
+ {
+ found = 1;
+ break;
+ }
+
+ if (found)
+ continue;
+
+ if (newIdx < newEnd)
+ {
+ data = (*(__IO uint16_t*)(oldIdx - 2));
+
+ FlashStatus = FLASH_ProgramHalfWord(newIdx, data);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+
+ FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+
+ newIdx += 4;
+ }
+ else
+ return EEPROM_OUT_SIZE;
+ }
+
+ // Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status
+ data = EE_CheckErasePage(oldPage, EEPROM_ERASED);
+ if (data != EEPROM_OK)
+ return data;
+
+ // Set new Page status
+ FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Verify if active page is full and Writes variable in EEPROM.
+ * @param Address: 16 bit virtual address of the variable
+ * @param Data: 16 bit data to be written as variable value
+ * @retval Success or error status:
+ * - FLASH_COMPLETE: on success
+ * - EEPROM_PAGE_FULL: if valid page is full (need page transfer)
+ * - EEPROM_NO_VALID_PAGE: if no valid page was found
+ * - EEPROM_OUT_SIZE: if EEPROM size exceeded
+ * - Flash error code: on write Flash error
+ */
+uint16_t EE_VerifyPageFullWriteVariable(uint16_t Address, uint16_t Data)
+{
+ FLASH_Status FlashStatus;
+ uint32_t idx, pageBase, pageEnd, newPage;
+ uint16_t count;
+
+ // Get valid Page for write operation
+ pageBase = EE_FindValidPage();
+ if (pageBase == 0)
+ return EEPROM_NO_VALID_PAGE;
+
+ // Get the valid Page end Address
+ pageEnd = pageBase + PageSize; // Set end of page
+
+ for (idx = pageEnd - 2; idx > pageBase; idx -= 4)
+ {
+ if ((*(__IO uint16_t*)idx) == Address) // Find last value for address
+ {
+ count = (*(__IO uint16_t*)(idx - 2)); // Read last data
+ if (count == Data)
+ return EEPROM_OK;
+ if (count == 0xFFFF)
+ {
+ FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data
+ if (FlashStatus == FLASH_COMPLETE)
+ return EEPROM_OK;
+ }
+ break;
+ }
+ }
+
+ // Check each active page address starting from begining
+ for (idx = pageBase + 4; idx < pageEnd; idx += 4)
+ if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
+ { // contents are 0xFFFFFFFF
+ FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+ FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+ return EEPROM_OK;
+ }
+
+ // Empty slot not found, need page transfer
+ // Calculate unique variables in page
+ count = EE_GetVariablesCount(pageBase, Address) + 1;
+ if (count >= (PageSize / 4 - 1))
+ return EEPROM_OUT_SIZE;
+
+ if (pageBase == PageBase1)
+ newPage = PageBase0; // New page address where variable will be moved to
+ else
+ newPage = PageBase1;
+
+ // Set the new Page status to RECEIVE_DATA status
+ FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+
+ // Write the variable passed as parameter in the new active page
+ FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+
+ FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+
+ return EE_PageTransfer(newPage, pageBase, Address);
+}
+
+/*EEPROMClass::EEPROMClass(void)
+{
+ PageBase0 = EEPROM_PAGE0_BASE;
+ PageBase1 = EEPROM_PAGE1_BASE;
+ PageSize = EEPROM_PAGE_SIZE;
+ Status = EEPROM_NOT_INIT;
+}*/
+/*
+uint16_t EEPROM_init(uint32_t pageBase0, uint32_t pageBase1, uint32_t pageSize)
+{
+ PageBase0 = pageBase0;
+ PageBase1 = pageBase1;
+ PageSize = pageSize;
+ return EEPROM_init();
+}*/
+
+uint16_t EEPROM_init(void)
+{
+ uint16_t status0 = 6, status1 = 6;
+ FLASH_Status FlashStatus;
+
+ FLASH_Unlock();
+ Status = EEPROM_NO_VALID_PAGE;
+
+ status0 = (*(__IO uint16_t *)PageBase0);
+ status1 = (*(__IO uint16_t *)PageBase1);
+
+ switch (status0)
+ {
+/*
+ Page0 Page1
+ ----- -----
+ EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased
+ EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased
+ EEPROM_ERASED make EE_Format
+ any Error: EEPROM_NO_VALID_PAGE
+*/
+ case EEPROM_ERASED:
+ if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid
+ Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
+ else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive
+ {
+ FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
+ if (FlashStatus != FLASH_COMPLETE)
+ Status = FlashStatus;
+ else
+ Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
+ }
+ else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM
+ Status = EEPROM_format();
+ break;
+/*
+ Page0 Page1
+ ----- -----
+ EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0
+ EEPROM_ERASED Page0 need set to valid, Page1 erased
+ any EEPROM_NO_VALID_PAGE
+*/
+ case EEPROM_RECEIVE_DATA:
+ if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid
+ Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF);
+ else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased
+ {
+ Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
+ if (Status == EEPROM_OK)
+ {
+ FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
+ if (FlashStatus != FLASH_COMPLETE)
+ Status = FlashStatus;
+ else
+ Status = EEPROM_OK;
+ }
+ }
+ break;
+/*
+ Page0 Page1
+ ----- -----
+ EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE
+ EEPROM_RECEIVE_DATA Transfer Page0 to Page1
+ any Page0 valid, Page1 erased
+*/
+ case EEPROM_VALID_PAGE:
+ if (status1 == EEPROM_VALID_PAGE) // Both pages valid
+ Status = EEPROM_NO_VALID_PAGE;
+ else if (status1 == EEPROM_RECEIVE_DATA)
+ Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF);
+ else
+ Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
+ break;
+/*
+ Page0 Page1
+ ----- -----
+ any EEPROM_VALID_PAGE Page1 valid, Page0 erased
+ EEPROM_RECEIVE_DATA Page1 valid, Page0 erased
+ any EEPROM_NO_VALID_PAGE
+*/
+ default:
+ if (status1 == EEPROM_VALID_PAGE)
+ Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0
+ else if (status1 == EEPROM_RECEIVE_DATA)
+ {
+ FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
+ if (FlashStatus != FLASH_COMPLETE)
+ Status = FlashStatus;
+ else
+ Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
+ }
+ break;
+ }
+ return Status;
+}
+
+/**
+ * @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0
+ * @param PAGE0 and PAGE1 base addresses
+ * @retval Status of the last operation (Flash write or erase) done during EEPROM formating
+ */
+uint16_t EEPROM_format(void)
+{
+ uint16_t status;
+ FLASH_Status FlashStatus;
+
+ FLASH_Unlock();
+
+ // Erase Page0
+ status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE);
+ if (status != EEPROM_OK)
+ return status;
+ if ((*(__IO uint16_t*)PageBase0) == EEPROM_ERASED)
+ {
+ // Set Page0 as valid page: Write VALID_PAGE at Page0 base address
+ FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
+ if (FlashStatus != FLASH_COMPLETE)
+ return FlashStatus;
+ }
+ // Erase Page1
+ return EE_CheckErasePage(PageBase1, EEPROM_ERASED);
+}
+
+/**
+ * @brief Returns the erase counter for current page
+ * @param Data: Global variable contains the read variable value
+ * @retval Success or error status:
+ * - EEPROM_OK: if erases counter return.
+ * - EEPROM_NO_VALID_PAGE: if no valid page was found.
+ */
+uint16_t EEPROM_erases(uint16_t *Erases)
+{
+ uint32_t pageBase;
+ if (Status != EEPROM_OK)
+ if (EEPROM_init() != EEPROM_OK)
+ return Status;
+
+ // Get active Page for read operation
+ pageBase = EE_FindValidPage();
+ if (pageBase == 0)
+ return EEPROM_NO_VALID_PAGE;
+
+ *Erases = (*(__IO uint16_t*)pageBase+2);
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Returns the last stored variable data, if found,
+ * which correspond to the passed virtual address
+ * @param Address: Variable virtual address
+ * @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors
+ */
+/*
+uint16_t EEPROM_read (uint16_t Address)
+{
+ uint16_t data;
+ EEPROM_read(Address, &data);
+ return data;
+}*/
+
+/**
+ * @brief Returns the last stored variable data, if found,
+ * which correspond to the passed virtual address
+ * @param Address: Variable virtual address
+ * @param Data: Pointer to data variable
+ * @retval Success or error status:
+ * - EEPROM_OK: if variable was found
+ * - EEPROM_BAD_ADDRESS: if the variable was not found
+ * - EEPROM_NO_VALID_PAGE: if no valid page was found.
+ */
+uint16_t EEPROM_read(uint16_t Address, uint16_t *Data)
+{
+ uint32_t pageBase, pageEnd;
+
+ // Set default data (empty EEPROM)
+ *Data = EEPROM_DEFAULT_DATA;
+
+ if (Status == EEPROM_NOT_INIT)
+ if (EEPROM_init() != EEPROM_OK)
+ return Status;
+
+ // Get active Page for read operation
+ pageBase = EE_FindValidPage();
+ if (pageBase == 0)
+ return EEPROM_NO_VALID_PAGE;
+
+ // Get the valid Page end Address
+ pageEnd = pageBase + ((uint32_t)(PageSize - 2));
+
+ // Check each active page address starting from end
+ for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
+ if ((*(__IO uint16_t*)pageEnd) == Address) // Compare the read address with the virtual address
+ {
+ *Data = (*(__IO uint16_t*)(pageEnd - 2)); // Get content of Address-2 which is variable value
+ return EEPROM_OK;
+ }
+
+ // Return ReadStatus value: (0: variable exist, 1: variable doesn't exist)
+ return EEPROM_BAD_ADDRESS;
+}
+
+/**
+ * @brief Writes/upadtes variable data in EEPROM.
+ * @param VirtAddress: Variable virtual address
+ * @param Data: 16 bit data to be written
+ * @retval Success or error status:
+ * - FLASH_COMPLETE: on success
+ * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
+ * - EEPROM_PAGE_FULL: if valid page is full
+ * - EEPROM_NO_VALID_PAGE: if no valid page was found
+ * - EEPROM_OUT_SIZE: if no empty EEPROM variables
+ * - Flash error code: on write Flash error
+ */
+uint16_t EEPROM_write(uint16_t Address, uint16_t Data)
+{
+ if (Status == EEPROM_NOT_INIT)
+ if (EEPROM_init() != EEPROM_OK)
+ return Status;
+
+ if (Address == 0xFFFF)
+ return EEPROM_BAD_ADDRESS;
+
+ // Write the variable virtual address and value in the EEPROM
+ uint16_t status = EE_VerifyPageFullWriteVariable(Address, Data);
+ return status;
+}
+
+/**
+ * @brief Writes/upadtes variable data in EEPROM.
+ The value is written only if differs from the one already saved at the same address.
+ * @param VirtAddress: Variable virtual address
+ * @param Data: 16 bit data to be written
+ * @retval Success or error status:
+ * - EEPROM_SAME_VALUE: If new Data matches existing EEPROM Data
+ * - FLASH_COMPLETE: on success
+ * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
+ * - EEPROM_PAGE_FULL: if valid page is full
+ * - EEPROM_NO_VALID_PAGE: if no valid page was found
+ * - EEPROM_OUT_SIZE: if no empty EEPROM variables
+ * - Flash error code: on write Flash error
+ */
+uint16_t EEPROM_update(uint16_t Address, uint16_t Data)
+{
+ uint16_t temp;
+ EEPROM_read(Address, &temp);
+ if (Address == Data)
+ return EEPROM_SAME_VALUE;
+ else
+ return EEPROM_write(Address, Data);
+}
+
+/**
+ * @brief Return number of variable
+ * @retval Number of variables
+ */
+uint16_t EEPROM_count(uint16_t *Count)
+{
+ if (Status == EEPROM_NOT_INIT)
+ if (EEPROM_init() != EEPROM_OK)
+ return Status;
+
+ // Get valid Page for write operation
+ uint32_t pageBase = EE_FindValidPage();
+ if (pageBase == 0)
+ return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers
+
+ *Count = EE_GetVariablesCount(pageBase, 0xFFFF);
+ return EEPROM_OK;
+}
+
+uint16_t EEPROM_maxcount(void)
+{
+ return ((PageSize / 4)-1);
+}
+
+
+uint8_t eeprom_read_byte (const uint8_t *Address)
+{
+ const uint16_t p = (const uint32_t) Address;
+ uint16_t temp;
+ EEPROM_read(p, &temp);
+ return (uint8_t) temp;
+}
+
+void eeprom_write_byte (uint8_t *Address, uint8_t Value)
+{
+ uint16_t p = (uint32_t) Address;
+ EEPROM_write(p, (uint16_t) Value);
+}
+
+void eeprom_update_byte (uint8_t *Address, uint8_t Value)
+{
+ uint16_t p = (uint32_t) Address;
+ EEPROM_update(p, (uint16_t) Value);
+}
+
+uint16_t eeprom_read_word (const uint16_t *Address)
+{
+ const uint16_t p = (const uint32_t) Address;
+ uint16_t temp;
+ EEPROM_read(p, &temp);
+ return temp;
+}
+
+void eeprom_write_word (uint16_t *Address, uint16_t Value)
+{
+ uint16_t p = (uint32_t) Address;
+ EEPROM_write(p, Value);
+}
+
+void eeprom_update_word (uint16_t *Address, uint16_t Value)
+{
+ uint16_t p = (uint32_t) Address;
+ EEPROM_update(p, Value);
+}
+
+uint32_t eeprom_read_dword (const uint32_t *Address)
+{
+ const uint16_t p = (const uint32_t) Address;
+ uint16_t temp1, temp2;
+ EEPROM_read(p, &temp1);
+ EEPROM_read(p + 1, &temp2);
+ return temp1 | (temp2 << 16);
+}
+
+void eeprom_write_dword (uint32_t *Address, uint32_t Value)
+{
+ uint16_t temp = (uint16_t) Value;
+ uint16_t p = (uint32_t) Address;
+ EEPROM_write(p, temp);
+ temp = (uint16_t) (Value >> 16);
+ EEPROM_write(p + 1, temp);
+}
+
+void eeprom_update_dword (uint32_t *Address, uint32_t Value)
+{
+ uint16_t temp = (uint16_t) Value;
+ uint16_t p = (uint32_t) Address;
+ EEPROM_update(p, temp);
+ temp = (uint16_t) (Value >> 16);
+ EEPROM_update(p + 1, temp);
+}
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h
new file mode 100755
index 000000000..d06d30266
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.h
@@ -0,0 +1,89 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * https://github.com/leaflabs/libmaple
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ */
+
+// This file must be modified if the MCU is not defined below.
+// This library also assumes that the pages are not used by the firmware.
+
+#ifndef __EEPROM_H
+#define __EEPROM_H
+
+#include "ch.h"
+#include "hal.h"
+#include "flash_stm32.h"
+
+// HACK ALERT. This definition may not match your processor
+// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
+#define MCU_STM32F303CC
+
+#ifndef EEPROM_PAGE_SIZE
+ #if defined (MCU_STM32F103RB)
+ #define EEPROM_PAGE_SIZE (uint16_t)0x400 /* Page size = 1KByte */
+ #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC)
+ #define EEPROM_PAGE_SIZE (uint16_t)0x800 /* Page size = 2KByte */
+ #else
+ #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
+ #endif
+#endif
+
+#ifndef EEPROM_START_ADDRESS
+ #if defined (MCU_STM32F103RB)
+ #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 128 * 1024 - 2 * EEPROM_PAGE_SIZE))
+ #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
+ #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE))
+ #elif defined (MCU_STM32F103RD)
+ #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE))
+ #elif defined (MCU_STM32F303CC)
+ #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 250 * 1024 - 2 * EEPROM_PAGE_SIZE))
+ #else
+ #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
+ #endif
+#endif
+
+/* Pages 0 and 1 base and end addresses */
+#define EEPROM_PAGE0_BASE ((uint32_t)(EEPROM_START_ADDRESS + 0x000))
+#define EEPROM_PAGE1_BASE ((uint32_t)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE))
+
+/* Page status definitions */
+#define EEPROM_ERASED ((uint16_t)0xFFFF) /* PAGE is empty */
+#define EEPROM_RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */
+#define EEPROM_VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
+
+/* Page full define */
+enum uint16_t
+ {
+ EEPROM_OK = ((uint16_t)0x0000),
+ EEPROM_OUT_SIZE = ((uint16_t)0x0081),
+ EEPROM_BAD_ADDRESS = ((uint16_t)0x0082),
+ EEPROM_BAD_FLASH = ((uint16_t)0x0083),
+ EEPROM_NOT_INIT = ((uint16_t)0x0084),
+ EEPROM_SAME_VALUE = ((uint16_t)0x0085),
+ EEPROM_NO_VALID_PAGE = ((uint16_t)0x00AB)
+ };
+
+#define EEPROM_DEFAULT_DATA 0xFFFF
+
+ uint16_t EEPROM_init(void);
+ uint16_t EEPROM_format(void);
+ uint16_t EEPROM_erases(uint16_t *);
+ uint16_t EEPROM_read (uint16_t address, uint16_t *data);
+ uint16_t EEPROM_write(uint16_t address, uint16_t data);
+ uint16_t EEPROM_update(uint16_t address, uint16_t data);
+ uint16_t EEPROM_count(uint16_t *);
+ uint16_t EEPROM_maxcount(void);
+
+#endif /* __EEPROM_H */
diff --git a/tmk_core/common/chibios/eeprom_teensy.c b/tmk_core/common/chibios/eeprom_teensy.c
new file mode 100644
index 000000000..9061b790c
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_teensy.c
@@ -0,0 +1,632 @@
+#include "ch.h"
+#include "hal.h"
+
+#include "eeconfig.h"
+
+/*************************************/
+/* Hardware backend */
+/* */
+/* Code from PJRC/Teensyduino */
+/*************************************/
+
+/* Teensyduino Core Library
+ * http://www.pjrc.com/teensy/
+ * Copyright (c) 2013 PJRC.COM, LLC.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * 1. The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * 2. If the Software is incorporated into a build system that allows
+ * selection among a list of target devices, then similar target
+ * devices manufactured by PJRC.COM must be included in the list of
+ * target devices and selectable in the same manner.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+
+#if defined(K20x) /* chip selection */
+/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */
+
+// The EEPROM is really RAM with a hardware-based backup system to
+// flash memory. Selecting a smaller size EEPROM allows more wear
+// leveling, for higher write endurance. If you edit this file,
+// set this to the smallest size your application can use. Also,
+// due to Freescale's implementation, writing 16 or 32 bit words
+// (aligned to 2 or 4 byte boundaries) has twice the endurance
+// compared to writing 8 bit bytes.
+//
+#define EEPROM_SIZE 32
+
+// Writing unaligned 16 or 32 bit data is handled automatically when
+// this is defined, but at a cost of extra code size. Without this,
+// any unaligned write will cause a hard fault exception! If you're
+// absolutely sure all 16 and 32 bit writes will be aligned, you can
+// remove the extra unnecessary code.
+//
+#define HANDLE_UNALIGNED_WRITES
+
+// Minimum EEPROM Endurance
+// ------------------------
+#if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
+ #define EEESIZE 0x33
+#elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
+ #define EEESIZE 0x34
+#elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
+ #define EEESIZE 0x35
+#elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
+ #define EEESIZE 0x36
+#elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
+ #define EEESIZE 0x37
+#elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
+ #define EEESIZE 0x38
+#elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
+ #define EEESIZE 0x39
+#endif
+
+/** \brief eeprom initialization
+ *
+ * FIXME: needs doc
+ */
+void eeprom_initialize(void)
+{
+ uint32_t count=0;
+ uint16_t do_flash_cmd[] = {
+ 0xf06f, 0x037f, 0x7003, 0x7803,
+ 0xf013, 0x0f80, 0xd0fb, 0x4770};
+ uint8_t status;
+
+ if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) {
+ // FlexRAM is configured as traditional RAM
+ // We need to reconfigure for EEPROM usage
+ FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command
+ FTFL->FCCOB4 = EEESIZE; // EEPROM Size
+ FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup
+ __disable_irq();
+ // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
+ (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT));
+ __enable_irq();
+ status = FTFL->FSTAT;
+ if (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)) {
+ FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL));
+ return; // error
+ }
+ }
+ // wait for eeprom to become ready (is this really necessary?)
+ while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
+ if (++count > 20000) break;
+ }
+}
+
+#define FlexRAM ((uint8_t *)0x14000000)
+
+/** \brief eeprom read byte
+ *
+ * FIXME: needs doc
+ */
+uint8_t eeprom_read_byte(const uint8_t *addr)
+{
+ uint32_t offset = (uint32_t)addr;
+ if (offset >= EEPROM_SIZE) return 0;
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+ return FlexRAM[offset];
+}
+
+/** \brief eeprom read word
+ *
+ * FIXME: needs doc
+ */
+uint16_t eeprom_read_word(const uint16_t *addr)
+{
+ uint32_t offset = (uint32_t)addr;
+ if (offset >= EEPROM_SIZE-1) return 0;
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+ return *(uint16_t *)(&FlexRAM[offset]);
+}
+
+/** \brief eeprom read dword
+ *
+ * FIXME: needs doc
+ */
+uint32_t eeprom_read_dword(const uint32_t *addr)
+{
+ uint32_t offset = (uint32_t)addr;
+ if (offset >= EEPROM_SIZE-3) return 0;
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+ return *(uint32_t *)(&FlexRAM[offset]);
+}
+
+/** \brief eeprom read block
+ *
+ * FIXME: needs doc
+ */
+void eeprom_read_block(void *buf, const void *addr, uint32_t len)
+{
+ uint32_t offset = (uint32_t)addr;
+ uint8_t *dest = (uint8_t *)buf;
+ uint32_t end = offset + len;
+
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+ if (end > EEPROM_SIZE) end = EEPROM_SIZE;
+ while (offset < end) {
+ *dest++ = FlexRAM[offset++];
+ }
+}
+
+/** \brief eeprom is ready
+ *
+ * FIXME: needs doc
+ */
+int eeprom_is_ready(void)
+{
+ return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0;
+}
+
+/** \brief flexram wait
+ *
+ * FIXME: needs doc
+ */
+static void flexram_wait(void)
+{
+ while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
+ // TODO: timeout
+ }
+}
+
+/** \brief eeprom_write_byte
+ *
+ * FIXME: needs doc
+ */
+void eeprom_write_byte(uint8_t *addr, uint8_t value)
+{
+ uint32_t offset = (uint32_t)addr;
+
+ if (offset >= EEPROM_SIZE) return;
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+ if (FlexRAM[offset] != value) {
+ FlexRAM[offset] = value;
+ flexram_wait();
+ }
+}
+
+/** \brief eeprom write word
+ *
+ * FIXME: needs doc
+ */
+void eeprom_write_word(uint16_t *addr, uint16_t value)
+{
+ uint32_t offset = (uint32_t)addr;
+
+ if (offset >= EEPROM_SIZE-1) return;
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+#ifdef HANDLE_UNALIGNED_WRITES
+ if ((offset & 1) == 0) {
+#endif
+ if (*(uint16_t *)(&FlexRAM[offset]) != value) {
+ *(uint16_t *)(&FlexRAM[offset]) = value;
+ flexram_wait();
+ }
+#ifdef HANDLE_UNALIGNED_WRITES
+ } else {
+ if (FlexRAM[offset] != value) {
+ FlexRAM[offset] = value;
+ flexram_wait();
+ }
+ if (FlexRAM[offset + 1] != (value >> 8)) {
+ FlexRAM[offset + 1] = value >> 8;
+ flexram_wait();
+ }
+ }
+#endif
+}
+
+/** \brief eeprom write dword
+ *
+ * FIXME: needs doc
+ */
+void eeprom_write_dword(uint32_t *addr, uint32_t value)
+{
+ uint32_t offset = (uint32_t)addr;
+
+ if (offset >= EEPROM_SIZE-3) return;
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+#ifdef HANDLE_UNALIGNED_WRITES
+ switch (offset & 3) {
+ case 0:
+#endif
+ if (*(uint32_t *)(&FlexRAM[offset]) != value) {
+ *(uint32_t *)(&FlexRAM[offset]) = value;
+ flexram_wait();
+ }
+ return;
+#ifdef HANDLE_UNALIGNED_WRITES
+ case 2:
+ if (*(uint16_t *)(&FlexRAM[offset]) != value) {
+ *(uint16_t *)(&FlexRAM[offset]) = value;
+ flexram_wait();
+ }
+ if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
+ *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
+ flexram_wait();
+ }
+ return;
+ default:
+ if (FlexRAM[offset] != value) {
+ FlexRAM[offset] = value;
+ flexram_wait();
+ }
+ if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
+ *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
+ flexram_wait();
+ }
+ if (FlexRAM[offset + 3] != (value >> 24)) {
+ FlexRAM[offset + 3] = value >> 24;
+ flexram_wait();
+ }
+ }
+#endif
+}
+
+/** \brief eeprom write block
+ *
+ * FIXME: needs doc
+ */
+void eeprom_write_block(const void *buf, void *addr, uint32_t len)
+{
+ uint32_t offset = (uint32_t)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+
+ if (offset >= EEPROM_SIZE) return;
+ if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
+ if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
+ if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
+ while (len > 0) {
+ uint32_t lsb = offset & 3;
+ if (lsb == 0 && len >= 4) {
+ // write aligned 32 bits
+ uint32_t val32;
+ val32 = *src++;
+ val32 |= (*src++ << 8);
+ val32 |= (*src++ << 16);
+ val32 |= (*src++ << 24);
+ if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
+ *(uint32_t *)(&FlexRAM[offset]) = val32;
+ flexram_wait();
+ }
+ offset += 4;
+ len -= 4;
+ } else if ((lsb == 0 || lsb == 2) && len >= 2) {
+ // write aligned 16 bits
+ uint16_t val16;
+ val16 = *src++;
+ val16 |= (*src++ << 8);
+ if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
+ *(uint16_t *)(&FlexRAM[offset]) = val16;
+ flexram_wait();
+ }
+ offset += 2;
+ len -= 2;
+ } else {
+ // write 8 bits
+ uint8_t val8 = *src++;
+ if (FlexRAM[offset] != val8) {
+ FlexRAM[offset] = val8;
+ flexram_wait();
+ }
+ offset++;
+ len--;
+ }
+ }
+}
+
+/*
+void do_flash_cmd(volatile uint8_t *fstat)
+{
+ *fstat = 0x80;
+ while ((*fstat & 0x80) == 0) ; // wait
+}
+00000000 :
+ 0: f06f 037f mvn.w r3, #127 ; 0x7f
+ 4: 7003 strb r3, [r0, #0]
+ 6: 7803 ldrb r3, [r0, #0]
+ 8: f013 0f80 tst.w r3, #128 ; 0x80
+ c: d0fb beq.n 6
+ e: 4770 bx lr
+*/
+
+#elif defined(KL2x) /* chip selection */
+/* Teensy LC (emulated) */
+
+#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
+
+extern uint32_t __eeprom_workarea_start__;
+extern uint32_t __eeprom_workarea_end__;
+
+#define EEPROM_SIZE 128
+
+static uint32_t flashend = 0;
+
+void eeprom_initialize(void)
+{
+ const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
+
+ do {
+ if (*p++ == 0xFFFF) {
+ flashend = (uint32_t)(p - 2);
+ return;
+ }
+ } while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__));
+ flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1);
+}
+
+uint8_t eeprom_read_byte(const uint8_t *addr)
+{
+ uint32_t offset = (uint32_t)addr;
+ const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
+ const uint16_t *end = (const uint16_t *)((uint32_t)flashend);
+ uint16_t val;
+ uint8_t data=0xFF;
+
+ if (!end) {
+ eeprom_initialize();
+ end = (const uint16_t *)((uint32_t)flashend);
+ }
+ if (offset < EEPROM_SIZE) {
+ while (p <= end) {
+ val = *p++;
+ if ((val & 255) == offset) data = val >> 8;
+ }
+ }
+ return data;
+}
+
+static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data)
+{
+ // with great power comes great responsibility....
+ uint32_t stat;
+ *(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC);
+ *(uint32_t *)&(FTFA->FCCOB7) = data;
+ __disable_irq();
+ (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT));
+ __enable_irq();
+ stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);
+ if (stat) {
+ FTFA->FSTAT = stat;
+ }
+ MCM->PLACR |= MCM_PLACR_CFCC;
+}
+
+void eeprom_write_byte(uint8_t *addr, uint8_t data)
+{
+ uint32_t offset = (uint32_t)addr;
+ const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend);
+ uint32_t i, val, flashaddr;
+ uint16_t do_flash_cmd[] = {
+ 0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770};
+ uint8_t buf[EEPROM_SIZE];
+
+ if (offset >= EEPROM_SIZE) return;
+ if (!end) {
+ eeprom_initialize();
+ end = (const uint16_t *)((uint32_t)flashend);
+ }
+ if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) {
+ val = (data << 8) | offset;
+ flashaddr = (uint32_t)end;
+ flashend = flashaddr;
+ if ((flashaddr & 2) == 0) {
+ val |= 0xFFFF0000;
+ } else {
+ val <<= 16;
+ val |= 0x0000FFFF;
+ }
+ flash_write(do_flash_cmd, flashaddr, val);
+ } else {
+ for (i=0; i < EEPROM_SIZE; i++) {
+ buf[i] = 0xFF;
+ }
+ val = 0;
+ for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) {
+ val = *p;
+ if ((val & 255) < EEPROM_SIZE) {
+ buf[val & 255] = val >> 8;
+ }
+ }
+ buf[offset] = data;
+ for (flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) {
+ *(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr;
+ __disable_irq();
+ (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT));
+ __enable_irq();
+ val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);;
+ if (val) FTFA->FSTAT = val;
+ MCM->PLACR |= MCM_PLACR_CFCC;
+ }
+ flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__);
+ for (i=0; i < EEPROM_SIZE; i++) {
+ if (buf[i] == 0xFF) continue;
+ if ((flashaddr & 2) == 0) {
+ val = (buf[i] << 8) | i;
+ } else {
+ val = val | (buf[i] << 24) | (i << 16);
+ flash_write(do_flash_cmd, flashaddr, val);
+ }
+ flashaddr += 2;
+ }
+ flashend = flashaddr;
+ if ((flashaddr & 2)) {
+ val |= 0xFFFF0000;
+ flash_write(do_flash_cmd, flashaddr, val);
+ }
+ }
+}
+
+/*
+void do_flash_cmd(volatile uint8_t *fstat)
+{
+ *fstat = 0x80;
+ while ((*fstat & 0x80) == 0) ; // wait
+}
+00000000 :
+ 0: 2380 movs r3, #128 ; 0x80
+ 2: 7003 strb r3, [r0, #0]
+ 4: 7803 ldrb r3, [r0, #0]
+ 6: b25b sxtb r3, r3
+ 8: 2b00 cmp r3, #0
+ a: dafb bge.n 4
+ c: 4770 bx lr
+*/
+
+
+uint16_t eeprom_read_word(const uint16_t *addr)
+{
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
+}
+
+uint32_t eeprom_read_dword(const uint32_t *addr)
+{
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
+ | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
+}
+
+void eeprom_read_block(void *buf, const void *addr, uint32_t len)
+{
+ const uint8_t *p = (const uint8_t *)addr;
+ uint8_t *dest = (uint8_t *)buf;
+ while (len--) {
+ *dest++ = eeprom_read_byte(p++);
+ }
+}
+
+int eeprom_is_ready(void)
+{
+ return 1;
+}
+
+void eeprom_write_word(uint16_t *addr, uint16_t value)
+{
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_write_dword(uint32_t *addr, uint32_t value)
+{
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_write_block(const void *buf, void *addr, uint32_t len)
+{
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
+
+#else
+// No EEPROM supported, so emulate it
+
+#define EEPROM_SIZE 32
+static uint8_t buffer[EEPROM_SIZE];
+
+uint8_t eeprom_read_byte(const uint8_t *addr) {
+ uint32_t offset = (uint32_t)addr;
+ return buffer[offset];
+}
+
+void eeprom_write_byte(uint8_t *addr, uint8_t value) {
+ uint32_t offset = (uint32_t)addr;
+ buffer[offset] = value;
+}
+
+uint16_t eeprom_read_word(const uint16_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
+}
+
+uint32_t eeprom_read_dword(const uint32_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
+ | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
+}
+
+void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
+ const uint8_t *p = (const uint8_t *)addr;
+ uint8_t *dest = (uint8_t *)buf;
+ while (len--) {
+ *dest++ = eeprom_read_byte(p++);
+ }
+}
+
+void eeprom_write_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_write_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
+
+#endif /* chip selection */
+// The update functions just calls write for now, but could probably be optimized
+
+void eeprom_update_byte(uint8_t *addr, uint8_t value) {
+ eeprom_write_byte(addr, value);
+}
+
+void eeprom_update_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_update_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c
new file mode 100755
index 000000000..e7199ac7b
--- /dev/null
+++ b/tmk_core/common/chibios/flash_stm32.c
@@ -0,0 +1,180 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * https://github.com/leaflabs/libmaple
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ */
+
+#define STM32F303xC
+
+#include "stm32f3xx.h"
+#include "flash_stm32.h"
+
+#define FLASH_KEY1 ((uint32_t)0x45670123)
+#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
+
+/* Delay definition */
+#define EraseTimeout ((uint32_t)0x00000FFF)
+#define ProgramTimeout ((uint32_t)0x0000001F)
+
+#define ASSERT(exp) (void)((0))
+
+/**
+ * @brief Inserts a time delay.
+ * @param None
+ * @retval None
+ */
+static void delay(void)
+{
+ __IO uint32_t i = 0;
+ for(i = 0xFF; i != 0; i--) { }
+}
+
+/**
+ * @brief Returns the FLASH Status.
+ * @param None
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP or FLASH_COMPLETE
+ */
+FLASH_Status FLASH_GetStatus(void)
+{
+ if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)
+ return FLASH_BUSY;
+
+ if ((FLASH->SR & FLASH_SR_PGERR) != 0)
+ return FLASH_ERROR_PG;
+
+ if ((FLASH->SR & FLASH_SR_WRPERR) != 0 )
+ return FLASH_ERROR_WRP;
+
+ if ((FLASH->SR & FLASH_OBR_OPTERR) != 0 )
+ return FLASH_ERROR_OPT;
+
+ return FLASH_COMPLETE;
+}
+
+/**
+ * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
+ * @param Timeout: FLASH progamming Timeout
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
+{
+ FLASH_Status status;
+
+ /* Check for the Flash Status */
+ status = FLASH_GetStatus();
+ /* Wait for a Flash operation to complete or a TIMEOUT to occur */
+ while ((status == FLASH_BUSY) && (Timeout != 0x00))
+ {
+ delay();
+ status = FLASH_GetStatus();
+ Timeout--;
+ }
+ if (Timeout == 0)
+ status = FLASH_TIMEOUT;
+ /* Return the operation status */
+ return status;
+}
+
+/**
+ * @brief Erases a specified FLASH page.
+ * @param Page_Address: The page address to be erased.
+ * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
+{
+ FLASH_Status status = FLASH_COMPLETE;
+ /* Check the parameters */
+ ASSERT(IS_FLASH_ADDRESS(Page_Address));
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to erase the page */
+ FLASH->CR |= FLASH_CR_PER;
+ FLASH->AR = Page_Address;
+ FLASH->CR |= FLASH_CR_STRT;
+
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(EraseTimeout);
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the erase operation is completed, disable the PER Bit */
+ FLASH->CR &= ~FLASH_CR_PER;
+ }
+ FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
+ }
+ /* Return the Erase Status */
+ return status;
+}
+
+/**
+ * @brief Programs a half word at a specified address.
+ * @param Address: specifies the address to be programmed.
+ * @param Data: specifies the data to be programmed.
+ * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ */
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
+{
+ FLASH_Status status = FLASH_BAD_ADDRESS;
+
+ if (IS_FLASH_ADDRESS(Address))
+ {
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ if(status == FLASH_COMPLETE)
+ {
+ /* if the previous operation is completed, proceed to program the new data */
+ FLASH->CR |= FLASH_CR_PG;
+ *(__IO uint16_t*)Address = Data;
+ /* Wait for last operation to be completed */
+ status = FLASH_WaitForLastOperation(ProgramTimeout);
+ if(status != FLASH_TIMEOUT)
+ {
+ /* if the program operation is completed, disable the PG Bit */
+ FLASH->CR &= ~FLASH_CR_PG;
+ }
+ FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief Unlocks the FLASH Program Erase Controller.
+ * @param None
+ * @retval None
+ */
+void FLASH_Unlock(void)
+{
+ /* Authorize the FPEC Access */
+ FLASH->KEYR = FLASH_KEY1;
+ FLASH->KEYR = FLASH_KEY2;
+}
+
+/**
+ * @brief Locks the FLASH Program Erase Controller.
+ * @param None
+ * @retval None
+ */
+void FLASH_Lock(void)
+{
+ /* Set the Lock Bit to lock the FPEC and the FCR */
+ FLASH->CR |= FLASH_CR_LOCK;
+}
diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h
new file mode 100755
index 000000000..cc065cbca
--- /dev/null
+++ b/tmk_core/common/chibios/flash_stm32.h
@@ -0,0 +1,53 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * https://github.com/leaflabs/libmaple
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ */
+
+#ifndef __FLASH_STM32_H
+#define __FLASH_STM32_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "ch.h"
+#include "hal.h"
+
+typedef enum
+ {
+ FLASH_BUSY = 1,
+ FLASH_ERROR_PG,
+ FLASH_ERROR_WRP,
+ FLASH_ERROR_OPT,
+ FLASH_COMPLETE,
+ FLASH_TIMEOUT,
+ FLASH_BAD_ADDRESS
+ } FLASH_Status;
+
+#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF))
+
+FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
+FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
+FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
+
+void FLASH_Unlock(void);
+void FLASH_Lock(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FLASH_STM32_H */
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 3e5987ee3..35de574a9 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -3,12 +3,20 @@
#include "eeprom.h"
#include "eeconfig.h"
+#ifdef STM32F303xC
+#include "hal.h"
+#include "eeprom_stm32.h"
+#endif
+
/** \brief eeconfig initialization
*
* FIXME: needs doc
*/
void eeconfig_init(void)
{
+#ifdef STM32F303xC
+ EEPROM_format();
+#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
eeprom_update_byte(EECONFIG_DEBUG, 0);
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
@@ -43,6 +51,9 @@ void eeconfig_enable(void)
*/
void eeconfig_disable(void)
{
+#ifdef STM32F303xC
+ EEPROM_format();
+#endif
eeprom_update_word(EECONFIG_MAGIC, 0xFFFF);
}
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 1397a90c7..fa498df48 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -25,6 +25,7 @@ along with this program. If not, see .
#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
/* eeprom parameteter address */
+#if !defined(STM32F303xC)
#define EECONFIG_MAGIC (uint16_t *)0
#define EECONFIG_DEBUG (uint8_t *)2
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
@@ -38,6 +39,21 @@ along with this program. If not, see .
// EEHANDS for two handed boards
#define EECONFIG_HANDEDNESS (uint8_t *)14
+#else
+/* STM32F3 uses 16byte block. Reconfigure memory map */
+#define EECONFIG_MAGIC (uint16_t *)0
+#define EECONFIG_DEBUG (uint8_t *)1
+#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
+#define EECONFIG_KEYMAP (uint8_t *)3
+#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
+#define EECONFIG_BACKLIGHT (uint8_t *)5
+#define EECONFIG_AUDIO (uint8_t *)6
+#define EECONFIG_RGBLIGHT (uint32_t *)7
+#define EECONFIG_UNICODEMODE (uint8_t *)9
+#define EECONFIG_STENOMODE (uint8_t *)10
+// EEHANDS for two handed boards
+#define EECONFIG_HANDEDNESS (uint8_t *)11
+#endif
/* debug bit */
#define EECONFIG_DEBUG_ENABLE (1<<0)
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index f2abc438d..568c1edb2 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -44,6 +44,9 @@
#ifdef MIDI_ENABLE
#include "qmk_midi.h"
#endif
+#ifdef STM32F303xC
+#include "eeprom_stm32.h"
+#endif
#include "suspend.h"
#include "wait.h"
@@ -109,6 +112,10 @@ int main(void) {
halInit();
chSysInit();
+#ifdef STM32F303xC
+ EEPROM_init();
+#endif
+
// TESTING
// chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
--
cgit v1.2.3-70-g09d2
From 94f92cedef54403b2d6df9ce7a2715d3c4732378 Mon Sep 17 00:00:00 2001
From: ishtob
Date: Fri, 31 Aug 2018 10:37:13 -0400
Subject: Fix emulated EEPROM start address on STM32F303 (#3819)
MCU has 254 flash, changed 250 to 254. tested working on a planck rev6
---
tmk_core/common/chibios/eeprom_stm32.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h
index d06d30266..68aa14f6d 100755
--- a/tmk_core/common/chibios/eeprom_stm32.h
+++ b/tmk_core/common/chibios/eeprom_stm32.h
@@ -48,7 +48,7 @@
#elif defined (MCU_STM32F103RD)
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE))
#elif defined (MCU_STM32F303CC)
- #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 250 * 1024 - 2 * EEPROM_PAGE_SIZE))
+ #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE))
#else
#error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
#endif
--
cgit v1.2.3-70-g09d2
From fa1ee47cf2293d06693b86e8dd188d9fbc9338c4 Mon Sep 17 00:00:00 2001
From: Steven Liu
Date: Tue, 4 Sep 2018 00:18:37 +0100
Subject: Enable mouse keys in register_code and unregister_code
This allows for macros to be assigned to press two mouse directions at same time, which allows for one key diagonals.
---
tmk_core/common/action.c | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index f7c039f45..76c150b40 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -773,6 +773,9 @@ void register_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(KEYCODE2CONSUMER(code));
}
+ else if IS_MOUSEKEY(code) {
+ mousekey_on(code);
+ }
}
/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -832,6 +835,9 @@ void unregister_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(0);
}
+ else if IS_MOUSEKEY(code) {
+ mousekey_off(code);
+ }
}
/** \brief Utilities for actions. (FIXME: Needs better description)
--
cgit v1.2.3-70-g09d2
From a14eb01883cd135105cebd4d5570337250cc76cb Mon Sep 17 00:00:00 2001
From: Jack Humbert
Date: Mon, 3 Sep 2018 19:48:09 -0400
Subject: fix mousekey call
---
tmk_core/common/action.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 76c150b40..ae0864749 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -773,9 +773,12 @@ void register_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(KEYCODE2CONSUMER(code));
}
- else if IS_MOUSEKEY(code) {
- mousekey_on(code);
- }
+
+ #ifdef MOUSEKEY_ENABLE
+ else if IS_MOUSEKEY(code) {
+ mousekey_on(code);
+ }
+ #endif
}
/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -835,9 +838,11 @@ void unregister_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(0);
}
- else if IS_MOUSEKEY(code) {
- mousekey_off(code);
- }
+ #ifdef MOUSEKEY_ENABLE
+ else if IS_MOUSEKEY(code) {
+ mousekey_off(code);
+ }
+ #endif
}
/** \brief Utilities for actions. (FIXME: Needs better description)
--
cgit v1.2.3-70-g09d2
From e5465e1c57f1ae6b71e1e665e4afd5f5e3909a89 Mon Sep 17 00:00:00 2001
From: patrickmt <40182064+patrickmt@users.noreply.github.com>
Date: Wed, 5 Sep 2018 12:25:47 -0400
Subject: CTRL and ALT updates
Added support to enter bootloader from software (bootloader version must be newer than "v2.18Jun 22 2018 17:28:08" until workaround for older is created).
Updated CTRL and ALT keymaps for entering bootloader with Fn+b held for >500ms.
Added basic MacOS keymap for ALT.
USB sleep LED indicator now turns off after 1 second.
Slowed down debug LED code printing.
---
keyboards/massdrop/alt/keymaps/default/keymap.c | 14 +-
keyboards/massdrop/alt/keymaps/mac/keymap.c | 212 +++++++++++++++++++++++
keyboards/massdrop/ctrl/keymaps/default/keymap.c | 16 +-
keyboards/massdrop/ctrl/keymaps/mac/keymap.c | 12 ++
tmk_core/common/arm_atsam/bootloader.c | 32 +++-
tmk_core/protocol/arm_atsam/d51_util.c | 4 +-
tmk_core/protocol/arm_atsam/main_arm_atsam.c | 7 +-
7 files changed, 290 insertions(+), 7 deletions(-)
create mode 100644 keyboards/massdrop/alt/keymaps/mac/keymap.c
(limited to 'tmk_core/common')
diff --git a/keyboards/massdrop/alt/keymaps/default/keymap.c b/keyboards/massdrop/alt/keymaps/default/keymap.c
index 3f0b84e38..9d8387bb7 100644
--- a/keyboards/massdrop/alt/keymaps/default/keymap.c
+++ b/keyboards/massdrop/alt/keymaps/default/keymap.c
@@ -19,6 +19,7 @@ enum alt_keycodes {
DBG_MTRX, //DEBUG Toggle Matrix Prints
DBG_KBD, //DEBUG Toggle Keyboard Prints
DBG_MOU, //DEBUG Toggle Mouse Prints
+ MD_BOOT, //Restart into bootloader after hold timeout
};
#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
@@ -37,7 +38,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_MUTE, \
L_T_BR, L_PSD, L_BRI, L_PSI, KC_TRNS, KC_TRNS, KC_TRNS, U_T_AUTO,U_T_AGCR,KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, KC_TRNS, \
L_T_PTD, L_PTP, L_BRD, L_PTN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, \
- KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, KC_TRNS, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_VOLD, \
+ KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, MD_BOOT, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_VOLD, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_END \
),
/*
@@ -68,6 +69,8 @@ void matrix_scan_user(void) {
#define MODS_ALT (keyboard_report->mods & MOD_BIT(KC_LALT) || keyboard_report->mods & MOD_BIT(KC_RALT))
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ static uint32_t key_timer;
+
switch (keycode) {
case L_BRI:
if (record->event.pressed) {
@@ -194,6 +197,15 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
CDC_print("\r\n");
}
return false;
+ case MD_BOOT:
+ if (record->event.pressed) {
+ key_timer = timer_read32();
+ } else {
+ if (timer_elapsed32(key_timer) >= 500) {
+ reset_keyboard();
+ }
+ }
+ return false;
default:
return true; //Process all other keycodes normally
}
diff --git a/keyboards/massdrop/alt/keymaps/mac/keymap.c b/keyboards/massdrop/alt/keymaps/mac/keymap.c
new file mode 100644
index 000000000..a8adbd3c8
--- /dev/null
+++ b/keyboards/massdrop/alt/keymaps/mac/keymap.c
@@ -0,0 +1,212 @@
+#include QMK_KEYBOARD_H
+
+enum alt_keycodes {
+ L_BRI = SAFE_RANGE, //LED Brightness Increase
+ L_BRD, //LED Brightness Decrease
+ L_PTN, //LED Pattern Select Next
+ L_PTP, //LED Pattern Select Previous
+ L_PSI, //LED Pattern Speed Increase
+ L_PSD, //LED Pattern Speed Decrease
+ L_T_MD, //LED Toggle Mode
+ L_T_ONF, //LED Toggle On / Off
+ L_ON, //LED On
+ L_OFF, //LED Off
+ L_T_BR, //LED Toggle Breath Effect
+ L_T_PTD, //LED Toggle Scrolling Pattern Direction
+ U_T_AUTO, //USB Extra Port Toggle Auto Detect / Always Active
+ U_T_AGCR, //USB Toggle Automatic GCR control
+ DBG_TOG, //DEBUG Toggle On / Off
+ DBG_MTRX, //DEBUG Toggle Matrix Prints
+ DBG_KBD, //DEBUG Toggle Keyboard Prints
+ DBG_MOU, //DEBUG Toggle Mouse Prints
+ MD_BOOT, //Restart into bootloader after hold timeout
+};
+
+#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
+
+keymap_config_t keymap_config;
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_DEL, \
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_HOME, \
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, \
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, \
+ KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_LEFT, KC_DOWN, KC_RGHT \
+ ),
+ [1] = LAYOUT(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_MUTE, \
+ L_T_BR, L_PSD, L_BRI, L_PSI, KC_TRNS, KC_TRNS, KC_TRNS, U_T_AUTO,U_T_AGCR,KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, KC_TRNS, \
+ L_T_PTD, L_PTP, L_BRD, L_PTN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, \
+ KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, MD_BOOT, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_VOLD, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_END \
+ ),
+ /*
+ [X] = LAYOUT(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
+ ),
+ */
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+
+};
+
+// Runs just one time when the keyboard initializes.
+void matrix_init_user(void) {
+};
+
+// Runs constantly in the background, in a loop.
+void matrix_scan_user(void) {
+};
+
+#define MODS_SHIFT (keyboard_report->mods & MOD_BIT(KC_LSHIFT) || keyboard_report->mods & MOD_BIT(KC_RSHIFT))
+#define MODS_CTRL (keyboard_report->mods & MOD_BIT(KC_LCTL) || keyboard_report->mods & MOD_BIT(KC_RCTRL))
+#define MODS_ALT (keyboard_report->mods & MOD_BIT(KC_LALT) || keyboard_report->mods & MOD_BIT(KC_RALT))
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ static uint32_t key_timer;
+
+ switch (keycode) {
+ case L_BRI:
+ if (record->event.pressed) {
+ if (LED_GCR_STEP > LED_GCR_MAX - gcr_desired) gcr_desired = LED_GCR_MAX;
+ else gcr_desired += LED_GCR_STEP;
+ if (led_animation_breathing) gcr_breathe = gcr_desired;
+ }
+ return false;
+ case L_BRD:
+ if (record->event.pressed) {
+ if (LED_GCR_STEP > gcr_desired) gcr_desired = 0;
+ else gcr_desired -= LED_GCR_STEP;
+ if (led_animation_breathing) gcr_breathe = gcr_desired;
+ }
+ return false;
+ case L_PTN:
+ if (record->event.pressed) {
+ if (led_animation_id == led_setups_count - 1) led_animation_id = 0;
+ else led_animation_id++;
+ }
+ return false;
+ case L_PTP:
+ if (record->event.pressed) {
+ if (led_animation_id == 0) led_animation_id = led_setups_count - 1;
+ else led_animation_id--;
+ }
+ return false;
+ case L_PSI:
+ if (record->event.pressed) {
+ led_animation_speed += ANIMATION_SPEED_STEP;
+ }
+ return false;
+ case L_PSD:
+ if (record->event.pressed) {
+ led_animation_speed -= ANIMATION_SPEED_STEP;
+ if (led_animation_speed < 0) led_animation_speed = 0;
+ }
+ return false;
+ case L_T_MD:
+ if (record->event.pressed) {
+ led_lighting_mode++;
+ if (led_lighting_mode > LED_MODE_MAX_INDEX) led_lighting_mode = LED_MODE_NORMAL;
+ }
+ return false;
+ case L_T_ONF:
+ if (record->event.pressed) {
+ led_enabled = !led_enabled;
+ I2C3733_Control_Set(led_enabled);
+ }
+ return false;
+ case L_ON:
+ if (record->event.pressed) {
+ led_enabled = 1;
+ I2C3733_Control_Set(led_enabled);
+ }
+ return false;
+ case L_OFF:
+ if (record->event.pressed) {
+ led_enabled = 0;
+ I2C3733_Control_Set(led_enabled);
+ }
+ return false;
+ case L_T_BR:
+ if (record->event.pressed) {
+ led_animation_breathing = !led_animation_breathing;
+ if (led_animation_breathing)
+ {
+ gcr_breathe = gcr_desired;
+ led_animation_breathe_cur = BREATHE_MIN_STEP;
+ breathe_dir = 1;
+ }
+ }
+ return false;
+ case L_T_PTD:
+ if (record->event.pressed) {
+ led_animation_direction = !led_animation_direction;
+ }
+ return false;
+ case U_T_AUTO:
+ if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
+ usb_extra_manual = !usb_extra_manual;
+ CDC_print("USB extra port manual mode ");
+ CDC_print(usb_extra_manual ? "enabled" : "disabled");
+ CDC_print("\r\n");
+ }
+ return false;
+ case U_T_AGCR:
+ if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
+ usb_gcr_auto = !usb_gcr_auto;
+ CDC_print("USB GCR auto mode ");
+ CDC_print(usb_gcr_auto ? "enabled" : "disabled");
+ CDC_print("\r\n");
+ }
+ return false;
+ case DBG_TOG:
+ if (record->event.pressed) {
+ debug_enable = !debug_enable;
+ CDC_print("Debug mode ");
+ CDC_print(debug_enable ? "enabled" : "disabled");
+ CDC_print("\r\n");
+ }
+ return false;
+ case DBG_MTRX:
+ if (record->event.pressed) {
+ debug_matrix = !debug_matrix;
+ CDC_print("Debug matrix ");
+ CDC_print(debug_matrix ? "enabled" : "disabled");
+ CDC_print("\r\n");
+ }
+ return false;
+ case DBG_KBD:
+ if (record->event.pressed) {
+ debug_keyboard = !debug_keyboard;
+ CDC_print("Debug keyboard ");
+ CDC_print(debug_keyboard ? "enabled" : "disabled");
+ CDC_print("\r\n");
+ }
+ return false;
+ case DBG_MOU:
+ if (record->event.pressed) {
+ debug_mouse = !debug_mouse;
+ CDC_print("Debug mouse ");
+ CDC_print(debug_mouse ? "enabled" : "disabled");
+ CDC_print("\r\n");
+ }
+ return false;
+ case MD_BOOT:
+ if (record->event.pressed) {
+ key_timer = timer_read32();
+ } else {
+ if (timer_elapsed32(key_timer) >= 500) {
+ reset_keyboard();
+ }
+ }
+ return false;
+ default:
+ return true; //Process all other keycodes normally
+ }
+}
diff --git a/keyboards/massdrop/ctrl/keymaps/default/keymap.c b/keyboards/massdrop/ctrl/keymaps/default/keymap.c
index ac58f336e..9bfb7fec5 100644
--- a/keyboards/massdrop/ctrl/keymaps/default/keymap.c
+++ b/keyboards/massdrop/ctrl/keymaps/default/keymap.c
@@ -19,6 +19,7 @@ enum ctrl_keycodes {
DBG_MTRX, //DEBUG Toggle Matrix Prints
DBG_KBD, //DEBUG Toggle Keyboard Prints
DBG_MOU, //DEBUG Toggle Mouse Prints
+ MD_BOOT, //Restart into bootloader after hold timeout
};
#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
@@ -39,7 +40,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MSTP, KC_VOLU, \
L_T_BR, L_PSD, L_BRI, L_PSI, KC_TRNS, KC_TRNS, KC_TRNS, U_T_AUTO,U_T_AGCR,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_VOLD, \
L_T_PTD, L_PTP, L_BRD, L_PTN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
- KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, KC_TRNS, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+ KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, MD_BOOT, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
/*
@@ -71,6 +72,8 @@ void matrix_scan_user(void) {
#define MODS_ALT (keyboard_report->mods & MOD_BIT(KC_LALT) || keyboard_report->mods & MOD_BIT(KC_RALT))
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ static uint32_t key_timer;
+
switch (keycode) {
case L_BRI:
if (record->event.pressed) {
@@ -197,7 +200,16 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
CDC_print("\r\n");
}
return false;
+ case MD_BOOT:
+ if (record->event.pressed) {
+ key_timer = timer_read32();
+ } else {
+ if (timer_elapsed32(key_timer) >= 500) {
+ reset_keyboard();
+ }
+ }
+ return false;
default:
return true; //Process all other keycodes normally
}
-}
\ No newline at end of file
+}
diff --git a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c
index 116aaa9a1..a03f891e8 100644
--- a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c
+++ b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c
@@ -19,6 +19,7 @@ enum ctrl_keycodes {
DBG_MTRX, //DEBUG Toggle Matrix Prints
DBG_KBD, //DEBUG Toggle Keyboard Prints
DBG_MOU, //DEBUG Toggle Mouse Prints
+ MD_BOOT, //Restart into bootloader after hold timeout
};
#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
@@ -71,6 +72,8 @@ void matrix_scan_user(void) {
#define MODS_ALT (keyboard_report->mods & MOD_BIT(KC_LALT) || keyboard_report->mods & MOD_BIT(KC_RALT))
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ static uint32_t key_timer;
+
switch (keycode) {
case L_BRI:
if (record->event.pressed) {
@@ -197,6 +200,15 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
CDC_print("\r\n");
}
return false;
+ case MD_BOOT:
+ if (record->event.pressed) {
+ key_timer = timer_read32();
+ } else {
+ if (timer_elapsed32(key_timer) >= 500) {
+ reset_keyboard();
+ }
+ }
+ return false;
default:
return true; //Process all other keycodes normally
}
diff --git a/tmk_core/common/arm_atsam/bootloader.c b/tmk_core/common/arm_atsam/bootloader.c
index 5155d9ff0..9701a6219 100644
--- a/tmk_core/common/arm_atsam/bootloader.c
+++ b/tmk_core/common/arm_atsam/bootloader.c
@@ -15,5 +15,35 @@
*/
#include "bootloader.h"
+#include "samd51j18a.h"
-void bootloader_jump(void) {}
+//Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
+void bootloader_jump(void)
+{
+ //Keyboards released with certain bootloader can not enter bootloader from app until workaround is created
+ uint8_t ver_no_jump[] = "v2.18Jun 22 2018 17:28:08";
+ uint8_t *ver_check = ver_no_jump;
+ uint8_t *boot_check = (uint8_t *)0x21A0;
+ while (*ver_check && *boot_check == *ver_check)
+ {
+ ver_check++;
+ boot_check++;
+ }
+ if (!*ver_check)
+ {
+ //Version match
+ //Software workaround would go here
+ return; //No software restart method implemented... must use hardware reset button
+ }
+
+ WDT->CTRLA.bit.ENABLE = 0;
+ while (WDT->SYNCBUSY.bit.ENABLE) {}
+ while (WDT->CTRLA.bit.ENABLE) {}
+ WDT->CONFIG.bit.WINDOW = 0;
+ WDT->CONFIG.bit.PER = 0;
+ WDT->EWCTRL.bit.EWOFFSET = 0;
+ WDT->CTRLA.bit.ENABLE = 1;
+ while (WDT->SYNCBUSY.bit.ENABLE) {}
+ while (!WDT->CTRLA.bit.ENABLE) {}
+ while (1) {} //Wait on timeout
+}
diff --git a/tmk_core/protocol/arm_atsam/d51_util.c b/tmk_core/protocol/arm_atsam/d51_util.c
index 91b58757c..bb63a9481 100644
--- a/tmk_core/protocol/arm_atsam/d51_util.c
+++ b/tmk_core/protocol/arm_atsam/d51_util.c
@@ -41,8 +41,8 @@ void m15_print(uint32_t x)
//Display unsigned 32-bit number through debug led
//Read as follows: 1230 = [*] [* *] [* * *] [**] (note zero is fast double flash)
-#define DLED_ONTIME 600000
-#define DLED_PAUSE 1000000
+#define DLED_ONTIME 1000000
+#define DLED_PAUSE 1500000
volatile uint32_t w;
void dled_print(uint32_t x, uint8_t long_pause)
{
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index e9514730e..8cc776703 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -225,6 +225,8 @@ int main(void)
{
if (usb_state == USB_STATE_POWERDOWN)
{
+ uint32_t timer_led = timer_read32();
+
led_on;
if (led_enabled)
{
@@ -233,7 +235,10 @@ int main(void)
I2C3733_Control_Set(0);
}
}
- while (usb_state == USB_STATE_POWERDOWN) {}
+ while (usb_state == USB_STATE_POWERDOWN)
+ {
+ if (timer_read32() - timer_led > 1000) led_off; //Good to indicate went to sleep, but only for a second
+ }
if (led_enabled)
{
for (drvid=0;drvid
Date: Sat, 21 Jul 2018 14:16:14 -0700
Subject: Fix RG Sleep issues for Teensy Controllers
Appearenly, teensy controllers have some issues with waking up. If the rgblight is called "too soon", it will cause the controller to lock up, intermittently. Adding a 10 ms
delay seems to fix this issue, as it lets it have enough time to handle things properly.
This has been tested extensively on my Ergodox EZ, and can be seen in the @drashna userspace, under the "suspend_wakeup_init_user" function.
---
tmk_core/common/avr/suspend.c | 3 +++
1 file changed, 3 insertions(+)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 3d4a48439..73fdda6cc 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -189,6 +189,9 @@ void suspend_wakeup_init(void)
#endif
led_set(host_keyboard_leds());
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
+#ifdef BOOTLOADER_TEENSY
+ wait_ms(10);
+#endif
rgblight_enable_noeeprom();
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_enable();
--
cgit v1.2.3-70-g09d2
From 6d6d91c834ef3415425e21d895d4ec91c67fd4b8 Mon Sep 17 00:00:00 2001
From: Takeshi ISHII <2170248+mtei@users.noreply.github.com>
Date: Fri, 14 Sep 2018 02:24:10 +0900
Subject: rgblight.[ch] more configurable (#3582)
* add temporary test code rgblight-macro-test1.[ch]
* rgblight.h : mode auto numberring and auto generate mode name symbol
No change in build result.
* rgblight.c use RGBLIGHT_MODE_xxx symbols
No change in build result.
* quantum.c use RGBLIGHT_MODE_xxx symbols
No change in build result.
* fix build break. when RGB_MATRIX_ENABLE defined
* add temporary test code rgblight-macro-test2.[ch]
* modify rgblight_mode_eeprom_helper() and rgblight_sethsv_eeprom_helper()
* modify rgblight_task()
* configurable each effect compile on/off in config.h
* update docs/feature_rgblight.md
* fix conflict. docs/feature_rgblight.md
* remove temporary test code rgblight-macro-test*.[ch]
* fix comment typo.
* remove old mode number from comment
* update docs/feature_rgblight.md about effect mode
* Revert "update docs/feature_rgblight.md about effect mode"
This reverts commit 43890663fcc9dda1899df7a37d382fc38b1a6d6d.
* some change docs/feature_rgblight.md
* fix typo
* docs/feature_rgblight.md update: revise mode number table
---
docs/feature_rgblight.md | 42 +++++---
quantum/quantum.c | 52 ++++++---
quantum/quantum.h | 6 ++
quantum/rgblight.c | 237 +++++++++++++++++++++++++++---------------
quantum/rgblight.h | 87 +++++++++++++++-
quantum/rgblight_reconfig.h | 36 +++++++
tmk_core/common/avr/suspend.c | 1 +
tmk_core/protocol/lufa/lufa.c | 1 +
8 files changed, 346 insertions(+), 116 deletions(-)
create mode 100644 quantum/rgblight_reconfig.h
(limited to 'tmk_core/common')
diff --git a/docs/feature_rgblight.md b/docs/feature_rgblight.md
index d48941a04..925dca724 100644
--- a/docs/feature_rgblight.md
+++ b/docs/feature_rgblight.md
@@ -79,20 +79,23 @@ Your RGB lighting can be configured by placing these `#define`s in your `config.
## Animations
-Not only can this lighting be whatever color you want, if `RGBLIGHT_ANIMATIONS` is defined, you also have a number of animation modes at your disposal:
-
-|Mode |Description |
-|-----|---------------------|
-|1 |Solid color |
-|2-5 |Solid color breathing|
-|6-8 |Cycling rainbow |
-|9-14 |Swirling rainbow |
-|15-20|Snake |
-|21-23|Knight |
-|24 |Christmas |
-|25-34|Static gradient |
-|35 |RGB Test |
-|36 |Alternating |
+
+Not only can this lighting be whatever color you want,
+if `RGBLIGHT_EFFECT_xxxx` or `RGBLIGHT_ANIMATIONS` is defined, you also have a number of animation modes at your disposal:
+
+|Mode number symbol |Additional number |Description |
+|-----------------------------|-------------------|---------------------------------------|
+|`RGBLIGHT_MODE_STATIC_LIGHT` | *None* |Solid color (this mode is always enabled) |
+|`RGBLIGHT_MODE_BREATHING` | 0,1,2,3 |Solid color breathing |
+|`RGBLIGHT_MODE_RAINBOW_MOOD` | 0,1,2 |Cycling rainbow |
+|`RGBLIGHT_MODE_RAINBOW_SWIRL`| 0,1,2,3,4,5 |Swirling rainbow |
+|`RGBLIGHT_MODE_SNAKE` | 0,1,2,3,4,5 |Snake |
+|`RGBLIGHT_MODE_KNIGHT` | 0,1,2 |Knight |
+|`RGBLIGHT_MODE_CHRISTMAS` | *None* |Christmas |
+|`RGBLIGHT_MODE_STATIC_GRADIENT`| 0,1,..,9 |Static gradient |
+|`RGBLIGHT_MODE_RGB_TEST` | *None* |RGB Test |
+|`RGBLIGHT_MODE_ALTERNATING` | *None* |Alternating |
+
Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstration.
@@ -100,7 +103,16 @@ The following options can be used to tweak the various animations:
|Define |Default |Description |
|------------------------------------|-------------|-------------------------------------------------------------------------------------|
-|`RGBLIGHT_ANIMATIONS` |*Not defined*|If defined, enables additional animation modes |
+|`RGBLIGHT_EFFECT_BREATHING` |*Not defined*|If defined, enable breathing animation mode. |
+|`RGBLIGHT_EFFECT_RAINBOW_MOOD` |*Not defined*|If defined, enable rainbow mood animation mode. |
+|`RGBLIGHT_EFFECT_RAINBOW_SWIRL` |*Not defined*|If defined, enable rainbow swirl animation mode. |
+|`RGBLIGHT_EFFECT_SNAKE` |*Not defined*|If defined, enable snake animation mode. |
+|`RGBLIGHT_EFFECT_KNIGHT` |*Not defined*|If defined, enable knight animation mode. |
+|`RGBLIGHT_EFFECT_CHRISTMAS` |*Not defined*|If defined, enable christmas animation mode. |
+|`RGBLIGHT_EFFECT_STATIC_GRADIENT` |*Not defined*|If defined, enable static gradient mode. |
+|`RGBLIGHT_EFFECT_RGB_TEST` |*Not defined*|If defined, enable RGB test animation mode. |
+|`RGBLIGHT_EFFECT_ALTERNATING` |*Not defined*|If defined, enable alternating animation mode. |
+|`RGBLIGHT_ANIMATIONS` |*Not defined*|If defined, enables all additional animation modes |
|`RGBLIGHT_EFFECT_BREATHE_CENTER` |`1.85` |Used to calculate the curve for the breathing animation. Valid values are 1.0 to 2.7 |
|`RGBLIGHT_EFFECT_BREATHE_MAX` |`255` |The maximum brightness for the breathing mode. Valid values are 1 to 255 |
|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation |
diff --git a/quantum/quantum.c b/quantum/quantum.c
index ab47fa48f..9d352a94c 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -445,75 +445,97 @@ bool process_record_quantum(keyrecord_t *record) {
return false;
case RGB_MODE_PLAIN:
if (record->event.pressed) {
- rgblight_mode(1);
+ rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
#ifdef SPLIT_KEYBOARD
RGB_DIRTY = true;
#endif
}
return false;
case RGB_MODE_BREATHE:
+ #ifdef RGBLIGHT_EFFECT_BREATHING
if (record->event.pressed) {
- if ((2 <= rgblight_get_mode()) && (rgblight_get_mode() < 5)) {
+ if ((RGBLIGHT_MODE_BREATHING <= rgblight_get_mode()) &&
+ (rgblight_get_mode() < RGBLIGHT_MODE_BREATHING_end)) {
rgblight_step();
} else {
- rgblight_mode(2);
+ rgblight_mode(RGBLIGHT_MODE_BREATHING);
}
}
+ #endif
return false;
case RGB_MODE_RAINBOW:
+ #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
if (record->event.pressed) {
- if ((6 <= rgblight_get_mode()) && (rgblight_get_mode() < 8)) {
+ if ((RGBLIGHT_MODE_RAINBOW_MOOD <= rgblight_get_mode()) &&
+ (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_MOOD_end)) {
rgblight_step();
} else {
- rgblight_mode(6);
+ rgblight_mode(RGBLIGHT_MODE_RAINBOW_MOOD);
}
}
+ #endif
return false;
case RGB_MODE_SWIRL:
+ #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
if (record->event.pressed) {
- if ((9 <= rgblight_get_mode()) && (rgblight_get_mode() < 14)) {
+ if ((RGBLIGHT_MODE_RAINBOW_SWIRL <= rgblight_get_mode()) &&
+ (rgblight_get_mode() < RGBLIGHT_MODE_RAINBOW_SWIRL_end)) {
rgblight_step();
} else {
- rgblight_mode(9);
+ rgblight_mode(RGBLIGHT_MODE_RAINBOW_SWIRL);
}
}
+ #endif
return false;
case RGB_MODE_SNAKE:
+ #ifdef RGBLIGHT_EFFECT_SNAKE
if (record->event.pressed) {
- if ((15 <= rgblight_get_mode()) && (rgblight_get_mode() < 20)) {
+ if ((RGBLIGHT_MODE_SNAKE <= rgblight_get_mode()) &&
+ (rgblight_get_mode() < RGBLIGHT_MODE_SNAKE_end)) {
rgblight_step();
} else {
- rgblight_mode(15);
+ rgblight_mode(RGBLIGHT_MODE_SNAKE);
}
}
+ #endif
return false;
case RGB_MODE_KNIGHT:
+ #ifdef RGBLIGHT_EFFECT_KNIGHT
if (record->event.pressed) {
- if ((21 <= rgblight_get_mode()) && (rgblight_get_mode() < 23)) {
+ if ((RGBLIGHT_MODE_KNIGHT <= rgblight_get_mode()) &&
+ (rgblight_get_mode() < RGBLIGHT_MODE_KNIGHT_end)) {
rgblight_step();
} else {
- rgblight_mode(21);
+ rgblight_mode(RGBLIGHT_MODE_KNIGHT);
}
}
+ #endif
return false;
case RGB_MODE_XMAS:
+ #ifdef RGBLIGHT_EFFECT_CHRISTMAS
if (record->event.pressed) {
- rgblight_mode(24);
+ rgblight_mode(RGBLIGHT_MODE_CHRISTMAS);
}
+ #endif
return false;
case RGB_MODE_GRADIENT:
+ #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
if (record->event.pressed) {
- if ((25 <= rgblight_get_mode()) && (rgblight_get_mode() < 34)) {
+ if ((RGBLIGHT_MODE_STATIC_GRADIENT <= rgblight_get_mode()) &&
+ (rgblight_get_mode() < RGBLIGHT_MODE_STATIC_GRADIENT_end)) {
rgblight_step();
} else {
- rgblight_mode(25);
+ rgblight_mode(RGBLIGHT_MODE_STATIC_GRADIENT);
}
}
+ #endif
return false;
case RGB_MODE_RGBTEST:
+ #ifdef RGBLIGHT_EFFECT_RGB_TEST
if (record->event.pressed) {
- rgblight_mode(35);
+ rgblight_mode(RGBLIGHT_MODE_RGB_TEST);
}
+ #endif
return false;
#endif // defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
#ifdef PROTOCOL_LUFA
diff --git a/quantum/quantum.h b/quantum/quantum.h
index b4e4de174..d1f761f17 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -32,6 +32,12 @@
#endif
#ifdef RGBLIGHT_ENABLE
#include "rgblight.h"
+#else
+ #ifdef RGB_MATRIX_ENABLE
+ /* dummy define RGBLIGHT_MODE_xxxx */
+ #define RGBLIGHT_H_DUMMY_DEFINE
+ #include "rgblight.h"
+ #endif
#endif
#ifdef SPLIT_KEYBOARD
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 4919ae4ab..03f77cc80 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -14,6 +14,7 @@
* along with this program. If not, see .
*/
#include
+#include
#ifdef __AVR__
#include
#include
@@ -29,23 +30,27 @@
#define RGBLIGHT_LIMIT_VAL 255
#endif
+#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_SINGLE_DYNAMIC(sym)
+#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_MULTI_DYNAMIC(sym)
+#define _RGBM_TMP_STATIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_TMP_DYNAMIC(sym)
+static uint8_t static_effect_table [] = {
+#include "rgblight.h"
+};
+
+static inline int is_static_effect(uint8_t mode) {
+ return memchr(static_effect_table, mode, sizeof(static_effect_table)) != NULL;
+}
+
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
-__attribute__ ((weak))
-const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
-__attribute__ ((weak))
-const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
-__attribute__ ((weak))
-const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
-__attribute__ ((weak))
-const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
-__attribute__ ((weak))
-const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
+#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
__attribute__ ((weak))
const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90};
-__attribute__ ((weak))
-const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
+#endif
rgblight_config_t rgblight_config;
@@ -129,7 +134,7 @@ void eeconfig_update_rgblight(uint32_t val) {
void eeconfig_update_rgblight_default(void) {
//dprintf("eeconfig_update_rgblight_default\n");
rgblight_config.enable = 1;
- rgblight_config.mode = 1;
+ rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
rgblight_config.hue = 0;
rgblight_config.sat = 255;
rgblight_config.val = RGBLIGHT_LIMIT_VAL;
@@ -163,9 +168,9 @@ void rgblight_init(void) {
}
eeconfig_debug_rgblight(); // display current eeprom values
- #ifdef RGBLIGHT_ANIMATIONS
+#ifdef RGBLIGHT_USE_TIMER
rgblight_timer_init(); // setup the timer
- #endif
+#endif
if (rgblight_config.enable) {
rgblight_mode_noeeprom(rgblight_config.mode);
@@ -178,9 +183,9 @@ void rgblight_update_dword(uint32_t dword) {
if (rgblight_config.enable)
rgblight_mode(rgblight_config.mode);
else {
- #ifdef RGBLIGHT_ANIMATIONS
+#ifdef RGBLIGHT_USE_TIMER
rgblight_timer_disable();
- #endif
+#endif
rgblight_set();
}
}
@@ -195,7 +200,7 @@ void rgblight_increase(void) {
void rgblight_decrease(void) {
uint8_t mode = 0;
// Mode will never be < 1. If it ever is, eeprom needs to be initialized.
- if (rgblight_config.mode > 1) {
+ if (rgblight_config.mode > RGBLIGHT_MODE_STATIC_LIGHT) {
mode = rgblight_config.mode - 1;
}
rgblight_mode(mode);
@@ -229,8 +234,8 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
if (!rgblight_config.enable) {
return;
}
- if (mode < 1) {
- rgblight_config.mode = 1;
+ if (mode < RGBLIGHT_MODE_STATIC_LIGHT) {
+ rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT;
} else if (mode > RGBLIGHT_MODES) {
rgblight_config.mode = RGBLIGHT_MODES;
} else {
@@ -242,30 +247,14 @@ void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) {
} else {
xprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode);
}
- if (rgblight_config.mode == 1) {
- #ifdef RGBLIGHT_ANIMATIONS
+ if( is_static_effect(rgblight_config.mode) ) {
+#ifdef RGBLIGHT_USE_TIMER
rgblight_timer_disable();
- #endif
- } else if ((rgblight_config.mode >= 2 && rgblight_config.mode <= 24) ||
- rgblight_config.mode == 35 || rgblight_config.mode == 36) {
- // MODE 2-5, breathing
- // MODE 6-8, rainbow mood
- // MODE 9-14, rainbow swirl
- // MODE 15-20, snake
- // MODE 21-23, knight
- // MODE 24, xmas
- // MODE 35 RGB test
- // MODE 36, alterating
-
- #ifdef RGBLIGHT_ANIMATIONS
+#endif
+ } else {
+#ifdef RGBLIGHT_USE_TIMER
rgblight_timer_enable();
- #endif
- } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) {
- // MODE 25-34, static gradient
-
- #ifdef RGBLIGHT_ANIMATIONS
- rgblight_timer_disable();
- #endif
+#endif
}
rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val);
}
@@ -317,9 +306,9 @@ void rgblight_disable(void) {
rgblight_config.enable = 0;
eeconfig_update_rgblight(rgblight_config.raw);
xprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
- #ifdef RGBLIGHT_ANIMATIONS
- rgblight_timer_disable();
- #endif
+#ifdef RGBLIGHT_USE_TIMER
+ rgblight_timer_disable();
+#endif
wait_ms(50);
rgblight_set();
}
@@ -327,9 +316,9 @@ void rgblight_disable(void) {
void rgblight_disable_noeeprom(void) {
rgblight_config.enable = 0;
xprintf("rgblight disable [noEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable);
- #ifdef RGBLIGHT_ANIMATIONS
+#ifdef RGBLIGHT_USE_TIMER
rgblight_timer_disable();
- #endif
+#endif
_delay_ms(50);
rgblight_set();
}
@@ -419,24 +408,43 @@ void rgblight_sethsv_noeeprom_old(uint16_t hue, uint8_t sat, uint8_t val) {
void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) {
if (rgblight_config.enable) {
- if (rgblight_config.mode == 1) {
+ if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) {
// same static color
LED_TYPE tmp_led;
sethsv(hue, sat, val, &tmp_led);
rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b);
} else {
// all LEDs in same color
- if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
+ if ( 1 == 0 ) { //dummy
+ }
+#ifdef RGBLIGHT_EFFECT_BREATHING
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_BREATHING &&
+ rgblight_config.mode <= RGBLIGHT_MODE_BREATHING_end) {
// breathing mode, ignore the change of val, use in memory value instead
val = rgblight_config.val;
- } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 14) {
- // rainbow mood and rainbow swirl, ignore the change of hue
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_MOOD &&
+ rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_MOOD_end) {
+ // rainbow mood, ignore the change of hue
+ hue = rgblight_config.hue;
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_SWIRL &&
+ rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_SWIRL_end) {
+ // rainbow swirl, ignore the change of hue
hue = rgblight_config.hue;
- } else if (rgblight_config.mode >= 25 && rgblight_config.mode <= 34) {
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_STATIC_GRADIENT &&
+ rgblight_config.mode <= RGBLIGHT_MODE_STATIC_GRADIENT_end) {
// static gradient
uint16_t _hue;
- int8_t direction = ((rgblight_config.mode - 25) % 2) ? -1 : 1;
- uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - 25) / 2]);
+ int8_t direction = ((rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) % 2) ? -1 : 1;
+ uint16_t range = pgm_read_word(&RGBLED_GRADIENT_RANGES[(rgblight_config.mode - RGBLIGHT_MODE_STATIC_GRADIENT) / 2]);
for (uint8_t i = 0; i < RGBLED_NUM; i++) {
_hue = (range / RGBLED_NUM * i * direction + hue + 360) % 360;
dprintf("rgblight rainbow set hsv: %u,%u,%d,%u\n", i, _hue, direction, range);
@@ -444,6 +452,7 @@ void rgblight_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool
}
rgblight_set();
}
+#endif
}
rgblight_config.hue = hue;
rgblight_config.sat = sat;
@@ -528,7 +537,7 @@ void rgblight_set(void) {
}
#endif
-#ifdef RGBLIGHT_ANIMATIONS
+#ifdef RGBLIGHT_USE_TIMER
// Animation timer -- AVR Timer3
void rgblight_timer_init(void) {
@@ -564,41 +573,77 @@ void rgblight_timer_toggle(void) {
void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) {
rgblight_enable();
- rgblight_mode(1);
+ rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT);
rgblight_setrgb(r, g, b);
}
void rgblight_task(void) {
if (rgblight_timer_enabled) {
- // mode = 1, static light, do nothing here
- if (rgblight_config.mode >= 2 && rgblight_config.mode <= 5) {
- // mode = 2 to 5, breathing mode
- rgblight_effect_breathing(rgblight_config.mode - 2);
- } else if (rgblight_config.mode >= 6 && rgblight_config.mode <= 8) {
- // mode = 6 to 8, rainbow mood mod
- rgblight_effect_rainbow_mood(rgblight_config.mode - 6);
- } else if (rgblight_config.mode >= 9 && rgblight_config.mode <= 14) {
- // mode = 9 to 14, rainbow swirl mode
- rgblight_effect_rainbow_swirl(rgblight_config.mode - 9);
- } else if (rgblight_config.mode >= 15 && rgblight_config.mode <= 20) {
- // mode = 15 to 20, snake mode
- rgblight_effect_snake(rgblight_config.mode - 15);
- } else if (rgblight_config.mode >= 21 && rgblight_config.mode <= 23) {
- // mode = 21 to 23, knight mode
- rgblight_effect_knight(rgblight_config.mode - 21);
- } else if (rgblight_config.mode == 24) {
- // mode = 24, christmas mode
+ // static light mode, do nothing here
+ if ( 1 == 0 ) { //dummy
+ }
+#ifdef RGBLIGHT_EFFECT_BREATHING
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_BREATHING &&
+ rgblight_config.mode <= RGBLIGHT_MODE_BREATHING_end) {
+ // breathing mode
+ rgblight_effect_breathing(rgblight_config.mode - RGBLIGHT_MODE_BREATHING );
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_MOOD &&
+ rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_MOOD_end) {
+ // rainbow mood mode
+ rgblight_effect_rainbow_mood(rgblight_config.mode - RGBLIGHT_MODE_RAINBOW_MOOD);
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_RAINBOW_SWIRL &&
+ rgblight_config.mode <= RGBLIGHT_MODE_RAINBOW_SWIRL_end) {
+ // rainbow swirl mode
+ rgblight_effect_rainbow_swirl(rgblight_config.mode - RGBLIGHT_MODE_RAINBOW_SWIRL);
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_SNAKE
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_SNAKE &&
+ rgblight_config.mode <= RGBLIGHT_MODE_SNAKE_end) {
+ // snake mode
+ rgblight_effect_snake(rgblight_config.mode - RGBLIGHT_MODE_SNAKE);
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_KNIGHT
+ else if (rgblight_config.mode >= RGBLIGHT_MODE_KNIGHT &&
+ rgblight_config.mode <= RGBLIGHT_MODE_KNIGHT_end) {
+ // knight mode
+ rgblight_effect_knight(rgblight_config.mode - RGBLIGHT_MODE_KNIGHT);
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_CHRISTMAS
+ else if (rgblight_config.mode == RGBLIGHT_MODE_CHRISTMAS) {
+ // christmas mode
rgblight_effect_christmas();
- } else if (rgblight_config.mode == 35) {
- // mode = 35, RGB test
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_RGB_TEST
+ else if (rgblight_config.mode == RGBLIGHT_MODE_RGB_TEST) {
+ // RGB test mode
rgblight_effect_rgbtest();
- } else if (rgblight_config.mode == 36){
+ }
+#endif
+#ifdef RGBLIGHT_EFFECT_ALTERNATING
+ else if (rgblight_config.mode == RGBLIGHT_MODE_ALTERNATING){
rgblight_effect_alternating();
}
+#endif
}
}
+#endif /* RGBLIGHT_USE_TIMER */
+
// Effects
+#ifdef RGBLIGHT_EFFECT_BREATHING
+__attribute__ ((weak))
+const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5};
+
void rgblight_effect_breathing(uint8_t interval) {
static uint8_t pos = 0;
static uint16_t last_timer = 0;
@@ -609,12 +654,17 @@ void rgblight_effect_breathing(uint8_t interval) {
}
last_timer = timer_read();
-
// http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/
val = (exp(sin((pos/255.0)*M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)*(RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E));
rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val);
pos = (pos + 1) % 256;
}
+#endif
+
+#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
+__attribute__ ((weak))
+const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30};
+
void rgblight_effect_rainbow_mood(uint8_t interval) {
static uint16_t current_hue = 0;
static uint16_t last_timer = 0;
@@ -626,6 +676,12 @@ void rgblight_effect_rainbow_mood(uint8_t interval) {
rgblight_sethsv_noeeprom_old(current_hue, rgblight_config.sat, rgblight_config.val);
current_hue = (current_hue + 1) % 360;
}
+#endif
+
+#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
+__attribute__ ((weak))
+const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20};
+
void rgblight_effect_rainbow_swirl(uint8_t interval) {
static uint16_t current_hue = 0;
static uint16_t last_timer = 0;
@@ -651,6 +707,12 @@ void rgblight_effect_rainbow_swirl(uint8_t interval) {
}
}
}
+#endif
+
+#ifdef RGBLIGHT_EFFECT_SNAKE
+__attribute__ ((weak))
+const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20};
+
void rgblight_effect_snake(uint8_t interval) {
static uint8_t pos = 0;
static uint16_t last_timer = 0;
@@ -689,6 +751,12 @@ void rgblight_effect_snake(uint8_t interval) {
pos = (pos + 1) % RGBLED_NUM;
}
}
+#endif
+
+#ifdef RGBLIGHT_EFFECT_KNIGHT
+__attribute__ ((weak))
+const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31};
+
void rgblight_effect_knight(uint8_t interval) {
static uint16_t last_timer = 0;
if (timer_elapsed(last_timer) < pgm_read_byte(&RGBLED_KNIGHT_INTERVALS[interval])) {
@@ -730,8 +798,9 @@ void rgblight_effect_knight(uint8_t interval) {
increment = -increment;
}
}
+#endif
-
+#ifdef RGBLIGHT_EFFECT_CHRISTMAS
void rgblight_effect_christmas(void) {
static uint16_t current_offset = 0;
static uint16_t last_timer = 0;
@@ -748,6 +817,11 @@ void rgblight_effect_christmas(void) {
}
rgblight_set();
}
+#endif
+
+#ifdef RGBLIGHT_EFFECT_RGB_TEST
+__attribute__ ((weak))
+const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024};
void rgblight_effect_rgbtest(void) {
static uint8_t pos = 0;
@@ -774,7 +848,9 @@ void rgblight_effect_rgbtest(void) {
rgblight_setrgb(r, g, b);
pos = (pos + 1) % 3;
}
+#endif
+#ifdef RGBLIGHT_EFFECT_ALTERNATING
void rgblight_effect_alternating(void){
static uint16_t last_timer = 0;
static uint16_t pos = 0;
@@ -795,5 +871,4 @@ void rgblight_effect_alternating(void){
rgblight_set();
pos = (pos + 1) % 2;
}
-
-#endif /* RGBLIGHT_ANIMATIONS */
+#endif
diff --git a/quantum/rgblight.h b/quantum/rgblight.h
index ba010dfae..d1e00eef3 100644
--- a/quantum/rgblight.h
+++ b/quantum/rgblight.h
@@ -16,11 +16,23 @@
#ifndef RGBLIGHT_H
#define RGBLIGHT_H
-#ifdef RGBLIGHT_ANIMATIONS
- #define RGBLIGHT_MODES 36
-#else
- #define RGBLIGHT_MODES 1
-#endif
+#include "rgblight_reconfig.h"
+
+#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_TMP_STATIC(sym) RGBLIGHT_MODE_ ## sym,
+#define _RGBM_TMP_DYNAMIC(sym) RGBLIGHT_MODE_ ## sym,
+enum RGBLIGHT_EFFECT_MODE {
+ RGBLIGHT_MODE_zero = 0,
+#include "rgblight.h"
+ RGBLIGHT_MODE_last
+};
+
+#ifndef RGBLIGHT_H_DUMMY_DEFINE
+
+#define RGBLIGHT_MODES (RGBLIGHT_MODE_last-1)
#ifndef RGBLIGHT_EFFECT_BREATHE_CENTER
#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1-2.7
@@ -168,4 +180,69 @@ void rgblight_effect_christmas(void);
void rgblight_effect_rgbtest(void);
void rgblight_effect_alternating(void);
+#endif // #ifndef RGBLIGHT_H_DUMMY_DEFINE
+#endif // RGBLIGHT_H
+
+#ifdef _RGBM_SINGLE_STATIC
+ _RGBM_SINGLE_STATIC( STATIC_LIGHT )
+ #ifdef RGBLIGHT_EFFECT_BREATHING
+ _RGBM_MULTI_DYNAMIC( BREATHING )
+ _RGBM_TMP_DYNAMIC( breathing_3 )
+ _RGBM_TMP_DYNAMIC( breathing_4 )
+ _RGBM_TMP_DYNAMIC( BREATHING_end )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD
+ _RGBM_MULTI_DYNAMIC( RAINBOW_MOOD )
+ _RGBM_TMP_DYNAMIC( rainbow_mood_7 )
+ _RGBM_TMP_DYNAMIC( RAINBOW_MOOD_end )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL
+ _RGBM_MULTI_DYNAMIC( RAINBOW_SWIRL )
+ _RGBM_TMP_DYNAMIC( rainbow_swirl_10 )
+ _RGBM_TMP_DYNAMIC( rainbow_swirl_11 )
+ _RGBM_TMP_DYNAMIC( rainbow_swirl_12 )
+ _RGBM_TMP_DYNAMIC( rainbow_swirl_13 )
+ _RGBM_TMP_DYNAMIC( RAINBOW_SWIRL_end )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_SNAKE
+ _RGBM_MULTI_DYNAMIC( SNAKE )
+ _RGBM_TMP_DYNAMIC( snake_16 )
+ _RGBM_TMP_DYNAMIC( snake_17 )
+ _RGBM_TMP_DYNAMIC( snake_18 )
+ _RGBM_TMP_DYNAMIC( snake_19 )
+ _RGBM_TMP_DYNAMIC( SNAKE_end )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_KNIGHT
+ _RGBM_MULTI_DYNAMIC( KNIGHT )
+ _RGBM_TMP_DYNAMIC( knight_22 )
+ _RGBM_TMP_DYNAMIC( KNIGHT_end )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_CHRISTMAS
+ _RGBM_SINGLE_DYNAMIC( CHRISTMAS )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT
+ _RGBM_MULTI_STATIC( STATIC_GRADIENT )
+ _RGBM_TMP_STATIC( static_gradient_26 )
+ _RGBM_TMP_STATIC( static_gradient_27 )
+ _RGBM_TMP_STATIC( static_gradient_28 )
+ _RGBM_TMP_STATIC( static_gradient_29 )
+ _RGBM_TMP_STATIC( static_gradient_30 )
+ _RGBM_TMP_STATIC( static_gradient_31 )
+ _RGBM_TMP_STATIC( static_gradient_32 )
+ _RGBM_TMP_STATIC( static_gradient_33 )
+ _RGBM_TMP_STATIC( STATIC_GRADIENT_end )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_RGB_TEST
+ _RGBM_SINGLE_DYNAMIC( RGB_TEST )
+ #endif
+ #ifdef RGBLIGHT_EFFECT_ALTERNATING
+ _RGBM_SINGLE_DYNAMIC( ALTERNATING )
+ #endif
#endif
+
+#undef _RGBM_SINGLE_STATIC
+#undef _RGBM_SINGLE_DYNAMIC
+#undef _RGBM_MULTI_STATIC
+#undef _RGBM_MULTI_DYNAMIC
+#undef _RGBM_TMP_STATIC
+#undef _RGBM_TMP_DYNAMIC
diff --git a/quantum/rgblight_reconfig.h b/quantum/rgblight_reconfig.h
new file mode 100644
index 000000000..11bd4fd11
--- /dev/null
+++ b/quantum/rgblight_reconfig.h
@@ -0,0 +1,36 @@
+#ifndef RGBLIGHT_RECONFIG_H
+#define RGBLIGHT_RECONFIG_H
+
+#ifdef RGBLIGHT_ANIMATIONS
+ // for backward compatibility
+ #define RGBLIGHT_EFFECT_BREATHING
+ #define RGBLIGHT_EFFECT_RAINBOW_MOOD
+ #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+ #define RGBLIGHT_EFFECT_SNAKE
+ #define RGBLIGHT_EFFECT_KNIGHT
+ #define RGBLIGHT_EFFECT_CHRISTMAS
+ #define RGBLIGHT_EFFECT_STATIC_GRADIENT
+ #define RGBLIGHT_EFFECT_RGB_TEST
+ #define RGBLIGHT_EFFECT_ALTERNATING
+#endif
+
+#ifdef RGBLIGHT_STATIC_PATTERNS
+ #define RGBLIGHT_EFFECT_STATIC_GRADIENT
+#endif
+
+// check dynamic animation effects chose ?
+#if defined(RGBLIGHT_EFFECT_BREATHING) || \
+ defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || \
+ defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || \
+ defined(RGBLIGHT_EFFECT_SNAKE) || \
+ defined(RGBLIGHT_EFFECT_KNIGHT) || \
+ defined(RGBLIGHT_EFFECT_CHRISTMAS) || \
+ defined(RGBLIGHT_EFFECT_RGB_TEST) || \
+ defined(RGBLIGHT_EFFECT_ALTERNATING)
+ #define RGBLIGHT_USE_TIMER
+ #ifndef RGBLIGHT_ANIMATIONS
+ #define RGBLIGHT_ANIMATIONS // for backward compatibility
+ #endif
+#endif
+
+#endif // RGBLIGHT_RECONFIG_H
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 73fdda6cc..d7a7f049c 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -10,6 +10,7 @@
#include "timer.h"
#include "led.h"
#include "host.h"
+#include "rgblight_reconfig.h"
#ifdef PROTOCOL_LUFA
#include "lufa.h"
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index cb918d3dc..95e0b95b2 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -54,6 +54,7 @@
#include "quantum.h"
#include
#include "outputselect.h"
+#include "rgblight_reconfig.h"
#ifdef NKRO_ENABLE
#include "keycode_config.h"
--
cgit v1.2.3-70-g09d2
From 48a992f1c037658bbacccefd2709ffdcda8bb345 Mon Sep 17 00:00:00 2001
From: Wilba6582
Date: Fri, 14 Sep 2018 04:37:13 +1000
Subject: Zeal60/Zeal65/M60-A implementation (#3879)
* Initial version of zeal60
* WIP
* Fixes issue #900
* Adding RGB underglow functionality.
Fixed a compile-time conflict caused by enabling RGB underglow functionality.
* Refactor RPC protocol
* Fix last merge
* README for RGB underglow updated.
* Additional README changes.
* Adding RGBW strip software-based current-limiting functionality.
* RGBW current-limiting functionality should be handled by RGBSTRIP_MAX_CURRENT_PER_LIGHT instead.
* Updated README to reflect implementation of built-in current limiting.
* Keymap readability improvements.
* Minor keymap improvements.
* Fixed LED driver init sequence, formatting
* Dimming implementation tested, working.
* Stab LEDs synced with spacebar hits in effects.
* RGB underglow tested and functional. Simplified README for RGB underglow.
* Undid accidental file deletion from previous merge conflict. Safer values for RGB underglow.
* Improved arrow key positions in keymap.
* Added functionality to correct uneven RGB underglow. Refactored related code.
* Reverted to safer values for underglow.
* Changes for v0.3
* Custom LED brightness scaling will take place after current adjustment in order to avoid being overridden.
* Create keymap.c
Added split backspace and split shift to ISO layout
* Create config.h
Turned on LEDs for new layout
* Fixed bug where left spacebar stabilizer LED (LC06) would adopt color of row above.
* Added hhkb_wilba keymap
* Update keymap.c
* Update keymap.c
* Update keymap.c
* Added indicators, full param setting via host
* Added "mousekey" layout
* Added Zeal65 support, factory test mode
* Keycode safe range changed, caused bugs
* Bumped EEPROM version due to change in QMK keycodes
* Disable HHKB "blocked" LEDs if KC_NO in keymap
* Added "disable_hhkb_blocker_leds"
* Required overridden function for keymaps in EEPROM
* Added polar coordinate mapping, effect speed
* Force Raw HID interface number to 1 always
* Fixed last merge from master
* Added effect speed to default keymaps
* add BACKLIGHT_ prefix to vars
* add BACKLIGHT_ prefix to vars
* Keymap speed effect; keymap improvements/fixes
Readme updated to match changes
* Refactored to use common IS31FL3731/I2C drivers
* Fixed make rules, backlight disabled feature
* Make split rightshift default for Zeal65
* Added M60-A as a "version" of Zeal60.
* Renamed IS31FL3731 driver functions
* Fix suspend_wakeup_init_kb() being defined twice
* First pass refactor dynamic keymaps
* Updated to changed I2C and ISSI drivers
* Refactor zeal_color.* usage to quantum/color.*
* Updated Zeal65, fixed dynamic_keymap
* Major refactoring of Zeal60 backlight and API
* Lots of little cleanups
* Added readme.md
* Added readme.md
* Added LAYOUT_60*() macros, refactored and cleaned up default keymaps
* Fix compile error in suspend.c
* Added Zeal65 LAYOUT macros, info.json
* Added rama/m60_a, deleted zeal60/keymaps/m60_a
* Fixed rama/m60_a/keymaps/proto
* Fixed compilation error for suspend.c
* Requested changes for PR
* Fixed readme.md images
* Another readme.md fix
* Added drashna's requested changes
---
common_features.mk | 5 +
keyboards/rama/m60_a/config.h | 128 ++
keyboards/rama/m60_a/info.json | 13 +
keyboards/rama/m60_a/keymaps/default/keymap.c | 40 +
keyboards/rama/m60_a/keymaps/proto/config.h | 5 +
keyboards/rama/m60_a/keymaps/proto/keymap.c | 40 +
keyboards/rama/m60_a/m60_a.c | 18 +
keyboards/rama/m60_a/m60_a.h | 37 +
keyboards/rama/m60_a/readme.md | 15 +
keyboards/rama/m60_a/rules.mk | 79 +
keyboards/zeal60/config.h | 125 ++
keyboards/zeal60/info.json | 25 +
.../zeal60/keymaps/ansi_split_bs_rshift/config.h | 21 +
.../zeal60/keymaps/ansi_split_bs_rshift/keymap.c | 38 +
keyboards/zeal60/keymaps/default/config.h | 20 +
keyboards/zeal60/keymaps/default/keymap.c | 38 +
keyboards/zeal60/keymaps/hhkb/config.h | 20 +
keyboards/zeal60/keymaps/hhkb/keymap.c | 38 +
keyboards/zeal60/keymaps/iso/config.h | 20 +
keyboards/zeal60/keymaps/iso/keymap.c | 38 +
keyboards/zeal60/keymaps/ryanmaclean/config.h | 21 +
keyboards/zeal60/keymaps/ryanmaclean/keymap.c | 84 ++
keyboards/zeal60/keymaps/tusing/Makefile | 6 +
keyboards/zeal60/keymaps/tusing/README.md | 80 ++
keyboards/zeal60/keymaps/tusing/config.h | 40 +
keyboards/zeal60/keymaps/tusing/keymap.c | 49 +
keyboards/zeal60/readme.md | 47 +
keyboards/zeal60/rgb_backlight.c | 1519 ++++++++++++++++++++
keyboards/zeal60/rgb_backlight.h | 101 ++
keyboards/zeal60/rgb_backlight_api.h | 42 +
keyboards/zeal60/rgb_backlight_keycodes.h | 34 +
keyboards/zeal60/rules.mk | 78 +
keyboards/zeal60/zeal60.c | 341 +++++
keyboards/zeal60/zeal60.h | 93 ++
keyboards/zeal60/zeal60_api.h | 33 +
keyboards/zeal60/zeal60_keycodes.h | 42 +
keyboards/zeal65/config.h | 125 ++
keyboards/zeal65/info.json | 16 +
keyboards/zeal65/keymaps/default/config.h | 5 +
keyboards/zeal65/keymaps/default/keymap.c | 38 +
keyboards/zeal65/keymaps/split_bs/config.h | 5 +
keyboards/zeal65/keymaps/split_bs/keymap.c | 38 +
keyboards/zeal65/readme.md | 16 +
keyboards/zeal65/rules.mk | 79 +
keyboards/zeal65/zeal65.c | 18 +
keyboards/zeal65/zeal65.h | 50 +
quantum/dynamic_keymap.c | 97 ++
quantum/dynamic_keymap.h | 31 +
tmk_core/common/avr/suspend.c | 37 +-
49 files changed, 3912 insertions(+), 16 deletions(-)
create mode 100644 keyboards/rama/m60_a/config.h
create mode 100644 keyboards/rama/m60_a/info.json
create mode 100644 keyboards/rama/m60_a/keymaps/default/keymap.c
create mode 100644 keyboards/rama/m60_a/keymaps/proto/config.h
create mode 100644 keyboards/rama/m60_a/keymaps/proto/keymap.c
create mode 100644 keyboards/rama/m60_a/m60_a.c
create mode 100644 keyboards/rama/m60_a/m60_a.h
create mode 100644 keyboards/rama/m60_a/readme.md
create mode 100644 keyboards/rama/m60_a/rules.mk
create mode 100644 keyboards/zeal60/config.h
create mode 100644 keyboards/zeal60/info.json
create mode 100644 keyboards/zeal60/keymaps/ansi_split_bs_rshift/config.h
create mode 100644 keyboards/zeal60/keymaps/ansi_split_bs_rshift/keymap.c
create mode 100644 keyboards/zeal60/keymaps/default/config.h
create mode 100644 keyboards/zeal60/keymaps/default/keymap.c
create mode 100644 keyboards/zeal60/keymaps/hhkb/config.h
create mode 100644 keyboards/zeal60/keymaps/hhkb/keymap.c
create mode 100644 keyboards/zeal60/keymaps/iso/config.h
create mode 100644 keyboards/zeal60/keymaps/iso/keymap.c
create mode 100644 keyboards/zeal60/keymaps/ryanmaclean/config.h
create mode 100644 keyboards/zeal60/keymaps/ryanmaclean/keymap.c
create mode 100644 keyboards/zeal60/keymaps/tusing/Makefile
create mode 100644 keyboards/zeal60/keymaps/tusing/README.md
create mode 100644 keyboards/zeal60/keymaps/tusing/config.h
create mode 100644 keyboards/zeal60/keymaps/tusing/keymap.c
create mode 100644 keyboards/zeal60/readme.md
create mode 100644 keyboards/zeal60/rgb_backlight.c
create mode 100644 keyboards/zeal60/rgb_backlight.h
create mode 100644 keyboards/zeal60/rgb_backlight_api.h
create mode 100644 keyboards/zeal60/rgb_backlight_keycodes.h
create mode 100644 keyboards/zeal60/rules.mk
create mode 100644 keyboards/zeal60/zeal60.c
create mode 100644 keyboards/zeal60/zeal60.h
create mode 100644 keyboards/zeal60/zeal60_api.h
create mode 100644 keyboards/zeal60/zeal60_keycodes.h
create mode 100644 keyboards/zeal65/config.h
create mode 100644 keyboards/zeal65/info.json
create mode 100644 keyboards/zeal65/keymaps/default/config.h
create mode 100644 keyboards/zeal65/keymaps/default/keymap.c
create mode 100644 keyboards/zeal65/keymaps/split_bs/config.h
create mode 100644 keyboards/zeal65/keymaps/split_bs/keymap.c
create mode 100644 keyboards/zeal65/readme.md
create mode 100644 keyboards/zeal65/rules.mk
create mode 100644 keyboards/zeal65/zeal65.c
create mode 100644 keyboards/zeal65/zeal65.h
create mode 100644 quantum/dynamic_keymap.c
create mode 100644 quantum/dynamic_keymap.h
(limited to 'tmk_core/common')
diff --git a/common_features.mk b/common_features.mk
index e0d4ca297..c637582d4 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -227,6 +227,11 @@ ifeq ($(strip $(HD44780_ENABLE)), yes)
OPT_DEFS += -DHD44780_ENABLE
endif
+ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
+ OPT_DEFS += -DDYNAMIC_KEYMAP_ENABLE
+ SRC += $(QUANTUM_DIR)/dynamic_keymap.c
+endif
+
QUANTUM_SRC:= \
$(QUANTUM_DIR)/quantum.c \
$(QUANTUM_DIR)/keymap_common.c \
diff --git a/keyboards/rama/m60_a/config.h b/keyboards/rama/m60_a/config.h
new file mode 100644
index 000000000..45e7d8896
--- /dev/null
+++ b/keyboards/rama/m60_a/config.h
@@ -0,0 +1,128 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "config_common.h"
+
+// USB Device descriptor parameter
+#define VENDOR_ID 0xFEED // This is same as Zeal60 for now
+#define PRODUCT_ID 0x6060 // This is same as Zeal60 for now
+#define DEVICE_VER 0x0001
+#define MANUFACTURER RAMA.WORKS
+#define PRODUCT RAMA M60-A
+#define DESCRIPTION RAMA M60-A Keyboard
+
+
+
+// key matrix size
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 14
+
+// Zeal60 PCB default pin-out
+#define MATRIX_ROW_PINS { F0, F1, F4, F6, F7 }
+#define MATRIX_COL_PINS { F5, D5, B1, B2, B3, D3, D2, C7, C6, B6, B5, B4, D7, D6 }
+#define UNUSED_PINS
+
+// IS31FL3731 driver
+#define DRIVER_COUNT 2
+#define DRIVER_LED_TOTAL 72
+
+// COL2ROW or ROW2COL
+#define DIODE_DIRECTION COL2ROW
+
+// Set 0 if debouncing isn't needed
+#define DEBOUNCING_DELAY 5
+
+// 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
+
+// key combination for command
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+/*
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ */
+
+// disable debug print
+//#define NO_DEBUG
+
+// disable print
+//#define NO_PRINT
+
+// disable action features
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
+
+#define RGB_BACKLIGHT_ENABLED 1
+
+// This conditionally compiles the backlight code for M60-A specifics
+#define RGB_BACKLIGHT_M60_A
+
+// enable/disable LEDs based on layout
+// they aren't really used if RGB_BACKLIGHT_M60_A defined
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 1
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 1
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 1
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 1
+
+// disable backlight when USB suspended (PC sleep/hibernate/shutdown)
+#define RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED 0
+
+// disable backlight after timeout in minutes, 0 = no timeout
+#define RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT 0
+
+// the default effect (RGB test)
+#define RGB_BACKLIGHT_EFFECT 255
+
+// These define which keys in the matrix are alphas/mods
+// Used for backlight effects so colors are different for
+// alphas vs. mods
+// Each value is for a row, bit 0 is column 0
+// Alpha=0 Mod=1
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_0 0b0000000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_1 0b0010000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_2 0b0011000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_3 0b0011000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 0b0011100000000111
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 4
+
+// EEPROM usage
+
+// TODO: refactor with new user EEPROM code (coming soon)
+#define EEPROM_MAGIC 0x451F
+#define EEPROM_MAGIC_ADDR 32
+// Bump this every time we change what we store
+// This will automatically reset the EEPROM with defaults
+// and avoid loading invalid data from the EEPROM
+#define EEPROM_VERSION 0x07
+#define EEPROM_VERSION_ADDR 34
+
+// Backlight config starts after EEPROM version
+#define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR 35
+// Dynamic keymap starts after backlight config (35+37)
+#define DYNAMIC_KEYMAP_EEPROM_ADDR 72
+
diff --git a/keyboards/rama/m60_a/info.json b/keyboards/rama/m60_a/info.json
new file mode 100644
index 000000000..577becd21
--- /dev/null
+++ b/keyboards/rama/m60_a/info.json
@@ -0,0 +1,13 @@
+{
+ "keyboard_name": "M60-A",
+ "url": "",
+ "maintainer": "Wilba",
+ "bootloader": "DFU",
+ "width": 15,
+ "height": 5,
+ "layouts": {
+ "LAYOUT_60_hhkb": {
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"|", "x":13, "y":0}, {"label":"~", "x":14, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"Delete", "x":13.5, "y":1, "w":1.5}, {"label":"Control", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"Fn", "x":14, "y":3}, {"label":"Os", "x":1.5, "y":4}, {"label":"Alt", "x":2.5, "y":4, "w":1.5}, {"x":4, "y":4, "w":7}, {"label":"Alt", "x":11, "y":4, "w":1.5}, {"label":"Os", "x":12.5, "y":4}]
+ }
+ }
+}
\ No newline at end of file
diff --git a/keyboards/rama/m60_a/keymaps/default/keymap.c b/keyboards/rama/m60_a/keymaps/default/keymap.c
new file mode 100644
index 000000000..7b6d9b756
--- /dev/null
+++ b/keyboards/rama/m60_a/keymaps/default/keymap.c
@@ -0,0 +1,40 @@
+// M60-A layout
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_60_hhkb(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, FN_MO13,
+ KC_LGUI, KC_LALT, KC_SPC, KC_RALT, FN_MO23),
+
+// Fn1 Layer
+[1] = LAYOUT_60_hhkb(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL,
+ KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_EJCT, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_60_hhkb(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_60_hhkb(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
+
+
diff --git a/keyboards/rama/m60_a/keymaps/proto/config.h b/keyboards/rama/m60_a/keymaps/proto/config.h
new file mode 100644
index 000000000..54a185ff1
--- /dev/null
+++ b/keyboards/rama/m60_a/keymaps/proto/config.h
@@ -0,0 +1,5 @@
+#pragma once
+
+// This fixes the diodes mounted reversed (fab fail) on M60-A prototype
+#undef DIODE_DIRECTION
+#define DIODE_DIRECTION ROW2COL
diff --git a/keyboards/rama/m60_a/keymaps/proto/keymap.c b/keyboards/rama/m60_a/keymaps/proto/keymap.c
new file mode 100644
index 000000000..7b6d9b756
--- /dev/null
+++ b/keyboards/rama/m60_a/keymaps/proto/keymap.c
@@ -0,0 +1,40 @@
+// M60-A layout
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_60_hhkb(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, FN_MO13,
+ KC_LGUI, KC_LALT, KC_SPC, KC_RALT, FN_MO23),
+
+// Fn1 Layer
+[1] = LAYOUT_60_hhkb(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL,
+ KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_EJCT, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_60_hhkb(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_60_hhkb(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
+
+
diff --git a/keyboards/rama/m60_a/m60_a.c b/keyboards/rama/m60_a/m60_a.c
new file mode 100644
index 000000000..80a98460d
--- /dev/null
+++ b/keyboards/rama/m60_a/m60_a.c
@@ -0,0 +1,18 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * 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 .
+ */
+#ifndef RGB_BACKLIGHT_M60_A
+#error RGB_BACKLIGHT_M60_A not defined, you done goofed somehao, brah
+#endif
diff --git a/keyboards/rama/m60_a/m60_a.h b/keyboards/rama/m60_a/m60_a.h
new file mode 100644
index 000000000..3caab6ac0
--- /dev/null
+++ b/keyboards/rama/m60_a/m60_a.h
@@ -0,0 +1,37 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "quantum.h"
+#include "../../zeal60/rgb_backlight_keycodes.h"
+#include "../../zeal60/zeal60_keycodes.h"
+
+#define XXX KC_NO
+
+#define LAYOUT_60_hhkb( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K2D, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
+ K41, K42, K47, K4B, K4C \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D }, \
+ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
+ { XXX, K41, K42, XXX, XXX, XXX, XXX, K47, XXX, XXX, XXX, K4B, K4C, XXX } \
+}
+
diff --git a/keyboards/rama/m60_a/readme.md b/keyboards/rama/m60_a/readme.md
new file mode 100644
index 000000000..fe54f0163
--- /dev/null
+++ b/keyboards/rama/m60_a/readme.md
@@ -0,0 +1,15 @@
+# RAMA M60-A
+
+![RAMA M60-A](https://static1.squarespace.com/static/563c788ae4b099120ae219e2/t/5aafa6a20e2e7254480b21bf/1535873164793/RAMA-M60-A-03.688.jpg?format=1500w)
+
+The M60-A represents the benchmark and equilibrium between function and design for us at Rama Works. The gently exaggerated design of the frame is not understated, but rather provocative. Inspiration and evolution from previous models are evident in the beautifully articulated design and the well defined aesthetic, the fingerprint of our 'Industrial Modern' designs. The M60-A offers a unique contender in the traditional 60% form factor. [More info at RAMA WORKS](https://rama.works/m60-a/)
+
+Keyboard Maintainer: [Wilba6582](https://github.com/Wilba6582)
+Hardware Supported: RAMA M60-A PCB
+Hardware Availability: [RAMA WORKS Store](https://ramaworks.store/)
+
+Make example for this keyboard (after setting up your build environment):
+
+ make rama/m60_a:default
+
+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).
\ No newline at end of file
diff --git a/keyboards/rama/m60_a/rules.mk b/keyboards/rama/m60_a/rules.mk
new file mode 100644
index 000000000..02617cf1c
--- /dev/null
+++ b/keyboards/rama/m60_a/rules.mk
@@ -0,0 +1,79 @@
+
+
+# project specific files
+SRC = ../zeal60/zeal60.c \
+ ../zeal60/rgb_backlight.c \
+ quantum/color.c \
+ drivers/issi/is31fl3731.c \
+ drivers/avr/i2c_master.c
+
+# MCU name
+MCU = atmega32u4
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# 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.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+F_CPU = 16000000
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+# Boot Section
+BOOTLOADER = atmel-dfu
+
+# Do not put the microcontroller into power saving mode
+# when we get USB suspend event. We want it to keep updating
+# backlight effects.
+OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
+
+# Build Options
+# change to "no" to disable the options, or define them in the Makefile in
+# the appropriate keymap folder that will get included automatically
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = no # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
+CONSOLE_ENABLE = no # Console for debug(+400)
+COMMAND_ENABLE = no # Commands for debug and configuration
+NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+MIDI_ENABLE = no # MIDI controls
+AUDIO_ENABLE = no # Audio output on port C6
+UNICODE_ENABLE = no # Unicode
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
+
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+
+RAW_ENABLE = yes
+DYNAMIC_KEYMAP_ENABLE = yes
+CIE1931_CURVE = yes
+
diff --git a/keyboards/zeal60/config.h b/keyboards/zeal60/config.h
new file mode 100644
index 000000000..baa4978a8
--- /dev/null
+++ b/keyboards/zeal60/config.h
@@ -0,0 +1,125 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "config_common.h"
+
+// USB Device descriptor parameter
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6060
+#define DEVICE_VER 0x0001
+#define MANUFACTURER ZealPC
+#define PRODUCT Zeal60
+#define DESCRIPTION Zeal60 (QMK Firmware)
+
+// key matrix size
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 14
+
+// Zeal60 PCB default pin-out
+#define MATRIX_ROW_PINS { F0, F1, F4, F6, F7 }
+#define MATRIX_COL_PINS { F5, D5, B1, B2, B3, D3, D2, C7, C6, B6, B5, B4, D7, D6 }
+#define UNUSED_PINS
+
+// IS31FL3731 driver
+#define DRIVER_COUNT 2
+#define DRIVER_LED_TOTAL 72
+
+// COL2ROW or ROW2COL
+#define DIODE_DIRECTION COL2ROW
+
+// Set 0 if debouncing isn't needed
+#define DEBOUNCING_DELAY 5
+
+// 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
+
+// key combination for command
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+/*
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ */
+
+// disable debug print
+//#define NO_DEBUG
+
+// disable print
+//#define NO_PRINT
+
+// disable action features
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
+
+#define RGB_BACKLIGHT_ENABLED 1
+
+// This conditionally compiles the backlight code for Zeal60 specifics
+#define RGB_BACKLIGHT_ZEAL60
+
+// enable/disable LEDs based on layout
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 0
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
+
+// disable backlight when USB suspended (PC sleep/hibernate/shutdown)
+#define RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED 0
+
+// disable backlight after timeout in minutes, 0 = no timeout
+#define RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT 0
+
+// the default effect (RGB test)
+#define RGB_BACKLIGHT_EFFECT 255
+
+// These define which keys in the matrix are alphas/mods
+// Used for backlight effects so colors are different for
+// alphas vs. mods
+// Each value is for a row, bit 0 is column 0
+// Alpha=0 Mod=1
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_0 0b0010000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_1 0b0000000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_2 0b0001000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_3 0b0011000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 0b0011110000000111
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 4
+
+// EEPROM usage
+
+// TODO: refactor with new user EEPROM code (coming soon)
+#define EEPROM_MAGIC 0x451F
+#define EEPROM_MAGIC_ADDR 32
+// Bump this every time we change what we store
+// This will automatically reset the EEPROM with defaults
+// and avoid loading invalid data from the EEPROM
+#define EEPROM_VERSION 0x07
+#define EEPROM_VERSION_ADDR 34
+
+// Backlight config starts after EEPROM version
+#define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR 35
+// Dynamic keymap starts after backlight config (35+37)
+#define DYNAMIC_KEYMAP_EEPROM_ADDR 72
+
diff --git a/keyboards/zeal60/info.json b/keyboards/zeal60/info.json
new file mode 100644
index 000000000..c4234e49a
--- /dev/null
+++ b/keyboards/zeal60/info.json
@@ -0,0 +1,25 @@
+{
+ "keyboard_name": "Zeal60",
+ "url": "",
+ "maintainer": "Wilba",
+ "bootloader": "DFU",
+ "width": 15,
+ "height": 5,
+ "layouts": {
+ "LAYOUT_all": {
+ "layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":1.25}, {"x":1.25, "y":3}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"x":14, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
+ },
+ "LAYOUT_60_ansi": {
+ "layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":2.75}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
+ },
+ "LAYOUT_60_iso": {
+ "layout": [{"label":"\u00ac", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"\"", "x":2, "y":0}, {"label":"\u00a3", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"Enter", "x":13.75, "y":1, "w":1.25, "h":2}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"@", "x":11.75, "y":2}, {"label":"~", "x":12.75, "y":2}, {"label":"Shift", "x":0, "y":3, "w":1.25}, {"label":"|", "x":1.25, "y":3}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":2.75}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"AltGr", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
+ },
+ "LAYOUT_60_ansi_split_bs_rshift": {
+ "layout": [{"label":"~", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"x":14, "y":3}, {"label":"Ctrl", "x":0, "y":4, "w":1.25}, {"label":"Win", "x":1.25, "y":4, "w":1.25}, {"label":"Alt", "x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":6.25}, {"label":"Alt", "x":10, "y":4, "w":1.25}, {"label":"Win", "x":11.25, "y":4, "w":1.25}, {"label":"Menu", "x":12.5, "y":4, "w":1.25}, {"label":"Ctrl", "x":13.75, "y":4, "w":1.25}]
+ },
+ "LAYOUT_60_hhkb": {
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"|", "x":13, "y":0}, {"label":"~", "x":14, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"Delete", "x":13.5, "y":1, "w":1.5}, {"label":"Control", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"Fn", "x":14, "y":3}, {"label":"Os", "x":1.5, "y":4}, {"label":"Alt", "x":2.5, "y":4, "w":1.5}, {"x":4, "y":4, "w":7}, {"label":"Alt", "x":11, "y":4, "w":1.5}, {"label":"Os", "x":12.5, "y":4}]
+ }
+ }
+}
\ No newline at end of file
diff --git a/keyboards/zeal60/keymaps/ansi_split_bs_rshift/config.h b/keyboards/zeal60/keymaps/ansi_split_bs_rshift/config.h
new file mode 100644
index 000000000..011cf5c5a
--- /dev/null
+++ b/keyboards/zeal60/keymaps/ansi_split_bs_rshift/config.h
@@ -0,0 +1,21 @@
+#pragma once
+
+/* enable/disable LEDs based on layout */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_7U_SPACEBAR
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
+
+#undef RGB_BACKLIGHT_USE_ISO_ENTER
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+
+#undef RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
+
diff --git a/keyboards/zeal60/keymaps/ansi_split_bs_rshift/keymap.c b/keyboards/zeal60/keymaps/ansi_split_bs_rshift/keymap.c
new file mode 100644
index 000000000..edb4f256b
--- /dev/null
+++ b/keyboards/zeal60/keymaps/ansi_split_bs_rshift/keymap.c
@@ -0,0 +1,38 @@
+// ANSI split backspace/right shift layout for Zeal60
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_60_ansi_split_bs_rshift(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_DEL,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, FN_MO13,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, FN_MO23, KC_RCTL),
+
+// Fn1 Layer
+[1] = LAYOUT_60_ansi_split_bs_rshift(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL,
+ KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_EJCT, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_60_ansi_split_bs_rshift(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_60_ansi_split_bs_rshift(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/zeal60/keymaps/default/config.h b/keyboards/zeal60/keymaps/default/config.h
new file mode 100644
index 000000000..f8478a3df
--- /dev/null
+++ b/keyboards/zeal60/keymaps/default/config.h
@@ -0,0 +1,20 @@
+#pragma once
+
+/* enable/disable LEDs based on layout */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_7U_SPACEBAR
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
+
+#undef RGB_BACKLIGHT_USE_ISO_ENTER
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+
+#undef RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
diff --git a/keyboards/zeal60/keymaps/default/keymap.c b/keyboards/zeal60/keymaps/default/keymap.c
new file mode 100644
index 000000000..3a13cf4d5
--- /dev/null
+++ b/keyboards/zeal60/keymaps/default/keymap.c
@@ -0,0 +1,38 @@
+// Default layout for Zeal60
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_60_ansi(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, FN_MO13, FN_MO23, KC_RCTL),
+
+// Fn1 Layer
+[1] = LAYOUT_60_ansi(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL ,
+ KC_CAPS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_END, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_60_ansi(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_60_ansi(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/zeal60/keymaps/hhkb/config.h b/keyboards/zeal60/keymaps/hhkb/config.h
new file mode 100644
index 000000000..25f74d3d2
--- /dev/null
+++ b/keyboards/zeal60/keymaps/hhkb/config.h
@@ -0,0 +1,20 @@
+#pragma once
+
+/* enable/disable LEDs based on layout */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 1
+
+#undef RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 1
+
+#undef RGB_BACKLIGHT_USE_7U_SPACEBAR
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 1
+
+#undef RGB_BACKLIGHT_USE_ISO_ENTER
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+
+#undef RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 1
diff --git a/keyboards/zeal60/keymaps/hhkb/keymap.c b/keyboards/zeal60/keymaps/hhkb/keymap.c
new file mode 100644
index 000000000..5cedc6e5e
--- /dev/null
+++ b/keyboards/zeal60/keymaps/hhkb/keymap.c
@@ -0,0 +1,38 @@
+// HHKB layout for Zeal60
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_60_hhkb(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, FN_MO13,
+ KC_LGUI, KC_LALT, KC_SPC, KC_RALT, FN_MO23),
+
+// Fn1 Layer
+[1] = LAYOUT_60_hhkb(
+ KC_PWR, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL,
+ KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_EJCT, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_60_hhkb(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_60_hhkb(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/zeal60/keymaps/iso/config.h b/keyboards/zeal60/keymaps/iso/config.h
new file mode 100644
index 000000000..c96ef1f05
--- /dev/null
+++ b/keyboards/zeal60/keymaps/iso/config.h
@@ -0,0 +1,20 @@
+#pragma once
+
+/* enable/disable LEDs based on layout */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 1
+
+#undef RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_7U_SPACEBAR
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
+
+#undef RGB_BACKLIGHT_USE_ISO_ENTER
+#define RGB_BACKLIGHT_USE_ISO_ENTER 1
+
+#undef RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
diff --git a/keyboards/zeal60/keymaps/iso/keymap.c b/keyboards/zeal60/keymaps/iso/keymap.c
new file mode 100644
index 000000000..55120f05e
--- /dev/null
+++ b/keyboards/zeal60/keymaps/iso/keymap.c
@@ -0,0 +1,38 @@
+// ISO layout for Zeal60
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_60_iso(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_ENT,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS,
+ KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, FN_MO13, FN_MO23, KC_RCTL),
+
+// Fn1 Layer
+[1] = LAYOUT_60_iso(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL ,
+ KC_CAPS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS,
+ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_END, KC_PGDN, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_60_iso(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_60_iso(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, ES_DEC, ES_INC, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/zeal60/keymaps/ryanmaclean/config.h b/keyboards/zeal60/keymaps/ryanmaclean/config.h
new file mode 100644
index 000000000..f1531eb34
--- /dev/null
+++ b/keyboards/zeal60/keymaps/ryanmaclean/config.h
@@ -0,0 +1,21 @@
+#pragma once
+
+/* enable/disable LEDs based on layout */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 1
+
+#undef RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 1
+
+#undef RGB_BACKLIGHT_USE_7U_SPACEBAR
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
+
+#undef RGB_BACKLIGHT_USE_ISO_ENTER
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+
+#undef RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
+
diff --git a/keyboards/zeal60/keymaps/ryanmaclean/keymap.c b/keyboards/zeal60/keymaps/ryanmaclean/keymap.c
new file mode 100644
index 000000000..2e342b497
--- /dev/null
+++ b/keyboards/zeal60/keymaps/ryanmaclean/keymap.c
@@ -0,0 +1,84 @@
+// Ryan MacLean's layout for Zeal60
+// Note that LGUI and RGUI are swapped with LALT and RALT respectively, for use with Macs
+// Also note that Control has replaced Caps Lock, and that pressing left or right shift once
+// will output left parenthese and right parenthese respectively.
+#include QMK_KEYBOARD_H
+
+// [0,13] is either left key of split backspace (e.g. HHKB \| key) or 2U backspace
+// [1,13] is either backslash or ISO Enter
+// [2,12] is either ANSI Enter or key left of ISO Enter
+// [2,13] is right key of split backspace (e.g. HHKB `~ key)
+// [3,1] is right key of split left-shift (e.g ISO key)
+// [3,13] is right key of split right-shift (e.g. HHKB Fn key)
+
+
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) // this is the function signature -- just copy/paste it into your keymap file as it is. KC_LSFT KC_LALT KC_LGUI KC_4
+{
+ switch(id) {
+ case 0: // macOS screenshot to capture are to clipboard - this would trigger when you hit a key mapped as M(0)
+ if (record->event.pressed) {
+ return MACRO( D(LSFT), D(LCTL), D(LGUI), T(4), U(LSFT), U(LCTL), U(LGUI), W(255), END ); // this sends the string 'hello' when the macro executes
+ }
+ break;
+ case 1: // macOS screenshot capture area to file - this would trigger when you hit a key mapped as M(1)
+ if (record->event.pressed) {
+ return MACRO( D(LSFT), D(LGUI), T(4), U(LSFT), U(LGUI), W(255), END ); // this sends the string 'hello' when the macro executes
+ }
+ break;
+ case 2: // macOS screenshot to clipboard - this would trigger when you hit a key mapped as M(2)
+ if (record->event.pressed) {
+ return MACRO( D(LSFT), D(LCTL), D(LGUI), T(3), U(LSFT), U(LCTL), U(LGUI), W(255), END ); // this sends the string 'hello' when the macro executes
+ }
+ break;
+ case 3: // macOS screenshot to file - this would trigger when you hit a key mapped as M(3)
+ if (record->event.pressed) {
+ return MACRO( D(LSFT), D(LGUI), T(3), U(LSFT), U(LGUI), W(255), END ); // this sends the string 'hello' when the macro executes
+ }
+ break;
+ }
+ return MACRO_NONE;
+};
+
+#define CADETL MT(KC_LSFT, KC_LBRC)
+#define CADETR MT(KC_RSFT, KC_RBRC)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = {
+ {KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS},
+ {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC},
+ {KC_LGUI, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_GRV},
+ {KC_LSPO, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSPC, FN_MO13},
+ {KC_LCTL, KC_LALT, KC_LGUI, KC_NO, KC_NO, KC_NO, KC_NO, KC_SPC, KC_NO, KC_NO, KC_RGUI, KC_RALT, KC_RCTL, FN_MO23}
+},
+
+// Fn1 Layer
+[1] = {
+ {KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS},
+ {KC_CAPS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_INS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_DEL},
+ {KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, KC_HOME, KC_PGUP, KC_TRNS, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_END, KC_PGDN, KC_TRNS, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS}
+},
+
+// Fn2 Layer
+[2] = {
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
+ {KC_TRNS, M(2), M(3), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
+ {KC_TRNS, M(1), M(0), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS}
+},
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = {
+ {KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS},
+ {KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS}
+}
+
+};
diff --git a/keyboards/zeal60/keymaps/tusing/Makefile b/keyboards/zeal60/keymaps/tusing/Makefile
new file mode 100644
index 000000000..762905da0
--- /dev/null
+++ b/keyboards/zeal60/keymaps/tusing/Makefile
@@ -0,0 +1,6 @@
+# Build Options
+# change to "no" to disable the options, or define them in the Makefile in
+# the appropriate keymap folder that will get included automatically
+#
+RGBLIGHT_ENABLE = yes
+AUDIO_ENABLE = no # Underglow cannot be used with audio.
diff --git a/keyboards/zeal60/keymaps/tusing/README.md b/keyboards/zeal60/keymaps/tusing/README.md
new file mode 100644
index 000000000..edddf1c58
--- /dev/null
+++ b/keyboards/zeal60/keymaps/tusing/README.md
@@ -0,0 +1,80 @@
+# RGB Underglow Strip on the Zeal60: A Guide
+
+
+
+## Requirements
+
+- WS2812B RGB strip, preferably 60 LEDs/meter
+- Wire, solder
+- Tape, hot glue, or some sort of adhesive
+
+## A. Connecting the strip
+You might find the [**full PCB image**](https://cdn.shopify.com/s/files/1/0490/7329/files/zeal60jumpers.png) helpful. Ignore the red boxes!
+
+1. Connect V+ to the receiving end of the thermistor labeled F1; connect GND to the board's GND pin. (*Avoid connecting +V to the board's +5V pin* - you will likely overload the thermistor, and you will limit your maximum brightness.)
+
+
+
+2. Connect DI to PB0.
+
+
+
+3. Should look something like this when finished:
+
+
+
+*Optional:* To allow considerably more light to escape, consider angling the strip outwards by using some sort of fulcrum under the strip. (I used a thick wire.)
+
+## B. Enabling the strip
+1. If it is not present already, add the following to your ***keymap's*** ```Makefile```:
+
+ ```Makefile
+ RGBLIGHT_ENABLE = yes
+ AUDIO_ENABLE = no #Underglow animations cannot be used with audio.
+ ```
+2. If it is not present already, add the following to your *keymap's* ```config.h```, and edit the values as necessary:
+
+ ```c
+ // Set up RGB underglow.
+ #define RGB_DI_PIN B0 // The pin your RGB strip is wired to
+ #define RGBLIGHT_ANIMATIONS // Require for fancier stuff (not compatible with audio)
+ #define RGBLED_NUM 35 // Number of LEDs
+ #define RGBLIGHT_HUE_STEP 5 // How much each press of rgb_hue changes hue
+ #define RGBLIGHT_SAT_STEP 10 // How much each press of rgb_sat changes sat
+ #define RGBLIGHT_VAL_STEP 10 // How much each press of rgb_val changes val
+ ```
+3. If they are not present already, add the following keycodes to your keymap to control the RGB strip: ```RGB_TOG``` (on/off), ```RGB_MOD``` (step through modes), ```RGB_HUI```, ```RGB_HUD```, ```RGB_SAI```, ```RGB_SAD```, ```RGB_VAI```, ```RGB_VAD``` (HSV increase/decrease). Add these to your keymap.
+
+## C. Dealing with current limits
+USB 2.0 ports on laptops provide up to 500mA max, but USB 3.0 ports can provide up to 900mA; USB 3.1 up to 1.5A; and powered USB hubs even more. We can run our keyboard at a higher brightness if we draw more power. **The Zeal60 uses 500mA at max brightness.** This means that **you have about 400mA remaining for the strip to use on a USB 3.0 port**; 1000mA free on a USB 3.1 port, so on and so forth.
+
+***Warning:*** **This means you will need to turn *off* your RGB strip before connecting to a USB 2.0 port**, as USB 2.0 cannot sustain the current necessary!
+
+1. If not present already, add the following to your keymap's ```config.h```. Change the numbers based on your needs. The ones below are safe underestimates.
+
+ ```c
+ // Enable current limiting for RGB underglow.
+ #define RGBSTRIP_CURRENT_LIMIT 400 // Strip current limit in mA. (USB amperage - 500mA for keyboard)
+ #define RGBSTRIP_MAX_CURRENT_PER_LIGHT 50 // mA per light when at max brightness.
+ ```
+ *Example:* I use a USB port capable of providing 1800 mA. The keyboard uses 500mA, so my personal value (in the `tusing` keymap) for `RGBSTRIP_CURRENT_LIMIT` is 1300. The particular WS2812B RGB strip I have uses a maximum of 60 mA per LED, so that is my personal value for `RGBSTRIP_MAX_CURRENT_PER_LIGHT`.
+2. Toggle on the LED strip (```RGB_TOG```) and step through animations (```RGB_MOD```) to test it out!
+
+## D. Sources and resources
+### A. Connecting the strip.
+* [In-depth description of connecting an RGB strip to the GH60](https://www.reddit.com/r/MechanicalKeyboards/comments/4d5or2/my_first_custom_build_satan_gh60_rbg_underglow_in/d1nz3o7/)
+* [32U4 Pinout](https://40.media.tumblr.com/93b6bbd4113418c2b45459bb177e67c5/tumblr_mi49a20QMB1s5t695o1_1280.png)
+* [Redditor describes connecting RGB strips on his Satan GH60](https://www.reddit.com/r/MechanicalKeyboards/comments/4hbjw4/finally_finished_my_satan_gh60_also_granite_o/d2qn8zx/?context=3)
+* [Another Redditor on RGB with the Satan GH60](https://www.reddit.com/r/MechanicalKeyboards/comments/4ewzdx/gh60_satan_with_the_rgb_mod/d251uu6/ )
+
+### B. Enabling the strip.
+* [QMK Wiki portion on underglow](https://github.com/jackhumbert/qmk_firmware/wiki#rgb-under-glow-mod)
+* [Planck ```Makefile```, ```config.h```, and ```keymap.c``` config example](https://github.com/jackhumbert/qmk_firmware/tree/master/keyboards/planck/keymaps/yang)
+* [Video demonstrating keycode functions and RGB modes on a KC60](https://www.youtube.com/watch?v=VKrpPAHlisY)
+
+### C. Dealing with current limits.
+* [Discussion of cutting jumpers and adding resistors to lower current from Zeal60](https://www.reddit.com/r/MechanicalKeyboards/comments/5hou92/photos_zeal60_lets_just_say_santa_came_early_this/db23qid/)
+* [A selection of 900mA-1.5A current hold fuses - look for an SMD 0805-sized fuse.](https://goo.gl/748avG)
+* [Video detailing technique to solder 0805 resistors](https://www.youtube.com/watch?v=PU7wLcuqc-I&t=123s&list=FLheMlKEVQ5cmVXazUt6HrxQ&index=2)
+* [QMK feature request to implement max power draw limits in ```config.h```](https://github.com/jackhumbert/qmk_firmware/issues/954)
+* [Commit enabling max power draw limits in ```config.h```](https://github.com/jackhumbert/qmk_firmware/commit/83e613ad239459582ae28f78b6c81535b9b138d7)
\ No newline at end of file
diff --git a/keyboards/zeal60/keymaps/tusing/config.h b/keyboards/zeal60/keymaps/tusing/config.h
new file mode 100644
index 000000000..93f260946
--- /dev/null
+++ b/keyboards/zeal60/keymaps/tusing/config.h
@@ -0,0 +1,40 @@
+#pragma once
+
+/* Enable/disable LEDs based on layout. */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 0
+
+#undef RGB_BACKLIGHT_USE_7U_SPACEBAR
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
+
+#undef RGB_BACKLIGHT_USE_ISO_ENTER
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+
+#undef RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
+
+// Set up RGB underglow.
+#define RGB_DI_PIN B0 // The pin your RGB strip is wired to
+#define RGBLIGHT_ANIMATIONS // Require for fancier stuff (not compatible with audio)
+#define RGBLED_NUM 35 // Number of LEDs
+#define RGBLIGHT_HUE_STEP 5 // How much each press of rgb_hue changes hue
+#define RGBLIGHT_SAT_STEP 10 // How much each press of rgb_sat changes sat
+#define RGBLIGHT_VAL_STEP 10 // How much each press of rgb_val changes val
+
+// Enable current limiting for RGB underglow.
+#define RGBSTRIP_CURRENT_LIMIT 1300 // Strip current limit in mA. (USB amperage - 500mA for keyboard)
+#define RGBSTRIP_MAX_CURRENT_PER_LIGHT 40 // mA per light when at max brightness.
+
+// Scale brightnes according to BRIGHTNESS_CORRECTION_TABLE in quantum/rgblight.c.
+// This allows to mitigate uneven brightness from LED underglow strips.
+// #define LED_BRIGHTNESS_CORRECTION
+
+// Prevent modifiers on layer 1 from persisting after we let go
+#define PREVENT_STUCK_MODIFIERS
+
diff --git a/keyboards/zeal60/keymaps/tusing/keymap.c b/keyboards/zeal60/keymaps/tusing/keymap.c
new file mode 100644
index 000000000..41d2effd4
--- /dev/null
+++ b/keyboards/zeal60/keymaps/tusing/keymap.c
@@ -0,0 +1,49 @@
+// Default layout for Zeal60
+#include QMK_KEYBOARD_H
+
+// For readability.
+#define _______ KC_TRNS
+#define _x_ KC_NO
+#define AUD_PRV LCTL(KC_MPRV) // Previous music track
+#define AUD_PLY LCTL(KC_MPLY) // Pause music
+#define AUD_NXT LCTL(KC_MNXT) // Next music track
+
+// Zeal60-specific keys:
+// EF_INC, EF_DEC, // next/previous backlight effect
+// H1_INC, H1_DEC, // Color 1 hue increase/decrease
+// S1_INC, S1_DEC, // Color 1 saturation increase/decrease
+// H2_INC, H2_DEC, // Color 2 hue increase/decrease
+// S2_INC, S2_DEC, // Color 2 saturation increase/decrease
+// BR_INC, BR_DEC, // backlight brightness increase/decrease
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+// Default layer: Pressing caps-lock momentarily switches to Layer 1.
+// This is the default layer. Pressing an empty keycode on another layer will take you here.
+ [0] = {
+ {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC},
+ {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS},
+ {MO(1), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, _x_ },
+ {KC_LSFT, _x_ , KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, _x_ },
+ {KC_LCTL, KC_LGUI, KC_LALT, _x_ , _x_ , _x_ , _x_ , KC_SPC, _x_ , _x_ , KC_LEFT, KC_UP, KC_DOWN, KC_RGHT}
+ },
+
+// Layer 1: Pressing enter switches to layer 2, where backlight controls live.
+// This is a momentary layer: once you let go of caps, you'll be back in layer 1.
+ [1] = {
+ {KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL },
+ {_______, KC_VOLD, KC_MUTE, KC_VOLU, _______, _______, _______, _______, KC_PSCR, KC_SLCK, KC_PAUS, KC_INS, KC_DEL, _______},
+ {_______, AUD_PRV, AUD_PLY, AUD_NXT, _______, _______, _______, _______, _______, _______, _______, _______, TO(2) , _x_ },
+ {KC_CAPS, _x_ , _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _x_ },
+ {KC_RCTL, KC_RGUI, KC_RALT, _x_ , _x_ , _x_ , _x_ , _______, _x_ , _x_ , KC_HOME, KC_PGUP, KC_PGDN, KC_END}
+ },
+
+// Layer 2: Zeal60 and backlight configuration. (Get here quickly by pressing Caps+Enter from Layer 1.)
+// This is a persistent layer. Get back to the default layer by pressing enter.
+ [2] = {
+ {RESET, EF_DEC, EF_INC, BR_DEC, BR_INC, ES_DEC, ES_INC, _______, _______, _______, _______, _______, _______, _______},
+ {_______, H1_DEC, H1_INC, S1_DEC, S1_INC, _______, _______, _______, _______, _______, _______, _______, _______, _______},
+ {_______, H2_DEC, H2_INC, S2_DEC, S2_INC, _______, _______, _______, _______, _______, _______, _______, TO(0) , _x_ },
+ {RGB_MOD, _x_ , RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, _______, _______, _______, _______, _______, _______, _______, _x_ },
+ {RGB_TOG, RGB_VAD, RGB_VAI, _x_ , _x_ , _x_ , _x_ , _______, _x_ , _x_ , _______, _______, _______, _______}
+ }
+};
diff --git a/keyboards/zeal60/readme.md b/keyboards/zeal60/readme.md
new file mode 100644
index 000000000..9eca28f83
--- /dev/null
+++ b/keyboards/zeal60/readme.md
@@ -0,0 +1,47 @@
+Zeal60
+====
+
+![Zeal60](https://cdn.shopify.com/s/files/1/0490/7329/products/Zeal60.jpg)
+
+This is a 60% PCB with per-key RGB LEDs and supports ANSI, ISO, winkey/winkeyless bottom row, HHKB-layout (split right shift and backspace).
+
+Keyboard Maintainer: [Wilba](http://wilba.tech/) and on [github](https://github.com/Wilba6582)
+Hardware Supported: Zeal60 PCB Rev 0-3
+Hardware Availability: https://zealpc.net/collections/group-buy-pre-orders/products/zeal60rgb
+
+Make example for this keyboard (after setting up your build environment):
+
+ make zeal60:default
+
+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).
+
+
+RGB Backlight Configuration
+====
+
+A keymap (in the keymaps directory) can optionally configure which RGB backlight LEDs are used, depending on the needs of the layout, by adding a config.h file in the keymap's directory.
+The following #define symbols will enable/disable a feature using 1 or 0.
+
+ RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+
+Split backspace is being used, enables the right LED of the split backspace (the top-right corner)
+
+ RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT
+
+Split left shift is being used (i.e. ISO layout), enables the right LED of the split left shift (the ISO key)
+
+ RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT
+
+Split right shift is being used (i.e. HHKB style layouts), enables the right LED of the split right shift (the Fn key)
+
+ RGB_BACKLIGHT_USE_7U_SPACEBAR
+
+A 7U spacebar is being used, controls the LEDs under the right stabilizer (of 7U spacebar) and right Alt (if 6.25U spacebar).
+
+ RGB_BACKLIGHT_USE_ISO_ENTER
+
+An ISO Enter is being used. Only used to tweak the location of the LED being used under ANSI Enter/backslash
+
+ RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS
+
+Disables the LEDs under HHKB corner blockers, useful for transparent cases.
diff --git a/keyboards/zeal60/rgb_backlight.c b/keyboards/zeal60/rgb_backlight.c
new file mode 100644
index 000000000..9f62a8d38
--- /dev/null
+++ b/keyboards/zeal60/rgb_backlight.c
@@ -0,0 +1,1519 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * 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 .
+ */
+#if RGB_BACKLIGHT_ENABLED
+
+#if defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_ZEAL65) || defined (RGB_BACKLIGHT_M60_A)
+#else
+#error None of the following was defined: RGB_BACKLIGHT_ZEAL60, RGB_BACKLIGHT_ZEAL65, RGB_BACKLIGHT_M60_A
+#endif
+
+#include "zeal60.h"
+#include "rgb_backlight.h"
+#include "rgb_backlight_api.h"
+#include "rgb_backlight_keycodes.h"
+
+#include
+#include
+#include
+#include "progmem.h"
+
+#include "quantum/color.h"
+#include "drivers/avr/i2c_master.h"
+#include "drivers/issi/is31fl3731.h"
+
+#define BACKLIGHT_EFFECT_MAX 10
+
+backlight_config g_config = {
+ .use_split_backspace = RGB_BACKLIGHT_USE_SPLIT_BACKSPACE,
+ .use_split_left_shift = RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT,
+ .use_split_right_shift = RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT,
+ .use_7u_spacebar = RGB_BACKLIGHT_USE_7U_SPACEBAR,
+ .use_iso_enter = RGB_BACKLIGHT_USE_ISO_ENTER,
+ .disable_hhkb_blocker_leds = RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS,
+ .disable_when_usb_suspended = RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED,
+ .disable_after_timeout = RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT,
+ .brightness = 255,
+ .effect = RGB_BACKLIGHT_EFFECT,
+ .effect_speed = 0,
+ .color_1 = { .h = 0, .s = 255, .v = 255 },
+ .color_2 = { .h = 127, .s = 255, .v = 255 },
+ .caps_lock_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
+ .layer_1_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
+ .layer_2_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
+ .layer_3_indicator = { .color = { .h = 0, .s = 0, .v = 255 }, .index = 255 },
+ .alphas_mods = {
+ RGB_BACKLIGHT_ALPHAS_MODS_ROW_0,
+ RGB_BACKLIGHT_ALPHAS_MODS_ROW_1,
+ RGB_BACKLIGHT_ALPHAS_MODS_ROW_2,
+ RGB_BACKLIGHT_ALPHAS_MODS_ROW_3,
+ RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 }
+};
+
+bool g_suspend_state = false;
+uint8_t g_indicator_state = 0;
+
+// Global tick at 20 Hz
+uint32_t g_tick = 0;
+
+// Ticks since this key was last hit.
+uint8_t g_key_hit[72];
+
+// Ticks since any key was last hit.
+uint32_t g_any_key_hit = 0;
+
+// This is a 7-bit address, that gets left-shifted and bit 0
+// set to 0 for write, 1 for read (as per I2C protocol)
+#define ISSI_ADDR_1 0x74
+#define ISSI_ADDR_2 0x76
+
+const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
+/* Refer to IS31 manual for these locations
+ * driver
+ * | R location
+ * | | G location
+ * | | | B location
+ * | | | | */
+ {0, C2_1, C3_1, C4_1}, // LA0
+ {0, C1_1, C3_2, C4_2}, // LA1
+ {0, C1_2, C2_2, C4_3}, // LA2
+ {0, C1_3, C2_3, C3_3}, // LA3
+ {0, C1_4, C2_4, C3_4}, // LA4
+ {0, C1_5, C2_5, C3_5}, // LA5
+ {0, C1_6, C2_6, C3_6}, // LA6
+ {0, C1_7, C2_7, C3_7}, // LA7
+ {0, C1_8, C2_8, C3_8}, // LA8
+ {0, C9_1, C8_1, C7_1}, // LA9
+ {0, C9_2, C8_2, C7_2}, // LA10
+ {0, C9_3, C8_3, C7_3}, // LA11
+ {0, C9_4, C8_4, C7_4}, // LA12
+ {0, C9_5, C8_5, C7_5}, // LA13
+ {0, C9_6, C8_6, C7_6}, // LA14
+ {0, C9_7, C8_7, C6_6}, // LA15
+ {0, C9_8, C7_7, C6_7}, // LA16
+ {0, C8_8, C7_8, C6_8}, // LA17
+
+ {0, C2_9, C3_9, C4_9}, // LB0
+ {0, C1_9, C3_10, C4_10}, // LB1
+ {0, C1_10, C2_10, C4_11}, // LB2
+ {0, C1_11, C2_11, C3_11}, // LB3
+ {0, C1_12, C2_12, C3_12}, // LB4
+ {0, C1_13, C2_13, C3_13}, // LB5
+ {0, C1_14, C2_14, C3_14}, // LB6
+ {0, C1_15, C2_15, C3_15}, // LB7
+ {0, C1_16, C2_16, C3_16}, // LB8
+ {0, C9_9, C8_9, C7_9}, // LB9
+ {0, C9_10, C8_10, C7_10}, // LB10
+ {0, C9_11, C8_11, C7_11}, // LB11
+ {0, C9_12, C8_12, C7_12}, // LB12
+ {0, C9_13, C8_13, C7_13}, // LB13
+ {0, C9_14, C8_14, C7_14}, // LB14
+ {0, C9_15, C8_15, C6_14}, // LB15
+ {0, C9_16, C7_15, C6_15}, // LB16
+ {0, C8_16, C7_16, C6_16}, // LB17
+
+ {1, C2_1, C3_1, C4_1}, // LC0
+ {1, C1_1, C3_2, C4_2}, // LC1
+ {1, C1_2, C2_2, C4_3}, // LC2
+ {1, C1_3, C2_3, C3_3}, // LC3
+ {1, C1_4, C2_4, C3_4}, // LC4
+ {1, C1_5, C2_5, C3_5}, // LC5
+ {1, C1_6, C2_6, C3_6}, // LC6
+ {1, C1_7, C2_7, C3_7}, // LC7
+ {1, C1_8, C2_8, C3_8}, // LC8
+ {1, C9_1, C8_1, C7_1}, // LC9
+ {1, C9_2, C8_2, C7_2}, // LC10
+ {1, C9_3, C8_3, C7_3}, // LC11
+ {1, C9_4, C8_4, C7_4}, // LC12
+ {1, C9_5, C8_5, C7_5}, // LC13
+ {1, C9_6, C8_6, C7_6}, // LC14
+ {1, C9_7, C8_7, C6_6}, // LC15
+ {1, C9_8, C7_7, C6_7}, // LC16
+ {1, C8_8, C7_8, C6_8}, // LC17
+
+ {1, C2_9, C3_9, C4_9}, // LD0
+ {1, C1_9, C3_10, C4_10}, // LD1
+ {1, C1_10, C2_10, C4_11}, // LD2
+ {1, C1_11, C2_11, C3_11}, // LD3
+ {1, C1_12, C2_12, C3_12}, // LD4
+ {1, C1_13, C2_13, C3_13}, // LD5
+ {1, C1_14, C2_14, C3_14}, // LD6
+ {1, C1_15, C2_15, C3_15}, // LD7
+ {1, C1_16, C2_16, C3_16}, // LD8
+ {1, C9_9, C8_9, C7_9}, // LD9
+ {1, C9_10, C8_10, C7_10}, // LD10
+ {1, C9_11, C8_11, C7_11}, // LD11
+ {1, C9_12, C8_12, C7_12}, // LD12
+ {1, C9_13, C8_13, C7_13}, // LD13
+ {1, C9_14, C8_14, C7_14}, // LD14
+ {1, C9_15, C8_15, C6_14}, // LD15
+ {1, C9_16, C7_15, C6_15}, // LD16
+ {1, C8_16, C7_16, C6_16}, // LD17
+};
+
+
+
+typedef struct Point {
+ uint8_t x;
+ uint8_t y;
+} Point;
+
+
+// index in range 0..71 (LA0..LA17, LB0..LB17, LC0..LC17, LD0..LD17)
+// point values in range x=0..224 y=0..64
+// origin is center of top-left key (i.e Esc)
+#if defined (RGB_BACKLIGHT_ZEAL65)
+const Point g_map_led_to_point[72] PROGMEM = {
+ // LA0..LA17
+ {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
+ {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
+ // LB0..LB17
+ {144,0}, {160,0}, {176,0}, {192,0}, {216,0}, {224,0}, {240,0}, {240,16}, {240,32},
+ {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {240,48}, {240,64}, {224,64},
+ // LC0..LC17
+ {96,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {255,255}, {48,60}, {28,64},
+ {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {20,44}, {10,48}, {4,64},
+ // LD0..LD17
+ {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {202,48}, {224,48},
+ {116,48}, {132,48}, {148,48}, {164,48}, {255,255}, {144,60}, {164,64}, {188,64}, {208,64}
+};
+const Point g_map_led_to_point_polar[72] PROGMEM = {
+ // LA0..LA17
+ {64,128}, {75,132}, {84,145}, {91,164}, {97,187}, {102,213}, {105,242}, {109,255}, {128,247},
+ {61,255}, {67,255}, {72,255}, {77,255}, {82,255}, {86,255}, {90,255}, {93,255}, {96,255},
+ // LB0..LB17
+ {56,255}, {51,255}, {46,255}, {42,255}, {37,255}, {35,255}, {32,255}, {19,255}, {0,255},
+ {53,132}, {44,145}, {37,164}, {31,187}, {26,213}, {22,249}, {237,255}, {224,255}, {221,255},
+ // LC0..LC17
+ {184,255}, {179,135}, {170,149}, {163,169}, {157,193}, {153,220}, {255,255}, {167,255}, {165,255},
+ {128,26}, {128,60}, {128,94}, {128,128}, {128,162}, {128,196}, {145,233}, {148,255}, {161,255},
+ // LD0..LD17
+ {0,9}, {0,43}, {0,77}, {0,111}, {0,145}, {255,201}, {224,181}, {230,217}, {235,255},
+ {189,128}, {200,131}, {210,141}, {218,159}, {201,228}, {201,228}, {206,255}, {213,255}, {218,255}
+};
+#elif defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
+const Point g_map_led_to_point[72] PROGMEM = {
+ // LA0..LA17
+ {120,16}, {104,16}, {88,16}, {72,16}, {56,16}, {40,16}, {24,16}, {4,16}, {4,32},
+ {128,0}, {112,0}, {96,0}, {80,0}, {64,0}, {48,0}, {32,0}, {16,0}, {0,0},
+ // LB0..LB17
+ {144,0}, {160,0}, {176,0}, {192,0}, {216,0}, {224,0}, {255,255}, {255,255}, {255,255},
+ {136,16}, {152,16}, {168,16}, {184,16}, {200,16}, {220,16}, {255,255}, {255,255}, {255,255},
+ // LC0..LC17
+ {102,64}, {100,48}, {84,48}, {68,48}, {52,48}, {36,48}, {60,64}, {43,64}, {23,64},
+ {108,32}, {92,32}, {76,32}, {60,32}, {44,32}, {28,32}, {20,48}, {2,48}, {3,64},
+ // LD0..LD17
+ {124,32}, {140,32}, {156,32}, {172,32}, {188,32}, {214,32}, {180,48}, {210,48}, {224,48},
+ {116,48}, {132,48}, {148,48}, {164,48}, {144,64}, {161,64}, {181,64}, {201,64}, {221,64}
+};
+const Point g_map_led_to_point_polar[72] PROGMEM = {
+ // LA0..LA17
+ {58,129}, {70,129}, {80,139}, {89,157}, {96,181}, {101,208}, {105,238}, {109,255}, {128,247}, {58,255},
+ {64,255}, {70,255}, {75,255}, {80,255}, {85,255}, {89,255}, {93,255}, {96,255},
+ // LB0..LB17
+ {53,255}, {48,255}, {43,255}, {39,255}, {34,255}, {32,255}, {255,255}, {255,255}, {255,255},
+ {48,139}, {39,157}, {32,181}, {27,208}, {23,238}, {19,255}, {255,255}, {255,255}, {255,255},
+ // LC0..LC17
+ {188,255}, {183,131}, {173,143}, {165,163}, {159,188}, {154,216}, {172,252}, {170,255}, {165,255},
+ {128,9}, {128,46}, {128,82}, {128,119}, {128,155}, {128,192}, {150,244}, {147,255}, {161,255},
+ // LD0..LD17
+ {0,27}, {0,64}, {0,101}, {0,137}, {0,174}, {255,233}, {228,201}, {235,255}, {237,255},
+ {195,128}, {206,136}, {215,152}, {222,175}, {205,234}, {209,255}, {214,255}, {219,255}, {223,255}
+};
+#endif
+
+// This may seem counter-intuitive, but it's quite flexible.
+// For each LED, get it's position to decide what color to make it.
+// This solves the issue of LEDs (and switches) not aligning to a grid,
+// or having a large "bitmap" and sampling them.
+void map_led_to_point( uint8_t index, Point *point )
+{
+ // Slightly messy way to get Point structs out of progmem.
+ uint8_t *addr = (uint8_t*)&g_map_led_to_point[index];
+ point->x = pgm_read_byte(addr);
+ point->y = pgm_read_byte(addr+1);
+
+ switch (index)
+ {
+ case 18+4: // LB4A
+ if ( g_config.use_split_backspace )
+ point->x -= 8;
+ break;
+ case 18+14: // LB14A
+ if ( g_config.use_iso_enter )
+ point->y += 8; // extremely pedantic
+ break;
+#if defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
+ case 36+0: // LC0A
+ if ( g_config.use_7u_spacebar )
+ point->x += 10;
+ break;
+ case 36+6: // LC6A
+ if ( g_config.use_7u_spacebar )
+ point->x += 4;
+ break;
+#endif
+ case 36+16: // LC16A
+ if ( !g_config.use_split_left_shift )
+ point->x += 8;
+ break;
+ case 54+5: // LD5A
+ if ( !g_config.use_iso_enter )
+ point->x -= 10;
+ break;
+ case 54+7: // LD7A
+ if ( !g_config.use_split_right_shift )
+ point->x -= 8;
+ break;
+ }
+}
+
+void map_led_to_point_polar( uint8_t index, Point *point )
+{
+ // Slightly messy way to get Point structs out of progmem.
+ uint8_t *addr = (uint8_t*)&g_map_led_to_point_polar[index];
+ point->x = pgm_read_byte(addr);
+ point->y = pgm_read_byte(addr+1);
+}
+
+//
+// Maps switch matrix coordinate (row,col) to LED index
+//
+
+
+#if defined (RGB_BACKLIGHT_ZEAL65)
+// Note: Left spacebar stab is at 4,3 (LC7)
+// Right spacebar stab is at 4,9 (D14)
+//
+// A17, A16, A15, A14, A13, A12, A11, A10, A9, B0, B1, B2, B3, B4, B6
+// A7, A6, A5, A4, A3, A2, A1, A0, B9, B10, B11, B12, B13, B14, B7
+// A8, C14, C13, C12, C11, C10, C9, D0, D1, D2, D3, D4, D5, B5, B8
+// C16, C15, C5, C4, C3, C2, C1, D9, D10, D11, D12, D6, D7, D8, B15
+// C17, C8, C7, ---, ---, ---, ---, C0, ---, D14, D15, D16, D17, B17, B16
+const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
+ { 0+17, 0+16, 0+15, 0+14, 0+13, 0+12, 0+11, 0+10, 0+9, 18+0, 18+1, 18+2, 18+3, 18+4, 18+6 },
+ { 0+7, 0+6, 0+5, 0+4, 0+3, 0+2, 0+1, 0+0, 18+9, 18+10, 18+11, 18+12, 18+13, 18+14, 18+7 },
+ { 0+8, 36+14, 36+13, 36+12, 36+11, 36+10, 36+9, 54+0, 54+1, 54+2, 54+3, 54+4, 54+5, 18+5, 18+8 },
+ { 36+16, 36+15, 36+5, 36+4, 36+3, 36+2, 36+1, 54+9, 54+10, 54+11, 54+12, 54+6, 54+7, 54+8, 18+15 },
+ { 36+17, 36+8, 36+7, 255, 255, 255, 255, 36+0, 255, 54+14, 54+15, 54+16, 54+17, 18+17, 18+16 }
+};
+#elif defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
+// Note: Left spacebar stab is at 4,3 (LC6)
+// Right spacebar stab is at 4,9 (LD13) or 4,10 (LD14)
+//
+// A17, A16, A15, A14, A13, A12, A11, A10, A9, B0, B1, B2, B3, B4,
+// A7, A6, A5, A4, A3, A2, A1, A0, B9, B10, B11, B12, B13, B14,
+// A8, C14, C13, C12, C11, C10, C9, D0, D1, D2, D3, D4, D5, B5,
+// C16, C15, C5, C4, C3, C2, C1, D9, D10, D11, D12, D6, D7, D8,
+// C17, C8, C7, C6, ---, ---, ---, C0, ---, D13, D14, D15, D16, D17,
+const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
+ { 0+17, 0+16, 0+15, 0+14, 0+13, 0+12, 0+11, 0+10, 0+9, 18+0, 18+1, 18+2, 18+3, 18+4 },
+ { 0+7, 0+6, 0+5, 0+4, 0+3, 0+2, 0+1, 0+0, 18+9, 18+10, 18+11, 18+12, 18+13, 18+14 },
+ { 0+8, 36+14, 36+13, 36+12, 36+11, 36+10, 36+9, 54+0, 54+1, 54+2, 54+3, 54+4, 54+5, 18+5 },
+ { 36+16, 36+15, 36+5, 36+4, 36+3, 36+2, 36+1, 54+9, 54+10, 54+11, 54+12, 54+6, 54+7, 54+8 },
+ { 36+17, 36+8, 36+7, 36+6, 255, 255, 255, 36+0, 255, 54+13, 54+14, 54+15, 54+16, 54+17 }
+};
+#endif
+
+void map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led )
+{
+ *led = 255;
+ if ( row < MATRIX_ROWS && column < MATRIX_COLS )
+ {
+ *led = pgm_read_byte(&g_map_row_column_to_led[row][column]);
+ }
+}
+
+void backlight_update_pwm_buffers(void)
+{
+ IS31FL3731_update_pwm_buffers( ISSI_ADDR_1, ISSI_ADDR_2 );
+ IS31FL3731_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 );
+}
+
+void backlight_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
+{
+ IS31FL3731_set_color( index, red, green, blue );
+}
+
+void backlight_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
+{
+ IS31FL3731_set_color_all( red, green, blue );
+}
+
+void backlight_set_key_hit(uint8_t row, uint8_t column)
+{
+ uint8_t led;
+ map_row_column_to_led(row,column,&led);
+ g_key_hit[led] = 0;
+
+ g_any_key_hit = 0;
+}
+
+// This is (F_CPU/1024) / 20 Hz
+// = 15625 Hz / 20 Hz
+// = 781
+#define TIMER3_TOP 781
+
+void backlight_timer_init(void)
+{
+ static uint8_t backlight_timer_is_init = 0;
+ if ( backlight_timer_is_init )
+ {
+ return;
+ }
+ backlight_timer_is_init = 1;
+
+ // Timer 3 setup
+ TCCR3B = _BV(WGM32) | // CTC mode OCR3A as TOP
+ _BV(CS32) | _BV(CS30); // prescale by /1024
+ // Set TOP value
+ uint8_t sreg = SREG;
+ cli();
+
+ OCR3AH = (TIMER3_TOP >> 8) & 0xff;
+ OCR3AL = TIMER3_TOP & 0xff;
+ SREG = sreg;
+}
+
+void backlight_timer_enable(void)
+{
+ TIMSK3 |= _BV(OCIE3A);
+}
+
+void backlight_timer_disable(void)
+{
+ TIMSK3 &= ~_BV(OCIE3A);
+}
+
+void backlight_set_suspend_state(bool state)
+{
+ g_suspend_state = state;
+}
+
+void backlight_set_indicator_state(uint8_t state)
+{
+ g_indicator_state = state;
+}
+
+void backlight_effect_rgb_test(void)
+{
+ // Mask out bits 4 and 5
+ // This 2-bit value will stay the same for 16 ticks.
+ switch ( (g_tick & 0x30) >> 4 )
+ {
+ case 0:
+ {
+ backlight_set_color_all( 255, 0, 0 );
+ break;
+ }
+ case 1:
+ {
+ backlight_set_color_all( 0, 255, 0 );
+ break;
+ }
+ case 2:
+ {
+ backlight_set_color_all( 0, 0, 255 );
+ break;
+ }
+ case 3:
+ {
+ backlight_set_color_all( 255, 255, 255 );
+ break;
+ }
+ }
+}
+
+// This tests the LEDs
+// Note that it will change the LED control registers
+// in the LED drivers, and leave them in an invalid
+// state for other backlight effects.
+// ONLY USE THIS FOR TESTING LEDS!
+void backlight_effect_single_LED_test(void)
+{
+ static uint8_t color = 0; // 0,1,2 for R,G,B
+ static uint8_t row = 0;
+ static uint8_t column = 0;
+
+ static uint8_t tick = 0;
+ tick++;
+
+ if ( tick > 2 )
+ {
+ tick = 0;
+ column++;
+ }
+ if ( column > 14 )
+ {
+ column = 0;
+ row++;
+ }
+ if ( row > 4 )
+ {
+ row = 0;
+ color++;
+ }
+ if ( color > 2 )
+ {
+ color = 0;
+ }
+
+ uint8_t led;
+ map_row_column_to_led( row, column, &led );
+ backlight_set_color_all( 255, 255, 255 );
+ backlight_test_led( led, color==0, color==1, color==2 );
+}
+
+// All LEDs off
+void backlight_effect_all_off(void)
+{
+ backlight_set_color_all( 0, 0, 0 );
+}
+
+// Solid color
+void backlight_effect_solid_color(void)
+{
+ HSV hsv = { .h = g_config.color_1.h, .s = g_config.color_1.s, .v = g_config.brightness };
+ RGB rgb = hsv_to_rgb( hsv );
+ backlight_set_color_all( rgb.r, rgb.g, rgb.b );
+}
+
+// alphas = color1, mods = color2
+void backlight_effect_alphas_mods(void)
+{
+ RGB rgb1 = hsv_to_rgb( (HSV){ .h = g_config.color_1.h, .s = g_config.color_1.s, .v = g_config.brightness } );
+ RGB rgb2 = hsv_to_rgb( (HSV){ .h = g_config.color_2.h, .s = g_config.color_2.s, .v = g_config.brightness } );
+
+ for ( int row = 0; row < MATRIX_ROWS; row++ )
+ {
+ for ( int column = 0; column < MATRIX_COLS; column++ )
+ {
+ uint8_t index;
+ map_row_column_to_led( row, column, &index );
+ if ( index < 72 )
+ {
+ if ( ( g_config.alphas_mods[row] & (1< 127 )
+ {
+ deltaH -= 256;
+ }
+ else if ( deltaH < -127 )
+ {
+ deltaH += 256;
+ }
+ // Divide delta by 4, this gives the delta per row
+ deltaH /= 4;
+
+ int16_t s1 = g_config.color_1.s;
+ int16_t s2 = g_config.color_2.s;
+ int16_t deltaS = ( s2 - s1 ) / 4;
+
+ HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
+ RGB rgb;
+ Point point;
+ for ( int i=0; i<72; i++ )
+ {
+ map_led_to_point( i, &point );
+ // The y range will be 0..64, map this to 0..4
+ uint8_t y = (point.y>>4);
+ // Relies on hue being 8-bit and wrapping
+ hsv.h = g_config.color_1.h + ( deltaH * y );
+ hsv.s = g_config.color_1.s + ( deltaS * y );
+ rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+}
+
+void backlight_effect_raindrops(bool initialize)
+{
+ int16_t h1 = g_config.color_1.h;
+ int16_t h2 = g_config.color_2.h;
+ int16_t deltaH = h2 - h1;
+ deltaH /= 4;
+
+ // Take the shortest path between hues
+ if ( deltaH > 127 )
+ {
+ deltaH -= 256;
+ }
+ else if ( deltaH < -127 )
+ {
+ deltaH += 256;
+ }
+
+ int16_t s1 = g_config.color_1.s;
+ int16_t s2 = g_config.color_2.s;
+ int16_t deltaS = ( s2 - s1 ) / 4;
+
+ HSV hsv;
+ RGB rgb;
+
+ // Change one LED every tick
+ uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % 72 : 255;
+
+ for ( int i=0; i<72; i++ )
+ {
+ // If initialize, all get set to random colors
+ // If not, all but one will stay the same as before.
+ if ( initialize || i == led_to_change )
+ {
+ hsv.h = h1 + ( deltaH * ( rand() & 0x03 ) );
+ hsv.s = s1 + ( deltaS * ( rand() & 0x03 ) );
+ // Override brightness with global brightness control
+ hsv.v = g_config.brightness;;
+
+ rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+ }
+}
+
+void backlight_effect_cycle_all(void)
+{
+ uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
+
+ // Relies on hue being 8-bit and wrapping
+ for ( int i=0; i<72; i++ )
+ {
+ uint16_t offset2 = g_key_hit[i]<<2;
+ // stabilizer LEDs use spacebar hits
+ if ( i == 36+6 || i == 54+13 || // LC6, LD13
+ ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
+ {
+ offset2 = g_key_hit[36+0]<<2;
+ }
+ offset2 = (offset2<=63) ? (63-offset2) : 0;
+
+ HSV hsv = { .h = offset+offset2, .s = 255, .v = g_config.brightness };
+ RGB rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+}
+
+void backlight_effect_cycle_left_right(void)
+{
+ uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
+ HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
+ RGB rgb;
+ Point point;
+ for ( int i=0; i<72; i++ )
+ {
+ uint16_t offset2 = g_key_hit[i]<<2;
+ // stabilizer LEDs use spacebar hits
+ if ( i == 36+6 || i == 54+13 || // LC6, LD13
+ ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
+ {
+ offset2 = g_key_hit[36+0]<<2;
+ }
+ offset2 = (offset2<=63) ? (63-offset2) : 0;
+
+ map_led_to_point( i, &point );
+ // Relies on hue being 8-bit and wrapping
+ hsv.h = point.x + offset + offset2;
+ rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+}
+
+void backlight_effect_cycle_up_down(void)
+{
+ uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
+ HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
+ RGB rgb;
+ Point point;
+ for ( int i=0; i<72; i++ )
+ {
+ uint16_t offset2 = g_key_hit[i]<<2;
+ // stabilizer LEDs use spacebar hits
+ if ( i == 36+6 || i == 54+13 || // LC6, LD13
+ ( g_config.use_7u_spacebar && i == 54+14 ) ) // LD14
+ {
+ offset2 = g_key_hit[36+0]<<2;
+ }
+ offset2 = (offset2<=63) ? (63-offset2) : 0;
+
+ map_led_to_point( i, &point );
+ // Relies on hue being 8-bit and wrapping
+ hsv.h = point.y + offset + offset2;
+ rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+}
+
+void backlight_effect_jellybean_raindrops( bool initialize )
+{
+ HSV hsv;
+ RGB rgb;
+
+ // Change one LED every tick
+ uint8_t led_to_change = ( g_tick & 0x000 ) == 0 ? rand() % 72 : 255;
+
+ for ( int i=0; i<72; i++ )
+ {
+ // If initialize, all get set to random colors
+ // If not, all but one will stay the same as before.
+ if ( initialize || i == led_to_change )
+ {
+ hsv.h = rand() & 0xFF;
+ hsv.s = rand() & 0xFF;
+ // Override brightness with global brightness control
+ hsv.v = g_config.brightness;;
+
+ rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+ }
+}
+
+void backlight_effect_cycle_radial1(void)
+{
+ uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
+ HSV hsv = { .h = 0, .s = 255, .v = g_config.brightness };
+ RGB rgb;
+ Point point;
+ for ( int i=0; i<72; i++ )
+ {
+ map_led_to_point_polar( i, &point );
+ // Relies on hue being 8-bit and wrapping
+ hsv.h = point.x + offset;
+ hsv.s = point.y;
+ rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+}
+
+void backlight_effect_cycle_radial2(void)
+{
+ uint8_t offset = ( g_tick << g_config.effect_speed ) & 0xFF;
+
+ HSV hsv = { .h = 0, .s = g_config.color_1.s, .v = g_config.brightness };
+ RGB rgb;
+ Point point;
+ for ( int i=0; i<72; i++ )
+ {
+ map_led_to_point_polar( i, &point );
+ uint8_t offset2 = offset + point.x;
+ if ( offset2 & 0x80 )
+ {
+ offset2 = ~offset2;
+ }
+ offset2 = offset2 >> 2;
+ hsv.h = g_config.color_1.h + offset2;
+ hsv.s = 127 + ( point.y >> 1 );
+ rgb = hsv_to_rgb( hsv );
+ backlight_set_color( i, rgb.r, rgb.g, rgb.b );
+ }
+}
+
+void backlight_effect_indicators_set_colors( uint8_t index, HSV hsv )
+{
+ RGB rgb = hsv_to_rgb( hsv );
+ if ( index == 254 )
+ {
+ backlight_set_color_all( rgb.r, rgb.g, rgb.b );
+ }
+ else
+ {
+ backlight_set_color( index, rgb.r, rgb.g, rgb.b );
+
+ // If the spacebar LED is the indicator,
+ // do the same for the spacebar stabilizers
+ if ( index == 36+0 ) // LC0
+ {
+#if defined (RGB_BACKLIGHT_ZEAL65)
+ backlight_set_color( 36+7, rgb.r, rgb.g, rgb.b ); // LC7
+ backlight_set_color( 54+14, rgb.r, rgb.g, rgb.b ); // LD14
+#elif defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_M60_A)
+ backlight_set_color( 36+6, rgb.r, rgb.g, rgb.b ); // LC6
+ backlight_set_color( 54+13, rgb.r, rgb.g, rgb.b ); // LD13
+ if ( g_config.use_7u_spacebar )
+ {
+ backlight_set_color( 54+14, rgb.r, rgb.g, rgb.b ); // LD14
+ }
+#endif
+ }
+ }
+}
+
+// This runs after another backlight effect and replaces
+// colors already set
+void backlight_effect_indicators(void)
+{
+ if ( g_config.caps_lock_indicator.index != 255 &&
+ ( g_indicator_state & (1< 0 && g_any_key_hit > g_config.disable_after_timeout * 60 * 20));
+ uint8_t effect = suspend_backlight ? 0 : g_config.effect;
+
+ // Keep track of the effect used last time,
+ // detect change in effect, so each effect can
+ // have an optional initialization.
+ static uint8_t effect_last = 255;
+ bool initialize = effect != effect_last;
+ effect_last = effect;
+
+ // this gets ticked at 20 Hz.
+ // each effect can opt to do calculations
+ // and/or request PWM buffer updates.
+ switch ( effect )
+ {
+ case 0:
+ backlight_effect_all_off();
+ break;
+ case 1:
+ backlight_effect_solid_color();
+ break;
+ case 2:
+ backlight_effect_alphas_mods();
+ break;
+ case 3:
+ backlight_effect_gradient_up_down();
+ break;
+ case 4:
+ backlight_effect_raindrops( initialize );
+ break;
+ case 5:
+ backlight_effect_cycle_all();
+ break;
+ case 6:
+ backlight_effect_cycle_left_right();
+ break;
+ case 7:
+ backlight_effect_cycle_up_down();
+ break;
+ case 8:
+ backlight_effect_jellybean_raindrops( initialize );
+ break;
+ case 9:
+ backlight_effect_cycle_radial1();
+ break;
+ case 10:
+ backlight_effect_cycle_radial2();
+ break;
+ default:
+ backlight_effect_all_off();
+ break;
+ }
+
+ if ( ! suspend_backlight )
+ {
+ backlight_effect_indicators();
+ }
+}
+
+void backlight_set_indicator_index( uint8_t *index, uint8_t row, uint8_t column )
+{
+ if ( row >= MATRIX_ROWS )
+ {
+ // Special value, 255=none, 254=all
+ *index = row;
+ }
+ else
+ {
+ map_row_column_to_led( row, column, index );
+ }
+}
+
+// Some helpers for setting/getting HSV
+void _set_color( HSV *color, uint8_t *data )
+{
+ color->h = data[0];
+ color->s = data[1];
+ color->v = data[2];
+}
+
+void _get_color( HSV *color, uint8_t *data )
+{
+ data[0] = color->h;
+ data[1] = color->s;
+ data[2] = color->v;
+}
+
+void backlight_config_set_value( uint8_t *data )
+{
+ bool reinitialize = false;
+ uint8_t *value_id = &(data[0]);
+ uint8_t *value_data = &(data[1]);
+ switch ( *value_id )
+ {
+#if defined (RGB_BACKLIGHT_ZEAL60) || defined(RGB_BACKLIGHT_ZEAL65)
+ case id_use_split_backspace:
+ {
+ g_config.use_split_backspace = (bool)*value_data;
+ reinitialize = true;
+ break;
+ }
+#endif
+#if defined (RGB_BACKLIGHT_ZEAL60)
+ case id_use_split_left_shift:
+ {
+ g_config.use_split_left_shift = (bool)*value_data;
+ reinitialize = true;
+ break;
+ }
+ case id_use_split_right_shift:
+ {
+ g_config.use_split_right_shift = (bool)*value_data;
+ reinitialize = true;
+ break;
+ }
+ case id_use_7u_spacebar:
+ {
+ g_config.use_7u_spacebar = (bool)*value_data;
+ reinitialize = true;
+ break;
+ }
+ case id_use_iso_enter:
+ {
+ g_config.use_iso_enter = (bool)*value_data;
+ reinitialize = true;
+ break;
+ }
+ case id_disable_hhkb_blocker_leds:
+ {
+ g_config.disable_hhkb_blocker_leds = (bool)*value_data;
+ reinitialize = true;
+ break;
+ }
+#endif
+ case id_disable_when_usb_suspended:
+ {
+ g_config.disable_when_usb_suspended = (bool)*value_data;
+ break;
+ }
+ case id_disable_after_timeout:
+ {
+ g_config.disable_after_timeout = *value_data;
+ break;
+ }
+ case id_brightness:
+ {
+ g_config.brightness = *value_data;
+ break;
+ }
+ case id_effect:
+ {
+ g_config.effect = *value_data;
+ break;
+ }
+ case id_effect_speed:
+ {
+ g_config.effect_speed = *value_data;
+ break;
+ }
+ case id_color_1:
+ {
+ _set_color( &(g_config.color_1), value_data );
+ break;
+ }
+ case id_color_2:
+ {
+ _set_color( &(g_config.color_2), value_data );
+ break;
+ }
+ case id_caps_lock_indicator_color:
+ {
+ _set_color( &(g_config.caps_lock_indicator.color), value_data );
+ break;
+ }
+ case id_caps_lock_indicator_row_col:
+ {
+ backlight_set_indicator_index( &(g_config.caps_lock_indicator.index), value_data[0], value_data[1] );
+ break;
+ }
+ case id_layer_1_indicator_color:
+ {
+ _set_color( &(g_config.layer_1_indicator.color), value_data );
+ break;
+ }
+ case id_layer_1_indicator_row_col:
+ {
+ backlight_set_indicator_index( &(g_config.layer_1_indicator.index), value_data[0], value_data[1] );
+ break;
+ }
+ case id_layer_2_indicator_color:
+ {
+ _set_color( &(g_config.layer_2_indicator.color), value_data );
+ break;
+ }
+ case id_layer_2_indicator_row_col:
+ {
+ backlight_set_indicator_index( &(g_config.layer_2_indicator.index), value_data[0], value_data[1] );
+ break;
+ }
+ case id_layer_3_indicator_color:
+ {
+ _set_color( &(g_config.layer_3_indicator.color), value_data );
+ break;
+ }
+ case id_layer_3_indicator_row_col:
+ {
+ backlight_set_indicator_index( &(g_config.layer_3_indicator.index), value_data[0], value_data[1] );
+ break;
+ }
+ case id_alphas_mods:
+ {
+ for ( int i=0; i<5; i++ )
+ {
+ g_config.alphas_mods[i] = ( *(value_data+i*2) << 8 ) | ( *(value_data+i*2+1) );
+ }
+ }
+ }
+
+ if ( reinitialize )
+ {
+ backlight_init_drivers();
+ }
+}
+
+void backlight_config_get_value( uint8_t *data )
+{
+ uint8_t *value_id = &(data[0]);
+ uint8_t *value_data = &(data[1]);
+ switch ( *value_id )
+ {
+ case id_use_split_backspace:
+ {
+ *value_data = ( g_config.use_split_backspace ? 1 : 0 );
+ break;
+ }
+ case id_use_split_left_shift:
+ {
+ *value_data = ( g_config.use_split_left_shift ? 1 : 0 );
+ break;
+ }
+ case id_use_split_right_shift:
+ {
+ *value_data = ( g_config.use_split_right_shift ? 1 : 0 );
+ break;
+ }
+ case id_use_7u_spacebar:
+ {
+ *value_data = ( g_config.use_7u_spacebar ? 1 : 0 );
+ break;
+ }
+ case id_use_iso_enter:
+ {
+ *value_data = ( g_config.use_iso_enter ? 1 : 0 );
+ break;
+ }
+ case id_disable_when_usb_suspended:
+ {
+ *value_data = ( g_config.disable_when_usb_suspended ? 1 : 0 );
+ break;
+ }
+ case id_disable_hhkb_blocker_leds:
+ {
+ *value_data = ( g_config.disable_hhkb_blocker_leds ? 1 : 0 );
+ break;
+ }
+ case id_disable_after_timeout:
+ {
+ *value_data = g_config.disable_after_timeout;
+ break;
+ }
+ case id_brightness:
+ {
+ *value_data = g_config.brightness;
+ break;
+ }
+ case id_effect:
+ {
+ *value_data = g_config.effect;
+ break;
+ }
+ case id_effect_speed:
+ {
+ *value_data = g_config.effect_speed;
+ break;
+ }
+ case id_color_1:
+ {
+ _get_color( &(g_config.color_1), value_data );
+ break;
+ }
+ case id_color_2:
+ {
+ _get_color( &(g_config.color_2), value_data );
+ break;
+ }
+ case id_caps_lock_indicator_color:
+ {
+ _get_color( &(g_config.caps_lock_indicator.color), value_data );
+ break;
+ }
+ case id_caps_lock_indicator_row_col:
+ {
+ //*value_data = g_config.caps_lock_indicator.index;
+ break;
+ }
+ case id_layer_1_indicator_color:
+ {
+ _get_color( &(g_config.layer_1_indicator.color), value_data );
+ break;
+ }
+ case id_layer_1_indicator_row_col:
+ {
+ //*value_data = g_config.layer_1_indicator.index;
+ break;
+ }
+ case id_layer_2_indicator_color:
+ {
+ _get_color( &(g_config.layer_2_indicator.color), value_data );
+ break;
+ }
+ case id_layer_2_indicator_row_col:
+ {
+ //*value_data = g_config.layer_2_indicator.index;
+ break;
+ }
+ case id_layer_3_indicator_color:
+ {
+ _get_color( &(g_config.layer_3_indicator.color), value_data );
+ break;
+ }
+ case id_layer_3_indicator_row_col:
+ {
+ //*value_data = g_config.layer_3_indicator.index;
+ break;
+ }
+ case id_alphas_mods:
+ {
+ for ( int i=0; i<5; i++ )
+ {
+ *(value_data+i*2) = g_config.alphas_mods[i] >> 8;
+ *(value_data+i*2+1) = g_config.alphas_mods[i] & 0xFF;
+ }
+ }
+ }
+}
+
+void backlight_config_set_alphas_mods( uint16_t *alphas_mods )
+{
+ for ( int i=0; i<5; i++ )
+ {
+ g_config.alphas_mods[i] = alphas_mods[i];
+ }
+
+ backlight_config_save();
+}
+
+void backlight_config_load(void)
+{
+ eeprom_read_block( &g_config, ((void*)RGB_BACKLIGHT_CONFIG_EEPROM_ADDR), sizeof(backlight_config) );
+}
+
+void backlight_config_save(void)
+{
+ eeprom_update_block( &g_config, ((void*)RGB_BACKLIGHT_CONFIG_EEPROM_ADDR), sizeof(backlight_config) );
+}
+
+void backlight_init_drivers(void)
+{
+ // Initialize I2C
+ i2c_init();
+ IS31FL3731_init( ISSI_ADDR_1 );
+ IS31FL3731_init( ISSI_ADDR_2 );
+
+ for ( int index = 0; index < 72; index++ )
+ {
+ // OR the possible "disabled" cases together, then NOT the result to get the enabled state
+ // LC6 LD13 not present on Zeal65
+#if defined (RGB_BACKLIGHT_ZEAL65)
+ bool enabled = !( ( index == 18+5 && !g_config.use_split_backspace ) || // LB5
+ ( index == 36+15 && !g_config.use_split_left_shift ) || // LC15
+ ( index == 54+8 && !g_config.use_split_right_shift ) || // LD8
+ ( index == 36+6 ) || // LC6
+ ( index == 54+13 ) ); // LD13
+#elif defined (RGB_BACKLIGHT_M60_A)
+ bool enabled = !(
+ // LB6 LB7 LB8 LB15 LB16 LB17 not present on M60-A
+ ( index == 18+6 ) || // LB6
+ ( index == 18+7 ) || // LB7
+ ( index == 18+8 ) || // LB8
+ ( index == 18+15 ) || // LB15
+ ( index == 18+16 ) || // LB16
+ ( index == 18+17 ) || // LB17
+ // HHKB blockers (LC17, LD17) and ISO extra keys (LC15,LD13) not present on M60-A
+ ( index == 36+17 ) || // LC17
+ ( index == 54+17 ) || // LD17
+ ( index == 36+15 ) || // LC15
+ ( index == 54+13 ) ); // LD13
+#elif defined (RGB_BACKLIGHT_ZEAL60)
+ // LB6 LB7 LB8 LB15 LB16 LB17 not present on Zeal60
+ bool enabled = !( ( index == 18+5 && !g_config.use_split_backspace ) || // LB5
+ ( index == 36+15 && !g_config.use_split_left_shift ) || // LC15
+ ( index == 54+8 && !g_config.use_split_right_shift ) || // LD8
+ ( index == 54+13 && g_config.use_7u_spacebar ) || // LD13
+ ( index == 36+17 && g_config.disable_hhkb_blocker_leds ) || // LC17
+ ( index == 54+17 && g_config.disable_hhkb_blocker_leds ) || // LD17
+ ( index == 18+6 ) || // LB6
+ ( index == 18+7 ) || // LB7
+ ( index == 18+8 ) || // LB8
+ ( index == 18+15 ) || // LB15
+ ( index == 18+16 ) || // LB16
+ ( index == 18+17 ) ); // LB17
+#endif
+ // This only caches it for later
+ IS31FL3731_set_led_control_register( index, enabled, enabled, enabled );
+ }
+ // This actually updates the LED drivers
+ IS31FL3731_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 );
+
+ // TODO: put the 1 second startup delay here?
+
+ // clear the key hits
+ for ( int led=0; led<72; led++ )
+ {
+ g_key_hit[led] = 255;
+ }
+}
+
+bool process_record_backlight(uint16_t keycode, keyrecord_t *record)
+{
+ // Record keypresses for backlight effects
+ if ( record->event.pressed )
+ {
+ backlight_set_key_hit( record->event.key.row, record->event.key.col );
+ }
+
+ switch(keycode)
+ {
+ case BR_INC:
+ if (record->event.pressed)
+ {
+ backlight_brightness_increase();
+ }
+ return false;
+ break;
+ case BR_DEC:
+ if (record->event.pressed)
+ {
+ backlight_brightness_decrease();
+ }
+ return false;
+ break;
+ case EF_INC:
+ if (record->event.pressed)
+ {
+ backlight_effect_increase();
+ }
+ return false;
+ break;
+ case EF_DEC:
+ if (record->event.pressed)
+ {
+ backlight_effect_decrease();
+ }
+ return false;
+ break;
+ case ES_INC:
+ if (record->event.pressed)
+ {
+ backlight_effect_speed_increase();
+ }
+ return false;
+ break;
+ case ES_DEC:
+ if (record->event.pressed)
+ {
+ backlight_effect_speed_decrease();
+ }
+ return false;
+ break;
+ case H1_INC:
+ if (record->event.pressed)
+ {
+ backlight_color_1_hue_increase();
+ }
+ return false;
+ break;
+ case H1_DEC:
+ if (record->event.pressed)
+ {
+ backlight_color_1_hue_decrease();
+ }
+ return false;
+ break;
+ case S1_INC:
+ if (record->event.pressed)
+ {
+ backlight_color_1_sat_increase();
+ }
+ return false;
+ break;
+ case S1_DEC:
+ if (record->event.pressed)
+ {
+ backlight_color_1_sat_decrease();
+ break;
+ }
+ return false;
+ break;
+ case H2_INC:
+ if (record->event.pressed)
+ {
+ backlight_color_2_hue_increase();
+ }
+ return false;
+ break;
+ case H2_DEC:
+ if (record->event.pressed)
+ {
+ backlight_color_2_hue_decrease();
+ }
+ return false;
+ break;
+ case S2_INC:
+ if (record->event.pressed)
+ {
+ backlight_color_2_sat_increase();
+ }
+ return false;
+ break;
+ case S2_DEC:
+ if (record->event.pressed)
+ {
+ backlight_color_2_sat_decrease();
+ break;
+ }
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+// Deals with the messy details of incrementing an integer
+uint8_t increment( uint8_t value, uint8_t step, uint8_t min, uint8_t max )
+{
+ int16_t new_value = value;
+ new_value += step;
+ return MIN( MAX( new_value, min ), max );
+}
+
+uint8_t decrement( uint8_t value, uint8_t step, uint8_t min, uint8_t max )
+{
+ int16_t new_value = value;
+ new_value -= step;
+ return MIN( MAX( new_value, min ), max );
+}
+
+void backlight_effect_increase(void)
+{
+ g_config.effect = increment( g_config.effect, 1, 0, BACKLIGHT_EFFECT_MAX );
+ backlight_config_save();
+}
+
+void backlight_effect_decrease(void)
+{
+ g_config.effect = decrement( g_config.effect, 1, 0, BACKLIGHT_EFFECT_MAX );
+ backlight_config_save();
+}
+
+void backlight_effect_speed_increase(void)
+{
+ g_config.effect_speed = increment( g_config.effect_speed, 1, 0, 3 );
+ backlight_config_save();
+}
+
+void backlight_effect_speed_decrease(void)
+{
+ g_config.effect_speed = decrement( g_config.effect_speed, 1, 0, 3 );
+ backlight_config_save();
+}
+
+void backlight_brightness_increase(void)
+{
+ g_config.brightness = increment( g_config.brightness, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_brightness_decrease(void)
+{
+ g_config.brightness = decrement( g_config.brightness, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_1_hue_increase(void)
+{
+ g_config.color_1.h = increment( g_config.color_1.h, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_1_hue_decrease(void)
+{
+ g_config.color_1.h = decrement( g_config.color_1.h, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_1_sat_increase(void)
+{
+ g_config.color_1.s = increment( g_config.color_1.s, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_1_sat_decrease(void)
+{
+ g_config.color_1.s = decrement( g_config.color_1.s, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_2_hue_increase(void)
+{
+ g_config.color_2.h = increment( g_config.color_2.h, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_2_hue_decrease(void)
+{
+ g_config.color_2.h = decrement( g_config.color_2.h, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_2_sat_increase(void)
+{
+ g_config.color_2.s = increment( g_config.color_2.s, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_color_2_sat_decrease(void)
+{
+ g_config.color_2.s = decrement( g_config.color_2.s, 8, 0, 255 );
+ backlight_config_save();
+}
+
+void backlight_test_led( uint8_t index, bool red, bool green, bool blue )
+{
+ for ( int i=0; i<72; i++ )
+ {
+ if ( i == index )
+ {
+ IS31FL3731_set_led_control_register( i, red, green, blue );
+ }
+ else
+ {
+ IS31FL3731_set_led_control_register( i, false, false, false );
+ }
+ }
+}
+
+void backlight_debug_led( bool state )
+{
+ if (state)
+ {
+ // Output high.
+ DDRE |= (1<<6);
+ PORTE |= (1<<6);
+ }
+ else
+ {
+ // Output low.
+ DDRE &= ~(1<<6);
+ PORTE &= ~(1<<6);
+ }
+}
+
+#endif // BACKLIGHT_ENABLED
diff --git a/keyboards/zeal60/rgb_backlight.h b/keyboards/zeal60/rgb_backlight.h
new file mode 100644
index 000000000..60f2ace51
--- /dev/null
+++ b/keyboards/zeal60/rgb_backlight.h
@@ -0,0 +1,101 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#if RGB_BACKLIGHT_ENABLED
+#else
+#error rgb_backlight.h included when RGB_BACKLIGHT_ENABLED == 0
+#endif // RGB_BACKLIGHT_ENABLED
+
+#include
+#include
+
+#include "quantum/color.h"
+
+typedef struct
+{
+ HSV color;
+ uint8_t index;
+} backlight_config_indicator;
+
+typedef struct
+{
+ bool use_split_backspace:1; // |
+ bool use_split_left_shift:1; // |
+ bool use_split_right_shift:1; // |
+ bool use_7u_spacebar:1; // |
+ bool use_iso_enter:1; // |
+ bool disable_when_usb_suspended:1; // |
+ bool disable_hhkb_blocker_leds:1; // |
+ bool __pad7:1; // 1 byte
+ uint8_t disable_after_timeout; // 1 byte
+ uint8_t brightness; // 1 byte
+ uint8_t effect; // 1 byte
+ uint8_t effect_speed; // 1 byte
+ HSV color_1; // 3 bytes
+ HSV color_2; // 3 bytes
+ backlight_config_indicator caps_lock_indicator; // 4 bytes
+ backlight_config_indicator layer_1_indicator; // 4 bytes
+ backlight_config_indicator layer_2_indicator; // 4 bytes
+ backlight_config_indicator layer_3_indicator; // 4 bytes
+ uint16_t alphas_mods[5]; // 10 bytes
+} backlight_config; // = 37 bytes
+
+void backlight_config_load(void);
+void backlight_config_save(void);
+void backlight_config_set_value( uint8_t *data );
+void backlight_config_get_value( uint8_t *data );
+
+void backlight_init_drivers(void);
+
+void backlight_timer_init(void);
+void backlight_timer_enable(void);
+void backlight_timer_disable(void);
+
+void backlight_set_suspend_state(bool state);
+void backlight_set_indicator_state(uint8_t state);
+
+// This should not be called from an interrupt
+// (eg. from a timer interrupt).
+// Call this while idle (in between matrix scans).
+// If the buffer is dirty, it will update the driver with the buffer.
+void backlight_update_pwm_buffers(void);
+
+// Handle backlight specific keycodes
+bool process_record_backlight(uint16_t keycode, keyrecord_t *record);
+
+void backlight_set_key_hit(uint8_t row, uint8_t col);
+
+void backlight_effect_increase(void);
+void backlight_effect_decrease(void);
+void backlight_effect_speed_increase(void);
+void backlight_effect_speed_decrease(void);
+
+void backlight_brightness_increase(void);
+void backlight_brightness_decrease(void);
+
+void backlight_color_1_hue_increase(void);
+void backlight_color_1_hue_decrease(void);
+void backlight_color_1_sat_increase(void);
+void backlight_color_1_sat_decrease(void);
+void backlight_color_2_hue_increase(void);
+void backlight_color_2_hue_decrease(void);
+void backlight_color_2_sat_increase(void);
+void backlight_color_2_sat_decrease(void);
+
+void backlight_test_led( uint8_t index, bool red, bool green, bool blue );
+void backlight_debug_led(bool state);
+
diff --git a/keyboards/zeal60/rgb_backlight_api.h b/keyboards/zeal60/rgb_backlight_api.h
new file mode 100644
index 000000000..01827e849
--- /dev/null
+++ b/keyboards/zeal60/rgb_backlight_api.h
@@ -0,0 +1,42 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+enum backlight_config_value
+{
+ id_use_split_backspace = 0x01,
+ id_use_split_left_shift = 0x02,
+ id_use_split_right_shift = 0x03,
+ id_use_7u_spacebar = 0x04,
+ id_use_iso_enter = 0x05,
+ id_disable_hhkb_blocker_leds = 0x06,
+ id_disable_when_usb_suspended = 0x07,
+ id_disable_after_timeout = 0x08,
+ id_brightness = 0x09,
+ id_effect = 0x0A,
+ id_effect_speed = 0x0B,
+ id_color_1 = 0x0C,
+ id_color_2 = 0x0D,
+ id_caps_lock_indicator_color = 0x0E,
+ id_caps_lock_indicator_row_col = 0x0F,
+ id_layer_1_indicator_color = 0x10,
+ id_layer_1_indicator_row_col = 0x11,
+ id_layer_2_indicator_color = 0x12,
+ id_layer_2_indicator_row_col = 0x13,
+ id_layer_3_indicator_color = 0x14,
+ id_layer_3_indicator_row_col = 0x15,
+ id_alphas_mods = 0x16
+};
diff --git a/keyboards/zeal60/rgb_backlight_keycodes.h b/keyboards/zeal60/rgb_backlight_keycodes.h
new file mode 100644
index 000000000..ba7f03f89
--- /dev/null
+++ b/keyboards/zeal60/rgb_backlight_keycodes.h
@@ -0,0 +1,34 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+// This is hardcoded at 0x5F00 so it's well after keycode value SAFE_RANGE
+enum backlight_keycodes {
+ BR_INC = 0x5F00, // backlight brightness increase
+ BR_DEC, // backlight brightness decrease
+ EF_INC, // backlight effect increase
+ EF_DEC, // backlight effect decrease
+ ES_INC,
+ ES_DEC,
+ H1_INC,
+ H1_DEC,
+ S1_INC,
+ S1_DEC,
+ H2_INC,
+ H2_DEC,
+ S2_INC,
+ S2_DEC
+};
diff --git a/keyboards/zeal60/rules.mk b/keyboards/zeal60/rules.mk
new file mode 100644
index 000000000..c4686f985
--- /dev/null
+++ b/keyboards/zeal60/rules.mk
@@ -0,0 +1,78 @@
+
+
+# project specific files
+SRC = rgb_backlight.c \
+ quantum/color.c \
+ drivers/issi/is31fl3731.c \
+ drivers/avr/i2c_master.c
+
+# MCU name
+MCU = atmega32u4
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# 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.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+F_CPU = 16000000
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+# Boot Section
+BOOTLOADER = atmel-dfu
+
+# Do not put the microcontroller into power saving mode
+# when we get USB suspend event. We want it to keep updating
+# backlight effects.
+OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
+
+# Build Options
+# change to "no" to disable the options, or define them in the Makefile in
+# the appropriate keymap folder that will get included automatically
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = no # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
+CONSOLE_ENABLE = no # Console for debug(+400)
+COMMAND_ENABLE = no # Commands for debug and configuration
+NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+MIDI_ENABLE = no # MIDI controls
+AUDIO_ENABLE = no # Audio output on port C6
+UNICODE_ENABLE = no # Unicode
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
+
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
+
+RAW_ENABLE = yes
+DYNAMIC_KEYMAP_ENABLE = yes
+CIE1931_CURVE = yes
+
diff --git a/keyboards/zeal60/zeal60.c b/keyboards/zeal60/zeal60.c
new file mode 100644
index 000000000..e516c4dbf
--- /dev/null
+++ b/keyboards/zeal60/zeal60.c
@@ -0,0 +1,341 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * 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 .
+ */
+#include "zeal60.h"
+#include "zeal60_api.h"
+
+// Check that no backlight functions are called
+#if RGB_BACKLIGHT_ENABLED
+#include "rgb_backlight.h"
+#endif // BACKLIGHT_ENABLED
+
+#include "raw_hid.h"
+#include "dynamic_keymap.h"
+#include "timer.h"
+#include "tmk_core/common/eeprom.h"
+
+bool eeprom_is_valid(void)
+{
+ return (eeprom_read_word(((void*)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC &&
+ eeprom_read_byte(((void*)EEPROM_VERSION_ADDR)) == EEPROM_VERSION);
+}
+
+void eeprom_set_valid(bool valid)
+{
+ eeprom_update_word(((void*)EEPROM_MAGIC_ADDR), valid ? EEPROM_MAGIC : 0xFFFF);
+ eeprom_update_byte(((void*)EEPROM_VERSION_ADDR), valid ? EEPROM_VERSION : 0xFF);
+}
+
+#ifdef RAW_ENABLE
+
+void raw_hid_receive( uint8_t *data, uint8_t length )
+{
+ uint8_t *command_id = &(data[0]);
+ uint8_t *command_data = &(data[1]);
+ switch ( *command_id )
+ {
+ case id_get_protocol_version:
+ {
+ command_data[0] = PROTOCOL_VERSION >> 8;
+ command_data[1] = PROTOCOL_VERSION & 0xFF;
+ break;
+ }
+ case id_get_keyboard_value:
+ {
+ if ( command_data[0] == 0x01 )
+ {
+ uint32_t value = timer_read32();
+ command_data[1] = (value >> 24 ) & 0xFF;
+ command_data[2] = (value >> 16 ) & 0xFF;
+ command_data[3] = (value >> 8 ) & 0xFF;
+ command_data[4] = value & 0xFF;
+ }
+ else
+ {
+ *command_id = id_unhandled;
+ }
+ break;
+ }
+#ifdef DYNAMIC_KEYMAP_ENABLE
+ case id_dynamic_keymap_get_keycode:
+ {
+ uint16_t keycode = dynamic_keymap_get_keycode( command_data[0], command_data[1], command_data[2] );
+ command_data[3] = keycode >> 8;
+ command_data[4] = keycode & 0xFF;
+ break;
+ }
+ case id_dynamic_keymap_set_keycode:
+ {
+ dynamic_keymap_set_keycode( command_data[0], command_data[1], command_data[2], ( command_data[3] << 8 ) | command_data[4] );
+ break;
+ }
+ case id_dynamic_keymap_clear_all:
+ {
+ dynamic_keymap_clear_all();
+ break;
+ }
+#endif // DYNAMIC_KEYMAP_ENABLE
+#if RGB_BACKLIGHT_ENABLED
+ case id_backlight_config_set_value:
+ {
+ backlight_config_set_value(command_data);
+ break;
+ }
+ case id_backlight_config_get_value:
+ {
+ backlight_config_get_value(command_data);
+ break;
+ }
+ case id_backlight_config_save:
+ {
+ backlight_config_save();
+ break;
+ }
+#endif // RGB_BACKLIGHT_ENABLED
+ default:
+ {
+ // Unhandled message.
+ *command_id = id_unhandled;
+ break;
+ }
+ }
+
+ // Return same buffer with values changed
+ raw_hid_send( data, length );
+
+}
+
+#endif
+
+void bootmagic_lite(void)
+{
+ // The lite version of TMK's bootmagic.
+ // 100% less potential for accidentally making the
+ // keyboard do stupid things.
+
+ // We need multiple scans because debouncing can't be turned off.
+ matrix_scan();
+ wait_ms(DEBOUNCING_DELAY);
+ wait_ms(DEBOUNCING_DELAY);
+ matrix_scan();
+
+ // If the Esc and space bar are held down on power up,
+ // reset the EEPROM valid state and jump to bootloader.
+ // Assumes Esc is at [0,0] and spacebar is at [4,7].
+ // This isn't very generalized, but we need something that doesn't
+ // rely on user's keymaps in firmware or EEPROM.
+ if ( ( matrix_get_row(0) & (1<<0) ) &&
+ ( matrix_get_row(4) & (1<<7) ) )
+ {
+ // Set the Zeal60 specific EEPROM state as invalid.
+ eeprom_set_valid(false);
+ // Set the TMK/QMK EEPROM state as invalid.
+ eeconfig_disable();
+ // Jump to bootloader.
+ bootloader_jump();
+ }
+}
+
+void matrix_init_kb(void)
+{
+ bootmagic_lite();
+
+ // If the EEPROM has the magic, the data is good.
+ // OK to load from EEPROM.
+ if (eeprom_is_valid())
+ {
+#if RGB_BACKLIGHT_ENABLED
+ backlight_config_load();
+#endif // RGB_BACKLIGHT_ENABLED
+ // TODO: do something to "turn on" keymaps in EEPROM?
+ }
+ else
+ {
+#if RGB_BACKLIGHT_ENABLED
+ // If the EEPROM has not been saved before, or is out of date,
+ // save the default values to the EEPROM. Default values
+ // come from construction of the zeal_backlight_config instance.
+ backlight_config_save();
+#endif // RGB_BACKLIGHT_ENABLED
+
+#ifdef DYNAMIC_KEYMAP_ENABLE
+ // This saves "empty" keymaps so it falls back to the keymaps
+ // in the firmware (aka. progmem/flash)
+ dynamic_keymap_clear_all();
+#endif
+
+ // Save the magic number last, in case saving was interrupted
+ eeprom_set_valid(true);
+ }
+
+#if RGB_BACKLIGHT_ENABLED
+ // Initialize LED drivers for backlight.
+ backlight_init_drivers();
+
+ backlight_timer_init();
+ backlight_timer_enable();
+#endif // RGB_BACKLIGHT_ENABLED
+
+ matrix_init_user();
+}
+
+void matrix_scan_kb(void)
+{
+#if RGB_BACKLIGHT_ENABLED
+ // This only updates the LED driver buffers if something has changed.
+ backlight_update_pwm_buffers();
+#endif // BACKLIGHT_ENABLED
+ matrix_scan_user();
+}
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record)
+{
+#if RGB_BACKLIGHT_ENABLED
+ process_record_backlight(keycode, record);
+#endif // BACKLIGHT_ENABLED
+
+ switch(keycode)
+ {
+ case FN_MO13:
+ if (record->event.pressed)
+ {
+ layer_on(1);
+ update_tri_layer(1, 2, 3);
+ }
+ else
+ {
+ layer_off(1);
+ update_tri_layer(1, 2, 3);
+ }
+ return false;
+ break;
+ case FN_MO23:
+ if (record->event.pressed)
+ {
+ layer_on(2);
+ update_tri_layer(1, 2, 3);
+ }
+ else
+ {
+ layer_off(2);
+ update_tri_layer(1, 2, 3);
+ }
+ return false;
+ break;
+ }
+
+ return process_record_user(keycode, record);
+}
+
+// This overrides the one in quantum/keymap_common.c
+uint16_t keymap_function_id_to_action( uint16_t function_id )
+{
+ // Zeal60 specific "action functions" are 0xF00 to 0xFFF
+ // i.e. F(0xF00) to F(0xFFF) are mapped to
+ // enum zeal60_action_functions by masking last 8 bits.
+ if ( function_id >= 0x0F00 && function_id <= 0x0FFF )
+ {
+ uint8_t id = function_id & 0xFF;
+ switch ( id )
+ {
+ case TRIPLE_TAP_1_3:
+ case TRIPLE_TAP_2_3:
+ {
+ return ACTION_FUNCTION_TAP(id);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+#if USE_KEYMAPS_IN_EEPROM
+
+#if 0
+ // This is how to implement actions stored in EEPROM.
+ // Not yet implemented. Not sure if it's worth the trouble
+ // before we have a nice GUI for keymap editing.
+ if ( eeprom_is_valid() &&
+ function_id < 32 ) // TODO: replace magic number
+ {
+ uint16_t action = keymap_action_load(function_id);
+
+ // If action is not "empty", return it, otherwise
+ // drop down to return the one in flash
+ if ( action != 0x0000 ) // TODO: replace magic number
+ {
+ return action;
+ }
+ }
+#endif
+
+#endif // USE_KEYMAPS_IN_EEPROM
+
+ return pgm_read_word(&fn_actions[function_id]);
+}
+
+
+// Zeal60 specific "action functions"
+void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ switch (id)
+ {
+ case TRIPLE_TAP_1_3:
+ case TRIPLE_TAP_2_3:
+ if (record->event.pressed)
+ {
+ layer_on( id == TRIPLE_TAP_1_3 ? 1 : 2 );
+
+ if (record->tap.count && !record->tap.interrupted)
+ {
+ if (record->tap.count >= 3)
+ {
+ layer_invert(3);
+ }
+ }
+ else
+ {
+ record->tap.count = 0;
+ }
+ }
+ else
+ {
+ layer_off( id == TRIPLE_TAP_1_3 ? 1 : 2 );
+ }
+ break;
+ }
+}
+
+void led_set_kb(uint8_t usb_led)
+{
+#if RGB_BACKLIGHT_ENABLED
+ backlight_set_indicator_state(usb_led);
+#endif // RGB_BACKLIGHT_ENABLED
+}
+
+void suspend_power_down_kb(void)
+{
+#if RGB_BACKLIGHT_ENABLED
+ backlight_set_suspend_state(true);
+#endif // RGB_BACKLIGHT_ENABLED
+}
+
+void suspend_wakeup_init_kb(void)
+{
+#if RGB_BACKLIGHT_ENABLED
+ backlight_set_suspend_state(false);
+#endif // RGB_BACKLIGHT_ENABLED
+}
+
diff --git a/keyboards/zeal60/zeal60.h b/keyboards/zeal60/zeal60.h
new file mode 100644
index 000000000..ef9de7989
--- /dev/null
+++ b/keyboards/zeal60/zeal60.h
@@ -0,0 +1,93 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "quantum.h"
+#include "rgb_backlight_keycodes.h"
+#include "zeal60_keycodes.h"
+
+#define XXX KC_NO
+
+#define LAYOUT_60_all( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K2D, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
+ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
+ K40, K41, K42, K47, K4A, K4B, K4C, K4D \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D }, \
+ { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
+ { K40, K41, K42, XXX, XXX, XXX, XXX, K47, XXX, XXX, K4A, K4B, K4C, K4D } \
+}
+
+#define LAYOUT_60_ansi( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, \
+ K40, K41, K42, K47, K4A, K4B, K4C, K4D \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, XXX }, \
+ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, XXX }, \
+ { K40, K41, K42, XXX, XXX, XXX, XXX, K47, XXX, XXX, K4A, K4B, K4C, K4D } \
+}
+
+#define LAYOUT_60_iso( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
+ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, \
+ K40, K41, K42, K47, K4A, K4B, K4C, K4D \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, XXX }, \
+ { K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, XXX }, \
+ { K40, K41, K42, XXX, XXX, XXX, XXX, K47, XXX, XXX, K4A, K4B, K4C, K4D } \
+}
+
+#define LAYOUT_60_ansi_split_bs_rshift( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K2D, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
+ K40, K41, K42, K47, K4A, K4B, K4C, K4D \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D }, \
+ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
+ { K40, K41, K42, XXX, XXX, XXX, XXX, K47, XXX, XXX, K4A, K4B, K4C, K4D } \
+}
+
+#define LAYOUT_60_hhkb( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K2D, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, \
+ K41, K42, K47, K4B, K4C \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D }, \
+ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
+ { XXX, K41, K42, XXX, XXX, XXX, XXX, K47, XXX, XXX, XXX, K4B, K4C, XXX } \
+}
+
diff --git a/keyboards/zeal60/zeal60_api.h b/keyboards/zeal60/zeal60_api.h
new file mode 100644
index 000000000..baa8ac09f
--- /dev/null
+++ b/keyboards/zeal60/zeal60_api.h
@@ -0,0 +1,33 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#define PROTOCOL_VERSION 0x0007
+
+enum zeal60_command_id
+{
+ id_get_protocol_version = 0x01, // always 0x01
+ id_get_keyboard_value,
+ id_set_keyboard_value,
+ id_dynamic_keymap_get_keycode,
+ id_dynamic_keymap_set_keycode,
+ id_dynamic_keymap_clear_all,
+ id_backlight_config_set_value,
+ id_backlight_config_get_value,
+ id_backlight_config_save,
+
+ id_unhandled = 0xFF,
+};
diff --git a/keyboards/zeal60/zeal60_keycodes.h b/keyboards/zeal60/zeal60_keycodes.h
new file mode 100644
index 000000000..9511801eb
--- /dev/null
+++ b/keyboards/zeal60/zeal60_keycodes.h
@@ -0,0 +1,42 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+// Can't use SAFE_RANGE here, it might change if someone adds
+// new values to enum quantum_keycodes.
+// Need to keep checking 0x5F10 is still in the safe range.
+// TODO: merge this into quantum_keycodes
+// Backlight keycodes are in range 0x5F00-0x5F0F
+enum zeal60_keycodes {
+ FN_MO13 = 0x5F10,
+ FN_MO23
+};
+
+// Zeal60 specific "action functions"
+// These are only valid IDs in action_function()
+// Use FN_TT13, FN_TT23, etc. in keymaps
+enum zeal60_action_functions {
+ TRIPLE_TAP_1_3 = 0x31,
+ TRIPLE_TAP_2_3 = 0x32
+};
+
+// Bitwise OR the above with 0x0F00 to use in F(x) macro
+// This reserves the top 256 of the 4096 range of F(x) keycodes,
+// leaving the rest for use in fn_actions[] or actions in EEPROM.
+#define FN_TT13 F((0x0F00|TRIPLE_TAP_1_3))
+#define FN_TT23 F((0x0F00|TRIPLE_TAP_2_3))
+
+#define TG_NKRO MAGIC_TOGGLE_NKRO
diff --git a/keyboards/zeal65/config.h b/keyboards/zeal65/config.h
new file mode 100644
index 000000000..2dbf61237
--- /dev/null
+++ b/keyboards/zeal65/config.h
@@ -0,0 +1,125 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "config_common.h"
+
+// USB Device descriptor parameter
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6065
+#define DEVICE_VER 0x0001
+#define MANUFACTURER ZealPC
+#define PRODUCT Zeal65
+#define DESCRIPTION Zeal65 (QMK Firmware)
+
+// key matrix size
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 15
+
+// Zeal60 PCB default pin-out
+#define MATRIX_ROW_PINS { F0, F1, F4, F6, F7 }
+#define MATRIX_COL_PINS { F5, D5, B1, B2, B3, D3, D2, C7, C6, B6, B5, B4, D7, D6, D4 }
+#define UNUSED_PINS
+
+// IS31FL3731 driver
+#define DRIVER_COUNT 2
+#define DRIVER_LED_TOTAL 72
+
+// COL2ROW or ROW2COL
+#define DIODE_DIRECTION COL2ROW
+
+// Set 0 if debouncing isn't needed
+#define DEBOUNCING_DELAY 5
+
+// 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
+
+// key combination for command
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+/*
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ */
+
+// disable debug print
+//#define NO_DEBUG
+
+// disable print
+//#define NO_PRINT
+
+// disable action features
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
+
+#define RGB_BACKLIGHT_ENABLED 1
+
+// This conditionally compiles the backlight code for Zeal65 specifics
+#define RGB_BACKLIGHT_ZEAL65
+
+// enable/disable LEDs based on layout
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
+#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
+#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 1
+#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
+#define RGB_BACKLIGHT_USE_ISO_ENTER 0
+#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
+
+// disable backlight when USB suspended (PC sleep/hibernate/shutdown)
+#define RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED 0
+
+// disable backlight after timeout in minutes, 0 = no timeout
+#define RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT 0
+
+// the default effect (RGB test)
+#define RGB_BACKLIGHT_EFFECT 255
+
+// These define which keys in the matrix are alphas/mods
+// Used for backlight effects so colors are different for
+// alphas vs. mods
+// Each value is for a row, bit 0 is column 0
+// Alpha=0 Mod=1
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_0 0b0110000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_1 0b0100000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_2 0b0101000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_3 0b0111000000000001
+#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 0b0111110000000011
+
+#define DYNAMIC_KEYMAP_LAYER_COUNT 4
+
+// EEPROM usage
+
+// TODO: refactor with new user EEPROM code (coming soon)
+#define EEPROM_MAGIC 0x451F
+#define EEPROM_MAGIC_ADDR 32
+// Bump this every time we change what we store
+// This will automatically reset the EEPROM with defaults
+// and avoid loading invalid data from the EEPROM
+#define EEPROM_VERSION 0x07
+#define EEPROM_VERSION_ADDR 34
+
+// Backlight config starts after EEPROM version
+#define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR 35
+// Dynamic keymap starts after backlight config (35+37)
+#define DYNAMIC_KEYMAP_EEPROM_ADDR 72
+
diff --git a/keyboards/zeal65/info.json b/keyboards/zeal65/info.json
new file mode 100644
index 000000000..94a090689
--- /dev/null
+++ b/keyboards/zeal65/info.json
@@ -0,0 +1,16 @@
+{
+ "keyboard_name": "Zeal65",
+ "url": "",
+ "maintainer": "Wilba",
+ "bootloader": "DFU",
+ "width": 16,
+ "height": 5,
+ "layouts": {
+ "LAYOUT_65_split_bs": {
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"|", "x":13, "y":0}, {"label":"Del", "x":14, "y":0}, {"label":"Home", "x":15, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"Backspace", "x":13.5, "y":1, "w":1.5}, {"label":"PgUp", "x":15, "y":1}, {"label":"Control", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"PgDn", "x":15, "y":2}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"\u2191", "x":14, "y":3}, {"label":"End", "x":15, "y":3}, {"label":"Win", "x":0, "y":4, "w":1.5}, {"label":"Alt", "x":1.5, "y":4, "w":1.5}, {"x":3, "y":4, "w":7}, {"label":"Fn2", "x":10, "y":4, "w":1.5}, {"label":"Fn1", "x":11.5, "y":4, "w":1.5}, {"label":"\u2190", "x":13, "y":4}, {"label":"\u2193", "x":14, "y":4}, {"label":"\u2192", "x":15, "y":4}]
+ },
+ "LAYOUT_65_normie": {
+ "layout": [{"label":"Esc", "x":0, "y":0}, {"label":"!", "x":1, "y":0}, {"label":"@", "x":2, "y":0}, {"label":"#", "x":3, "y":0}, {"label":"$", "x":4, "y":0}, {"label":"%", "x":5, "y":0}, {"label":"^", "x":6, "y":0}, {"label":"&", "x":7, "y":0}, {"label":"*", "x":8, "y":0}, {"label":"(", "x":9, "y":0}, {"label":")", "x":10, "y":0}, {"label":"_", "x":11, "y":0}, {"label":"+", "x":12, "y":0}, {"label":"Backspace", "x":13, "y":0, "w":2}, {"label":"Home", "x":15, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"Q", "x":1.5, "y":1}, {"label":"W", "x":2.5, "y":1}, {"label":"E", "x":3.5, "y":1}, {"label":"R", "x":4.5, "y":1}, {"label":"T", "x":5.5, "y":1}, {"label":"Y", "x":6.5, "y":1}, {"label":"U", "x":7.5, "y":1}, {"label":"I", "x":8.5, "y":1}, {"label":"O", "x":9.5, "y":1}, {"label":"P", "x":10.5, "y":1}, {"label":"{", "x":11.5, "y":1}, {"label":"}", "x":12.5, "y":1}, {"label":"|", "x":13.5, "y":1, "w":1.5}, {"label":"PgUp", "x":15, "y":1}, {"label":"Control", "x":0, "y":2, "w":1.75}, {"label":"A", "x":1.75, "y":2}, {"label":"S", "x":2.75, "y":2}, {"label":"D", "x":3.75, "y":2}, {"label":"F", "x":4.75, "y":2}, {"label":"G", "x":5.75, "y":2}, {"label":"H", "x":6.75, "y":2}, {"label":"J", "x":7.75, "y":2}, {"label":"K", "x":8.75, "y":2}, {"label":"L", "x":9.75, "y":2}, {"label":":", "x":10.75, "y":2}, {"label":"\"", "x":11.75, "y":2}, {"label":"Enter", "x":12.75, "y":2, "w":2.25}, {"label":"PgDn", "x":15, "y":2}, {"label":"Shift", "x":0, "y":3, "w":2.25}, {"label":"Z", "x":2.25, "y":3}, {"label":"X", "x":3.25, "y":3}, {"label":"C", "x":4.25, "y":3}, {"label":"V", "x":5.25, "y":3}, {"label":"B", "x":6.25, "y":3}, {"label":"N", "x":7.25, "y":3}, {"label":"M", "x":8.25, "y":3}, {"label":"<", "x":9.25, "y":3}, {"label":">", "x":10.25, "y":3}, {"label":"?", "x":11.25, "y":3}, {"label":"Shift", "x":12.25, "y":3, "w":1.75}, {"label":"\u2191", "x":14, "y":3}, {"label":"End", "x":15, "y":3}, {"label":"Win", "x":0, "y":4, "w":1.5}, {"label":"Alt", "x":1.5, "y":4, "w":1.5}, {"x":3, "y":4, "w":7}, {"label":"Fn2", "x":10, "y":4, "w":1.5}, {"label":"Fn1", "x":11.5, "y":4, "w":1.5}, {"label":"\u2190", "x":13, "y":4}, {"label":"\u2193", "x":14, "y":4}, {"label":"\u2192", "x":15, "y":4}]
+ }
+ }
+}
\ No newline at end of file
diff --git a/keyboards/zeal65/keymaps/default/config.h b/keyboards/zeal65/keymaps/default/config.h
new file mode 100644
index 000000000..f579dfaa7
--- /dev/null
+++ b/keyboards/zeal65/keymaps/default/config.h
@@ -0,0 +1,5 @@
+#pragma once
+
+/* enable/disable LEDs based on layout */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
diff --git a/keyboards/zeal65/keymaps/default/keymap.c b/keyboards/zeal65/keymaps/default/keymap.c
new file mode 100644
index 000000000..dd1a715d0
--- /dev/null
+++ b/keyboards/zeal65/keymaps/default/keymap.c
@@ -0,0 +1,38 @@
+// Default layout for Zeal65
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_65_normie(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_PGUP,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END,
+ KC_LCTL, KC_LALT, KC_SPC, FN_MO23, FN_MO13, KC_LEFT, KC_DOWN, KC_RGHT),
+
+// Fn1 Layer
+[1] = LAYOUT_65_normie(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_65_normie(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_65_normie(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/zeal65/keymaps/split_bs/config.h b/keyboards/zeal65/keymaps/split_bs/config.h
new file mode 100644
index 000000000..018be8d7c
--- /dev/null
+++ b/keyboards/zeal65/keymaps/split_bs/config.h
@@ -0,0 +1,5 @@
+#pragma once
+
+/* enable/disable LEDs based on layout */
+#undef RGB_BACKLIGHT_USE_SPLIT_BACKSPACE
+#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 1
diff --git a/keyboards/zeal65/keymaps/split_bs/keymap.c b/keyboards/zeal65/keymaps/split_bs/keymap.c
new file mode 100644
index 000000000..96b04c358
--- /dev/null
+++ b/keyboards/zeal65/keymaps/split_bs/keymap.c
@@ -0,0 +1,38 @@
+// Split-backspace layout for Zeal65
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// Default layer
+[0] = LAYOUT_65_split_bs(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_DEL, KC_HOME,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_PGUP,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGDN,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_END,
+ KC_LGUI, KC_LALT, KC_SPC, FN_MO23, FN_MO13, KC_LEFT, KC_DOWN, KC_RGHT),
+
+// Fn1 Layer
+[1] = LAYOUT_65_split_bs(
+ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_DEL, KC_TRNS,
+ KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn2 Layer
+[2] = LAYOUT_65_split_bs(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+// Fn3 Layer (zeal60 Configuration)
+[3] = LAYOUT_65_split_bs(
+ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, BR_DEC, BR_INC, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
+
+};
diff --git a/keyboards/zeal65/readme.md b/keyboards/zeal65/readme.md
new file mode 100644
index 000000000..8f43dc243
--- /dev/null
+++ b/keyboards/zeal65/readme.md
@@ -0,0 +1,16 @@
+Zeal65
+====
+
+![Zeal65](https://cdn.shopify.com/s/files/1/0490/7329/products/Zeal65_PCB2.jpg)
+
+This is a 65% PCB with per-key RGB LEDs and supports fixed, 1800-like bottom row and split backspace. It was designed for the Zephyr custom keyboard.
+
+Keyboard Maintainer: [Wilba](http://wilba.tech/) and on [github](https://github.com/Wilba6582)
+Hardware Supported: Zeal65 PCB Rev 1
+Hardware Availability: https://zealpc.net/collections/group-buy-pre-orders/products/zephyr
+
+Make example for this keyboard (after setting up your build environment):
+
+ make zeal65:default
+
+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).
diff --git a/keyboards/zeal65/rules.mk b/keyboards/zeal65/rules.mk
new file mode 100644
index 000000000..02617cf1c
--- /dev/null
+++ b/keyboards/zeal65/rules.mk
@@ -0,0 +1,79 @@
+
+
+# project specific files
+SRC = ../zeal60/zeal60.c \
+ ../zeal60/rgb_backlight.c \
+ quantum/color.c \
+ drivers/issi/is31fl3731.c \
+ drivers/avr/i2c_master.c
+
+# MCU name
+MCU = atmega32u4
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# 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.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+F_CPU = 16000000
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+# Boot Section
+BOOTLOADER = atmel-dfu
+
+# Do not put the microcontroller into power saving mode
+# when we get USB suspend event. We want it to keep updating
+# backlight effects.
+OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
+
+# Build Options
+# change to "no" to disable the options, or define them in the Makefile in
+# the appropriate keymap folder that will get included automatically
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = no # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
+CONSOLE_ENABLE = no # Console for debug(+400)
+COMMAND_ENABLE = no # Commands for debug and configuration
+NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
+MIDI_ENABLE = no # MIDI controls
+AUDIO_ENABLE = no # Audio output on port C6
+UNICODE_ENABLE = no # Unicode
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
+
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+
+RAW_ENABLE = yes
+DYNAMIC_KEYMAP_ENABLE = yes
+CIE1931_CURVE = yes
+
diff --git a/keyboards/zeal65/zeal65.c b/keyboards/zeal65/zeal65.c
new file mode 100644
index 000000000..540c93080
--- /dev/null
+++ b/keyboards/zeal65/zeal65.c
@@ -0,0 +1,18 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * 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 .
+ */
+#ifndef RGB_BACKLIGHT_ZEAL65
+#error RGB_BACKLIGHT_ZEAL65 not defined, you done goofed somehao, brah
+#endif
diff --git a/keyboards/zeal65/zeal65.h b/keyboards/zeal65/zeal65.h
new file mode 100644
index 000000000..3ee4f49e5
--- /dev/null
+++ b/keyboards/zeal65/zeal65.h
@@ -0,0 +1,50 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "quantum.h"
+#include "../zeal60/rgb_backlight_keycodes.h"
+#include "../zeal60/zeal60_keycodes.h"
+
+#define XXX KC_NO
+
+#define LAYOUT_65_split_bs( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K2D, K0E, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \
+ K40, K41, K47, K4A, K4B, K4C, K4D, K4E \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E }, \
+ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \
+ { K40, K41, XXX, XXX, XXX, XXX, XXX, K47, XXX, XXX, K4A, K4B, K4C, K4D, K4E } \
+}
+
+#define LAYOUT_65_normie( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2E, \
+ K30, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, \
+ K40, K41, K47, K4A, K4B, K4C, K4D, K4E \
+) { \
+ { K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E }, \
+ { K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E }, \
+ { K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, XXX, K2E }, \
+ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E }, \
+ { K40, K41, XXX, XXX, XXX, XXX, XXX, K47, XXX, XXX, K4A, K4B, K4C, K4D, K4E } \
+}
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
new file mode 100644
index 000000000..9f18612d5
--- /dev/null
+++ b/quantum/dynamic_keymap.c
@@ -0,0 +1,97 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * 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 .
+ */
+
+#include "config.h"
+#include "keymap.h" // to get keymaps[][][]
+
+#include "dynamic_keymap.h"
+
+#ifdef DYNAMIC_KEYMAP_ENABLE
+
+#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR
+#error DYNAMIC_KEYMAP_EEPROM_ADDR not defined
+#endif
+
+#ifndef DYNAMIC_KEYMAP_LAYER_COUNT
+#error DYNAMIC_KEYMAP_LAYER_COUNT not defined
+#endif
+
+#define KC_EENULL 0xFFFF // TODO: move to enum quantum_keycodes
+
+void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column)
+{
+ // TODO: optimize this with some left shifts
+ return ((void*)DYNAMIC_KEYMAP_EEPROM_ADDR) + ( layer * MATRIX_ROWS * MATRIX_COLS * 2 ) +
+ ( row * MATRIX_COLS * 2 ) + ( column * 2 );
+}
+
+uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column)
+{
+ void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
+ // Big endian, so we can read/write EEPROM directly from host if we want
+ uint16_t keycode = eeprom_read_byte(address) << 8;
+ keycode |= eeprom_read_byte(address + 1);
+ return keycode;
+}
+
+void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode)
+{
+ void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column);
+ // Big endian, so we can read/write EEPROM directly from host if we want
+ eeprom_update_byte(address, (uint8_t)(keycode >> 8));
+ eeprom_update_byte(address+1, (uint8_t)(keycode & 0xFF));
+}
+
+void dynamic_keymap_clear_all(void)
+{
+ // Save "empty" keymaps.
+ for ( int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++ )
+ {
+ for ( int row = 0; row < MATRIX_ROWS; row++ )
+ {
+ for ( int column = 0; column < MATRIX_COLS; column++ )
+ {
+ dynamic_keymap_set_keycode(layer, row, column, KC_EENULL);
+ }
+ }
+ }
+}
+
+// This overrides the one in quantum/keymap_common.c
+uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
+{
+ // This used to test EEPROM for magic bytes, but it was redundant.
+ // Test for EEPROM usage change (fresh install, address change, etc.)
+ // externally and call dynamic_keymap_default_save()
+ if ( layer < DYNAMIC_KEYMAP_LAYER_COUNT &&
+ key.row < MATRIX_ROWS && // possibly redundant
+ key.col < MATRIX_COLS ) // possibly redundant
+ {
+ uint16_t keycode = dynamic_keymap_get_keycode(layer, key.row, key.col);
+
+ // If keycode is not "empty", return it, otherwise
+ // drop down to return the one in flash
+ if ( keycode != KC_EENULL)
+ {
+ return keycode;
+ }
+ }
+
+ return pgm_read_word(&keymaps[layer][key.row][key.col]);
+}
+
+#endif // DYNAMIC_KEYMAP_ENABLE
+
diff --git a/quantum/dynamic_keymap.h b/quantum/dynamic_keymap.h
new file mode 100644
index 000000000..b0133aeb8
--- /dev/null
+++ b/quantum/dynamic_keymap.h
@@ -0,0 +1,31 @@
+/* Copyright 2017 Jason Williams (Wilba)
+ *
+ * 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 .
+ */
+
+#ifndef DYNAMIC_KEYMAP_H
+#define DYNAMIC_KEYMAP_H
+
+#include
+#include
+
+void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column);
+uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column);
+void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode);
+void dynamic_keymap_clear_all(void);
+
+// This overrides the one in quantum/keymap_common.c
+// uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
+
+#endif //DYNAMIC_KEYMAP_H
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index d7a7f049c..5bca64685 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -56,6 +56,24 @@ void suspend_idle(uint8_t time)
sleep_disable();
}
+
+// TODO: This needs some cleanup
+
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_user (void) { }
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_kb(void) {
+ suspend_power_down_user();
+}
+
#ifndef NO_SUSPEND_POWER_DOWN
/** \brief Power down MCU with watchdog timer
*
@@ -73,21 +91,6 @@ void suspend_idle(uint8_t time)
*/
static uint8_t wdt_timeout = 0;
-/** \brief Run keyboard level Power down
- *
- * FIXME: needs doc
- */
-__attribute__ ((weak))
-void suspend_power_down_user (void) { }
-/** \brief Run keyboard level Power down
- *
- * FIXME: needs doc
- */
-__attribute__ ((weak))
-void suspend_power_down_kb(void) {
- suspend_power_down_user();
-}
-
/** \brief Power down
*
* FIXME: needs doc
@@ -144,6 +147,8 @@ static void power_down(uint8_t wdto)
*/
void suspend_power_down(void)
{
+ suspend_power_down_kb();
+
#ifndef NO_SUSPEND_POWER_DOWN
power_down(WDTO_15MS);
#endif
@@ -198,7 +203,7 @@ void suspend_wakeup_init(void)
rgblight_timer_enable();
#endif
#endif
- suspend_wakeup_init_kb();
+ suspend_wakeup_init_kb();
}
#ifndef NO_SUSPEND_POWER_DOWN
--
cgit v1.2.3-70-g09d2
From 743449472e58651ec8111e6f70811103fb0a28bd Mon Sep 17 00:00:00 2001
From: Joe Wasson
Date: Mon, 17 Sep 2018 10:48:02 -0700
Subject: Make `PREVENT_STUCK_MODIFIERS` the default (#3107)
* Remove chording as it is not documented, not used, and needs work.
* Make Leader Key an optional feature.
* Switch from `PREVENT_STUCK_MODIFIERS` to `STRICT_LAYER_RELEASE`
* Remove `#define PREVENT_STUCK_MODIFIERS` from keymaps.
---
common_features.mk | 11 ++--
docs/config_options.md | 4 +-
docs/feature_leader_key.md | 8 +++
docs/understanding_qmk.md | 2 +-
keyboards/1upkeyboards/1up60rgb/config.h | 3 -
keyboards/1upkeyboards/sweet16/config.h | 7 +-
keyboards/acr60/config.h | 3 -
keyboards/alf/x2/config.h | 5 +-
keyboards/alpha/config.h | 2 -
keyboards/alu84/config.h | 3 -
keyboards/at101_blackheart/config.h | 3 -
keyboards/atreus/keymaps/jeremy/keymap.c | 2 -
keyboards/atreus/keymaps/khitsule/config.h | 4 +-
keyboards/atreus/keymaps/xk/config.h | 3 +-
keyboards/atreus62/keymaps/mneme/config.h | 1 -
keyboards/atreus62/keymaps/mneme/rules.mk | 1 +
.../bfo9000/keymaps/andylikescandy6x18/config.h | 3 -
keyboards/bigseries/1key/config.h | 3 -
keyboards/bigseries/2key/config.h | 3 -
keyboards/bigseries/3key/config.h | 3 -
keyboards/bigseries/4key/config.h | 3 -
keyboards/bigswitch/config.h | 2 -
keyboards/catch22/config.h | 3 -
keyboards/chimera_ergo/config.h | 2 -
keyboards/chimera_ls/config.h | 2 -
keyboards/chimera_ortho/config.h | 2 -
keyboards/chocopad/config.h | 6 +-
keyboards/clueboard/60/config.h | 3 -
keyboards/clueboard/66/keymaps/bloodlvst/config.h | 1 -
keyboards/comet46/config.h | 2 -
keyboards/contra/config.h | 4 --
keyboards/contra/keymaps/ryanm101/config.h | 5 +-
keyboards/crawlpad/config.h | 3 -
keyboards/crkbd/keymaps/default/config.h | 1 -
keyboards/dichotemy/config.h | 2 -
keyboards/dilly/config.h | 6 +-
keyboards/dz60/config.h | 3 -
keyboards/dz60/keymaps/LEdiodes/config.h | 3 -
keyboards/ergodone/config.h | 2 -
keyboards/ergodox_ez/config.h | 2 -
.../ergodox_ez/keymaps/heartrobotninja/rules.mk | 3 +-
keyboards/ergodox_ez/keymaps/vim/vim.h | 1 -
keyboards/ergodox_infinity/keymaps/gordon/config.h | 2 -
keyboards/ergodox_infinity/keymaps/narze/config.h | 1 -
.../keymaps/not-quite-neo/rules.mk | 3 +-
keyboards/ergoinu/config.h | 2 -
keyboards/ergotravel/keymaps/ckofy/config.h | 3 -
keyboards/felix/config.h | 4 +-
keyboards/four_banger/config.h | 5 +-
keyboards/fourier/keymaps/jennetters/config.h | 5 +-
keyboards/fractal/config.h | 4 --
keyboards/frosty_flake/keymaps/nikchi/rules.mk | 3 +-
keyboards/gh80_3000/config.h | 6 +-
keyboards/gherkin/config.h | 6 +-
keyboards/gherkin/keymaps/talljoe_gherkin/config.h | 4 +-
keyboards/gonnerd/keymaps/gam3cat/config.h | 1 -
keyboards/hadron/keymaps/default/config.h | 1 -
keyboards/hadron/keymaps/side_numpad/config.h | 1 -
keyboards/handwired/MS_sculpt_mobile/config.h | 8 +--
.../handwired/atreus50/keymaps/ajp10304/config.h | 2 -
keyboards/handwired/dactyl/config.h | 2 -
keyboards/handwired/kbod/config.h | 4 +-
.../handwired/promethium/keymaps/default/config.h | 2 -
.../handwired/promethium/keymaps/priyadi/config.h | 2 -
keyboards/handwired/space_oddity/config.h | 4 --
keyboards/helix/pico/config.h | 1 -
keyboards/helix/rev1/keymaps/OLED_sample/config.h | 3 +-
keyboards/helix/rev2/config.h | 1 -
keyboards/hhkb/keymaps/blakedietz/rules.mk | 1 +
keyboards/infinity60/config.h | 2 -
keyboards/iris/keymaps/davidrambo/config.h | 1 -
keyboards/iris/keymaps/jennetters/config.h | 5 +-
keyboards/iris/keymaps/krusli/config.h | 2 -
keyboards/iris/keymaps/xyverz/config.h | 2 -
keyboards/jc65/v32u4/keymaps/gam3cat/config.h | 1 -
keyboards/jj40/keymaps/ajp10304/config.h | 8 ---
keyboards/jj40/keymaps/fun40/config.h | 1 -
keyboards/jj40/keymaps/krusli/config.h | 1 -
keyboards/jj40/keymaps/oscillope/config.h | 1 -
keyboards/jj40/keymaps/suzuken/config.h | 1 -
keyboards/jj40/keymaps/waples/config.h | 1 -
keyboards/jm60/config.h | 2 -
keyboards/k_type/config.h | 2 -
keyboards/katana60/config.h | 3 +-
keyboards/kbd75/config.h | 3 -
.../kinesis/keymaps/insertsnideremarks/config.h | 1 -
keyboards/lets_split/keymaps/OLED_sample/config.h | 2 -
keyboards/lets_split/keymaps/adam/config.h | 1 -
keyboards/lets_split/keymaps/khord/config.h | 3 -
keyboards/lets_split/keymaps/piemod/config.h | 1 -
keyboards/lets_split/keymaps/waples/config.h | 2 -
keyboards/lets_split/keymaps/xk/config.h | 1 -
keyboards/m10a/keymaps/gam3cat/config.h | 2 -
keyboards/mechmini/v2/config.h | 3 -
keyboards/melody96/config.h | 3 -
keyboards/minidox/keymaps/alairock/config.h | 1 -
keyboards/minidox/keymaps/khitsule/config.h | 4 +-
keyboards/mint60/config.h | 1 -
keyboards/mitosis/config.h | 2 -
keyboards/niu_mini/config.h | 3 -
keyboards/novelpad/config.h | 3 -
keyboards/noxary/268/config.h | 5 +-
keyboards/ok60/config.h | 3 -
keyboards/omnikey_blackheart/config.h | 6 +-
keyboards/paladin64/config.h | 2 -
keyboards/pegasushoof/keymaps/citadel/config.h | 3 -
keyboards/planck/keymaps/ajp10304/config.h | 8 ---
keyboards/planck/keymaps/altgr/config.h | 3 -
keyboards/planck/keymaps/am/config.h | 3 -
keyboards/planck/keymaps/andylikescandy/config.h | 3 -
keyboards/planck/keymaps/bone2planck/config.h | 8 ---
keyboards/planck/keymaps/davidrambo/config.h | 5 +-
keyboards/planck/keymaps/dshields/config.h | 1 -
keyboards/planck/keymaps/espynn/keymap.c | 1 -
keyboards/planck/keymaps/experimental/config.h | 2 -
keyboards/planck/keymaps/experimental/rules.mk | 3 +-
keyboards/planck/keymaps/hiea/config.h | 3 -
keyboards/planck/keymaps/hieax/config.h | 3 -
keyboards/planck/keymaps/ishtob/config.h | 2 -
keyboards/planck/keymaps/jarred/config.h | 4 +-
keyboards/planck/keymaps/jeremy-dev/keymap.c | 1 -
keyboards/planck/keymaps/kmontag42/rules.mk | 1 +
keyboards/planck/keymaps/lae3/config.h | 8 ---
keyboards/planck/keymaps/mitch/config.h | 3 +-
keyboards/planck/keymaps/mitch/readme.md | 4 --
keyboards/planck/keymaps/narze/config.h | 3 +-
keyboards/planck/keymaps/neo2planck/config.h | 8 ---
keyboards/planck/keymaps/priyadi/config.h | 2 -
keyboards/planck/keymaps/sdothum/config.h | 3 -
keyboards/planck/keymaps/steno/config.h | 4 +-
keyboards/planck/keymaps/tehwalris/config.h | 4 +-
keyboards/planck/keymaps/vifon/config.h | 3 -
keyboards/planck/keymaps/yale/config.h | 11 ----
keyboards/planck/keymaps/zach/config.h | 1 -
keyboards/planck/rev6/config.h | 3 -
keyboards/playkbtw/ca66/config.h | 2 -
keyboards/playkbtw/pk60/config.h | 5 +-
keyboards/preonic/keymaps/bucktooth/config.h | 1 -
keyboards/preonic/keymaps/jacwib/config.h | 1 -
keyboards/preonic/keymaps/kuatsure/rules.mk | 1 +
keyboards/preonic/keymaps/that_canadian/config.h | 8 ---
keyboards/preonic/keymaps/zach/config.h | 1 -
keyboards/preonic/rev3/config.h | 3 -
keyboards/prime_r/config.h | 4 --
.../rorschach/keymaps/insertsnideremarks/config.h | 1 -
keyboards/s60_x/keymaps/bluebear/config.h | 3 -
keyboards/s60_x/rgb/config.h | 5 +-
keyboards/s65_plus/config.h | 3 -
keyboards/s65_x/config.h | 4 --
keyboards/sx60/config.h | 4 --
keyboards/telophase/config.h | 2 -
keyboards/tetris/config.h | 5 +-
.../bananasplit/keymaps/talljoe/config.h | 1 -
keyboards/tokyo60/config.h | 3 -
keyboards/tomato/config.h | 3 -
keyboards/uk78/config.h | 3 -
keyboards/viterbi/keymaps/drashna/config.h | 2 +-
keyboards/whitefox/config.h | 2 -
keyboards/xd60/keymaps/kmontag42/rules.mk | 1 +
keyboards/xd75/keymaps/davidrambo/config.h | 3 +-
keyboards/xd75/keymaps/tdl-jturner/config.h | 1 -
keyboards/xmmx/config.h | 6 +-
keyboards/ymd96/keymaps/hgoel89/config.h | 1 -
keyboards/z150_blackheart/config.h | 6 +-
keyboards/zeal60/keymaps/tusing/config.h | 4 --
keyboards/zlant/config.h | 3 -
layouts/community/60_ansi/talljoe-ansi/config.h | 1 -
.../60_ansi_split_bs_rshift/talljoe/config.h | 1 -
layouts/community/60_hhkb/talljoe-hhkb/config.h | 1 -
layouts/community/ergodox/adam/config.h | 1 -
layouts/community/ergodox/albert/rules.mk | 3 +-
layouts/community/ergodox/algernon/rules.mk | 1 +
layouts/community/ergodox/alphadox/config.h | 1 -
layouts/community/ergodox/deadcyclo/rules.mk | 1 +
.../community/ergodox/erez_experimental/rules.mk | 3 +-
layouts/community/ergodox/familiar/rules.mk | 1 +
layouts/community/ergodox/mclennon_osx/README.md | 4 +-
layouts/community/ergodox/techtomas/readme.md | 2 +-
layouts/community/ortho_4x12/symbolic/config.h | 4 --
layouts/community/tkl_ansi/talljoe-tkl/config.h | 1 -
quantum/process_keycode/process_chording.c | 76 ----------------------
quantum/process_keycode/process_chording.h | 32 ---------
quantum/process_keycode/process_leader.c | 2 +-
quantum/quantum.c | 7 +-
quantum/quantum.h | 7 +-
quantum/quantum_keycodes.h | 6 +-
tmk_core/common/action.c | 2 +-
tmk_core/common/action.h | 2 +-
tmk_core/common/action_layer.c | 4 +-
tmk_core/common/action_layer.h | 2 +-
users/333fred/333fred_config.h | 1 -
users/bocaj/config.h | 1 -
users/drashna/config.h | 5 --
users/ishtob/config.h | 3 +-
users/replicaJunction/config.h | 6 --
users/talljoe/config.h | 1 -
users/wanleg/config.h | 2 -
users/zer09/config.h | 2 +-
198 files changed, 91 insertions(+), 599 deletions(-)
delete mode 100644 keyboards/jj40/keymaps/ajp10304/config.h
delete mode 100644 keyboards/m10a/keymaps/gam3cat/config.h
delete mode 100644 keyboards/planck/keymaps/ajp10304/config.h
delete mode 100644 keyboards/planck/keymaps/bone2planck/config.h
delete mode 100644 keyboards/planck/keymaps/lae3/config.h
delete mode 100644 keyboards/planck/keymaps/neo2planck/config.h
delete mode 100644 keyboards/planck/keymaps/yale/config.h
delete mode 100644 keyboards/preonic/keymaps/that_canadian/config.h
create mode 100644 keyboards/xd60/keymaps/kmontag42/rules.mk
delete mode 100644 quantum/process_keycode/process_chording.c
delete mode 100644 quantum/process_keycode/process_chording.h
(limited to 'tmk_core/common')
diff --git a/common_features.mk b/common_features.mk
index c637582d4..7af778980 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -221,7 +221,6 @@ ifeq ($(strip $(USB_HID_ENABLE)), yes)
include $(TMK_DIR)/protocol/usb_hid.mk
endif
-
ifeq ($(strip $(HD44780_ENABLE)), yes)
SRC += drivers/avr/hd44780.c
OPT_DEFS += -DHD44780_ENABLE
@@ -232,11 +231,15 @@ ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/dynamic_keymap.c
endif
+ifeq ($(strip $(LEADER_ENABLE)), yes)
+ SRC += $(QUANTUM_DIR)/process_keycode/process_leader.c
+ OPT_DEFS += -DLEADER_ENABLE
+endif
+
QUANTUM_SRC:= \
$(QUANTUM_DIR)/quantum.c \
$(QUANTUM_DIR)/keymap_common.c \
- $(QUANTUM_DIR)/keycode_config.c \
- $(QUANTUM_DIR)/process_keycode/process_leader.c
+ $(QUANTUM_DIR)/keycode_config.c
ifndef CUSTOM_MATRIX
ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
@@ -251,5 +254,5 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_flags.c \
$(QUANTUM_DIR)/split_common/split_util.c \
$(QUANTUM_DIR)/split_common/i2c.c \
- $(QUANTUM_DIR)/split_common/serial.c
+ $(QUANTUM_DIR)/split_common/serial.c
endif
diff --git a/docs/config_options.md b/docs/config_options.md
index eaaa59872..072857727 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -119,8 +119,8 @@ If you define these options you will enable the associated feature, which may in
* `#define FORCE_NKRO`
* NKRO by default requires to be turned on, this forces it on during keyboard startup regardless of EEPROM setting. NKRO can still be turned off but will be turned on again if the keyboard reboots.
-* `#define PREVENT_STUCK_MODIFIERS`
- * stores the layer a key press came from so the same layer is used when the key is released, regardless of which layers are enabled
+* `#define STRICT_LAYER_RELEASE`
+ * force a key release to be evaluated using the current layer stack instead of remembering which layer it came from (used for advanced cases)
## Behaviors That Can Be Configured
diff --git a/docs/feature_leader_key.md b/docs/feature_leader_key.md
index 46633b287..0c3f4a133 100644
--- a/docs/feature_leader_key.md
+++ b/docs/feature_leader_key.md
@@ -39,3 +39,11 @@ void matrix_scan_user(void) {
As you can see, you have a few function. You can use `SEQ_ONE_KEY` for single-key sequences (Leader followed by just one key), and `SEQ_TWO_KEYS`, `SEQ_THREE_KEYS` up to `SEQ_FIVE_KEYS` for longer sequences.
Each of these accepts one or more keycodes as arguments. This is an important point: You can use keycodes from **any layer on your keyboard**. That layer would need to be active for the leader macro to fire, obviously.
+
+## Adding Leader Key Support in the `rules.mk`
+
+To add support for Leader Key you simply need to add a single line to your keymap's `rules.mk`:
+
+```
+LEADER_ENABLE = yes
+```
diff --git a/docs/understanding_qmk.md b/docs/understanding_qmk.md
index bf695d008..35596cc69 100644
--- a/docs/understanding_qmk.md
+++ b/docs/understanding_qmk.md
@@ -129,6 +129,7 @@ Comparing against our keymap we can see that the pressed key is KC_NLCK. From he
##### Process Record
+
The `process_record()` function itself is deceptively simple, but hidden within is a gateway to overriding functionality at various levels of QMK. The chain of events is listed below, using cluecard whenever we need to look at the keyboard/keymap level functions. Depending on options set in rule.mk or elsewhere, only a subset of the functions below will be included in final firmware.
* [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/08c682c193f43e5d54df990680ae93fc2e06150a/tmk_core/common/action.c#L172)
@@ -146,7 +147,6 @@ The `process_record()` function itself is deceptively simple, but hidden within
* [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/661ca4440cc42f3b60697e98985c44b0571ccfc1/quantum/process_keycode/process_music.c#L114)
* [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/661ca4440cc42f3b60697e98985c44b0571ccfc1/quantum/process_keycode/process_tap_dance.c#L136)
* [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/661ca4440cc42f3b60697e98985c44b0571ccfc1/quantum/process_keycode/process_leader.c#L38)
- * [`bool process_chording(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/661ca4440cc42f3b60697e98985c44b0571ccfc1/quantum/process_keycode/process_chording.c#L41)
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/661ca4440cc42f3b60697e98985c44b0571ccfc1/quantum/process_keycode/process_combo.c#L115)
* [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/661ca4440cc42f3b60697e98985c44b0571ccfc1/quantum/process_keycode/process_unicode.c#L22)
* [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/661ca4440cc42f3b60697e98985c44b0571ccfc1/quantum/process_keycode/process_ucis.c#L91)
diff --git a/keyboards/1upkeyboards/1up60rgb/config.h b/keyboards/1upkeyboards/1up60rgb/config.h
index bfdf354af..ee49211b4 100644
--- a/keyboards/1upkeyboards/1up60rgb/config.h
+++ b/keyboards/1upkeyboards/1up60rgb/config.h
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/1upkeyboards/sweet16/config.h b/keyboards/1upkeyboards/sweet16/config.h
index 77d9e276d..20d99651d 100644
--- a/keyboards/1upkeyboards/sweet16/config.h
+++ b/keyboards/1upkeyboards/sweet16/config.h
@@ -9,7 +9,7 @@
#define DEVICE_VER 0x0001
#define MANUFACTURER 1up Keyboards
#define PRODUCT Sweet16
-#define DESCRIPTION 4x4 grid
+#define DESCRIPTION 4x4 grid
/* key matrix size */
#define MATRIX_ROWS 4
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN B1
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
@@ -55,4 +52,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/acr60/config.h b/keyboards/acr60/config.h
index c44ba737e..3066f349d 100644
--- a/keyboards/acr60/config.h
+++ b/keyboards/acr60/config.h
@@ -41,9 +41,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 20
diff --git a/keyboards/alf/x2/config.h b/keyboards/alf/x2/config.h
index 31212ce33..f2106fa88 100644
--- a/keyboards/alf/x2/config.h
+++ b/keyboards/alf/x2/config.h
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
@@ -55,4 +52,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/alpha/config.h b/keyboards/alpha/config.h
index 029527563..1e16f5ca3 100755
--- a/keyboards/alpha/config.h
+++ b/keyboards/alpha/config.h
@@ -43,8 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
#define RGB_DI_PIN F4
#ifdef RGB_DI_PIN
diff --git a/keyboards/alu84/config.h b/keyboards/alu84/config.h
index 9e013dbcc..9d2dca409 100755
--- a/keyboards/alu84/config.h
+++ b/keyboards/alu84/config.h
@@ -59,9 +59,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLED_NUM 16
diff --git a/keyboards/at101_blackheart/config.h b/keyboards/at101_blackheart/config.h
index 6a809a02f..237cb095e 100644
--- a/keyboards/at101_blackheart/config.h
+++ b/keyboards/at101_blackheart/config.h
@@ -38,6 +38,3 @@
#define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
\ No newline at end of file
diff --git a/keyboards/atreus/keymaps/jeremy/keymap.c b/keyboards/atreus/keymaps/jeremy/keymap.c
index 42bef9d80..890980f41 100644
--- a/keyboards/atreus/keymaps/jeremy/keymap.c
+++ b/keyboards/atreus/keymaps/jeremy/keymap.c
@@ -4,8 +4,6 @@
#include "action_layer.h"
#include "keymap_colemak.h"
-#define PREVENT_STUCK_MODIFIERS
-
// Each layer gets a name for readability, which is then used in the keymap matrix below.
#define ALPH 0
#define NUMS 1
diff --git a/keyboards/atreus/keymaps/khitsule/config.h b/keyboards/atreus/keymaps/khitsule/config.h
index 19714ec7d..c74909a9f 100644
--- a/keyboards/atreus/keymaps/khitsule/config.h
+++ b/keyboards/atreus/keymaps/khitsule/config.h
@@ -3,8 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
-
#define IGNORE_MOD_TAP_INTERRUPT
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/atreus/keymaps/xk/config.h b/keyboards/atreus/keymaps/xk/config.h
index 2f8110167..a8b9c8805 100644
--- a/keyboards/atreus/keymaps/xk/config.h
+++ b/keyboards/atreus/keymaps/xk/config.h
@@ -30,8 +30,7 @@ the Free Software Foundation, either version 2 of the License, or
#define MOUSEKEY_WHEEL_MAX_SPEED 8
#define MOUSEKEY_WHEEL_TIME_TO_MAX 40
-#define PREVENT_STUCK_MODIFIERS
#define IGNORE_MOD_TAP_INTERRUPT
#define PERMISSIVE_HOLD
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/atreus62/keymaps/mneme/config.h b/keyboards/atreus62/keymaps/mneme/config.h
index 73eb0fa33..a89bf5503 100644
--- a/keyboards/atreus62/keymaps/mneme/config.h
+++ b/keyboards/atreus62/keymaps/mneme/config.h
@@ -1,6 +1,5 @@
#define ONESHOT_TIMEOUT 3000
#define TAPPING_TERM 200
-#define PREVENT_STUCK_MODIFIERS
#define FORCE_NKRO
#define LEADER_TIMEOUT 1000
diff --git a/keyboards/atreus62/keymaps/mneme/rules.mk b/keyboards/atreus62/keymaps/mneme/rules.mk
index 046aec273..160ce6edb 100644
--- a/keyboards/atreus62/keymaps/mneme/rules.mk
+++ b/keyboards/atreus62/keymaps/mneme/rules.mk
@@ -3,3 +3,4 @@ NKRO_ENABLE = true
MOUSEKEY_ENABLE = no
EXTRAKEY_ENABLE = yes
CONSOLE_ENABLE = no
+LEADER_ENABLE = yes
diff --git a/keyboards/bfo9000/keymaps/andylikescandy6x18/config.h b/keyboards/bfo9000/keymaps/andylikescandy6x18/config.h
index 9d124a98e..be57e385e 100644
--- a/keyboards/bfo9000/keymaps/andylikescandy6x18/config.h
+++ b/keyboards/bfo9000/keymaps/andylikescandy6x18/config.h
@@ -37,7 +37,4 @@ along with this program. If not, see .
#define PERMISSIVE_HOLD
- #define PREVENT_STUCK_MODIFIERS
-
-
#endif
diff --git a/keyboards/bigseries/1key/config.h b/keyboards/bigseries/1key/config.h
index 4e30276fc..966f2062c 100755
--- a/keyboards/bigseries/1key/config.h
+++ b/keyboards/bigseries/1key/config.h
@@ -47,9 +47,6 @@ along with this program. If not, see .
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef RGBLIGHT_ENABLE
#define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/bigseries/2key/config.h b/keyboards/bigseries/2key/config.h
index 83c8e3141..79b9ed378 100755
--- a/keyboards/bigseries/2key/config.h
+++ b/keyboards/bigseries/2key/config.h
@@ -47,9 +47,6 @@ along with this program. If not, see .
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef RGBLIGHT_ENABLE
#define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/bigseries/3key/config.h b/keyboards/bigseries/3key/config.h
index e10b14db4..9963a8219 100755
--- a/keyboards/bigseries/3key/config.h
+++ b/keyboards/bigseries/3key/config.h
@@ -47,9 +47,6 @@ along with this program. If not, see .
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef RGBLIGHT_ENABLE
#define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/bigseries/4key/config.h b/keyboards/bigseries/4key/config.h
index 3ebcfe091..a222512d3 100755
--- a/keyboards/bigseries/4key/config.h
+++ b/keyboards/bigseries/4key/config.h
@@ -47,9 +47,6 @@ along with this program. If not, see .
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef RGBLIGHT_ENABLE
#define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/bigswitch/config.h b/keyboards/bigswitch/config.h
index cc290fd79..a0ef6b555 100755
--- a/keyboards/bigswitch/config.h
+++ b/keyboards/bigswitch/config.h
@@ -47,8 +47,6 @@ along with this program. If not, see .
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
#ifdef RGBLIGHT_ENABLE
#define RGB_DI_PIN D3
diff --git a/keyboards/catch22/config.h b/keyboards/catch22/config.h
index cb7ca7d84..f151e7048 100644
--- a/keyboards/catch22/config.h
+++ b/keyboards/catch22/config.h
@@ -46,9 +46,6 @@ along with this program. If not, see .
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef RGBLIGHT_ENABLE
#define RGB_DI_PIN F6
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/chimera_ergo/config.h b/keyboards/chimera_ergo/config.h
index 86ee23718..8ce195cc0 100644
--- a/keyboards/chimera_ergo/config.h
+++ b/keyboards/chimera_ergo/config.h
@@ -52,8 +52,6 @@ along with this program. If not, see .
* These options are also useful to firmware size reduction.
*/
-#define PREVENT_STUCK_MODIFIERS
-
/* disable debug print */
//#define NO_DEBUG
diff --git a/keyboards/chimera_ls/config.h b/keyboards/chimera_ls/config.h
index d92878026..254dad306 100644
--- a/keyboards/chimera_ls/config.h
+++ b/keyboards/chimera_ls/config.h
@@ -52,8 +52,6 @@ along with this program. If not, see .
* These options are also useful to firmware size reduction.
*/
-#define PREVENT_STUCK_MODIFIERS
-
/* disable debug print */
//#define NO_DEBUG
diff --git a/keyboards/chimera_ortho/config.h b/keyboards/chimera_ortho/config.h
index 44c6212b1..4bf85eb88 100644
--- a/keyboards/chimera_ortho/config.h
+++ b/keyboards/chimera_ortho/config.h
@@ -52,8 +52,6 @@ along with this program. If not, see .
* These options are also useful to firmware size reduction.
*/
-#define PREVENT_STUCK_MODIFIERS
-
/* disable debug print */
//#define NO_DEBUG
diff --git a/keyboards/chocopad/config.h b/keyboards/chocopad/config.h
index bf861ccda..2163ff8bc 100644
--- a/keyboards/chocopad/config.h
+++ b/keyboards/chocopad/config.h
@@ -40,10 +40,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLIGHT_HUE_STEP 8
@@ -56,4 +52,4 @@
#define ws2812_PORTREG PORTD
#define ws2812_DDRREG DDRD
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/clueboard/60/config.h b/keyboards/clueboard/60/config.h
index 5c5a86296..a862d2cda 100644
--- a/keyboards/clueboard/60/config.h
+++ b/keyboards/clueboard/60/config.h
@@ -49,9 +49,6 @@
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCE 6
-/* Prevent modifiers from being stuck on after layer changes. */
-#define PREVENT_STUCK_MODIFIERS
-
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
//#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
diff --git a/keyboards/clueboard/66/keymaps/bloodlvst/config.h b/keyboards/clueboard/66/keymaps/bloodlvst/config.h
index 320401dbd..456936cf9 100644
--- a/keyboards/clueboard/66/keymaps/bloodlvst/config.h
+++ b/keyboards/clueboard/66/keymaps/bloodlvst/config.h
@@ -3,6 +3,5 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
#define DISABLE_SPACE_CADET_ROLLOVER
#endif
diff --git a/keyboards/comet46/config.h b/keyboards/comet46/config.h
index 90d923f90..2421f5341 100644
--- a/keyboards/comet46/config.h
+++ b/keyboards/comet46/config.h
@@ -52,8 +52,6 @@ along with this program. If not, see .
* These options are also useful to firmware size reduction.
*/
-#define PREVENT_STUCK_MODIFIERS
-
/* disable debug print */
//#define NO_DEBUG
diff --git a/keyboards/contra/config.h b/keyboards/contra/config.h
index 85077ed46..c6bb374da 100755
--- a/keyboards/contra/config.h
+++ b/keyboards/contra/config.h
@@ -43,10 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
diff --git a/keyboards/contra/keymaps/ryanm101/config.h b/keyboards/contra/keymaps/ryanm101/config.h
index 9a458b892..224a4a37d 100644
--- a/keyboards/contra/keymaps/ryanm101/config.h
+++ b/keyboards/contra/keymaps/ryanm101/config.h
@@ -3,7 +3,6 @@
#include "config_common.h"
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_TERM 200
#ifdef AUDIO_ENABLE
@@ -28,7 +27,7 @@
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
-
+
#define MIDI_BASIC
/* enable advanced MIDI features:
@@ -42,4 +41,4 @@
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/crawlpad/config.h b/keyboards/crawlpad/config.h
index a07c79cd2..c72be83f2 100755
--- a/keyboards/crawlpad/config.h
+++ b/keyboards/crawlpad/config.h
@@ -40,9 +40,6 @@
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef RGBLIGHT_ENABLE
#define RGB_DI_PIN D3
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/crkbd/keymaps/default/config.h b/keyboards/crkbd/keymaps/default/config.h
index 8d25f7cbc..c573530f7 100644
--- a/keyboards/crkbd/keymaps/default/config.h
+++ b/keyboards/crkbd/keymaps/default/config.h
@@ -36,7 +36,6 @@ along with this program. If not, see .
#define USE_SERIAL_PD2
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
diff --git a/keyboards/dichotemy/config.h b/keyboards/dichotemy/config.h
index b3bd6d942..1d92cf74e 100644
--- a/keyboards/dichotemy/config.h
+++ b/keyboards/dichotemy/config.h
@@ -52,8 +52,6 @@ along with this program. If not, see .
* These options are also useful to firmware size reduction.
*/
-#define PREVENT_STUCK_MODIFIERS
-
/* disable debug print */
//#define NO_DEBUG
diff --git a/keyboards/dilly/config.h b/keyboards/dilly/config.h
index 97a6e533b..d9ca4597c 100644
--- a/keyboards/dilly/config.h
+++ b/keyboards/dilly/config.h
@@ -43,10 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLIGHT_HUE_STEP 8
@@ -59,4 +55,4 @@
#define ws2812_PORTREG PORTD
#define ws2812_DDRREG DDRD
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/dz60/config.h b/keyboards/dz60/config.h
index 8e1a5ae5f..e58eae085 100644
--- a/keyboards/dz60/config.h
+++ b/keyboards/dz60/config.h
@@ -41,9 +41,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 16
diff --git a/keyboards/dz60/keymaps/LEdiodes/config.h b/keyboards/dz60/keymaps/LEdiodes/config.h
index bb78d9bb6..4f991b9ca 100644
--- a/keyboards/dz60/keymaps/LEdiodes/config.h
+++ b/keyboards/dz60/keymaps/LEdiodes/config.h
@@ -41,9 +41,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 16
diff --git a/keyboards/ergodone/config.h b/keyboards/ergodone/config.h
index 1feff26aa..2c764d782 100644
--- a/keyboards/ergodone/config.h
+++ b/keyboards/ergodone/config.h
@@ -53,8 +53,6 @@
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 5
-#define PREVENT_STUCK_MODIFIERS
-
#define USB_MAX_POWER_CONSUMPTION 500
/* NKRO */
diff --git a/keyboards/ergodox_ez/config.h b/keyboards/ergodox_ez/config.h
index 07a9b5497..7a350183b 100644
--- a/keyboards/ergodox_ez/config.h
+++ b/keyboards/ergodox_ez/config.h
@@ -97,8 +97,6 @@ along with this program. If not, see .
*/
#define DEBOUNCE 15
-#define PREVENT_STUCK_MODIFIERS
-
#define USB_MAX_POWER_CONSUMPTION 500
// RGB backlight
diff --git a/keyboards/ergodox_ez/keymaps/heartrobotninja/rules.mk b/keyboards/ergodox_ez/keymaps/heartrobotninja/rules.mk
index 38112a906..db5e5d155 100644
--- a/keyboards/ergodox_ez/keymaps/heartrobotninja/rules.mk
+++ b/keyboards/ergodox_ez/keymaps/heartrobotninja/rules.mk
@@ -13,6 +13,7 @@ AUTOLOG_ENABLE = no
RGBLIGHT_ENABLE = yes
RGBLIGHT_ANIMATION = yes
EXTRAKEY_ENABLE = yes
+LEADER_ENABLE = yes
OPT_DEFS += -DUSER_PRINT
@@ -31,4 +32,4 @@ OPT_DEFS += -DKEYMAP_VERSION=\"$(KEYMAP_VERSION)\\\#$(KEYMAP_BRANCH)\"
ifndef QUANTUM_DIR
include ../../../../Makefile
-endif
\ No newline at end of file
+endif
diff --git a/keyboards/ergodox_ez/keymaps/vim/vim.h b/keyboards/ergodox_ez/keymaps/vim/vim.h
index e9b682fd3..7565c6e3e 100644
--- a/keyboards/ergodox_ez/keymaps/vim/vim.h
+++ b/keyboards/ergodox_ez/keymaps/vim/vim.h
@@ -9,7 +9,6 @@
#define PRESS(keycode) register_code16(keycode)
#define RELEASE(keycode) unregister_code16(keycode)
-#define PREVENT_STUCK_MODIFIERS
uint16_t VIM_QUEUE = KC_NO;
diff --git a/keyboards/ergodox_infinity/keymaps/gordon/config.h b/keyboards/ergodox_infinity/keymaps/gordon/config.h
index 88d495b12..772ce0bac 100644
--- a/keyboards/ergodox_infinity/keymaps/gordon/config.h
+++ b/keyboards/ergodox_infinity/keymaps/gordon/config.h
@@ -15,8 +15,6 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#define PREVENT_STUCK_MODIFIERS
-
#undef IGNORE_MOD_TAP_INTERRUPT
#define IGNORE_MOD_TAP_INTERRUPT
diff --git a/keyboards/ergodox_infinity/keymaps/narze/config.h b/keyboards/ergodox_infinity/keymaps/narze/config.h
index 8174edd35..551327a12 100644
--- a/keyboards/ergodox_infinity/keymaps/narze/config.h
+++ b/keyboards/ergodox_infinity/keymaps/narze/config.h
@@ -13,7 +13,6 @@
#define IGNORE_MOD_TAP_INTERRUPT
#define PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
#undef MOUSEKEY_DELAY
#define MOUSEKEY_DELAY 100
diff --git a/keyboards/ergodox_infinity/keymaps/not-quite-neo/rules.mk b/keyboards/ergodox_infinity/keymaps/not-quite-neo/rules.mk
index 75624bb8c..74505bd69 100644
--- a/keyboards/ergodox_infinity/keymaps/not-quite-neo/rules.mk
+++ b/keyboards/ergodox_infinity/keymaps/not-quite-neo/rules.mk
@@ -1,2 +1,3 @@
BACKLIGHT_ENABLE = yes
-UNICODE_ENABLE = yes
\ No newline at end of file
+UNICODE_ENABLE = yes
+LEADER_ENABLE = yes
diff --git a/keyboards/ergoinu/config.h b/keyboards/ergoinu/config.h
index 4b7c58400..de72635b1 100644
--- a/keyboards/ergoinu/config.h
+++ b/keyboards/ergoinu/config.h
@@ -31,8 +31,6 @@ along with this program. If not, see .
#define PRODUCT ergoinu
#define DESCRIPTION An (Not Portable But Small) Ergonomic split keyboard
-
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
diff --git a/keyboards/ergotravel/keymaps/ckofy/config.h b/keyboards/ergotravel/keymaps/ckofy/config.h
index caae080d7..41ec06657 100644
--- a/keyboards/ergotravel/keymaps/ckofy/config.h
+++ b/keyboards/ergotravel/keymaps/ckofy/config.h
@@ -33,9 +33,6 @@ along with this program. If not, see .
#define TAPPING_TOGGLE 2
-// required if modifiers are defined in layers besided the default one.
-#define PREVENT_STUCK_MODIFIERS
-
#undef RGBLED_NUM
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 12
diff --git a/keyboards/felix/config.h b/keyboards/felix/config.h
index f70089af4..003fe87dc 100644
--- a/keyboards/felix/config.h
+++ b/keyboards/felix/config.h
@@ -42,8 +42,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
/* there is no rgb underglow by default. */
#define RGB_DI_PIN
@@ -53,4 +51,4 @@
#define RGBLIGHT_SAT_STEP 8
#define RGBLIGHT_VAL_STEP 8
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/four_banger/config.h b/keyboards/four_banger/config.h
index 96011cbdf..8dceff5db 100644
--- a/keyboards/four_banger/config.h
+++ b/keyboards/four_banger/config.h
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E6
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
@@ -55,4 +52,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/fourier/keymaps/jennetters/config.h b/keyboards/fourier/keymaps/jennetters/config.h
index 87cda7b5c..5f99c65ad 100644
--- a/keyboards/fourier/keymaps/jennetters/config.h
+++ b/keyboards/fourier/keymaps/jennetters/config.h
@@ -22,10 +22,7 @@ along with this program. If not, see .
#define TAPPING_TERM 100
-/* Try to prevent sticky keys */
-#define PREVENT_STUCK_MODIFIERS
-
/* Use I2C or Serial, not both */
#define USE_SERIAL
-// #define USE_I2C
\ No newline at end of file
+// #define USE_I2C
diff --git a/keyboards/fractal/config.h b/keyboards/fractal/config.h
index 30b703b6e..1a5901f98 100755
--- a/keyboards/fractal/config.h
+++ b/keyboards/fractal/config.h
@@ -43,10 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
diff --git a/keyboards/frosty_flake/keymaps/nikchi/rules.mk b/keyboards/frosty_flake/keymaps/nikchi/rules.mk
index ad86e82d2..b21eb6404 100644
--- a/keyboards/frosty_flake/keymaps/nikchi/rules.mk
+++ b/keyboards/frosty_flake/keymaps/nikchi/rules.mk
@@ -1,5 +1,5 @@
# Build Options
-# change to "no" to disable the options, or define them in the Makefile in
+# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
@@ -17,6 +17,7 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
TAP_DANCE_ENABLE = yes
+LEADER_ENABLE = yes
ifndef QUANTUM_DIR
include ../../../../Makefile
diff --git a/keyboards/gh80_3000/config.h b/keyboards/gh80_3000/config.h
index 83d30129a..ca72aba5a 100644
--- a/keyboards/gh80_3000/config.h
+++ b/keyboards/gh80_3000/config.h
@@ -43,10 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
@@ -55,4 +51,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/gherkin/config.h b/keyboards/gherkin/config.h
index 4607962d7..34f38e35c 100644
--- a/keyboards/gherkin/config.h
+++ b/keyboards/gherkin/config.h
@@ -43,10 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
@@ -55,4 +51,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/gherkin/keymaps/talljoe_gherkin/config.h b/keyboards/gherkin/keymaps/talljoe_gherkin/config.h
index 3e9e692d3..7fa3bf328 100644
--- a/keyboards/gherkin/keymaps/talljoe_gherkin/config.h
+++ b/keyboards/gherkin/keymaps/talljoe_gherkin/config.h
@@ -3,6 +3,4 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/gonnerd/keymaps/gam3cat/config.h b/keyboards/gonnerd/keymaps/gam3cat/config.h
index a3819d3a5..d86da86e4 100644
--- a/keyboards/gonnerd/keymaps/gam3cat/config.h
+++ b/keyboards/gonnerd/keymaps/gam3cat/config.h
@@ -1,7 +1,6 @@
#include "../../config.h"
//GRAVE_ESC override for CTRL+SHIFT+ESC Windows task manager shortcut.
#define GRAVE_ESC_CTRL_OVERRIDE
-#define PREVENT_STUCK_MODIFIERS
//Delay matrix scan for tap dance, reduce to activate modifier keys faster.
//#define TAPPING_TERM 200
diff --git a/keyboards/hadron/keymaps/default/config.h b/keyboards/hadron/keymaps/default/config.h
index 0f349ad93..09922b61b 100644
--- a/keyboards/hadron/keymaps/default/config.h
+++ b/keyboards/hadron/keymaps/default/config.h
@@ -5,7 +5,6 @@
#define LEADER_TIMEOUT 300
//#define BACKLIGHT_BREATHING
-#define PREVENT_STUCK_MODIFIERS
#define USE_I2C
#define SSD1306OLED
diff --git a/keyboards/hadron/keymaps/side_numpad/config.h b/keyboards/hadron/keymaps/side_numpad/config.h
index 0f349ad93..09922b61b 100644
--- a/keyboards/hadron/keymaps/side_numpad/config.h
+++ b/keyboards/hadron/keymaps/side_numpad/config.h
@@ -5,7 +5,6 @@
#define LEADER_TIMEOUT 300
//#define BACKLIGHT_BREATHING
-#define PREVENT_STUCK_MODIFIERS
#define USE_I2C
#define SSD1306OLED
diff --git a/keyboards/handwired/MS_sculpt_mobile/config.h b/keyboards/handwired/MS_sculpt_mobile/config.h
index f89514278..c3bdf333e 100644
--- a/keyboards/handwired/MS_sculpt_mobile/config.h
+++ b/keyboards/handwired/MS_sculpt_mobile/config.h
@@ -28,10 +28,10 @@ along with this program. If not, see .
#define DESCRIPTION 6000
/* key matrix size */
-#define MATRIX_ROWS 8
-#define MATRIX_COLS 18
+#define MATRIX_ROWS 8
+#define MATRIX_COLS 18
-#ifdef ASTAR
+#ifdef ASTAR
#define PRODUCT sculpt mobile astar
/*0 1 2 3 4 5 6 7 8 */
#define MATRIX_ROW_PINS {D7, C6, D4, D0, D1, D3, D2, E2}
@@ -95,6 +95,4 @@ along with this program. If not, see .
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
-#define PREVENT_STUCK_MODIFIERS
-
#endif
diff --git a/keyboards/handwired/atreus50/keymaps/ajp10304/config.h b/keyboards/handwired/atreus50/keymaps/ajp10304/config.h
index 6916d1a7d..f5e6bbabe 100644
--- a/keyboards/handwired/atreus50/keymaps/ajp10304/config.h
+++ b/keyboards/handwired/atreus50/keymaps/ajp10304/config.h
@@ -3,8 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
-
#undef MATRIX_ROW_PINS
#undef MATRIX_COL_PINS
diff --git a/keyboards/handwired/dactyl/config.h b/keyboards/handwired/dactyl/config.h
index a990cc720..08931ecd3 100644
--- a/keyboards/handwired/dactyl/config.h
+++ b/keyboards/handwired/dactyl/config.h
@@ -63,8 +63,6 @@ along with this program. If not, see .
/* Set 0 if debouncing isn't needed */
#define DEBOUNCE 15
-#define PREVENT_STUCK_MODIFIERS
-
#define USB_MAX_POWER_CONSUMPTION 500
#endif
diff --git a/keyboards/handwired/kbod/config.h b/keyboards/handwired/kbod/config.h
index f3d0c8bf2..a3f3e3908 100644
--- a/keyboards/handwired/kbod/config.h
+++ b/keyboards/handwired/kbod/config.h
@@ -48,7 +48,7 @@ along with this program. If not, see .
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
#define DIODE_DIRECTION COL2ROW
-
+
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
@@ -159,8 +159,6 @@ along with this program. If not, see .
//#define NO_ACTION_MACRO
//#define NO_ACTION_FUNCTION
-#define PREVENT_STUCK_MODIFIERS
-
#undef TAPPING_TOGGLE
#define TAPPING_TOGGLE 2
diff --git a/keyboards/handwired/promethium/keymaps/default/config.h b/keyboards/handwired/promethium/keymaps/default/config.h
index fa86e2247..2064f3676 100644
--- a/keyboards/handwired/promethium/keymaps/default/config.h
+++ b/keyboards/handwired/promethium/keymaps/default/config.h
@@ -11,8 +11,6 @@
/* skip bootmagic and eeconfig */
#define BOOTMAGIC_KEY_SKIP KC_SPACE
-#define PREVENT_STUCK_MODIFIERS
-
#define RGBSPS_ENABLE
#define RGBSPS_DEMO_ENABLE
diff --git a/keyboards/handwired/promethium/keymaps/priyadi/config.h b/keyboards/handwired/promethium/keymaps/priyadi/config.h
index fa86e2247..2064f3676 100644
--- a/keyboards/handwired/promethium/keymaps/priyadi/config.h
+++ b/keyboards/handwired/promethium/keymaps/priyadi/config.h
@@ -11,8 +11,6 @@
/* skip bootmagic and eeconfig */
#define BOOTMAGIC_KEY_SKIP KC_SPACE
-#define PREVENT_STUCK_MODIFIERS
-
#define RGBSPS_ENABLE
#define RGBSPS_DEMO_ENABLE
diff --git a/keyboards/handwired/space_oddity/config.h b/keyboards/handwired/space_oddity/config.h
index 9c9361ced..46d854099 100644
--- a/keyboards/handwired/space_oddity/config.h
+++ b/keyboards/handwired/space_oddity/config.h
@@ -49,10 +49,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
diff --git a/keyboards/helix/pico/config.h b/keyboards/helix/pico/config.h
index b49f0173b..41edfcbc2 100644
--- a/keyboards/helix/pico/config.h
+++ b/keyboards/helix/pico/config.h
@@ -28,7 +28,6 @@ along with this program. If not, see .
#define DESCRIPTION A split keyboard for the cheap makers
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
diff --git a/keyboards/helix/rev1/keymaps/OLED_sample/config.h b/keyboards/helix/rev1/keymaps/OLED_sample/config.h
index 0e1b787a5..5e8989d96 100644
--- a/keyboards/helix/rev1/keymaps/OLED_sample/config.h
+++ b/keyboards/helix/rev1/keymaps/OLED_sample/config.h
@@ -35,7 +35,8 @@ along with this program. If not, see .
#define SSD1306OLED
-#define PREVENT_STUCK_MODIFIERS
+#define USE_SERIAL_PD2
+
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
diff --git a/keyboards/helix/rev2/config.h b/keyboards/helix/rev2/config.h
index 058236122..b354d312d 100644
--- a/keyboards/helix/rev2/config.h
+++ b/keyboards/helix/rev2/config.h
@@ -28,7 +28,6 @@ along with this program. If not, see .
#define DESCRIPTION A split keyboard for the cheap makers
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
diff --git a/keyboards/hhkb/keymaps/blakedietz/rules.mk b/keyboards/hhkb/keymaps/blakedietz/rules.mk
index 7c16b2c98..7d97e7a52 100644
--- a/keyboards/hhkb/keymaps/blakedietz/rules.mk
+++ b/keyboards/hhkb/keymaps/blakedietz/rules.mk
@@ -1,2 +1,3 @@
TAP_DANCE_ENABLE = no
UNICODE_ENABLE = no
+LEADER_ENABLE = yes
diff --git a/keyboards/infinity60/config.h b/keyboards/infinity60/config.h
index 8306c8f7e..c1e9ec5b1 100644
--- a/keyboards/infinity60/config.h
+++ b/keyboards/infinity60/config.h
@@ -18,8 +18,6 @@ along with this program. If not, see .
#ifndef CONFIG_H
#define CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
-
/* USB Device descriptor parameter */
#define VENDOR_ID 0x1c11
#define PRODUCT_ID 0xb04d
diff --git a/keyboards/iris/keymaps/davidrambo/config.h b/keyboards/iris/keymaps/davidrambo/config.h
index 01e078e32..2cdff4213 100644
--- a/keyboards/iris/keymaps/davidrambo/config.h
+++ b/keyboards/iris/keymaps/davidrambo/config.h
@@ -27,7 +27,6 @@ along with this program. If not, see .
/* Select hand configuration */
#define PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
#define MASTER_LEFT
// #define MASTER_RIGHT
// #define EE_HANDS
diff --git a/keyboards/iris/keymaps/jennetters/config.h b/keyboards/iris/keymaps/jennetters/config.h
index a3c0634f5..42f91bd02 100644
--- a/keyboards/iris/keymaps/jennetters/config.h
+++ b/keyboards/iris/keymaps/jennetters/config.h
@@ -19,9 +19,6 @@ along with this program. If not, see .
#define TAPPING_TERM 150
-/* Try to prevent sticky keys */
-#define PREVENT_STUCK_MODIFIERS
-
/* Use I2C or Serial, not both */
#define USE_SERIAL
@@ -38,4 +35,4 @@ along with this program. If not, see .
#define RGBLED_NUM 12
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8
-#define RGBLIGHT_VAL_STEP 8
\ No newline at end of file
+#define RGBLIGHT_VAL_STEP 8
diff --git a/keyboards/iris/keymaps/krusli/config.h b/keyboards/iris/keymaps/krusli/config.h
index a53c746ad..72e35c472 100644
--- a/keyboards/iris/keymaps/krusli/config.h
+++ b/keyboards/iris/keymaps/krusli/config.h
@@ -20,8 +20,6 @@ along with this program. If not, see .
#include "config_common.h"
-// #define PREVENT_STUCK_MODIFIERS
-
/* Use I2C or Serial, not both */
#define USE_SERIAL
diff --git a/keyboards/iris/keymaps/xyverz/config.h b/keyboards/iris/keymaps/xyverz/config.h
index 0c61a8eac..b820a0753 100644
--- a/keyboards/iris/keymaps/xyverz/config.h
+++ b/keyboards/iris/keymaps/xyverz/config.h
@@ -23,8 +23,6 @@ along with this program. If not, see .
#define USE_SERIAL
#define EE_HANDS
-#define PREVENT_STUCK_MODIFIERS
-
#undef PRODUCT
#define PRODUCT Iris Keyboard
diff --git a/keyboards/jc65/v32u4/keymaps/gam3cat/config.h b/keyboards/jc65/v32u4/keymaps/gam3cat/config.h
index a3819d3a5..d86da86e4 100644
--- a/keyboards/jc65/v32u4/keymaps/gam3cat/config.h
+++ b/keyboards/jc65/v32u4/keymaps/gam3cat/config.h
@@ -1,7 +1,6 @@
#include "../../config.h"
//GRAVE_ESC override for CTRL+SHIFT+ESC Windows task manager shortcut.
#define GRAVE_ESC_CTRL_OVERRIDE
-#define PREVENT_STUCK_MODIFIERS
//Delay matrix scan for tap dance, reduce to activate modifier keys faster.
//#define TAPPING_TERM 200
diff --git a/keyboards/jj40/keymaps/ajp10304/config.h b/keyboards/jj40/keymaps/ajp10304/config.h
deleted file mode 100644
index 11cafbefc..000000000
--- a/keyboards/jj40/keymaps/ajp10304/config.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
diff --git a/keyboards/jj40/keymaps/fun40/config.h b/keyboards/jj40/keymaps/fun40/config.h
index 89807d84a..f2b5d264e 100644
--- a/keyboards/jj40/keymaps/fun40/config.h
+++ b/keyboards/jj40/keymaps/fun40/config.h
@@ -4,6 +4,5 @@
#include "../../config.h"
#define FORCE_NKRO
-#define PREVENT_STUCK_MODIFIERS
#endif
diff --git a/keyboards/jj40/keymaps/krusli/config.h b/keyboards/jj40/keymaps/krusli/config.h
index 6d98a37a6..e710dbbb6 100644
--- a/keyboards/jj40/keymaps/krusli/config.h
+++ b/keyboards/jj40/keymaps/krusli/config.h
@@ -3,7 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
// #define TAPPING_TERM 300
#endif
diff --git a/keyboards/jj40/keymaps/oscillope/config.h b/keyboards/jj40/keymaps/oscillope/config.h
index d7f991fa9..e812903de 100644
--- a/keyboards/jj40/keymaps/oscillope/config.h
+++ b/keyboards/jj40/keymaps/oscillope/config.h
@@ -3,7 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_TERM 200
#endif
diff --git a/keyboards/jj40/keymaps/suzuken/config.h b/keyboards/jj40/keymaps/suzuken/config.h
index 52aaa8f24..b1d74e1e6 100644
--- a/keyboards/jj40/keymaps/suzuken/config.h
+++ b/keyboards/jj40/keymaps/suzuken/config.h
@@ -3,7 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_TERM 300
#endif
diff --git a/keyboards/jj40/keymaps/waples/config.h b/keyboards/jj40/keymaps/waples/config.h
index 52aaa8f24..b1d74e1e6 100644
--- a/keyboards/jj40/keymaps/waples/config.h
+++ b/keyboards/jj40/keymaps/waples/config.h
@@ -3,7 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_TERM 300
#endif
diff --git a/keyboards/jm60/config.h b/keyboards/jm60/config.h
index 847cf2078..cb5c90bb1 100644
--- a/keyboards/jm60/config.h
+++ b/keyboards/jm60/config.h
@@ -18,8 +18,6 @@ along with this program. If not, see .
#ifndef CONFIG_H
#define CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
-
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6464
diff --git a/keyboards/k_type/config.h b/keyboards/k_type/config.h
index d19e0ff64..4937d9ad9 100644
--- a/keyboards/k_type/config.h
+++ b/keyboards/k_type/config.h
@@ -18,8 +18,6 @@ along with this program. If not, see .
#ifndef CONFIG_H
#define CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
-
/* USB Device descriptor parameter */
#define VENDOR_ID 0x1c11
#define PRODUCT_ID 0xb04d
diff --git a/keyboards/katana60/config.h b/keyboards/katana60/config.h
index 169cffb42..aaf2b5d54 100644
--- a/keyboards/katana60/config.h
+++ b/keyboards/katana60/config.h
@@ -48,7 +48,7 @@ along with this program. If not, see .
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
#define DIODE_DIRECTION ROW2COL
-
+
// #define BACKLIGHT_PIN B7
// #define BACKLIGHT_BREATHING
// #define BACKLIGHT_LEVELS 3
@@ -111,7 +111,6 @@ along with this program. If not, see .
)
#define TAPPING_TERM 200
-#define PREVENT_STUCK_MODIFIERS
/* control how magic key switches layers */
//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
diff --git a/keyboards/kbd75/config.h b/keyboards/kbd75/config.h
index f76d9082f..726afcaf6 100644
--- a/keyboards/kbd75/config.h
+++ b/keyboards/kbd75/config.h
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/kinesis/keymaps/insertsnideremarks/config.h b/keyboards/kinesis/keymaps/insertsnideremarks/config.h
index 3548fa348..9ce094be5 100644
--- a/keyboards/kinesis/keymaps/insertsnideremarks/config.h
+++ b/keyboards/kinesis/keymaps/insertsnideremarks/config.h
@@ -5,7 +5,6 @@
#include "../../config.h"
// place overrides here
-#define PREVENT_STUCK_MODIFIERS
#define IGNORE_MOD_TAP_INTERRUPT
#define TAPPING_TERM 175
#define TAPPING_TOGGLE 2
diff --git a/keyboards/lets_split/keymaps/OLED_sample/config.h b/keyboards/lets_split/keymaps/OLED_sample/config.h
index e8632fe61..6aa909d28 100644
--- a/keyboards/lets_split/keymaps/OLED_sample/config.h
+++ b/keyboards/lets_split/keymaps/OLED_sample/config.h
@@ -38,8 +38,6 @@ along with this program. If not, see .
#define SSD1306OLED
//#define OLED_ROTATE180
-
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
diff --git a/keyboards/lets_split/keymaps/adam/config.h b/keyboards/lets_split/keymaps/adam/config.h
index ff29eb1bd..59a2e5db7 100644
--- a/keyboards/lets_split/keymaps/adam/config.h
+++ b/keyboards/lets_split/keymaps/adam/config.h
@@ -43,7 +43,6 @@ along with this program. If not, see .
#undef TAPPING_TERM
#define TAPPING_TERM 200 //At 500 some bad logic takes hold
-#define PREVENT_STUCK_MODIFIERS
#define IGNORE_MOD_TAP_INTERRUPT
#define PERMISSIVE_HOLD
diff --git a/keyboards/lets_split/keymaps/khord/config.h b/keyboards/lets_split/keymaps/khord/config.h
index 4ebdbad76..71ec20dbc 100644
--- a/keyboards/lets_split/keymaps/khord/config.h
+++ b/keyboards/lets_split/keymaps/khord/config.h
@@ -25,9 +25,6 @@ along with this program. If not, see .
#define TAPPING_TERM 150
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
/* Use I2C or Serial, not both */
#define USE_SERIAL
diff --git a/keyboards/lets_split/keymaps/piemod/config.h b/keyboards/lets_split/keymaps/piemod/config.h
index 001b62e41..1b3fd7544 100644
--- a/keyboards/lets_split/keymaps/piemod/config.h
+++ b/keyboards/lets_split/keymaps/piemod/config.h
@@ -43,7 +43,6 @@ along with this program. If not, see .
#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 1
// Typing Options
-#define PREVENT_STUCK_MODIFIERS
#define QMK_KEYS_PER_SCAN 4
#endif
diff --git a/keyboards/lets_split/keymaps/waples/config.h b/keyboards/lets_split/keymaps/waples/config.h
index 98ebeff45..5221fd011 100644
--- a/keyboards/lets_split/keymaps/waples/config.h
+++ b/keyboards/lets_split/keymaps/waples/config.h
@@ -12,6 +12,4 @@
// #define MASTER_RIGHT
#define EE_HANDS // We like to have choices I guess
-#define PREVENT_STUCK_MODIFIERS // When switching layers, this will release all mods
-
#endif
diff --git a/keyboards/lets_split/keymaps/xk/config.h b/keyboards/lets_split/keymaps/xk/config.h
index c75ed12cc..a5cd51857 100644
--- a/keyboards/lets_split/keymaps/xk/config.h
+++ b/keyboards/lets_split/keymaps/xk/config.h
@@ -37,7 +37,6 @@ the Free Software Foundation, either version 2 of the License, or
#define EE_HANDS
-#define PREVENT_STUCK_MODIFIERS
#define IGNORE_MOD_TAP_INTERRUPT
#define PERMISSIVE_HOLD
diff --git a/keyboards/m10a/keymaps/gam3cat/config.h b/keyboards/m10a/keymaps/gam3cat/config.h
deleted file mode 100644
index 73bc50bc2..000000000
--- a/keyboards/m10a/keymaps/gam3cat/config.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
diff --git a/keyboards/mechmini/v2/config.h b/keyboards/mechmini/v2/config.h
index 58c751e0f..e0922bb7e 100755
--- a/keyboards/mechmini/v2/config.h
+++ b/keyboards/mechmini/v2/config.h
@@ -62,9 +62,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/melody96/config.h b/keyboards/melody96/config.h
index 6083dcf75..67123a7e5 100644
--- a/keyboards/melody96/config.h
+++ b/keyboards/melody96/config.h
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/minidox/keymaps/alairock/config.h b/keyboards/minidox/keymaps/alairock/config.h
index 445606031..3649fdd12 100644
--- a/keyboards/minidox/keymaps/alairock/config.h
+++ b/keyboards/minidox/keymaps/alairock/config.h
@@ -36,5 +36,4 @@ along with this program. If not, see .
#define RGBLIGHT_HUE_STEP 10
#define RGBLIGHT_SAT_STEP 17
#define RGBLIGHT_VAL_STEP 17
-#define PREVENT_STUCK_MODIFIERS
#endif
diff --git a/keyboards/minidox/keymaps/khitsule/config.h b/keyboards/minidox/keymaps/khitsule/config.h
index 702354864..645e80ee8 100644
--- a/keyboards/minidox/keymaps/khitsule/config.h
+++ b/keyboards/minidox/keymaps/khitsule/config.h
@@ -1,8 +1,6 @@
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
-#define PREVENT_STUCK_MODIFIERS
-
#define IGNORE_MOD_TAP_INTERRUPT
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/mint60/config.h b/keyboards/mint60/config.h
index 37b69e93a..51c586e63 100644
--- a/keyboards/mint60/config.h
+++ b/keyboards/mint60/config.h
@@ -29,7 +29,6 @@ along with this program. If not, see .
#define PRODUCT Mint60
#define DESCRIPTION A row staggered split keyboard
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_FORCE_HOLD
#define TAPPING_TERM 100
diff --git a/keyboards/mitosis/config.h b/keyboards/mitosis/config.h
index 6101ee123..5cfd2e4b1 100644
--- a/keyboards/mitosis/config.h
+++ b/keyboards/mitosis/config.h
@@ -52,8 +52,6 @@ along with this program. If not, see .
* These options are also useful to firmware size reduction.
*/
-#define PREVENT_STUCK_MODIFIERS
-
/* disable debug print */
//#define NO_DEBUG
diff --git a/keyboards/niu_mini/config.h b/keyboards/niu_mini/config.h
index 2f2230616..b9d3ed4e9 100644
--- a/keyboards/niu_mini/config.h
+++ b/keyboards/niu_mini/config.h
@@ -64,9 +64,6 @@ along with this program. If not, see .
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/novelpad/config.h b/keyboards/novelpad/config.h
index 0d6a71343..3a47c0eb6 100755
--- a/keyboards/novelpad/config.h
+++ b/keyboards/novelpad/config.h
@@ -53,9 +53,6 @@ along with this program. If not, see .
false \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define BACKLIGHT_LEVELS 10
#define BACKLIGHT_PIN B7
diff --git a/keyboards/noxary/268/config.h b/keyboards/noxary/268/config.h
index b2cb95e95..7eec79a1b 100644
--- a/keyboards/noxary/268/config.h
+++ b/keyboards/noxary/268/config.h
@@ -60,9 +60,6 @@ along with this program. If not, see .
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
/* ws2812b options */
#define RGB_DI_PIN B5
#ifdef RGB_DI_PIN
@@ -73,4 +70,4 @@ along with this program. If not, see .
#define RGBLIGHT_VAL_STEP 16
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/ok60/config.h b/keyboards/ok60/config.h
index 61c2fa0ed..db7b74e58 100644
--- a/keyboards/ok60/config.h
+++ b/keyboards/ok60/config.h
@@ -71,9 +71,6 @@ along with this program. If not, see .
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN F6
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 10
diff --git a/keyboards/omnikey_blackheart/config.h b/keyboards/omnikey_blackheart/config.h
index 14b4a5f17..94412cfa6 100644
--- a/keyboards/omnikey_blackheart/config.h
+++ b/keyboards/omnikey_blackheart/config.h
@@ -45,10 +45,6 @@
/* force n-key rollover*/
#define FORCE_NKRO
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
@@ -57,4 +53,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/paladin64/config.h b/keyboards/paladin64/config.h
index 27f54bf16..a5280f4d4 100755
--- a/keyboards/paladin64/config.h
+++ b/keyboards/paladin64/config.h
@@ -110,8 +110,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
#define RGB_DI_PIN D0
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/pegasushoof/keymaps/citadel/config.h b/keyboards/pegasushoof/keymaps/citadel/config.h
index e8eafe2e1..2d27ff392 100644
--- a/keyboards/pegasushoof/keymaps/citadel/config.h
+++ b/keyboards/pegasushoof/keymaps/citadel/config.h
@@ -8,7 +8,4 @@
#undef PRODUCT
#define PRODUCT Pegasus Hoof Citadel
-/* necessary option for this keymap, because CAPS is redefined in Layer 0 */
-#define PREVENT_STUCK_MODIFIERS
-
#endif
diff --git a/keyboards/planck/keymaps/ajp10304/config.h b/keyboards/planck/keymaps/ajp10304/config.h
deleted file mode 100644
index 11cafbefc..000000000
--- a/keyboards/planck/keymaps/ajp10304/config.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
diff --git a/keyboards/planck/keymaps/altgr/config.h b/keyboards/planck/keymaps/altgr/config.h
index d55258c02..e517a8b24 100644
--- a/keyboards/planck/keymaps/altgr/config.h
+++ b/keyboards/planck/keymaps/altgr/config.h
@@ -3,9 +3,6 @@
#include "../../config.h"
-// required because lower/raise modifiers are redefined by colemak-dh
-#define PREVENT_STUCK_MODIFIERS
-
// tap dance key press termination interval
#define TAPPING_TERM 250
diff --git a/keyboards/planck/keymaps/am/config.h b/keyboards/planck/keymaps/am/config.h
index b2b87045b..1ae457e3b 100644
--- a/keyboards/planck/keymaps/am/config.h
+++ b/keyboards/planck/keymaps/am/config.h
@@ -1,8 +1,5 @@
#pragma once
-/* Prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef AUDIO_ENABLE
#define STARTUP_SONG SONG(PLANCK_SOUND)
diff --git a/keyboards/planck/keymaps/andylikescandy/config.h b/keyboards/planck/keymaps/andylikescandy/config.h
index 0de5f3db0..01169db2a 100644
--- a/keyboards/planck/keymaps/andylikescandy/config.h
+++ b/keyboards/planck/keymaps/andylikescandy/config.h
@@ -17,9 +17,6 @@
#define PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
-
-
/*
* MIDI options
*/
diff --git a/keyboards/planck/keymaps/bone2planck/config.h b/keyboards/planck/keymaps/bone2planck/config.h
deleted file mode 100644
index 3e9e692d3..000000000
--- a/keyboards/planck/keymaps/bone2planck/config.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
\ No newline at end of file
diff --git a/keyboards/planck/keymaps/davidrambo/config.h b/keyboards/planck/keymaps/davidrambo/config.h
index c3bebf579..2decb3dc8 100644
--- a/keyboards/planck/keymaps/davidrambo/config.h
+++ b/keyboards/planck/keymaps/davidrambo/config.h
@@ -3,7 +3,6 @@
#define CONFIG_USER_H
#define TAPPING_TERM 200
#include "../../config.h"
-#define PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
+#define PERMISSIVE_HOLD
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/planck/keymaps/dshields/config.h b/keyboards/planck/keymaps/dshields/config.h
index 480ba453a..9ba854ef0 100644
--- a/keyboards/planck/keymaps/dshields/config.h
+++ b/keyboards/planck/keymaps/dshields/config.h
@@ -10,7 +10,6 @@
#define _______ KC_TRNS
#define XXXXXXX KC_NO
-#define PREVENT_STUCK_MODIFIERS
#define USB_MAX_POWER_CONSUMPTION 100
#define ONESHOT_TAP_TOGGLE 2
diff --git a/keyboards/planck/keymaps/espynn/keymap.c b/keyboards/planck/keymaps/espynn/keymap.c
index 9cf508af6..5615a78bf 100644
--- a/keyboards/planck/keymaps/espynn/keymap.c
+++ b/keyboards/planck/keymaps/espynn/keymap.c
@@ -5,7 +5,6 @@
#ifdef BACKLIGHT_ENABLE
#include "backlight.h"
#endif
-#define PREVENT_STUCK_MODIFIERS
extern keymap_config_t keymap_config;
// Symbolic names for macro IDs.
diff --git a/keyboards/planck/keymaps/experimental/config.h b/keyboards/planck/keymaps/experimental/config.h
index 0864b5fbc..86cc4760b 100644
--- a/keyboards/planck/keymaps/experimental/config.h
+++ b/keyboards/planck/keymaps/experimental/config.h
@@ -5,8 +5,6 @@
#define LEADER_TIMEOUT 300
#define BACKLIGHT_BREATHING
-#define PREVENT_STUCK_MODIFIERS
-
/* ws2812 RGB LED */
#define RGB_DI_PIN B1
diff --git a/keyboards/planck/keymaps/experimental/rules.mk b/keyboards/planck/keymaps/experimental/rules.mk
index b135dfca0..168d3cb9f 100644
--- a/keyboards/planck/keymaps/experimental/rules.mk
+++ b/keyboards/planck/keymaps/experimental/rules.mk
@@ -18,10 +18,11 @@ BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SWAP_HANDS_ENABLE = yes # Enable one-hand typing
STENO_ENABLE = yes # Enable TX Bolt protocol for Stenography, requires VIRTSER and may not work with mouse keys
+LEADER_ENABLE = yes
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
ifndef QUANTUM_DIR
include ../../../../Makefile
-endif
\ No newline at end of file
+endif
diff --git a/keyboards/planck/keymaps/hiea/config.h b/keyboards/planck/keymaps/hiea/config.h
index 9bb5e0873..655cdf5db 100644
--- a/keyboards/planck/keymaps/hiea/config.h
+++ b/keyboards/planck/keymaps/hiea/config.h
@@ -3,9 +3,6 @@
#include "../../config.h"
-// required because lower/raise modifiers are redefined by colemak-dh
-#define PREVENT_STUCK_MODIFIERS
-
// tap dance key press termination interval
#define TAPPING_TERM 250
diff --git a/keyboards/planck/keymaps/hieax/config.h b/keyboards/planck/keymaps/hieax/config.h
index 9bb5e0873..655cdf5db 100644
--- a/keyboards/planck/keymaps/hieax/config.h
+++ b/keyboards/planck/keymaps/hieax/config.h
@@ -3,9 +3,6 @@
#include "../../config.h"
-// required because lower/raise modifiers are redefined by colemak-dh
-#define PREVENT_STUCK_MODIFIERS
-
// tap dance key press termination interval
#define TAPPING_TERM 250
diff --git a/keyboards/planck/keymaps/ishtob/config.h b/keyboards/planck/keymaps/ishtob/config.h
index e58ade0b0..688607634 100755
--- a/keyboards/planck/keymaps/ishtob/config.h
+++ b/keyboards/planck/keymaps/ishtob/config.h
@@ -2,7 +2,6 @@
#ifndef USERSPACE_CONFIG_H
#define USERSPACE_CONFIG_H
-
#ifdef AUDIO_ENABLE
// #define STARTUP_SONG SONG(E1M1_DOOM)
@@ -24,7 +23,6 @@
#define FORCE_NKRO
#define LEADER_TIMEOUT 300
-#define PREVENT_STUCK_MODIFIERS
#undef DEBOUNCE
#define DEBOUNCE 0
diff --git a/keyboards/planck/keymaps/jarred/config.h b/keyboards/planck/keymaps/jarred/config.h
index f98b8935e..9e8f404c1 100644
--- a/keyboards/planck/keymaps/jarred/config.h
+++ b/keyboards/planck/keymaps/jarred/config.h
@@ -19,8 +19,6 @@
#include "config_common.h"
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef AUDIO_ENABLE
#define STARTUP_SONG SONG(PLANCK_SOUND)
#endif
@@ -34,6 +32,6 @@
#define MOUSEKEY_WHEEL_DELAY 0
#define MOUSEKEY_WHEEL_MAX_SPEED 4
-#define MOUSEKEY_WHEEL_TIME_TO_MAX 255
+#define MOUSEKEY_WHEEL_TIME_TO_MAX 255
#endif
diff --git a/keyboards/planck/keymaps/jeremy-dev/keymap.c b/keyboards/planck/keymaps/jeremy-dev/keymap.c
index 5aea44329..89b7e6b84 100644
--- a/keyboards/planck/keymaps/jeremy-dev/keymap.c
+++ b/keyboards/planck/keymaps/jeremy-dev/keymap.c
@@ -1,7 +1,6 @@
// This is the personal keymap of Jeremy Cowgar (@jcowgar). It is written for the programmer.
// Configuration options
-#define PREVENT_STUCK_MODIFIERS
#pragma message "You may need to add LAYOUT_planck_grid to your keymap layers - see default for an example"
#include "planck.h"
diff --git a/keyboards/planck/keymaps/kmontag42/rules.mk b/keyboards/planck/keymaps/kmontag42/rules.mk
index b9f73934a..0c100076b 100644
--- a/keyboards/planck/keymaps/kmontag42/rules.mk
+++ b/keyboards/planck/keymaps/kmontag42/rules.mk
@@ -1,4 +1,5 @@
UNICODE_ENABLE = yes
+LEADER_ENABLE = yes
ifndef QUANTUM_DIR
include ../../../../Makefile
diff --git a/keyboards/planck/keymaps/lae3/config.h b/keyboards/planck/keymaps/lae3/config.h
deleted file mode 100644
index a28634e69..000000000
--- a/keyboards/planck/keymaps/lae3/config.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef LAE3_KEYMAP_H
-#define LAE3_KEYMAP_H
-
-#include "../../config.h"
-
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
diff --git a/keyboards/planck/keymaps/mitch/config.h b/keyboards/planck/keymaps/mitch/config.h
index 10591b3c8..bb7989d90 100644
--- a/keyboards/planck/keymaps/mitch/config.h
+++ b/keyboards/planck/keymaps/mitch/config.h
@@ -1,6 +1,5 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
// for the broken board
#undef MATRIX_COL_PINS
-#define MATRIX_COL_PINS { F1, F0, B0, B2, F4, F5, F6, F7, D4, D6, B4, D7 }
\ No newline at end of file
+#define MATRIX_COL_PINS { F1, F0, B0, B2, F4, F5, F6, F7, D4, D6, B4, D7 }
diff --git a/keyboards/planck/keymaps/mitch/readme.md b/keyboards/planck/keymaps/mitch/readme.md
index 3869304f4..9ed1133ef 100644
--- a/keyboards/planck/keymaps/mitch/readme.md
+++ b/keyboards/planck/keymaps/mitch/readme.md
@@ -20,7 +20,3 @@ rest of the symbols, mostly mapped with the ten key numbers.
The normal right shift key uses the `MT` macro to trigger Enter on tap and right
shift when held.
-
-This keymap sets the `PREVENT_STUCK_MODIFIERS` flag to avoid the occasional WTF
-moments when using a modifier keys and accidentally releasing them after moving
-to a new layer.
diff --git a/keyboards/planck/keymaps/narze/config.h b/keyboards/planck/keymaps/narze/config.h
index e081a93b5..19d784b2b 100644
--- a/keyboards/planck/keymaps/narze/config.h
+++ b/keyboards/planck/keymaps/narze/config.h
@@ -33,10 +33,9 @@
#define IGNORE_MOD_TAP_INTERRUPT
#define PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
#define SUPER_DUPER_SOUND S__NOTE(_B1)
#define MOUSEKEY_DELAY 100
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/planck/keymaps/neo2planck/config.h b/keyboards/planck/keymaps/neo2planck/config.h
deleted file mode 100644
index 3e9e692d3..000000000
--- a/keyboards/planck/keymaps/neo2planck/config.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
\ No newline at end of file
diff --git a/keyboards/planck/keymaps/priyadi/config.h b/keyboards/planck/keymaps/priyadi/config.h
index 448ae3b90..876d057bf 100644
--- a/keyboards/planck/keymaps/priyadi/config.h
+++ b/keyboards/planck/keymaps/priyadi/config.h
@@ -11,8 +11,6 @@
/* skip bootmagic and eeconfig */
#define BOOTMAGIC_KEY_SKIP KC_SPACE
-#define PREVENT_STUCK_MODIFIERS
-
#define UNICODE_TYPE_DELAY 0
#define LAYOUT_DVORAK
diff --git a/keyboards/planck/keymaps/sdothum/config.h b/keyboards/planck/keymaps/sdothum/config.h
index 4b2cdeece..8bed79e6f 100644
--- a/keyboards/planck/keymaps/sdothum/config.h
+++ b/keyboards/planck/keymaps/sdothum/config.h
@@ -3,9 +3,6 @@
#include "../../config.h"
-// required because lower/raise modifiers are redefined by colemak-dh
-#define PREVENT_STUCK_MODIFIERS
-
// tap dance key press termination interval
#define TAPPING_TERM 250
diff --git a/keyboards/planck/keymaps/steno/config.h b/keyboards/planck/keymaps/steno/config.h
index 1879ab007..4f99c7eb8 100644
--- a/keyboards/planck/keymaps/steno/config.h
+++ b/keyboards/planck/keymaps/steno/config.h
@@ -15,8 +15,6 @@
#define MUSIC_MASK (keycode != KC_NO)
-#define PREVENT_STUCK_MODIFIERS
-
/*
* MIDI options
*/
@@ -41,4 +39,4 @@
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/planck/keymaps/tehwalris/config.h b/keyboards/planck/keymaps/tehwalris/config.h
index 4725e1426..c5d55b969 100644
--- a/keyboards/planck/keymaps/tehwalris/config.h
+++ b/keyboards/planck/keymaps/tehwalris/config.h
@@ -3,8 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
-
#ifdef AUDIO_ENABLE
// #define STARTUP_SONG SONG(PLANCK_SOUND)
#define STARTUP_SONG SONG(NO_SOUND)
@@ -27,7 +25,7 @@
/* enable basic MIDI features:
- MIDI notes can be sent when in Music mode is on
*/
-
+
#define MIDI_BASIC
/* enable advanced MIDI features:
diff --git a/keyboards/planck/keymaps/vifon/config.h b/keyboards/planck/keymaps/vifon/config.h
index 4cb4a1235..be395faad 100644
--- a/keyboards/planck/keymaps/vifon/config.h
+++ b/keyboards/planck/keymaps/vifon/config.h
@@ -26,9 +26,6 @@
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 2
-/* prevent the modifiers from being stuck, sacrificing some memory */
-#define PREVENT_STUCK_MODIFIERS
-
/* A larger buffer for the dynamic macros as this keymap is not taking
* up that much memory.
*/
diff --git a/keyboards/planck/keymaps/yale/config.h b/keyboards/planck/keymaps/yale/config.h
deleted file mode 100644
index 8a916bbd0..000000000
--- a/keyboards/planck/keymaps/yale/config.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
-
-
-
diff --git a/keyboards/planck/keymaps/zach/config.h b/keyboards/planck/keymaps/zach/config.h
index 19a3856a3..dc79bad06 100644
--- a/keyboards/planck/keymaps/zach/config.h
+++ b/keyboards/planck/keymaps/zach/config.h
@@ -55,7 +55,6 @@
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
-#define PREVENT_STUCK_MODIFIERS
//#define DYNAMIC_MACRO_ENABLE // Enable if you need to use the macro functionality
//#define SPACE_CADET // Parenthesis on L/R shift
diff --git a/keyboards/planck/rev6/config.h b/keyboards/planck/rev6/config.h
index 0e462180b..afd69f7d8 100644
--- a/keyboards/planck/rev6/config.h
+++ b/keyboards/planck/rev6/config.h
@@ -50,9 +50,6 @@
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCE 6
-/* Prevent modifiers from being stuck on after layer changes. */
-#define PREVENT_STUCK_MODIFIERS
-
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
//#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
diff --git a/keyboards/playkbtw/ca66/config.h b/keyboards/playkbtw/ca66/config.h
index c35718042..53bbe95e3 100644
--- a/keyboards/playkbtw/ca66/config.h
+++ b/keyboards/playkbtw/ca66/config.h
@@ -42,8 +42,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
#define RGB_DI_PIN B1
#ifdef RGB_DI_PIN
diff --git a/keyboards/playkbtw/pk60/config.h b/keyboards/playkbtw/pk60/config.h
index 06101349c..601e3c8a5 100644
--- a/keyboards/playkbtw/pk60/config.h
+++ b/keyboards/playkbtw/pk60/config.h
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN E2
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
@@ -55,4 +52,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/preonic/keymaps/bucktooth/config.h b/keyboards/preonic/keymaps/bucktooth/config.h
index b98883120..23e9e0ed2 100644
--- a/keyboards/preonic/keymaps/bucktooth/config.h
+++ b/keyboards/preonic/keymaps/bucktooth/config.h
@@ -4,6 +4,5 @@
#include "../../config.h"
#define FORCE_NKRO 1
-#define PREVENT_STUCK_MODIFIERS
#endif
diff --git a/keyboards/preonic/keymaps/jacwib/config.h b/keyboards/preonic/keymaps/jacwib/config.h
index b98883120..23e9e0ed2 100644
--- a/keyboards/preonic/keymaps/jacwib/config.h
+++ b/keyboards/preonic/keymaps/jacwib/config.h
@@ -4,6 +4,5 @@
#include "../../config.h"
#define FORCE_NKRO 1
-#define PREVENT_STUCK_MODIFIERS
#endif
diff --git a/keyboards/preonic/keymaps/kuatsure/rules.mk b/keyboards/preonic/keymaps/kuatsure/rules.mk
index 76d73acef..9369f99a9 100644
--- a/keyboards/preonic/keymaps/kuatsure/rules.mk
+++ b/keyboards/preonic/keymaps/kuatsure/rules.mk
@@ -1 +1,2 @@
BACKLIGHT_ENABLE = no
+LEADER_ENABLE = yes
diff --git a/keyboards/preonic/keymaps/that_canadian/config.h b/keyboards/preonic/keymaps/that_canadian/config.h
deleted file mode 100644
index 11cafbefc..000000000
--- a/keyboards/preonic/keymaps/that_canadian/config.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define PREVENT_STUCK_MODIFIERS
-
-#endif
diff --git a/keyboards/preonic/keymaps/zach/config.h b/keyboards/preonic/keymaps/zach/config.h
index bb8913c7a..40a083da3 100644
--- a/keyboards/preonic/keymaps/zach/config.h
+++ b/keyboards/preonic/keymaps/zach/config.h
@@ -87,7 +87,6 @@ along with this program. If not, see .
//#define NO_ACTION_ONESHOT
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
-#define PREVENT_STUCK_MODIFIERS
//#define DYNAMIC_MACRO_ENABLE // Enable if you need to use the macro functionality
//#define SPACE_CADET // Parenthesis on L/R shift
diff --git a/keyboards/preonic/rev3/config.h b/keyboards/preonic/rev3/config.h
index 3f57c591a..98899dc6a 100644
--- a/keyboards/preonic/rev3/config.h
+++ b/keyboards/preonic/rev3/config.h
@@ -50,9 +50,6 @@
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCE 6
-/* Prevent modifiers from being stuck on after layer changes. */
-#define PREVENT_STUCK_MODIFIERS
-
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
//#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
diff --git a/keyboards/prime_r/config.h b/keyboards/prime_r/config.h
index b53f14905..ad92199a2 100644
--- a/keyboards/prime_r/config.h
+++ b/keyboards/prime_r/config.h
@@ -60,10 +60,6 @@ along with this program. If not, see .
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
diff --git a/keyboards/rorschach/keymaps/insertsnideremarks/config.h b/keyboards/rorschach/keymaps/insertsnideremarks/config.h
index 90fb5120d..2048232c9 100644
--- a/keyboards/rorschach/keymaps/insertsnideremarks/config.h
+++ b/keyboards/rorschach/keymaps/insertsnideremarks/config.h
@@ -11,7 +11,6 @@
// #define MASTER_RIGHT
#define EE_HANDS
-#define PREVENT_STUCK_MODIFIERS
#define IGNORE_MOD_TAP_INTERRUPT
#define TAPPING_TERM 175
#define TAPPING_TOGGLE 2
diff --git a/keyboards/s60_x/keymaps/bluebear/config.h b/keyboards/s60_x/keymaps/bluebear/config.h
index 35754b523..10bddf0d3 100644
--- a/keyboards/s60_x/keymaps/bluebear/config.h
+++ b/keyboards/s60_x/keymaps/bluebear/config.h
@@ -105,7 +105,4 @@ along with this program. If not, see .
// Space Cadet Rollover - if set, allows to tap opposite shift key to cancel erroneous press
#define DISABLE_SPACE_CADET_ROLLOVER
-// Prevent stuck modifiers
-#define PREVENT_STUCK_MODIFIERS
-
#endif
diff --git a/keyboards/s60_x/rgb/config.h b/keyboards/s60_x/rgb/config.h
index ec8b0f49e..d9c26658d 100644
--- a/keyboards/s60_x/rgb/config.h
+++ b/keyboards/s60_x/rgb/config.h
@@ -17,9 +17,6 @@
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN F6
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
@@ -29,4 +26,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/s65_plus/config.h b/keyboards/s65_plus/config.h
index df60e60a8..60512db46 100644
--- a/keyboards/s65_plus/config.h
+++ b/keyboards/s65_plus/config.h
@@ -49,7 +49,4 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#endif
diff --git a/keyboards/s65_x/config.h b/keyboards/s65_x/config.h
index 8288ef783..367efc526 100644
--- a/keyboards/s65_x/config.h
+++ b/keyboards/s65_x/config.h
@@ -49,8 +49,4 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#endif
diff --git a/keyboards/sx60/config.h b/keyboards/sx60/config.h
index f22fbe8be..52a1cc7a1 100755
--- a/keyboards/sx60/config.h
+++ b/keyboards/sx60/config.h
@@ -46,10 +46,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
diff --git a/keyboards/telophase/config.h b/keyboards/telophase/config.h
index 09655c025..be0a36977 100644
--- a/keyboards/telophase/config.h
+++ b/keyboards/telophase/config.h
@@ -52,8 +52,6 @@ along with this program. If not, see .
* These options are also useful to firmware size reduction.
*/
-#define PREVENT_STUCK_MODIFIERS
-
/* disable debug print */
//#define NO_DEBUG
diff --git a/keyboards/tetris/config.h b/keyboards/tetris/config.h
index 9c7f525a7..7e7dac7cf 100644
--- a/keyboards/tetris/config.h
+++ b/keyboards/tetris/config.h
@@ -41,9 +41,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define TAPPING_TERM 200
#define PERMISSIVE_HOLD
@@ -62,4 +59,4 @@
//#define RGBLIGHT_LIMIT_VAL 128
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/thevankeyboards/bananasplit/keymaps/talljoe/config.h b/keyboards/thevankeyboards/bananasplit/keymaps/talljoe/config.h
index bb2aadfa6..fc9bd3d61 100644
--- a/keyboards/thevankeyboards/bananasplit/keymaps/talljoe/config.h
+++ b/keyboards/thevankeyboards/bananasplit/keymaps/talljoe/config.h
@@ -3,7 +3,6 @@
#include QMK_KEYBOARD_CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
#define SPACE_COUNT 3
#define TEMPLATE( \
diff --git a/keyboards/tokyo60/config.h b/keyboards/tokyo60/config.h
index 6e6ab2215..16927be17 100644
--- a/keyboards/tokyo60/config.h
+++ b/keyboards/tokyo60/config.h
@@ -47,9 +47,6 @@
/* Locking resynchronize hack */
#define LOCKING_RESYNC_ENABLE
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN F7
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/keyboards/tomato/config.h b/keyboards/tomato/config.h
index f33c13108..185cb326c 100644
--- a/keyboards/tomato/config.h
+++ b/keyboards/tomato/config.h
@@ -34,9 +34,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
/* eliminate lag on space cadet mods */
#define PERMISSIVE_HOLD
diff --git a/keyboards/uk78/config.h b/keyboards/uk78/config.h
index 35f5bf70b..34d672079 100644
--- a/keyboards/uk78/config.h
+++ b/keyboards/uk78/config.h
@@ -60,9 +60,6 @@ along with this program. If not, see .
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
/* ws2812b options */
#define RGB_DI_PIN F6
#ifdef RGB_DI_PIN
diff --git a/keyboards/viterbi/keymaps/drashna/config.h b/keyboards/viterbi/keymaps/drashna/config.h
index 687f80441..a1e361e34 100644
--- a/keyboards/viterbi/keymaps/drashna/config.h
+++ b/keyboards/viterbi/keymaps/drashna/config.h
@@ -53,7 +53,7 @@ along with this program. If not, see .
#define NO_MUSIC_MODE
#endif
-#undef PREVENT_STUCK_MODIFIERS
+#define STRICT_LAYER_RELEASE
#define LAYOUT_ortho_5x7( \
L00, L01, L02, L03, L04, L05, L06, \
diff --git a/keyboards/whitefox/config.h b/keyboards/whitefox/config.h
index 9f021fb51..a8047cf54 100644
--- a/keyboards/whitefox/config.h
+++ b/keyboards/whitefox/config.h
@@ -18,8 +18,6 @@ along with this program. If not, see .
#ifndef CONFIG_H
#define CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
-
/* USB Device descriptor parameter */
#define VENDOR_ID 0x1c11
#define PRODUCT_ID 0xb04d
diff --git a/keyboards/xd60/keymaps/kmontag42/rules.mk b/keyboards/xd60/keymaps/kmontag42/rules.mk
new file mode 100644
index 000000000..d0d2ef6d5
--- /dev/null
+++ b/keyboards/xd60/keymaps/kmontag42/rules.mk
@@ -0,0 +1 @@
+LEADER_ENABLE = yes
diff --git a/keyboards/xd75/keymaps/davidrambo/config.h b/keyboards/xd75/keymaps/davidrambo/config.h
index e87ccde79..f21914703 100644
--- a/keyboards/xd75/keymaps/davidrambo/config.h
+++ b/keyboards/xd75/keymaps/davidrambo/config.h
@@ -20,7 +20,6 @@
#include "../../config.h"
#define TAPPING_TERM 200
-#define PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
+#define PERMISSIVE_HOLD
#endif
diff --git a/keyboards/xd75/keymaps/tdl-jturner/config.h b/keyboards/xd75/keymaps/tdl-jturner/config.h
index 561a48d7e..985247bb2 100644
--- a/keyboards/xd75/keymaps/tdl-jturner/config.h
+++ b/keyboards/xd75/keymaps/tdl-jturner/config.h
@@ -26,7 +26,6 @@
#define TAPPING_TOGGLE 2
//#define PERMISSIVE_HOLD
//#define QMK_KEYS_PER_SCAN 4
-#define PREVENT_STUCK_MODIFIERS
#define FORCE_NKRO
#define MOUSEKEY_INTERVAL 16
diff --git a/keyboards/xmmx/config.h b/keyboards/xmmx/config.h
index f3f893e28..8cb2cf82d 100644
--- a/keyboards/xmmx/config.h
+++ b/keyboards/xmmx/config.h
@@ -43,10 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
@@ -55,4 +51,4 @@
#define RGBLIGHT_VAL_STEP 8
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/ymd96/keymaps/hgoel89/config.h b/keyboards/ymd96/keymaps/hgoel89/config.h
index 52aaa8f24..b1d74e1e6 100644
--- a/keyboards/ymd96/keymaps/hgoel89/config.h
+++ b/keyboards/ymd96/keymaps/hgoel89/config.h
@@ -3,7 +3,6 @@
#include "../../config.h"
-#define PREVENT_STUCK_MODIFIERS
#define TAPPING_TERM 300
#endif
diff --git a/keyboards/z150_blackheart/config.h b/keyboards/z150_blackheart/config.h
index d2fce9aee..362153652 100644
--- a/keyboards/z150_blackheart/config.h
+++ b/keyboards/z150_blackheart/config.h
@@ -39,14 +39,10 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
-
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 0
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8
#define RGBLIGHT_VAL_STEP 8
-#endif
\ No newline at end of file
+#endif
diff --git a/keyboards/zeal60/keymaps/tusing/config.h b/keyboards/zeal60/keymaps/tusing/config.h
index 93f260946..64aaece50 100644
--- a/keyboards/zeal60/keymaps/tusing/config.h
+++ b/keyboards/zeal60/keymaps/tusing/config.h
@@ -34,7 +34,3 @@
// Scale brightnes according to BRIGHTNESS_CORRECTION_TABLE in quantum/rgblight.c.
// This allows to mitigate uneven brightness from LED underglow strips.
// #define LED_BRIGHTNESS_CORRECTION
-
-// Prevent modifiers on layer 1 from persisting after we let go
-#define PREVENT_STUCK_MODIFIERS
-
diff --git a/keyboards/zlant/config.h b/keyboards/zlant/config.h
index 456d225aa..ae9dcfef6 100755
--- a/keyboards/zlant/config.h
+++ b/keyboards/zlant/config.h
@@ -43,9 +43,6 @@
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
)
-/* prevent stuck modifiers */
-#define PREVENT_STUCK_MODIFIERS
-
#define RGB_DI_PIN D6
#ifdef RGB_DI_PIN
#define RGBLIGHT_ANIMATIONS
diff --git a/layouts/community/60_ansi/talljoe-ansi/config.h b/layouts/community/60_ansi/talljoe-ansi/config.h
index 1990b0ee3..4326a2fd1 100644
--- a/layouts/community/60_ansi/talljoe-ansi/config.h
+++ b/layouts/community/60_ansi/talljoe-ansi/config.h
@@ -3,7 +3,6 @@
#include QMK_KEYBOARD_CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
#define ENABLE_GAME_LAYER
#define TEMPLATE( \
diff --git a/layouts/community/60_ansi_split_bs_rshift/talljoe/config.h b/layouts/community/60_ansi_split_bs_rshift/talljoe/config.h
index 81ab5cf89..bf18fd9f7 100644
--- a/layouts/community/60_ansi_split_bs_rshift/talljoe/config.h
+++ b/layouts/community/60_ansi_split_bs_rshift/talljoe/config.h
@@ -3,7 +3,6 @@
#include QMK_KEYBOARD_CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
#define ENABLE_GAME_LAYER
#define TEMPLATE( \
diff --git a/layouts/community/60_hhkb/talljoe-hhkb/config.h b/layouts/community/60_hhkb/talljoe-hhkb/config.h
index 938ea6cd6..9e907feeb 100644
--- a/layouts/community/60_hhkb/talljoe-hhkb/config.h
+++ b/layouts/community/60_hhkb/talljoe-hhkb/config.h
@@ -3,7 +3,6 @@
#include QMK_KEYBOARD_CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
#define ENABLE_GAME_LAYER
#define TEMPLATE( \
diff --git a/layouts/community/ergodox/adam/config.h b/layouts/community/ergodox/adam/config.h
index 21af8c6b8..1a8fddb50 100644
--- a/layouts/community/ergodox/adam/config.h
+++ b/layouts/community/ergodox/adam/config.h
@@ -2,5 +2,4 @@
#undef TAPPING_TERM
#define TAPPING_TERM 300 //At 500 some bad logic takes hold
-#define PREVENT_STUCK_MODIFIERS
#define IGNORE_MOD_TAP_INTERRUPT
diff --git a/layouts/community/ergodox/albert/rules.mk b/layouts/community/ergodox/albert/rules.mk
index fcd019e83..47549b50f 100644
--- a/layouts/community/ergodox/albert/rules.mk
+++ b/layouts/community/ergodox/albert/rules.mk
@@ -1,3 +1,2 @@
COMMAND_ENABLE = no # Commands for debug and configuration
-
-
+LEADER_ENABLE = yes
diff --git a/layouts/community/ergodox/algernon/rules.mk b/layouts/community/ergodox/algernon/rules.mk
index f795a8676..53dec5153 100644
--- a/layouts/community/ergodox/algernon/rules.mk
+++ b/layouts/community/ergodox/algernon/rules.mk
@@ -8,6 +8,7 @@ TAP_DANCE_ENABLE = yes
KEYLOGGER_ENABLE ?= yes
UCIS_ENABLE = yes
MOUSEKEY_ENABLE = no
+LEADER_ENABLE = yes
AUTOLOG_ENABLE ?= no
diff --git a/layouts/community/ergodox/alphadox/config.h b/layouts/community/ergodox/alphadox/config.h
index 6fc64f508..9e076dead 100644
--- a/layouts/community/ergodox/alphadox/config.h
+++ b/layouts/community/ergodox/alphadox/config.h
@@ -4,7 +4,6 @@
#include QMK_KEYBOARD_CONFIG_H
#define FORCE_NKRO
-#define PREVENT_STUCK_MODIFIERS
#undef TAPPING_TERM
#undef IGNORE_MOD_TAP_INTERRUPT
diff --git a/layouts/community/ergodox/deadcyclo/rules.mk b/layouts/community/ergodox/deadcyclo/rules.mk
index 039f07c8e..f5093529b 100644
--- a/layouts/community/ergodox/deadcyclo/rules.mk
+++ b/layouts/community/ergodox/deadcyclo/rules.mk
@@ -1 +1,2 @@
UNICODE_ENABLE = yes
+LEADER_ENABLE = yes
diff --git a/layouts/community/ergodox/erez_experimental/rules.mk b/layouts/community/ergodox/erez_experimental/rules.mk
index 839dd82e1..f68b56f87 100644
--- a/layouts/community/ergodox/erez_experimental/rules.mk
+++ b/layouts/community/ergodox/erez_experimental/rules.mk
@@ -3,5 +3,4 @@
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
COMMAND_ENABLE = no # Commands for debug and configuration
-
-
+LEADER_ENABLE = yes
diff --git a/layouts/community/ergodox/familiar/rules.mk b/layouts/community/ergodox/familiar/rules.mk
index 31e0fcf29..4a3c58621 100644
--- a/layouts/community/ergodox/familiar/rules.mk
+++ b/layouts/community/ergodox/familiar/rules.mk
@@ -1 +1,2 @@
TAP_DANCE_ENABLE=yes
+LEADER_ENABLE = yes
diff --git a/layouts/community/ergodox/mclennon_osx/README.md b/layouts/community/ergodox/mclennon_osx/README.md
index 28cdb7c10..53b3d4841 100644
--- a/layouts/community/ergodox/mclennon_osx/README.md
+++ b/layouts/community/ergodox/mclennon_osx/README.md
@@ -1,5 +1,5 @@
# Ergodox EZ for OS X
-This keymapping is designed to be reasonably familiar to an ordinary Mac keyboard while taking advantage of the Ergodox EZ's features. Caps lock instead enables a layer which allows a user to use HJKL as arrow keys and to control media. Shift and control have additional mappings on S and D to provide easier access while holding down caps lock.
+This keymapping is designed to be reasonably familiar to an ordinary Mac keyboard while taking advantage of the Ergodox EZ's features. Caps lock instead enables a layer which allows a user to use HJKL as arrow keys and to control media. Shift and control have additional mappings on S and D to provide easier access while holding down caps lock.
-If you choose to compile this yourself, be sure to compile with `#define PREVENT_STUCK_MODIFIERS` in your `config.h`. Firmware built using [qmk_firmware](https://github.com/qmk/qmk_firmware/).
+Firmware built using [qmk_firmware](https://github.com/qmk/qmk_firmware/).
diff --git a/layouts/community/ergodox/techtomas/readme.md b/layouts/community/ergodox/techtomas/readme.md
index 36e0591a8..3d1bcb9e1 100644
--- a/layouts/community/ergodox/techtomas/readme.md
+++ b/layouts/community/ergodox/techtomas/readme.md
@@ -39,7 +39,7 @@ The right arrow key and End key toggle the control layer on the left board. Ther
On the left board you have mouse control with left & right click in the location of the G and B keys.
On the right board you have vim-style arrow keys using hjkl
-The left thumb cluster moves shift and alt within easy reach while holding the toggle (end). So far I've found this convient to navigate and skip around text when using the hjkl arrow keys. I found that it was easy to get the alt key stuck on depending on what key you released first so I added the PREVENT_STUCK_MODIFIERS to the config.h to help with that.
+The left thumb cluster moves shift and alt within easy reach while holding the toggle (end). So far I've found this convient to navigate and skip around text when using the hjkl arrow keys.
## Changelog
diff --git a/layouts/community/ortho_4x12/symbolic/config.h b/layouts/community/ortho_4x12/symbolic/config.h
index 702c9226c..c29b07706 100644
--- a/layouts/community/ortho_4x12/symbolic/config.h
+++ b/layouts/community/ortho_4x12/symbolic/config.h
@@ -20,10 +20,6 @@ along with this program. If not, see .
#pragma once
-// prevent stuck modifiers
-#define PREVENT_STUCK_MODIFIERS
-
-
// hold & tapping delay setting
#define TAPPING_TERM 100
diff --git a/layouts/community/tkl_ansi/talljoe-tkl/config.h b/layouts/community/tkl_ansi/talljoe-tkl/config.h
index 8b27d4136..02f8a94e3 100644
--- a/layouts/community/tkl_ansi/talljoe-tkl/config.h
+++ b/layouts/community/tkl_ansi/talljoe-tkl/config.h
@@ -3,7 +3,6 @@
#include QMK_KEYBOARD_CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
#define ENABLE_GAME_LAYER
#define TEMPLATE_TKL(\
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c
deleted file mode 100644
index 6c6ebe300..000000000
--- a/quantum/process_keycode/process_chording.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright 2016 Jack Humbert
- *
- * 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 .
- */
-
-#include "process_chording.h"
-
-bool keys_chord(uint8_t keys[]) {
- uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
- bool pass = true;
- uint8_t in = 0;
- for (uint8_t i = 0; i < chord_key_count; i++) {
- bool found = false;
- for (uint8_t j = 0; j < keys_size; j++) {
- if (chord_keys[i] == (keys[j] & 0xFF)) {
- in++; // detects key in chord
- found = true;
- break;
- }
- }
- if (found)
- continue;
- if (chord_keys[i] != 0) {
- pass = false; // makes sure rest are blank
- }
- }
- return (pass && (in == keys_size));
-}
-
-bool process_chording(uint16_t keycode, keyrecord_t *record) {
- if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) {
- if (record->event.pressed) {
- if (!chording) {
- chording = true;
- for (uint8_t i = 0; i < CHORDING_MAX; i++)
- chord_keys[i] = 0;
- chord_key_count = 0;
- chord_key_down = 0;
- }
- chord_keys[chord_key_count] = (keycode & 0xFF);
- chord_key_count++;
- chord_key_down++;
- return false;
- } else {
- if (chording) {
- chord_key_down--;
- if (chord_key_down == 0) {
- chording = false;
- // Chord Dictionary
- if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
- register_code(KC_A);
- unregister_code(KC_A);
- return false;
- }
- for (uint8_t i = 0; i < chord_key_count; i++) {
- register_code(chord_keys[i]);
- unregister_code(chord_keys[i]);
- return false;
- }
- }
- }
- }
- }
- return true;
-}
diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h
deleted file mode 100644
index 8c0f4862a..000000000
--- a/quantum/process_keycode/process_chording.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright 2016 Jack Humbert
- *
- * 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 .
- */
-
-#ifndef PROCESS_CHORDING_H
-#define PROCESS_CHORDING_H
-
-#include "quantum.h"
-
-// Chording stuff
-#define CHORDING_MAX 4
-bool chording = false;
-
-uint8_t chord_keys[CHORDING_MAX] = {0};
-uint8_t chord_key_count = 0;
-uint8_t chord_key_down = 0;
-
-bool process_chording(uint16_t keycode, keyrecord_t *record);
-
-#endif
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c
index c87ef115a..eddbf71f7 100644
--- a/quantum/process_keycode/process_leader.c
+++ b/quantum/process_keycode/process_leader.c
@@ -14,7 +14,7 @@
* along with this program. If not, see .
*/
-#ifndef DISABLE_LEADER
+#ifdef LEADER_ENABLE
#include "process_leader.h"
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 9d352a94c..9bf91eb86 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -196,7 +196,7 @@ bool process_record_quantum(keyrecord_t *record) {
keypos_t key = record->event.key;
uint16_t keycode;
- #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+ #if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
/* TODO: Use store_or_get_action() or a similar function. */
if (!disable_action_cache) {
uint8_t layer;
@@ -251,12 +251,9 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef TAP_DANCE_ENABLE
process_tap_dance(keycode, record) &&
#endif
- #ifndef DISABLE_LEADER
+ #ifdef LEADER_ENABLE
process_leader(keycode, record) &&
#endif
- #ifndef DISABLE_CHORDING
- process_chording(keycode, record) &&
- #endif
#ifdef COMBO_ENABLE
process_combo(keycode, record) &&
#endif
diff --git a/quantum/quantum.h b/quantum/quantum.h
index d1f761f17..7cf16d81e 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -89,15 +89,10 @@ extern uint32_t default_layer_state;
#include "process_music.h"
#endif
-#ifndef DISABLE_LEADER
+#ifdef LEADER_ENABLE
#include "process_leader.h"
#endif
-#define DISABLE_CHORDING
-#ifndef DISABLE_CHORDING
- #include "process_chording.h"
-#endif
-
#ifdef UNICODE_ENABLE
#include "process_unicode.h"
#endif
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 0ecc293a8..3b8795496 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -63,10 +63,6 @@ enum quantum_keycodes {
QK_ONE_SHOT_LAYER_MAX = 0x54FF,
QK_ONE_SHOT_MOD = 0x5500,
QK_ONE_SHOT_MOD_MAX = 0x55FF,
-#ifndef DISABLE_CHORDING
- QK_CHORDING = 0x5600,
- QK_CHORDING_MAX = 0x56FF,
-#endif
QK_TAP_DANCE = 0x5700,
QK_TAP_DANCE_MAX = 0x57FF,
QK_LAYER_TAP_TOGGLE = 0x5800,
@@ -123,7 +119,7 @@ enum quantum_keycodes {
GRAVE_ESC,
// Leader key
-#ifndef DISABLE_LEADER
+#ifdef LEADER_ENABLE
KC_LEAD,
#endif
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index ae0864749..76d02bc9d 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -120,7 +120,7 @@ void process_hand_swap(keyevent_t *event) {
}
#endif
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
bool disable_action_cache = false;
void process_record_nocache(keyrecord_t *record)
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index acc55c7d3..0322c73ed 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -62,7 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
bool process_record_quantum(keyrecord_t *record);
/* Utilities for actions. */
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
extern bool disable_action_cache;
#endif
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index f3cd381ab..62375dfbf 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -219,7 +219,7 @@ void layer_debug(void)
}
#endif
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
void update_source_layers_cache(keypos_t key, uint8_t layer)
@@ -263,7 +263,7 @@ uint8_t read_source_layers_cache(keypos_t key)
*/
action_t store_or_get_action(bool pressed, keypos_t key)
{
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
if (disable_action_cache) {
return layer_switch_get_action(key);
}
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 72a6bd8f6..7bf116be2 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -88,7 +88,7 @@ uint32_t layer_state_set_kb(uint32_t state);
#endif
/* pressed actions cache */
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
/* The number of bits needed to represent the layer number: log2(32). */
#define MAX_LAYER_BITS 5
void update_source_layers_cache(keypos_t key, uint8_t layer);
diff --git a/users/333fred/333fred_config.h b/users/333fred/333fred_config.h
index 7c637d8d3..b158e2d5a 100644
--- a/users/333fred/333fred_config.h
+++ b/users/333fred/333fred_config.h
@@ -1,4 +1,3 @@
#pragma once
-#define PREVENT_STUCK_MODIFIERS
#define PERMISSIVE_HOLD
diff --git a/users/bocaj/config.h b/users/bocaj/config.h
index ce5ec65d6..0e726598c 100644
--- a/users/bocaj/config.h
+++ b/users/bocaj/config.h
@@ -10,7 +10,6 @@
// actually sends Ctrl-x. That's bad.)
#define IGNORE_MOD_TAP_INTERRUPT
#undef PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
#ifdef TAPPING_TERM
#undef TAPPING_TERM
diff --git a/users/drashna/config.h b/users/drashna/config.h
index dd6875ceb..92efcc5c7 100644
--- a/users/drashna/config.h
+++ b/users/drashna/config.h
@@ -43,7 +43,6 @@
// actually sends Ctrl-x. That's bad.)
#define IGNORE_MOD_TAP_INTERRUPT
#undef PERMISSIVE_HOLD
-#define PREVENT_STUCK_MODIFIERS
// #define TAPPING_FORCE_HOLD
//#define RETRO_TAPPING
@@ -64,8 +63,4 @@
#define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION
-#define DISABLE_LEADER
-
#define MACRO_TIMER 5
-
-
diff --git a/users/ishtob/config.h b/users/ishtob/config.h
index 9c4a7ed8d..1f567f4a5 100755
--- a/users/ishtob/config.h
+++ b/users/ishtob/config.h
@@ -15,7 +15,6 @@
//#define LEADER_TIMEOUT 300
//#define BACKLIGHT_BREATHING
-#define PREVENT_STUCK_MODIFIERS
//#define PERMISSIVE_HOLD
// #define QMK_KEYS_PER_SCAN 4
@@ -72,5 +71,5 @@
// Most tactile encoders have detents every 4 stages
#define ENCODER_RESOLUTION 4
-
+
#endif
diff --git a/users/replicaJunction/config.h b/users/replicaJunction/config.h
index f3556c87e..4b58b579f 100644
--- a/users/replicaJunction/config.h
+++ b/users/replicaJunction/config.h
@@ -6,12 +6,6 @@
// https://docs.qmk.fm/reference/config-options#features-that-can-be-enabled
////////////////////////////////////////////////////////////////////////////////
-// Prevent modifiers from sticking when switching layers
-// Uses 5 bytes of memory per 8 keys, but makes sure modifiers don't get "stuck" switching layers
-#define PREVENT_STUCK_MODIFIERS
-
-
-
////////////////////////////////////////////////////////////////////////////////
// Behaviors That Can Be Configured
// https://docs.qmk.fm/reference/config-options#behaviors-that-can-be-configured
diff --git a/users/talljoe/config.h b/users/talljoe/config.h
index 15bbde6bc..1cdbb5a41 100644
--- a/users/talljoe/config.h
+++ b/users/talljoe/config.h
@@ -1,7 +1,6 @@
#ifndef USERSPACE_CONFIG_H
#define USERSPACE_CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
#define IGNORE_MOD_TAP_INTERRUPT
#define RESET_LAYER 15
diff --git a/users/wanleg/config.h b/users/wanleg/config.h
index 22073449b..28e7690e6 100644
--- a/users/wanleg/config.h
+++ b/users/wanleg/config.h
@@ -1,8 +1,6 @@
#ifndef USERSPACE_CONFIG_H
#define USERSPACE_CONFIG_H
-#define PREVENT_STUCK_MODIFIERS
-
//TAPPING_TERM
#ifdef TAP_DANCE_ENABLE
#define TAPPING_TERM 200
diff --git a/users/zer09/config.h b/users/zer09/config.h
index 766806462..4cb65c258 100644
--- a/users/zer09/config.h
+++ b/users/zer09/config.h
@@ -11,7 +11,7 @@
// actually sends Ctrl-x. That's bad.)
#define IGNORE_MOD_TAP_INTERRUPT
#undef PERMISSIVE_HOLD
-#undef PREVENT_STUCK_MODIFIERS
+#define STRICT_LAYER_RELEASE
#define FORCE_NKRO
--
cgit v1.2.3-70-g09d2
From 239f02408e219567be060be7e65e92e888304ed0 Mon Sep 17 00:00:00 2001
From: patrickmt <40182064+patrickmt@users.noreply.github.com>
Date: Fri, 28 Sep 2018 21:32:15 -0400
Subject: Massdrop keyboard updates for SEND_STRING, syscalls, stdio, debug
prints, Auto Shift (#3973)
* Update for SEND_STRING usage
Update for SEND_STRING usage.
Sending keyboard reports (kbd, nkro) now obey the minimum polling time.
While attempting to send a keyboard report and waiting for a USB poll, other functions of the keyboard, including LED effects and power management, will continue to operate at their intended intervals.
* Updates for send string, syscalls, stdio, debug prints, auto shift
Now properly waiting for previous keys sent over USB to complete before sending new.
Added heap to linker and now compiling with syscalls support.
Removed custom string functions and now using stdio.
dprintf now works as intended through virtser device.
* CTRL and ALT keymap updates
CTRL mac keymap updated
ALT default and mac keymap updated
ALT rules.mk added Auto Shift with default no
* Code cleanup as per discussion with vomindoraan
Code cleanup as per discussion with vomindoraan
---
keyboards/massdrop/alt/alt.h | 10 +
keyboards/massdrop/alt/keymaps/default/keymap.c | 35 +--
keyboards/massdrop/alt/keymaps/mac/keymap.c | 33 +--
keyboards/massdrop/alt/rules.mk | 1 +
keyboards/massdrop/ctrl/ctrl.h | 10 +
keyboards/massdrop/ctrl/keymaps/default/keymap.c | 39 +--
keyboards/massdrop/ctrl/keymaps/mac/keymap.c | 41 +---
keyboards/massdrop/ctrl/rules.mk | 1 +
.../SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld | 16 +-
tmk_core/arm_atsam.mk | 2 +-
tmk_core/common/arm_atsam/printf.h | 2 +-
tmk_core/common/print.h | 2 +-
tmk_core/protocol/arm_atsam.mk | 1 -
tmk_core/protocol/arm_atsam/arm_atsam_protocol.h | 1 -
tmk_core/protocol/arm_atsam/d51_util.h | 10 +
tmk_core/protocol/arm_atsam/main_arm_atsam.c | 136 ++++++-----
tmk_core/protocol/arm_atsam/usb/spfssf.c | 268 ---------------------
tmk_core/protocol/arm_atsam/usb/spfssf.h | 57 -----
tmk_core/protocol/arm_atsam/usb/udi_cdc.c | 8 +-
tmk_core/protocol/arm_atsam/usb/udi_cdc.h | 10 +-
tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c | 10 +-
tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h | 2 +
22 files changed, 175 insertions(+), 520 deletions(-)
delete mode 100644 tmk_core/protocol/arm_atsam/usb/spfssf.c
delete mode 100644 tmk_core/protocol/arm_atsam/usb/spfssf.h
(limited to 'tmk_core/common')
diff --git a/keyboards/massdrop/alt/alt.h b/keyboards/massdrop/alt/alt.h
index 387985512..8dfed8d2d 100644
--- a/keyboards/massdrop/alt/alt.h
+++ b/keyboards/massdrop/alt/alt.h
@@ -22,3 +22,13 @@
{ K45, KC_NO, K46, K47, K48, K49, K50, K51, K52, K53, K54, K55, K56, K57, K58, }, \
{ K59, K60, K61, KC_NO, KC_NO, KC_NO, K62, KC_NO, KC_NO, KC_NO, K63, K64, K65, K66, K67, }, \
}
+
+#define TOGGLE_FLAG_AND_PRINT(var, name) { \
+ if (var) { \
+ dprintf(name " disabled\r\n"); \
+ var = !var; \
+ } else { \
+ var = !var; \
+ dprintf(name " enabled\r\n"); \
+ } \
+ }
diff --git a/keyboards/massdrop/alt/keymaps/default/keymap.c b/keyboards/massdrop/alt/keymaps/default/keymap.c
index 0cbce8629..a5c443ffc 100644
--- a/keyboards/massdrop/alt/keymaps/default/keymap.c
+++ b/keyboards/massdrop/alt/keymaps/default/keymap.c
@@ -136,8 +136,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case L_T_BR:
if (record->event.pressed) {
led_animation_breathing = !led_animation_breathing;
- if (led_animation_breathing)
- {
+ if (led_animation_breathing) {
gcr_breathe = gcr_desired;
led_animation_breathe_cur = BREATHE_MIN_STEP;
breathe_dir = 1;
@@ -151,50 +150,32 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return false;
case U_T_AUTO:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_extra_manual = !usb_extra_manual;
- CDC_print("USB extra port manual mode ");
- CDC_print(usb_extra_manual ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode");
}
return false;
case U_T_AGCR:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_gcr_auto = !usb_gcr_auto;
- CDC_print("USB GCR auto mode ");
- CDC_print(usb_gcr_auto ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
}
return false;
case DBG_TOG:
if (record->event.pressed) {
- debug_enable = !debug_enable;
- CDC_print("Debug mode ");
- CDC_print(debug_enable ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
}
return false;
case DBG_MTRX:
if (record->event.pressed) {
- debug_matrix = !debug_matrix;
- CDC_print("Debug matrix ");
- CDC_print(debug_matrix ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
}
return false;
case DBG_KBD:
if (record->event.pressed) {
- debug_keyboard = !debug_keyboard;
- CDC_print("Debug keyboard ");
- CDC_print(debug_keyboard ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
}
return false;
case DBG_MOU:
if (record->event.pressed) {
- debug_mouse = !debug_mouse;
- CDC_print("Debug mouse ");
- CDC_print(debug_mouse ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
}
return false;
case MD_BOOT:
@@ -209,4 +190,4 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
default:
return true; //Process all other keycodes normally
}
-}
\ No newline at end of file
+}
diff --git a/keyboards/massdrop/alt/keymaps/mac/keymap.c b/keyboards/massdrop/alt/keymaps/mac/keymap.c
index e886290e7..d6978fd80 100644
--- a/keyboards/massdrop/alt/keymaps/mac/keymap.c
+++ b/keyboards/massdrop/alt/keymaps/mac/keymap.c
@@ -136,8 +136,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case L_T_BR:
if (record->event.pressed) {
led_animation_breathing = !led_animation_breathing;
- if (led_animation_breathing)
- {
+ if (led_animation_breathing) {
gcr_breathe = gcr_desired;
led_animation_breathe_cur = BREATHE_MIN_STEP;
breathe_dir = 1;
@@ -151,50 +150,32 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return false;
case U_T_AUTO:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_extra_manual = !usb_extra_manual;
- CDC_print("USB extra port manual mode ");
- CDC_print(usb_extra_manual ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode");
}
return false;
case U_T_AGCR:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_gcr_auto = !usb_gcr_auto;
- CDC_print("USB GCR auto mode ");
- CDC_print(usb_gcr_auto ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
}
return false;
case DBG_TOG:
if (record->event.pressed) {
- debug_enable = !debug_enable;
- CDC_print("Debug mode ");
- CDC_print(debug_enable ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
}
return false;
case DBG_MTRX:
if (record->event.pressed) {
- debug_matrix = !debug_matrix;
- CDC_print("Debug matrix ");
- CDC_print(debug_matrix ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
}
return false;
case DBG_KBD:
if (record->event.pressed) {
- debug_keyboard = !debug_keyboard;
- CDC_print("Debug keyboard ");
- CDC_print(debug_keyboard ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
}
return false;
case DBG_MOU:
if (record->event.pressed) {
- debug_mouse = !debug_mouse;
- CDC_print("Debug mouse ");
- CDC_print(debug_mouse ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
}
return false;
case MD_BOOT:
diff --git a/keyboards/massdrop/alt/rules.mk b/keyboards/massdrop/alt/rules.mk
index daf679585..c5539158f 100644
--- a/keyboards/massdrop/alt/rules.mk
+++ b/keyboards/massdrop/alt/rules.mk
@@ -30,3 +30,4 @@ FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400)
VIRTSER_ENABLE = no # USB Serial Driver
RAW_ENABLE = no # Raw device
+AUTO_SHIFT_ENABLE = no # Auto Shift
diff --git a/keyboards/massdrop/ctrl/ctrl.h b/keyboards/massdrop/ctrl/ctrl.h
index dc7c7eabe..c83efca16 100644
--- a/keyboards/massdrop/ctrl/ctrl.h
+++ b/keyboards/massdrop/ctrl/ctrl.h
@@ -30,3 +30,13 @@
{ K59, K60, K61, K62, K63, K76, K50, K33 }, \
{ K72, K73, K74, K75, K85, K86, K87, }, \
}
+
+#define TOGGLE_FLAG_AND_PRINT(var, name) { \
+ if (var) { \
+ dprintf(name " disabled\r\n"); \
+ var = !var; \
+ } else { \
+ var = !var; \
+ dprintf(name " enabled\r\n"); \
+ } \
+ }
diff --git a/keyboards/massdrop/ctrl/keymaps/default/keymap.c b/keyboards/massdrop/ctrl/keymaps/default/keymap.c
index 9bfb7fec5..88c1ac312 100644
--- a/keyboards/massdrop/ctrl/keymaps/default/keymap.c
+++ b/keyboards/massdrop/ctrl/keymaps/default/keymap.c
@@ -33,7 +33,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, \
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
- KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
),
[1] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MUTE, KC_TRNS, KC_TRNS, \
@@ -41,7 +41,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
L_T_BR, L_PSD, L_BRI, L_PSI, KC_TRNS, KC_TRNS, KC_TRNS, U_T_AUTO,U_T_AGCR,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_VOLD, \
L_T_PTD, L_PTP, L_BRD, L_PTN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, MD_BOOT, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
/*
[X] = LAYOUT(
@@ -50,7 +50,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
*/
};
@@ -139,8 +139,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case L_T_BR:
if (record->event.pressed) {
led_animation_breathing = !led_animation_breathing;
- if (led_animation_breathing)
- {
+ if (led_animation_breathing) {
gcr_breathe = gcr_desired;
led_animation_breathe_cur = BREATHE_MIN_STEP;
breathe_dir = 1;
@@ -154,50 +153,32 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return false;
case U_T_AUTO:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_extra_manual = !usb_extra_manual;
- CDC_print("USB extra port manual mode ");
- CDC_print(usb_extra_manual ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode");
}
return false;
case U_T_AGCR:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_gcr_auto = !usb_gcr_auto;
- CDC_print("USB GCR auto mode ");
- CDC_print(usb_gcr_auto ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
}
return false;
case DBG_TOG:
if (record->event.pressed) {
- debug_enable = !debug_enable;
- CDC_print("Debug mode ");
- CDC_print(debug_enable ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
}
return false;
case DBG_MTRX:
if (record->event.pressed) {
- debug_matrix = !debug_matrix;
- CDC_print("Debug matrix ");
- CDC_print(debug_matrix ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
}
return false;
case DBG_KBD:
if (record->event.pressed) {
- debug_keyboard = !debug_keyboard;
- CDC_print("Debug keyboard ");
- CDC_print(debug_keyboard ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
}
return false;
case DBG_MOU:
if (record->event.pressed) {
- debug_mouse = !debug_mouse;
- CDC_print("Debug mouse ");
- CDC_print(debug_mouse ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
}
return false;
case MD_BOOT:
diff --git a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c
index a03f891e8..6c5dfe19c 100644
--- a/keyboards/massdrop/ctrl/keymaps/mac/keymap.c
+++ b/keyboards/massdrop/ctrl/keymaps/mac/keymap.c
@@ -33,15 +33,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, KC_END, KC_PGDN, \
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, \
- KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
+ KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
),
[1] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MUTE, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MSTP, KC_VOLU, \
L_T_BR, L_PSD, L_BRI, L_PSI, KC_TRNS, KC_TRNS, KC_TRNS, U_T_AUTO,U_T_AGCR,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_VOLD, \
L_T_PTD, L_PTP, L_BRD, L_PTN, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
- KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, KC_TRNS, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
+ KC_TRNS, L_T_MD, L_T_ONF, KC_TRNS, KC_TRNS, MD_BOOT, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
/*
[X] = LAYOUT(
@@ -50,7 +50,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, TG_NKRO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
- KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
*/
};
@@ -139,8 +139,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
case L_T_BR:
if (record->event.pressed) {
led_animation_breathing = !led_animation_breathing;
- if (led_animation_breathing)
- {
+ if (led_animation_breathing) {
gcr_breathe = gcr_desired;
led_animation_breathe_cur = BREATHE_MIN_STEP;
breathe_dir = 1;
@@ -154,50 +153,32 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return false;
case U_T_AUTO:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_extra_manual = !usb_extra_manual;
- CDC_print("USB extra port manual mode ");
- CDC_print(usb_extra_manual ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode");
}
return false;
case U_T_AGCR:
if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
- usb_gcr_auto = !usb_gcr_auto;
- CDC_print("USB GCR auto mode ");
- CDC_print(usb_gcr_auto ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
}
return false;
case DBG_TOG:
if (record->event.pressed) {
- debug_enable = !debug_enable;
- CDC_print("Debug mode ");
- CDC_print(debug_enable ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_enable, "Debug mode");
}
return false;
case DBG_MTRX:
if (record->event.pressed) {
- debug_matrix = !debug_matrix;
- CDC_print("Debug matrix ");
- CDC_print(debug_matrix ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_matrix, "Debug matrix");
}
return false;
case DBG_KBD:
if (record->event.pressed) {
- debug_keyboard = !debug_keyboard;
- CDC_print("Debug keyboard ");
- CDC_print(debug_keyboard ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_keyboard, "Debug keyboard");
}
return false;
case DBG_MOU:
if (record->event.pressed) {
- debug_mouse = !debug_mouse;
- CDC_print("Debug mouse ");
- CDC_print(debug_mouse ? "enabled" : "disabled");
- CDC_print("\r\n");
+ TOGGLE_FLAG_AND_PRINT(debug_mouse, "Debug mouse");
}
return false;
case MD_BOOT:
diff --git a/keyboards/massdrop/ctrl/rules.mk b/keyboards/massdrop/ctrl/rules.mk
index daf679585..c5539158f 100644
--- a/keyboards/massdrop/ctrl/rules.mk
+++ b/keyboards/massdrop/ctrl/rules.mk
@@ -30,3 +30,4 @@ FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
HD44780_ENABLE = no # Enable support for HD44780 based LCDs (+400)
VIRTSER_ENABLE = no # USB Serial Driver
RAW_ENABLE = no # Raw device
+AUTO_SHIFT_ENABLE = no # Auto Shift
diff --git a/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld b/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld
index 3d114f5b7..35db61971 100644
--- a/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld
+++ b/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld
@@ -35,7 +35,7 @@ SEARCH_DIR(.)
/* Memory Spaces Definitions */
MEMORY
{
- //rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
+/*rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000*/
rom (rx) : ORIGIN = 0x00004000, LENGTH = 0x0003C000
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000
bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000
@@ -45,6 +45,9 @@ MEMORY
/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x8000;
+/* The heap size used by the application. */
+HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : DEFINED(__heap_size__) ? __heap_size__ : 0x800;
+
_srom = ORIGIN(rom);
_lrom = LENGTH(rom);
_erom = ORIGIN(rom) + LENGTH(rom);
@@ -153,6 +156,17 @@ SECTIONS
_ezero = .;
} > ram
+ /* .heap section for syscalls */
+ .heap (NOLOAD) :
+ {
+ . = ALIGN(4);
+ _end = .;
+ end = .;
+ _heap_start = .;
+ . = . + HEAP_SIZE;
+ _heap_end = .;
+ } > ram
+
/* stack section */
.stack (NOLOAD):
{
diff --git a/tmk_core/arm_atsam.mk b/tmk_core/arm_atsam.mk
index ef412d59d..06823fb62 100644
--- a/tmk_core/arm_atsam.mk
+++ b/tmk_core/arm_atsam.mk
@@ -36,7 +36,7 @@ LDFLAGS +=-Wl,--gc-sections
LDFLAGS += -Wl,-Map="%OUT%%PROJ_NAME%.map"
LDFLAGS += -Wl,--start-group
LDFLAGS += -Wl,--end-group
-LDFLAGS += -Wl,--gc-sections
+LDFLAGS += --specs=rdimon.specs
LDFLAGS += -T$(LIB_PATH)/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld
OPT_DEFS += -DPROTOCOL_ARM_ATSAM
diff --git a/tmk_core/common/arm_atsam/printf.h b/tmk_core/common/arm_atsam/printf.h
index 582c83bf5..3206b40bd 100644
--- a/tmk_core/common/arm_atsam/printf.h
+++ b/tmk_core/common/arm_atsam/printf.h
@@ -1,8 +1,8 @@
#ifndef _PRINTF_H_
#define _PRINTF_H_
-#define __xprintf dpf
int dpf(const char *_Format, ...);
+#define __xprintf dpf
#endif //_PRINTF_H_
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index 9cbe67bad..d94527657 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -29,7 +29,7 @@
#include
#include "util.h"
-#if defined(PROTOCOL_CHIBIOS)
+#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM)
#define PSTR(x) x
#endif
diff --git a/tmk_core/protocol/arm_atsam.mk b/tmk_core/protocol/arm_atsam.mk
index d535b64cd..04e02790a 100644
--- a/tmk_core/protocol/arm_atsam.mk
+++ b/tmk_core/protocol/arm_atsam.mk
@@ -10,7 +10,6 @@ SRC += $(ARM_ATSAM_DIR)/spi.c
SRC += $(ARM_ATSAM_DIR)/startup.c
SRC += $(ARM_ATSAM_DIR)/usb/main_usb.c
-SRC += $(ARM_ATSAM_DIR)/usb/spfssf.c
SRC += $(ARM_ATSAM_DIR)/usb/udc.c
SRC += $(ARM_ATSAM_DIR)/usb/udi_cdc.c
SRC += $(ARM_ATSAM_DIR)/usb/udi_hid.c
diff --git a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
index be73beccd..2ba099174 100644
--- a/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
+++ b/tmk_core/protocol/arm_atsam/arm_atsam_protocol.h
@@ -36,7 +36,6 @@ along with this program. If not, see .
#include "issi3733_driver.h"
#include "./usb/compiler.h"
#include "./usb/udc.h"
-#include "./usb/spfssf.h"
#include "./usb/udi_cdc.h"
#endif //MD_BOOTLOADER
diff --git a/tmk_core/protocol/arm_atsam/d51_util.h b/tmk_core/protocol/arm_atsam/d51_util.h
index 465889c7c..7a35f7989 100644
--- a/tmk_core/protocol/arm_atsam/d51_util.h
+++ b/tmk_core/protocol/arm_atsam/d51_util.h
@@ -32,6 +32,16 @@ along with this program. If not, see .
#define m15_on REG_PORT_OUTSET1 = 0x40000000 //PB30 High
#define m15_off REG_PORT_OUTCLR1 = 0x40000000 //PB30 Low
+//Debug Port PB23
+#define m27_ena REG_PORT_DIRSET1 = 0x800000 //PB23 Output
+#define m27_on REG_PORT_OUTSET1 = 0x800000 //PB23 High
+#define m27_off REG_PORT_OUTCLR1 = 0x800000 //PB23 Low
+
+//Debug Port PB31
+#define m28_ena REG_PORT_DIRSET1 = 0x80000000 //PB31 Output
+#define m28_on REG_PORT_OUTSET1 = 0x80000000 //PB31 High
+#define m28_off REG_PORT_OUTCLR1 = 0x80000000 //PB31 Low
+
#define m15_loop(M15X) {uint8_t M15L=M15X; while(M15L--){m15_on;CLK_delay_us(1);m15_off;}}
void m15_print(uint32_t x);
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index 8cc776703..676dac4ea 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -31,6 +31,7 @@ along with this program. If not, see .
//From keyboard's directory
#include "config_led.h"
+void main_subtasks(void);
uint8_t keyboard_leds(void);
void send_keyboard(report_keyboard_t *report);
void send_mouse(report_mouse_t *report);
@@ -65,7 +66,7 @@ void send_keyboard(report_keyboard_t *report)
if (!keymap_config.nkro)
{
#endif //NKRO_ENABLE
- dprint("s-kbd\r\n");
+ while (udi_hid_kbd_b_report_trans_ongoing) { main_subtasks(); } //Run other tasks while waiting for USB to be free
irqflags = __get_PRIMASK();
__disable_irq();
@@ -81,7 +82,7 @@ void send_keyboard(report_keyboard_t *report)
}
else
{
- dprint("s-nkro\r\n");
+ while (udi_hid_nkro_b_report_trans_ongoing) { main_subtasks(); } //Run other tasks while waiting for USB to be free
irqflags = __get_PRIMASK();
__disable_irq();
@@ -102,8 +103,6 @@ void send_mouse(report_mouse_t *report)
#ifdef MOUSEKEY_ENABLE
uint32_t irqflags;
- dprint("s-mou\r\n");
-
irqflags = __get_PRIMASK();
__disable_irq();
__DMB();
@@ -120,8 +119,6 @@ void send_mouse(report_mouse_t *report)
void send_system(uint16_t data)
{
#ifdef EXTRAKEY_ENABLE
- dprintf("s-exks %i\r\n", data);
-
uint32_t irqflags;
irqflags = __get_PRIMASK();
@@ -142,8 +139,6 @@ void send_system(uint16_t data)
void send_consumer(uint16_t data)
{
#ifdef EXTRAKEY_ENABLE
- dprintf("s-exkc %i\r\n",data);
-
uint32_t irqflags;
irqflags = __get_PRIMASK();
@@ -160,6 +155,77 @@ void send_consumer(uint16_t data)
#endif //EXTRAKEY_ENABLE
}
+uint8_t g_drvid;
+
+void main_subtask_usb_state(void)
+{
+ if (usb_state == USB_STATE_POWERDOWN)
+ {
+ uint32_t timer_led = timer_read32();
+
+ led_on;
+ if (led_enabled)
+ {
+ for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++)
+ {
+ I2C3733_Control_Set(0);
+ }
+ }
+ while (usb_state == USB_STATE_POWERDOWN)
+ {
+ if (timer_read32() - timer_led > 1000) led_off; //Good to indicate went to sleep, but only for a second
+ }
+ if (led_enabled)
+ {
+ for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++)
+ {
+ I2C3733_Control_Set(1);
+ }
+ }
+ led_off;
+ }
+}
+
+void main_subtask_led(void)
+{
+ led_matrix_task();
+}
+
+void main_subtask_power_check(void)
+{
+ static uint64_t next_5v_checkup = 0;
+
+ if (CLK_get_ms() > next_5v_checkup)
+ {
+ next_5v_checkup = CLK_get_ms() + 5;
+
+ v_5v = adc_get(ADC_5V);
+ v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v;
+
+ gcr_compute();
+ }
+}
+
+void main_subtask_usb_extra_device(void)
+{
+ static uint64_t next_usb_checkup = 0;
+
+ if (CLK_get_ms() > next_usb_checkup)
+ {
+ next_usb_checkup = CLK_get_ms() + 10;
+
+ USB_HandleExtraDevice();
+ }
+}
+
+void main_subtasks(void)
+{
+ main_subtask_usb_state();
+ main_subtask_led();
+ main_subtask_power_check();
+ main_subtask_usb_extra_device();
+}
+
int main(void)
{
led_ena;
@@ -201,9 +267,8 @@ int main(void)
i2c_led_q_init();
- uint8_t drvid;
- for (drvid=0;drvid 1000) led_off; //Good to indicate went to sleep, but only for a second
- }
- if (led_enabled)
- {
- for (drvid=0;drvid next_5v_checkup)
- {
- next_5v_checkup = CLK_get_ms() + 5;
-
- v_5v = adc_get(ADC_5V);
- v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v;
-
- gcr_compute();
- }
-
- if (CLK_get_ms() > next_usb_checkup)
- {
- next_usb_checkup = CLK_get_ms() + 10;
-
- USB_HandleExtraDevice();
- }
+ main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals
#ifdef VIRTSER_ENABLE
if (CLK_get_ms() > next_print)
{
next_print = CLK_get_ms() + 250;
- //dpf("5v=%i 5vu=%i dlow=%i dhi=%i gca=%i gcd=%i\r\n",v_5v,v_5v_avg,v_5v_avg-V5_LOW,v_5v_avg-V5_HIGH,gcr_actual,gcr_desired);
+ dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n",v_5v,v_5v_avg,v_5v_avg-V5_LOW,v_5v_avg-V5_HIGH,gcr_actual,gcr_desired);
}
#endif //VIRTSER_ENABLE
}
diff --git a/tmk_core/protocol/arm_atsam/usb/spfssf.c b/tmk_core/protocol/arm_atsam/usb/spfssf.c
deleted file mode 100644
index 449a8bb7d..000000000
--- a/tmk_core/protocol/arm_atsam/usb/spfssf.c
+++ /dev/null
@@ -1,268 +0,0 @@
-#include "samd51j18a.h"
-#include "stdarg.h"
-#include "spfssf.h"
-#include "usb_util.h"
-
-int vspf(char *_Dest, const char *_Format, va_list va)
-{
- //va_list va; //Variable argument list variable
- char *d = _Dest; //Pointer to dest
-
- //va_start(va,_Format); //Initialize the variable argument list
- while (*_Format) //While not end of format string
- {
- if (*_Format == SPF_SPEC_START) //If current format string character is the specifier start character
- {
- _Format++; //Skip over the character
- while (*_Format && *_Format <= 64) _Format++; //Forward past any options
- if (*_Format == SPF_SPEC_START) *d++ = *_Format; //If the character is the specifier start character, output the character and advance dest
- else if (*_Format == SPF_SPEC_LONG) //If the character is the long type
- {
- _Format++; //Skip over the character
- if (*_Format == SPF_SPEC_DECIMAL) //If the character is the decimal type
- {
- int64_t buf = va_arg(va,int64_t); //Get the next value from the va list
- //if (buf < 0) { *d++ = '-'; buf = -buf; } //If the given number is negative, add a negative sign to the dest and invert number
- //spf_uint2str_32_3t(&d,buf,32); //Perform the conversion
- d += UTIL_ltoa_radix(buf, d, 10);
- }
- else if (*_Format == SPF_SPEC_UNSIGNED) //If the character is the unsigned type
- {
- uint64_t num = va_arg(va,uint64_t); //Get the next value from the va list
- //spf_uint2str_32_3t(&d,num,32); //Perform the conversion
- d += UTIL_ltoa_radix(num, d, 10);
- }
- else if (*_Format == SPF_SPEC_UHINT || *_Format == SPF_SPEC_UHINT_UP) //If the character is the unsigned type
- {
- uint64_t buf = va_arg(va,uint64_t); //Get the next value from the va list
- //spf_uint2hex_32(&d,(unsigned long) buf);
- d += UTIL_ltoa_radix(buf, d, 16);
- }
- else //If the character was not a known type
- {
- *d++ = SPF_SPEC_START; //Output the start specifier
- *d++ = SPF_SPEC_LONG; //Output the long type
- *d++ = *_Format; //Output the unknown type
- }
- }
- else if (*_Format == SPF_SPEC_DECIMAL) //If the character is the decimal type
- {
- int buf = va_arg(va,int); //Get the next value from the va list
- //if (buf < 0) { *d++ = '-'; buf = -buf; } //If the given number is negative, add a negative sign to the dest and invert number
- //spf_uint2str_32_3t(&d,buf,16); //Perform the conversion
- d += UTIL_itoa(buf, d);
- }
- else if (*_Format == SPF_SPEC_INT) //If the character is the integer type
- {
- int buf = va_arg(va,int); //Get the next value from the va list
- //if (buf < 0) { *d++ = '-'; buf = -buf; } //If the given number is negative, add a negative sign to the dest and inverted number
- //spf_uint2str_32_3t(&d,buf,16); //Perform the conversion
- d += UTIL_itoa(buf, d);
- }
- else if (*_Format == SPF_SPEC_UINT) //If the character is the unsigned integer type
- {
- int buf = va_arg(va,int); //Get the next value from the va list
- //spf_uint2str_32_3t(&d,buf,16); //Perform the conversion
- d += UTIL_utoa(buf, d);
- }
- else if (*_Format == SPF_SPEC_STRING) //If the character is the string type
- {
- char *buf = va_arg(va,char*); //Get the next value from the va list
- while (*buf) *d++ = *buf++; //Perform the conversion (simply output characters and adcance pointers)
- }
- else if (*_Format == SPF_SPEC_UHINT || *_Format == SPF_SPEC_UHINT_UP) //If the character is the short type
- {
- int buf = va_arg(va,unsigned int); //Get the next value from the va list
- //spf_uint2hex_32(&d,(unsigned long) buf); //Perform the conversion
- d += UTIL_utoa(buf, d);
- }
- else //If the character type is unknown
- {
- *d++ = SPF_SPEC_START; //Output the start specifier
- *d++ = *_Format; //Output the unknown type
- }
- }
- else *d++ = *_Format; //If the character is unknown, output it to dest and advance dest
- _Format++; //Advance the format buffer pointer to next character
- }
- //va_end(va); //End the variable argument list
-
- *d = '\0'; //Cap off the destination string with a zero
-
- return d - _Dest; //Return the length of the destintion buffer
-}
-
-int spf(char *_Dest, const char *_Format, ...)
-{
- va_list va; //Variable argument list variable
- int result;
-
- va_start(va,_Format); //Initialize the variable argument list
- result = vspf(_Dest, _Format, va);
- va_end(va);
- return result;
-}
-
-//sscanf string to number (integer types)
-int64_t ssf_ston(const char **_Src, uint32_t count, uint32_t *conv_count)
-{
- int64_t value = 0; //Return value accumulator
- uint32_t counter=count; //Counter to keep track of numbers converted
- const char* p; //Pointer to first non space character
-
- while (*(*_Src) == SSF_SKIP_SPACE) (*_Src)++; //Forward through the whitespace to next non whitespace
-
- p = (*_Src); //Set pointer to first non space character
- if (*p == '+' || *p == '-') (*_Src)++; //Skip over sign if any
- while (*(*_Src) >= ASCII_NUM_START &&
- *(*_Src) <= ASCII_NUM_END &&
- counter) //While the source character is a digit and counter is not zero
- {
- value *= 10; //Multiply result by 10 to make room for next 1's place number
- value += *(*_Src)++ - ASCII_NUM_START; //Add source number to value
- counter--; //Decrement counter
- }
- if (counter - count == 0) return 0; //If no number conversion were performed, return 0
- if (*p == '-') value = -value; //If the number given was negative, make the result negative
-
- if (conv_count) (*conv_count)++; //Increment the converted count
- return value; //Return the value
-}
-
-uint64_t ssf_hton(const char **_Src, uint32_t count,uint32_t *conv_count)
-{
- int64_t value=0; //Return value accumulator
- uint32_t counter=count; //Counter to keep track of numbers converted
- //const char* p; //Pointer to first non space character
- char c;
-
- while (*(*_Src) == SSF_SKIP_SPACE) (*_Src)++; //Forward through the whitespace to next non whitespace
-
- //p = (*_Src); //Set pointer to first non space character
-
- while (counter)
- {
- c = *(*_Src)++;
- if (c >= 'a' && c <= 'f') c -= ('a'-'A'); //toupper
- if (c < '0' || (c > '9' && c < 'A') || c > 'F') break;
- value *= 16; //Multiply result by 10 to make room for next 1's place number
- c = c - '0';
- if (c > 9) c -= 7;
- value += c; //Add source number to value
- counter--; //Decrement counter
- }
-
- if (counter - count == 0) return 0; //If no number conversion were performed, return 0
- //if (*p == '-') value = -value; //If the number given was negative, make the result negative
-
- if (conv_count) (*conv_count)++; //Increment the converted count
- return value;
-}
-
-//sscanf
-int ssf(const char *_Src, const char *_Format, ...)
-{
- va_list va; //Variable argument list variable
- unsigned char looking_for=0; //Static char specified in format to be found in source
- uint32_t conv_count=0; //Count of conversions made
-
- va_start(va,_Format); //Initialize the variable argument list
- while (*_Format) //While the format string has not been fully read
- {
- if (looking_for != 0) //If we are looking for a matching character in the source string
- {
- while (*_Src != looking_for && *_Src) _Src++; //While the character is not found in the source string and not the end of the source
- // string, increment the pointer position
- if (*_Src == looking_for) _Src++; //If the character was found, step over it
- else break; //Else the end was reached and the scan is now invalid (Could not find static character)
- looking_for = 0; //Clear the looking for character
- }
- if (*_Format == SSF_SPEC_START) //If the current format character is the specifier start character
- {
- _Format++; //Step over the specifier start character
- if (*_Format == SSF_SPEC_DECIMAL) //If the decimal specifier type is found
- {
- int *value=va_arg(va,int*); //User given destination address
- //*value = (int)ssf_ston(&_Src,5,&conv_count); //Run conversion
- *value = (int)ssf_ston(&_Src,10,&conv_count); //Run conversion
- }
- else if (*_Format == SSF_SPEC_LONG) //If the long specifier type is found
- {
- _Format++; //Skip over the specifier type
- if (*_Format == SSF_SPEC_DECIMAL) //If the decimal specifier type is found
- {
- int64_t *value=va_arg(va,int64_t*); //User given destination address
- //*value = (int64_t)ssf_ston(&_Src,10,&conv_count); //Run conversion
- *value = (int64_t)ssf_ston(&_Src,19,&conv_count); //Run conversion
- }
- else if (*_Format == SSF_SPEC_UHINT) //If the decimal specifier type is found
- {
- uint64_t *value=va_arg(va,uint64_t *); //User given destination address
- //*value = (uint64_t int)ssf_hton(&_Src,12,&conv_count); //Run conversion
- *value = (uint64_t)ssf_hton(&_Src,16,&conv_count); //Run conversion
- }
- }
- else if (*_Format == SSF_SPEC_SHORTINT) //If the short int specifier type is found
- {
- _Format++; //Skip over the specifier type
- if (*_Format == SSF_SPEC_SHORTINT) //If the short int specifier type is found
- {
- _Format++; //Skip over the specifier type
- if (*_Format == SSF_SPEC_DECIMAL) //If the decimal specifier type is found
- {
- unsigned char *value=va_arg(va,unsigned char*); //User given destination address
- //*value = (unsigned char)ssf_ston(&_Src,3,&conv_count); //Run conversion
- *value = (unsigned char)ssf_ston(&_Src,5,&conv_count); //Run conversion
- }
- }
- }
- else if (*_Format == SSF_SPEC_STRING) //If the specifier type is string
- {
- char *value=va_arg(va,char*); //User given destination address, max chars read pointer
- while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace
- while (*_Src != SSF_SKIP_SPACE && *_Src) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest
- *value = 0; //Cap off the string pointer with zero
- conv_count++; //Increment the converted count
- }
- else if (*_Format == SSF_SPEC_VERSION) //If the specifier type is string
- {
- char *value=va_arg(va,char*); //User given destination address, max chars read pointer
- while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace
- while (*_Src != SSF_DELIM_COMMA && *_Src) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest
- *value = 0; //Cap off the string pointer with zero
- conv_count++; //Increment the converted count
- }
- else if (*_Format >= ASCII_NUM_START && *_Format <= ASCII_NUM_END)
- {
- uint32_t len = (uint32_t)ssf_ston(&_Format,3,NULL); //Convert the given length
- if (*_Format == SSF_SPEC_STRING) //If the specifier type is string
- {
- char *value=va_arg(va,char*),*e; //User given destination address, max chars read pointer
- while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace
- e = (char*)_Src+len; //Set a maximum length pointer location
- while (*_Src != SSF_SKIP_SPACE && *_Src && _Src != e) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest
- *value = 0; //Cap off the string pointer with zero
- conv_count++; //Increment the converted count
- }
- else if (*_Format == SSF_SPEC_VERSION) //If the specifier type is string
- {
- char *value=va_arg(va,char*),*e; //User given destination address, max chars read pointer
- while (*_Src == SSF_SKIP_SPACE) _Src++; //Forward through the whitespace to next non whitespace
- e = (char*)_Src+len; //Set a maximum length pointer location
- while (*_Src != SSF_DELIM_COMMA && *_Src && _Src != e) *value++ = *_Src++; //While any character but space and not end of string and not end location, copy char to dest
- *value = 0; //Cap off the string pointer with zero
- conv_count++; //Increment the converted count
- }
- }
- else if (*_Format == SSF_SPEC_START) looking_for = *_Format; //If another start specifier character is found, output a specifier character
- else break; //Scan is now invalid (Uknown type specified)
- }
- else if (*_Format == SSF_SKIP_SPACE) { } //If a space is found, ignore it
- else looking_for = *_Format; //If any other character is found, it is static and should be found in src as well
- _Format++; //Skip over current format character
- }
-
- va_end(va); //End the variable argument list
- return conv_count; //Return the number of conversions made
-}
-
diff --git a/tmk_core/protocol/arm_atsam/usb/spfssf.h b/tmk_core/protocol/arm_atsam/usb/spfssf.h
deleted file mode 100644
index 337a904df..000000000
--- a/tmk_core/protocol/arm_atsam/usb/spfssf.h
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef ____spfssf_h
-#define ____spfssf_h
-
-#include
-
-#define sprintf spf
-#define sscanf ssf
-
-#define SIZEOF_OFFSET 1
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#define SPF_NONE 0
-
-#define SPF_SPEC_START 37 //%
-#define SPF_SPEC_DECIMAL 100 //d 16bit dec signed (-32767 to 32767) DONE same as i
-#define SPF_SPEC_INT 105 //i 16bit dec signed (-32767 to 32767) DONE same as d
-#define SPF_SPEC_UINT 117 //u 16bit dec unsigned (0 to 65535) DONE
-#define SPF_SPEC_STRING 115 //s variable length (abcd...) DONE
-#define SPF_SPEC_UHINT 120 //x 16bit hex lwrc (7fa) DONE
-#define SPF_SPEC_UHINT_UP 88 //x 16bit hex lwrc (7fa) DONE
-#define SPF_SPEC_LONG 108 //l start of either ld or lu DONE
-#define SPF_SPEC_DECIMAL 100 //ld 32bit dec signed (-2147483647 to 2147483647) DONE
-#define SPF_SPEC_UNSIGNED 117 //lu 32bit dec unsigned (0 to 4294967295) DONE
-#define SPF_SPEC_UHINT 120 //lx 32bit hex unsigned (0 to ffffffff) DONE
-
-#define SSF_SPEC_START 37 //%
-#define SSF_SPEC_SHORTINT 104 //h 8bit dec signed (-127 to 127) DONE
-#define SSF_LEN_SHORTINT 3 //hhd
-#define SSF_SPEC_DECIMAL 100 //d 16bit dec signed (-32767 to 32767) DONE
-#define SSF_LEN_DECIMAL 5 //32767
-#define SSF_SPEC_INT 105 //i 16bit dec signed (-32767 to 32767) DONE
-#define SSF_LEN_INT 5 //32767
-#define SSF_SPEC_LONG 108 //l start of either ld or lu DONE
-#define SSF_SPEC_DECIMAL 100 //ld 32bit dec signed (-2147483647 to 2147483647) DONE
-#define SSF_SPEC_UHINT 120 //lx 32bit hex unsigned DONE
-#define SSF_LEN_LDECIMAL 10 //2147483647
-#define SSF_SPEC_STRING 115 //s variable length (abcd...) DONE
-#define SSF_SKIP_SPACE 32 //space
-
-#define SSF_SPEC_VERSION 118 //v collect to comma delimiter - special
-#define SSF_DELIM_COMMA 44 //,
-
-#define ASCII_NUM_START 48 //0
-#define ASCII_NUM_END 58 //9
-
-#define T_UINT32_0_LIMIT 14
-#define T_UINT32_1_LIMIT 27
-
-int vspf(char *_Dest, const char *_Format, va_list va);
-int spf(char *_Dest, const char *_Format, ...);
-int ssf(const char *_Src, const char *_Format, ...);
-
-#endif //____spfssf_h
-
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c b/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
index b4159d325..15f0f760c 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
@@ -54,7 +54,6 @@
#include
#include "udi_cdc_conf.h"
#include "udi_device_conf.h"
-#include "spfssf.h"
#include "stdarg.h"
#include "tmk_core/protocol/arm_atsam/clks.h"
@@ -1259,7 +1258,6 @@ uint32_t CDC_print(char *printbuf)
return 1;
}
-
char printbuf[CDC_PRINTBUF_SIZE];
int dpf(const char *_Format, ...)
@@ -1267,8 +1265,8 @@ int dpf(const char *_Format, ...)
va_list va; //Variable argument list variable
int result;
- va_start(va,_Format); //Initialize the variable argument list
- result = vspf(printbuf, _Format, va);
+ va_start(va, _Format); //Initialize the variable argument list
+ result = vsnprintf(printbuf, CDC_PRINTBUF_SIZE, _Format, va);
va_end(va);
CDC_print(printbuf);
@@ -1377,8 +1375,6 @@ void CDC_init(void)
printbuf[0]=0;
}
-char printbuf[CDC_PRINTBUF_SIZE];
-
#endif //CDC line 62
//@}
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc.h b/tmk_core/protocol/arm_atsam/usb/udi_cdc.h
index 6b70e96d0..e134cf236 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_cdc.h
+++ b/tmk_core/protocol/arm_atsam/usb/udi_cdc.h
@@ -57,8 +57,8 @@
#include "udi.h"
// Check the number of port
-#ifndef UDI_CDC_PORT_NB
-# define UDI_CDC_PORT_NB 1
+#ifndef UDI_CDC_PORT_NB
+# define UDI_CDC_PORT_NB 1
#endif
#if (UDI_CDC_PORT_NB > 1)
# error UDI_CDC_PORT_NB must be at most 1
@@ -86,9 +86,6 @@ extern UDC_DESC_STORAGE udi_api_t udi_api_cdc_data;
//! CDC data endpoints size for FS speed (8B, 16B, 32B, 64B)
#define UDI_CDC_DATA_EPS_FS_SIZE CDC_RX_SIZE
-#define CDC_PRINT_BUF_SIZE 256
-extern char printbuf[CDC_PRINT_BUF_SIZE];
-
//@}
/**
@@ -371,9 +368,6 @@ uint32_t CDC_print(char *printbuf);
uint32_t CDC_input(void);
void CDC_init(void);
-#define __xprintf dpf
-int dpf(const char *_Format, ...);
-
#ifdef __cplusplus
}
#endif
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
index 18f69350c..1a6f7905e 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
@@ -45,6 +45,7 @@
*/
#include "samd51j18a.h"
+#include "d51_util.h"
#include "conf_usb.h"
#include "usb_protocol.h"
#include "udd.h"
@@ -86,7 +87,7 @@ bool udi_hid_kbd_b_report_valid;
COMPILER_WORD_ALIGNED
uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE];
-static bool udi_hid_kbd_b_report_trans_ongoing;
+volatile bool udi_hid_kbd_b_report_trans_ongoing;
COMPILER_WORD_ALIGNED
static uint8_t udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE];
@@ -186,8 +187,7 @@ bool udi_hid_kbd_send_report(void)
return false;
}
- memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report,
- UDI_HID_KBD_REPORT_SIZE);
+ memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report, UDI_HID_KBD_REPORT_SIZE);
udi_hid_kbd_b_report_valid = false;
udi_hid_kbd_b_report_trans_ongoing =
udd_ep_run(UDI_HID_KBD_EP_IN | USB_EP_DIR_IN,
@@ -249,7 +249,7 @@ bool udi_hid_nkro_b_report_valid;
COMPILER_WORD_ALIGNED
uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
-static bool udi_hid_nkro_b_report_trans_ongoing;
+volatile bool udi_hid_nkro_b_report_trans_ongoing;
COMPILER_WORD_ALIGNED
static uint8_t udi_hid_nkro_report_trans[UDI_HID_NKRO_REPORT_SIZE];
@@ -355,7 +355,7 @@ bool udi_hid_nkro_send_report(void)
return false;
}
- memcpy(udi_hid_nkro_report_trans, udi_hid_nkro_report,UDI_HID_NKRO_REPORT_SIZE);
+ memcpy(udi_hid_nkro_report_trans, udi_hid_nkro_report, UDI_HID_NKRO_REPORT_SIZE);
udi_hid_nkro_b_report_valid = false;
udi_hid_nkro_b_report_trans_ongoing =
udd_ep_run(UDI_HID_NKRO_EP_IN | USB_EP_DIR_IN,
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h
index 9a2741534..babfdb7a7 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h
@@ -60,6 +60,7 @@ extern "C" {
#ifdef KBD
extern UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd;
extern bool udi_hid_kbd_b_report_valid;
+extern volatile bool udi_hid_kbd_b_report_trans_ongoing;
extern uint8_t udi_hid_kbd_report_set;
bool udi_hid_kbd_send_report(void);
#endif //KBD
@@ -70,6 +71,7 @@ bool udi_hid_kbd_send_report(void);
#ifdef NKRO
extern UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro;
extern bool udi_hid_nkro_b_report_valid;
+extern volatile bool udi_hid_nkro_b_report_trans_ongoing;
bool udi_hid_nkro_send_report(void);
#endif //NKRO
--
cgit v1.2.3-70-g09d2
From daf0cc60bff54be948c923cdc40aa80b82a27f6d Mon Sep 17 00:00:00 2001
From: patrickmt <40182064+patrickmt@users.noreply.github.com>
Date: Fri, 28 Sep 2018 22:34:56 -0400
Subject: CTRL keyboard bootloader_jump support
Adds support for CTRL keyboards to enter bootloader via bootloader_jump()
---
.../SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld | 3 ++
tmk_core/common/arm_atsam/bootloader.c | 32 ++++++++++++----------
tmk_core/protocol/arm_atsam/md_bootloader.h | 7 +++++
tmk_core/protocol/arm_atsam/startup.c | 11 ++++++++
4 files changed, 38 insertions(+), 15 deletions(-)
(limited to 'tmk_core/common')
diff --git a/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld b/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld
index 35db61971..1c6354786 100644
--- a/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld
+++ b/lib/arm_atsam/packs/atmel/SAMD51_DFP/1.0.70/gcc/gcc/samd51j18a_flash.ld
@@ -51,6 +51,9 @@ HEAP_SIZE = DEFINED(HEAP_SIZE) ? HEAP_SIZE : DEFINED(__heap_size__) ? __heap_siz
_srom = ORIGIN(rom);
_lrom = LENGTH(rom);
_erom = ORIGIN(rom) + LENGTH(rom);
+_sram = ORIGIN(ram);
+_lram = LENGTH(ram);
+_eram = ORIGIN(ram) + LENGTH(ram);
/* Section Definitions */
SECTIONS
diff --git a/tmk_core/common/arm_atsam/bootloader.c b/tmk_core/common/arm_atsam/bootloader.c
index 9701a6219..ba71bfeb0 100644
--- a/tmk_core/common/arm_atsam/bootloader.c
+++ b/tmk_core/common/arm_atsam/bootloader.c
@@ -16,25 +16,27 @@
#include "bootloader.h"
#include "samd51j18a.h"
+#include "md_bootloader.h"
//Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
-void bootloader_jump(void)
-{
- //Keyboards released with certain bootloader can not enter bootloader from app until workaround is created
- uint8_t ver_no_jump[] = "v2.18Jun 22 2018 17:28:08";
- uint8_t *ver_check = ver_no_jump;
- uint8_t *boot_check = (uint8_t *)0x21A0;
- while (*ver_check && *boot_check == *ver_check)
- {
- ver_check++;
- boot_check++;
+void bootloader_jump(void) {
+#ifdef KEYBOARD_massdrop_ctrl
+ //CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
+ uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; //The version to match (NULL terminated by compiler)
+ uint8_t *ver_check = ver_ram_method; //Pointer to version match string for traversal
+ uint8_t *ver_rom = (uint8_t *)0x21A0; //Pointer to address in ROM where this specific bootloader version would exist
+
+ while (*ver_check && *ver_rom == *ver_check) { //While there are check version characters to match and bootloader's version matches check's version
+ ver_check++; //Move check version pointer to next character
+ ver_rom++; //Move ROM version pointer to next character
}
- if (!*ver_check)
- {
- //Version match
- //Software workaround would go here
- return; //No software restart method implemented... must use hardware reset button
+
+ if (!*ver_check) { //If check version pointer is NULL, all characters have matched
+ *MAGIC_ADDR = BOOTLOADER_MAGIC; //Set magic number into RAM
+ NVIC_SystemReset(); //Perform system reset
+ while (1) {} //Won't get here
}
+#endif
WDT->CTRLA.bit.ENABLE = 0;
while (WDT->SYNCBUSY.bit.ENABLE) {}
diff --git a/tmk_core/protocol/arm_atsam/md_bootloader.h b/tmk_core/protocol/arm_atsam/md_bootloader.h
index 1316876c8..956145c31 100644
--- a/tmk_core/protocol/arm_atsam/md_bootloader.h
+++ b/tmk_core/protocol/arm_atsam/md_bootloader.h
@@ -7,6 +7,13 @@ extern uint32_t _erom;
#define BOOTLOADER_SERIAL_MAX_SIZE 20 //DO NOT MODIFY!
+#ifdef KEYBOARD_massdrop_ctrl
+//WARNING: These are only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support
+extern uint32_t _eram;
+#define BOOTLOADER_MAGIC 0x3B9ACA00
+#define MAGIC_ADDR (uint32_t *)(&_eram - 4)
+#endif
+
#ifdef MD_BOOTLOADER
#define MCU_HZ 48000000
diff --git a/tmk_core/protocol/arm_atsam/startup.c b/tmk_core/protocol/arm_atsam/startup.c
index a62d02f1c..f29fac179 100644
--- a/tmk_core/protocol/arm_atsam/startup.c
+++ b/tmk_core/protocol/arm_atsam/startup.c
@@ -28,6 +28,7 @@
*/
#include "samd51.h"
+#include "md_bootloader.h"
/* Initialize segments */
extern uint32_t _sfixed;
@@ -500,6 +501,16 @@ const DeviceVectors exception_table = {
*/
void Reset_Handler(void)
{
+#ifdef KEYBOARD_massdrop_ctrl
+ /* WARNING: This is only for CTRL bootloader release "v2.18Jun 22 2018 17:28:08" for bootloader_jump support */
+ if (*MAGIC_ADDR == BOOTLOADER_MAGIC) {
+ /* At this point, the bootloader's memory is initialized properly, so undo the jump to here, then jump back */
+ *MAGIC_ADDR = 0x00000000; /* Change value to prevent potential bootloader entrance loop */
+ __set_MSP(0x20008818); /* MSP according to bootloader */
+ SCB->VTOR = 0x00000000; /* Vector table back to bootloader's */
+ asm("bx %0"::"r"(0x00001267)); /* Jump past bootloader RCAUSE check using THUMB */
+ }
+#endif
uint32_t *pSrc, *pDest;
/* Initialize the relocate segment */
--
cgit v1.2.3-70-g09d2
From 4318797d198b58bb807b3e436c7d8924d8b4a6fe Mon Sep 17 00:00:00 2001
From: Drashna Jaelre
Date: Mon, 27 Aug 2018 09:16:54 -0700
Subject: Add user level to default_layer_state_set
---
tmk_core/common/action_layer.c | 11 ++++++++++-
tmk_core/common/action_layer.h | 2 ++
users/drashna/drashna.c | 4 ++--
3 files changed, 14 insertions(+), 3 deletions(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index 62375dfbf..b8dcb34f3 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -15,13 +15,22 @@
*/
uint32_t default_layer_state = 0;
+/** \brief Default Layer State Set At user Level
+ *
+ * FIXME: Needs docs
+ */
+__attribute__((weak))
+uint32_t default_layer_state_set_user(uint32_t state) {
+ return state;
+}
+
/** \brief Default Layer State Set At Keyboard Level
*
* FIXME: Needs docs
*/
__attribute__((weak))
uint32_t default_layer_state_set_kb(uint32_t state) {
- return state;
+ return default_layer_state_set_user(state);
}
/** \brief Default Layer State Set
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 7bf116be2..6d48321f9 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -31,6 +31,8 @@ void default_layer_set(uint32_t state);
__attribute__((weak))
uint32_t default_layer_state_set_kb(uint32_t state);
+__attribute__((weak))
+uint32_t default_layer_state_set_user(uint32_t state);
#ifndef NO_ACTION_LAYER
/* bitwise operation */
diff --git a/users/drashna/drashna.c b/users/drashna/drashna.c
index 7bb272a26..9489fb456 100644
--- a/users/drashna/drashna.c
+++ b/users/drashna/drashna.c
@@ -403,8 +403,8 @@ uint32_t layer_state_set_user(uint32_t state) {
}
-uint32_t default_layer_state_set_kb(uint32_t state) {
- return default_layer_state_set_keymap (state);
+uint32_t default_layer_state_set_user(uint32_t state) {
+ return default_layer_state_set_keymap(state);
}
--
cgit v1.2.3-70-g09d2
From e885c793bcffcba03e18e93e41120b21cdfb6b75 Mon Sep 17 00:00:00 2001
From: Drashna Jaelre
Date: Mon, 1 Oct 2018 17:53:14 -0700
Subject: Add Function level EECONFIG code for EEPROM (#3084)
* Add Function level EEPROM configuration
Add kb and user functions for EEPROM, and example of how to use it.
* Bug fixes and demo
* Additional cleanup
* Add EEPROM reset macro to example
* Forgot init function in list
* Move eeconfig_init_quantum function to quantum.c and actually set default layer
* See if removing weak quantum function fixes issue
* Fix travis compile error
* Remove ifdef blocks from EECONFIG so settings are always set
* Fix for ARM EEPROM updates
* Fix merge issues
* Fix potential STM32 EEPROM issues
---
docs/custom_quantum_functions.md | 140 ++++++++++++
keyboards/ergodox_ez/keymaps/rgb_layer/config.h | 24 +++
keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c | 271 ++++++++++++++++++++++++
quantum/quantum.c | 3 +
tmk_core/common/eeconfig.c | 103 ++++++---
tmk_core/common/eeconfig.h | 44 ++--
6 files changed, 545 insertions(+), 40 deletions(-)
create mode 100644 keyboards/ergodox_ez/keymaps/rgb_layer/config.h
create mode 100644 keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c
(limited to 'tmk_core/common')
diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md
index 10c5c75a2..f8b84cd6b 100644
--- a/docs/custom_quantum_functions.md
+++ b/docs/custom_quantum_functions.md
@@ -244,3 +244,143 @@ uint32_t layer_state_set_user(uint32_t state) {
* Keymap: `uint32_t layer_state_set_user(uint32_t state)`
The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status)
+
+
+# Persistent Configuration (EEPROM)
+
+This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss. The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM.
+
+The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function.
+
+Keep in mind that EEPROM has a limited number of writes. While this is very high, it's not the only thing writing to the EEPROM, and if you write too often, you can potentially drastically shorten the life of your MCU.
+
+* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated.
+
+### Example Implementation
+
+This is an example of how to add settings, and read and write it. We're using the user keymap for the example here. This is a complex function, and has a lot going on. In fact, it uses a lot of the above functions to work!
+
+
+In your keymap.c file, add this to the top:
+```
+typedef union {
+ uint32_t raw;
+ struct {
+ bool rgb_layer_change :1;
+ };
+} user_config_t;
+
+user_config_t user_config;
+```
+
+This sets up a 32 bit structure that we can store settings with in memory, and write to the EEPROM. Using this removes the need to define variables, since they're defined in this structure. Remember that `bool` (boolean) values use 1 bit, `uint8_t` uses 8 bits, `uint16_t` uses up 16 bits. You can mix and match, but changing the order can cause issues, as it will change the values that are read and written.
+
+We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `matrix_init_user` and `process_record_user` to configure everything.
+
+Now, using the `matrix_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap. And It should look like:
+```
+void matrix_init_user(void) {
+ // Call the keymap level matrix init.
+
+ // Read the user config from EEPROM
+ user_config.raw = eeconfig_read_user();
+
+ // Set default layer, if enabled
+ if (user_config.rgb_layer_change) {
+ rgblight_enable_noeeprom();
+ rgblight_sethsv_noeeprom_cyan();
+ rgblight_mode_noeeprom(1);
+ }
+}
+```
+The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above.
+
+```
+uint32_t layer_state_set_user(uint32_t state) {
+ switch (biton32(state)) {
+ case _RAISE:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); }
+ break;
+ case _LOWER:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); }
+ break;
+ case _PLOVER:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); }
+ break;
+ case _ADJUST:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); }
+ break;
+ default: // for any other layers, or the default layer
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); }
+ break;
+ }
+ return state;
+}
+```
+This will cause the RGB underglow to be changed ONLY if the value was enabled. Now to configure this value, create a new keycode for `process_record_user` called `RGB_LYR` and `EPRM`. Additionally, we want to make sure that if you use the normal RGB codes, that it turns off Using the example above, make it look this:
+```
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case FOO:
+ if (record->event.pressed) {
+ // Do something when pressed
+ } else {
+ // Do something else when release
+ }
+ return false; // Skip all further processing of this key
+ case KC_ENTER:
+ // Play a tone when enter is pressed
+ if (record->event.pressed) {
+ PLAY_NOTE_ARRAY(tone_qwerty);
+ }
+ return true; // Let QMK send the enter press/release events
+ case EPRM:
+ if (record->event.pressed) {
+ eeconfig_init(); // resets the EEPROM to default
+ }
+ return false;
+ case RGB_LYR: // This allows me to use underglow as layer indication, or as normal
+ if (record->event.pressed) {
+ user_config.rgb_layer_change ^= 1; // Toggles the status
+ eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM
+ if (user_config.rgb_layer_change) { // if layer state indication is enabled,
+ layer_state_set(layer_state); // then immediately update the layer color
+ }
+ }
+ return false; break;
+ case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference)
+ if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
+ if (user_config.rgb_layer_change) { // only if this is enabled
+ user_config.rgb_layer_change = false; // disable it, and
+ eeconfig_update_user(user_config.raw); // write the setings to EEPROM
+ }
+ }
+ return true; break;
+ default:
+ return true; // Process all other keycodes normally
+ }
+}
+```
+And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. For example, if you want to set rgb layer indication by default, and save the default valued.
+
+```
+void eeconfig_init_user(void) { // EEPROM is getting reset!
+ user_config.rgb_layer_change = true; // We want this enabled by default
+ eeconfig_update_user(user_config.raw); // Write default value to EEPROM now
+
+ // use the non noeeprom versions, to write these values to EEPROM too
+ rgblight_enable(); // Enable RGB by default
+ rgblight_sethsv_cyan(); // Set it to CYAN by default
+ rgblight_mode(1); // set to solid by default
+}
+```
+
+And you're done. The RGB layer indication will only work if you want it to. And it will be saved, even after unplugging the board. And if you use any of the RGB codes, it will disable the layer indication, so that it stays on the mode and color that you set it to.
+
+### 'EECONFIG' Function Documentation
+
+* Keyboard/Revision: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` and `void eeconfig_update_kb(uint32_t val)`
+* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)`
+
+The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM.
diff --git a/keyboards/ergodox_ez/keymaps/rgb_layer/config.h b/keyboards/ergodox_ez/keymaps/rgb_layer/config.h
new file mode 100644
index 000000000..59302b800
--- /dev/null
+++ b/keyboards/ergodox_ez/keymaps/rgb_layer/config.h
@@ -0,0 +1,24 @@
+#ifndef KEYMAP_CONFIG_H
+#define KEYMAP_CONFIG_H
+
+
+ #define RGBLIGHT_SLEEP
+
+
+#ifndef QMK_KEYS_PER_SCAN
+#define QMK_KEYS_PER_SCAN 4
+#endif // !QMK_KEYS_PER_SCAN
+
+#define IGNORE_MOD_TAP_INTERRUPT
+#undef PERMISSIVE_HOLD
+#undef PREVENT_STUCK_MODIFIERS
+
+
+#define FORCE_NKRO
+
+#ifndef TAPPING_TOGGLE
+#define TAPPING_TOGGLE 1
+#endif
+
+#endif // !USERSPACE_CONFIG_H
+
diff --git a/keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c b/keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c
new file mode 100644
index 000000000..384d7d094
--- /dev/null
+++ b/keyboards/ergodox_ez/keymaps/rgb_layer/keymap.c
@@ -0,0 +1,271 @@
+#include QMK_KEYBOARD_H
+#include "version.h"
+
+#define BASE 0 // default layer
+#define SYMB 1 // symbols
+#define MDIA 2 // media keys
+
+enum custom_keycodes {
+ PLACEHOLDER = SAFE_RANGE, // can always be here
+ EPRM,
+ VRSN,
+ RGB_SLD,
+ RGB_LYR
+};
+
+typedef union {
+ uint32_t raw;
+ struct {
+ bool rgb_layer_change :1;
+ };
+} user_config_t;
+
+user_config_t user_config;
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+/* Keymap 0: Basic layer
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | = | 1 | 2 | 3 | 4 | 5 | LEFT | | RIGHT| 6 | 7 | 8 | 9 | 0 | - |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | Del | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | \ |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | BkSp | A | S | D | F | G |------| |------| H | J | K | L |; / L2|' / Cmd |
+ * |--------+------+------+------+------+------| Hyper| | Meh |------+------+------+------+------+--------|
+ * | LShift |Z/Ctrl| X | C | V | B | | | | N | M | , | . |//Ctrl| RShift |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * |Grv/L1| '" |AltShf| Left | Right| | Up | Down | [ | ] | ~L1 |
+ * `----------------------------------' `----------------------------------'
+ * ,-------------. ,-------------.
+ * | App | LGui | | Alt |Ctrl/Esc|
+ * ,------|------|------| |------+--------+------.
+ * | | | Home | | PgUp | | |
+ * | Space|Backsp|------| |------| Tab |Enter |
+ * | |ace | End | | PgDn | | |
+ * `--------------------' `----------------------'
+ */
+// If it accepts an argument (i.e, is a function), it doesn't need KC_.
+// Otherwise, it needs KC_*
+[BASE] = LAYOUT_ergodox( // layer 0 : default
+ // left hand
+ KC_EQL, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT,
+ KC_DELT, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
+ KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G,
+ KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
+ LT(SYMB,KC_GRV),KC_QUOT, LALT(KC_LSFT), KC_LEFT,KC_RGHT,
+ ALT_T(KC_APP), KC_LGUI,
+ KC_HOME,
+ KC_SPC,KC_BSPC,KC_END,
+ // right hand
+ KC_RGHT, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
+ TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSLS,
+ KC_H, KC_J, KC_K, KC_L, LT(MDIA, KC_SCLN),GUI_T(KC_QUOT),
+ MEH_T(KC_NO),KC_N, KC_M, KC_COMM,KC_DOT, CTL_T(KC_SLSH), KC_RSFT,
+ KC_UP, KC_DOWN,KC_LBRC,KC_RBRC, TT(SYMB),
+ KC_LALT, CTL_T(KC_ESC),
+ KC_PGUP,
+ KC_PGDN,KC_TAB, KC_ENT
+ ),
+/* Keymap 1: Symbol Layer
+ *
+ * ,---------------------------------------------------. ,--------------------------------------------------.
+ * |Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
+ * |---------+------+------+------+------+------+------| |------+------+------+------+------+------+--------|
+ * | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
+ * |---------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
+ * |---------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
+ * `---------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | EPRM | | | | | | | . | 0 | = | |
+ * `-----------------------------------' `----------------------------------'
+ * ,-------------. ,-------------.
+ * |Animat| LYR | |Toggle|Solid |
+ * ,------|------|------| |------+------+------.
+ * |Bright|Bright| | | |Hue- |Hue+ |
+ * |ness- |ness+ |------| |------| | |
+ * | | | | | | | |
+ * `--------------------' `--------------------'
+ */
+// SYMBOLS
+[SYMB] = LAYOUT_ergodox(
+ // left hand
+ VRSN, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
+ RESET, KC_EXLM,KC_AT, KC_LCBR,KC_RCBR,KC_PIPE,KC_TRNS,
+ KC_TRNS,KC_HASH,KC_DLR, KC_LPRN,KC_RPRN,KC_GRV,
+ EPRM,KC_PERC,KC_CIRC,KC_LBRC,KC_RBRC,KC_TILD,KC_TRNS,
+ KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+ RGB_MOD,RGB_LYR,
+ KC_TRNS,
+ RGB_VAD,RGB_VAI,KC_TRNS,
+ // right hand
+ KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
+ KC_TRNS, KC_UP, KC_7, KC_8, KC_9, KC_ASTR, KC_F12,
+ KC_DOWN, KC_4, KC_5, KC_6, KC_PLUS, KC_TRNS,
+ KC_TRNS, KC_AMPR, KC_1, KC_2, KC_3, KC_BSLS, KC_TRNS,
+ KC_TRNS,KC_DOT, KC_0, KC_EQL, KC_TRNS,
+ RGB_TOG, RGB_SLD,
+ KC_TRNS,
+ KC_TRNS, RGB_HUD, RGB_HUI
+),
+/* Keymap 2: Media and mouse keys
+ *
+ * ,--------------------------------------------------. ,--------------------------------------------------.
+ * | | | | | | | | | | | | | | | |
+ * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
+ * | | | | MsUp | | | | | | | | | | | |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
+ * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
+ * | | | | | | | | | | | | Prev | Next | | |
+ * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
+ * | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
+ * `----------------------------------' `----------------------------------'
+ * ,-------------. ,-------------.
+ * | | | | | |
+ * ,------|------|------| |------+------+------.
+ * | | | | | | |Brwser|
+ * | | |------| |------| |Back |
+ * | | | | | | | |
+ * `--------------------' `--------------------'
+ */
+// MEDIA AND MOUSE
+[MDIA] = LAYOUT_ergodox(
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS,
+ // right hand
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
+ KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
+ KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
+ KC_TRNS, KC_TRNS,
+ KC_TRNS,
+ KC_TRNS, KC_TRNS, KC_WBAK
+),
+};
+
+void eeconfig_init_user(void) {
+ rgblight_enable();
+ rgblight_sethsv_cyan();
+ rgblight_mode(1);
+ user_config.rgb_layer_change = true;
+ eeconfig_update_user(user_config.raw);
+}
+
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ // dynamically generate these.
+ case EPRM:
+ if (record->event.pressed) {
+ eeconfig_init();
+ }
+ return false;
+ break;
+ case VRSN:
+ if (record->event.pressed) {
+ SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
+ }
+ return false;
+ break;
+ case RGB_SLD:
+ if (record->event.pressed) {
+ #ifdef RGBLIGHT_ENABLE
+ rgblight_mode(1);
+ #endif
+ }
+ return false;
+ break;
+ case RGB_LYR: // This allows me to use underglow as layer indication, or as normal
+ if (record->event.pressed) {
+ user_config.rgb_layer_change ^= 1; // Toggles the status
+ eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM
+ if (user_config.rgb_layer_change) { // if layer state indication is enabled,
+ layer_state_set(layer_state); // then immediately update the layer color
+ }
+ }
+ return false; break;
+ case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference)
+ if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
+ if (user_config.rgb_layer_change) { // only if this is enabled
+ user_config.rgb_layer_change = false; // disable it, and
+ eeconfig_update_user(user_config.raw); // write the setings to EEPROM
+ }
+ }
+ return true; break;
+ }
+ return true;
+}
+
+void matrix_init_user(void) {
+ // Call the keymap level matrix init.
+
+ // Read the user config from EEPROM
+ user_config.raw = eeconfig_read_user();
+
+ // Set default layer, if enabled
+ if (user_config.rgb_layer_change) {
+ rgblight_enable_noeeprom();
+ rgblight_sethsv_noeeprom_cyan();
+ rgblight_mode_noeeprom(1);
+ }
+}
+
+// Runs constantly in the background, in a loop.
+void matrix_scan_user(void) {
+
+};
+
+uint32_t layer_state_set_user(uint32_t state) {
+ ergodox_board_led_off();
+ ergodox_right_led_1_off();
+ ergodox_right_led_2_off();
+ ergodox_right_led_3_off();
+ switch (biton32(state)) {
+ case SYMB:
+ ergodox_right_led_1_on();
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); }
+ break;
+ case MDIA:
+ ergodox_right_led_2_on();
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); }
+ break;
+ case 3:
+ ergodox_right_led_3_on();
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_blue(); rgblight_mode_noeeprom(1); }
+ break;
+ case 4:
+ ergodox_right_led_1_on();
+ ergodox_right_led_2_on();
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_orange(); rgblight_mode_noeeprom(1); }
+ break;
+ case 5:
+ ergodox_right_led_1_on();
+ ergodox_right_led_3_on();
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_yellow(); rgblight_mode_noeeprom(1); }
+ break;
+ case 6:
+ ergodox_right_led_2_on();
+ ergodox_right_led_3_on();
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_pink(); rgblight_mode_noeeprom(1); }
+ break;
+ case 7:
+ ergodox_right_led_1_on();
+ ergodox_right_led_2_on();
+ ergodox_right_led_3_on();
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); }
+ break;
+ default: // for any other layers, or the default layer
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); }
+ break;
+ }
+ return state;
+}
+
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 84ccbdeab..eed59f811 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -945,6 +945,9 @@ void tap_random_base64(void) {
}
void matrix_init_quantum() {
+ if (!eeconfig_is_enabled() && !eeconfig_is_disabled()) {
+ eeconfig_init();
+ }
#ifdef BACKLIGHT_ENABLE
backlight_init_ports();
#endif
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 35de574a9..0fec410a9 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -8,32 +8,54 @@
#include "eeprom_stm32.h"
#endif
-/** \brief eeconfig initialization
+extern uint32_t default_layer_state;
+/** \brief eeconfig enable
*
* FIXME: needs doc
*/
-void eeconfig_init(void)
-{
+__attribute__ ((weak))
+void eeconfig_init_user(void) {
+ // Reset user EEPROM value to blank, rather than to a set value
+ eeconfig_update_user(0);
+}
+
+__attribute__ ((weak))
+void eeconfig_init_kb(void) {
+ // Reset Keyboard EEPROM value to blank, rather than to a set value
+ eeconfig_update_kb(0);
+
+ eeconfig_init_user();
+}
+
+
+/*
+ * FIXME: needs doc
+ */
+void eeconfig_init_quantum(void) {
#ifdef STM32F303xC
EEPROM_format();
#endif
- eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
- eeprom_update_byte(EECONFIG_DEBUG, 0);
- eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
- eeprom_update_byte(EECONFIG_KEYMAP, 0);
- eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
-#ifdef BACKLIGHT_ENABLE
- eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
-#endif
-#ifdef AUDIO_ENABLE
- eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
-#endif
-#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
- eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
-#endif
-#ifdef STENO_ENABLE
- eeprom_update_byte(EECONFIG_STENOMODE, 0);
-#endif
+ eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
+ eeprom_update_byte(EECONFIG_DEBUG, 0);
+ eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
+ default_layer_state = 0;
+ eeprom_update_byte(EECONFIG_KEYMAP, 0);
+ eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
+ eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
+ eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
+ eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
+ eeprom_update_byte(EECONFIG_STENOMODE, 0);
+
+ eeconfig_init_kb();
+}
+
+/** \brief eeconfig initialization
+ *
+ * FIXME: needs doc
+ */
+void eeconfig_init(void) {
+
+ eeconfig_init_quantum();
}
/** \brief eeconfig enable
@@ -54,7 +76,7 @@ void eeconfig_disable(void)
#ifdef STM32F303xC
EEPROM_format();
#endif
- eeprom_update_word(EECONFIG_MAGIC, 0xFFFF);
+ eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
}
/** \brief eeconfig is enabled
@@ -66,6 +88,15 @@ bool eeconfig_is_enabled(void)
return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
}
+/** \brief eeconfig is disabled
+ *
+ * FIXME: needs doc
+ */
+bool eeconfig_is_disabled(void)
+{
+ return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
+}
+
/** \brief eeconfig read debug
*
* FIXME: needs doc
@@ -99,7 +130,6 @@ uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMA
*/
void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); }
-#ifdef BACKLIGHT_ENABLE
/** \brief eeconfig read backlight
*
* FIXME: needs doc
@@ -110,9 +140,8 @@ uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BA
* FIXME: needs doc
*/
void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); }
-#endif
-#ifdef AUDIO_ENABLE
+
/** \brief eeconfig read audio
*
* FIXME: needs doc
@@ -123,4 +152,28 @@ uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO)
* FIXME: needs doc
*/
void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); }
-#endif
+
+
+/** \brief eeconfig read kb
+ *
+ * FIXME: needs doc
+ */
+uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); }
+/** \brief eeconfig update kb
+ *
+ * FIXME: needs doc
+ */
+
+void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); }
+/** \brief eeconfig read user
+ *
+ * FIXME: needs doc
+ */
+uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); }
+/** \brief eeconfig update user
+ *
+ * FIXME: needs doc
+ */
+void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); }
+
+
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index fa498df48..a45cb8b12 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -23,36 +23,41 @@ along with this program. If not, see .
#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
+#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
/* eeprom parameteter address */
#if !defined(STM32F303xC)
#define EECONFIG_MAGIC (uint16_t *)0
-#define EECONFIG_DEBUG (uint8_t *)2
-#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
-#define EECONFIG_KEYMAP (uint8_t *)4
-#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
-#define EECONFIG_BACKLIGHT (uint8_t *)6
-#define EECONFIG_AUDIO (uint8_t *)7
+#define EECONFIG_DEBUG (uint8_t *)2
+#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
+#define EECONFIG_KEYMAP (uint8_t *)4
+#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
+#define EECONFIG_BACKLIGHT (uint8_t *)6
+#define EECONFIG_AUDIO (uint8_t *)7
#define EECONFIG_RGBLIGHT (uint32_t *)8
#define EECONFIG_UNICODEMODE (uint8_t *)12
#define EECONFIG_STENOMODE (uint8_t *)13
// EEHANDS for two handed boards
-#define EECONFIG_HANDEDNESS (uint8_t *)14
+#define EECONFIG_HANDEDNESS (uint8_t *)14
+#define EECONFIG_KEYBOARD (uint32_t *)15
+#define EECONFIG_USER (uint32_t *)19
#else
/* STM32F3 uses 16byte block. Reconfigure memory map */
#define EECONFIG_MAGIC (uint16_t *)0
-#define EECONFIG_DEBUG (uint8_t *)1
-#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
-#define EECONFIG_KEYMAP (uint8_t *)3
-#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
-#define EECONFIG_BACKLIGHT (uint8_t *)5
-#define EECONFIG_AUDIO (uint8_t *)6
+#define EECONFIG_DEBUG (uint8_t *)1
+#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
+#define EECONFIG_KEYMAP (uint8_t *)3
+#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
+#define EECONFIG_BACKLIGHT (uint8_t *)5
+#define EECONFIG_AUDIO (uint8_t *)6
#define EECONFIG_RGBLIGHT (uint32_t *)7
-#define EECONFIG_UNICODEMODE (uint8_t *)9
+#define EECONFIG_UNICODEMODE (uint8_t *)9
#define EECONFIG_STENOMODE (uint8_t *)10
// EEHANDS for two handed boards
-#define EECONFIG_HANDEDNESS (uint8_t *)11
+#define EECONFIG_HANDEDNESS (uint8_t *)11
+#define EECONFIG_KEYBOARD (uint32_t *)12
+#define EECONFIG_USER (uint32_t *)14
#endif
/* debug bit */
@@ -73,8 +78,12 @@ along with this program. If not, see .
bool eeconfig_is_enabled(void);
+bool eeconfig_is_disabled(void);
void eeconfig_init(void);
+void eeconfig_init_quantum(void);
+void eeconfig_init_kb(void);
+void eeconfig_init_user(void);
void eeconfig_enable(void);
@@ -99,4 +108,9 @@ uint8_t eeconfig_read_audio(void);
void eeconfig_update_audio(uint8_t val);
#endif
+uint32_t eeconfig_read_kb(void);
+void eeconfig_update_kb(uint32_t val);
+uint32_t eeconfig_read_user(void);
+void eeconfig_update_user(uint32_t val);
+
#endif
--
cgit v1.2.3-70-g09d2
From 26f4e7031a643ce2760ae7b6df3bd2c79710451a Mon Sep 17 00:00:00 2001
From: Drashna Jaelre
Date: Mon, 1 Oct 2018 17:53:47 -0700
Subject: Add tap_code function (#3784)
* Add tap_code
* formatting
* Doc clarification
* Rename variable to make more consistent
---
docs/feature_macros.md | 4 ++++
tmk_core/common/action.h | 1 +
2 files changed, 5 insertions(+)
(limited to 'tmk_core/common')
diff --git a/docs/feature_macros.md b/docs/feature_macros.md
index 673153081..ba5d91882 100644
--- a/docs/feature_macros.md
+++ b/docs/feature_macros.md
@@ -228,6 +228,10 @@ This sends the `` keydown event to the computer. Some examples would be `KC_
Parallel to `register_code` function, this sends the `` keyup event to the computer. If you don't use this, the key will be held down until it's sent.
+### `tap_code();`
+
+This will send `register_code()` and then `unregister_code()`. This is useful if you want to send both the press and release events ("tap" the key, rather than hold it).
+
### `clear_keyboard();`
This will clear all mods and keys currently pressed.
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 0322c73ed..833febe9c 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -88,6 +88,7 @@ void process_record(keyrecord_t *record);
void process_action(keyrecord_t *record, action_t action);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
+inline void tap_code(uint8_t code) { register_code(code); unregister_code(code); }
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
--
cgit v1.2.3-70-g09d2
From dad579c8f81bdde08e598f9d99249893d5d779a8 Mon Sep 17 00:00:00 2001
From: Drashna Jaelre
Date: Wed, 3 Oct 2018 22:33:06 -0700
Subject: Add mousekey_send to (un)register_code
---
tmk_core/common/action.c | 2 ++
1 file changed, 2 insertions(+)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 76d02bc9d..8bdcd54e3 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -777,6 +777,7 @@ void register_code(uint8_t code)
#ifdef MOUSEKEY_ENABLE
else if IS_MOUSEKEY(code) {
mousekey_on(code);
+ mousekey_send();
}
#endif
}
@@ -841,6 +842,7 @@ void unregister_code(uint8_t code)
#ifdef MOUSEKEY_ENABLE
else if IS_MOUSEKEY(code) {
mousekey_off(code);
+ mousekey_send();
}
#endif
}
--
cgit v1.2.3-70-g09d2
From ab91e07753720f8114d6c427139a1436e6efa3ce Mon Sep 17 00:00:00 2001
From: patrickmt <40182064+patrickmt@users.noreply.github.com>
Date: Tue, 9 Oct 2018 15:14:13 -0400
Subject: Massdrop keyboards console device support for hid_listen
Added hid_listen USB device for arm_atsam USB protocol.
Debug printing is now done through the console device (CONSOLE_ENABLE = yes) rather than the virtser device, for viewing in hid_listen.
Function dpf(...) renamed to CDC_printf(...) and should now be called directly if intending to print to the virtual serial device.
---
tmk_core/common.mk | 1 +
tmk_core/common/arm_atsam/printf.c | 66 ++++++++++
tmk_core/common/arm_atsam/printf.h | 7 +-
tmk_core/protocol/arm_atsam/main_arm_atsam.c | 12 +-
tmk_core/protocol/arm_atsam/usb/conf_usb.h | 5 +
tmk_core/protocol/arm_atsam/usb/main_usb.c | 14 ++
tmk_core/protocol/arm_atsam/usb/udi_cdc.c | 4 +-
tmk_core/protocol/arm_atsam/usb/udi_cdc.h | 1 +
tmk_core/protocol/arm_atsam/usb/udi_device_conf.h | 88 +++++++++++--
tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c | 146 +++++++++++++++++++++
tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h | 11 ++
tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c | 6 +
tmk_core/protocol/arm_atsam/usb/usb_main.h | 6 +
13 files changed, 347 insertions(+), 20 deletions(-)
create mode 100644 tmk_core/common/arm_atsam/printf.c
(limited to 'tmk_core/common')
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 319d196ae..4a0f7dcf9 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -43,6 +43,7 @@ endif
endif
ifeq ($(PLATFORM),ARM_ATSAM)
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
endif
diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c
new file mode 100644
index 000000000..d49d234de
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.c
@@ -0,0 +1,66 @@
+/*
+Copyright 2018 Massdrop Inc.
+
+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 .
+*/
+
+#ifdef CONSOLE_PRINT
+
+#include "samd51j18a.h"
+#include "arm_atsam_protocol.h"
+#include "printf.h"
+#include
+#include
+
+void console_printf(char *fmt, ...) {
+ while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
+
+ static char console_printbuf[CONSOLE_PRINTBUF_SIZE]; //Print and send buffer
+ va_list va;
+ int result;
+
+ va_start(va, fmt);
+ result = vsnprintf(console_printbuf, CONSOLE_PRINTBUF_SIZE, fmt, va);
+ va_end(va);
+
+ uint32_t irqflags;
+ char *pconbuf = console_printbuf; //Pointer to start send from
+ int send_out = CONSOLE_EPSIZE; //Bytes to send per transfer
+
+ while (result > 0) { //While not error and bytes remain
+ while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
+
+ irqflags = __get_PRIMASK();
+ __disable_irq();
+ __DMB();
+
+ if (result < CONSOLE_EPSIZE) { //If remaining bytes are less than console epsize
+ memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); //Clear the buffer
+ send_out = result; //Send remaining size
+ }
+
+ memcpy(udi_hid_con_report, pconbuf, send_out); //Copy data into the send buffer
+
+ udi_hid_con_b_report_valid = 1; //Set report valid
+ udi_hid_con_send_report(); //Send report
+
+ __DMB();
+ __set_PRIMASK(irqflags);
+
+ result -= send_out; //Decrement result by bytes sent
+ pconbuf += send_out; //Increment buffer point by bytes sent
+ }
+}
+
+#endif //CONSOLE_PRINT
diff --git a/tmk_core/common/arm_atsam/printf.h b/tmk_core/common/arm_atsam/printf.h
index 3206b40bd..1f1c2280b 100644
--- a/tmk_core/common/arm_atsam/printf.h
+++ b/tmk_core/common/arm_atsam/printf.h
@@ -1,8 +1,11 @@
#ifndef _PRINTF_H_
#define _PRINTF_H_
-int dpf(const char *_Format, ...);
-#define __xprintf dpf
+#define CONSOLE_PRINTBUF_SIZE 512
+
+void console_printf(char *fmt, ...);
+
+#define __xprintf console_printf
#endif //_PRINTF_H_
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index 676dac4ea..54d056a14 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -276,9 +276,9 @@ int main(void)
host_set_driver(&arm_atsam_driver);
-#ifdef VIRTSER_ENABLE
+#ifdef CONSOLE_ENABLE
uint64_t next_print = 0;
-#endif //VIRTSER_ENABLE
+#endif //CONSOLE_ENABLE
v_5v_avg = adc_get(ADC_5V);
@@ -290,15 +290,17 @@ int main(void)
main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals
-#ifdef VIRTSER_ENABLE
+#ifdef CONSOLE_ENABLE
if (CLK_get_ms() > next_print)
{
next_print = CLK_get_ms() + 250;
- dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n",v_5v,v_5v_avg,v_5v_avg-V5_LOW,v_5v_avg-V5_HIGH,gcr_actual,gcr_desired);
+ //Add any debug information here that you want to see very often
+ //dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
}
-#endif //VIRTSER_ENABLE
+#endif //CONSOLE_ENABLE
}
+
return 1;
}
diff --git a/tmk_core/protocol/arm_atsam/usb/conf_usb.h b/tmk_core/protocol/arm_atsam/usb/conf_usb.h
index 8f0f47268..c91caffe0 100644
--- a/tmk_core/protocol/arm_atsam/usb/conf_usb.h
+++ b/tmk_core/protocol/arm_atsam/usb/conf_usb.h
@@ -134,6 +134,11 @@
#define UDI_HID_EXK_DISABLE_EXT() main_exk_disable()
#endif
+#ifdef CON
+#define UDI_HID_CON_ENABLE_EXT() main_con_enable()
+#define UDI_HID_CON_DISABLE_EXT() main_con_disable()
+#endif
+
#ifdef MOU
#define UDI_HID_MOU_ENABLE_EXT() main_mou_enable()
#define UDI_HID_MOU_DISABLE_EXT() main_mou_disable()
diff --git a/tmk_core/protocol/arm_atsam/usb/main_usb.c b/tmk_core/protocol/arm_atsam/usb/main_usb.c
index e943cbcdc..0f676ab63 100644
--- a/tmk_core/protocol/arm_atsam/usb/main_usb.c
+++ b/tmk_core/protocol/arm_atsam/usb/main_usb.c
@@ -88,6 +88,20 @@ void main_exk_disable(void)
}
#endif
+#ifdef CON
+volatile bool main_b_con_enable = false;
+bool main_con_enable(void)
+{
+ main_b_con_enable = true;
+ return true;
+}
+
+void main_con_disable(void)
+{
+ main_b_con_enable = false;
+}
+#endif
+
#ifdef MOU
volatile bool main_b_mou_enable = false;
bool main_mou_enable(void)
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c b/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
index 15f0f760c..5f3c289e8 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_cdc.c
@@ -1260,7 +1260,7 @@ uint32_t CDC_print(char *printbuf)
char printbuf[CDC_PRINTBUF_SIZE];
-int dpf(const char *_Format, ...)
+int CDC_printf(const char *_Format, ...)
{
va_list va; //Variable argument list variable
int result;
@@ -1356,7 +1356,7 @@ uint32_t CDC_print(char *printbuf)
return 0;
}
-int dpf(const char *_Format, ...)
+int CDC_printf(const char *_Format, ...)
{
return 0;
}
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_cdc.h b/tmk_core/protocol/arm_atsam/usb/udi_cdc.h
index e134cf236..86077ce53 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_cdc.h
+++ b/tmk_core/protocol/arm_atsam/usb/udi_cdc.h
@@ -365,6 +365,7 @@ extern inbuf_t inbuf;
#endif //CDC
uint32_t CDC_print(char *printbuf);
+int CDC_printf(const char *_Format, ...);
uint32_t CDC_input(void);
void CDC_init(void);
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h b/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h
index c78726234..1e82b9ecc 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h
+++ b/tmk_core/protocol/arm_atsam/usb/udi_device_conf.h
@@ -44,10 +44,10 @@ along with this program. If not, see .
#define RAW
#endif
-//#define CONSOLE_ENABLE //deferred implementation
-//#ifdef CONSOLE_ENABLE
-//#define CON
-//#endif
+//#define CONSOLE_ENABLE //rules.mk
+#ifdef CONSOLE_ENABLE
+#define CON
+#endif
//#define NKRO_ENABLE //rules.mk
#ifdef NKRO_ENABLE
@@ -110,8 +110,9 @@ along with this program. If not, see .
#endif
#ifdef CON
-#define CONSOLE_INTERFACE NEXT_INTERFACE_4
-#define NEXT_INTERFACE_5 (CONSOLE_INTERFACE + 1)
+#define CON_INTERFACE NEXT_INTERFACE_4
+#define NEXT_INTERFACE_5 (CON_INTERFACE + 1)
+#define UDI_HID_CON_IFACE_NUMBER CON_INTERFACE
#else
#define NEXT_INTERFACE_5 NEXT_INTERFACE_4
#endif
@@ -211,11 +212,16 @@ along with this program. If not, see .
#endif
#ifdef CON
-#define CONSOLE_IN_EPNUM NEXT_IN_EPNUM_4
-#define NEXT_IN_EPNUM_5 (CONSOLE_IN_EPNUM + 1)
-#define CONSOLE_OUT_EPNUM NEXT_OUT_EPNUM_1
-#define NEXT_OUT_EPNUM_2 (CONSOLE_OUT_EPNUM + 1)
-#define CONSOLE_POLLING_INTERVAL 1
+#define CON_IN_EPNUM NEXT_IN_EPNUM_4
+#define UDI_HID_CON_EP_IN CON_IN_EPNUM
+#define NEXT_IN_EPNUM_5 (CON_IN_EPNUM + 1)
+#define CON_OUT_EPNUM NEXT_OUT_EPNUM_1
+#define UDI_HID_CON_EP_OUT CON_OUT_EPNUM
+#define NEXT_OUT_EPNUM_2 (CON_OUT_EPNUM + 1)
+#define CON_POLLING_INTERVAL 1
+#ifndef UDI_HID_CON_STRING_ID
+#define UDI_HID_CON_STRING_ID 0
+#endif
#else
#define NEXT_IN_EPNUM_5 NEXT_IN_EPNUM_4
#define NEXT_OUT_EPNUM_2 NEXT_OUT_EPNUM_1
@@ -558,6 +564,66 @@ COMPILER_PACK_RESET()
#endif //RAW
+// **********************************************************************
+// CON Descriptor structure and content
+// **********************************************************************
+#ifdef CON
+
+COMPILER_PACK_SET(1)
+
+typedef struct {
+ usb_iface_desc_t iface;
+ usb_hid_descriptor_t hid;
+ usb_ep_desc_t ep_out;
+ usb_ep_desc_t ep_in;
+} udi_hid_con_desc_t;
+
+typedef struct {
+ uint8_t array[34];
+} udi_hid_con_report_desc_t;
+
+#define UDI_HID_CON_DESC {\
+ .iface.bLength = sizeof(usb_iface_desc_t),\
+ .iface.bDescriptorType = USB_DT_INTERFACE,\
+ .iface.bInterfaceNumber = UDI_HID_CON_IFACE_NUMBER,\
+ .iface.bAlternateSetting = 0,\
+ .iface.bNumEndpoints = 2,\
+ .iface.bInterfaceClass = HID_CLASS,\
+ .iface.bInterfaceSubClass = HID_SUB_CLASS_NOBOOT,\
+ .iface.bInterfaceProtocol = HID_SUB_CLASS_NOBOOT,\
+ .iface.iInterface = UDI_HID_CON_STRING_ID,\
+ .hid.bLength = sizeof(usb_hid_descriptor_t),\
+ .hid.bDescriptorType = USB_DT_HID,\
+ .hid.bcdHID = LE16(USB_HID_BDC_V1_11),\
+ .hid.bCountryCode = USB_HID_NO_COUNTRY_CODE,\
+ .hid.bNumDescriptors = USB_HID_NUM_DESC,\
+ .hid.bRDescriptorType = USB_DT_HID_REPORT,\
+ .hid.wDescriptorLength = LE16(sizeof(udi_hid_con_report_desc_t)),\
+ .ep_out.bLength = sizeof(usb_ep_desc_t),\
+ .ep_out.bDescriptorType = USB_DT_ENDPOINT,\
+ .ep_out.bEndpointAddress = UDI_HID_CON_EP_OUT | USB_EP_DIR_OUT,\
+ .ep_out.bmAttributes = USB_EP_TYPE_INTERRUPT,\
+ .ep_out.wMaxPacketSize = LE16(CONSOLE_EPSIZE),\
+ .ep_out.bInterval = CON_POLLING_INTERVAL,\
+ .ep_in.bLength = sizeof(usb_ep_desc_t),\
+ .ep_in.bDescriptorType = USB_DT_ENDPOINT,\
+ .ep_in.bEndpointAddress = UDI_HID_CON_EP_IN | USB_EP_DIR_IN,\
+ .ep_in.bmAttributes = USB_EP_TYPE_INTERRUPT,\
+ .ep_in.wMaxPacketSize = LE16(CONSOLE_EPSIZE),\
+ .ep_in.bInterval = CON_POLLING_INTERVAL,\
+}
+
+#define UDI_HID_CON_REPORT_SIZE CONSOLE_EPSIZE
+
+extern uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
+
+//report buffer
+extern uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
+
+COMPILER_PACK_RESET()
+
+#endif //CON
+
// **********************************************************************
// CDC Descriptor structure and content
// **********************************************************************
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
index 1a6f7905e..18f9784ae 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
@@ -843,3 +843,149 @@ static void udi_hid_raw_setreport_valid(void)
}
#endif //RAW
+
+//********************************************************************************************
+// CON
+//********************************************************************************************
+#ifdef CON
+
+bool udi_hid_con_enable(void);
+void udi_hid_con_disable(void);
+bool udi_hid_con_setup(void);
+uint8_t udi_hid_con_getsetting(void);
+
+UDC_DESC_STORAGE udi_api_t udi_api_hid_con = {
+ .enable = (bool(*)(void))udi_hid_con_enable,
+ .disable = (void (*)(void))udi_hid_con_disable,
+ .setup = (bool(*)(void))udi_hid_con_setup,
+ .getsetting = (uint8_t(*)(void))udi_hid_con_getsetting,
+ .sof_notify = NULL,
+};
+
+COMPILER_WORD_ALIGNED
+static uint8_t udi_hid_con_rate;
+
+COMPILER_WORD_ALIGNED
+static uint8_t udi_hid_con_protocol;
+
+COMPILER_WORD_ALIGNED
+uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
+
+bool udi_hid_con_b_report_valid;
+
+COMPILER_WORD_ALIGNED
+uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
+
+volatile bool udi_hid_con_b_report_trans_ongoing;
+
+COMPILER_WORD_ALIGNED
+static uint8_t udi_hid_con_report_trans[UDI_HID_CON_REPORT_SIZE];
+
+COMPILER_WORD_ALIGNED
+UDC_DESC_STORAGE udi_hid_con_report_desc_t udi_hid_con_report_desc = {
+ {
+ 0x06, 0x31, 0xFF, // Vendor Page (PJRC Teensy compatible)
+ 0x09, 0x74, // Vendor Usage (PJRC Teensy compatible)
+ 0xA1, 0x01, // Collection (Application)
+ 0x09, 0x75, // Usage (Vendor)
+ 0x15, 0x00, // Logical Minimum (0x00)
+ 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
+ 0x95, CONSOLE_EPSIZE, // Report Count
+ 0x75, 0x08, // Report Size (8)
+ 0x81, 0x02, // Input (Data)
+ 0x09, 0x76, // Usage (Vendor)
+ 0x15, 0x00, // Logical Minimum (0x00)
+ 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
+ 0x95, CONSOLE_EPSIZE, // Report Count
+ 0x75, 0x08, // Report Size (8)
+ 0x91, 0x02, // Output (Data)
+ 0xC0, // End Collection
+ }
+};
+
+static bool udi_hid_con_setreport(void);
+static void udi_hid_con_setreport_valid(void);
+
+static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
+
+bool udi_hid_con_enable(void)
+{
+ // Initialize internal values
+ udi_hid_con_rate = 0;
+ udi_hid_con_protocol = 0;
+ udi_hid_con_b_report_trans_ongoing = false;
+ memset(udi_hid_con_report, 0, UDI_HID_CON_REPORT_SIZE);
+ udi_hid_con_b_report_valid = false;
+ return UDI_HID_CON_ENABLE_EXT();
+}
+
+void udi_hid_con_disable(void)
+{
+ UDI_HID_CON_DISABLE_EXT();
+}
+
+bool udi_hid_con_setup(void)
+{
+ return udi_hid_setup(&udi_hid_con_rate,
+ &udi_hid_con_protocol,
+ (uint8_t *) &udi_hid_con_report_desc,
+ udi_hid_con_setreport);
+}
+
+uint8_t udi_hid_con_getsetting(void)
+{
+ return 0;
+}
+
+static bool udi_hid_con_setreport(void)
+{
+ if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
+ && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
+ && (UDI_HID_CON_REPORT_SIZE == udd_g_ctrlreq.req.wLength)) {
+ udd_g_ctrlreq.payload = udi_hid_con_report_set;
+ udd_g_ctrlreq.callback = udi_hid_con_setreport_valid;
+ udd_g_ctrlreq.payload_size = UDI_HID_CON_REPORT_SIZE;
+ return true;
+ }
+ return false;
+}
+
+bool udi_hid_con_send_report(void)
+{
+ if (!main_b_con_enable) {
+ return false;
+ }
+
+ if (udi_hid_con_b_report_trans_ongoing) {
+ return false;
+ }
+
+ memcpy(udi_hid_con_report_trans, udi_hid_con_report,UDI_HID_CON_REPORT_SIZE);
+ udi_hid_con_b_report_valid = false;
+ udi_hid_con_b_report_trans_ongoing =
+ udd_ep_run(UDI_HID_CON_EP_IN | USB_EP_DIR_IN,
+ false,
+ udi_hid_con_report_trans,
+ UDI_HID_CON_REPORT_SIZE,
+ udi_hid_con_report_sent);
+
+ return udi_hid_con_b_report_trans_ongoing;
+}
+
+static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
+{
+ UNUSED(status);
+ UNUSED(nb_sent);
+ UNUSED(ep);
+ udi_hid_con_b_report_trans_ongoing = false;
+ if (udi_hid_con_b_report_valid) {
+ udi_hid_con_send_report();
+ }
+}
+
+static void udi_hid_con_setreport_valid(void)
+{
+
+}
+
+#endif //CON
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h
index babfdb7a7..e442919a9 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.h
@@ -85,6 +85,17 @@ extern uint8_t udi_hid_exk_report_set;
bool udi_hid_exk_send_report(void);
#endif //EXK
+//********************************************************************************************
+// CON Console
+//********************************************************************************************
+#ifdef CON
+extern UDC_DESC_STORAGE udi_api_t udi_api_hid_con;
+extern bool udi_hid_con_b_report_valid;
+extern uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
+extern volatile bool udi_hid_con_b_report_trans_ongoing;
+bool udi_hid_con_send_report(void);
+#endif //CON
+
//********************************************************************************************
// MOU Mouse
//********************************************************************************************
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c
index 16bd4e514..2d6e35e25 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd_desc.c
@@ -134,6 +134,9 @@ UDC_DESC_STORAGE udc_desc_t udc_desc = {
#ifdef EXK
.hid_exk = UDI_HID_EXK_DESC,
#endif
+#ifdef CON
+ .hid_con = UDI_HID_CON_DESC,
+#endif
#ifdef NKRO
.hid_nkro = UDI_HID_NKRO_DESC,
#endif
@@ -155,6 +158,9 @@ UDC_DESC_STORAGE udi_api_t *udi_apis[USB_DEVICE_NB_INTERFACE] = {
#ifdef EXK
&udi_api_hid_exk,
#endif
+ #ifdef CON
+ &udi_api_hid_con,
+ #endif
#ifdef NKRO
&udi_api_hid_nkro,
#endif
diff --git a/tmk_core/protocol/arm_atsam/usb/usb_main.h b/tmk_core/protocol/arm_atsam/usb/usb_main.h
index b7adaa1a7..76ced474d 100644
--- a/tmk_core/protocol/arm_atsam/usb/usb_main.h
+++ b/tmk_core/protocol/arm_atsam/usb/usb_main.h
@@ -82,6 +82,12 @@ bool main_exk_enable(void);
void main_exk_disable(void);
#endif //EXK
+#ifdef CON
+extern volatile bool main_b_con_enable;
+bool main_con_enable(void);
+void main_con_disable(void);
+#endif //CON
+
#ifdef MOU
extern volatile bool main_b_mou_enable;
bool main_mou_enable(void);
--
cgit v1.2.3-70-g09d2
From f4094930a393ec3dc597e06e95cd3365e3f8cb97 Mon Sep 17 00:00:00 2001
From: Takuya Urakawa
Date: Fri, 19 Oct 2018 13:33:23 +0900
Subject: stm32f1xx EEPROM emulation (#3914)
* * Add stm32f1xx EEPROM emulation
* Fix eeprom update compare bug
Squashed commit of the following:
commit b8f248ae08cec0cd81ecbb8854d9b39221d4d573
Author: hsgw
Date: Sat Sep 15 19:13:48 2018 +0900
fix EEPROM_update wrong compare
commit d4ed4e6ea864e967a3e17f7edee4b0c3b4a25541
Author: hsgw
Date: Sat Sep 15 17:43:47 2018 +0900
eeprom fix initialization define
commit b61aa7c04d70c64df3416d63e5da08b73b6053af
Author: hsgw
Date: Sat Sep 15 16:33:40 2018 +0900
maybe working
* Fix FLASH_KEY defines
---
tmk_core/common.mk | 7 +++++++
tmk_core/common/chibios/eeprom_stm32.c | 8 ++++----
tmk_core/common/chibios/eeprom_stm32.h | 12 +++++++++---
tmk_core/common/chibios/flash_stm32.c | 24 ++++++++++++++++--------
tmk_core/common/eeconfig.c | 6 +++---
tmk_core/common/eeconfig.h | 2 +-
tmk_core/protocol/chibios/main.c | 4 ++--
7 files changed, 42 insertions(+), 21 deletions(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 4a0f7dcf9..33bcc97b2 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -34,6 +34,13 @@ ifeq ($(PLATFORM),CHIBIOS)
ifeq ($(MCU_SERIES), STM32F3xx)
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
+ TMK_COMMON_DEFS += -DEEPROM_EMU_STM32F303xC
+ TMK_COMMON_DEFS += -DSTM32_EEPROM_ENABLE
+ else ifeq ($(MCU_SERIES), STM32F1xx)
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
+ TMK_COMMON_DEFS += -DEEPROM_EMU_STM32F103xB
+ TMK_COMMON_DEFS += -DSTM32_EEPROM_ENABLE
else
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
endif
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
index 3c1945122..a86998550 100755
--- a/tmk_core/common/chibios/eeprom_stm32.c
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -10,7 +10,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
* https://github.com/leaflabs/libmaple
*
* Modifications for QMK and STM32F303 by Yiancar
@@ -274,7 +274,7 @@ uint16_t EE_VerifyPageFullWriteVariable(uint16_t Address, uint16_t Data)
// Check each active page address starting from begining
for (idx = pageBase + 4; idx < pageEnd; idx += 4)
- if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
+ if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
{ // contents are 0xFFFFFFFF
FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data
if (FlashStatus != FLASH_COMPLETE)
@@ -517,7 +517,7 @@ uint16_t EEPROM_read(uint16_t Address, uint16_t *Data)
// Get the valid Page end Address
pageEnd = pageBase + ((uint32_t)(PageSize - 2));
-
+
// Check each active page address starting from end
for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
if ((*(__IO uint16_t*)pageEnd) == Address) // Compare the read address with the virtual address
@@ -574,7 +574,7 @@ uint16_t EEPROM_update(uint16_t Address, uint16_t Data)
{
uint16_t temp;
EEPROM_read(Address, &temp);
- if (Address == Data)
+ if (temp == Data)
return EEPROM_SAME_VALUE;
else
return EEPROM_write(Address, Data);
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h
index 68aa14f6d..09229530c 100755
--- a/tmk_core/common/chibios/eeprom_stm32.h
+++ b/tmk_core/common/chibios/eeprom_stm32.h
@@ -10,7 +10,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
* https://github.com/leaflabs/libmaple
*
* Modifications for QMK and STM32F303 by Yiancar
@@ -27,8 +27,14 @@
#include "flash_stm32.h"
// HACK ALERT. This definition may not match your processor
-// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
-#define MCU_STM32F303CC
+// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
+#if defined(EEPROM_EMU_STM32F303xC)
+ #define MCU_STM32F303CC
+#elif defined(EEPROM_EMU_STM32F103xB)
+ #define MCU_STM32F103RB
+#else
+ #error "not implemented."
+#endif
#ifndef EEPROM_PAGE_SIZE
#if defined (MCU_STM32F103RB)
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c
index e7199ac7b..273593484 100755
--- a/tmk_core/common/chibios/flash_stm32.c
+++ b/tmk_core/common/chibios/flash_stm32.c
@@ -10,19 +10,27 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
* https://github.com/leaflabs/libmaple
*
* Modifications for QMK and STM32F303 by Yiancar
*/
-#define STM32F303xC
+#if defined(EEPROM_EMU_STM32F303xC)
+ #define STM32F303xC
+ #include "stm32f3xx.h"
+#elif defined(EEPROM_EMU_STM32F103xB)
+ #define STM32F103xB
+ #include "stm32f1xx.h"
+#else
+ #error "not implemented."
+#endif
-#include "stm32f3xx.h"
#include "flash_stm32.h"
-#define FLASH_KEY1 ((uint32_t)0x45670123)
-#define FLASH_KEY2 ((uint32_t)0xCDEF89AB)
+#if defined(EEPROM_EMU_STM32F103xB)
+ #define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
+#endif
/* Delay definition */
#define EraseTimeout ((uint32_t)0x00000FFF)
@@ -71,7 +79,7 @@ FLASH_Status FLASH_GetStatus(void)
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
-{
+{
FLASH_Status status;
/* Check for the Flash Status */
@@ -102,7 +110,7 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
ASSERT(IS_FLASH_ADDRESS(Page_Address));
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
-
+
if(status == FLASH_COMPLETE)
{
/* if the previous operation is completed, proceed to erase the page */
@@ -128,7 +136,7 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
* @param Address: specifies the address to be programmed.
* @param Data: specifies the data to be programmed.
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
- * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
+ * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 0fec410a9..d8bab7d2e 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -3,7 +3,7 @@
#include "eeprom.h"
#include "eeconfig.h"
-#ifdef STM32F303xC
+#ifdef STM32_EEPROM_ENABLE
#include "hal.h"
#include "eeprom_stm32.h"
#endif
@@ -32,7 +32,7 @@ void eeconfig_init_kb(void) {
* FIXME: needs doc
*/
void eeconfig_init_quantum(void) {
-#ifdef STM32F303xC
+#ifdef STM32_EEPROM_ENABLE
EEPROM_format();
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
@@ -73,7 +73,7 @@ void eeconfig_enable(void)
*/
void eeconfig_disable(void)
{
-#ifdef STM32F303xC
+#ifdef STM32_EEPROM_ENABLE
EEPROM_format();
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index a45cb8b12..8d4e1d4d0 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -26,7 +26,7 @@ along with this program. If not, see .
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
/* eeprom parameteter address */
-#if !defined(STM32F303xC)
+#if !defined(STM32_EEPROM_ENABLE)
#define EECONFIG_MAGIC (uint16_t *)0
#define EECONFIG_DEBUG (uint8_t *)2
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index dcc6d9d07..6cceccd23 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -44,7 +44,7 @@
#ifdef MIDI_ENABLE
#include "qmk_midi.h"
#endif
-#ifdef STM32F303xC
+#ifdef STM32_EEPROM_ENABLE
#include "eeprom_stm32.h"
#endif
#include "suspend.h"
@@ -112,7 +112,7 @@ int main(void) {
halInit();
chSysInit();
-#ifdef STM32F303xC
+#ifdef STM32_EEPROM_ENABLE
EEPROM_init();
#endif
--
cgit v1.2.3-70-g09d2
From 8e3330bbf6f8c4faf39a3df20fa3ab62910c8b19 Mon Sep 17 00:00:00 2001
From: a-chol
Date: Sun, 21 Oct 2018 18:20:24 +0200
Subject: Keyboard: bminiex : Working backlight (#4171)
* bminiex : Working backlight
* bminiex keyboard with fixes
* bminiex keyboard more fixes
---
keyboards/bminiex/backlight.c | 211 +++++++++++++++
keyboards/bminiex/backlight_custom.h | 13 +
keyboards/bminiex/bminiex.c | 97 +++++++
keyboards/bminiex/bminiex.h | 58 +++++
keyboards/bminiex/breathing_custom.h | 140 ++++++++++
keyboards/bminiex/config.h | 41 +++
keyboards/bminiex/i2c.c | 106 ++++++++
keyboards/bminiex/i2c.h | 25 ++
keyboards/bminiex/keymaps/default/keymap.c | 29 +++
keyboards/bminiex/matrix.c | 122 +++++++++
keyboards/bminiex/readme.md | 14 +
keyboards/bminiex/rules.mk | 56 ++++
keyboards/bminiex/usbconfig.h | 396 +++++++++++++++++++++++++++++
tmk_core/common/backlight.h | 5 +-
14 files changed, 1309 insertions(+), 4 deletions(-)
create mode 100644 keyboards/bminiex/backlight.c
create mode 100644 keyboards/bminiex/backlight_custom.h
create mode 100644 keyboards/bminiex/bminiex.c
create mode 100644 keyboards/bminiex/bminiex.h
create mode 100644 keyboards/bminiex/breathing_custom.h
create mode 100644 keyboards/bminiex/config.h
create mode 100644 keyboards/bminiex/i2c.c
create mode 100644 keyboards/bminiex/i2c.h
create mode 100644 keyboards/bminiex/keymaps/default/keymap.c
create mode 100644 keyboards/bminiex/matrix.c
create mode 100644 keyboards/bminiex/readme.md
create mode 100644 keyboards/bminiex/rules.mk
create mode 100644 keyboards/bminiex/usbconfig.h
(limited to 'tmk_core/common')
diff --git a/keyboards/bminiex/backlight.c b/keyboards/bminiex/backlight.c
new file mode 100644
index 000000000..94e8126d8
--- /dev/null
+++ b/keyboards/bminiex/backlight.c
@@ -0,0 +1,211 @@
+/**
+ * Backlighting code for PS2AVRGB boards (ATMEGA32A)
+ * Kenneth A. (github.com/krusli | krusli.me)
+ */
+
+#include "backlight.h"
+#include "quantum.h"
+
+#include
+#include
+
+#include "backlight_custom.h"
+#include "breathing_custom.h"
+
+// DEBUG
+#include
+#include
+
+// Port D: digital pins of the AVR chipset
+#define NUMLOCK_PORT (1 << 0) // D0
+#define CAPSLOCK_PORT (1 << 1) // D1
+#define BACKLIGHT_PORT (1 << 4) // D4
+#define SCROLLLOCK_PORT (1 << 6) // D6
+
+#define TIMER_CLK_DIV64 0x03 ///< Timer clocked at F_CPU/64
+#define TIMER1PRESCALE TIMER_CLK_DIV64 ///< timer 1 prescaler default
+
+#define TIMER_PRESCALE_MASK 0x07 ///< Timer Prescaler Bit-Mask
+
+#define PWM_MAX 0xFF
+#define TIMER_TOP 255 // 8 bit PWM
+
+extern backlight_config_t backlight_config;
+
+/**
+ * References
+ * Port Registers: https://www.arduino.cc/en/Reference/PortManipulation
+ * TCCR1A: https://electronics.stackexchange.com/questions/92350/what-is-the-difference-between-tccr1a-and-tccr1b
+ * Timers: http://www.avrbeginners.net/architecture/timers/timers.html
+ * 16-bit timer setup: http://sculland.com/ATmega168/Interrupts-And-Timers/16-Bit-Timer-Setup/
+ * PS2AVRGB firmware: https://github.com/showjean/ps2avrU/tree/master/firmware
+ */
+
+// @Override
+// turn LEDs on and off depending on USB caps/num/scroll lock states.
+__attribute__ ((weak))
+void led_set_user(uint8_t usb_led) {
+ if (usb_led & (1 << USB_LED_NUM_LOCK)) {
+ // turn on
+ DDRD |= NUMLOCK_PORT;
+ PORTD |= NUMLOCK_PORT;
+ } else {
+ // turn off
+ DDRD &= ~NUMLOCK_PORT;
+ PORTD &= ~NUMLOCK_PORT;
+ }
+
+ if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
+ DDRD |= CAPSLOCK_PORT;
+ PORTD |= CAPSLOCK_PORT;
+ } else {
+ DDRD &= ~CAPSLOCK_PORT;
+ PORTD &= ~CAPSLOCK_PORT;
+ }
+
+ if (usb_led & (1 << USB_LED_SCROLL_LOCK)) {
+ DDRD |= SCROLLLOCK_PORT;
+ PORTD |= SCROLLLOCK_PORT;
+ } else {
+ DDRD &= ~SCROLLLOCK_PORT;
+ PORTD &= ~SCROLLLOCK_PORT;
+ }
+}
+
+#ifdef BACKLIGHT_ENABLE
+
+// sets up Timer 1 for 8-bit PWM
+void timer1PWMSetup(void) { // NOTE ONLY CALL THIS ONCE
+ // default 8 bit mode
+ TCCR1A &= ~(1 << 1); // cbi(TCCR1A,PWM11); <- set PWM11 bit to HIGH
+ TCCR1A |= (1 << 0); // sbi(TCCR1A,PWM10); <- set PWM10 bit to LOW
+
+ // clear output compare value A
+ // outb(OCR1AH, 0);
+ // outb(OCR1AL, 0);
+
+ // clear output comparator registers for B
+ OCR1BH = 0; // outb(OCR1BH, 0);
+ OCR1BL = 0; // outb(OCR1BL, 0);
+}
+
+bool is_init = false;
+void timer1Init(void) {
+ // timer1SetPrescaler(TIMER1PRESCALE)
+ // set to DIV/64
+ (TCCR1B) = ((TCCR1B) & ~TIMER_PRESCALE_MASK) | TIMER1PRESCALE;
+
+ // reset TCNT1
+ TCNT1H = 0; // outb(TCNT1H, 0);
+ TCNT1L = 0; // outb(TCNT1L, 0);
+
+ // TOIE1: Timer Overflow Interrupt Enable (Timer 1);
+ TIMSK |= _BV(TOIE1); // sbi(TIMSK, TOIE1);
+
+ is_init = true;
+}
+
+void timer1UnInit(void) {
+ // set prescaler back to NONE
+ (TCCR1B) = ((TCCR1B) & ~TIMER_PRESCALE_MASK) | 0x00; // TIMERRTC_CLK_STOP
+
+ // disable timer overflow interrupt
+ TIMSK &= ~_BV(TOIE1); // overflow bit?
+
+ setPWM(0);
+
+ is_init = false;
+}
+
+
+// handle TCNT1 overflow
+//! Interrupt handler for tcnt1 overflow interrupt
+ISR(TIMER1_OVF_vect, ISR_NOBLOCK)
+{
+ // sei();
+ // handle breathing here
+ #ifdef BACKLIGHT_BREATHING
+ if (is_breathing()) {
+ custom_breathing_handler();
+ }
+ #endif
+}
+
+// enable timer 1 PWM
+// timer1PWMBOn()
+void timer1PWMBEnable(void) {
+ // turn on channel B (OC1B) PWM output
+ // set OC1B as non-inverted PWM
+ TCCR1A |= _BV(COM1B1);
+ TCCR1A &= ~_BV(COM1B0);
+}
+
+// disable timer 1 PWM
+// timer1PWMBOff()
+void timer1PWMBDisable(void) {
+ TCCR1A &= ~_BV(COM1B1);
+ TCCR1A &= ~_BV(COM1B0);
+}
+
+void enableBacklight(void) {
+ DDRD |= BACKLIGHT_PORT; // set digital pin 4 as output
+ PORTD |= BACKLIGHT_PORT; // set digital pin 4 to high
+}
+
+void disableBacklight(void) {
+ // DDRD &= ~BACKLIGHT_PORT; // set digital pin 4 as input
+ PORTD &= ~BACKLIGHT_PORT; // set digital pin 4 to low
+}
+
+void startPWM(void) {
+ timer1Init();
+ timer1PWMBEnable();
+ enableBacklight();
+}
+
+void stopPWM(void) {
+ timer1UnInit();
+ disableBacklight();
+ timer1PWMBDisable();
+}
+
+void b_led_init_ports(void) {
+ /* turn backlight on/off depending on user preference */
+ #if BACKLIGHT_ON_STATE == 0
+ // DDRx register: sets the direction of Port D
+ // DDRD &= ~BACKLIGHT_PORT; // set digital pin 4 as input
+ PORTD &= ~BACKLIGHT_PORT; // set digital pin 4 to low
+ #else
+ DDRD |= BACKLIGHT_PORT; // set digital pin 4 as output
+ PORTD |= BACKLIGHT_PORT; // set digital pin 4 to high
+ #endif
+
+ timer1PWMSetup();
+ startPWM();
+
+ #ifdef BACKLIGHT_BREATHING
+ breathing_enable();
+ #endif
+}
+
+void b_led_set(uint8_t level) {
+ if (level > BACKLIGHT_LEVELS) {
+ level = BACKLIGHT_LEVELS;
+ }
+
+ setPWM((int)(TIMER_TOP * (float) level / BACKLIGHT_LEVELS));
+}
+
+// called every matrix scan
+void b_led_task(void) {
+ // do nothing for now
+}
+
+void setPWM(uint16_t xValue) {
+ if (xValue > TIMER_TOP) {
+ xValue = TIMER_TOP;
+ }
+ OCR1B = xValue; // timer1PWMBSet(xValue);
+}
+
+#endif // BACKLIGHT_ENABLE
diff --git a/keyboards/bminiex/backlight_custom.h b/keyboards/bminiex/backlight_custom.h
new file mode 100644
index 000000000..51365fe3b
--- /dev/null
+++ b/keyboards/bminiex/backlight_custom.h
@@ -0,0 +1,13 @@
+/**
+ * Backlighting code for PS2AVRGB boards (ATMEGA32A)
+ * Kenneth A. (github.com/krusli | krusli.me)
+ */
+
+#pragma once
+
+#include
+void b_led_init_ports(void);
+void b_led_set(uint8_t level);
+void b_led_task(void);
+void setPWM(uint16_t xValue);
+
diff --git a/keyboards/bminiex/bminiex.c b/keyboards/bminiex/bminiex.c
new file mode 100644
index 000000000..d9b05aba5
--- /dev/null
+++ b/keyboards/bminiex/bminiex.c
@@ -0,0 +1,97 @@
+/*
+Copyright 2017 Luiz Ribeiro
+
+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 .
+*/
+
+#include "bminiex.h"
+#include "rgblight.h"
+
+#include
+
+#include "action_layer.h"
+#include "i2c.h"
+#include "quantum.h"
+
+#include "backlight.h"
+#include "backlight_custom.h"
+
+// for keyboard subdirectory level init functions
+// @Override
+void matrix_init_kb(void) {
+ // call user level keymaps, if any
+ matrix_init_user();
+}
+
+#ifdef BACKLIGHT_ENABLE
+/// Overrides functions in `quantum.c`
+void backlight_init_ports(void) {
+ b_led_init_ports();
+}
+
+void backlight_task(void) {
+ b_led_task();
+}
+
+void backlight_set(uint8_t level) {
+ b_led_set(level);
+}
+#endif
+
+#ifdef RGBLIGHT_ENABLE
+extern rgblight_config_t rgblight_config;
+
+// custom RGB driver
+void rgblight_set(void) {
+ if (!rgblight_config.enable) {
+ for (uint8_t i=0; i
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#include "quantum.h"
+
+#define LAYOUT( \
+ K05, K25, K35, K45, K55, K06, KA6, KA7, K07, KB5, KC5, KD5, KE5, KD1, KE1, KE2, K65, K75, K85, K95, \
+ K04, K14, K24, K34, K44, K54, K16, KB6, KB7, K17, KA4, KB4, KC4, KE4, KD0, K64, K74, K84, K94, \
+ K03, K13, K23, K33, K43, K53, K26, KC6, KC7, K27, KA3, KB3, KC3, KD3, K67, K63, K73, K83, \
+ K02, K12, K22, K32, K42, K52, K36, KD6, KD7, K37, KA2, KB2, KC2, KD2, KE0, K62, K72, K82, K92, \
+ K01, K30, K11, K21, K31, K41, K51, K46, KE6, KE7, K47, KA1, KB1, K86, K77, K61, K71, K81, \
+ K00, K10, K20, K56, K57, KB0, KC0, K66, K76, K96, K60, K80, K90 \
+){ \
+ { K00, K10, K20, K30, KC_NO, KC_NO, K60, KC_NO, K80, K90, KC_NO, KB0, KC0, KD0, KE0 }, \
+ { K01, K11, K21, K31, K41, K51, K61, K71, K81, KC_NO, KA1, KB1, KC_NO, KD1, KE1 }, \
+ { K02, K12, K22, K32, K42, K52, K62, K72, K82, K92, KA2, KB2, KC2, KD2, KE2 }, \
+ { K03, K13, K23, K33, K43, K53, K63, K73, K83, KC_NO, KA3, KB3, KC3, KD3, KC_NO }, \
+ { K04, K14, K24, K34, K44, K54, K64, K74, K84, K94, KA4, KB4, KC4, KC_NO, KE4 }, \
+ { K05, KC_NO, K25, K35, K45, K55, K65, K75, K85, K95, KC_NO, KB5, KC5, KD5, KE5 }, \
+ { K06, K16, K26, K36, K46, K56, K66, K76, K86, K96, KA6, KB6, KC6, KD6, KE6 }, \
+ { K07, K17, K27, K37, K47, K57, K67, K77, KC_NO, KC_NO, KA7, KB7, KC7, KD7, KE7 } \
+}
+
+#define LAYOUT_kc( \
+ K05, K25, K35, K45, K55, K06, KA6, KA7, K07, KB5, KC5, KD5, KE5, KD1, KE1, KE2, K65, K75, K85, K95, \
+ K04, K14, K24, K34, K44, K54, K16, KB6, KB7, K17, KA4, KB4, KC4, KE4, KD0, K64, K74, K84, K94, \
+ K03, K13, K23, K33, K43, K53, K26, KC6, KC7, K27, KA3, KB3, KC3, KD3, K67, K63, K73, K83, \
+ K02, K12, K22, K32, K42, K52, K36, KD6, KD7, K37, KA2, KB2, KC2, KD2, KE0, K62, K72, K82, K92, \
+ K01, K30, K11, K21, K31, K41, K51, K46, KE6, KE7, K47, KA1, KB1, K86, K77, K61, K71, K81, \
+ K00, K10, K20, K56, K57, KB0, KC0, K66, K76, K96, K60, K80, K90 \
+) \
+{ \
+ { KC_##K00, KC_##K10, KC_##K20, KC_##K30, KC_NO, KC_NO, KC_##K60, KC_NO, KC_##K80, KC_##K90, KC_NO, KC_##KB0, KC_##KC0, KC_##KD0, KC_##KE0 }, \
+ { KC_##K01, KC_##K11, KC_##K21, KC_##K31, KC_##K41, KC_##K51, KC_##K61, KC_##K71, KC_##K81, KC_NO, KC_##KA1, KC_##KB1, KC_NO, KC_##KD1, KC_##KE1 }, \
+ { KC_##K02, KC_##K12, KC_##K22, KC_##K32, KC_##K42, KC_##K52, KC_##K62, KC_##K72, KC_##K82, KC_##K92, KC_##KA2, KC_##KB2, KC_##KC2, KC_##KD2, KC_##KE2 }, \
+ { KC_##K03, KC_##K13, KC_##K23, KC_##K33, KC_##K43, KC_##K53, KC_##K63, KC_##K73, KC_##K83, KC_NO, KC_##KA3, KC_##KB3, KC_##KC3, KC_##KD3, KC_NO }, \
+ { KC_##K04, KC_##K14, KC_##K24, KC_##K34, KC_##K44, KC_##K54, KC_##K64, KC_##K74, KC_##K84, KC_##K94, KC_##KA4, KC_##KB4, KC_##KC4, KC_NO, KC_##KE4 }, \
+ { KC_##K05, KC_NO, KC_##K25, KC_##K35, KC_##K45, KC_##K55, KC_##K65, KC_##K75, KC_##K85, KC_##K95, KC_NO, KC_##KB5, KC_##KC5, KC_##KD5, KC_##KE5 }, \
+ { KC_##K06, KC_##K16, KC_##K26, KC_##K36, KC_##K46, KC_##K56, KC_##K66, KC_##K76, KC_##K86, KC_##K96, KC_##KA6, KC_##KB6, KC_##KC6, KC_##KD6, KC_##KE6 }, \
+ { KC_##K07, KC_##K17, KC_##K27, KC_##K37, KC_##K47, KC_##K57, KC_##K67, KC_##K77, KC_NO, KC_NO, KC_##KA7, KC_##KB7, KC_##KC7, KC_##KD7, KC_##KE7 } \
+}
+
diff --git a/keyboards/bminiex/breathing_custom.h b/keyboards/bminiex/breathing_custom.h
new file mode 100644
index 000000000..71416b1b4
--- /dev/null
+++ b/keyboards/bminiex/breathing_custom.h
@@ -0,0 +1,140 @@
+/**
+ * Breathing effect code for PS2AVRGB boards (ATMEGA32A)
+ * Works in conjunction with `backlight.c`.
+ *
+ * Code adapted from `quantum.c` to register with the existing TIMER1 overflow
+ * handler in `backlight.c` instead of setting up its own timer.
+ * Kenneth A. (github.com/krusli | krusli.me)
+ */
+
+#ifdef BACKLIGHT_ENABLE
+#ifdef BACKLIGHT_BREATHING
+
+#include "backlight_custom.h"
+
+#ifndef BREATHING_PERIOD
+#define BREATHING_PERIOD 6
+#endif
+
+#define breathing_min() do {breathing_counter = 0;} while (0)
+#define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0)
+
+// TODO make this share code with quantum.c
+
+#define BREATHING_NO_HALT 0
+#define BREATHING_HALT_OFF 1
+#define BREATHING_HALT_ON 2
+#define BREATHING_STEPS 128
+
+static uint8_t breathing_period = BREATHING_PERIOD;
+static uint8_t breathing_halt = BREATHING_NO_HALT;
+static uint16_t breathing_counter = 0;
+
+static bool breathing = false;
+
+bool is_breathing(void) {
+ return breathing;
+}
+
+// See http://jared.geek.nz/2013/feb/linear-led-pwm
+static uint16_t cie_lightness(uint16_t v) {
+ if (v <= 5243) // if below 8% of max
+ return v / 9; // same as dividing by 900%
+ else {
+ uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare
+ // to get a useful result with integer division, we shift left in the expression above
+ // and revert what we've done again after squaring.
+ y = y * y * y >> 8;
+ if (y > 0xFFFFUL) // prevent overflow
+ return 0xFFFFU;
+ else
+ return (uint16_t) y;
+ }
+}
+
+void breathing_enable(void) {
+ breathing = true;
+ breathing_counter = 0;
+ breathing_halt = BREATHING_NO_HALT;
+ // interrupt already registered
+}
+
+void breathing_pulse(void) {
+ if (get_backlight_level() == 0)
+ breathing_min();
+ else
+ breathing_max();
+ breathing_halt = BREATHING_HALT_ON;
+ // breathing_interrupt_enable();
+ breathing = true;
+}
+
+void breathing_disable(void) {
+ breathing = false;
+ // backlight_set(get_backlight_level());
+ b_led_set(get_backlight_level()); // custom implementation of backlight_set()
+}
+
+void breathing_self_disable(void)
+{
+ if (get_backlight_level() == 0)
+ breathing_halt = BREATHING_HALT_OFF;
+ else
+ breathing_halt = BREATHING_HALT_ON;
+}
+
+void breathing_toggle(void) {
+ if (is_breathing())
+ breathing_disable();
+ else
+ breathing_enable();
+}
+
+void breathing_period_set(uint8_t value)
+{
+ if (!value)
+ value = 1;
+ breathing_period = value;
+}
+
+void breathing_period_default(void) {
+ breathing_period_set(BREATHING_PERIOD);
+}
+
+void breathing_period_inc(void)
+{
+ breathing_period_set(breathing_period+1);
+}
+
+void breathing_period_dec(void)
+{
+ breathing_period_set(breathing_period-1);
+}
+
+/* To generate breathing curve in python:
+ * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)]
+ */
+static const uint8_t breathing_table[BREATHING_STEPS] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+// Use this before the cie_lightness function.
+static inline uint16_t scale_backlight(uint16_t v) {
+ return v / BACKLIGHT_LEVELS * get_backlight_level();
+}
+
+void custom_breathing_handler(void) {
+ uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS;
+ // resetting after one period to prevent ugly reset at overflow.
+ breathing_counter = (breathing_counter + 1) % (breathing_period * 244);
+ uint8_t index = breathing_counter / interval % BREATHING_STEPS;
+
+ if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) ||
+ ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1)))
+ {
+ // breathing_interrupt_disable();
+ }
+
+ setPWM(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U)));
+}
+
+#endif // BACKLIGHT_BREATHING
+#endif // BACKLIGHT_ENABLE
diff --git a/keyboards/bminiex/config.h b/keyboards/bminiex/config.h
new file mode 100644
index 000000000..3f160109e
--- /dev/null
+++ b/keyboards/bminiex/config.h
@@ -0,0 +1,41 @@
+/*
+Copyright 2017 Luiz Ribeiro
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+#define VENDOR_ID 0x20A0
+#define PRODUCT_ID 0x422E
+#define MANUFACTURER winkeyless.kr
+#define PRODUCT B.mini Ex
+
+#define RGBLED_NUM 20
+
+/* matrix size */
+#define MATRIX_ROWS 8
+#define MATRIX_COLS 15
+
+#define RGBLIGHT_ANIMATIONS
+
+#define BACKLIGHT_LEVELS 5
+
+#define NO_UART 1
+
+/* key combination for command */
+#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
+
diff --git a/keyboards/bminiex/i2c.c b/keyboards/bminiex/i2c.c
new file mode 100644
index 000000000..a4f952135
--- /dev/null
+++ b/keyboards/bminiex/i2c.c
@@ -0,0 +1,106 @@
+/*
+Copyright 2016 Luiz Ribeiro
+
+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 .
+*/
+
+// Please do not modify this file
+
+#include
+#include
+
+#include "i2c.h"
+
+void i2c_set_bitrate(uint16_t bitrate_khz) {
+ uint8_t bitrate_div = ((F_CPU / 1000l) / bitrate_khz);
+ if (bitrate_div >= 16) {
+ bitrate_div = (bitrate_div - 16) / 2;
+ }
+ TWBR = bitrate_div;
+}
+
+void i2c_init(void) {
+ // set pull-up resistors on I2C bus pins
+ PORTC |= 0b11;
+
+ i2c_set_bitrate(400);
+
+ // enable TWI (two-wire interface)
+ TWCR |= (1 << TWEN);
+
+ // enable TWI interrupt and slave address ACK
+ TWCR |= (1 << TWIE);
+ TWCR |= (1 << TWEA);
+}
+
+uint8_t i2c_start(uint8_t address) {
+ // reset TWI control register
+ TWCR = 0;
+
+ // begin transmission and wait for it to end
+ TWCR = (1<
+
+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 .
+*/
+
+// Please do not modify this file
+
+#pragma once
+
+void i2c_init(void);
+void i2c_set_bitrate(uint16_t bitrate_khz);
+uint8_t i2c_send(uint8_t address, uint8_t *data, uint16_t length);
+
diff --git a/keyboards/bminiex/keymaps/default/keymap.c b/keyboards/bminiex/keymaps/default/keymap.c
new file mode 100644
index 000000000..ed949d74f
--- /dev/null
+++ b/keyboards/bminiex/keymaps/default/keymap.c
@@ -0,0 +1,29 @@
+/*
+Copyright 2017 Luiz Ribeiro
+
+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 .
+*/
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR,KC_HOME,KC_END, KC_NO, KC_NO, KC_NO, KC_NO,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL, KC_BSPC, KC_DEL, KC_NLCK, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC,KC_NO, KC_INS, KC_P7, KC_P8, KC_P9,
+ KC_LCAP, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,KC_NUHS,KC_ENT, KC_PGUP, KC_P4, KC_P5, KC_P6, KC_PPLS,
+ KC_LSFT,KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH,KC_RSFT, KC_UP, KC_PGDN, KC_P1, KC_P2, KC_P3,
+ KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_APP ,KC_RCTL,KC_LEFT,KC_DOWN,KC_RGHT, KC_P0, KC_PDOT, KC_PENT
+ )
+};
diff --git a/keyboards/bminiex/matrix.c b/keyboards/bminiex/matrix.c
new file mode 100644
index 000000000..8faaed8ac
--- /dev/null
+++ b/keyboards/bminiex/matrix.c
@@ -0,0 +1,122 @@
+/*
+Copyright 2017 Luiz Ribeiro
+
+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 .
+*/
+
+#include
+#include
+
+#include "matrix.h"
+#include "backlight.h"
+
+#ifndef DEBOUNCE
+#define DEBOUNCE 5
+#endif
+
+static uint8_t debouncing = DEBOUNCE;
+
+static matrix_row_t matrix[MATRIX_ROWS];
+static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+
+__attribute__ ((weak))
+void matrix_init_user(void) {}
+__attribute__ ((weak))
+void matrix_scan_user(void) {}
+__attribute__ ((weak))
+void matrix_init_kb(void) {
+ matrix_init_user();
+}
+__attribute__ ((weak))
+void matrix_scan_kb(void) {
+ matrix_scan_user();
+}
+
+void matrix_init(void) {
+ // all outputs for rows high
+ DDRB = 0xFF;
+ PORTB = 0xFF;
+ // all inputs for columns
+ DDRA = 0x00;
+ DDRC &= ~(0x111111<<2);
+ DDRD &= ~(1<> 1) & 0x55) | ((x << 1) & 0xaa);
+ x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
+ x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
+ return x;
+}
+
+uint8_t matrix_scan(void) {
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ matrix_set_row_status(row);
+ _delay_us(5);
+
+ matrix_row_t cols = (
+ // cols 0..7, PORTA 0 -> 7
+ (~PINA) & 0xFF
+ ) | (
+ // cols 8..13, PORTC 7 -> 0
+ bit_reverse((~PINC) & 0xFF) << 8
+ ) | (
+ // col 14, PORTD 7
+ ((~PIND) & (1 << PIND7)) << 7
+ );
+
+ if (matrix_debouncing[row] != cols) {
+ matrix_debouncing[row] = cols;
+ debouncing = DEBOUNCE;
+ }
+ }
+
+ if (debouncing) {
+ if (--debouncing) {
+ _delay_ms(1);
+ } else {
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ matrix[i] = matrix_debouncing[i];
+ }
+ }
+ }
+
+ matrix_scan_quantum();
+
+ return 1;
+}
+
+inline matrix_row_t matrix_get_row(uint8_t row) {
+ return matrix[row];
+}
+
+void matrix_print(void) {
+}
diff --git a/keyboards/bminiex/readme.md b/keyboards/bminiex/readme.md
new file mode 100644
index 000000000..204bcbbb1
--- /dev/null
+++ b/keyboards/bminiex/readme.md
@@ -0,0 +1,14 @@
+B.mini EX
+=========
+
+A compact fullsize keyboard with RGB
+
+Keyboard Maintainer: QMK Community
+Hardware Supported: B.mini EX PCB
+Hardware Availability: https://winkeyless.kr/product/b-mini-ex-x2-pcb/
+
+Make example for this keyboard (after setting up your build environment):
+
+ make bminiex:default
+
+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).
\ No newline at end of file
diff --git a/keyboards/bminiex/rules.mk b/keyboards/bminiex/rules.mk
new file mode 100644
index 000000000..e5d3a2a88
--- /dev/null
+++ b/keyboards/bminiex/rules.mk
@@ -0,0 +1,56 @@
+# Copyright 2017 Luiz Ribeiro
+#
+# 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 .
+
+# MCU name
+MCU = atmega32a
+PROTOCOL = VUSB
+
+# unsupported features for now
+NO_UART = yes
+NO_SUSPEND_POWER_DOWN = yes
+
+# processor frequency
+F_CPU = 12000000
+
+# Bootloader
+# This definition is optional, and if your keyboard supports multiple bootloaders of
+# different sizes, comment this out, and the correct address will be loaded
+# automatically (+60). See bootloader.mk for all options.
+BOOTLOADER = bootloadHID
+
+# build options
+BOOTMAGIC_ENABLE = yes
+MOUSEKEY_ENABLE = yes
+EXTRAKEY_ENABLE = yes
+CONSOLE_ENABLE = no
+DEBUG_ENABLE = no
+COMMAND_ENABLE = no
+BACKLIGHT_ENABLE = yes
+BACKLIGHT_CUSTOM_DRIVER = yes
+RGBLIGHT_ENABLE = yes
+RGBLIGHT_CUSTOM_DRIVER = yes
+TAP_DANCE_ENABLE = no
+
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+
+OPT_DEFS = -DDEBUG_LEVEL=0
+
+# custom matrix setup
+CUSTOM_MATRIX = yes
+SRC = matrix.c i2c.c backlight.c
+
+# programming options
+PROGRAM_CMD = ./util/atmega32a_program.py $(TARGET).hex
diff --git a/keyboards/bminiex/usbconfig.h b/keyboards/bminiex/usbconfig.h
new file mode 100644
index 000000000..d2d848fcd
--- /dev/null
+++ b/keyboards/bminiex/usbconfig.h
@@ -0,0 +1,396 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+#include "config.h"
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORTNAME D
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#define USB_CFG_DMINUS_BIT 3
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#define USB_CFG_DPLUS_BIT 2
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
+/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
+ * 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code
+ * require no crystal, they tolerate +/- 1% deviation from the nominal
+ * frequency. All other rates require a precision of 2000 ppm and thus a
+ * crystal!
+ * Since F_CPU should be defined to your actual clock rate anyway, you should
+ * not need to modify this setting.
+ */
+#define USB_CFG_CHECK_CRC 0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+/* #define USB_CFG_PULLUP_IOPORTNAME D */
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+/* #define USB_CFG_PULLUP_BIT 4 */
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT 1
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3 1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER 3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT 0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE 0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
+ * you need the interrupt-in endpoints in order to comply to an interface
+ * (e.g. HID), but never want to send any data. This option saves a couple
+ * of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL 1
+/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
+ * interval. The value is in milliseconds and must not be less than 10 ms for
+ * low speed devices.
+ */
+#define USB_CFG_IS_SELF_POWERED 0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+#define USB_CFG_MAX_BUS_POWER 500
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE 1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ 0
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL 0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_DRIVER_FLASH_PAGE 0
+/* If the device has more than 64 kBytes of flash, define this to the 64 k page
+ * where the driver's constants (descriptors) are located. Or in other words:
+ * Define this to 1 for boot loaders on the ATMega128.
+ */
+#define USB_CFG_LONG_TRANSFERS 0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#define USB_COUNT_SOF 1
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/* #ifdef __ASSEMBLER__
+ * macro myAssemblerMacro
+ * in YL, TCNT0
+ * sts timer0Snapshot, YL
+ * endm
+ * #endif
+ * #define USB_SOF_HOOK myAssemblerMacro
+ * This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+#define USB_CFG_CHECK_DATA_TOGGLING 0
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC 0
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID (VENDOR_ID & 0xFF), ((VENDOR_ID >> 8) & 0xFF)
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you may use one of obdev's free
+ * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_ID (PRODUCT_ID & 0xFF), ((PRODUCT_ID >> 8) & 0xFF)
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you may use one of obdev's free shared VID/PID pairs. See the file
+ * USB-IDs-for-free.txt for details!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_VERSION 0x00, 0x02
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME 'w', 'i', 'n', 'k', 'e', 'y', 'l', 'e', 's', 's', '.', 'k', 'r'
+#define USB_CFG_VENDOR_NAME_LEN 13
+/* These two values define the vendor name returned by the USB device. The name
+ * must be given as a list of characters under single quotes. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ * ALWAYS define a vendor name containing your Internet domain name if you use
+ * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
+ * details.
+ */
+#define USB_CFG_DEVICE_NAME 'p', 's', '2', 'a', 'v', 'r', 'G', 'B'
+#define USB_CFG_DEVICE_NAME_LEN 8
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros. See the file USB-IDs-for-free.txt before you assign a name if
+ * you use a shared VID/PID.
+ */
+/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
+/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
+/* Same as above for the serial number. If you don't want a serial number,
+ * undefine the macros.
+ * It may be useful to provide the serial number through other means than at
+ * compile time. See the section about descriptor properties below for how
+ * to fine tune control over USB descriptors such as the string descriptor
+ * for the serial number.
+ */
+#define USB_CFG_DEVICE_CLASS 0
+#define USB_CFG_DEVICE_SUBCLASS 0
+/* See USB specification if you want to conform to an existing device class.
+ * Class 0xff is "vendor specific".
+ */
+#define USB_CFG_INTERFACE_CLASS 3 /* HID */
+#define USB_CFG_INTERFACE_SUBCLASS 1 /* Boot */
+#define USB_CFG_INTERFACE_PROTOCOL 1 /* Keyboard */
+/* See USB specification if you want to conform to an existing device class or
+ * protocol. The following classes must be set at interface level:
+ * HID class is 3, no subclass and protocol required (but may be useful!)
+ * CDC class is 2, use subclass 2 and protocol 1 for ACM
+ */
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+/* #define USB_PUBLIC static */
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ * + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ * at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ * used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ * you want RAM pointers.
+ * + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ * in static memory is in RAM, not in flash memory.
+ * + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ * the driver must know the descriptor's length. The descriptor itself is
+ * found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ * char usbDescriptorDevice[];
+ * char usbDescriptorConfiguration[];
+ * char usbDescriptorHidReport[];
+ * char usbDescriptorString0[];
+ * int usbDescriptorStringVendor[];
+ * int usbDescriptorStringDevice[];
+ * int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ * USB_CFG_DESCR_PROPS_DEVICE
+ * USB_CFG_DESCR_PROPS_CONFIGURATION
+ * USB_CFG_DESCR_PROPS_STRINGS
+ * USB_CFG_DESCR_PROPS_STRING_0
+ * USB_CFG_DESCR_PROPS_STRING_VENDOR
+ * USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ * USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ * USB_CFG_DESCR_PROPS_HID
+ * USB_CFG_DESCR_PROPS_HID_REPORT
+ * USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int serialNumberDescriptor[] = {
+ * USB_STRING_DESCRIPTOR_HEADER(6),
+ * 'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE 0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
+#define USB_CFG_DESCR_PROPS_STRINGS 0
+#define USB_CFG_DESCR_PROPS_STRING_0 0
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
+#define USB_CFG_DESCR_PROPS_HID USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_HID 0
+#define USB_CFG_DESCR_PROPS_HID_REPORT USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_HID_REPORT 0
+#define USB_CFG_DESCR_PROPS_UNKNOWN 0
+
+#define usbMsgPtr_t unsigned short
+/* If usbMsgPtr_t is not defined, it defaults to 'uchar *'. We define it to
+ * a scalar type here because gcc generates slightly shorter code for scalar
+ * arithmetics than for pointer arithmetics. Remove this define for backward
+ * type compatibility or define it to an 8 bit type if you use data in RAM only
+ * and all RAM is below 256 bytes (tiny memory model in IAR CC).
+ */
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+/* #define USB_INTR_CFG MCUCR */
+/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE GIMSK */
+/* #define USB_INTR_ENABLE_BIT INT0 */
+/* #define USB_INTR_PENDING GIFR */
+/* #define USB_INTR_PENDING_BIT INTF0 */
+/* #define USB_INTR_VECTOR INT0_vect */
+
+/* Set INT1 for D- falling edge to count SOF */
+/* #define USB_INTR_CFG EICRA */
+#define USB_INTR_CFG_SET ((1 << ISC11) | (0 << ISC10))
+/* #define USB_INTR_CFG_CLR 0 */
+/* #define USB_INTR_ENABLE EIMSK */
+#define USB_INTR_ENABLE_BIT INT1
+/* #define USB_INTR_PENDING EIFR */
+#define USB_INTR_PENDING_BIT INTF1
+#define USB_INTR_VECTOR INT1_vect
+
+#endif /* __usbconfig_h_included__ */
diff --git a/tmk_core/common/backlight.h b/tmk_core/common/backlight.h
index f57309267..ef8ab9b2b 100644
--- a/tmk_core/common/backlight.h
+++ b/tmk_core/common/backlight.h
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#ifndef BACKLIGHT_H
-#define BACKLIGHT_H
+#pragma once
#include
#include
@@ -37,5 +36,3 @@ void backlight_step(void);
void backlight_set(uint8_t level);
void backlight_level(uint8_t level);
uint8_t get_backlight_level(void);
-
-#endif
--
cgit v1.2.3-70-g09d2
From cd23984afcee9a8dd2b1b44876b77141d692de45 Mon Sep 17 00:00:00 2001
From: patrickmt <40182064+patrickmt@users.noreply.github.com>
Date: Mon, 29 Oct 2018 10:04:52 -0400
Subject: Fix undefined reference to `console_printf` for CTRL and ALT
keyboards
Fix undefined reference to `console_printf` for CTRL and ALT keyboards when enabling CONSOLE_ENABLE
---
tmk_core/common/arm_atsam/printf.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c
index d49d234de..7f298d1fd 100644
--- a/tmk_core/common/arm_atsam/printf.c
+++ b/tmk_core/common/arm_atsam/printf.c
@@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#ifdef CONSOLE_PRINT
+#ifdef CONSOLE_ENABLE
#include "samd51j18a.h"
#include "arm_atsam_protocol.h"
@@ -63,4 +63,4 @@ void console_printf(char *fmt, ...) {
}
}
-#endif //CONSOLE_PRINT
+#endif //CONSOLE_ENABLE
--
cgit v1.2.3-70-g09d2
From a5fa75fcb3de822f4e43dcf29cee6eb9f945a992 Mon Sep 17 00:00:00 2001
From: Danny Nguyen
Date: Fri, 2 Nov 2018 15:28:16 -0400
Subject: Move disable JTAG code from `keyboard_init` to `keyboard_setup`
This way all split keyboards are using that code instead of just those using split_common with the fix
---
quantum/split_common/matrix.c | 6 ------
quantum/split_common/split_util.c | 14 --------------
tmk_core/common/keyboard.c | 14 +++++++++-----
tmk_core/common/keyboard.h | 2 ++
4 files changed, 11 insertions(+), 25 deletions(-)
(limited to 'tmk_core/common')
diff --git a/quantum/split_common/matrix.c b/quantum/split_common/matrix.c
index ff6738b58..d6359b51f 100644
--- a/quantum/split_common/matrix.c
+++ b/quantum/split_common/matrix.c
@@ -128,12 +128,6 @@ uint8_t matrix_cols(void)
void matrix_init(void)
{
-#ifdef DISABLE_JTAG
- // JTAG disable for PORT F. write JTD bit twice within four cycles.
- MCUCR |= (1<
Date: Fri, 2 Nov 2018 15:30:51 -0400
Subject: USB Suspend for arm_atsam protocol
Rewrote USB state tracking for implementation of suspend state.
Updated suspend.c in entirety.
Main subtasks (generally hardware related) are now run prior to keyboard task.
---
tmk_core/common/arm_atsam/suspend.c | 90 ++++++++++++++++++++++++----
tmk_core/protocol/arm_atsam/i2c_master.c | 5 +-
tmk_core/protocol/arm_atsam/main_arm_atsam.c | 80 ++++++++++++++++---------
tmk_core/protocol/arm_atsam/usb/ui.c | 8 +--
tmk_core/protocol/arm_atsam/usb/ui.h | 6 --
5 files changed, 136 insertions(+), 53 deletions(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/arm_atsam/suspend.c b/tmk_core/common/arm_atsam/suspend.c
index 01d1930ea..e34965df6 100644
--- a/tmk_core/common/arm_atsam/suspend.c
+++ b/tmk_core/common/arm_atsam/suspend.c
@@ -1,17 +1,85 @@
-/* Copyright 2017 Fred Sundvik
+#include "matrix.h"
+#include "i2c_master.h"
+#include "led_matrix.h"
+#include "suspend.h"
+
+/** \brief Suspend idle
*
- * 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.
+ * FIXME: needs doc
+ */
+void suspend_idle(uint8_t time) {
+ /* Note: Not used anywhere currently */
+}
+
+/** \brief Run user level Power down
*
- * 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.
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_user (void) {
+
+}
+
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_kb(void) {
+ suspend_power_down_user();
+}
+
+/** \brief Suspend power down
+ *
+ * FIXME: needs doc
+ */
+void suspend_power_down(void)
+{
+ I2C3733_Control_Set(0); //Disable LED driver
+
+ suspend_power_down_kb();
+}
+
+__attribute__ ((weak)) void matrix_power_up(void) {}
+__attribute__ ((weak)) void matrix_power_down(void) {}
+bool suspend_wakeup_condition(void) {
+ matrix_power_up();
+ matrix_scan();
+ matrix_power_down();
+ for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
+ if (matrix_get_row(r)) return true;
+ }
+ return false;
+}
+
+/** \brief run user level code immediately after wakeup
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_wakeup_init_user(void) {
+
+}
+
+/** \brief run keyboard level code immediately after wakeup
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_wakeup_init_kb(void) {
+ suspend_wakeup_init_user();
+}
+
+/** \brief run immediately after wakeup
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * FIXME: needs doc
*/
+void suspend_wakeup_init(void) {
+ /* If LEDs are set to enabled, enable the hardware */
+ if (led_enabled) {
+ I2C3733_Control_Set(1);
+ }
+ suspend_wakeup_init_kb();
+}
diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c
index 4f5a79e89..ece9ee5db 100644
--- a/tmk_core/protocol/arm_atsam/i2c_master.c
+++ b/tmk_core/protocol/arm_atsam/i2c_master.c
@@ -261,8 +261,9 @@ uint8_t I2C3733_Init_Control(void)
{
DBGC(DC_I2C3733_INIT_CONTROL_BEGIN);
- srdata.bit.SDB_N = 1;
- SPI_WriteSRData();
+ //Hardware state shutdown on boot
+ //USB state machine will enable driver when communication is ready
+ I2C3733_Control_Set(0);
CLK_delay_ms(1);
diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
index d3dc272ee..13034a05d 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -31,6 +31,8 @@ along with this program. If not, see .
//From keyboard's directory
#include "config_led.h"
+uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; //Saved USB state from hardware value to detect changes
+
void main_subtasks(void);
uint8_t keyboard_leds(void);
void send_keyboard(report_keyboard_t *report);
@@ -62,12 +64,6 @@ void send_keyboard(report_keyboard_t *report)
{
uint32_t irqflags;
- if (usb_state == USB_STATE_POWERDOWN)
- {
- udc_remotewakeup();
- return;
- }
-
#ifdef NKRO_ENABLE
if (!keymap_config.nkro)
{
@@ -161,41 +157,56 @@ void send_consumer(uint16_t data)
#endif //EXTRAKEY_ENABLE
}
-uint8_t g_drvid;
-uint8_t g_usb_sleeping = 0;
-
void main_subtask_usb_state(void)
{
- if (usb_state == USB_STATE_POWERDOWN)
+ static uint32_t fsmstate_on_delay = 0; //Delay timer to be sure USB is actually operating before bringing up hardware
+ uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; //Current state from hardware register
+
+ if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If USB SUSPENDED
{
- if (!g_usb_sleeping)
+ fsmstate_on_delay = 0; //Clear ON delay timer
+
+ if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If previously not SUSPENDED
{
- g_usb_sleeping = 1;
- if (led_enabled)
- {
- for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++)
- {
- I2C3733_Control_Set(0);
- }
- }
+ suspend_power_down(); //Run suspend routine
+ g_usb_state = fsmstate_now; //Save current USB state
}
}
- else if (g_usb_sleeping)
+ else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //Else if USB SLEEPING
{
- g_usb_sleeping = 0;
- if (led_enabled)
+ fsmstate_on_delay = 0; //Clear ON delay timer
+
+ if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //If previously not SLEEPING
{
- for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++)
+ suspend_power_down(); //Run suspend routine
+ g_usb_state = fsmstate_now; //Save current USB state
+ }
+ }
+ else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val) //Else if USB ON
+ {
+ if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) //If previously not ON
+ {
+ if (fsmstate_on_delay == 0) //If ON delay timer is cleared
{
- I2C3733_Control_Set(1);
+ fsmstate_on_delay = CLK_get_ms() + 250; //Set ON delay timer
+ }
+ else if (CLK_get_ms() > fsmstate_on_delay) //Else if ON delay timer is active and timed out
+ {
+ suspend_wakeup_init(); //Run wakeup routine
+ g_usb_state = fsmstate_now; //Save current USB state
}
}
}
+ else //Else if USB is in a state not being tracked
+ {
+ fsmstate_on_delay = 0; //Clear ON delay timer
+ }
}
void main_subtask_led(void)
{
- if (g_usb_sleeping) return;
+ if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) return; //Only run LED tasks if USB is operating
+
led_matrix_task();
}
@@ -275,8 +286,8 @@ int main(void)
i2c_led_q_init();
- for (g_drvid = 0; g_drvid < ISSI3733_DRIVER_COUNT; g_drvid++)
- I2C_LED_Q_ONOFF(g_drvid); //Queue data
+ for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
+ I2C_LED_Q_ONOFF(drvid); //Queue data
keyboard_setup();
@@ -294,10 +305,21 @@ int main(void)
while (1)
{
- keyboard_task();
-
main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals
+ if (g_usb_state == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val || g_usb_state == USB_FSMSTATUS_FSMSTATE_SLEEP_Val)
+ {
+ if (suspend_wakeup_condition())
+ {
+ udc_remotewakeup(); //Send remote wakeup signal
+ wait_ms(50);
+ }
+
+ continue;
+ }
+
+ keyboard_task();
+
#ifdef CONSOLE_ENABLE
if (CLK_get_ms() > next_print)
{
diff --git a/tmk_core/protocol/arm_atsam/usb/ui.c b/tmk_core/protocol/arm_atsam/usb/ui.c
index 031678b64..70a619109 100644
--- a/tmk_core/protocol/arm_atsam/usb/ui.c
+++ b/tmk_core/protocol/arm_atsam/usb/ui.c
@@ -52,8 +52,6 @@
#include "samd51j18a.h"
#include "ui.h"
-volatile uint8_t usb_state;
-
//! Sequence process running each \c SEQUENCE_PERIOD ms
#define SEQUENCE_PERIOD 150
@@ -72,12 +70,12 @@ static void ui_wakeup_handler(void)
void ui_init(void)
{
- usb_state = USB_STATE_POWERUP;
+
}
void ui_powerdown(void)
{
- usb_state = USB_STATE_POWERDOWN;
+
}
void ui_wakeup_enable(void)
@@ -92,7 +90,7 @@ void ui_wakeup_disable(void)
void ui_wakeup(void)
{
- usb_state = USB_STATE_POWERUP;
+
}
void ui_process(uint16_t framenumber)
diff --git a/tmk_core/protocol/arm_atsam/usb/ui.h b/tmk_core/protocol/arm_atsam/usb/ui.h
index 3d899e669..d1c767d45 100644
--- a/tmk_core/protocol/arm_atsam/usb/ui.h
+++ b/tmk_core/protocol/arm_atsam/usb/ui.h
@@ -47,12 +47,6 @@
#ifndef _UI_H_
#define _UI_H_
-extern volatile uint8_t usb_state;
-
-#define USB_STATE_UNKNOWN 0
-#define USB_STATE_POWERDOWN 1
-#define USB_STATE_POWERUP 2
-
//! \brief Initializes the user interface
void ui_init(void);
--
cgit v1.2.3-70-g09d2
From 40313cfa3b4a4f1643382f0446e0a889ef3e76dc Mon Sep 17 00:00:00 2001
From: Drashna Jaelre
Date: Tue, 30 Oct 2018 18:00:43 -0700
Subject: Fix Terminal feature on ChibiOS
---
common_features.mk | 1 +
tmk_core/common.mk | 4 +++-
tmk_core/common/print.h | 2 ++
3 files changed, 6 insertions(+), 1 deletion(-)
(limited to 'tmk_core/common')
diff --git a/common_features.mk b/common_features.mk
index f44dfc47d..8f53a82aa 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -213,6 +213,7 @@ endif
ifeq ($(strip $(TERMINAL_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_terminal.c
OPT_DEFS += -DTERMINAL_ENABLE
+ OPT_DEFS += -DUSER_PRINT
endif
ifeq ($(strip $(USB_HID_ENABLE)), yes)
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 3844b13d4..65dcf96f6 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -43,9 +43,11 @@ ifeq ($(PLATFORM),CHIBIOS)
TMK_COMMON_DEFS += -DSTM32_EEPROM_ENABLE
else
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
-endif
+ endif
ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
TMK_COMMON_SRC += $(CHIBIOS)/os/various/syscalls.c
+ else ifeq($(strip $(TERMINAL_ENABLE)), yes)
+ TMK_COMMON_SRC += $(CHIBIOS)/os/various/syscalls.c
endif
endif
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index d94527657..06c6cbd7f 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -73,7 +73,9 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
#elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
+#ifndef TERMINAL_ENABLE
# include "chibios/printf.h"
+#endif
# ifdef USER_PRINT /* USER_PRINT */
--
cgit v1.2.3-70-g09d2
From 73e634482ea8f57d1f1a5f1e16bc3ffd74f84b8e Mon Sep 17 00:00:00 2001
From: Drashna Jaelre
Date: Tue, 30 Oct 2018 18:03:46 -0700
Subject: command.h include was not set correctly
---
tmk_core/common/command.h | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/command.h b/tmk_core/common/command.h
index d9d89ba0f..c38f2b9e8 100644
--- a/tmk_core/common/command.h
+++ b/tmk_core/common/command.h
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#ifndef COMMAND_H
-#define COMMAND
+#pragma once
/* FIXME: Add doxygen comments for the behavioral defines in here. */
@@ -155,5 +154,3 @@ bool command_proc(uint8_t code);
#define XMAGIC_KC(key) KC_##key
#define MAGIC_KC(key) XMAGIC_KC(key)
-
-#endif
--
cgit v1.2.3-70-g09d2
From 0cda2f43e2c95fe5dd440e6391ae807f508b040b Mon Sep 17 00:00:00 2001
From: Phillip Tennen
Date: Wed, 14 Nov 2018 16:45:46 +0100
Subject: Backlight status functions (#4259)
* add functions to set specific backlight state
* add function to query backlight state
* update documentation with new backlight functions
* Update tmk_core/common/backlight.c
Co-Authored-By: codyd51
* Update tmk_core/common/backlight.h
Co-Authored-By: codyd51
* update docs for is_backlight_enabled() name change
---
docs/feature_backlight.md | 19 ++++++++++-------
tmk_core/common/backlight.c | 51 +++++++++++++++++++++++++++++++++++++++------
tmk_core/common/backlight.h | 4 ++++
3 files changed, 60 insertions(+), 14 deletions(-)
(limited to 'tmk_core/common')
diff --git a/docs/feature_backlight.md b/docs/feature_backlight.md
index 7bb7e03a8..f7a35406c 100644
--- a/docs/feature_backlight.md
+++ b/docs/feature_backlight.md
@@ -54,14 +54,17 @@ In this handler, the value of an incrementing counter is mapped onto a precomput
## Backlight Functions
-|Function |Description |
-|----------|----------------------------------------------------------|
-|`backlight_toggle()` |Turn the backlight on or off |
-|`backlight_step()` |Cycle through backlight levels |
-|`backlight_increase()` |Increase the backlight level |
-|`backlight_decrease()` |Decrease the backlight level |
-|`backlight_level(x)` |Sets the backlight level to specified level |
-|`get_backlight_level()`|Return the current backlight level |
+|Function |Description |
+|----------|-----------------------------------------------------------|
+|`backlight_toggle()` |Turn the backlight on or off |
+|`backlight_enable()` |Turn the backlight on |
+|`backlight_disable()` |Turn the backlight off |
+|`backlight_step()` |Cycle through backlight levels |
+|`backlight_increase()` |Increase the backlight level |
+|`backlight_decrease()` |Decrease the backlight level |
+|`backlight_level(x)` |Sets the backlight level to specified level |
+|`get_backlight_level()` |Return the current backlight level |
+|`is_backlight_enabled()`|Return whether the backlight is currently on |
### Backlight Breathing Functions
diff --git a/tmk_core/common/backlight.c b/tmk_core/common/backlight.c
index 3e29aacc4..8ddacd98b 100644
--- a/tmk_core/common/backlight.c
+++ b/tmk_core/common/backlight.c
@@ -76,12 +76,51 @@ void backlight_decrease(void)
*/
void backlight_toggle(void)
{
- backlight_config.enable ^= 1;
- if (backlight_config.raw == 1) // enabled but level = 0
- backlight_config.level = 1;
- eeconfig_update_backlight(backlight_config.raw);
- dprintf("backlight toggle: %u\n", backlight_config.enable);
- backlight_set(backlight_config.enable ? backlight_config.level : 0);
+ bool enabled = backlight_config.enable;
+ dprintf("backlight toggle: %u\n", enabled);
+ if (enabled)
+ backlight_disable();
+ else
+ backlight_enable();
+}
+
+/** \brief Enable backlight
+ *
+ * FIXME: needs doc
+ */
+void backlight_enable(void)
+{
+ if (backlight_config.enable) return; // do nothing if backlight is already on
+
+ backlight_config.enable = true;
+ if (backlight_config.raw == 1) // enabled but level == 0
+ backlight_config.level = 1;
+ eeconfig_update_backlight(backlight_config.raw);
+ dprintf("backlight enable\n");
+ backlight_set(backlight_config.level);
+}
+
+/** /brief Disable backlight
+ *
+ * FIXME: needs doc
+ */
+void backlight_disable(void)
+{
+ if (!backlight_config.enable) return; // do nothing if backlight is already off
+
+ backlight_config.enable = false;
+ eeconfig_update_backlight(backlight_config.raw);
+ dprintf("backlight disable\n");
+ backlight_set(0);
+}
+
+/** /brief Get the backlight status
+ *
+ * FIXME: needs doc
+ */
+bool is_backlight_enabled(void)
+{
+ return backlight_config.enable;
}
/** \brief Backlight step through levels
diff --git a/tmk_core/common/backlight.h b/tmk_core/common/backlight.h
index ef8ab9b2b..420c9d19e 100644
--- a/tmk_core/common/backlight.h
+++ b/tmk_core/common/backlight.h
@@ -32,7 +32,11 @@ void backlight_init(void);
void backlight_increase(void);
void backlight_decrease(void);
void backlight_toggle(void);
+void backlight_enable(void);
+void backlight_disable(void);
+bool is_backlight_enabled(void);
void backlight_step(void);
void backlight_set(uint8_t level);
void backlight_level(uint8_t level);
uint8_t get_backlight_level(void);
+
--
cgit v1.2.3-70-g09d2
From 39bd760faf2666e91d6dc5b199f02fa3206c6acd Mon Sep 17 00:00:00 2001
From: James Laird-Wah
Date: Fri, 16 Nov 2018 17:22:05 +1100
Subject: Use a single endpoint for HID reports (#3951)
* Unify multiple HID interfaces into one
This reduces the number of USB endpoints required, which frees them up
for other things.
NKRO and EXTRAKEY always use the shared endpoint.
By default, MOUSEKEY also uses it. This means it won't work as a Boot
Procotol mouse in some BIOSes, etc. If you really think your
keyboard needs to work as a mouse in your BIOS, set
MOUSE_SHARED_EP = no in your rules.mk.
By default, the core keyboard does not use the shared endpoint, as not
all BIOSes are standards compliant and that's one place you don't want
to find out your keyboard doesn't work.. If you are really confident,
you can set KEYBOARD_SHARED_EP = yes to use the shared endpoint here
too.
* unify endpoints: ChibiOS protocol implementation
* fixup: missing #ifdef EXTRAKEY_ENABLEs
broke build on AVR with EXTRAKEY disabled
* endpoints: restore error when too many endpoints required
* lufa: wait up to 10ms to send keyboard input
This avoids packets being dropped when two reports are sent in quick
succession (eg. releasing a dual role key).
* endpoints: fix compile on ARM_ATSAM
* endpoint: ARM_ATSAM fixes
No longer use wrong or unexpected endpoint IDs
* endpoints: accommodate VUSB protocol
V-USB has its own, understandably simple ideas about the report formats.
It already blasts the mouse and extrakeys through one endpoint with
report IDs. We just stay out of its way.
* endpoints: document new endpoint configuration options
* endpoints: respect keyboard_report->mods in NKRO
The caller(s) of host_keyboard_send expect to be able to just drop
modifiers in the mods field and not worry about whether NKRO is in use.
This is a good thing. So we just shift it over if needs be.
* endpoints: report.c: update for new keyboard_report format
---
docs/config_options.md | 29 ++++
tmk_core/common.mk | 21 +++
tmk_core/common/host.c | 22 +++
tmk_core/common/report.c | 21 ++-
tmk_core/common/report.h | 46 ++++--
tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c | 5 +-
tmk_core/protocol/chibios/usb_main.c | 176 ++++++++++-----------
tmk_core/protocol/chibios/usb_main.h | 11 +-
tmk_core/protocol/lufa/lufa.c | 92 ++++++-----
tmk_core/protocol/usb_descriptor.c | 213 ++++++++++++--------------
tmk_core/protocol/usb_descriptor.h | 170 ++++++++------------
11 files changed, 426 insertions(+), 380 deletions(-)
(limited to 'tmk_core/common')
diff --git a/docs/config_options.md b/docs/config_options.md
index c4921c21d..b811fa877 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -261,3 +261,32 @@ Use these to enable or disable building certain features. The more you have enab
* Forces the keyboard to wait for a USB connection to be established before it starts up
* `NO_USB_STARTUP_CHECK`
* Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master.
+
+## USB Endpoint Limitations
+
+In order to provide services over USB, QMK has to use USB endpoints.
+These are a finite resource: each microcontroller has only a certain number.
+This limits what features can be enabled together.
+If the available endpoints are exceeded, a build error is thrown.
+
+The following features can require separate endpoints:
+
+* `MOUSEKEY_ENABLE`
+* `EXTRAKEY_ENABLE`
+* `CONSOLE_ENABLE`
+* `NKRO_ENABLE`
+* `MIDI_ENABLE`
+* `RAW_ENABLE`
+* `VIRTSER_ENABLE`
+
+In order to improve utilisation of the endpoints, the HID features can be combined to use a single endpoint.
+By default, `MOUSEKEY`, `EXTRAKEY`, and `NKRO` are combined into a single endpoint.
+
+The base keyboard functionality can also be combined into the endpoint,
+by setting `KEYBOARD_SHARED_EP = yes`.
+This frees up one more endpoint,
+but it can prevent the keyboard working in some BIOSes,
+as they do not implement Boot Keyboard protocol switching.
+
+Combining the mouse also breaks Boot Mouse compatibility.
+The mouse can be uncombined by setting `MOUSE_SHARED_EP = no` if this functionality is required.
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 8eac1734f..063115acb 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -82,15 +82,31 @@ else
TMK_COMMON_SRC += $(COMMON_DIR)/magic.c
endif
+SHARED_EP_ENABLE = no
+MOUSE_SHARED_EP ?= yes
+ifeq ($(strip $(KEYBOARD_SHARED_EP)), yes)
+ TMK_COMMON_DEFS += -DKEYBOARD_SHARED_EP
+ SHARED_EP_ENABLE = yes
+ # With the current usb_descriptor.c code,
+ # you can't share kbd without sharing mouse;
+ # that would be a very unexpected use case anyway
+ MOUSE_SHARED_EP = yes
+endif
ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
TMK_COMMON_SRC += $(COMMON_DIR)/mousekey.c
TMK_COMMON_DEFS += -DMOUSEKEY_ENABLE
TMK_COMMON_DEFS += -DMOUSE_ENABLE
+
+ ifeq ($(strip $(MOUSE_SHARED_EP)), yes)
+ TMK_COMMON_DEFS += -DMOUSE_SHARED_EP
+ SHARED_EP_ENABLE = yes
+ endif
endif
ifeq ($(strip $(EXTRAKEY_ENABLE)), yes)
TMK_COMMON_DEFS += -DEXTRAKEY_ENABLE
+ SHARED_EP_ENABLE = yes
endif
ifeq ($(strip $(RAW_ENABLE)), yes)
@@ -111,6 +127,7 @@ endif
ifeq ($(strip $(NKRO_ENABLE)), yes)
TMK_COMMON_DEFS += -DNKRO_ENABLE
+ SHARED_EP_ENABLE = yes
endif
ifeq ($(strip $(USB_6KRO_ENABLE)), yes)
@@ -182,6 +199,10 @@ ifeq ($(strip $(KEYMAP_SECTION_ENABLE)), yes)
endif
endif
+ifeq ($(strip $(SHARED_EP_ENABLE)), yes)
+ TMK_COMMON_DEFS += -DSHARED_EP_ENABLE
+endif
+
# Bootloader address
ifdef STM32_BOOTLOADER_ADDRESS
TMK_COMMON_DEFS += -DSTM32_BOOTLOADER_ADDRESS=$(STM32_BOOTLOADER_ADDRESS)
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
index e12b62216..f5d041699 100644
--- a/tmk_core/common/host.c
+++ b/tmk_core/common/host.c
@@ -22,6 +22,11 @@ along with this program. If not, see .
#include "util.h"
#include "debug.h"
+#ifdef NKRO_ENABLE
+ #include "keycode_config.h"
+ extern keymap_config_t keymap_config;
+#endif
+
static host_driver_t *driver;
static uint16_t last_system_report = 0;
static uint16_t last_consumer_report = 0;
@@ -46,6 +51,20 @@ uint8_t host_keyboard_leds(void)
void host_keyboard_send(report_keyboard_t *report)
{
if (!driver) return;
+#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
+ if (keyboard_protocol && keymap_config.nkro) {
+ /* The callers of this function assume that report->mods is where mods go in.
+ * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
+ */
+ report->nkro.mods = report->mods;
+ report->nkro.report_id = REPORT_ID_NKRO;
+ } else
+#endif
+ {
+#ifdef KEYBOARD_SHARED_EP
+ report->report_id = REPORT_ID_KEYBOARD;
+#endif
+ }
(*driver->send_keyboard)(report);
if (debug_keyboard) {
@@ -60,6 +79,9 @@ void host_keyboard_send(report_keyboard_t *report)
void host_mouse_send(report_mouse_t *report)
{
if (!driver) return;
+#ifdef MOUSE_SHARED_EP
+ report->report_id = REPORT_ID_MOUSE;
+#endif
(*driver->send_mouse)(report);
}
diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c
index eb3b44312..6a06b70c6 100644
--- a/tmk_core/common/report.c
+++ b/tmk_core/common/report.c
@@ -19,6 +19,7 @@
#include "keycode_config.h"
#include "debug.h"
#include "util.h"
+#include
/** \brief has_anykey
*
@@ -27,8 +28,16 @@
uint8_t has_anykey(report_keyboard_t* keyboard_report)
{
uint8_t cnt = 0;
- for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
- if (keyboard_report->raw[i])
+ uint8_t *p = keyboard_report->keys;
+ uint8_t lp = sizeof(keyboard_report->keys);
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ p = keyboard_report->nkro.bits;
+ lp = sizeof(keyboard_report->nkro.bits);
+ }
+#endif
+ while (lp--) {
+ if (*p++)
cnt++;
}
return cnt;
@@ -237,7 +246,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
void clear_keys_from_report(report_keyboard_t* keyboard_report)
{
// not clear mods
- for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
- keyboard_report->raw[i] = 0;
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
+ return;
}
+#endif
+ memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
}
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 167f38275..5a1a6b19c 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -23,9 +23,11 @@ along with this program. If not, see .
/* report id */
-#define REPORT_ID_MOUSE 1
-#define REPORT_ID_SYSTEM 2
-#define REPORT_ID_CONSUMER 3
+#define REPORT_ID_KEYBOARD 1
+#define REPORT_ID_MOUSE 2
+#define REPORT_ID_SYSTEM 3
+#define REPORT_ID_CONSUMER 4
+#define REPORT_ID_NKRO 5
/* mouse buttons */
#define MOUSE_BTN1 (1<<0)
@@ -72,32 +74,35 @@ along with this program. If not, see .
#define SYSTEM_WAKE_UP 0x0083
+#define NKRO_SHARED_EP
/* key report size(NKRO or boot mode) */
#if defined(NKRO_ENABLE)
- #if defined(PROTOCOL_PJRC)
- #include "usb.h"
- #define KEYBOARD_REPORT_SIZE KBD2_SIZE
- #define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
- #define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
- #elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
+ #if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
#include "protocol/usb_descriptor.h"
- #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
- #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
- #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
+ #define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
#elif defined(PROTOCOL_ARM_ATSAM)
#include "protocol/arm_atsam/usb/udi_device_epsize.h"
- #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
- #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
#define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
+ #undef NKRO_SHARED_EP
+ #undef MOUSE_SHARED_EP
#else
#error "NKRO not supported with this protocol"
+ #endif
#endif
+#ifdef KEYBOARD_SHARED_EP
+# define KEYBOARD_REPORT_SIZE 9
#else
# define KEYBOARD_REPORT_SIZE 8
-# define KEYBOARD_REPORT_KEYS 6
#endif
+#define KEYBOARD_REPORT_KEYS 6
+
+/* VUSB hardcodes keyboard and mouse+extrakey only */
+#if defined(PROTOCOL_VUSB)
+ #undef KEYBOARD_SHARED_EP
+ #undef MOUSE_SHARED_EP
+#endif
#ifdef __cplusplus
extern "C" {
@@ -126,12 +131,18 @@ extern "C" {
typedef union {
uint8_t raw[KEYBOARD_REPORT_SIZE];
struct {
+#ifdef KEYBOARD_SHARED_EP
+ uint8_t report_id;
+#endif
uint8_t mods;
uint8_t reserved;
uint8_t keys[KEYBOARD_REPORT_KEYS];
};
#ifdef NKRO_ENABLE
- struct {
+ struct nkro_report {
+#ifdef NKRO_SHARED_EP
+ uint8_t report_id;
+#endif
uint8_t mods;
uint8_t bits[KEYBOARD_REPORT_BITS];
} nkro;
@@ -139,6 +150,9 @@ typedef union {
} __attribute__ ((packed)) report_keyboard_t;
typedef struct {
+#ifdef MOUSE_SHARED_EP
+ uint8_t report_id;
+#endif
uint8_t buttons;
int8_t x;
int8_t y;
diff --git a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
index 18f9784ae..c263ac4aa 100644
--- a/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
+++ b/tmk_core/protocol/arm_atsam/usb/udi_hid_kbd.c
@@ -54,6 +54,7 @@
#include "udi_hid.h"
#include "udi_hid_kbd.h"
#include
+#include "report.h"
//***************************************************************************
// KBD
@@ -430,7 +431,7 @@ UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {
0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x80, // Usage (System Control),
0xA1, 0x01, // Collection (Application),
- 0x85, 0x02, // Report ID (2) (System),
+ 0x85, REPORT_ID_SYSTEM, // Report ID (2) (System),
0x16, 0x01, 0x00, // Logical Minimum (1),
0x26, 0x03, 0x00, // Logical Maximum (3),
0x1A, 0x81, 0x00, // Usage Minimum (81) (System Power Down),
@@ -445,7 +446,7 @@ UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {
0x05, 0x0C, // Usage Page (Consumer),
0x09, 0x01, // Usage (Consumer Control),
0xA1, 0x01, // Collection (Application),
- 0x85, 0x03, // Report ID (3) (Consumer),
+ 0x85, REPORT_ID_CONSUMER, // Report ID (3) (Consumer),
0x16, 0x01, 0x00, // Logical Minimum (1),
0x26, 0x9C, 0x02, // Logical Maximum (668),
0x1A, 0x01, 0x00, // Usage Minimum (1),
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 71892c4f4..3028e7ea2 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -95,6 +95,7 @@ static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype
return &desc;
}
+#ifndef KEYBOARD_SHARED_EP
/* keyboard endpoint state structure */
static USBInEndpointState kbd_ep_state;
/* keyboard endpoint initialization structure (IN) */
@@ -110,8 +111,9 @@ static const USBEndpointConfig kbd_ep_config = {
2, /* IN multiplier */
NULL /* SETUP buffer (not a SETUP endpoint) */
};
+#endif
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
/* mouse endpoint state structure */
static USBInEndpointState mouse_ep_state;
@@ -128,45 +130,26 @@ static const USBEndpointConfig mouse_ep_config = {
2, /* IN multiplier */
NULL /* SETUP buffer (not a SETUP endpoint) */
};
-#endif /* MOUSE_ENABLE */
-
-#ifdef EXTRAKEY_ENABLE
-/* extrakey endpoint state structure */
-static USBInEndpointState extra_ep_state;
-
-/* extrakey endpoint initialization structure (IN) */
-static const USBEndpointConfig extra_ep_config = {
- USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
- NULL, /* SETUP packet notification callback */
- extra_in_cb, /* IN notification callback */
- NULL, /* OUT notification callback */
- EXTRAKEY_EPSIZE, /* IN maximum packet size */
- 0, /* OUT maximum packet size */
- &extra_ep_state, /* IN Endpoint state */
- NULL, /* OUT endpoint state */
- 2, /* IN multiplier */
- NULL /* SETUP buffer (not a SETUP endpoint) */
-};
-#endif /* EXTRAKEY_ENABLE */
+#endif
-#ifdef NKRO_ENABLE
-/* nkro endpoint state structure */
-static USBInEndpointState nkro_ep_state;
+#ifdef SHARED_EP_ENABLE
+/* shared endpoint state structure */
+static USBInEndpointState shared_ep_state;
-/* nkro endpoint initialization structure (IN) */
-static const USBEndpointConfig nkro_ep_config = {
+/* shared endpoint initialization structure (IN) */
+static const USBEndpointConfig shared_ep_config = {
USB_EP_MODE_TYPE_INTR, /* Interrupt EP */
NULL, /* SETUP packet notification callback */
- nkro_in_cb, /* IN notification callback */
+ shared_in_cb, /* IN notification callback */
NULL, /* OUT notification callback */
- NKRO_EPSIZE, /* IN maximum packet size */
+ SHARED_EPSIZE, /* IN maximum packet size */
0, /* OUT maximum packet size */
- &nkro_ep_state, /* IN Endpoint state */
+ &shared_ep_state, /* IN Endpoint state */
NULL, /* OUT endpoint state */
2, /* IN multiplier */
NULL /* SETUP buffer (not a SETUP endpoint) */
};
-#endif /* NKRO_ENABLE */
+#endif
typedef struct {
size_t queue_capacity_in;
@@ -309,16 +292,15 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
case USB_EVENT_CONFIGURED:
osalSysLockFromISR();
/* Enable the endpoints specified into the configuration. */
+#ifndef KEYBOARD_SHARED_EP
usbInitEndpointI(usbp, KEYBOARD_IN_EPNUM, &kbd_ep_config);
-#ifdef MOUSE_ENABLE
+#endif
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
usbInitEndpointI(usbp, MOUSE_IN_EPNUM, &mouse_ep_config);
-#endif /* MOUSE_ENABLE */
-#ifdef EXTRAKEY_ENABLE
- usbInitEndpointI(usbp, EXTRAKEY_IN_EPNUM, &extra_ep_config);
-#endif /* EXTRAKEY_ENABLE */
-#ifdef NKRO_ENABLE
- usbInitEndpointI(usbp, NKRO_IN_EPNUM, &nkro_ep_config);
-#endif /* NKRO_ENABLE */
+#endif
+#ifdef SHARED_EP_ENABLE
+ usbInitEndpointI(usbp, SHARED_IN_EPNUM, &shared_ep_config);
+#endif
for (int i=0;isetup fields:
* 0: bmRequestType (bitmask)
@@ -409,42 +402,16 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
case HID_GET_REPORT:
switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */
case KEYBOARD_INTERFACE:
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
-#endif /* NKRO_ENABLE */
usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent), NULL);
return TRUE;
break;
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE:
usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL);
return TRUE;
break;
-#endif /* MOUSE_ENABLE */
-
-#ifdef EXTRAKEY_ENABLE
- case EXTRAKEY_INTERFACE:
- if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */
- switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */
- case REPORT_ID_SYSTEM:
- extra_report_blank[0] = REPORT_ID_SYSTEM;
- usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
- return TRUE;
- break;
- case REPORT_ID_CONSUMER:
- extra_report_blank[0] = REPORT_ID_CONSUMER;
- usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL);
- return TRUE;
- break;
- default:
- return FALSE;
- }
- } else {
- return FALSE;
- }
- break;
-#endif /* EXTRAKEY_ENABLE */
+#endif
default:
usbSetupTransfer(usbp, NULL, 0, NULL);
@@ -472,12 +439,25 @@ static bool usb_request_hook_cb(USBDriver *usbp) {
case HID_SET_REPORT:
switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */
case KEYBOARD_INTERFACE:
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
-#endif /* NKRO_ENABLE */
+#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
+ case SHARED_INTERFACE:
+#endif
/* keyboard_led_stats =
* keyboard_led_stats needs be word (or dword), otherwise we get an exception on F0 */
- usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL);
+ has_report_id = 0;
+#if defined(SHARED_EP_ENABLE)
+ if (usbp->setup[4] == SHARED_INTERFACE) {
+ has_report_id = 1;
+ }
+#endif
+ if (usbp->setup[4] == KEYBOARD_INTERFACE && !keyboard_protocol) {
+ has_report_id = 0;
+ }
+ if (has_report_id) {
+ usbSetupTransfer(usbp, set_report_buf, sizeof(set_report_buf), set_led_transfer_cb);
+ } else {
+ usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL);
+ }
return TRUE;
break;
}
@@ -591,20 +571,13 @@ void init_usb_driver(USBDriver *usbp) {
* ---------------------------------------------------------
*/
/* keyboard IN callback hander (a kbd report has made it IN) */
+#ifndef KEYBOARD_SHARED_EP
void kbd_in_cb(USBDriver *usbp, usbep_t ep) {
/* STUB */
(void)usbp;
(void)ep;
}
-
-#ifdef NKRO_ENABLE
-/* nkro IN callback hander (a nkro report has made it IN) */
-void nkro_in_cb(USBDriver *usbp, usbep_t ep) {
- /* STUB */
- (void)usbp;
- (void)ep;
-}
-#endif /* NKRO_ENABLE */
+#endif
/* start-of-frame handler
* TODO: i guess it would be better to re-implement using timers,
@@ -628,9 +601,9 @@ static void keyboard_idle_timer_cb(void *arg) {
}
#ifdef NKRO_ENABLE
- if(!keymap_config.nkro && keyboard_idle) {
+ if(!keymap_config.nkro && keyboard_idle && keyboard_protocol) {
#else /* NKRO_ENABLE */
- if(keyboard_idle) {
+ if(keyboard_idle && keyboard_protocol) {
#endif /* NKRO_ENABLE */
/* TODO: are we sure we want the KBD_ENDPOINT? */
if(!usbGetTransmitStatusI(usbp, KEYBOARD_IN_EPNUM)) {
@@ -661,25 +634,25 @@ void send_keyboard(report_keyboard_t *report) {
osalSysUnlock();
#ifdef NKRO_ENABLE
- if(keymap_config.nkro) { /* NKRO protocol */
+ if(keymap_config.nkro && keyboard_protocol) { /* NKRO protocol */
/* need to wait until the previous packet has made it through */
/* can rewrite this using the synchronous API, then would wait
* until *after* the packet has been transmitted. I think
* this is more efficient */
/* busy wait, should be short and not very common */
osalSysLock();
- if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_IN_EPNUM)) {
+ if(usbGetTransmitStatusI(&USB_DRIVER, SHARED_IN_EPNUM)) {
/* Need to either suspend, or loop and call unlock/lock during
* every iteration - otherwise the system will remain locked,
* no interrupts served, so USB not going through as well.
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
- osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_IN_EPNUM]->in_state->thread);
+ osalThreadSuspendS(&(&USB_DRIVER)->epc[SHARED_IN_EPNUM]->in_state->thread);
}
- usbStartTransmitI(&USB_DRIVER, NKRO_IN_EPNUM, (uint8_t *)report, sizeof(report_keyboard_t));
+ usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)report, sizeof(struct nkro_report));
osalSysUnlock();
} else
#endif /* NKRO_ENABLE */
- { /* boot protocol */
+ { /* regular protocol */
/* need to wait until the previous packet has made it through */
/* busy wait, should be short and not very common */
osalSysLock();
@@ -690,7 +663,15 @@ void send_keyboard(report_keyboard_t *report) {
* Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */
osalThreadSuspendS(&(&USB_DRIVER)->epc[KEYBOARD_IN_EPNUM]->in_state->thread);
}
- usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, (uint8_t *)report, KEYBOARD_EPSIZE);
+ uint8_t *data, size;
+ if (keyboard_protocol) {
+ data = (uint8_t*)report;
+ size = KEYBOARD_REPORT_SIZE;
+ } else { /* boot protocol */
+ data = &report->mods;
+ size = 8;
+ }
+ usbStartTransmitI(&USB_DRIVER, KEYBOARD_IN_EPNUM, data, size);
osalSysUnlock();
}
keyboard_report_sent = *report;
@@ -703,11 +684,13 @@ void send_keyboard(report_keyboard_t *report) {
#ifdef MOUSE_ENABLE
+#ifndef MOUSE_SHARED_EP
/* mouse IN callback hander (a mouse report has made it IN) */
void mouse_in_cb(USBDriver *usbp, usbep_t ep) {
(void)usbp;
(void)ep;
}
+#endif
void send_mouse(report_mouse_t *report) {
osalSysLock();
@@ -737,19 +720,24 @@ void send_mouse(report_mouse_t *report) {
#endif /* MOUSE_ENABLE */
/* ---------------------------------------------------------
- * Extrakey functions
+ * Shared EP functions
* ---------------------------------------------------------
*/
-
-#ifdef EXTRAKEY_ENABLE
-
-/* extrakey IN callback hander */
-void extra_in_cb(USBDriver *usbp, usbep_t ep) {
+#ifdef SHARED_EP_ENABLE
+/* shared IN callback hander */
+void shared_in_cb(USBDriver *usbp, usbep_t ep) {
/* STUB */
(void)usbp;
(void)ep;
}
+#endif
+
+/* ---------------------------------------------------------
+ * Extrakey functions
+ * ---------------------------------------------------------
+ */
+#ifdef EXTRAKEY_ENABLE
static void send_extra_report(uint8_t report_id, uint16_t data) {
osalSysLock();
if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
@@ -762,7 +750,7 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
.usage = data
};
- usbStartTransmitI(&USB_DRIVER, EXTRAKEY_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
+ usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
osalSysUnlock();
}
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index 1f7eb12f8..55e8882cc 100644
--- a/tmk_core/protocol/chibios/usb_main.h
+++ b/tmk_core/protocol/chibios/usb_main.h
@@ -65,6 +65,14 @@ void nkro_in_cb(USBDriver *usbp, usbep_t ep);
void mouse_in_cb(USBDriver *usbp, usbep_t ep);
#endif /* MOUSE_ENABLE */
+/* ---------------
+ * Shared EP header
+ * ---------------
+ */
+
+/* shared IN request callback handler */
+void shared_in_cb(USBDriver *usbp, usbep_t ep);
+
/* ---------------
* Extrakey header
* ---------------
@@ -72,9 +80,6 @@ void mouse_in_cb(USBDriver *usbp, usbep_t ep);
#ifdef EXTRAKEY_ENABLE
-/* extrakey IN request callback handler */
-void extra_in_cb(USBDriver *usbp, usbep_t ep);
-
/* extra report structure */
typedef struct {
uint8_t report_id;
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 95e0b95b2..e88e6f34a 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -409,19 +409,21 @@ void EVENT_USB_Device_ConfigurationChanged(void)
bool ConfigSuccess = true;
/* Setup Keyboard HID Report Endpoints */
+#ifndef KEYBOARD_SHARED_EP
ConfigSuccess &= ENDPOINT_CONFIG(KEYBOARD_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
KEYBOARD_EPSIZE, ENDPOINT_BANK_SINGLE);
+#endif
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
/* Setup Mouse HID Report Endpoint */
ConfigSuccess &= ENDPOINT_CONFIG(MOUSE_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
MOUSE_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
-#ifdef EXTRAKEY_ENABLE
- /* Setup Extra HID Report Endpoint */
- ConfigSuccess &= ENDPOINT_CONFIG(EXTRAKEY_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
- EXTRAKEY_EPSIZE, ENDPOINT_BANK_SINGLE);
+#ifdef SHARED_EP_ENABLE
+ /* Setup Shared HID Report Endpoint */
+ ConfigSuccess &= ENDPOINT_CONFIG(SHARED_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
+ SHARED_EPSIZE, ENDPOINT_BANK_SINGLE);
#endif
#ifdef RAW_ENABLE
@@ -442,12 +444,6 @@ void EVENT_USB_Device_ConfigurationChanged(void)
#endif
#endif
-#ifdef NKRO_ENABLE
- /* Setup NKRO HID Report Endpoints */
- ConfigSuccess &= ENDPOINT_CONFIG(NKRO_IN_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,
- NKRO_EPSIZE, ENDPOINT_BANK_SINGLE);
-#endif
-
#ifdef MIDI_ENABLE
ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_IN_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
ConfigSuccess &= Endpoint_ConfigureEndpoint(MIDI_STREAM_OUT_EPADDR, EP_TYPE_BULK, MIDI_STREAM_EPSIZE, ENDPOINT_BANK_SINGLE);
@@ -512,8 +508,8 @@ void EVENT_USB_Device_ControlRequest(void)
// Interface
switch (USB_ControlRequest.wIndex) {
case KEYBOARD_INTERFACE:
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
+#if defined(SHARED_EP_ENABLE) && !defined(KEYBOARD_SHARED_EP)
+ case SHARED_INTERFACE:
#endif
Endpoint_ClearSETUP();
@@ -521,7 +517,17 @@ void EVENT_USB_Device_ControlRequest(void)
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
+#if defined(SHARED_EP_ENABLE)
+ uint8_t report_id = REPORT_ID_KEYBOARD;
+ if (keyboard_protocol) {
+ report_id = Endpoint_Read_8();
+ }
+ if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
+ keyboard_led_stats = Endpoint_Read_8();
+ }
+#else
keyboard_led_stats = Endpoint_Read_8();
+#endif
Endpoint_ClearOUT();
Endpoint_ClearStatusStage();
@@ -612,16 +618,20 @@ static void send_keyboard(report_keyboard_t *report)
#ifdef MODULE_ADAFRUIT_BLE
adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys));
#elif MODULE_RN42
- bluefruit_serial_send(0xFD);
- bluefruit_serial_send(0x09);
- bluefruit_serial_send(0x01);
- for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
- bluefruit_serial_send(report->raw[i]);
- }
+ bluefruit_serial_send(0xFD);
+ bluefruit_serial_send(0x09);
+ bluefruit_serial_send(0x01);
+ bluefruit_serial_send(report->mods);
+ bluefruit_serial_send(report->reserved);
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+ bluefruit_serial_send(report->keys[i]);
+ }
#else
bluefruit_serial_send(0xFD);
- for (uint8_t i = 0; i < KEYBOARD_EPSIZE; i++) {
- bluefruit_serial_send(report->raw[i]);
+ bluefruit_serial_send(report->mods);
+ bluefruit_serial_send(report->reserved);
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+ bluefruit_serial_send(report->keys[i]);
}
#endif
}
@@ -632,30 +642,24 @@ static void send_keyboard(report_keyboard_t *report)
}
/* Select the Keyboard Report Endpoint */
+ uint8_t ep = KEYBOARD_IN_EPNUM;
+ uint8_t size = KEYBOARD_REPORT_SIZE;
#ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) {
- /* Report protocol - NKRO */
- Endpoint_SelectEndpoint(NKRO_IN_EPNUM);
-
- /* Check if write ready for a polling interval around 1ms */
- while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(4);
- if (!Endpoint_IsReadWriteAllowed()) return;
-
- /* Write Keyboard Report Data */
- Endpoint_Write_Stream_LE(report, NKRO_EPSIZE, NULL);
+ ep = SHARED_IN_EPNUM;
+ size = sizeof(struct nkro_report);
}
- else
#endif
- {
- /* Boot protocol */
- Endpoint_SelectEndpoint(KEYBOARD_IN_EPNUM);
-
- /* Check if write ready for a polling interval around 10ms */
- while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
- if (!Endpoint_IsReadWriteAllowed()) return;
+ Endpoint_SelectEndpoint(ep);
+ /* Check if write ready for a polling interval around 10ms */
+ while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
+ if (!Endpoint_IsReadWriteAllowed()) return;
- /* Write Keyboard Report Data */
- Endpoint_Write_Stream_LE(report, KEYBOARD_EPSIZE, NULL);
+ /* If we're in Boot Protocol, don't send any report ID or other funky fields */
+ if (!keyboard_protocol) {
+ Endpoint_Write_Stream_LE(&report->mods, 8, NULL);
+ } else {
+ Endpoint_Write_Stream_LE(report, size, NULL);
}
/* Finalize the stream transfer to send the last packet */
@@ -718,6 +722,7 @@ static void send_mouse(report_mouse_t *report)
*/
static void send_system(uint16_t data)
{
+#ifdef EXTRAKEY_ENABLE
uint8_t timeout = 255;
if (USB_DeviceState != DEVICE_STATE_Configured)
@@ -727,7 +732,7 @@ static void send_system(uint16_t data)
.report_id = REPORT_ID_SYSTEM,
.usage = data - SYSTEM_POWER_DOWN + 1
};
- Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
+ Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
/* Check if write ready for a polling interval around 10ms */
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@@ -735,6 +740,7 @@ static void send_system(uint16_t data)
Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
Endpoint_ClearIN();
+#endif
}
/** \brief Send Consumer
@@ -743,6 +749,7 @@ static void send_system(uint16_t data)
*/
static void send_consumer(uint16_t data)
{
+#ifdef EXTRAKEY_ENABLE
uint8_t timeout = 255;
uint8_t where = where_to_send();
@@ -786,7 +793,7 @@ static void send_consumer(uint16_t data)
.report_id = REPORT_ID_CONSUMER,
.usage = data
};
- Endpoint_SelectEndpoint(EXTRAKEY_IN_EPNUM);
+ Endpoint_SelectEndpoint(SHARED_IN_EPNUM);
/* Check if write ready for a polling interval around 10ms */
while (timeout-- && !Endpoint_IsReadWriteAllowed()) _delay_us(40);
@@ -794,6 +801,7 @@ static void send_consumer(uint16_t data)
Endpoint_Write_Stream_LE(&r, sizeof(report_extra_t), NULL);
Endpoint_ClearIN();
+#endif
}
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index cab344675..589ad23cd 100644
--- a/tmk_core/protocol/usb_descriptor.c
+++ b/tmk_core/protocol/usb_descriptor.c
@@ -47,11 +47,18 @@
/*******************************************************************************
* HID Report Descriptors
******************************************************************************/
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
-{
+#ifdef KEYBOARD_SHARED_EP
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
+#define SHARED_REPORT_STARTED
+#else
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] = {
+#endif
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x06), /* Keyboard */
HID_RI_COLLECTION(8, 0x01), /* Application */
+# ifdef KEYBOARD_SHARED_EP
+ HID_RI_REPORT_ID(8, REPORT_ID_KEYBOARD),
+# endif
HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
@@ -84,14 +91,25 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM KeyboardReport[] =
HID_RI_REPORT_SIZE(8, 0x08),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
+
+#ifndef KEYBOARD_SHARED_EP
};
+#endif
-#ifdef MOUSE_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
-{
+#if defined(MOUSE_ENABLE)
+
+# if !defined(MOUSE_SHARED_EP)
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] = {
+# elif !defined(SHARED_REPORT_STARTED)
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
+#define SHARED_REPORT_STARTED
+# endif
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x02), /* Mouse */
HID_RI_COLLECTION(8, 0x01), /* Application */
+# ifdef MOUSE_SHARED_EP
+ HID_RI_REPORT_ID(8, REPORT_ID_MOUSE),
+# endif
HID_RI_USAGE(8, 0x01), /* Pointer */
HID_RI_COLLECTION(8, 0x00), /* Physical */
@@ -133,12 +151,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM MouseReport[] =
HID_RI_END_COLLECTION(0),
HID_RI_END_COLLECTION(0),
+# ifndef MOUSE_SHARED_EP
};
+# endif
#endif
-#ifdef EXTRAKEY_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
-{
+#if defined(SHARED_EP_ENABLE) && !defined(SHARED_REPORT_STARTED)
+const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
+#endif
+# ifdef EXTRAKEY_ENABLE
HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
HID_RI_USAGE(8, 0x80), /* System Control */
HID_RI_COLLECTION(8, 0x01), /* Application */
@@ -164,6 +185,43 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ExtrakeyReport[] =
HID_RI_REPORT_COUNT(8, 1),
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_RI_END_COLLECTION(0),
+# endif
+
+# ifdef NKRO_ENABLE
+ HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
+ HID_RI_USAGE(8, 0x06), /* Keyboard */
+ HID_RI_COLLECTION(8, 0x01), /* Application */
+ HID_RI_REPORT_ID(8, REPORT_ID_NKRO),
+ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+ HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
+ HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, 0x08),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+
+ HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
+ HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
+ HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
+ HID_RI_REPORT_COUNT(8, 0x05),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
+ HID_RI_REPORT_COUNT(8, 0x01),
+ HID_RI_REPORT_SIZE(8, 0x03),
+ HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
+
+ HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
+ HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
+ HID_RI_USAGE_MAXIMUM(8, KEYBOARD_REPORT_BITS*8-1),
+ HID_RI_LOGICAL_MINIMUM(8, 0x00),
+ HID_RI_LOGICAL_MAXIMUM(8, 0x01),
+ HID_RI_REPORT_COUNT(8, KEYBOARD_REPORT_BITS*8),
+ HID_RI_REPORT_SIZE(8, 0x01),
+ HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
+ HID_RI_END_COLLECTION(0),
+# endif
+#ifdef SHARED_EP_ENABLE
};
#endif
@@ -211,42 +269,6 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM ConsoleReport[] =
};
#endif
-#ifdef NKRO_ENABLE
-const USB_Descriptor_HIDReport_Datatype_t PROGMEM NKROReport[] =
-{
- HID_RI_USAGE_PAGE(8, 0x01), /* Generic Desktop */
- HID_RI_USAGE(8, 0x06), /* Keyboard */
- HID_RI_COLLECTION(8, 0x01), /* Application */
- HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
- HID_RI_USAGE_MINIMUM(8, 0xE0), /* Keyboard Left Control */
- HID_RI_USAGE_MAXIMUM(8, 0xE7), /* Keyboard Right GUI */
- HID_RI_LOGICAL_MINIMUM(8, 0x00),
- HID_RI_LOGICAL_MAXIMUM(8, 0x01),
- HID_RI_REPORT_COUNT(8, 0x08),
- HID_RI_REPORT_SIZE(8, 0x01),
- HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
-
- HID_RI_USAGE_PAGE(8, 0x08), /* LEDs */
- HID_RI_USAGE_MINIMUM(8, 0x01), /* Num Lock */
- HID_RI_USAGE_MAXIMUM(8, 0x05), /* Kana */
- HID_RI_REPORT_COUNT(8, 0x05),
- HID_RI_REPORT_SIZE(8, 0x01),
- HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
- HID_RI_REPORT_COUNT(8, 0x01),
- HID_RI_REPORT_SIZE(8, 0x03),
- HID_RI_OUTPUT(8, HID_IOF_CONSTANT),
-
- HID_RI_USAGE_PAGE(8, 0x07), /* Key Codes */
- HID_RI_USAGE_MINIMUM(8, 0x00), /* Keyboard 0 */
- HID_RI_USAGE_MAXIMUM(8, (NKRO_EPSIZE-1)*8-1), /* Keyboard Right GUI */
- HID_RI_LOGICAL_MINIMUM(8, 0x00),
- HID_RI_LOGICAL_MAXIMUM(8, 0x01),
- HID_RI_REPORT_COUNT(8, (NKRO_EPSIZE-1)*8),
- HID_RI_REPORT_SIZE(8, 0x01),
- HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
- HID_RI_END_COLLECTION(0),
-};
-#endif
/*******************************************************************************
* Device Descriptors
@@ -303,6 +325,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
/*
* Keyboard
*/
+#ifndef KEYBOARD_SHARED_EP
.Keyboard_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -339,11 +362,12 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.EndpointSize = KEYBOARD_EPSIZE,
.PollingIntervalMS = 0x0A
},
+#endif
/*
* Mouse
*/
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
.Mouse_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
@@ -383,26 +407,31 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
#endif
/*
- * Extra
+ * Shared
*/
-#ifdef EXTRAKEY_ENABLE
- .Extrakey_Interface =
+#ifdef SHARED_EP_ENABLE
+ .Shared_Interface =
{
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
- .InterfaceNumber = EXTRAKEY_INTERFACE,
+ .InterfaceNumber = SHARED_INTERFACE,
.AlternateSetting = 0x00,
.TotalEndpoints = 1,
.Class = HID_CSCP_HIDClass,
+# ifdef KEYBOARD_SHARED_EP
+ .SubClass = HID_CSCP_BootSubclass,
+ .Protocol = HID_CSCP_KeyboardBootProtocol,
+# else
.SubClass = HID_CSCP_NonBootSubclass,
.Protocol = HID_CSCP_NonBootProtocol,
+#endif
.InterfaceStrIndex = NO_DESCRIPTOR
},
- .Extrakey_HID =
+ .Shared_HID =
{
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
@@ -410,16 +439,16 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
.CountryCode = 0x00,
.TotalReportDescriptors = 1,
.HIDReportType = HID_DTYPE_Report,
- .HIDReportLength = sizeof(ExtrakeyReport)
+ .HIDReportLength = sizeof(SharedReport)
},
- .Extrakey_INEndpoint =
+ .Shared_INEndpoint =
{
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
- .EndpointAddress = (ENDPOINT_DIR_IN | EXTRAKEY_IN_EPNUM),
+ .EndpointAddress = (ENDPOINT_DIR_IN | SHARED_IN_EPNUM),
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = EXTRAKEY_EPSIZE,
+ .EndpointSize = SHARED_EPSIZE,
.PollingIntervalMS = 0x0A
},
#endif
@@ -528,48 +557,6 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
},
#endif
- /*
- * NKRO
- */
-#ifdef NKRO_ENABLE
- .NKRO_Interface =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
-
- .InterfaceNumber = NKRO_INTERFACE,
- .AlternateSetting = 0x00,
-
- .TotalEndpoints = 1,
-
- .Class = HID_CSCP_HIDClass,
- .SubClass = HID_CSCP_NonBootSubclass,
- .Protocol = HID_CSCP_NonBootProtocol,
-
- .InterfaceStrIndex = NO_DESCRIPTOR
- },
-
- .NKRO_HID =
- {
- .Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
-
- .HIDSpec = VERSION_BCD(1,1,1),
- .CountryCode = 0x00,
- .TotalReportDescriptors = 1,
- .HIDReportType = HID_DTYPE_Report,
- .HIDReportLength = sizeof(NKROReport)
- },
-
- .NKRO_INEndpoint =
- {
- .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
-
- .EndpointAddress = (ENDPOINT_DIR_IN | NKRO_IN_EPNUM),
- .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
- .EndpointSize = NKRO_EPSIZE,
- .PollingIntervalMS = 0x01
- },
-#endif
-
#ifdef MIDI_ENABLE
.Audio_Interface_Association =
{
@@ -936,19 +923,21 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
break;
case HID_DTYPE_HID:
switch (wIndex) {
+#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE:
Address = &ConfigurationDescriptor.Keyboard_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
-#ifdef MOUSE_ENABLE
+#endif
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE:
Address = &ConfigurationDescriptor.Mouse_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
-#ifdef EXTRAKEY_ENABLE
- case EXTRAKEY_INTERFACE:
- Address = &ConfigurationDescriptor.Extrakey_HID;
+#ifdef SHARED_EP_ENABLE
+ case SHARED_INTERFACE:
+ Address = &ConfigurationDescriptor.Shared_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
#endif
@@ -963,31 +952,27 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
Address = &ConfigurationDescriptor.Console_HID;
Size = sizeof(USB_HID_Descriptor_HID_t);
break;
-#endif
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
- Address = &ConfigurationDescriptor.NKRO_HID;
- Size = sizeof(USB_HID_Descriptor_HID_t);
- break;
#endif
}
break;
case HID_DTYPE_Report:
switch (wIndex) {
+#ifndef KEYBOARD_SHARED_EP
case KEYBOARD_INTERFACE:
Address = &KeyboardReport;
Size = sizeof(KeyboardReport);
break;
-#ifdef MOUSE_ENABLE
+#endif
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
case MOUSE_INTERFACE:
Address = &MouseReport;
Size = sizeof(MouseReport);
break;
#endif
-#ifdef EXTRAKEY_ENABLE
- case EXTRAKEY_INTERFACE:
- Address = &ExtrakeyReport;
- Size = sizeof(ExtrakeyReport);
+#ifdef SHARED_EP_ENABLE
+ case SHARED_INTERFACE:
+ Address = &SharedReport;
+ Size = sizeof(SharedReport);
break;
#endif
#ifdef RAW_ENABLE
@@ -1001,12 +986,6 @@ uint16_t get_usb_descriptor(const uint16_t wValue,
Address = &ConsoleReport;
Size = sizeof(ConsoleReport);
break;
-#endif
-#ifdef NKRO_ENABLE
- case NKRO_INTERFACE:
- Address = &NKROReport;
- Size = sizeof(NKROReport);
- break;
#endif
}
break;
diff --git a/tmk_core/protocol/usb_descriptor.h b/tmk_core/protocol/usb_descriptor.h
index 586d07df6..3ca0c00b3 100644
--- a/tmk_core/protocol/usb_descriptor.h
+++ b/tmk_core/protocol/usb_descriptor.h
@@ -53,26 +53,27 @@ typedef struct
{
USB_Descriptor_Configuration_Header_t Config;
+#ifndef KEYBOARD_SHARED_EP
// Keyboard HID Interface
USB_Descriptor_Interface_t Keyboard_Interface;
USB_HID_Descriptor_HID_t Keyboard_HID;
USB_Descriptor_Endpoint_t Keyboard_INEndpoint;
+#endif
-#ifdef MOUSE_ENABLE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
// Mouse HID Interface
USB_Descriptor_Interface_t Mouse_Interface;
USB_HID_Descriptor_HID_t Mouse_HID;
USB_Descriptor_Endpoint_t Mouse_INEndpoint;
#endif
-#ifdef EXTRAKEY_ENABLE
- // Extrakey HID Interface
- USB_Descriptor_Interface_t Extrakey_Interface;
- USB_HID_Descriptor_HID_t Extrakey_HID;
- USB_Descriptor_Endpoint_t Extrakey_INEndpoint;
+#if defined(SHARED_EP_ENABLE)
+ USB_Descriptor_Interface_t Shared_Interface;
+ USB_HID_Descriptor_HID_t Shared_HID;
+ USB_Descriptor_Endpoint_t Shared_INEndpoint;
#endif
-#ifdef RAW_ENABLE
+#if defined(RAW_ENABLE)
// Raw HID Interface
USB_Descriptor_Interface_t Raw_Interface;
USB_HID_Descriptor_HID_t Raw_HID;
@@ -88,13 +89,6 @@ typedef struct
USB_Descriptor_Endpoint_t Console_OUTEndpoint;
#endif
-#ifdef NKRO_ENABLE
- // NKRO HID Interface
- USB_Descriptor_Interface_t NKRO_Interface;
- USB_HID_Descriptor_HID_t NKRO_HID;
- USB_Descriptor_Endpoint_t NKRO_INEndpoint;
-#endif
-
#ifdef MIDI_ENABLE
USB_Descriptor_Interface_Association_t Audio_Interface_Association;
// MIDI Audio Control Interface
@@ -133,133 +127,105 @@ typedef struct
/* index of interface */
-#define KEYBOARD_INTERFACE 0
-
+enum usb_interfaces {
+#if !defined(KEYBOARD_SHARED_EP)
+ KEYBOARD_INTERFACE,
+#else
+# define KEYBOARD_INTERFACE SHARED_INTERFACE
+#endif
// It is important that the Raw HID interface is at a constant
// interface number, to support Linux/OSX platforms and chrome.hid
// If Raw HID is enabled, let it be always 1.
-#ifdef RAW_ENABLE
-# define RAW_INTERFACE (KEYBOARD_INTERFACE + 1)
-#else
-# define RAW_INTERFACE KEYBOARD_INTERFACE
+#if defined(RAW_ENABLE)
+ RAW_INTERFACE,
#endif
-
-#ifdef MOUSE_ENABLE
-# define MOUSE_INTERFACE (RAW_INTERFACE + 1)
-#else
-# define MOUSE_INTERFACE RAW_INTERFACE
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
+ MOUSE_INTERFACE,
#endif
-
-#ifdef EXTRAKEY_ENABLE
-# define EXTRAKEY_INTERFACE (MOUSE_INTERFACE + 1)
-#else
-# define EXTRAKEY_INTERFACE MOUSE_INTERFACE
+#if defined(SHARED_EP_ENABLE)
+ SHARED_INTERFACE,
#endif
-
-#ifdef CONSOLE_ENABLE
-# define CONSOLE_INTERFACE (EXTRAKEY_INTERFACE + 1)
-#else
-# define CONSOLE_INTERFACE EXTRAKEY_INTERFACE
-#endif
-
-#ifdef NKRO_ENABLE
-# define NKRO_INTERFACE (CONSOLE_INTERFACE + 1)
-#else
-# define NKRO_INTERFACE CONSOLE_INTERFACE
+#if defined(CONSOLE_ENABLE)
+ CONSOLE_INTERFACE,
#endif
-
-#ifdef MIDI_ENABLE
-# define AC_INTERFACE (NKRO_INTERFACE + 1)
-# define AS_INTERFACE (NKRO_INTERFACE + 2)
-#else
-# define AS_INTERFACE NKRO_INTERFACE
+#if defined(MIDI_ENABLE)
+ AC_INTERFACE,
+ AS_INTERFACE,
#endif
-
-#ifdef VIRTSER_ENABLE
-# define CCI_INTERFACE (AS_INTERFACE + 1)
-# define CDI_INTERFACE (AS_INTERFACE + 2)
-#else
-# define CDI_INTERFACE AS_INTERFACE
+#if defined(VIRTSER_ENABLE)
+ CCI_INTERFACE,
+ CDI_INTERFACE,
#endif
+ TOTAL_INTERFACES
+};
-/* nubmer of interfaces */
-#define TOTAL_INTERFACES (CDI_INTERFACE + 1)
-
+#define NEXT_EPNUM __COUNTER__
-// Endopoint number and size
-#define KEYBOARD_IN_EPNUM 1
-
-#ifdef MOUSE_ENABLE
-# define MOUSE_IN_EPNUM (KEYBOARD_IN_EPNUM + 1)
+enum usb_endpoints {
+ __unused_epnum__ = NEXT_EPNUM, /* EP numbering starts at 1 */
+#if !defined(KEYBOARD_SHARED_EP)
+ KEYBOARD_IN_EPNUM = NEXT_EPNUM,
#else
-# define MOUSE_IN_EPNUM KEYBOARD_IN_EPNUM
+# define KEYBOARD_IN_EPNUM SHARED_IN_EPNUM
#endif
-
-#ifdef EXTRAKEY_ENABLE
-# define EXTRAKEY_IN_EPNUM (MOUSE_IN_EPNUM + 1)
+#if defined(MOUSE_ENABLE) && !defined(MOUSE_SHARED_EP)
+ MOUSE_IN_EPNUM = NEXT_EPNUM,
#else
-# define EXTRAKEY_IN_EPNUM MOUSE_IN_EPNUM
+# define MOUSE_IN_EPNUM SHARED_IN_EPNUM
#endif
-
-#ifdef RAW_ENABLE
-# define RAW_IN_EPNUM (EXTRAKEY_IN_EPNUM + 1)
-# define RAW_OUT_EPNUM (EXTRAKEY_IN_EPNUM + 2)
-#else
-# define RAW_OUT_EPNUM EXTRAKEY_IN_EPNUM
+#if defined(RAW_ENABLE)
+ RAW_IN_EPNUM = NEXT_EPNUM,
+ RAW_OUT_EPNUM = NEXT_EPNUM,
#endif
-
-#ifdef CONSOLE_ENABLE
-# define CONSOLE_IN_EPNUM (RAW_OUT_EPNUM + 1)
+#if defined(SHARED_EP_ENABLE)
+ SHARED_IN_EPNUM = NEXT_EPNUM,
+#endif
+#if defined(CONSOLE_ENABLE)
+ CONSOLE_IN_EPNUM = NEXT_EPNUM,
#ifdef PROTOCOL_CHIBIOS
// ChibiOS has enough memory and descriptor to actually enable the endpoint
// It could use the same endpoint numbers, as that's supported by ChibiOS
// But the QMK code currently assumes that the endpoint numbers are different
-# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 2)
+ CONSOLE_OUT_EPNUM = NEXT_EPNUM,
#else
-# define CONSOLE_OUT_EPNUM (RAW_OUT_EPNUM + 1)
+#define CONSOLE_OUT_EPNUM CONSOLE_IN_EPNUM
#endif
-#else
-# define CONSOLE_OUT_EPNUM RAW_OUT_EPNUM
#endif
-
-#ifdef NKRO_ENABLE
-# define NKRO_IN_EPNUM (CONSOLE_OUT_EPNUM + 1)
-#else
-# define NKRO_IN_EPNUM CONSOLE_OUT_EPNUM
-#endif
-
#ifdef MIDI_ENABLE
-# define MIDI_STREAM_IN_EPNUM (NKRO_IN_EPNUM + 1)
-// # define MIDI_STREAM_OUT_EPNUM (NKRO_IN_EPNUM + 1)
-# define MIDI_STREAM_OUT_EPNUM (NKRO_IN_EPNUM + 2)
+ MIDI_STREAM_IN_EPNUM = NEXT_EPNUM,
+ MIDI_STREAM_OUT_EPNUM = NEXT_EPNUM,
# define MIDI_STREAM_IN_EPADDR (ENDPOINT_DIR_IN | MIDI_STREAM_IN_EPNUM)
# define MIDI_STREAM_OUT_EPADDR (ENDPOINT_DIR_OUT | MIDI_STREAM_OUT_EPNUM)
-#else
-# define MIDI_STREAM_OUT_EPNUM NKRO_IN_EPNUM
#endif
-
#ifdef VIRTSER_ENABLE
-# define CDC_NOTIFICATION_EPNUM (MIDI_STREAM_OUT_EPNUM + 1)
-# define CDC_IN_EPNUM (MIDI_STREAM_OUT_EPNUM + 2)
-# define CDC_OUT_EPNUM (MIDI_STREAM_OUT_EPNUM + 3)
+ CDC_NOTIFICATION_EPNUM = NEXT_EPNUM,
+ CDC_IN_EPNUM = NEXT_EPNUM,
+ CDC_OUT_EPNUM = NEXT_EPNUM,
# define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | CDC_NOTIFICATION_EPNUM)
# define CDC_IN_EPADDR (ENDPOINT_DIR_IN | CDC_IN_EPNUM)
# define CDC_OUT_EPADDR (ENDPOINT_DIR_OUT | CDC_OUT_EPNUM)
-#else
-# define CDC_OUT_EPNUM MIDI_STREAM_OUT_EPNUM
#endif
+};
+
+#if defined(PROTOCOL_LUFA)
+/* LUFA tells us total endpoints including control */
+#define MAX_ENDPOINTS (ENDPOINT_TOTAL_ENDPOINTS - 1)
+#elif defined(PROTOCOL_CHIBIOS)
+/* ChibiOS gives us number of available user endpoints, not control */
+#define MAX_ENDPOINTS USB_MAX_ENDPOINTS
+#endif
+/* TODO - ARM_ATSAM */
+
-#if (defined(PROTOCOL_LUFA) && CDC_OUT_EPNUM > (ENDPOINT_TOTAL_ENDPOINTS - 1)) || \
- (defined(PROTOCOL_CHIBIOS) && CDC_OUT_EPNUM > USB_MAX_ENDPOINTS)
-# error "There are not enough available endpoints to support all functions. Remove some in the rules.mk file.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL, STENO)"
+#if (NEXT_EPNUM - 1) > MAX_ENDPOINTS
+# error There are not enough available endpoints to support all functions. Remove some in the rules.mk file. (MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL, STENO)
#endif
#define KEYBOARD_EPSIZE 8
+#define SHARED_EPSIZE 32
#define MOUSE_EPSIZE 8
-#define EXTRAKEY_EPSIZE 8
#define RAW_EPSIZE 32
#define CONSOLE_EPSIZE 32
-#define NKRO_EPSIZE 32
#define MIDI_STREAM_EPSIZE 64
#define CDC_NOTIFICATION_EPSIZE 8
#define CDC_EPSIZE 16
--
cgit v1.2.3-70-g09d2
From 90f9fb4eee0da25e5408e54ed872c6da2a40c5f3 Mon Sep 17 00:00:00 2001
From: mtei <2170248+mtei@users.noreply.github.com>
Date: Fri, 5 Oct 2018 14:54:22 +0900
Subject: Fixed docs/newbs_testing_debugging.md and tmk_core/common/print.h
---
docs/newbs_testing_debugging.md | 2 +-
tmk_core/common/print.h | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
(limited to 'tmk_core/common')
diff --git a/docs/newbs_testing_debugging.md b/docs/newbs_testing_debugging.md
index 1d8021dec..45509110a 100644
--- a/docs/newbs_testing_debugging.md
+++ b/docs/newbs_testing_debugging.md
@@ -28,6 +28,6 @@ Sometimes it's useful to print debug messages from within your [custom code](cus
After that you can use a few different print functions:
* `print("string")`: Print a simple string.
-* `sprintf("%s string", var)`: Print a formatted string
+* `uprintf("%s string", var)`: Print a formatted string
* `dprint("string")` Print a simple string, but only when debug mode is enabled
* `dprintf("%s string", var)`: Print a formatted string, but only when debug mode is enabled
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index 06c6cbd7f..2d7184bd0 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -60,7 +60,7 @@
# define println(s) xputs(PSTR(s "\r\n"))
# define uprint(s) print(s)
# define uprintln(s) println(s)
-# define uprintf(fmt, ...) xprintf(fmt, ...)
+# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# endif /* USER_PRINT / NORMAL PRINT */
@@ -125,7 +125,7 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
# define println(s) xprintf(s "\r\n")
# define uprint(s) print(s)
# define uprintln(s) println(s)
-# define uprintf(fmt, ...) xprintf(fmt, ...)
+# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# endif /* USER_PRINT / NORMAL PRINT */
@@ -141,19 +141,19 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
# define xprintf(fmt, ...)
// Create user print defines
-# define uprintf(fmt, ...) __xprintf(fmt, ...)
+# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define uprint(s) xprintf(s)
# define uprintln(s) xprintf(s "\r\n")
# else /* NORMAL PRINT */
// Create user & normal print defines
-# define xprintf(fmt, ...) __xprintf(fmt, ...)
+# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define print(s) xprintf(s)
# define println(s) xprintf(s "\r\n")
# define uprint(s) print(s)
# define uprintln(s) println(s)
-# define uprintf(fmt, ...) xprintf(fmt, ...)
+# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# endif /* USER_PRINT / NORMAL PRINT */
--
cgit v1.2.3-70-g09d2
From 8b85ec2a987d378fb95eea1468eadea70aec2cbf Mon Sep 17 00:00:00 2001
From: Giuseppe Rota
Date: Wed, 28 Nov 2018 17:19:07 +0100
Subject: Add Extrakey support for Brightness up/down (#4477)
---
docs/keycode.txt | 2 ++
docs/keycodes.md | 2 ++
docs/keycodes_basic.md | 2 ++
quantum/keymap_common.c | 2 +-
tmk_core/common/keycode.h | 6 +++++-
tmk_core/common/report.h | 7 ++++++-
6 files changed, 18 insertions(+), 3 deletions(-)
(limited to 'tmk_core/common')
diff --git a/docs/keycode.txt b/docs/keycode.txt
index b2070f711..bd93b0a94 100644
--- a/docs/keycode.txt
+++ b/docs/keycode.txt
@@ -209,6 +209,8 @@ KC_WWW_FORWARD KC_WFWD
KC_WWW_STOP KC_WSTP
KC_WWW_REFRESH KC_WREF
KC_WWW_FAVORITES KC_WFAV
+KC_BRIGHTNESS_UP KC_BRIU
+KC_BRIGHTNESS_DOWN KC_BRID
/* Mousekey */
KC_MS_UP KC_MS_U Mouse Cursor Up
KC_MS_DOWN KC_MS_D Mouse Cursor Down
diff --git a/docs/keycodes.md b/docs/keycodes.md
index 1c5f46d6e..75b01389c 100644
--- a/docs/keycodes.md
+++ b/docs/keycodes.md
@@ -203,6 +203,8 @@ This is a reference only. Each group of keys links to the page documenting their
|`KC_WWW_FAVORITES` |`KC_WFAV` |Browser Favorites (Windows) |
|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD` |Next Track (macOS) |
|`KC_MEDIA_REWIND` |`KC_MRWD` |Previous Track (macOS) |
+|`KC_BRIGHTNESS_UP` |`KC_BRIU` |Brightness Up |
+|`KC_BRIGHTNESS_DOWN` |`KC_BRID` |Brightness Down |
## [Quantum Keycodes](quantum_keycodes.md#qmk-keycodes)
diff --git a/docs/keycodes_basic.md b/docs/keycodes_basic.md
index ada9cc0e5..9cc00f032 100644
--- a/docs/keycodes_basic.md
+++ b/docs/keycodes_basic.md
@@ -219,6 +219,8 @@ Windows and macOS use different keycodes for "next track" and "previous track".
|`KC_WWW_FAVORITES` |`KC_WFAV`|Browser Favorites (Windows) |
|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD`|Next Track (macOS) |
|`KC_MEDIA_REWIND` |`KC_MRWD`|Previous Track (macOS) |
+|`KC_BRIGHTNESS_UP` |`KC_BRIU`|Brightness Up |
+|`KC_BRIGHTNESS_DOWN` |`KC_BRID`|Brightness Down |
## Number Pad
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 50af15d62..f6c8b70d2 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -64,7 +64,7 @@ action_t action_for_key(uint8_t layer, keypos_t key)
case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
break;
- case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
+ case KC_AUDIO_MUTE ... KC_BRIGHTNESS_DOWN:
action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
break;
case KC_MS_UP ... KC_MS_ACCEL2:
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index 61642ae84..d6fef2beb 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -33,7 +33,7 @@ along with this program. If not, see .
#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
-#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_MRWD)
+#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID)
#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
@@ -170,6 +170,8 @@ along with this program. If not, see .
#define KC_WFAV KC_WWW_FAVORITES
#define KC_MFFD KC_MEDIA_FAST_FORWARD
#define KC_MRWD KC_MEDIA_REWIND
+#define KC_BRIU KC_BRIGHTNESS_UP
+#define KC_BRID KC_BRIGHTNESS_DOWN
/* Mouse Keys */
#define KC_MS_U KC_MS_UP
@@ -457,6 +459,8 @@ enum internal_special_keycodes {
KC_WWW_FAVORITES,
KC_MEDIA_FAST_FORWARD,
KC_MEDIA_REWIND,
+ KC_BRIGHTNESS_UP,
+ KC_BRIGHTNESS_DOWN,
/* Fn keys */
KC_FN0 = 0xC0,
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 5a1a6b19c..eb9afb727 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -38,6 +38,7 @@ along with this program. If not, see .
/* Consumer Page(0x0C)
* following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx
+ * see also https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/display-brightness-control
*/
#define AUDIO_MUTE 0x00E2
#define AUDIO_VOL_UP 0x00E9
@@ -47,6 +48,8 @@ along with this program. If not, see .
#define TRANSPORT_STOP 0x00B7
#define TRANSPORT_STOP_EJECT 0x00CC
#define TRANSPORT_PLAY_PAUSE 0x00CD
+#define BRIGHTNESSUP 0x006F
+#define BRIGHTNESSDOWN 0x0070
/* application launch */
#define AL_CC_CONFIG 0x0183
#define AL_EMAIL 0x018A
@@ -189,7 +192,9 @@ typedef struct {
(key == KC_WWW_FORWARD ? AC_FORWARD : \
(key == KC_WWW_STOP ? AC_STOP : \
(key == KC_WWW_REFRESH ? AC_REFRESH : \
- (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))
+ (key == KC_BRIGHTNESS_UP ? BRIGHTNESSUP : \
+ (key == KC_BRIGHTNESS_DOWN ? BRIGHTNESSDOWN : \
+ (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))))
uint8_t has_anykey(report_keyboard_t* keyboard_report);
uint8_t get_first_key(report_keyboard_t* keyboard_report);
--
cgit v1.2.3-70-g09d2
From 4099536c0e7a099b181a80e483b4b95f389b5a7e Mon Sep 17 00:00:00 2001
From: ishtob
Date: Tue, 4 Dec 2018 11:04:57 -0500
Subject: adding Hadron v3 keyboard, QWIIC devices support, haptic feedback
support (#4462)
* add initial support for hadron ver3
* add initial support for hadron ver3
* pull qwiic support for micro_led to be modified for use in hadron's 64x24 ssd1306 oled display
* initial work on OLED using qwiic driver
* early work to get 128x32 oled working by redefining qwiic micro oled parameters. Currently working, but would affect qwiic's micro oled functionality
* moved oled defines to config.h and added ifndef to micro_oled driver
* WORKING :D - note, still work in progress to get the start location correct on the 128x32 display.
* added equation to automatically calculate display offset based on screen width
* adding time-out timer to oled display
* changed read lock staus via read_led_state
* lock indications fixes
* Added scroll lock indication to oled
* add support for DRV2605 haptic driver
* Improve readabiity of DRV2605 driver.
-added typedef for waveform library
-added unions for registers
* Update keyboards/hadron/ver2/keymaps/default/config.h
Co-Authored-By: ishtob
* Update keyboards/hadron/ver2/keymaps/default/config.h
Co-Authored-By: ishtob
* Update keyboards/hadron/ver2/keymaps/default/config.h
Co-Authored-By: ishtob
* Update keyboards/hadron/ver2/keymaps/default/config.h
Co-Authored-By: ishtob
* Fixes for PR
* PR fixes
* fix old persistent layer function to use new set_single_persistent_default_layer
* fix issues with changing makefile defines that broken per-key haptic pulse
* Comment fixes
* Add definable parameter and auto-calibration based on motor choice
---
common_features.mk | 9 +
drivers/arm/i2c_master.c | 12 +-
drivers/arm/i2c_master.h | 1 +
drivers/haptic/DRV2605L.c | 129 +++
drivers/haptic/DRV2605L.h | 394 +++++++
drivers/qwiic/micro_oled.c | 691 ++++++++++++
drivers/qwiic/micro_oled.h | 134 +++
drivers/qwiic/qwiic.c | 31 +
drivers/qwiic/qwiic.h | 28 +
drivers/qwiic/qwiic.mk | 18 +
drivers/qwiic/util/font5x7.h | 288 +++++
drivers/qwiic/util/font8x16.h | 127 +++
keyboards/hadron/config.h | 10 +-
keyboards/hadron/hadron.c | 24 -
keyboards/hadron/hadron.h | 4 +-
keyboards/hadron/keymaps/default/config.h | 20 -
keyboards/hadron/keymaps/default/keymap.c | 493 --------
keyboards/hadron/keymaps/default/readme.md | 2 -
keyboards/hadron/keymaps/default/rules.mk | 24 -
keyboards/hadron/keymaps/readme.md | 23 -
keyboards/hadron/keymaps/side_numpad/config.h | 20 -
keyboards/hadron/keymaps/side_numpad/keymap.c | 502 ---------
keyboards/hadron/keymaps/side_numpad/readme.md | 2 -
keyboards/hadron/keymaps/side_numpad/rules.mk | 26 -
keyboards/hadron/readme.md | 4 +-
keyboards/hadron/rules.mk | 73 --
keyboards/hadron/ver2/config.h | 11 +
keyboards/hadron/ver2/keymaps/default/config.h | 9 +
keyboards/hadron/ver2/keymaps/default/keymap.c | 448 ++++++++
keyboards/hadron/ver2/keymaps/default/readme.md | 2 +
keyboards/hadron/ver2/keymaps/readme.md | 23 +
keyboards/hadron/ver2/keymaps/side_numpad/config.h | 8 +
keyboards/hadron/ver2/keymaps/side_numpad/keymap.c | 484 ++++++++
.../hadron/ver2/keymaps/side_numpad/readme.md | 2 +
keyboards/hadron/ver2/keymaps/side_numpad/rules.mk | 26 +
keyboards/hadron/ver2/rules.mk | 77 +-
keyboards/hadron/ver2/ver2.c | 27 +-
.../ver3/boards/GENERIC_STM32_F303XC/board.c | 126 +++
.../ver3/boards/GENERIC_STM32_F303XC/board.h | 1187 ++++++++++++++++++++
.../ver3/boards/GENERIC_STM32_F303XC/board.mk | 5 +
keyboards/hadron/ver3/bootloader_defs.h | 7 +
keyboards/hadron/ver3/chconf.h | 520 +++++++++
keyboards/hadron/ver3/config.h | 192 ++++
keyboards/hadron/ver3/halconf.h | 388 +++++++
keyboards/hadron/ver3/keymaps/default/config.h | 1 +
keyboards/hadron/ver3/keymaps/default/keymap.c | 295 +++++
keyboards/hadron/ver3/keymaps/default/readme.md | 2 +
keyboards/hadron/ver3/keymaps/readme.md | 23 +
keyboards/hadron/ver3/matrix.c | 195 ++++
keyboards/hadron/ver3/mcuconf.h | 257 +++++
keyboards/hadron/ver3/rev3.h | 21 +
keyboards/hadron/ver3/rules.mk | 57 +
keyboards/hadron/ver3/ver3.c | 196 ++++
keyboards/hadron/ver3/ver3.h | 21 +
keyboards/helix/rev1/keymaps/OLED_sample/rules.mk | 25 -
tmk_core/common/action_layer.h | 4 +-
tmk_core/common/keyboard.c | 10 +
57 files changed, 6487 insertions(+), 1251 deletions(-)
create mode 100644 drivers/haptic/DRV2605L.c
create mode 100644 drivers/haptic/DRV2605L.h
create mode 100644 drivers/qwiic/micro_oled.c
create mode 100644 drivers/qwiic/micro_oled.h
create mode 100644 drivers/qwiic/qwiic.c
create mode 100644 drivers/qwiic/qwiic.h
create mode 100644 drivers/qwiic/qwiic.mk
create mode 100644 drivers/qwiic/util/font5x7.h
create mode 100644 drivers/qwiic/util/font8x16.h
delete mode 100644 keyboards/hadron/keymaps/default/config.h
delete mode 100644 keyboards/hadron/keymaps/default/keymap.c
delete mode 100644 keyboards/hadron/keymaps/default/readme.md
delete mode 100644 keyboards/hadron/keymaps/default/rules.mk
delete mode 100644 keyboards/hadron/keymaps/readme.md
delete mode 100644 keyboards/hadron/keymaps/side_numpad/config.h
delete mode 100644 keyboards/hadron/keymaps/side_numpad/keymap.c
delete mode 100644 keyboards/hadron/keymaps/side_numpad/readme.md
delete mode 100644 keyboards/hadron/keymaps/side_numpad/rules.mk
create mode 100644 keyboards/hadron/ver2/keymaps/default/config.h
create mode 100644 keyboards/hadron/ver2/keymaps/default/keymap.c
create mode 100644 keyboards/hadron/ver2/keymaps/default/readme.md
create mode 100644 keyboards/hadron/ver2/keymaps/readme.md
create mode 100644 keyboards/hadron/ver2/keymaps/side_numpad/config.h
create mode 100644 keyboards/hadron/ver2/keymaps/side_numpad/keymap.c
create mode 100644 keyboards/hadron/ver2/keymaps/side_numpad/readme.md
create mode 100644 keyboards/hadron/ver2/keymaps/side_numpad/rules.mk
create mode 100644 keyboards/hadron/ver3/boards/GENERIC_STM32_F303XC/board.c
create mode 100644 keyboards/hadron/ver3/boards/GENERIC_STM32_F303XC/board.h
create mode 100644 keyboards/hadron/ver3/boards/GENERIC_STM32_F303XC/board.mk
create mode 100644 keyboards/hadron/ver3/bootloader_defs.h
create mode 100644 keyboards/hadron/ver3/chconf.h
create mode 100644 keyboards/hadron/ver3/config.h
create mode 100644 keyboards/hadron/ver3/halconf.h
create mode 100644 keyboards/hadron/ver3/keymaps/default/config.h
create mode 100644 keyboards/hadron/ver3/keymaps/default/keymap.c
create mode 100644 keyboards/hadron/ver3/keymaps/default/readme.md
create mode 100644 keyboards/hadron/ver3/keymaps/readme.md
create mode 100644 keyboards/hadron/ver3/matrix.c
create mode 100644 keyboards/hadron/ver3/mcuconf.h
create mode 100644 keyboards/hadron/ver3/rev3.h
create mode 100644 keyboards/hadron/ver3/rules.mk
create mode 100644 keyboards/hadron/ver3/ver3.c
create mode 100644 keyboards/hadron/ver3/ver3.h
delete mode 100644 keyboards/helix/rev1/keymaps/OLED_sample/rules.mk
(limited to 'tmk_core/common')
diff --git a/common_features.mk b/common_features.mk
index 8f53a82aa..bd88e04d6 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -225,6 +225,13 @@ ifeq ($(strip $(ENCODER_ENABLE)), yes)
OPT_DEFS += -DENCODER_ENABLE
endif
+ifeq ($(strip $(HAPTIC_ENABLE)), DRV2605L)
+ COMMON_VPATH += $(DRIVER_PATH)/haptic
+ SRC += DRV2605L.c
+ SRC += i2c_master.c
+ OPT_DEFS += -DDRV2605L
+endif
+
ifeq ($(strip $(HD44780_ENABLE)), yes)
SRC += drivers/avr/hd44780.c
OPT_DEFS += -DHD44780_ENABLE
@@ -240,6 +247,8 @@ ifeq ($(strip $(LEADER_ENABLE)), yes)
OPT_DEFS += -DLEADER_ENABLE
endif
+include $(DRIVER_PATH)/qwiic/qwiic.mk
+
QUANTUM_SRC:= \
$(QUANTUM_DIR)/quantum.c \
$(QUANTUM_DIR)/keymap_common.c \
diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c
index de5843839..ab962ea95 100644
--- a/drivers/arm/i2c_master.c
+++ b/drivers/arm/i2c_master.c
@@ -32,7 +32,7 @@
static uint8_t i2c_address;
-// This configures the I2C clock to 400Mhz assuming a 72Mhz clock
+// This configures the I2C clock to 400khz assuming a 72Mhz clock
// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
static const I2CConfig i2cconfig = {
STM32_TIMINGR_PRESC(15U) |
@@ -45,10 +45,14 @@ static const I2CConfig i2cconfig = {
__attribute__ ((weak))
void i2c_init(void)
{
- setPinInput(B6); // Try releasing special pins for a short time
- setPinInput(B7);
- chThdSleepMilliseconds(10);
+ //palSetGroupMode(GPIOB, GPIOB_PIN6 | GPIOB_PIN7, 0, PAL_MODE_INPUT);
+
+ // Try releasing special pins for a short time
+ palSetPadMode(GPIOB, 6, PAL_MODE_INPUT);
+ palSetPadMode(GPIOB, 7, PAL_MODE_INPUT);
+ chThdSleepMilliseconds(10);
+
palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP);
diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h
index 591fa7f77..392760328 100644
--- a/drivers/arm/i2c_master.h
+++ b/drivers/arm/i2c_master.h
@@ -34,6 +34,7 @@ void i2c_init(void);
uint8_t i2c_start(uint8_t address);
uint8_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
+uint8_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length);
uint8_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
uint8_t i2c_readReg(uint8_t devaddr, uint8_t* regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
uint8_t i2c_stop(uint16_t timeout);
diff --git a/drivers/haptic/DRV2605L.c b/drivers/haptic/DRV2605L.c
new file mode 100644
index 000000000..97ca292b9
--- /dev/null
+++ b/drivers/haptic/DRV2605L.c
@@ -0,0 +1,129 @@
+/* Copyright 2018 ishtob
+ * Driver for DRV2605L written for 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 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 .
+ */
+#include "DRV2605L.h"
+#include "print.h"
+#include
+#include
+#include
+
+
+uint8_t DRV2605L_transfer_buffer[20];
+uint8_t DRV2605L_tx_register[0];
+uint8_t DRV2605L_read_buffer[0];
+uint8_t DRV2605L_read_register;
+
+
+void DRV_write(uint8_t drv_register, uint8_t settings) {
+ DRV2605L_transfer_buffer[0] = drv_register;
+ DRV2605L_transfer_buffer[1] = settings;
+ i2c_transmit(DRV2605L_BASE_ADDRESS << 1, DRV2605L_transfer_buffer, 2, 100);
+}
+
+uint8_t DRV_read(uint8_t regaddress) {
+ DRV2605L_tx_register[0] = regaddress;
+ if (MSG_OK != i2c_transmit_receive(DRV2605L_BASE_ADDRESS << 1,
+ DRV2605L_tx_register, 1,
+ DRV2605L_read_buffer, 1
+)){
+ printf("err reading reg \n");
+ }
+ DRV2605L_read_register = (uint8_t)DRV2605L_read_buffer[0];
+return DRV2605L_read_register;
+}
+
+void DRV_init(void)
+{
+ i2c_init();
+ i2c_start(DRV2605L_BASE_ADDRESS);
+
+ /* 0x07 sets DRV2605 into calibration mode */
+ DRV_write(DRV_MODE,0x07);
+
+// DRV_write(DRV_FEEDBACK_CTRL,0xB6);
+
+ #if FB_ERM_LRA == 0
+ /* ERM settings */
+ DRV_write(DRV_RATED_VOLT, (RATED_VOLTAGE/21.33)*1000);
+ #if ERM_OPEN_LOOP == 0
+ DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (((V_PEAK*(DRIVE_TIME+BLANKING_TIME+IDISS_TIME))/0.02133)/(DRIVE_TIME-0.0003)));
+ #elif ERM_OPEN_LOOP == 1
+ DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK/0.02196));
+ #endif
+ #elif FB_ERM_LRA == 1
+ DRV_write(DRV_RATED_VOLT, ((V_RMS * sqrt(1 - ((4 * ((150+(SAMPLE_TIME*50))*0.000001)) + 0.0003)* F_LRA)/0.02071)));
+ #if LRA_OPEN_LOOP == 0
+ DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, ((V_PEAK/sqrt(1-(F_LRA*0.0008))/0.02133)));
+ #elif LRA_OPEN_LOOP == 1
+ DRV_write(DRV_OVERDRIVE_CLAMP_VOLT, (V_PEAK/0.02196));
+ #endif
+ #endif
+
+ DRVREG_FBR FB_SET;
+ FB_SET.Bits.ERM_LRA = FB_ERM_LRA;
+ FB_SET.Bits.BRAKE_FACTOR = FB_BRAKEFACTOR;
+ FB_SET.Bits.LOOP_GAIN =FB_LOOPGAIN;
+ FB_SET.Bits.BEMF_GAIN = 0; /* auto-calibration populates this field*/
+ DRV_write(DRV_FEEDBACK_CTRL, (uint8_t) FB_SET.Byte);
+ DRVREG_CTRL1 C1_SET;
+ C1_SET.Bits.C1_DRIVE_TIME = DRIVE_TIME;
+ C1_SET.Bits.C1_AC_COUPLE = AC_COUPLE;
+ C1_SET.Bits.C1_STARTUP_BOOST = STARTUP_BOOST;
+ DRV_write(DRV_CTRL_1, (uint8_t) C1_SET.Byte);
+ DRVREG_CTRL2 C2_SET;
+ C2_SET.Bits.C2_BIDIR_INPUT = BIDIR_INPUT;
+ C2_SET.Bits.C2_BRAKE_STAB = BRAKE_STAB;
+ C2_SET.Bits.C2_SAMPLE_TIME = SAMPLE_TIME;
+ C2_SET.Bits.C2_BLANKING_TIME = BLANKING_TIME;
+ C2_SET.Bits.C2_IDISS_TIME = IDISS_TIME;
+ DRV_write(DRV_CTRL_2, (uint8_t) C2_SET.Byte);
+ DRVREG_CTRL3 C3_SET;
+ C3_SET.Bits.C3_LRA_OPEN_LOOP = LRA_OPEN_LOOP;
+ C3_SET.Bits.C3_N_PWM_ANALOG = N_PWM_ANALOG;
+ C3_SET.Bits.C3_LRA_DRIVE_MODE = LRA_DRIVE_MODE;
+ C3_SET.Bits.C3_DATA_FORMAT_RTO = DATA_FORMAT_RTO;
+ C3_SET.Bits.C3_SUPPLY_COMP_DIS = SUPPLY_COMP_DIS;
+ C3_SET.Bits.C3_ERM_OPEN_LOOP = ERM_OPEN_LOOP;
+ C3_SET.Bits.C3_NG_THRESH = NG_THRESH;
+ DRV_write(DRV_CTRL_3, (uint8_t) C3_SET.Byte);
+ DRVREG_CTRL4 C4_SET;
+ C4_SET.Bits.C4_ZC_DET_TIME = ZC_DET_TIME;
+ C4_SET.Bits.C4_AUTO_CAL_TIME = AUTO_CAL_TIME;
+ DRV_write(DRV_CTRL_4, (uint8_t) C4_SET.Byte);
+ DRV_write(DRV_LIB_SELECTION,LIB_SELECTION);
+ //start autocalibration
+ DRV_write(DRV_GO, 0x01);
+
+ /* 0x00 sets DRV2605 out of standby and to use internal trigger
+ * 0x01 sets DRV2605 out of standby and to use external trigger */
+ DRV_write(DRV_MODE,0x00);
+
+ /* 0x06: LRA library */
+ DRV_write(DRV_WAVEFORM_SEQ_1, 0x01);
+
+ /* 0xB9: LRA, 4x brake factor, medium gain, 7.5x back EMF
+ * 0x39: ERM, 4x brake factor, medium gain, 1.365x back EMF */
+
+ /* TODO: setup auto-calibration as part of initiation */
+
+}
+
+void DRV_pulse(uint8_t sequence)
+{
+ DRV_write(DRV_GO, 0x00);
+ DRV_write(DRV_WAVEFORM_SEQ_1, sequence);
+ DRV_write(DRV_GO, 0x01);
+}
\ No newline at end of file
diff --git a/drivers/haptic/DRV2605L.h b/drivers/haptic/DRV2605L.h
new file mode 100644
index 000000000..de9d294e9
--- /dev/null
+++ b/drivers/haptic/DRV2605L.h
@@ -0,0 +1,394 @@
+/* Copyright 2018 ishtob
+ * Driver for DRV2605L written for 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#pragma once
+#include "i2c_master.h"
+
+/* Initialization settings
+
+ * Feedback Control Settings */
+#ifndef FB_ERM_LRA
+#define FB_ERM_LRA 1 /* For ERM:0 or LRA:1*/
+#endif
+#ifndef FB_BRAKEFACTOR
+#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */
+#endif
+#ifndef FB_LOOPGAIN
+#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */
+#endif
+
+#ifndef RATED_VOLTAGE
+#define RATED_VOLTAGE 2 /* 2v as safe range in case device voltage is not set */
+#ifndef V_PEAK
+#define V_PEAK 2.8
+#endif
+#endif
+
+/* LRA specific settings */
+#if FB_ERM_LRA == 1
+#ifndef V_RMS
+#define V_RMS 2.0
+#endif
+#ifndef V_PEAK
+#define V_PEAK 2.1
+#endif
+#ifndef F_LRA
+#define F_LRA 205
+#endif
+#endif
+
+/* Library Selection */
+#ifndef LIB_SELECTION
+#if FB_ERM_LRA == 1
+#define LIB_SELECTION 6 /* For Empty:0' TS2200 library A to D:1-5, LRA Library: 6 */
+#else
+#define LIB_SELECTION 1
+#endif
+#endif
+
+/* Control 1 register settings */
+#ifndef DRIVE_TIME
+#define DRIVE_TIME 25
+#endif
+#ifndef AC_COUPLE
+#define AC_COUPLE 0
+#endif
+#ifndef STARTUP_BOOST
+#define STARTUP_BOOST 1
+#endif
+
+/* Control 2 Settings */
+#ifndef BIDIR_INPUT
+#define BIDIR_INPUT 1
+#endif
+#ifndef BRAKE_STAB
+#define BRAKE_STAB 1 /* Loopgain is reduced when braking is almost complete to improve stability */
+#endif
+#ifndef SAMPLE_TIME
+#define SAMPLE_TIME 3
+#endif
+#ifndef BLANKING_TIME
+#define BLANKING_TIME 1
+#endif
+#ifndef IDISS_TIME
+#define IDISS_TIME 1
+#endif
+
+/* Control 3 settings */
+#ifndef NG_THRESH
+#define NG_THRESH 2
+#endif
+#ifndef ERM_OPEN_LOOP
+#define ERM_OPEN_LOOP 1
+#endif
+#ifndef SUPPLY_COMP_DIS
+#define SUPPLY_COMP_DIS 0
+#endif
+#ifndef DATA_FORMAT_RTO
+#define DATA_FORMAT_RTO 0
+#endif
+#ifndef LRA_DRIVE_MODE
+#define LRA_DRIVE_MODE 0
+#endif
+#ifndef N_PWM_ANALOG
+#define N_PWM_ANALOG 0
+#endif
+#ifndef LRA_OPEN_LOOP
+#define LRA_OPEN_LOOP 0
+#endif
+
+/* Control 4 settings */
+#ifndef ZC_DET_TIME
+#define ZC_DET_TIME 0
+#endif
+#ifndef AUTO_CAL_TIME
+#define AUTO_CAL_TIME 3
+#endif
+
+/* register defines -------------------------------------------------------- */
+#define DRV2605L_BASE_ADDRESS 0x5A /* DRV2605L Base address */
+#define DRV_STATUS 0x00
+#define DRV_MODE 0x01
+#define DRV_RTP_INPUT 0x02
+#define DRV_LIB_SELECTION 0x03
+#define DRV_WAVEFORM_SEQ_1 0x04
+#define DRV_WAVEFORM_SEQ_2 0x05
+#define DRV_WAVEFORM_SEQ_3 0x06
+#define DRV_WAVEFORM_SEQ_4 0x07
+#define DRV_WAVEFORM_SEQ_5 0x08
+#define DRV_WAVEFORM_SEQ_6 0x09
+#define DRV_WAVEFORM_SEQ_7 0x0A
+#define DRV_WAVEFORM_SEQ_8 0x0B
+#define DRV_GO 0x0C
+#define DRV_OVERDRIVE_TIME_OFFSET 0x0D
+#define DRV_SUSTAIN_TIME_OFFSET_P 0x0E
+#define DRV_SUSTAIN_TIME_OFFSET_N 0x0F
+#define DRV_BRAKE_TIME_OFFSET 0x10
+#define DRV_AUDIO_2_VIBE_CTRL 0x11
+#define DRV_AUDIO_2_VIBE_MIN_IN 0x12
+#define DRV_AUDIO_2_VIBE_MAX_IN 0x13
+#define DRV_AUDIO_2_VIBE_MIN_OUTDRV 0x14
+#define DRV_AUDIO_2_VIBE_MAX_OUTDRV 0x15
+#define DRV_RATED_VOLT 0x16
+#define DRV_OVERDRIVE_CLAMP_VOLT 0x17
+#define DRV_AUTO_CALIB_COMP_RESULT 0x18
+#define DRV_AUTO_CALIB_BEMF_RESULT 0x19
+#define DRV_FEEDBACK_CTRL 0x1A
+#define DRV_CTRL_1 0x1B
+#define DRV_CTRL_2 0x1C
+#define DRV_CTRL_3 0x1D
+#define DRV_CTRL_4 0x1E
+#define DRV_CTRL_5 0x1F
+#define DRV_OPEN_LOOP_PERIOD 0x20
+#define DRV_VBAT_VOLT_MONITOR 0x21
+#define DRV_LRA_RESONANCE_PERIOD 0x22
+
+void DRV_init(void);
+void DRV_write(const uint8_t drv_register, const uint8_t settings);
+uint8_t DRV_read(const uint8_t regaddress);
+void DRV_pulse(const uint8_t sequence);
+
+
+typedef enum DRV_EFFECT{
+ clear_sequence = 0,
+ strong_click = 1,
+ strong_click_60 = 2,
+ strong_click_30 = 3,
+ sharp_click = 4,
+ sharp_click_60 = 5,
+ sharp_click_30 = 6,
+ soft_bump = 7,
+ soft_bump_60 = 8,
+ soft_bump_30 = 9,
+ dbl_click = 10,
+ dbl_click_60 = 11,
+ trp_click = 12,
+ soft_fuzz = 13,
+ strong_buzz = 14,
+ alert_750ms = 15,
+ alert_1000ms = 16,
+ strong_click1 = 17,
+ strong_click2_80 = 18,
+ strong_click3_60 = 19,
+ strong_click4_30 = 20,
+ medium_click1 = 21,
+ medium_click2_80 = 22,
+ medium_click3_60 = 23,
+ sharp_tick1 = 24,
+ sharp_tick2_80 = 25,
+ sharp_tick3_60 = 26,
+ sh_dblclick_str = 27,
+ sh_dblclick_str_80 = 28,
+ sh_dblclick_str_60 = 29,
+ sh_dblclick_str_30 = 30,
+ sh_dblclick_med = 31,
+ sh_dblclick_med_80 = 32,
+ sh_dblclick_med_60 = 33,
+ sh_dblsharp_tick = 34,
+ sh_dblsharp_tick_80 = 35,
+ sh_dblsharp_tick_60 = 36,
+ lg_dblclick_str = 37,
+ lg_dblclick_str_80 = 38,
+ lg_dblclick_str_60 = 39,
+ lg_dblclick_str_30 = 40,
+ lg_dblclick_med = 41,
+ lg_dblclick_med_80 = 42,
+ lg_dblclick_med_60 = 43,
+ lg_dblsharp_tick = 44,
+ lg_dblsharp_tick_80 = 45,
+ lg_dblsharp_tick_60 = 46,
+ buzz = 47,
+ buzz_80 = 48,
+ buzz_60 = 49,
+ buzz_40 = 50,
+ buzz_20 = 51,
+ pulsing_strong = 52,
+ pulsing_strong_80 = 53,
+ pulsing_medium = 54,
+ pulsing_medium_80 = 55,
+ pulsing_sharp = 56,
+ pulsing_sharp_80 = 57,
+ transition_click = 58,
+ transition_click_80 = 59,
+ transition_click_60 = 60,
+ transition_click_40 = 61,
+ transition_click_20 = 62,
+ transition_click_10 = 63,
+ transition_hum = 64,
+ transition_hum_80 = 65,
+ transition_hum_60 = 66,
+ transition_hum_40 = 67,
+ transition_hum_20 = 68,
+ transition_hum_10 = 69,
+ transition_rampdown_long_smooth1 = 70,
+ transition_rampdown_long_smooth2 = 71,
+ transition_rampdown_med_smooth1 = 72,
+ transition_rampdown_med_smooth2 = 73,
+ transition_rampdown_short_smooth1 = 74,
+ transition_rampdown_short_smooth2 = 75,
+ transition_rampdown_long_sharp1 = 76,
+ transition_rampdown_long_sharp2 = 77,
+ transition_rampdown_med_sharp1 = 78,
+ transition_rampdown_med_sharp2 = 79,
+ transition_rampdown_short_sharp1 = 80,
+ transition_rampdown_short_sharp2 = 81,
+ transition_rampup_long_smooth1 = 82,
+ transition_rampup_long_smooth2 = 83,
+ transition_rampup_med_smooth1 = 84,
+ transition_rampup_med_smooth2 = 85,
+ transition_rampup_short_smooth1 = 86,
+ transition_rampup_short_smooth2 = 87,
+ transition_rampup_long_sharp1 = 88,
+ transition_rampup_long_sharp2 = 89,
+ transition_rampup_med_sharp1 = 90,
+ transition_rampup_med_sharp2 = 91,
+ transition_rampup_short_sharp1 = 92,
+ transition_rampup_short_sharp2 = 93,
+ transition_rampdown_long_smooth1_50 = 94,
+ transition_rampdown_long_smooth2_50 = 95,
+ transition_rampdown_med_smooth1_50 = 96,
+ transition_rampdown_med_smooth2_50 = 97,
+ transition_rampdown_short_smooth1_50 = 98,
+ transition_rampdown_short_smooth2_50 = 99,
+ transition_rampdown_long_sharp1_50 = 100,
+ transition_rampdown_long_sharp2_50 = 101,
+ transition_rampdown_med_sharp1_50 = 102,
+ transition_rampdown_med_sharp2_50 = 103,
+ transition_rampdown_short_sharp1_50 = 104,
+ transition_rampdown_short_sharp2_50 = 105,
+ transition_rampup_long_smooth1_50 = 106,
+ transition_rampup_long_smooth2_50 = 107,
+ transition_rampup_med_smooth1_50 = 108,
+ transition_rampup_med_smooth2_50 = 109,
+ transition_rampup_short_smooth1_50 = 110,
+ transition_rampup_short_smooth2_50 = 111,
+ transition_rampup_long_sharp1_50 = 112,
+ transition_rampup_long_sharp2_50 = 113,
+ transition_rampup_med_sharp1_50 = 114,
+ transition_rampup_med_sharp2_50 = 115,
+ transition_rampup_short_sharp1_50 = 116,
+ transition_rampup_short_sharp2_50 = 117,
+ long_buzz_for_programmatic_stopping = 118,
+ smooth_hum1_50 = 119,
+ smooth_hum2_40 = 120,
+ smooth_hum3_30 = 121,
+ smooth_hum4_20 = 122,
+ smooth_hum5_10 = 123,
+} DRV_EFFECT;
+
+/* Register bit array unions */
+
+typedef union DRVREG_STATUS { /* register 0x00 */
+ uint8_t Byte;
+ struct {
+ uint8_t OC_DETECT :1; /* set to 1 when overcurrent event is detected */
+ uint8_t OVER_TEMP :1; /* set to 1 when device exceeds temp threshold */
+ uint8_t FB_STS :1; /* set to 1 when feedback controller has timed out */
+ /* auto-calibration routine and diagnostic result
+ * result | auto-calibation | diagnostic |
+ * 0 | passed | actuator func normal |
+ * 1 | failed | actuator func fault* |
+ * * actuator is not present or is shorted, timing out, or giving out–of-range back-EMF */
+ uint8_t DIAG_RESULT :1;
+ uint8_t :1;
+ uint8_t DEVICE_ID :3; /* Device IDs 3: DRV2605 4: DRV2604 5: DRV2604L 6: DRV2605L */
+ } Bits;
+} DRVREG_STATUS;
+
+typedef union DRVREG_MODE { /* register 0x01 */
+ uint8_t Byte;
+ struct {
+ uint8_t MODE :3; /* Mode setting */
+ uint8_t :3;
+ uint8_t STANDBY :1; /* 0:standby 1:ready */
+ } Bits;
+} DRVREG_MODE;
+
+typedef union DRVREG_WAIT {
+ uint8_t Byte;
+ struct {
+ uint8_t WAIT_MODE :1; /* Set to 1 to interpret as wait for next 7 bits x10ms */
+ uint8_t WAIT_TIME :7;
+ } Bits;
+} DRVREG_WAIT;
+
+typedef union DRVREG_FBR{ /* register 0x1A */
+ uint8_t Byte;
+ struct {
+ uint8_t BEMF_GAIN :2;
+ uint8_t LOOP_GAIN :2;
+ uint8_t BRAKE_FACTOR :3;
+ uint8_t ERM_LRA :1;
+ } Bits;
+} DRVREG_FBR;
+
+typedef union DRVREG_CTRL1{ /* register 0x1B */
+ uint8_t Byte;
+ struct {
+ uint8_t C1_DRIVE_TIME :5;
+ uint8_t C1_AC_COUPLE :1;
+ uint8_t :1;
+ uint8_t C1_STARTUP_BOOST :1;
+ } Bits;
+} DRVREG_CTRL1;
+
+typedef union DRVREG_CTRL2{ /* register 0x1C */
+ uint8_t Byte;
+ struct {
+ uint8_t C2_IDISS_TIME :2;
+ uint8_t C2_BLANKING_TIME :2;
+ uint8_t C2_SAMPLE_TIME :2;
+ uint8_t C2_BRAKE_STAB :1;
+ uint8_t C2_BIDIR_INPUT :1;
+ } Bits;
+} DRVREG_CTRL2;
+
+typedef union DRVREG_CTRL3{ /* register 0x1D */
+ uint8_t Byte;
+ struct {
+ uint8_t C3_LRA_OPEN_LOOP :1;
+ uint8_t C3_N_PWM_ANALOG :1;
+ uint8_t C3_LRA_DRIVE_MODE :1;
+ uint8_t C3_DATA_FORMAT_RTO :1;
+ uint8_t C3_SUPPLY_COMP_DIS :1;
+ uint8_t C3_ERM_OPEN_LOOP :1;
+ uint8_t C3_NG_THRESH :2;
+ } Bits;
+} DRVREG_CTRL3;
+
+typedef union DRVREG_CTRL4{ /* register 0x1E */
+ uint8_t Byte;
+ struct {
+ uint8_t C4_OTP_PROGRAM :1;
+ uint8_t :1;
+ uint8_t C4_OTP_STATUS :1;
+ uint8_t :1;
+ uint8_t C4_AUTO_CAL_TIME :2;
+ uint8_t C4_ZC_DET_TIME :2;
+ } Bits;
+} DRVREG_CTRL4;
+
+typedef union DRVREG_CTRL5{ /* register 0x1F */
+ uint8_t Byte;
+ struct {
+ uint8_t C5_IDISS_TIME :2;
+ uint8_t C5_BLANKING_TIME :2;
+ uint8_t C5_PLAYBACK_INTERVAL :1;
+ uint8_t C5_LRA_AUTO_OPEN_LOOP :1;
+ uint8_t C5_AUTO_OL_CNT :2;
+ } Bits;
+} DRVREG_CTRL5;
\ No newline at end of file
diff --git a/drivers/qwiic/micro_oled.c b/drivers/qwiic/micro_oled.c
new file mode 100644
index 000000000..35c5d6ee1
--- /dev/null
+++ b/drivers/qwiic/micro_oled.c
@@ -0,0 +1,691 @@
+/* Jim Lindblom @ SparkFun Electronics
+ * October 26, 2014
+ * https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED
+ *
+ * Modified by:
+ * Emil Varughese @ Edwin Robotics Pvt. Ltd.
+ * July 27, 2015
+ * https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
+ *
+ * This code was heavily based around the MicroView library, written by GeekAmmo
+ * (https://github.com/geekammo/MicroView-Arduino-Library).
+ *
+ * Adapted for QMK by:
+ * Jack Humbert
+ * October 11, 2018
+ *
+ * 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 .
+ */
+#include "micro_oled.h"
+#include
+#include "util/font5x7.h"
+#include "util/font8x16.h"
+#include "string.h"
+
+#define TOTALFONTS 2
+const unsigned char * fonts_pointer[]= { font5x7, font8x16 };
+
+uint8_t foreColor,drawMode,fontWidth, fontHeight, fontType, fontStartChar, fontTotalChar, cursorX, cursorY;
+uint16_t fontMapWidth;
+
+#define _BV(x) (1 << (x))
+#define swap(a, b) { uint8_t t = a; a = b; b = t; }
+
+uint8_t micro_oled_transfer_buffer[20];
+static uint8_t micro_oled_screen_current[LCDWIDTH*LCDWIDTH/8] = { 0 };
+
+/* LCD Memory organised in 64 horizontal pixel and 6 rows of byte
+ B B .............B -----
+ y y .............y \
+ t t .............t \
+ e e .............e \
+ 0 1 .............63 \
+ \
+ D0 D0.............D0 \
+ D1 D1.............D1 / ROW 0
+ D2 D2.............D2 /
+ D3 D3.............D3 /
+ D4 D4.............D4 /
+ D5 D5.............D5 /
+ D6 D6.............D6 /
+ D7 D7.............D7 ----
+ */
+
+#if LCDWIDTH == 64
+ #if LCDWIDTH == 48
+static uint8_t micro_oled_screen_buffer[] = {
+// QMK Logo - generated at http://www.majer.ch/lcd/adf_bitmap.php
+//64x48 image
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00,
+0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00,
+0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60,
+0xF8, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFE,
+0xFE, 0xF8, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x8C, 0x8C, 0x8C, 0x8C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
+0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x8C, 0x8C, 0x8C, 0x8C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x31, 0x31, 0x31, 0x31, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0xF1, 0xE3, 0xE7, 0xCF,
+0xCF, 0xCF, 0xCF, 0x00, 0x00, 0xCF, 0xCF, 0xCF, 0xC7, 0xE7,
+0xE3, 0xF1, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0x31, 0x31, 0x31, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06,
+0x06, 0x06, 0x1F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF8, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0x7F, 0x7F, 0x1F, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
+0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00,
+0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00
+};
+ #endif
+#elif LCDWIDTH == 128
+ #if LCDHEIGHT == 32
+ static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = {
+//128x32 qmk image
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xFC, 0xFC, 0xE0, 0xFC, 0xFC,
+0xE0, 0xF0, 0xFC, 0xE0, 0xE0, 0xFC, 0xE0, 0xE0, 0xFC, 0xFC,
+0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x30, 0xE0, 0x00, 0x00,
+0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
+0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80,
+0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
+0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80,
+0x80, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xB2, 0xB2, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF, 0x03,
+0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x03, 0xFF, 0xFF, 0xFF,
+0xFF, 0xB7, 0xB2, 0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1F, 0x02, 0x02, 0x03, 0x01, 0x00, 0x06, 0x1F, 0x10,
+0x10, 0x10, 0x1F, 0x06, 0x00, 0x03, 0x1E, 0x18, 0x0F, 0x01,
+0x0F, 0x18, 0x1E, 0x01, 0x00, 0x0F, 0x1F, 0x12, 0x02, 0x12,
+0x13, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0E, 0x1F, 0x12,
+0x02, 0x12, 0x13, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x1F,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x48, 0x4D, 0x4D, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFE, 0xF8, 0xF9, 0xF3, 0xF3, 0xC0, 0x80, 0xF3,
+0xF3, 0xF3, 0xF9, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xED,
+0x4D, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0xC0, 0x00, 0x70, 0xC0,
+0x00, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0C,
+0x04, 0x04, 0x04, 0x04, 0x1C, 0xF0, 0x00, 0x00, 0xFC, 0x0C,
+0x38, 0xE0, 0x00, 0x00, 0xC0, 0x38, 0x0C, 0xFC, 0x00, 0x00,
+0xFC, 0xFC, 0x60, 0x90, 0x0C, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x3F,
+0x3F, 0x07, 0x3F, 0x3F, 0x07, 0x0F, 0x3F, 0x07, 0x07, 0x3F,
+0x07, 0x07, 0x3F, 0x3F, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+0x06, 0x04, 0x04, 0x07, 0x01, 0x00, 0x00, 0x13, 0x1E, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x04, 0x04,
+0x04, 0x04, 0x07, 0x0D, 0x08, 0x00, 0x07, 0x00, 0x00, 0x01,
+0x07, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x07,
+0x00, 0x01, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00
+ };
+ #elif LCDHEIGHT == 64
+ static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0,
+0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00,
+0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xC0, 0xC0, 0xC0, 0xC0, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE, 0xFF,
+0x7F, 0x7E, 0xFE, 0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7F, 0xFE,
+0xFE, 0xFF, 0xFF, 0xFE, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0xFC,
+0xFC, 0xF8, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x88, 0x88, 0x88, 0xDD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xDD, 0x88, 0x88, 0x88, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFE, 0xF8, 0xF0, 0xF3, 0xF3, 0xE7, 0xE7, 0x00,
+0x00, 0xE7, 0xE7, 0xF3, 0xF3, 0xF0, 0xF8, 0xFE, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x0F, 0x1F, 0x3F,
+0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F,
+0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF, 0x3F, 0x3F, 0xFF, 0xFF,
+0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x01, 0x01, 0x01, 0x01, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00,
+0x80, 0x03, 0x03, 0x00, 0x00, 0x01, 0x03, 0x00, 0x80, 0x01,
+0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xFF, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x70,
+0x88, 0x04, 0x04, 0x04, 0xF8, 0x00, 0x00, 0x3C, 0xE0, 0xC0,
+0x38, 0x1C, 0xE0, 0x80, 0x70, 0x0C, 0x00, 0xF8, 0xAC, 0x24,
+0x24, 0x3C, 0x30, 0x00, 0x00, 0xFC, 0x0C, 0x04, 0x00, 0xF8,
+0xAC, 0x24, 0x24, 0x2C, 0x30, 0x00, 0x70, 0xDC, 0x04, 0x04,
+0x88, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
+0x8C, 0x04, 0x04, 0xF8, 0x00, 0x04, 0x3C, 0xE0, 0x80, 0xF0,
+0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x83, 0x01, 0x01,
+0x01, 0x81, 0xFE, 0x3C, 0x00, 0x00, 0xFF, 0x03, 0x0E, 0x70,
+0xC0, 0xE0, 0x38, 0x06, 0x03, 0xFF, 0x00, 0x00, 0xFF, 0x18,
+0x38, 0x66, 0xC3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+//TODO: generate bitmap of QMK logo here
+ #endif
+#else
+//catchall for custom screen szies
+ static uint8_t micro_oled_screen_buffer[LCDWIDTH*LCDWIDTH/8] = {0};
+#endif
+
+
+
+void micro_oled_init(void) {
+
+ i2c_init();
+ i2c_start(I2C_ADDRESS_SA0_1);
+
+ // Display Init sequence for 64x48 OLED module
+ send_command(DISPLAYOFF); // 0xAE
+
+ send_command(SETDISPLAYCLOCKDIV); // 0xD5
+ send_command(0x80); // the suggested ratio 0x80
+
+ send_command(SETMULTIPLEX); // 0xA8
+ send_command(LCDHEIGHT - 1);
+
+ send_command(SETDISPLAYOFFSET); // 0xD3
+ send_command(0x00); // no offset
+
+ send_command(SETSTARTLINE | 0x00); // line #0
+
+ send_command(CHARGEPUMP); // enable charge pump
+ send_command(0x14);
+
+ send_command(NORMALDISPLAY); // 0xA6
+ send_command(DISPLAYALLONRESUME); // 0xA4
+
+//display at regular orientation
+ send_command(SEGREMAP | 0x1);
+ send_command(COMSCANDEC);
+
+//rotate display 180
+#ifdef micro_oled_rotate_180
+ send_command(SEGREMAP);
+ send_command(COMSCANINC);
+#endif
+
+ send_command(MEMORYMODE);
+ send_command(0x10);
+
+ send_command(SETCOMPINS); // 0xDA
+if (LCDHEIGHT > 32) {
+ send_command(0x12);
+} else {
+ send_command(0x02);
+}
+ send_command(SETCONTRAST); // 0x81
+ send_command(0x8F);
+
+ send_command(SETPRECHARGE); // 0xd9
+ send_command(0xF1);
+
+ send_command(SETVCOMDESELECT); // 0xDB
+ send_command(0x40);
+
+ send_command(DISPLAYON); //--turn on oled panel
+ clear_screen(); // Erase hardware memory inside the OLED controller to avoid random data in memory.
+ send_buffer();
+}
+
+void send_command(uint8_t command) {
+ micro_oled_transfer_buffer[0] = I2C_COMMAND;
+ micro_oled_transfer_buffer[1] = command;
+ i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100);
+}
+
+void send_data(uint8_t data) {
+ micro_oled_transfer_buffer[0] = I2C_DATA;
+ micro_oled_transfer_buffer[1] = data;
+ i2c_transmit(I2C_ADDRESS_SA0_1 << 1, micro_oled_transfer_buffer, 2, 100);
+}
+
+/** \brief Set SSD1306 page address.
+ Send page address command and address to the SSD1306 OLED controller.
+*/
+void set_page_address(uint8_t address) {
+ address = (0xB0 | address);
+ send_command(address);
+}
+
+/** \brief Set SSD1306 column address.
+ Send column address command and address to the SSD1306 OLED controller.
+*/
+void set_column_address(uint8_t address) {
+ send_command( ( 0x10 | (address >> 4) ) + ((128 - LCDWIDTH) >> 8) );
+ send_command( 0x0F & address );
+}
+
+/** \brief Clear SSD1306's memory.
+ To clear GDRAM inside the LCD controller.
+*/
+void clear_screen(void) {
+ for (int i=0;i<8; i++) {
+ set_page_address(i);
+ set_column_address(0);
+ for (int j=0; j<0x80; j++) {
+ send_data(0);
+ }
+ }
+}
+
+/** \brief Clear SSD1306's memory.
+ To clear GDRAM inside the LCD controller.
+*/
+void clear_buffer(void) {
+//384
+ memset(micro_oled_screen_buffer, 0, LCDWIDTH*LCDWIDTH/8);
+}
+
+/** \brief Invert display.
+ The PIXEL_ON color of the display will turn to PIXEL_OFF and the PIXEL_OFF will turn to PIXEL_ON.
+*/
+void invert_screen(bool invert) {
+ if (invert) {
+ send_command(INVERTDISPLAY);
+ } else {
+ send_command(NORMALDISPLAY);
+ }
+}
+
+/** \brief Set contrast.
+ OLED contract value from 0 to 255. Note: Contrast level is not very obvious.
+*/
+void set_contrast(uint8_t contrast) {
+ send_command(SETCONTRAST); // 0x81
+ send_command(contrast);
+}
+
+/** \brief Transfer display buffer.
+ Sends the updated buffer to the controller - the current status is checked before to save i2c exectution time
+*/
+void send_buffer(void) {
+ uint8_t i, j;
+
+ uint8_t page_addr = 0xFF;
+ for (i = 0; i < LCDHEIGHT/8; i++) {
+ uint8_t col_addr = 0xFF;
+ for (j = 0; j < LCDWIDTH; j++) {
+ if (micro_oled_screen_buffer[i*LCDWIDTH+j] != micro_oled_screen_current[i*LCDWIDTH+j]) {
+ if (page_addr != i) {
+ set_page_address(i);
+ }
+ if (col_addr != j) {
+ set_column_address(j);
+ }
+ send_data(micro_oled_screen_buffer[i*LCDWIDTH+j]);
+ micro_oled_screen_current[i*LCDWIDTH+j] = micro_oled_screen_buffer[i*LCDWIDTH+j];
+ col_addr = j + 1;
+ }
+ }
+ }
+}
+
+/** \brief Draw pixel with color and mode.
+ Draw color pixel in the screen buffer's x,y position with NORM or XOR draw mode.
+*/
+void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode) {
+ if ((x<0) || (x>=LCDWIDTH) || (y<0) || (y>=LCDHEIGHT))
+ return;
+
+ if (mode == XOR) {
+ if (color == PIXEL_ON)
+ micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] ^= _BV((y%8));
+ } else {
+ if (color == PIXEL_ON)
+ micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] |= _BV((y%8));
+ else
+ micro_oled_screen_buffer[x + (y/8)*LCDWIDTH] &= ~_BV((y%8));
+ }
+}
+
+/** \brief Draw line with color and mode.
+Draw line using color and mode from x0,y0 to x1,y1 of the screen buffer.
+*/
+void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode) {
+ uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
+ if (steep) {
+ swap(x0, y0);
+ swap(x1, y1);
+ }
+
+ if (x0 > x1) {
+ swap(x0, x1);
+ swap(y0, y1);
+ }
+
+ uint8_t dx, dy;
+ dx = x1 - x0;
+ dy = abs(y1 - y0);
+
+ int8_t err = dx / 2;
+ int8_t ystep;
+
+ if (y0 < y1) {
+ ystep = 1;
+ } else {
+ ystep = -1;}
+
+ for (; x0=TOTALFONTS) || (font<0))
+ return;
+
+ uint8_t fontType = font;
+ uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType]+0);
+ uint8_t fontHeight = pgm_read_byte(fonts_pointer[fontType]+1);
+ uint8_t fontStartChar = pgm_read_byte(fonts_pointer[fontType]+2);
+ uint8_t fontTotalChar = pgm_read_byte(fonts_pointer[fontType]+3);
+ uint16_t fontMapWidth = (pgm_read_byte(fonts_pointer[fontType]+4)*100)+pgm_read_byte(fonts_pointer[fontType]+5); // two bytes values into integer 16
+
+ if ((c(fontStartChar+fontTotalChar-1))) // no bitmap for the required c
+ return;
+
+ tempC=c-fontStartChar;
+
+ // each row (in datasheet is call page) is 8 bits high, 16 bit high character will have 2 rows to be drawn
+ rowsToDraw=fontHeight/8; // 8 is LCD's page size, see SSD1306 datasheet
+ if (rowsToDraw<=1) rowsToDraw=1;
+
+ // the following draw function can draw anywhere on the screen, but SLOW pixel by pixel draw
+ if (rowsToDraw==1) {
+ for (i=0;i>=1;
+ }
+ }
+ return;
+ }
+
+ // font height over 8 bit
+ // take character "0" ASCII 48 as example
+ charPerBitmapRow = fontMapWidth/fontWidth; // 256/8 =32 char per row
+ charColPositionOnBitmap = tempC % charPerBitmapRow; // =16
+ charRowPositionOnBitmap = (int)(tempC/charPerBitmapRow); // =1
+ charBitmapStartPosition = (charRowPositionOnBitmap * fontMapWidth * (fontHeight/8)) + (charColPositionOnBitmap * fontWidth) ;
+
+ // each row on LCD is 8 bit height (see datasheet for explanation)
+ for(row=0;row>=1;
+ }
+ }
+ }
+
+}
+
+void draw_string(uint8_t x, uint8_t y, char * string, uint8_t color, uint8_t mode, uint8_t font) {
+
+ if ((font>=TOTALFONTS) || (font<0))
+ return;
+
+ uint8_t fontType = font;
+ uint8_t fontWidth = pgm_read_byte(fonts_pointer[fontType]+0);
+
+ uint8_t cur_x = x;
+ for (int i = 0; i < strlen(string); i++) {
+ draw_char(cur_x, y, string[i], color, mode, font);
+ cur_x += fontWidth + 1;
+ }
+
+}
diff --git a/drivers/qwiic/micro_oled.h b/drivers/qwiic/micro_oled.h
new file mode 100644
index 000000000..5d6a1029e
--- /dev/null
+++ b/drivers/qwiic/micro_oled.h
@@ -0,0 +1,134 @@
+/* Jim Lindblom @ SparkFun Electronics
+ * October 26, 2014
+ * https://github.com/sparkfun/Micro_OLED_Breakout/tree/master/Firmware/Arduino/libraries/SFE_MicroOLED
+ *
+ * Modified by:
+ * Emil Varughese @ Edwin Robotics Pvt. Ltd.
+ * July 27, 2015
+ * https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
+ *
+ * This code was heavily based around the MicroView library, written by GeekAmmo
+ * (https://github.com/geekammo/MicroView-Arduino-Library).
+ *
+ * Adapted for QMK by:
+ * Jack Humbert
+ * October 11, 2018
+ *
+ * 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 .
+ */
+#pragma once
+
+#include "qwiic.h"
+
+void micro_oled_init(void);
+
+void send_command(uint8_t command);
+void send_data(uint8_t data);
+void set_page_address(uint8_t address);
+void set_column_address(uint8_t address);
+void clear_screen(void);
+void clear_buffer(void);
+void send_buffer(void);
+void draw_pixel(uint8_t x, uint8_t y, uint8_t color, uint8_t mode);
+void draw_line(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t color, uint8_t mode);
+void draw_line_hori(uint8_t x, uint8_t y, uint8_t width, uint8_t color, uint8_t mode);
+void draw_line_vert(uint8_t x, uint8_t y, uint8_t height, bool color, uint8_t mode);
+void draw_rect(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
+void draw_rect_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
+void draw_rect_filled(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
+void draw_rect_filled_soft(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t color, uint8_t mode);
+void draw_char(uint8_t x, uint8_t y, uint8_t c, uint8_t color, uint8_t mode, uint8_t font);
+void draw_string(uint8_t x, uint8_t y, char * string, uint8_t color, uint8_t mode, uint8_t font);
+
+#define I2C_ADDRESS_SA0_0 0b0111100
+#ifndef I2C_ADDRESS_SA0_1
+#define I2C_ADDRESS_SA0_1 0b0111101
+#endif
+#define I2C_COMMAND 0x00
+#define I2C_DATA 0x40
+#define PIXEL_OFF 0
+#define PIXEL_ON 1
+
+#ifndef LCDWIDTH
+#define LCDWIDTH 64
+#endif
+#ifndef LCDWIDTH
+#define LCDHEIGHT 48
+#endif
+#define FONTHEADERSIZE 6
+
+#define NORM 0
+#define XOR 1
+
+#define PAGE 0
+#define ALL 1
+
+#define WIDGETSTYLE0 0
+#define WIDGETSTYLE1 1
+#define WIDGETSTYLE2 2
+
+#define SETCONTRAST 0x81
+#define DISPLAYALLONRESUME 0xA4
+#define DISPLAYALLON 0xA5
+#define NORMALDISPLAY 0xA6
+#define INVERTDISPLAY 0xA7
+#define DISPLAYOFF 0xAE
+#define DISPLAYON 0xAF
+#define SETDISPLAYOFFSET 0xD3
+#define SETCOMPINS 0xDA
+#define SETVCOMDESELECT 0xDB
+#define SETDISPLAYCLOCKDIV 0xD5
+#define SETPRECHARGE 0xD9
+#define SETMULTIPLEX 0xA8
+#define SETLOWCOLUMN 0x00
+#define SETHIGHCOLUMN 0x10
+#define SETSTARTLINE 0x40
+#define MEMORYMODE 0x20
+#define COMSCANINC 0xC0
+#define COMSCANDEC 0xC8
+#define SEGREMAP 0xA0
+#define CHARGEPUMP 0x8D
+#define EXTERNALVCC 0x01
+#define SWITCHCAPVCC 0x02
+
+// Scroll
+#define ACTIVATESCROLL 0x2F
+#define DEACTIVATESCROLL 0x2E
+#define SETVERTICALSCROLLAREA 0xA3
+#define RIGHTHORIZONTALSCROLL 0x26
+#define LEFT_HORIZONTALSCROLL 0x27
+#define VERTICALRIGHTHORIZONTALSCROLL 0x29
+#define VERTICALLEFTHORIZONTALSCROLL 0x2A
+
+typedef enum CMD {
+ CMD_CLEAR, //0
+ CMD_INVERT, //1
+ CMD_CONTRAST, //2
+ CMD_DISPLAY, //3
+ CMD_SETCURSOR, //4
+ CMD_PIXEL, //5
+ CMD_LINE, //6
+ CMD_LINEH, //7
+ CMD_LINEV, //8
+ CMD_RECT, //9
+ CMD_RECTFILL, //10
+ CMD_CIRCLE, //11
+ CMD_CIRCLEFILL, //12
+ CMD_DRAWCHAR, //13
+ CMD_DRAWBITMAP, //14
+ CMD_GETLCDWIDTH, //15
+ CMD_GETLCDHEIGHT, //16
+ CMD_SETCOLOR, //17
+ CMD_SETDRAWMODE //18
+} commCommand_t;
\ No newline at end of file
diff --git a/drivers/qwiic/qwiic.c b/drivers/qwiic/qwiic.c
new file mode 100644
index 000000000..904791992
--- /dev/null
+++ b/drivers/qwiic/qwiic.c
@@ -0,0 +1,31 @@
+/* Copyright 2018 Jack Humbert
+ *
+ * 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 .
+ */
+#include "qwiic.h"
+
+void qwiic_init(void) {
+ #ifdef QWIIC_JOYSTIIC_ENABLE
+ joystiic_init();
+ #endif
+ #ifdef QWIIC_MICRO_OLED_ENABLE
+ micro_oled_init();
+ #endif
+}
+
+void qwiic_task(void) {
+ #ifdef QWIIC_JOYSTIIC_ENABLE
+ joystiic_task();
+ #endif
+}
diff --git a/drivers/qwiic/qwiic.h b/drivers/qwiic/qwiic.h
new file mode 100644
index 000000000..160fb28df
--- /dev/null
+++ b/drivers/qwiic/qwiic.h
@@ -0,0 +1,28 @@
+/* Copyright 2018 Jack Humbert
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#pragma once
+
+#include "i2c_master.h"
+
+#ifdef QWIIC_JOYSTIIC_ENABLE
+ #include "joystiic.h"
+#endif
+#ifdef QWIIC_MICRO_OLED_ENABLE
+ #include "micro_oled.h"
+#endif
+
+void qwiic_init(void);
+void qwiic_task(void);
diff --git a/drivers/qwiic/qwiic.mk b/drivers/qwiic/qwiic.mk
new file mode 100644
index 000000000..4ae2d78e3
--- /dev/null
+++ b/drivers/qwiic/qwiic.mk
@@ -0,0 +1,18 @@
+ifneq ($(strip $(QWIIC_ENABLE)),)
+ COMMON_VPATH += $(DRIVER_PATH)/qwiic
+ OPT_DEFS += -DQWIIC_ENABLE
+ SRC += qwiic.c
+ ifeq ($(filter "i2c_master.c", $(SRC)),)
+ SRC += i2c_master.c
+ endif
+endif
+
+ifneq ($(filter JOYSTIIC, $(QWIIC_ENABLE)),)
+ OPT_DEFS += -DQWIIC_JOYSTIIC_ENABLE
+ SRC += joystiic.c
+endif
+
+ifneq ($(filter MICRO_OLED, $(QWIIC_ENABLE)),)
+ OPT_DEFS += -DQWIIC_MICRO_OLED_ENABLE
+ SRC += micro_oled.c
+endif
diff --git a/drivers/qwiic/util/font5x7.h b/drivers/qwiic/util/font5x7.h
new file mode 100644
index 000000000..0bad206b7
--- /dev/null
+++ b/drivers/qwiic/util/font5x7.h
@@ -0,0 +1,288 @@
+/******************************************************************************
+font5x7.h
+Definition for small font
+
+This file was imported from the MicroView library, written by GeekAmmo
+(https://github.com/geekammo/MicroView-Arduino-Library), and released 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 .
+
+Modified by:
+Emil Varughese @ Edwin Robotics Pvt. Ltd.
+July 27, 2015
+https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
+
+******************************************************************************/
+#pragma once
+
+#include "progmem.h"
+
+// Standard ASCII 5x7 font
+static const unsigned char font5x7[] PROGMEM = {
+ // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256)
+ 5,8,0,255,12,75,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
+ 0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
+ 0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
+ 0x18, 0x3C, 0x7E, 0x3C, 0x18,
+ 0x1C, 0x57, 0x7D, 0x57, 0x1C,
+ 0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
+ 0x00, 0x18, 0x3C, 0x18, 0x00,
+ 0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
+ 0x00, 0x18, 0x24, 0x18, 0x00,
+ 0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
+ 0x30, 0x48, 0x3A, 0x06, 0x0E,
+ 0x26, 0x29, 0x79, 0x29, 0x26,
+ 0x40, 0x7F, 0x05, 0x05, 0x07,
+ 0x40, 0x7F, 0x05, 0x25, 0x3F,
+ 0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
+ 0x7F, 0x3E, 0x1C, 0x1C, 0x08,
+ 0x08, 0x1C, 0x1C, 0x3E, 0x7F,
+ 0x14, 0x22, 0x7F, 0x22, 0x14,
+ 0x5F, 0x5F, 0x00, 0x5F, 0x5F,
+ 0x06, 0x09, 0x7F, 0x01, 0x7F,
+ 0x00, 0x66, 0x89, 0x95, 0x6A,
+ 0x60, 0x60, 0x60, 0x60, 0x60,
+ 0x94, 0xA2, 0xFF, 0xA2, 0x94,
+ 0x08, 0x04, 0x7E, 0x04, 0x08,
+ 0x10, 0x20, 0x7E, 0x20, 0x10,
+ 0x08, 0x08, 0x2A, 0x1C, 0x08,
+ 0x08, 0x1C, 0x2A, 0x08, 0x08,
+ 0x1E, 0x10, 0x10, 0x10, 0x10,
+ 0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
+ 0x30, 0x38, 0x3E, 0x38, 0x30,
+ 0x06, 0x0E, 0x3E, 0x0E, 0x06,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x5F, 0x00, 0x00,
+ 0x00, 0x07, 0x00, 0x07, 0x00,
+ 0x14, 0x7F, 0x14, 0x7F, 0x14,
+ 0x24, 0x2A, 0x7F, 0x2A, 0x12,
+ 0x23, 0x13, 0x08, 0x64, 0x62,
+ 0x36, 0x49, 0x56, 0x20, 0x50,
+ 0x00, 0x08, 0x07, 0x03, 0x00,
+ 0x00, 0x1C, 0x22, 0x41, 0x00,
+ 0x00, 0x41, 0x22, 0x1C, 0x00,
+ 0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
+ 0x08, 0x08, 0x3E, 0x08, 0x08,
+ 0x00, 0x80, 0x70, 0x30, 0x00,
+ 0x08, 0x08, 0x08, 0x08, 0x08,
+ 0x00, 0x00, 0x60, 0x60, 0x00,
+ 0x20, 0x10, 0x08, 0x04, 0x02,
+ 0x3E, 0x51, 0x49, 0x45, 0x3E,
+ 0x00, 0x42, 0x7F, 0x40, 0x00,
+ 0x72, 0x49, 0x49, 0x49, 0x46,
+ 0x21, 0x41, 0x49, 0x4D, 0x33,
+ 0x18, 0x14, 0x12, 0x7F, 0x10,
+ 0x27, 0x45, 0x45, 0x45, 0x39,
+ 0x3C, 0x4A, 0x49, 0x49, 0x31,
+ 0x41, 0x21, 0x11, 0x09, 0x07,
+ 0x36, 0x49, 0x49, 0x49, 0x36,
+ 0x46, 0x49, 0x49, 0x29, 0x1E,
+ 0x00, 0x00, 0x14, 0x00, 0x00,
+ 0x00, 0x40, 0x34, 0x00, 0x00,
+ 0x00, 0x08, 0x14, 0x22, 0x41,
+ 0x14, 0x14, 0x14, 0x14, 0x14,
+ 0x00, 0x41, 0x22, 0x14, 0x08,
+ 0x02, 0x01, 0x59, 0x09, 0x06,
+ 0x3E, 0x41, 0x5D, 0x59, 0x4E,
+ 0x7C, 0x12, 0x11, 0x12, 0x7C,
+ 0x7F, 0x49, 0x49, 0x49, 0x36,
+ 0x3E, 0x41, 0x41, 0x41, 0x22,
+ 0x7F, 0x41, 0x41, 0x41, 0x3E,
+ 0x7F, 0x49, 0x49, 0x49, 0x41,
+ 0x7F, 0x09, 0x09, 0x09, 0x01,
+ 0x3E, 0x41, 0x41, 0x51, 0x73,
+ 0x7F, 0x08, 0x08, 0x08, 0x7F,
+ 0x00, 0x41, 0x7F, 0x41, 0x00,
+ 0x20, 0x40, 0x41, 0x3F, 0x01,
+ 0x7F, 0x08, 0x14, 0x22, 0x41,
+ 0x7F, 0x40, 0x40, 0x40, 0x40,
+ 0x7F, 0x02, 0x1C, 0x02, 0x7F,
+ 0x7F, 0x04, 0x08, 0x10, 0x7F,
+ 0x3E, 0x41, 0x41, 0x41, 0x3E,
+ 0x7F, 0x09, 0x09, 0x09, 0x06,
+ 0x3E, 0x41, 0x51, 0x21, 0x5E,
+ 0x7F, 0x09, 0x19, 0x29, 0x46,
+ 0x26, 0x49, 0x49, 0x49, 0x32,
+ 0x03, 0x01, 0x7F, 0x01, 0x03,
+ 0x3F, 0x40, 0x40, 0x40, 0x3F,
+ 0x1F, 0x20, 0x40, 0x20, 0x1F,
+ 0x3F, 0x40, 0x38, 0x40, 0x3F,
+ 0x63, 0x14, 0x08, 0x14, 0x63,
+ 0x03, 0x04, 0x78, 0x04, 0x03,
+ 0x61, 0x59, 0x49, 0x4D, 0x43,
+ 0x00, 0x7F, 0x41, 0x41, 0x41,
+ 0x02, 0x04, 0x08, 0x10, 0x20,
+ 0x00, 0x41, 0x41, 0x41, 0x7F,
+ 0x04, 0x02, 0x01, 0x02, 0x04,
+ 0x40, 0x40, 0x40, 0x40, 0x40,
+ 0x00, 0x03, 0x07, 0x08, 0x00,
+ 0x20, 0x54, 0x54, 0x78, 0x40,
+ 0x7F, 0x28, 0x44, 0x44, 0x38,
+ 0x38, 0x44, 0x44, 0x44, 0x28,
+ 0x38, 0x44, 0x44, 0x28, 0x7F,
+ 0x38, 0x54, 0x54, 0x54, 0x18,
+ 0x00, 0x08, 0x7E, 0x09, 0x02,
+ 0x18, 0xA4, 0xA4, 0x9C, 0x78,
+ 0x7F, 0x08, 0x04, 0x04, 0x78,
+ 0x00, 0x44, 0x7D, 0x40, 0x00,
+ 0x20, 0x40, 0x40, 0x3D, 0x00,
+ 0x7F, 0x10, 0x28, 0x44, 0x00,
+ 0x00, 0x41, 0x7F, 0x40, 0x00,
+ 0x7C, 0x04, 0x78, 0x04, 0x78,
+ 0x7C, 0x08, 0x04, 0x04, 0x78,
+ 0x38, 0x44, 0x44, 0x44, 0x38,
+ 0xFC, 0x18, 0x24, 0x24, 0x18,
+ 0x18, 0x24, 0x24, 0x18, 0xFC,
+ 0x7C, 0x08, 0x04, 0x04, 0x08,
+ 0x48, 0x54, 0x54, 0x54, 0x24,
+ 0x04, 0x04, 0x3F, 0x44, 0x24,
+ 0x3C, 0x40, 0x40, 0x20, 0x7C,
+ 0x1C, 0x20, 0x40, 0x20, 0x1C,
+ 0x3C, 0x40, 0x30, 0x40, 0x3C,
+ 0x44, 0x28, 0x10, 0x28, 0x44,
+ 0x4C, 0x90, 0x90, 0x90, 0x7C,
+ 0x44, 0x64, 0x54, 0x4C, 0x44,
+ 0x00, 0x08, 0x36, 0x41, 0x00,
+ 0x00, 0x00, 0x77, 0x00, 0x00,
+ 0x00, 0x41, 0x36, 0x08, 0x00,
+ 0x02, 0x01, 0x02, 0x04, 0x02,
+ 0x3C, 0x26, 0x23, 0x26, 0x3C,
+ 0x1E, 0xA1, 0xA1, 0x61, 0x12,
+ 0x3A, 0x40, 0x40, 0x20, 0x7A,
+ 0x38, 0x54, 0x54, 0x55, 0x59,
+ 0x21, 0x55, 0x55, 0x79, 0x41,
+ 0x21, 0x54, 0x54, 0x78, 0x41,
+ 0x21, 0x55, 0x54, 0x78, 0x40,
+ 0x20, 0x54, 0x55, 0x79, 0x40,
+ 0x0C, 0x1E, 0x52, 0x72, 0x12,
+ 0x39, 0x55, 0x55, 0x55, 0x59,
+ 0x39, 0x54, 0x54, 0x54, 0x59,
+ 0x39, 0x55, 0x54, 0x54, 0x58,
+ 0x00, 0x00, 0x45, 0x7C, 0x41,
+ 0x00, 0x02, 0x45, 0x7D, 0x42,
+ 0x00, 0x01, 0x45, 0x7C, 0x40,
+ 0xF0, 0x29, 0x24, 0x29, 0xF0,
+ 0xF0, 0x28, 0x25, 0x28, 0xF0,
+ 0x7C, 0x54, 0x55, 0x45, 0x00,
+ 0x20, 0x54, 0x54, 0x7C, 0x54,
+ 0x7C, 0x0A, 0x09, 0x7F, 0x49,
+ 0x32, 0x49, 0x49, 0x49, 0x32,
+ 0x32, 0x48, 0x48, 0x48, 0x32,
+ 0x32, 0x4A, 0x48, 0x48, 0x30,
+ 0x3A, 0x41, 0x41, 0x21, 0x7A,
+ 0x3A, 0x42, 0x40, 0x20, 0x78,
+ 0x00, 0x9D, 0xA0, 0xA0, 0x7D,
+ 0x39, 0x44, 0x44, 0x44, 0x39,
+ 0x3D, 0x40, 0x40, 0x40, 0x3D,
+ 0x3C, 0x24, 0xFF, 0x24, 0x24,
+ 0x48, 0x7E, 0x49, 0x43, 0x66,
+ 0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
+ 0xFF, 0x09, 0x29, 0xF6, 0x20,
+ 0xC0, 0x88, 0x7E, 0x09, 0x03,
+ 0x20, 0x54, 0x54, 0x79, 0x41,
+ 0x00, 0x00, 0x44, 0x7D, 0x41,
+ 0x30, 0x48, 0x48, 0x4A, 0x32,
+ 0x38, 0x40, 0x40, 0x22, 0x7A,
+ 0x00, 0x7A, 0x0A, 0x0A, 0x72,
+ 0x7D, 0x0D, 0x19, 0x31, 0x7D,
+ 0x26, 0x29, 0x29, 0x2F, 0x28,
+ 0x26, 0x29, 0x29, 0x29, 0x26,
+ 0x30, 0x48, 0x4D, 0x40, 0x20,
+ 0x38, 0x08, 0x08, 0x08, 0x08,
+ 0x08, 0x08, 0x08, 0x08, 0x38,
+ 0x2F, 0x10, 0xC8, 0xAC, 0xBA,
+ 0x2F, 0x10, 0x28, 0x34, 0xFA,
+ 0x00, 0x00, 0x7B, 0x00, 0x00,
+ 0x08, 0x14, 0x2A, 0x14, 0x22,
+ 0x22, 0x14, 0x2A, 0x14, 0x08,
+ 0xAA, 0x00, 0x55, 0x00, 0xAA,
+ 0xAA, 0x55, 0xAA, 0x55, 0xAA,
+ 0x00, 0x00, 0x00, 0xFF, 0x00,
+ 0x10, 0x10, 0x10, 0xFF, 0x00,
+ 0x14, 0x14, 0x14, 0xFF, 0x00,
+ 0x10, 0x10, 0xFF, 0x00, 0xFF,
+ 0x10, 0x10, 0xF0, 0x10, 0xF0,
+ 0x14, 0x14, 0x14, 0xFC, 0x00,
+ 0x14, 0x14, 0xF7, 0x00, 0xFF,
+ 0x00, 0x00, 0xFF, 0x00, 0xFF,
+ 0x14, 0x14, 0xF4, 0x04, 0xFC,
+ 0x14, 0x14, 0x17, 0x10, 0x1F,
+ 0x10, 0x10, 0x1F, 0x10, 0x1F,
+ 0x14, 0x14, 0x14, 0x1F, 0x00,
+ 0x10, 0x10, 0x10, 0xF0, 0x00,
+ 0x00, 0x00, 0x00, 0x1F, 0x10,
+ 0x10, 0x10, 0x10, 0x1F, 0x10,
+ 0x10, 0x10, 0x10, 0xF0, 0x10,
+ 0x00, 0x00, 0x00, 0xFF, 0x10,
+ 0x10, 0x10, 0x10, 0x10, 0x10,
+ 0x10, 0x10, 0x10, 0xFF, 0x10,
+ 0x00, 0x00, 0x00, 0xFF, 0x14,
+ 0x00, 0x00, 0xFF, 0x00, 0xFF,
+ 0x00, 0x00, 0x1F, 0x10, 0x17,
+ 0x00, 0x00, 0xFC, 0x04, 0xF4,
+ 0x14, 0x14, 0x17, 0x10, 0x17,
+ 0x14, 0x14, 0xF4, 0x04, 0xF4,
+ 0x00, 0x00, 0xFF, 0x00, 0xF7,
+ 0x14, 0x14, 0x14, 0x14, 0x14,
+ 0x14, 0x14, 0xF7, 0x00, 0xF7,
+ 0x14, 0x14, 0x14, 0x17, 0x14,
+ 0x10, 0x10, 0x1F, 0x10, 0x1F,
+ 0x14, 0x14, 0x14, 0xF4, 0x14,
+ 0x10, 0x10, 0xF0, 0x10, 0xF0,
+ 0x00, 0x00, 0x1F, 0x10, 0x1F,
+ 0x00, 0x00, 0x00, 0x1F, 0x14,
+ 0x00, 0x00, 0x00, 0xFC, 0x14,
+ 0x00, 0x00, 0xF0, 0x10, 0xF0,
+ 0x10, 0x10, 0xFF, 0x10, 0xFF,
+ 0x14, 0x14, 0x14, 0xFF, 0x14,
+ 0x10, 0x10, 0x10, 0x1F, 0x00,
+ 0x00, 0x00, 0x00, 0xF0, 0x10,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFF, 0xFF,
+ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
+ 0x38, 0x44, 0x44, 0x38, 0x44,
+ 0x7C, 0x2A, 0x2A, 0x3E, 0x14,
+ 0x7E, 0x02, 0x02, 0x06, 0x06,
+ 0x02, 0x7E, 0x02, 0x7E, 0x02,
+ 0x63, 0x55, 0x49, 0x41, 0x63,
+ 0x38, 0x44, 0x44, 0x3C, 0x04,
+ 0x40, 0x7E, 0x20, 0x1E, 0x20,
+ 0x06, 0x02, 0x7E, 0x02, 0x02,
+ 0x99, 0xA5, 0xE7, 0xA5, 0x99,
+ 0x1C, 0x2A, 0x49, 0x2A, 0x1C,
+ 0x4C, 0x72, 0x01, 0x72, 0x4C,
+ 0x30, 0x4A, 0x4D, 0x4D, 0x30,
+ 0x30, 0x48, 0x78, 0x48, 0x30,
+ 0xBC, 0x62, 0x5A, 0x46, 0x3D,
+ 0x3E, 0x49, 0x49, 0x49, 0x00,
+ 0x7E, 0x01, 0x01, 0x01, 0x7E,
+ 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
+ 0x44, 0x44, 0x5F, 0x44, 0x44,
+ 0x40, 0x51, 0x4A, 0x44, 0x40,
+ 0x40, 0x44, 0x4A, 0x51, 0x40,
+ 0x00, 0x00, 0xFF, 0x01, 0x03,
+ 0xE0, 0x80, 0xFF, 0x00, 0x00,
+ 0x08, 0x08, 0x6B, 0x6B, 0x08,
+ 0x36, 0x12, 0x36, 0x24, 0x36,
+ 0x06, 0x0F, 0x09, 0x0F, 0x06,
+ 0x00, 0x00, 0x18, 0x18, 0x00,
+ 0x00, 0x00, 0x10, 0x10, 0x00,
+ 0x30, 0x40, 0xFF, 0x01, 0x01,
+ 0x00, 0x1F, 0x01, 0x01, 0x1E,
+ 0x00, 0x19, 0x1D, 0x17, 0x12,
+ 0x00, 0x3C, 0x3C, 0x3C, 0x3C,
+ 0x00, 0x00, 0x00, 0x00, 0x00
+};
diff --git a/drivers/qwiic/util/font8x16.h b/drivers/qwiic/util/font8x16.h
new file mode 100644
index 000000000..c070e4ec8
--- /dev/null
+++ b/drivers/qwiic/util/font8x16.h
@@ -0,0 +1,127 @@
+/******************************************************************************
+font8x16.h
+Definition for medium font
+
+This file was imported from the MicroView library, written by GeekAmmo
+(https://github.com/geekammo/MicroView-Arduino-Library), and released 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 .
+
+Modified by:
+Emil Varughese @ Edwin Robotics Pvt. Ltd.
+July 27, 2015
+https://github.com/emil01/SparkFun_Micro_OLED_Arduino_Library/
+******************************************************************************/
+#pragma once
+
+#include "progmem.h"
+
+static const unsigned char font8x16[] PROGMEM = {
+ // first row defines - FONTWIDTH, FONTHEIGHT, ASCII START CHAR, TOTAL CHARACTERS, FONT MAP WIDTH HIGH, FONT MAP WIDTH LOW (2,56 meaning 256)
+ 8,16,32,96,2,56,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xBE, 0x90, 0xD0, 0xBE, 0x90, 0x00,
+ 0x00, 0x1C, 0x62, 0xFF, 0xC2, 0x80, 0x00, 0x00, 0x0C, 0x12, 0x92, 0x4C, 0xB0, 0x88, 0x06, 0x00,
+ 0x80, 0x7C, 0x62, 0xB2, 0x1C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0E, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xE0, 0x18, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x04, 0x18, 0xE0, 0x00, 0x00,
+ 0x00, 0x24, 0x18, 0x7E, 0x18, 0x24, 0x00, 0x00, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00,
+ 0xF8, 0x04, 0xC2, 0x32, 0x0C, 0xF8, 0x00, 0x00, 0x00, 0x04, 0x04, 0xFE, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00,
+ 0xC0, 0xA0, 0x98, 0x84, 0xFE, 0x80, 0x80, 0x00, 0x00, 0x1E, 0x12, 0x12, 0x22, 0xC2, 0x00, 0x00,
+ 0xF8, 0x44, 0x22, 0x22, 0x22, 0xC0, 0x00, 0x00, 0x00, 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00,
+ 0x00, 0x8C, 0x52, 0x22, 0x52, 0x8C, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x26, 0xF8, 0x00, 0x00,
+ 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
+ 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x02, 0x82, 0x42, 0x22, 0x1C, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x04, 0x0F, 0x04, 0x03, 0x00, 0x00, 0x04, 0x02, 0x01, 0x03, 0x04, 0x04, 0x03, 0x00,
+ 0x03, 0x04, 0x04, 0x04, 0x05, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x06, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, 0x06, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x03, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00,
+ 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
+ 0x01, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x0E, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
+ 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xF8, 0x04, 0x72, 0x8A, 0xFA, 0x84, 0x78, 0x00, 0x00, 0xC0, 0x38, 0x06, 0x38, 0xC0, 0x00, 0x00,
+ 0x00, 0xFE, 0x22, 0x22, 0x22, 0xDC, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00,
+ 0xFE, 0x02, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00, 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00,
+ 0x00, 0xFE, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x22, 0xE2, 0x00, 0x00,
+ 0xFE, 0x20, 0x20, 0x20, 0x20, 0xFE, 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0xFE, 0x40, 0xB0, 0x08, 0x04, 0x02, 0x00, 0x00,
+ 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x0C, 0x70, 0x80, 0x70, 0x0C, 0xFE, 0x00,
+ 0xFE, 0x0C, 0x30, 0xC0, 0x00, 0xFE, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00,
+ 0xFE, 0x42, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, 0xF8, 0x04, 0x02, 0x02, 0x04, 0xF8, 0x00, 0x00,
+ 0x00, 0xFE, 0x42, 0x42, 0xA2, 0x1C, 0x00, 0x00, 0x00, 0x1C, 0x22, 0x42, 0x42, 0x80, 0x00, 0x00,
+ 0x02, 0x02, 0x02, 0xFE, 0x02, 0x02, 0x02, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,
+ 0x06, 0x38, 0xC0, 0x00, 0xC0, 0x38, 0x06, 0x00, 0x3E, 0xC0, 0xF0, 0x0E, 0xF0, 0xC0, 0x3E, 0x00,
+ 0x00, 0x06, 0x98, 0x60, 0x98, 0x06, 0x00, 0x00, 0x00, 0x06, 0x18, 0xE0, 0x18, 0x06, 0x00, 0x00,
+ 0x02, 0x02, 0xC2, 0x32, 0x0A, 0x06, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x02, 0x02, 0x00,
+ 0x00, 0x06, 0x18, 0x60, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00,
+ 0x40, 0x30, 0x0C, 0x0C, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00,
+ 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
+ 0x07, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x04, 0x07, 0x00, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x04, 0x07, 0x04, 0x04, 0x00, 0x00,
+ 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00,
+ 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x0C, 0x12, 0x11, 0x10, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
+ 0x00, 0x06, 0x01, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00,
+ 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0xE0, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00,
+ 0x00, 0x20, 0xFC, 0x22, 0x22, 0x22, 0x02, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00,
+ 0x00, 0xFE, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x80, 0x40, 0x20, 0x10, 0x00, 0x00,
+ 0x00, 0x02, 0x02, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x20, 0x10, 0xF0, 0x20, 0x10, 0xF0, 0x00,
+ 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xE0, 0x00, 0x00,
+ 0x00, 0xF0, 0x20, 0x10, 0x10, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00,
+ 0x00, 0xF0, 0x20, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x20, 0x00, 0x00,
+ 0x00, 0x20, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00,
+ 0x00, 0x70, 0x80, 0x00, 0x80, 0x70, 0x00, 0x00, 0xF0, 0x00, 0xC0, 0x30, 0xC0, 0x00, 0xF0, 0x00,
+ 0x00, 0x30, 0xC0, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x80, 0x70, 0x00, 0x00,
+ 0x00, 0x10, 0x10, 0x90, 0x50, 0x30, 0x00, 0x00, 0x00, 0x80, 0x80, 0x7E, 0x02, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x7E, 0x80, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00,
+ 0x00, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
+ 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x24, 0x24, 0x22, 0x1F, 0x00, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
+ 0x00, 0x3F, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x3F, 0x00, 0x00,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x00, 0x00, 0x03, 0x04, 0x04, 0x02, 0x07, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x04, 0x03, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x00, 0x01, 0x06, 0x01, 0x00,
+ 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x00, 0x00, 0x20, 0x20, 0x31, 0x0E, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x05, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
diff --git a/keyboards/hadron/config.h b/keyboards/hadron/config.h
index 9111ad727..d54d2c543 100644
--- a/keyboards/hadron/config.h
+++ b/keyboards/hadron/config.h
@@ -24,7 +24,7 @@ along with this program. If not, see .
#define PRODUCT_ID 0x6060
#define MANUFACTURER ishtob
#define PRODUCT Hadron Keyboard
-#define DESCRIPTION A cherry ML ortholinear keyboard
+#define DESCRIPTION A low profile ortholinear keyboard
@@ -46,9 +46,9 @@ along with this program. If not, see .
#define DEBOUNCING_DELAY 5
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
-#define LOCKING_SUPPORT_ENABLE
+//#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
-#define LOCKING_RESYNC_ENABLE
+//#define LOCKING_RESYNC_ENABLE
/* key combination for command */
#define IS_COMMAND() ( \
@@ -70,7 +70,7 @@ along with this program. If not, see .
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT
-#define NO_ACTION_MACRO
-#define NO_ACTION_FUNCTION
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
diff --git a/keyboards/hadron/hadron.c b/keyboards/hadron/hadron.c
index ca5b20e89..fa5065b32 100644
--- a/keyboards/hadron/hadron.c
+++ b/keyboards/hadron/hadron.c
@@ -1,26 +1,2 @@
#include "hadron.h"
-
-void matrix_init_kb(void) {
-
- matrix_init_user();
-}
-
-void matrix_scan_kb(void) {
- // put your looping keyboard code here
- // runs every cycle (a lot)
- matrix_scan_user();
-}
-
-bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
- // put your per-action keyboard code here
- // runs for every action, just before processing by the firmware
-
- return process_record_user(keycode, record);
-}
-
-void led_set_kb(uint8_t usb_led) {
- // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
-
- led_set_user(usb_led);
-}
\ No newline at end of file
diff --git a/keyboards/hadron/hadron.h b/keyboards/hadron/hadron.h
index a165f4c5c..426face6f 100644
--- a/keyboards/hadron/hadron.h
+++ b/keyboards/hadron/hadron.h
@@ -7,7 +7,9 @@
#ifdef SUBPROJECT_ver2
#include "ver2.h"
#endif
-
+#ifdef SUBPROJECT_ver3
+ #include "ver3.h"
+#endif
#include "quantum.h"
diff --git a/keyboards/hadron/keymaps/default/config.h b/keyboards/hadron/keymaps/default/config.h
deleted file mode 100644
index 09922b61b..000000000
--- a/keyboards/hadron/keymaps/default/config.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define LEADER_TIMEOUT 300
-//#define BACKLIGHT_BREATHING
-
-#define USE_I2C
-#define SSD1306OLED
-#define OLED_ROTATE180
-
-/* ws2812 RGB LED*/
-#define RGB_DI_PIN D4
-#define RGBLIGHT_ANIMATIONS
-#define RGBLED_NUM 14 // Number of LEDs
-#define RGBLIGHT_HUE_STEP 10
-#define RGBLIGHT_SAT_STEP 17
-
-#endif
diff --git a/keyboards/hadron/keymaps/default/keymap.c b/keyboards/hadron/keymaps/default/keymap.c
deleted file mode 100644
index de5979c1d..000000000
--- a/keyboards/hadron/keymaps/default/keymap.c
+++ /dev/null
@@ -1,493 +0,0 @@
-#include QMK_KEYBOARD_H
-#include "LUFA/Drivers/Peripheral/TWI.h"
-#ifdef AUDIO_ENABLE
- #include "audio.h"
-#endif
-#ifdef USE_I2C
-#include "i2c.h"
-#endif
-#ifdef SSD1306OLED
-#include "ssd1306.h"
-#endif
-extern keymap_config_t keymap_config;
-
-//Following line allows macro to read current RGB settings
-extern rgblight_config_t rgblight_config;
-
-// Each layer gets a name for readability, which is then used in the keymap matrix below.
-// The underscores don't mean anything - you can have a layer called STUFF or any other name.
-// Layer names don't all need to be of the same length, obviously, and you can also skip them
-// entirely and just use numbers.
-#define _QWERTY 0
-#define _COLEMAK 1
-#define _DVORAK 2
-#define _LOWER 3
-#define _RAISE 4
-#define _MOUSECURSOR 8
-#define _ADJUST 16
-
-enum preonic_keycodes {
- QWERTY = SAFE_RANGE,
- COLEMAK,
- DVORAK,
- LOWER,
- RAISE,
- BACKLIT,
- RGBLED_TOGGLE,
- RGBLED_STEP_MODE,
- RGBLED_INCREASE_HUE,
- RGBLED_DECREASE_HUE,
- RGBLED_INCREASE_SAT,
- RGBLED_DECREASE_SAT,
- RGBLED_INCREASE_VAL,
- RGBLED_DECREASE_VAL,
-};
-
-enum macro_keycodes {
- KC_DEMOMACRO,
-};
-
-// Fillers to make layering more clear
-#define _______ KC_TRNS
-#define XXXXXXX KC_NO
-// Custom macros
-#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
-#define CTL_TTAB CTL_T(KC_TAB) // Tap for Esc, hold for Ctrl
-#define CTL_ENT CTL_T(KC_ENT) // Tap for Enter, hold for Ctrl
-#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
-// Requires KC_TRNS/_______ for the trigger key in the destination layer
-#define LT_MC(kc) LT(_MOUSECURSOR, kc) // L-ayer T-ap M-ouse C-ursor
-#define LT_RAI(kc) LT(_RAISE, kc) // L-ayer T-ap to Raise
-#define DEMOMACRO M(KC_DEMOMACRO) // Sample for macros
-
-
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
-
-/* Qwerty
- * ,------+------+------+------+------+------------------------------------------------.
- * | Esc | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | DEL |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | Tab | Q | W | E | R | T | 7 | 8 | 9 | Y | U | I | O | P | Bksp |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | CAPS | A | S | D | F | G | 4 | 5 | 6 | H | J | K | L | ;/Nav| ' |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| Z | X | C | V | B | 1 | 2 | 3 | N | M | , | . | / |Ctl/Et|
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_QWERTY] = LAYOUT(
- KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_P7, KC_P8, KC_P9, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
- KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_P4, KC_P5, KC_P6, KC_H, KC_J, KC_K, KC_L,LT_MC(KC_SCLN), KC_QUOT, \
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_P1, KC_P2, KC_P3, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, CTL_ENT, \
- KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT,KC_DOWN, KC_UP, KC_RGHT \
-),
-
-/* Colemak
- * ,------+------+------+------+------+------------------------------------------------.
- * | Esc | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | 0 | - |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | Tab | Q | W | F | P | G | 7 | 8 | 9 | J | L | U | Y | ; | Bksp |
- * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
- * | CAPS | A | R | S | T | D | 4 | 5 | 6 | H | N | E | I | O | ' |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| Z | X | C | V | B | 1 | 2 | 3 | K | M | , | . | / |Ctl/Et|
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_COLEMAK] = LAYOUT(
- KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
- KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_P7, KC_P8, KC_P9, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
- KC_LCTRL, KC_A, KC_R, KC_S, KC_T, KC_D, KC_P4, KC_P5, KC_P6, KC_H, KC_N, KC_E, KC_I, LT_MC(KC_O), KC_QUOT, \
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_P1, KC_P2, KC_P3, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, CTL_ENT, \
- KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
- ),
-
-/* Dvorak
- * ,------+------+------+------+------+------------------------------------------------.
- * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | Tab | " | , | . | P | Y | 7 | 8 | 9 | F | G | C | R | L | Bksp |
- * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
- * | Esc | A | O | E | U | I | 4 | 5 | 6 | D | H | T | N | S | / |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| ; | Q | J | K | X | 1 | 2 | 3 | B | M | W | V | Z |Ctl/Et|
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_DVORAK] = LAYOUT(
- KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
- KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_P7, KC_P8, KC_P9, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
- KC_LCTL, KC_A, KC_O, KC_E, KC_U, KC_I, KC_P4, KC_P5, KC_P6, KC_D, KC_H, KC_T, KC_N, LT_MC(KC_S), KC_SLSH, \
- KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_P1, KC_P2, KC_P3, KC_B, KC_M, KC_W, KC_V, KC_Z, CTL_ENT, \
- KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
-),
-
-/* Lower
- * ,------+------+------+------+------+------------------------------------------------.
- * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | ~ | ! | @ | # | $ | % | | | | ^ | & | * | ( | ) | Del |
- * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
- * | | F1 | F2 | F3 | F4 | F5 | | | | F6 | _ | + | { | } | | |
- * |------+------+------+------+------+------|------+------+------+------+------+------+------+------+------|
- * | | F7 | F8 | F9 | F10 | F11 | | | | F12 |ISO ~ |ISO | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | | | Next | Vol- | Vol+ | Play |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_LOWER] = LAYOUT(
- KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
- KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, _______, _______, _______, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
- _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, _______, KC_F6, KC_UNDS, KC_PLUS, KC_LBRC, KC_RBRC, KC_PIPE, \
- _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, KC_F12,S(KC_NUHS),S(KC_NUBS),_______,_______, _______, \
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
-),
-
-/* Raise
- * ,------+------+------+------+------+------------------------------------------------.
- * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | ` | 1 | 2 | 3 | 4 | 5 | | | | 6 | 7 | 8 | 9 | 0 | Del |
- * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
- * | Del | F1 | F2 | F3 | F4 | F5 | | | | F6 | - | = | [ | ] | \ |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | F7 | F8 | F9 | F10 | F11 | | | | F12 |ISO # |ISO / | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | | | Next | Vol- | Vol+ | Play |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_RAISE] = LAYOUT(
- KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
- KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, _______, _______, _______, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
- KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, _______, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
- _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \
- _______, _______, _______, _______, _______, KC_SPC, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
-),
-
-/* Mouse Layer (semi-col)
- * ,------+------+------+------+------+------------------------------------------------.
- * | ACCL0| ACCL1| ACCL2| | | | | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | | | | | | | | | Home | Wh_Up| WHL_L| M_Up | WHL_R| Macro| |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | End | Wh_Dn| M_Lft| M_Dn | M_Rt | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | BTN2 | BTN3 | BTN4 | BTN5 | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | BTN1 | | | | BTN1 | | | | | |
- * `--------------------------------------------------------------------------------------------------------'
- */
-
-[_MOUSECURSOR] = LAYOUT(
- KC_ACL0, KC_ACL1, KC_ACL2, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
- _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGUP, KC_WH_L, KC_MS_U, KC_WH_R,DEMOMACRO,_______, \
- _______, _______, _______, _______, _______, _______, _______, _______, KC_END , KC_PGDN, KC_MS_L, KC_MS_D, KC_MS_R, _______, _______, \
- _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_BTN2, KC_BTN3, KC_BTN4, KC_BTN5, _______, _______, \
- _______, _______, _______, _______, _______, KC_BTN1, _______, _______, _______, KC_BTN1, _______, _______, _______, _______, _______ \
-),
-
-/* Adjust (Lower + Raise)
- * ,------+------+------+------+------+------------------------------------------------.
- * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | Reset|RGB TG|RGB ST|RGBH -|RGBH +|RGBS -|RGBS +|RGBV -|RGBV +| | | | | | Del |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | |Aud on|Audoff|AGnorm| | | |AGswap|Qwerty|Colemk| | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | |Voice-|Voice+|Mus on|Musoff| | | | | | | | BL + |BL ST |BL TG |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | | | | | | |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_ADJUST] = LAYOUT(
- KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
- RESET, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______, KC_DEL, \
- _______, _______, _______, AU_ON, AU_OFF, AG_NORM, _______, _______, _______, AG_SWAP, QWERTY, COLEMAK, _______, _______, _______, \
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, BL_DEC, BL_INC, BL_STEP, BL_TOGG, \
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______\
-)
-
-
-
-};
-
-
-#ifdef AUDIO_ENABLE
-
-float tone_startup[][2] = SONG(STARTUP_SOUND);
-float tone_qwerty[][2] = SONG(QWERTY_SOUND);
-float tone_dvorak[][2] = SONG(DVORAK_SOUND);
-float tone_colemak[][2] = SONG(COLEMAK_SOUND);
-float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
-float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
-#endif
-
-// define variables for reactive RGB
-bool RGB_INIT = false;
-bool TOG_STATUS = false;
-int RGB_current_mode;
-
-
-
-void persistant_default_layer_set(uint16_t default_layer) {
- eeconfig_update_default_layer(default_layer);
- default_layer_set(default_layer);
-}
-
-void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
- if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
- rgblight_mode(RGB_current_mode);
- layer_on(layer3);
- } else {
- layer_off(layer3);
- }
-}
-
-bool process_record_user(uint16_t keycode, keyrecord_t *record) {
- switch (keycode) {
- case QWERTY:
- if (record->event.pressed) {
- #ifdef AUDIO_ENABLE
- PLAY_SONG(tone_qwerty);
- #endif
- persistant_default_layer_set(1UL<<_QWERTY);
- }
- return false;
- break;
- case COLEMAK:
- if (record->event.pressed) {
- #ifdef AUDIO_ENABLE
- PLAY_SONG(tone_colemak);
- #endif
- persistant_default_layer_set(1UL<<_COLEMAK);
- }
- return false;
- break;
- case LOWER:
- if (record->event.pressed) {
- //not sure how to have keyboard check mode and set it to a variable, so my work around
- //uses another variable that would be set to true after the first time a reactive key is pressed.
- if (RGB_INIT) {} else {
- RGB_current_mode = rgblight_config.mode;
- RGB_INIT = true;
- }
- if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
- } else {
- TOG_STATUS = !TOG_STATUS;
- rgblight_mode(16);
- }
- layer_on(_LOWER);
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- } else {
- rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
- TOG_STATUS = false;
- layer_off(_LOWER);
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- }
- return false;
- break;
- case RAISE:
- if (record->event.pressed) {
- //not sure how to have keyboard check mode and set it to a variable, so my work around
- //uses another variable that would be set to true after the first time a reactive key is pressed.
- if (RGB_INIT) {} else {
- RGB_current_mode = rgblight_config.mode;
- RGB_INIT = true;
- }
- if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
- } else {
- TOG_STATUS = !TOG_STATUS;
- rgblight_mode(15);
- }
- layer_on(_RAISE);
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- } else {
- rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
- layer_off(_RAISE);
- TOG_STATUS = false;
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- }
- return false;
- break;
- case BACKLIT:
- if (record->event.pressed) {
- register_code(KC_RSFT);
- #ifdef BACKLIGHT_ENABLE
- backlight_step();
- #endif
- } else {
- unregister_code(KC_RSFT);
- }
- return false;
- break;
- case RGB_MOD:
- //led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
- if (record->event.pressed) {
- rgblight_mode(RGB_current_mode);
- rgblight_step();
- RGB_current_mode = rgblight_config.mode;
- }
- return false;
- break;
- }
- return true;
-}
-
-void matrix_init_user(void) {
- #ifdef USE_I2C
- i2c_master_init();
- #ifdef SSD1306OLED
- // calls code for the SSD1306 OLED
- _delay_ms(400);
- TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
- iota_gfx_init(); // turns on the display
- #endif
- #endif
- #ifdef AUDIO_ENABLE
- startup_user();
- #endif
-}
-
-void matrix_scan_user(void) {
- #ifdef SSD1306OLED
- iota_gfx_task(); // this is what updates the display continuously
- #endif
-}
-
-#ifdef AUDIO_ENABLE
-
-void startup_user()
-{
- _delay_ms(20); // gets rid of tick
- PLAY_SONG(tone_startup);
-}
-
-void shutdown_user()
-{cc
- PLAY_SONG(tone_goodbye);
- _delay_ms(150);
- stop_all_notes();
-}
-
-void music_on_user(void)
-{
- music_scale_user();
-}
-
-void music_scale_user(void)
-{
- PLAY_SONG(music_scale);
-}
-
-#endif
-
-/*
- * Macro definition
- */
-const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
-{
- if (!eeconfig_is_enabled()) {
- eeconfig_init();
- }
-
- switch (id) {
- case KC_DEMOMACRO:
- if (record->event.pressed){
- return MACRO (I(1), T(H),T(E),T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
- }
- }
-
- return MACRO_NONE;
-}
-
-void matrix_update(struct CharacterMatrix *dest,
- const struct CharacterMatrix *source) {
- if (memcmp(dest->display, source->display, sizeof(dest->display))) {
- memcpy(dest->display, source->display, sizeof(dest->display));
- dest->dirty = true;
- }
-}
-
-//assign the right code to your layers for OLED display
-#define L_BASE 0
-#define L_LOWER 8
-#define L_RAISE 16
-#define L_FNLAYER 64
-#define L_NUMLAY 128
-#define L_NLOWER 136
-#define L_NFNLAYER 192
-#define L_MOUSECURSOR 256
-#define L_ADJUST 65560
-
-void iota_gfx_task_user(void) {
-#if DEBUG_TO_SCREEN
- if (debug_enable) {
- return;
- }
-#endif
-
- struct CharacterMatrix matrix;
-
- matrix_clear(&matrix);
- matrix_write_P(&matrix, PSTR("USB: "));
-#ifdef PROTOCOL_LUFA
- switch (USB_DeviceState) {
- case DEVICE_STATE_Unattached:
- matrix_write_P(&matrix, PSTR("Unattached"));
- break;
- case DEVICE_STATE_Suspended:
- matrix_write_P(&matrix, PSTR("Suspended"));
- break;
- case DEVICE_STATE_Configured:
- matrix_write_P(&matrix, PSTR("Connected"));
- break;
- case DEVICE_STATE_Powered:
- matrix_write_P(&matrix, PSTR("Powered"));
- break;
- case DEVICE_STATE_Default:
- matrix_write_P(&matrix, PSTR("Default"));
- break;
- case DEVICE_STATE_Addressed:
- matrix_write_P(&matrix, PSTR("Addressed"));
- break;
- default:
- matrix_write_P(&matrix, PSTR("Invalid"));
- }
-#endif
-
-// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
-
- char buf[40];
- snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
- matrix_write_P(&matrix, PSTR("\n\nLayer: "));
- switch (layer_state) {
- case L_BASE:
- matrix_write_P(&matrix, PSTR("Default"));
- break;
- case L_RAISE:
- matrix_write_P(&matrix, PSTR("Raise"));
- break;
- case L_LOWER:
- matrix_write_P(&matrix, PSTR("Lower"));
- break;
- case L_ADJUST:
- matrix_write_P(&matrix, PSTR("ADJUST"));
- break;
- default:
- matrix_write(&matrix, buf);
- }
-
- // Host Keyboard LED Status
- char led[40];
- snprintf(led, sizeof(led), "\n%s %s %s",
- (host_keyboard_leds() & (1<sort lines), and use this format:
-
- * **folder_name** description
-
-# List of Planck keymaps
-
-* **default** default Planck layout
-* **cbbrowne** cbbrowne's Planck layout
\ No newline at end of file
diff --git a/keyboards/hadron/keymaps/side_numpad/config.h b/keyboards/hadron/keymaps/side_numpad/config.h
deleted file mode 100644
index 09922b61b..000000000
--- a/keyboards/hadron/keymaps/side_numpad/config.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef CONFIG_USER_H
-#define CONFIG_USER_H
-
-#include "../../config.h"
-
-#define LEADER_TIMEOUT 300
-//#define BACKLIGHT_BREATHING
-
-#define USE_I2C
-#define SSD1306OLED
-#define OLED_ROTATE180
-
-/* ws2812 RGB LED*/
-#define RGB_DI_PIN D4
-#define RGBLIGHT_ANIMATIONS
-#define RGBLED_NUM 14 // Number of LEDs
-#define RGBLIGHT_HUE_STEP 10
-#define RGBLIGHT_SAT_STEP 17
-
-#endif
diff --git a/keyboards/hadron/keymaps/side_numpad/keymap.c b/keyboards/hadron/keymaps/side_numpad/keymap.c
deleted file mode 100644
index fa42c79ea..000000000
--- a/keyboards/hadron/keymaps/side_numpad/keymap.c
+++ /dev/null
@@ -1,502 +0,0 @@
-#include QMK_KEYBOARD_H
-#include "LUFA/Drivers/Peripheral/TWI.h"
-#ifdef AUDIO_ENABLE
- #include "audio.h"
-#endif
-#ifdef USE_I2C
-#include "i2c.h"
-#endif
-#ifdef SSD1306OLED
-#include "ssd1306.h"
-#endif
-extern keymap_config_t keymap_config;
-
-//Following line allows macro to read current RGB settings
-extern rgblight_config_t rgblight_config;
-
-// Each layer gets a name for readability, which is then used in the keymap matrix below.
-// The underscores don't mean anything - you can have a layer called STUFF or any other name.
-// Layer names don't all need to be of the same length, obviously, and you can also skip them
-// entirely and just use numbers.
-#define _QWERTY 0
-#define _LOWER 3
-#define _RAISE 4
-#define _FNLAYER 6
-#define _NUMLAY 7
-#define _MOUSECURSOR 8
-#define _ADJUST 16
-
-enum preonic_keycodes {
- QWERTY = SAFE_RANGE,
- COLEMAK,
- DVORAK,
- LOWER,
- RAISE,
- BACKLIT,
- RGBLED_TOGGLE,
- RGBLED_STEP_MODE,
- RGBLED_INCREASE_HUE,
- RGBLED_DECREASE_HUE,
- RGBLED_INCREASE_SAT,
- RGBLED_DECREASE_SAT,
- RGBLED_INCREASE_VAL,
- RGBLED_DECREASE_VAL,
-};
-
-enum macro_keycodes {
- KC_DEMOMACRO,
-};
-
-// Fillers to make layering more clear
-#define _______ KC_TRNS
-#define XXXXXXX KC_NO
-// Custom macros
-#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
-#define CTL_TTAB CTL_T(KC_TAB) // Tap for Esc, hold for Ctrl
-#define CTL_ENT CTL_T(KC_ENT) // Tap for Enter, hold for Ctrl
-#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
-// Requires KC_TRNS/_______ for the trigger key in the destination layer
-#define LT_FN(kc) LT(_FNLAYER, kc) // L-ayer T-ap Function Layer
-#define LT_MC(kc) LT(_MOUSECURSOR, kc) // L-ayer T-ap M-ouse C-ursor
-#define LT_RAI(kc) LT(_RAISE, kc) // L-ayer T-ap to Raise
-#define TG_NUMLAY TG(_NUMLAY) //Toggle for layer _NUMLAY
-#define DEMOMACRO M(KC_DEMOMACRO) // My login macros
-
-
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
-
-/* Qwerty
- * ,------+------+------+------+------+------------------------------------------------.
- * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | 7 | 8 | 9 |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | CAPS | A | S | D | F | G | H | J | K | L | ; |Enter | 4 | 5 | 6 |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | Shift| Z | X | C | V | B | N | M | , | . | / | = | 1 | 2 | 3 |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | ~ | Ctrl | Alt | GUI |Lower |Space |Space |Raise | RAlt | Ins | Del |NumLay| 0 | . | ENT |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_QWERTY] = LAYOUT(
- KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,\
- KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, KC_P7, KC_P8, KC_P9, \
- KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, LT_MC(KC_SCLN), CTL_ENT, KC_P4, KC_P5, KC_P6, \
- KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_EQL, KC_P1, KC_P2, KC_P3, \
- KC_GRV, KC_RCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_RALT, KC_INS, KC_DEL, TG_NUMLAY, KC_P0, KC_PDOT, KC_PENT \
-),
-
-/* Lower
- * ,-----------------------------------------------------------------------------------.
- * | | | | | | | | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | ~ | \ | | | |
- * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
- * | CAPS | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | [ | ] | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | Next | Vol- | Vol+ | Play | | | |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_LOWER] = LAYOUT(
- KC_ESC, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \
- KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_GRV, KC_BSLS, _______, _______, _______, \
- KC_CAPS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_EQL, KC_LBRC, KC_RBRC, KC_PIPE, _______, _______, _______, \
- _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, S(KC_NUHS), S(KC_NUBS), KC_LCBR, KC_RCBR, _______, _______, _______, _______, \
- _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, _______, _______, _______\
-),
-
-/* Raise
- * ,-----------------------------------------------------------------------------------.
- * | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | ~ | \ | | | |
- * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
- * | | A | Up | D | PrSc | | 4 | 5 | 6 | * | : | ' | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | Lt | Dn | Rt | Mute | | 1 | 2 | 3 | Up | / | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | |Space | 0 | | Left | Down | Right| | | | |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_RAISE] = LAYOUT(
- KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
- KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_PLUS, KC_BSLS, _______, _______, _______, \
- _______, KC_A, KC_UP, KC_D, KC_PSCR, _______, KC_4, KC_5, KC_6, KC_PAST, KC_COLN, KC_QUOT, _______, _______, _______, \
- _______, KC_LEFT, KC_DOWN, KC_RIGHT, KC__MUTE, _______, KC_1, KC_2, KC_3, KC_UP, KC_SLSH, _______, _______, _______, _______, \
- _______, _______, _______, _______, _______, KC_SPC, KC_0, _______, KC_LEFT, KC_DOWN, KC_RIGHT, _______, _______, _______, _______ \
-),
-
-/* FN layer on Esc key
- * ,-----------------------------------------------------------------------------------.
- * | | | | | | | | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | | ! | @ | # | $ | % | ^ | & | * | ( | ) | + | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | F1 | F2 | F3 | F4 | F5 | F6 | _ | = | [ | ] | ' | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | { | } | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | Next | Vol- | Vol+ | Play | | | |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_FNLAYER] = LAYOUT(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,\
- _______, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_PLUS, _______, _______, _______, \
- _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_EQL, KC_LBRC, KC_RBRC, KC_QUOT, _______, _______, _______, \
- _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS), S(KC_NUBS), KC_LCBR, KC_RCBR, _______, _______, _______, _______, \
- _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, _______, _______, _______ \
-),
-
-/* Num Layer
- * ,-----------------------------------------------------------------------------------.
- * | | | | | | | | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | | | | | | | | | | | | | F7 | F8 | F9 |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | | | | F4 | F5 | F6 |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | | | | | Up | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | | | Exit | Left | Down | Rght |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_NUMLAY] = LAYOUT(
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,\
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS, KC_HOME, KC_PGUP, \
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, KC_END, KC_PGDN, \
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PMNS, KC_UP, KC_PPLS, \
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RIGHT \
-),
-
-/* Mouse Layer (semi-col)
- * ,-----------------------------------------------------------------------------------.
- * | |ACCL0| ACCL1| ACCL2 | | | | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | | | | | | Home | Wh_Up| WHL_L| M_Up | WHL_R| | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | End | Wh_Dn| M_Lft| M_Dn | M_Rt | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | BTN2 | BTN3 | BTN4 | BTN5 | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | BTN1 | | | | BTN1 | | | | | |
- * `--------------------------------------------------------------------------------------------------------'
- */
-
-[_MOUSECURSOR] = LAYOUT(
- _______, KC_ACL0, KC_ACL1, KC_ACL2, _______, _______, _______, _______, _______, _______, _______, _______,\
- _______, _______, _______, _______, _______, KC_HOME, KC_PGUP, KC_WH_L, KC_MS_U, KC_WH_R, DEMOMACRO, _______, _______, _______, _______, \
- _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_END , KC_PGDN, KC_MS_L, KC_MS_D, KC_MS_R, _______, _______, _______, _______, _______, \
- _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, KC_BTN2, KC_BTN3, KC_BTN4, KC_BTN5, _______, _______, _______, _______, _______, \
- _______, _______, _______, _______, _______, KC_BTN1, KC_BTN1, _______, _______, _______, _______, _______, _______, _______, _______ \
-),
-
-/* Adjust (Lower + Raise)
-
- * ,-----------------------------------------------------------------------------------.
- * | Reset| | | | | | | | | VolD | VolU | Mute |
- * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
- * | |RGB TG|RGB ST|RGBH -|RGBH +|RGBS -|RGBS +|RGBV -|RGBV +| | | Del | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty| | | | | | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | BL + |BL ST |BLSTEP| BL TG| | | |
- * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
- * | | | | | | | | | | | | | | | |
- * `--------------------------------------------------------------------------------------------------------'
- */
-[_ADJUST] = LAYOUT(
- RESET, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_VOLD, KC_VOLU, KC_MUTE, \
- _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, KC_DEL, _______, _______, _______, \
- _______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, _______, _______, _______, _______, _______, _______, _______, \
- _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, BL_DEC, BL_INC, BL_STEP, BL_TOGG, _______, _______, _______, \
- _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
-)
-
-
-
-};
-
-
-#ifdef AUDIO_ENABLE
-
-float tone_startup[][2] = SONG(STARTUP_SOUND);
-float tone_qwerty[][2] = SONG(QWERTY_SOUND);
-float music_scale[][2] = SONG(MUSIC_SCALE_SOUND);
-float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
-#endif
-
-// define variables for reactive RGB
-bool RGB_INIT = false;
-bool TOG_STATUS = false;
-bool NUMLAY_STATUS = false;
-int RGB_current_mode;
-
-
-
-void persistant_default_layer_set(uint16_t default_layer) {
- eeconfig_update_default_layer(default_layer);
- default_layer_set(default_layer);
-}
-
-void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
- if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
- rgblight_mode(RGB_current_mode);
- layer_on(layer3);
- } else {
- layer_off(layer3);
- }
-}
-
-bool process_record_user(uint16_t keycode, keyrecord_t *record) {
- switch (keycode) {
- case QWERTY:
- if (record->event.pressed) {
- #ifdef AUDIO_ENABLE
- PLAY_SONG(tone_qwerty);
- #endif
- persistant_default_layer_set(1UL<<_QWERTY);
- }
- return false;
- break;
- case LOWER:
- if (record->event.pressed) {
- //not sure how to have keyboard check mode and set it to a variable, so my work around
- //uses another variable that would be set to true after the first time a reactive key is pressed.
- if (RGB_INIT) {} else {
- RGB_current_mode = rgblight_config.mode;
- RGB_INIT = true;
- }
- if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
- } else {
- TOG_STATUS = !TOG_STATUS;
- rgblight_mode(16);
- }
- layer_on(_LOWER);
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- } else {
- rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
- TOG_STATUS = false;
- layer_off(_LOWER);
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- }
- return false;
- break;
- case RAISE:
- if (record->event.pressed) {
- //not sure how to have keyboard check mode and set it to a variable, so my work around
- //uses another variable that would be set to true after the first time a reactive key is pressed.
- if (RGB_INIT) {} else {
- RGB_current_mode = rgblight_config.mode;
- RGB_INIT = true;
- }
- if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
- } else {
- TOG_STATUS = !TOG_STATUS;
- rgblight_mode(15);
- }
- layer_on(_RAISE);
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- } else {
- rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
- layer_off(_RAISE);
- TOG_STATUS = false;
- update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
- }
- return false;
- break;
- case BACKLIT:
- if (record->event.pressed) {
- register_code(KC_RSFT);
- #ifdef BACKLIGHT_ENABLE
- backlight_step();
- #endif
- } else {
- unregister_code(KC_RSFT);
- }
- return false;
- break;
- //my attempt for RGB layer lock indication via changing the mode, still have to figure out how to not have other keypress not override this mode
- case TG_NUMLAY:
- if (record->event.pressed) {
- if (RGB_INIT) {} else {
- RGB_current_mode = rgblight_config.mode;
- RGB_INIT = true;
- }
- NUMLAY_STATUS = !NUMLAY_STATUS;
- if (NUMLAY_STATUS) {
- rgblight_mode(4);
- layer_on(_NUMLAY);
- } else {
- rgblight_mode(RGB_current_mode);
- layer_off(_NUMLAY); }
- }
- return false;
- break;
- case RGB_MOD:
- //led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
- if (record->event.pressed) {
- rgblight_mode(RGB_current_mode);
- rgblight_step();
- RGB_current_mode = rgblight_config.mode;
- }
- return false;
- break;
- }
- return true;
-}
-
-void matrix_init_user(void) {
- #ifdef USE_I2C
- i2c_master_init();
- #ifdef SSD1306OLED
- // calls code for the SSD1306 OLED
- _delay_ms(400);
- TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
- iota_gfx_init(); // turns on the display
- #endif
- #endif
- #ifdef AUDIO_ENABLE
- startup_user();
- #endif
-}
-
-void matrix_scan_user(void) {
- #ifdef SSD1306OLED
- iota_gfx_task(); // this is what updates the display continuously
- #endif
-}
-
-#ifdef AUDIO_ENABLE
-
-void startup_user()
-{
- _delay_ms(20); // gets rid of tick
- PLAY_SONG(tone_startup);
-}
-
-void shutdown_user()
-{cc
- PLAY_SONG(tone_goodbye);
- _delay_ms(150);
- stop_all_notes();
-}
-
-void music_on_user(void)
-{
- music_scale_user();
-}
-
-void music_scale_user(void)
-{
- PLAY_SONG(music_scale);
-}
-
-#endif
-
-/*
- * Macro definition
- */
-const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
-{
- if (!eeconfig_is_enabled()) {
- eeconfig_init();
- }
-
- switch (id) {
- case KC_DEMOMACRO:
- if (record->event.pressed){
- return MACRO (I(1), T(H),T(E),T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
- }
- }
-
- return MACRO_NONE;
-}
-
-void matrix_update(struct CharacterMatrix *dest,
- const struct CharacterMatrix *source) {
- if (memcmp(dest->display, source->display, sizeof(dest->display))) {
- memcpy(dest->display, source->display, sizeof(dest->display));
- dest->dirty = true;
- }
-}
-
-//assign the right code to your layers for OLED display
-#define L_BASE 0
-#define L_LOWER 8
-#define L_RAISE 16
-#define L_FNLAYER 64
-#define L_NUMLAY 128
-#define L_NLOWER 136
-#define L_NFNLAYER 192
-#define L_MOUSECURSOR 256
-#define L_ADJUST 65560
-
-void iota_gfx_task_user(void) {
-#if DEBUG_TO_SCREEN
- if (debug_enable) {
- return;
- }
-#endif
-
- struct CharacterMatrix matrix;
-
- matrix_clear(&matrix);
- matrix_write_P(&matrix, PSTR("USB: "));
-#ifdef PROTOCOL_LUFA
- switch (USB_DeviceState) {
- case DEVICE_STATE_Unattached:
- matrix_write_P(&matrix, PSTR("Unattached"));
- break;
- case DEVICE_STATE_Suspended:
- matrix_write_P(&matrix, PSTR("Suspended"));
- break;
- case DEVICE_STATE_Configured:
- matrix_write_P(&matrix, PSTR("Connected"));
- break;
- case DEVICE_STATE_Powered:
- matrix_write_P(&matrix, PSTR("Powered"));
- break;
- case DEVICE_STATE_Default:
- matrix_write_P(&matrix, PSTR("Default"));
- break;
- case DEVICE_STATE_Addressed:
- matrix_write_P(&matrix, PSTR("Addressed"));
- break;
- default:
- matrix_write_P(&matrix, PSTR("Invalid"));
- }
-#endif
-
-// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
-
- char buf[40];
- snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
- matrix_write_P(&matrix, PSTR("\n\nLayer: "));
- switch (layer_state) {
- case L_BASE:
- matrix_write_P(&matrix, PSTR("Default"));
- break;
- case L_RAISE:
- matrix_write_P(&matrix, PSTR("Raise"));
- break;
- case L_LOWER:
- matrix_write_P(&matrix, PSTR("Lower"));
- break;
- case L_ADJUST:
- matrix_write_P(&matrix, PSTR("ADJUST"));
- break;
- default:
- matrix_write(&matrix, buf);
- }
-
- // Host Keyboard LED Status
- char led[40];
- snprintf(led, sizeof(led), "\n%s %s %s",
- (host_keyboard_leds() & (1<.
#define UNUSED_PINS
+#define USE_I2C
+#define SSD1306OLED
+#define OLED_ROTATE180
+
+/* ws2812 RGB LED*/
+#define RGB_DI_PIN D4
+#define RGBLIGHT_ANIMATIONS
+#define RGBLED_NUM 14 // Number of LEDs
+#define RGBLIGHT_HUE_STEP 10
+#define RGBLIGHT_SAT_STEP 17
+
diff --git a/keyboards/hadron/ver2/keymaps/default/config.h b/keyboards/hadron/ver2/keymaps/default/config.h
new file mode 100644
index 000000000..e1fdd6dd3
--- /dev/null
+++ b/keyboards/hadron/ver2/keymaps/default/config.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
+ SONG(COLEMAK_SOUND) \
+ }
+
+#define LEADER_TIMEOUT 300
+//#define BACKLIGHT_BREATHING
+
diff --git a/keyboards/hadron/ver2/keymaps/default/keymap.c b/keyboards/hadron/ver2/keymaps/default/keymap.c
new file mode 100644
index 000000000..cc79f5267
--- /dev/null
+++ b/keyboards/hadron/ver2/keymaps/default/keymap.c
@@ -0,0 +1,448 @@
+#include QMK_KEYBOARD_H
+#ifdef AUDIO_ENABLE
+ #include "audio.h"
+#endif
+#ifdef USE_I2C
+#include "i2c.h"
+#endif
+#ifdef SSD1306OLED
+#include "ssd1306.h"
+#endif
+extern keymap_config_t keymap_config;
+
+//Following line allows macro to read current RGB settings
+extern rgblight_config_t rgblight_config;
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+// Layer names don't all need to be of the same length, obviously, and you can also skip them
+// entirely and just use numbers.
+#define _QWERTY 0
+#define _COLEMAK 1
+#define _DVORAK 2
+#define _LOWER 3
+#define _RAISE 4
+#define _MOUSECURSOR 8
+#define _ADJUST 16
+
+enum preonic_keycodes {
+ QWERTY = SAFE_RANGE,
+ COLEMAK,
+ DVORAK,
+ LOWER,
+ RAISE,
+ BACKLIT,
+ RGBLED_TOGGLE,
+ RGBLED_STEP_MODE,
+ RGBLED_INCREASE_HUE,
+ RGBLED_DECREASE_HUE,
+ RGBLED_INCREASE_SAT,
+ RGBLED_DECREASE_SAT,
+ RGBLED_INCREASE_VAL,
+ RGBLED_DECREASE_VAL,
+};
+
+enum macro_keycodes {
+ KC_DEMOMACRO,
+};
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+// Custom macros
+#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
+#define CTL_TTAB CTL_T(KC_TAB) // Tap for Esc, hold for Ctrl
+#define CTL_ENT CTL_T(KC_ENT) // Tap for Enter, hold for Ctrl
+#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
+// Requires KC_TRNS/_______ for the trigger key in the destination layer
+#define LT_MC(kc) LT(_MOUSECURSOR, kc) // L-ayer T-ap M-ouse C-ursor
+#define LT_RAI(kc) LT(_RAISE, kc) // L-ayer T-ap to Raise
+#define DEMOMACRO M(KC_DEMOMACRO) // Sample for macros
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | DEL |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Tab | Q | W | E | R | T | 7 | 8 | 9 | Y | U | I | O | P | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | CAPS | A | S | D | F | G | 4 | 5 | 6 | H | J | K | L | ;/Nav| ' |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | 1 | 2 | 3 | N | M | , | . | / |Ctl/Et|
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_QWERTY] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_P7, KC_P8, KC_P9, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_P4, KC_P5, KC_P6, KC_H, KC_J, KC_K, KC_L,LT_MC(KC_SCLN), KC_QUOT, \
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_P1, KC_P2, KC_P3, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, CTL_ENT, \
+ KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT,KC_DOWN, KC_UP, KC_RGHT \
+),
+
+/* Colemak
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Tab | Q | W | F | P | G | 7 | 8 | 9 | J | L | U | Y | ; | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | CAPS | A | R | S | T | D | 4 | 5 | 6 | H | N | E | I | O | ' |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | 1 | 2 | 3 | K | M | , | . | / |Ctl/Et|
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_COLEMAK] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
+ KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_P7, KC_P8, KC_P9, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
+ KC_LCTRL, KC_A, KC_R, KC_S, KC_T, KC_D, KC_P4, KC_P5, KC_P6, KC_H, KC_N, KC_E, KC_I, LT_MC(KC_O), KC_QUOT, \
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_P1, KC_P2, KC_P3, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, CTL_ENT, \
+ KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
+ ),
+
+/* Dvorak
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Tab | " | , | . | P | Y | 7 | 8 | 9 | F | G | C | R | L | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | Esc | A | O | E | U | I | 4 | 5 | 6 | D | H | T | N | S | / |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| ; | Q | J | K | X | 1 | 2 | 3 | B | M | W | V | Z |Ctl/Et|
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_DVORAK] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
+ KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_P7, KC_P8, KC_P9, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
+ KC_LCTL, KC_A, KC_O, KC_E, KC_U, KC_I, KC_P4, KC_P5, KC_P6, KC_D, KC_H, KC_T, KC_N, LT_MC(KC_S), KC_SLSH, \
+ KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_P1, KC_P2, KC_P3, KC_B, KC_M, KC_W, KC_V, KC_Z, CTL_ENT, \
+ KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
+),
+
+/* Lower
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | ~ | ! | @ | # | $ | % | | | | ^ | & | * | ( | ) | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | | F1 | F2 | F3 | F4 | F5 | | | | F6 | _ | + | { | } | | |
+ * |------+------+------+------+------+------|------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | | | | F12 |ISO ~ |ISO | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_LOWER] = LAYOUT(
+ KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
+ KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, _______, _______, _______, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, _______, KC_F6, KC_UNDS, KC_PLUS, KC_LBRC, KC_RBRC, KC_PIPE, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, KC_F12,S(KC_NUHS),S(KC_NUBS),_______,_______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Raise
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | ` | 1 | 2 | 3 | 4 | 5 | | | | 6 | 7 | 8 | 9 | 0 | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | | | | F6 | - | = | [ | ] | \ |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | | | | F12 |ISO # |ISO / | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_RAISE] = LAYOUT(
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, _______, _______, _______, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, _______, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \
+ _______, _______, _______, _______, _______, KC_SPC, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Mouse Layer (semi-col)
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | ACCL0| ACCL1| ACCL2| | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | | | | | | | | | Home | Wh_Up| WHL_L| M_Up | WHL_R| Macro| |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | End | Wh_Dn| M_Lft| M_Dn | M_Rt | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | BTN2 | BTN3 | BTN4 | BTN5 | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | BTN1 | | | | BTN1 | | | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+
+[_MOUSECURSOR] = LAYOUT(
+ KC_ACL0, KC_ACL1, KC_ACL2, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGUP, KC_WH_L, KC_MS_U, KC_WH_R,DEMOMACRO,_______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_END , KC_PGDN, KC_MS_L, KC_MS_D, KC_MS_R, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_BTN2, KC_BTN3, KC_BTN4, KC_BTN5, _______, _______, \
+ _______, _______, _______, _______, _______, KC_BTN1, _______, _______, _______, KC_BTN1, _______, _______, _______, _______, _______ \
+),
+
+/* Adjust (Lower + Raise)
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Reset|RGB TG|RGB ST|RGBH -|RGBH +|RGBS -|RGBS +|RGBV -|RGBV +| | | | | | Del |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | |Aud on|Audoff|AGnorm| | | |AGswap|Qwerty|Colemk| | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | |Voice-|Voice+|Mus on|Musoff| | | | | | | | BL + |BL ST |BL TG |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_ADJUST] = LAYOUT(
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
+ RESET, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______, KC_DEL, \
+ _______, _______, _______, AU_ON, AU_OFF, AG_NORM, _______, _______, _______, AG_SWAP, QWERTY, COLEMAK, _______, _______, _______, \
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, BL_DEC, BL_INC, BL_STEP, BL_TOGG, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______\
+)
+
+
+
+};
+
+// define variables for reactive RGB
+bool RGB_INIT = false;
+bool TOG_STATUS = false;
+int RGB_current_mode;
+
+void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
+ if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
+ rgblight_mode(RGB_current_mode);
+ layer_on(layer3);
+ } else {
+ layer_off(layer3);
+ }
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case QWERTY:
+ if (record->event.pressed) {
+ set_single_persistent_default_layer(_QWERTY);
+ }
+ return false;
+ break;
+ case COLEMAK:
+ if (record->event.pressed) {
+ set_single_persistent_default_layer(_COLEMAK);
+ }
+ return false;
+ break;
+ case LOWER:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ if (RGB_INIT) {} else {
+ RGB_current_mode = rgblight_config.mode;
+ RGB_INIT = true;
+ }
+ if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+ } else {
+ TOG_STATUS = !TOG_STATUS;
+ rgblight_mode(16);
+ }
+ layer_on(_LOWER);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ } else {
+ rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
+ TOG_STATUS = false;
+ layer_off(_LOWER);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ }
+ return false;
+ break;
+ case RAISE:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ if (RGB_INIT) {} else {
+ RGB_current_mode = rgblight_config.mode;
+ RGB_INIT = true;
+ }
+ if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+ } else {
+ TOG_STATUS = !TOG_STATUS;
+ rgblight_mode(15);
+ }
+ layer_on(_RAISE);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ } else {
+ rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
+ layer_off(_RAISE);
+ TOG_STATUS = false;
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ }
+ return false;
+ break;
+ case BACKLIT:
+ if (record->event.pressed) {
+ register_code(KC_RSFT);
+ #ifdef BACKLIGHT_ENABLE
+ backlight_step();
+ #endif
+ } else {
+ unregister_code(KC_RSFT);
+ }
+ return false;
+ break;
+ case RGB_MOD:
+ //led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
+ if (record->event.pressed) {
+ rgblight_mode(RGB_current_mode);
+ rgblight_step();
+ RGB_current_mode = rgblight_config.mode;
+ }
+ return false;
+ break;
+ }
+ return true;
+}
+
+
+
+/*
+ * Macro definition
+ */
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ if (!eeconfig_is_enabled()) {
+ eeconfig_init();
+ }
+
+ switch (id) {
+ case KC_DEMOMACRO:
+ if (record->event.pressed){
+ return MACRO (I(1), T(H),T(E),T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
+ }
+ }
+
+ return MACRO_NONE;
+}
+
+
+//Functions for ver2
+#ifdef KEYBOARD_hadron_ver2
+#include "LUFA/Drivers/Peripheral/TWI.h"
+void matrix_init_user(void) {
+ #ifdef USE_I2C
+ i2c_master_init();
+ #ifdef SSD1306OLED
+ // calls code for the SSD1306 OLED
+ _delay_ms(400);
+ TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
+ iota_gfx_init(); // turns on the display
+ #endif
+ #endif
+ #ifdef AUDIO_ENABLE
+ startup_user();
+ #endif
+}
+
+
+void matrix_scan_user(void) {
+ #ifdef SSD1306OLED
+ iota_gfx_task(); // this is what updates the display continuously
+ #endif
+}
+
+void matrix_update(struct CharacterMatrix *dest,
+ const struct CharacterMatrix *source) {
+ if (memcmp(dest->display, source->display, sizeof(dest->display))) {
+ memcpy(dest->display, source->display, sizeof(dest->display));
+ dest->dirty = true;
+ }
+}
+//assign the right code to your layers for OLED display
+#define L_BASE 0
+#define L_LOWER 8
+#define L_RAISE 16
+#define L_FNLAYER 64
+#define L_NUMLAY 128
+#define L_NLOWER 136
+#define L_NFNLAYER 192
+#define L_MOUSECURSOR 256
+#define L_ADJUST 65560
+
+void iota_gfx_task_user(void) {
+#if DEBUG_TO_SCREEN
+ if (debug_enable) {
+ return;
+ }
+#endif
+
+ struct CharacterMatrix matrix;
+
+ matrix_clear(&matrix);
+ matrix_write_P(&matrix, PSTR("USB: "));
+#ifdef PROTOCOL_LUFA
+ switch (USB_DeviceState) {
+ case DEVICE_STATE_Unattached:
+ matrix_write_P(&matrix, PSTR("Unattached"));
+ break;
+ case DEVICE_STATE_Suspended:
+ matrix_write_P(&matrix, PSTR("Suspended"));
+ break;
+ case DEVICE_STATE_Configured:
+ matrix_write_P(&matrix, PSTR("Connected"));
+ break;
+ case DEVICE_STATE_Powered:
+ matrix_write_P(&matrix, PSTR("Powered"));
+ break;
+ case DEVICE_STATE_Default:
+ matrix_write_P(&matrix, PSTR("Default"));
+ break;
+ case DEVICE_STATE_Addressed:
+ matrix_write_P(&matrix, PSTR("Addressed"));
+ break;
+ default:
+ matrix_write_P(&matrix, PSTR("Invalid"));
+ }
+#endif
+
+// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
+
+ char buf[40];
+ snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
+ matrix_write_P(&matrix, PSTR("\n\nLayer: "));
+ switch (layer_state) {
+ case L_BASE:
+ matrix_write_P(&matrix, PSTR("Default"));
+ break;
+ case L_RAISE:
+ matrix_write_P(&matrix, PSTR("Raise"));
+ break;
+ case L_LOWER:
+ matrix_write_P(&matrix, PSTR("Lower"));
+ break;
+ case L_ADJUST:
+ matrix_write_P(&matrix, PSTR("ADJUST"));
+ break;
+ default:
+ matrix_write(&matrix, buf);
+ }
+
+ // Host Keyboard LED Status
+ char led[40];
+ snprintf(led, sizeof(led), "\n%s %s %s",
+ (host_keyboard_leds() & (1<sort lines), and use this format:
+
+ * **folder_name** description
+
+# List of Planck keymaps
+
+* **default** default Planck layout
+* **cbbrowne** cbbrowne's Planck layout
\ No newline at end of file
diff --git a/keyboards/hadron/ver2/keymaps/side_numpad/config.h b/keyboards/hadron/ver2/keymaps/side_numpad/config.h
new file mode 100644
index 000000000..409279a95
--- /dev/null
+++ b/keyboards/hadron/ver2/keymaps/side_numpad/config.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND)\
+ }
+
+#define LEADER_TIMEOUT 300
+//#define BACKLIGHT_BREATHING
+
diff --git a/keyboards/hadron/ver2/keymaps/side_numpad/keymap.c b/keyboards/hadron/ver2/keymaps/side_numpad/keymap.c
new file mode 100644
index 000000000..248bb7ca6
--- /dev/null
+++ b/keyboards/hadron/ver2/keymaps/side_numpad/keymap.c
@@ -0,0 +1,484 @@
+#include QMK_KEYBOARD_H
+#include "LUFA/Drivers/Peripheral/TWI.h"
+#ifdef AUDIO_ENABLE
+ #include "audio.h"
+#endif
+#ifdef USE_I2C
+#include "i2c.h"
+#endif
+#ifdef SSD1306OLED
+#include "ssd1306.h"
+#endif
+extern keymap_config_t keymap_config;
+
+//Following line allows macro to read current RGB settings
+extern rgblight_config_t rgblight_config;
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+// Layer names don't all need to be of the same length, obviously, and you can also skip them
+// entirely and just use numbers.
+#define _QWERTY 0
+#define _LOWER 3
+#define _RAISE 4
+#define _FNLAYER 6
+#define _NUMLAY 7
+#define _MOUSECURSOR 8
+#define _ADJUST 16
+
+enum preonic_keycodes {
+ QWERTY = SAFE_RANGE,
+ COLEMAK,
+ DVORAK,
+ LOWER,
+ RAISE,
+ BACKLIT,
+ RGBLED_TOGGLE,
+ RGBLED_STEP_MODE,
+ RGBLED_INCREASE_HUE,
+ RGBLED_DECREASE_HUE,
+ RGBLED_INCREASE_SAT,
+ RGBLED_DECREASE_SAT,
+ RGBLED_INCREASE_VAL,
+ RGBLED_DECREASE_VAL,
+};
+
+enum macro_keycodes {
+ KC_DEMOMACRO,
+};
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+// Custom macros
+#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
+#define CTL_TTAB CTL_T(KC_TAB) // Tap for Esc, hold for Ctrl
+#define CTL_ENT CTL_T(KC_ENT) // Tap for Enter, hold for Ctrl
+#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
+// Requires KC_TRNS/_______ for the trigger key in the destination layer
+#define LT_FN(kc) LT(_FNLAYER, kc) // L-ayer T-ap Function Layer
+#define LT_MC(kc) LT(_MOUSECURSOR, kc) // L-ayer T-ap M-ouse C-ursor
+#define LT_RAI(kc) LT(_RAISE, kc) // L-ayer T-ap to Raise
+#define TG_NUMLAY TG(_NUMLAY) //Toggle for layer _NUMLAY
+#define DEMOMACRO M(KC_DEMOMACRO) // My login macros
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp | 7 | 8 | 9 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | CAPS | A | S | D | F | G | H | J | K | L | ; |Enter | 4 | 5 | 6 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | N | M | , | . | / | = | 1 | 2 | 3 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ~ | Ctrl | Alt | GUI |Lower |Space |Space |Raise | RAlt | Ins | Del |NumLay| 0 | . | ENT |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_QWERTY] = LAYOUT(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,\
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, KC_P7, KC_P8, KC_P9, \
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, LT_MC(KC_SCLN), CTL_ENT, KC_P4, KC_P5, KC_P6, \
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_EQL, KC_P1, KC_P2, KC_P3, \
+ KC_GRV, KC_RCTL, KC_LALT, KC_LGUI, LOWER, KC_SPC, KC_SPC, RAISE, KC_RALT, KC_INS, KC_DEL, TG_NUMLAY, KC_P0, KC_PDOT, KC_PENT \
+),
+
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * | | | | | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | ~ | \ | | | |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | CAPS | F1 | F2 | F3 | F4 | F5 | F6 | _ | + | { | } | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | [ | ] | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | Next | Vol- | Vol+ | Play | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_LOWER] = LAYOUT(
+ KC_ESC, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, \
+ KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_GRV, KC_BSLS, _______, _______, _______, \
+ KC_CAPS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_EQL, KC_LBRC, KC_RBRC, KC_PIPE, _______, _______, _______, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, S(KC_NUHS), S(KC_NUBS), KC_LCBR, KC_RCBR, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, _______, _______, _______\
+),
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | ~ | \ | | | |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | | A | Up | D | PrSc | | 4 | 5 | 6 | * | : | ' | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | Lt | Dn | Rt | Mute | | 1 | 2 | 3 | Up | / | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | |Space | 0 | | Left | Down | Right| | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_RAISE] = LAYOUT(
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
+ KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_PLUS, KC_BSLS, _______, _______, _______, \
+ _______, KC_A, KC_UP, KC_D, KC_PSCR, _______, KC_4, KC_5, KC_6, KC_PAST, KC_COLN, KC_QUOT, _______, _______, _______, \
+ _______, KC_LEFT, KC_DOWN, KC_RIGHT, KC__MUTE, _______, KC_1, KC_2, KC_3, KC_UP, KC_SLSH, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, KC_SPC, KC_0, _______, KC_LEFT, KC_DOWN, KC_RIGHT, _______, _______, _______, _______ \
+),
+
+/* FN layer on Esc key
+ * ,-----------------------------------------------------------------------------------.
+ * | | | | | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | | ! | @ | # | $ | % | ^ | & | * | ( | ) | + | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | F1 | F2 | F3 | F4 | F5 | F6 | _ | = | [ | ] | ' | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | F12 |ISO ~ |ISO | | { | } | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | Next | Vol- | Vol+ | Play | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_FNLAYER] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,\
+ _______, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_PLUS, _______, _______, _______, \
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_UNDS, KC_EQL, KC_LBRC, KC_RBRC, KC_QUOT, _______, _______, _______, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,S(KC_NUHS), S(KC_NUBS), KC_LCBR, KC_RCBR, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY, _______, _______, _______ \
+),
+
+/* Num Layer
+ * ,-----------------------------------------------------------------------------------.
+ * | | | | | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | | | | | | | | | | | | | F7 | F8 | F9 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | | F4 | F5 | F6 |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | | | Up | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | Exit | Left | Down | Rght |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_NUMLAY] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,\
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_INS, KC_HOME, KC_PGUP, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, KC_END, KC_PGDN, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PMNS, KC_UP, KC_PPLS, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RIGHT \
+),
+
+/* Mouse Layer (semi-col)
+ * ,-----------------------------------------------------------------------------------.
+ * | |ACCL0| ACCL1| ACCL2 | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | | | | | | Home | Wh_Up| WHL_L| M_Up | WHL_R| | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | End | Wh_Dn| M_Lft| M_Dn | M_Rt | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | BTN2 | BTN3 | BTN4 | BTN5 | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | BTN1 | | | | BTN1 | | | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+
+[_MOUSECURSOR] = LAYOUT(
+ _______, KC_ACL0, KC_ACL1, KC_ACL2, _______, _______, _______, _______, _______, _______, _______, _______,\
+ _______, _______, _______, _______, _______, KC_HOME, KC_PGUP, KC_WH_L, KC_MS_U, KC_WH_R, DEMOMACRO, _______, _______, _______, _______, \
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_END , KC_PGDN, KC_MS_L, KC_MS_D, KC_MS_R, _______, _______, _______, _______, _______, \
+ _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, KC_BTN2, KC_BTN3, KC_BTN4, KC_BTN5, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, KC_BTN1, KC_BTN1, _______, _______, _______, _______, _______, _______, _______, _______ \
+),
+
+/* Adjust (Lower + Raise)
+
+ * ,-----------------------------------------------------------------------------------.
+ * | Reset| | | | | | | | | VolD | VolU | Mute |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | |RGB TG|RGB ST|RGBH -|RGBH +|RGBS -|RGBS +|RGBV -|RGBV +| | | Del | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | |Aud on|Audoff|AGnorm|AGswap|Qwerty| | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof| | BL + |BL ST |BLSTEP| BL TG| | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_ADJUST] = LAYOUT(
+ RESET, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_VOLD, KC_VOLU, KC_MUTE, \
+ _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, KC_DEL, _______, _______, _______, \
+ _______, _______, _______, AU_ON, AU_OFF, AG_NORM, AG_SWAP, QWERTY, _______, _______, _______, _______, _______, _______, _______, \
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, BL_DEC, BL_INC, BL_STEP, BL_TOGG, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ \
+)
+
+
+
+};
+
+// define variables for reactive RGB
+bool RGB_INIT = false;
+bool TOG_STATUS = false;
+bool NUMLAY_STATUS = false;
+int RGB_current_mode;
+
+
+void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
+ if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
+ rgblight_mode(RGB_current_mode);
+ layer_on(layer3);
+ } else {
+ layer_off(layer3);
+ }
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case QWERTY:
+ if (record->event.pressed) {
+ set_single_persistent_default_layer(_QWERTY);
+ }
+ return false;
+ break;
+ case LOWER:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ if (RGB_INIT) {} else {
+ RGB_current_mode = rgblight_config.mode;
+ RGB_INIT = true;
+ }
+ if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+ } else {
+ TOG_STATUS = !TOG_STATUS;
+ rgblight_mode(16);
+ }
+ layer_on(_LOWER);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ } else {
+ rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
+ TOG_STATUS = false;
+ layer_off(_LOWER);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ }
+ return false;
+ break;
+ case RAISE:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ if (RGB_INIT) {} else {
+ RGB_current_mode = rgblight_config.mode;
+ RGB_INIT = true;
+ }
+ if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+ } else {
+ TOG_STATUS = !TOG_STATUS;
+ rgblight_mode(15);
+ }
+ layer_on(_RAISE);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ } else {
+ rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
+ layer_off(_RAISE);
+ TOG_STATUS = false;
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ }
+ return false;
+ break;
+ case BACKLIT:
+ if (record->event.pressed) {
+ register_code(KC_RSFT);
+ #ifdef BACKLIGHT_ENABLE
+ backlight_step();
+ #endif
+ } else {
+ unregister_code(KC_RSFT);
+ }
+ return false;
+ break;
+ //my attempt for RGB layer lock indication via changing the mode, still have to figure out how to not have other keypress not override this mode
+ case TG_NUMLAY:
+ if (record->event.pressed) {
+ if (RGB_INIT) {} else {
+ RGB_current_mode = rgblight_config.mode;
+ RGB_INIT = true;
+ }
+ NUMLAY_STATUS = !NUMLAY_STATUS;
+ if (NUMLAY_STATUS) {
+ rgblight_mode(4);
+ layer_on(_NUMLAY);
+ } else {
+ rgblight_mode(RGB_current_mode);
+ layer_off(_NUMLAY); }
+ }
+ return false;
+ break;
+ case RGB_MOD:
+ //led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
+ if (record->event.pressed) {
+ rgblight_mode(RGB_current_mode);
+ rgblight_step();
+ RGB_current_mode = rgblight_config.mode;
+ }
+ return false;
+ break;
+ }
+ return true;
+}
+
+void matrix_init_user(void) {
+ #ifdef USE_I2C
+ i2c_master_init();
+ #ifdef SSD1306OLED
+ // calls code for the SSD1306 OLED
+ _delay_ms(400);
+ TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 800000));
+ iota_gfx_init(); // turns on the display
+ #endif
+ #endif
+ #ifdef AUDIO_ENABLE
+ startup_user();
+ #endif
+}
+
+void matrix_scan_user(void) {
+ #ifdef SSD1306OLED
+ iota_gfx_task(); // this is what updates the display continuously
+ #endif
+}
+
+#ifdef AUDIO_ENABLE
+
+void startup_user()
+{
+ _delay_ms(20); // gets rid of tick
+ PLAY_SONG(tone_startup);
+}
+
+void shutdown_user()
+{cc
+ PLAY_SONG(tone_goodbye);
+ _delay_ms(150);
+ stop_all_notes();
+}
+
+void music_on_user(void)
+{
+ music_scale_user();
+}
+
+void music_scale_user(void)
+{
+ PLAY_SONG(music_scale);
+}
+
+#endif
+
+/*
+ * Macro definition
+ */
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ if (!eeconfig_is_enabled()) {
+ eeconfig_init();
+ }
+
+ switch (id) {
+ case KC_DEMOMACRO:
+ if (record->event.pressed){
+ return MACRO (I(1), T(H),T(E),T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
+ }
+ }
+
+ return MACRO_NONE;
+}
+
+void matrix_update(struct CharacterMatrix *dest,
+ const struct CharacterMatrix *source) {
+ if (memcmp(dest->display, source->display, sizeof(dest->display))) {
+ memcpy(dest->display, source->display, sizeof(dest->display));
+ dest->dirty = true;
+ }
+}
+
+//assign the right code to your layers for OLED display
+#define L_BASE 0
+#define L_LOWER 8
+#define L_RAISE 16
+#define L_FNLAYER 64
+#define L_NUMLAY 128
+#define L_NLOWER 136
+#define L_NFNLAYER 192
+#define L_MOUSECURSOR 256
+#define L_ADJUST 65560
+
+void iota_gfx_task_user(void) {
+#if DEBUG_TO_SCREEN
+ if (debug_enable) {
+ return;
+ }
+#endif
+
+ struct CharacterMatrix matrix;
+
+ matrix_clear(&matrix);
+ matrix_write_P(&matrix, PSTR("USB: "));
+#ifdef PROTOCOL_LUFA
+ switch (USB_DeviceState) {
+ case DEVICE_STATE_Unattached:
+ matrix_write_P(&matrix, PSTR("Unattached"));
+ break;
+ case DEVICE_STATE_Suspended:
+ matrix_write_P(&matrix, PSTR("Suspended"));
+ break;
+ case DEVICE_STATE_Configured:
+ matrix_write_P(&matrix, PSTR("Connected"));
+ break;
+ case DEVICE_STATE_Powered:
+ matrix_write_P(&matrix, PSTR("Powered"));
+ break;
+ case DEVICE_STATE_Default:
+ matrix_write_P(&matrix, PSTR("Default"));
+ break;
+ case DEVICE_STATE_Addressed:
+ matrix_write_P(&matrix, PSTR("Addressed"));
+ break;
+ default:
+ matrix_write_P(&matrix, PSTR("Invalid"));
+ }
+#endif
+
+// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
+
+ char buf[40];
+ snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
+ matrix_write_P(&matrix, PSTR("\n\nLayer: "));
+ switch (layer_state) {
+ case L_BASE:
+ matrix_write_P(&matrix, PSTR("Default"));
+ break;
+ case L_RAISE:
+ matrix_write_P(&matrix, PSTR("Raise"));
+ break;
+ case L_LOWER:
+ matrix_write_P(&matrix, PSTR("Lower"));
+ break;
+ case L_ADJUST:
+ matrix_write_P(&matrix, PSTR("ADJUST"));
+ break;
+ default:
+ matrix_write(&matrix, buf);
+ }
+
+ // Host Keyboard LED Status
+ char led[40];
+ snprintf(led, sizeof(led), "\n%s %s %s",
+ (host_keyboard_leds() & (1</tmk_core/tool/chibios/ch-bootloader-jump.patch
+ */
+#define STM32_BOOTLOADER_ADDRESS 0x1FFFD800
diff --git a/keyboards/hadron/ver3/chconf.h b/keyboards/hadron/ver3/chconf.h
new file mode 100644
index 000000000..1d9f12ff1
--- /dev/null
+++ b/keyboards/hadron/ver3/chconf.h
@@ -0,0 +1,520 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 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.
+*/
+
+/**
+ * @file templates/chconf.h
+ * @brief Configuration file template.
+ * @details A copy of this file must be placed in each project directory, it
+ * contains the application specific kernel settings.
+ *
+ * @addtogroup config
+ * @details Kernel related settings and hooks.
+ * @{
+ */
+
+#ifndef CHCONF_H
+#define CHCONF_H
+
+#define _CHIBIOS_RT_CONF_
+
+/*===========================================================================*/
+/**
+ * @name System timers settings
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief System time counter resolution.
+ * @note Allowed values are 16 or 32 bits.
+ */
+#define CH_CFG_ST_RESOLUTION 32
+
+/**
+ * @brief System tick frequency.
+ * @details Frequency of the system timer that drives the system ticks. This
+ * setting also defines the system tick time unit.
+ */
+#define CH_CFG_ST_FREQUENCY 100000
+
+/**
+ * @brief Time delta constant for the tick-less mode.
+ * @note If this value is zero then the system uses the classic
+ * periodic tick. This value represents the minimum number
+ * of ticks that is safe to specify in a timeout directive.
+ * The value one is not valid, timeouts are rounded up to
+ * this value.
+ */
+#define CH_CFG_ST_TIMEDELTA 2
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel parameters and options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Round robin interval.
+ * @details This constant is the number of system ticks allowed for the
+ * threads before preemption occurs. Setting this value to zero
+ * disables the preemption for threads with equal priority and the
+ * round robin becomes cooperative. Note that higher priority
+ * threads can still preempt, the kernel is always preemptive.
+ * @note Disabling the round robin preemption makes the kernel more compact
+ * and generally faster.
+ * @note The round robin preemption is not supported in tickless mode and
+ * must be set to zero in that case.
+ */
+#define CH_CFG_TIME_QUANTUM 0
+
+/**
+ * @brief Managed RAM size.
+ * @details Size of the RAM area to be managed by the OS. If set to zero
+ * then the whole available RAM is used. The core memory is made
+ * available to the heap allocator and/or can be used directly through
+ * the simplified core memory allocator.
+ *
+ * @note In order to let the OS manage the whole RAM the linker script must
+ * provide the @p __heap_base__ and @p __heap_end__ symbols.
+ * @note Requires @p CH_CFG_USE_MEMCORE.
+ */
+#define CH_CFG_MEMCORE_SIZE 0
+
+/**
+ * @brief Idle thread automatic spawn suppression.
+ * @details When this option is activated the function @p chSysInit()
+ * does not spawn the idle thread. The application @p main()
+ * function becomes the idle thread and must implement an
+ * infinite loop.
+ */
+#define CH_CFG_NO_IDLE_THREAD FALSE
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Performance options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief OS optimization.
+ * @details If enabled then time efficient rather than space efficient code
+ * is used when two possible implementations exist.
+ *
+ * @note This is not related to the compiler optimization options.
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_OPTIMIZE_SPEED TRUE
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Subsystem options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Time Measurement APIs.
+ * @details If enabled then the time measurement APIs are included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_TM TRUE
+
+/**
+ * @brief Threads registry APIs.
+ * @details If enabled then the registry APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_REGISTRY TRUE
+
+/**
+ * @brief Threads synchronization APIs.
+ * @details If enabled then the @p chThdWait() function is included in
+ * the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_WAITEXIT TRUE
+
+/**
+ * @brief Semaphores APIs.
+ * @details If enabled then the Semaphores APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_SEMAPHORES TRUE
+
+/**
+ * @brief Semaphores queuing mode.
+ * @details If enabled then the threads are enqueued on semaphores by
+ * priority rather than in FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE
+
+/**
+ * @brief Mutexes APIs.
+ * @details If enabled then the mutexes APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_MUTEXES TRUE
+
+/**
+ * @brief Enables recursive behavior on mutexes.
+ * @note Recursive mutexes are heavier and have an increased
+ * memory footprint.
+ *
+ * @note The default is @p FALSE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE
+
+/**
+ * @brief Conditional Variables APIs.
+ * @details If enabled then the conditional variables APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MUTEXES.
+ */
+#define CH_CFG_USE_CONDVARS TRUE
+
+/**
+ * @brief Conditional Variables APIs with timeout.
+ * @details If enabled then the conditional variables APIs with timeout
+ * specification are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_CONDVARS.
+ */
+#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE
+
+/**
+ * @brief Events Flags APIs.
+ * @details If enabled then the event flags APIs are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_EVENTS TRUE
+
+/**
+ * @brief Events Flags APIs with timeout.
+ * @details If enabled then the events APIs with timeout specification
+ * are included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_EVENTS.
+ */
+#define CH_CFG_USE_EVENTS_TIMEOUT TRUE
+
+/**
+ * @brief Synchronous Messages APIs.
+ * @details If enabled then the synchronous messages APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_MESSAGES TRUE
+
+/**
+ * @brief Synchronous Messages queuing mode.
+ * @details If enabled then messages are served by priority rather than in
+ * FIFO order.
+ *
+ * @note The default is @p FALSE. Enable this if you have special
+ * requirements.
+ * @note Requires @p CH_CFG_USE_MESSAGES.
+ */
+#define CH_CFG_USE_MESSAGES_PRIORITY TRUE
+
+/**
+ * @brief Mailboxes APIs.
+ * @details If enabled then the asynchronous messages (mailboxes) APIs are
+ * included in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_SEMAPHORES.
+ */
+#define CH_CFG_USE_MAILBOXES TRUE
+
+/**
+ * @brief Core Memory Manager APIs.
+ * @details If enabled then the core memory manager APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_MEMCORE TRUE
+
+/**
+ * @brief Heap Allocator APIs.
+ * @details If enabled then the memory heap allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or
+ * @p CH_CFG_USE_SEMAPHORES.
+ * @note Mutexes are recommended.
+ */
+#define CH_CFG_USE_HEAP TRUE
+
+/**
+ * @brief Memory Pools Allocator APIs.
+ * @details If enabled then the memory pools allocator APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ */
+#define CH_CFG_USE_MEMPOOLS TRUE
+
+/**
+ * @brief Dynamic Threads APIs.
+ * @details If enabled then the dynamic threads creation APIs are included
+ * in the kernel.
+ *
+ * @note The default is @p TRUE.
+ * @note Requires @p CH_CFG_USE_WAITEXIT.
+ * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS.
+ */
+#define CH_CFG_USE_DYNAMIC TRUE
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Debug options
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Debug option, kernel statistics.
+ *
+ * @note The default is @p FALSE.
+ */
+#define CH_DBG_STATISTICS FALSE
+
+/**
+ * @brief Debug option, system state check.
+ * @details If enabled the correct call protocol for system APIs is checked
+ * at runtime.
+ *
+ * @note The default is @p FALSE.
+ */
+#define CH_DBG_SYSTEM_STATE_CHECK FALSE
+
+/**
+ * @brief Debug option, parameters checks.
+ * @details If enabled then the checks on the API functions input
+ * parameters are activated.
+ *
+ * @note The default is @p FALSE.
+ */
+#define CH_DBG_ENABLE_CHECKS FALSE
+
+/**
+ * @brief Debug option, consistency checks.
+ * @details If enabled then all the assertions in the kernel code are
+ * activated. This includes consistency checks inside the kernel,
+ * runtime anomalies and port-defined checks.
+ *
+ * @note The default is @p FALSE.
+ */
+#define CH_DBG_ENABLE_ASSERTS FALSE
+
+/**
+ * @brief Debug option, trace buffer.
+ * @details If enabled then the trace buffer is activated.
+ *
+ * @note The default is @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED
+
+/**
+ * @brief Trace buffer entries.
+ * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is
+ * different from @p CH_DBG_TRACE_MASK_DISABLED.
+ */
+#define CH_DBG_TRACE_BUFFER_SIZE 128
+
+/**
+ * @brief Debug option, stack checks.
+ * @details If enabled then a runtime stack check is performed.
+ *
+ * @note The default is @p FALSE.
+ * @note The stack check is performed in a architecture/port dependent way.
+ * It may not be implemented or some ports.
+ * @note The default failure mode is to halt the system with the global
+ * @p panic_msg variable set to @p NULL.
+ */
+#define CH_DBG_ENABLE_STACK_CHECK TRUE
+
+/**
+ * @brief Debug option, stacks initialization.
+ * @details If enabled then the threads working area is filled with a byte
+ * value when a thread is created. This can be useful for the
+ * runtime measurement of the used stack.
+ *
+ * @note The default is @p FALSE.
+ */
+#define CH_DBG_FILL_THREADS FALSE
+
+/**
+ * @brief Debug option, threads profiling.
+ * @details If enabled then a field is added to the @p thread_t structure that
+ * counts the system ticks occurred while executing the thread.
+ *
+ * @note The default is @p FALSE.
+ * @note This debug option is not currently compatible with the
+ * tickless mode.
+ */
+#define CH_DBG_THREADS_PROFILING FALSE
+
+/** @} */
+
+/*===========================================================================*/
+/**
+ * @name Kernel hooks
+ * @{
+ */
+/*===========================================================================*/
+
+/**
+ * @brief Threads descriptor structure extension.
+ * @details User fields added to the end of the @p thread_t structure.
+ */
+#define CH_CFG_THREAD_EXTRA_FIELDS \
+ /* Add threads custom fields here.*/
+
+/**
+ * @brief Threads initialization hook.
+ * @details User initialization code added to the @p chThdInit() API.
+ *
+ * @note It is invoked from within @p chThdInit() and implicitly from all
+ * the threads creation APIs.
+ */
+#define CH_CFG_THREAD_INIT_HOOK(tp) { \
+ /* Add threads initialization code here.*/ \
+}
+
+/**
+ * @brief Threads finalization hook.
+ * @details User finalization code added to the @p chThdExit() API.
+ */
+#define CH_CFG_THREAD_EXIT_HOOK(tp) { \
+ /* Add threads finalization code here.*/ \
+}
+
+/**
+ * @brief Context switch hook.
+ * @details This hook is invoked just before switching between threads.
+ */
+#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \
+ /* Context switch code here.*/ \
+}
+
+/**
+ * @brief ISR enter hook.
+ */
+#define CH_CFG_IRQ_PROLOGUE_HOOK() { \
+ /* IRQ prologue code here.*/ \
+}
+
+/**
+ * @brief ISR exit hook.
+ */
+#define CH_CFG_IRQ_EPILOGUE_HOOK() { \
+ /* IRQ epilogue code here.*/ \
+}
+
+/**
+ * @brief Idle thread enter hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to activate a power saving mode.
+ */
+#define CH_CFG_IDLE_ENTER_HOOK() { \
+ /* Idle-enter code here.*/ \
+}
+
+/**
+ * @brief Idle thread leave hook.
+ * @note This hook is invoked within a critical zone, no OS functions
+ * should be invoked from here.
+ * @note This macro can be used to deactivate a power saving mode.
+ */
+#define CH_CFG_IDLE_LEAVE_HOOK() { \
+ /* Idle-leave code here.*/ \
+}
+
+/**
+ * @brief Idle Loop hook.
+ * @details This hook is continuously invoked by the idle thread loop.
+ */
+#define CH_CFG_IDLE_LOOP_HOOK() { \
+ /* Idle loop code here.*/ \
+}
+
+/**
+ * @brief System tick event hook.
+ * @details This hook is invoked in the system tick handler immediately
+ * after processing the virtual timers queue.
+ */
+#define CH_CFG_SYSTEM_TICK_HOOK() { \
+ /* System tick event code here.*/ \
+}
+
+/**
+ * @brief System halt hook.
+ * @details This hook is invoked in case to a system halting error before
+ * the system is halted.
+ */
+#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
+ /* System halt code here.*/ \
+}
+
+/**
+ * @brief Trace hook.
+ * @details This hook is invoked each time a new record is written in the
+ * trace buffer.
+ */
+#define CH_CFG_TRACE_HOOK(tep) { \
+ /* Trace code here.*/ \
+}
+
+/** @} */
+
+/*===========================================================================*/
+/* Port-specific settings (override port settings defaulted in chcore.h). */
+/*===========================================================================*/
+
+#endif /* CHCONF_H */
+
+/** @} */
diff --git a/keyboards/hadron/ver3/config.h b/keyboards/hadron/ver3/config.h
new file mode 100644
index 000000000..11288f7a5
--- /dev/null
+++ b/keyboards/hadron/ver3/config.h
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2018 Jack Humbert
+ *
+ * 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 .
+ */
+
+#ifndef REV3_CONFIG_H
+#define REV3_CONFIG_H
+
+/* USB Device descriptor parameter */
+#define DEVICE_VER 0x0003
+
+#undef MATRIX_ROWS
+#undef MATRIX_COLS
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 15
+
+
+//Audio
+#undef AUDIO_VOICES
+#undef C6_AUDIO
+
+#ifdef AUDIO_ENABLE
+ #define STARTUP_SONG SONG(PLANCK_SOUND)
+ // #define STARTUP_SONG SONG(NO_SOUND)
+
+ #define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \
+ SONG(COLEMAK_SOUND), \
+ SONG(DVORAK_SOUND) \
+ }
+#define AUDIO_CLICKY
+ /* to enable clicky on startup */
+ //#define AUDIO_CLICKY_ON
+#define AUDIO_CLICKY_FREQ_RANDOMNESS 1.5f
+#endif
+
+//configure qwiic micro_oled driver for the 128x32 oled
+#ifdef QWIIC_MICRO_OLED_ENABLE
+
+#undef I2C_ADDRESS_SA0_1
+#define I2C_ADDRESS_SA0_1 0b0111100
+#define LCDWIDTH 128
+#define LCDHEIGHT 32
+#define micro_oled_rotate_180
+
+#endif
+/*
+ * Keyboard Matrix Assignments
+ *
+ * Change this to how you wired your keyboard
+ * COLS: AVR pins used for columns, left to right
+ * ROWS: AVR pins used for rows, top to bottom
+ * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
+ * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
+ *
+*/
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCE 6
+
+/* 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
+
+/*
+ * Force NKRO
+ *
+ * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
+ * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
+ * makefile for this to work.)
+ *
+ * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
+ * until the next keyboard reset.
+ *
+ * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
+ * fully operational during normal computer usage.
+ *
+ * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
+ * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
+ * bootmagic, NKRO mode will always be enabled until it is toggled again during a
+ * power-up.
+ *
+ */
+//#define FORCE_NKRO
+
+/* key combination for magic key command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+/*
+ * Feature disable options
+ * These options are also useful to firmware size reduction.
+ */
+
+/* disable debug print */
+//#define NO_DEBUG
+
+/* disable print */
+//#define NO_PRINT
+
+/* disable action features */
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
+/*
+ * MIDI options
+ */
+
+/* Prevent use of disabled MIDI features in the keymap */
+//#define MIDI_ENABLE_STRICT 1
+
+/* enable basic MIDI features:
+ - MIDI notes can be sent when in Music mode is on
+*/
+
+#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+ - MIDI notes can be added to the keymap
+ - Octave shift and transpose
+ - Virtual sustain, portamento, and modulation wheel
+ - etc.
+*/
+//#define MIDI_ADVANCED
+
+/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
+//#define MIDI_TONE_KEYCODE_OCTAVES 2
+
+/* Haptic Driver initialization settings
+ * Feedback Control Settings */
+#define FB_ERM_LRA 1 /* For ERM:0 or LRA:1*/
+#define FB_BRAKEFACTOR 6 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */
+#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */
+
+#define RATED_VOLTAGE 2
+#define V_RMS 2.0
+#define V_PEAK 2.85
+#define F_LRA 205
+/* Library Selection */
+#define LIB_SELECTION 6 /* For Empty:0' TS2200 library A to D:1-5, LRA Library: 6 */
+
+/* Control 1 register settings */
+#define DRIVE_TIME 25
+#define AC_COUPLE 0
+#define STARTUP_BOOST 1
+
+/* Control 2 Settings */
+#define BIDIR_INPUT 1
+#define BRAKE_STAB 1 /* Loopgain is reduced when braking is almost complete to improve stability */
+#define SAMPLE_TIME 3
+#define BLANKING_TIME 1
+#define IDISS_TIME 1
+
+/* Control 3 settings */
+#define NG_THRESH 2
+#define ERM_OPEN_LOOP 1
+#define SUPPLY_COMP_DIS 0
+#define DATA_FORMAT_RTO 0
+#define LRA_DRIVE_MODE 0
+#define N_PWM_ANALOG 0
+#define LRA_OPEN_LOOP 0
+/* Control 4 settings */
+#define ZC_DET_TIME 0
+#define AUTO_CAL_TIME 3
+
+//#define WS2812_LED_N 2
+//#define RGBLED_NUM WS2812_LED_N
+//#define WS2812_TIM_N 2
+//#define WS2812_TIM_CH 2
+//#define PORT_WS2812 GPIOA
+//#define PIN_WS2812 15
+//#define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA stream for TIMx_UP (look up in reference manual under DMA Channel selection)
+//#define WS2812_DMA_CHANNEL 7 // DMA channel for TIMx_UP
+//#define WS2812_EXTERNAL_PULLUP
+
+#endif
diff --git a/keyboards/hadron/ver3/halconf.h b/keyboards/hadron/ver3/halconf.h
new file mode 100644
index 000000000..c3e0cbb72
--- /dev/null
+++ b/keyboards/hadron/ver3/halconf.h
@@ -0,0 +1,388 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 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.
+*/
+
+/**
+ * @file templates/halconf.h
+ * @brief HAL configuration header.
+ * @details HAL configuration file, this file allows to enable or disable the
+ * various device drivers from your application. You may also use
+ * this file in order to override the device drivers default settings.
+ *
+ * @addtogroup HAL_CONF
+ * @{
+ */
+
+#ifndef HALCONF_H
+#define HALCONF_H
+
+#include "mcuconf.h"
+
+/**
+ * @brief Enables the PAL subsystem.
+ */
+#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
+#define HAL_USE_PAL TRUE
+#endif
+
+/**
+ * @brief Enables the ADC subsystem.
+ */
+#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
+#define HAL_USE_ADC FALSE
+#endif
+
+/**
+ * @brief Enables the CAN subsystem.
+ */
+#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
+#define HAL_USE_CAN FALSE
+#endif
+
+/**
+ * @brief Enables the DAC subsystem.
+ */
+#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__)
+#define HAL_USE_DAC TRUE
+#endif
+
+/**
+ * @brief Enables the EXT subsystem.
+ */
+#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
+#define HAL_USE_EXT FALSE
+#endif
+
+/**
+ * @brief Enables the GPT subsystem.
+ */
+#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
+#define HAL_USE_GPT TRUE
+#endif
+
+/**
+ * @brief Enables the I2C subsystem.
+ */
+#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
+#define HAL_USE_I2C TRUE
+#endif
+
+/**
+ * @brief Enables the I2S subsystem.
+ */
+#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
+#define HAL_USE_I2S FALSE
+#endif
+
+/**
+ * @brief Enables the ICU subsystem.
+ */
+#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
+#define HAL_USE_ICU FALSE
+#endif
+
+/**
+ * @brief Enables the MAC subsystem.
+ */
+#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
+#define HAL_USE_MAC FALSE
+#endif
+
+/**
+ * @brief Enables the MMC_SPI subsystem.
+ */
+#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_MMC_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the PWM subsystem.
+ */
+#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
+#define HAL_USE_PWM FALSE
+#endif
+
+/**
+ * @brief Enables the QSPI subsystem.
+ */
+#if !defined(HAL_USE_QSPI) || defined(__DOXYGEN__)
+#define HAL_USE_QSPI FALSE
+#endif
+
+/**
+ * @brief Enables the RTC subsystem.
+ */
+#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
+#define HAL_USE_RTC FALSE
+#endif
+
+/**
+ * @brief Enables the SDC subsystem.
+ */
+#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
+#define HAL_USE_SDC FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL subsystem.
+ */
+#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL FALSE
+#endif
+
+/**
+ * @brief Enables the SERIAL over USB subsystem.
+ */
+#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
+#define HAL_USE_SERIAL_USB TRUE
+#endif
+
+/**
+ * @brief Enables the SPI subsystem.
+ */
+#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
+#define HAL_USE_SPI FALSE
+#endif
+
+/**
+ * @brief Enables the UART subsystem.
+ */
+#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
+#define HAL_USE_UART FALSE
+#endif
+
+/**
+ * @brief Enables the USB subsystem.
+ */
+#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
+#define HAL_USE_USB TRUE
+#endif
+
+/**
+ * @brief Enables the WDG subsystem.
+ */
+#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__)
+#define HAL_USE_WDG FALSE
+#endif
+
+/*===========================================================================*/
+/* ADC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
+#define ADC_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define ADC_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* CAN driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Sleep mode related APIs inclusion switch.
+ */
+#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
+#define CAN_USE_SLEEP_MODE TRUE
+#endif
+
+/*===========================================================================*/
+/* I2C driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables the mutual exclusion APIs on the I2C bus.
+ */
+#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define I2C_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* MAC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
+#define MAC_USE_ZERO_COPY FALSE
+#endif
+
+/**
+ * @brief Enables an event sources for incoming packets.
+ */
+#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
+#define MAC_USE_EVENTS TRUE
+#endif
+
+/*===========================================================================*/
+/* MMC_SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ * This option is recommended also if the SPI driver does not
+ * use a DMA channel and heavily loads the CPU.
+ */
+#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
+#define MMC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SDC driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of initialization attempts before rejecting the card.
+ * @note Attempts are performed at 10mS intervals.
+ */
+#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
+#define SDC_INIT_RETRY 100
+#endif
+
+/**
+ * @brief Include support for MMC cards.
+ * @note MMC support is not yet implemented so this option must be kept
+ * at @p FALSE.
+ */
+#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
+#define SDC_MMC_SUPPORT FALSE
+#endif
+
+/**
+ * @brief Delays insertions.
+ * @details If enabled this options inserts delays into the MMC waiting
+ * routines releasing some extra CPU time for the threads with
+ * lower priority, this may slow down the driver a bit however.
+ */
+#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
+#define SDC_NICE_WAITING TRUE
+#endif
+
+/*===========================================================================*/
+/* SERIAL driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Default bit rate.
+ * @details Configuration parameter, this is the baud rate selected for the
+ * default configuration.
+ */
+#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
+#define SERIAL_DEFAULT_BITRATE 38400
+#endif
+
+/**
+ * @brief Serial buffers size.
+ * @details Configuration parameter, you can change the depth of the queue
+ * buffers depending on the requirements of your application.
+ * @note The default is 16 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_BUFFERS_SIZE 16
+#endif
+
+/*===========================================================================*/
+/* SERIAL_USB driver related setting. */
+/*===========================================================================*/
+
+/**
+ * @brief Serial over USB buffers size.
+ * @details Configuration parameter, the buffer size must be a multiple of
+ * the USB data endpoint maximum packet size.
+ * @note The default is 256 bytes for both the transmission and receive
+ * buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_SIZE 1
+#endif
+
+/**
+ * @brief Serial over USB number of buffers.
+ * @note The default is 2 buffers.
+ */
+#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
+#define SERIAL_USB_BUFFERS_NUMBER 2
+#endif
+
+/*===========================================================================*/
+/* SPI driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
+#define SPI_USE_WAIT TRUE
+#endif
+
+/**
+ * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define SPI_USE_MUTUAL_EXCLUSION TRUE
+#endif
+
+/*===========================================================================*/
+/* UART driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_WAIT) || defined(__DOXYGEN__)
+#define UART_USE_WAIT FALSE
+#endif
+
+/**
+ * @brief Enables the @p uartAcquireBus() and @p uartReleaseBus() APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(UART_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
+#define UART_USE_MUTUAL_EXCLUSION FALSE
+#endif
+
+/*===========================================================================*/
+/* USB driver related settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Enables synchronous APIs.
+ * @note Disabling this option saves both code and data space.
+ */
+#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__)
+#define USB_USE_WAIT TRUE
+#endif
+
+#endif /* HALCONF_H */
+
+/** @} */
diff --git a/keyboards/hadron/ver3/keymaps/default/config.h b/keyboards/hadron/ver3/keymaps/default/config.h
new file mode 100644
index 000000000..6f70f09be
--- /dev/null
+++ b/keyboards/hadron/ver3/keymaps/default/config.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/keyboards/hadron/ver3/keymaps/default/keymap.c b/keyboards/hadron/ver3/keymaps/default/keymap.c
new file mode 100644
index 000000000..11761b321
--- /dev/null
+++ b/keyboards/hadron/ver3/keymaps/default/keymap.c
@@ -0,0 +1,295 @@
+#include QMK_KEYBOARD_H
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+// Layer names don't all need to be of the same length, obviously, and you can also skip them
+// entirely and just use numbers.
+#define _QWERTY 0
+#define _COLEMAK 1
+#define _DVORAK 2
+#define _LOWER 3
+#define _RAISE 4
+#define _MOUSECURSOR 8
+#define _ADJUST 16
+
+enum preonic_keycodes {
+ QWERTY = SAFE_RANGE,
+ COLEMAK,
+ DVORAK,
+ LOWER,
+ RAISE,
+ BACKLIT,
+ RGBLED_TOGGLE,
+ RGBLED_STEP_MODE,
+ RGBLED_INCREASE_HUE,
+ RGBLED_DECREASE_HUE,
+ RGBLED_INCREASE_SAT,
+ RGBLED_DECREASE_SAT,
+ RGBLED_INCREASE_VAL,
+ RGBLED_DECREASE_VAL,
+};
+
+enum macro_keycodes {
+ KC_DEMOMACRO,
+};
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+// Custom macros
+#define CTL_ESC CTL_T(KC_ESC) // Tap for Esc, hold for Ctrl
+#define CTL_TTAB CTL_T(KC_TAB) // Tap for Esc, hold for Ctrl
+#define CTL_ENT CTL_T(KC_ENT) // Tap for Enter, hold for Ctrl
+#define SFT_ENT SFT_T(KC_ENT) // Tap for Enter, hold for Shift
+// Requires KC_TRNS/_______ for the trigger key in the destination layer
+#define LT_MC(kc) LT(_MOUSECURSOR, kc) // L-ayer T-ap M-ouse C-ursor
+#define LT_RAI(kc) LT(_RAISE, kc) // L-ayer T-ap to Raise
+#define DEMOMACRO M(KC_DEMOMACRO) // Sample for macros
+
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Qwerty
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | DEL |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Tab | Q | W | E | R | T | 7 | 8 | 9 | Y | U | I | O | P | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | CAPS | A | S | D | F | G | 4 | 5 | 6 | H | J | K | L | ;/Nav| ' |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | 1 | 2 | 3 | N | M | , | . | / |Ctl/Et|
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_QWERTY] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_P7, KC_P8, KC_P9, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_P4, KC_P5, KC_P6, KC_H, KC_J, KC_K, KC_L,LT_MC(KC_SCLN), KC_QUOT, \
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_P1, KC_P2, KC_P3, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, CTL_ENT, \
+ KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT,KC_DOWN, KC_UP, KC_RGHT \
+),
+
+/* Colemak
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Tab | Q | W | F | P | G | 7 | 8 | 9 | J | L | U | Y | ; | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | CAPS | A | R | S | T | D | 4 | 5 | 6 | H | N | E | I | O | ' |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | 1 | 2 | 3 | K | M | , | . | / |Ctl/Et|
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_COLEMAK] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
+ KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_P7, KC_P8, KC_P9, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC, \
+ KC_LCTRL, KC_A, KC_R, KC_S, KC_T, KC_D, KC_P4, KC_P5, KC_P6, KC_H, KC_N, KC_E, KC_I, LT_MC(KC_O), KC_QUOT, \
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_P1, KC_P2, KC_P3, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, CTL_ENT, \
+ KC_GRV, KC_CAPS, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
+ ),
+
+/* Dvorak
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Tab | " | , | . | P | Y | 7 | 8 | 9 | F | G | C | R | L | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | Esc | A | O | E | U | I | 4 | 5 | 6 | D | H | T | N | S | / |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| ; | Q | J | K | X | 1 | 2 | 3 | B | M | W | V | Z |Ctl/Et|
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | ` | Ctrl | Alt | GUI |Lower |Space | 0 | . | = |Space |Raise | Left | Down | Up |Right |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_DVORAK] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_DEL,\
+ KC_TAB, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_P7, KC_P8, KC_P9, KC_F, KC_G, KC_C, KC_R, KC_L, KC_BSPC, \
+ KC_LCTL, KC_A, KC_O, KC_E, KC_U, KC_I, KC_P4, KC_P5, KC_P6, KC_D, KC_H, KC_T, KC_N, LT_MC(KC_S), KC_SLSH, \
+ KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_P1, KC_P2, KC_P3, KC_B, KC_M, KC_W, KC_V, KC_Z, CTL_ENT, \
+ KC_GRV, KC_LCTRL, KC_LGUI, KC_LALT, LOWER, KC_SPC, KC_P0, KC_DOT, KC_EQL, KC_SPC, RAISE, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT \
+),
+
+/* Lower
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | ~ | ! | @ | # | $ | % | | | | ^ | & | * | ( | ) | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | | F1 | F2 | F3 | F4 | F5 | | | | F6 | _ | + | { | } | | |
+ * |------+------+------+------+------+------|------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | | | | F12 |ISO ~ |ISO | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_LOWER] = LAYOUT(
+ KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
+ KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, _______, _______, _______, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_DEL, \
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, _______, KC_F6, KC_UNDS, KC_PLUS, KC_LBRC, KC_RBRC, KC_PIPE, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, KC_F12,S(KC_NUHS),S(KC_NUBS),_______,_______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Raise
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | ` | 1 | 2 | 3 | 4 | 5 | | | | 6 | 7 | 8 | 9 | 0 | Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------+------+------+------|
+ * | Del | F1 | F2 | F3 | F4 | F5 | | | | F6 | - | = | [ | ] | \ |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | F7 | F8 | F9 | F10 | F11 | | | | F12 |ISO # |ISO / | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | Next | Vol- | Vol+ | Play |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_RAISE] = LAYOUT(
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, _______, _______, _______, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL, \
+ KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, _______, _______, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
+ _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, KC_F12, KC_NUHS, KC_NUBS, _______, _______, _______, \
+ _______, _______, _______, _______, _______, KC_SPC, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
+),
+
+/* Mouse Layer (semi-col)
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | ACCL0| ACCL1| ACCL2| | | | | | | | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | | | | | | | | | Home | Wh_Up| WHL_L| M_Up | WHL_R| Macro| |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | End | Wh_Dn| M_Lft| M_Dn | M_Rt | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | BTN2 | BTN3 | BTN4 | BTN5 | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | BTN1 | | | | BTN1 | | | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+
+[_MOUSECURSOR] = LAYOUT(
+ KC_ACL0, KC_ACL1, KC_ACL2, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_HOME, KC_PGUP, KC_WH_L, KC_MS_U, KC_WH_R,DEMOMACRO,_______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, KC_END , KC_PGDN, KC_MS_L, KC_MS_D, KC_MS_R, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_BTN2, KC_BTN3, KC_BTN4, KC_BTN5, _______, _______, \
+ _______, _______, _______, _______, _______, KC_BTN1, _______, _______, _______, KC_BTN1, _______, _______, _______, _______, _______ \
+),
+
+/* Adjust (Lower + Raise)
+ * ,------+------+------+------+------+------------------------------------------------.
+ * | Esc | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+--------------------.
+ * | Reset|RGB TG|RGB ST|RGBH -|RGBH +|RGBS -|RGBS +|RGBV -|RGBV +| | | | | | Del |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | |Aud on|Audoff|AGnorm| | | |AGswap|Qwerty|Colemk| | | |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | |Voice-|Voice+|Mus on|Musoff| | | | | | | | BL + |BL ST |BL TG |
+ * |------+------+------+------+------+------+------+------+------+------+------+------+------+------+------|
+ * | | | | | | | | | | | | | | | |
+ * `--------------------------------------------------------------------------------------------------------'
+ */
+[_ADJUST] = LAYOUT(
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
+ RESET, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______, _______, _______, KC_DEL, \
+ _______, _______, _______, AU_ON, AU_OFF, AG_NORM, _______, _______, _______, AG_SWAP, QWERTY, COLEMAK, _______, _______, _______, \
+ _______, MUV_DE, MUV_IN, MU_ON, MU_OFF, MI_ON, MI_OFF, _______, _______, _______, _______, BL_DEC, BL_INC, BL_STEP, BL_TOGG, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, CK_RST, CK_DOWN, CK_UP, CK_TOGG\
+)
+
+
+
+};
+
+uint32_t layer_state_set_user(uint32_t state) {
+ return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
+
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case QWERTY:
+ if (record->event.pressed) {
+ set_single_persistent_default_layer(_QWERTY);
+ }
+ return false;
+ break;
+ case COLEMAK:
+ if (record->event.pressed) {
+ set_single_persistent_default_layer(_COLEMAK);
+ }
+ return false;
+ break;
+ case LOWER:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ layer_on(_LOWER);
+ } else {
+ layer_off(_LOWER);
+ }
+ return false;
+ break;
+ case RAISE:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ layer_on(_RAISE);
+ } else {
+ layer_off(_RAISE);
+ }
+ return false;
+ break;
+ case BACKLIT:
+ if (record->event.pressed) {
+ register_code(KC_RSFT);
+ #ifdef BACKLIGHT_ENABLE
+ backlight_step();
+ #endif
+ } else {
+ unregister_code(KC_RSFT);
+ }
+ return false;
+ break;
+ }
+ return true;
+}
+
+bool music_mask_user(uint16_t keycode) {
+ switch (keycode) {
+ case RAISE:
+ case LOWER:
+ return false;
+ default:
+ return true;
+ }
+}
+
+
+/*
+ * Macro definition
+ */
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ if (!eeconfig_is_enabled()) {
+ eeconfig_init();
+ }
+
+ switch (id) {
+ case KC_DEMOMACRO:
+ if (record->event.pressed){
+ return MACRO (I(1), T(H),T(E),T(L), T(L), T(O), T(SPACE), T(W), T(O), T(R), T(L), T(D), END);
+ }
+ }
+
+ return MACRO_NONE;
+}
+
+
+void matrix_init_user(void) {
+}
+
+
+void matrix_scan_user(void) {
+}
+
diff --git a/keyboards/hadron/ver3/keymaps/default/readme.md b/keyboards/hadron/ver3/keymaps/default/readme.md
new file mode 100644
index 000000000..88b958ec4
--- /dev/null
+++ b/keyboards/hadron/ver3/keymaps/default/readme.md
@@ -0,0 +1,2 @@
+# The Default Hadron Layout
+
diff --git a/keyboards/hadron/ver3/keymaps/readme.md b/keyboards/hadron/ver3/keymaps/readme.md
new file mode 100644
index 000000000..54fb5f6d9
--- /dev/null
+++ b/keyboards/hadron/ver3/keymaps/readme.md
@@ -0,0 +1,23 @@
+# How to add your own keymap
+
+Folders can be named however you'd like (will be approved upon merging), or should follow the format with a preceding `_`:
+
+ _[ISO 3166-1 alpha-2 code*]_[layout variant]_[layout name/author]
+
+\* See full list: https://en.wikipedia.org/wiki/ISO_3166-1#Officially_assigned_code_elements
+
+and contain the following files:
+
+* `keymap.c`
+* `readme.md` *recommended*
+* `config.h` *optional*, found automatically when compiling
+* `Makefile` *optional*, found automatically when compling
+
+When adding your keymap to this list, keep it organised alphabetically (select list, edit->sort lines), and use this format:
+
+ * **folder_name** description
+
+# List of Planck keymaps
+
+* **default** default Planck layout
+* **cbbrowne** cbbrowne's Planck layout
\ No newline at end of file
diff --git a/keyboards/hadron/ver3/matrix.c b/keyboards/hadron/ver3/matrix.c
new file mode 100644
index 000000000..329d1328a
--- /dev/null
+++ b/keyboards/hadron/ver3/matrix.c
@@ -0,0 +1,195 @@
+#include
+#include "hal.h"
+#include "timer.h"
+#include "wait.h"
+#include "printf.h"
+#include "backlight.h"
+#include "matrix.h"
+#include "action.h"
+#include "keycode.h"
+
+/* matrix state(1:on, 0:off) */
+static matrix_row_t matrix[MATRIX_ROWS];
+static matrix_row_t matrix_debouncing[MATRIX_COLS];
+static bool debouncing = false;
+static uint16_t debouncing_time = 0;
+
+static uint8_t encoder_state = 0;
+static int8_t encoder_value = 0;
+static int8_t encoder_LUT[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 };
+
+__attribute__ ((weak))
+void matrix_init_user(void) {}
+
+__attribute__ ((weak))
+void matrix_scan_user(void) {}
+
+__attribute__ ((weak))
+void matrix_init_kb(void) {
+ matrix_init_user();
+}
+
+__attribute__ ((weak))
+void matrix_scan_kb(void) {
+ matrix_scan_user();
+}
+
+void matrix_init(void) {
+ printf("matrix init\n");
+ //debug_matrix = true;
+
+ // encoder setup
+ palSetPadMode(GPIOB, 13, PAL_MODE_INPUT_PULLUP);
+ palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP);
+
+ encoder_state = (palReadPad(GPIOB, 13) << 0) | (palReadPad(GPIOB, 14) << 1);
+
+ // actual matrix setup
+ palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOA, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOA, 1, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOA, 2, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOA, 3, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOA, 6, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOC, 13, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL);
+ palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL);
+
+ palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN);
+ palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN);
+ palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN);
+ palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN);
+ palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN);
+
+
+ memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
+ memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_row_t));
+
+
+ matrix_init_quantum();
+}
+
+__attribute__ ((weak))
+void encoder_update(bool clockwise) { }
+
+#ifndef ENCODER_RESOLUTION
+ #define ENCODER_RESOLUTION 4
+#endif
+
+uint8_t matrix_scan(void) {
+ // encoder on B13 and B14
+ encoder_state <<= 2;
+ encoder_state |= (palReadPad(GPIOB, 13) << 0) | (palReadPad(GPIOB, 14) << 1);
+ encoder_value += encoder_LUT[encoder_state & 0xF];
+ if (encoder_value >= ENCODER_RESOLUTION) {
+ encoder_update(0);
+ }
+ if (encoder_value <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise
+ encoder_update(1);
+ }
+ encoder_value %= ENCODER_RESOLUTION;
+
+ // actual matrix
+ for (int col = 0; col < MATRIX_COLS; col++) {
+ matrix_row_t data = 0;
+
+ // strobe col { PB8, PB2, PB10, PA0, PA1, PA2, PB0, PA3, PB1, PA6, PA7, PB1, PA6, PA7, PB12, PC3, PB11, }
+ switch (col) {
+ case 0: palSetPad(GPIOB, 8); break;
+ case 1: palSetPad(GPIOB, 2); break;
+ case 2: palSetPad(GPIOB, 10); break;
+ case 3: palSetPad(GPIOA, 0); break;
+ case 4: palSetPad(GPIOA, 1); break;
+ case 5: palSetPad(GPIOA, 2); break;
+ case 6: palSetPad(GPIOB, 0); break;
+ case 7: palSetPad(GPIOA, 3); break;
+ case 8: palSetPad(GPIOB, 1); break;
+ case 9: palSetPad(GPIOA, 6); break;
+ case 10: palSetPad(GPIOA, 7); break;
+ case 11: palSetPad(GPIOB, 12); break;
+ case 12: palSetPad(GPIOC, 13); break;
+ case 13: palSetPad(GPIOB, 11); break;
+ case 14: palSetPad(GPIOB, 9); break;
+ }
+
+ // need wait to settle pin state
+ wait_us(20);
+
+ // read row data { PC15, PC14, PA10, PA9, PA8 }
+ data = (
+ (palReadPad(GPIOC, 15) << 0 ) |
+ (palReadPad(GPIOC, 14) << 1 ) |
+ (palReadPad(GPIOA, 10) << 2 ) |
+ (palReadPad(GPIOA, 9) << 3 ) |
+ (palReadPad(GPIOA, 8) << 4 )
+ );
+
+ // unstrobe col { PB8, PB2, PB10, PA0, PA1, PA2, PB0, PA3, PB1, PA6, PA7, PB1, PA6, PA7, PB12, PC3, PB11, }
+ switch (col) {
+ case 0: palClearPad(GPIOB, 8); break;
+ case 1: palClearPad(GPIOB, 2); break;
+ case 2: palClearPad(GPIOB, 10); break;
+ case 3: palClearPad(GPIOA, 0); break;
+ case 4: palClearPad(GPIOA, 1); break;
+ case 5: palClearPad(GPIOA, 2); break;
+ case 6: palClearPad(GPIOB, 0); break;
+ case 7: palClearPad(GPIOA, 3); break;
+ case 8: palClearPad(GPIOB, 1); break;
+ case 9: palClearPad(GPIOA, 6); break;
+ case 10: palClearPad(GPIOA, 7); break;
+ case 11: palClearPad(GPIOB, 12); break;
+ case 12: palClearPad(GPIOC, 13); break;
+ case 13: palClearPad(GPIOB, 11); break;
+ case 14: palClearPad(GPIOB, 9); break;
+ }
+
+ if (matrix_debouncing[col] != data) {
+ matrix_debouncing[col] = data;
+ debouncing = true;
+ debouncing_time = timer_read();
+ }
+ }
+
+ if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
+ for (int row = 0; row < MATRIX_ROWS; row++) {
+ matrix[row] = 0;
+ for (int col = 0; col < MATRIX_COLS; col++) {
+ matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col);
+ }
+ }
+ debouncing = false;
+ }
+
+ matrix_scan_quantum();
+
+ return 1;
+}
+
+bool matrix_is_on(uint8_t row, uint8_t col) {
+ return (matrix[row] & (1<
+ *
+ * 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 .
+ */
+#ifndef REV3_H
+#define REV3_H
+
+#include "hadron.h"
+
+#endif
\ No newline at end of file
diff --git a/keyboards/hadron/ver3/rules.mk b/keyboards/hadron/ver3/rules.mk
new file mode 100644
index 000000000..8375efdd3
--- /dev/null
+++ b/keyboards/hadron/ver3/rules.mk
@@ -0,0 +1,57 @@
+# project specific files
+SRC = matrix.c
+
+## chip/board settings
+# - the next two should match the directories in
+# /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
+MCU_FAMILY = STM32
+MCU_SERIES = STM32F3xx
+
+# Linker script to use
+# - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/
+# or /ld/
+MCU_LDSCRIPT = STM32F303xC
+
+# Startup code to use
+# - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/
+MCU_STARTUP = stm32f3xx
+
+# Board: it should exist either in /os/hal/boards/
+# or /boards
+BOARD = GENERIC_STM32_F303XC
+
+# Cortex version
+MCU = cortex-m4
+
+# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7
+ARMV = 7
+
+USE_FPU = yes
+
+# Vector table for application
+# 0x00000000-0x00001000 area is occupied by bootlaoder.*/
+# The CORTEX_VTOR... is needed only for MCHCK/Infinity KB
+# OPT_DEFS = -DCORTEX_VTOR_INIT=0x08005000
+OPT_DEFS =
+
+# Options to pass to dfu-util when flashing
+DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave
+
+# Build Options
+# comment out to disable the options.
+#
+BACKLIGHT_ENABLE = no
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
+## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.)
+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
+#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
+NKRO_ENABLE = yes # USB Nkey Rollover
+CUSTOM_MATRIX = yes # Custom matrix file
+AUDIO_ENABLE = yes
+RGBLIGHT_ENABLE = no
+HAPTIC_ENABLE = DRV2605L
+QWIIC_ENABLE += MICRO_OLED
+# SERIAL_LINK_ENABLE = yes
diff --git a/keyboards/hadron/ver3/ver3.c b/keyboards/hadron/ver3/ver3.c
new file mode 100644
index 000000000..5e5e3e009
--- /dev/null
+++ b/keyboards/hadron/ver3/ver3.c
@@ -0,0 +1,196 @@
+/* Copyright 2018 Jack Humbert
+ *
+ * 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 .
+ */
+#include "ver3.h"
+#include "qwiic.h"
+#include "action_layer.h"
+#include "matrix.h"
+#include "DRV2605L.h"
+
+#ifdef QWIIC_MICRO_OLED_ENABLE
+
+/* screen off after this many milliseconds */
+#include "timer.h"
+#define ScreenOffInterval 60000 /* milliseconds */
+static uint16_t last_flush;
+
+volatile uint8_t led_numlock = false;
+volatile uint8_t led_capslock = false;
+volatile uint8_t led_scrolllock = false;
+
+static uint8_t layer;
+static bool queue_for_send = false;
+static uint8_t encoder_value = 32;
+
+__attribute__ ((weak))
+void draw_ui(void) {
+ clear_buffer();
+ last_flush = timer_read();
+ send_command(DISPLAYON);
+
+/* Layer indicator is 41 x 10 pixels */
+#define LAYER_INDICATOR_X 0
+#define LAYER_INDICATOR_Y 0
+
+ draw_string(LAYER_INDICATOR_X + 1, LAYER_INDICATOR_Y + 2, "LAYER", PIXEL_ON, NORM, 0);
+ draw_rect_filled_soft(LAYER_INDICATOR_X + 32, LAYER_INDICATOR_Y + 1, 9, 9, PIXEL_ON, NORM);
+ draw_char(LAYER_INDICATOR_X + 34, LAYER_INDICATOR_Y + 2, layer + 0x30, PIXEL_ON, XOR, 0);
+
+/* Matrix display is 19 x 9 pixels */
+#define MATRIX_DISPLAY_X 0
+#define MATRIX_DISPLAY_Y 18
+
+ for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
+ for (uint8_t y = 0; y < MATRIX_COLS; y++) {
+ draw_pixel(MATRIX_DISPLAY_X + y + 2, MATRIX_DISPLAY_Y + x + 2,(matrix_get_row(x) & (1 << y)) > 0, NORM);
+ }
+ }
+ draw_rect_soft(MATRIX_DISPLAY_X, MATRIX_DISPLAY_Y, 19, 9, PIXEL_ON, NORM);
+ /* hadron oled location on thumbnail */
+ draw_rect_filled_soft(MATRIX_DISPLAY_X + 14, MATRIX_DISPLAY_Y + 2, 3, 1, PIXEL_ON, NORM);
+/*
+ draw_rect_soft(0, 13, 64, 6, PIXEL_ON, NORM);
+ draw_line_vert(encoder_value, 13, 6, PIXEL_ON, NORM);
+
+*/
+
+/* Mod display is 41 x 16 pixels */
+#define MOD_DISPLAY_X 30
+#define MOD_DISPLAY_Y 18
+
+ uint8_t mods = get_mods();
+ if (mods & MOD_LSFT) {
+ draw_rect_filled_soft(MOD_DISPLAY_X + 0, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
+ draw_string(MOD_DISPLAY_X + 3, MOD_DISPLAY_Y + 2, "S", PIXEL_OFF, NORM, 0);
+ } else {
+ draw_string(MOD_DISPLAY_X + 3, MOD_DISPLAY_Y + 2, "S", PIXEL_ON, NORM, 0);
+ }
+ if (mods & MOD_LCTL) {
+ draw_rect_filled_soft(MOD_DISPLAY_X + 10, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
+ draw_string(MOD_DISPLAY_X + 13, MOD_DISPLAY_Y + 2, "C", PIXEL_OFF, NORM, 0);
+ } else {
+ draw_string(MOD_DISPLAY_X + 13, MOD_DISPLAY_Y + 2, "C", PIXEL_ON, NORM, 0);
+ }
+ if (mods & MOD_LALT) {
+ draw_rect_filled_soft(MOD_DISPLAY_X + 20, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
+ draw_string(MOD_DISPLAY_X + 23, MOD_DISPLAY_Y + 2, "A", PIXEL_OFF, NORM, 0);
+ } else {
+ draw_string(MOD_DISPLAY_X + 23, MOD_DISPLAY_Y + 2, "A", PIXEL_ON, NORM, 0);
+ }
+ if (mods & MOD_LGUI) {
+ draw_rect_filled_soft(MOD_DISPLAY_X + 30, MOD_DISPLAY_Y, 5 + (1 * 6), 11, PIXEL_ON, NORM);
+ draw_string(MOD_DISPLAY_X + 33, MOD_DISPLAY_Y + 2, "G", PIXEL_OFF, NORM, 0);
+ } else {
+ draw_string(MOD_DISPLAY_X + 33, MOD_DISPLAY_Y + 2, "G", PIXEL_ON, NORM, 0);
+ }
+
+/* Lock display is 23 x 32 */
+#define LOCK_DISPLAY_X 100
+#define LOCK_DISPLAY_Y 0
+
+ if (led_numlock == true) {
+ draw_rect_filled_soft(LOCK_DISPLAY_X, LOCK_DISPLAY_Y, 5 + (3 * 6), 9, PIXEL_ON, NORM);
+ draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 1, "NUM", PIXEL_OFF, NORM, 0);
+ } else if (led_numlock == false) {
+ draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 1, "NUM", PIXEL_ON, NORM, 0);
+ }
+ if (led_capslock == true) {
+ draw_rect_filled_soft(LOCK_DISPLAY_X + 0, LOCK_DISPLAY_Y + 11, 5 + (3 * 6), 9, PIXEL_ON, NORM);
+ draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 11 +1, "CAP", PIXEL_OFF, NORM, 0);
+ } else if (led_capslock == false) {
+ draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 11 +1, "CAP", PIXEL_ON, NORM, 0);
+ }
+
+ if (led_scrolllock == true) {
+ draw_rect_filled_soft(LOCK_DISPLAY_X + 0, LOCK_DISPLAY_Y + 22, 5 + (3 * 6), 9, PIXEL_ON, NORM);
+ draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 22 +1, "SCR", PIXEL_OFF, NORM, 0);
+ } else if (led_scrolllock == false) {
+ draw_string(LOCK_DISPLAY_X + 3, LOCK_DISPLAY_Y + 22 +1, "SCR", PIXEL_ON, NORM, 0);
+ }
+ send_buffer();
+}
+
+void read_host_led_state(void) {
+ uint8_t leds = host_keyboard_leds();
+ if (leds & (1 << USB_LED_NUM_LOCK)) {
+ if (led_numlock == false){
+ led_numlock = true;}
+ } else {
+ if (led_numlock == true){
+ led_numlock = false;}
+ }
+ if (leds & (1 << USB_LED_CAPS_LOCK)) {
+ if (led_capslock == false){
+ led_capslock = true;}
+ } else {
+ if (led_capslock == true){
+ led_capslock = false;}
+ }
+ if (leds & (1 << USB_LED_SCROLL_LOCK)) {
+ if (led_scrolllock == false){
+ led_scrolllock = true;}
+ } else {
+ if (led_scrolllock == true){
+ led_scrolllock = false;}
+ }
+}
+
+uint32_t layer_state_set_kb(uint32_t state) {
+ state = layer_state_set_user(state);
+ layer = biton32(state);
+ queue_for_send = true;
+ return state;
+}
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+ queue_for_send = true;
+ return process_record_user(keycode, record);
+}
+
+void encoder_update_kb(uint8_t index, bool clockwise) {
+ encoder_value = (encoder_value + (clockwise ? 1 : -1)) % 64;
+ queue_for_send = true;
+}
+
+#endif
+
+void matrix_init_kb(void) {
+#ifdef DRV2605L
+ DRV_init();
+#endif
+ queue_for_send = true;
+ matrix_init_user();
+}
+
+void matrix_scan_kb(void) {
+
+if (queue_for_send) {
+ #ifdef DRV2605L
+ DRV_EFFECT play_eff = strong_click;
+ DRV_pulse(play_eff);
+ #endif
+#ifdef QWIIC_MICRO_OLED_ENABLE
+ read_host_led_state();
+ draw_ui();
+#endif
+ queue_for_send = false;
+ }
+#ifdef QWIIC_MICRO_OLED_ENABLE
+ if (timer_elapsed(last_flush) > ScreenOffInterval) {
+ send_command(DISPLAYOFF); /* 0xAE */
+ }
+#endif
+ matrix_scan_user();
+}
diff --git a/keyboards/hadron/ver3/ver3.h b/keyboards/hadron/ver3/ver3.h
new file mode 100644
index 000000000..516f7b9a1
--- /dev/null
+++ b/keyboards/hadron/ver3/ver3.h
@@ -0,0 +1,21 @@
+/* Copyright 2018 Jack Humbert
+ *
+ * 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 .
+ */
+#ifndef VER3_H
+#define VER3_H
+
+#include "hadron.h"
+
+#endif
\ No newline at end of file
diff --git a/keyboards/helix/rev1/keymaps/OLED_sample/rules.mk b/keyboards/helix/rev1/keymaps/OLED_sample/rules.mk
deleted file mode 100644
index c56d6f37e..000000000
--- a/keyboards/helix/rev1/keymaps/OLED_sample/rules.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-
-# Build Options
-# change to "no" to disable the options, or define them in the Makefile in
-# the appropriate keymap folder that will get included automatically
-#
-BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
-MOUSEKEY_ENABLE = no # Mouse keys(+4700)
-EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
-CONSOLE_ENABLE = no # Console for debug(+400)
-COMMAND_ENABLE = no # Commands for debug and configuration
-NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
-BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
-MIDI_ENABLE = no # MIDI controls
-AUDIO_ENABLE = no # Audio output on port C6
-UNICODE_ENABLE = no # Unicode
-BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
-RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight.
-SWAP_HANDS_ENABLE = no # Enable one-hand typing
-
-# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
-SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
-
-ifndef QUANTUM_DIR
- include ../../../../Makefile
-endif
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 6d48321f9..f1551d251 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -82,12 +82,10 @@ void layer_xor(uint32_t state);
#define layer_or(state)
#define layer_and(state)
#define layer_xor(state)
+#endif
-__attribute__((weak))
uint32_t layer_state_set_user(uint32_t state);
-__attribute__((weak))
uint32_t layer_state_set_kb(uint32_t state);
-#endif
/* pressed actions cache */
#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index a6a5fb56b..6f659b244 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -72,6 +72,9 @@ along with this program. If not, see .
#ifdef HD44780_ENABLE
# include "hd44780.h"
#endif
+#ifdef QWIIC_ENABLE
+# include "qwiic.h"
+#endif
#ifdef MATRIX_HAS_GHOST
extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
@@ -161,6 +164,9 @@ bool is_keyboard_master(void) {
void keyboard_init(void) {
timer_init();
matrix_init();
+#ifdef QWIIC_ENABLE
+ qwiic_init();
+#endif
#ifdef PS2_MOUSE_ENABLE
ps2_mouse_init();
#endif
@@ -270,6 +276,10 @@ void keyboard_task(void)
MATRIX_LOOP_END:
+#ifdef QWIIC_ENABLE
+ qwiic_task();
+#endif
+
#ifdef MOUSEKEY_ENABLE
// mousekey repeat & acceleration
mousekey_task();
--
cgit v1.2.3-70-g09d2
From 28fbf84cc5ff52f545011ea4198a6cc6d054f896 Mon Sep 17 00:00:00 2001
From: Konstantin Đorđević
Date: Wed, 12 Dec 2018 19:17:19 +0100
Subject: Add standard definitions for ALGR and KC_ALGR (#4389)
* Add standard ALGR defition, remove (re)definitions from language files
* Use ALGR(kc) consistently in ALTGR(kc) aliases
* Non-Nordic keymaps should not use NO_ALGR
* Add standard KC_ALGR definition
* Update docs with ALGR and KC_ALGR
* Update SS_ALGR and ALGR_T aliases
---
docs/feature_advanced_keycodes.md | 4 ++--
docs/keycodes.md | 4 ++--
docs/keycodes_basic.md | 2 +-
keyboards/handwired/reddot/keymaps/default/keymap.c | 4 ++--
keyboards/xd75/keymaps/germanized/config.h | 1 -
quantum/keymap_extras/keymap_belgian.h | 5 +----
quantum/keymap_extras/keymap_bepo.h | 5 +----
quantum/keymap_extras/keymap_canadian_multilingual.h | 5 +----
quantum/keymap_extras/keymap_fr_ch.h | 1 -
quantum/keymap_extras/keymap_french.h | 5 +----
quantum/keymap_extras/keymap_german.h | 1 -
quantum/keymap_extras/keymap_german_ch.h | 1 -
quantum/keymap_extras/keymap_hungarian.h | 1 -
quantum/keymap_extras/keymap_italian.h | 1 -
quantum/keymap_extras/keymap_nordic.h | 1 -
quantum/keymap_extras/keymap_slovenian.h | 1 -
quantum/keymap_extras/keymap_spanish.h | 3 +--
quantum/keymap_extras/keymap_uk.h | 3 +--
quantum/quantum.h | 1 +
quantum/quantum_keycodes.h | 5 +++--
tmk_core/common/keycode.h | 1 +
21 files changed, 18 insertions(+), 37 deletions(-)
(limited to 'tmk_core/common')
diff --git a/docs/feature_advanced_keycodes.md b/docs/feature_advanced_keycodes.md
index bb5cb7419..e5f241f7f 100644
--- a/docs/feature_advanced_keycodes.md
+++ b/docs/feature_advanced_keycodes.md
@@ -68,7 +68,7 @@ These allow you to combine a modifier with a keycode. When pressed, the keydown
|`LGUI(kc)`|`LCMD(kc)`, `LWIN(kc)`|Hold Left GUI and press `kc` |
|`RCTL(kc)`| |Hold Right Control and press `kc` |
|`RSFT(kc)`| |Hold Right Shift and press `kc` |
-|`RALT(kc)`| |Hold Right Alt and press `kc` |
+|`RALT(kc)`|`ALGR(kc)` |Hold Right Alt and press `kc` |
|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)`|Hold Right GUI and press `kc` |
|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc`|
|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` |
@@ -92,7 +92,7 @@ The modifiers this keycode and `OSM()` accept are prefixed with `MOD_`, not `KC_
|`MOD_LGUI`|Left GUI (Windows/Command/Meta key) |
|`MOD_RCTL`|Right Control |
|`MOD_RSFT`|Right Shift |
-|`MOD_RALT`|Right Alt |
+|`MOD_RALT`|Right Alt (AltGr) |
|`MOD_RGUI`|Right GUI (Windows/Command/Meta key) |
|`MOD_HYPR`|Hyper (Left Control, Shift, Alt and GUI)|
|`MOD_MEH` |Meh (Left Control, Shift, and Alt) |
diff --git a/docs/keycodes.md b/docs/keycodes.md
index 75b01389c..d12a85aa1 100644
--- a/docs/keycodes.md
+++ b/docs/keycodes.md
@@ -177,7 +177,7 @@ This is a reference only. Each group of keys links to the page documenting their
|`KC_LGUI` |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key) |
|`KC_RCTRL` |`KC_RCTL` |Right Control |
|`KC_RSHIFT` |`KC_RSFT` |Right Shift |
-|`KC_RALT` | |Right Alt |
+|`KC_RALT` |`KC_ALGR` |Right Alt (AltGr) |
|`KC_RGUI` |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key) |
|`KC_SYSTEM_POWER` |`KC_PWR` |System Power Down |
|`KC_SYSTEM_SLEEP` |`KC_SLEP` |System Sleep |
@@ -331,7 +331,7 @@ This is a reference only. Each group of keys links to the page documenting their
|`LGUI(kc)`|`LCMD(kc)`, `LWIN(kc)`|Hold Left GUI and press `kc` |
|`RCTL(kc)`| |Hold Right Control and press `kc` |
|`RSFT(kc)`| |Hold Right Shift and press `kc` |
-|`RALT(kc)`| |Hold Right Alt and press `kc` |
+|`RALT(kc)`|`ALGR(kc)` |Hold Right Alt and press `kc` |
|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)`|Hold Right GUI and press `kc` |
|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc`|
|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` |
diff --git a/docs/keycodes_basic.md b/docs/keycodes_basic.md
index 9cc00f032..cba876d34 100644
--- a/docs/keycodes_basic.md
+++ b/docs/keycodes_basic.md
@@ -116,7 +116,7 @@ The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07
|`KC_LGUI` |`KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key) |
|`KC_RCTRL` |`KC_RCTL` |Right Control |
|`KC_RSHIFT`|`KC_RSFT` |Right Shift |
-|`KC_RALT` | |Right Alt |
+|`KC_RALT` |`KC_ALGR` |Right Alt (AltGr) |
|`KC_RGUI` |`KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)|
## International
diff --git a/keyboards/handwired/reddot/keymaps/default/keymap.c b/keyboards/handwired/reddot/keymaps/default/keymap.c
index 44ee2ce51..c67cc0e4c 100755
--- a/keyboards/handwired/reddot/keymaps/default/keymap.c
+++ b/keyboards/handwired/reddot/keymaps/default/keymap.c
@@ -8,14 +8,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LALT, FR_AMP, FR_EACU, FR_QUOT, FR_APOS, FR_LPRN, KC_BSPACE, KC_DELETE, FR_MINS, FR_EGRV, FR_UNDS, FR_CCED, FR_AGRV, FR_RPRN, FR_EQL, KC_INSERT, KC_HOME, KC_PGUP,\
KC_LGUI, FR_A, FR_Z, KC_E, KC_R, KC_T, KC_LSFT, KC_ENT, KC_Y, KC_U, KC_I, KC_O, KC_P, FR_CIRC, FR_DLR, KC_DELETE, KC_END, KC_PGDOWN, KC_KP_PLUS,\
KC_LCTL, FR_Q, KC_S, KC_D, KC_F, KC_G, KC_ENT, KC_H, KC_J, KC_K, KC_L, FR_M, FR_UGRV, FR_ASTR, KC_KP_1, KC_UP, KC_KP_3,\
- FR_LESS, FR_W, KC_X, KC_C, KC_V, KC_B, KC_SPACE, KC_SPACE, KC_N, FR_COMM, FR_SCLN, FR_COLN, FR_EXLM, NO_ALGR, KC_LEFT, KC_DOWN, KC_RIGHT, KC_KP_ENTER),
+ FR_LESS, FR_W, KC_X, KC_C, KC_V, KC_B, KC_SPACE, KC_SPACE, KC_N, FR_COMM, FR_SCLN, FR_COLN, FR_EXLM, FR_ALGR, KC_LEFT, KC_DOWN, KC_RIGHT, KC_KP_ENTER),
[1] = KEYMAP(
KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TAB, KC_CAPS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_FN0, KC_KP_SLASH, KC_KP_ASTERISK, KC_KP_MINUS,\
KC_LALT, FR_AMP, FR_EACU, FR_QUOT, FR_APOS, FR_LPRN, KC_BSPACE, KC_DELETE, FR_MINS, FR_EGRV, FR_UNDS, FR_CCED, FR_AGRV, FR_RPRN, FR_EQL, KC_7, KC_8, KC_9,\
KC_LGUI, FR_A, FR_Z, KC_E, KC_R, KC_T, KC_LSFT, KC_ENT, KC_Y, KC_U, KC_I, KC_O, KC_P, FR_CIRC, FR_DLR, KC_4, KC_5, KC_6, KC_KP_PLUS,\
KC_LCTL, FR_Q, KC_S, KC_D, KC_F, KC_G, KC_ENT, KC_H, KC_J, KC_K, KC_L, FR_M, FR_UGRV, FR_ASTR, KC_1, KC_2, KC_3,\
- FR_LESS, FR_W, KC_X, KC_C, KC_V, KC_B, KC_SPACE, KC_SPACE, KC_N, FR_COMM, FR_SCLN, FR_COLN, FR_EXLM, NO_ALGR, KC_LEFT, KC_DOWN, KC_RIGHT, KC_KP_ENTER),
+ FR_LESS, FR_W, KC_X, KC_C, KC_V, KC_B, KC_SPACE, KC_SPACE, KC_N, FR_COMM, FR_SCLN, FR_COLN, FR_EXLM, FR_ALGR, KC_LEFT, KC_DOWN, KC_RIGHT, KC_KP_ENTER),
};
diff --git a/keyboards/xd75/keymaps/germanized/config.h b/keyboards/xd75/keymaps/germanized/config.h
index 5b19bddb0..379b95471 100644
--- a/keyboards/xd75/keymaps/germanized/config.h
+++ b/keyboards/xd75/keymaps/germanized/config.h
@@ -28,7 +28,6 @@
#define TAPPING_TERM 200
// Alt gr
-#define ALGR(kc) RALT(kc)
#define DE_ALGR KC_RALT
// normal characters
diff --git a/quantum/keymap_extras/keymap_belgian.h b/quantum/keymap_extras/keymap_belgian.h
index 764c56141..573fa2e8a 100644
--- a/quantum/keymap_extras/keymap_belgian.h
+++ b/quantum/keymap_extras/keymap_belgian.h
@@ -22,10 +22,7 @@
#define BE_LALT KC_LGUI
// Alt gr
-#ifndef ALGR
-#define ALGR(kc) RALT(kc)
-#endif
-#define NO_ALGR KC_RALT
+#define BE_ALGR KC_RALT
// Normal characters
// Line 1
diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h
index 05fd2b002..e6545a7a8 100644
--- a/quantum/keymap_extras/keymap_bepo.h
+++ b/quantum/keymap_extras/keymap_bepo.h
@@ -21,10 +21,7 @@
// Alt gr
#ifndef ALTGR
-#define ALTGR(kc) RALT(kc)
-#endif
-#ifndef ALGR
-#define ALGR(kc) ALTGR(kc)
+#define ALTGR(kc) ALGR(kc)
#endif
#define BP_ALGR KC_RALT
diff --git a/quantum/keymap_extras/keymap_canadian_multilingual.h b/quantum/keymap_extras/keymap_canadian_multilingual.h
index 1d45bee32..fbeef2187 100644
--- a/quantum/keymap_extras/keymap_canadian_multilingual.h
+++ b/quantum/keymap_extras/keymap_canadian_multilingual.h
@@ -20,10 +20,7 @@
// Alt gr
#ifndef ALTGR
-#define ALTGR(kc) RALT(kc)
-#endif
-#ifndef ALGR
-#define ALGR(kc) ALTGR(kc)
+#define ALTGR(kc) ALGR(kc)
#endif
#define CSA_ALTGR KC_RALT
diff --git a/quantum/keymap_extras/keymap_fr_ch.h b/quantum/keymap_extras/keymap_fr_ch.h
index c0ca832a6..4eeca7209 100644
--- a/quantum/keymap_extras/keymap_fr_ch.h
+++ b/quantum/keymap_extras/keymap_fr_ch.h
@@ -19,7 +19,6 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
#define FR_CH_ALGR KC_RALT
// normal characters
diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h
index 3308dc5f7..d2de859ee 100644
--- a/quantum/keymap_extras/keymap_french.h
+++ b/quantum/keymap_extras/keymap_french.h
@@ -19,10 +19,7 @@
#include "keymap.h"
// Alt gr
-#ifndef ALGR
-#define ALGR(kc) RALT(kc)
-#endif
-#define NO_ALGR KC_RALT
+#define FR_ALGR KC_RALT
// Normal characters
#define FR_SUP2 KC_GRV
diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h
index e007c26ef..a215570fd 100644
--- a/quantum/keymap_extras/keymap_german.h
+++ b/quantum/keymap_extras/keymap_german.h
@@ -20,7 +20,6 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
#define DE_ALGR KC_RALT
// normal characters
diff --git a/quantum/keymap_extras/keymap_german_ch.h b/quantum/keymap_extras/keymap_german_ch.h
index 67350d660..f0376a17c 100644
--- a/quantum/keymap_extras/keymap_german_ch.h
+++ b/quantum/keymap_extras/keymap_german_ch.h
@@ -19,7 +19,6 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
#define CH_ALGR KC_RALT
// normal characters
diff --git a/quantum/keymap_extras/keymap_hungarian.h b/quantum/keymap_extras/keymap_hungarian.h
index b37244092..cd2dc94cf 100644
--- a/quantum/keymap_extras/keymap_hungarian.h
+++ b/quantum/keymap_extras/keymap_hungarian.h
@@ -20,7 +20,6 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
#define HU_ALGR KC_RALT
// basic letters
diff --git a/quantum/keymap_extras/keymap_italian.h b/quantum/keymap_extras/keymap_italian.h
index 0ff6ce876..f62908150 100644
--- a/quantum/keymap_extras/keymap_italian.h
+++ b/quantum/keymap_extras/keymap_italian.h
@@ -20,7 +20,6 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
#define IT_ALGR KC_RALT
// normal characters
diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h
index 6b34db558..4210d3714 100644
--- a/quantum/keymap_extras/keymap_nordic.h
+++ b/quantum/keymap_extras/keymap_nordic.h
@@ -19,7 +19,6 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
#define NO_ALGR KC_RALT
// Normal characters
diff --git a/quantum/keymap_extras/keymap_slovenian.h b/quantum/keymap_extras/keymap_slovenian.h
index f27123c2a..47f5bceed 100644
--- a/quantum/keymap_extras/keymap_slovenian.h
+++ b/quantum/keymap_extras/keymap_slovenian.h
@@ -21,7 +21,6 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
#define SI_ALGR KC_RALT
//Swapped Z and Y
diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h
index 224db7be1..19d12551a 100644
--- a/quantum/keymap_extras/keymap_spanish.h
+++ b/quantum/keymap_extras/keymap_spanish.h
@@ -19,8 +19,7 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
-#define NO_ALGR KC_RALT
+#define ES_ALGR KC_RALT
// Normal characters
#define ES_OVRR KC_GRV
diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h
index de47103cb..a7bcd697e 100644
--- a/quantum/keymap_extras/keymap_uk.h
+++ b/quantum/keymap_extras/keymap_uk.h
@@ -19,8 +19,7 @@
#include "keymap.h"
// Alt gr
-#define ALGR(kc) RALT(kc)
-#define NO_ALGR KC_RALT
+#define UK_ALGR KC_RALT
// Normal characters
#define UK_HASH KC_NUHS
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 41c7d8351..5920e4b13 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -197,6 +197,7 @@ extern uint32_t default_layer_state;
#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT)
#define SS_LSFT(string) SS_DOWN(X_LSHIFT) string SS_UP(X_LSHIFT)
#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT)
+#define SS_ALGR(string) SS_RALT(string)
#define SEND_STRING(str) send_string_P(PSTR(str))
extern const bool ascii_to_shift_lut[0x80];
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 7670d53e9..283b4a65c 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -470,6 +470,7 @@ enum quantum_keycodes {
#define RCTL(kc) (QK_RCTL | (kc))
#define RSFT(kc) (QK_RSFT | (kc))
#define RALT(kc) (QK_RALT | (kc))
+#define ALGR(kc) RALT(kc)
#define RGUI(kc) (QK_RGUI | (kc))
#define RCMD(kc) RGUI(kc)
#define RWIN(kc) RGUI(kc)
@@ -480,7 +481,7 @@ enum quantum_keycodes {
#define SGUI(kc) (QK_LGUI | QK_LSFT | (kc))
#define SCMD(kc) SGUI(kc)
#define SWIN(kc) SGUI(kc)
-#define LCA(kc) (QK_LCTL | QK_LALT | (kc))
+#define LCA(kc) (QK_LCTL | QK_LALT | (kc))
#define MOD_HYPR 0xf
#define MOD_MEH 0x7
@@ -645,7 +646,7 @@ enum quantum_keycodes {
#define ALT_T(kc) MT(MOD_LALT, kc)
#define LALT_T(kc) MT(MOD_LALT, kc)
#define RALT_T(kc) MT(MOD_RALT, kc)
-#define ALGR_T(kc) MT(MOD_RALT, kc) // dual-function AltGR
+#define ALGR_T(kc) RALT_T(kc)
#define GUI_T(kc) MT(MOD_LGUI, kc)
#define CMD_T(kc) GUI_T(kc)
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index d6fef2beb..ac3edbd21 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -140,6 +140,7 @@ along with this program. If not, see .
#define KC_LWIN KC_LGUI
#define KC_RCTL KC_RCTRL
#define KC_RSFT KC_RSHIFT
+#define KC_ALGR KC_RALT
#define KC_RCMD KC_RGUI
#define KC_RWIN KC_RGUI
--
cgit v1.2.3-70-g09d2
From 02d44beb4410b806cb8c38e272941d212fee8a74 Mon Sep 17 00:00:00 2001
From: Drashna Jaelre
Date: Fri, 14 Dec 2018 09:01:58 -0800
Subject: Fix up tap_code functionality (#4609)
* Add delay in Tap Code to avoid issues
I think a few people have reporting issues with it working properly, and it may be a timing issue. The 'register_code' uses this sort of delay in some of the functions, and
this is probably why.
Adding the 100ms delay should hopefully fix any issues with it.
* Make tap_code delay configurable
* Update documentation
* Bring tap_code16 inline with changes
* Fix type for tap_code16
Bad copy-paste job
* Just use the value check for the define
* Clarify timing in docs
Co-Authored-By: drashna
* Wordsmithing
Co-Authored-By: drashna
---
docs/config_options.md | 2 ++
docs/feature_macros.md | 2 ++
quantum/quantum.c | 8 ++++++++
quantum/quantum.h | 2 +-
tmk_core/common/action.c | 12 ++++++++++++
tmk_core/common/action.h | 2 +-
6 files changed, 26 insertions(+), 2 deletions(-)
(limited to 'tmk_core/common')
diff --git a/docs/config_options.md b/docs/config_options.md
index b811fa877..69fecc8b4 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -160,6 +160,8 @@ If you define these options you will enable the associated feature, which may in
* Set this to the number of combos that you're using in the [Combo](feature_combo.md) feature.
* `#define COMBO_TERM 200`
* how long for the Combo keys to be detected. Defaults to `TAPPING_TERM` if not defined.
+* `#define TAP_CODE_DELAY 100`
+ * Sets the delay between `register_code` and `unregister_code`, if you're having issues with it registering properly (common on VUSB boards). The value is in milliseconds.
## RGB Light Configuration
diff --git a/docs/feature_macros.md b/docs/feature_macros.md
index 29ba29fef..aa13fb97f 100644
--- a/docs/feature_macros.md
+++ b/docs/feature_macros.md
@@ -250,6 +250,8 @@ Parallel to `register_code` function, this sends the `` keyup event to the c
This will send `register_code()` and then `unregister_code()`. This is useful if you want to send both the press and release events ("tap" the key, rather than hold it).
+If you're having issues with taps (un)registering, you can add a delay between the register and unregister events by setting `#define TAP_CODE_DELAY 100` in your `config.h` file. The value is in milliseconds.
+
### `clear_keyboard();`
This will clear all mods and keys currently pressed.
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 69692233e..a57d4f89f 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -132,6 +132,14 @@ void unregister_code16 (uint16_t code) {
}
}
+void tap_code16(uint16_t code) {
+ register_code16(code);
+ #if TAP_CODE_DELAY > 0
+ wait_ms(TAP_CODE_DELAY);
+ #endif
+ unregister_code16(code);
+}
+
__attribute__ ((weak))
bool process_action_kb(keyrecord_t *record) {
return true;
diff --git a/quantum/quantum.h b/quantum/quantum.h
index 5920e4b13..0faf1af29 100644
--- a/quantum/quantum.h
+++ b/quantum/quantum.h
@@ -243,7 +243,7 @@ void shutdown_user(void);
void register_code16(uint16_t code);
void unregister_code16(uint16_t code);
-inline void tap_code16(uint16_t code) { register_code16(code); unregister_code16(code); }
+void tap_code16(uint16_t code);
#ifdef BACKLIGHT_ENABLE
void backlight_init_ports(void);
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 8bdcd54e3..456d1e25f 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -847,6 +847,18 @@ void unregister_code(uint8_t code)
#endif
}
+/** \brief Utilities for actions. (FIXME: Needs better description)
+ *
+ * FIXME: Needs documentation.
+ */
+void tap_code(uint8_t code) {
+ register_code(code);
+ #if TAP_CODE_DELAY > 0
+ wait_ms(TAP_CODE_DELAY);
+ #endif
+ unregister_code(code);
+}
+
/** \brief Utilities for actions. (FIXME: Needs better description)
*
* FIXME: Needs documentation.
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 833febe9c..5d797fd62 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -88,7 +88,7 @@ void process_record(keyrecord_t *record);
void process_action(keyrecord_t *record, action_t action);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
-inline void tap_code(uint8_t code) { register_code(code); unregister_code(code); }
+void tap_code(uint8_t code);
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
--
cgit v1.2.3-70-g09d2
From 8f790948e5f7ed62b2c56e1a6aa63dae89d5c860 Mon Sep 17 00:00:00 2001
From: Takeshi ISHII <2170248+mtei@users.noreply.github.com>
Date: Sat, 15 Dec 2018 14:31:56 +0900
Subject: Refactor quantum/split_common/i2c.c, quantum/split_common/serial.c
(#4522)
* add temporary compile test shell script
* Extended support of SKIP_VERSION to make invariant compile results during testing.
* build_keyboard.mk, tmk_core/rules.mk: add LIB_SRC, QUANTUM_LIB_SRC support
Support compiled object enclosed in library.
e.g.
```
LIB_SRC += xxxx.c
xxxx.c --> xxxx.o ---> xxxx.a
```
* remove 'ifdef/ifndef USE_I2C' from quantum/split_common/{i2c|serial}.c
* add SKIP_DEBUG_INFO into tmk_core/rules.mk
When SKIP_DEBUG_INFO=yes is specified, do not use the -g option at compile time.
* tmk_core/rules.mk: Library object need -fno-lto
* add SKIP_DEBUG_INFO=yes
* remove temporary compile test shell script
* add '#define SOFT_SERIAL_PIN D0' to keyboards/lets_split/rev?/config.h
* quantum/split_common/serial.c: Changed not to use USE_I2C.
---
build_keyboard.mk | 6 ++++++
common_features.mk | 6 +++---
keyboards/lets_split/rev1/config.h | 3 +++
keyboards/lets_split/rev2/config.h | 3 +++
keyboards/lets_split/sockets/config.h | 3 +++
quantum/split_common/i2c.c | 3 ---
quantum/split_common/serial.c | 16 ++++++----------
tmk_core/common/command.c | 4 ++++
tmk_core/rules.mk | 36 +++++++++++++++++++++++++++--------
9 files changed, 56 insertions(+), 24 deletions(-)
(limited to 'tmk_core/common')
diff --git a/build_keyboard.mk b/build_keyboard.mk
index d225fe821..b639b92d3 100644
--- a/build_keyboard.mk
+++ b/build_keyboard.mk
@@ -34,6 +34,10 @@ $(error MASTER does not have a valid value(left/right))
endif
endif
+ifdef SKIP_VERSION
+ OPT_DEFS += -DSKIP_VERSION
+endif
+
# Determine which subfolders exist.
KEYBOARD_FOLDER_PATH_1 := $(KEYBOARD)
KEYBOARD_FOLDER_PATH_2 := $(patsubst %/,%,$(dir $(KEYBOARD_FOLDER_PATH_1)))
@@ -278,6 +282,7 @@ ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
endif
# # project specific files
+SRC += $(patsubst %.c,%.clib,$(LIB_SRC))
SRC += $(KEYBOARD_SRC) \
$(KEYMAP_C) \
$(QUANTUM_SRC)
@@ -296,6 +301,7 @@ include $(TMK_PATH)/protocol.mk
include $(TMK_PATH)/common.mk
include bootloader.mk
+SRC += $(patsubst %.c,%.clib,$(QUANTUM_LIB_SRC))
SRC += $(TMK_COMMON_SRC)
OPT_DEFS += $(TMK_COMMON_DEFS)
EXTRALDFLAGS += $(TMK_COMMON_LDFLAGS)
diff --git a/common_features.mk b/common_features.mk
index 97febe2e7..73aab5d84 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -270,7 +270,7 @@ ifeq ($(strip $(SPLIT_KEYBOARD)), yes)
endif
OPT_DEFS += -DSPLIT_KEYBOARD
QUANTUM_SRC += $(QUANTUM_DIR)/split_common/split_flags.c \
- $(QUANTUM_DIR)/split_common/split_util.c \
- $(QUANTUM_DIR)/split_common/i2c.c \
- $(QUANTUM_DIR)/split_common/serial.c
+ $(QUANTUM_DIR)/split_common/split_util.c
+ QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/i2c.c
+ QUANTUM_LIB_SRC += $(QUANTUM_DIR)/split_common/serial.c
endif
diff --git a/keyboards/lets_split/rev1/config.h b/keyboards/lets_split/rev1/config.h
index a8d614915..18b7cce5a 100644
--- a/keyboards/lets_split/rev1/config.h
+++ b/keyboards/lets_split/rev1/config.h
@@ -45,6 +45,9 @@ along with this program. If not, see .
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
+/* serial.c configuration for split keyboard */
+#define SOFT_SERIAL_PIN D0
+
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
diff --git a/keyboards/lets_split/rev2/config.h b/keyboards/lets_split/rev2/config.h
index 8844e5bb8..1c0871cd1 100644
--- a/keyboards/lets_split/rev2/config.h
+++ b/keyboards/lets_split/rev2/config.h
@@ -45,6 +45,9 @@ along with this program. If not, see .
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
+/* serial.c configuration for split keyboard */
+#define SOFT_SERIAL_PIN D0
+
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
diff --git a/keyboards/lets_split/sockets/config.h b/keyboards/lets_split/sockets/config.h
index 10d0c997e..6939d37dc 100644
--- a/keyboards/lets_split/sockets/config.h
+++ b/keyboards/lets_split/sockets/config.h
@@ -45,6 +45,9 @@ along with this program. If not, see .
/* Set 0 if debouncing isn't needed */
#define DEBOUNCING_DELAY 5
+/* serial.c configuration for split keyboard */
+#define SOFT_SERIAL_PIN D0
+
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
#define LOCKING_SUPPORT_ENABLE
/* Locking resynchronize hack */
diff --git a/quantum/split_common/i2c.c b/quantum/split_common/i2c.c
index b3d7fcc68..45e958b39 100644
--- a/quantum/split_common/i2c.c
+++ b/quantum/split_common/i2c.c
@@ -7,8 +7,6 @@
#include "i2c.h"
#include "split_flags.h"
-#if defined(USE_I2C) || defined(EH)
-
// Limits the amount of we wait for any one i2c transaction.
// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
// 9 bits, a single transaction will take around 90μs to complete.
@@ -184,4 +182,3 @@ ISR(TWI_vect) {
// Reset everything, so we are ready for the next TWI interrupt
TWCR |= (1<
#include "serial.h"
-#ifndef USE_I2C
-
-#ifndef SOFT_SERIAL_PIN
- #error quantum/split_common/serial.c need SOFT_SERIAL_PIN define
-#endif
+#ifdef SOFT_SERIAL_PIN
#ifdef __AVR_ATmega32U4__
// if using ATmega32U4 I2C, can not use PD0 and PD1 in soft serial.
- #ifdef USE_I2C
- #if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
- #error Using ATmega32U4 I2C, so can not use PD0, PD1
- #endif
+ #ifdef USE_AVR_I2C
+ #if SOFT_SERIAL_PIN == D0 || SOFT_SERIAL_PIN == D1
+ #error Using ATmega32U4 I2C, so can not use PD0, PD1
+ #endif
#endif
#if SOFT_SERIAL_PIN >= D0 && SOFT_SERIAL_PIN <= D3
@@ -278,4 +274,4 @@ int serial_update_buffers(void) {
return 0;
}
-#endif
+#endif /* SOFT_SERIAL_PIN */
diff --git a/tmk_core/common/command.c b/tmk_core/common/command.c
index f79d5a257..aab99290d 100644
--- a/tmk_core/common/command.c
+++ b/tmk_core/common/command.c
@@ -181,7 +181,11 @@ static void print_version(void)
print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
"VER: " STR(DEVICE_VER) "\n");
+#ifdef SKIP_VERSION
+ print("BUILD: (" __DATE__ ")\n");
+#else
print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n");
+#endif
/* build options */
print("OPTIONS:"
diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk
index ce3cd83b3..2e419dd66 100644
--- a/tmk_core/rules.mk
+++ b/tmk_core/rules.mk
@@ -28,12 +28,13 @@ VPATH :=
# Convert all SRC to OBJ
define OBJ_FROM_SRC
-$(patsubst %.c,$1/%.o,$(patsubst %.cpp,$1/%.o,$(patsubst %.cc,$1/%.o,$(patsubst %.S,$1/%.o,$($1_SRC)))))
+$(patsubst %.c,$1/%.o,$(patsubst %.cpp,$1/%.o,$(patsubst %.cc,$1/%.o,$(patsubst %.S,$1/%.o,$(patsubst %.clib,$1/%.a,$($1_SRC))))))
endef
$(foreach OUTPUT,$(OUTPUTS),$(eval $(OUTPUT)_OBJ +=$(call OBJ_FROM_SRC,$(OUTPUT))))
# Define a list of all objects
OBJ := $(foreach OUTPUT,$(OUTPUTS),$($(OUTPUT)_OBJ))
+NO_LTO_OBJ := $(filter %.a,$(OBJ))
MASTER_OUTPUT := $(firstword $(OUTPUTS))
@@ -81,7 +82,9 @@ CSTANDARD = -std=gnu99
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
-CFLAGS += -g$(DEBUG)
+ifndef SKIP_DEBUG_INFO
+ CFLAGS += -g$(DEBUG)
+endif
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
# add color
@@ -110,7 +113,9 @@ CFLAGS += $(CSTANDARD)
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler.
# -adhlns...: create assembler listing
-CPPFLAGS += -g$(DEBUG)
+ifndef SKIP_DEBUG_INFO
+ CPPFLAGS += -g$(DEBUG)
+endif
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
# to supress "warning: only initialized variables can be placed into program memory area"
@@ -138,7 +143,11 @@ CPPFLAGS += -Wa,-adhlns=$(@:%.o=%.lst)
# -listing-cont-lines: Sets the maximum number of continuation lines of hex
# dump that will be displayed for a given single line of source input.
ASFLAGS += $(ADEFS)
-ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100
+ifndef SKIP_DEBUG_INFO
+ ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100
+else
+ ASFLAGS += -Wa,-adhlns=$(@:%.o=%.lst),--listing-cont-lines=100
+endif
#---------------- Library Options ----------------
# Minimalistic printf version
@@ -210,6 +219,11 @@ ALL_CFLAGS = $(MCUFLAGS) $(CFLAGS) $(EXTRAFLAGS)
ALL_CPPFLAGS = $(MCUFLAGS) -x c++ $(CPPFLAGS) $(EXTRAFLAGS)
ALL_ASFLAGS = $(MCUFLAGS) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS)
+define NO_LTO
+$(patsubst %.a,%.o,$1): NOLTO_CFLAGS += -fno-lto
+endef
+$(foreach LOBJ, $(NO_LTO_OBJ), $(eval $(call NO_LTO,$(LOBJ))))
+
MOVE_DEP = mv -f $(patsubst %.o,%.td,$@) $(patsubst %.o,%.d,$@)
@@ -290,8 +304,8 @@ $1_INCFLAGS := $$(patsubst %,-I%,$$($1_INC))
ifdef $1_CONFIG
$1_CONFIG_FLAGS += $$(patsubst %,-include %,$$($1_CONFIG))
endif
-$1_CFLAGS = $$(ALL_CFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS)
-$1_CPPFLAGS= $$(ALL_CPPFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS)
+$1_CFLAGS = $$(ALL_CFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS)
+$1_CPPFLAGS= $$(ALL_CPPFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS) $$(NOLTO_CFLAGS)
$1_ASFLAGS= $$(ALL_ASFLAGS) $$($1_DEFS) $$($1_INCFLAGS) $$($1_CONFIG_FLAGS)
# Compile: create object files from C source files.
@@ -321,6 +335,12 @@ $1/%.o : %.S $1/asflags.txt $1/compiler.txt | $(BEGIN)
$$(eval CMD=$$(CC) -c $$($1_ASFLAGS) $$< -o $$@)
@$$(BUILD_CMD)
+$1/%.a : $1/%.o
+ @mkdir -p $$(@D)
+ @$(SILENT) || printf "Archiving: $$<" | $$(AWK_CMD)
+ $$(eval CMD=$$(AR) $$@ $$<)
+ @$$(BUILD_CMD)
+
$1/force:
$1/cflags.txt: $1/force
@@ -346,7 +366,7 @@ $(MASTER_OUTPUT)/ldflags.txt: $(MASTER_OUTPUT)/force
# We have to use static rules for the .d files for some reason
-DEPS = $(patsubst %.o,%.d,$(OBJ))
+DEPS = $(patsubst %.o,%.d,$(patsubst %.a,%.o,$(OBJ)))
# Keep the .d files
.PRECIOUS: $(DEPS)
# Empty rule to force recompilation if the .d file is missing
@@ -391,7 +411,7 @@ $(shell mkdir -p $(BUILD_DIR) 2>/dev/null)
$(eval $(foreach OUTPUT,$(OUTPUTS),$(shell mkdir -p $(OUTPUT) 2>/dev/null)))
# Include the dependency files.
--include $(patsubst %.o,%.d,$(OBJ))
+-include $(patsubst %.o,%.d,$(patsubst %.a,%.o,$(OBJ)))
# Listing of phony targets.
--
cgit v1.2.3-70-g09d2
From 93b004c943a4b13bd640fc83000e910b72cb4640 Mon Sep 17 00:00:00 2001
From: Konstantin Đorđević
Date: Fri, 28 Dec 2018 20:07:56 +0100
Subject: Keep pressed keys on layer state change (fixes #2053, #2279) (#3905)
* Keep pressed keys on layer state change
* Add doc comment for clear_keyboard_but_mods_and_keys
* Keep pressed keys only if PREVENT_STUCK_MODIFIERS is on
* Check STRICT_LAYER_RELEASE instead of PREVENT_STUCK_MODIFIERS
---
tmk_core/common/action.c | 11 ++++++++++-
tmk_core/common/action.h | 1 +
tmk_core/common/action_layer.c | 8 ++++++++
3 files changed, 19 insertions(+), 1 deletion(-)
(limited to 'tmk_core/common')
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 456d1e25f..b99c2acaa 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -898,10 +898,19 @@ void clear_keyboard(void)
* FIXME: Needs documentation.
*/
void clear_keyboard_but_mods(void)
+{
+ clear_keys();
+ clear_keyboard_but_mods_and_keys();
+}
+
+/** \brief Utilities for actions. (FIXME: Needs better description)
+ *
+ * FIXME: Needs documentation.
+ */
+void clear_keyboard_but_mods_and_keys()
{
clear_weak_mods();
clear_macro_mods();
- clear_keys();
send_keyboard_report();
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index 5d797fd62..8e47e5339 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -94,6 +94,7 @@ void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
+void clear_keyboard_but_mods_and_keys(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(keypos_t key);
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index b8dcb34f3..120ce3f51 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -44,7 +44,11 @@ static void default_layer_state_set(uint32_t state)
default_layer_debug(); debug(" to ");
default_layer_state = state;
default_layer_debug(); debug("\n");
+#ifdef STRICT_LAYER_RELEASE
clear_keyboard_but_mods(); // To avoid stuck keys
+#else
+ clear_keyboard_but_mods_and_keys(); // Don't reset held keys
+#endif
}
/** \brief Default Layer Print
@@ -127,7 +131,11 @@ void layer_state_set(uint32_t state)
layer_debug(); dprint(" to ");
layer_state = state;
layer_debug(); dprintln();
+#ifdef STRICT_LAYER_RELEASE
clear_keyboard_but_mods(); // To avoid stuck keys
+#else
+ clear_keyboard_but_mods_and_keys(); // Don't reset held keys
+#endif
}
/** \brief Layer clear
--
cgit v1.2.3-70-g09d2