summaryrefslogtreecommitdiffstats
path: root/tmk_core/common
diff options
context:
space:
mode:
authorAlex Ong <the.onga@gmail.com>2019-01-04 19:43:45 +1100
committerAlex Ong <the.onga@gmail.com>2019-01-04 19:43:45 +1100
commit2bb2977c133646c4e056960e72029270d77cc1eb (patch)
tree235d491f992121ac1716c5bf2fafb80983748576 /tmk_core/common
parenta55c838961c89097ab849ed6cb1f261791e6b9b4 (diff)
parent47c91fc7f75ae0a477e55b687aa0fc30da0a283c (diff)
Merge branch 'master' into debounce_refactor
# Conflicts: # tmk_core/common/keyboard.c
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 f7c039f457..b99c2acaa7 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -120,7 +120,7 @@ void process_hand_swap(keyevent_t *event) {
}
#endif
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
bool disable_action_cache = false;
void process_record_nocache(keyrecord_t *record)
@@ -773,6 +773,13 @@ void register_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(KEYCODE2CONSUMER(code));
}
+
+ #ifdef MOUSEKEY_ENABLE
+ else if IS_MOUSEKEY(code) {
+ mousekey_on(code);
+ mousekey_send();
+ }
+ #endif
}
/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -832,6 +839,24 @@ void unregister_code(uint8_t code)
else if IS_CONSUMER(code) {
host_consumer_send(0);
}
+ #ifdef MOUSEKEY_ENABLE
+ else if IS_MOUSEKEY(code) {
+ mousekey_off(code);
+ mousekey_send();
+ }
+ #endif
+}
+
+/** \brief Utilities for actions. (FIXME: Needs better description)
+ *
+ * FIXME: Needs documentation.
+ */
+void tap_code(uint8_t code) {
+ register_code(code);
+ #if TAP_CODE_DELAY > 0
+ wait_ms(TAP_CODE_DELAY);
+ #endif
+ unregister_code(code);
}
/** \brief Utilities for actions. (FIXME: Needs better description)
@@ -874,9 +899,18 @@ void clear_keyboard(void)
*/
void clear_keyboard_but_mods(void)
{
+ clear_keys();
+ clear_keyboard_but_mods_and_keys();
+}
+
+/** \brief Utilities for actions. (FIXME: Needs better description)
+ *
+ * FIXME: Needs documentation.
+ */
+void clear_keyboard_but_mods_and_keys()
+{
clear_weak_mods();
clear_macro_mods();
- clear_keys();
send_keyboard_report();
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
diff --git a/tmk_core/common/action.h b/tmk_core/common/action.h
index acc55c7d38..8e47e5339e 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);
bool process_record_quantum(keyrecord_t *record);
/* Utilities for actions. */
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
extern bool disable_action_cache;
#endif
@@ -88,11 +88,13 @@ void process_record(keyrecord_t *record);
void process_action(keyrecord_t *record, action_t action);
void register_code(uint8_t code);
void unregister_code(uint8_t code);
+void tap_code(uint8_t code);
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
+void clear_keyboard_but_mods_and_keys(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(keypos_t key);
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index f3cd381ab0..120ce3f51b 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -15,13 +15,22 @@
*/
uint32_t default_layer_state = 0;
+/** \brief Default Layer State Set At user Level
+ *
+ * FIXME: Needs docs
+ */
+__attribute__((weak))
+uint32_t default_layer_state_set_user(uint32_t state) {
+ return state;
+}
+
/** \brief Default Layer State Set At Keyboard Level
*
* FIXME: Needs docs
*/
__attribute__((weak))
uint32_t default_layer_state_set_kb(uint32_t state) {
- return state;
+ return default_layer_state_set_user(state);
}
/** \brief Default Layer State Set
@@ -35,7 +44,11 @@ static void default_layer_state_set(uint32_t state)
default_layer_debug(); debug(" to ");
default_layer_state = state;
default_layer_debug(); debug("\n");
+#ifdef STRICT_LAYER_RELEASE
clear_keyboard_but_mods(); // To avoid stuck keys
+#else
+ clear_keyboard_but_mods_and_keys(); // Don't reset held keys
+#endif
}
/** \brief Default Layer Print
@@ -118,7 +131,11 @@ void layer_state_set(uint32_t state)
layer_debug(); dprint(" to ");
layer_state = state;
layer_debug(); dprintln();
+#ifdef STRICT_LAYER_RELEASE
clear_keyboard_but_mods(); // To avoid stuck keys
+#else
+ clear_keyboard_but_mods_and_keys(); // Don't reset held keys
+#endif
}
/** \brief Layer clear
@@ -219,7 +236,7 @@ void layer_debug(void)
}
#endif
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS] = {{0}};
void update_source_layers_cache(keypos_t key, uint8_t layer)
@@ -263,7 +280,7 @@ uint8_t read_source_layers_cache(keypos_t key)
*/
action_t store_or_get_action(bool pressed, keypos_t key)
{
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
if (disable_action_cache) {
return layer_switch_get_action(key);
}
diff --git a/tmk_core/common/action_layer.h b/tmk_core/common/action_layer.h
index 72a6bd8f68..f1551d2519 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);
__attribute__((weak))
uint32_t default_layer_state_set_kb(uint32_t state);
+__attribute__((weak))
+uint32_t default_layer_state_set_user(uint32_t state);
#ifndef NO_ACTION_LAYER
/* bitwise operation */
@@ -80,15 +82,13 @@ void layer_xor(uint32_t state);
#define layer_or(state)
#define layer_and(state)
#define layer_xor(state)
+#endif
-__attribute__((weak))
uint32_t layer_state_set_user(uint32_t state);
-__attribute__((weak))
uint32_t layer_state_set_kb(uint32_t state);
-#endif
/* pressed actions cache */
-#if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
+#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
/* The number of bits needed to represent the layer number: log2(32). */
#define MAX_LAYER_BITS 5
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 0000000000..ba71bfeb0b
--- /dev/null
+++ b/tmk_core/common/arm_atsam/bootloader.c
@@ -0,0 +1,51 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+#include "samd51j18a.h"
+#include "md_bootloader.h"
+
+//Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
+void bootloader_jump(void) {
+#ifdef KEYBOARD_massdrop_ctrl
+ //CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
+ uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; //The version to match (NULL terminated by compiler)
+ uint8_t *ver_check = ver_ram_method; //Pointer to version match string for traversal
+ uint8_t *ver_rom = (uint8_t *)0x21A0; //Pointer to address in ROM where this specific bootloader version would exist
+
+ while (*ver_check && *ver_rom == *ver_check) { //While there are check version characters to match and bootloader's version matches check's version
+ ver_check++; //Move check version pointer to next character
+ ver_rom++; //Move ROM version pointer to next character
+ }
+
+ if (!*ver_check) { //If check version pointer is NULL, all characters have matched
+ *MAGIC_ADDR = BOOTLOADER_MAGIC; //Set magic number into RAM
+ NVIC_SystemReset(); //Perform system reset
+ while (1) {} //Won't get here
+ }
+#endif
+
+ WDT->CTRLA.bit.ENABLE = 0;
+ while (WDT->SYNCBUSY.bit.ENABLE) {}
+ while (WDT->CTRLA.bit.ENABLE) {}
+ WDT->CONFIG.bit.WINDOW = 0;
+ WDT->CONFIG.bit.PER = 0;
+ WDT->EWCTRL.bit.EWOFFSET = 0;
+ WDT->CTRLA.bit.ENABLE = 1;
+ while (WDT->SYNCBUSY.bit.ENABLE) {}
+ while (!WDT->CTRLA.bit.ENABLE) {}
+ while (1) {} //Wait on timeout
+}
diff --git a/tmk_core/common/arm_atsam/eeprom.c b/tmk_core/common/arm_atsam/eeprom.c
new file mode 100644
index 0000000000..61cc039efa
--- /dev/null
+++ b/tmk_core/common/arm_atsam/eeprom.c
@@ -0,0 +1,98 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "eeprom.h"
+
+#define EEPROM_SIZE 32
+
+static uint8_t buffer[EEPROM_SIZE];
+
+uint8_t eeprom_read_byte(const uint8_t *addr) {
+ uintptr_t offset = (uintptr_t)addr;
+ return buffer[offset];
+}
+
+void eeprom_write_byte(uint8_t *addr, uint8_t value) {
+ uintptr_t offset = (uintptr_t)addr;
+ buffer[offset] = value;
+}
+
+uint16_t eeprom_read_word(const uint16_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
+}
+
+uint32_t eeprom_read_dword(const uint32_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
+ | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
+}
+
+void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
+ const uint8_t *p = (const uint8_t *)addr;
+ uint8_t *dest = (uint8_t *)buf;
+ while (len--) {
+ *dest++ = eeprom_read_byte(p++);
+ }
+}
+
+void eeprom_write_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_write_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
+
+void eeprom_update_byte(uint8_t *addr, uint8_t value) {
+ eeprom_write_byte(addr, value);
+}
+
+void eeprom_update_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_update_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
diff --git a/tmk_core/common/arm_atsam/printf.c b/tmk_core/common/arm_atsam/printf.c
new file mode 100644
index 0000000000..7f298d1fda
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.c
@@ -0,0 +1,66 @@
+/*
+Copyright 2018 Massdrop Inc.
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef CONSOLE_ENABLE
+
+#include "samd51j18a.h"
+#include "arm_atsam_protocol.h"
+#include "printf.h"
+#include <string.h>
+#include <stdarg.h>
+
+void console_printf(char *fmt, ...) {
+ while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
+
+ static char console_printbuf[CONSOLE_PRINTBUF_SIZE]; //Print and send buffer
+ va_list va;
+ int result;
+
+ va_start(va, fmt);
+ result = vsnprintf(console_printbuf, CONSOLE_PRINTBUF_SIZE, fmt, va);
+ va_end(va);
+
+ uint32_t irqflags;
+ char *pconbuf = console_printbuf; //Pointer to start send from
+ int send_out = CONSOLE_EPSIZE; //Bytes to send per transfer
+
+ while (result > 0) { //While not error and bytes remain
+ while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
+
+ irqflags = __get_PRIMASK();
+ __disable_irq();
+ __DMB();
+
+ if (result < CONSOLE_EPSIZE) { //If remaining bytes are less than console epsize
+ memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); //Clear the buffer
+ send_out = result; //Send remaining size
+ }
+
+ memcpy(udi_hid_con_report, pconbuf, send_out); //Copy data into the send buffer
+
+ udi_hid_con_b_report_valid = 1; //Set report valid
+ udi_hid_con_send_report(); //Send report
+
+ __DMB();
+ __set_PRIMASK(irqflags);
+
+ result -= send_out; //Decrement result by bytes sent
+ pconbuf += send_out; //Increment buffer point by bytes sent
+ }
+}
+
+#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 0000000000..1f1c2280b5
--- /dev/null
+++ b/tmk_core/common/arm_atsam/printf.h
@@ -0,0 +1,11 @@
+#ifndef _PRINTF_H_
+#define _PRINTF_H_
+
+#define CONSOLE_PRINTBUF_SIZE 512
+
+void console_printf(char *fmt, ...);
+
+#define __xprintf console_printf
+
+#endif //_PRINTF_H_
+
diff --git a/tmk_core/common/arm_atsam/suspend.c b/tmk_core/common/arm_atsam/suspend.c
new file mode 100644
index 0000000000..e34965df64
--- /dev/null
+++ b/tmk_core/common/arm_atsam/suspend.c
@@ -0,0 +1,85 @@
+#include "matrix.h"
+#include "i2c_master.h"
+#include "led_matrix.h"
+#include "suspend.h"
+
+/** \brief Suspend idle
+ *
+ * FIXME: needs doc
+ */
+void suspend_idle(uint8_t time) {
+ /* Note: Not used anywhere currently */
+}
+
+/** \brief Run user level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_user (void) {
+
+}
+
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_kb(void) {
+ suspend_power_down_user();
+}
+
+/** \brief Suspend power down
+ *
+ * FIXME: needs doc
+ */
+void suspend_power_down(void)
+{
+ I2C3733_Control_Set(0); //Disable LED driver
+
+ suspend_power_down_kb();
+}
+
+__attribute__ ((weak)) void matrix_power_up(void) {}
+__attribute__ ((weak)) void matrix_power_down(void) {}
+bool suspend_wakeup_condition(void) {
+ matrix_power_up();
+ matrix_scan();
+ matrix_power_down();
+ for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
+ if (matrix_get_row(r)) return true;
+ }
+ return false;
+}
+
+/** \brief run user level code immediately after wakeup
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_wakeup_init_user(void) {
+
+}
+
+/** \brief run keyboard level code immediately after wakeup
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_wakeup_init_kb(void) {
+ suspend_wakeup_init_user();
+}
+
+/** \brief run immediately after wakeup
+ *
+ * FIXME: needs doc
+ */
+void suspend_wakeup_init(void) {
+ /* If LEDs are set to enabled, enable the hardware */
+ if (led_enabled) {
+ I2C3733_Control_Set(1);
+ }
+
+ suspend_wakeup_init_kb();
+}
+
diff --git a/tmk_core/common/arm_atsam/timer.c b/tmk_core/common/arm_atsam/timer.c
new file mode 100644
index 0000000000..bcfe5002c3
--- /dev/null
+++ b/tmk_core/common/arm_atsam/timer.c
@@ -0,0 +1,59 @@
+#include "samd51j18a.h"
+#include "timer.h"
+#include "tmk_core/protocol/arm_atsam/clks.h"
+
+void set_time(uint64_t tset)
+{
+ ms_clk = tset;
+}
+
+void timer_init(void)
+{
+ ms_clk = 0;
+}
+
+uint16_t timer_read(void)
+{
+ return (uint16_t)ms_clk;
+}
+
+uint32_t timer_read32(void)
+{
+ return (uint32_t)ms_clk;
+}
+
+uint64_t timer_read64(void)
+{
+ return ms_clk;
+}
+
+uint16_t timer_elapsed(uint16_t tlast)
+{
+ return TIMER_DIFF_16(timer_read(), tlast);
+}
+
+uint32_t timer_elapsed32(uint32_t tlast)
+{
+ return TIMER_DIFF_32(timer_read32(), tlast);
+}
+
+uint32_t timer_elapsed64(uint32_t tlast)
+{
+ uint64_t tnow = timer_read64();
+ return (tnow >= tlast ? tnow - tlast : UINT64_MAX - tlast + tnow);
+}
+
+void timer_clear(void)
+{
+ ms_clk = 0;
+}
+
+void wait_ms(uint64_t msec)
+{
+ CLK_delay_ms(msec);
+}
+
+void wait_us(uint16_t usec)
+{
+ CLK_delay_us(usec);
+}
diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c
index 3d4a48439b..5bca646854 100644
--- a/tmk_core/common/avr/suspend.c
+++ b/tmk_core/common/avr/suspend.c
@@ -10,6 +10,7 @@
#include "timer.h"
#include "led.h"
#include "host.h"
+#include "rgblight_reconfig.h"
#ifdef PROTOCOL_LUFA
#include "lufa.h"
@@ -55,6 +56,24 @@ void suspend_idle(uint8_t time)
sleep_disable();
}
+
+// TODO: This needs some cleanup
+
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_user (void) { }
+/** \brief Run keyboard level Power down
+ *
+ * FIXME: needs doc
+ */
+__attribute__ ((weak))
+void suspend_power_down_kb(void) {
+ suspend_power_down_user();
+}
+
#ifndef NO_SUSPEND_POWER_DOWN
/** \brief Power down MCU with watchdog timer
*
@@ -72,21 +91,6 @@ void suspend_idle(uint8_t time)
*/
static uint8_t wdt_timeout = 0;
-/** \brief Run keyboard level Power down
- *
- * FIXME: needs doc
- */
-__attribute__ ((weak))
-void suspend_power_down_user (void) { }
-/** \brief Run keyboard level Power down
- *
- * FIXME: needs doc
- */
-__attribute__ ((weak))
-void suspend_power_down_kb(void) {
- suspend_power_down_user();
-}
-
/** \brief Power down
*
* FIXME: needs doc
@@ -143,6 +147,8 @@ static void power_down(uint8_t wdto)
*/
void suspend_power_down(void)
{
+ suspend_power_down_kb();
+
#ifndef NO_SUSPEND_POWER_DOWN
power_down(WDTO_15MS);
#endif
@@ -189,12 +195,15 @@ void suspend_wakeup_init(void)
#endif
led_set(host_keyboard_leds());
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
+#ifdef BOOTLOADER_TEENSY
+ wait_ms(10);
+#endif
rgblight_enable_noeeprom();
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_enable();
#endif
#endif
- suspend_wakeup_init_kb();
+ suspend_wakeup_init_kb();
}
#ifndef NO_SUSPEND_POWER_DOWN
diff --git a/tmk_core/common/backlight.c b/tmk_core/common/backlight.c
index 3e29aacc49..8ddacd98b6 100644
--- a/tmk_core/common/backlight.c
+++ b/tmk_core/common/backlight.c
@@ -76,12 +76,51 @@ void backlight_decrease(void)
*/
void backlight_toggle(void)
{
- backlight_config.enable ^= 1;
- if (backlight_config.raw == 1) // enabled but level = 0
- backlight_config.level = 1;
- eeconfig_update_backlight(backlight_config.raw);
- dprintf("backlight toggle: %u\n", backlight_config.enable);
- backlight_set(backlight_config.enable ? backlight_config.level : 0);
+ bool enabled = backlight_config.enable;
+ dprintf("backlight toggle: %u\n", enabled);
+ if (enabled)
+ backlight_disable();
+ else
+ backlight_enable();
+}
+
+/** \brief Enable backlight
+ *
+ * FIXME: needs doc
+ */
+void backlight_enable(void)
+{
+ if (backlight_config.enable) return; // do nothing if backlight is already on
+
+ backlight_config.enable = true;
+ if (backlight_config.raw == 1) // enabled but level == 0
+ backlight_config.level = 1;
+ eeconfig_update_backlight(backlight_config.raw);
+ dprintf("backlight enable\n");
+ backlight_set(backlight_config.level);
+}
+
+/** /brief Disable backlight
+ *
+ * FIXME: needs doc
+ */
+void backlight_disable(void)
+{
+ if (!backlight_config.enable) return; // do nothing if backlight is already off
+
+ backlight_config.enable = false;
+ eeconfig_update_backlight(backlight_config.raw);
+ dprintf("backlight disable\n");
+ backlight_set(0);
+}
+
+/** /brief Get the backlight status
+ *
+ * FIXME: needs doc
+ */
+bool is_backlight_enabled(void)
+{
+ return backlight_config.enable;
}
/** \brief Backlight step through levels
diff --git a/tmk_core/common/backlight.h b/tmk_core/common/backlight.h
index f573092674..420c9d19ed 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
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef BACKLIGHT_H
-#define BACKLIGHT_H
+#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -33,9 +32,11 @@ void backlight_init(void);
void backlight_increase(void);
void backlight_decrease(void);
void backlight_toggle(void);
+void backlight_enable(void);
+void backlight_disable(void);
+bool is_backlight_enabled(void);
void backlight_step(void);
void backlight_set(uint8_t level);
void backlight_level(uint8_t level);
uint8_t get_backlight_level(void);
-#endif
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
new file mode 100755
index 0000000000..a869985501
--- /dev/null
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -0,0 +1,673 @@
+/*
+ * This software is experimental and a work in progress.
+ * Under no circumstances should these files be used in relation to any critical system(s).
+ * Use of these files is at your own risk.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
+ * https://github.com/leaflabs/libmaple
+ *
+ * Modifications for QMK and STM32F303 by Yiancar
+ */
+
+#include "eeprom_stm32.h"
+
+ FLASH_Status EE_ErasePage(uint32_t);
+
+ uint16_t EE_CheckPage(uint32_t, uint16_t);
+ uint16_t EE_CheckErasePage(uint32_t, uint16_t);
+ uint16_t EE_Format(void);
+ uint32_t EE_FindValidPage(void);
+ uint16_t EE_GetVariablesCount(uint32_t, uint16_t);
+ uint16_t EE_PageTransfer(uint32_t, uint32_t, uint16_t);
+ uint16_t EE_VerifyPageFullWriteVariable(uint16_t, uint16_t);
+
+ uint32_t PageBase0 = EEPROM_PAGE0_BASE;
+ uint32_t PageBase1 = EEPROM_PAGE1_BASE;
+ uint32_t PageSize = EEPROM_PAGE_SIZE;
+ uint16_t Status = EEPROM_NOT_INIT;
+
+// See http://www.st.com/web/en/resource/technical/document/application_note/CD00165693.pdf
+
+/**
+ * @brief Check page for blank
+ * @param page base address
+ * @retval Success or error
+ * EEPROM_BAD_FLASH: page not empty after erase
+ * EEPROM_OK: page blank
+ */
+uint16_t EE_CheckPage(uint32_t pageBase, uint16_t status)
+{
+ uint32_t pageEnd = pageBase + (uint32_t)PageSize;
+
+ // Page Status not EEPROM_ERASED and not a "state"
+ if ((*(__IO uint16_t*)pageBase) != EEPROM_ERASED && (*(__IO uint16_t*)pageBase) != status)
+ return EEPROM_BAD_FLASH;
+ for(pageBase += 4; pageBase < pageEnd; pageBase += 4)
+ if ((*(__IO uint32_t*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty
+ return EEPROM_BAD_FLASH;
+ return EEPROM_OK;
+}
+
+/**
+ * @brief Erase page with increment erase counter (page + 2)
+ * @param page base address
+ * @retval Success or error
+ * FLASH_COMPLETE: success erase
+ * - Flash error code: on write Flash error
+ */
+FLASH_Status EE_ErasePage(uint32_t pageBase)
+{
+ FLASH_Status FlashStatus;
+ uint16_t data = (*(__IO uint16_t*)(pageBase));
+ if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA))
+ data = (*(__IO uint16_t*)(pageBase + 2)) + 1;
+ else
+ data = 0;
+
+ FlashStatus = FLASH_ErasePage(pageBase);
+ if (FlashStatus == FLASH_COMPLETE)
+ FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data);
+
+ return FlashStatus;
+}
+
+/**
+ * @brief Check page for blank and erase it
+ * @param page base address
+ * @retval Success or error
+ * - Flash error code: on write Flash error
+ * - EEPROM_BAD_FLASH: page not empty after erase
+ * - EEPROM_OK: page blank
+ */
+uint16_t EE_CheckErasePage(