USB接続で書き込めないDigispark ATtiny85のブートローダをアップデートして復活させる方法

# はじめに

自分の場合、「[**ここ**](https://www.amazon.co.jp/dp/B01KUNSFUS/)」で購入した6個の内、なぜか2個だけスケッチが書き込めなかった（ブートローダのアップデートもできない）。不良品として諦めていたが、ネットで「[Flashing the micronucleus](https://gist.github.com/Ircama/22707e938e9c8f169d9fe187797a2a2c#flashing-the-micronucleus)」を見つけ、実践したら無事に復活した。今回の記事は、ここに書かれている手順のフォローである。

当方の環境はMacだが、Windowsや他のOSでも基本的には同様のはずである。

## 1. 母艦となるArduinoとDigispark ATtiny85を接続する

当方はArduino Unoを使い、次のピンを接続した。（Uno以外でも[Arduino as ISP](https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoISP#use-arduino-as-isp)になれるボードであれば可）

| Arduino |	| Digispark<br> ATtiny85 | ATTINY85<br>description |
| :--: | :--: | :--: | :--- |
| D10 | → | P5 | RESET |
| D11 | → | P0 | SPI MOSI |
| D12 | → | P1 | SPI MISO |
| D13 | → | P2 | SPI SCK |
| 5V  | → | 5V | VCC |
| GND | → | GND | GND |

![IMG_7167.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/9b7a1819-927a-5d6d-febd-15368674cacf.png)

元記事には5VとGNDの記載は無く「DigisparkデバイスはUSB経由で電源を供給する」と書いてあるが、USBと接続するのはArduino Unoであって、この場合はDigispark ATtiny85はUSBと切り離されているので、Arduinoから電源を供給することにした。

## 2. ArduinoISPをアップロード

Arduino IDEの「スケッチ例」→「ArduinoISP」スケッチを母艦となるArduinoにアップロードする。
当然ながら、ボードは「Arduino Uno」を選択し、シリアルポートはArduino Unoが接続されているポートを選択する。

## 3. ボードマネージャの追加

Arduino IDEの「設定」→「追加のボードマネージャのURL」に「`https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json`」を追加する。また、「より詳細な情報を表示する」の「**書き込み**」に☑️**チェック**を入れ、[OK]で更新した設定を保存する。
![スクショ1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/f75f6340-8729-3ab7-9bdd-59b18bf77b90.png)

次に、Arduino IDEの「ツール」→「ボード」→「ボードマネージャー...」から「attiny」を検索し、「**attiny** by **David A. Mellis**」をインストールする。
![スクショ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/e6ffc8d0-6505-ec21-1067-a184a8023e38.png)


## 4. ArduinoISPを使用するように設定する

「ツール」→「ボード」→「ATtiny Microcontrollers」→「ATtiny25/45/85」を選択する
「ツール」→「プロセッサ」→「ATtiny85」を選択する
「ツール」→「クロック」→「Internal 1 MHz」を選択する
「ツール」→「シリアルポート」→ 適切なArduinoポートを選択する
「ツール」→「書込装置」→「Arduino **_as_** ISP」を選択する （<font color=red>注意</font>「ArduinoISP」ではない）
![スクショ3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/5a2a4db1-6e41-ea67-8a55-21e48c9cbc33.png)



## 5. LEDブリンクのスケッチをアップロードする

「スケッチ例」→「Basics」→「Blink」を選択。スケッチをコンパイルしてアップロードする。
`LED_BUILTIN`が未定義エラーとなる場合は、`#define LED_BUILTIN 1`を1行追加する。
（Arduino Unoを母艦としてDigispark ATtiny85にBlinkスケッチをアップロード）

```log:Upload　Log
最大8192バイトのフラッシュメモリのうち、スケッチが676バイト（8%）を使っています。
最大512バイトのRAMのうち、グローバル変数が9バイト（1%）を使っていて、ローカル変数で503バイト使うことができます。
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -pattiny85 -cstk500v1 -P/dev/cu.usbmodem14301 -b19200 -Uflash:w:/var/folders/h4/sspkr8xs1gx3_wxf2rjd2y_w0000gn/T/arduino_build_977121/Blink.ino.hex:i 

avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf"
         User configuration file is "/Users/username/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : /dev/cu.usbmodem14301
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATtiny85
         Chip Erase delay              : 400000 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : possible i/o
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    12     4    0 no        512    4      0  4000  4500 0xff 0xff
           flash         65     6    32    0 yes      8192   64    128 30000 30000 0xff 0xff
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e930b (probably t85)
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 "/var/folders/h4/sspkr8xs1gx3_wxf2rjd2y_w0000gn/T/arduino_build_977121/Blink.ino.hex"
avrdude: writing flash (676 bytes):

Writing | ################################################## | 100% 0.99s

avrdude: 676 bytes of flash written
avrdude: verifying flash memory against /var/folders/h4/sspkr8xs1gx3_wxf2rjd2y_w0000gn/T/arduino_build_977121/Blink.ino.hex:
avrdude: load data flash data from input file /var/folders/h4/sspkr8xs1gx3_wxf2rjd2y_w0000gn/T/arduino_build_977121/Blink.ino.hex:
avrdude: input file /var/folders/h4/sspkr8xs1gx3_wxf2rjd2y_w0000gn/T/arduino_build_977121/Blink.ino.hex contains 676 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.50s

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

avrdude done.  Thank you.
```

このとき、IDEの出力エリアに、スケッチのロードに使用された、コマンドライン引数とパスを含む完全なAVRDUDEコマンドが表示されたはずだ（上のLogだと3行目）。
また、この段階でエラーが出る場合は、母艦のArudinoとDigispark ATtiny85の接続に誤りがある場合か、Digispark ATtiny85が本当に死んでいる場合のどちらかであろう。配線はよく確認してもらいたい。

```shell:スケッチのロードに使用された、コマンドライン引数とパスを含む完全なAVRDUDEコマンド
<path>/avrdude -C<path>/avrdude.conf -v -pattiny85 -cstk500v1 -P<com port> -b19200 -Uflash:w:<path>/blink.ino.hex:i

```

**このコマンドラインをメモしておく**（適用なテキストエディタにコピーしておくとよい）。
Blinkのスケッチをアップロードしたが、コマンドライン（パス情報）を調べるのが目的であり、実は書き込むスケッチはなんでもよい。

> Blinkの書き込みの終わったDigispark ATtiny85は<font color=red>LED</font>が激しく点滅しているはずだ。本来1秒間隔のはずだが、これはclockとfusesの関係から起きている。今回の記事とは直接関係がないので、これについての説明は省略する。


## 6. ヒューズを読み取る

上のコマンドラインを以下のように書き換え、ヒューズ(fuses)を読み取る。書き換えるパラメタは最後の引数のところ。

```shell:ヒューズを読み取る
<path>/avrdude -C<path>/avrdude.conf -v -pattiny85 -cstk500v1 -P<com port> -b19200 -U lfuse:r:-:i
```

通常の操作では、ヒューズは E：FE、H：DF、L：F1 である必要がある。（このあたりは実はよく分かっていない）

自分のDigispark ATtiny85だと以下の内容だった。

```shell:Macで実行
$ /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -pattiny85 -cstk500v1 -P/dev/cu.usbmodem14401 -b19200 -U lfuse:r:-:i

（中略）

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e930b (probably t85)
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as FF
avrdude: reading lfuse memory:

Reading | ################################################## | 100% 0.01s

avrdude: writing output file "<stdout>"
:01000000629D
:00000001FF

avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OK (E:FF, H:DF, L:62)

avrdude done.  Thank you.
$ 
```


## 7. micronucleus firmwareのダウンロード

micronucleus firmwareを「[https://github.com/ArminJo/micronucleus-firmware/tree/master/firmware/releases](https://github.com/ArminJo/micronucleus-firmware/tree/master/firmware/releases)」からダウンロードする。

## 8. ダウンロードしたfirmware（ブートローダ）をアップロードする

メモしたコマンドラインを書き換えて、ダウンロードした`t85_default.hex`のアップロードとヒューズを設定する。

```shell:Flash　micronucleus　and　update　fuses
<path>/avrdude -C<path>/avrdude.conf -v -pattiny85 -cstk500v1 -P<com port> -b19200 -Uflash:w:<path>\t85_default.hex:i -U lfuse:w:0xf1:m -U hfuse:w:0xdf:m -U efuse:w:0xfe:m
```

元記事だとupgradesではなく_releases_を選択すると書いてあるが、自分は`micronucleus-1.11-upgrade.hex`を使ったが問題なくできた。

```shell:micronucleus-1.11-upgrade.hex
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -pattiny85 -cstk500v1 -P/dev/cu.usbmodem14401 -b19200  -Uflash:w:/Users/username/Developer/Arduino/DigisparkATtiny85/micronucleus-1.11-upgrade.hex:i -U lfuse:w:0xf1:m -U hfuse:w:0xdf:m -U efuse:w:0xfe:m
```

以上で、Digispark ATtiny85が復活したはずだ。Digispark ATtiny85を母艦から切り離し、直接USB接続でアップロードできるか試してもらいたい。


## 9. micronucleusのアップグレード

元記事だと、この後、必要に応じてmicronucleusをアップグレードできると書いてある。

```shell:（例）
micronucleus.exe /run upgradet85_entry_on_power_on_no_pullup_fast_exit_on_no_USB.hex

```

自分の場合は、以前紹介した「[Digispark ATtiny85 起動までの5秒を取り除く](https://qiita.com/nak435/items/67aca33ca49b6f328faa)」のブートローダに書き換えたが、USB接続で問題なく書き込めた。

```shell:Terminal
./micronucleus --run micronucleus-1.11-entry-jumper-pb0-upgrade.hex 
```

以上で完全復活である。


# 終わりに

ブートローダかヒューズの設定漏れだったのかと思うが、これまで「書き込めない」と諦めていた方の参考になれば幸いである。


以上