Mint60のキーマップをMacとWindowsで変更する

# はじめに

この記事はMint60という自作キーボードのキーマップを変更したときの備忘録です。キーマップの変更には、QMK Firmwareでファームウェアをビルドしてキーボードに書き込む必要がありますが、手順や自分が悩んだ部分について書いてみようと思います。Mint60の組み立てについては、開発者の方が公開されているので、そちらを参照ください。
ファームウェアのビルド、書き込みにはMacとWindows（WSL）を使用していますが、
macOS Catalinaでの書き込みには成功しておらず、macOS MojaveとWSLでのみ書き込みを確認しています。

## 参考

- [QMK Firmware](https://qmk.fm/)

## 環境

- macOS Catalina, Mojave
- Windows 10（Windows Subsystem for Linux Ubuntu）

## Macの手順

### ビルド環境の構築

QMK FirmwareをGitHubからCloneします。

```sh
git clone https://github.com/qmk/qmk_firmware
cd qmk_firmware
```

ファームウェアのビルドに必要なツールをインストールします。
インストールコマンドは公式ドキュメントに記載されていますが、シェルスクリプトがリポジトリに格納されています。

```sh
./util/qmk_install.sh
```

### キーマップの作成

今回ファームウェアを作成するmint60はデフォルトのキーマップが定義されています。
編集用にデフォルトのキーマップを元に新しいキーマップ（Custom）を定義してみます。

```sh
cp -r ./keyboards/mint60/keymaps/default ./keyboards/mint60/keymaps/custom
```

キーマップは`keymap.c`に定義されていますので変更します。
指定するキー値については、[Keycodes Overview](https://docs.qmk.fm/#/keycodes)を参照してください。

```c
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [0] = LAYOUT( \
    KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,      KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,    KC_BSPC,  \
    KC_TAB,    KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,      KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS,  \
    KC_CAPS,     KC_A,    KC_S,    KC_D,    KC_F,    KC_G,      KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,        KC_ENT,   \
    KC_LSFT,       KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,      KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,   KC_UP,  MO(1),   \
    KC_ESC,    KC_LCTL,    KC_LGUI,    KC_LALT,    KC_SPC,        KC_BSPC, KC_ENT,  LALT(KC_GRV),               KC_LEFT,KC_DOWN,KC_RGHT \
  ),
  [1] = LAYOUT( \
    KC_ESC,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,     KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,    KC_DEL, \
    RGB_TOG,   RGBRST,  RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, \
    XXXXXXX,     RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,        XXXXXXX, \
    _______,       XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,   XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, KC_PGUP, _______, \
    XXXXXXX,   _______,    _______,    _______,    XXXXXXX,       XXXXXXX, XXXXXXX, XXXXXXX,                   KC_HOME, KC_PGDN, KC_END \
  )
};
```

### ファームウェアのビルド（Mac）

キーマップを作成したらファームウェアをビルドします。ビルドは`make {キーボード名}:{キーマップ名}`で行います。ビルドに成功すると、qmk_firmwareのルートディレクトリに`{キーボード名}_{キーマップ名}.hex`というバイナリが生成されます。

```sh
make mint60:custom
```

私の環境では、以下のエラーでビルドに失敗しました。メッセージのとおり`make git-submodule`を実行してからビルドします。

```sh
WARNING:
 Some git sub-modules are out of date or modified, please consider running:
 make git-submodule
 You can ignore this warning if you are not compiling any ChibiOS keyboards,
 or if you have modified the ChibiOS libraries yourself.
```

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

ファームウェアが用意できたら、キーボードに搭載されているPro Microに書き込みます。書き込みは`make {キーボード名}:{キーマップ名}:avrdude`を実行します。

```sh
make mint60:custom:avrdude
```

コマンドを実行したらキーボードを接続し、Pro microをリセットしてください。
Mint60の場合、キーボードの背面にリセット用のタクトスイッチがありますので、押すとPro Microへの書き込みが開始されます。Mint60は分割タイプのキーボードなので、もう片方もファームウェアを書き込みます。

実行してみると自分の環境では書き込みに成功せず、以下の内容が出力されました。

```sh
Connecting to programmer: .avrdude: butterfly_recv(): programmer is not responding

avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: ser_drain(): read error: Device not configured
avrdude: ser_send(): write error: Device not configured
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: ser_send(): write error: Device not configured
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: ser_send(): write error: Device not configured
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
Found programmer: Id = ""; type =
    Software Version = .; Hardware Version = .
avrdude: ser_send(): write error: Device not configured
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: ser_send(): write error: Device not configured
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: error: buffered memory access not supported. Maybe it isn't
a butterfly/AVR109 but a AVR910 device?
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: ser_send(): write error: Device not configured
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: error: programmer did not respond to command: leave prog mode
avrdude: ser_send(): write error: Device not configured
avrdude: ser_recv(): read error: Device not configured
avrdude: butterfly_recv(): programmer is not responding
avrdude: error: programmer did not respond to command: exit bootloader
avrdude: ser_close(): can't reset attributes for device: Device not configured

avrdude done.  Thank you.

make[1]: *** [avrdude] Error 1
make: Make finished with errors
*** [mint60:custom:avrdude] Error 1
```

調べてみるとGitHubにissueが上がっていました。
[macOS Catalina: Pro Micro (w/Caterina bootloader) flashing - avrdude: butterfly_recv(): programmer is not responding #6133](https://github.com/qmk/qmk_firmware/issues/6133)

macOS Catalinaで発生しており、自分もMojaveからCatalina version 10.15にアップデートした環境で書き込みをしていました。issueでは、Catalinaの挙動がavrdudeツールの通信に影響しているとのこと。試しにMohave環境で書き込みを行うとあっさり成功しました。

## Windows10（WSL）の手順

macOS mohaveでのファームウェア書き込みには一応成功しましたが、自作したmint60キーボードはWindows環境で使用する予定でした。環境構築が面倒だったのでMacを使用しましたが、Windows10にWSLをインストールし、ファームウェアのビルド、書き込みが可能な環境を構築しました。WSLのディストリビューションはUbuntuを使用しています。

### ビルド環境の構築（WSL）

macOSと同様にシェルスクリプトを実行します。

```sh
./util/qmk_install.sh
```

### ファームウェアのビルド（WSL）

ビルドはmacOSの手順と同じなので省略します。

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

macOSと同様に`make {キーボード名}:{キーマップ名}:avrdude`を実行すると失敗しました。

```sh
ERROR: AVR flashing cannot be automated within the Windows Subsystem for Linux (WSL) currently. Instead, take the .hex file generated and flash it using AVRDUDE, AVRDUDESS, or XLoader.
```

エラーメッセージの内容から、avrdudeツールを手動で実行して書き込む必要がありそうです。
いろいろ試行錯誤した結果、Pro microをリセットをしたあと、すぐにavrdudeツールのコマンドを実行することで書き込みに成功しました。
あらかじめ以下のコマンドを打ち込んでおき、Pro microをリセットしたあとすぐにEnterキー押下でコマンドを発行できるようにして実施するのがコツです。

`avrdude -p atmega32u4 -c avr109 -P /dev/ttyS{COMポート番号} -U flash:w:'{ファームウェアのファイルパス}`

- -pオプション AVRマイコンを指定します。Pro microはatmega32u4です。

- -cオプション 書き込みに使用するブートローダ向けのライタ avr109を指定します。

- -Pオプション Pro microをリセットした直後に接続される、COMポートに対応したデバイスファイルのパスを記載します。注意点として、Pro microはリセットすると、COM接続が確立し一定時間経過後に切断される挙動をします。何秒か経過すると切断されるため、Windowsのデバイスマネージャを開いておき、Pro microを一度リセットして接続されるCOMポート番号を確認しました。

- -Uオプション ビルドしたファームウェア（.hexファイル）のパスを指定します。

私の環境ではCOMポート3を使用していたので、最終的に次のコマンドになりました。
Mint60は分割タイプのキーボードなので両方ともファームウェアを書き込んで完了です。

```sh
avrdude -p atmega32u4 -c avr109 -P /dev/ttyS3 -U flash:w:./mint60_custom.hex
```