aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/arm_atsam/eeprom.c94
-rw-r--r--tmk_core/common/arm_atsam/gpio.h8
-rw-r--r--tmk_core/common/avr/suspend.c98
-rw-r--r--tmk_core/common/chibios/_wait.h2
-rw-r--r--tmk_core/common/chibios/bootloader.c22
-rw-r--r--tmk_core/common/chibios/chibios_config.h62
-rw-r--r--tmk_core/common/chibios/eeprom_stm32.c57
-rw-r--r--tmk_core/common/chibios/eeprom_stm32_defs.h25
-rw-r--r--tmk_core/common/chibios/eeprom_teensy.c213
-rw-r--r--tmk_core/common/chibios/flash_stm32.c48
-rw-r--r--tmk_core/common/chibios/gd32v_compatibility.h120
-rw-r--r--tmk_core/common/chibios/suspend.c89
-rw-r--r--tmk_core/common/chibios/syscall-fallbacks.c6
-rw-r--r--tmk_core/common/host.c127
-rw-r--r--tmk_core/common/host.h56
-rw-r--r--tmk_core/common/host_driver.h34
-rw-r--r--tmk_core/common/raw_hid.h5
-rw-r--r--tmk_core/common/report.c280
-rw-r--r--tmk_core/common/report.h319
-rw-r--r--tmk_core/common/suspend.h2
-rw-r--r--tmk_core/common/sync_timer.c58
-rw-r--r--tmk_core/common/sync_timer.h54
-rw-r--r--tmk_core/common/test/rules.mk1
-rw-r--r--tmk_core/common/usb_util.c29
-rw-r--r--tmk_core/common/usb_util.h22
-rw-r--r--tmk_core/common/virtser.h7
26 files changed, 579 insertions, 1259 deletions
diff --git a/tmk_core/common/arm_atsam/eeprom.c b/tmk_core/common/arm_atsam/eeprom.c
index ccd5d15a5..ff1a69262 100644
--- a/tmk_core/common/arm_atsam/eeprom.c
+++ b/tmk_core/common/arm_atsam/eeprom.c
@@ -13,24 +13,110 @@
13 * You should have received a copy of the GNU General Public License 13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */ 15 */
16
17#include "eeprom.h" 16#include "eeprom.h"
17#include "debug.h"
18#include "samd51j18a.h"
19#include "core_cm4.h"
20#include "component/nvmctrl.h"
18 21
19#ifndef EEPROM_SIZE 22#ifndef EEPROM_SIZE
20# include "eeconfig.h" 23# include "eeconfig.h"
21# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO 24# define EEPROM_SIZE (((EECONFIG_SIZE + 3) / 4) * 4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
22#endif 25#endif
23 26
24__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE]; 27#ifndef MAX
28# define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
29#endif
30
31#ifndef BUSY_RETRIES
32# define BUSY_RETRIES 10000
33#endif
34
35// #define DEBUG_EEPROM_OUTPUT
36
37/*
38 * Debug print utils
39 */
40#if defined(DEBUG_EEPROM_OUTPUT)
41# define eeprom_printf(fmt, ...) xprintf(fmt, ##__VA_ARGS__);
42#else /* NO_DEBUG */
43# define eeprom_printf(fmt, ...)
44#endif /* NO_DEBUG */
45
46__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE] = {0};
47volatile uint8_t * SmartEEPROM8 = (uint8_t *)SEEPROM_ADDR;
48
49static inline bool eeprom_is_busy(void) {
50 int timeout = BUSY_RETRIES;
51 while (NVMCTRL->SEESTAT.bit.BUSY && timeout-- > 0)
52 ;
53
54 return NVMCTRL->SEESTAT.bit.BUSY;
55}
56
57static uint32_t get_virtual_eeprom_size(void) {
58 // clang-format off
59 static const uint32_t VIRTUAL_EEPROM_MAP[11][8] = {
60 /* 4 8 16 32 64 128 256 512 */
61 /* 0*/ { 0, 0, 0, 0, 0, 0, 0, 0 },
62 /* 1*/ { 512, 1024, 2048, 4096, 4096, 4096, 4096, 4096 },
63 /* 2*/ { 512, 1024, 2048, 4096, 8192, 8192, 8192, 8192 },
64 /* 3*/ { 512, 1024, 2048, 4096, 8192, 16384, 16384, 16384 },
65 /* 4*/ { 512, 1024, 2048, 4096, 8192, 16384, 16384, 16384 },
66 /* 5*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 },
67 /* 6*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 },
68 /* 7*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 },
69 /* 8*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 32768 },
70 /* 9*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 },
71 /*10*/ { 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536 },
72 };
73 // clang-format on
74
75 static uint32_t virtual_eeprom_size = UINT32_MAX;
76 if (virtual_eeprom_size == UINT32_MAX) {
77 virtual_eeprom_size = VIRTUAL_EEPROM_MAP[NVMCTRL->SEESTAT.bit.PSZ][NVMCTRL->SEESTAT.bit.SBLK];
78 }
79 // eeprom_printf("get_virtual_eeprom_size:: %d:%d:%d\n", NVMCTRL->SEESTAT.bit.PSZ, NVMCTRL->SEESTAT.bit.SBLK, virtual_eeprom_size);
80 return virtual_eeprom_size;
81}
25 82
26uint8_t eeprom_read_byte(const uint8_t *addr) { 83uint8_t eeprom_read_byte(const uint8_t *addr) {
27 uintptr_t offset = (uintptr_t)addr; 84 uintptr_t offset = (uintptr_t)addr;
28 return buffer[offset]; 85 if (offset >= MAX(EEPROM_SIZE, get_virtual_eeprom_size())) {
86 eeprom_printf("eeprom_read_byte:: out of bounds\n");
87 return 0x0;
88 }
89
90 if (get_virtual_eeprom_size() == 0) {
91 return buffer[offset];
92 }
93
94 if (eeprom_is_busy()) {
95 eeprom_printf("eeprom_write_byte:: timeout\n");
96 return 0x0;
97 }
98
99 return SmartEEPROM8[offset];
29} 100}
30 101
31void eeprom_write_byte(uint8_t *addr, uint8_t value) { 102void eeprom_write_byte(uint8_t *addr, uint8_t value) {
32 uintptr_t offset = (uintptr_t)addr; 103 uintptr_t offset = (uintptr_t)addr;
33 buffer[offset] = value; 104 if (offset >= MAX(EEPROM_SIZE, get_virtual_eeprom_size())) {
105 eeprom_printf("eeprom_write_byte:: out of bounds\n");
106 return;
107 }
108
109 if (get_virtual_eeprom_size() == 0) {
110 buffer[offset] = value;
111 return;
112 }
113
114 if (eeprom_is_busy()) {
115 eeprom_printf("eeprom_write_byte:: timeout\n");
116 return;
117 }
118
119 SmartEEPROM8[offset] = value;
34} 120}
35 121
36uint16_t eeprom_read_word(const uint16_t *addr) { 122uint16_t eeprom_read_word(const uint16_t *addr) {
diff --git a/tmk_core/common/arm_atsam/gpio.h b/tmk_core/common/arm_atsam/gpio.h
index c2d5a3088..915ed0ef4 100644
--- a/tmk_core/common/arm_atsam/gpio.h
+++ b/tmk_core/common/arm_atsam/gpio.h
@@ -64,7 +64,13 @@ typedef uint8_t pin_t;
64 PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \ 64 PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
65 } while (0) 65 } while (0)
66 66
67#define writePin(pin, level) ((level) ? (writePinHigh(pin)) : (writePinLow(pin))) 67#define writePin(pin, level) \
68 do { \
69 if (level) \
70 PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \
71 else \
72 PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
73 } while (0)
68 74
69#define readPin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0) 75#define readPin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0)
70 76
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 690d7f38c..b614746e6 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -16,25 +16,6 @@
16# include "vusb.h" 16# include "vusb.h"
17#endif 17#endif
18 18
19#ifdef BACKLIGHT_ENABLE
20# include "backlight.h"
21#endif
22
23#ifdef AUDIO_ENABLE
24# include "audio.h"
25#endif /* AUDIO_ENABLE */
26
27#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
28# include "rgblight.h"
29#endif
30
31#ifdef LED_MATRIX_ENABLE
32# include "led_matrix.h"
33#endif
34#ifdef RGB_MATRIX_ENABLE
35# include "rgb_matrix.h"
36#endif
37
38/** \brief Suspend idle 19/** \brief Suspend idle
39 * 20 *
40 * FIXME: needs doc 21 * FIXME: needs doc
@@ -50,17 +31,6 @@ void suspend_idle(uint8_t time) {
50 31
51// TODO: This needs some cleanup 32// TODO: This needs some cleanup
52 33
53/** \brief Run keyboard level Power down
54 *
55 * FIXME: needs doc
56 */
57__attribute__((weak)) void suspend_power_down_user(void) {}
58/** \brief Run keyboard level Power down
59 *
60 * FIXME: needs doc
61 */
62__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
63
64#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) 34#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)
65 35
66// clang-format off 36// clang-format off
@@ -135,41 +105,9 @@ void suspend_power_down(void) {
135 if (!vusb_suspended) return; 105 if (!vusb_suspended) return;
136#endif 106#endif
137 107
138 suspend_power_down_kb(); 108 suspend_power_down_quantum();
139 109
140#ifndef NO_SUSPEND_POWER_DOWN 110#ifndef NO_SUSPEND_POWER_DOWN
141 // Turn off backlight
142# ifdef BACKLIGHT_ENABLE
143 backlight_set(0);
144# endif
145
146 // Turn off LED indicators
147 uint8_t leds_off = 0;
148# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
149 if (is_backlight_enabled()) {
150 // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
151 leds_off |= (1 << USB_LED_CAPS_LOCK);
152 }
153# endif
154 led_set(leds_off);
155
156 // Turn off audio
157# ifdef AUDIO_ENABLE
158 stop_all_notes();
159# endif
160
161 // Turn off underglow
162# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
163 rgblight_suspend();
164# endif
165
166# if defined(LED_MATRIX_ENABLE)
167 led_matrix_set_suspend_state(true);
168# endif
169# if defined(RGB_MATRIX_ENABLE)
170 rgb_matrix_set_suspend_state(true);
171# endif
172
173 // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt) 111 // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt)
174# if defined(WDT_vect) 112# if defined(WDT_vect)
175 power_down(WDTO_15MS); 113 power_down(WDTO_15MS);
@@ -189,18 +127,6 @@ bool suspend_wakeup_condition(void) {
189 return false; 127 return false;
190} 128}
191 129
192/** \brief run user level code immediately after wakeup
193 *
194 * FIXME: needs doc
195 */
196__attribute__((weak)) void suspend_wakeup_init_user(void) {}
197
198/** \brief run keyboard level code immediately after wakeup
199 *
200 * FIXME: needs doc
201 */
202__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
203
204/** \brief run immediately after wakeup 130/** \brief run immediately after wakeup
205 * 131 *
206 * FIXME: needs doc 132 * FIXME: needs doc
@@ -209,27 +135,7 @@ void suspend_wakeup_init(void) {
209 // clear keyboard state 135 // clear keyboard state
210 clear_keyboard(); 136 clear_keyboard();
211 137
212 // Turn on backlight 138 suspend_wakeup_init_quantum();
213#ifdef BACKLIGHT_ENABLE
214 backlight_init();
215#endif
216
217 // Restore LED indicators
218 led_set(host_keyboard_leds());
219
220 // Wake up underglow
221#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
222 rgblight_wakeup();
223#endif
224
225#if defined(LED_MATRIX_ENABLE)
226 led_matrix_set_suspend_state(false);
227#endif
228#if defined(RGB_MATRIX_ENABLE)
229 rgb_matrix_set_suspend_state(false);
230#endif
231
232 suspend_wakeup_init_kb();
233} 139}
234 140
235#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) 141#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)
diff --git a/tmk_core/common/chibios/_wait.h b/tmk_core/common/chibios/_wait.h
index b740afbd2..2f36c64a2 100644
--- a/tmk_core/common/chibios/_wait.h
+++ b/tmk_core/common/chibios/_wait.h
@@ -43,8 +43,6 @@ void wait_us(uint16_t duration);
43 43
44#include "_wait.c" 44#include "_wait.c"
45 45
46#define CPU_CLOCK STM32_SYSCLK
47
48/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus 46/* For GPIOs on ARM-based MCUs, the input pins are sampled by the clock of the bus
49 * to which the GPIO is connected. 47 * to which the GPIO is connected.
50 * The connected buses differ depending on the various series of MCUs. 48 * The connected buses differ depending on the various series of MCUs.
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c
index f9514ee5f..5cadadeee 100644
--- a/tmk_core/common/chibios/bootloader.c
+++ b/tmk_core/common/chibios/bootloader.c
@@ -95,6 +95,28 @@ void enter_bootloader_mode_if_requested(void) {
95 } 95 }
96} 96}
97 97
98#elif defined(GD32VF103)
99
100# define DBGMCU_KEY_UNLOCK 0x4B5A6978
101# define DBGMCU_CMD_RESET 0x1
102
103__IO uint32_t *DBGMCU_KEY = (uint32_t *)DBGMCU_BASE + 0x0CU;
104__IO uint32_t *DBGMCU_CMD = (uint32_t *)DBGMCU_BASE + 0x08U;
105
106__attribute__((weak)) void bootloader_jump(void) {
107 /* The MTIMER unit of the GD32VF103 doesn't have the MSFRST
108 * register to generate a software reset request.
109 * BUT instead two undocumented registers in the debug peripheral
110 * that allow issueing a software reset. WHO would need the MSFRST
111 * register anyway? Source:
112 * https://github.com/esmil/gd32vf103inator/blob/master/include/gd32vf103/dbg.h */
113 *DBGMCU_KEY = DBGMCU_KEY_UNLOCK;
114 *DBGMCU_CMD = DBGMCU_CMD_RESET;
115}
116
117void enter_bootloader_mode_if_requested(void) { /* Jumping to bootloader is not possible from user code. */
118}
119
98#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS 120#elif defined(KL2x) || defined(K20x) || defined(MK66F18) || defined(MIMXRT1062) // STM32_BOOTLOADER_DUAL_BANK // STM32_BOOTLOADER_ADDRESS
99/* Kinetis */ 121/* Kinetis */
100 122
diff --git a/tmk_core/common/chibios/chibios_config.h b/tmk_core/common/chibios/chibios_config.h
index 23c65f942..ad2f808a9 100644
--- a/tmk_core/common/chibios/chibios_config.h
+++ b/tmk_core/common/chibios/chibios_config.h
@@ -19,22 +19,60 @@
19# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used 19# define SPLIT_USB_DETECT // Force this on when dedicated pin is not used
20#endif 20#endif
21 21
22#if defined(STM32F1XX) 22// STM32 compatibility
23# define USE_GPIOV1 23#if defined(MCU_STM32)
24# define CPU_CLOCK STM32_SYSCLK
25
26# if defined(STM32F1XX)
27# define USE_GPIOV1
28# define PAL_MODE_ALTERNATE_OPENDRAIN PAL_MODE_STM32_ALTERNATE_OPENDRAIN
29# define PAL_MODE_ALTERNATE_PUSHPULL PAL_MODE_STM32_ALTERNATE_PUSHPULL
30# else
31# define PAL_OUTPUT_TYPE_OPENDRAIN PAL_STM32_OTYPE_OPENDRAIN
32# define PAL_OUTPUT_TYPE_PUSHPULL PAL_STM32_OTYPE_PUSHPULL
33# define PAL_OUTPUT_SPEED_HIGHEST PAL_STM32_OSPEED_HIGHEST
34# define PAL_PUPDR_FLOATING PAL_STM32_PUPDR_FLOATING
35# endif
36
37# if defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32L1XX)
38# define USE_I2CV1
39# endif
40#endif
41
42// GD32 compatibility
43#if defined(MCU_GD32V)
44# define CPU_CLOCK GD32_SYSCLK
45
46# if defined(GD32VF103)
47# define USE_GPIOV1
48# define USE_I2CV1
49# define PAL_MODE_ALTERNATE_OPENDRAIN PAL_MODE_GD32_ALTERNATE_OPENDRAIN
50# define PAL_MODE_ALTERNATE_PUSHPULL PAL_MODE_GD32_ALTERNATE_PUSHPULL
51# endif
24#endif 52#endif
25 53
26#if defined(STM32F1XX) || defined(STM32F2XX) || defined(STM32F4XX) || defined(STM32L1XX) 54#if defined(GD32VF103)
27# define USE_I2CV1 55/* This chip has the same API as STM32F103, but uses different names for literally the same thing.
56 * As of 4.7.2021 QMK is tailored to use STM32 defines/names, for compatibility sake
57 * we just redefine the GD32 names. */
58# include "gd32v_compatibility.h"
28#endif 59#endif
29 60
30// teensy 61// teensy compatibility
31#if defined(K20x) || defined(KL2x) 62#if defined(MCU_KINETIS)
32# define USE_I2CV1 63# define CPU_CLOCK KINETIS_SYSCLK_FREQUENCY
33# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed 64
34# define USE_GPIOV1 65# if defined(K20x) || defined(KL2x)
35# define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY 66# define USE_I2CV1
67# define USE_I2CV1_CONTRIB // for some reason a bunch of ChibiOS-Contrib boards only have clock_speed
68# define USE_GPIOV1
69# endif
36#endif 70#endif
37 71
38#if defined(MK66F18) 72#if defined(HT32)
39# define STM32_SYSCLK KINETIS_SYSCLK_FREQUENCY 73# define CPU_CLOCK HT32_CK_SYS_FREQUENCY
74# define PAL_MODE_ALTERNATE PAL_HT32_MODE_AF
75# define PAL_OUTPUT_TYPE_OPENDRAIN (PAL_HT32_MODE_OD | PAL_HT32_MODE_DIR)
76# define PAL_OUTPUT_TYPE_PUSHPULL PAL_HT32_MODE_DIR
77# define PAL_OUTPUT_SPEED_HIGHEST 0
40#endif 78#endif
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
index 1fdf8c1e2..acc6a4851 100644
--- a/tmk_core/common/chibios/eeprom_stm32.c
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -620,48 +620,11 @@ uint16_t EEPROM_ReadDataWord(uint16_t Address) {
620} 620}
621 621
622/***************************************************************************** 622/*****************************************************************************
623 * Wrap library in AVR style functions. 623 * Bind to eeprom_driver.c
624 *******************************************************************************/ 624 *******************************************************************************/
625uint8_t eeprom_read_byte(const uint8_t *Address) { return EEPROM_ReadDataByte((const uintptr_t)Address); } 625void eeprom_driver_init(void) { EEPROM_Init(); }
626 626
627void eeprom_write_byte(uint8_t *Address, uint8_t Value) { EEPROM_WriteDataByte((uintptr_t)Address, Value); } 627void eeprom_driver_erase(void) { EEPROM_Erase(); }
628
629void eeprom_update_byte(uint8_t *Address, uint8_t Value) { EEPROM_WriteDataByte((uintptr_t)Address, Value); }
630
631uint16_t eeprom_read_word(const uint16_t *Address) { return EEPROM_ReadDataWord((const uintptr_t)Address); }
632
633void eeprom_write_word(uint16_t *Address, uint16_t Value) { EEPROM_WriteDataWord((uintptr_t)Address, Value); }
634
635void eeprom_update_word(uint16_t *Address, uint16_t Value) { EEPROM_WriteDataWord((uintptr_t)Address, Value); }
636
637uint32_t eeprom_read_dword(const uint32_t *Address) {
638 const uint16_t p = (const uintptr_t)Address;
639 /* Check word alignment */
640 if (p % 2) {
641 /* Not aligned */
642 return (uint32_t)EEPROM_ReadDataByte(p) | (uint32_t)(EEPROM_ReadDataWord(p + 1) << 8) | (uint32_t)(EEPROM_ReadDataByte(p + 3) << 24);
643 } else {
644 /* Aligned */
645 return EEPROM_ReadDataWord(p) | (EEPROM_ReadDataWord(p + 2) << 16);
646 }
647}
648
649void eeprom_write_dword(uint32_t *Address, uint32_t Value) {
650 uint16_t p = (const uintptr_t)Address;
651 /* Check word alignment */
652 if (p % 2) {
653 /* Not aligned */
654 EEPROM_WriteDataByte(p, (uint8_t)Value);
655 EEPROM_WriteDataWord(p + 1, (uint16_t)(Value >> 8));
656 EEPROM_WriteDataByte(p + 3, (uint8_t)(Value >> 24));
657 } else {
658 /* Aligned */
659 EEPROM_WriteDataWord(p, (uint16_t)Value);
660 EEPROM_WriteDataWord(p + 2, (uint16_t)(Value >> 16));
661 }
662}
663
664void eeprom_update_dword(uint32_t *Address, uint32_t Value) { eeprom_write_dword(Address, Value); }
665 628
666void eeprom_read_block(void *buf, const void *addr, size_t len) { 629void eeprom_read_block(void *buf, const void *addr, size_t len) {
667 const uint8_t *src = (const uint8_t *)addr; 630 const uint8_t *src = (const uint8_t *)addr;
@@ -670,14 +633,14 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) {
670 /* Check word alignment */ 633 /* Check word alignment */
671 if (len && (uintptr_t)src % 2) { 634 if (len && (uintptr_t)src % 2) {
672 /* Read the unaligned first byte */ 635 /* Read the unaligned first byte */
673 *dest++ = eeprom_read_byte(src++); 636 *dest++ = EEPROM_ReadDataByte((const uintptr_t)src++);
674 --len; 637 --len;
675 } 638 }
676 639
677 uint16_t value; 640 uint16_t value;
678 bool aligned = ((uintptr_t)dest % 2 == 0); 641 bool aligned = ((uintptr_t)dest % 2 == 0);
679 while (len > 1) { 642 while (len > 1) {
680 value = eeprom_read_word((uint16_t *)src); 643 value = EEPROM_ReadDataWord((const uintptr_t)((uint16_t *)src));
681 if (aligned) { 644 if (aligned) {
682 *(uint16_t *)dest = value; 645 *(uint16_t *)dest = value;
683 dest += 2; 646 dest += 2;
@@ -689,7 +652,7 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) {
689 len -= 2; 652 len -= 2;
690 } 653 }
691 if (len) { 654 if (len) {
692 *dest = eeprom_read_byte(src); 655 *dest = EEPROM_ReadDataByte((const uintptr_t)src);
693 } 656 }
694} 657}
695 658
@@ -700,7 +663,7 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
700 /* Check word alignment */ 663 /* Check word alignment */
701 if (len && (uintptr_t)dest % 2) { 664 if (len && (uintptr_t)dest % 2) {
702 /* Write the unaligned first byte */ 665 /* Write the unaligned first byte */
703 eeprom_write_byte(dest++, *src++); 666 EEPROM_WriteDataByte((uintptr_t)dest++, *src++);
704 --len; 667 --len;
705 } 668 }
706 669
@@ -712,15 +675,13 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
712 } else { 675 } else {
713 value = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8); 676 value = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8);
714 } 677 }
715 eeprom_write_word((uint16_t *)dest, value); 678 EEPROM_WriteDataWord((uintptr_t)((uint16_t *)dest), value);
716 dest += 2; 679 dest += 2;
717 src += 2; 680 src += 2;
718 len -= 2; 681 len -= 2;
719 } 682 }
720 683
721 if (len) { 684 if (len) {
722 eeprom_write_byte(dest, *src); 685 EEPROM_WriteDataByte((uintptr_t)dest, *src);
723 } 686 }
724} 687}
725
726void eeprom_update_block(const void *buf, void *addr, size_t len) { eeprom_write_block(buf, addr, len); }
diff --git a/tmk_core/common/chibios/eeprom_stm32_defs.h b/tmk_core/common/chibios/eeprom_stm32_defs.h
index 22b4ab858..66904f247 100644
--- a/tmk_core/common/chibios/eeprom_stm32_defs.h
+++ b/tmk_core/common/chibios/eeprom_stm32_defs.h
@@ -18,7 +18,7 @@
18#include <hal.h> 18#include <hal.h>
19 19
20#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) 20#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT)
21# if defined(STM32F103xB) || defined(STM32F042x6) 21# if defined(STM32F103xB) || defined(STM32F042x6) || defined(GD32VF103C8) || defined(GD32VF103CB)
22# ifndef FEE_PAGE_SIZE 22# ifndef FEE_PAGE_SIZE
23# define FEE_PAGE_SIZE 0x400 // Page size = 1KByte 23# define FEE_PAGE_SIZE 0x400 // Page size = 1KByte
24# endif 24# endif
@@ -32,25 +32,38 @@
32# ifndef FEE_PAGE_COUNT 32# ifndef FEE_PAGE_COUNT
33# define FEE_PAGE_COUNT 4 // How many pages are used 33# define FEE_PAGE_COUNT 4 // How many pages are used
34# endif 34# endif
35# elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE)
36# ifndef FEE_PAGE_SIZE
37# define FEE_PAGE_SIZE 0x4000 // Page size = 16KByte
38# endif
39# ifndef FEE_PAGE_COUNT
40# define FEE_PAGE_COUNT 1 // How many pages are used
41# endif
35# endif 42# endif
36#endif 43#endif
37 44
38#if !defined(FEE_MCU_FLASH_SIZE) 45#if !defined(FEE_MCU_FLASH_SIZE)
39# if defined(STM32F042x6) 46# if defined(STM32F042x6)
40# define FEE_MCU_FLASH_SIZE 32 // Size in Kb 47# define FEE_MCU_FLASH_SIZE 32 // Size in Kb
41# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) 48# elif defined(GD32VF103C8)
49# define FEE_MCU_FLASH_SIZE 64 // Size in Kb
50# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) || defined(GD32VF103CB)
42# define FEE_MCU_FLASH_SIZE 128 // Size in Kb 51# define FEE_MCU_FLASH_SIZE 128 // Size in Kb
43# elif defined(STM32F303xC) 52# elif defined(STM32F303xC) || defined(STM32F401xC)
44# define FEE_MCU_FLASH_SIZE 256 // Size in Kb 53# define FEE_MCU_FLASH_SIZE 256 // Size in Kb
45# elif defined(STM32F103xE) 54# elif defined(STM32F103xE) || defined(STM32F401xE) || defined(STM32F411xE)
46# define FEE_MCU_FLASH_SIZE 512 // Size in Kb 55# define FEE_MCU_FLASH_SIZE 512 // Size in Kb
56# elif defined(STM32F405xG)
57# define FEE_MCU_FLASH_SIZE 1024 // Size in Kb
47# endif 58# endif
48#endif 59#endif
49 60
50/* Start of the emulated eeprom */ 61/* Start of the emulated eeprom */
51#if !defined(FEE_PAGE_BASE_ADDRESS) 62#if !defined(FEE_PAGE_BASE_ADDRESS)
52# if 0 63# if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xG) || defined(STM32F411xE)
53/* TODO: Add support for F4 */ 64# ifndef FEE_PAGE_BASE_ADDRESS
65# define FEE_PAGE_BASE_ADDRESS 0x08004000 // bodge to force 2nd 16k page
66# endif
54# else 67# else
55# ifndef FEE_FLASH_BASE 68# ifndef FEE_FLASH_BASE
56# define FEE_FLASH_BASE 0x8000000 69# define FEE_FLASH_BASE 0x8000000
diff --git a/tmk_core/common/chibios/eeprom_teensy.c b/tmk_core/common/chibios/eeprom_teensy.c
index 4aaf66526..97da6f9e1 100644
--- a/tmk_core/common/chibios/eeprom_teensy.c
+++ b/tmk_core/common/chibios/eeprom_teensy.c
@@ -39,7 +39,126 @@
39 * SOFTWARE. 39 * SOFTWARE.
40 */ 40 */
41 41
42#if defined(K20x) /* chip selection */ 42#define SMC_PMSTAT_RUN ((uint8_t)0x01)
43#define SMC_PMSTAT_HSRUN ((uint8_t)0x80)
44
45#define F_CPU KINETIS_SYSCLK_FREQUENCY
46
47static inline int kinetis_hsrun_disable(void) {
48#if defined(MK66F18)
49 if (SMC->PMSTAT == SMC_PMSTAT_HSRUN) {
50// First, reduce the CPU clock speed, but do not change
51// the peripheral speed (F_BUS). Serial1 & Serial2 baud
52// rates will be impacted, but most other peripherals
53// will continue functioning at the same speed.
54# if F_CPU == 256000000 && F_BUS == 64000000
55 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // TODO: TEST
56# elif F_CPU == 256000000 && F_BUS == 128000000
57 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // TODO: TEST
58# elif F_CPU == 240000000 && F_BUS == 60000000
59 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // ok
60# elif F_CPU == 240000000 && F_BUS == 80000000
61 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok
62# elif F_CPU == 240000000 && F_BUS == 120000000
63 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok
64# elif F_CPU == 216000000 && F_BUS == 54000000
65 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // ok
66# elif F_CPU == 216000000 && F_BUS == 72000000
67 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok
68# elif F_CPU == 216000000 && F_BUS == 108000000
69 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok
70# elif F_CPU == 192000000 && F_BUS == 48000000
71 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 3, 1, 7); // ok
72# elif F_CPU == 192000000 && F_BUS == 64000000
73 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok
74# elif F_CPU == 192000000 && F_BUS == 96000000
75 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok
76# elif F_CPU == 180000000 && F_BUS == 60000000
77 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 8); // ok
78# elif F_CPU == 180000000 && F_BUS == 90000000
79 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 7); // ok
80# elif F_CPU == 168000000 && F_BUS == 56000000
81 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 5); // ok
82# elif F_CPU == 144000000 && F_BUS == 48000000
83 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(2, 2, 2, 5); // ok
84# elif F_CPU == 144000000 && F_BUS == 72000000
85 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(1, 1, 1, 5); // ok
86# elif F_CPU == 120000000 && F_BUS == 60000000
87 SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1 - 1) | SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2 - 1) |
88# if defined(MK66F18)
89 SIM_CLKDIV1_OUTDIV3(KINETIS_CLKDIV1_OUTDIV3 - 1) |
90# endif
91 SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4 - 1);
92# else
93 return 0;
94# endif
95 // Then turn off HSRUN mode
96 SMC->PMCTRL = SMC_PMCTRL_RUNM_SET(0);
97 while (SMC->PMSTAT == SMC_PMSTAT_HSRUN)
98 ; // wait
99 return 1;
100 }
101#endif
102 return 0;
103}
104
105static inline int kinetis_hsrun_enable(void) {
106#if defined(MK66F18)
107 if (SMC->PMSTAT == SMC_PMSTAT_RUN) {
108 // Turn HSRUN mode on
109 SMC->PMCTRL = SMC_PMCTRL_RUNM_SET(3);
110 while (SMC->PMSTAT != SMC_PMSTAT_HSRUN) {
111 ;
112 } // wait
113// Then configure clock for full speed
114# if F_CPU == 256000000 && F_BUS == 64000000
115 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 7);
116# elif F_CPU == 256000000 && F_BUS == 128000000
117 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 7);
118# elif F_CPU == 240000000 && F_BUS == 60000000
119 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 7);
120# elif F_CPU == 240000000 && F_BUS == 80000000
121 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 7);
122# elif F_CPU == 240000000 && F_BUS == 120000000
123 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 7);
124# elif F_CPU == 216000000 && F_BUS == 54000000
125 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 7);
126# elif F_CPU == 216000000 && F_BUS == 72000000
127 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 7);
128# elif F_CPU == 216000000 && F_BUS == 108000000
129 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 7);
130# elif F_CPU == 192000000 && F_BUS == 48000000
131 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 3, 0, 6);
132# elif F_CPU == 192000000 && F_BUS == 64000000
133 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 6);
134# elif F_CPU == 192000000 && F_BUS == 96000000
135 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 6);
136# elif F_CPU == 180000000 && F_BUS == 60000000
137 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 6);
138# elif F_CPU == 180000000 && F_BUS == 90000000
139 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 6);
140# elif F_CPU == 168000000 && F_BUS == 56000000
141 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 5);
142# elif F_CPU == 144000000 && F_BUS == 48000000
143 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 2, 0, 4);
144# elif F_CPU == 144000000 && F_BUS == 72000000
145 SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIVS(0, 1, 0, 4);
146# elif F_CPU == 120000000 && F_BUS == 60000000
147 SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1 - 1) | SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2 - 1) |
148# if defined(MK66F18)
149 SIM_CLKDIV1_OUTDIV3(KINETIS_CLKDIV1_OUTDIV3 - 1) |
150# endif
151 SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4 - 1);
152# else
153 return 0;
154# endif
155 return 1;
156 }
157#endif
158 return 0;
159}
160
161#if defined(K20x) || defined(MK66F18) /* chip selection */
43/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ 162/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */
44 163
45// The EEPROM is really RAM with a hardware-based backup system to 164// The EEPROM is really RAM with a hardware-based backup system to
@@ -69,22 +188,34 @@
69// 188//
70# define HANDLE_UNALIGNED_WRITES 189# define HANDLE_UNALIGNED_WRITES
71 190
191# if defined(K20x)
192# define EEPROM_MAX 2048
193# define EEPARTITION 0x03 // all 32K dataflash for EEPROM, none for Data
194# define EEESPLIT 0x30 // must be 0x30 on these chips
195# elif defined(MK66F18)
196# define EEPROM_MAX 4096
197# define EEPARTITION 0x05 // 128K dataflash for EEPROM, 128K for Data
198# define EEESPLIT 0x10 // best endurance: 0x00 = first 12%, 0x10 = first 25%, 0x30 = all equal
199# endif
200
72// Minimum EEPROM Endurance 201// Minimum EEPROM Endurance
73// ------------------------ 202// ------------------------
74# if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word 203# if (EEPROM_SIZE == 4096)
75# define EEESIZE 0x33 204# define EEESIZE 0x02
205# elif (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
206# define EEESIZE 0x03
76# elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word 207# elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
77# define EEESIZE 0x34 208# define EEESIZE 0x04
78# elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word 209# elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
79# define EEESIZE 0x35 210# define EEESIZE 0x05
80# elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word 211# elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
81# define EEESIZE 0x36 212# define EEESIZE 0x06
82# elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word 213# elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
83# define EEESIZE 0x37 214# define EEESIZE 0x07
84# elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word 215# elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
85# define EEESIZE 0x38 216# define EEESIZE 0x08
86# elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word 217# elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
87# define EEESIZE 0x39 218# define EEESIZE 0x09
88# endif 219# endif
89 220
90/** \brief eeprom initialization 221/** \brief eeprom initialization
@@ -97,15 +228,21 @@ void eeprom_initialize(void) {
97 uint8_t status; 228 uint8_t status;
98 229
99 if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { 230 if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) {
231 uint8_t stat = FTFL->FSTAT & 0x70;
232 if (stat) FTFL->FSTAT = stat;
233
100 // FlexRAM is configured as traditional RAM 234 // FlexRAM is configured as traditional RAM
101 // We need to reconfigure for EEPROM usage 235 // We need to reconfigure for EEPROM usage
102 FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command 236 kinetis_hsrun_disable();
103 FTFL->FCCOB4 = EEESIZE; // EEPROM Size 237 FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command
104 FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup 238 FTFL->FCCOB3 = 0;
239 FTFL->FCCOB4 = EEESPLIT | EEESIZE;
240 FTFL->FCCOB5 = EEPARTITION;
105 __disable_irq(); 241 __disable_irq();
106 // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... 242 // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
107 (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); 243 (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT));
108 __enable_irq(); 244 __enable_irq();
245 kinetis_hsrun_enable();
109 status = FTFL->FSTAT; 246 status = FTFL->FSTAT;
110 if (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)) { 247 if (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)) {
111 FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)); 248 FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL));
@@ -114,11 +251,11 @@ void eeprom_initialize(void) {
114 } 251 }
115 // wait for eeprom to become ready (is this really necessary?) 252 // wait for eeprom to become ready (is this really necessary?)
116 while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { 253 while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
117 if (++count > 20000) break; 254 if (++count > 200000) break;
118 } 255 }
119} 256}
120 257
121# define FlexRAM ((uint8_t *)0x14000000) 258# define FlexRAM ((volatile uint8_t *)0x14000000)
122 259
123/** \brief eeprom read byte 260/** \brief eeprom read byte
124 * 261 *
@@ -195,8 +332,12 @@ void eeprom_write_byte(uint8_t *addr, uint8_t value) {
195 if (offset >= EEPROM_SIZE) return; 332 if (offset >= EEPROM_SIZE) return;
196 if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); 333 if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
197 if (FlexRAM[offset] != value) { 334 if (FlexRAM[offset] != value) {
335 kinetis_hsrun_disable();
336 uint8_t stat = FTFL->FSTAT & 0x70;
337 if (stat) FTFL->FSTAT = stat;
198 FlexRAM[offset] = value; 338 FlexRAM[offset] = value;
199 flexram_wait(); 339 flexram_wait();
340 kinetis_hsrun_enable();
200 } 341 }
201} 342}
202 343
@@ -213,18 +354,30 @@ void eeprom_write_word(uint16_t *addr, uint16_t value) {
213 if ((offset & 1) == 0) { 354 if ((offset & 1) == 0) {
214# endif 355# endif
215 if (*(uint16_t *)(&FlexRAM[offset]) != value) { 356 if (*(uint16_t *)(&FlexRAM[offset]) != value) {
357 kinetis_hsrun_disable();
358 uint8_t stat = FTFL->FSTAT & 0x70;
359 if (stat) FTFL->FSTAT = stat;
216 *(uint16_t *)(&FlexRAM[offset]) = value; 360 *(uint16_t *)(&FlexRAM[offset]) = value;
217 flexram_wait(); 361 flexram_wait();
362 kinetis_hsrun_enable();
218 } 363 }
219# ifdef HANDLE_UNALIGNED_WRITES 364# ifdef HANDLE_UNALIGNED_WRITES
220 } else { 365 } else {
221 if (FlexRAM[offset] != value) { 366 if (FlexRAM[offset] != value) {
367 kinetis_hsrun_disable();
368 uint8_t stat = FTFL->FSTAT & 0x70;
369 if (stat) FTFL->FSTAT = stat;
222 FlexRAM[offset] = value; 370 FlexRAM[offset] = value;
223 flexram_wait(); 371 flexram_wait();
372 kinetis_hsrun_enable();
224 } 373 }
225 if (FlexRAM[offset + 1] != (value >> 8)) { 374 if (FlexRAM[offset + 1] != (value >> 8)) {
375 kinetis_hsrun_disable();
376 uint8_t stat = FTFL->FSTAT & 0x70;
377 if (stat) FTFL->FSTAT = stat;
226 FlexRAM[offset + 1] = value >> 8; 378 FlexRAM[offset + 1] = value >> 8;
227 flexram_wait(); 379 flexram_wait();
380 kinetis_hsrun_enable();
228 } 381 }
229 } 382 }
230# endif 383# endif
@@ -244,33 +397,57 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value) {
244 case 0: 397 case 0:
245# endif 398# endif
246 if (*(uint32_t *)(&FlexRAM[offset]) != value) { 399 if (*(uint32_t *)(&FlexRAM[offset]) != value) {
400 kinetis_hsrun_disable();
401 uint8_t stat = FTFL->FSTAT & 0x70;
402 if (stat) FTFL->FSTAT = stat;
247 *(uint32_t *)(&FlexRAM[offset]) = value; 403 *(uint32_t *)(&FlexRAM[offset]) = value;
248 flexram_wait(); 404 flexram_wait();
405 kinetis_hsrun_enable();
249 } 406 }
250 return; 407 return;
251# ifdef HANDLE_UNALIGNED_WRITES 408# ifdef HANDLE_UNALIGNED_WRITES
252 case 2: 409 case 2:
253 if (*(uint16_t *)(&FlexRAM[offset]) != value) { 410 if (*(uint16_t *)(&FlexRAM[offset]) != value) {
411 kinetis_hsrun_disable();
412 uint8_t stat = FTFL->FSTAT & 0x70;
413 if (stat) FTFL->FSTAT = stat;
254 *(uint16_t *)(&FlexRAM[offset]) = value; 414 *(uint16_t *)(&FlexRAM[offset]) = value;
255 flexram_wait(); 415 flexram_wait();
416 kinetis_hsrun_enable();
256 } 417 }
257 if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { 418 if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
419 kinetis_hsrun_disable();
420 uint8_t stat = FTFL->FSTAT & 0x70;
421 if (stat) FTFL->FSTAT = stat;
258 *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; 422 *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
259 flexram_wait(); 423 flexram_wait();
424 kinetis_hsrun_enable();
260 } 425 }
261 return; 426 return;
262 default: 427 default:
263 if (FlexRAM[offset] != value) { 428 if (FlexRAM[offset] != value) {
429 kinetis_hsrun_disable();
430 uint8_t stat = FTFL->FSTAT & 0x70;
431 if (stat) FTFL->FSTAT = stat;
264 FlexRAM[offset] = value; 432 FlexRAM[offset] = value;
265 flexram_wait(); 433 flexram_wait();
434 kinetis_hsrun_enable();
266 } 435 }
267 if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { 436 if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
437 kinetis_hsrun_disable();
438 uint8_t stat = FTFL->FSTAT & 0x70;
439 if (stat) FTFL->FSTAT = stat;
268 *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; 440 *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
269 flexram_wait(); 441 flexram_wait();
442 kinetis_hsrun_enable();
270 } 443 }
271 if (FlexRAM[offset + 3] != (value >> 24)) { 444 if (FlexRAM[offset + 3] != (value >> 24)) {
445 kinetis_hsrun_disable();
446 uint8_t stat = FTFL->FSTAT & 0x70;
447 if (stat) FTFL->FSTAT = stat;
272 FlexRAM[offset + 3] = value >> 24; 448 FlexRAM[offset + 3] = value >> 24;
273 flexram_wait(); 449 flexram_wait();
450 kinetis_hsrun_enable();
274 } 451 }
275 } 452 }
276# endif 453# endif
@@ -288,6 +465,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
288 if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); 465 if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
289 if (len >= EEPROM_SIZE) len = EEPROM_SIZE; 466 if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
290 if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset; 467 if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
468 kinetis_hsrun_disable();
291 while (len > 0) { 469 while (len > 0) {
292 uint32_t lsb = offset & 3; 470 uint32_t lsb = offset & 3;
293 if (lsb == 0 && len >= 4) { 471 if (lsb == 0 && len >= 4) {
@@ -298,6 +476,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
298 val32 |= (*src++ << 16); 476 val32 |= (*src++ << 16);
299 val32 |= (*src++ << 24); 477 val32 |= (*src++ << 24);
300 if (*(uint32_t *)(&FlexRAM[offset]) != val32) { 478 if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
479 uint8_t stat = FTFL->FSTAT & 0x70;
480 if (stat) FTFL->FSTAT = stat;
301 *(uint32_t *)(&FlexRAM[offset]) = val32; 481 *(uint32_t *)(&FlexRAM[offset]) = val32;
302 flexram_wait(); 482 flexram_wait();
303 } 483 }
@@ -309,6 +489,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
309 val16 = *src++; 489 val16 = *src++;
310 val16 |= (*src++ << 8); 490 val16 |= (*src++ << 8);
311 if (*(uint16_t *)(&FlexRAM[offset]) != val16) { 491 if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
492 uint8_t stat = FTFL->FSTAT & 0x70;
493 if (stat) FTFL->FSTAT = stat;
312 *(uint16_t *)(&FlexRAM[offset]) = val16; 494 *(uint16_t *)(&FlexRAM[offset]) = val16;
313 flexram_wait(); 495 flexram_wait();
314 } 496 }
@@ -318,6 +500,8 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
318 // write 8 bits 500 // write 8 bits
319 uint8_t val8 = *src++; 501 uint8_t val8 = *src++;
320 if (FlexRAM[offset] != val8) { 502 if (FlexRAM[offset] != val8) {
503 uint8_t stat = FTFL->FSTAT & 0x70;
504 if (stat) FTFL->FSTAT = stat;
321 FlexRAM[offset] = val8; 505 FlexRAM[offset] = val8;
322 flexram_wait(); 506 flexram_wait();
323 } 507 }
@@ -325,6 +509,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
325 len--; 509 len--;
326 } 510 }
327 } 511 }
512 kinetis_hsrun_enable();
328} 513}
329 514
330/* 515/*
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c
index 6b80ff71c..72c41b8b7 100644
--- a/tmk_core/common/chibios/flash_stm32.c
+++ b/tmk_core/common/chibios/flash_stm32.c
@@ -19,10 +19,38 @@
19#include <hal.h> 19#include <hal.h>
20#include "flash_stm32.h" 20#include "flash_stm32.h"
21 21
22#if defined(EEPROM_EMU_STM32F103xB) 22#if defined(STM32F1XX)
23# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR 23# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
24#endif 24#endif
25 25
26#if defined(MCU_GD32V)
27/* GigaDevice GD32VF103 is a STM32F103 clone at heart. */
28# include "gd32v_compatibility.h"
29#endif
30
31#if defined(STM32F4XX)
32# define FLASH_SR_PGERR (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR)
33
34# define FLASH_KEY1 0x45670123U
35# define FLASH_KEY2 0xCDEF89ABU
36
37static uint8_t ADDR2PAGE(uint32_t Page_Address) {
38 switch (Page_Address) {
39 case 0x08000000 ... 0x08003FFF:
40 return 0;
41 case 0x08004000 ... 0x08007FFF:
42 return 1;
43 case 0x08008000 ... 0x0800BFFF:
44 return 2;
45 case 0x0800C000 ... 0x0800FFFF:
46 return 3;
47 }
48
49 // TODO: bad times...
50 return 7;
51}
52#endif
53
26/* Delay definition */ 54/* Delay definition */
27#define EraseTimeout ((uint32_t)0x00000FFF) 55#define EraseTimeout ((uint32_t)0x00000FFF)
28#define ProgramTimeout ((uint32_t)0x0000001F) 56#define ProgramTimeout ((uint32_t)0x0000001F)
@@ -53,7 +81,9 @@ FLASH_Status FLASH_GetStatus(void) {
53 81
54 if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP; 82 if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP;
55 83
84#if defined(FLASH_OBR_OPTERR)
56 if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT; 85 if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT;
86#endif
57 87
58 return FLASH_COMPLETE; 88 return FLASH_COMPLETE;
59} 89}
@@ -95,15 +125,24 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
95 125
96 if (status == FLASH_COMPLETE) { 126 if (status == FLASH_COMPLETE) {
97 /* if the previous operation is completed, proceed to erase the page */ 127 /* if the previous operation is completed, proceed to erase the page */
128#if defined(FLASH_CR_SNB)
129 FLASH->CR &= ~FLASH_CR_SNB;
130 FLASH->CR |= FLASH_CR_SER | (ADDR2PAGE(Page_Address) << FLASH_CR_SNB_Pos);
131#else
98 FLASH->CR |= FLASH_CR_PER; 132 FLASH->CR |= FLASH_CR_PER;
99 FLASH->AR = Page_Address; 133 FLASH->AR = Page_Address;
134#endif
100 FLASH->CR |= FLASH_CR_STRT; 135 FLASH->CR |= FLASH_CR_STRT;
101 136
102 /* Wait for last operation to be completed */ 137 /* Wait for last operation to be completed */
103 status = FLASH_WaitForLastOperation(EraseTimeout); 138 status = FLASH_WaitForLastOperation(EraseTimeout);
104 if (status != FLASH_TIMEOUT) { 139 if (status != FLASH_TIMEOUT) {
105 /* if the erase operation is completed, disable the PER Bit */ 140 /* if the erase operation is completed, disable the configured Bits */
141#if defined(FLASH_CR_SNB)
142 FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB);
143#else
106 FLASH->CR &= ~FLASH_CR_PER; 144 FLASH->CR &= ~FLASH_CR_PER;
145#endif
107 } 146 }
108 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR); 147 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
109 } 148 }
@@ -126,6 +165,11 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
126 status = FLASH_WaitForLastOperation(ProgramTimeout); 165 status = FLASH_WaitForLastOperation(ProgramTimeout);
127 if (status == FLASH_COMPLETE) { 166 if (status == FLASH_COMPLETE) {
128 /* if the previous operation is completed, proceed to program the new data */ 167 /* if the previous operation is completed, proceed to program the new data */
168
169#if defined(FLASH_CR_PSIZE)
170 FLASH->CR &= ~FLASH_CR_PSIZE;
171 FLASH->CR |= FLASH_CR_PSIZE_0;
172#endif
129 FLASH->CR |= FLASH_CR_PG; 173 FLASH->CR |= FLASH_CR_PG;
130 *(__IO uint16_t*)Address = Data; 174 *(__IO uint16_t*)Address = Data;
131 /* Wait for last operation to be completed */ 175 /* Wait for last operation to be completed */
diff --git a/tmk_core/common/chibios/gd32v_compatibility.h b/tmk_core/common/chibios/gd32v_compatibility.h
new file mode 100644
index 000000000..f4dcfd8c5
--- /dev/null
+++ b/tmk_core/common/chibios/gd32v_compatibility.h
@@ -0,0 +1,120 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19/* GD32VF103 has the same API as STM32F103, but uses different names for literally the same thing.
20 * As of 23.7.2021 QMK is tailored to use STM32 defines/names, for compatibility sake
21 * we just redefine the GD32 names. */
22
23/* Close your eyes kids. */
24#define MCU_STM32
25
26/* AFIO redefines */
27#define MAPR PCF0
28#define AFIO_MAPR_USART1_REMAP AFIO_PCF0_USART0_REMAP
29#define AFIO_MAPR_USART2_REMAP AFIO_PCF0_USART1_REMAP
30#define AFIO_MAPR_USART3_REMAP_PARTIALREMAP AFIO_PCF0_USART2_REMAP_PARTIALREMAP
31#define AFIO_MAPR_USART3_REMAP_FULLREMAP AFIO_PCF0_USART2_REMAP_FULLREMAP
32
33/* DMA redefines. */
34#define STM32_DMA_STREAM(stream) GD32_DMA_STREAM(stream)
35#define STM32_DMA_STREAM_ID(peripheral, channel) GD32_DMA_STREAM_ID(peripheral - 1, channel - 1)
36#define STM32_DMA_CR_DIR_M2P GD32_DMA_CTL_DIR_M2P
37#define STM32_DMA_CR_PSIZE_WORD GD32_DMA_CTL_PWIDTH_WORD
38#define STM32_DMA_CR_MSIZE_WORD GD32_DMA_CTL_MWIDTH_WORD
39#define STM32_DMA_CR_MINC GD32_DMA_CTL_MNAGA
40#define STM32_DMA_CR_CIRC GD32_DMA_CTL_CMEN
41#define STM32_DMA_CR_PL GD32_DMA_CTL_PRIO
42#define STM32_DMA_CR_CHSEL GD32_DMA_CTL_CHSEL
43#define cr1 ctl0
44#define cr2 ctl1
45#define cr3 ctl2
46#define dier dmainten
47
48/* ADC redefines */
49#if HAL_USE_ADC
50# define STM32_ADC_USE_ADC1 GD32_ADC_USE_ADC0
51
52# define smpr1 sampt0
53# define smpr2 sampt1
54# define sqr1 rsq0
55# define sqr2 rsq1
56# define sqr3 rsq2
57
58# define ADC_SMPR2_SMP_AN0 ADC_SAMPT1_SMP_SPT0
59# define ADC_SMPR2_SMP_AN1 ADC_SAMPT1_SMP_SPT1
60# define ADC_SMPR2_SMP_AN2 ADC_SAMPT1_SMP_SPT2
61# define ADC_SMPR2_SMP_AN3 ADC_SAMPT1_SMP_SPT3
62# define ADC_SMPR2_SMP_AN4 ADC_SAMPT1_SMP_SPT4
63# define ADC_SMPR2_SMP_AN5 ADC_SAMPT1_SMP_SPT5
64# define ADC_SMPR2_SMP_AN6 ADC_SAMPT1_SMP_SPT6
65# define ADC_SMPR2_SMP_AN7 ADC_SAMPT1_SMP_SPT7
66# define ADC_SMPR2_SMP_AN8 ADC_SAMPT1_SMP_SPT8
67# define ADC_SMPR2_SMP_AN9 ADC_SAMPT1_SMP_SPT9
68
69# define ADC_SMPR1_SMP_AN10 ADC_SAMPT0_SMP_SPT10
70# define ADC_SMPR1_SMP_AN11 ADC_SAMPT0_SMP_SPT11
71# define ADC_SMPR1_SMP_AN12 ADC_SAMPT0_SMP_SPT12
72# define ADC_SMPR1_SMP_AN13 ADC_SAMPT0_SMP_SPT13
73# define ADC_SMPR1_SMP_AN14 ADC_SAMPT0_SMP_SPT14
74# define ADC_SMPR1_SMP_AN15 ADC_SAMPT0_SMP_SPT15
75
76# define ADC_SQR3_SQ1_N ADC_RSQ2_RSQ1_N
77#endif
78
79/* FLASH redefines */
80#if defined(EEPROM_ENABLE)
81# define SR STAT
82# define FLASH_SR_BSY FLASH_STAT_BUSY
83# define FLASH_SR_PGERR FLASH_STAT_PGERR
84# define FLASH_SR_EOP FLASH_STAT_ENDF
85# define FLASH_SR_WRPRTERR FLASH_STAT_WPERR
86# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
87# define FLASH_OBR_OPTERR FLASH_OBSTAT_OBERR
88# define AR ADDR
89# define CR CTL
90# define FLASH_CR_PER FLASH_CTL_PER
91# define FLASH_CR_STRT FLASH_CTL_START
92# define FLASH_CR_LOCK FLASH_CTL_LK
93# define FLASH_CR_PG FLASH_CTL_PG
94# define KEYR KEY
95#endif
96
97/* Serial USART redefines. */
98#if HAL_USE_SERIAL
99# if !defined(SERIAL_USART_CR1)
100# define SERIAL_USART_CR1 (USART_CTL0_PCEN | USART_CTL0_PM | USART_CTL0_WL) // parity enable, odd parity, 9 bit length
101# endif
102# if !defined(SERIAL_USART_CR2)
103# define SERIAL_USART_CR2 (USART_CTL1_STB_1) // 2 stop bits
104# endif
105# if !defined(SERIAL_USART_CR3)
106# define SERIAL_USART_CR3 0x0
107# endif
108# define USART_CR3_HDSEL USART_CTL2_HDEN
109# define CCR CHCV
110#endif
111
112/* SPI redefines. */
113#if HAL_USE_SPI
114# define SPI_CR1_LSBFIRST SPI_CTL0_LF
115# define SPI_CR1_CPHA SPI_CTL0_CKPH
116# define SPI_CR1_CPOL SPI_CTL0_CKPL
117# define SPI_CR1_BR_0 SPI_CTL0_PSC_0
118# define SPI_CR1_BR_1 SPI_CTL0_PSC_1
119# define SPI_CR1_BR_2 SPI_CTL0_PSC_2
120#endif
diff --git a/tmk_core/common/chibios/suspend.c b/tmk_core/common/chibios/suspend.c
index 38517e06f..9310a9992 100644
--- a/tmk_core/common/chibios/suspend.c
+++ b/tmk_core/common/chibios/suspend.c
@@ -7,30 +7,12 @@
7#include "action.h" 7#include "action.h"
8#include "action_util.h" 8#include "action_util.h"
9#include "mousekey.h" 9#include "mousekey.h"
10#include "programmable_button.h"
10#include "host.h" 11#include "host.h"
11#include "suspend.h" 12#include "suspend.h"
12#include "led.h" 13#include "led.h"
13#include "wait.h" 14#include "wait.h"
14 15
15#ifdef AUDIO_ENABLE
16# include "audio.h"
17#endif /* AUDIO_ENABLE */
18
19#ifdef BACKLIGHT_ENABLE
20# include "backlight.h"
21#endif
22
23#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
24# include "rgblight.h"
25#endif
26
27#ifdef LED_MATRIX_ENABLE
28# include "led_matrix.h"
29#endif
30#ifdef RGB_MATRIX_ENABLE
31# include "rgb_matrix.h"
32#endif
33
34/** \brief suspend idle 16/** \brief suspend idle
35 * 17 *
36 * FIXME: needs doc 18 * FIXME: needs doc
@@ -40,61 +22,12 @@ void suspend_idle(uint8_t time) {
40 wait_ms(time); 22 wait_ms(time);
41} 23}
42 24
43/** \brief Run keyboard level Power down
44 *
45 * FIXME: needs doc
46 */
47__attribute__((weak)) void suspend_power_down_user(void) {}
48/** \brief Run keyboard level Power down
49 *
50 * FIXME: needs doc
51 */
52__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
53
54/** \brief suspend power down 25/** \brief suspend power down
55 * 26 *
56 * FIXME: needs doc 27 * FIXME: needs doc
57 */ 28 */
58void suspend_power_down(void) { 29void suspend_power_down(void) {
59#ifdef BACKLIGHT_ENABLE 30 suspend_power_down_quantum();
60 backlight_set(0);
61#endif
62
63#ifdef LED_MATRIX_ENABLE
64 led_matrix_task();
65#endif
66#ifdef RGB_MATRIX_ENABLE
67 rgb_matrix_task();
68#endif
69
70 // Turn off LED indicators
71 uint8_t leds_off = 0;
72#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
73 if (is_backlight_enabled()) {
74 // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
75 leds_off |= (1 << USB_LED_CAPS_LOCK);
76 }
77#endif
78 led_set(leds_off);
79
80 // TODO: figure out what to power down and how
81 // shouldn't power down TPM/FTM if we want a breathing LED
82 // also shouldn't power down USB
83#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
84 rgblight_suspend();
85#endif
86
87#if defined(LED_MATRIX_ENABLE)
88 led_matrix_set_suspend_state(true);
89#endif
90#if defined(RGB_MATRIX_ENABLE)
91 rgb_matrix_set_suspend_state(true);
92#endif
93#ifdef AUDIO_ENABLE
94 stop_all_notes();
95#endif /* AUDIO_ENABLE */
96
97 suspend_power_down_kb();
98 // on AVR, this enables the watchdog for 15ms (max), and goes to 31 // on AVR, this enables the watchdog for 15ms (max), and goes to
99 // SLEEP_MODE_PWR_DOWN 32 // SLEEP_MODE_PWR_DOWN
100 33
@@ -147,23 +80,13 @@ void suspend_wakeup_init(void) {
147#ifdef MOUSEKEY_ENABLE 80#ifdef MOUSEKEY_ENABLE
148 mousekey_clear(); 81 mousekey_clear();
149#endif /* MOUSEKEY_ENABLE */ 82#endif /* MOUSEKEY_ENABLE */
83#ifdef PROGRAMMABLE_BUTTON_ENABLE
84 programmable_button_clear();
85#endif /* PROGRAMMABLE_BUTTON_ENABLE */
150#ifdef EXTRAKEY_ENABLE 86#ifdef EXTRAKEY_ENABLE
151 host_system_send(0); 87 host_system_send(0);
152 host_consumer_send(0); 88 host_consumer_send(0);
153#endif /* EXTRAKEY_ENABLE */ 89#endif /* EXTRAKEY_ENABLE */
154#ifdef BACKLIGHT_ENABLE
155 backlight_init();
156#endif /* BACKLIGHT_ENABLE */
157 led_set(host_keyboard_leds());
158#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
159 rgblight_wakeup();
160#endif
161 90
162#if defined(LED_MATRIX_ENABLE) 91 suspend_wakeup_init_quantum();
163 led_matrix_set_suspend_state(false);
164#endif
165#if defined(RGB_MATRIX_ENABLE)
166 rgb_matrix_set_suspend_state(false);
167#endif
168 suspend_wakeup_init_kb();
169} 92}
diff --git a/tmk_core/common/chibios/syscall-fallbacks.c b/tmk_core/common/chibios/syscall-fallbacks.c
index 739017ae1..4569879c7 100644
--- a/tmk_core/common/chibios/syscall-fallbacks.c
+++ b/tmk_core/common/chibios/syscall-fallbacks.c
@@ -18,6 +18,12 @@
18#include <sys/stat.h> 18#include <sys/stat.h>
19#include <sys/types.h> 19#include <sys/types.h>
20 20
21/* To compile the ChibiOS syscall stubs with picolibc
22 * the _reent struct has to be defined. */
23#if defined(USE_PICOLIBC)
24struct _reent;
25#endif
26
21#pragma GCC diagnostic ignored "-Wmissing-prototypes" 27#pragma GCC diagnostic ignored "-Wmissing-prototypes"
22 28
23__attribute__((weak, used)) int _open_r(struct _reent *r, const char *path, int flag, int m) { 29__attribute__((weak, used)) int _open_r(struct _reent *r, const char *path, int flag, int m) {
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
deleted file mode 100644
index f0c396b18..000000000
--- a/tmk_core/common/host.c
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2Copyright 2011,2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <stdint.h>
19//#include <avr/interrupt.h>
20#include "keyboard.h"
21#include "keycode.h"
22#include "host.h"
23#include "util.h"
24#include "debug.h"
25#include "digitizer.h"
26
27#ifdef NKRO_ENABLE
28# include "keycode_config.h"
29extern keymap_config_t keymap_config;
30#endif
31
32static host_driver_t *driver;
33static uint16_t last_system_report = 0;
34static uint16_t last_consumer_report = 0;
35
36void host_set_driver(host_driver_t *d) { driver = d; }
37
38host_driver_t *host_get_driver(void) { return driver; }
39
40#ifdef SPLIT_KEYBOARD
41uint8_t split_led_state = 0;
42void set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; }
43#endif
44
45uint8_t host_keyboard_leds(void) {
46#ifdef SPLIT_KEYBOARD
47 if (!is_keyboard_master()) return split_led_state;
48#endif
49 if (!driver) return 0;
50 return (*driver->keyboard_leds)();
51}
52
53led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); }
54
55/* send report */
56void host_keyboard_send(report_keyboard_t *report) {
57 if (!driver) return;
58#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
59 if (keyboard_protocol && keymap_config.nkro) {
60 /* The callers of this function assume that report->mods is where mods go in.
61 * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
62 */
63 report->nkro.mods = report->mods;
64 report->nkro.report_id = REPORT_ID_NKRO;
65 } else
66#endif
67 {
68#ifdef KEYBOARD_SHARED_EP
69 report->report_id = REPORT_ID_KEYBOARD;
70#endif
71 }
72 (*driver->send_keyboard)(report);
73
74 if (debug_keyboard) {
75 dprint("keyboard_report: ");
76 for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
77 dprintf("%02X ", report->raw[i]);
78 }
79 dprint("\n");
80 }
81}
82
83void host_mouse_send(report_mouse_t *report) {
84 if (!driver) return;
85#ifdef MOUSE_SHARED_EP
86 report->report_id = REPORT_ID_MOUSE;
87#endif
88 (*driver->send_mouse)(report);
89}
90
91void host_system_send(uint16_t report) {
92 if (report == last_system_report) return;
93 last_system_report = report;
94
95 if (!driver) return;
96 (*driver->send_system)(report);
97}
98
99void host_consumer_send(uint16_t report) {
100 if (report == last_consumer_report) return;
101 last_consumer_report = report;
102
103 if (!driver) return;
104 (*driver->send_consumer)(report);
105}
106
107void host_digitizer_send(digitizer_t *digitizer) {
108 if (!driver) return;
109
110 report_digitizer_t report = {
111#ifdef DIGITIZER_SHARED_EP
112 .report_id = REPORT_ID_DIGITIZER,
113#endif
114 .tip = digitizer->tipswitch & 0x1,
115 .inrange = digitizer->inrange & 0x1,
116 .x = (uint16_t)(digitizer->x * 0x7FFF),
117 .y = (uint16_t)(digitizer->y * 0x7FFF),
118 };
119
120 send_digitizer(&report);
121}
122
123__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
124
125uint16_t host_last_system_report(void) { return last_system_report; }
126
127uint16_t host_last_consumer_report(void) { return last_consumer_report; }
diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h
deleted file mode 100644
index 2cffef6e1..000000000
--- a/tmk_core/common/host.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include <stdbool.h>
22#include "report.h"
23#include "host_driver.h"
24#include "led.h"
25
26#define IS_LED_ON(leds, led_name) ((leds) & (1 << (led_name)))
27#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name)))
28
29#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name)
30#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name)
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36extern uint8_t keyboard_idle;
37extern uint8_t keyboard_protocol;
38
39/* host driver */
40void host_set_driver(host_driver_t *driver);
41host_driver_t *host_get_driver(void);
42
43/* host driver interface */
44uint8_t host_keyboard_leds(void);
45led_t host_keyboard_led_state(void);
46void host_keyboard_send(report_keyboard_t *report);
47void host_mouse_send(report_mouse_t *report);
48void host_system_send(uint16_t data);
49void host_consumer_send(uint16_t data);
50
51uint16_t host_last_system_report(void);
52uint16_t host_last_consumer_report(void);
53
54#ifdef __cplusplus
55}
56#endif
diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h
deleted file mode 100644
index 2aebca043..000000000
--- a/tmk_core/common/host_driver.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include "report.h"
22#ifdef MIDI_ENABLE
23# include "midi.h"
24#endif
25
26typedef struct {
27 uint8_t (*keyboard_leds)(void);
28 void (*send_keyboard)(report_keyboard_t *);
29 void (*send_mouse)(report_mouse_t *);
30 void (*send_system)(uint16_t);
31 void (*send_consumer)(uint16_t);
32} host_driver_t;
33
34void send_digitizer(report_digitizer_t *report); \ No newline at end of file
diff --git a/tmk_core/common/raw_hid.h b/tmk_core/common/raw_hid.h
deleted file mode 100644
index 6d60ab2bf..000000000
--- a/tmk_core/common/raw_hid.h
+++ /dev/null
@@ -1,5 +0,0 @@
1#pragma once
2
3void raw_hid_receive(uint8_t *data, uint8_t length);
4
5void raw_hid_send(uint8_t *data, uint8_t length);
diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c
deleted file mode 100644
index 854b59ae4..000000000
--- a/tmk_core/common/report.c
+++ /dev/null
@@ -1,280 +0,0 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "report.h"
18#include "host.h"
19#include "keycode_config.h"
20#include "debug.h"
21#include "util.h"
22#include <string.h>
23
24#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
25# define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
26# define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
27# define RO_INC(a) RO_ADD(a, 1)
28# define RO_DEC(a) RO_SUB(a, 1)
29static int8_t cb_head = 0;
30static int8_t cb_tail = 0;
31static int8_t cb_count = 0;
32#endif
33
34/** \brief has_anykey
35 *
36 * FIXME: Needs doc
37 */
38uint8_t has_anykey(report_keyboard_t* keyboard_report) {
39 uint8_t cnt = 0;
40 uint8_t* p = keyboard_report->keys;
41 uint8_t lp = sizeof(keyboard_report->keys);
42#ifdef NKRO_ENABLE
43 if (keyboard_protocol && keymap_config.nkro) {
44 p = keyboard_report->nkro.bits;
45 lp = sizeof(keyboard_report->nkro.bits);
46 }
47#endif
48 while (lp--) {
49 if (*p++) cnt++;
50 }
51 return cnt;
52}
53
54/** \brief get_first_key
55 *
56 * FIXME: Needs doc
57 */
58uint8_t get_first_key(report_keyboard_t* keyboard_report) {
59#ifdef NKRO_ENABLE
60 if (keyboard_protocol && keymap_config.nkro) {
61 uint8_t i = 0;
62 for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
63 ;
64 return i << 3 | biton(keyboard_report->nkro.bits[i]);
65 }
66#endif
67#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
68 uint8_t i = cb_head;
69 do {
70 if (keyboard_report->keys[i] != 0) {
71 break;
72 }
73 i = RO_INC(i);
74 } while (i != cb_tail);
75 return keyboard_report->keys[i];
76#else
77 return keyboard_report->keys[0];
78#endif
79}
80
81/** \brief Checks if a key is pressed in the report
82 *
83 * Returns true if the keyboard_report reports that the key is pressed, otherwise false
84 * Note: The function doesn't support modifers currently, and it returns false for KC_NO
85 */
86bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) {
87 if (key == KC_NO) {
88 return false;
89 }
90#ifdef NKRO_ENABLE
91 if (keyboard_protocol && keymap_config.nkro) {
92 if ((key >> 3) < KEYBOARD_REPORT_BITS) {
93 return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7);
94 } else {
95 return false;
96 }
97 }
98#endif
99 for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
100 if (keyboard_report->keys[i] == key) {
101 return true;
102 }
103 }
104 return false;
105}
106
107/** \brief add key byte
108 *
109 * FIXME: Needs doc
110 */
111void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
112#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
113 int8_t i = cb_head;
114 int8_t empty = -1;
115 if (cb_count) {
116 do {
117 if (keyboard_report->keys[i] == code) {
118 return;
119 }
120 if (empty == -1 && keyboard_report->keys[i] == 0) {
121 empty = i;
122 }
123 i = RO_INC(i);
124 } while (i != cb_tail);
125 if (i == cb_tail) {
126 if (cb_tail == cb_head) {
127 // buffer is full
128 if (empty == -1) {
129 // pop head when has no empty space
130 cb_head = RO_INC(cb_head);
131 cb_count--;
132 } else {
133 // left shift when has empty space
134 uint8_t offset = 1;
135 i = RO_INC(empty);
136 do {
137 if (keyboard_report->keys[i] != 0) {
138 keyboard_report->keys[empty] = keyboard_report->keys[i];
139 keyboard_report->keys[i] = 0;
140 empty = RO_INC(empty);
141 } else {
142 offset++;
143 }
144 i = RO_INC(i);
145 } while (i != cb_tail);
146 cb_tail = RO_SUB(cb_tail, offset);
147 }
148 }
149 }
150 }
151 // add to tail
152 keyboard_report->keys[cb_tail] = code;
153 cb_tail = RO_INC(cb_tail);
154 cb_count++;
155#else
156 int8_t i = 0;
157 int8_t empty = -1;
158 for (; i < KEYBOARD_REPORT_KEYS; i++) {
159 if (keyboard_report->keys[i] == code) {
160 break;
161 }
162 if (empty == -1 && keyboard_report->keys[i] == 0) {
163 empty = i;
164 }
165 }
166 if (i == KEYBOARD_REPORT_KEYS) {
167 if (empty != -1) {
168 keyboard_report->keys[empty] = code;
169 }
170 }
171#endif
172}
173
174/** \brief del key byte
175 *
176 * FIXME: Needs doc
177 */
178void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
179#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
180 uint8_t i = cb_head;
181 if (cb_count) {
182 do {
183 if (keyboard_report->keys[i] == code) {
184 keyboard_report->keys[i] = 0;
185 cb_count--;
186 if (cb_count == 0) {
187 // reset head and tail
188 cb_tail = cb_head = 0;
189 }
190 if (i == RO_DEC(cb_tail)) {
191 // left shift when next to tail
192 do {
193 cb_tail = RO_DEC(cb_tail);
194 if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
195 break;
196 }
197 } while (cb_tail != cb_head);
198 }
199 break;
200 }
201 i = RO_INC(i);
202 } while (i != cb_tail);
203 }
204#else
205 for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
206 if (keyboard_report->keys[i] == code) {
207 keyboard_report->keys[i] = 0;
208 }
209 }
210#endif
211}
212
213#ifdef NKRO_ENABLE
214/** \brief add key bit
215 *
216 * FIXME: Needs doc
217 */
218void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
219 if ((code >> 3) < KEYBOARD_REPORT_BITS) {
220 keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7);
221 } else {
222 dprintf("add_key_bit: can't add: %02X\n", code);
223 }
224}
225
226/** \brief del key bit
227 *
228 * FIXME: Needs doc
229 */
230void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
231 if ((code >> 3) < KEYBOARD_REPORT_BITS) {
232 keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7));
233 } else {
234 dprintf("del_key_bit: can't del: %02X\n", code);
235 }
236}
237#endif
238
239/** \brief add key to report
240 *
241 * FIXME: Needs doc
242 */
243void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
244#ifdef NKRO_ENABLE
245 if (keyboard_protocol && keymap_config.nkro) {
246 add_key_bit(keyboard_report, key);
247 return;
248 }
249#endif
250 add_key_byte(keyboard_report, key);
251}
252
253/** \brief del key from report
254 *
255 * FIXME: Needs doc
256 */
257void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
258#ifdef NKRO_ENABLE
259 if (keyboard_protocol && keymap_config.nkro) {
260 del_key_bit(keyboard_report, key);
261 return;
262 }
263#endif
264 del_key_byte(keyboard_report, key);
265}
266
267/** \brief clear key from report
268 *
269 * FIXME: Needs doc
270 */
271void clear_keys_from_report(report_keyboard_t* keyboard_report) {
272 // not clear mods
273#ifdef NKRO_ENABLE
274 if (keyboard_protocol && keymap_config.nkro) {
275 memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
276 return;
277 }
278#endif
279 memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
280}
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
deleted file mode 100644
index f2223e806..000000000
--- a/tmk_core/common/report.h
+++ /dev/null
@@ -1,319 +0,0 @@
1/*
2Copyright 2011,2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#pragma once
19
20#include <stdint.h>
21#include <stdbool.h>
22#include "keycode.h"
23
24// clang-format off
25
26/* HID report IDs */
27enum hid_report_ids {
28 REPORT_ID_KEYBOARD = 1,
29 REPORT_ID_MOUSE,
30 REPORT_ID_SYSTEM,
31 REPORT_ID_CONSUMER,
32 REPORT_ID_NKRO,
33 REPORT_ID_JOYSTICK,
34 REPORT_ID_DIGITIZER
35};
36
37/* Mouse buttons */
38#define MOUSE_BTN_MASK(n) (1 << (n))
39enum mouse_buttons {
40 MOUSE_BTN1 = MOUSE_BTN_MASK(0),
41 MOUSE_BTN2 = MOUSE_BTN_MASK(1),
42 MOUSE_BTN3 = MOUSE_BTN_MASK(2),
43 MOUSE_BTN4 = MOUSE_BTN_MASK(3),
44 MOUSE_BTN5 = MOUSE_BTN_MASK(4),
45 MOUSE_BTN6 = MOUSE_BTN_MASK(5),
46 MOUSE_BTN7 = MOUSE_BTN_MASK(6),
47 MOUSE_BTN8 = MOUSE_BTN_MASK(7)
48};
49
50/* Consumer Page (0x0C)
51 *
52 * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=75
53 */
54enum consumer_usages {
55 // 15.5 Display Controls
56 SNAPSHOT = 0x065,
57 BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf
58 BRIGHTNESS_DOWN = 0x070,
59 // 15.7 Transport Controls
60 TRANSPORT_RECORD = 0x0B2,
61 TRANSPORT_FAST_FORWARD = 0x0B3,
62 TRANSPORT_REWIND = 0x0B4,
63 TRANSPORT_NEXT_TRACK = 0x0B5,
64 TRANSPORT_PREV_TRACK = 0x0B6,
65 TRANSPORT_STOP = 0x0B7,
66 TRANSPORT_EJECT = 0x0B8,
67 TRANSPORT_RANDOM_PLAY = 0x0B9,
68 TRANSPORT_STOP_EJECT = 0x0CC,
69 TRANSPORT_PLAY_PAUSE = 0x0CD,
70 // 15.9.1 Audio Controls - Volume
71 AUDIO_MUTE = 0x0E2,
72 AUDIO_VOL_UP = 0x0E9,
73 AUDIO_VOL_DOWN = 0x0EA,
74 // 15.15 Application Launch Buttons
75 AL_CC_CONFIG = 0x183,
76 AL_EMAIL = 0x18A,
77 AL_CALCULATOR = 0x192,
78 AL_LOCAL_BROWSER = 0x194,
79 AL_LOCK = 0x19E,
80 AL_CONTROL_PANEL = 0x19F,
81 AL_ASSISTANT = 0x1CB,
82 AL_KEYBOARD_LAYOUT = 0x1AE,
83 // 15.16 Generic GUI Application Controls
84 AC_NEW = 0x201,
85 AC_OPEN = 0x202,
86 AC_CLOSE = 0x203,
87 AC_EXIT = 0x204,
88 AC_MAXIMIZE = 0x205,
89 AC_MINIMIZE = 0x206,
90 AC_SAVE = 0x207,
91 AC_PRINT = 0x208,
92 AC_PROPERTIES = 0x209,
93 AC_UNDO = 0x21A,
94 AC_COPY = 0x21B,
95 AC_CUT = 0x21C,
96 AC_PASTE = 0x21D,
97 AC_SELECT_ALL = 0x21E,
98 AC_FIND = 0x21F,
99 AC_SEARCH = 0x221,
100 AC_HOME = 0x223,
101 AC_BACK = 0x224,
102 AC_FORWARD = 0x225,
103 AC_STOP = 0x226,
104 AC_REFRESH = 0x227,
105 AC_BOOKMARKS = 0x22A
106};
107
108/* Generic Desktop Page (0x01)
109 *
110 * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=26
111 */
112enum desktop_usages {
113 // 4.5.1 System Controls - Power Controls
114 SYSTEM_POWER_DOWN = 0x81,
115 SYSTEM_SLEEP = 0x82,
116 SYSTEM_WAKE_UP = 0x83,
117 SYSTEM_RESTART = 0x8F,
118 // 4.10 System Display Controls
119 SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5
120};
121
122// clang-format on
123
124#define NKRO_SHARED_EP
125/* key report size(NKRO or boot mode) */
126#if defined(NKRO_ENABLE)
127# if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
128# include "protocol/usb_descriptor.h"
129# define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
130# elif defined(PROTOCOL_ARM_ATSAM)
131# include "protocol/arm_atsam/usb/udi_device_epsize.h"
132# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
133# undef NKRO_SHARED_EP
134# undef MOUSE_SHARED_EP
135# else
136# error "NKRO not supported with this protocol"
137# endif
138#endif
139
140#ifdef KEYBOARD_SHARED_EP
141# define KEYBOARD_REPORT_SIZE 9
142#else
143# define KEYBOARD_REPORT_SIZE 8
144#endif
145
146#define KEYBOARD_REPORT_KEYS 6
147
148#ifdef __cplusplus
149extern "C" {
150#endif
151
152/*
153 * keyboard report is 8-byte array retains state of 8 modifiers and 6 keys.
154 *
155 * byte |0 |1 |2 |3 |4 |5 |6 |7
156 * -----+--------+--------+--------+--------+--------+--------+--------+--------
157 * desc |mods |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5]
158 *
159 * It is exended to 16 bytes to retain 120keys+8mods when NKRO mode.
160 *
161 * byte |0 |1 |2 |3 |4 |5 |6 |7 ... |15
162 * -----+--------+--------+--------+--------+--------+--------+--------+-------- +--------
163 * desc |mods |bits[0] |bits[1] |bits[2] |bits[3] |bits[4] |bits[5] |bits[6] ... |bit[14]
164 *
165 * mods retains state of 8 modifiers.
166 *
167 * bit |0 |1 |2 |3 |4 |5 |6 |7
168 * -----+--------+--------+--------+--------+--------+--------+--------+--------
169 * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui
170 *
171 */
172typedef union {
173 uint8_t raw[KEYBOARD_REPORT_SIZE];
174 struct {
175#ifdef KEYBOARD_SHARED_EP
176 uint8_t report_id;
177#endif
178 uint8_t mods;
179 uint8_t reserved;
180 uint8_t keys[KEYBOARD_REPORT_KEYS];
181 };
182#ifdef NKRO_ENABLE
183 struct nkro_report {
184# ifdef NKRO_SHARED_EP
185 uint8_t report_id;
186# endif
187 uint8_t mods;
188 uint8_t bits[KEYBOARD_REPORT_BITS];
189 } nkro;
190#endif
191} __attribute__((packed)) report_keyboard_t;
192
193typedef struct {
194 uint8_t report_id;
195 uint16_t usage;
196} __attribute__((packed)) report_extra_t;
197
198typedef struct {
199#ifdef MOUSE_SHARED_EP
200 uint8_t report_id;
201#endif
202 uint8_t buttons;
203 int8_t x;
204 int8_t y;
205 int8_t v;
206 int8_t h;
207} __attribute__((packed)) report_mouse_t;
208
209typedef struct {
210#ifdef DIGITIZER_SHARED_EP
211 uint8_t report_id;
212#endif
213 uint8_t tip : 1;
214 uint8_t inrange : 1;
215 uint8_t pad2 : 6;
216 uint16_t x;
217 uint16_t y;
218} __attribute__((packed)) report_digitizer_t;
219
220typedef struct {
221#if JOYSTICK_AXES_COUNT > 0
222# if JOYSTICK_AXES_RESOLUTION > 8
223 int16_t axes[JOYSTICK_AXES_COUNT];
224# else
225 int8_t axes[JOYSTICK_AXES_COUNT];
226# endif
227#endif
228
229#if JOYSTICK_BUTTON_COUNT > 0
230 uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1];
231#endif
232} __attribute__((packed)) joystick_report_t;
233
234/* keycode to system usage */
235static inline uint16_t KEYCODE2SYSTEM(uint8_t key) {
236 switch (key) {
237 case KC_SYSTEM_POWER:
238 return SYSTEM_POWER_DOWN;
239 case KC_SYSTEM_SLEEP:
240 return SYSTEM_SLEEP;
241 case KC_SYSTEM_WAKE:
242 return SYSTEM_WAKE_UP;
243 default:
244 return 0;
245 }
246}
247
248/* keycode to consumer usage */
249static inline uint16_t KEYCODE2CONSUMER(uint8_t key) {
250 switch (key) {
251 case KC_AUDIO_MUTE:
252 return AUDIO_MUTE;
253 case KC_AUDIO_VOL_UP:
254 return AUDIO_VOL_UP;
255 case KC_AUDIO_VOL_DOWN:
256 return AUDIO_VOL_DOWN;
257 case KC_MEDIA_NEXT_TRACK:
258 return TRANSPORT_NEXT_TRACK;
259 case KC_MEDIA_PREV_TRACK:
260 return TRANSPORT_PREV_TRACK;
261 case KC_MEDIA_FAST_FORWARD:
262 return TRANSPORT_FAST_FORWARD;
263 case KC_MEDIA_REWIND:
264 return TRANSPORT_REWIND;
265 case KC_MEDIA_STOP:
266 return TRANSPORT_STOP;
267 case KC_MEDIA_EJECT:
268 return TRANSPORT_STOP_EJECT;
269 case KC_MEDIA_PLAY_PAUSE:
270 return TRANSPORT_PLAY_PAUSE;
271 case KC_MEDIA_SELECT:
272 return AL_CC_CONFIG;
273 case KC_MAIL:
274 return AL_EMAIL;
275 case KC_CALCULATOR:
276 return AL_CALCULATOR;
277 case KC_MY_COMPUTER:
278 return AL_LOCAL_BROWSER;
279 case KC_WWW_SEARCH:
280 return AC_SEARCH;
281 case KC_WWW_HOME:
282 return AC_HOME;
283 case KC_WWW_BACK:
284 return AC_BACK;
285 case KC_WWW_FORWARD:
286 return AC_FORWARD;
287 case KC_WWW_STOP:
288 return AC_STOP;
289 case KC_WWW_REFRESH:
290 return AC_REFRESH;
291 case KC_BRIGHTNESS_UP:
292 return BRIGHTNESS_UP;
293 case KC_BRIGHTNESS_DOWN:
294 return BRIGHTNESS_DOWN;
295 case KC_WWW_FAVORITES:
296 return AC_BOOKMARKS;
297 default:
298 return 0;
299 }
300}
301
302uint8_t has_anykey(report_keyboard_t* keyboard_report);
303uint8_t get_first_key(report_keyboard_t* keyboard_report);
304bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key);
305
306void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
307void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
308#ifdef NKRO_ENABLE
309void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
310void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
311#endif
312
313void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key);
314void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key);
315void clear_keys_from_report(report_keyboard_t* keyboard_report);
316
317#ifdef __cplusplus
318}
319#endif
diff --git a/tmk_core/common/suspend.h b/tmk_core/common/suspend.h
index 95845e4b6..081735f90 100644
--- a/tmk_core/common/suspend.h
+++ b/tmk_core/common/suspend.h
@@ -10,8 +10,10 @@ void suspend_wakeup_init(void);
10 10
11void suspend_wakeup_init_user(void); 11void suspend_wakeup_init_user(void);
12void suspend_wakeup_init_kb(void); 12void suspend_wakeup_init_kb(void);
13void suspend_wakeup_init_quantum(void);
13void suspend_power_down_user(void); 14void suspend_power_down_user(void);
14void suspend_power_down_kb(void); 15void suspend_power_down_kb(void);
16void suspend_power_down_quantum(void);
15 17
16#ifndef USB_SUSPEND_WAKEUP_DELAY 18#ifndef USB_SUSPEND_WAKEUP_DELAY
17# define USB_SUSPEND_WAKEUP_DELAY 0 19# define USB_SUSPEND_WAKEUP_DELAY 0
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c
deleted file mode 100644
index 68b92d8b4..000000000
--- a/tmk_core/common/sync_timer.c
+++ /dev/null
@@ -1,58 +0,0 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#include "sync_timer.h"
27#include "keyboard.h"
28
29#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER)
30volatile int32_t sync_timer_ms;
31
32void sync_timer_init(void) { sync_timer_ms = 0; }
33
34void sync_timer_update(uint32_t time) {
35 if (is_keyboard_master()) return;
36 sync_timer_ms = time - timer_read32();
37}
38
39uint16_t sync_timer_read(void) {
40 if (is_keyboard_master()) return timer_read();
41 return sync_timer_read32();
42}
43
44uint32_t sync_timer_read32(void) {
45 if (is_keyboard_master()) return timer_read32();
46 return sync_timer_ms + timer_read32();
47}
48
49uint16_t sync_timer_elapsed(uint16_t last) {
50 if (is_keyboard_master()) return timer_elapsed(last);
51 return TIMER_DIFF_16(sync_timer_read(), last);
52}
53
54uint32_t sync_timer_elapsed32(uint32_t last) {
55 if (is_keyboard_master()) return timer_elapsed32(last);
56 return TIMER_DIFF_32(sync_timer_read32(), last);
57}
58#endif
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
deleted file mode 100644
index 744e2b50d..000000000
--- a/tmk_core/common/sync_timer.h
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2Copyright (C) 2020 Ryan Caltabiano <https://github.com/XScorpion2>
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to
7use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8of the Software, and to permit persons to whom the Software is furnished to do
9so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all
12copies or substantial portions of the Software.
13
14If you happen to meet one of the copyright holders in a bar you are obligated
15to buy them one pint of beer.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24*/
25
26#pragma once
27
28#include <stdint.h>
29#include "timer.h"
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#if (defined(SPLIT_KEYBOARD) || defined(SERIAL_LINK_ENABLE)) && !defined(DISABLE_SYNC_TIMER)
36void sync_timer_init(void);
37void sync_timer_update(uint32_t time);
38uint16_t sync_timer_read(void);
39uint32_t sync_timer_read32(void);
40uint16_t sync_timer_elapsed(uint16_t last);
41uint32_t sync_timer_elapsed32(uint32_t last);
42#else
43# define sync_timer_init()
44# define sync_timer_clear()
45# define sync_timer_update(t)
46# define sync_timer_read() timer_read()
47# define sync_timer_read32() timer_read32()
48# define sync_timer_elapsed(t) timer_elapsed(t)
49# define sync_timer_elapsed32(t) timer_elapsed32(t)
50#endif
51
52#ifdef __cplusplus
53}
54#endif
diff --git a/tmk_core/common/test/rules.mk b/tmk_core/common/test/rules.mk
index 48632a095..73d2302da 100644
--- a/tmk_core/common/test/rules.mk
+++ b/tmk_core/common/test/rules.mk
@@ -16,6 +16,7 @@ eeprom_stm32_tiny_INC := $(eeprom_stm32_INC)
16eeprom_stm32_large_INC := $(eeprom_stm32_INC) 16eeprom_stm32_large_INC := $(eeprom_stm32_INC)
17 17
18eeprom_stm32_SRC := \ 18eeprom_stm32_SRC := \
19 $(TOP_DIR)/drivers/eeprom/eeprom_driver.c \
19 $(TMK_PATH)/common/test/eeprom_stm32_tests.cpp \ 20 $(TMK_PATH)/common/test/eeprom_stm32_tests.cpp \
20 $(TMK_PATH)/common/test/flash_stm32_mock.c \ 21 $(TMK_PATH)/common/test/flash_stm32_mock.c \
21 $(TMK_PATH)/common/chibios/eeprom_stm32.c 22 $(TMK_PATH)/common/chibios/eeprom_stm32.c
diff --git a/tmk_core/common/usb_util.c b/tmk_core/common/usb_util.c
deleted file mode 100644
index dd1deeaa1..000000000
--- a/tmk_core/common/usb_util.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#include "quantum.h"
17#include "usb_util.h"
18
19__attribute__((weak)) void usb_disconnect(void) {}
20__attribute__((weak)) bool usb_connected_state(void) { return true; }
21__attribute__((weak)) bool usb_vbus_state(void) {
22#ifdef USB_VBUS_PIN
23 setPinInput(USB_VBUS_PIN);
24 wait_us(5);
25 return readPin(USB_VBUS_PIN);
26#else
27 return true;
28#endif
29}
diff --git a/tmk_core/common/usb_util.h b/tmk_core/common/usb_util.h
deleted file mode 100644
index 13db9fbfb..000000000
--- a/tmk_core/common/usb_util.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/* Copyright 2021 QMK
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16#pragma once
17
18#include <stdbool.h>
19
20void usb_disconnect(void);
21bool usb_connected_state(void);
22bool usb_vbus_state(void);
diff --git a/tmk_core/common/virtser.h b/tmk_core/common/virtser.h
deleted file mode 100644
index a0645f9e0..000000000
--- a/tmk_core/common/virtser.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#pragma once
2
3/* Define this function in your code to process incoming bytes */
4void virtser_recv(const uint8_t ch);
5
6/* Call this to send a character over the Virtual Serial Device */
7void virtser_send(const uint8_t byte);