Memoteki

メモ的な何か。https://memoteki.net/about をお読みください。

Arduino AVR

ATmega328Pにoptifixを書き込む方法

2017/12/22

ブートローダを書き込んでいない、生のATmega328Pに「optifix」と呼ばれるoptibootの改良版のブートローダを書き込む方法をメモしておきます。

概要

生のATmega328Pに「optifix」と呼ばれるoptibootの改良版のブートローダを書き込む手順を回路図つきで紹介しています。
この方法ではArduino UNOが必須です。


2017年12月22日追記
2017年12月現在、ArduinoのIDEからブートローダを書き込む機能がありますのでこの方法は新しくありません。

手順

配線

http://arduino.cc/en/Tutorial/ArduinoToBreadboard
ここに書いてある方法でArduino UNOと書き込み対象のマイコンを接続していきます。

必要な物は

・ブレッドボード
・Arduino UNO
・ATmega328P
・10kΩの抵抗
・22pFのコンデンサ
・16MHzのクリスタル
・ジャンパ

です。

BreadboardAVR

optifixのダウンロードと編集

http://arduino.cc/forum/index.php/topic,28733.0.html
ここにあるoptifix.zipを用います。

そのままでは使用できないので、optifix.zipを展開して中のoptiloader.hを書き換えます。

#include <WProgram.h>

typedef struct image {
    char image_name[30];	       /* Ie "optiboot_diecimila.hex" */

これを

#include <Arduino.h>

typedef struct image {
    char image_name[30];	       /* Ie "optiboot_diecimila.hex" */

このように1行目を書き換えて保存します。

改行コードの関係でメモ帳は避けた方がよいです。

あとはArduinoIDEで先ほどのoptifix.pdeを開いて、シリアルモニターを開き、通信速度を19200baudに設定し、スケッチをアップロードして次のように表示されれば終わりです。

OptiFix Bootstrap programmer.
2011 by Bill Westfield (WestfW)

Starting Program Mode [OK]

Reading signature:950F
Searching for image...
  Found "optiboot_atmega328.hex" for atmega328
  Start address at 7E00
  Total bytes read: 508

Setting fuses for programming
  Lock: 3F FFE000  Low: FF FFA000  High: DE FFA800  Ext: 5 FFA400

Programming bootloader: 512 bytes at 0x3F00
  Commit Page: 3F00:3F00
  Commit Page: 3F40:3F40
  Commit Page: 3F80:3F80
  Commit Page: 3FC0:3FC0

Restoring normal fuses
  Lock: F FFE000

Type 'G' or hit RESET for next chip

あとはもとのマイコンと入れ替えてBlinkなど適当なテストプログラムが動く事を確認できると思います。

元のマイコンをはずして書き込む事も可能です。

ArduinoUSBSerial

fuseがUno標準のoptibootとoptifixでは異なるようです。


フューズの違い
フューズの設定はUnoとOptifixでは微妙に違います。EESAVEだけですので、EEPROM使う人はちょっと気をつけてください。

Uno: Low:FF HI:D6 Ext:FD
Optifix: Low:FF HI:DE Ext:FD

簡単!ATmega328Pにブートローダを書きこむ | N.Yamazaki's blog

EESAVEはFlash書き込み時にEEPROMを消すか、ということらしいです。


で、Fuseビットをよくよく見ると「EESAVE」というのがあって
これを設定することでFlash書き込み時にEEPROMの消去を阻止できることが
ようやく分かった。
マイコン風聞録 - *: EESAVE

実際に、Arduino UNOに載ってたATmega328Pのfuseを読んでみるとhFusesは0xD6でした。

しかし、boards.txtを読んでみると、

uno.name=Arduino Uno
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.speed=115200
uno.bootloader.low_fuses=0xff
uno.bootloader.high_fuses=0xde
uno.bootloader.extended_fuses=0x05
uno.bootloader.path=optiboot
uno.bootloader.file=optiboot_atmega328.hex
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.core=arduino
uno.build.variant=standard

optibootだけどhFusesがDEになってますね。

0xDEなので1101 1110。
0xD6は1101 0110。

# ATMega328P fuse bits (fuse bits for other devices are different!):
# Example for 8 MHz internal oscillator, default setting
# Fuse high byte:
# 0xd9 = 1 1 0 1 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000)
# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0
# | | | | | +-------- BOOTSZ1
# | | | | +---------- EESAVE (0 : preserve EEPROM over chip erase)
# | | | +-------------- WDTON (0 : Watchdog timer always on)
# | | +---------------- SPIEN (1 : serial programming is disabled)
# | +------------------ DWEN (0 : debugWIRE enabled)
# +-------------------- RSTDISBL (0 : RESET pin is disabled)

【備忘】ATmega328P fuse bit default setting : 湧雲日記

ということがわかったので

 1 1 0 1 1 1 1 0 = 0xDE (optiboot)
 ^ ^ ^ ^ ^ ^ ^ ^------ BOOTRST (boot reset vector at 0x0000)
 | | | | | | +-------- BOOTSZ0
 | | | | | +---------- BOOTSZ1
 | | | | +------------ EESAVE   (0 : preserve EEPROM over chip erase)
 | | | +-------------- WDTON    (0 : Watchdog timer always on)
 | | +---------------- SPIEN    (1 : serial programming is disabled)
 | +------------------ DWEN     (0 : debugWIRE enabled)
 +-------------------- RSTDISBL (0 : RESET pin is disabled)

 1 1 0 1 0 1 1 0 = 0xD6 (Arduino UNO)
 ^ ^ ^ ^ ^ ^ ^ ^------ BOOTRST (boot reset vector at 0x0000)
 | | | | | | +-------- BOOTSZ0
 | | | | | +---------- BOOTSZ1
 | | | | +------------ EESAVE   (0 : preserve EEPROM over chip erase)
 | | | +-------------- WDTON    (0 : Watchdog timer always on)
 | | +---------------- SPIEN    (1 : serial programming is disabled)
 | +------------------ DWEN     (0 : debugWIRE enabled)
 +-------------------- RSTDISBL (0 : RESET pin is disabled)

つまり、boards.txtの通りだと、Flash書き込み時にEEPROMが消去されてしまう。
消して困る場合は、hFusesを0xD6に書き換えれば良いと思われます。(未検証)

fusesについてはこのページが便利です。
http://www.frank-zhao.com/fusecalc/fusecalc.php?chip=atmega328p

マイコンにはシール貼っておくとかなり便利です。

http://homepage1.nifty.com/ORBIT/etc/orbit-a01_arduino_sticker.pdf

このPDFとかいい感じです。

一応ミラー。

orbit-a01_arduino_sticker.pdf

このブートローダだと16MHzのクリスタルを必ずつけないといけないので注意してください。

USBシリアル変換モジュールをブレッドボードに載せたりすると楽かもしれないです。

https://www.sparkfun.com/products/9716
ここにある回路図を参考にすればFT232RL(秋月で300円)と少しのパーツだけで作れるから安上がり…かな?

今度やってみます。

-Arduino, AVR
-, , , , , , , , ,