Merge branch 'master' into debounce_refactor
# Conflicts: # tmk_core/common/keyboard.c
This commit is contained in:
commit
2bb2977c13
3425 changed files with 216380 additions and 20651 deletions
|
@ -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)
|
||||
|
@ -873,10 +898,19 @@ void clear_keyboard(void)
|
|||
* FIXME: Needs documentation.
|
||||
*/
|
||||
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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
__attribute__((weak))
|
||||
uint32_t layer_state_set_user(uint32_t state);
|
||||
__attribute__((weak))
|
||||
uint32_t layer_state_set_kb(uint32_t state);
|
||||
#endif
|
||||
|
||||
uint32_t layer_state_set_user(uint32_t state);
|
||||
uint32_t layer_state_set_kb(uint32_t state);
|
||||
|
||||
/* 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);
|
||||
|
|
51
tmk_core/common/arm_atsam/bootloader.c
Normal file
51
tmk_core/common/arm_atsam/bootloader.c
Normal file
|
@ -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
|
||||
}
|
98
tmk_core/common/arm_atsam/eeprom.c
Normal file
98
tmk_core/common/arm_atsam/eeprom.c
Normal file
|
@ -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++);
|
||||
}
|
||||
}
|
66
tmk_core/common/arm_atsam/printf.c
Normal file
66
tmk_core/common/arm_atsam/printf.c
Normal file
|
@ -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
|
11
tmk_core/common/arm_atsam/printf.h
Normal file
11
tmk_core/common/arm_atsam/printf.h
Normal file
|
@ -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_
|
||||
|
85
tmk_core/common/arm_atsam/suspend.c
Normal file
85
tmk_core/common/arm_atsam/suspend.c
Normal file
|
@ -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();
|
||||
}
|
||||
|
59
tmk_core/common/arm_atsam/timer.c
Normal file
59
tmk_core/common/arm_atsam/timer.c
Normal file
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
673
tmk_core/common/chibios/eeprom_stm32.c
Executable file
673
tmk_core/common/chibios/eeprom_stm32.c
Executable file
|
@ -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(uint32_t pageBase, uint16_t status)
|
||||
{
|
||||
uint16_t FlashStatus;
|
||||
if (EE_CheckPage(pageBase, status) != EEPROM_OK)
|
||||
{
|
||||
FlashStatus = EE_ErasePage(pageBase);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
return EE_CheckPage(pageBase, status);
|
||||
}
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find valid Page for write or read operation
|
||||
* @param Page0: Page0 base address
|
||||
* Page1: Page1 base address
|
||||
* @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found
|
||||
*/
|
||||
uint32_t EE_FindValidPage(void)
|
||||
{
|
||||
uint16_t status0 = (*(__IO uint16_t*)PageBase0); // Get Page0 actual status
|
||||
uint16_t status1 = (*(__IO uint16_t*)PageBase1); // Get Page1 actual status
|
||||
|
||||
if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED)
|
||||
return PageBase0;
|
||||
if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED)
|
||||
return PageBase1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate unique variables in EEPROM
|
||||
* @param start: address of first slot to check (page + 4)
|
||||
* @param end: page end address
|
||||
* @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF)
|
||||
* @retval count of variables
|
||||
*/
|
||||
uint16_t EE_GetVariablesCount(uint32_t pageBase, uint16_t skipAddress)
|
||||
{
|
||||
uint16_t varAddress, nextAddress;
|
||||
uint32_t idx;
|
||||
uint32_t pageEnd = pageBase + (uint32_t)PageSize;
|
||||
uint16_t count = 0;
|
||||
|
||||
for (pageBase += 6; pageBase < pageEnd; pageBase += 4)
|
||||
{
|
||||
varAddress = (*(__IO uint16_t*)pageBase);
|
||||
if (varAddress == 0xFFFF || varAddress == skipAddress)
|
||||
continue;
|
||||
|
||||
count++;
|
||||
for(idx = pageBase + 4; idx < pageEnd; idx += 4)
|
||||
{
|
||||
nextAddress = (*(__IO uint16_t*)idx);
|
||||
if (nextAddress == varAddress)
|
||||
{
|
||||
count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transfers last updated variables data from the full Page to an empty one.
|
||||
* @param newPage: new page base address
|
||||
* @param oldPage: old page base address
|
||||
* @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF)
|
||||
* @retval Success or error status:
|
||||
* - FLASH_COMPLETE: on success
|
||||
* - EEPROM_OUT_SIZE: if valid new page is full
|
||||
* - Flash error code: on write Flash error
|
||||
*/
|
||||
uint16_t EE_PageTransfer(uint32_t newPage, uint32_t oldPage, uint16_t SkipAddress)
|
||||
{
|
||||
uint32_t oldEnd, newEnd;
|
||||
uint32_t oldIdx, newIdx, idx;
|
||||
uint16_t address, data, found;
|
||||
FLASH_Status FlashStatus;
|
||||
|
||||
// Transfer process: transfer variables from old to the new active page
|
||||
newEnd = newPage + ((uint32_t)PageSize);
|
||||
|
||||
// Find first free element in new page
|
||||
for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4)
|
||||
if ((*(__IO uint32_t*)newIdx) == 0xFFFFFFFF) // Verify if element
|
||||
break; // contents are 0xFFFFFFFF
|
||||
if (newIdx >= newEnd)
|
||||
return EEPROM_OUT_SIZE;
|
||||
|
||||
oldEnd = oldPage + 4;
|
||||
oldIdx = oldPage + (uint32_t)(PageSize - 2);
|
||||
|
||||
for (; oldIdx > oldEnd; oldIdx -= 4)
|
||||
{
|
||||
address = *(__IO uint16_t*)oldIdx;
|
||||
if (address == 0xFFFF || address == SkipAddress)
|
||||
continue; // it's means that power off after write data
|
||||
|
||||
found = 0;
|
||||
for (idx = newPage + 6; idx < newIdx; idx += 4)
|
||||
if ((*(__IO uint16_t*)(idx)) == address)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
if (newIdx < newEnd)
|
||||
{
|
||||
data = (*(__IO uint16_t*)(oldIdx - 2));
|
||||
|
||||
FlashStatus = FLASH_ProgramHalfWord(newIdx, data);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
|
||||
FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
|
||||
newIdx += 4;
|
||||
}
|
||||
else
|
||||
return EEPROM_OUT_SIZE;
|
||||
}
|
||||
|
||||
// Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status
|
||||
data = EE_CheckErasePage(oldPage, EEPROM_ERASED);
|
||||
if (data != EEPROM_OK)
|
||||
return data;
|
||||
|
||||
// Set new Page status
|
||||
FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Verify if active page is full and Writes variable in EEPROM.
|
||||
* @param Address: 16 bit virtual address of the variable
|
||||
* @param Data: 16 bit data to be written as variable value
|
||||
* @retval Success or error status:
|
||||
* - FLASH_COMPLETE: on success
|
||||
* - EEPROM_PAGE_FULL: if valid page is full (need page transfer)
|
||||
* - EEPROM_NO_VALID_PAGE: if no valid page was found
|
||||
* - EEPROM_OUT_SIZE: if EEPROM size exceeded
|
||||
* - Flash error code: on write Flash error
|
||||
*/
|
||||
uint16_t EE_VerifyPageFullWriteVariable(uint16_t Address, uint16_t Data)
|
||||
{
|
||||
FLASH_Status FlashStatus;
|
||||
uint32_t idx, pageBase, pageEnd, newPage;
|
||||
uint16_t count;
|
||||
|
||||
// Get valid Page for write operation
|
||||
pageBase = EE_FindValidPage();
|
||||
if (pageBase == 0)
|
||||
return EEPROM_NO_VALID_PAGE;
|
||||
|
||||
// Get the valid Page end Address
|
||||
pageEnd = pageBase + PageSize; // Set end of page
|
||||
|
||||
for (idx = pageEnd - 2; idx > pageBase; idx -= 4)
|
||||
{
|
||||
if ((*(__IO uint16_t*)idx) == Address) // Find last value for address
|
||||
{
|
||||
count = (*(__IO uint16_t*)(idx - 2)); // Read last data
|
||||
if (count == Data)
|
||||
return EEPROM_OK;
|
||||
if (count == 0xFFFF)
|
||||
{
|
||||
FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data
|
||||
if (FlashStatus == FLASH_COMPLETE)
|
||||
return EEPROM_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check each active page address starting from begining
|
||||
for (idx = pageBase + 4; idx < pageEnd; idx += 4)
|
||||
if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
|
||||
{ // contents are 0xFFFFFFFF
|
||||
FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
// Empty slot not found, need page transfer
|
||||
// Calculate unique variables in page
|
||||
count = EE_GetVariablesCount(pageBase, Address) + 1;
|
||||
if (count >= (PageSize / 4 - 1))
|
||||
return EEPROM_OUT_SIZE;
|
||||
|
||||
if (pageBase == PageBase1)
|
||||
newPage = PageBase0; // New page address where variable will be moved to
|
||||
else
|
||||
newPage = PageBase1;
|
||||
|
||||
// Set the new Page status to RECEIVE_DATA status
|
||||
FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
|
||||
// Write the variable passed as parameter in the new active page
|
||||
FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
|
||||
FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
|
||||
return EE_PageTransfer(newPage, pageBase, Address);
|
||||
}
|
||||
|
||||
/*EEPROMClass::EEPROMClass(void)
|
||||
{
|
||||
PageBase0 = EEPROM_PAGE0_BASE;
|
||||
PageBase1 = EEPROM_PAGE1_BASE;
|
||||
PageSize = EEPROM_PAGE_SIZE;
|
||||
Status = EEPROM_NOT_INIT;
|
||||
}*/
|
||||
/*
|
||||
uint16_t EEPROM_init(uint32_t pageBase0, uint32_t pageBase1, uint32_t pageSize)
|
||||
{
|
||||
PageBase0 = pageBase0;
|
||||
PageBase1 = pageBase1;
|
||||
PageSize = pageSize;
|
||||
return EEPROM_init();
|
||||
}*/
|
||||
|
||||
uint16_t EEPROM_init(void)
|
||||
{
|
||||
uint16_t status0 = 6, status1 = 6;
|
||||
FLASH_Status FlashStatus;
|
||||
|
||||
FLASH_Unlock();
|
||||
Status = EEPROM_NO_VALID_PAGE;
|
||||
|
||||
status0 = (*(__IO uint16_t *)PageBase0);
|
||||
status1 = (*(__IO uint16_t *)PageBase1);
|
||||
|
||||
switch (status0)
|
||||
{
|
||||
/*
|
||||
Page0 Page1
|
||||
----- -----
|
||||
EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased
|
||||
EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased
|
||||
EEPROM_ERASED make EE_Format
|
||||
any Error: EEPROM_NO_VALID_PAGE
|
||||
*/
|
||||
case EEPROM_ERASED:
|
||||
if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid
|
||||
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
|
||||
else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive
|
||||
{
|
||||
FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
Status = FlashStatus;
|
||||
else
|
||||
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
|
||||
}
|
||||
else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM
|
||||
Status = EEPROM_format();
|
||||
break;
|
||||
/*
|
||||
Page0 Page1
|
||||
----- -----
|
||||
EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0
|
||||
EEPROM_ERASED Page0 need set to valid, Page1 erased
|
||||
any EEPROM_NO_VALID_PAGE
|
||||
*/
|
||||
case EEPROM_RECEIVE_DATA:
|
||||
if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid
|
||||
Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF);
|
||||
else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased
|
||||
{
|
||||
Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
|
||||
if (Status == EEPROM_OK)
|
||||
{
|
||||
FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
Status = FlashStatus;
|
||||
else
|
||||
Status = EEPROM_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
Page0 Page1
|
||||
----- -----
|
||||
EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE
|
||||
EEPROM_RECEIVE_DATA Transfer Page0 to Page1
|
||||
any Page0 valid, Page1 erased
|
||||
*/
|
||||
case EEPROM_VALID_PAGE:
|
||||
if (status1 == EEPROM_VALID_PAGE) // Both pages valid
|
||||
Status = EEPROM_NO_VALID_PAGE;
|
||||
else if (status1 == EEPROM_RECEIVE_DATA)
|
||||
Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF);
|
||||
else
|
||||
Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
|
||||
break;
|
||||
/*
|
||||
Page0 Page1
|
||||
----- -----
|
||||
any EEPROM_VALID_PAGE Page1 valid, Page0 erased
|
||||
EEPROM_RECEIVE_DATA Page1 valid, Page0 erased
|
||||
any EEPROM_NO_VALID_PAGE
|
||||
*/
|
||||
default:
|
||||
if (status1 == EEPROM_VALID_PAGE)
|
||||
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0
|
||||
else if (status1 == EEPROM_RECEIVE_DATA)
|
||||
{
|
||||
FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
Status = FlashStatus;
|
||||
else
|
||||
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0
|
||||
* @param PAGE0 and PAGE1 base addresses
|
||||
* @retval Status of the last operation (Flash write or erase) done during EEPROM formating
|
||||
*/
|
||||
uint16_t EEPROM_format(void)
|
||||
{
|
||||
uint16_t status;
|
||||
FLASH_Status FlashStatus;
|
||||
|
||||
FLASH_Unlock();
|
||||
|
||||
// Erase Page0
|
||||
status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE);
|
||||
if (status != EEPROM_OK)
|
||||
return status;
|
||||
if ((*(__IO uint16_t*)PageBase0) == EEPROM_ERASED)
|
||||
{
|
||||
// Set Page0 as valid page: Write VALID_PAGE at Page0 base address
|
||||
FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
|
||||
if (FlashStatus != FLASH_COMPLETE)
|
||||
return FlashStatus;
|
||||
}
|
||||
// Erase Page1
|
||||
return EE_CheckErasePage(PageBase1, EEPROM_ERASED);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the erase counter for current page
|
||||
* @param Data: Global variable contains the read variable value
|
||||
* @retval Success or error status:
|
||||
* - EEPROM_OK: if erases counter return.
|
||||
* - EEPROM_NO_VALID_PAGE: if no valid page was found.
|
||||
*/
|
||||
uint16_t EEPROM_erases(uint16_t *Erases)
|
||||
{
|
||||
uint32_t pageBase;
|
||||
if (Status != EEPROM_OK)
|
||||
if (EEPROM_init() != EEPROM_OK)
|
||||
return Status;
|
||||
|
||||
// Get active Page for read operation
|
||||
pageBase = EE_FindValidPage();
|
||||
if (pageBase == 0)
|
||||
return EEPROM_NO_VALID_PAGE;
|
||||
|
||||
*Erases = (*(__IO uint16_t*)pageBase+2);
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the last stored variable data, if found,
|
||||
* which correspond to the passed virtual address
|
||||
* @param Address: Variable virtual address
|
||||
* @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors
|
||||
*/
|
||||
/*
|
||||
uint16_t EEPROM_read (uint16_t Address)
|
||||
{
|
||||
uint16_t data;
|
||||
EEPROM_read(Address, &data);
|
||||
return data;
|
||||
}*/
|
||||
|
||||
/**
|
||||
* @brief Returns the last stored variable data, if found,
|
||||
* which correspond to the passed virtual address
|
||||
* @param Address: Variable virtual address
|
||||
* @param Data: Pointer to data variable
|
||||
* @retval Success or error status:
|
||||
* - EEPROM_OK: if variable was found
|
||||
* - EEPROM_BAD_ADDRESS: if the variable was not found
|
||||
* - EEPROM_NO_VALID_PAGE: if no valid page was found.
|
||||
*/
|
||||
uint16_t EEPROM_read(uint16_t Address, uint16_t *Data)
|
||||
{
|
||||
uint32_t pageBase, pageEnd;
|
||||
|
||||
// Set default data (empty EEPROM)
|
||||
*Data = EEPROM_DEFAULT_DATA;
|
||||
|
||||
if (Status == EEPROM_NOT_INIT)
|
||||
if (EEPROM_init() != EEPROM_OK)
|
||||
return Status;
|
||||
|
||||
// Get active Page for read operation
|
||||
pageBase = EE_FindValidPage();
|
||||
if (pageBase == 0)
|
||||
return EEPROM_NO_VALID_PAGE;
|
||||
|
||||
// Get the valid Page end Address
|
||||
pageEnd = pageBase + ((uint32_t)(PageSize - 2));
|
||||
|
||||
// Check each active page address starting from end
|
||||
for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
|
||||
if ((*(__IO uint16_t*)pageEnd) == Address) // Compare the read address with the virtual address
|
||||
{
|
||||
*Data = (*(__IO uint16_t*)(pageEnd - 2)); // Get content of Address-2 which is variable value
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
// Return ReadStatus value: (0: variable exist, 1: variable doesn't exist)
|
||||
return EEPROM_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes/upadtes variable data in EEPROM.
|
||||
* @param VirtAddress: Variable virtual address
|
||||
* @param Data: 16 bit data to be written
|
||||
* @retval Success or error status:
|
||||
* - FLASH_COMPLETE: on success
|
||||
* - EEPROM_BAD_ADDRESS: if address = 0xFFFF
|
||||
* - EEPROM_PAGE_FULL: if valid page is full
|
||||
* - EEPROM_NO_VALID_PAGE: if no valid page was found
|
||||
* - EEPROM_OUT_SIZE: if no empty EEPROM variables
|
||||
* - Flash error code: on write Flash error
|
||||
*/
|
||||
uint16_t EEPROM_write(uint16_t Address, uint16_t Data)
|
||||
{
|
||||
if (Status == EEPROM_NOT_INIT)
|
||||
if (EEPROM_init() != EEPROM_OK)
|
||||
return Status;
|
||||
|
||||
if (Address == 0xFFFF)
|
||||
return EEPROM_BAD_ADDRESS;
|
||||
|
||||
// Write the variable virtual address and value in the EEPROM
|
||||
uint16_t status = EE_VerifyPageFullWriteVariable(Address, Data);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes/upadtes variable data in EEPROM.
|
||||
The value is written only if differs from the one already saved at the same address.
|
||||
* @param VirtAddress: Variable virtual address
|
||||
* @param Data: 16 bit data to be written
|
||||
* @retval Success or error status:
|
||||
* - EEPROM_SAME_VALUE: If new Data matches existing EEPROM Data
|
||||
* - FLASH_COMPLETE: on success
|
||||
* - EEPROM_BAD_ADDRESS: if address = 0xFFFF
|
||||
* - EEPROM_PAGE_FULL: if valid page is full
|
||||
* - EEPROM_NO_VALID_PAGE: if no valid page was found
|
||||
* - EEPROM_OUT_SIZE: if no empty EEPROM variables
|
||||
* - Flash error code: on write Flash error
|
||||
*/
|
||||
uint16_t EEPROM_update(uint16_t Address, uint16_t Data)
|
||||
{
|
||||
uint16_t temp;
|
||||
EEPROM_read(Address, &temp);
|
||||
if (temp == Data)
|
||||
return EEPROM_SAME_VALUE;
|
||||
else
|
||||
return EEPROM_write(Address, Data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return number of variable
|
||||
* @retval Number of variables
|
||||
*/
|
||||
uint16_t EEPROM_count(uint16_t *Count)
|
||||
{
|
||||
if (Status == EEPROM_NOT_INIT)
|
||||
if (EEPROM_init() != EEPROM_OK)
|
||||
return Status;
|
||||
|
||||
// Get valid Page for write operation
|
||||
uint32_t pageBase = EE_FindValidPage();
|
||||
if (pageBase == 0)
|
||||
return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers
|
||||
|
||||
*Count = EE_GetVariablesCount(pageBase, 0xFFFF);
|
||||
return EEPROM_OK;
|
||||
}
|
||||
|
||||
uint16_t EEPROM_maxcount(void)
|
||||
{
|
||||
return ((PageSize / 4)-1);
|
||||
}
|
||||
|
||||
|
||||
uint8_t eeprom_read_byte (const uint8_t *Address)
|
||||
{
|
||||
const uint16_t p = (const uint32_t) Address;
|
||||
uint16_t temp;
|
||||
EEPROM_read(p, &temp);
|
||||
return (uint8_t) temp;
|
||||
}
|
||||
|
||||
void eeprom_write_byte (uint8_t *Address, uint8_t Value)
|
||||
{
|
||||
uint16_t p = (uint32_t) Address;
|
||||
EEPROM_write(p, (uint16_t) Value);
|
||||
}
|
||||
|
||||
void eeprom_update_byte (uint8_t *Address, uint8_t Value)
|
||||
{
|
||||
uint16_t p = (uint32_t) Address;
|
||||
EEPROM_update(p, (uint16_t) Value);
|
||||
}
|
||||
|
||||
uint16_t eeprom_read_word (const uint16_t *Address)
|
||||
{
|
||||
const uint16_t p = (const uint32_t) Address;
|
||||
uint16_t temp;
|
||||
EEPROM_read(p, &temp);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void eeprom_write_word (uint16_t *Address, uint16_t Value)
|
||||
{
|
||||
uint16_t p = (uint32_t) Address;
|
||||
EEPROM_write(p, Value);
|
||||
}
|
||||
|
||||
void eeprom_update_word (uint16_t *Address, uint16_t Value)
|
||||
{
|
||||
uint16_t p = (uint32_t) Address;
|
||||
EEPROM_update(p, Value);
|
||||
}
|
||||
|
||||
uint32_t eeprom_read_dword (const uint32_t *Address)
|
||||
{
|
||||
const uint16_t p = (const uint32_t) Address;
|
||||
uint16_t temp1, temp2;
|
||||
EEPROM_read(p, &temp1);
|
||||
EEPROM_read(p + 1, &temp2);
|
||||
return temp1 | (temp2 << 16);
|
||||
}
|
||||
|
||||
void eeprom_write_dword (uint32_t *Address, uint32_t Value)
|
||||
{
|
||||
uint16_t temp = (uint16_t) Value;
|
||||
uint16_t p = (uint32_t) Address;
|
||||
EEPROM_write(p, temp);
|
||||
temp = (uint16_t) (Value >> 16);
|
||||
EEPROM_write(p + 1, temp);
|
||||
}
|
||||
|
||||
void eeprom_update_dword (uint32_t *Address, uint32_t Value)
|
||||
{
|
||||
uint16_t temp = (uint16_t) Value;
|
||||
uint16_t p = (uint32_t) Address;
|
||||
EEPROM_update(p, temp);
|
||||
temp = (uint16_t) (Value >> 16);
|
||||
EEPROM_update(p + 1, temp);
|
||||
}
|
95
tmk_core/common/chibios/eeprom_stm32.h
Executable file
95
tmk_core/common/chibios/eeprom_stm32.h
Executable file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// This file must be modified if the MCU is not defined below.
|
||||
// This library also assumes that the pages are not used by the firmware.
|
||||
|
||||
#ifndef __EEPROM_H
|
||||
#define __EEPROM_H
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "flash_stm32.h"
|
||||
|
||||
// HACK ALERT. This definition may not match your processor
|
||||
// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
|
||||
#if defined(EEPROM_EMU_STM32F303xC)
|
||||
#define MCU_STM32F303CC
|
||||
#elif defined(EEPROM_EMU_STM32F103xB)
|
||||
#define MCU_STM32F103RB
|
||||
#else
|
||||
#error "not implemented."
|
||||
#endif
|
||||
|
||||
#ifndef EEPROM_PAGE_SIZE
|
||||
#if defined (MCU_STM32F103RB)
|
||||
#define EEPROM_PAGE_SIZE (uint16_t)0x400 /* Page size = 1KByte */
|
||||
#elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC)
|
||||
#define EEPROM_PAGE_SIZE (uint16_t)0x800 /* Page size = 2KByte */
|
||||
#else
|
||||
#error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EEPROM_START_ADDRESS
|
||||
#if defined (MCU_STM32F103RB)
|
||||
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 128 * 1024 - 2 * EEPROM_PAGE_SIZE))
|
||||
#elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
|
||||
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE))
|
||||
#elif defined (MCU_STM32F103RD)
|
||||
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE))
|
||||
#elif defined (MCU_STM32F303CC)
|
||||
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE))
|
||||
#else
|
||||
#error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Pages 0 and 1 base and end addresses */
|
||||
#define EEPROM_PAGE0_BASE ((uint32_t)(EEPROM_START_ADDRESS + 0x000))
|
||||
#define EEPROM_PAGE1_BASE ((uint32_t)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE))
|
||||
|
||||
/* Page status definitions */
|
||||
#define EEPROM_ERASED ((uint16_t)0xFFFF) /* PAGE is empty */
|
||||
#define EEPROM_RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */
|
||||
#define EEPROM_VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
|
||||
|
||||
/* Page full define */
|
||||
enum uint16_t
|
||||
{
|
||||
EEPROM_OK = ((uint16_t)0x0000),
|
||||
EEPROM_OUT_SIZE = ((uint16_t)0x0081),
|
||||
EEPROM_BAD_ADDRESS = ((uint16_t)0x0082),
|
||||
EEPROM_BAD_FLASH = ((uint16_t)0x0083),
|
||||
EEPROM_NOT_INIT = ((uint16_t)0x0084),
|
||||
EEPROM_SAME_VALUE = ((uint16_t)0x0085),
|
||||
EEPROM_NO_VALID_PAGE = ((uint16_t)0x00AB)
|
||||
};
|
||||
|
||||
#define EEPROM_DEFAULT_DATA 0xFFFF
|
||||
|
||||
uint16_t EEPROM_init(void);
|
||||
uint16_t EEPROM_format(void);
|
||||
uint16_t EEPROM_erases(uint16_t *);
|
||||
uint16_t EEPROM_read (uint16_t address, uint16_t *data);
|
||||
uint16_t EEPROM_write(uint16_t address, uint16_t data);
|
||||
uint16_t EEPROM_update(uint16_t address, uint16_t data);
|
||||
uint16_t EEPROM_count(uint16_t *);
|
||||
uint16_t EEPROM_maxcount(void);
|
||||
|
||||
#endif /* __EEPROM_H */
|
188
tmk_core/common/chibios/flash_stm32.c
Executable file
188
tmk_core/common/chibios/flash_stm32.c
Executable file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#if defined(EEPROM_EMU_STM32F303xC)
|
||||
#define STM32F303xC
|
||||
#include "stm32f3xx.h"
|
||||
#elif defined(EEPROM_EMU_STM32F103xB)
|
||||
#define STM32F103xB
|
||||
#include "stm32f1xx.h"
|
||||
#else
|
||||
#error "not implemented."
|
||||
#endif
|
||||
|
||||
#include "flash_stm32.h"
|
||||
|
||||
#if defined(EEPROM_EMU_STM32F103xB)
|
||||
#define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
|
||||
#endif
|
||||
|
||||
/* Delay definition */
|
||||
#define EraseTimeout ((uint32_t)0x00000FFF)
|
||||
#define ProgramTimeout ((uint32_t)0x0000001F)
|
||||
|
||||
#define ASSERT(exp) (void)((0))
|
||||
|
||||
/**
|
||||
* @brief Inserts a time delay.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void delay(void)
|
||||
{
|
||||
__IO uint32_t i = 0;
|
||||
for(i = 0xFF; i != 0; i--) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the FLASH Status.
|
||||
* @param None
|
||||
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
|
||||
* FLASH_ERROR_WRP or FLASH_COMPLETE
|
||||
*/
|
||||
FLASH_Status FLASH_GetStatus(void)
|
||||
{
|
||||
if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)
|
||||
return FLASH_BUSY;
|
||||
|
||||
if ((FLASH->SR & FLASH_SR_PGERR) != 0)
|
||||
return FLASH_ERROR_PG;
|
||||
|
||||
if ((FLASH->SR & FLASH_SR_WRPERR) != 0 )
|
||||
return FLASH_ERROR_WRP;
|
||||
|
||||
if ((FLASH->SR & FLASH_OBR_OPTERR) != 0 )
|
||||
return FLASH_ERROR_OPT;
|
||||
|
||||
return FLASH_COMPLETE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
|
||||
* @param Timeout: FLASH progamming Timeout
|
||||
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
|
||||
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
|
||||
*/
|
||||
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
|
||||
{
|
||||
FLASH_Status status;
|
||||
|
||||
/* Check for the Flash Status */
|
||||
status = FLASH_GetStatus();
|
||||
/* Wait for a Flash operation to complete or a TIMEOUT to occur */
|
||||
while ((status == FLASH_BUSY) && (Timeout != 0x00))
|
||||
{
|
||||
delay();
|
||||
status = FLASH_GetStatus();
|
||||
Timeout--;
|
||||
}
|
||||
if (Timeout == 0)
|
||||
status = FLASH_TIMEOUT;
|
||||
/* Return the operation status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erases a specified FLASH page.
|
||||
* @param Page_Address: The page address to be erased.
|
||||
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
|
||||
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
|
||||
*/
|
||||
FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
|
||||
{
|
||||
FLASH_Status status = FLASH_COMPLETE;
|
||||
/* Check the parameters */
|
||||
ASSERT(IS_FLASH_ADDRESS(Page_Address));
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(EraseTimeout);
|
||||
|
||||
if(status == FLASH_COMPLETE)
|
||||
{
|
||||
/* if the previous operation is completed, proceed to erase the page */
|
||||
FLASH->CR |= FLASH_CR_PER;
|
||||
FLASH->AR = Page_Address;
|
||||
FLASH->CR |= FLASH_CR_STRT;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(EraseTimeout);
|
||||
if(status != FLASH_TIMEOUT)
|
||||
{
|
||||
/* if the erase operation is completed, disable the PER Bit */
|
||||
FLASH->CR &= ~FLASH_CR_PER;
|
||||
}
|
||||
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
|
||||
}
|
||||
/* Return the Erase Status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Programs a half word at a specified address.
|
||||
* @param Address: specifies the address to be programmed.
|
||||
* @param Data: specifies the data to be programmed.
|
||||
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
|
||||
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
|
||||
*/
|
||||
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
FLASH_Status status = FLASH_BAD_ADDRESS;
|
||||
|
||||
if (IS_FLASH_ADDRESS(Address))
|
||||
{
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(ProgramTimeout);
|
||||
if(status == FLASH_COMPLETE)
|
||||
{
|
||||
/* if the previous operation is completed, proceed to program the new data */
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
*(__IO uint16_t*)Address = Data;
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(ProgramTimeout);
|
||||
if(status != FLASH_TIMEOUT)
|
||||
{
|
||||
/* if the program operation is completed, disable the PG Bit */
|
||||
FLASH->CR &= ~FLASH_CR_PG;
|
||||
}
|
||||
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlocks the FLASH Program Erase Controller.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_Unlock(void)
|
||||
{
|
||||
/* Authorize the FPEC Access */
|
||||
FLASH->KEYR = FLASH_KEY1;
|
||||
FLASH->KEYR = FLASH_KEY2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Locks the FLASH Program Erase Controller.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_Lock(void)
|
||||
{
|
||||
/* Set the Lock Bit to lock the FPEC and the FCR */
|
||||
FLASH->CR |= FLASH_CR_LOCK;
|
||||
}
|
53
tmk_core/common/chibios/flash_stm32.h
Executable file
53
tmk_core/common/chibios/flash_stm32.h
Executable file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef __FLASH_STM32_H
|
||||
#define __FLASH_STM32_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FLASH_BUSY = 1,
|
||||
FLASH_ERROR_PG,
|
||||
FLASH_ERROR_WRP,
|
||||
FLASH_ERROR_OPT,
|
||||
FLASH_COMPLETE,
|
||||
FLASH_TIMEOUT,
|
||||
FLASH_BAD_ADDRESS
|
||||
} FLASH_Status;
|
||||
|
||||
#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF))
|
||||
|
||||
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
|
||||
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
|
||||
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
|
||||
|
||||
void FLASH_Unlock(void);
|
||||
void FLASH_Lock(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __FLASH_STM32_H */
|
|
@ -181,7 +181,11 @@ static void print_version(void)
|
|||
print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
|
||||
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
|
||||
"VER: " STR(DEVICE_VER) "\n");
|
||||
#ifdef SKIP_VERSION
|
||||
print("BUILD: (" __DATE__ ")\n");
|
||||
#else
|
||||
print("BUILD: " STR(QMK_VERSION) " (" __TIME__ " " __DATE__ ")\n");
|
||||
#endif
|
||||
|
||||
/* build options */
|
||||
print("OPTIONS:"
|
||||
|
|
|
@ -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 COMMAND_H
|
||||
#define COMMAND
|
||||
#pragma once
|
||||
|
||||
/* FIXME: Add doxygen comments for the behavioral defines in here. */
|
||||
|
||||
|
@ -155,5 +154,3 @@ bool command_proc(uint8_t code);
|
|||
|
||||
#define XMAGIC_KC(key) KC_##key
|
||||
#define MAGIC_KC(key) XMAGIC_KC(key)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,29 +3,59 @@
|
|||
#include "eeprom.h"
|
||||
#include "eeconfig.h"
|
||||
|
||||
#ifdef STM32_EEPROM_ENABLE
|
||||
#include "hal.h"
|
||||
#include "eeprom_stm32.h"
|
||||
#endif
|
||||
|
||||
extern uint32_t default_layer_state;
|
||||
/** \brief eeconfig enable
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
__attribute__ ((weak))
|
||||
void eeconfig_init_user(void) {
|
||||
// Reset user EEPROM value to blank, rather than to a set value
|
||||
eeconfig_update_user(0);
|
||||
}
|
||||
|
||||
__attribute__ ((weak))
|
||||
void eeconfig_init_kb(void) {
|
||||
// Reset Keyboard EEPROM value to blank, rather than to a set value
|
||||
eeconfig_update_kb(0);
|
||||
|
||||
eeconfig_init_user();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
void eeconfig_init_quantum(void) {
|
||||
#ifdef STM32_EEPROM_ENABLE
|
||||
EEPROM_format();
|
||||
#endif
|
||||
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
|
||||
eeprom_update_byte(EECONFIG_DEBUG, 0);
|
||||
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
|
||||
default_layer_state = 0;
|
||||
eeprom_update_byte(EECONFIG_KEYMAP, 0);
|
||||
eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
|
||||
eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
|
||||
eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
|
||||
eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
|
||||
eeprom_update_byte(EECONFIG_STENOMODE, 0);
|
||||
|
||||
eeconfig_init_kb();
|
||||
}
|
||||
|
||||
/** \brief eeconfig initialization
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
void eeconfig_init(void)
|
||||
{
|
||||
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
|
||||
eeprom_update_byte(EECONFIG_DEBUG, 0);
|
||||
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
|
||||
eeprom_update_byte(EECONFIG_KEYMAP, 0);
|
||||
eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
|
||||
#endif
|
||||
#ifdef AUDIO_ENABLE
|
||||
eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
|
||||
#endif
|
||||
#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
|
||||
eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
|
||||
#endif
|
||||
#ifdef STENO_ENABLE
|
||||
eeprom_update_byte(EECONFIG_STENOMODE, 0);
|
||||
#endif
|
||||
void eeconfig_init(void) {
|
||||
|
||||
eeconfig_init_quantum();
|
||||
}
|
||||
|
||||
/** \brief eeconfig enable
|
||||
|
@ -43,7 +73,10 @@ void eeconfig_enable(void)
|
|||
*/
|
||||
void eeconfig_disable(void)
|
||||
{
|
||||
eeprom_update_word(EECONFIG_MAGIC, 0xFFFF);
|
||||
#ifdef STM32_EEPROM_ENABLE
|
||||
EEPROM_format();
|
||||
#endif
|
||||
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
|
||||
}
|
||||
|
||||
/** \brief eeconfig is enabled
|
||||
|
@ -55,6 +88,15 @@ bool eeconfig_is_enabled(void)
|
|||
return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
|
||||
}
|
||||
|
||||
/** \brief eeconfig is disabled
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
bool eeconfig_is_disabled(void)
|
||||
{
|
||||
return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
|
||||
}
|
||||
|
||||
/** \brief eeconfig read debug
|
||||
*
|
||||
* FIXME: needs doc
|
||||
|
@ -88,7 +130,6 @@ uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMA
|
|||
*/
|
||||
void eeconfig_update_keymap(uint8_t val) { eeprom_update_byte(EECONFIG_KEYMAP, val); }
|
||||
|
||||
#ifdef BACKLIGHT_ENABLE
|
||||
/** \brief eeconfig read backlight
|
||||
*
|
||||
* FIXME: needs doc
|
||||
|
@ -99,9 +140,8 @@ uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BA
|
|||
* FIXME: needs doc
|
||||
*/
|
||||
void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); }
|
||||
#endif
|
||||
|
||||
#ifdef AUDIO_ENABLE
|
||||
|
||||
/** \brief eeconfig read audio
|
||||
*
|
||||
* FIXME: needs doc
|
||||
|
@ -112,4 +152,28 @@ uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO)
|
|||
* FIXME: needs doc
|
||||
*/
|
||||
void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); }
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief eeconfig read kb
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); }
|
||||
/** \brief eeconfig update kb
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
|
||||
void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, val); }
|
||||
/** \brief eeconfig read user
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); }
|
||||
/** \brief eeconfig update user
|
||||
*
|
||||
* FIXME: needs doc
|
||||
*/
|
||||
void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); }
|
||||
|
||||
|
||||
|
|
|
@ -23,21 +23,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
|
||||
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
|
||||
|
||||
/* eeprom parameteter address */
|
||||
#if !defined(STM32_EEPROM_ENABLE)
|
||||
#define EECONFIG_MAGIC (uint16_t *)0
|
||||
#define EECONFIG_DEBUG (uint8_t *)2
|
||||
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
|
||||
#define EECONFIG_KEYMAP (uint8_t *)4
|
||||
#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
|
||||
#define EECONFIG_BACKLIGHT (uint8_t *)6
|
||||
#define EECONFIG_AUDIO (uint8_t *)7
|
||||
#define EECONFIG_DEBUG (uint8_t *)2
|
||||
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
|
||||
#define EECONFIG_KEYMAP (uint8_t *)4
|
||||
#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
|
||||
#define EECONFIG_BACKLIGHT (uint8_t *)6
|
||||
#define EECONFIG_AUDIO (uint8_t *)7
|
||||
#define EECONFIG_RGBLIGHT (uint32_t *)8
|
||||
#define EECONFIG_UNICODEMODE (uint8_t *)12
|
||||
#define EECONFIG_STENOMODE (uint8_t *)13
|
||||
// EEHANDS for two handed boards
|
||||
#define EECONFIG_HANDEDNESS (uint8_t *)14
|
||||
#define EECONFIG_HANDEDNESS (uint8_t *)14
|
||||
#define EECONFIG_KEYBOARD (uint32_t *)15
|
||||
#define EECONFIG_USER (uint32_t *)19
|
||||
|
||||
#else
|
||||
/* STM32F3 uses 16byte block. Reconfigure memory map */
|
||||
#define EECONFIG_MAGIC (uint16_t *)0
|
||||
#define EECONFIG_DEBUG (uint8_t *)1
|
||||
#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
|
||||
#define EECONFIG_KEYMAP (uint8_t *)3
|
||||
#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
|
||||
#define EECONFIG_BACKLIGHT (uint8_t *)5
|
||||
#define EECONFIG_AUDIO (uint8_t *)6
|
||||
#define EECONFIG_RGBLIGHT (uint32_t *)7
|
||||
#define EECONFIG_UNICODEMODE (uint8_t *)9
|
||||
#define EECONFIG_STENOMODE (uint8_t *)10
|
||||
// EEHANDS for two handed boards
|
||||
#define EECONFIG_HANDEDNESS (uint8_t *)11
|
||||
#define EECONFIG_KEYBOARD (uint32_t *)12
|
||||
#define EECONFIG_USER (uint32_t *)14
|
||||
#endif
|
||||
|
||||
/* debug bit */
|
||||
#define EECONFIG_DEBUG_ENABLE (1<<0)
|
||||
|
@ -57,8 +78,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
bool eeconfig_is_enabled(void);
|
||||
bool eeconfig_is_disabled(void);
|
||||
|
||||
void eeconfig_init(void);
|
||||
void eeconfig_init_quantum(void);
|
||||
void eeconfig_init_kb(void);
|
||||
void eeconfig_init_user(void);
|
||||
|
||||
void eeconfig_enable(void);
|
||||
|
||||
|
@ -83,4 +108,9 @@ uint8_t eeconfig_read_audio(void);
|
|||
void eeconfig_update_audio(uint8_t val);
|
||||
#endif
|
||||
|
||||
uint32_t eeconfig_read_kb(void);
|
||||
void eeconfig_update_kb(uint32_t val);
|
||||
uint32_t eeconfig_read_user(void);
|
||||
void eeconfig_update_user(uint32_t val);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "util.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
#include "keycode_config.h"
|
||||
extern keymap_config_t keymap_config;
|
||||
#endif
|
||||
|
||||
static host_driver_t *driver;
|
||||
static uint16_t last_system_report = 0;
|
||||
static uint16_t last_consumer_report = 0;
|
||||
|
@ -46,6 +51,20 @@ uint8_t host_keyboard_leds(void)
|
|||
void host_keyboard_send(report_keyboard_t *report)
|
||||
{
|
||||
if (!driver) return;
|
||||
#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
|
||||
if (keyboard_protocol && keymap_config.nkro) {
|
||||
/* The callers of this function assume that report->mods is where mods go in.
|
||||
* But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
|
||||
*/
|
||||
report->nkro.mods = report->mods;
|
||||
report->nkro.report_id = REPORT_ID_NKRO;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef KEYBOARD_SHARED_EP
|
||||
report->report_id = REPORT_ID_KEYBOARD;
|
||||
#endif
|
||||
}
|
||||
(*driver->send_keyboard)(report);
|
||||
|
||||
if (debug_keyboard) {
|
||||
|
@ -60,6 +79,9 @@ void host_keyboard_send(report_keyboard_t *report)
|
|||
void host_mouse_send(report_mouse_t *report)
|
||||
{
|
||||
if (!driver) return;
|
||||
#ifdef MOUSE_SHARED_EP
|
||||
report->report_id = REPORT_ID_MOUSE;
|
||||
#endif
|
||||
(*driver->send_mouse)(report);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifdef HD44780_ENABLE
|
||||
# include "hd44780.h"
|
||||
#endif
|
||||
#ifdef QWIIC_ENABLE
|
||||
# include "qwiic.h"
|
||||
#endif
|
||||
|
||||
#ifdef MATRIX_HAS_GHOST
|
||||
extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
|
||||
|
@ -121,6 +124,14 @@ static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata)
|
|||
|
||||
#endif
|
||||
|
||||
void disable_jtag(void) {
|
||||
// To use PORTF disable JTAG with writing JTD bit twice within four cycles.
|
||||
#if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__))
|
||||
MCUCR |= _BV(JTD);
|
||||
MCUCR |= _BV(JTD);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief matrix_setup
|
||||
*
|
||||
* FIXME: needs doc
|
||||
|
@ -134,6 +145,7 @@ void matrix_setup(void) {
|
|||
* FIXME: needs doc
|
||||
*/
|
||||
void keyboard_setup(void) {
|
||||
disable_jtag();
|
||||
matrix_setup();
|
||||
}
|
||||
|
||||
|
@ -152,13 +164,11 @@ bool is_keyboard_master(void) {
|
|||
*/
|
||||
void keyboard_init(void) {
|
||||
timer_init();
|
||||
// To use PORTF disable JTAG with writing JTD bit twice within four cycles.
|
||||
#if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega32U4__))
|
||||
MCUCR |= _BV(JTD);
|
||||
MCUCR |= _BV(JTD);
|
||||
#endif
|
||||
matrix_init();
|
||||
matrix_debounce_init();
|
||||
#ifdef QWIIC_ENABLE
|
||||
qwiic_init();
|
||||
#endif
|
||||
#ifdef PS2_MOUSE_ENABLE
|
||||
ps2_mouse_init();
|
||||
#endif
|
||||
|
@ -256,6 +266,10 @@ void keyboard_task(void)
|
|||
|
||||
MATRIX_LOOP_END:
|
||||
|
||||
#ifdef QWIIC_ENABLE
|
||||
qwiic_task();
|
||||
#endif
|
||||
|
||||
#ifdef MOUSEKEY_ENABLE
|
||||
// mousekey repeat & acceleration
|
||||
mousekey_task();
|
||||
|
|
|
@ -57,6 +57,8 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
|
|||
.time = (timer_read() | 1) \
|
||||
}
|
||||
|
||||
void disable_jtag(void);
|
||||
|
||||
/* it runs once at early stage of startup before keyboard_init. */
|
||||
void keyboard_setup(void);
|
||||
/* it runs once after initializing host side protocol, debug and MCU peripherals. */
|
||||
|
|
|
@ -33,7 +33,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
|
||||
#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
|
||||
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_MRWD)
|
||||
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID)
|
||||
|
||||
#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
|
||||
|
||||
|
@ -140,6 +140,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define KC_LWIN KC_LGUI
|
||||
#define KC_RCTL KC_RCTRL
|
||||
#define KC_RSFT KC_RSHIFT
|
||||
#define KC_ALGR KC_RALT
|
||||
#define KC_RCMD KC_RGUI
|
||||
#define KC_RWIN KC_RGUI
|
||||
|
||||
|
@ -170,6 +171,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define KC_WFAV KC_WWW_FAVORITES
|
||||
#define KC_MFFD KC_MEDIA_FAST_FORWARD
|
||||
#define KC_MRWD KC_MEDIA_REWIND
|
||||
#define KC_BRIU KC_BRIGHTNESS_UP
|
||||
#define KC_BRID KC_BRIGHTNESS_DOWN
|
||||
|
||||
/* Mouse Keys */
|
||||
#define KC_MS_U KC_MS_UP
|
||||
|
@ -457,6 +460,8 @@ enum internal_special_keycodes {
|
|||
KC_WWW_FAVORITES,
|
||||
KC_MEDIA_FAST_FORWARD,
|
||||
KC_MEDIA_REWIND,
|
||||
KC_BRIGHTNESS_UP,
|
||||
KC_BRIGHTNESS_DOWN,
|
||||
|
||||
/* Fn keys */
|
||||
KC_FN0 = 0xC0,
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <stdbool.h>
|
||||
#include "util.h"
|
||||
|
||||
#if defined(PROTOCOL_CHIBIOS)
|
||||
#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM)
|
||||
#define PSTR(x) x
|
||||
#endif
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
|||
# define println(s) xputs(PSTR(s "\r\n"))
|
||||
# define uprint(s) print(s)
|
||||
# define uprintln(s) println(s)
|
||||
# define uprintf(fmt, ...) xprintf(fmt, ...)
|
||||
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
|
||||
|
||||
# endif /* USER_PRINT / NORMAL PRINT */
|
||||
|
||||
|
@ -73,7 +73,9 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
|
|||
|
||||
#elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
|
||||
|
||||
#ifndef TERMINAL_ENABLE
|
||||
# include "chibios/printf.h"
|
||||
#endif
|
||||
|
||||
# ifdef USER_PRINT /* USER_PRINT */
|
||||
|
||||
|
@ -99,6 +101,34 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
|
|||
|
||||
# endif /* USER_PRINT / NORMAL PRINT */
|
||||
|
||||
#elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */
|
||||
|
||||
# include "arm_atsam/printf.h"
|
||||
|
||||
# ifdef USER_PRINT /* USER_PRINT */
|
||||
|
||||
// Remove normal print defines
|
||||
# define print(s)
|
||||
# define println(s)
|
||||
# define xprintf(fmt, ...)
|
||||
|
||||
// Create user print defines
|
||||
# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
# define uprint(s) xprintf(s)
|
||||
# define uprintln(s) xprintf(s "\r\n")
|
||||
|
||||
# else /* NORMAL PRINT */
|
||||
|
||||
// Create user & normal print defines
|
||||
# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
# define print(s) xprintf(s)
|
||||
# define println(s) xprintf(s "\r\n")
|
||||
# define uprint(s) print(s)
|
||||
# define uprintln(s) println(s)
|
||||
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
|
||||
|
||||
# endif /* USER_PRINT / NORMAL PRINT */
|
||||
|
||||
#elif defined(__arm__) /* __arm__ */
|
||||
|
||||
# include "mbed/xprintf.h"
|
||||
|
@ -111,26 +141,26 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
|
|||
# define xprintf(fmt, ...)
|
||||
|
||||
// Create user print defines
|
||||
# define uprintf(fmt, ...) __xprintf(fmt, ...)
|
||||
# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
# define uprint(s) xprintf(s)
|
||||
# define uprintln(s) xprintf(s "\r\n")
|
||||
|
||||
# else /* NORMAL PRINT */
|
||||
|
||||
// Create user & normal print defines
|
||||
# define xprintf(fmt, ...) __xprintf(fmt, ...)
|
||||
# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
|
||||
# define print(s) xprintf(s)
|
||||
# define println(s) xprintf(s "\r\n")
|
||||
# define uprint(s) print(s)
|
||||
# define uprintln(s) println(s)
|
||||
# define uprintf(fmt, ...) xprintf(fmt, ...)
|
||||
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
|
||||
|
||||
# endif /* USER_PRINT / NORMAL PRINT */
|
||||
|
||||
/* TODO: to select output destinations: UART/USBSerial */
|
||||
# define print_set_sendchar(func)
|
||||
|
||||
#endif /* __AVR__ / PROTOCOL_CHIBIOS / __arm__ */
|
||||
#endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM / __arm__ */
|
||||
|
||||
// User print disables the normal print messages in the body of QMK/TMK code and
|
||||
// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "keycode_config.h"
|
||||
#include "debug.h"
|
||||
#include "util.h"
|
||||
#include <string.h>
|
||||
|
||||
/** \brief has_anykey
|
||||
*
|
||||
|
@ -27,8 +28,16 @@
|
|||
uint8_t has_anykey(report_keyboard_t* keyboard_report)
|
||||
{
|
||||
uint8_t cnt = 0;
|
||||
for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
|
||||
if (keyboard_report->raw[i])
|
||||
uint8_t *p = keyboard_report->keys;
|
||||
uint8_t lp = sizeof(keyboard_report->keys);
|
||||
#ifdef NKRO_ENABLE
|
||||
if (keyboard_protocol && keymap_config.nkro) {
|
||||
p = keyboard_report->nkro.bits;
|
||||
lp = sizeof(keyboard_report->nkro.bits);
|
||||
}
|
||||
#endif
|
||||
while (lp--) {
|
||||
if (*p++)
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
|
@ -237,7 +246,11 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
|
|||
void clear_keys_from_report(report_keyboard_t* keyboard_report)
|
||||
{
|
||||
// not clear mods
|
||||
for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
|
||||
keyboard_report->raw[i] = 0;
|
||||
#ifdef NKRO_ENABLE
|
||||
if (keyboard_protocol && keymap_config.nkro) {
|
||||
memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
|
||||
}
|
||||
|
|
|
@ -23,9 +23,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
|
||||
/* report id */
|
||||
#define REPORT_ID_MOUSE 1
|
||||
#define REPORT_ID_SYSTEM 2
|
||||
#define REPORT_ID_CONSUMER 3
|
||||
#define REPORT_ID_KEYBOARD 1
|
||||
#define REPORT_ID_MOUSE 2
|
||||
#define REPORT_ID_SYSTEM 3
|
||||
#define REPORT_ID_CONSUMER 4
|
||||
#define REPORT_ID_NKRO 5
|
||||
|
||||
/* mouse buttons */
|
||||
#define MOUSE_BTN1 (1<<0)
|
||||
|
@ -36,6 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
/* Consumer Page(0x0C)
|
||||
* following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx
|
||||
* see also https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/display-brightness-control
|
||||
*/
|
||||
#define AUDIO_MUTE 0x00E2
|
||||
#define AUDIO_VOL_UP 0x00E9
|
||||
|
@ -45,6 +48,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define TRANSPORT_STOP 0x00B7
|
||||
#define TRANSPORT_STOP_EJECT 0x00CC
|
||||
#define TRANSPORT_PLAY_PAUSE 0x00CD
|
||||
#define BRIGHTNESSUP 0x006F
|
||||
#define BRIGHTNESSDOWN 0x0070
|
||||
/* application launch */
|
||||
#define AL_CC_CONFIG 0x0183
|
||||
#define AL_EMAIL 0x018A
|
||||
|
@ -72,27 +77,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#define SYSTEM_WAKE_UP 0x0083
|
||||
|
||||
|
||||
#define NKRO_SHARED_EP
|
||||
/* key report size(NKRO or boot mode) */
|
||||
#if defined(NKRO_ENABLE)
|
||||
#if defined(PROTOCOL_PJRC)
|
||||
#include "usb.h"
|
||||
#define KEYBOARD_REPORT_SIZE KBD2_SIZE
|
||||
#define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
|
||||
#define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
|
||||
#elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
|
||||
#if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
|
||||
#include "protocol/usb_descriptor.h"
|
||||
#define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
|
||||
#define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
|
||||
#define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
|
||||
#elif defined(PROTOCOL_ARM_ATSAM)
|
||||
#include "protocol/arm_atsam/usb/udi_device_epsize.h"
|
||||
#define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
|
||||
#undef NKRO_SHARED_EP
|
||||
#undef MOUSE_SHARED_EP
|
||||
#else
|
||||
#error "NKRO not supported with this protocol"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef KEYBOARD_SHARED_EP
|
||||
# define KEYBOARD_REPORT_SIZE 9
|
||||
#else
|
||||
# define KEYBOARD_REPORT_SIZE 8
|
||||
# define KEYBOARD_REPORT_KEYS 6
|
||||
#endif
|
||||
|
||||
#define KEYBOARD_REPORT_KEYS 6
|
||||
|
||||
/* VUSB hardcodes keyboard and mouse+extrakey only */
|
||||
#if defined(PROTOCOL_VUSB)
|
||||
#undef KEYBOARD_SHARED_EP
|
||||
#undef MOUSE_SHARED_EP
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -121,12 +134,18 @@ extern "C" {
|
|||
typedef union {
|
||||
uint8_t raw[KEYBOARD_REPORT_SIZE];
|
||||
struct {
|
||||
#ifdef KEYBOARD_SHARED_EP
|
||||
uint8_t report_id;
|
||||
#endif
|
||||
uint8_t mods;
|
||||
uint8_t reserved;
|
||||
uint8_t keys[KEYBOARD_REPORT_KEYS];
|
||||
};
|
||||
#ifdef NKRO_ENABLE
|
||||
struct {
|
||||
struct nkro_report {
|
||||
#ifdef NKRO_SHARED_EP
|
||||
uint8_t report_id;
|
||||
#endif
|
||||
uint8_t mods;
|
||||
uint8_t bits[KEYBOARD_REPORT_BITS];
|
||||
} nkro;
|
||||
|
@ -134,6 +153,9 @@ typedef union {
|
|||
} __attribute__ ((packed)) report_keyboard_t;
|
||||
|
||||
typedef struct {
|
||||
#ifdef MOUSE_SHARED_EP
|
||||
uint8_t report_id;
|
||||
#endif
|
||||
uint8_t buttons;
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
|
@ -170,7 +192,9 @@ typedef struct {
|
|||
(key == KC_WWW_FORWARD ? AC_FORWARD : \
|
||||
(key == KC_WWW_STOP ? AC_STOP : \
|
||||
(key == KC_WWW_REFRESH ? AC_REFRESH : \
|
||||
(key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))
|
||||
(key == KC_BRIGHTNESS_UP ? BRIGHTNESSUP : \
|
||||
(key == KC_BRIGHTNESS_DOWN ? BRIGHTNESSDOWN : \
|
||||
(key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))))
|
||||
|
||||
uint8_t has_anykey(report_keyboard_t* keyboard_report);
|
||||
uint8_t get_first_key(report_keyboard_t* keyboard_report);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue