Vial対応のキーボードを作ろうと思ったら少し躓いたので備忘録です。もともとSTM32F303へのVialをしたことがありその際の話ここに書いています。
簡単だったのでSTM32F103でも同じようにいけるでしょと思ったらこれだけかなり面倒でした。何があったかというと、所定の設定をして、Via対応のキーボードと同じようにビルドしたbinファイルを書いたらUSBからデバイスを全く認識しなくなりました。おそらくハードフォルトとかの類な気はしますが、純正ブートローダーが立ち上がらないのは解せません。
ではどうすればよいのかというと機種ごとに専用のブートローダーをビルドしてそれを事前に書き込んだ上で、そこにVialで作成したbinを書き込む必要があります。
というわけで若干面倒だったので簡単にまとめておきます。
目次
- STM32F103は他のSTのマイコンと少し違う
- SWD経由のフラッシュ操作
- Vial対応Bootloaderのviblをビルドする
- VialでHID Bootloaderを確認する
- Vialプログラムに手を加える
- ファームウェアを書き込んで確認する
- まとめ
STM32F103は他のSTマイコンと少し違う
STM32F103は他のSTM32F303などと違って、純正で入っているブートローダーがUSBのものではなく、SWDかUARTでしか書けない仕様になっています。なので、一度USBで使えるようにUSB用のブートローダー(純正のSWD/UARTブートローダーと区別するために、USBブートローダーと以降表記)を書き込み、そのあとにQMK/VIA対応のプログラムを書くという手順を踏みます。
私はUARTでUSBブートローダーを書き込みそのあとVIAL対応のファームウェアを書いたのですが、USBデバイスとして認識されなくなりました。なので、BOOT0ピンをHIGHにして純正のブートローダーで再度USBブートローダーを書き込もうと思ったのですが、それができなくなっていました。UART経由の削除要求も受け付けなくなっていました。純正ブートローダーを破壊は基本的に不可能なはずなので、何が悪いのかさっぱりわかりません。ひとまずSWD経由では操作できることが分かったので、SWD経由で削除していきます。普段は使っていないのですがST-LINK V2の互換品を握っていてよかったです。
SWD経由でのフラッシュ操作
ST-LINKを普段使わないので何を使おうか悩ましいのですが、比較的GUIで簡単に扱えるSTM32CubeProgrammerを使おうと思います。STのサイトからダウンロードしてインストールします。
インストールできたら、ST-LINKとボードを接続します。SWDIO,SWDCLK,+3.3V,GND,RSTの5本を接続します。これらが接続できたらST-LINKとPCを接続します。
そこまでできたらSTM32CubeProgを起動し低下のような画面まで行きます。

この状態で右上の接続を押して、その上の表示が緑になって接続済みになればOKです。その状態で左のタブの上から二つ目を開くと以下のような画面になるのでその状態でフルチップ消去を押します。

すると書かれたプログラムが全て消されるので再びBootloaderを書き込むことができます。今までは、コマンドラインツールで書き込んでいましたが、ここからも書き込めることを知ったので、今回はこのままBootloaderの書き込みなども行ってみたいと思います。
Vial対応Bootloaderのviblをビルドする
専用のブートローダーをビルドする必要があると最初に書きましたが、それがviblです。数年前に更新が止まっていますが、bootloaderなんて安定すればそれまでなのでそんなものでしょう。とはいえ若干気になることがいくつかありましたが、それはひとまず置いておくとします。
viblをビルドするにあたっては実際には若干Vial側の設定も必要になりますが、ひとまず一気解説しきります。
まずこのブートローダーはベースになっているのがHID Bootloaderというもので、多くの方がViaやQMKで使っていたSTM32Duino Bootloaderとは別物です。簡単に調べてみるとブートローダーのフットプリントが半分の4KBほどになっているようです。あとはその名前の通り、このブートローダはHIDデバイスとして認識されると。なので、FWアップデートなどをする場合はブートローダに入った際にHIDとして認識される状態ですることになります。これがキーボードをアップデートする場合にはちょうど良いという感じですね。STM32Duino Bootloaderは本体をResetする必要があるので、そこらへんは面倒でした。そして今回のように完全にだんまりしたりBootloaderで書き込めなくなる可能性も…まあここはWrite Protectionを書けるとかで対策できるとは思います。
少し脱線しましたたが、HIDデバイスとして認識される都合上、USBデバイスの基本情報を組み込む必要あるため専用ファームウェアが必要という感じです。なので、実際に書き込むVial側のデータがいるということはそこに関連があります。端的に言えばデバイス固有の情報を事前に組み込むということですね。
というわけでビルドしてくのですが、gitで拾ってきて設定してビルドしていきます。
git clone https://github.com/vial-kb/vibl.git
cd vibl
ここで設定していきます。基本的には書いてある通り進めます。ざっくり書くと設定は2か所です。
まずCMkeLists.txtを編集します。
cd vibl
nano bootloader/CMakeLists.txt
一番最後に以下を追記します。サンプルで入っている行は消して大丈夫です。
add_bootloader(any_name)
好きな名前で設定してください。ここの値を後で使います。次にconfig.hを編集します。
nano bootloader/src/config.h
サンプルで書かれている部分があるのでそこを利用しながら書き換えてみます。以下のような部分です。
#elif defined(any_name)
#define VIAL_KEYBOARD_UID {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22}
/* setup for bluepill */
#define BL_COL_BANK GPIOB
#define BL_COL_PIN 8
#define BL_ROW_BANK GPIOB
#define BL_ROW_PIN 5
#else
#error
このようにifdefに埋め込む感じです。名前は先ほどCMakeLists.txtで指定した名前にしておきます。私はそれでなぜか正常にビルドできなかったので、config.hの頭に直接define値を書いて語かましてビルドしました。
また、VIAL_KEYBOAD_UIDはVial側のファームウェアを作成する際に生成するUIDを入れるようにします。入れない場合は全て0xFFで埋めましょう。
また、BL_xxx_xxxxとなっている項目ですが、ここには緊急ファームウェア書き込みで使うピンを指定します。具体的には不正なファームウェアを書き込んでしまった場合にユーザープログラム領域(キーボードのファームウェアの領域)にジャンプしてしまうと二度と書き込みができなくなります。それを防ぐために電源投入時にどのキーが押されていた場合にブートローダにとどまるかを設定するしておく必要があります。この例ではPB8とPB5のマトリクスがクロスする部分で設定がされています。COL2ROWがROW2COLになっている場合は逆に設定してねと書いてあるので、どんなキーボードかによって実際に
あとはビルドですが、READMEに書いてある通りに進めます。
cd bootloader
mkdir build && cd build
cmake ..
make
するとbuildにbinができているはずです。これがbootloaderです。これを書き込んでいきます。接続したらファイルを選んで「プログラミングの開始」選ぶだけです。

これで書き込みができたら右上の切断を選択してキーボードを接続してみます。これでエラーが出なければひとまずBootloaderは正しくかけていることになります。
VialでHID Bootloaderを確認する
実際にVialでHIDブートローダが正しく認識できているかを確認します。ウェブ版はキーボードとして認識されないものが正しく動くかわからないので、ひとまずスタンドアロンで動くものを利用します。フットプリントのサイズてきにWEBHIDを扱っている余裕はなさそうな気がします。
スタンドアロン版のVialを入手して起動します。その状態でキーボードを接続するとBootloaderを選択できるようになっていると思います。Vial Bootloaderが表示されればOK。

Vialプログラムに手を加える
これも若干面倒でした。どうやったらQMK/VIAのプログラムを移植できるのかというのは以前に記事にしたのと公式にも書いてあるのでそちらを読んでください。ここまでやるとひとまずそれっぽいbinファイルが吐き出されるのですが、これを書きこんでも動かないどころか純正ブートローダの挙動もおかしくなるので気を付けてください。
それを防ぐためにVial専用のブートローダーまで作ってきたわけですが、それ用にさらにVialプログラムを変更する必要があります。まず、大前提として最新のQMK/Vialのコードである程度改変してビルドできているということにします。
その状態からさらにいくつか変更を加えます。基本的にVial Bootloaderに書かれている通りなのですが、その通りだとダメなところがあります。まず、BOOTLOADERを変更します。rules.mkを以下のような形に修正します。
MCU = STM32F103
BOOTLOADER = vibl
BOOTLOADERはSTM32DUINOにしていた方が多いかと思いますが、viblに変更します。人によって色々階層があると思いますが、基本的にはkeymasと同じ階層に書いておくとよいでしょう。比較的上位の層を変える必要があるので、STM32F103でVial対応する場合はVial専用のフォルダを作成して管理するのが良さそうです。
viblの方を見るとvial.jsonに何か追記すると書いてあるのですが、これは罠です。これを書くとコンパイルできません。開発当初は必要だったようですが、今はjsonの方は触らないで大丈夫です。
viblにはこれでビルドと書いてあるのですが、これでビルドすると場合によってはこのようなエラーが出ます。
lib/chibios/os/hal/ports/STM32/LLD/SYSTICKv1/hal_st_lld.c:79:2: error: #error "TIM2 is not a 32bits timer"
79 | #error "TIM2 is not a 32bits timer"
| ^~~~~
[ERRORS]
|
|
|
make[1]: *** [builddefs/common_rules.mk:365: .build/obj_th25tk_rev1_f103_vial/lib/chibios/os/hal/ports/STM32/LLD/SYSTICKv1/hal_st_lld.o] Error 1
Make finished with errors
make: *** [Makefile:428: th25tk/rev1/f103:vial] Error 1
TIM2n is not a 32bit timerという謎のエラーです。自分の使っているキーボードの設定を眺めてもTIM2は使っていないように見えるのでどこで引っかかっているのかわかりません。ここで、調べてみるとQMKでは以下のような記述をする必要があるとのこと。
#define CH_CFG_ST_TIMEDELTA 0
とりあえずdefineだしHALで起きているっぽいのでhalconf.hに書いたところredefinedと怒られました。おそらくここではだめなのでしょう。少し気になっているのが、QMKや普通にviblに設定しない分にはVialでもビルドできるのに、viblに設定した段階でのみできなくなる点です。なので、おそらくここはVial側のコードに依存していることがわかりますね。どこに記述したらよいのか調べていると、サンプルコードではchconf.hというファイルに記述しているようです。私のベースのキーボードにそのファイルがなかったので新規に作成して中身をコピペします。
#pragma once
#define CH_CFG_ST_TIMEDELTA 0
#include_next <chconf.h>
これで再度ビルドするとビルドが成功しました。ビルドに成功するとbinではなく専用の.vfwというファイルが生成されます。これがキーボードのファームウェア本体です。
ファームウェアを書き込んで確認する
先ほど専用ブートローダが書き込めているかを確認したと思いますが、その下部分でファームウェア(.vfw)を選択して書き込めるので書き込んでみましょう。
書き込み終わったらキーボード挿し直して再接続します。

ちゃんとキーマップが表示されればOKです。あとは色々キーマップとかいじってみて設定を保存できるか確認ですね。もちろんSecurityuのところからUnlockも忘れずに。
あとは緊急書き込みモードにできることを確認しましょう。一度キーボードをPCから外します。ブートローダを作成する段階で、緊急書き込みモード用に設定したキーを押しながらキーボードをPCに接続してください。このとき、キーボードの画面が表示されず、Vial Bootloaderの方が表示されれば緊急書き込みモードも正しく動作していることを確認できます。
まとめ
STM32F103で対応するのは調べるのも含めて若干面倒でした。といっても私が一から調べたため時間がかかっただけで、ちゃんと知っていればそんなに時間のかからない話です。
ただ、Vial側のビルドもよくわからないところで引っかかったのは予想外でした。しかも変更を加える箇所も間違えると動かないのも難しいところでした。
ひとまず、ちゃんと専用ブートローダを作成すればSTM32F103でも問題なくVial対応できるということも分かったの満足です。
ちなみにFWの容量が53KB、HIDブートローダが4KBのフットプリントプリントなので一応5KBぐらいは余裕がある感じです。色々機能を入れているのでRGBライトを切ったりだとか色々工夫すればさらに容量は圧縮できるのでSTM32F103C8T6でもレイヤーを増やしたり色々できるマイコンで比較的安価という立ち位置は変わらなそうです。
以上です。お読みいただきありがとうございました。