diff options
Diffstat (limited to 'tmk_core/common')
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) |
| 124 | bool disable_action_cache = false; | 124 | bool disable_action_cache = false; |
| 125 | 125 | ||
| 126 | void process_record_nocache(keyrecord_t *record) | 126 | void 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 | */ | ||
| 854 | void 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 | */ |
| 875 | void clear_keyboard_but_mods(void) | 900 | void 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 | */ | ||
| 910 | void 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); | |||
| 62 | bool process_record_quantum(keyrecord_t *record); | 62 | bool 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) |
| 66 | extern bool disable_action_cache; | 66 | extern bool disable_action_cache; |
| 67 | #endif | 67 | #endif |
| 68 | 68 | ||
| @@ -88,11 +88,13 @@ void process_record(keyrecord_t *record); | |||
| 88 | void process_action(keyrecord_t *record, action_t action); | 88 | void process_action(keyrecord_t *record, action_t action); |
| 89 | void register_code(uint8_t code); | 89 | void register_code(uint8_t code); |
| 90 | void unregister_code(uint8_t code); | 90 | void unregister_code(uint8_t code); |
| 91 | void tap_code(uint8_t code); | ||
| 91 | void register_mods(uint8_t mods); | 92 | void register_mods(uint8_t mods); |
| 92 | void unregister_mods(uint8_t mods); | 93 | void unregister_mods(uint8_t mods); |
| 93 | //void set_mods(uint8_t mods); | 94 | //void set_mods(uint8_t mods); |
| 94 | void clear_keyboard(void); | 95 | void clear_keyboard(void); |
| 95 | void clear_keyboard_but_mods(void); | 96 | void clear_keyboard_but_mods(void); |
| 97 | void clear_keyboard_but_mods_and_keys(void); | ||
| 96 | void layer_switch(uint8_t new_layer); | 98 | void layer_switch(uint8_t new_layer); |
| 97 | bool is_tap_key(keypos_t key); | 99 | bool 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 | */ |
| 16 | uint32_t default_layer_state = 0; | 16 | uint32_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)) | ||
| 23 | uint32_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)) |
| 23 | uint32_t default_layer_state_set_kb(uint32_t state) { | 32 | uint32_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) |
| 223 | uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}}; | 240 | uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}}; |
| 224 | 241 | ||
| 225 | void update_source_layers_cache(keypos_t key, uint8_t layer) | 242 | void 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 | */ |
| 264 | action_t store_or_get_action(bool pressed, keypos_t key) | 281 | action_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)) |
| 33 | uint32_t default_layer_state_set_kb(uint32_t state); | 33 | uint32_t default_layer_state_set_kb(uint32_t state); |
| 34 | __attribute__((weak)) | ||
| 35 | uint32_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)) | ||
| 85 | uint32_t layer_state_set_user(uint32_t state); | 87 | uint32_t layer_state_set_user(uint32_t state); |
| 86 | __attribute__((weak)) | ||
| 87 | uint32_t layer_state_set_kb(uint32_t state); | 88 | uint32_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 |
| 94 | void update_source_layers_cache(keypos_t key, uint8_t layer); | 94 | void 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. | ||
| 22 | void 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 | |||
| 21 | static uint8_t buffer[EEPROM_SIZE]; | ||
| 22 | |||
| 23 | uint8_t eeprom_read_byte(const uint8_t *addr) { | ||
| 24 | uintptr_t offset = (uintptr_t)addr; | ||
| 25 | return buffer[offset]; | ||
| 26 | } | ||
| 27 | |||
| 28 | void eeprom_write_byte(uint8_t *addr, uint8_t value) { | ||
| 29 | uintptr_t offset = (uintptr_t)addr; | ||
| 30 | buffer[offset] = value; | ||
| 31 | } | ||
| 32 | |||
| 33 | uint16_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 | |||
| 38 | uint32_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 | |||
| 44 | void 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 | |||
| 52 | void 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 | |||
| 58 | void 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 | |||
| 66 | void 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 | |||
| 74 | void eeprom_update_byte(uint8_t *addr, uint8_t value) { | ||
| 75 | eeprom_write_byte(addr, value); | ||
| 76 | } | ||
| 77 | |||
| 78 | void 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 | |||
| 84 | void 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 | |||
| 92 | void 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 | /* | ||
| 2 | Copyright 2018 Massdrop Inc. | ||
| 3 | |||
| 4 | This program is free software: you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation, either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along 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 | |||
| 26 | void 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 | |||
| 6 | void 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 | */ | ||
| 10 | void 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)) | ||
| 19 | void suspend_power_down_user (void) { | ||
| 20 | |||
| 21 | } | ||
| 22 | |||
| 23 | /** \brief Run keyboard level Power down | ||
| 24 | * | ||
| 25 | * FIXME: needs doc | ||
| 26 | */ | ||
| 27 | __attribute__ ((weak)) | ||
| 28 | void suspend_power_down_kb(void) { | ||
| 29 | suspend_power_down_user(); | ||
| 30 | } | ||
| 31 | |||
| 32 | /** \brief Suspend power down | ||
| 33 | * | ||
| 34 | * FIXME: needs doc | ||
| 35 | */ | ||
| 36 | void 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) {} | ||
| 45 | bool 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)) | ||
| 60 | void 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)) | ||
| 69 | void suspend_wakeup_init_kb(void) { | ||
| 70 | suspend_wakeup_init_user(); | ||
| 71 | } | ||
| 72 | |||
| 73 | /** \brief run immediately after wakeup | ||
| 74 | * | ||
| 75 | * FIXME: needs doc | ||
| 76 | */ | ||
| 77 | void 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 | |||
| 5 | void set_time(uint64_t tset) | ||
| 6 | { | ||
| 7 | ms_clk = tset; | ||
| 8 | } | ||
| 9 | |||
| 10 | void timer_init(void) | ||
| 11 | { | ||
| 12 | ms_clk = 0; | ||
| 13 | } | ||
| 14 | |||
| 15 | uint16_t timer_read(void) | ||
| 16 | { | ||
| 17 | return (uint16_t)ms_clk; | ||
| 18 | } | ||
| 19 | |||
| 20 | uint32_t timer_read32(void) | ||
| 21 | { | ||
| 22 | return (uint32_t)ms_clk; | ||
| 23 | } | ||
| 24 | |||
| 25 | uint64_t timer_read64(void) | ||
| 26 | { | ||
| 27 | return ms_clk; | ||
| 28 | } | ||
| 29 | |||
| 30 | uint16_t timer_elapsed(uint16_t tlast) | ||
| 31 | { | ||
| 32 | return TIMER_DIFF_16(timer_read(), tlast); | ||
| 33 | } | ||
| 34 | |||
| 35 | uint32_t timer_elapsed32(uint32_t tlast) | ||
| 36 | { | ||
| 37 | return TIMER_DIFF_32(timer_read32(), tlast); | ||
| 38 | } | ||
| 39 | |||
| 40 | uint32_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 | |||
| 46 | void timer_clear(void) | ||
| 47 | { | ||
| 48 | ms_clk = 0; | ||
| 49 | } | ||
| 50 | |||
| 51 | void wait_ms(uint64_t msec) | ||
| 52 | { | ||
| 53 | CLK_delay_ms(msec); | ||
| 54 | } | ||
| 55 | |||
| 56 | void 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)) | ||
| 67 | void suspend_power_down_user (void) { } | ||
| 68 | /** \brief Run keyboard level Power down | ||
| 69 | * | ||
| 70 | * FIXME: needs doc | ||
| 71 | */ | ||
| 72 | __attribute__ ((weak)) | ||
| 73 | void 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 | */ |
| 73 | static uint8_t wdt_timeout = 0; | 92 | static uint8_t wdt_timeout = 0; |
| 74 | 93 | ||
| 75 | /** \brief Run keyboard level Power down | ||
| 76 | * | ||
| 77 | * FIXME: needs doc | ||
| 78 | */ | ||
| 79 | __attribute__ ((weak)) | ||
| 80 | void suspend_power_down_user (void) { } | ||
| 81 | /** \brief Run keyboard level Power down | ||
| 82 | * | ||
| 83 | * FIXME: needs doc | ||
| 84 | */ | ||
| 85 | __attribute__ ((weak)) | ||
| 86 | void 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 | */ |
| 144 | void suspend_power_down(void) | 148 | void 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 | */ |
| 77 | void backlight_toggle(void) | 77 | void 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 | */ | ||
| 91 | void 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 | */ | ||
| 107 | void 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 | */ | ||
| 121 | bool 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 | |||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | along 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); | |||
| 33 | void backlight_increase(void); | 32 | void backlight_increase(void); |
| 34 | void backlight_decrease(void); | 33 | void backlight_decrease(void); |
| 35 | void backlight_toggle(void); | 34 | void backlight_toggle(void); |
| 35 | void backlight_enable(void); | ||
| 36 | void backlight_disable(void); | ||
| 37 | bool is_backlight_enabled(void); | ||
| 36 | void backlight_step(void); | 38 | void backlight_step(void); |
| 37 | void backlight_set(uint8_t level); | 39 | void backlight_set(uint8_t level); |
| 38 | void backlight_level(uint8_t level); | 40 | void backlight_level(uint8_t level); |
| 39 | uint8_t get_backlight_level(void); | 41 | uint8_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 | */ | ||
| 45 | uint16_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 | */ | ||
| 65 | FLASH_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 | */ | ||
| 89 | uint16_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 | */ | ||
| 108 | uint32_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 | */ | ||
| 128 | uint16_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 | */ | ||
| 165 | uint16_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 | */ | ||
| 244 | uint16_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 | /* | ||
| 324 | uint16_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 | |||
| 332 | uint16_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 | */ | ||
| 433 | uint16_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 | */ | ||
| 462 | uint16_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 | /* | ||
| 485 | uint16_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 | */ | ||
| 502 | uint16_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 | */ | ||
| 545 | uint16_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 | */ | ||
| 573 | uint16_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 | */ | ||
| 587 | uint16_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 | |||
| 602 | uint16_t EEPROM_maxcount(void) | ||
| 603 | { | ||
| 604 | return ((PageSize / 4)-1); | ||
| 605 | } | ||
| 606 | |||
| 607 | |||
| 608 | uint8_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 | |||
| 616 | void 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 | |||
| 622 | void 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 | |||
| 628 | uint16_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 | |||
| 636 | void eeprom_write_word (uint16_t *Address, uint16_t Value) | ||
| 637 | { | ||
| 638 | uint16_t p = (uint32_t) Address; | ||
| 639 | EEPROM_write(p, Value); | ||
| 640 | } | ||
| 641 | |||
| 642 | void eeprom_update_word (uint16_t *Address, uint16_t Value) | ||
| 643 | { | ||
| 644 | uint16_t p = (uint32_t) Address; | ||
| 645 | EEPROM_update(p, Value); | ||
| 646 | } | ||
| 647 | |||
| 648 | uint32_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 | |||
| 657 | void 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 | |||
| 666 | void 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 */ | ||
| 73 | enum 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 | */ | ||
| 46 | static 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 | */ | ||
| 58 | FLASH_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 | */ | ||
| 81 | FLASH_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 | */ | ||
| 106 | FLASH_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 | */ | ||
| 141 | FLASH_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 | */ | ||
| 172 | void 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 | */ | ||
| 184 | void 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 | |||
| 29 | typedef 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 | |||
| 42 | FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); | ||
| 43 | FLASH_Status FLASH_ErasePage(uint32_t Page_Address); | ||
| 44 | FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); | ||
| 45 | |||
| 46 | void FLASH_Unlock(void); | ||
| 47 | void 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 | |||
| 15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 | along 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 | |||
| 11 | extern uint32_t default_layer_state; | ||
| 12 | /** \brief eeconfig enable | ||
| 7 | * | 13 | * |
| 8 | * FIXME: needs doc | 14 | * FIXME: needs doc |
| 9 | */ | 15 | */ |
| 10 | void eeconfig_init(void) | 16 | __attribute__ ((weak)) |
| 11 | { | 17 | void 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 | 23 | void 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 | */ |
| 34 | void 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 | */ | ||
| 56 | void 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 | */ |
| 44 | void eeconfig_disable(void) | 74 | void 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 | */ | ||
| 95 | bool 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 | */ |
| 89 | void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); } | 131 | void 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 | */ |
| 101 | void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); } | 142 | void 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 | */ |
| 114 | void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); } | 154 | void 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 | */ | ||
| 161 | uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); } | ||
| 162 | /** \brief eeconfig update kb | ||
| 163 | * | ||
| 164 | * FIXME: needs doc | ||
| 165 | */ | ||
| 166 | |||
| 167 | void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); } | ||
| 168 | /** \brief eeconfig read user | ||
| 169 | * | ||
| 170 | * FIXME: needs doc | ||
| 171 | */ | ||
| 172 | uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); } | ||
| 173 | /** \brief eeconfig update user | ||
| 174 | * | ||
| 175 | * FIXME: needs doc | ||
| 176 | */ | ||
| 177 | void 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 | ||
| 59 | bool eeconfig_is_enabled(void); | 80 | bool eeconfig_is_enabled(void); |
| 81 | bool eeconfig_is_disabled(void); | ||
| 60 | 82 | ||
| 61 | void eeconfig_init(void); | 83 | void eeconfig_init(void); |
| 84 | void eeconfig_init_quantum(void); | ||
| 85 | void eeconfig_init_kb(void); | ||
| 86 | void eeconfig_init_user(void); | ||
| 62 | 87 | ||
| 63 | void eeconfig_enable(void); | 88 | void eeconfig_enable(void); |
| 64 | 89 | ||
| @@ -83,4 +108,9 @@ uint8_t eeconfig_read_audio(void); | |||
| 83 | void eeconfig_update_audio(uint8_t val); | 108 | void eeconfig_update_audio(uint8_t val); |
| 84 | #endif | 109 | #endif |
| 85 | 110 | ||
| 111 | uint32_t eeconfig_read_kb(void); | ||
| 112 | void eeconfig_update_kb(uint32_t val); | ||
| 113 | uint32_t eeconfig_read_user(void); | ||
| 114 | void 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 | |||
| 25 | static host_driver_t *driver; | 30 | static host_driver_t *driver; |
| 26 | static uint16_t last_system_report = 0; | 31 | static uint16_t last_system_report = 0; |
| 27 | static uint16_t last_consumer_report = 0; | 32 | static uint16_t last_consumer_report = 0; |
| @@ -46,6 +51,20 @@ uint8_t host_keyboard_leds(void) | |||
| 46 | void host_keyboard_send(report_keyboard_t *report) | 51 | void 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) | |||
| 60 | void host_mouse_send(report_mouse_t *report) | 79 | void 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 |
| 77 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | 80 | extern 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 | ||
| 126 | void 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 | */ |
| 135 | void keyboard_setup(void) { | 146 | void 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 | */ |
| 152 | void keyboard_init(void) { | 164 | void 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 | ||
| 267 | MATRIX_LOOP_END: | 277 | MATRIX_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 | ||
| 60 | void 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. */ |
| 61 | void keyboard_setup(void); | 63 | void 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) */ |
| 181 | enum hid_keyboard_keypad_usage { | 196 | enum 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 */ | ||
| 415 | enum internal_special_keycodes { | 435 | enum 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 */ | 501 | enum 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 @@ | |||
| 27 | uint8_t has_anykey(report_keyboard_t* keyboard_report) | 28 | uint8_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) | |||
| 237 | void clear_keys_from_report(report_keyboard_t* keyboard_report) | 246 | void 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 |
| 98 | extern "C" { | 111 | extern "C" { |
| @@ -121,12 +134,18 @@ extern "C" { | |||
| 121 | typedef union { | 134 | typedef 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 | ||
| 136 | typedef struct { | 155 | typedef 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 | ||
| 175 | uint8_t has_anykey(report_keyboard_t* keyboard_report); | 199 | uint8_t has_anykey(report_keyboard_t* keyboard_report); |
| 176 | uint8_t get_first_key(report_keyboard_t* keyboard_report); | 200 | uint8_t get_first_key(report_keyboard_t* keyboard_report); |
