I've wired up a really tiny keyboard on a breadboard and am trying to see if I can have 4 layers with only 2 function keys. I'm not sure if I missed it in the documentation somewhere, but is it possible to do something like this?
none -> layer 0 (default)
Fn0 -> layer 1
Fn1 -> layer 2
Fn0 & Fn1 -> layer 3
Thanks.
abjr, yes it is possible.
In fact you can define five layers.
none: layer0
KeyA: layer1
KeyB: layer2
KeyA+B: layer3
KeyB+A: layer4
In tmk layer action is essentially a bit operation of 'layer_state' variable. Each layer has own bit in the variable and it indicates current state of the layer. For example:
Layer Layer bit
---------------------------------
L0 000x (default layer)
L1 001x
L2 01xx
L3 1xxx
0: off, 1: on, x: dont' care
See action_layer.c, action_code.h and action.c in common directory if documentation is not enough.
Apparently key has down and up event but note that these evnents do not necessarily occur in same layer. In particular 'layer switcing' key will have down and up envent on different layers.
You can define your keymap in following four ways at least. Each way has a bit different behavior, so you may want to select and combinate them.
1) you can define like this:
|KeyA |KeyB
Layer |Down Up |Down Up
-------+--------------------+--------------------
L0 |L1_on N/A |L2_on N/A
L1 |N/A L1_off |L3_on N/A
L2 |L4_on N/A |N/A L2_off
L3 |N/A L1_off |N/A L3_off
L4 |N/A L4_off |N/A L2_off
Fn Press Relese Action
---------------------------------------------------------------
FN0 L1_on --- ACTION_LAYER_ON(1, ON_PRESS)
FN1 L2_on --- ACTION_LAYER_ON(2, ON_PRESS)
FN2 L3_on --- ACTION_LAYER_ON(3, ON_PRESS)
FN3 L4_on --- ACTION_LAYER_ON(4, ON_PRESS)
FN4 --- L1_off ACTION_LAYER_OFF(1, ON_RELESE)
FN5 --- L2_off ACTION_LAYER_OFF(2, ON_RELESE)
FN6 --- L3_off ACTION_LAYER_OFF(3, ON_RELESE)
FN7 --- L4_off ACTION_LAYER_OFF(4, ON_RELESE)
Keymap KeyA KeyB
----------------------------
KEYMAP_L0: FN0 FN1
KEYMAP_L1: FN4 FN2
KEYMAP_L2: FN3 FN5
KEYMAP_L3: FN4 FN6
KEYMAP_L4: FN7 FN5
2) Using ACTION_LAYER_ON_OFF you will be able to omit some Fn keys.
Fn Press Relese Action
---------------------------------------------------------------
FN0 L1_on L1_off ACTION_LAYER_ON_OFF(1)
FN1 L2_on L2_off ACTION_LAYER_ON_OFF(2)
FN2 L3_on L3_off ACTION_LAYER_ON_OFF(3)
FN3 L4_on L4_off ACTION_LAYER_ON_OFF(4)
Keymap KeyA KeyB
----------------------------
KEYMAP_L0: FN0 FN1
KEYMAP_L1: FN0 FN2
KEYMAP_L2: FN3 FN1
KEYMAP_L3: FN0 FN2
KEYMAP_L4: FN3 FN1
3) Or using ACTION_LAYER_SET you can define layer transition table instead of bit operation.
|KeyA |KeyB
Layer |Down Up |Down Up
-------+--------------------+--------------------
L0 |to_L1 N/A |to_L2 N/A
L1 |N/A to_L0 |to_L3 N/A
L2 |to_L3 N/A |N/A to_L0
L3 |N/A to_L2 |N/A to_L1
Fn Press Relese Action
---------------------------------------------------------------
FN0 to_L1 ACTION_LAYER_SET(1, ON_PRESS)
FN1 to_L2 ACTION_LAYER_SET(2, ON_PRESS)
FN2 to_L3 ACTION_LAYER_SET(3, ON_PRESS)
FN3 --- to_L0 ACTION_LAYER_SET(0, ON_RELESE)
FN4 --- to_L1 ACTION_LAYER_SET(1, ON_RELESE)
FN5 --- to_L2 ACTION_LAYER_SET(2, ON_RELESE)
Keymap KeyA KeyB
----------------------------
KEYMAP_L0: FN0 FN1
KEYMAP_L1: FN3 FN2
KEYMAP_L2: FN2 FN3
KEYMAP_L3: FN5 FN4
4) Also you can use ACTION_LAYER_SET_CLEAR
|KeyA |KeyB
Layer |Down Up |Down Up
-------+--------------------+--------------------
L0 |to_L1 N/A |to_L2 N/A
L1 |N/A to_L0 |to_L3 N/A
L2 |to_L3 N/A |N/A to_L0
L3 |N/A to_L0 |N/A to_L0
Fn Press Relese Action
---------------------------------------------------------------
FN0 to_L1 to_L0 ACTION_LAYER_SET_CLEAR(1)
FN1 to_L2 to_L0 ACTION_LAYER_SET_CLEAR(2)
FN2 to_L3 to_L0 ACTION_LAYER_SET_CLEAR(3)
Keymap KeyA KeyB
----------------------------
KEYMAP_L0: FN0 FN1
KEYMAP_L1: FN0 FN2
KEYMAP_L2: FN2 FN1
KEYMAP_L3: FN2 FN2
Not tested but it should work.