aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/action.c38
-rw-r--r--tmk_core/common/action.h4
-rw-r--r--tmk_core/common/action_layer.c23
-rw-r--r--tmk_core/common/action_layer.h8
-rw-r--r--tmk_core/common/arm_atsam/bootloader.c51
-rw-r--r--tmk_core/common/arm_atsam/eeprom.c98
-rw-r--r--tmk_core/common/arm_atsam/printf.c66
-rw-r--r--tmk_core/common/arm_atsam/printf.h11
-rw-r--r--tmk_core/common/arm_atsam/suspend.c85
-rw-r--r--tmk_core/common/arm_atsam/timer.c59
-rw-r--r--tmk_core/common/avr/suspend.c41
-rw-r--r--tmk_core/common/backlight.c51
-rw-r--r--tmk_core/common/backlight.h7
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.c673
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.h95
-rw-r--r--tmk_core/common/chibios/eeprom_teensy.c (renamed from tmk_core/common/chibios/eeprom.c)0
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.c188
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.h53
-rw-r--r--tmk_core/common/command.c4
-rw-r--r--tmk_core/common/command.h5
-rw-r--r--tmk_core/common/eeconfig.c112
-rw-r--r--tmk_core/common/eeconfig.h44
-rw-r--r--tmk_core/common/host.c22
-rw-r--r--tmk_core/common/keyboard.c24
-rw-r--r--tmk_core/common/keyboard.h2
-rw-r--r--tmk_core/common/keycode.h816
-rw-r--r--tmk_core/common/print.h42
-rw-r--r--tmk_core/common/report.c21
-rw-r--r--tmk_core/common/report.h52
29 files changed, 2198 insertions, 497 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index f7c039f45..b99c2acaa 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -120,7 +120,7 @@ void process_hand_swap(keyevent_t *event) {
120} 120}
121#endif 121#endif
122 122
123#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 123#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
124bool disable_action_cache = false; 124bool disable_action_cache = false;
125 125
126void process_record_nocache(keyrecord_t *record) 126void process_record_nocache(keyrecord_t *record)
@@ -773,6 +773,13 @@ void register_code(uint8_t code)
773 else if IS_CONSUMER(code) { 773 else if IS_CONSUMER(code) {
774 host_consumer_send(KEYCODE2CONSUMER(code)); 774 host_consumer_send(KEYCODE2CONSUMER(code));
775 } 775 }
776
777 #ifdef MOUSEKEY_ENABLE
778 else if IS_MOUSEKEY(code) {
779 mousekey_on(code);
780 mousekey_send();
781 }
782 #endif
776} 783}
777 784
778/** \brief Utilities for actions. (FIXME: Needs better description) 785/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -832,6 +839,24 @@ void unregister_code(uint8_t code)
832 else if IS_CONSUMER(code) { 839 else if IS_CONSUMER(code) {
833 host_consumer_send(0); 840 host_consumer_send(0);
834 } 841 }
842 #ifdef MOUSEKEY_ENABLE
843 else if IS_MOUSEKEY(code) {
844 mousekey_off(code);
845 mousekey_send();
846 }
847 #endif
848}
849
850/** \brief Utilities for actions. (FIXME: Needs better description)
851 *
852 * FIXME: Needs documentation.
853 */
854void tap_code(uint8_t code) {
855 register_code(code);
856 #if TAP_CODE_DELAY > 0
857 wait_ms(TAP_CODE_DELAY);
858 #endif
859 unregister_code(code);
835} 860}
836 861
837/** \brief Utilities for actions. (FIXME: Needs better description) 862/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -874,9 +899,18 @@ void clear_keyboard(void)
874 */ 899 */
875void clear_keyboard_but_mods(void) 900void clear_keyboard_but_mods(void)
876{ 901{
902 clear_keys();
903 clear_keyboard_but_mods_and_keys();
904}
905
906/** \brief Utilities for actions. (FIXME: Needs better description)
907 *
908 * FIXME: Needs documentation.
909 */
910void clear_keyboard_but_mods_and_keys()
911{
877 clear_weak_mods(); 912 clear_weak_mods();
878 clear_macro_mods(); 913 clear_macro_mods();
879 clear_keys();
880 send_keyboard_report(); 914 send_keyboard_report();
881#ifdef MOUSEKEY_ENABLE 915#ifdef MOUSEKEY_ENABLE
882 mousekey_clear(); 916 mousekey_clear();
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index acc55c7d3..8e47e5339 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);
62bool process_record_quantum(keyrecord_t *record); 62bool process_record_quantum(keyrecord_t *record);
63 63
64/* Utilities for actions. */ 64/* Utilities for actions. */
65#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 65#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
66extern bool disable_action_cache; 66extern bool disable_action_cache;
67#endif 67#endif
68 68
@@ -88,11 +88,13 @@ void process_record(keyrecord_t *record);
88void process_action(keyrecord_t *record, action_t action); 88void process_action(keyrecord_t *record, action_t action);
89void register_code(uint8_t code); 89void register_code(uint8_t code);
90void unregister_code(uint8_t code); 90void unregister_code(uint8_t code);
91void tap_code(uint8_t code);
91void register_mods(uint8_t mods); 92void register_mods(uint8_t mods);
92void unregister_mods(uint8_t mods); 93void unregister_mods(uint8_t mods);
93//void set_mods(uint8_t mods); 94//void set_mods(uint8_t mods);
94void clear_keyboard(void); 95void clear_keyboard(void);
95void clear_keyboard_but_mods(void); 96void clear_keyboard_but_mods(void);
97void clear_keyboard_but_mods_and_keys(void);
96void layer_switch(uint8_t new_layer); 98void layer_switch(uint8_t new_layer);
97bool is_tap_key(keypos_t key); 99bool is_tap_key(keypos_t key);
98 100
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index f3cd381ab..120ce3f51 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -15,13 +15,22 @@
15 */ 15 */
16uint32_t default_layer_state = 0; 16uint32_t default_layer_state = 0;
17 17
18/** \brief Default Layer State Set At user Level
19 *
20 * FIXME: Needs docs
21 */
22__attribute__((weak))
23uint32_t default_layer_state_set_user(uint32_t state) {
24 return state;
25}
26
18/** \brief Default Layer State Set At Keyboard Level 27/** \brief Default Layer State Set At Keyboard Level
19 * 28 *
20 * FIXME: Needs docs 29 * FIXME: Needs docs
21 */ 30 */
22__attribute__((weak)) 31__attribute__((weak))
23uint32_t default_layer_state_set_kb(uint32_t state) { 32uint32_t default_layer_state_set_kb(uint32_t state) {
24 return state; 33 return default_layer_state_set_user(state);
25} 34}
26 35
27/** \brief Default Layer State Set 36/** \brief Default Layer State Set
@@ -35,7 +44,11 @@ static void default_layer_state_set(uint32_t state)
35 default_layer_debug(); debug(" to "); 44 default_layer_debug(); debug(" to ");
36 default_layer_state = state; 45 default_layer_state = state;
37 default_layer_debug(); debug("\n"); 46 default_layer_debug(); debug("\n");
47#ifdef STRICT_LAYER_RELEASE
38 clear_keyboard_but_mods(); // To avoid stuck keys 48 clear_keyboard_but_mods(); // To avoid stuck keys
49#else
50 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
51#endif
39} 52}
40 53
41/** \brief Default Layer Print 54/** \brief Default Layer Print
@@ -118,7 +131,11 @@ void layer_state_set(uint32_t state)
118 layer_debug(); dprint(" to "); 131 layer_debug(); dprint(" to ");
119 layer_state = state; 132 layer_state = state;
120 layer_debug(); dprintln(); 133 layer_debug(); dprintln();
134#ifdef STRICT_LAYER_RELEASE
121 clear_keyboard_but_mods(); // To avoid stuck keys 135 clear_keyboard_but_mods(); // To avoid stuck keys
136#else
137 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
138#endif
122} 139}
123 140
124/** \brief Layer clear 141/** \brief Layer clear
@@ -219,7 +236,7 @@ void layer_debug(void)
219} 236}
220#endif 237#endif
221 238
222#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 239#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
223uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}}; 240uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
224 241
225void update_source_layers_cache(keypos_t key, uint8_t layer) 242void update_source_layers_cache(keypos_t key, uint8_t layer)
@@ -263,7 +280,7 @@ uint8_t read_source_layers_cache(keypos_t key)
263 */ 280 */
264action_t store_or_get_action(bool pressed, keypos_t key) 281action_t store_or_get_action(bool pressed, keypos_t key)
265{ 282{
266#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 283#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
267 if (disable_action_cache) { 284 if (disable_action_cache) {
268 return layer_switch_get_action(key); 285 return layer_switch_get_action(key);
269 } 286 }
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 72a6bd8f6..f1551d251 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);
31 31
32__attribute__((weak)) 32__attribute__((weak))
33uint32_t default_layer_state_set_kb(uint32_t state); 33uint32_t default_layer_state_set_kb(uint32_t state);
34__attribute__((weak))
35uint32_t default_layer_state_set_user(uint32_t state);
34 36
35#ifndef NO_ACTION_LAYER 37#ifndef NO_ACTION_LAYER
36/* bitwise operation */ 38/* bitwise operation */
@@ -80,15 +82,13 @@ void layer_xor(uint32_t state);
80#define layer_or(state) 82#define layer_or(state)
81#define layer_and(state) 83#define layer_and(state)
82#define layer_xor(state) 84#define layer_xor(state)
85#endif
83 86
84__attribute__((weak))
85uint32_t layer_state_set_user(uint32_t state); 87uint32_t layer_state_set_user(uint32_t state);
86__attribute__((weak))
87uint32_t layer_state_set_kb(uint32_t state); 88uint32_t layer_state_set_kb(uint32_t state);
88#endif
89 89
90/* pressed actions cache */ 90/* pressed actions cache */
91#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 91#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
92/* The number of bits needed to represent the layer number: log2(32). */ 92/* The number of bits needed to represent the layer number: log2(32). */
93#define MAX_LAYER_BITS 5 93#define MAX_LAYER_BITS 5
94void update_source_layers_cache(keypos_t key, uint8_t layer); 94void update_source_layers_cache(keypos_t key, uint8_t layer);
diff --git a/tmk_core/common/arm_atsam/bootloader.c b/tmk_core/common/arm_atsam/bootloader.c
new file mode 100644
index 000000000..ba71bfeb0
--- /dev/null
+++ b/tmk_core/common/arm_atsam/bootloader.c
@@ -0,0 +1,51 @@
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 "bootloader.h"
18#include "samd51j18a.h"
19#include "md_bootloader.h"
20
21//Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
22void bootloader_jump(void) {
23#ifdef KEYBOARD_massdrop_ctrl
24 //CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
25 uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; //The version to match (NULL terminated by compiler)
26 uint8_t *ver_check = ver_ram_method; //Pointer to version match string for traversal
27 uint8_t *ver_rom = (uint8_t *)0x21A0; //Pointer to address in ROM where this specific bootloader version would exist
28
29 while (*ver_check && *ver_rom == *ver_check) { //While there are check version characters to match and bootloader's version matches check's version
30 ver_check++; //Move check version pointer to next character
31 ver_rom++; //Move ROM version pointer to next character
32 }
33
34 if (!*ver_check) { //If check version pointer is NULL, all characters have matched
35 *MAGIC_ADDR = BOOTLOADER_MAGIC; //Set magic number into RAM
36 NVIC_SystemReset(); //Perform system reset
37 while (1) {} //Won't get here
38 }
39#endif
40
41 WDT->CTRLA.bit.ENABLE = 0;
42 while (WDT->SYNCBUSY.bit.ENABLE) {}
43 while (WDT->CTRLA.bit.ENABLE) {}
44 WDT->CONFIG.bit.WINDOW = 0;
45 WDT->CONFIG.bit.PER = 0;
46 WDT->EWCTRL.bit.EWOFFSET = 0;
47 WDT->CTRLA.bit.ENABLE = 1;
48 while (WDT->SYNCBUSY.bit.ENABLE) {}
49 while (!WDT->CTRLA.bit.ENABLE) {}
50 while (1) {} //Wait on timeout
51}
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 @@
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 "eeprom.h"
18
19#define EEPROM_SIZE 32
20
21static uint8_t buffer[EEPROM_SIZE];
22
23uint8_t eeprom_read_byte(const uint8_t *addr) {
24 uintptr_t offset = (uintptr_t)addr;
25 return buffer[offset];
26}
27
28void eeprom_write_byte(uint8_t *addr, uint8_t value) {
29 uintptr_t offset = (uintptr_t)addr;
30 buffer[offset] = value;
31}
32
33uint16_t eeprom_read_word(const uint16_t *addr) {
34 const uint8_t *p = (const uint8_t *)addr;
35 return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
36}
37
38uint32_t eeprom_read_dword(const uint32_t *addr) {
39 const uint8_t *p = (const uint8_t *)addr;
40 return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
41 | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
42}
43
44void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
45 const uint8_t *p = (const uint8_t *)addr;
46 uint8_t *dest = (uint8_t *)buf;
47 while (len--) {
48 *dest++ = eeprom_read_byte(p++);
49 }
50}
51
52void eeprom_write_word(uint16_t *addr, uint16_t value) {
53 uint8_t *p = (uint8_t *)addr;
54 eeprom_write_byte(p++, value);
55 eeprom_write_byte(p, value >> 8);
56}
57
58void eeprom_write_dword(uint32_t *addr, uint32_t value) {
59 uint8_t *p = (uint8_t *)addr;
60 eeprom_write_byte(p++, value);
61 eeprom_write_byte(p++, value >> 8);
62 eeprom_write_byte(p++, value >> 16);
63 eeprom_write_byte(p, value >> 24);
64}
65
66void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
67 uint8_t *p = (uint8_t *)addr;
68 const uint8_t *src = (const uint8_t *)buf;
69 while (len--) {
70 eeprom_write_byte(p++, *src++);
71 }
72}
73
74void eeprom_update_byte(uint8_t *addr, uint8_t value) {
75 eeprom_write_byte(addr, value);
76}
77
78void eeprom_update_word(uint16_t *addr, uint16_t value) {
79 uint8_t *p = (uint8_t *)addr;
80 eeprom_write_byte(p++, value);
81 eeprom_write_byte(p, value >> 8);
82}
83
84void eeprom_update_dword(uint32_t *addr, uint32_t value) {
85 uint8_t *p = (uint8_t *)addr;
86 eeprom_write_byte(p++, value);
87 eeprom_write_byte(p++, value >> 8);
88 eeprom_write_byte(p++, value >> 16);
89 eeprom_write_byte(p, value >> 24);
90}
91
92void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
93 uint8_t *p = (uint8_t *)addr;
94 const uint8_t *src = (const uint8_t *)buf;
95 while (len--) {
96 eeprom_write_byte(p++, *src++);
97 }
98}
diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c
new file mode 100644
index 000000000..7f298d1fd
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.c
@@ -0,0 +1,66 @@
1/*
2Copyright 2018 Massdrop Inc.
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#ifdef CONSOLE_ENABLE
19
20#include "samd51j18a.h"
21#include "arm_atsam_protocol.h"
22#include "printf.h"
23#include <string.h>
24#include <stdarg.h>
25
26void console_printf(char *fmt, ...) {
27 while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
28
29 static char console_printbuf[CONSOLE_PRINTBUF_SIZE]; //Print and send buffer
30 va_list va;
31 int result;
32
33 va_start(va, fmt);
34 result = vsnprintf(console_printbuf, CONSOLE_PRINTBUF_SIZE, fmt, va);
35 va_end(va);
36
37 uint32_t irqflags;
38 char *pconbuf = console_printbuf; //Pointer to start send from
39 int send_out = CONSOLE_EPSIZE; //Bytes to send per transfer
40
41 while (result > 0) { //While not error and bytes remain
42 while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
43
44 irqflags = __get_PRIMASK();
45 __disable_irq();
46 __DMB();
47
48 if (result < CONSOLE_EPSIZE) { //If remaining bytes are less than console epsize
49 memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); //Clear the buffer
50 send_out = result; //Send remaining size
51 }
52
53 memcpy(udi_hid_con_report, pconbuf, send_out); //Copy data into the send buffer
54
55 udi_hid_con_b_report_valid = 1; //Set report valid
56 udi_hid_con_send_report(); //Send report
57
58 __DMB();
59 __set_PRIMASK(irqflags);
60
61 result -= send_out; //Decrement result by bytes sent
62 pconbuf += send_out; //Increment buffer point by bytes sent
63 }
64}
65
66#endif //CONSOLE_ENABLE
diff --git a/tmk_core/common/arm_atsam/printf.h b/tmk_core/common/arm_atsam/printf.h
new file mode 100644
index 000000000..1f1c2280b
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.h
@@ -0,0 +1,11 @@
1#ifndef _PRINTF_H_
2#define _PRINTF_H_
3
4#define CONSOLE_PRINTBUF_SIZE 512
5
6void console_printf(char *fmt, ...);
7
8#define __xprintf console_printf
9
10#endif //_PRINTF_H_
11
diff --git a/tmk_core/common/arm_atsam/suspend.c b/tmk_core/common/arm_atsam/suspend.c
new file mode 100644
index 000000000..e34965df6
--- /dev/null
+++ b/tmk_core/common/arm_atsam/suspend.c
@@ -0,0 +1,85 @@
1#include "matrix.h"
2#include "i2c_master.h"
3#include "led_matrix.h"
4#include "suspend.h"
5
6/** \brief Suspend idle
7 *
8 * FIXME: needs doc
9 */
10void suspend_idle(uint8_t time) {
11 /* Note: Not used anywhere currently */
12}
13
14/** \brief Run user level Power down
15 *
16 * FIXME: needs doc
17 */
18__attribute__ ((weak))
19void suspend_power_down_user (void) {
20
21}
22
23/** \brief Run keyboard level Power down
24 *
25 * FIXME: needs doc
26 */
27__attribute__ ((weak))
28void suspend_power_down_kb(void) {
29 suspend_power_down_user();
30}
31
32/** \brief Suspend power down
33 *
34 * FIXME: needs doc
35 */
36void suspend_power_down(void)
37{
38 I2C3733_Control_Set(0); //Disable LED driver
39
40 suspend_power_down_kb();
41}
42
43__attribute__ ((weak)) void matrix_power_up(void) {}
44__attribute__ ((weak)) void matrix_power_down(void) {}
45bool suspend_wakeup_condition(void) {
46 matrix_power_up();
47 matrix_scan();
48 matrix_power_down();
49 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
50 if (matrix_get_row(r)) return true;
51 }
52 return false;
53}
54
55/** \brief run user level code immediately after wakeup
56 *
57 * FIXME: needs doc
58 */
59__attribute__ ((weak))
60void suspend_wakeup_init_user(void) {
61
62}
63
64/** \brief run keyboard level code immediately after wakeup
65 *
66 * FIXME: needs doc
67 */
68__attribute__ ((weak))
69void suspend_wakeup_init_kb(void) {
70 suspend_wakeup_init_user();
71}
72
73/** \brief run immediately after wakeup
74 *
75 * FIXME: needs doc
76 */
77void suspend_wakeup_init(void) {
78 /* If LEDs are set to enabled, enable the hardware */
79 if (led_enabled) {
80 I2C3733_Control_Set(1);
81 }
82
83 suspend_wakeup_init_kb();
84}
85
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 @@
1#include "samd51j18a.h"
2#include "timer.h"
3#include "tmk_core/protocol/arm_atsam/clks.h"
4
5void set_time(uint64_t tset)
6{
7 ms_clk = tset;
8}
9
10void timer_init(void)
11{
12 ms_clk = 0;
13}
14
15uint16_t timer_read(void)
16{
17 return (uint16_t)ms_clk;
18}
19
20uint32_t timer_read32(void)
21{
22 return (uint32_t)ms_clk;
23}
24
25uint64_t timer_read64(void)
26{
27 return ms_clk;
28}
29
30uint16_t timer_elapsed(uint16_t tlast)
31{
32 return TIMER_DIFF_16(timer_read(), tlast);
33}
34
35uint32_t timer_elapsed32(uint32_t tlast)
36{
37 return TIMER_DIFF_32(timer_read32(), tlast);
38}
39
40uint32_t timer_elapsed64(uint32_t tlast)
41{
42 uint64_t tnow = timer_read64();
43 return (tnow >= tlast ? tnow - tlast : UINT64_MAX - tlast + tnow);
44}
45
46void timer_clear(void)
47{
48 ms_clk = 0;
49}
50
51void wait_ms(uint64_t msec)
52{
53 CLK_delay_ms(msec);
54}
55
56void wait_us(uint16_t usec)
57{
58 CLK_delay_us(usec);
59}
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 3d4a48439..5bca64685 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -10,6 +10,7 @@
10#include "timer.h" 10#include "timer.h"
11#include "led.h" 11#include "led.h"
12#include "host.h" 12#include "host.h"
13#include "rgblight_reconfig.h"
13 14
14#ifdef PROTOCOL_LUFA 15#ifdef PROTOCOL_LUFA
15 #include "lufa.h" 16 #include "lufa.h"
@@ -55,6 +56,24 @@ void suspend_idle(uint8_t time)
55 sleep_disable(); 56 sleep_disable();
56} 57}
57 58
59
60// TODO: This needs some cleanup
61
62/** \brief Run keyboard level Power down
63 *
64 * FIXME: needs doc
65 */
66__attribute__ ((weak))
67void suspend_power_down_user (void) { }
68/** \brief Run keyboard level Power down
69 *
70 * FIXME: needs doc
71 */
72__attribute__ ((weak))
73void suspend_power_down_kb(void) {
74 suspend_power_down_user();
75}
76
58#ifndef NO_SUSPEND_POWER_DOWN 77#ifndef NO_SUSPEND_POWER_DOWN
59/** \brief Power down MCU with watchdog timer 78/** \brief Power down MCU with watchdog timer
60 * 79 *
@@ -72,21 +91,6 @@ void suspend_idle(uint8_t time)
72 */ 91 */
73static uint8_t wdt_timeout = 0; 92static uint8_t wdt_timeout = 0;
74 93
75/** \brief Run keyboard level Power down
76 *
77 * FIXME: needs doc
78 */
79__attribute__ ((weak))
80void suspend_power_down_user (void) { }
81/** \brief Run keyboard level Power down
82 *
83 * FIXME: needs doc
84 */
85__attribute__ ((weak))
86void suspend_power_down_kb(void) {
87 suspend_power_down_user();
88}
89
90/** \brief Power down 94/** \brief Power down
91 * 95 *
92 * FIXME: needs doc 96 * FIXME: needs doc
@@ -143,6 +147,8 @@ static void power_down(uint8_t wdto)
143 */ 147 */
144void suspend_power_down(void) 148void suspend_power_down(void)
145{ 149{
150 suspend_power_down_kb();
151
146#ifndef NO_SUSPEND_POWER_DOWN 152#ifndef NO_SUSPEND_POWER_DOWN
147 power_down(WDTO_15MS); 153 power_down(WDTO_15MS);
148#endif 154#endif
@@ -189,12 +195,15 @@ void suspend_wakeup_init(void)
189#endif 195#endif
190 led_set(host_keyboard_leds()); 196 led_set(host_keyboard_leds());
191#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) 197#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
198#ifdef BOOTLOADER_TEENSY
199 wait_ms(10);
200#endif
192 rgblight_enable_noeeprom(); 201 rgblight_enable_noeeprom();
193#ifdef RGBLIGHT_ANIMATIONS 202#ifdef RGBLIGHT_ANIMATIONS
194 rgblight_timer_enable(); 203 rgblight_timer_enable();
195#endif 204#endif
196#endif 205#endif
197 suspend_wakeup_init_kb(); 206 suspend_wakeup_init_kb();
198} 207}
199 208
200#ifndef NO_SUSPEND_POWER_DOWN 209#ifndef NO_SUSPEND_POWER_DOWN
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)
76 */ 76 */
77void backlight_toggle(void) 77void backlight_toggle(void)
78{ 78{
79 backlight_config.enable ^= 1; 79 bool enabled = backlight_config.enable;
80 if (backlight_config.raw == 1) // enabled but level = 0 80 dprintf("backlight toggle: %u\n", enabled);
81 backlight_config.level = 1; 81 if (enabled)
82 eeconfig_update_backlight(backlight_config.raw); 82 backlight_disable();
83 dprintf("backlight toggle: %u\n", backlight_config.enable); 83 else
84 backlight_set(backlight_config.enable ? backlight_config.level : 0); 84 backlight_enable();
85}
86
87/** \brief Enable backlight
88 *
89 * FIXME: needs doc
90 */
91void backlight_enable(void)
92{
93 if (backlight_config.enable) return; // do nothing if backlight is already on
94
95 backlight_config.enable = true;
96 if (backlight_config.raw == 1) // enabled but level == 0
97 backlight_config.level = 1;
98 eeconfig_update_backlight(backlight_config.raw);
99 dprintf("backlight enable\n");
100 backlight_set(backlight_config.level);
101}
102
103/** /brief Disable backlight
104 *
105 * FIXME: needs doc
106 */
107void backlight_disable(void)
108{
109 if (!backlight_config.enable) return; // do nothing if backlight is already off
110
111 backlight_config.enable = false;
112 eeconfig_update_backlight(backlight_config.raw);
113 dprintf("backlight disable\n");
114 backlight_set(0);
115}
116
117/** /brief Get the backlight status
118 *
119 * FIXME: needs doc
120 */
121bool is_backlight_enabled(void)
122{
123 return backlight_config.enable;
85} 124}
86 125
87/** \brief Backlight step through levels 126/** \brief Backlight step through levels
diff --git a/tmk_core/common/backlight.h b/tmk_core/common/backlight.h
index f57309267..420c9d19e 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
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#ifndef BACKLIGHT_H 18#pragma once
19#define BACKLIGHT_H
20 19
21#include <stdint.h> 20#include <stdint.h>
22#include <stdbool.h> 21#include <stdbool.h>
@@ -33,9 +32,11 @@ void backlight_init(void);
33void backlight_increase(void); 32void backlight_increase(void);
34void backlight_decrease(void); 33void backlight_decrease(void);
35void backlight_toggle(void); 34void backlight_toggle(void);
35void backlight_enable(void);
36void backlight_disable(void);
37bool is_backlight_enabled(void);
36void backlight_step(void); 38void backlight_step(void);
37void backlight_set(uint8_t level); 39void backlight_set(uint8_t level);
38void backlight_level(uint8_t level); 40void backlight_level(uint8_t level);
39uint8_t get_backlight_level(void); 41uint8_t get_backlight_level(void);
40 42
41#endif
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
new file mode 100755
index 000000000..a86998550
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -0,0 +1,673 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#include "eeprom_stm32.h"
20
21 FLASH_Status EE_ErasePage(uint32_t);
22
23 uint16_t EE_CheckPage(uint32_t, uint16_t);
24 uint16_t EE_CheckErasePage(uint32_t, uint16_t);
25 uint16_t EE_Format(void);
26 uint32_t EE_FindValidPage(void);
27 uint16_t EE_GetVariablesCount(uint32_t, uint16_t);
28 uint16_t EE_PageTransfer(uint32_t, uint32_t, uint16_t);
29 uint16_t EE_VerifyPageFullWriteVariable(uint16_t, uint16_t);
30
31 uint32_t PageBase0 = EEPROM_PAGE0_BASE;
32 uint32_t PageBase1 = EEPROM_PAGE1_BASE;
33 uint32_t PageSize = EEPROM_PAGE_SIZE;
34 uint16_t Status = EEPROM_NOT_INIT;
35
36// See http://www.st.com/web/en/resource/technical/document/application_note/CD00165693.pdf
37
38/**
39 * @brief Check page for blank
40 * @param page base address
41 * @retval Success or error
42 * EEPROM_BAD_FLASH: page not empty after erase
43 * EEPROM_OK: page blank
44 */
45uint16_t EE_CheckPage(uint32_t pageBase, uint16_t status)
46{
47 uint32_t pageEnd = pageBase + (uint32_t)PageSize;
48
49 // Page Status not EEPROM_ERASED and not a "state"
50 if ((*(__IO uint16_t*)pageBase) != EEPROM_ERASED && (*(__IO uint16_t*)pageBase) != status)
51 return EEPROM_BAD_FLASH;
52 for(pageBase += 4; pageBase < pageEnd; pageBase += 4)
53 if ((*(__IO uint32_t*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty
54 return EEPROM_BAD_FLASH;
55 return EEPROM_OK;
56}
57
58/**
59 * @brief Erase page with increment erase counter (page + 2)
60 * @param page base address
61 * @retval Success or error
62 * FLASH_COMPLETE: success erase
63 * - Flash error code: on write Flash error
64 */
65FLASH_Status EE_ErasePage(uint32_t pageBase)
66{
67 FLASH_Status FlashStatus;
68 uint16_t data = (*(__IO uint16_t*)(pageBase));
69 if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA))
70 data = (*(__IO uint16_t*)(pageBase + 2)) + 1;
71 else
72 data = 0;
73
74 FlashStatus = FLASH_ErasePage(pageBase);
75 if (FlashStatus == FLASH_COMPLETE)
76 FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data);
77
78 return FlashStatus;
79}
80
81/**
82 * @brief Check page for blank and erase it
83 * @param page base address
84 * @retval Success or error
85 * - Flash error code: on write Flash error
86 * - EEPROM_BAD_FLASH: page not empty after erase
87 * - EEPROM_OK: page blank
88 */
89uint16_t EE_CheckErasePage(uint32_t pageBase, uint16_t status)
90{
91 uint16_t FlashStatus;
92 if (EE_CheckPage(pageBase, status) != EEPROM_OK)
93 {
94 FlashStatus = EE_ErasePage(pageBase);
95 if (FlashStatus != FLASH_COMPLETE)
96 return FlashStatus;
97 return EE_CheckPage(pageBase, status);
98 }
99 return EEPROM_OK;
100}
101
102/**
103 * @brief Find valid Page for write or read operation
104 * @param Page0: Page0 base address
105 * Page1: Page1 base address
106 * @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found
107 */
108uint32_t EE_FindValidPage(void)
109{
110 uint16_t status0 = (*(__IO uint16_t*)PageBase0); // Get Page0 actual status
111 uint16_t status1 = (*(__IO uint16_t*)PageBase1); // Get Page1 actual status
112
113 if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED)
114 return PageBase0;
115 if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED)
116 return PageBase1;
117
118 return 0;
119}
120
121/**
122 * @brief Calculate unique variables in EEPROM
123 * @param start: address of first slot to check (page + 4)
124 * @param end: page end address
125 * @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF)
126 * @retval count of variables
127 */
128uint16_t EE_GetVariablesCount(uint32_t pageBase, uint16_t skipAddress)
129{
130 uint16_t varAddress, nextAddress;
131 uint32_t idx;
132 uint32_t pageEnd = pageBase + (uint32_t)PageSize;
133 uint16_t count = 0;
134
135 for (pageBase += 6; pageBase < pageEnd; pageBase += 4)
136 {
137 varAddress = (*(__IO uint16_t*)pageBase);
138 if (varAddress == 0xFFFF || varAddress == skipAddress)
139 continue;
140
141 count++;
142 for(idx = pageBase + 4; idx < pageEnd; idx += 4)
143 {
144 nextAddress = (*(__IO uint16_t*)idx);
145 if (nextAddress == varAddress)
146 {
147 count--;
148 break;
149 }
150 }
151 }
152 return count;
153}
154
155/**
156 * @brief Transfers last updated variables data from the full Page to an empty one.
157 * @param newPage: new page base address
158 * @param oldPage: old page base address
159 * @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF)
160 * @retval Success or error status:
161 * - FLASH_COMPLETE: on success
162 * - EEPROM_OUT_SIZE: if valid new page is full
163 * - Flash error code: on write Flash error
164 */
165uint16_t EE_PageTransfer(uint32_t newPage, uint32_t oldPage, uint16_t SkipAddress)
166{
167 uint32_t oldEnd, newEnd;
168 uint32_t oldIdx, newIdx, idx;
169 uint16_t address, data, found;
170 FLASH_Status FlashStatus;
171
172 // Transfer process: transfer variables from old to the new active page
173 newEnd = newPage + ((uint32_t)PageSize);
174
175 // Find first free element in new page
176 for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4)
177 if ((*(__IO uint32_t*)newIdx) == 0xFFFFFFFF) // Verify if element
178 break; // contents are 0xFFFFFFFF
179 if (newIdx >= newEnd)
180 return EEPROM_OUT_SIZE;
181
182 oldEnd = oldPage + 4;
183 oldIdx = oldPage + (uint32_t)(PageSize - 2);
184
185 for (; oldIdx > oldEnd; oldIdx -= 4)
186 {
187 address = *(__IO uint16_t*)oldIdx;
188 if (address == 0xFFFF || address == SkipAddress)
189 continue; // it's means that power off after write data
190
191 found = 0;
192 for (idx = newPage + 6; idx < newIdx; idx += 4)
193 if ((*(__IO uint16_t*)(idx)) == address)
194 {
195 found = 1;
196 break;
197 }
198
199 if (found)
200 continue;
201
202 if (newIdx < newEnd)
203 {
204 data = (*(__IO uint16_t*)(oldIdx - 2));
205
206 FlashStatus = FLASH_ProgramHalfWord(newIdx, data);
207 if (FlashStatus != FLASH_COMPLETE)
208 return FlashStatus;
209
210 FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address);
211 if (FlashStatus != FLASH_COMPLETE)
212 return FlashStatus;
213
214 newIdx += 4;
215 }
216 else
217 return EEPROM_OUT_SIZE;
218 }
219
220 // Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status
221 data = EE_CheckErasePage(oldPage, EEPROM_ERASED);
222 if (data != EEPROM_OK)
223 return data;
224
225 // Set new Page status
226 FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE);
227 if (FlashStatus != FLASH_COMPLETE)
228 return FlashStatus;
229
230 return EEPROM_OK;
231}
232
233/**
234 * @brief Verify if active page is full and Writes variable in EEPROM.
235 * @param Address: 16 bit virtual address of the variable
236 * @param Data: 16 bit data to be written as variable value
237 * @retval Success or error status:
238 * - FLASH_COMPLETE: on success
239 * - EEPROM_PAGE_FULL: if valid page is full (need page transfer)
240 * - EEPROM_NO_VALID_PAGE: if no valid page was found
241 * - EEPROM_OUT_SIZE: if EEPROM size exceeded
242 * - Flash error code: on write Flash error
243 */
244uint16_t EE_VerifyPageFullWriteVariable(uint16_t Address, uint16_t Data)
245{
246 FLASH_Status FlashStatus;
247 uint32_t idx, pageBase, pageEnd, newPage;
248 uint16_t count;
249
250 // Get valid Page for write operation
251 pageBase = EE_FindValidPage();
252 if (pageBase == 0)
253 return EEPROM_NO_VALID_PAGE;
254
255 // Get the valid Page end Address
256 pageEnd = pageBase + PageSize; // Set end of page
257
258 for (idx = pageEnd - 2; idx > pageBase; idx -= 4)
259 {
260 if ((*(__IO uint16_t*)idx) == Address) // Find last value for address
261 {
262 count = (*(__IO uint16_t*)(idx - 2)); // Read last data
263 if (count == Data)
264 return EEPROM_OK;
265 if (count == 0xFFFF)
266 {
267 FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data
268 if (FlashStatus == FLASH_COMPLETE)
269 return EEPROM_OK;
270 }
271 break;
272 }
273 }
274
275 // Check each active page address starting from begining
276 for (idx = pageBase + 4; idx < pageEnd; idx += 4)
277 if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
278 { // contents are 0xFFFFFFFF
279 FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data
280 if (FlashStatus != FLASH_COMPLETE)
281 return FlashStatus;
282 FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address
283 if (FlashStatus != FLASH_COMPLETE)
284 return FlashStatus;
285 return EEPROM_OK;
286 }
287
288 // Empty slot not found, need page transfer
289 // Calculate unique variables in page
290 count = EE_GetVariablesCount(pageBase, Address) + 1;
291 if (count >= (PageSize / 4 - 1))
292 return EEPROM_OUT_SIZE;
293
294 if (pageBase == PageBase1)
295 newPage = PageBase0; // New page address where variable will be moved to
296 else
297 newPage = PageBase1;
298
299 // Set the new Page status to RECEIVE_DATA status
300 FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA);
301 if (FlashStatus != FLASH_COMPLETE)
302 return FlashStatus;
303
304 // Write the variable passed as parameter in the new active page
305 FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data);
306 if (FlashStatus != FLASH_COMPLETE)
307 return FlashStatus;
308
309 FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address);
310 if (FlashStatus != FLASH_COMPLETE)
311 return FlashStatus;
312
313 return EE_PageTransfer(newPage, pageBase, Address);
314}
315
316/*EEPROMClass::EEPROMClass(void)
317{
318 PageBase0 = EEPROM_PAGE0_BASE;
319 PageBase1 = EEPROM_PAGE1_BASE;
320 PageSize = EEPROM_PAGE_SIZE;
321 Status = EEPROM_NOT_INIT;
322}*/
323/*
324uint16_t EEPROM_init(uint32_t pageBase0, uint32_t pageBase1, uint32_t pageSize)
325{
326 PageBase0 = pageBase0;
327 PageBase1 = pageBase1;
328 PageSize = pageSize;
329 return EEPROM_init();
330}*/
331
332uint16_t EEPROM_init(void)
333{
334 uint16_t status0 = 6, status1 = 6;
335 FLASH_Status FlashStatus;
336
337 FLASH_Unlock();
338 Status = EEPROM_NO_VALID_PAGE;
339
340 status0 = (*(__IO uint16_t *)PageBase0);
341 status1 = (*(__IO uint16_t *)PageBase1);
342
343 switch (status0)
344 {
345/*
346 Page0 Page1
347 ----- -----
348 EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased
349 EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased
350 EEPROM_ERASED make EE_Format
351 any Error: EEPROM_NO_VALID_PAGE
352*/
353 case EEPROM_ERASED:
354 if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid
355 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
356 else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive
357 {
358 FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
359 if (FlashStatus != FLASH_COMPLETE)
360 Status = FlashStatus;
361 else
362 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
363 }
364 else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM
365 Status = EEPROM_format();
366 break;
367/*
368 Page0 Page1
369 ----- -----
370 EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0
371 EEPROM_ERASED Page0 need set to valid, Page1 erased
372 any EEPROM_NO_VALID_PAGE
373*/
374 case EEPROM_RECEIVE_DATA:
375 if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid
376 Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF);
377 else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased
378 {
379 Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
380 if (Status == EEPROM_OK)
381 {
382 FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
383 if (FlashStatus != FLASH_COMPLETE)
384 Status = FlashStatus;
385 else
386 Status = EEPROM_OK;
387 }
388 }
389 break;
390/*
391 Page0 Page1
392 ----- -----
393 EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE
394 EEPROM_RECEIVE_DATA Transfer Page0 to Page1
395 any Page0 valid, Page1 erased
396*/
397 case EEPROM_VALID_PAGE:
398 if (status1 == EEPROM_VALID_PAGE) // Both pages valid
399 Status = EEPROM_NO_VALID_PAGE;
400 else if (status1 == EEPROM_RECEIVE_DATA)
401 Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF);
402 else
403 Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
404 break;
405/*
406 Page0 Page1
407 ----- -----
408 any EEPROM_VALID_PAGE Page1 valid, Page0 erased
409 EEPROM_RECEIVE_DATA Page1 valid, Page0 erased
410 any EEPROM_NO_VALID_PAGE
411*/
412 default:
413 if (status1 == EEPROM_VALID_PAGE)
414 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0
415 else if (status1 == EEPROM_RECEIVE_DATA)
416 {
417 FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
418 if (FlashStatus != FLASH_COMPLETE)
419 Status = FlashStatus;
420 else
421 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
422 }
423 break;
424 }
425 return Status;
426}
427
428/**
429 * @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0
430 * @param PAGE0 and PAGE1 base addresses
431 * @retval Status of the last operation (Flash write or erase) done during EEPROM formating
432 */
433uint16_t EEPROM_format(void)
434{
435 uint16_t status;
436 FLASH_Status FlashStatus;
437
438 FLASH_Unlock();
439
440 // Erase Page0
441 status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE);
442 if (status != EEPROM_OK)
443 return status;
444 if ((*(__IO uint16_t*)PageBase0) == EEPROM_ERASED)
445 {
446 // Set Page0 as valid page: Write VALID_PAGE at Page0 base address
447 FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
448 if (FlashStatus != FLASH_COMPLETE)
449 return FlashStatus;
450 }
451 // Erase Page1
452 return EE_CheckErasePage(PageBase1, EEPROM_ERASED);
453}
454
455/**
456 * @brief Returns the erase counter for current page
457 * @param Data: Global variable contains the read variable value
458 * @retval Success or error status:
459 * - EEPROM_OK: if erases counter return.
460 * - EEPROM_NO_VALID_PAGE: if no valid page was found.
461 */
462uint16_t EEPROM_erases(uint16_t *Erases)
463{
464 uint32_t pageBase;
465 if (Status != EEPROM_OK)
466 if (EEPROM_init() != EEPROM_OK)
467 return Status;
468
469 // Get active Page for read operation
470 pageBase = EE_FindValidPage();
471 if (pageBase == 0)
472 return EEPROM_NO_VALID_PAGE;
473
474 *Erases = (*(__IO uint16_t*)pageBase+2);
475 return EEPROM_OK;
476}
477
478/**
479 * @brief Returns the last stored variable data, if found,
480 * which correspond to the passed virtual address
481 * @param Address: Variable virtual address
482 * @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors
483 */
484/*
485uint16_t EEPROM_read (uint16_t Address)
486{
487 uint16_t data;
488 EEPROM_read(Address, &data);
489 return data;
490}*/
491
492/**
493 * @brief Returns the last stored variable data, if found,
494 * which correspond to the passed virtual address
495 * @param Address: Variable virtual address
496 * @param Data: Pointer to data variable
497 * @retval Success or error status:
498 * - EEPROM_OK: if variable was found
499 * - EEPROM_BAD_ADDRESS: if the variable was not found
500 * - EEPROM_NO_VALID_PAGE: if no valid page was found.
501 */
502uint16_t EEPROM_read(uint16_t Address, uint16_t *Data)
503{
504 uint32_t pageBase, pageEnd;
505
506 // Set default data (empty EEPROM)
507 *Data = EEPROM_DEFAULT_DATA;
508
509 if (Status == EEPROM_NOT_INIT)
510 if (EEPROM_init() != EEPROM_OK)
511 return Status;
512
513 // Get active Page for read operation
514 pageBase = EE_FindValidPage();
515 if (pageBase == 0)
516 return EEPROM_NO_VALID_PAGE;
517
518 // Get the valid Page end Address
519 pageEnd = pageBase + ((uint32_t)(PageSize - 2));
520
521 // Check each active page address starting from end
522 for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
523 if ((*(__IO uint16_t*)pageEnd) == Address) // Compare the read address with the virtual address
524 {
525 *Data = (*(__IO uint16_t*)(pageEnd - 2)); // Get content of Address-2 which is variable value
526 return EEPROM_OK;
527 }
528
529 // Return ReadStatus value: (0: variable exist, 1: variable doesn't exist)
530 return EEPROM_BAD_ADDRESS;
531}
532
533/**
534 * @brief Writes/upadtes variable data in EEPROM.
535 * @param VirtAddress: Variable virtual address
536 * @param Data: 16 bit data to be written
537 * @retval Success or error status:
538 * - FLASH_COMPLETE: on success
539 * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
540 * - EEPROM_PAGE_FULL: if valid page is full
541 * - EEPROM_NO_VALID_PAGE: if no valid page was found
542 * - EEPROM_OUT_SIZE: if no empty EEPROM variables
543 * - Flash error code: on write Flash error
544 */
545uint16_t EEPROM_write(uint16_t Address, uint16_t Data)
546{
547 if (Status == EEPROM_NOT_INIT)
548 if (EEPROM_init() != EEPROM_OK)
549 return Status;
550
551 if (Address == 0xFFFF)
552 return EEPROM_BAD_ADDRESS;
553
554 // Write the variable virtual address and value in the EEPROM
555 uint16_t status = EE_VerifyPageFullWriteVariable(Address, Data);
556 return status;
557}
558
559/**
560 * @brief Writes/upadtes variable data in EEPROM.
561 The value is written only if differs from the one already saved at the same address.
562 * @param VirtAddress: Variable virtual address
563 * @param Data: 16 bit data to be written
564 * @retval Success or error status:
565 * - EEPROM_SAME_VALUE: If new Data matches existing EEPROM Data
566 * - FLASH_COMPLETE: on success
567 * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
568 * - EEPROM_PAGE_FULL: if valid page is full
569 * - EEPROM_NO_VALID_PAGE: if no valid page was found
570 * - EEPROM_OUT_SIZE: if no empty EEPROM variables
571 * - Flash error code: on write Flash error
572 */
573uint16_t EEPROM_update(uint16_t Address, uint16_t Data)
574{
575 uint16_t temp;
576 EEPROM_read(Address, &temp);
577 if (temp == Data)
578 return EEPROM_SAME_VALUE;
579 else
580 return EEPROM_write(Address, Data);
581}
582
583/**
584 * @brief Return number of variable
585 * @retval Number of variables
586 */
587uint16_t EEPROM_count(uint16_t *Count)
588{
589 if (Status == EEPROM_NOT_INIT)
590 if (EEPROM_init() != EEPROM_OK)
591 return Status;
592
593 // Get valid Page for write operation
594 uint32_t pageBase = EE_FindValidPage();
595 if (pageBase == 0)
596 return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers
597
598 *Count = EE_GetVariablesCount(pageBase, 0xFFFF);
599 return EEPROM_OK;
600}
601
602uint16_t EEPROM_maxcount(void)
603{
604 return ((PageSize / 4)-1);
605}
606
607
608uint8_t eeprom_read_byte (const uint8_t *Address)
609{
610 const uint16_t p = (const uint32_t) Address;
611 uint16_t temp;
612 EEPROM_read(p, &temp);
613 return (uint8_t) temp;
614}
615
616void eeprom_write_byte (uint8_t *Address, uint8_t Value)
617{
618 uint16_t p = (uint32_t) Address;
619 EEPROM_write(p, (uint16_t) Value);
620}
621
622void eeprom_update_byte (uint8_t *Address, uint8_t Value)
623{
624 uint16_t p = (uint32_t) Address;
625 EEPROM_update(p, (uint16_t) Value);
626}
627
628uint16_t eeprom_read_word (const uint16_t *Address)
629{
630 const uint16_t p = (const uint32_t) Address;
631 uint16_t temp;
632 EEPROM_read(p, &temp);
633 return temp;
634}
635
636void eeprom_write_word (uint16_t *Address, uint16_t Value)
637{
638 uint16_t p = (uint32_t) Address;
639 EEPROM_write(p, Value);
640}
641
642void eeprom_update_word (uint16_t *Address, uint16_t Value)
643{
644 uint16_t p = (uint32_t) Address;
645 EEPROM_update(p, Value);
646}
647
648uint32_t eeprom_read_dword (const uint32_t *Address)
649{
650 const uint16_t p = (const uint32_t) Address;
651 uint16_t temp1, temp2;
652 EEPROM_read(p, &temp1);
653 EEPROM_read(p + 1, &temp2);
654 return temp1 | (temp2 << 16);
655}
656
657void eeprom_write_dword (uint32_t *Address, uint32_t Value)
658{
659 uint16_t temp = (uint16_t) Value;
660 uint16_t p = (uint32_t) Address;
661 EEPROM_write(p, temp);
662 temp = (uint16_t) (Value >> 16);
663 EEPROM_write(p + 1, temp);
664}
665
666void eeprom_update_dword (uint32_t *Address, uint32_t Value)
667{
668 uint16_t temp = (uint16_t) Value;
669 uint16_t p = (uint32_t) Address;
670 EEPROM_update(p, temp);
671 temp = (uint16_t) (Value >> 16);
672 EEPROM_update(p + 1, temp);
673}
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h
new file mode 100755
index 000000000..09229530c
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.h
@@ -0,0 +1,95 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19// This file must be modified if the MCU is not defined below.
20// This library also assumes that the pages are not used by the firmware.
21
22#ifndef __EEPROM_H
23#define __EEPROM_H
24
25#include "ch.h"
26#include "hal.h"
27#include "flash_stm32.h"
28
29// HACK ALERT. This definition may not match your processor
30// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
31#if defined(EEPROM_EMU_STM32F303xC)
32 #define MCU_STM32F303CC
33#elif defined(EEPROM_EMU_STM32F103xB)
34 #define MCU_STM32F103RB
35#else
36 #error "not implemented."
37#endif
38
39#ifndef EEPROM_PAGE_SIZE
40 #if defined (MCU_STM32F103RB)
41 #define EEPROM_PAGE_SIZE (uint16_t)0x400 /* Page size = 1KByte */
42 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC)
43 #define EEPROM_PAGE_SIZE (uint16_t)0x800 /* Page size = 2KByte */
44 #else
45 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
46 #endif
47#endif
48
49#ifndef EEPROM_START_ADDRESS
50 #if defined (MCU_STM32F103RB)
51 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 128 * 1024 - 2 * EEPROM_PAGE_SIZE))
52 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
53 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE))
54 #elif defined (MCU_STM32F103RD)
55 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE))
56 #elif defined (MCU_STM32F303CC)
57 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE))
58 #else
59 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
60 #endif
61#endif
62
63/* Pages 0 and 1 base and end addresses */
64#define EEPROM_PAGE0_BASE ((uint32_t)(EEPROM_START_ADDRESS + 0x000))
65#define EEPROM_PAGE1_BASE ((uint32_t)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE))
66
67/* Page status definitions */
68#define EEPROM_ERASED ((uint16_t)0xFFFF) /* PAGE is empty */
69#define EEPROM_RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */
70#define EEPROM_VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
71
72/* Page full define */
73enum uint16_t
74 {
75 EEPROM_OK = ((uint16_t)0x0000),
76 EEPROM_OUT_SIZE = ((uint16_t)0x0081),
77 EEPROM_BAD_ADDRESS = ((uint16_t)0x0082),
78 EEPROM_BAD_FLASH = ((uint16_t)0x0083),
79 EEPROM_NOT_INIT = ((uint16_t)0x0084),
80 EEPROM_SAME_VALUE = ((uint16_t)0x0085),
81 EEPROM_NO_VALID_PAGE = ((uint16_t)0x00AB)
82 };
83
84#define EEPROM_DEFAULT_DATA 0xFFFF
85
86 uint16_t EEPROM_init(void);
87 uint16_t EEPROM_format(void);
88 uint16_t EEPROM_erases(uint16_t *);
89 uint16_t EEPROM_read (uint16_t address, uint16_t *data);
90 uint16_t EEPROM_write(uint16_t address, uint16_t data);
91 uint16_t EEPROM_update(uint16_t address, uint16_t data);
92 uint16_t EEPROM_count(uint16_t *);
93 uint16_t EEPROM_maxcount(void);
94
95#endif /* __EEPROM_H */
diff --git a/tmk_core/common/chibios/eeprom.c b/tmk_core/common/chibios/eeprom_teensy.c
index 9061b790c..9061b790c 100644
--- a/tmk_core/common/chibios/eeprom.c
+++ b/tmk_core/common/chibios/eeprom_teensy.c
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c
new file mode 100755
index 000000000..273593484
--- /dev/null
+++ b/tmk_core/common/chibios/flash_stm32.c
@@ -0,0 +1,188 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#if defined(EEPROM_EMU_STM32F303xC)
20 #define STM32F303xC
21 #include "stm32f3xx.h"
22#elif defined(EEPROM_EMU_STM32F103xB)
23 #define STM32F103xB
24 #include "stm32f1xx.h"
25#else
26 #error "not implemented."
27#endif
28
29#include "flash_stm32.h"
30
31#if defined(EEPROM_EMU_STM32F103xB)
32 #define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
33#endif
34
35/* Delay definition */
36#define EraseTimeout ((uint32_t)0x00000FFF)
37#define ProgramTimeout ((uint32_t)0x0000001F)
38
39#define ASSERT(exp) (void)((0))
40
41/**
42 * @brief Inserts a time delay.
43 * @param None
44 * @retval None
45 */
46static void delay(void)
47{
48 __IO uint32_t i = 0;
49 for(i = 0xFF; i != 0; i--) { }
50}
51
52/**
53 * @brief Returns the FLASH Status.
54 * @param None
55 * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
56 * FLASH_ERROR_WRP or FLASH_COMPLETE
57 */
58FLASH_Status FLASH_GetStatus(void)
59{
60 if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)
61 return FLASH_BUSY;
62
63 if ((FLASH->SR & FLASH_SR_PGERR) != 0)
64 return FLASH_ERROR_PG;
65
66 if ((FLASH->SR & FLASH_SR_WRPERR) != 0 )
67 return FLASH_ERROR_WRP;
68
69 if ((FLASH->SR & FLASH_OBR_OPTERR) != 0 )
70 return FLASH_ERROR_OPT;
71
72 return FLASH_COMPLETE;
73}
74
75/**
76 * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
77 * @param Timeout: FLASH progamming Timeout
78 * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
79 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
80 */
81FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
82{
83 FLASH_Status status;
84
85 /* Check for the Flash Status */
86 status = FLASH_GetStatus();
87 /* Wait for a Flash operation to complete or a TIMEOUT to occur */
88 while ((status == FLASH_BUSY) && (Timeout != 0x00))
89 {
90 delay();
91 status = FLASH_GetStatus();
92 Timeout--;
93 }
94 if (Timeout == 0)
95 status = FLASH_TIMEOUT;
96 /* Return the operation status */
97 return status;
98}
99
100/**
101 * @brief Erases a specified FLASH page.
102 * @param Page_Address: The page address to be erased.
103 * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
104 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
105 */
106FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
107{
108 FLASH_Status status = FLASH_COMPLETE;
109 /* Check the parameters */
110 ASSERT(IS_FLASH_ADDRESS(Page_Address));
111 /* Wait for last operation to be completed */
112 status = FLASH_WaitForLastOperation(EraseTimeout);
113
114 if(status == FLASH_COMPLETE)
115 {
116 /* if the previous operation is completed, proceed to erase the page */
117 FLASH->CR |= FLASH_CR_PER;
118 FLASH->AR = Page_Address;
119 FLASH->CR |= FLASH_CR_STRT;
120
121 /* Wait for last operation to be completed */
122 status = FLASH_WaitForLastOperation(EraseTimeout);
123 if(status != FLASH_TIMEOUT)
124 {
125 /* if the erase operation is completed, disable the PER Bit */
126 FLASH->CR &= ~FLASH_CR_PER;
127 }
128 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
129 }
130 /* Return the Erase Status */
131 return status;
132}
133
134/**
135 * @brief Programs a half word at a specified address.
136 * @param Address: specifies the address to be programmed.
137 * @param Data: specifies the data to be programmed.
138 * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
139 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
140 */
141FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
142{
143 FLASH_Status status = FLASH_BAD_ADDRESS;
144
145 if (IS_FLASH_ADDRESS(Address))
146 {
147 /* Wait for last operation to be completed */
148 status = FLASH_WaitForLastOperation(ProgramTimeout);
149 if(status == FLASH_COMPLETE)
150 {
151 /* if the previous operation is completed, proceed to program the new data */
152 FLASH->CR |= FLASH_CR_PG;
153 *(__IO uint16_t*)Address = Data;
154 /* Wait for last operation to be completed */
155 status = FLASH_WaitForLastOperation(ProgramTimeout);
156 if(status != FLASH_TIMEOUT)
157 {
158 /* if the program operation is completed, disable the PG Bit */
159 FLASH->CR &= ~FLASH_CR_PG;
160 }
161 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
162 }
163 }
164 return status;
165}
166
167/**
168 * @brief Unlocks the FLASH Program Erase Controller.
169 * @param None
170 * @retval None
171 */
172void FLASH_Unlock(void)
173{
174 /* Authorize the FPEC Access */
175 FLASH->KEYR = FLASH_KEY1;
176 FLASH->KEYR = FLASH_KEY2;
177}
178
179/**
180 * @brief Locks the FLASH Program Erase Controller.
181 * @param None
182 * @retval None
183 */
184void FLASH_Lock(void)
185{
186 /* Set the Lock Bit to lock the FPEC and the FCR */
187 FLASH->CR |= FLASH_CR_LOCK;
188}
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 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#ifndef __FLASH_STM32_H
20#define __FLASH_STM32_H
21
22#ifdef __cplusplus
23 extern "C" {
24#endif
25
26#include "ch.h"
27#include "hal.h"
28
29typedef enum
30 {
31 FLASH_BUSY = 1,
32 FLASH_ERROR_PG,
33 FLASH_ERROR_WRP,
34 FLASH_ERROR_OPT,
35 FLASH_COMPLETE,
36 FLASH_TIMEOUT,
37 FLASH_BAD_ADDRESS
38 } FLASH_Status;
39
40#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF))
41
42FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
43FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
44FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
45
46void FLASH_Unlock(void);
47void FLASH_Lock(void);
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif /* __FLASH_STM32_H */
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)
181 print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") " 181 print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
182 "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") " 182 "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
183 "VER: " STR(DEVICE_VER) "\n"); 183 "VER: " STR(DEVICE_VER) "\n");
184#ifdef SKIP_VERSION
185 print("BUILD: (" __DATE__ ")\n");
186#else
184 print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n"); 187 print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n");
188#endif
185 189
186 /* build options */ 190 /* build options */
187 print("OPTIONS:" 191 print("OPTIONS:"
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
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#ifndef COMMAND_H 18#pragma once
19#define COMMAND
20 19
21/* FIXME: Add doxygen comments for the behavioral defines in here. */ 20/* FIXME: Add doxygen comments for the behavioral defines in here. */
22 21
@@ -155,5 +154,3 @@ bool command_proc(uint8_t code);
155 154
156#define XMAGIC_KC(key) KC_##key 155#define XMAGIC_KC(key) KC_##key
157#define MAGIC_KC(key) XMAGIC_KC(key) 156#define MAGIC_KC(key) XMAGIC_KC(key)
158
159#endif
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 3e5987ee3..d8bab7d2e 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -3,29 +3,59 @@
3#include "eeprom.h" 3#include "eeprom.h"
4#include "eeconfig.h" 4#include "eeconfig.h"
5 5
6/** \brief eeconfig initialization 6#ifdef STM32_EEPROM_ENABLE
7#include "hal.h"
8#include "eeprom_stm32.h"
9#endif
10
11extern uint32_t default_layer_state;
12/** \brief eeconfig enable
7 * 13 *
8 * FIXME: needs doc 14 * FIXME: needs doc
9 */ 15 */
10void eeconfig_init(void) 16__attribute__ ((weak))
11{ 17void eeconfig_init_user(void) {
12 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); 18 // Reset user EEPROM value to blank, rather than to a set value
13 eeprom_update_byte(EECONFIG_DEBUG, 0); 19 eeconfig_update_user(0);
14 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); 20}
15 eeprom_update_byte(EECONFIG_KEYMAP, 0); 21
16 eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0); 22__attribute__ ((weak))
17#ifdef BACKLIGHT_ENABLE 23void eeconfig_init_kb(void) {
18 eeprom_update_byte(EECONFIG_BACKLIGHT, 0); 24 // Reset Keyboard EEPROM value to blank, rather than to a set value
19#endif 25 eeconfig_update_kb(0);
20#ifdef AUDIO_ENABLE 26
21 eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default 27 eeconfig_init_user();
22#endif 28}
23#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) 29
24 eeprom_update_dword(EECONFIG_RGBLIGHT, 0); 30
25#endif 31/*
26#ifdef STENO_ENABLE 32 * FIXME: needs doc
27 eeprom_update_byte(EECONFIG_STENOMODE, 0); 33 */
34void eeconfig_init_quantum(void) {
35#ifdef STM32_EEPROM_ENABLE
36 EEPROM_format();
28#endif 37#endif
38 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
39 eeprom_update_byte(EECONFIG_DEBUG, 0);
40 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
41 default_layer_state = 0;
42 eeprom_update_byte(EECONFIG_KEYMAP, 0);
43 eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
44 eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
45 eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
46 eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
47 eeprom_update_byte(EECONFIG_STENOMODE, 0);
48
49 eeconfig_init_kb();
50}
51
52/** \brief eeconfig initialization
53 *
54 * FIXME: needs doc
55 */
56void eeconfig_init(void) {
57
58 eeconfig_init_quantum();
29} 59}
30 60
31/** \brief eeconfig enable 61/** \brief eeconfig enable
@@ -43,7 +73,10 @@ void eeconfig_enable(void)
43 */ 73 */
44void eeconfig_disable(void) 74void eeconfig_disable(void)
45{ 75{
46 eeprom_update_word(EECONFIG_MAGIC, 0xFFFF); 76#ifdef STM32_EEPROM_ENABLE
77 EEPROM_format();
78#endif
79 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
47} 80}
48 81
49/** \brief eeconfig is enabled 82/** \brief eeconfig is enabled
@@ -55,6 +88,15 @@ bool eeconfig_is_enabled(void)
55 return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); 88 return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
56} 89}
57 90
91/** \brief eeconfig is disabled
92 *
93 * FIXME: needs doc
94 */
95bool eeconfig_is_disabled(void)
96{
97 return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
98}
99
58/** \brief eeconfig read debug 100/** \brief eeconfig read debug
59 * 101 *
60 * FIXME: needs doc 102 * FIXME: needs doc
@@ -88,7 +130,6 @@ uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMA
88 */ 130 */
89void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); } 131void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); }
90 132
91#ifdef BACKLIGHT_ENABLE
92/** \brief eeconfig read backlight 133/** \brief eeconfig read backlight
93 * 134 *
94 * FIXME: needs doc 135 * FIXME: needs doc
@@ -99,9 +140,8 @@ uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BA
99 * FIXME: needs doc 140 * FIXME: needs doc
100 */ 141 */
101void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); } 142void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); }
102#endif
103 143
104#ifdef AUDIO_ENABLE 144
105/** \brief eeconfig read audio 145/** \brief eeconfig read audio
106 * 146 *
107 * FIXME: needs doc 147 * FIXME: needs doc
@@ -112,4 +152,28 @@ uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO)
112 * FIXME: needs doc 152 * FIXME: needs doc
113 */ 153 */
114void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); } 154void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); }
115#endif 155
156
157/** \brief eeconfig read kb
158 *
159 * FIXME: needs doc
160 */
161uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); }
162/** \brief eeconfig update kb
163 *
164 * FIXME: needs doc
165 */
166
167void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); }
168/** \brief eeconfig read user
169 *
170 * FIXME: needs doc
171 */
172uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); }
173/** \brief eeconfig update user
174 *
175 * FIXME: needs doc
176 */
177void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); }
178
179
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 1397a90c7..8d4e1d4d0 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -23,21 +23,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23 23
24 24
25#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED 25#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
26#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
26 27
27/* eeprom parameteter address */ 28/* eeprom parameteter address */
29#if !defined(STM32_EEPROM_ENABLE)
28#define EECONFIG_MAGIC (uint16_t *)0 30#define EECONFIG_MAGIC (uint16_t *)0
29#define EECONFIG_DEBUG (uint8_t *)2 31#define EECONFIG_DEBUG (uint8_t *)2
30#define EECONFIG_DEFAULT_LAYER (uint8_t *)3 32#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
31#define EECONFIG_KEYMAP (uint8_t *)4 33#define EECONFIG_KEYMAP (uint8_t *)4
32#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5 34#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
33#define EECONFIG_BACKLIGHT (uint8_t *)6 35#define EECONFIG_BACKLIGHT (uint8_t *)6
34#define EECONFIG_AUDIO (uint8_t *)7 36#define EECONFIG_AUDIO (uint8_t *)7
35#define EECONFIG_RGBLIGHT (uint32_t *)8 37#define EECONFIG_RGBLIGHT (uint32_t *)8
36#define EECONFIG_UNICODEMODE (uint8_t *)12 38#define EECONFIG_UNICODEMODE (uint8_t *)12
37#define EECONFIG_STENOMODE (uint8_t *)13 39#define EECONFIG_STENOMODE (uint8_t *)13
38// EEHANDS for two handed boards 40// EEHANDS for two handed boards
39#define EECONFIG_HANDEDNESS (uint8_t *)14 41#define EECONFIG_HANDEDNESS (uint8_t *)14
42#define EECONFIG_KEYBOARD (uint32_t *)15
43#define EECONFIG_USER (uint32_t *)19
40 44
45#else
46/* STM32F3 uses 16byte block. Reconfigure memory map */
47#define EECONFIG_MAGIC (uint16_t *)0
48#define EECONFIG_DEBUG (uint8_t *)1
49#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
50#define EECONFIG_KEYMAP (uint8_t *)3
51#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
52#define EECONFIG_BACKLIGHT (uint8_t *)5
53#define EECONFIG_AUDIO (uint8_t *)6
54#define EECONFIG_RGBLIGHT (uint32_t *)7
55#define EECONFIG_UNICODEMODE (uint8_t *)9
56#define EECONFIG_STENOMODE (uint8_t *)10
57// EEHANDS for two handed boards
58#define EECONFIG_HANDEDNESS (uint8_t *)11
59#define EECONFIG_KEYBOARD (uint32_t *)12
60#define EECONFIG_USER (uint32_t *)14
61#endif
41 62
42/* debug bit */ 63/* debug bit */
43#define EECONFIG_DEBUG_ENABLE (1<<0) 64#define EECONFIG_DEBUG_ENABLE (1<<0)
@@ -57,8 +78,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
57 78
58 79
59bool eeconfig_is_enabled(void); 80bool eeconfig_is_enabled(void);
81bool eeconfig_is_disabled(void);
60 82
61void eeconfig_init(void); 83void eeconfig_init(void);
84void eeconfig_init_quantum(void);
85void eeconfig_init_kb(void);
86void eeconfig_init_user(void);
62 87
63void eeconfig_enable(void); 88void eeconfig_enable(void);
64 89
@@ -83,4 +108,9 @@ uint8_t eeconfig_read_audio(void);
83void eeconfig_update_audio(uint8_t val); 108void eeconfig_update_audio(uint8_t val);
84#endif 109#endif
85 110
111uint32_t eeconfig_read_kb(void);
112void eeconfig_update_kb(uint32_t val);
113uint32_t eeconfig_read_user(void);
114void eeconfig_update_user(uint32_t val);
115
86#endif 116#endif
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 <http://www.gnu.org/licenses/>.
22#include "util.h" 22#include "util.h"
23#include "debug.h" 23#include "debug.h"
24 24
25#ifdef NKRO_ENABLE
26 #include "keycode_config.h"
27 extern keymap_config_t keymap_config;
28#endif
29
25static host_driver_t *driver; 30static host_driver_t *driver;
26static uint16_t last_system_report = 0; 31static uint16_t last_system_report = 0;
27static uint16_t last_consumer_report = 0; 32static uint16_t last_consumer_report = 0;
@@ -46,6 +51,20 @@ uint8_t host_keyboard_leds(void)
46void host_keyboard_send(report_keyboard_t *report) 51void host_keyboard_send(report_keyboard_t *report)
47{ 52{
48 if (!driver) return; 53 if (!driver) return;
54#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
55 if (keyboard_protocol && keymap_config.nkro) {
56 /* The callers of this function assume that report->mods is where mods go in.
57 * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
58 */
59 report->nkro.mods = report->mods;
60 report->nkro.report_id = REPORT_ID_NKRO;
61 } else
62#endif
63 {
64#ifdef KEYBOARD_SHARED_EP
65 report->report_id = REPORT_ID_KEYBOARD;
66#endif
67 }
49 (*driver->send_keyboard)(report); 68 (*driver->send_keyboard)(report);
50 69
51 if (debug_keyboard) { 70 if (debug_keyboard) {
@@ -60,6 +79,9 @@ void host_keyboard_send(report_keyboard_t *report)
60void host_mouse_send(report_mouse_t *report) 79void host_mouse_send(report_mouse_t *report)
61{ 80{
62 if (!driver) return; 81 if (!driver) return;
82#ifdef MOUSE_SHARED_EP
83 report->report_id = REPORT_ID_MOUSE;
84#endif
63 (*driver->send_mouse)(report); 85 (*driver->send_mouse)(report);
64} 86}
65 87
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 13b3cb4c0..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 <http://www.gnu.org/licenses/>.
72#ifdef HD44780_ENABLE 72#ifdef HD44780_ENABLE
73# include "hd44780.h" 73# include "hd44780.h"
74#endif 74#endif
75#ifdef QWIIC_ENABLE
76# include "qwiic.h"
77#endif
75 78
76#ifdef MATRIX_HAS_GHOST 79#ifdef MATRIX_HAS_GHOST
77extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; 80extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
@@ -120,6 +123,14 @@ static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata)
120 123
121#endif 124#endif
122 125
126void disable_jtag(void) {
127// To use PORTF disable JTAG with writing JTD bit twice within four cycles.
128#if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__))
129 MCUCR |= _BV(JTD);
130 MCUCR |= _BV(JTD);
131#endif
132}
133
123/** \brief matrix_setup 134/** \brief matrix_setup
124 * 135 *
125 * FIXME: needs doc 136 * FIXME: needs doc
@@ -133,6 +144,7 @@ void matrix_setup(void) {
133 * FIXME: needs doc 144 * FIXME: needs doc
134 */ 145 */
135void keyboard_setup(void) { 146void keyboard_setup(void) {
147 disable_jtag();
136 matrix_setup(); 148 matrix_setup();
137} 149}
138 150
@@ -151,12 +163,10 @@ bool is_keyboard_master(void) {
151 */ 163 */
152void keyboard_init(void) { 164void keyboard_init(void) {
153 timer_init(); 165 timer_init();
154// To use PORTF disable JTAG with writing JTD bit twice within four cycles.
155#if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__))
156 MCUCR |= _BV(JTD);
157 MCUCR |= _BV(JTD);
158#endif
159 matrix_init(); 166 matrix_init();
167#ifdef QWIIC_ENABLE
168 qwiic_init();
169#endif
160#ifdef PS2_MOUSE_ENABLE 170#ifdef PS2_MOUSE_ENABLE
161 ps2_mouse_init(); 171 ps2_mouse_init();
162#endif 172#endif
@@ -266,6 +276,10 @@ void keyboard_task(void)
266 276
267MATRIX_LOOP_END: 277MATRIX_LOOP_END:
268 278
279#ifdef QWIIC_ENABLE
280 qwiic_task();
281#endif
282
269#ifdef MOUSEKEY_ENABLE 283#ifdef MOUSEKEY_ENABLE
270 // mousekey repeat & acceleration 284 // mousekey repeat & acceleration
271 mousekey_task(); 285 mousekey_task();
diff --git a/tmk_core/common/keyboard.h b/tmk_core/common/keyboard.h
index f17003c2f..71e594a89 100644
--- a/tmk_core/common/keyboard.h
+++ b/tmk_core/common/keyboard.h
@@ -57,6 +57,8 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
57 .time = (timer_read() | 1) \ 57 .time = (timer_read() | 1) \
58} 58}
59 59
60void disable_jtag(void);
61
60/* it runs once at early stage of startup before keyboard_init. */ 62/* it runs once at early stage of startup before keyboard_init. */
61void keyboard_setup(void); 63void keyboard_setup(void);
62/* it runs once after initializing host side protocol, debug and MCU peripherals. */ 64/* it runs once after initializing host side protocol, debug and MCU peripherals. */
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index 9cb4f1e0c..ac3edbd21 100644
--- a/tmk_core/common/keycode.h
+++ b/tmk_core/common/keycode.h
@@ -16,8 +16,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18/* 18/*
19 * Keycodes based on HID Usage Keyboard/Keypad Page(0x07) plus special codes 19 * Keycodes based on HID Keyboard/Keypad Usage Page (0x07) plus media keys from Generic Desktop Page (0x01) and Consumer Page (0x0C)
20 * https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf 20 *
21 * See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf
21 * or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older) 22 * or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older)
22 */ 23 */
23#ifndef KEYCODE_H 24#ifndef KEYCODE_H
@@ -30,76 +31,82 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
30#define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL) 31#define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL)
31#define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI) 32#define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI)
32 33
33
34#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF)) 34#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
35#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE) 35#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
36#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_MRWD) 36#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID)
37
37#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) 38#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
39
38#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2) 40#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
39#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) 41#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
40#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5) 42#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5)
41#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) 43#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
42#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) 44#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
43 45
44#define MOD_BIT(code) (1<<MOD_INDEX(code)) 46#define MOD_BIT(code) (1 << MOD_INDEX(code))
45#define MOD_INDEX(code) ((code) & 0x07) 47#define MOD_INDEX(code) ((code) & 0x07)
46#define FN_BIT(code) (1<<FN_INDEX(code))
47#define FN_INDEX(code) ((code) - KC_FN0)
48#define FN_MIN KC_FN0
49#define FN_MAX KC_FN31
50 48
49#define FN_BIT(code) (1 << FN_INDEX(code))
50#define FN_INDEX(code) ((code) - KC_FN0)
51#define FN_MIN KC_FN0
52#define FN_MAX KC_FN31
51 53
52/* 54/*
53 * Short names for ease of definition of keymap 55 * Short names for ease of definition of keymap
54 */ 56 */
55#define KC_LCTL KC_LCTRL 57/* Transparent */
56#define KC_RCTL KC_RCTRL 58#define KC_TRANSPARENT 0x01
57#define KC_LSFT KC_LSHIFT 59#define KC_TRNS KC_TRANSPARENT
58#define KC_RSFT KC_RSHIFT 60
61/* Punctuation */
62#define KC_ENT KC_ENTER
59#define KC_ESC KC_ESCAPE 63#define KC_ESC KC_ESCAPE
60#define KC_BSPC KC_BSPACE 64#define KC_BSPC KC_BSPACE
61#define KC_ENT KC_ENTER
62#define KC_DEL KC_DELETE
63#define KC_INS KC_INSERT
64#define KC_CAPS KC_CAPSLOCK
65#define KC_CLCK KC_CAPSLOCK
66#define KC_RGHT KC_RIGHT
67#define KC_PGDN KC_PGDOWN
68#define KC_PSCR KC_PSCREEN
69#define KC_SLCK KC_SCROLLLOCK
70#define KC_PAUS KC_PAUSE
71#define KC_BRK KC_PAUSE
72#define KC_NLCK KC_NUMLOCK
73#define KC_SPC KC_SPACE 65#define KC_SPC KC_SPACE
74#define KC_MINS KC_MINUS 66#define KC_MINS KC_MINUS
75#define KC_EQL KC_EQUAL 67#define KC_EQL KC_EQUAL
76#define KC_GRV KC_GRAVE
77#define KC_RBRC KC_RBRACKET
78#define KC_LBRC KC_LBRACKET 68#define KC_LBRC KC_LBRACKET
79#define KC_COMM KC_COMMA 69#define KC_RBRC KC_RBRACKET
80#define KC_BSLS KC_BSLASH 70#define KC_BSLS KC_BSLASH
81#define KC_SLSH KC_SLASH 71#define KC_NUHS KC_NONUS_HASH
82#define KC_SCLN KC_SCOLON 72#define KC_SCLN KC_SCOLON
83#define KC_QUOT KC_QUOTE 73#define KC_QUOT KC_QUOTE
84#define KC_APP KC_APPLICATION 74#define KC_GRV KC_GRAVE
85#define KC_NUHS KC_NONUS_HASH 75#define KC_COMM KC_COMMA
76#define KC_SLSH KC_SLASH
86#define KC_NUBS KC_NONUS_BSLASH 77#define KC_NUBS KC_NONUS_BSLASH
78
79/* Lock Keys */
80#define KC_CLCK KC_CAPSLOCK
81#define KC_CAPS KC_CAPSLOCK
82#define KC_SLCK KC_SCROLLLOCK
83#define KC_NLCK KC_NUMLOCK
87#define KC_LCAP KC_LOCKING_CAPS 84#define KC_LCAP KC_LOCKING_CAPS
88#define KC_LNUM KC_LOCKING_NUM 85#define KC_LNUM KC_LOCKING_NUM
89#define KC_LSCR KC_LOCKING_SCROLL 86#define KC_LSCR KC_LOCKING_SCROLL
87
88/* Commands */
89#define KC_PSCR KC_PSCREEN
90#define KC_PAUS KC_PAUSE
91#define KC_BRK KC_PAUSE
92#define KC_INS KC_INSERT
93#define KC_DEL KC_DELETE
94#define KC_PGDN KC_PGDOWN
95#define KC_RGHT KC_RIGHT
96#define KC_APP KC_APPLICATION
97#define KC_EXEC KC_EXECUTE
98#define KC_SLCT KC_SELECT
99#define KC_AGIN KC_AGAIN
100#define KC_PSTE KC_PASTE
90#define KC_ERAS KC_ALT_ERASE 101#define KC_ERAS KC_ALT_ERASE
91#define KC_CLR KC_CLEAR 102#define KC_CLR KC_CLEAR
92/* Japanese specific */ 103
93#define KC_ZKHK KC_GRAVE
94#define KC_RO KC_INT1
95#define KC_KANA KC_INT2
96#define KC_JYEN KC_INT3
97#define KC_HENK KC_INT4
98#define KC_MHEN KC_INT5
99/* Korean specific */
100#define KC_HAEN KC_LANG1
101#define KC_HANJ KC_LANG2
102/* Keypad */ 104/* Keypad */
105#define KC_PSLS KC_KP_SLASH
106#define KC_PAST KC_KP_ASTERISK
107#define KC_PMNS KC_KP_MINUS
108#define KC_PPLS KC_KP_PLUS
109#define KC_PENT KC_KP_ENTER
103#define KC_P1 KC_KP_1 110#define KC_P1 KC_KP_1
104#define KC_P2 KC_KP_2 111#define KC_P2 KC_KP_2
105#define KC_P3 KC_KP_3 112#define KC_P3 KC_KP_3
@@ -111,47 +118,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
111#define KC_P9 KC_KP_9 118#define KC_P9 KC_KP_9
112#define KC_P0 KC_KP_0 119#define KC_P0 KC_KP_0
113#define KC_PDOT KC_KP_DOT 120#define KC_PDOT KC_KP_DOT
114#define KC_PCMM KC_KP_COMMA
115#define KC_PSLS KC_KP_SLASH
116#define KC_PAST KC_KP_ASTERISK
117#define KC_PMNS KC_KP_MINUS
118#define KC_PPLS KC_KP_PLUS
119#define KC_PEQL KC_KP_EQUAL 121#define KC_PEQL KC_KP_EQUAL
120#define KC_PENT KC_KP_ENTER 122#define KC_PCMM KC_KP_COMMA
121/* Unix function key */ 123
122#define KC_EXEC KC_EXECUTE 124/* Japanese specific */
123#define KC_SLCT KC_SELECT 125#define KC_ZKHK KC_GRAVE
124#define KC_AGIN KC_AGAIN 126#define KC_RO KC_INT1
125#define KC_PSTE KC_PASTE 127#define KC_KANA KC_INT2
126/* Mousekey */ 128#define KC_JYEN KC_INT3
127#define KC_MS_U KC_MS_UP 129#define KC_HENK KC_INT4
128#define KC_MS_D KC_MS_DOWN 130#define KC_MHEN KC_INT5
129#define KC_MS_L KC_MS_LEFT 131
130#define KC_MS_R KC_MS_RIGHT 132/* Korean specific */
131#define KC_BTN1 KC_MS_BTN1 133#define KC_HAEN KC_LANG1
132#define KC_BTN2 KC_MS_BTN2 134#define KC_HANJ KC_LANG2
133#define KC_BTN3 KC_MS_BTN3 135
134#define KC_BTN4 KC_MS_BTN4 136/* Modifiers */
135#define KC_BTN5 KC_MS_BTN5 137#define KC_LCTL KC_LCTRL
136#define KC_WH_U KC_MS_WH_UP 138#define KC_LSFT KC_LSHIFT
137#define KC_WH_D KC_MS_WH_DOWN 139#define KC_LCMD KC_LGUI
138#define KC_WH_L KC_MS_WH_LEFT 140#define KC_LWIN KC_LGUI
139#define KC_WH_R KC_MS_WH_RIGHT 141#define KC_RCTL KC_RCTRL
140#define KC_ACL0 KC_MS_ACCEL0 142#define KC_RSFT KC_RSHIFT
141#define KC_ACL1 KC_MS_ACCEL1 143#define KC_ALGR KC_RALT
142#define KC_ACL2 KC_MS_ACCEL2 144#define KC_RCMD KC_RGUI
143/* Sytem Control */ 145#define KC_RWIN KC_RGUI
146
147/* Generic Desktop Page (0x01) */
144#define KC_PWR KC_SYSTEM_POWER 148#define KC_PWR KC_SYSTEM_POWER
145#define KC_SLEP KC_SYSTEM_SLEEP 149#define KC_SLEP KC_SYSTEM_SLEEP
146#define KC_WAKE KC_SYSTEM_WAKE 150#define KC_WAKE KC_SYSTEM_WAKE
147/* Consumer Page */ 151
152/* Consumer Page (0x0C) */
148#define KC_MUTE KC_AUDIO_MUTE 153#define KC_MUTE KC_AUDIO_MUTE
149#define KC_VOLU KC_AUDIO_VOL_UP 154#define KC_VOLU KC_AUDIO_VOL_UP
150#define KC_VOLD KC_AUDIO_VOL_DOWN 155#define KC_VOLD KC_AUDIO_VOL_DOWN
151#define KC_MNXT KC_MEDIA_NEXT_TRACK 156#define KC_MNXT KC_MEDIA_NEXT_TRACK
152#define KC_MPRV KC_MEDIA_PREV_TRACK 157#define KC_MPRV KC_MEDIA_PREV_TRACK
153#define KC_MFFD KC_MEDIA_FAST_FORWARD
154#define KC_MRWD KC_MEDIA_REWIND
155#define KC_MSTP KC_MEDIA_STOP 158#define KC_MSTP KC_MEDIA_STOP
156#define KC_MPLY KC_MEDIA_PLAY_PAUSE 159#define KC_MPLY KC_MEDIA_PLAY_PAUSE
157#define KC_MSEL KC_MEDIA_SELECT 160#define KC_MSEL KC_MEDIA_SELECT
@@ -166,339 +169,356 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
166#define KC_WSTP KC_WWW_STOP 169#define KC_WSTP KC_WWW_STOP
167#define KC_WREF KC_WWW_REFRESH 170#define KC_WREF KC_WWW_REFRESH
168#define KC_WFAV KC_WWW_FAVORITES 171#define KC_WFAV KC_WWW_FAVORITES
169/* Transparent */ 172#define KC_MFFD KC_MEDIA_FAST_FORWARD
170#define KC_TRANSPARENT 1 173#define KC_MRWD KC_MEDIA_REWIND
171#define KC_TRNS KC_TRANSPARENT 174#define KC_BRIU KC_BRIGHTNESS_UP
172/* GUI key aliases */ 175#define KC_BRID KC_BRIGHTNESS_DOWN
173#define KC_LCMD KC_LGUI
174#define KC_LWIN KC_LGUI
175#define KC_RCMD KC_RGUI
176#define KC_RWIN KC_RGUI
177
178 176
177/* Mouse Keys */
178#define KC_MS_U KC_MS_UP
179#define KC_MS_D KC_MS_DOWN
180#define KC_MS_L KC_MS_LEFT
181#define KC_MS_R KC_MS_RIGHT
182#define KC_BTN1 KC_MS_BTN1
183#define KC_BTN2 KC_MS_BTN2
184#define KC_BTN3 KC_MS_BTN3
185#define KC_BTN4 KC_MS_BTN4
186#define KC_BTN5 KC_MS_BTN5
187#define KC_WH_U KC_MS_WH_UP
188#define KC_WH_D KC_MS_WH_DOWN
189#define KC_WH_L KC_MS_WH_LEFT
190#define KC_WH_R KC_MS_WH_RIGHT
191#define KC_ACL0 KC_MS_ACCEL0
192#define KC_ACL1 KC_MS_ACCEL1
193#define KC_ACL2 KC_MS_ACCEL2
179 194
180/* USB HID Keyboard/Keypad Usage(0x07) */ 195/* Keyboard/Keypad Page (0x07) */
181enum hid_keyboard_keypad_usage { 196enum hid_keyboard_keypad_usage {
182 KC_NO = 0x00, 197 KC_NO = 0x00,
183 KC_ROLL_OVER, 198 KC_ROLL_OVER,
184 KC_POST_FAIL, 199 KC_POST_FAIL,
185 KC_UNDEFINED, 200 KC_UNDEFINED,
186 KC_A, 201 KC_A,
187 KC_B, 202 KC_B,
188 KC_C, 203 KC_C,
189 KC_D, 204 KC_D,
190 KC_E, 205 KC_E,
191 KC_F, 206 KC_F,
192 KC_G, 207 KC_G,
193 KC_H, 208 KC_H,
194 KC_I, 209 KC_I,
195 KC_J, 210 KC_J,
196 KC_K, 211 KC_K,
197 KC_L, 212 KC_L,
198 KC_M, /* 0x10 */ 213 KC_M, //0x10
199 KC_N, 214 KC_N,
200 KC_O, 215 KC_O,
201 KC_P, 216 KC_P,
202 KC_Q, 217 KC_Q,
203 KC_R, 218 KC_R,
204 KC_S, 219 KC_S,
205 KC_T, 220 KC_T,
206 KC_U, 221 KC_U,
207 KC_V, 222 KC_V,
208 KC_W, 223 KC_W,
209 KC_X, 224 KC_X,
210 KC_Y, 225 KC_Y,
211 KC_Z, 226 KC_Z,
212 KC_1, 227 KC_1,
213 KC_2, 228 KC_2,
214 KC_3, /* 0x20 */ 229 KC_3, //0x20
215 KC_4, 230 KC_4,
216 KC_5, 231 KC_5,
217 KC_6, 232 KC_6,
218 KC_7, 233 KC_7,
219 KC_8, 234 KC_8,
220 KC_9, 235 KC_9,
221 KC_0, 236 KC_0,
222 KC_ENTER, 237 KC_ENTER,
223 KC_ESCAPE, 238 KC_ESCAPE,
224 KC_BSPACE, 239 KC_BSPACE,
225 KC_TAB, 240 KC_TAB,
226 KC_SPACE, 241 KC_SPACE,
227 KC_MINUS, 242 KC_MINUS,
228 KC_EQUAL, 243 KC_EQUAL,
229 KC_LBRACKET, 244 KC_LBRACKET,
230 KC_RBRACKET, /* 0x30 */ 245 KC_RBRACKET, //0x30
231 KC_BSLASH, /* \ (and |) */ 246 KC_BSLASH,
232 KC_NONUS_HASH, /* Non-US # and ~ (Typically near the Enter key) */ 247 KC_NONUS_HASH,
233 KC_SCOLON, /* ; (and :) */ 248 KC_SCOLON,
234 KC_QUOTE, /* ' and " */ 249 KC_QUOTE,
235 KC_GRAVE, /* Grave accent and tilde */ 250 KC_GRAVE,
236 KC_COMMA, /* , and < */ 251 KC_COMMA,
237 KC_DOT, /* . and > */ 252 KC_DOT,
238 KC_SLASH, /* / and ? */ 253 KC_SLASH,
239 KC_CAPSLOCK, 254 KC_CAPSLOCK,
240 KC_F1, 255 KC_F1,
241 KC_F2, 256 KC_F2,
242 KC_F3, 257 KC_F3,
243 KC_F4, 258 KC_F4,
244 KC_F5, 259 KC_F5,
245 KC_F6, 260 KC_F6,
246 KC_F7, /* 0x40 */ 261 KC_F7, //0x40
247 KC_F8, 262 KC_F8,
248 KC_F9, 263 KC_F9,
249 KC_F10, 264 KC_F10,
250 KC_F11, 265 KC_F11,
251 KC_F12, 266 KC_F12,
252 KC_PSCREEN, 267 KC_PSCREEN,
253 KC_SCROLLLOCK, 268 KC_SCROLLLOCK,
254 KC_PAUSE, 269 KC_PAUSE,
255 KC_INSERT, 270 KC_INSERT,
256 KC_HOME, 271 KC_HOME,
257 KC_PGUP, 272 KC_PGUP,
258 KC_DELETE, 273 KC_DELETE,
259 KC_END, 274 KC_END,
260 KC_PGDOWN, 275 KC_PGDOWN,
261 KC_RIGHT, 276 KC_RIGHT,
262 KC_LEFT, /* 0x50 */ 277 KC_LEFT, //0x50
263 KC_DOWN, 278 KC_DOWN,
264 KC_UP, 279 KC_UP,
265 KC_NUMLOCK, 280 KC_NUMLOCK,
266 KC_KP_SLASH, 281 KC_KP_SLASH,
267 KC_KP_ASTERISK, 282 KC_KP_ASTERISK,
268 KC_KP_MINUS, 283 KC_KP_MINUS,
269 KC_KP_PLUS, 284 KC_KP_PLUS,
270 KC_KP_ENTER, 285 KC_KP_ENTER,
271 KC_KP_1, 286 KC_KP_1,
272 KC_KP_2, 287 KC_KP_2,
273 KC_KP_3, 288 KC_KP_3,
274 KC_KP_4, 289 KC_KP_4,
275 KC_KP_5, 290 KC_KP_5,
276 KC_KP_6, 291 KC_KP_6,
277 KC_KP_7, 292 KC_KP_7,
278 KC_KP_8, /* 0x60 */ 293 KC_KP_8, //0x60
279 KC_KP_9, 294 KC_KP_9,
280 KC_KP_0, 295 KC_KP_0,
281 KC_KP_DOT, 296 KC_KP_DOT,
282 KC_NONUS_BSLASH, /* Non-US \ and | (Typically near the Left-Shift key) */ 297 KC_NONUS_BSLASH,
283 KC_APPLICATION, 298 KC_APPLICATION,
284 KC_POWER, 299 KC_POWER,
285 KC_KP_EQUAL, 300 KC_KP_EQUAL,
286 KC_F13, 301 KC_F13,
287 KC_F14, 302 KC_F14,
288 KC_F15, 303 KC_F15,
289 KC_F16, 304 KC_F16,
290 KC_F17, 305 KC_F17,
291 KC_F18, 306 KC_F18,
292 KC_F19, 307 KC_F19,
293 KC_F20, 308 KC_F20,
294 KC_F21, /* 0x70 */ 309 KC_F21, //0x70
295 KC_F22, 310 KC_F22,
296 KC_F23, 311 KC_F23,
297 KC_F24, 312 KC_F24,
298 KC_EXECUTE, 313 KC_EXECUTE,
299 KC_HELP, 314 KC_HELP,
300 KC_MENU, 315 KC_MENU,
301 KC_SELECT, 316 KC_SELECT,
302 KC_STOP, 317 KC_STOP,
303 KC_AGAIN, 318 KC_AGAIN,
304 KC_UNDO, 319 KC_UNDO,
305 KC_CUT, 320 KC_CUT,
306 KC_COPY, 321 KC_COPY,
307 KC_PASTE, 322 KC_PASTE,
308 KC_FIND, 323 KC_FIND,
309 KC__MUTE, 324 KC__MUTE,
310 KC__VOLUP, /* 0x80 */ 325 KC__VOLUP, //0x80
311 KC__VOLDOWN, 326 KC__VOLDOWN,
312 KC_LOCKING_CAPS, /* locking Caps Lock */ 327 KC_LOCKING_CAPS,
313 KC_LOCKING_NUM, /* locking Num Lock */ 328 KC_LOCKING_NUM,
314 KC_LOCKING_SCROLL, /* locking Scroll Lock */ 329 KC_LOCKING_SCROLL,
315 KC_KP_COMMA, 330 KC_KP_COMMA,
316 KC_KP_EQUAL_AS400, /* equal sign on AS/400 */ 331 KC_KP_EQUAL_AS400,
317 KC_INT1, 332 KC_INT1,
318 KC_INT2, 333 KC_INT2,
319 KC_INT3, 334 KC_INT3,
320 KC_INT4, 335 KC_INT4,
321 KC_INT5, 336 KC_INT5,
322 KC_INT6, 337 KC_INT6,
323 KC_INT7, 338 KC_INT7,
324 KC_INT8, 339 KC_INT8,
325 KC_INT9, 340 KC_INT9,
326 KC_LANG1, /* 0x90 */ 341 KC_LANG1, //0x90
327 KC_LANG2, 342 KC_LANG2,
328 KC_LANG3, 343 KC_LANG3,
329 KC_LANG4, 344 KC_LANG4,
330 KC_LANG5, 345 KC_LANG5,
331 KC_LANG6, 346 KC_LANG6,
332 KC_LANG7, 347 KC_LANG7,
333 KC_LANG8, 348 KC_LANG8,
334 KC_LANG9, 349 KC_LANG9,
335 KC_ALT_ERASE, 350 KC_ALT_ERASE,
336 KC_SYSREQ, 351 KC_SYSREQ,
337 KC_CANCEL, 352 KC_CANCEL,
338 KC_CLEAR, 353 KC_CLEAR,
339 KC_PRIOR, 354 KC_PRIOR,
340 KC_RETURN, 355 KC_RETURN,
341 KC_SEPARATOR, 356 KC_SEPARATOR,
342 KC_OUT, /* 0xA0 */ 357 KC_OUT, //0xA0
343 KC_OPER, 358 KC_OPER,
344 KC_CLEAR_AGAIN, 359 KC_CLEAR_AGAIN,
345 KC_CRSEL, 360 KC_CRSEL,
346 KC_EXSEL, /* 0xA4 */ 361 KC_EXSEL,
347
348 /* NOTE: 0xA5-DF are used for internal special purpose */
349 362
350#if 0 363#if 0
351 /* NOTE: Following codes(0xB0-DD) are not used. Leave them for reference. */ 364 // ***************************************************************
352 KC_KP_00 = 0xB0, 365 // These keycodes are present in the HID spec, but are *
353 KC_KP_000, 366 // nonfunctional on modern OSes. QMK uses this range (0xA5-0xDF) *
354 KC_THOUSANDS_SEPARATOR, 367 // for the media and function keys instead - see below. *
355 KC_DECIMAL_SEPARATOR, 368 // ***************************************************************
356 KC_CURRENCY_UNIT, 369
357 KC_CURRENCY_SUB_UNIT, 370 KC_KP_00 = 0xB0,
358 KC_KP_LPAREN, 371 KC_KP_000,
359 KC_KP_RPAREN, 372 KC_THOUSANDS_SEPARATOR,
360 KC_KP_LCBRACKET, /* { */ 373 KC_DECIMAL_SEPARATOR,
361 KC_KP_RCBRACKET, /* } */ 374 KC_CURRENCY_UNIT,
362 KC_KP_TAB, 375 KC_CURRENCY_SUB_UNIT,
363 KC_KP_BSPACE, 376 KC_KP_LPAREN,
364 KC_KP_A, 377 KC_KP_RPAREN,
365 KC_KP_B, 378 KC_KP_LCBRACKET,
366 KC_KP_C, 379 KC_KP_RCBRACKET,
367 KC_KP_D, 380 KC_KP_TAB,
368 KC_KP_E, /* 0xC0 */ 381 KC_KP_BSPACE,
369 KC_KP_F, 382 KC_KP_A,
370 KC_KP_XOR, 383 KC_KP_B,
371 KC_KP_HAT, 384 KC_KP_C,
372 KC_KP_PERC, 385 KC_KP_D,
373 KC_KP_LT, 386 KC_KP_E, //0xC0
374 KC_KP_GT, 387 KC_KP_F,
375 KC_KP_AND, 388 KC_KP_XOR,
376 KC_KP_LAZYAND, 389 KC_KP_HAT,
377 KC_KP_OR, 390 KC_KP_PERC,
378 KC_KP_LAZYOR, 391 KC_KP_LT,
379 KC_KP_COLON, 392 KC_KP_GT,
380 KC_KP_HASH, 393 KC_KP_AND,
381 KC_KP_SPACE, 394 KC_KP_LAZYAND,
382 KC_KP_ATMARK, 395 KC_KP_OR,
383 KC_KP_EXCLAMATION, 396 KC_KP_LAZYOR,
384 KC_KP_MEM_STORE, /* 0xD0 */ 397 KC_KP_COLON,
385 KC_KP_MEM_RECALL, 398 KC_KP_HASH,
386 KC_KP_MEM_CLEAR, 399 KC_KP_SPACE,
387 KC_KP_MEM_ADD, 400 KC_KP_ATMARK,
388 KC_KP_MEM_SUB, 401 KC_KP_EXCLAMATION,
389 KC_KP_MEM_MUL, 402 KC_KP_MEM_STORE, //0xD0
390 KC_KP_MEM_DIV, 403 KC_KP_MEM_RECALL,
391 KC_KP_PLUS_MINUS, 404 KC_KP_MEM_CLEAR,
392 KC_KP_CLEAR, 405 KC_KP_MEM_ADD,
393 KC_KP_CLEAR_ENTRY, 406 KC_KP_MEM_SUB,
394 KC_KP_BINARY, 407 KC_KP_MEM_MUL,
395 KC_KP_OCTAL, 408 KC_KP_MEM_DIV,
396 KC_KP_DECIMAL, 409 KC_KP_PLUS_MINUS,
397 KC_KP_HEXADECIMAL, /* 0xDD */ 410 KC_KP_CLEAR,
411 KC_KP_CLEAR_ENTRY,
412 KC_KP_BINARY,
413 KC_KP_OCTAL,
414 KC_KP_DECIMAL,
415 KC_KP_HEXADECIMAL,
398#endif 416#endif
399 417
400 /* Modifiers */ 418 /* Modifiers */
401 KC_LCTRL = 0xE0, 419 KC_LCTRL = 0xE0,
402 KC_LSHIFT, 420 KC_LSHIFT,
403 KC_LALT, 421 KC_LALT,
404 KC_LGUI, 422 KC_LGUI,
405 KC_RCTRL, 423 KC_RCTRL,
406 KC_RSHIFT, 424 KC_RSHIFT,
407 KC_RALT, 425 KC_RALT,
408 KC_RGUI, 426 KC_RGUI
409 427
410 /* NOTE: 0xE8-FF are used for internal special purpose */ 428 // **********************************************
429 // * 0xF0-0xFF are unallocated in the HID spec. *
430 // * QMK uses these for Mouse Keys - see below. *
431 // **********************************************
411}; 432};
412 433
413/* Special keycodes */ 434/* Media and Function keys */
414/* NOTE: 0xA5-DF and 0xE8-FF are used for internal special purpose */
415enum internal_special_keycodes { 435enum internal_special_keycodes {
416 /* System Control */ 436 /* Generic Desktop Page (0x01) */
417 KC_SYSTEM_POWER = 0xA5, 437 KC_SYSTEM_POWER = 0xA5,
418 KC_SYSTEM_SLEEP, 438 KC_SYSTEM_SLEEP,
419 KC_SYSTEM_WAKE, 439 KC_SYSTEM_WAKE,
420 440
421 /* Media Control */ 441 /* Consumer Page (0x0C) */
422 KC_AUDIO_MUTE, 442 KC_AUDIO_MUTE,
423 KC_AUDIO_VOL_UP, 443 KC_AUDIO_VOL_UP,
424 KC_AUDIO_VOL_DOWN, 444 KC_AUDIO_VOL_DOWN,
425 KC_MEDIA_NEXT_TRACK, 445 KC_MEDIA_NEXT_TRACK,
426 KC_MEDIA_PREV_TRACK, 446 KC_MEDIA_PREV_TRACK,
427 KC_MEDIA_STOP, 447 KC_MEDIA_STOP,
428 KC_MEDIA_PLAY_PAUSE, 448 KC_MEDIA_PLAY_PAUSE,
429 KC_MEDIA_SELECT, 449 KC_MEDIA_SELECT,
430 KC_MEDIA_EJECT, 450 KC_MEDIA_EJECT, //0xB0
431 KC_MAIL, 451 KC_MAIL,
432 KC_CALCULATOR, 452 KC_CALCULATOR,
433 KC_MY_COMPUTER, 453 KC_MY_COMPUTER,
434 KC_WWW_SEARCH, 454 KC_WWW_SEARCH,
435 KC_WWW_HOME, 455 KC_WWW_HOME,
436 KC_WWW_BACK, 456 KC_WWW_BACK,
437 KC_WWW_FORWARD, 457 KC_WWW_FORWARD,
438 KC_WWW_STOP, 458 KC_WWW_STOP,
439 KC_WWW_REFRESH, 459 KC_WWW_REFRESH,
440 KC_WWW_FAVORITES, 460 KC_WWW_FAVORITES,
441 KC_MEDIA_FAST_FORWARD, 461 KC_MEDIA_FAST_FORWARD,
442 KC_MEDIA_REWIND, /* 0xBC */ 462 KC_MEDIA_REWIND,
443 463 KC_BRIGHTNESS_UP,
444 /* Fn key */ 464 KC_BRIGHTNESS_DOWN,
445 KC_FN0 = 0xC0, 465
446 KC_FN1, 466 /* Fn keys */
447 KC_FN2, 467 KC_FN0 = 0xC0,
448 KC_FN3, 468 KC_FN1,
449 KC_FN4, 469 KC_FN2,
450 KC_FN5, 470 KC_FN3,
451 KC_FN6, 471 KC_FN4,
452 KC_FN7, 472 KC_FN5,
453 KC_FN8, 473 KC_FN6,
454 KC_FN9, 474 KC_FN7,
455 KC_FN10, 475 KC_FN8,
456 KC_FN11, 476 KC_FN9,
457 KC_FN12, 477 KC_FN10,
458 KC_FN13, 478 KC_FN11,
459 KC_FN14, 479 KC_FN12,
460 KC_FN15, 480 KC_FN13,
461 481 KC_FN14,
462 KC_FN16 = 0xD0, 482 KC_FN15,
463 KC_FN17, 483 KC_FN16, //0xD0
464 KC_FN18, 484 KC_FN17,
465 KC_FN19, 485 KC_FN18,
466 KC_FN20, 486 KC_FN19,
467 KC_FN21, 487 KC_FN20,
468 KC_FN22, 488 KC_FN21,
469 KC_FN23, 489 KC_FN22,
470 KC_FN24, 490 KC_FN23,
471 KC_FN25, 491 KC_FN24,
472 KC_FN26, 492 KC_FN25,
473 KC_FN27, 493 KC_FN26,
474 KC_FN28, 494 KC_FN27,
475 KC_FN29, 495 KC_FN28,
476 KC_FN30, 496 KC_FN29,
477 KC_FN31, /* 0xDF */ 497 KC_FN30,
478 498 KC_FN31
479 /**************************************/
480 /* 0xE0-E7 for Modifiers. DO NOT USE. */
481 /**************************************/
482
483 /* Mousekey */
484 KC_MS_UP = 0xF0,
485 KC_MS_DOWN,
486 KC_MS_LEFT,
487 KC_MS_RIGHT,
488 KC_MS_BTN1,
489 KC_MS_BTN2,
490 KC_MS_BTN3,
491 KC_MS_BTN4,
492 KC_MS_BTN5, /* 0xF8 */
493 /* Mousekey wheel */
494 KC_MS_WH_UP,
495 KC_MS_WH_DOWN,
496 KC_MS_WH_LEFT,
497 KC_MS_WH_RIGHT, /* 0xFC */
498 /* Mousekey accel */
499 KC_MS_ACCEL0,
500 KC_MS_ACCEL1,
501 KC_MS_ACCEL2 /* 0xFF */
502}; 499};
503 500
504#endif /* KEYCODE_H */ 501enum mouse_keys {
502 /* Mouse Buttons */
503 KC_MS_UP = 0xF0,
504 KC_MS_DOWN,
505 KC_MS_LEFT,
506 KC_MS_RIGHT,
507 KC_MS_BTN1,
508 KC_MS_BTN2,
509 KC_MS_BTN3,
510 KC_MS_BTN4,
511 KC_MS_BTN5,
512
513 /* Mouse Wheel */
514 KC_MS_WH_UP,
515 KC_MS_WH_DOWN,
516 KC_MS_WH_LEFT,
517 KC_MS_WH_RIGHT,
518
519 /* Acceleration */
520 KC_MS_ACCEL0,
521 KC_MS_ACCEL1,
522 KC_MS_ACCEL2
523};
524#endif
diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h
index 8836c0fc7..2d7184bd0 100644
--- a/tmk_core/common/print.h
+++ b/tmk_core/common/print.h
@@ -29,7 +29,7 @@
29#include <stdbool.h> 29#include <stdbool.h>
30#include "util.h" 30#include "util.h"
31 31
32#if defined(PROTOCOL_CHIBIOS) 32#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM)
33#define PSTR(x) x 33#define PSTR(x) x
34#endif 34#endif
35 35
@@ -60,7 +60,7 @@
60# define println(s) xputs(PSTR(s "\r\n")) 60# define println(s) xputs(PSTR(s "\r\n"))
61# define uprint(s) print(s) 61# define uprint(s) print(s)
62# define uprintln(s) println(s) 62# define uprintln(s) println(s)
63# define uprintf(fmt, ...) xprintf(fmt, ...) 63# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
64 64
65# endif /* USER_PRINT / NORMAL PRINT */ 65# endif /* USER_PRINT / NORMAL PRINT */
66 66
@@ -73,7 +73,9 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
73 73
74#elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */ 74#elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
75 75
76#ifndef TERMINAL_ENABLE
76# include "chibios/printf.h" 77# include "chibios/printf.h"
78#endif
77 79
78# ifdef USER_PRINT /* USER_PRINT */ 80# ifdef USER_PRINT /* USER_PRINT */
79 81
@@ -99,6 +101,34 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
99 101
100# endif /* USER_PRINT / NORMAL PRINT */ 102# endif /* USER_PRINT / NORMAL PRINT */
101 103
104#elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */
105
106# include "arm_atsam/printf.h"
107
108# ifdef USER_PRINT /* USER_PRINT */
109
110// Remove normal print defines
111# define print(s)
112# define println(s)
113# define xprintf(fmt, ...)
114
115// Create user print defines
116# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
117# define uprint(s) xprintf(s)
118# define uprintln(s) xprintf(s "\r\n")
119
120# else /* NORMAL PRINT */
121
122// Create user & normal print defines
123# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
124# define print(s) xprintf(s)
125# define println(s) xprintf(s "\r\n")
126# define uprint(s) print(s)
127# define uprintln(s) println(s)
128# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
129
130# endif /* USER_PRINT / NORMAL PRINT */
131
102#elif defined(__arm__) /* __arm__ */ 132#elif defined(__arm__) /* __arm__ */
103 133
104# include "mbed/xprintf.h" 134# include "mbed/xprintf.h"
@@ -111,26 +141,26 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
111# define xprintf(fmt, ...) 141# define xprintf(fmt, ...)
112 142
113// Create user print defines 143// Create user print defines
114# define uprintf(fmt, ...) __xprintf(fmt, ...) 144# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
115# define uprint(s) xprintf(s) 145# define uprint(s) xprintf(s)
116# define uprintln(s) xprintf(s "\r\n") 146# define uprintln(s) xprintf(s "\r\n")
117 147
118# else /* NORMAL PRINT */ 148# else /* NORMAL PRINT */
119 149
120// Create user & normal print defines 150// Create user & normal print defines
121# define xprintf(fmt, ...) __xprintf(fmt, ...) 151# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
122# define print(s) xprintf(s) 152# define print(s) xprintf(s)
123# define println(s) xprintf(s "\r\n") 153# define println(s) xprintf(s "\r\n")
124# define uprint(s) print(s) 154# define uprint(s) print(s)
125# define uprintln(s) println(s) 155# define uprintln(s) println(s)
126# define uprintf(fmt, ...) xprintf(fmt, ...) 156# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
127 157
128# endif /* USER_PRINT / NORMAL PRINT */ 158# endif /* USER_PRINT / NORMAL PRINT */
129 159
130/* TODO: to select output destinations: UART/USBSerial */ 160/* TODO: to select output destinations: UART/USBSerial */
131# define print_set_sendchar(func) 161# define print_set_sendchar(func)
132 162
133#endif /* __AVR__ / PROTOCOL_CHIBIOS / __arm__ */ 163#endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM / __arm__ */
134 164
135// User print disables the normal print messages in the body of QMK/TMK code and 165// User print disables the normal print messages in the body of QMK/TMK code and
136// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do 166// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
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 @@
19#include "keycode_config.h" 19#include "keycode_config.h"
20#include "debug.h" 20#include "debug.h"
21#include "util.h" 21#include "util.h"
22#include <string.h>
22 23
23/** \brief has_anykey 24/** \brief has_anykey
24 * 25 *
@@ -27,8 +28,16 @@
27uint8_t has_anykey(report_keyboard_t* keyboard_report) 28uint8_t has_anykey(report_keyboard_t* keyboard_report)
28{ 29{
29 uint8_t cnt = 0; 30 uint8_t cnt = 0;
30 for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) { 31 uint8_t *p = keyboard_report->keys;
31 if (keyboard_report->raw[i]) 32 uint8_t lp = sizeof(keyboard_report->keys);
33#ifdef NKRO_ENABLE
34 if (keyboard_protocol && keymap_config.nkro) {
35 p = keyboard_report->nkro.bits;
36 lp = sizeof(keyboard_report->nkro.bits);
37 }
38#endif
39 while (lp--) {
40 if (*p++)
32 cnt++; 41 cnt++;
33 } 42 }
34 return cnt; 43 return cnt;
@@ -237,7 +246,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
237void clear_keys_from_report(report_keyboard_t* keyboard_report) 246void clear_keys_from_report(report_keyboard_t* keyboard_report)
238{ 247{
239 // not clear mods 248 // not clear mods
240 for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) { 249#ifdef NKRO_ENABLE
241 keyboard_report->raw[i] = 0; 250 if (keyboard_protocol && keymap_config.nkro) {
251 memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
252 return;
242 } 253 }
254#endif
255 memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
243} 256}
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 6c27eb9dc..eb9afb727 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -23,9 +23,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23 23
24 24
25/* report id */ 25/* report id */
26#define REPORT_ID_MOUSE 1 26#define REPORT_ID_KEYBOARD 1
27#define REPORT_ID_SYSTEM 2 27#define REPORT_ID_MOUSE 2
28#define REPORT_ID_CONSUMER 3 28#define REPORT_ID_SYSTEM 3
29#define REPORT_ID_CONSUMER 4
30#define REPORT_ID_NKRO 5
29 31
30/* mouse buttons */ 32/* mouse buttons */
31#define MOUSE_BTN1 (1<<0) 33#define MOUSE_BTN1 (1<<0)
@@ -36,6 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
36 38
37/* Consumer Page(0x0C) 39/* Consumer Page(0x0C)
38 * following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx 40 * following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx
41 * see also https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/display-brightness-control
39 */ 42 */
40#define AUDIO_MUTE 0x00E2 43#define AUDIO_MUTE 0x00E2
41#define AUDIO_VOL_UP 0x00E9 44#define AUDIO_VOL_UP 0x00E9
@@ -45,6 +48,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
45#define TRANSPORT_STOP 0x00B7 48#define TRANSPORT_STOP 0x00B7
46#define TRANSPORT_STOP_EJECT 0x00CC 49#define TRANSPORT_STOP_EJECT 0x00CC
47#define TRANSPORT_PLAY_PAUSE 0x00CD 50#define TRANSPORT_PLAY_PAUSE 0x00CD
51#define BRIGHTNESSUP 0x006F
52#define BRIGHTNESSDOWN 0x0070
48/* application launch */ 53/* application launch */
49#define AL_CC_CONFIG 0x0183 54#define AL_CC_CONFIG 0x0183
50#define AL_EMAIL 0x018A 55#define AL_EMAIL 0x018A
@@ -72,27 +77,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
72#define SYSTEM_WAKE_UP 0x0083 77#define SYSTEM_WAKE_UP 0x0083
73 78
74 79
80#define NKRO_SHARED_EP
75/* key report size(NKRO or boot mode) */ 81/* key report size(NKRO or boot mode) */
76#if defined(NKRO_ENABLE) 82#if defined(NKRO_ENABLE)
77 #if defined(PROTOCOL_PJRC) 83 #if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
78 #include "usb.h"
79 #define KEYBOARD_REPORT_SIZE KBD2_SIZE
80 #define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
81 #define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
82 #elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
83 #include "protocol/usb_descriptor.h" 84 #include "protocol/usb_descriptor.h"
84 #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE 85 #define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
85 #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) 86 #elif defined(PROTOCOL_ARM_ATSAM)
87 #include "protocol/arm_atsam/usb/udi_device_epsize.h"
86 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) 88 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
89 #undef NKRO_SHARED_EP
90 #undef MOUSE_SHARED_EP
87 #else 91 #else
88 #error "NKRO not supported with this protocol" 92 #error "NKRO not supported with this protocol"
93 #endif
89#endif 94#endif
90 95
96#ifdef KEYBOARD_SHARED_EP
97# define KEYBOARD_REPORT_SIZE 9
91#else 98#else
92# define KEYBOARD_REPORT_SIZE 8 99# define KEYBOARD_REPORT_SIZE 8
93# define KEYBOARD_REPORT_KEYS 6
94#endif 100#endif
95 101
102#define KEYBOARD_REPORT_KEYS 6
103
104/* VUSB hardcodes keyboard and mouse+extrakey only */
105#if defined(PROTOCOL_VUSB)
106 #undef KEYBOARD_SHARED_EP
107 #undef MOUSE_SHARED_EP
108#endif
96 109
97#ifdef __cplusplus 110#ifdef __cplusplus
98extern "C" { 111extern "C" {
@@ -121,12 +134,18 @@ extern "C" {
121typedef union { 134typedef union {
122 uint8_t raw[KEYBOARD_REPORT_SIZE]; 135 uint8_t raw[KEYBOARD_REPORT_SIZE];
123 struct { 136 struct {
137#ifdef KEYBOARD_SHARED_EP
138 uint8_t report_id;
139#endif
124 uint8_t mods; 140 uint8_t mods;
125 uint8_t reserved; 141 uint8_t reserved;
126 uint8_t keys[KEYBOARD_REPORT_KEYS]; 142 uint8_t keys[KEYBOARD_REPORT_KEYS];
127 }; 143 };
128#ifdef NKRO_ENABLE 144#ifdef NKRO_ENABLE
129 struct { 145 struct nkro_report {
146#ifdef NKRO_SHARED_EP
147 uint8_t report_id;
148#endif
130 uint8_t mods; 149 uint8_t mods;
131 uint8_t bits[KEYBOARD_REPORT_BITS]; 150 uint8_t bits[KEYBOARD_REPORT_BITS];
132 } nkro; 151 } nkro;
@@ -134,6 +153,9 @@ typedef union {
134} __attribute__ ((packed)) report_keyboard_t; 153} __attribute__ ((packed)) report_keyboard_t;
135 154
136typedef struct { 155typedef struct {
156#ifdef MOUSE_SHARED_EP
157 uint8_t report_id;
158#endif
137 uint8_t buttons; 159 uint8_t buttons;
138 int8_t x; 160 int8_t x;
139 int8_t y; 161 int8_t y;
@@ -170,7 +192,9 @@ typedef struct {
170 (key == KC_WWW_FORWARD ? AC_FORWARD : \ 192 (key == KC_WWW_FORWARD ? AC_FORWARD : \
171 (key == KC_WWW_STOP ? AC_STOP : \ 193 (key == KC_WWW_STOP ? AC_STOP : \
172 (key == KC_WWW_REFRESH ? AC_REFRESH : \ 194 (key == KC_WWW_REFRESH ? AC_REFRESH : \
173 (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0))))))))))))))))))))) 195 (key == KC_BRIGHTNESS_UP ? BRIGHTNESSUP : \
196 (key == KC_BRIGHTNESS_DOWN ? BRIGHTNESSDOWN : \
197 (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))))
174 198
175uint8_t has_anykey(report_keyboard_t* keyboard_report); 199uint8_t has_anykey(report_keyboard_t* keyboard_report);
176uint8_t get_first_key(report_keyboard_t* keyboard_report); 200uint8_t get_first_key(report_keyboard_t* keyboard_report);