ATmega32u4 (4) – AT90USB1286

Date: 2021/12/11 (initial publish), 2022/07/30 (last update)

Source: jp/note-00038.md

Previous Post Top Next Post

TOC

基本のUSB AVRのATmega32u4AT90USB1286 を中心としたAVRチップに関して、ブートローダー関係を、1年半2年ぶりに見直し書きます。

開発環境

ATmega328P (2)の開発環境を再現すればOKです。

USB系のAVRで、変数名等の細かなところにとにかく疑問が出れば、/usr/lib/avr/include/以下を見れば分かります。。

FUSEビットのSET

FUSEビットは、プログラム設定されると「0」で、プログラム解除されると「1」です。 不揮発メモリーのリセット状態が1なので、こうされている理屈は分かるのですが、通常のPIN信号電位等と逆で混乱します。

電源投入時ちゃんとファームウエアーが立ち上がるには、BOOTRSTは1にして application reset (address 0x0000)としないといけません。 (BOOTRSTは0だと Reset vector = boot loader resetとなり、メモリー末尾に行きます。)

FUSEの設定変更(JTAG)

FUSEの設定変更は当然ですが要注意です。 よく考えずにJTAGをENABLEしたら、一部GPIOピンが動作しなくなって驚きました。

BOOT MODE (HWBE)のこと

USB系のAVRの起動の基本確認事項として、BOOTのモードの状況を確認します。

ARDUINO LEONARDO やTEENSY系の基板のPE2 (ALE,/HWBE)では、1K等で接地されています。だから、実際に出会うボードのリセットボタンが押された際のBOOT挙動は以下です。

ISP接続によるMCUのプログラミング

AVR-ISP II等を使うと、ブートローダーも何もない状態ででもISP接続でMCUに直接プログラム書き込みができます。

ブートローダーの書き換えにはこれを使います

確実ですが、接続が面倒でICピンを占領するので、定常的使用にはむきません。

TEENSY系でのISP接続でのブートローダー書き込み接続

TEENSY系はARDUINOのようなISP接続でのブートローダー書き込み専用コネクターはついていません. だから、AVRISP2から出ているケーブル端の以下のようなコネクター穴に、PIN-PINのアダプターを差し込みます。 (私の場合クリップケーブル端のデュポンコネクターの横穴はフラットケーブルの方向に向けてつけている。写真参照) 接続はこのPIN-PINのアダプター経由で連結したクリップをボード端の穴へ繋ぐのが簡単のようです。

つまり、私のアダプターは:

================= (RED LINE)
FLAT CABLE ======  YELLOW  2 - VCC    *  *   1 - MISO   RED
FLAT CABLE ======  BLACK   4 - MOSI   *  *   3 - SCK    GREEN
FLAT CABLE ======  BLUE    6 - GND    *  *   5 - RESET  WHITE (w/yellow clip)

この接続先は以下です。

TEENSY 2.0 (TOP VIEW)
                              MINI
                              USB
                    	+---+-----+---+
                    GND |*  |     |  *|Vcc
                    PB0 |*  |     |  *|PF0  ADC0
SCLK 3 GREEN ------ PB1 |@  |     |  *|PF1  ADC1
MOSI 4 BLACK ------ PB2 |@  +-----+  *|PF4  ADC4
MISO 1 RED -------- PB3 |@  *     *  *|PF5  ADC5
                    PB7 |*           *|PF6  ADC6
                    PD0 |*           *|PF7  ADC7
                    PD1 |*           *|PB6  ADC13
                    PD2 |*           *|PB5  ADC12
                    PD3 |*           *|PB4  ADC11
                    PC6 |*           *|PD7  ADC10
                    PC7 |* * @ @ @ * *|PD6  ADC9 (LED) -- low V for analog
                        +-------------+
                           ^ ^ ^ ^ ^
                    PD5 ---+ | | | +---PD4  ADC8
VCC 2 YELLOW ----------------+ | |
GND 6 BLUE   ------------------+ |
RST 5 WHITE  --------------------+
TEENSY 2.0++ (TOP VIEW)
                              MINI
                              USB
                    	+---+-----+---+
                    GND |*  |     |  *|Vcc
                    PB7 |*  |     |  *|PB6
                    PD0 |*  |     |  *|PB5
                    PD1 |*  +-----+  *|PB4
                    PD2 |*           @|PB3 ---- RED   1 MISO
                    PD3 |*           @|PB2 ---- BLACK 4 MOSI
                    PD4 |*           @|PB1 ---- GREEN 3 SCLK
                    PD5 |*           *|PB0
              (LED) PD6 |*           *|PE7
                    PD7 |*           *|PE6
                    PE0 |*           *|GND
                    PE1 |*           *|AREF
                    PC0 |*           *|PF0
                    PC1 |*           *|PF1
                    PC2 |*           *|PF2
                    PC3 |*           *|PF3
                    PC4 |*           *|PF4
                    PC5 |*           *|PF5
                    PC6 |*           *|PF6
                    PC7 |*   @ @ @   *|PF7
                        +-------------+
                             ^ ^ ^
                             | | |
VCC 2 YELLOW ----------------+ | |
GND 6 BLUE   ------------------+ |
RST 5 WHITE  --------------------+

ここで、ボードの横の配線取り回しの順番は時計回りで見ると両者同じですが、 コネクター側から見た順番が逆です。間違って繋ぐと、毎回IDが違うと言われて 正しくないが同じIDが読み出されるのでノイズ問題じゃないようで頭を抱え込みました。 後でつなぎ違いに気づいたときは、こわれそうにない間違いでほっとしましたが。。。

TEENSY系でのISP接続でのブートローダー書き込みプログラム

各種ブートローダーを、ISP接続でATmega32u4やAT90USB1286に導入しFUSE設定もする スクリプトを作成しました。一式を、 https://github.com/osamuaoki/osamuaoki-hugo-proj の 中の005_teensy以下に起きます。その中で./setup-teensy とすると、作業環境が準備でるようにしました。

さて、まず./avrdude...コマンドでavrdudeを使い、完全なチップの初期化のためにISP接続してFUSE設定とブートローダーの導入をします。

TEENSY 2.0 ISPケーブル接続例

NOTE: 上記写真で、評価ボードに一見電源供給をしていないように見えますが、使用したAVR-ISP IIは以前書いたように改造済みですのでちゃんと電源は来ています。 改造しない純正品のままだと、別途USBケーブルを繋ぎ、それをUSB電源アダプターにでも繋ぐ必要があります。

ブートローダーによるMCUのプログラミング

通常のファームウエアー書き換えは、すでに書き込まれたブートローダーを使うのが便利です。

ブートローダー起動時にUSB接続されたデバイスがどういうデバイスとしてホストに認識されるかにより、USB AVRのブートローダーには基本3種類のケースがあります。

結論から言うと、MCUに入れるブートローダーとホスト側のツールは以下です:

動作検証

基本、ファームウエアーを導入し動作させて確認するのが一番です。

TEENSY 2.0 の動作検証メモ

実験的にTEENSY2.0で確認したのは以下です。電圧印加にはVR等をPIN二つないでます。

手動配線キーボードの配線確認メモ

このあと触れるQMKを動かす用に準備した手動配線キーボードの配線確認をしました。

まず、基板上のLEDの動作を確認します。(avrmon: B D6 OH) 過電流にならないように、LEDを消します。(avrmon: B D6 OL)

キーボードのハンド配線の場合、トラブルしがちです。実際1つ断線がありました。

ダイオードの方向がCOL2ROWの場合の待機状態は:

この状態では、スイッチを押しても入力変化(DC)はありません。

次に、COLUMN配線のチェックをするために、ひとまず全ROWをHIGH選択します。

この場合、同じCOLUMNのキーは区別できませんが、COLUMNに対応するBITがLOWになるので、スイッチ操作でスイッチの動作が確認できます。(DC)

私の場合、題6COLUMNが変化しませんでした。MCUボード上の対応ピンはMCUのPULL-UPが有効なので5Vきっちり出ますが、その先の電圧が0付近でばたばたしています。

問題ピンに繋がった配線をキーボードから切り離し電圧を測ってもまともに電圧が出ません。

どうも、C3の芋はんだか途中断線です。

次に、ROW配線のチェックをするために、ひとまず全ROWをLOW選択します。

そして、1つのROWだけをHIGH選択し対応するROWにあるキースイッチを押すとCOLUMN側に変化があることを確認します。 さらに、関係のないキースイッチを押してもCOLUMN側に変化がないことを確認します。

最後に、LEDの動作と明るさの確認をします。

各種ブートローダの状況確認メモ

Arduino系のブートローダー

Arduinoのブートローダー

ARDUINOは元々シリアル接続して書き換えます。USB-SERIAL変換接続が、ARDUINO UNOボードではFT232のような専用変換チップではなくサブMCUとなるATmega32u2に使われています。

キーボードプロジェクトを考えるので、シリアルに見えるArduinoのブートローダーあまり優先順位は高くありませんが、状況を確認します。

現在巷にあふれるARDUINOもどきは、FT232をUSBシリアル専用変換に使っていたARDUINO UNO の前世代の設計ベースで、FT232をよりやすいCH340に使っています。

こんなARDUINOもどきも含め、すべてのARDUINO UNOやARDUINO MINIのような、ATmega328P系のボードはシリアル通信でファームウエアーを書き換えるようになっています。 これはUSBを直接サポートするATmega32u4系のARDUINO MICRO, PRO MICRO、LEONARDOも同じプロトコルで、出荷時シリアル接続(CDC)のブートローダーが導入されています。

REPO:

LUFAは現在 LUFA-170418-125-gd10535a4bなので当時の11109と違い、LUFAの11109 以降を使うと、 32u4 Caterina はCaterinaをパッチしないとうまく動作しない などと言う記事もありますが、それからだいぶ経つので2022年の最新版なら大丈夫かな。

ちなみに本物のUNOには、USB-SERIAL変換をするファームウエアーが導入されていたサブMCU(Atmega8u2) が搭載されています。 このサブMCU自体の書き換えにもちいるブートローダーはシリアル変換ファームウエアーとともにArduino Uno and Mega 2560 Firmwares for the ATmega8U2にあります。 これは通常のARDUINOの書き換えで書き込まれないようにブートローダーはDFUです。

Sparkfanの改造版Caterina (4KB) – CDC ブートローダー

Sparkfanの改造版Caterinaの特徴

REPO:

Sparkfanの改造版Caterinaはいい感じのCDCですが、TeensyのLEDに対応するものがなかったので、リビルドはトライしていません。

Katiana (4KB) – CDC ブートローダー

googleで興味ある、フォーラムへのポスト を見つけました。 LUFAの2017ごろをベースに、Arduinoの改変を含め、USBシリアル番号等を含めた各種独自改造 をしています。 カウントダウンすることで、クロックのプリスケーリングを 1:1以外に設定することにも対応し、そえでも4KBに収まっ ているそうです。ただAtmega32u4専用だそうです。 GCC 5.4対応のPRは要チェックです。

REPO:

TeensyのLEDに対応するものがなかったので、リビルドはトライしていません。

LUFA (4KB each) – CDC, DFU, HID ブートローダー

LUFAはCDC, DFU, HID の3種類すべてのブートローダーを提供しています。

最新のLUFAベースで私がPRしたLUFAのブランチを、さらにBUILD用にパラメーター変更し 生成したHEXやビルドログもコミットしたLUFAのブランチを作りました。

ビルドは以下のような感じで終わります。これが実際のAVR上のメモリサイズのようです。(Hexファイルに普通のsizeコマンドすると少し大きな数字がでる。)

...
avr-size --mcu=atmega32u4 --format=avr BootloaderCDC.elf
AVR Memory Usage
----------------
Device: atmega32u4

Program:    3846 bytes (11.7% Full)
(.text + .data + .bootloader)

Data:        164 bytes (6.4% Full)
(.data + .bss + .noinit)


 [INFO]    : Finished building project "BootloaderCDC".

すべてのビルド結果をまとめると以下で、いずれも4KBのブート領域確保が必要でした。

Program Data board mcu bootloader programmer
3846 164 teensy2 atmega32u4 BootloaderCDC avrdude -c arduino
3882 133 teensy2 atmega32u4 BootloaderDFU dfu-programmer
2118 86 teensy2 atmega32u4 BootloaderHID hid_bootloader_cli
3790 164 teensy2pp at90usb1286 BootloaderCDC avrdude -c arduino
3812 133 teensy2pp at90usb1286 BootloaderDFU dfu-programmer
2124 86 teensy2pp at90usb1286 BootloaderHID hid_bootloader_cli

ここで、最近のavrdudeはDFUもサポートしているので、dfu-programmer とあるところはavrdude -c flip1 としても同じです。

比較的機能が少なく小さいHIDブートローダーでも、わずかではありますが2KBを越えているので、ブート専用領域に4KBを取っておく必要があります。

メモリーが少ないATmega32u4では下記のNanoBoot(512Bに収まる)を使います。

hid_bootloader_cli

LUFAのhid bootloaderに対応する、ホストPC側のプログラムです。 Debianでコンパイルするには、libusb-devパッケージが導入されている 必要があります。

nanoBoot改LED (512B) – HID ブートローダー

元々のnanoBoot は512 Byteに収まる小さな優れものBootloaderです。これは LUFA HIDブートローダーを徹底的にハンドオプティマイズしたものです。 ただし、オリジナルはCKDIV8と非設定限定で、LEDでの ブートローダーの起動確認もできませんでした。本物の Teensy 2.0 と同じFUSE設定では使えませんでした。それにつけても 非常に丁寧にコメントが書き込まれているアッセンブラーの 手動最適化手法が満載の素晴らしいコードとコメントでした。

自分が欲しい機能のCKDIV8対応と、LED点灯でのブートローダー の起動確認を何とか押し込むように、限られたスペースに押し込む パズル感覚のコーディングでしました。更にコード縮小をし、 sigprof さんが途中までしていた「String Descriptor」にも対応をしながら 512 Bに収まるようになりました。アップストリームにはまだマージ されていません。この導入には私がフォークしPRしている 私のnanoBootを参照ください。

すでに以前sigprof提案の アップロードサイズ制限はマージされているので、512Bに収まる範囲で かなり機能の良いbootloaderとなっていると思います。

これで中華コンパチ評価ボードを本物の Teensy 2.0 でも本物と同じユーザー向けのメモリー量を確保して使えます。

私のレポの、led branchに私のソースの最新版を、led-hex branchに最新版の コンパイル結果のHEXファイル集 までコミットしています。

各種ブートローダーの比較

QMKを導入すると、同時にAVR開発環境も整えられ、よさそうなブートローダーも拾ってきてくれます。

メモリーがタイトなatmega32u4は上記のnanoBootが良いと思いますが、AT90USB1286は余裕があるので選択肢があります。でも一筋縄ではいきませんでした。

余談:DFU色々

DFUにはATmel専用みたいで古くからあるdfu-programmerがあります。

これ以外に、DFU 1.0 and DFU 1.1specifications対応でSTM32対応しているdfu-utilもあります。

どうも一番新しいfwupdに入っていてDFU 1.0, DFU 1.1 にくわえ ST DfuSe vendor extensionに対応しているdfu-toolがあります。この辺、基本AVRはdfu-programmerでいきます。

ここで、DfuSeが"DFU STによるVender Extension(ベンダー拡張)“の略と分かりちょっと納得。

STM32系のARMチップの際にでも他の2つは使ってみます。

Previous Post Top Next Post