diff options
author | Alex Ong <the.onga@gmail.com> | 2019-01-04 19:43:45 +1100 |
---|---|---|
committer | Alex Ong <the.onga@gmail.com> | 2019-01-04 19:43:45 +1100 |
commit | 2bb2977c133646c4e056960e72029270d77cc1eb (patch) | |
tree | 235d491f992121ac1716c5bf2fafb80983748576 /tmk_core/common | |
parent | a55c838961c89097ab849ed6cb1f261791e6b9b4 (diff) | |
parent | 47c91fc7f75ae0a477e55b687aa0fc30da0a283c (diff) |
Merge branch 'master' into debounce_refactor
# Conflicts:
# tmk_core/common/keyboard.c
Diffstat (limited to 'tmk_core/common')
29 files changed, 1786 insertions, 100 deletions
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index 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( |