ATmega32u4 (2)

Date: 2020/03/29 (initial publish), 2022/03/23 (last update)

Source: jp/note-00020.md

Previous Post Top Next Post

TOC

今回も引き続き基本のUSB AVRの ATmega32u4 を中心としたAVRチップのプログラム方法とその環境に関して、 調査と情報の整理をします。

ISP接続

Arduino系の開発ボードなら、6pinのICSPコネクターが付いているので 1pin(ポチマーク)側にAVRISP mkIIからのISP接続フラットケーブルの 赤線側を合わせて挿せば良い ので簡単でした。

ATmega32u4の開発ボードの SparkFun Pro MicroTeensy 2.0 や、AT90USB1286の開発ボードの Teensy 2.0++ などやそのコンパチ品はICSPコネクターが付いていないので 「直結接続」が必要です。

「直結接続」のために、以下の写真のように片側にクリップ、 片側にオスやメスのデュポンコネクターが付いたワイヤーを準備 しました。(AVR系をAVRUSP mkIIでISP書き換えするにはオスの デュポンコネクター版だけで充分ですが、将来ARM系のSTM32F等を ST-LINK/V2等で書き換えするのにはメスのデュポンコネクター版が あると便利そうなので両方準備してみました。)

直結用クリップワイヤー

左右逆にしないことが大事なので、接続関係をここにまとめます。

ISP接続フラットケーブルのコネクター (赤線側上です。コネクター穴側から見た「左図」が大事!)

                  RED SIDE 赤線側
BTM VIEW コネクター穴側                 TOP VIEW
VCC  2  1 MISO                        MISO 1  2 VCC
MOSI 4  3 SCK                         SCK  3  4 MOSI
GND  6  5 RST                         RST  5  6 GND

(こっちがメイン)
Looking from                          Looking from the
the hole side                         back of the connector hole

以下、開発ボードの端子はチップが載っている表側(TOP側)から、 USBコネクターを「左」に置き見て、「半時計回り」(CCW)で 「0スタート」(逆方向は-1スタート、角からスタート、重複命名有り) で位置表記し、ISPコネクターの端子は赤線側を上にして、 コネクター穴側から見て位置表記することとします。

Teensy 2.0開発ボードの場合(所有):

                              MINI
下                            USB                 上
                    	+---+-----+---+
Interior            GND |*  |     |  *|Vcc              Interior
PE6         SS      PB0 |*  |     |  *|PF0  ADC0        AREF
AIN0        SCLK    PB1 |*  |     |  *|PF1  ADC1          |
INT6        MOSI    PB2 |*  +-----+  *|PF4  ADC4          |
  +->       MISO    PB3 |*  *     *  *|PF5  ADC5        <-+
RTS OC1C    OC0A    PB7 |*           *|PF6  ADC6
SCL OC0B    INT0    PD0 |*           *|PF7  ADC7
SDA         INT1    PD1 |*           *|PB6  ADC13   OC1B    OC4B
RXD1        INT2    PD2 |*           *|PB5  ADC12   OC1A    ~OC4B
TXD1        INT3    PD3 |*           *|PB4  ADC11
~OC4A       OC3A    PC6 |*           *|PD7  ADC10   T0      OC4D
OC4A        ICP3    PC7 |* * * * * * *|PD6  ADC9    T1      ~OC4D  (LED)
                        +-------------+
                           ^ ^ ^ ^ ^
CTS         XCK1    PD5 ---+ | | | +---PD4  ADC8    ICP1
VCC * -----------------------+ | |
GND * -------------------------+ |
RST * ---------------------------+
                                右

Teensy 2.0++開発ボードの場合(所有):

                              MINI
下                            USB                 上
                    	+---+-----+---+
                    GND |*  |     |  *|Vcc
     OC1C   OC0A    PB7 |*  |     |  *|PB6  OC1B
SCL  OC0B   INT0    PD0 |*  |     |  *|PB5  OC1A
SDA  OC2B   INT1    PD1 |*  +-----+  *|PB4  OC2A
RXD1        INT2    PD2 |*           *|PB3  MISO
TXD1        INT3    PD3 |*           *|PB2  MOSI
ICP1                PD4 |*           *|PB1  SCLK
XCK1                PD5 |*           *|PB0  SS
T1 (LED)            PD6 |*           *|PE7  INT7    AINI
T0                  PD7 |*           *|PE6  INT6    OC1A    ~OC4B
                    PE0 |*           *|GND
                    PE1 |*           *|AREF
                    PC0 |*           *|PF0  ADC0
                    PC1 |*           *|PF1  ADC1
                    PC2 |*           *|PF2  ADC2
T3                  PC3 |*           *|PF3  ADC3
     OC3C           PC4 |*           *|PF4  ADC4
     OC3B           PC5 |*           *|PF5  ADC5
     OC3A           PC6 |*           *|PF6  ADC6
ICP3                PC7 |*   * * *   *|PF7  ADC7
                        +-------------+
                             ^ ^ ^
CTS         XCK1             | | |
VCC * -----------------------+ | |
GND * -------------------------+ |
RST * ---------------------------+
                                右

参考:Pro Micro開発ボードの場合(非所有、推定):

参考:Arduino Micro開発ボードの場合(非所有、推定):

以下では、外部電源接続無しでISP接続で読み書きできるよう にした改造AVRISP mkIIを 使っています。

teensy 2.0 compat.

ブレッドボードに挿し一部クリップ接続で検査!

ISP接続 ブレッドボード+クリップ

$ sudo avrdude -c avrisp2 -P usb -p m32u4 -v
....
avrdude: stk500v2_command(): command failed
avrdude: stk500v2_program_enable(): bad AVRISPmkII connection status: Unknown status 0x00
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.


avrdude done.  Thank you.

うーん、前に何か悪いことしてチップを壊したかな?ちょっと不安。 ブレッドボードは接触によく不安があるし、挟むタイプのクリップは 挟む線が太いと外れやすくここも接触に不安がありました。

そこで不安を解消するように、開発ボードがPIN付き基板なので メス+オスのデュポンコネクターのワイヤーでしっかり接続して、 再チャレンジしました。

ISP接続 ワイヤー

ちなみに、上の写真の左下のJフック型端子は裸ボードやPIN端子との 結線に意外と使い勝手が良かったのが意外でした。メスデュポンと Jフック型端子をつないだISPコネクター線を今度の機会に作りたく なりました。

$ sudo avrdude -c avrisp2 -P usb -p m32u4 -v -F
...

avrdude: Device signature = 0x1e9587 (probably m32u4)
avrdude: safemode: lfuse reads as 5F
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as C5

avrdude: safemode: lfuse reads as 5F
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as C5
avrdude: safemode: Fuses OK (E:C5, H:D9, L:5F)

avrdude done.  Thank you.

まずは良し良しでした。とにかく素人電子工作では接触不良に要注意です。 さらに-U lock:r:-:hをつけると、0xC5コードが出て文字化けした後、 0xffと表示されます。

ちなみに、正規品はブート領域が4KBではなく、512Bで、BOD設定も違います。

Teensy 2.0++ compat.

こっちはピン無し裸ボードなので、上記の直結用クリップワイヤーを 使ってつなぎました。

$ sudo avrdude -c avrisp2 -P usb -p usb1286 -v -F
.....
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e9782 (probably usb1287)
avrdude: safemode: lfuse reads as 4F
avrdude: safemode: hfuse reads as DD
avrdude: safemode: efuse reads as F5

avrdude: safemode: lfuse reads as 4F
avrdude: safemode: hfuse reads as DD
avrdude: safemode: efuse reads as F5
avrdude: safemode: Fuses OK (E:F5, H:DD, L:4F)

うまくはつながっているようですが、チョット変です。上記だと;

正直、AtmelのDFUやLUFAのDFUが約4KBあるのに、なぜこの開発ボードの チップは2KBのブート領域なのかはチョット不思議です。安売りしていた のはこれが原因かな?(他のFUSE値は大きな問題ではないとは考えます。)

純正Atmel DFUは4KBより少し大きいのも気になります。

Fuse設定のあるべき姿の考察

Fuse設定のあるべき姿を考えてみました。分かるところから押さえます。 まずATmega32u4を考えます。

P354-P355にかかれたチップのデフォルトは:

です。これを基本に、理由毎に変更します。

CKDIV8は出荷時にプログラムされている(=0)がTeensyの設定でも採用 されています。一見チョット不安になりましたが、実際にはスタート アップコードにCLKPR = 0x80;CLKPR = 0;を置くのがTeensyの標準の ようで分周を1に戻すのでので、これは問題ないとみました。

まず、5V 16 MHz Crystal使用でBODをするから、以下確定です(P30,P31)。

だから

HFUSEは JTAGは使わないので外す (これはTeensyもLeonardo等のArduino系 も同じ設定)ことにして、後はブートローダーのサイズとリセット挙動の 関係で決めます。

リセットボタンは押し際には現在実行中のプログラムが止まり、さらに 押したままでは何も起こらず、離した際にリセットがMCUにかかります。

まず、「Teensyの環境では、電源投入時に先頭アドレス0x0000に飛び アプリケーションのファームウエアーが動き、リセットボタンを押して 離した際にはHIDデバイスとなるbootloaderが始動する」というのが基本です。 PCのリセットボタンのイメージでアプリケーションが再起動することは ないので要注意です。bootloaderがアプリケーションのファームウエアー を導入した後ではじめてそのアプリケーションのファームウエアーが動く ようです。純正のTeensyは、アドレス0x000にアプリケーションとして Blinkが、アドレス0x8000-0x0200 = 0x7E00 Byte (32KB - 512B) に bootloaderとしてHIDデバイスとなるbootloaderが導入されるようです。

一方、「Arduinoの基本環境では、電源投入時に先頭アドレス0x0000に飛び アプリケーションのファームウエアーが動く」まではTeensyとも同じです が、「リセットボタンを押して離した際にCIDデバイス(仮想シリアル)と なるbootloaderが始動」しますが、 実際にbootloaderがアプリケーションのファームウエアーを導入した際に は導入した後はそのアプリケーションのファームウエアーが動くのでしょう が、「8秒間たってもbootloaderがアプリケーションのファームウエアーを 導入しないときにも先頭アドレス0x0000に飛びアプリケーションのファーム ウエアーが動く」ようです。純正のArduino(Leonardo, micro)は、アドレス 0x8000-0x1000 = 0x7000 Byte (32KB - 4KB) にbootloaderとしてCIDデバイス (仮想シリアル)となるbootloader(Caterina)が導入されるようです。さらに、 SPARKFUNが公開している改良bootloader(Caterina改)では、「リセットボタン をダブルクリックすると待ち時間無しで先頭アドレス0x0000に飛びアプリ ケーションのファームウエアーが動く」ようです。まとめると、リセット時 にbootloader が動くのはTeensyと同じですが、Arduino系のbootloaderは賢く条件を満たせ ばアプリケーションのファームウエアーがリセットされた状態で最初から 動くようになっています。

この辺の違いを認識しないと、各種情報を読む際に混乱します。

チップのHFUSEとEFUSEのデフォルトはBOOTRST非設定(リセット=1)、 HWBE設定(セット=0)となっています。

どの開発ボード(teensy・Pro Micro・Arduino Leonardo・Arduino Micro) でも、ALE/HWB pinが接地されています。この場合、Boot Reset Fuse (BOOTRST)の設定によらず、teensyのデフォルトのようにHWBE FUSEビット が設定(セット=0)されるとリセットボタンを押して離した際に有無言わず ブートローダーに飛びます。一方、Pro Micro・Arduino Leonardo・ Arduino MicroデフォルトのようにHWBE FUSEビットが非設定(リセット=1) でBoot Reset Fuse (BOOTRST)を設定(セット=0)としてもリセットボタンを 押して離した際にブートローダーに飛びます。

もしHWBE FUSEビットを非設定(リセット=1)にデフォルトから変更すると、 Boot Reset Fuse (BOOTRST)を設定(セット=0)のままだと、リセットが かかるとアプリのファームウエアーのアドレス$0000に飛ぶようになり ます。

ポイントは普通の開発ボードでは、TeensyかArduinoのFUSE設定の組み合 わせ方を混ぜなければ良いようです。

もちろん、HWBE FUSEビット非設定(リセット=1)に変更して、Boot Reset Fuse (BOOTRST)設定(セット=0)して、$0000に置くファームウエアーに ハードリセット時に飛ばせますが、かなり特殊です。$0000に置く ファームウエアーが、ブートローダーに後で飛べるようにでもして おかないと不便ですので、、、

4KBの標準的なブートローダーだと:

512BのnanoBoot/teensyブートローダーだと:

さて残るはEFUSEです。ハイニブル等は変更理由はないので決めるべきは BOD電圧です。(EFUSEは上位4ビットは何を書いても0xF->0xCになります) します)

HWBE非設定(=1 Caterina系)

HWBE設定(=0 Teensy系)

電圧が低くなると、最高動作周波数が落ちるのでプリスケーラー 設定関係(CLKPRレジスターや、CKDIV8ヒューズ)も配慮がいるかな?

落ちにくくするためにBOD=2.4V teensyを真似しましょう。

LOCKの上2ビットは無効なのでややこしいです。

デフォルトは0xEC=0x1Cです。ブートローダーを覗けません。書き換え禁止。 0xFF=0x3Fは一切ロック無しです。 0xEF=0x2FとするとブートローダーへのSPM書き込みを禁止しますね。 0xCF=0x0FとするとブートローダーへのSPM書き込みを禁止の上にブートローダーを覗けませんね。

アプリケーションやEEPROMの書き込み・制約・。書き換え禁止は興味無いですね。 趣味のデバイスは基本ロック不要です。

ATmega32u4のFuse設定のあるべき姿

Caterina系 4KB

teensy系 512B

AT90usb1286のFuse設定のあるべき姿

ブートローダーの大きさ次第です。

ちなみに以下は参考情報です。

Fuse関連で困ったらは、 fusecalcPro Micro クローン ATmega32U4を使うAVR fuse でも見ましょう。

Previous Post Top Next Post