SNSへはこちら

Pro Micro互換ボードを買ったので色々調べる

先日は Atmega16u2 についての記事を書きました。でもまあ、ADC が無かったりしてなんか中途半端なので、今回は Shigezone さんで購入したボードについてまとめておきたいと思います。備忘録ですね〜

仕様

まずこのボードですが、Sparkfun で販売されている Arduino 互換ボードの互換品らしいですね。そう、中華です。汚い言葉を使えばパチモンの類なのですが、Shigezone さんではこれが 600 円という破格で売られていましたので、買いました。ってかこのマイコンそんなに高くないんだから、このくらいが適正価格な気もしますがね。まあそれでも大本は Arduino なのでこんなにも高いんでしょう。あとこれ、Pro Mini というものもあるんですが、こちらはまるっきり載っているチップが違いますので、お間違えなく。

回路図は Pro Micro の方から見てください。では簡単にまとめます。

  • 5V, 16MHz 外部クリスタル動作
    • ボード上のレギュレータは賑やかし
    • こちらのサイトによると、これは 5V のレギュレータらしい。あれ、入力って 5V だよね...?つまり意味がない
  • Micro USB 対応
  • USB ブートローダが工場出荷時に内蔵
    • Arduino IDE で使えるらしい、が今回は興味ないのでスルー
    • この情報を求めていた方には申し訳ないですが、Arduino IDE を使う場合は他のサイトに情報がありますので、そちらを参照してください。
  • クリスタルレスで Low-speed USB デバイスを実装可能(このボードでは既に付いているのでまあ関係ないですが)

という感じで、つまりは USB ケーブルを差すだけで書き込みと動作をサクッと出来てしまうという代物ですね。まあ書き込み環境がいい感じに揃っているマイコンシリーズなので、確かに自作キーボードとして使用されるのもわかりますね。
ところで自作キーボードって、ファームウェアから自作しなきゃ本当の自作とは言

では、以下で詳細を調べていきます。

Fuse Bytes

例のサイトを使って解析していきます。avrdude を叩いた所、出てきました。その結果はこちら

まあ簡単に言うと、

  • 外部オシレータによって動作
    • このボードは 16MHz
  • CPU クロックの8分周なし
    • つまり 16MHz そのものでマイコンが動いている
  • SPI 書き込みが有効
  • ハードウェアブート無効
    • BOOTRST フューズが 0 かつ、今回のボードでは HWB# ピンが GND に固定されているので、リセット時に 必ずブートローダーに入るようになっている

という設定でした。特に必ずブートローダーが起動するところは気に入りませんが、そのへんの動作も見ていきます。

USBブートローダ

色々いじくり回しすぎて誤って壊す前に、様子を見てみましょう。

$ lsusb
...
Bus 020 Device 012: ID 1b4f:9206 1b4f SparkFun Pro Micro
...

なるほど。よく知りませんが(すみません)、Pro Micro(?) として認識されているっぽいですね。それでまあ、AVR のブートローダ機能というのはユーザーがソフトウェア的に書くことが出来るので、書き込み器に対応したブートローダを書き込んでおく必要があります。それでこれは、僕が好む CLI ツールである dfu-programmer が対応してくれていません。一方で、搭載しているブートローダーのおかげで、avrdude に対応しています

バックアップ

では、今後これを書き換えることを考えて、hex 形式でこのブートローダをバックアップしておきましょう。FT232RL を接続して、そこを介してデータを読んでいきます。

$ avrdude -P ft0 -c ft232r -p m32u4 -U flash:r:bootloader_ProMicro.hex:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.10s

avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: reading flash memory:

Reading | ################################################## | 100% 16.69s

avrdude: writing output file "bootloader_ProMicro_leonardo.hex"

avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)

avrdude done.  Thank you.

これでカレントディレクトリに bootloader_ProMicro.hex があるはずです。バックアップ完了。

デフォルトの動作

Shigezone さんの販売ページによると、以下のような挙動を示すらしい。

Pro Microを接続する前から表示されてるシリアルポート番号はデフォルトで割り当てられてるものなので、ボードを挿したときに追加されるものがボードのシリアルポートとなります。
で、Pro Microはちょっと特殊な動作として「リセットスイッチを2回連続で押すとシリアルポートが8秒間みえる」というものがあります。
「リセットスイッチなんてないっす!」となりますが、ボードのRSTと、すぐ隣のGND端子とを何かで接続すればリセットできます。

RESET ピンによるリセットをある時間以内に2回連続かけると、8秒間だけ USB シリアルが有効になるという挙動を示すらしいです。つまりこのブートローダで Arduino IDE を使う場合は、書き込み実行の直前に2回リセット端子を GND にショートしてやればいいということになります。 でもこれは関係ないようです。Mac を使っている限り、別にこの処理を行わずともずっと USB シリアルは PC 側から見え続けますし。

それでちょっと試してみたんですが、どうやらこの操作をすると、avrdude から一定時間書き込みの待受状態になるっぽいですね。
普通に起動している時に avrdude を叩いても応答がないままですが...取り敢えず USB ケーブルを繋げてコマンドを打ってみます。

$ avrdude -p m32u4 -c avr109 -P /dev/cu.usbmodem14301                                                                                                                                                 [master]

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

^C

一方で2回リセット端子を GND にショートした後にもう一度コマンドを叩くと...

$ avrdude -p m32u4 -c avr109 -P /dev/cu.usbmodem14301                                                                                                                                                 [master]

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587 (probably m32u4)

avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)

avrdude done.  Thank you.

おお、認識しました。こういうことですかね。どうやらこのブートローダは AVR109 というプロトコルを使用しているようで、これが avrdude に対応しているっぽい。僕自身よくわかりませんが、興味ある人は調べてみると強い人がまとめてくださっていると思います。

テストプログラムの書き込み

それではお試しLチカプログラムを書きますか。気分的にアセンブリしたいと思います。

それでは以下のようなコードを書きます。

.cseg
.org 0x0000
rjmp main

.equ DDRF  = 0x10
.equ PORTF = 0x11

wait:
    ldi r16, 0xFF
    ldi r17, 1
wait_loop:
    dec r16
    mul r16, r17
    mul r16, r17
    mul r16, r17
    mul r16, r17
    mul r16, r17
    cpse r16, r17
    jmp wait_loop
    ret

wait2:
    ldi r18, 0xFF
wait2_loop:
    dec r18
    call wait
    cpse r18, r17
    jmp wait2_loop
    ret

main:
    sbi DDRF, 4
loop:
    cbi PORTF, 4
    rcall wait2
    sbi PORTF, 4
    rcall wait2
    rjmp loop

これを blink.asm としたあとに、アセンブルして書き込みます。書き込み直前には RESET を GND に2回チョンチョンとショートさせ、一息置いてから avrdude を実行します。

$ avra blink.asm
AVRA: advanced AVR macro assembler Version 1.4.1
Copyright (C) 1998-2010. Check out README file for more info

   AVRA is an open source assembler for Atmel AVR microcontroller family
   It can be used as a replacement of 'AVRASM32.EXE' the original assembler
   shipped with AVR Studio. We do not guarantee full compatibility for avra.

   AVRA comes with NO WARRANTY, to the extent permitted by law.
   You may redistribute copies of avra under the terms
   of the GNU General Public License.
   For more information about these matters, see the files named COPYING.

Pass 1...
Warning : No .DEVICE definition found. Cannot make useful address range check !
Warning : No .DEVICE definition found. Cannot make useful address range check !
Warning : No .DEVICE definition found. Cannot make useful address range check !
Pass 2...
done


Assembly complete with no errors (3 warnings).
Segment usage:
   Code      :        27 words (54 bytes)
   Data      :         0 bytes
   EEPROM    :         0 bytes

$ avrdude -p m32u4 -c avr109 -P /dev/cu.usbmodem14301 -U flash:w:blink.hex

Connecting to programmer: .
Found programmer: Id = "CATERIN"; type = S
    Software Version = 1.0; No Hardware Version given.
Programmer supports auto addr increment.
Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices:
    Device code: 0x44

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9587 (probably m32u4)
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 "blink.hex"
avrdude: input file a.hex auto detected as Intel Hex
avrdude: writing flash (54 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 54 bytes of flash written
avrdude: verifying flash memory against blink.hex:
avrdude: load data flash data from input file blink.hex:
avrdude: input file blink.hex auto detected as Intel Hex
avrdude: input file blink.hex contains 54 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 54 bytes of flash verified

avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)

avrdude done.  Thank you.

以上のように書き込みが完了し、PF4(ボード上では A3) に差した LED が高速点滅していたら書き込み完了です。意外とすんなり行きました。

でも

2回チョンチョンするの面倒じゃないですか?意外と時間もシビアなのであまりやりやすい方法とは思えません。そこで、Atmel 純正ブートローダに差し替えて、Arduino もどきとしての記憶を消し去ってやりたいと思います。

ただし以下に要注意です。

  1. 書き込んだプログラムは自動起動しなくなる
    • リセット時は常にブートローダで止まります。
    • 通常はフューズビットを書き換えて HWE# ピンの電圧レベルでブートモードを切り替えられるのですが、Pro Micro では非常に残念なことに HWE# ピンが Low に固定されているため。
    • つまりこの操作を行うと不便になる。
    • でもまあ、開発目的で頻繁に ROM を書き換えるのであれば、この純正ブートローダの方が便利だと思いますけどね。
  2. avrdude は使えなくなる
    • dfu-programmer で書き込み/起動を行うようになります。
    • もちろん、また FT232RL を介して接続すれば avrdude で元のブートローダファームウェアに戻せます。

ブートローダの書き込み

先程と同様に FT232RL を繋げます。こちらにある DFU ブートローダーの zip を落とし、32U4 向けのものを書き込んでください。

$ avrdude -P ft0 -c ft232r -p m32u4 -U flash:w:ATMega32U4-usbdevice_dfu-1_0_0.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.10s

avrdude: Device signature = 0x1e9587 (probably m32u4)
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 "ATMega32U4-usbdevice_dfu-1_0_0.hex"
avrdude: input file ATMega32U4-usbdevice_dfu-1_0_0.hex auto detected as Intel Hex
avrdude: writing flash (32768 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against ATMega32U4-usbdevice_dfu-1_0_0.hex:
avrdude: load data flash data from input file ATMega32U4-usbdevice_dfu-1_0_0.hex:
avrdude: input file ATMega32U4-usbdevice_dfu-1_0_0.hex auto detected as Intel Hex
avrdude: input file ATMega32U4-usbdevice_dfu-1_0_0.hex contains 32768 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 32768 bytes of flash verified

avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF)

avrdude done.  Thank you.

出来たら回路から外し、USB ケーブルを繋げてみてください。

動作の確認/書き込み

その状態で lsusb をしてみて、Atmel Corporation ATm32U4DFU というような表示があれば動作に成功しています。

では続いて先程のLチカプログラムを書いてみましょう。

$ dfu-programmer atmega32u4 erase --force && dfu-programmer atmega32u4 flash blink.hex
$ dfu-programmer atmega32u4 launch --no-reset

ここで --no-reset が重要です。上で述べたとおり、単純にリセットするとまたブートローダにエントリーしてしまいますから、このオプションを付けることでアプリケーションが起動します。