鶏と卵 で書いたように、最初 の AVR ライタ をどうするかという問題があって、それは、パラレルポートを持ってさえいれば簡単に解決する。ただ今後レガシーインターフェイスがない PC も増えてくるだろうし、なにか良い方法はないかと日ごろ思っていた。SERJTAGは、FT245RL USBパラレル変換モジュール+ATtiny2313 を使った自作の高速な JTAG インターフェイスだが、作っているうちに、FT245R/FT232R BitBang 版 avrdude を作れるだけの知識が付いてしまった。鶏と卵 問題の解決にもなるし、BitBang と SERJTAG の性能比較もできるし ... ということで作ってみることにしてしまった。
BitBangMode の使い方は秘密にされていて、オープンソースになっていない。実をいうと、FTDI が供給するバイナリを使わないと使えないのが気に入らないので、積極的にサポートしたくはないのだ。..でもレガシーレスのPCで本当になにも手段がないときに使えるものは、コレぐらいしかないのだ。
追記:つれづれ日記からコメントをもらった。自分は AVR ライタをいくつも持っているのに、最初 の AVR ライタ を気にするのは、より多くの人に AVR での電子工作の世界に入ってきてほしいためだ。ローコストでAVRライタが手に入れば敷居が下がる。その結果、人が増えれば、自分の記事の有用性が増す。
ものは、serjtag-0.3.tar.gz と serjtag-0.3.zip。
SERJTAG に同梱した。対応したバイナリも同梱している。(USB910 は次のバージョンで同梱する予定)
この avrdude.exe を使えば、
FT232RL USBシリアル変換モジュール(950円)・FT245RL USBパラレル変換モジュールを用意するだけで、AVR へ書き込みができるようになる。ブレッドボードがあるなら、電源も AVR を書き込む程度 (30mA ?) ぐらいなら供給できるし、本当に他になにもいらない。
ちゃんとしたISP ケーブルを作るとしても、カモン USB-05を切って使えば簡単につくれる。前にも書いたと思うが、サポートしているのは、FT245R/FT232R (と FT2232) だけである。FT245BM(AM)/FT232BM(AM) は、Synchronus BitBangMode をサポートしていないので使えない。FTDI ならなんでも良いわけではないので注意。
ちなみに、ピン配置は次のようにした。(09/01/05 訂正)
FT232R FT245R chip pin# BitBang bit
MISO RxD D1 5 1
SCK TxD D0 1 0
MOSI RTS D2 3 2
RESET DTR D4 2 4
これは、avrdude.conf で定義しているので、ft245r の記述を参考に変更すれば、他のピン配置にも対応できる。
追記:avrdude.conf に記載したデフォルトの配置がバグってました。バグにあわせると↑になります。なお、デフォルトの配置はあくまでサンプルです。使用する装置に合わせて avrdude.conf を変更のこと。
秋月のもの以外では、ストロベリーリナックスの FT232RL USB→シリアル変換モジュールキット、wS☆Nakの#121A USB DIPアダプタ (FT232RL)などが良さそうだ。電子工作では、mini-B コネクタより、B コネクタの方が電流が流せて良い場合もある。秋月のは、ピン・プラグが最初から付いていて、ケーブルにするには、それがかえって使いにくい。アイテムラボのピッチ変換基板SOP28-P65(2)を使って作るのも良いだろう。FT245RL/FT232RL はほとんど外付け部品がいらない。必要なのは、パスコンぐらいで、それは変換基板に付けられる。
使い方は、-c オプション プログラマ名 に ft245r を指定し、-P オプション ポート名 に ft0 を指定する。あと -B ビットクロック オプションも対応していて、500 kHz 程度まで指定できる。(ただし 指定した周波数以下にするだけの意味 )
さて、例によって 4072 バイトのバイナリの書き込み/ベリファイ性能を見てみる。
書き込み ベリファイ 実効性能 (bps)
FT245R Synchronous BitBang
-B 4800 28.75 秒 27.50 秒 4738
-B 9600 14.86 秒 13.69 秒 9518
-B 19200 8.06 秒 7.00 秒 18614
-B 28800 5.67 秒 4.61 秒 28265
-B 38400 4.50 秒 3.47 秒 37551
-B 115200 2.36 秒 1.34 秒 97241
-B 230400 2.06 秒 1.08 秒 120651
-B 460800 1.63 秒 0.64 秒 203600
SERJTAG(FT245R 版)
- Linux 1.27 秒 0.27 秒 482607
- Windows 0.50 秒 0.44 秒 296145
注1)実効性能 は、バイト数 x 4 バイト/ベリファイ時間
注2)FT245R ドライバは、遅延タイマを 16ms から 5ms に設定変更
AVR ライタとしては、かなりの性能だと思う。だがしかし、SERJTAG はそれ以上の性能にできた。これでこそ作った意味があるというものだ。それはともかく、AVR ライタを持っていない人は、これを機会にぜひ AVR で遊んでみてほしい。プログラマをすでに持っている人もエマージェンシー用に使えるし、ひとつ持っていると良いかもしれない。
追記:
ここの説明は非常にいいかげんです。
1. avrdude.conf がバグっているので修正すること
2. 新品のチップは、クロックが遅いので、-B 4800 を指定する
この2 点に気をつけてください。
使うまえに、外付けAVRライタ無しでBootloaderを書き込む(Kimio Kosaka さん)をチェックしたほうが良いと思います。
あと、(番外) FTDI BitBang AVR-Writer と tomoの電子工作でファンコントロール:ファーム書換方法についても参考になると思います。
最近は秋月電子でもFT245をモジュールにしたものが購入できます(使ってみました)。
これでAVRライタも良いのですが、更に安価に製作できるものを企画中です。
興味があれば、以下のURLを参照ください。
(書き込み済のAVRと専用基板を安価(予定では部品一式で1,000円未満を予定)に提供する方法でAVRユーザをふやそうという試みです。果たして功を奏するでしょうか、、。)
http://www-ice.yamagata-cit.ac.jp/ken/senshu/sitedev/index.php?memo%2FAVRSP
http://www.wsnak.com/kit/new.php
AVRライタだけでなく、mega168やATtiny2313などの基板も安価に購入できます。
何とかAVRの普及につながればと考えています。
http://www.geocities.jp/arduino_diecimila/bootloader/index.html
serjtag-0.3.zipへの直接リンクとミラーを行っておりますが許可いただけますでしょうか。
FT232RL単体がAVRライタとして働くのは本当に驚きました。
それはともかく、Arudino みたいな FT232RL+ AVR のボードでは便利に使えそうですね。作っておいて良かったと思いました。
Arduinoを使っている人々には「目からウロコ」状態のようです。
AVR ATmega88 & 168 でファンコンを自作しておりますtomoと申します。
http://www.wa.commufa.jp/~fanduino/index.html
FT232RLとAVRを組合せたAVR-Fanconでは、すzさんのavrdudeが大変便利で、勝手ながらリンクさせていただいております。
そこで、2点だけ質問させていただきたいのですが、
1.avrdude.exeファイルを当方のホームページからダウンロードできるようにさせていただけませんか?
2.avrdude実行後は、/RESETがLowのままとなり電源を一旦切らないとAVRが起動できませんが、対応策はありますでしょうか?
以上、わがままなお願いと質問ですがよろしくお願いします。
ファームの書換方法のページを拝見しました。PC の電源を落とすしかないのはとても面倒そうですね。
コードをみかえしてみると、close 時の RESET の状態の考慮がまったくないため、残念ですがそのままでは対処できません。
ソースコードを添付しており、MinGW と MSYS があればビルドできるので、ご自身でビルドにトライしてみてはどうでしょう? serjtag-0.3/avrdude-serjtag/README.txt に方法を載せています。
たぶん、par.c の par_close() を参考に、pgm->exit_state を見る処理を加えれば良いのだと思います。
しかし、私にはどこをどうしてよいやらという感じです。
ファーム書換時だけのことですので、当面はこのままで行こうかなと思っています。
{
char buf[128];
int i;
i=0;
buf[i++] = 's'; /* Set Port */
buf[i++] = 0; /* flags */
buf[i++] = 1; /* bytes */
buf[i++] = 0; /* TDI(MOSI) = 0, TMS(RESET) = 0, TCK(SCK) = 0 */
//buf[i++] = JTAG_SET_TMS; /* TDI(MOSI) = 0, TMS(RESET) = 1, TCK(SCK) = 0 */
serjtag_send(pgm, buf, i);
usleep(5000); // 5ms
serial_close(&pgm->fd);
pgm->fd.ifd = -1;
}
こんな風にやればリセットかかるかと思ったのですがダメでした。
ft245の方を使っていました。
static void ft245r_close(PROGRAMMER * pgm)
{
set_reset(pgm, 1);
FT_Close(handle);
}
とすればリセットかかります。