diff options
Diffstat (limited to 'tmk_core/common')
29 files changed, 1786 insertions, 100 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 fe626efb3..1bfd4c9cc 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c | |||
| @@ -73,6 +73,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 73 | #ifdef HD44780_ENABLE | 73 | #ifdef HD44780_ENABLE |
| 74 | # include "hd44780.h" | 74 | # include "hd44780.h" |
| 75 | #endif | 75 | #endif |
| 76 | #ifdef QWIIC_ENABLE | ||
| 77 | # include "qwiic.h" | ||
| 78 | #endif | ||
| 76 | 79 | ||
| 77 | #ifdef MATRIX_HAS_GHOST | 80 | #ifdef MATRIX_HAS_GHOST |
| 78 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; | 81 | extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; |
| @@ -121,6 +124,14 @@ static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) | |||
| 121 | 124 | ||
| 122 | #endif | 125 | #endif |
| 123 | 126 | ||
| 127 | void disable_jtag(void) { | ||
| 128 | // To use PORTF disable JTAG with writing JTD bit twice within four cycles. | ||
| 129 | #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__)) | ||
| 130 | MCUCR |= _BV(JTD); | ||
| 131 | MCUCR |= _BV(JTD); | ||
| 132 | #endif | ||
| 133 | } | ||
| 134 | |||
| 124 | /** \brief matrix_setup | 135 | /** \brief matrix_setup |
| 125 | * | 136 | * |
| 126 | * FIXME: needs doc | 137 | * FIXME: needs doc |
| @@ -134,6 +145,7 @@ void matrix_setup(void) { | |||
| 134 | * FIXME: needs doc | 145 | * FIXME: needs doc |
| 135 | */ | 146 | */ |
| 136 | void keyboard_setup(void) { | 147 | void keyboard_setup(void) { |
| 148 | disable_jtag(); | ||
| 137 | matrix_setup(); | 149 | matrix_setup(); |
| 138 | } | 150 | } |
| 139 | 151 | ||
| @@ -152,13 +164,11 @@ bool is_keyboard_master(void) { | |||
| 152 | */ | 164 | */ |
| 153 | void keyboard_init(void) { | 165 | void keyboard_init(void) { |
| 154 | timer_init(); | 166 | timer_init(); |
| 155 | // To use PORTF disable JTAG with writing JTD bit twice within four cycles. | ||
| 156 | #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__)) | ||
| 157 | MCUCR |= _BV(JTD); | ||
| 158 | MCUCR |= _BV(JTD); | ||
| 159 | #endif | ||
| 160 | matrix_init(); | 167 | matrix_init(); |
| 161 | matrix_debounce_init(); | 168 | matrix_debounce_init(); |
| 169 | #ifdef QWIIC_ENABLE | ||
| 170 | qwiic_init(); | ||
| 171 | #endif | ||
| 162 | #ifdef PS2_MOUSE_ENABLE | 172 | #ifdef PS2_MOUSE_ENABLE |
| 163 | ps2_mouse_init(); | 173 | ps2_mouse_init(); |
| 164 | #endif | 174 | #endif |
| @@ -256,6 +266,10 @@ void keyboard_task(void) | |||
| 256 | 266 | ||
| 257 | MATRIX_LOOP_END: | 267 | MATRIX_LOOP_END: |
| 258 | 268 | ||
| 269 | #ifdef QWIIC_ENABLE | ||
| 270 | qwiic_task(); | ||
| 271 | #endif | ||
| 272 | |||
| 259 | #ifdef MOUSEKEY_ENABLE | 273 | #ifdef MOUSEKEY_ENABLE |
| 260 | // mousekey repeat & acceleration | 274 | // mousekey repeat & acceleration |
| 261 | mousekey_task(); | 275 | 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 61642ae84..ac3edbd21 100644 --- a/tmk_core/common/keycode.h +++ b/tmk_core/common/keycode.h | |||
| @@ -33,7 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 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 | ||
| 38 | #define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) | 38 | #define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31) |
| 39 | 39 | ||
| @@ -140,6 +140,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 140 | #define KC_LWIN KC_LGUI | 140 | #define KC_LWIN KC_LGUI |
| 141 | #define KC_RCTL KC_RCTRL | 141 | #define KC_RCTL KC_RCTRL |
| 142 | #define KC_RSFT KC_RSHIFT | 142 | #define KC_RSFT KC_RSHIFT |
| 143 | #define KC_ALGR KC_RALT | ||
| 143 | #define KC_RCMD KC_RGUI | 144 | #define KC_RCMD KC_RGUI |
| 144 | #define KC_RWIN KC_RGUI | 145 | #define KC_RWIN KC_RGUI |
| 145 | 146 | ||
| @@ -170,6 +171,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 170 | #define KC_WFAV KC_WWW_FAVORITES | 171 | #define KC_WFAV KC_WWW_FAVORITES |
| 171 | #define KC_MFFD KC_MEDIA_FAST_FORWARD | 172 | #define KC_MFFD KC_MEDIA_FAST_FORWARD |
| 172 | #define KC_MRWD KC_MEDIA_REWIND | 173 | #define KC_MRWD KC_MEDIA_REWIND |
| 174 | #define KC_BRIU KC_BRIGHTNESS_UP | ||
| 175 | #define KC_BRID KC_BRIGHTNESS_DOWN | ||
| 173 | 176 | ||
| 174 | /* Mouse Keys */ | 177 | /* Mouse Keys */ |
| 175 | #define KC_MS_U KC_MS_UP | 178 | #define KC_MS_U KC_MS_UP |
| @@ -457,6 +460,8 @@ enum internal_special_keycodes { | |||
| 457 | KC_WWW_FAVORITES, | 460 | KC_WWW_FAVORITES, |
| 458 | KC_MEDIA_FAST_FORWARD, | 461 | KC_MEDIA_FAST_FORWARD, |
| 459 | KC_MEDIA_REWIND, | 462 | KC_MEDIA_REWIND, |
| 463 | KC_BRIGHTNESS_UP, | ||
| 464 | KC_BRIGHTNESS_DOWN, | ||
| 460 | 465 | ||
| 461 | /* Fn keys */ | 466 | /* Fn keys */ |
| 462 | KC_FN0 = 0xC0, | 467 | KC_FN0 = 0xC0, |
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); |
