Conflicts:
	tmk_core/doc/keymap.md
This commit is contained in:
tmk 2016-04-21 14:37:16 +09:00
commit 53bd4a01be
17 changed files with 372 additions and 67 deletions

View file

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_macro.h"
#include "action_util.h"
#include "action.h"
#include "hook.h"
#ifdef DEBUG_ACTION
#include "debug.h"
@ -39,6 +40,7 @@ void action_exec(keyevent_t event)
if (!IS_NOEVENT(event)) {
dprint("\n---- action_exec: start -----\n");
dprint("EVENT: "); debug_event(event); dprintln();
hook_matrix_change(event);
}
keyrecord_t record = { .event = event };

View file

@ -3,6 +3,7 @@
#include "action.h"
#include "util.h"
#include "action_layer.h"
#include "hook.h"
#ifdef DEBUG_ACTION
#include "debug.h"
@ -62,6 +63,7 @@ static void layer_state_set(uint32_t state)
dprint("layer_state: ");
layer_debug(); dprint(" to ");
layer_state = state;
hook_layer_change(layer_state);
layer_debug(); dprintln();
clear_keyboard_but_mods(); // To avoid stuck keys
}

View file

@ -10,6 +10,7 @@
#include "action_layer.h"
#include "eeconfig.h"
#include "bootmagic.h"
#include "hook.h"
keymap_config_t keymap_config;
@ -41,6 +42,9 @@ void bootmagic(void)
bootloader_jump();
}
/* user-defined checks */
hook_bootmagic();
/* debug enable */
debug_config.raw = eeconfig_read_debug();
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_ENABLE)) {

View file

@ -42,5 +42,6 @@ void bootloader_jump(void) {
#endif /* defined(KIIBOHD_BOOTLOADER) */
#else /* neither STM32 nor KINETIS */
__attribute__((weak))
void bootloader_jump(void) {}
#endif

View file

@ -4,11 +4,27 @@
#include "led.h"
#include "sleep_led.h"
#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
/* All right, we go the "software" way: LP timer, toggle LED in interrupt.
/* All right, we go the "software" way: timer, toggle LED in interrupt.
* Based on hasu's code for AVRs.
* Use LP timer on Kinetises, TIM14 on STM32F0.
*/
#if defined(KL2x) || defined(K20x)
/* Use Low Power Timer (LPTMR) */
#define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
#define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
#elif defined(STM32F0XX)
/* Use TIM14 manually */
#define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
#define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
#endif
#if defined(KL2x) || defined(K20x) || defined(STM32F0XX) /* common parts for timers/interrupts */
/* Breathing Sleep LED brighness(PWM On period) table
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
*
@ -22,8 +38,8 @@ static const uint8_t breathing_table[64] = {
15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Low Power Timer interrupt handler */
OSAL_IRQ_HANDLER(KINETIS_LPTMR0_IRQ_VECTOR) {
/* interrupt handler */
OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
OSAL_IRQ_PROLOGUE();
/* Software PWM
@ -55,11 +71,16 @@ OSAL_IRQ_HANDLER(KINETIS_LPTMR0_IRQ_VECTOR) {
}
/* Reset the counter */
LPTMR0->CSR |= LPTMRx_CSR_TCF;
RESET_COUNTER;
OSAL_IRQ_EPILOGUE();
}
#endif /* common parts for known platforms */
#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
/* LPTMR clock options */
#define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
#define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
@ -144,7 +165,48 @@ void sleep_led_toggle(void) {
LPTMR0->CSR ^= LPTMRx_CSR_TEN;
}
#else /* platform selection: not on familiar Kinetis chips */
#elif defined(STM32F0XX) /* platform selection: STM32F0XX */
/* Initialise the timer */
void sleep_led_init(void) {
/* enable clock */
rccEnableTIM14(FALSE); /* low power enable = FALSE */
rccResetTIM14();
/* prescale */
/* Assuming 48MHz internal clock */
/* getting cca 65484 irqs/sec */
STM32_TIM14->PSC = 733;
/* auto-reload */
/* 0 => interrupt every time */
STM32_TIM14->ARR = 3;
/* enable counter update event interrupt */
STM32_TIM14->DIER |= STM32_TIM_DIER_UIE;
/* register interrupt vector */
nvicEnableVector(STM32_TIM14_NUMBER, 2); /* vector, priority */
}
void sleep_led_enable(void) {
/* Enable the timer */
STM32_TIM14->CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS;
/* URS => update event only on overflow; setting UG bit disabled */
}
void sleep_led_disable(void) {
/* Disable the timer */
STM32_TIM14->CR1 = 0;
}
void sleep_led_toggle(void) {
/* Toggle the timer */
STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN;
}
#else /* platform selection: not on familiar chips */
void sleep_led_init(void) {
}

61
tmk_core/common/hook.c Normal file
View file

@ -0,0 +1,61 @@
/*
Copyright 2016 Jun Wako <wakojun@gmail.com>
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 "keyboard.h"
#include "hook.h"
/* -------------------------------------------------
* Definitions of hardware-independent default hooks
* ------------------------------------------------- */
/* Called on layer state change event. */
/* Default behaviour: do nothing. */
__attribute__((weak))
void hook_layer_change(uint8_t layer_state) {
(void)layer_state;
}
/* Called periodically from the matrix scan loop (very often!) */
/* Default behaviour: do nothing. */
__attribute__((weak))
void hook_keyboard_loop(void) {}
/* Called on matrix state change event (every keypress => often!) */
/* Default behaviour: do nothing. */
__attribute__((weak))
void hook_matrix_change(keyevent_t event) {
(void)event;
}
/* Called on indicator LED update event (when reported from host). */
/* Default behaviour: calls led_set (for compatibility). */
__attribute__((weak))
void hook_keyboard_leds_change(uint8_t led_status) {
keyboard_set_leds(led_status);
}
/* Called once, on checking the bootmagic combos. */
/* Default behaviour: do nothing. */
__attribute__((weak))
void hook_bootmagic(void) {
/* An example: */
// #include "bootmagic.h"
// #include "keymap.h"
// if(bootmagic_scan_keycode(KC_W)) {
// // do something
// }
}

74
tmk_core/common/hook.h Normal file
View file

@ -0,0 +1,74 @@
/*
Copyright 2016 Jun Wako <wakojun@gmail.com>
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/>.
*/
#ifndef _HOOKS_H_
#define _HOOKS_H_
#include "keyboard.h"
#include "led.h"
/* -------------------------------------
* Hardware / one-off hooks
* ------------------------------------- */
/* Called once, before initialising USB. */
/* Default behaviour: do nothing. */
void hook_early_init(void);
/* Called once, after USB is connected and keyboard initialised. */
/* Default behaviour: do nothing. */
void hook_late_init(void);
/* Called once, on getting SUSPEND event from USB. */
/* Default behaviour: do nothing. */
void hook_usb_suspend_entry(void);
/* Called repeatedly during the SUSPENDed state. */
/* Default behaviour: power down and periodically check
* the matrix, cause wakeup if needed. */
void hook_usb_suspend_loop(void);
/* Called once, on getting WAKE event from USB. */
/* Default behaviour: disables sleep LED breathing and restores
* the "normal" indicator LED status by default. */
void hook_usb_wakeup(void);
/* Called once, on checking the bootmagic combos. */
/* Default behaviour: do nothing. */
void hook_bootmagic(void);
/* -------------------------------------
* Keyboard / periodic hooks
* ------------------------------------- */
/* Called periodically from the keyboard loop (very often!) */
/* Default behaviour: do nothing. */
void hook_keyboard_loop(void);
/* Called on matrix state change event (every keypress => often!) */
/* Default behaviour: do nothing. */
void hook_matrix_change(keyevent_t event);
/* Called on layer state change event. */
/* Default behaviour: do nothing. */
void hook_layer_change(uint8_t layer_state);
/* Called on indicator LED update event (when reported from host). */
/* Default behaviour: calls keyboard_set_leds (for compatibility). */
void hook_keyboard_leds_change(uint8_t led_status);
#endif /* _HOOKS_H_ */

View file

@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "bootmagic.h"
#include "eeconfig.h"
#include "backlight.h"
#include "hook.h"
#ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
#endif
@ -128,11 +129,13 @@ void keyboard_task(void)
if (debug_matrix) matrix_print();
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_change & ((matrix_row_t)1<<c)) {
action_exec((keyevent_t){
keyevent_t e = (keyevent_t){
.key = (keypos_t){ .row = r, .col = c },
.pressed = (matrix_row & ((matrix_row_t)1<<c)),
.time = (timer_read() | 1) /* time should not be 0 */
});
};
action_exec(e);
hook_matrix_change(e);
// record a processed key
matrix_prev[r] ^= ((matrix_row_t)1<<c);
// process a key per task call
@ -146,6 +149,8 @@ void keyboard_task(void)
MATRIX_LOOP_END:
hook_keyboard_loop();
#ifdef MOUSEKEY_ENABLE
// mousekey repeat & acceleration
mousekey_task();
@ -166,12 +171,12 @@ MATRIX_LOOP_END:
// update LED
if (led_status != host_keyboard_leds()) {
led_status = host_keyboard_leds();
keyboard_set_leds(led_status);
if (debug_keyboard) dprintf("LED: %02X\n", led_status);
hook_keyboard_leds_change(led_status);
}
}
void keyboard_set_leds(uint8_t leds)
{
if (debug_keyboard) { debug("keyboard_set_led: "); debug_hex8(leds); debug("\n"); }
led_set(leds);
}