BLE Micro Pro で Corne を BLE 化 ~カスタムキーコードを添えて~

BLE Micro Pro を使って、 Corne を BLE 化した手順の備忘録です。
誰かの参考になれば幸いです。

# BLE Micro Pro とは

BLE Micro Pro は、 [sekigon][sekigon_prof] 氏が作成した、 Pro Micro 互換の BLE に対応したマイコンボードです。
これを Pro Micro の代わりにキーボードに載せることで、パソコンへの Bluetooth 接続や、左右分離型キーボードの左右の通信さえ無線化できます。
[遊舎工房][bmp_yusha]さんや [BOOTH][bmp_booth] で購入できます。一緒に[電池基盤][bmp_battery_yusha]（BOOTH は[こちら][bmp_battery_booth]）も購入すると捗るでしょう。（ステマ）

最近、[標準ファームウェアの Beta 版][bmp_default_firm]がリリースされ、より使いやすくなってきました。

ではさっそく、 Corne に BLE Micro Pro を搭載して、 BLE 化していきましょう。

# BLE Micro Pro の準備

## 環境構築

**私は Windows 環境のため、以降そちらを前提として進めます。**

### QMK Firmware 環境構築

BLE Micro Pro のファームウェアは [QMK Firmware][qmk_git] からフォークされた、専用のものを使用します。
そのため、まずは QMK Firmware の環境構築を行います。

特別変わった手順はありませんので、[公式ドキュメント][qmk_getting_started]通りに進めてください。

なお、 QMK Firmware 自体は WSL でもビルド、書き込みはできますが、 BLE Micro Pro では現状 WSL での書き込みに対応していないので、手順通りにおとなしく MSYS2 をインストールしましょう。

### BLE Micro Pro 環境構築

こちらも sekigon 氏がドキュメントを作成していますので、その手順通りに進めてください。

https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/master/AboutDefaultFirmware/doc/build_bmp_qmk_firmware.md

### BLE Micro Pro へブートローダの書き込み

**既に最新のファームウェアが書き込まれている場合はスキップしてください。**

最新のブートローダを書き込んで、 BLE Micro Pro を標準ファームウェアに対応させます。
こちらも、 sekigon 氏のドキュメントに沿って実行してください。

https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/master/AboutDefaultFirmware/doc/getting_start.md

# BLE Micro Pro 用のファームウェアの作成

手順通りに環境構築すると、 `qmk_firmware` と `qmk_firmware_bmp` の2つのディレクトリができていると思います。
**以下は `qmk_firmware_bmp` ディレクトリ内で実行してください。**

## 新しいキーボードプロジェクトの作成

こちらの手順に従って新しいキーボードを作成します。
普通であればキーマップを追加するのだけですが、 BLE Micro Pro 用に `rules.mk` などをいろいろ書き換えたり面倒なので、新しく作ってしまったほうが楽だと思います。

Corne が対象なので、私はキーボード名を雑に `crkbd_bmp` などとしました。

https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/master/AboutDefaultFirmware/doc/define_new_keyboard.md

そうしたら、出来上がった `crkbd_bmp.h` に [Corne のファームウェア][crkbd]の `rev1.h` の内容をコピペしてしまいましょう。

## マスタ/スレーブ用のキーマップの準備

BLE Micro Pro では、分離型の場合、それぞれにマスタ/スレーブ用のファームウェアを書き込む必要があります。
`keymaps\default` ディレクトリがあると思うので、ディレクトリごと複製してマスタ/スレーブのキーマップを作ってしまいましょう。

複製したら、マスタ用キーマップの `config.h` に以下を追加しましょう。

```cpp
#define IS_LEFT_HAND true
#define BMP_DEFAULT_MODE SPLIT_MASTER
```

スレーブ用キーマップの `config.h` には以下を追加します。

```cpp
#define IS_LEFT_HAND false
#define BMP_DEFAULT_MODE SPLIT_SLAVE
```

Corne は左手がマスタとなるように設計されているので上記のような設定をしていますが、他のキーボードについてはそれぞれに合わせて書き換えてください。

## キーマップのカスタマイズ

では、実際にキーマップをカスタマイズしていきましょう。
といっても、ブートローダ書き込みのドキュメントにあるように、 既に定義されているキーコードのみを使用するのであれば、標準ファームウェアを書き込んだ際に BLE Micro Pro 内に生成された `KEYMAP.JSN` を編集すれば事足ります。

今回は、定義されていないオレオレキーコードを実装していきます。

### keymap.c の編集

`keymap.c` はマスタ/スレーブで同じものを使えるので、片方編集したら、もう片方にコピペで問題ありません。
まずは、例によって `crkbd\keymaps\default\keymap.c` の中身をコピペしてきましょう。

#### custom_keycodes の設定

いつも通り `keymaps` 配列に登録するためのカスタムキーコードを定義します。

```cpp
#include "bmp.h"
#include "bmp_custom_keycode.h"

enum custom_keycodes {
    CUSTOM_KEY_CODE_A = BMP_SAFE_RANGE,
    CUSTOM_KEY_CODE_B,
    CUSTOM_KEY_CODE_C
};
```

ここで重要なのは、**最初のカスタムキーコードに `BMP_SAFE_RANGE` を設定している**ことです。
普通の QMK Firmware であれば、 `SAFE_RANGE` を設定しますが、 BLE Micro Pro では既にいくつかのカスタムキーコードが定義されており、そこで `SAFE_RANGE` が使用されています。なので、代わりに `BMP_SAFE_RANGE` が定義されており、それを使用します。
`SAFE_RANGE` を使用してしまうとキーコードが書き換わり、意図しない挙動になるおそれがあります。

#### custom_keys_user の設定

これは公式の QMK Firmware には存在しない、 BLE Micro Pro 独自の設定です。
これを設定することで内部の辞書にキーコード文字列が登録され、 `KEYMAP.JSN` にカスタムキーコード文字列を直接設定しても認識してくれるようになります。

```cpp
#include "bmp.h"
#include "keycode_str_converter.h"

const key_string_map_t custom_keys_user = {
    .start_kc = CUSTOM_KEY_CODE_A,                                             // 割り当てを開始するキーコード
    .end_kc = CUSTOM_KEY_CODE_C,                                               // 最後に割り当てをするキーコード
    .key_strings = "CUSTOM_KEY_CODE_A\0CUSTOM_KEY_CODE_B\0CUSTOM_KEY_CODE_C\0" // それぞれのキーコードに割り当てる文字列
};
```

`\0` を区切り文字として、それぞれのキーコードに割り当てる文字列を順番に羅列します。今回は `CUSTOM_KEY_CODE_A ~ C` まで定義しているので、計3つ分登録しています。

また、以下のように書くこともできます。
カスタムキーコードを大量に定義しており、横に長くなりすぎてしまうときなどに有用です。

```cpp
#include "bmp.h"
#include "keycode_str_converter.h"

const key_string_map_t custom_keys_user = {
    .start_kc = CUSTOM_KEY_CODE_A,
    .end_kc = CUSTOM_KEY_CODE_C,
    .key_strings = "CUSTOM_KEY_CODE_A\0" // 末尾に "," などは不要
    "CUSTOM_KEY_CODE_B\0"
    "CUSTOM_KEY_CODE_C\0"
};
```

なお、 `.key_strings` に羅列する文字列の順番を間違うと文字列と実際のキーコードの対応がおかしくなるので気を付けてください。

```cpp
#include "bmp.h"
#include "keycode_str_converter.h"

const key_string_map_t custom_keys_user = {
    .start_kc = CUSTOM_KEY_CODE_A,
    .end_kc = CUSTOM_KEY_CODE_C,
    .key_strings = "CUSTOM_KEY_CODE_A\0"
    "CUSTOM_KEY_CODE_C\0" // CUSUTOM_KEY_CODE_B に "CUSTOM_KEY_CODE_C" という文字列が割り当てられる
    "CUSTOM_KEY_CODE_B\0" // CUSUTOM_KEY_CODE_C に "CUSTOM_KEY_CODE_B" という文字列が割り当てられる
};
```

#### キーマップの編集

ここまでで BLE Micro Pro 用の定義は済みましたので、あとは普通に `keymaps[][MATRIX_ROWS][MATRIX_COLS]` や `process_record_user` を編集して、キーマップやカスタムキーコードの挙動を定義してください。

# ファームウェアの書き込み

あとはこの手順に従って、マスタ/スレーブ用のファームウェアをそれぞれ書き込んでください。

https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/master/AboutDefaultFirmware/doc/build_bmp_qmk_firmware.md

書き込みが終わった後 `KEYMAP.JSN` を確認すると、定義していた `CUSTOM_KEY_CODE_A` などが `KC_NO` や `EX(65535)` （ `()` 内は何桁かの数字）などになってることがありますが、辞書自体は BLE Micro Pro 内部に保持されているので、書き換えてやれば問題なく動きます。

# 完成！！

以上で終了です。
「BLE Micro Pro を導入したいけど、全然わからん！！！」という人の助けになれば幸いです。

また、電池持ちや宗教上（？）の理由で OLED や LED の設定はオミットしています。ご了承ください。

それでは、皆さんも BLE Micro Pro で快適な無線自作キーボードライフを！！

[qmk_git]:https://github.com/qmk/qmk_firmware
[qmk_getting_started]:https://docs.qmk.fm/#/newbs_getting_started
[crkbd]:https://github.com/qmk/qmk_firmware/tree/master/keyboards/crkbd
[sekigon_prof]:https://github.com/sekigon-gonnoc
[bmp_git]:https://github.com/sekigon-gonnoc/BLE-Micro-Pro
[bmp_default_firm]:https://github.com/sekigon-gonnoc/BLE-Micro-Pro/tree/master/AboutDefaultFirmware
[bmp_yusha]:https://yushakobo.jp/shop/ble-micro-pro/
[bmp_booth]:https://booth.pm/ja/items/1177319
[bmp_battery_yusha]:https://yushakobo.jp/shop/ble-micro-pro-battery-board/
[bmp_battery_booth]:https://nogikes.booth.pm/items/1655285