ArduinoとPlaidを使ってマイコンを複製する方法

前置き

自作キーボードのPlaidはお気に入りのキーボードであるが、このキーボードは、ProMicroを使う代わりにマイコンのATMega328Pを基板に乗せており、さらに、キーボードにISPポートが用意されている。

なので、このキーボードをAVRライターがわりに使えるのではないか、また、秋月とかで購入したATMega328Pにデータをバックアップしておいて、いざというときはマイコンだけ置き換えて対処する、といったこともできるんじゃないかと思って挑戦してみた。

その挑戦がうまくいったので、その手順を備忘録として残しておく。

作業の手順

作業に使うものは次のとおり。

  1. Plaid
  2. Arduino Uno(互換品でOK)
  3. ブレッドボード・ジャンパーワイヤ(オス-メス)6本

作業の手順は以下のとおり。

ArduinoをAVRライターにする

手順

Arduino IDEをインストール

こちらのサイトでアプリをダウンロードしてインストールする。

Arduinoのシリアルポートの接続先を確認

Arduino IDEを使う方法

まず、Arduinoを接続せずにAuduino IDEを立ち上げ、メニューバーの「ツール」->「シリアルポート」に表示されるデバイスを確認する。

Arduino IDE(Arduino接続前)

それからArduinoを接続して再度「ツール」->「シリアルポート」を確認すると、Arduinoのシリアルポートの接続先を確認できる。

Arduino IDE(Arduino接続後)
ターミナルで確認する方法

まず、Arduinoを接続せずにAuduino IDEを立ち上げ、メニューバーの「ツール」->「シリアルポート」に表示されるデバイスを確認する。それからArduinoを接続して再度「ツール」->「シリアルポート」を確認すると、Arduinoのシリアルポートの接続先を確認できる。

まず、Arduinoを接続しないでターミナルを開いて次のコマンドを実行し、シリアルデバイスを確認する。

$ ls -la /dev/tty.*
crw-rw-rw-  1 root  wheel   19,   0  9 25 07:35 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel   19,   2  9 25 07:35 /dev/tty.iPhone-WirelessiAP-1

次に、Arduinoを接続して同じコマンド実行すると、Arduinoのシリアルポートの接続先を確認できる。

$ ls -la /dev/tty.*
crw-rw-rw-  1 root  wheel   19,   0  9 25 07:35 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel   19,   2  9 25 07:35 /dev/tty.iPhone-WirelessiAP-1
crw-rw-rw-  1 root  wheel   19, 200 10 10 00:02 /dev/tty.usbmodem14212401 #これがArduinoのシリアルポート

2回目で登場した/dev/tty.usbmodem14212401が、Arduinoのシリアルポートの接続先である。

ArduinoにArduinoISPスケッチを書き込む

メニューバーの「ファイル」->「スケッチ例」->「11. Arduino ISP」->「ArduinoISP」を選択する。

Arduino IDE(スケッチ例-Adruino ISP)

それから、「スケッチ」->「マイコンボードに書き込む」を選択して書き込む。

Arduino IDE(スケッチ書き込み)

これで、ArduinoをAVRライターとして使う準備が整ったことになる。

必要なバイナリやライブラリのインストール

以下のコマンドで必要なバイナリやライブラリをインストールできる。ただし、Plaidを使うためにQMK Firmwareをセットアップすれば必要なバイナリ等もインストールされるので、改めてインストールする必要性は乏しい(はず)。

$ brew tap osx-cross/avr
$ brew tap PX4/homebrew-px4
$ brew update
$ brew install avr-gcc@8
$ brew install dfu-programmer
$ brew install gcc-arm-none-eabi
$ brew install avrdude

手順

avrdudeのインストール

次のコードを実行してavrdudeをインストール

$ brew install avrdude --with-usb

avrdudeのテスト起動

次のコードを実行してavrdudeを実行してみる。

$ avrdude
Usage: avrdude [options]
Options:
  -p <partno>                Required. Specify AVR device.
  -b <baudrate>              Override RS-232 baud rate.
  -B <bitclock>              Specify JTAG/STK500v2 bit clock period (us).
  -C <config-file>           Specify location of configuration file.
  -c <programmer>            Specify programmer type.
  -D                         Disable auto erase for flash memory
  -i <delay>                 ISP Clock Delay [in microseconds]
  -P <port>                  Specify connection port.
  -F                         Override invalid signature check.
  -e                         Perform a chip erase.
  -O                         Perform RC oscillator calibration (see AVR053).
  -U <memtype>:r|w|v:<filename>[:format]
                             Memory operation specification.
                             Multiple -U options are allowed, each request
                             is performed in the order specified.
  -n                         Do not write anything to the device.
  -V                         Do not verify.
  -u                         Disable safemode, default when running from a script.
  -s                         Silent safemode operation, will not ask you if
                             fuses should be changed back.
  -t                         Enter terminal mode.
  -E <exitspec>[,<exitspec>] List programmer exit specifications.
  -x <extended_param>        Pass <extended_param> to programmer.
  -y                         Count # erase cycles in EEPROM.
  -Y <number>                Initialize erase cycle # in EEPROM.
  -v                         Verbose output. -v -v for more.
  -q                         Quell progress output. -q -q for less.
  -l logfile                 Use logfile rather than stderr for diagnostics.
  -?                         Display this usage.
avrdude version 6.3, URL: <http://savannah.nongnu.org/projects/avrdude/>

ArduinoとPlaidを接続する

ArduinoとISPポートの接続

ArduinoをISPライターとして使う場合に、Arduinoで使うピンと、書き込み先のATMega328Pで使うピンの対応関係は次のとおり。

ArduinoATMega328P
101(reset)
1117
1218
1319
5V(VCC)
GND(GND)

PlaidのISPポートとATMega328Pのピン配置の接続

Plaidの回路図で、基板にあるISPポートの各ピンがATMega328Pのどのピンと接続されているか確認する。確認結果は次のとおり。

Plaid(ISP)ATMega328P
118
319
417
2(VCC)
5(RESET)
6(GND)

なお、Plaidの基板にあるピンの順番は次の写真のとおり。黒い三角(▲)が指し示すピンが1番ピンである。

PlaidとArduinoの接続

上の2つの表を元に、ArduinoとPlaidを次のとおり接続する。

ArduinoPlaid
105(RESET)
114
121
133
5V2(VCC)
GND6(GND)

Avrdudeの読み込みが可能か確認する

次のコマンドを入力して、デバイスIDを読み取る。無事に読み取れれば次のようなメッセージが出力される。

$ avrdude -c avrisp -P COMポート番号 -b 19200 -p m328p
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: Fuses OK (E:FC, H:D0, L:D7)
avrdude done. Thank you.

正常に動くPlaidのデータを読み込む

以上の作業により、Plaidに取り付けているATMega328Pのデータを読み取って、新しいATMega328Pに書き込むことができるようになった。

そのため、次は具体的な作業方法を説明する。

ヒューズビットの読み込み

次のコマンドを入力して、正常に動いているATMega328Pのヒューズビットを読み込んでおく。この値は、新しいATMega328Pにhexデータを書き込んだ後の設定作業で使用する。

$ avrdude -c avrisp -P COMポート番号 -b 19200 -p m328p -U lfuse:r:con:h -U hfuse:r:con:h -U efuse:r:con:h
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.03s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading lfuse memory:
Reading | ################################################## | 100% 0.01s
avrdude: writing output file "con"
avrdude: reading hfuse memory:
Reading | ################################################## | 100% 0.01s
avrdude: writing output file "con"
avrdude: reading efuse memory:
Reading | ################################################## | 100% 0.01s
avrdude: writing output file "con"
avrdude: safemode: Fuses OK (E:FC, H:D0, L:D7) #カッコ内の値がヒューズビットの値
avrdude done. Thank you.

hexデータの読み込み

次のコマンドを入力して、正常に動いているATMega328Pに書き込まれているデータをbackup.hexファイルとして読み込む。このファイルを使って、別のATMega328Pに書き込む。

$ avrdude -c avrisp -P COMポート番号 -b 19200 -p m328p -U flash:r:backup.hex:i
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading flash memory:
Reading | ################################################## | 100% 19.92s
avrdude: writing output file "backup.hex"
avrdude: safemode: Fuses OK (E:FC, H:D0, L:D7)
avrdude done. Thank you.

新しいATMega328Pへの書き込み

上記の作業で正常に動いてるPlaidのデータは読み込めたので、ここで、Plaidに取り付けてあるATMega328Pを取り外す。それから、新しいATMega328Pを取り付ける。

取り外す前に、ArduinoとPlaidの接続を切るかArduinoとPCの接続を切ること。そして、接続を切ったまま取り外しと取り付けを行い、取り付けが完了したら再接続する。

ブートローダの書き込み

ブートローダが書き込まれていないATMega328pを使う場合、ブートローダの書き込みを最初に行う。ブートローダ書き込み済みならこの作業は不要である。

PlaidのブートローダにはUSBaspLoaderをUSBブートローダとして使用する。そのため、USBaspLoaderが必要になるが、Plaidの開発者のhsgw氏がPlaid用のUSBaspLoaderを公開してくれているので、それを利用する。

# hsgw氏が作成しているPlaidのブランチをcloneする
# MasterブランチにPlaid用のファームウェアは存在しないので注意!
$ git clone -b plaid https://github.com/hsgw/USBaspLoader.git

続いて、USBaspLoaderをATMega328pに書き込む。

$ cd USBaspLoader/firmware
$ avrdude -c avrisp -P COMポート番号 -b 19200 -p m328p -U flash:w:main.hex:i
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.03s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: writing flash (30878 bytes):
Writing | ################################################## | 100% 0.00s
avrdude: 30878 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 30878 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 0.00s
avrdude: verifying ...
avrdude: 30878 bytes of flash verified
avrdude: safemode: Fuses OK (E:FF, H:D9, L:62)
avrdude done. Thank you.

hexデータの書き込み

次のコマンドを入力して、先ほど読み取ったbackup.hexファイルを書き込む。

$ avrdude -c avrisp -P COMポート番号 -b 19200 -p m328p -U flash:w:backup.hex:i
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "backup.hex"
avrdude: writing flash (30866 bytes):
Writing | ################################################## | 100% 33.70s
avrdude: 30866 bytes of flash written
avrdude: verifying flash memory against backup.hex:
avrdude: load data flash data from input file backup.hex:
avrdude: input file backup.hex contains 30866 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 18.83s
avrdude: verifying ...
avrdude: 30866 bytes of flash verified
avrdude: safemode: Fuses OK (E:FF, H:D9, L:62)
avrdude done. Thank you.

ヒューズビットの値書き込み

最後に、新しいATMega328pのヒューズビットに、上記の作業で確認した値を書き込む。

$ avrdude -c avrisp -P COMポート番号 -b 19200 -p m328p -U flash:w:backup.hex:i
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.02s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "backup.hex"
avrdude: writing flash (30866 bytes):
Writing | ################################################## | 100% 33.70s
avrdude: 30866 bytes of flash written
avrdude: verifying flash memory against backup.hex:
avrdude: load data flash data from input file backup.hex:
avrdude: input file backup.hex contains 30866 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 18.83s
avrdude: verifying ...
avrdude: 30866 bytes of flash verified
avrdude: safemode: Fuses OK (E:FF, H:D9, L:62)
avrdude done. Thank you.

動作確認

ここまでの作業が終わったら、ArduinoからPlaidを外し、PlaidとPCを接続して入力テストを行う。

作業がきちんとできていれば、それまでと同様にPlaidが使えるはずである。

補足

QMK Firmwareでmake plaid:defaultで作成した.hexファイルを使って書き込んでみたが、一部のキーが動かなかった。そのため、書き込み用ファイルは、上記の作業で正常に動くPlaidから吸い出すしかないと思われる。