メカニカルキーボードK66のためにQMKをビルドする

これは何?

カニカルキーボードK66を手に入れて、レビューしましたが、ただ普通のキーボードとして使うだけでは面白くない・・

inajob.github.io

ということで自作キーボードでよく使われるキーボード用のファームウェアであるQMKをK66でも利用する方法があるようなので、挑戦してみることにしました。

 

あらかじめ断っておきますが、このページの手順を真似てキーボードが文鎮化してしまったとしても、私は一切責任を負いませんので、試してみる方は自己責任でお願いします。後述しますが、同じK66でもこの手法が使えないものも存在するようです。

 

情報源

Wormier Docs - Wormier Docs

このURLにアクセスするとK66で利用できるQMKのビルド方法などが紹介されています。現在もアクティブに活動しているので、以降の記事の内容は古くなっている可能性があります。最新の情報は上記のURLなので、実際にK66用にQMKをビルドしようとしている方は、上記URLを参考にするとよいと思います。

 

QMKをそのまま利用できないのか?

QMKの本系は特定のプロセッサ向けに作られており、AVR(ATMega32u4)やARM(STM32系)などメジャーなマイコンの場合は本家のQMKそのまま利用できることがほとんどです。

また、自作キーボードの場合は自分で利用するCPUを選ぶので、QMKの対応しているCPUを選ぶでしょう。

しかし今回は既製品であるK66です。このキーボードに搭載されているのはARM Crotex-m0のIC 「VS11K15A」です。

f:id:inajob:20210616220742p:plain

全く聞いたことがないICですが、これはeVisionという会社の物らしく、さらに調べるとSonixという会社のSN32系のICと互換性があるようです(全く同じでマーキングが違うのか、互換性のある別物なのかは自分はよくわかってないです。)

 

ということでSN32系のIC用にQMKを移植する必要があります。

先人の歩み

はっきり言ってこの作業、自分にはお手上げです。普段はArduinoでぬるま湯開発しているので、ARMの、しかも聞いたこともないメーカーのICなんて何から手を付けて良いかわかりません。

 

しかし、今回は先人がいます。はじめに紹介したURLの内容の通りに進めれば、K66用のQMKがビルドできるという事なので、その手順に従って作業していくことにしました。

ICの書き換えはどうやるの?

一般的にはこのような組み込み用のマイコンファームウェアを読み出したり、書き込んだりするためには、ICSPとかJTAGとか、そういう書き込み用の端子に専用の書き込み器を接続することが多いです。K66の場合もどうやらJTAGが利用できるようですが、先人はもっと簡単な方法を発見していました。

 

HIDデバイスとして認識されているキーボードに特定のシーケンスでアクセスすることで、書き込みモードに切り替えるという技により、専用の書き込み機などを使わずにファームウェアの書き換えを実現しています。

womier-flasher/main.py at master · wormier-docs/womier-flasher · GitHub (この行ですね)

この機能はオリジナルのK66のファームウェアに実装されているのだと思います。(確証は無いです・・)

Jumploader

さて、ICの書き換え方法がわかりました。それっぽいファームウェアを作って、早速書き換えてみたいのですが、下手なファームウェアを書き込むと速攻でキーボードが「文鎮化」してしまいます。

文鎮化しても、何度も書き換えて試せばよいじゃない?と思われるかもしれませんが、前述した書き込みモードへの切り替え機能自体を壊してしまうと、もう簡単に書き換えることが出来なくなってしまいます。

(おそらくJTAGなどを使えば、この状態からでも書き込みできるとは思いますが、はんだ付けや専用の器具が必要となります。)

ということで、役立つのがJumploaderです。マイコンのブート時に実行される先頭部分にこのJumploaderを書き込みます。このJumploaderはキーボード用に最適化されており、通常起動時は何もせず素通りし特定の番地のプログラムへジャンプします。

しかし、マイコン起動時にBackSpaceを押しっぱなしにしておくことで、書き込み待機状態になります。

 

このJumpLoaderさえうまく書き込んでしまえば、変なファームウェアを書き込んでしまっても、BackSpaceを押しっぱなしにしてUSBケーブルを抜き挿しすることで、書き込みできる状態に出来ます。

 

ソースコードはこれっぽいです。 GitHub - xyzz/sn32f260-keyboard-bootloader

f:id:inajob:20210627215011p:plain

WomierFlasher

さて、ここまでの流れをワンタッチで実行することが出来るソフトウェアが公開されています。それがWomierFlasherです。

「オリジナルファームウェアを書き込み待機状態に切り替える」「Jumploaderを書き込む」「オリジナルのファームウェアを書き戻す」「QMKのバイナリを書き込む」

といった作業がGUIでポチポチで実行できます。

f:id:inajob:20210627215035p:plain

QMKのビルド

さて、ここまでわかれば後はK66用のQMKをビルドするだけです。といいつつ、ここで無茶苦茶ハマってしまいました。

どうも、ARM用GCCのバージョン依存によるもののようで、誤ったバージョンだと、ビルドが失敗したり、ビルドはうまくいくが、完成したファームウェア何かおかしいというようなことが起きました。

 

何かおかしいというのは、症状はいろいろあるのですが、、「初めに押したキーが押しっぱなしになってしまう」「LEDのアニメーションが停止し、キーボードとしても無反応となる」などです。

 

さて、どうやったら正しいファームウェアが作れるのか・・いろいろな組み合わせを試してみました。

SN32用のQMKの系譜

smp4488/qmk_firmware

https://github.com/smp4488/qmk_firmware/tree/womier-k66-rgb-support/keyboards/womier/k66

これがQMKからforkされたSN32用のQMKです。

 

SonixQMK/qmk_firmware

https://github.com/SonixQMK/qmk_firmware

さらにこれ、名前的にはこれがSonixのIC用のQMKのリポジトリのように見えます。(しかしここにはK66のサポートはありません。)

 

toastdb/qmk_firmware

https://github.com/toastdb/qmk_firmware/tree/womier_k66

そしてこれです。このtoastdb/qmk_firmwareがいま一番アクティブに開発されているリポジトリのように見えます。

 

また、このキーボードに搭載されているサイドLEDはまだ制御できないようで、絶賛開発中のようです。(もしかしたらサイドLEDが動くブランチがあるかもしれません)

ビルドできた組み合わせ

前述のQMKのリポジトリの中で自分がうまくビルドできたのは1つ目のsmp4488/qmk_firmwareと3つ目のtoastdb/qmk_firmwareでした。

 

ビルド環境の再現性を保つためにDockerで環境を整備することにしました。QMKのインストーラがインストールするARM用のGCCが期待したバージョンとは違うため、別途ダウンロードした古いバージョンのARM用GCCをインストールする必要がありました。

 

細かい手順はgistにまとめました。

gist.github.com

K66のDiscordにはtoastdb/qmk_firmwareの作者の方がいて、どうもこの手順のGCCとは違うバージョンのようなのですが、自分の場合はこの手順でないと何か動作のおかしいファームウェアが生成されてしまいました。

 

ただ、ごくまれにキーボードが固まってしまう現象が発生することを確認しています。K66のDiscordでは、このような問題を話題にしている人がいないことから、なにかこの手順に問題があるような気がしていますが、まだ原因不明です。

何かわかればこのページを更新しようと思います。

QMKで遊ぶ

ここまでくればQMKを使った自作キーボードと同じようにキーをカスタマイズすることが出来ます。

自分はFn+Spaceを「かな」、Fn+右Altを「英数」に割り当てて、簡単に日本語入力の切り替えができるようにしてみました。結構便利です。

この手順を試す際の罠

Discordでいろいろな方の話を見ていると、同じK66でも搭載されているICが違うものがあるようです。この場合はこの記事の手順は利用できません。

(特に私が紹介しているBanggoodにおいても、同じICのものが届くとは限らないと思います。K66を購入した方は、ぜひ私にどのICが搭載されていたか教えてください。)

まとめ

カニカルキーボードが触ってみたくて買ったK66ですが、思わぬHackが楽しめました。調べていく中で、JumploaderSN32用の移植K66専用の対応、、と様々な人たちの功績の積み重ねがあることを知りました。

ARM系のマイコンを深く触ったことがなかったのですが、まだまだ勉強が必要だなと思いました。ちょっとソースコードを見たところChibiOSというRTOSを使ってマイコン間の差異を吸収しているようでした。ChibiOS・・ 学ぶことは多そうです・・