QMK で slave 側でも process_record() を発火する
左右分離型キーボードでは、キー押下イベントのハンドリングに使う process_record() 及びそこから派生する process_record_user() 等の関数は、通常は master 側でしか実行されない。
通常はそれで問題ないが、slave 側でも OLED にキーイベントに関連した表示を行いたい場合に困った。ググっても良い情報は得られなかったので、ソースを追って調べてみた。
先に結論
-
SPLIT_TRANSPORT_MIRRORを定義 -
should_process_keypress()を override してtrueを返す
#define SPLIT_TRANSPORT_MIRROR
bool should_process_keypress(void) { return true; }
should_process_keypress()
process_record() を追うと、tmk_core/common/keyboard.c の keyboard_task() で発火しており、その条件として should_process_keypress() が使われていた。
またこの関数が override 可能であり、コメントを読むと今回の用途どんぴしゃだった。
/** \brief should_process_keypress
*
* Override this function if you have a condition where keypresses processing should change:
* - splits where the slave side needs to process for rgb/oled functionality
*/
__attribute__((weak)) bool should_process_keypress(void) { return is_keyboard_master();
デフォルトでは上記のように master でだけで true を返しているので、常に true を返してあげれば今回の目的の挙動になるはず。
SPLIT_TRANSPORT_MIRROR
加えて、こちらも定義する必要があった。
matrix scan されたキーの押下状態は、通常は slave から master の方向にのみ TRRS ケーブルを介して送信される。slave 側で両手分のイベントを把握するためには逆方向の情報伝達が必要で、それを実現するのがこのオプション。
ドキュメントによると matrix scan のパフォーマンスに多少影響が出るようなことが書いてあったが、やってみた感じ特に体感では影響は出ていない。まあそんなにタイピング速くないので。
うまく行かないところ
この二つでほとんどうまく動いたが、slave 側で read_layer_state() の結果がおかしいという現象が見られた。本来のレイヤーキーを押しても反映されず、別のキーに反応してしまう。
が、今回の個人的な目的は達したので深追いせずここで終了。
Discussion
記事と関係ないことですが、すみません。
新しい入力方法を私も模索しておりまして、今回、マウスアナログ入力のテキストコピーソフトを作成したので、ぜひ使ってほしいと思い、ここに書いてます。もちろん無料です。https://zenn.dev/kemii/articles/7d6d9331cbaa0d
ドンピシャの記事で大変助かりました!
ある程度時間がたった時にIdle状態で節電したかったのですが、Slave側に連絡がいかなくて困っていました。おかげさまで5+5で10mA節電できました。