Skip to content

Commit 4f2c5bf

Browse files
committed
Merge commit '71381457fa1311dfa0b58ba882a96db740640871'
Conflicts: tmk_core/doc/keymap.md
2 parents 53a9c08 + d5c5ac6 commit 4f2c5bf

File tree

17 files changed

+372
-67
lines changed

17 files changed

+372
-67
lines changed

common.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ SRC += $(COMMON_DIR)/host.c \
99
$(COMMON_DIR)/print.c \
1010
$(COMMON_DIR)/debug.c \
1111
$(COMMON_DIR)/util.c \
12+
$(COMMON_DIR)/hook.c \
1213
$(COMMON_DIR)/avr/suspend.c \
1314
$(COMMON_DIR)/avr/xprintf.S \
1415
$(COMMON_DIR)/avr/timer.c \

common/action.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2626
#include "action_macro.h"
2727
#include "action_util.h"
2828
#include "action.h"
29+
#include "hook.h"
2930

3031
#ifdef DEBUG_ACTION
3132
#include "debug.h"
@@ -39,6 +40,7 @@ void action_exec(keyevent_t event)
3940
if (!IS_NOEVENT(event)) {
4041
dprint("\n---- action_exec: start -----\n");
4142
dprint("EVENT: "); debug_event(event); dprintln();
43+
hook_matrix_change(event);
4244
}
4345

4446
keyrecord_t record = { .event = event };

common/action_layer.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "action.h"
44
#include "util.h"
55
#include "action_layer.h"
6+
#include "hook.h"
67

78
#ifdef DEBUG_ACTION
89
#include "debug.h"
@@ -62,6 +63,7 @@ static void layer_state_set(uint32_t state)
6263
dprint("layer_state: ");
6364
layer_debug(); dprint(" to ");
6465
layer_state = state;
66+
hook_layer_change(layer_state);
6567
layer_debug(); dprintln();
6668
clear_keyboard_but_mods(); // To avoid stuck keys
6769
}

common/bootmagic.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "action_layer.h"
1111
#include "eeconfig.h"
1212
#include "bootmagic.h"
13+
#include "hook.h"
1314

1415
keymap_config_t keymap_config;
1516

@@ -41,6 +42,9 @@ void bootmagic(void)
4142
bootloader_jump();
4243
}
4344

45+
/* user-defined checks */
46+
hook_bootmagic();
47+
4448
/* debug enable */
4549
debug_config.raw = eeconfig_read_debug();
4650
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_ENABLE)) {

common/chibios/bootloader.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@ void bootloader_jump(void) {
4242
#endif /* defined(KIIBOHD_BOOTLOADER) */
4343

4444
#else /* neither STM32 nor KINETIS */
45+
__attribute__((weak))
4546
void bootloader_jump(void) {}
4647
#endif

common/chibios/sleep_led.c

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,27 @@
44
#include "led.h"
55
#include "sleep_led.h"
66

7-
#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
8-
/* All right, we go the "software" way: LP timer, toggle LED in interrupt.
7+
/* All right, we go the "software" way: timer, toggle LED in interrupt.
98
* Based on hasu's code for AVRs.
9+
* Use LP timer on Kinetises, TIM14 on STM32F0.
1010
*/
1111

12+
#if defined(KL2x) || defined(K20x)
13+
14+
/* Use Low Power Timer (LPTMR) */
15+
#define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
16+
#define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
17+
18+
#elif defined(STM32F0XX)
19+
20+
/* Use TIM14 manually */
21+
#define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
22+
#define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
23+
24+
#endif
25+
26+
#if defined(KL2x) || defined(K20x) || defined(STM32F0XX) /* common parts for timers/interrupts */
27+
1228
/* Breathing Sleep LED brighness(PWM On period) table
1329
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
1430
*
@@ -22,8 +38,8 @@ static const uint8_t breathing_table[64] = {
2238
15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2339
};
2440

25-
/* Low Power Timer interrupt handler */
26-
OSAL_IRQ_HANDLER(KINETIS_LPTMR0_IRQ_VECTOR) {
41+
/* interrupt handler */
42+
OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
2743
OSAL_IRQ_PROLOGUE();
2844

2945
/* Software PWM
@@ -55,11 +71,16 @@ OSAL_IRQ_HANDLER(KINETIS_LPTMR0_IRQ_VECTOR) {
5571
}
5672

5773
/* Reset the counter */
58-
LPTMR0->CSR |= LPTMRx_CSR_TCF;
74+
RESET_COUNTER;
5975

6076
OSAL_IRQ_EPILOGUE();
6177
}
6278

79+
#endif /* common parts for known platforms */
80+
81+
82+
#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
83+
6384
/* LPTMR clock options */
6485
#define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
6586
#define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
@@ -144,7 +165,48 @@ void sleep_led_toggle(void) {
144165
LPTMR0->CSR ^= LPTMRx_CSR_TEN;
145166
}
146167

147-
#else /* platform selection: not on familiar Kinetis chips */
168+
#elif defined(STM32F0XX) /* platform selection: STM32F0XX */
169+
170+
/* Initialise the timer */
171+
void sleep_led_init(void) {
172+
/* enable clock */
173+
rccEnableTIM14(FALSE); /* low power enable = FALSE */
174+
rccResetTIM14();
175+
176+
/* prescale */
177+
/* Assuming 48MHz internal clock */
178+
/* getting cca 65484 irqs/sec */
179+
STM32_TIM14->PSC = 733;
180+
181+
/* auto-reload */
182+
/* 0 => interrupt every time */
183+
STM32_TIM14->ARR = 3;
184+
185+
/* enable counter update event interrupt */
186+
STM32_TIM14->DIER |= STM32_TIM_DIER_UIE;
187+
188+
/* register interrupt vector */
189+
nvicEnableVector(STM32_TIM14_NUMBER, 2); /* vector, priority */
190+
}
191+
192+
void sleep_led_enable(void) {
193+
/* Enable the timer */
194+
STM32_TIM14->CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS;
195+
/* URS => update event only on overflow; setting UG bit disabled */
196+
}
197+
198+
void sleep_led_disable(void) {
199+
/* Disable the timer */
200+
STM32_TIM14->CR1 = 0;
201+
}
202+
203+
void sleep_led_toggle(void) {
204+
/* Toggle the timer */
205+
STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN;
206+
}
207+
208+
209+
#else /* platform selection: not on familiar chips */
148210

149211
void sleep_led_init(void) {
150212
}

common/hook.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright 2016 Jun Wako <[email protected]>
3+
4+
This program is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 2 of the License, or
7+
(at your option) any later version.
8+
9+
This program is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include "keyboard.h"
19+
#include "hook.h"
20+
21+
/* -------------------------------------------------
22+
* Definitions of hardware-independent default hooks
23+
* ------------------------------------------------- */
24+
25+
/* Called on layer state change event. */
26+
/* Default behaviour: do nothing. */
27+
__attribute__((weak))
28+
void hook_layer_change(uint8_t layer_state) {
29+
(void)layer_state;
30+
}
31+
32+
/* Called periodically from the matrix scan loop (very often!) */
33+
/* Default behaviour: do nothing. */
34+
__attribute__((weak))
35+
void hook_keyboard_loop(void) {}
36+
37+
/* Called on matrix state change event (every keypress => often!) */
38+
/* Default behaviour: do nothing. */
39+
__attribute__((weak))
40+
void hook_matrix_change(keyevent_t event) {
41+
(void)event;
42+
}
43+
44+
/* Called on indicator LED update event (when reported from host). */
45+
/* Default behaviour: calls led_set (for compatibility). */
46+
__attribute__((weak))
47+
void hook_keyboard_leds_change(uint8_t led_status) {
48+
keyboard_set_leds(led_status);
49+
}
50+
51+
/* Called once, on checking the bootmagic combos. */
52+
/* Default behaviour: do nothing. */
53+
__attribute__((weak))
54+
void hook_bootmagic(void) {
55+
/* An example: */
56+
// #include "bootmagic.h"
57+
// #include "keymap.h"
58+
// if(bootmagic_scan_keycode(KC_W)) {
59+
// // do something
60+
// }
61+
}

common/hook.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
Copyright 2016 Jun Wako <[email protected]>
3+
4+
This program is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 2 of the License, or
7+
(at your option) any later version.
8+
9+
This program is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#ifndef _HOOKS_H_
19+
#define _HOOKS_H_
20+
21+
#include "keyboard.h"
22+
#include "led.h"
23+
24+
/* -------------------------------------
25+
* Hardware / one-off hooks
26+
* ------------------------------------- */
27+
28+
/* Called once, before initialising USB. */
29+
/* Default behaviour: do nothing. */
30+
void hook_early_init(void);
31+
32+
/* Called once, after USB is connected and keyboard initialised. */
33+
/* Default behaviour: do nothing. */
34+
void hook_late_init(void);
35+
36+
/* Called once, on getting SUSPEND event from USB. */
37+
/* Default behaviour: do nothing. */
38+
void hook_usb_suspend_entry(void);
39+
40+
/* Called repeatedly during the SUSPENDed state. */
41+
/* Default behaviour: power down and periodically check
42+
* the matrix, cause wakeup if needed. */
43+
void hook_usb_suspend_loop(void);
44+
45+
/* Called once, on getting WAKE event from USB. */
46+
/* Default behaviour: disables sleep LED breathing and restores
47+
* the "normal" indicator LED status by default. */
48+
void hook_usb_wakeup(void);
49+
50+
/* Called once, on checking the bootmagic combos. */
51+
/* Default behaviour: do nothing. */
52+
void hook_bootmagic(void);
53+
54+
/* -------------------------------------
55+
* Keyboard / periodic hooks
56+
* ------------------------------------- */
57+
58+
/* Called periodically from the keyboard loop (very often!) */
59+
/* Default behaviour: do nothing. */
60+
void hook_keyboard_loop(void);
61+
62+
/* Called on matrix state change event (every keypress => often!) */
63+
/* Default behaviour: do nothing. */
64+
void hook_matrix_change(keyevent_t event);
65+
66+
/* Called on layer state change event. */
67+
/* Default behaviour: do nothing. */
68+
void hook_layer_change(uint8_t layer_state);
69+
70+
/* Called on indicator LED update event (when reported from host). */
71+
/* Default behaviour: calls keyboard_set_leds (for compatibility). */
72+
void hook_keyboard_leds_change(uint8_t led_status);
73+
74+
#endif /* _HOOKS_H_ */

common/keyboard.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
3030
#include "bootmagic.h"
3131
#include "eeconfig.h"
3232
#include "backlight.h"
33+
#include "hook.h"
3334
#ifdef MOUSEKEY_ENABLE
3435
# include "mousekey.h"
3536
#endif
@@ -128,11 +129,13 @@ void keyboard_task(void)
128129
if (debug_matrix) matrix_print();
129130
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
130131
if (matrix_change & ((matrix_row_t)1<<c)) {
131-
action_exec((keyevent_t){
132+
keyevent_t e = (keyevent_t){
132133
.key = (keypos_t){ .row = r, .col = c },
133134
.pressed = (matrix_row & ((matrix_row_t)1<<c)),
134135
.time = (timer_read() | 1) /* time should not be 0 */
135-
});
136+
};
137+
action_exec(e);
138+
hook_matrix_change(e);
136139
// record a processed key
137140
matrix_prev[r] ^= ((matrix_row_t)1<<c);
138141
// process a key per task call
@@ -146,6 +149,8 @@ void keyboard_task(void)
146149

147150
MATRIX_LOOP_END:
148151

152+
hook_keyboard_loop();
153+
149154
#ifdef MOUSEKEY_ENABLE
150155
// mousekey repeat & acceleration
151156
mousekey_task();
@@ -166,12 +171,12 @@ void keyboard_task(void)
166171
// update LED
167172
if (led_status != host_keyboard_leds()) {
168173
led_status = host_keyboard_leds();
169-
keyboard_set_leds(led_status);
174+
if (debug_keyboard) dprintf("LED: %02X\n", led_status);
175+
hook_keyboard_leds_change(led_status);
170176
}
171177
}
172178

173179
void keyboard_set_leds(uint8_t leds)
174180
{
175-
if (debug_keyboard) { debug("keyboard_set_led: "); debug_hex8(leds); debug("\n"); }
176181
led_set(leds);
177182
}

doc/keymap.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ The **layer state** indicates the current on/off status of all layers. It is def
5151
#### 0.1.2 The default layer
5252
The **default layer** is the base keymap layer (0-31) which is always active and considered the "bottom" of the stack. When the firmware boots, the default layer is the only active layer. It is set to layer 0 by default, though this can be changed ~~in *config.h*~~ via Boot Magic settings.
5353

54-
Initial state of Keymap Change base layout
55-
----------------------- ------------------
54+
Initial state of Keymap Change base layout
55+
----------------------- ------------------
5656

5757
31 31
5858
30 30

0 commit comments

Comments
 (0)