Skip to content

Commit fb3a323

Browse files
committed
Merge branch 'master' into newapi
2 parents 01e33ea + d5c5ac6 commit fb3a323

File tree

9 files changed

+185
-65
lines changed

9 files changed

+185
-65
lines changed

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/keymap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ static action_t keycode_to_action(uint8_t keycode)
142142
case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE:
143143
action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode));
144144
break;
145-
case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
145+
case KC_AUDIO_MUTE ... KC_WWW_FAVORITES:
146146
action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode));
147147
break;
148148
case KC_MS_UP ... KC_MS_ACCEL2:

doc/keymap.md

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ Keymap framework - how to define your keymap
33
***NOTE: This is not final version, may be inconsistent with source code and changed occasionally for a while.***
44

55
## 0. Keymap and layers
6-
**Keymap** is comprised of multiple layers of key layout, you can define **32 layers** at most.
7-
**Layer** is an array of **keycodes** to define **actions** for each physical keys.
8-
respective layers can be validated simultaneously. Layers are indexed with 0 to 31 and higher layer has precedence.
6+
The **keymap** is an array composed of one or more layers.
7+
Each **layer** is an array of **keycodes**, defining **actions** for each physical key.
8+
Layers can be activated and deactivated independently. Multiple layers may be active at once, resulting in the currently-active **layer state**. Each layer has an index between 0-31. As active layers are stacked together, higher layers take precedence over lower layers.
99

1010
Keymap: 32 Layers Layer: Keycode matrix
1111
----------------- ---------------------
@@ -21,31 +21,17 @@ respective layers can be validated simultaneously. Layers are indexed with 0 to
2121
1 /___________// | 1 `--------------------------
2222
0 /___________/ V low 0 `--------------------------
2323

24+
**Note:** The keymap array is limited to **32 layers**.
2425

2526

26-
### 0.1 Keymap status
27-
Keymap has its state in two parameters:
28-
**`default_layer`** indicates a base keymap layer(0-31) which is always valid and to be referred, **`keymap_stat`** is 16bit variable which has current on/off status of layers on its each bit.
2927

30-
Keymap layer '0' is usually `default_layer` and which is the only valid layer and other layers is initially off after boot up firmware, though, you can configured them in `config.h`.
31-
To change `default_layer` will be useful when you switch key layout completely, say you want Colmak instead of Qwerty.
28+
### 0.1 Layer state
29+
The current keymap layer state is determined by two parameters: the *default layer*, and the individual *layer states*. Changing the default layer is useful for switching key layouts completely; for example, switching to Dvorak, Colemak or Workman instead of QWERTY. Individual layer states, on the other hand, can be used to overlay the base layer with other functions such as navigation keys, function keys (F1-F12), media keys or other actions.
3230

33-
Initial state of Keymap Change base layout
34-
----------------------- ------------------
31+
Because the default layer is really just a special case affecting the overall layer state, it is important to first understand how the layer state is determined.
3532

36-
31 31
37-
30 30
38-
29 29
39-
: :
40-
: : ____________
41-
2 ____________ 2 / /
42-
1 / / ,->1 /___________/
43-
,->0 /___________/ | 0
44-
| |
45-
`--- default_layer = 0 `--- default_layer = 1
46-
layer_state = 0x00000001 layer_state = 0x00000002
47-
48-
On the other hand, you shall change `layer_state` to overlay base layer with some layers for feature such as navigation keys, function key(F1-F12), media keys or special actions.
33+
#### 0.1.1 The layer state
34+
The **layer state** indicates the current on/off status of all layers. It is defined in the firmware by a 32-bit integer, `layer_state`, which stores each layer's on/off status in a single bit: 0 for off, 1 for on. As layers are activated and deactivated, their respective bits are flipped, changing the value of `layer_state`.
4935

5036
Overlay feature layer
5137
--------------------- bit|status
@@ -62,28 +48,64 @@ On the other hand, you shall change `layer_state` to overlay base layer with som
6248
`--- default_layer = 1 |
6349
layer_state = 0x60000002 <-'
6450

51+
#### 0.1.2 The default layer
52+
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.
53+
54+
Initial state of Keymap Change base layout
55+
----------------------- ------------------
56+
57+
31 31
58+
30 30
59+
29 29
60+
: :
61+
: : ____________
62+
2 ____________ 2 / /
63+
1 / / ,->1 /___________/
64+
,->0 /___________/ | 0
65+
| |
66+
`--- default_layer = 0 `--- default_layer = 1
67+
layer_state = 0x00000001 layer_state = 0x00000002
68+
69+
Note that the `default_layer_state` variable only determines the lowest value to which `layer_state` may be set, and that `default_layer_state` is used by the core firmware when determining the starting value of `layer_state` before applying changes. In other words, the default layer will *always* be set to *on* in `layer_state`.
70+
71+
The default layer is defined in the firmware by the `default_layer_state` variable, which is identical in format to the `layer_state` variable exlpained above. The value may be changed using the following functions:
72+
73+
- `default_layer_state_set(state)` sets the state to the specified 32-bit integer value.
74+
- AND/OR/XOR functions set the state based on a boolean logic comparison between the current state and the specified 32-bit integer value:
75+
- `default_layer_state_and(state)`
76+
- `default_layer_state_or(state)`
77+
- `default_layer_state_xor(state)`
78+
79+
For example, to set layer 3 as the default layer:
80+
81+
```C
82+
// convert 3 to a 32-bit unsigned long value, and set the default layer
83+
default_layer_state_set(1UL<<3);
84+
```
85+
6586
6687
6788
### 0.2 Layer Precedence and Transparency
68-
Note that ***higher layer has higher priority on stack of layers***, namely firmware falls down from top layer to bottom to look up keycode. Once it spots keycode other than **`KC_TRNS`**(transparent) on a layer it stops searching and lower layers aren't referred.
89+
Note that ***higher layers have priority in the layer stack***. The firmware starts at the topmost active layer, and works down to the bottom to find the an active keycode. Once the search encounters any keycode other than **`KC_TRNS`** (transparent) on an active layer, the search is halted and the remaining lower layers aren't examined, even if they are active.
90+
91+
**Note:** a layer must be activated before it may be included in the stack search.
92+
93+
`KC_TRNS` is a special placeholder which can be used on overlay layers. This allows for the creation of "partial" layers which fall back on the lower layers, eliminating a good deal of repetition in keymap files.
6994
70-
You can place `KC_TRNS` on overlay layer changes just part of layout to fall back on lower or base layer.
71-
Key with `KC_TRANS` doesn't has its own keycode and refers to lower valid layers for keycode, instead.
72-
See example below.
7395
7496
7597
### 0.3 Keymap Example
76-
Keymap is **`keymaps[]`** C array in fact and you can define layers in it with **`KEYMAP()`** C macro and keycodes. To use complex actions you need to define `Fn` keycode in **`fn_actions[]`** array.
98+
The keymap is defined in the **`keymaps[]`** array, a 2-dimensional array of rows and columns corresponding to positions in the keyboard matrix. But most often the layers are defined using C macros to allow for easier reading and editing of the keymap files. To use complex actions you need to define `Fn` keycodes in the **`fn_actions[]`** array.
7799
78-
This is a keymap example for [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard.
79-
This example has three layers, 'Qwerty' as base layer, 'Cursor' and 'Mousekey'.
100+
This is a keymap example for the [HHKB](http://en.wikipedia.org/wiki/Happy_Hacking_Keyboard) keyboard.
101+
This example has three layers: the QWERTY base layer, and two overlay layers for cursor and mousekey control, respectively.
80102
In this example,
81103
82-
`Fn0` is a **momentary layer switching** key, you can use keys on Cursor layer while holding the key.
104+
`Fn0` is a **momentary layer switching** key--you can use keys on the Cursor layer while holding the key.
83105
84-
`Fn1` is a momentary layer switching key with tapping feature, you can get semicolon **';'** with taping the key and switch layers while holding the key. The word **'tap'** or **'tapping'** mean to press and release a key quickly.
106+
`Fn1` is a momentary layer switching key with tapping function--tapping the key as one would normally use it, sends the semicolon **';'** keycode, while holding the key down switches layers.
85107
86-
`Fn2` is a **toggle layer switch** key, you can stay switched layer after releasing the key unlike momentary switching.
108+
`Fn2` is a **toggle layer switch** key--pressing the key toggles the layer on until you press it again.
87109
88110
You can find other keymap definitions in file `keymap.c` located on project directories.
89111

protocol/chibios/README.md

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
## TMK running on top of ChibiOS
22

3+
This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever [ChibiOS] supports. The notable examples are ARM-based Teensies (3.x and LC) and on the boards with STM32 MCUs.
4+
5+
### Usage
6+
7+
- To use, unpack or symlink [ChibiOS] to `tmk_core/tool/chibios/chibios`. For Kinetis support (this means Teensies, Infinity keyboard, WhiteFox keyboard), you'll need a fork which implements the USB driver, e.g. [this one](https://github.com/flabbergast/ChibiOS/tree/kinetis).
8+
- You will also need to install an ARM toolchain, for instance from [here](https://launchpad.net/gcc-arm-embedded). On linux, this is usually also present as a package for your distribution (as `gcc-arm` or something similar). On OS X, you can use [homebrew](http://brew.sh/) with an appropriate tap.
9+
310
### Notes
411

5-
- To use, unpack or symlink [ChibiOS] {currently 3.0.2} to `tmk_core/tool/chibios/chibios`. For Kinetis support, you'll need a fork which implements the USB driver, e.g. [this one](https://github.com/flabbergast/ChibiOS/tree/kinetis).
12+
- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for ARM Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md).
613
- For gcc options, inspect `tmk_core/tool/chibios/chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of warnings on that.
714
Also pay attention to `-O0` (enabled for debugging); for deployment use `-O2`.
815
- USB string descriptors are messy. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck.
9-
- There are some random constants left so far, e.g. 5ms sleep between calling `keyboard_task`, or 1.5sec wait for USB init, in `main.c`. There should be no such in `usb_main.c` (the main USB stack). Everything is based on timers/interrupts/kernel scheduling (well except `keyboard_task`), so no periodically called things (again, except `keyboard_task`, which is just how TMK is designed).
1016
- It is easy to add some code for testing (e.g. blink LED, do stuff on button press, etc...) - just create another thread in `main.c`, it will run independently of the keyboard business.
11-
- Jumping to (the built-in) bootloaders on STM32 works, but it is not entirely pleasant, since it is very much MCU dependent. So, one needs to dig out the right address to jump to, and either pass it to the compiler in the `Makefile`, or better, define it in `<your_kb>/bootloader_defs.h`. Also, a patch to upstream ChibiOS is needed (supplied), because it `ResetHandler` needs adjusting.
12-
- Sleep LED works, but at the moment only on/off, i.e. no breathing.
17+
- Jumping to (the built-in) bootloaders on STM32 works, but it is not entirely pleasant, since it is very much MCU dependent. So, one needs to dig out the right address to jump to, and either pass it to the compiler in the `Makefile`, or better, define it in `<your_kb>/bootloader_defs.h`. An additional startup code is also needed; the best way to deal with this is to define custom board files. (Example forthcoming.)
18+
19+
### Experimental pre-ChibiOS 4 support
20+
- As an alternative to the mentioned flabbergast branch above, you can use the [master branch of ChibiOS](https://github.com/ChibiOS/ChibiOS).
21+
- Note that the Kinetis support has moved to the [ChibiOS-Contrib repository](https://github.com/ChibiOS/ChibiOS-Contrib), so you need to put that into your repository in the same way as you did for the main ChibiOS repository.
22+
- You also need to define CHIBIOS_CONTRIB in your makefile and point it to the right directory.
23+
- You need to add some new options to chconf.h, or you will get compiler errors. Just copy the new options from samples provided by the ChibiOS-Contrib repository.
1324

1425
### Immediate todo
1526

16-
- host-wakeup packet sending during suspend
17-
- power saving for suspend?
18-
- PWM for sleep led
27+
- power saving for suspend
1928

2029
### Not tested, but possibly working
2130

@@ -27,14 +36,14 @@ Also pay attention to `-O0` (enabled for debugging); for deployment use `-O2`.
2736

2837
### Tried with
2938

30-
- ChibiOS 3.0.1, 3.0.2 and ST F072RB DISCOVERY board.
31-
- Need to test on other STM32 chips (F3, F4) to make it as much chip-independent as possible.
32-
- ChibiOS with Kinetis patches and Teensy LC and 3.0.
39+
- Infinity, WhiteFox keyboards
40+
- all ARM-based Teensies
41+
- some STM32-based boards (e.g. ST-F072RB-DISCOVERY board, STM32F042 breakout board, Maple Mini (STM32F103-based))
3342

34-
## ChibiOS-supported MCUs (as of 3.0.2)
43+
## ChibiOS-supported MCUs
3544

3645
- Pretty much all STM32 chips.
37-
- There is some support for K20x and KL2x Freescale chips (i.e. Teensy 3.x/LC, mchck, FRDM-KL2{5,6}Z, FRDM-K20D50M), but again, no official USB stack yet. However the `kinetis` branch of [my ChibiOS fork](https://github.com/flabbergast/ChibiOS). With this fork, TMK work normally on all the ARM Teensies.
46+
- There is some support for K20x and KL2x Freescale chips (i.e. Teensy 3.x/LC, mchck, FRDM-KL2{5,6}Z, FRDM-K20D50M), but again, no official USB stack yet. However the `kinetis` branch of [flabbergast's ChibiOS fork](https://github.com/flabbergast/ChibiOS). With this fork, TMK work normally on all the ARM Teensies.
3847
- There is also support for AVR8, but the USB stack is not implemented for them yet, and also the kernel itself takes about 1k of RAM. I think people managed to get ChibiOS running on atmega32[8p/u4] though.
3948
- I've seen community support for Nordic NRF51822 (the chip in Adafruit's Bluefruit bluetooth-low-energy boards), but not sure about the extent.
4049

@@ -43,7 +52,6 @@ Also pay attention to `-O0` (enabled for debugging); for deployment use `-O2`.
4352
- STM32F0x2 chips can do crystal-less USB, but they still need a 3.3V voltage regulator.
4453
- The BOOT0 pin should be tied to GND.
4554
- For a hardware way of accessing the in-built DFU bootloader, in addition to the reset button, put another button between the BOOT0 pin and 3V3.
46-
- For breathing the caps lock LED during the suspended state ("sleep LED"), it is desirable to have that LED on a hardware PWM pin (there's usually plenty of those, look for TIMERs in the datasheet). However this is not strictly necessary, because instead of direct output of a timer to a pin (better of course), it is easy to define timer callbacks in ChibiOS that turn on/off an arbitrary pin.
4755

4856

4957

protocol/vusb.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SRC += $(VUSB_DIR)/main.c \
1010

1111

1212
ifdef NO_UART
13+
OPT_DEFS += -DNO_UART
1314
SRC += $(COMMON_DIR)/sendchar_null.c
1415
else
1516
SRC += $(COMMON_DIR)/sendchar_uart.c \

protocol/vusb/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ int main(void)
4949
#endif
5050

5151
CLKPR = 0x80, CLKPR = 0;
52-
#ifndef PS2_USE_USART
52+
#ifndef NO_UART
5353
uart_init(UART_BAUD_RATE);
5454
#endif
5555

0 commit comments

Comments
 (0)