ArduinoのBootloader書き込む際のメモ

秋月電子で購入できるATMEGA328P等は、基本的にBootloaderがかかれてないものです。
これを書き込めるようにするために、先人達が色々な方法を試されていたので、
メモしときます。
それぞれの仕組みとかも勉強用に。


◆一番簡単な方法
Arduino Duemilanove + YCIT版avrdude + Windows
http://www.geocities.jp/arduino_diecimila/bootloader/senshu_avrdude.html


色々迷ったあげく、これで一瞬でできました。
やり方としては、DuemilanoveのFT232RL付近にあるショートされた穴にピンヘッダをつけて、
Duemilanoveをライターとして使う方法です。
ただ、これは簡単すぎて勉強にならなかったです。。。


1. Readしてみる
Programmerは(diecimila)FT232 Sync Bitbangを指定
DeviceはautoでDevice Readボタンを押す


2. Fuse書き込み
ATmega328Pの場合は,hfuse = DA,lfuse = FF,efuse = 05


3. ブートローダ書き込み
ATmega328Pの場合はarduino-srcの中とかにあるATmegaBOOT_168_atmega328.hexを書き込み


4. ロックビットの書込み
Lock Bit欄に OFにセットして書き込み


CUIで頑張る
Arduino Duemilanove + YCIT版avrdude + Mac
http://zampoh.cocolog-nifty.com/blog/2009/03/arduino---atmeg.html
参考: http://www.geocities.jp/arduino_diecimila/bootloader/index.html


環境は上と同様ですが、
こちらはGUIのツールを使わずコマンドラインでやる方法です。
手順は、avrdude-serjtagのBUILD-linmac.txtに大体書いてますが、メモしときます。

1. FTDIドライバ, avrdude, avrdude-serjtag, arduinoをDL。
FTDIドライバ ... http://www.ftdichip.com/Drivers/D2XX.htm
avrdude ... http://ftp.twaren.net/Unix/NonGNU/avrdude/avrdude-5.10.tar.gz
avrdude-serjtag ... http://nmj.sumomo.ne.jp/suz-avr/serjtag/avrdude-serjtag04m.zip
arduino ... http://arduino.googlecode.com/files/arduino-0022-src.tar.gz


2. FTDIドライバのファイルをlibに入れる
$ cp libftd2xx0.4.16/ftd2xx.h /usr/include
$ cp libftd2xx0.4.16/WinTypes.h /usr/include
$ cp libftd2xx.0.1.7.dylib /usr/lib
$ ln -sf /usr/lib/libftd2xx.so.0.1.7.dylib /usr/lib/libftd2xx.dylib


3. avrdudeにパッチをあてる
$ tar zxvf avrdude-5.10.tar.gz
$ cd avrdude-5.10
$ patch -p1 < ../avrdude-serjtag/src/avrdude-5.10-serjtag.patch
$ patch -p1 < ../avrdude-serjtag/src/avrdude-5.8-ft245r.patch
$ patch -p1 < ../avrdude-serjtag/src/avrdude-5.8-conf.patch
$ patch -p1 < ../avrdude-serjtag/src/avrdude-5.8-confu2.patch
$ patch -p1 < ../avrdude-serjtag/src/avrdude-5.8-ubsasp.patch
$ patch -p1 < ../avrdude-serjtag/src/avrdude-5.10-ubsasp2.patch
$ patch -p1 < ../avrdude-serjtag/src/avrdude-5.10-ser_posix-fix.patch


4. インストール
$ ./configure CFLAGS="-g -O2 -DSUPPORT_FT245R" LIBS="-lftd2xx"
$ make


5. Atmega328P用設定追加
$ vi ~/.avrduderc


#arduino duemilanove
programmer
id="duemilanove";
desc = "FT232R Synchronous BitBang";
type = ft245r;
miso = 3; # CTS X3(1)
sck = 5; # DSR X3(2)
mosi = 6; # DCD X3(3)
reset = 7; # RI X3(4)
;

#------------------------------------------------------------
# ATmega328
#------------------------------------------------------------

part
id = "m328p";
desc = "ATMEGA328P";
has_debugwire = yes;
flash_instr = 0xB6, 0x01, 0x11;
eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
0x99, 0xF9, 0xBB, 0xAF;
stk500_devcode = 0x86;
# avr910_devcode = 0x;
signature = 0x1e 0x95 0x0F;
pagel = 0xd7;
bs2 = 0xc2;
chip_erase_delay = 9000;
pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
"x x x x x x x x x x x x x x x x";

chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
"x x x x x x x x x x x x x x x x";

timeout = 200;
stabdelay = 100;
cmdexedelay = 25;
synchloops = 32;
bytedelay = 0;
pollindex = 3;
pollvalue = 0x53;
predelay = 1;
postdelay = 1;
pollmethod = 1;

pp_controlstack =
0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
hventerstabdelay = 100;
progmodedelay = 0;
latchcycles = 5;
togglevtg = 1;
poweroffdelay = 15;
resetdelayms = 1;
resetdelayus = 0;
hvleavestabdelay = 15;
resetdelay = 15;
chiperasepulsewidth = 0;
chiperasepolltimeout = 10;
programfusepulsewidth = 0;
programfusepolltimeout = 5;
programlockpulsewidth = 0;
programlockpolltimeout = 5;

memory "eeprom"
paged = no;
page_size = 4;
size = 1024;
min_write_delay = 3600;
max_write_delay = 3600;
readback_p1 = 0xff;
readback_p2 = 0xff;
read = " 1 0 1 0 0 0 0 0",
" 0 0 0 x x x a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";

write = " 1 1 0 0 0 0 0 0",
" 0 0 0 x x x a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" i i i i i i i i";

loadpage_lo = " 1 1 0 0 0 0 0 1",
" 0 0 0 0 0 0 0 0",
" 0 0 0 0 0 0 a1 a0",
" i i i i i i i i";

writepage = " 1 1 0 0 0 0 1 0",
" 0 0 x x x x a9 a8",
" a7 a6 a5 a4 a3 a2 0 0",
" x x x x x x x x";

mode = 0x41;
delay = 5;
blocksize = 4;
readsize = 256;
;

memory "flash"
paged = yes;
size = 32768;
page_size = 128;
num_pages = 256;
min_write_delay = 4500;
max_write_delay = 4500;
readback_p1 = 0xff;
readback_p2 = 0xff;
read_lo = " 0 0 1 0 0 0 0 0",
" 0 0 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";

read_hi = " 0 0 1 0 1 0 0 0",
" 0 0 a13 a12 a11 a10 a9 a8",
" a7 a6 a5 a4 a3 a2 a1 a0",
" o o o o o o o o";

loadpage_lo = " 0 1 0 0 0 0 0 0",
" 0 0 0 x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" i i i i i i i i";

loadpage_hi = " 0 1 0 0 1 0 0 0",
" 0 0 0 x x x x x",
" x x a5 a4 a3 a2 a1 a0",
" i i i i i i i i";

writepage = " 0 1 0 0 1 1 0 0",
" 0 0 a13 a12 a11 a10 a9 a8",
" a7 a6 x x x x x x",
" x x x x x x x x";

mode = 0x41;
delay = 6;
blocksize = 128;
readsize = 256;

;

memory "lfuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
"x x x x x x x x o o o o o o o o";

write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
"x x x x x x x x i i i i i i i i";
;

memory "hfuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
"x x x x x x x x o o o o o o o o";

write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
"x x x x x x x x i i i i i i i i";
;

memory "efuse"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
"x x x x x x x x x x x x x o o o";

write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
"x x x x x x x x x x x x x i i i";
;

memory "lock"
size = 1;
min_write_delay = 4500;
max_write_delay = 4500;
read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
"x x x x x x x x x x o o o o o o";

write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
"x x x x x x x x 1 1 i i i i i i";
;

memory "calibration"
size = 1;
read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
"0 0 0 0 0 0 0 0 o o o o o o o o";
;

memory "signature"
size = 3;
read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
"x x x x x x a1 a0 o o o o o o o o";
;
;


6. 試してみる
・avrdudeを使う前にドライバをunloadする必要がある
$ sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext
※再loadは下記で
$ sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext
・実験!!
$ avrdude -c duemilanove -P ft0 -p m328p -t -B 4800


avrdude: BitBang OK
avrdude: pin assign miso 3 sck 5 mosi 6 reset 7
avrdude: drain OK

ft245r: bitclk 4800 -> ft baud 2400
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e950f
avrdude>

こんな感じのが出ればok。


7. Fuse書き込み
avrdude> quit
$ avrdude -c diecimila -P ft0 -p m328p -t -B 4800
avrdude> erase
avrdude> w efuse 0 0x05
avrdude> w hfuse 0 0xDA
avrdude> w lfuse 0 0xFF
avrdude> d efuse
avrdude> d hfuse
avrdude> d lfuse
avrdude> quit


8. ブートローダを書き込む!!
$ cd /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/bootloaders/atmega
$ avrdude -c diecimila -P ft0 -p m328p -U flash:w:ATmegaBOOT_168_atmega328.hex


9. ロックビットを書き込む!!
$ avrdude -c diecimila -P ft0 -p m328p -t
avrdude> w lock 0 0x0F
avrdude> quit


10. Arduinoのプログラムとか書いてみるー!!
上記終了後, USBケーブルをぬいて、書き込み用に配線したジャンパをぬいてPC再起動後、
USBをサイド接続してArduinoのリセットボタンを押してから、
Arduino IDEを起動して適当なプログラム書き込んで動くか試す。
ただ、このアップロード時に「error at /Users/yuki/.avrduderc:5 unrecognized character: "f"」といったエラーが出る場合、設定ファイルを一時的にコメントアウトする必要があるかもです。
※プログラムを書き込む際は
$ sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext
を忘れないように。じゃないとシリアルポートを読んでくれません。


◆ FT232RL USBシリアル変換モジュールをライターとして使う
http://www.geocities.jp/arduino_diecimila/bootloader/index_old.html


上述の2つの方法を、ライターにArduinoを使わず、
秋月のFT232RL USBシリアル変換モジュールに変えてためした。


結果、Arduino UNOにマイコンをのせるとダメだけど、
Duliminovaでは正しく動いた様子!