自作キーボードビルドログ：その３「ErgoDash」無線化対応 ソフトウェア編

https://qiita.com/h-oikawa/items/10b672e03653a1b3fa62 の続き。

BLE Micro Proにファームウェア／キー設定を書き込む。

**追記) 本記事はmacOSでの実行ログです。windowsでの各種コマンド実行方法は別途検索して下さい。**


## ファームウェアの書き込み(初回)
**※おそらく最初から最新の標準ファームウェア(後述)を使用する場合、この手順は不要**

[先人の方の記事](https://log.brdr.jp/post/395)を参考に、qmk_firmware_bleのリポジトリをクローン＆nrfutil実行環境をセットアップ。

`ergodash_ble`のdefault設定をmakeコマンドでビルドし、USB接続の待ち受けが始まったらリセットスイッチを押した状態でUSBをつなぐ。

```bash
$ make ergodash_ble/master:default:nrfutil
Making ergodash_ble/master with keymap default and target nrfutil

"PLATFORM NRF5"
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling: tmk_core/common/command.c                                                                [OK]
...
Linking: ergodash_ble_master_default.elf                                                            [OK]
Creating binary load file for flashing: ergodash_ble_master_default.bin                             [OK]

|===============================================================|
|##      ##    ###    ########  ##    ## #### ##    ##  ######  |
|##  ##  ##   ## ##   ##     ## ###   ##  ##  ###   ## ##    ## |
|##  ##  ##  ##   ##  ##     ## ####  ##  ##  ####  ## ##       |
|##  ##  ## ##     ## ########  ## ## ##  ##  ## ## ## ##   ####|
|##  ##  ## ######### ##   ##   ##  ####  ##  ##  #### ##    ## |
|##  ##  ## ##     ## ##    ##  ##   ###  ##  ##   ### ##    ## |
| ###  ###  ##     ## ##     ## ##    ## #### ##    ##  ######  |
|===============================================================|
|You are generating a package with the debug bit enabled in the |
|init packet. This is only compatible with a debug bootloader   |
|and is not suitable for production.                            |
|===============================================================|


|===============================================================|
|##      ##    ###    ########  ##    ## #### ##    ##  ######  |
|##  ##  ##   ## ##   ##     ## ###   ##  ##  ###   ## ##    ## |
|##  ##  ##  ##   ##  ##     ## ####  ##  ##  ####  ## ##       |
|##  ##  ## ##     ## ########  ## ## ##  ##  ## ## ## ##   ####|
|##  ##  ## ######### ##   ##   ##  ####  ##  ##  #### ##    ## |
|##  ##  ## ##     ## ##    ##  ##   ###  ##  ##   ### ##    ## |
| ###  ###  ##     ## ##     ## ##    ## #### ##    ##  ######  |
|===============================================================|
|You are not providing a signature key, which means the DFU     |
|files will not be signed, and are vulnerable to tampering.     |
|This is only compatible with a signature-less bootloader and is|
|not suitable for production environments.                      |
|===============================================================|

Zip created at ergodash_ble_master_default.zip
Detecting USB port, put your controller into dfu-mode now...........................................................................................................
Detected controller on USB port at /dev/tty.usbmodemF659423AAB571
Programming Started
  [####################################]  100%
Device programmed.
```

slave(右手)側も同様。

```bash
$ make ergodash_ble/slave:default:nrfutil
Making ergodash_ble/slave with keymap default and target nrfutil

"PLATFORM NRF5"
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiling: keyboards/ergodash_ble/ergodash_ble.c                                                    [OK]
...
Linking: ergodash_ble_slave_default.elf                                                             [OK]
Creating binary load file for flashing: ergodash_ble_slave_default.bin                              [OK]

|===============================================================|
|##      ##    ###    ########  ##    ## #### ##    ##  ######  |
|##  ##  ##   ## ##   ##     ## ###   ##  ##  ###   ## ##    ## |
|##  ##  ##  ##   ##  ##     ## ####  ##  ##  ####  ## ##       |
|##  ##  ## ##     ## ########  ## ## ##  ##  ## ## ## ##   ####|
|##  ##  ## ######### ##   ##   ##  ####  ##  ##  #### ##    ## |
|##  ##  ## ##     ## ##    ##  ##   ###  ##  ##   ### ##    ## |
| ###  ###  ##     ## ##     ## ##    ## #### ##    ##  ######  |
|===============================================================|
|You are generating a package with the debug bit enabled in the |
|init packet. This is only compatible with a debug bootloader   |
|and is not suitable for production.                            |
|===============================================================|


|===============================================================|
|##      ##    ###    ########  ##    ## #### ##    ##  ######  |
|##  ##  ##   ## ##   ##     ## ###   ##  ##  ###   ## ##    ## |
|##  ##  ##  ##   ##  ##     ## ####  ##  ##  ####  ## ##       |
|##  ##  ## ##     ## ########  ## ## ##  ##  ## ## ## ##   ####|
|##  ##  ## ######### ##   ##   ##  ####  ##  ##  #### ##    ## |
|##  ##  ## ##     ## ##    ##  ##   ###  ##  ##   ### ##    ## |
| ###  ###  ##     ## ##     ## ##    ## #### ##    ##  ######  |
|===============================================================|
|You are not providing a signature key, which means the DFU     |
|files will not be signed, and are vulnerable to tampering.     |
|This is only compatible with a signature-less bootloader and is|
|not suitable for production environments.                      |
|===============================================================|

Zip created at ergodash_ble_slave_default.zip
Detecting USB port, put your controller into dfu-mode now......................................................................
Detected controller on USB port at /dev/tty.usbmodemDBBB702F38B61
Programming Started
  [####################################]  100%
Device programmed.
```

## ファームウェアUPDATE

最新の[BLE Micro Pro 標準ファームウェア](https://github.com/sekigon-gonnoc/BLE-Micro-Pro/tree/master/AboutDefaultFirmware)ならPCにストレージデバイスとして接続して中のキーマップなどを編集出来るらしい。
自分のBMPはUSB接続してもストレージとして認識されないので、ファームウェアのバージョンをアップデートしてみる。

[getting_startページ](https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/master/AboutDefaultFirmware/doc/getting_start.md)の説明を参考に手順を進める。
Releaseページから最新のブートローダとコンパイル済みアプリケーションのzipファイルをDL。

```bash
$ ll ./ble*
-rw-r--r--@ 1 root  staff   120K  3 20 12:49 ./ble_micro_pro_bootloader_0_4_4.zip
-rw-r--r--@ 1 root  staff    65K  3 20 12:50 ./ble_micro_pro_default_0_4_2.zip
```

BMPにシリアル接続するため、接続ポートを調べる。

```bash
$ ll /dev/tty.*
crw-rw-rw-  1 root  wheel    9,   0  3  5 13:31 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel    9,   2  3  5 13:31 /dev/tty.iPad-WirelessiAPv2
crw-rw-rw-  1 root  wheel    9,  52  3 20 13:30 /dev/tty.usbmodem0000000000005
```

USB接続前後で増えたデバイスがBMP。(今回の場合は`tty.usbmodem0000000000005`)

試しにcuコマンドで繋ぎ、helpを実行してみる。
(直でcuを実行したら`Permission denied`と言われたのでsudoで実行)

```bash
$ sudo cu -l /dev/tty.usbmodem0000000000005
Password:
Connected.

>help
reset	Reset system
adv	Start advertising
dfu	Jump to bootloader
show	Show bonded devices
del	Delete bond information
help	Show this message
>
```

コマンドの数が[公式の一覧ページ](https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/master/AboutDefaultFirmware/doc/cli.md)より少ないのはやはりバージョンが古いからの模様。

ファームウェアを書き込むため、dfuでブートローダ起動。

```bash
>dfu
cu: Got hangup signal

Disconnected.
```

一度接続が切れるので、再度シリアルデバイスが認識されているか確認。

```
$ ll /dev/tty.*
crw-rw-rw-  1 root  wheel    9,   0  3  5 13:31 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel    9,   2  3  5 13:31 /dev/tty.iPad-WirelessiAPv2
crw-rw-rw-  1 root  wheel    9,  48  3 20 13:20 /dev/tty.usbmodemDBBB702F38B61
```

対象のシリアルポートを確認したら以下コマンドで最新のbootloaderを書き込み。

```bash
$ nrfutil dfu usb-serial -pkg ./ble_micro_pro_bootloader_0_4_4.zip -p /dev/tty.usbmodemDBBB702F38B61
  [####################################]  100%
Device programmed.
```

続いてアプリケーションの方も同様にアップデートする。

```bash
$ ll /dev/tty.*
crw-rw-rw-  1 root  wheel    9,   0  3  5 13:31 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel    9,   2  3  5 13:31 /dev/tty.iPad-WirelessiAPv2
crw-rw-rw-  1 root  wheel    9,  32  3 20 13:06 /dev/tty.usbmodem0000000000005

$ sudo cu -l /dev/tty.usbmodem0000000000005
Connected.

>dfu
cu: Got hangup signal

Disconnected.
$ ll /dev/tty.*
crw-rw-rw-  1 root  wheel    9,   0  3  5 13:31 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel    9,   2  3  5 13:31 /dev/tty.iPad-WirelessiAPv2
crw-rw-rw-  1 root  wheel    9,  34  3 20 13:08 /dev/tty.usbmodem0000000000011
crw-rw-rw-  1 root  wheel    9,  36  3 20 13:08 /dev/tty.usbmodem0000000000014
```

ブートローダをアップデート後、なぜかdfuでの接続ポートが２つに増えているが、ひとまず`usbmodem0000000000011`の方で問題なさそう。

```bash
$ nrfutil dfu usb-serial -pkg ./ble_micro_pro_default_0_4_2.zip -p /dev/tty.usbmodem0000000000011
  [####################################]  100%
Device programmed.
```

slave側も同様の手順でアップデート。(割愛)

ファームウェアアップデート後、再度USB接続したら無事ストレージデバイスとして認識された。

<img width="781" alt="スクリーンショット 2020-03-20 13.18.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104276/4110d0ed-0f0c-ab9b-8a1c-358719d1c1f1.png">

シリアル接続のコマンドも増えている。

```bash
$ sudo cu -l /dev/tty.usbmodem0000000000014
Connected.

>help
reset	Reset system
adv	Start advertising
dfu	Jump to bootloader
show	Show bonded devices
del	Delete bond information
help	Show this message
map	Show keymap
conf	Show config
conv	Show keymap
update	Update file
remove	Remove file
debug	Debug print setting
dump	Dump memory
dumps	Dump memory
led	LED control
ee	eeprom control
web	Start web config mode
i2c	Test i2c
```

試しにconfを実行。

```bash
>conf
{"config":{"version":2,
"device_info":{"vid":"0x0000","pid":"0x0000","name":"ble_micro_pro","manufacture":"sekigon-gonnoc","description":"A development board for wireless split keyboards"},
"matrix":{"rows":1,"cols":19,"device_rows":1,"device_cols":19,"debounce":1,"is_left_hand":1,"diode_direction":0,"row_pins":[33],"col_pins":[1,2,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22],
"layout":[
  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18]},
"mode":"SINGLE","startup":0,
"peripheral":{"max_interval":60,"min_interval":30,"slave_latency":7},
"central":{"max_interval":60,"min_interval":30,"slave_latency":7},
"led":{"pin":255,"num":128},
"keymap":{"locale":"US","use_ascii":0},
"reserved":[0,0,0,0,0,0,0,0]}}
>
```

ファームウェア書き込み直後なのでconfigはデフォルト。

### 設定ファイルの修正

ErgoDashキーボードとして使用するため、[このページ](https://github.com/sekigon-gonnoc/BLE-Micro-Pro/tree/master/AboutDefaultFirmware/keyboards/ergodash)からキー配列に対応するjsonをDLする。
自分の場合は以下２つ。

- ergodash_rev1_layout_4key_master_left_config.json
- ergodash_rev1_layout_4key_slave_right_config.json

`CONFIG.JSN`としてリネームし、各ストレージ内にアップロード。

続いてキーマップの設定。

[BMP対応版QMK Configurator](https://sekigon-gonnoc.github.io/qmk_configurator/#/ergodash/rev1/LAYOUT_4key)でキーマップを設計し、jsonファイルをDL。

`KEYMAP.JSN`としてリネームし、masterのストレージ内にアップロード。

### Bluetooth接続

設定編集後、BMPを再起動。

初回起動時は自動で左右(master<->slave)間でペアリングを行うらしい。
シリアル接続しておくとペアリング状況が確認出来る。

- master側 

```bash
<info> app: Scanning slave keyboard...
<info> app: Fast advertising.
<info> app: Connected to the slave keyboard
<info> app: Connected to device 0.
<info> app: New Bond, add the peer to the whitelist if possible
<info> app: 	m_whitelist_peer_cnt 1, MAX_PEERS_WLIST 8
>show
 0:Slave :  xx:xx:xx:xx:xx:xx
```

- slave側

```bash
<info> app: Connected to master keyboard:0
<info> app: New Bond, add the peer to the whitelist if possible
<info> app: 	m_whitelist_peer_cnt 1, MAX_PEERS_WLIST 8
>show
 0:Master:  yy:yy:yy:yy:yy:yy
```

master<->slaveの接続が出来たら使用デバイス(PC)とのペアリングを追加する。

advコマンド(または`AD_WO_L`に割り当てたキーを押下)でペアリング開始。
デバイスのBluetooth機器一覧に「ErgoDash」という名前で検出されるので接続。

```bash
>adv
<info> app: Slow advertising.
<info> app: Connected to device 1.
<info> app: New Bond, add the peer to the whitelist if possible
<info> app: 	m_whitelist_peer_cnt 2, MAX_PEERS_WLIST 8
>show
 0:Slave :  xx:xx:xx:xx:xx:xx
 1:Device:  zz:zz:zz:zz:zz:zz
```

キー入力が認識されたら基本設定は完了。

あとは自分の理想のキー配置を求めて設定を弄っていくだけ。
BMP固有のカスタムキーコードは[ここ](https://github.com/sekigon-gonnoc/BLE-Micro-Pro/blob/master/AboutDefaultFirmware/doc/bmp_custom_keycode.md)を参照。
必須なのはペアリング関連の`AD_WO_L`と`ADV_IDx`くらい?
`ENT_DFU`なども一応割り当てては置いたが、リセットスイッチがあれば使うことはなさそう。
他のキーも試してみて特筆すべきことが見つかれば追記予定。

---
無事当初やりたかった左右分割無線キーボードが実現！
![P_20200321_204424_vHDR_Auto.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104276/0fb77876-816e-f36f-efba-c20d7f9ed9ed.jpeg)

中学以来の半田付け作業は非常に新鮮で楽しめたが、キーキャップ・スイッチの種類の多さ、キー配列のカスタマイズ性などやはり自由度が高い分自作キーボードの沼は相当深い印象。

BMPでの無線化についてはまだ情報少なく躓きどころも多めな気がするので、今後挑戦する方の参考になれば幸い。