aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common')
-rw-r--r--tmk_core/common/action.c38
-rw-r--r--tmk_core/common/action.h4
-rw-r--r--tmk_core/common/action_layer.c23
-rw-r--r--tmk_core/common/action_layer.h8
-rw-r--r--tmk_core/common/arm_atsam/bootloader.c51
-rw-r--r--tmk_core/common/arm_atsam/eeprom.c98
-rw-r--r--tmk_core/common/arm_atsam/printf.c66
-rw-r--r--tmk_core/common/arm_atsam/printf.h11
-rw-r--r--tmk_core/common/arm_atsam/suspend.c85
-rw-r--r--tmk_core/common/arm_atsam/timer.c59
-rw-r--r--tmk_core/common/avr/suspend.c41
-rw-r--r--tmk_core/common/backlight.c51
-rw-r--r--tmk_core/common/backlight.h7
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.c673
-rwxr-xr-xtmk_core/common/chibios/eeprom_stm32.h95
-rw-r--r--tmk_core/common/chibios/eeprom_teensy.c (renamed from tmk_core/common/chibios/eeprom.c)0
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.c188
-rwxr-xr-xtmk_core/common/chibios/flash_stm32.h53
-rw-r--r--tmk_core/common/command.c4
-rw-r--r--tmk_core/common/command.h5
-rw-r--r--tmk_core/common/eeconfig.c112
-rw-r--r--tmk_core/common/eeconfig.h44
-rw-r--r--tmk_core/common/host.c22
-rw-r--r--tmk_core/common/keyboard.c24
-rw-r--r--tmk_core/common/keyboard.h2
-rw-r--r--tmk_core/common/keycode.h7
-rw-r--r--tmk_core/common/print.h42
-rw-r--r--tmk_core/common/report.c21
-rw-r--r--tmk_core/common/report.h52
29 files changed, 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)
124bool disable_action_cache = false; 124bool disable_action_cache = false;
125 125
126void process_record_nocache(keyrecord_t *record) 126void process_record_nocache(keyrecord_t *record)
@@ -773,6 +773,13 @@ void register_code(uint8_t code)
773 else if IS_CONSUMER(code) { 773 else if IS_CONSUMER(code) {
774 host_consumer_send(KEYCODE2CONSUMER(code)); 774 host_consumer_send(KEYCODE2CONSUMER(code));
775 } 775 }
776
777 #ifdef MOUSEKEY_ENABLE
778 else if IS_MOUSEKEY(code) {
779 mousekey_on(code);
780 mousekey_send();
781 }
782 #endif
776} 783}
777 784
778/** \brief Utilities for actions. (FIXME: Needs better description) 785/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -832,6 +839,24 @@ void unregister_code(uint8_t code)
832 else if IS_CONSUMER(code) { 839 else if IS_CONSUMER(code) {
833 host_consumer_send(0); 840 host_consumer_send(0);
834 } 841 }
842 #ifdef MOUSEKEY_ENABLE
843 else if IS_MOUSEKEY(code) {
844 mousekey_off(code);
845 mousekey_send();
846 }
847 #endif
848}
849
850/** \brief Utilities for actions. (FIXME: Needs better description)
851 *
852 * FIXME: Needs documentation.
853 */
854void tap_code(uint8_t code) {
855 register_code(code);
856 #if TAP_CODE_DELAY > 0
857 wait_ms(TAP_CODE_DELAY);
858 #endif
859 unregister_code(code);
835} 860}
836 861
837/** \brief Utilities for actions. (FIXME: Needs better description) 862/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -874,9 +899,18 @@ void clear_keyboard(void)
874 */ 899 */
875void clear_keyboard_but_mods(void) 900void clear_keyboard_but_mods(void)
876{ 901{
902 clear_keys();
903 clear_keyboard_but_mods_and_keys();
904}
905
906/** \brief Utilities for actions. (FIXME: Needs better description)
907 *
908 * FIXME: Needs documentation.
909 */
910void clear_keyboard_but_mods_and_keys()
911{
877 clear_weak_mods(); 912 clear_weak_mods();
878 clear_macro_mods(); 913 clear_macro_mods();
879 clear_keys();
880 send_keyboard_report(); 914 send_keyboard_report();
881#ifdef MOUSEKEY_ENABLE 915#ifdef MOUSEKEY_ENABLE
882 mousekey_clear(); 916 mousekey_clear();
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index acc55c7d3..8e47e5339 100644
--- a/tmk_core/common/action.h
+++ b/tmk_core/common/action.h
@@ -62,7 +62,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt);
62bool process_record_quantum(keyrecord_t *record); 62bool process_record_quantum(keyrecord_t *record);
63 63
64/* Utilities for actions. */ 64/* Utilities for actions. */
65#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 65#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
66extern bool disable_action_cache; 66extern bool disable_action_cache;
67#endif 67#endif
68 68
@@ -88,11 +88,13 @@ void process_record(keyrecord_t *record);
88void process_action(keyrecord_t *record, action_t action); 88void process_action(keyrecord_t *record, action_t action);
89void register_code(uint8_t code); 89void register_code(uint8_t code);
90void unregister_code(uint8_t code); 90void unregister_code(uint8_t code);
91void tap_code(uint8_t code);
91void register_mods(uint8_t mods); 92void register_mods(uint8_t mods);
92void unregister_mods(uint8_t mods); 93void unregister_mods(uint8_t mods);
93//void set_mods(uint8_t mods); 94//void set_mods(uint8_t mods);
94void clear_keyboard(void); 95void clear_keyboard(void);
95void clear_keyboard_but_mods(void); 96void clear_keyboard_but_mods(void);
97void clear_keyboard_but_mods_and_keys(void);
96void layer_switch(uint8_t new_layer); 98void layer_switch(uint8_t new_layer);
97bool is_tap_key(keypos_t key); 99bool is_tap_key(keypos_t key);
98 100
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index f3cd381ab..120ce3f51 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -15,13 +15,22 @@
15 */ 15 */
16uint32_t default_layer_state = 0; 16uint32_t default_layer_state = 0;
17 17
18/** \brief Default Layer State Set At user Level
19 *
20 * FIXME: Needs docs
21 */
22__attribute__((weak))
23uint32_t default_layer_state_set_user(uint32_t state) {
24 return state;
25}
26
18/** \brief Default Layer State Set At Keyboard Level 27/** \brief Default Layer State Set At Keyboard Level
19 * 28 *
20 * FIXME: Needs docs 29 * FIXME: Needs docs
21 */ 30 */
22__attribute__((weak)) 31__attribute__((weak))
23uint32_t default_layer_state_set_kb(uint32_t state) { 32uint32_t default_layer_state_set_kb(uint32_t state) {
24 return state; 33 return default_layer_state_set_user(state);
25} 34}
26 35
27/** \brief Default Layer State Set 36/** \brief Default Layer State Set
@@ -35,7 +44,11 @@ static void default_layer_state_set(uint32_t state)
35 default_layer_debug(); debug(" to "); 44 default_layer_debug(); debug(" to ");
36 default_layer_state = state; 45 default_layer_state = state;
37 default_layer_debug(); debug("\n"); 46 default_layer_debug(); debug("\n");
47#ifdef STRICT_LAYER_RELEASE
38 clear_keyboard_but_mods(); // To avoid stuck keys 48 clear_keyboard_but_mods(); // To avoid stuck keys
49#else
50 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
51#endif
39} 52}
40 53
41/** \brief Default Layer Print 54/** \brief Default Layer Print
@@ -118,7 +131,11 @@ void layer_state_set(uint32_t state)
118 layer_debug(); dprint(" to "); 131 layer_debug(); dprint(" to ");
119 layer_state = state; 132 layer_state = state;
120 layer_debug(); dprintln(); 133 layer_debug(); dprintln();
134#ifdef STRICT_LAYER_RELEASE
121 clear_keyboard_but_mods(); // To avoid stuck keys 135 clear_keyboard_but_mods(); // To avoid stuck keys
136#else
137 clear_keyboard_but_mods_and_keys(); // Don't reset held keys
138#endif
122} 139}
123 140
124/** \brief Layer clear 141/** \brief Layer clear
@@ -219,7 +236,7 @@ void layer_debug(void)
219} 236}
220#endif 237#endif
221 238
222#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 239#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
223uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}}; 240uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
224 241
225void update_source_layers_cache(keypos_t key, uint8_t layer) 242void update_source_layers_cache(keypos_t key, uint8_t layer)
@@ -263,7 +280,7 @@ uint8_t read_source_layers_cache(keypos_t key)
263 */ 280 */
264action_t store_or_get_action(bool pressed, keypos_t key) 281action_t store_or_get_action(bool pressed, keypos_t key)
265{ 282{
266#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 283#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
267 if (disable_action_cache) { 284 if (disable_action_cache) {
268 return layer_switch_get_action(key); 285 return layer_switch_get_action(key);
269 } 286 }
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 72a6bd8f6..f1551d251 100644
--- a/tmk_core/common/action_layer.h
+++ b/tmk_core/common/action_layer.h
@@ -31,6 +31,8 @@ void default_layer_set(uint32_t state);
31 31
32__attribute__((weak)) 32__attribute__((weak))
33uint32_t default_layer_state_set_kb(uint32_t state); 33uint32_t default_layer_state_set_kb(uint32_t state);
34__attribute__((weak))
35uint32_t default_layer_state_set_user(uint32_t state);
34 36
35#ifndef NO_ACTION_LAYER 37#ifndef NO_ACTION_LAYER
36/* bitwise operation */ 38/* bitwise operation */
@@ -80,15 +82,13 @@ void layer_xor(uint32_t state);
80#define layer_or(state) 82#define layer_or(state)
81#define layer_and(state) 83#define layer_and(state)
82#define layer_xor(state) 84#define layer_xor(state)
85#endif
83 86
84__attribute__((weak))
85uint32_t layer_state_set_user(uint32_t state); 87uint32_t layer_state_set_user(uint32_t state);
86__attribute__((weak))
87uint32_t layer_state_set_kb(uint32_t state); 88uint32_t layer_state_set_kb(uint32_t state);
88#endif
89 89
90/* pressed actions cache */ 90/* pressed actions cache */
91#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS) 91#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
92/* The number of bits needed to represent the layer number: log2(32). */ 92/* The number of bits needed to represent the layer number: log2(32). */
93#define MAX_LAYER_BITS 5 93#define MAX_LAYER_BITS 5
94void update_source_layers_cache(keypos_t key, uint8_t layer); 94void update_source_layers_cache(keypos_t key, uint8_t layer);
diff --git a/tmk_core/common/arm_atsam/bootloader.c b/tmk_core/common/arm_atsam/bootloader.c
new file mode 100644
index 000000000..ba71bfeb0
--- /dev/null
+++ b/tmk_core/common/arm_atsam/bootloader.c
@@ -0,0 +1,51 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "bootloader.h"
18#include "samd51j18a.h"
19#include "md_bootloader.h"
20
21//Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
22void bootloader_jump(void) {
23#ifdef KEYBOARD_massdrop_ctrl
24 //CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
25 uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; //The version to match (NULL terminated by compiler)
26 uint8_t *ver_check = ver_ram_method; //Pointer to version match string for traversal
27 uint8_t *ver_rom = (uint8_t *)0x21A0; //Pointer to address in ROM where this specific bootloader version would exist
28
29 while (*ver_check && *ver_rom == *ver_check) { //While there are check version characters to match and bootloader's version matches check's version
30 ver_check++; //Move check version pointer to next character
31 ver_rom++; //Move ROM version pointer to next character
32 }
33
34 if (!*ver_check) { //If check version pointer is NULL, all characters have matched
35 *MAGIC_ADDR = BOOTLOADER_MAGIC; //Set magic number into RAM
36 NVIC_SystemReset(); //Perform system reset
37 while (1) {} //Won't get here
38 }
39#endif
40
41 WDT->CTRLA.bit.ENABLE = 0;
42 while (WDT->SYNCBUSY.bit.ENABLE) {}
43 while (WDT->CTRLA.bit.ENABLE) {}
44 WDT->CONFIG.bit.WINDOW = 0;
45 WDT->CONFIG.bit.PER = 0;
46 WDT->EWCTRL.bit.EWOFFSET = 0;
47 WDT->CTRLA.bit.ENABLE = 1;
48 while (WDT->SYNCBUSY.bit.ENABLE) {}
49 while (!WDT->CTRLA.bit.ENABLE) {}
50 while (1) {} //Wait on timeout
51}
diff --git a/tmk_core/common/arm_atsam/eeprom.c b/tmk_core/common/arm_atsam/eeprom.c
new file mode 100644
index 000000000..61cc039ef
--- /dev/null
+++ b/tmk_core/common/arm_atsam/eeprom.c
@@ -0,0 +1,98 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "eeprom.h"
18
19#define EEPROM_SIZE 32
20
21static uint8_t buffer[EEPROM_SIZE];
22
23uint8_t eeprom_read_byte(const uint8_t *addr) {
24 uintptr_t offset = (uintptr_t)addr;
25 return buffer[offset];
26}
27
28void eeprom_write_byte(uint8_t *addr, uint8_t value) {
29 uintptr_t offset = (uintptr_t)addr;
30 buffer[offset] = value;
31}
32
33uint16_t eeprom_read_word(const uint16_t *addr) {
34 const uint8_t *p = (const uint8_t *)addr;
35 return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
36}
37
38uint32_t eeprom_read_dword(const uint32_t *addr) {
39 const uint8_t *p = (const uint8_t *)addr;
40 return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
41 | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
42}
43
44void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
45 const uint8_t *p = (const uint8_t *)addr;
46 uint8_t *dest = (uint8_t *)buf;
47 while (len--) {
48 *dest++ = eeprom_read_byte(p++);
49 }
50}
51
52void eeprom_write_word(uint16_t *addr, uint16_t value) {
53 uint8_t *p = (uint8_t *)addr;
54 eeprom_write_byte(p++, value);
55 eeprom_write_byte(p, value >> 8);
56}
57
58void eeprom_write_dword(uint32_t *addr, uint32_t value) {
59 uint8_t *p = (uint8_t *)addr;
60 eeprom_write_byte(p++, value);
61 eeprom_write_byte(p++, value >> 8);
62 eeprom_write_byte(p++, value >> 16);
63 eeprom_write_byte(p, value >> 24);
64}
65
66void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
67 uint8_t *p = (uint8_t *)addr;
68 const uint8_t *src = (const uint8_t *)buf;
69 while (len--) {
70 eeprom_write_byte(p++, *src++);
71 }
72}
73
74void eeprom_update_byte(uint8_t *addr, uint8_t value) {
75 eeprom_write_byte(addr, value);
76}
77
78void eeprom_update_word(uint16_t *addr, uint16_t value) {
79 uint8_t *p = (uint8_t *)addr;
80 eeprom_write_byte(p++, value);
81 eeprom_write_byte(p, value >> 8);
82}
83
84void eeprom_update_dword(uint32_t *addr, uint32_t value) {
85 uint8_t *p = (uint8_t *)addr;
86 eeprom_write_byte(p++, value);
87 eeprom_write_byte(p++, value >> 8);
88 eeprom_write_byte(p++, value >> 16);
89 eeprom_write_byte(p, value >> 24);
90}
91
92void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
93 uint8_t *p = (uint8_t *)addr;
94 const uint8_t *src = (const uint8_t *)buf;
95 while (len--) {
96 eeprom_write_byte(p++, *src++);
97 }
98}
diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c
new file mode 100644
index 000000000..7f298d1fd
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.c
@@ -0,0 +1,66 @@
1/*
2Copyright 2018 Massdrop Inc.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifdef CONSOLE_ENABLE
19
20#include "samd51j18a.h"
21#include "arm_atsam_protocol.h"
22#include "printf.h"
23#include <string.h>
24#include <stdarg.h>
25
26void console_printf(char *fmt, ...) {
27 while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
28
29 static char console_printbuf[CONSOLE_PRINTBUF_SIZE]; //Print and send buffer
30 va_list va;
31 int result;
32
33 va_start(va, fmt);
34 result = vsnprintf(console_printbuf, CONSOLE_PRINTBUF_SIZE, fmt, va);
35 va_end(va);
36
37 uint32_t irqflags;
38 char *pconbuf = console_printbuf; //Pointer to start send from
39 int send_out = CONSOLE_EPSIZE; //Bytes to send per transfer
40
41 while (result > 0) { //While not error and bytes remain
42 while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
43
44 irqflags = __get_PRIMASK();
45 __disable_irq();
46 __DMB();
47
48 if (result < CONSOLE_EPSIZE) { //If remaining bytes are less than console epsize
49 memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); //Clear the buffer
50 send_out = result; //Send remaining size
51 }
52
53 memcpy(udi_hid_con_report, pconbuf, send_out); //Copy data into the send buffer
54
55 udi_hid_con_b_report_valid = 1; //Set report valid
56 udi_hid_con_send_report(); //Send report
57
58 __DMB();
59 __set_PRIMASK(irqflags);
60
61 result -= send_out; //Decrement result by bytes sent
62 pconbuf += send_out; //Increment buffer point by bytes sent
63 }
64}
65
66#endif //CONSOLE_ENABLE
diff --git a/tmk_core/common/arm_atsam/printf.h b/tmk_core/common/arm_atsam/printf.h
new file mode 100644
index 000000000..1f1c2280b
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.h
@@ -0,0 +1,11 @@
1#ifndef _PRINTF_H_
2#define _PRINTF_H_
3
4#define CONSOLE_PRINTBUF_SIZE 512
5
6void console_printf(char *fmt, ...);
7
8#define __xprintf console_printf
9
10#endif //_PRINTF_H_
11
diff --git a/tmk_core/common/arm_atsam/suspend.c b/tmk_core/common/arm_atsam/suspend.c
new file mode 100644
index 000000000..e34965df6
--- /dev/null
+++ b/tmk_core/common/arm_atsam/suspend.c
@@ -0,0 +1,85 @@
1#include "matrix.h"
2#include "i2c_master.h"
3#include "led_matrix.h"
4#include "suspend.h"
5
6/** \brief Suspend idle
7 *
8 * FIXME: needs doc
9 */
10void suspend_idle(uint8_t time) {
11 /* Note: Not used anywhere currently */
12}
13
14/** \brief Run user level Power down
15 *
16 * FIXME: needs doc
17 */
18__attribute__ ((weak))
19void suspend_power_down_user (void) {
20
21}
22
23/** \brief Run keyboard level Power down
24 *
25 * FIXME: needs doc
26 */
27__attribute__ ((weak))
28void suspend_power_down_kb(void) {
29 suspend_power_down_user();
30}
31
32/** \brief Suspend power down
33 *
34 * FIXME: needs doc
35 */
36void suspend_power_down(void)
37{
38 I2C3733_Control_Set(0); //Disable LED driver
39
40 suspend_power_down_kb();
41}
42
43__attribute__ ((weak)) void matrix_power_up(void) {}
44__attribute__ ((weak)) void matrix_power_down(void) {}
45bool suspend_wakeup_condition(void) {
46 matrix_power_up();
47 matrix_scan();
48 matrix_power_down();
49 for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
50 if (matrix_get_row(r)) return true;
51 }
52 return false;
53}
54
55/** \brief run user level code immediately after wakeup
56 *
57 * FIXME: needs doc
58 */
59__attribute__ ((weak))
60void suspend_wakeup_init_user(void) {
61
62}
63
64/** \brief run keyboard level code immediately after wakeup
65 *
66 * FIXME: needs doc
67 */
68__attribute__ ((weak))
69void suspend_wakeup_init_kb(void) {
70 suspend_wakeup_init_user();
71}
72
73/** \brief run immediately after wakeup
74 *
75 * FIXME: needs doc
76 */
77void suspend_wakeup_init(void) {
78 /* If LEDs are set to enabled, enable the hardware */
79 if (led_enabled) {
80 I2C3733_Control_Set(1);
81 }
82
83 suspend_wakeup_init_kb();
84}
85
diff --git a/tmk_core/common/arm_atsam/timer.c b/tmk_core/common/arm_atsam/timer.c
new file mode 100644
index 000000000..bcfe5002c
--- /dev/null
+++ b/tmk_core/common/arm_atsam/timer.c
@@ -0,0 +1,59 @@
1#include "samd51j18a.h"
2#include "timer.h"
3#include "tmk_core/protocol/arm_atsam/clks.h"
4
5void set_time(uint64_t tset)
6{
7 ms_clk = tset;
8}
9
10void timer_init(void)
11{
12 ms_clk = 0;
13}
14
15uint16_t timer_read(void)
16{
17 return (uint16_t)ms_clk;
18}
19
20uint32_t timer_read32(void)
21{
22 return (uint32_t)ms_clk;
23}
24
25uint64_t timer_read64(void)
26{
27 return ms_clk;
28}
29
30uint16_t timer_elapsed(uint16_t tlast)
31{
32 return TIMER_DIFF_16(timer_read(), tlast);
33}
34
35uint32_t timer_elapsed32(uint32_t tlast)
36{
37 return TIMER_DIFF_32(timer_read32(), tlast);
38}
39
40uint32_t timer_elapsed64(uint32_t tlast)
41{
42 uint64_t tnow = timer_read64();
43 return (tnow >= tlast ? tnow - tlast : UINT64_MAX - tlast + tnow);
44}
45
46void timer_clear(void)
47{
48 ms_clk = 0;
49}
50
51void wait_ms(uint64_t msec)
52{
53 CLK_delay_ms(msec);
54}
55
56void wait_us(uint16_t usec)
57{
58 CLK_delay_us(usec);
59}
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 3d4a48439..5bca64685 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -10,6 +10,7 @@
10#include "timer.h" 10#include "timer.h"
11#include "led.h" 11#include "led.h"
12#include "host.h" 12#include "host.h"
13#include "rgblight_reconfig.h"
13 14
14#ifdef PROTOCOL_LUFA 15#ifdef PROTOCOL_LUFA
15 #include "lufa.h" 16 #include "lufa.h"
@@ -55,6 +56,24 @@ void suspend_idle(uint8_t time)
55 sleep_disable(); 56 sleep_disable();
56} 57}
57 58
59
60// TODO: This needs some cleanup
61
62/** \brief Run keyboard level Power down
63 *
64 * FIXME: needs doc
65 */
66__attribute__ ((weak))
67void suspend_power_down_user (void) { }
68/** \brief Run keyboard level Power down
69 *
70 * FIXME: needs doc
71 */
72__attribute__ ((weak))
73void suspend_power_down_kb(void) {
74 suspend_power_down_user();
75}
76
58#ifndef NO_SUSPEND_POWER_DOWN 77#ifndef NO_SUSPEND_POWER_DOWN
59/** \brief Power down MCU with watchdog timer 78/** \brief Power down MCU with watchdog timer
60 * 79 *
@@ -72,21 +91,6 @@ void suspend_idle(uint8_t time)
72 */ 91 */
73static uint8_t wdt_timeout = 0; 92static uint8_t wdt_timeout = 0;
74 93
75/** \brief Run keyboard level Power down
76 *
77 * FIXME: needs doc
78 */
79__attribute__ ((weak))
80void suspend_power_down_user (void) { }
81/** \brief Run keyboard level Power down
82 *
83 * FIXME: needs doc
84 */
85__attribute__ ((weak))
86void suspend_power_down_kb(void) {
87 suspend_power_down_user();
88}
89
90/** \brief Power down 94/** \brief Power down
91 * 95 *
92 * FIXME: needs doc 96 * FIXME: needs doc
@@ -143,6 +147,8 @@ static void power_down(uint8_t wdto)
143 */ 147 */
144void suspend_power_down(void) 148void suspend_power_down(void)
145{ 149{
150 suspend_power_down_kb();
151
146#ifndef NO_SUSPEND_POWER_DOWN 152#ifndef NO_SUSPEND_POWER_DOWN
147 power_down(WDTO_15MS); 153 power_down(WDTO_15MS);
148#endif 154#endif
@@ -189,12 +195,15 @@ void suspend_wakeup_init(void)
189#endif 195#endif
190 led_set(host_keyboard_leds()); 196 led_set(host_keyboard_leds());
191#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) 197#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
198#ifdef BOOTLOADER_TEENSY
199 wait_ms(10);
200#endif
192 rgblight_enable_noeeprom(); 201 rgblight_enable_noeeprom();
193#ifdef RGBLIGHT_ANIMATIONS 202#ifdef RGBLIGHT_ANIMATIONS
194 rgblight_timer_enable(); 203 rgblight_timer_enable();
195#endif 204#endif
196#endif 205#endif
197 suspend_wakeup_init_kb(); 206 suspend_wakeup_init_kb();
198} 207}
199 208
200#ifndef NO_SUSPEND_POWER_DOWN 209#ifndef NO_SUSPEND_POWER_DOWN
diff --git a/tmk_core/common/backlight.c b/tmk_core/common/backlight.c
index 3e29aacc4..8ddacd98b 100644
--- a/tmk_core/common/backlight.c
+++ b/tmk_core/common/backlight.c
@@ -76,12 +76,51 @@ void backlight_decrease(void)
76 */ 76 */
77void backlight_toggle(void) 77void backlight_toggle(void)
78{ 78{
79 backlight_config.enable ^= 1; 79 bool enabled = backlight_config.enable;
80 if (backlight_config.raw == 1) // enabled but level = 0 80 dprintf("backlight toggle: %u\n", enabled);
81 backlight_config.level = 1; 81 if (enabled)
82 eeconfig_update_backlight(backlight_config.raw); 82 backlight_disable();
83 dprintf("backlight toggle: %u\n", backlight_config.enable); 83 else
84 backlight_set(backlight_config.enable ? backlight_config.level : 0); 84 backlight_enable();
85}
86
87/** \brief Enable backlight
88 *
89 * FIXME: needs doc
90 */
91void backlight_enable(void)
92{
93 if (backlight_config.enable) return; // do nothing if backlight is already on
94
95 backlight_config.enable = true;
96 if (backlight_config.raw == 1) // enabled but level == 0
97 backlight_config.level = 1;
98 eeconfig_update_backlight(backlight_config.raw);
99 dprintf("backlight enable\n");
100 backlight_set(backlight_config.level);
101}
102
103/** /brief Disable backlight
104 *
105 * FIXME: needs doc
106 */
107void backlight_disable(void)
108{
109 if (!backlight_config.enable) return; // do nothing if backlight is already off
110
111 backlight_config.enable = false;
112 eeconfig_update_backlight(backlight_config.raw);
113 dprintf("backlight disable\n");
114 backlight_set(0);
115}
116
117/** /brief Get the backlight status
118 *
119 * FIXME: needs doc
120 */
121bool is_backlight_enabled(void)
122{
123 return backlight_config.enable;
85} 124}
86 125
87/** \brief Backlight step through levels 126/** \brief Backlight step through levels
diff --git a/tmk_core/common/backlight.h b/tmk_core/common/backlight.h
index f57309267..420c9d19e 100644
--- a/tmk_core/common/backlight.h
+++ b/tmk_core/common/backlight.h
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#ifndef BACKLIGHT_H 18#pragma once
19#define BACKLIGHT_H
20 19
21#include <stdint.h> 20#include <stdint.h>
22#include <stdbool.h> 21#include <stdbool.h>
@@ -33,9 +32,11 @@ void backlight_init(void);
33void backlight_increase(void); 32void backlight_increase(void);
34void backlight_decrease(void); 33void backlight_decrease(void);
35void backlight_toggle(void); 34void backlight_toggle(void);
35void backlight_enable(void);
36void backlight_disable(void);
37bool is_backlight_enabled(void);
36void backlight_step(void); 38void backlight_step(void);
37void backlight_set(uint8_t level); 39void backlight_set(uint8_t level);
38void backlight_level(uint8_t level); 40void backlight_level(uint8_t level);
39uint8_t get_backlight_level(void); 41uint8_t get_backlight_level(void);
40 42
41#endif
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
new file mode 100755
index 000000000..a86998550
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -0,0 +1,673 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#include "eeprom_stm32.h"
20
21 FLASH_Status EE_ErasePage(uint32_t);
22
23 uint16_t EE_CheckPage(uint32_t, uint16_t);
24 uint16_t EE_CheckErasePage(uint32_t, uint16_t);
25 uint16_t EE_Format(void);
26 uint32_t EE_FindValidPage(void);
27 uint16_t EE_GetVariablesCount(uint32_t, uint16_t);
28 uint16_t EE_PageTransfer(uint32_t, uint32_t, uint16_t);
29 uint16_t EE_VerifyPageFullWriteVariable(uint16_t, uint16_t);
30
31 uint32_t PageBase0 = EEPROM_PAGE0_BASE;
32 uint32_t PageBase1 = EEPROM_PAGE1_BASE;
33 uint32_t PageSize = EEPROM_PAGE_SIZE;
34 uint16_t Status = EEPROM_NOT_INIT;
35
36// See http://www.st.com/web/en/resource/technical/document/application_note/CD00165693.pdf
37
38/**
39 * @brief Check page for blank
40 * @param page base address
41 * @retval Success or error
42 * EEPROM_BAD_FLASH: page not empty after erase
43 * EEPROM_OK: page blank
44 */
45uint16_t EE_CheckPage(uint32_t pageBase, uint16_t status)
46{
47 uint32_t pageEnd = pageBase + (uint32_t)PageSize;
48
49 // Page Status not EEPROM_ERASED and not a "state"
50 if ((*(__IO uint16_t*)pageBase) != EEPROM_ERASED && (*(__IO uint16_t*)pageBase) != status)
51 return EEPROM_BAD_FLASH;
52 for(pageBase += 4; pageBase < pageEnd; pageBase += 4)
53 if ((*(__IO uint32_t*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty
54 return EEPROM_BAD_FLASH;
55 return EEPROM_OK;
56}
57
58/**
59 * @brief Erase page with increment erase counter (page + 2)
60 * @param page base address
61 * @retval Success or error
62 * FLASH_COMPLETE: success erase
63 * - Flash error code: on write Flash error
64 */
65FLASH_Status EE_ErasePage(uint32_t pageBase)
66{
67 FLASH_Status FlashStatus;
68 uint16_t data = (*(__IO uint16_t*)(pageBase));
69 if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA))
70 data = (*(__IO uint16_t*)(pageBase + 2)) + 1;
71 else
72 data = 0;
73
74 FlashStatus = FLASH_ErasePage(pageBase);
75 if (FlashStatus == FLASH_COMPLETE)
76 FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data);
77
78 return FlashStatus;
79}
80
81/**
82 * @brief Check page for blank and erase it
83 * @param page base address
84 * @retval Success or error
85 * - Flash error code: on write Flash error
86 * - EEPROM_BAD_FLASH: page not empty after erase
87 * - EEPROM_OK: page blank
88 */
89uint16_t EE_CheckErasePage(uint32_t pageBase, uint16_t status)
90{
91 uint16_t FlashStatus;
92 if (EE_CheckPage(pageBase, status) != EEPROM_OK)
93 {
94 FlashStatus = EE_ErasePage(pageBase);
95 if (FlashStatus != FLASH_COMPLETE)
96 return FlashStatus;
97 return EE_CheckPage(pageBase, status);
98 }
99 return EEPROM_OK;
100}
101
102/**
103 * @brief Find valid Page for write or read operation
104 * @param Page0: Page0 base address
105 * Page1: Page1 base address
106 * @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found
107 */
108uint32_t EE_FindValidPage(void)
109{
110 uint16_t status0 = (*(__IO uint16_t*)PageBase0); // Get Page0 actual status
111 uint16_t status1 = (*(__IO uint16_t*)PageBase1); // Get Page1 actual status
112
113 if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED)
114 return PageBase0;
115 if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED)
116 return PageBase1;
117
118 return 0;
119}
120
121/**
122 * @brief Calculate unique variables in EEPROM
123 * @param start: address of first slot to check (page + 4)
124 * @param end: page end address
125 * @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF)
126 * @retval count of variables
127 */
128uint16_t EE_GetVariablesCount(uint32_t pageBase, uint16_t skipAddress)
129{
130 uint16_t varAddress, nextAddress;
131 uint32_t idx;
132 uint32_t pageEnd = pageBase + (uint32_t)PageSize;
133 uint16_t count = 0;
134
135 for (pageBase += 6; pageBase < pageEnd; pageBase += 4)
136 {
137 varAddress = (*(__IO uint16_t*)pageBase);
138 if (varAddress == 0xFFFF || varAddress == skipAddress)
139 continue;
140
141 count++;
142 for(idx = pageBase + 4; idx < pageEnd; idx += 4)
143 {
144 nextAddress = (*(__IO uint16_t*)idx);
145 if (nextAddress == varAddress)
146 {
147 count--;
148 break;
149 }
150 }
151 }
152 return count;
153}
154
155/**
156 * @brief Transfers last updated variables data from the full Page to an empty one.
157 * @param newPage: new page base address
158 * @param oldPage: old page base address
159 * @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF)
160 * @retval Success or error status:
161 * - FLASH_COMPLETE: on success
162 * - EEPROM_OUT_SIZE: if valid new page is full
163 * - Flash error code: on write Flash error
164 */
165uint16_t EE_PageTransfer(uint32_t newPage, uint32_t oldPage, uint16_t SkipAddress)
166{
167 uint32_t oldEnd, newEnd;
168 uint32_t oldIdx, newIdx, idx;
169 uint16_t address, data, found;
170 FLASH_Status FlashStatus;
171
172 // Transfer process: transfer variables from old to the new active page
173 newEnd = newPage + ((uint32_t)PageSize);
174
175 // Find first free element in new page
176 for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4)
177 if ((*(__IO uint32_t*)newIdx) == 0xFFFFFFFF) // Verify if element
178 break; // contents are 0xFFFFFFFF
179 if (newIdx >= newEnd)
180 return EEPROM_OUT_SIZE;
181
182 oldEnd = oldPage + 4;
183 oldIdx = oldPage + (uint32_t)(PageSize - 2);
184
185 for (; oldIdx > oldEnd; oldIdx -= 4)
186 {
187 address = *(__IO uint16_t*)oldIdx;
188 if (address == 0xFFFF || address == SkipAddress)
189 continue; // it's means that power off after write data
190
191 found = 0;
192 for (idx = newPage + 6; idx < newIdx; idx += 4)
193 if ((*(__IO uint16_t*)(idx)) == address)
194 {
195 found = 1;
196 break;
197 }
198
199 if (found)
200 continue;
201
202 if (newIdx < newEnd)
203 {
204 data = (*(__IO uint16_t*)(oldIdx - 2));
205
206 FlashStatus = FLASH_ProgramHalfWord(newIdx, data);
207 if (FlashStatus != FLASH_COMPLETE)
208 return FlashStatus;
209
210 FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address);
211 if (FlashStatus != FLASH_COMPLETE)
212 return FlashStatus;
213
214 newIdx += 4;
215 }
216 else
217 return EEPROM_OUT_SIZE;
218 }
219
220 // Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status
221 data = EE_CheckErasePage(oldPage, EEPROM_ERASED);
222 if (data != EEPROM_OK)
223 return data;
224
225 // Set new Page status
226 FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE);
227 if (FlashStatus != FLASH_COMPLETE)
228 return FlashStatus;
229
230 return EEPROM_OK;
231}
232
233/**
234 * @brief Verify if active page is full and Writes variable in EEPROM.
235 * @param Address: 16 bit virtual address of the variable
236 * @param Data: 16 bit data to be written as variable value
237 * @retval Success or error status:
238 * - FLASH_COMPLETE: on success
239 * - EEPROM_PAGE_FULL: if valid page is full (need page transfer)
240 * - EEPROM_NO_VALID_PAGE: if no valid page was found
241 * - EEPROM_OUT_SIZE: if EEPROM size exceeded
242 * - Flash error code: on write Flash error
243 */
244uint16_t EE_VerifyPageFullWriteVariable(uint16_t Address, uint16_t Data)
245{
246 FLASH_Status FlashStatus;
247 uint32_t idx, pageBase, pageEnd, newPage;
248 uint16_t count;
249
250 // Get valid Page for write operation
251 pageBase = EE_FindValidPage();
252 if (pageBase == 0)
253 return EEPROM_NO_VALID_PAGE;
254
255 // Get the valid Page end Address
256 pageEnd = pageBase + PageSize; // Set end of page
257
258 for (idx = pageEnd - 2; idx > pageBase; idx -= 4)
259 {
260 if ((*(__IO uint16_t*)idx) == Address) // Find last value for address
261 {
262 count = (*(__IO uint16_t*)(idx - 2)); // Read last data
263 if (count == Data)
264 return EEPROM_OK;
265 if (count == 0xFFFF)
266 {
267 FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data
268 if (FlashStatus == FLASH_COMPLETE)
269 return EEPROM_OK;
270 }
271 break;
272 }
273 }
274
275 // Check each active page address starting from begining
276 for (idx = pageBase + 4; idx < pageEnd; idx += 4)
277 if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
278 { // contents are 0xFFFFFFFF
279 FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data
280 if (FlashStatus != FLASH_COMPLETE)
281 return FlashStatus;
282 FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address
283 if (FlashStatus != FLASH_COMPLETE)
284 return FlashStatus;
285 return EEPROM_OK;
286 }
287
288 // Empty slot not found, need page transfer
289 // Calculate unique variables in page
290 count = EE_GetVariablesCount(pageBase, Address) + 1;
291 if (count >= (PageSize / 4 - 1))
292 return EEPROM_OUT_SIZE;
293
294 if (pageBase == PageBase1)
295 newPage = PageBase0; // New page address where variable will be moved to
296 else
297 newPage = PageBase1;
298
299 // Set the new Page status to RECEIVE_DATA status
300 FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA);
301 if (FlashStatus != FLASH_COMPLETE)
302 return FlashStatus;
303
304 // Write the variable passed as parameter in the new active page
305 FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data);
306 if (FlashStatus != FLASH_COMPLETE)
307 return FlashStatus;
308
309 FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address);
310 if (FlashStatus != FLASH_COMPLETE)
311 return FlashStatus;
312
313 return EE_PageTransfer(newPage, pageBase, Address);
314}
315
316/*EEPROMClass::EEPROMClass(void)
317{
318 PageBase0 = EEPROM_PAGE0_BASE;
319 PageBase1 = EEPROM_PAGE1_BASE;
320 PageSize = EEPROM_PAGE_SIZE;
321 Status = EEPROM_NOT_INIT;
322}*/
323/*
324uint16_t EEPROM_init(uint32_t pageBase0, uint32_t pageBase1, uint32_t pageSize)
325{
326 PageBase0 = pageBase0;
327 PageBase1 = pageBase1;
328 PageSize = pageSize;
329 return EEPROM_init();
330}*/
331
332uint16_t EEPROM_init(void)
333{
334 uint16_t status0 = 6, status1 = 6;
335 FLASH_Status FlashStatus;
336
337 FLASH_Unlock();
338 Status = EEPROM_NO_VALID_PAGE;
339
340 status0 = (*(__IO uint16_t *)PageBase0);
341 status1 = (*(__IO uint16_t *)PageBase1);
342
343 switch (status0)
344 {
345/*
346 Page0 Page1
347 ----- -----
348 EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased
349 EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased
350 EEPROM_ERASED make EE_Format
351 any Error: EEPROM_NO_VALID_PAGE
352*/
353 case EEPROM_ERASED:
354 if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid
355 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
356 else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive
357 {
358 FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
359 if (FlashStatus != FLASH_COMPLETE)
360 Status = FlashStatus;
361 else
362 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
363 }
364 else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM
365 Status = EEPROM_format();
366 break;
367/*
368 Page0 Page1
369 ----- -----
370 EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0
371 EEPROM_ERASED Page0 need set to valid, Page1 erased
372 any EEPROM_NO_VALID_PAGE
373*/
374 case EEPROM_RECEIVE_DATA:
375 if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid
376 Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF);
377 else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased
378 {
379 Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
380 if (Status == EEPROM_OK)
381 {
382 FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
383 if (FlashStatus != FLASH_COMPLETE)
384 Status = FlashStatus;
385 else
386 Status = EEPROM_OK;
387 }
388 }
389 break;
390/*
391 Page0 Page1
392 ----- -----
393 EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE
394 EEPROM_RECEIVE_DATA Transfer Page0 to Page1
395 any Page0 valid, Page1 erased
396*/
397 case EEPROM_VALID_PAGE:
398 if (status1 == EEPROM_VALID_PAGE) // Both pages valid
399 Status = EEPROM_NO_VALID_PAGE;
400 else if (status1 == EEPROM_RECEIVE_DATA)
401 Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF);
402 else
403 Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
404 break;
405/*
406 Page0 Page1
407 ----- -----
408 any EEPROM_VALID_PAGE Page1 valid, Page0 erased
409 EEPROM_RECEIVE_DATA Page1 valid, Page0 erased
410 any EEPROM_NO_VALID_PAGE
411*/
412 default:
413 if (status1 == EEPROM_VALID_PAGE)
414 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0
415 else if (status1 == EEPROM_RECEIVE_DATA)
416 {
417 FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
418 if (FlashStatus != FLASH_COMPLETE)
419 Status = FlashStatus;
420 else
421 Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
422 }
423 break;
424 }
425 return Status;
426}
427
428/**
429 * @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0
430 * @param PAGE0 and PAGE1 base addresses
431 * @retval Status of the last operation (Flash write or erase) done during EEPROM formating
432 */
433uint16_t EEPROM_format(void)
434{
435 uint16_t status;
436 FLASH_Status FlashStatus;
437
438 FLASH_Unlock();
439
440 // Erase Page0
441 status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE);
442 if (status != EEPROM_OK)
443 return status;
444 if ((*(__IO uint16_t*)PageBase0) == EEPROM_ERASED)
445 {
446 // Set Page0 as valid page: Write VALID_PAGE at Page0 base address
447 FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
448 if (FlashStatus != FLASH_COMPLETE)
449 return FlashStatus;
450 }
451 // Erase Page1
452 return EE_CheckErasePage(PageBase1, EEPROM_ERASED);
453}
454
455/**
456 * @brief Returns the erase counter for current page
457 * @param Data: Global variable contains the read variable value
458 * @retval Success or error status:
459 * - EEPROM_OK: if erases counter return.
460 * - EEPROM_NO_VALID_PAGE: if no valid page was found.
461 */
462uint16_t EEPROM_erases(uint16_t *Erases)
463{
464 uint32_t pageBase;
465 if (Status != EEPROM_OK)
466 if (EEPROM_init() != EEPROM_OK)
467 return Status;
468
469 // Get active Page for read operation
470 pageBase = EE_FindValidPage();
471 if (pageBase == 0)
472 return EEPROM_NO_VALID_PAGE;
473
474 *Erases = (*(__IO uint16_t*)pageBase+2);
475 return EEPROM_OK;
476}
477
478/**
479 * @brief Returns the last stored variable data, if found,
480 * which correspond to the passed virtual address
481 * @param Address: Variable virtual address
482 * @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors
483 */
484/*
485uint16_t EEPROM_read (uint16_t Address)
486{
487 uint16_t data;
488 EEPROM_read(Address, &data);
489 return data;
490}*/
491
492/**
493 * @brief Returns the last stored variable data, if found,
494 * which correspond to the passed virtual address
495 * @param Address: Variable virtual address
496 * @param Data: Pointer to data variable
497 * @retval Success or error status:
498 * - EEPROM_OK: if variable was found
499 * - EEPROM_BAD_ADDRESS: if the variable was not found
500 * - EEPROM_NO_VALID_PAGE: if no valid page was found.
501 */
502uint16_t EEPROM_read(uint16_t Address, uint16_t *Data)
503{
504 uint32_t pageBase, pageEnd;
505
506 // Set default data (empty EEPROM)
507 *Data = EEPROM_DEFAULT_DATA;
508
509 if (Status == EEPROM_NOT_INIT)
510 if (EEPROM_init() != EEPROM_OK)
511 return Status;
512
513 // Get active Page for read operation
514 pageBase = EE_FindValidPage();
515 if (pageBase == 0)
516 return EEPROM_NO_VALID_PAGE;
517
518 // Get the valid Page end Address
519 pageEnd = pageBase + ((uint32_t)(PageSize - 2));
520
521 // Check each active page address starting from end
522 for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
523 if ((*(__IO uint16_t*)pageEnd) == Address) // Compare the read address with the virtual address
524 {
525 *Data = (*(__IO uint16_t*)(pageEnd - 2)); // Get content of Address-2 which is variable value
526 return EEPROM_OK;
527 }
528
529 // Return ReadStatus value: (0: variable exist, 1: variable doesn't exist)
530 return EEPROM_BAD_ADDRESS;
531}
532
533/**
534 * @brief Writes/upadtes variable data in EEPROM.
535 * @param VirtAddress: Variable virtual address
536 * @param Data: 16 bit data to be written
537 * @retval Success or error status:
538 * - FLASH_COMPLETE: on success
539 * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
540 * - EEPROM_PAGE_FULL: if valid page is full
541 * - EEPROM_NO_VALID_PAGE: if no valid page was found
542 * - EEPROM_OUT_SIZE: if no empty EEPROM variables
543 * - Flash error code: on write Flash error
544 */
545uint16_t EEPROM_write(uint16_t Address, uint16_t Data)
546{
547 if (Status == EEPROM_NOT_INIT)
548 if (EEPROM_init() != EEPROM_OK)
549 return Status;
550
551 if (Address == 0xFFFF)
552 return EEPROM_BAD_ADDRESS;
553
554 // Write the variable virtual address and value in the EEPROM
555 uint16_t status = EE_VerifyPageFullWriteVariable(Address, Data);
556 return status;
557}
558
559/**
560 * @brief Writes/upadtes variable data in EEPROM.
561 The value is written only if differs from the one already saved at the same address.
562 * @param VirtAddress: Variable virtual address
563 * @param Data: 16 bit data to be written
564 * @retval Success or error status:
565 * - EEPROM_SAME_VALUE: If new Data matches existing EEPROM Data
566 * - FLASH_COMPLETE: on success
567 * - EEPROM_BAD_ADDRESS: if address = 0xFFFF
568 * - EEPROM_PAGE_FULL: if valid page is full
569 * - EEPROM_NO_VALID_PAGE: if no valid page was found
570 * - EEPROM_OUT_SIZE: if no empty EEPROM variables
571 * - Flash error code: on write Flash error
572 */
573uint16_t EEPROM_update(uint16_t Address, uint16_t Data)
574{
575 uint16_t temp;
576 EEPROM_read(Address, &temp);
577 if (temp == Data)
578 return EEPROM_SAME_VALUE;
579 else
580 return EEPROM_write(Address, Data);
581}
582
583/**
584 * @brief Return number of variable
585 * @retval Number of variables
586 */
587uint16_t EEPROM_count(uint16_t *Count)
588{
589 if (Status == EEPROM_NOT_INIT)
590 if (EEPROM_init() != EEPROM_OK)
591 return Status;
592
593 // Get valid Page for write operation
594 uint32_t pageBase = EE_FindValidPage();
595 if (pageBase == 0)
596 return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers
597
598 *Count = EE_GetVariablesCount(pageBase, 0xFFFF);
599 return EEPROM_OK;
600}
601
602uint16_t EEPROM_maxcount(void)
603{
604 return ((PageSize / 4)-1);
605}
606
607
608uint8_t eeprom_read_byte (const uint8_t *Address)
609{
610 const uint16_t p = (const uint32_t) Address;
611 uint16_t temp;
612 EEPROM_read(p, &temp);
613 return (uint8_t) temp;
614}
615
616void eeprom_write_byte (uint8_t *Address, uint8_t Value)
617{
618 uint16_t p = (uint32_t) Address;
619 EEPROM_write(p, (uint16_t) Value);
620}
621
622void eeprom_update_byte (uint8_t *Address, uint8_t Value)
623{
624 uint16_t p = (uint32_t) Address;
625 EEPROM_update(p, (uint16_t) Value);
626}
627
628uint16_t eeprom_read_word (const uint16_t *Address)
629{
630 const uint16_t p = (const uint32_t) Address;
631 uint16_t temp;
632 EEPROM_read(p, &temp);
633 return temp;
634}
635
636void eeprom_write_word (uint16_t *Address, uint16_t Value)
637{
638 uint16_t p = (uint32_t) Address;
639 EEPROM_write(p, Value);
640}
641
642void eeprom_update_word (uint16_t *Address, uint16_t Value)
643{
644 uint16_t p = (uint32_t) Address;
645 EEPROM_update(p, Value);
646}
647
648uint32_t eeprom_read_dword (const uint32_t *Address)
649{
650 const uint16_t p = (const uint32_t) Address;
651 uint16_t temp1, temp2;
652 EEPROM_read(p, &temp1);
653 EEPROM_read(p + 1, &temp2);
654 return temp1 | (temp2 << 16);
655}
656
657void eeprom_write_dword (uint32_t *Address, uint32_t Value)
658{
659 uint16_t temp = (uint16_t) Value;
660 uint16_t p = (uint32_t) Address;
661 EEPROM_write(p, temp);
662 temp = (uint16_t) (Value >> 16);
663 EEPROM_write(p + 1, temp);
664}
665
666void eeprom_update_dword (uint32_t *Address, uint32_t Value)
667{
668 uint16_t temp = (uint16_t) Value;
669 uint16_t p = (uint32_t) Address;
670 EEPROM_update(p, temp);
671 temp = (uint16_t) (Value >> 16);
672 EEPROM_update(p + 1, temp);
673}
diff --git a/tmk_core/common/chibios/eeprom_stm32.h b/tmk_core/common/chibios/eeprom_stm32.h
new file mode 100755
index 000000000..09229530c
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.h
@@ -0,0 +1,95 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19// This file must be modified if the MCU is not defined below.
20// This library also assumes that the pages are not used by the firmware.
21
22#ifndef __EEPROM_H
23#define __EEPROM_H
24
25#include "ch.h"
26#include "hal.h"
27#include "flash_stm32.h"
28
29// HACK ALERT. This definition may not match your processor
30// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
31#if defined(EEPROM_EMU_STM32F303xC)
32 #define MCU_STM32F303CC
33#elif defined(EEPROM_EMU_STM32F103xB)
34 #define MCU_STM32F103RB
35#else
36 #error "not implemented."
37#endif
38
39#ifndef EEPROM_PAGE_SIZE
40 #if defined (MCU_STM32F103RB)
41 #define EEPROM_PAGE_SIZE (uint16_t)0x400 /* Page size = 1KByte */
42 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC)
43 #define EEPROM_PAGE_SIZE (uint16_t)0x800 /* Page size = 2KByte */
44 #else
45 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
46 #endif
47#endif
48
49#ifndef EEPROM_START_ADDRESS
50 #if defined (MCU_STM32F103RB)
51 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 128 * 1024 - 2 * EEPROM_PAGE_SIZE))
52 #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
53 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE))
54 #elif defined (MCU_STM32F103RD)
55 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE))
56 #elif defined (MCU_STM32F303CC)
57 #define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE))
58 #else
59 #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
60 #endif
61#endif
62
63/* Pages 0 and 1 base and end addresses */
64#define EEPROM_PAGE0_BASE ((uint32_t)(EEPROM_START_ADDRESS + 0x000))
65#define EEPROM_PAGE1_BASE ((uint32_t)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE))
66
67/* Page status definitions */
68#define EEPROM_ERASED ((uint16_t)0xFFFF) /* PAGE is empty */
69#define EEPROM_RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */
70#define EEPROM_VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
71
72/* Page full define */
73enum uint16_t
74 {
75 EEPROM_OK = ((uint16_t)0x0000),
76 EEPROM_OUT_SIZE = ((uint16_t)0x0081),
77 EEPROM_BAD_ADDRESS = ((uint16_t)0x0082),
78 EEPROM_BAD_FLASH = ((uint16_t)0x0083),
79 EEPROM_NOT_INIT = ((uint16_t)0x0084),
80 EEPROM_SAME_VALUE = ((uint16_t)0x0085),
81 EEPROM_NO_VALID_PAGE = ((uint16_t)0x00AB)
82 };
83
84#define EEPROM_DEFAULT_DATA 0xFFFF
85
86 uint16_t EEPROM_init(void);
87 uint16_t EEPROM_format(void);
88 uint16_t EEPROM_erases(uint16_t *);
89 uint16_t EEPROM_read (uint16_t address, uint16_t *data);
90 uint16_t EEPROM_write(uint16_t address, uint16_t data);
91 uint16_t EEPROM_update(uint16_t address, uint16_t data);
92 uint16_t EEPROM_count(uint16_t *);
93 uint16_t EEPROM_maxcount(void);
94
95#endif /* __EEPROM_H */
diff --git a/tmk_core/common/chibios/eeprom.c b/tmk_core/common/chibios/eeprom_teensy.c
index 9061b790c..9061b790c 100644
--- a/tmk_core/common/chibios/eeprom.c
+++ b/tmk_core/common/chibios/eeprom_teensy.c
diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c
new file mode 100755
index 000000000..273593484
--- /dev/null
+++ b/tmk_core/common/chibios/flash_stm32.c
@@ -0,0 +1,188 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#if defined(EEPROM_EMU_STM32F303xC)
20 #define STM32F303xC
21 #include "stm32f3xx.h"
22#elif defined(EEPROM_EMU_STM32F103xB)
23 #define STM32F103xB
24 #include "stm32f1xx.h"
25#else
26 #error "not implemented."
27#endif
28
29#include "flash_stm32.h"
30
31#if defined(EEPROM_EMU_STM32F103xB)
32 #define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
33#endif
34
35/* Delay definition */
36#define EraseTimeout ((uint32_t)0x00000FFF)
37#define ProgramTimeout ((uint32_t)0x0000001F)
38
39#define ASSERT(exp) (void)((0))
40
41/**
42 * @brief Inserts a time delay.
43 * @param None
44 * @retval None
45 */
46static void delay(void)
47{
48 __IO uint32_t i = 0;
49 for(i = 0xFF; i != 0; i--) { }
50}
51
52/**
53 * @brief Returns the FLASH Status.
54 * @param None
55 * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
56 * FLASH_ERROR_WRP or FLASH_COMPLETE
57 */
58FLASH_Status FLASH_GetStatus(void)
59{
60 if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)
61 return FLASH_BUSY;
62
63 if ((FLASH->SR & FLASH_SR_PGERR) != 0)
64 return FLASH_ERROR_PG;
65
66 if ((FLASH->SR & FLASH_SR_WRPERR) != 0 )
67 return FLASH_ERROR_WRP;
68
69 if ((FLASH->SR & FLASH_OBR_OPTERR) != 0 )
70 return FLASH_ERROR_OPT;
71
72 return FLASH_COMPLETE;
73}
74
75/**
76 * @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
77 * @param Timeout: FLASH progamming Timeout
78 * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
79 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
80 */
81FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
82{
83 FLASH_Status status;
84
85 /* Check for the Flash Status */
86 status = FLASH_GetStatus();
87 /* Wait for a Flash operation to complete or a TIMEOUT to occur */
88 while ((status == FLASH_BUSY) && (Timeout != 0x00))
89 {
90 delay();
91 status = FLASH_GetStatus();
92 Timeout--;
93 }
94 if (Timeout == 0)
95 status = FLASH_TIMEOUT;
96 /* Return the operation status */
97 return status;
98}
99
100/**
101 * @brief Erases a specified FLASH page.
102 * @param Page_Address: The page address to be erased.
103 * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
104 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
105 */
106FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
107{
108 FLASH_Status status = FLASH_COMPLETE;
109 /* Check the parameters */
110 ASSERT(IS_FLASH_ADDRESS(Page_Address));
111 /* Wait for last operation to be completed */
112 status = FLASH_WaitForLastOperation(EraseTimeout);
113
114 if(status == FLASH_COMPLETE)
115 {
116 /* if the previous operation is completed, proceed to erase the page */
117 FLASH->CR |= FLASH_CR_PER;
118 FLASH->AR = Page_Address;
119 FLASH->CR |= FLASH_CR_STRT;
120
121 /* Wait for last operation to be completed */
122 status = FLASH_WaitForLastOperation(EraseTimeout);
123 if(status != FLASH_TIMEOUT)
124 {
125 /* if the erase operation is completed, disable the PER Bit */
126 FLASH->CR &= ~FLASH_CR_PER;
127 }
128 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
129 }
130 /* Return the Erase Status */
131 return status;
132}
133
134/**
135 * @brief Programs a half word at a specified address.
136 * @param Address: specifies the address to be programmed.
137 * @param Data: specifies the data to be programmed.
138 * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
139 * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
140 */
141FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
142{
143 FLASH_Status status = FLASH_BAD_ADDRESS;
144
145 if (IS_FLASH_ADDRESS(Address))
146 {
147 /* Wait for last operation to be completed */
148 status = FLASH_WaitForLastOperation(ProgramTimeout);
149 if(status == FLASH_COMPLETE)
150 {
151 /* if the previous operation is completed, proceed to program the new data */
152 FLASH->CR |= FLASH_CR_PG;
153 *(__IO uint16_t*)Address = Data;
154 /* Wait for last operation to be completed */
155 status = FLASH_WaitForLastOperation(ProgramTimeout);
156 if(status != FLASH_TIMEOUT)
157 {
158 /* if the program operation is completed, disable the PG Bit */
159 FLASH->CR &= ~FLASH_CR_PG;
160 }
161 FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
162 }
163 }
164 return status;
165}
166
167/**
168 * @brief Unlocks the FLASH Program Erase Controller.
169 * @param None
170 * @retval None
171 */
172void FLASH_Unlock(void)
173{
174 /* Authorize the FPEC Access */
175 FLASH->KEYR = FLASH_KEY1;
176 FLASH->KEYR = FLASH_KEY2;
177}
178
179/**
180 * @brief Locks the FLASH Program Erase Controller.
181 * @param None
182 * @retval None
183 */
184void FLASH_Lock(void)
185{
186 /* Set the Lock Bit to lock the FPEC and the FCR */
187 FLASH->CR |= FLASH_CR_LOCK;
188}
diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h
new file mode 100755
index 000000000..cc065cbca
--- /dev/null
+++ b/tmk_core/common/chibios/flash_stm32.h
@@ -0,0 +1,53 @@
1/*
2 * This software is experimental and a work in progress.
3 * Under no circumstances should these files be used in relation to any critical system(s).
4 * Use of these files is at your own risk.
5 *
6 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
7 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
8 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
9 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
11 * DEALINGS IN THE SOFTWARE.
12 *
13 * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
14 * https://github.com/leaflabs/libmaple
15 *
16 * Modifications for QMK and STM32F303 by Yiancar
17 */
18
19#ifndef __FLASH_STM32_H
20#define __FLASH_STM32_H
21
22#ifdef __cplusplus
23 extern "C" {
24#endif
25
26#include "ch.h"
27#include "hal.h"
28
29typedef enum
30 {
31 FLASH_BUSY = 1,
32 FLASH_ERROR_PG,
33 FLASH_ERROR_WRP,
34 FLASH_ERROR_OPT,
35 FLASH_COMPLETE,
36 FLASH_TIMEOUT,
37 FLASH_BAD_ADDRESS
38 } FLASH_Status;
39
40#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF))
41
42FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
43FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
44FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
45
46void FLASH_Unlock(void);
47void FLASH_Lock(void);
48
49#ifdef __cplusplus
50}
51#endif
52
53#endif /* __FLASH_STM32_H */
diff --git a/tmk_core/common/command.c b/tmk_core/common/command.c
index f79d5a257..aab99290d 100644
--- a/tmk_core/common/command.c
+++ b/tmk_core/common/command.c
@@ -181,7 +181,11 @@ static void print_version(void)
181 print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") " 181 print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
182 "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") " 182 "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
183 "VER: " STR(DEVICE_VER) "\n"); 183 "VER: " STR(DEVICE_VER) "\n");
184#ifdef SKIP_VERSION
185 print("BUILD: (" __DATE__ ")\n");
186#else
184 print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n"); 187 print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n");
188#endif
185 189
186 /* build options */ 190 /* build options */
187 print("OPTIONS:" 191 print("OPTIONS:"
diff --git a/tmk_core/common/command.h b/tmk_core/common/command.h
index d9d89ba0f..c38f2b9e8 100644
--- a/tmk_core/common/command.h
+++ b/tmk_core/common/command.h
@@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>. 15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/ 16*/
17 17
18#ifndef COMMAND_H 18#pragma once
19#define COMMAND
20 19
21/* FIXME: Add doxygen comments for the behavioral defines in here. */ 20/* FIXME: Add doxygen comments for the behavioral defines in here. */
22 21
@@ -155,5 +154,3 @@ bool command_proc(uint8_t code);
155 154
156#define XMAGIC_KC(key) KC_##key 155#define XMAGIC_KC(key) KC_##key
157#define MAGIC_KC(key) XMAGIC_KC(key) 156#define MAGIC_KC(key) XMAGIC_KC(key)
158
159#endif
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 3e5987ee3..d8bab7d2e 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -3,29 +3,59 @@
3#include "eeprom.h" 3#include "eeprom.h"
4#include "eeconfig.h" 4#include "eeconfig.h"
5 5
6/** \brief eeconfig initialization 6#ifdef STM32_EEPROM_ENABLE
7#include "hal.h"
8#include "eeprom_stm32.h"
9#endif
10
11extern uint32_t default_layer_state;
12/** \brief eeconfig enable
7 * 13 *
8 * FIXME: needs doc 14 * FIXME: needs doc
9 */ 15 */
10void eeconfig_init(void) 16__attribute__ ((weak))
11{ 17void eeconfig_init_user(void) {
12 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); 18 // Reset user EEPROM value to blank, rather than to a set value
13 eeprom_update_byte(EECONFIG_DEBUG, 0); 19 eeconfig_update_user(0);
14 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); 20}
15 eeprom_update_byte(EECONFIG_KEYMAP, 0); 21
16 eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0); 22__attribute__ ((weak))
17#ifdef BACKLIGHT_ENABLE 23void eeconfig_init_kb(void) {
18 eeprom_update_byte(EECONFIG_BACKLIGHT, 0); 24 // Reset Keyboard EEPROM value to blank, rather than to a set value
19#endif 25 eeconfig_update_kb(0);
20#ifdef AUDIO_ENABLE 26
21 eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default 27 eeconfig_init_user();
22#endif 28}
23#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) 29
24 eeprom_update_dword(EECONFIG_RGBLIGHT, 0); 30
25#endif 31/*
26#ifdef STENO_ENABLE 32 * FIXME: needs doc
27 eeprom_update_byte(EECONFIG_STENOMODE, 0); 33 */
34void eeconfig_init_quantum(void) {
35#ifdef STM32_EEPROM_ENABLE
36 EEPROM_format();
28#endif 37#endif
38 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
39 eeprom_update_byte(EECONFIG_DEBUG, 0);
40 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
41 default_layer_state = 0;
42 eeprom_update_byte(EECONFIG_KEYMAP, 0);
43 eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
44 eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
45 eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
46 eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
47 eeprom_update_byte(EECONFIG_STENOMODE, 0);
48
49 eeconfig_init_kb();
50}
51
52/** \brief eeconfig initialization
53 *
54 * FIXME: needs doc
55 */
56void eeconfig_init(void) {
57
58 eeconfig_init_quantum();
29} 59}
30 60
31/** \brief eeconfig enable 61/** \brief eeconfig enable
@@ -43,7 +73,10 @@ void eeconfig_enable(void)
43 */ 73 */
44void eeconfig_disable(void) 74void eeconfig_disable(void)
45{ 75{
46 eeprom_update_word(EECONFIG_MAGIC, 0xFFFF); 76#ifdef STM32_EEPROM_ENABLE
77 EEPROM_format();
78#endif
79 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
47} 80}
48 81
49/** \brief eeconfig is enabled 82/** \brief eeconfig is enabled
@@ -55,6 +88,15 @@ bool eeconfig_is_enabled(void)
55 return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); 88 return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
56} 89}
57 90
91/** \brief eeconfig is disabled
92 *
93 * FIXME: needs doc
94 */
95bool eeconfig_is_disabled(void)
96{
97 return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
98}
99
58/** \brief eeconfig read debug 100/** \brief eeconfig read debug
59 * 101 *
60 * FIXME: needs doc 102 * FIXME: needs doc
@@ -88,7 +130,6 @@ uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMA
88 */ 130 */
89void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); } 131void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); }
90 132
91#ifdef BACKLIGHT_ENABLE
92/** \brief eeconfig read backlight 133/** \brief eeconfig read backlight
93 * 134 *
94 * FIXME: needs doc 135 * FIXME: needs doc
@@ -99,9 +140,8 @@ uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BA
99 * FIXME: needs doc 140 * FIXME: needs doc
100 */ 141 */
101void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); } 142void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); }
102#endif
103 143
104#ifdef AUDIO_ENABLE 144
105/** \brief eeconfig read audio 145/** \brief eeconfig read audio
106 * 146 *
107 * FIXME: needs doc 147 * FIXME: needs doc
@@ -112,4 +152,28 @@ uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO)
112 * FIXME: needs doc 152 * FIXME: needs doc
113 */ 153 */
114void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); } 154void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); }
115#endif 155
156
157/** \brief eeconfig read kb
158 *
159 * FIXME: needs doc
160 */
161uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); }
162/** \brief eeconfig update kb
163 *
164 * FIXME: needs doc
165 */
166
167void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); }
168/** \brief eeconfig read user
169 *
170 * FIXME: needs doc
171 */
172uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); }
173/** \brief eeconfig update user
174 *
175 * FIXME: needs doc
176 */
177void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); }
178
179
diff --git a/tmk_core/common/eeconfig.h b/tmk_core/common/eeconfig.h
index 1397a90c7..8d4e1d4d0 100644
--- a/tmk_core/common/eeconfig.h
+++ b/tmk_core/common/eeconfig.h
@@ -23,21 +23,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23 23
24 24
25#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED 25#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
26#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
26 27
27/* eeprom parameteter address */ 28/* eeprom parameteter address */
29#if !defined(STM32_EEPROM_ENABLE)
28#define EECONFIG_MAGIC (uint16_t *)0 30#define EECONFIG_MAGIC (uint16_t *)0
29#define EECONFIG_DEBUG (uint8_t *)2 31#define EECONFIG_DEBUG (uint8_t *)2
30#define EECONFIG_DEFAULT_LAYER (uint8_t *)3 32#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
31#define EECONFIG_KEYMAP (uint8_t *)4 33#define EECONFIG_KEYMAP (uint8_t *)4
32#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5 34#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
33#define EECONFIG_BACKLIGHT (uint8_t *)6 35#define EECONFIG_BACKLIGHT (uint8_t *)6
34#define EECONFIG_AUDIO (uint8_t *)7 36#define EECONFIG_AUDIO (uint8_t *)7
35#define EECONFIG_RGBLIGHT (uint32_t *)8 37#define EECONFIG_RGBLIGHT (uint32_t *)8
36#define EECONFIG_UNICODEMODE (uint8_t *)12 38#define EECONFIG_UNICODEMODE (uint8_t *)12
37#define EECONFIG_STENOMODE (uint8_t *)13 39#define EECONFIG_STENOMODE (uint8_t *)13
38// EEHANDS for two handed boards 40// EEHANDS for two handed boards
39#define EECONFIG_HANDEDNESS (uint8_t *)14 41#define EECONFIG_HANDEDNESS (uint8_t *)14
42#define EECONFIG_KEYBOARD (uint32_t *)15
43#define EECONFIG_USER (uint32_t *)19
40 44
45#else
46/* STM32F3 uses 16byte block. Reconfigure memory map */
47#define EECONFIG_MAGIC (uint16_t *)0
48#define EECONFIG_DEBUG (uint8_t *)1
49#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
50#define EECONFIG_KEYMAP (uint8_t *)3
51#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
52#define EECONFIG_BACKLIGHT (uint8_t *)5
53#define EECONFIG_AUDIO (uint8_t *)6
54#define EECONFIG_RGBLIGHT (uint32_t *)7
55#define EECONFIG_UNICODEMODE (uint8_t *)9
56#define EECONFIG_STENOMODE (uint8_t *)10
57// EEHANDS for two handed boards
58#define EECONFIG_HANDEDNESS (uint8_t *)11
59#define EECONFIG_KEYBOARD (uint32_t *)12
60#define EECONFIG_USER (uint32_t *)14
61#endif
41 62
42/* debug bit */ 63/* debug bit */
43#define EECONFIG_DEBUG_ENABLE (1<<0) 64#define EECONFIG_DEBUG_ENABLE (1<<0)
@@ -57,8 +78,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
57 78
58 79
59bool eeconfig_is_enabled(void); 80bool eeconfig_is_enabled(void);
81bool eeconfig_is_disabled(void);
60 82
61void eeconfig_init(void); 83void eeconfig_init(void);
84void eeconfig_init_quantum(void);
85void eeconfig_init_kb(void);
86void eeconfig_init_user(void);
62 87
63void eeconfig_enable(void); 88void eeconfig_enable(void);
64 89
@@ -83,4 +108,9 @@ uint8_t eeconfig_read_audio(void);
83void eeconfig_update_audio(uint8_t val); 108void eeconfig_update_audio(uint8_t val);
84#endif 109#endif
85 110
111uint32_t eeconfig_read_kb(void);
112void eeconfig_update_kb(uint32_t val);
113uint32_t eeconfig_read_user(void);
114void eeconfig_update_user(uint32_t val);
115
86#endif 116#endif
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
index e12b62216..f5d041699 100644
--- a/tmk_core/common/host.c
+++ b/tmk_core/common/host.c
@@ -22,6 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
22#include "util.h" 22#include "util.h"
23#include "debug.h" 23#include "debug.h"
24 24
25#ifdef NKRO_ENABLE
26 #include "keycode_config.h"
27 extern keymap_config_t keymap_config;
28#endif
29
25static host_driver_t *driver; 30static host_driver_t *driver;
26static uint16_t last_system_report = 0; 31static uint16_t last_system_report = 0;
27static uint16_t last_consumer_report = 0; 32static uint16_t last_consumer_report = 0;
@@ -46,6 +51,20 @@ uint8_t host_keyboard_leds(void)
46void host_keyboard_send(report_keyboard_t *report) 51void host_keyboard_send(report_keyboard_t *report)
47{ 52{
48 if (!driver) return; 53 if (!driver) return;
54#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
55 if (keyboard_protocol && keymap_config.nkro) {
56 /* The callers of this function assume that report->mods is where mods go in.
57 * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
58 */
59 report->nkro.mods = report->mods;
60 report->nkro.report_id = REPORT_ID_NKRO;
61 } else
62#endif
63 {
64#ifdef KEYBOARD_SHARED_EP
65 report->report_id = REPORT_ID_KEYBOARD;
66#endif
67 }
49 (*driver->send_keyboard)(report); 68 (*driver->send_keyboard)(report);
50 69
51 if (debug_keyboard) { 70 if (debug_keyboard) {
@@ -60,6 +79,9 @@ void host_keyboard_send(report_keyboard_t *report)
60void host_mouse_send(report_mouse_t *report) 79void host_mouse_send(report_mouse_t *report)
61{ 80{
62 if (!driver) return; 81 if (!driver) return;
82#ifdef MOUSE_SHARED_EP
83 report->report_id = REPORT_ID_MOUSE;
84#endif
63 (*driver->send_mouse)(report); 85 (*driver->send_mouse)(report);
64} 86}
65 87
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index 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
78extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; 81extern 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
127void 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 */
136void keyboard_setup(void) { 147void 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 */
153void keyboard_init(void) { 165void 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
257MATRIX_LOOP_END: 267MATRIX_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
60void disable_jtag(void);
61
60/* it runs once at early stage of startup before keyboard_init. */ 62/* it runs once at early stage of startup before keyboard_init. */
61void keyboard_setup(void); 63void keyboard_setup(void);
62/* it runs once after initializing host side protocol, debug and MCU peripherals. */ 64/* it runs once after initializing host side protocol, debug and MCU peripherals. */
diff --git a/tmk_core/common/keycode.h b/tmk_core/common/keycode.h
index 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 @@
27uint8_t has_anykey(report_keyboard_t* keyboard_report) 28uint8_t has_anykey(report_keyboard_t* keyboard_report)
28{ 29{
29 uint8_t cnt = 0; 30 uint8_t cnt = 0;
30 for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) { 31 uint8_t *p = keyboard_report->keys;
31 if (keyboard_report->raw[i]) 32 uint8_t lp = sizeof(keyboard_report->keys);
33#ifdef NKRO_ENABLE
34 if (keyboard_protocol && keymap_config.nkro) {
35 p = keyboard_report->nkro.bits;
36 lp = sizeof(keyboard_report->nkro.bits);
37 }
38#endif
39 while (lp--) {
40 if (*p++)
32 cnt++; 41 cnt++;
33 } 42 }
34 return cnt; 43 return cnt;
@@ -237,7 +246,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
237void clear_keys_from_report(report_keyboard_t* keyboard_report) 246void clear_keys_from_report(report_keyboard_t* keyboard_report)
238{ 247{
239 // not clear mods 248 // not clear mods
240 for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) { 249#ifdef NKRO_ENABLE
241 keyboard_report->raw[i] = 0; 250 if (keyboard_protocol && keymap_config.nkro) {
251 memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
252 return;
242 } 253 }
254#endif
255 memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
243} 256}
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 6c27eb9dc..eb9afb727 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -23,9 +23,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
23 23
24 24
25/* report id */ 25/* report id */
26#define REPORT_ID_MOUSE 1 26#define REPORT_ID_KEYBOARD 1
27#define REPORT_ID_SYSTEM 2 27#define REPORT_ID_MOUSE 2
28#define REPORT_ID_CONSUMER 3 28#define REPORT_ID_SYSTEM 3
29#define REPORT_ID_CONSUMER 4
30#define REPORT_ID_NKRO 5
29 31
30/* mouse buttons */ 32/* mouse buttons */
31#define MOUSE_BTN1 (1<<0) 33#define MOUSE_BTN1 (1<<0)
@@ -36,6 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
36 38
37/* Consumer Page(0x0C) 39/* Consumer Page(0x0C)
38 * following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx 40 * following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx
41 * see also https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/display-brightness-control
39 */ 42 */
40#define AUDIO_MUTE 0x00E2 43#define AUDIO_MUTE 0x00E2
41#define AUDIO_VOL_UP 0x00E9 44#define AUDIO_VOL_UP 0x00E9
@@ -45,6 +48,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
45#define TRANSPORT_STOP 0x00B7 48#define TRANSPORT_STOP 0x00B7
46#define TRANSPORT_STOP_EJECT 0x00CC 49#define TRANSPORT_STOP_EJECT 0x00CC
47#define TRANSPORT_PLAY_PAUSE 0x00CD 50#define TRANSPORT_PLAY_PAUSE 0x00CD
51#define BRIGHTNESSUP 0x006F
52#define BRIGHTNESSDOWN 0x0070
48/* application launch */ 53/* application launch */
49#define AL_CC_CONFIG 0x0183 54#define AL_CC_CONFIG 0x0183
50#define AL_EMAIL 0x018A 55#define AL_EMAIL 0x018A
@@ -72,27 +77,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
72#define SYSTEM_WAKE_UP 0x0083 77#define SYSTEM_WAKE_UP 0x0083
73 78
74 79
80#define NKRO_SHARED_EP
75/* key report size(NKRO or boot mode) */ 81/* key report size(NKRO or boot mode) */
76#if defined(NKRO_ENABLE) 82#if defined(NKRO_ENABLE)
77 #if defined(PROTOCOL_PJRC) 83 #if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
78 #include "usb.h"
79 #define KEYBOARD_REPORT_SIZE KBD2_SIZE
80 #define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
81 #define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
82 #elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
83 #include "protocol/usb_descriptor.h" 84 #include "protocol/usb_descriptor.h"
84 #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE 85 #define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
85 #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) 86 #elif defined(PROTOCOL_ARM_ATSAM)
87 #include "protocol/arm_atsam/usb/udi_device_epsize.h"
86 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) 88 #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
89 #undef NKRO_SHARED_EP
90 #undef MOUSE_SHARED_EP
87 #else 91 #else
88 #error "NKRO not supported with this protocol" 92 #error "NKRO not supported with this protocol"
93 #endif
89#endif 94#endif
90 95
96#ifdef KEYBOARD_SHARED_EP
97# define KEYBOARD_REPORT_SIZE 9
91#else 98#else
92# define KEYBOARD_REPORT_SIZE 8 99# define KEYBOARD_REPORT_SIZE 8
93# define KEYBOARD_REPORT_KEYS 6
94#endif 100#endif
95 101
102#define KEYBOARD_REPORT_KEYS 6
103
104/* VUSB hardcodes keyboard and mouse+extrakey only */
105#if defined(PROTOCOL_VUSB)
106 #undef KEYBOARD_SHARED_EP
107 #undef MOUSE_SHARED_EP
108#endif
96 109
97#ifdef __cplusplus 110#ifdef __cplusplus
98extern "C" { 111extern "C" {
@@ -121,12 +134,18 @@ extern "C" {
121typedef union { 134typedef union {
122 uint8_t raw[KEYBOARD_REPORT_SIZE]; 135 uint8_t raw[KEYBOARD_REPORT_SIZE];
123 struct { 136 struct {
137#ifdef KEYBOARD_SHARED_EP
138 uint8_t report_id;
139#endif
124 uint8_t mods; 140 uint8_t mods;
125 uint8_t reserved; 141 uint8_t reserved;
126 uint8_t keys[KEYBOARD_REPORT_KEYS]; 142 uint8_t keys[KEYBOARD_REPORT_KEYS];
127 }; 143 };
128#ifdef NKRO_ENABLE 144#ifdef NKRO_ENABLE
129 struct { 145 struct nkro_report {
146#ifdef NKRO_SHARED_EP
147 uint8_t report_id;
148#endif
130 uint8_t mods; 149 uint8_t mods;
131 uint8_t bits[KEYBOARD_REPORT_BITS]; 150 uint8_t bits[KEYBOARD_REPORT_BITS];
132 } nkro; 151 } nkro;
@@ -134,6 +153,9 @@ typedef union {
134} __attribute__ ((packed)) report_keyboard_t; 153} __attribute__ ((packed)) report_keyboard_t;
135 154
136typedef struct { 155typedef struct {
156#ifdef MOUSE_SHARED_EP
157 uint8_t report_id;
158#endif
137 uint8_t buttons; 159 uint8_t buttons;
138 int8_t x; 160 int8_t x;
139 int8_t y; 161 int8_t y;
@@ -170,7 +192,9 @@ typedef struct {
170 (key == KC_WWW_FORWARD ? AC_FORWARD : \ 192 (key == KC_WWW_FORWARD ? AC_FORWARD : \
171 (key == KC_WWW_STOP ? AC_STOP : \ 193 (key == KC_WWW_STOP ? AC_STOP : \
172 (key == KC_WWW_REFRESH ? AC_REFRESH : \ 194 (key == KC_WWW_REFRESH ? AC_REFRESH : \
173 (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0))))))))))))))))))))) 195 (key == KC_BRIGHTNESS_UP ? BRIGHTNESSUP : \
196 (key == KC_BRIGHTNESS_DOWN ? BRIGHTNESSDOWN : \
197 (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))))
174 198
175uint8_t has_anykey(report_keyboard_t* keyboard_report); 199uint8_t has_anykey(report_keyboard_t* keyboard_report);
176uint8_t get_first_key(report_keyboard_t* keyboard_report); 200uint8_t get_first_key(report_keyboard_t* keyboard_report);