2009年11月28日

FT245R/FT232R で avrdude (2)

FT245R/FT232R で avrdude の serjtag-0.3.zip に添付した avrdude-serjtag をバージョンアップした。

ものは、avrdude-serjtag04e.zip (最低限のテストはしたけど何か問題があるかも。)

    最新版(暫定リリース): avrdude-serjtag04n.zip

    注意: USBasp の改造が含まれていますが、オリジナル USBasp で動作しない問題があります。ft245r BitBang ライタも未テスト。

    注意2: USBasp の新版がリリースされています。永らく更新がなかったので、もう更新されないだろうと思い、好き勝手にプロトコル拡張してしまいました。新版と競合しますので、オリジナル USBasp を使用している方は、04n のバイナリを使用できません。


もともとは、自作ライタのプロトコル SERJTAG を avrdude に対応したときのおまけだったが、広く使われるようになったので、独立させた。serjtag の名前がユニークなので そのまま使うことにして、申し訳程度に SERJTAG にも対応している。

今頃になって、バージョンアップしたのは、自分の環境整備の一環。最近は、AT90USB162 で遊んでいるので、ライタがいらなかったのだが、USBaspLoader の移植とかはじめたので、必要になってきたため。

変更点(リリース関係)



  • ベースバージョンを 5.3.1 → 5.8 に 上げた。

    新しいデバイスの定義が最初から入っているため。できるだけ新しいのを選択。

    (+ m168p (ATMEGA168P) が入っていなかったので conf に 追加)

  • libusb-0.1.12.2 をリンク

    USBasp も使うので、リンクするようにした。ただし、ドライバや DLL は同梱していないので、使う場合は別途入手するか、WinAVR -20090313 の環境を使う必要がある。

  • ftd2xx.dll の添付をやめた。

    ドライバをインストールすれば dll もインストールされるので不要。

  • avrdude.conf のサーチを変更。

    exe ファイルを avrdude-xx.exe と変更した場合、avrdude-xx.conf をまずサーチするようにした。

  • usbasp の動作を変更 (非互換なので注意)

    終了時の動作を -E オプションで決めるようにした。

      -E reset ( リセットする )
      -E noreset ( リセットしない → デフォルト )


    Vendor名、Product名を指定できるようにした。

      -P [Vendor名]:[Product名]

      Vendor名、Product名 のどちらかは省略可 。省略した場合

       Vendor名 = www.fischl.de
      プロダクト名 = USBasp

      ※ライタ/ブートローダ の デバッグ用。


  • Mac OS X / Linux のビルド方法のメモ添付

    Mac OS X / Linux で も使えることが分かったので。

変更点(ft245r 機能)



  • デバイス定義の追加と見直し。

    以下の 3 タイプ 5 種類にした。

    ft245r : sample configration for FT232R/FT245R
    ft232r0 : FT232R channel 0
    miso : D1/RXD
    sck : D2/RTS
    mosi : D0/TXD
    reset : D4/DTR

    diecimila : Arduino Diecimila or clone
    ft232r1 : FT232R channel 1
    miso : D3/CTS
    sck : D5/DSR
    mosi : D6/DCD
    reset : D7/RI

    breakout : sparkfun FTDI Basic Breakout
    miso : RXI (2)
    sck : CTS (5)
    mosi : TXO (3)
    reset : DTR (1)

    推奨は、diecimila = ft232r1。ft245r は、TXD ⇔ RTS を入れ替えた。serjtag-0.3 で間違えたので直したかったのだ。


    (秋月 AE-UM232R を使った例。XTAL1 と LED については↓参照)


      追記 2011/1/22 ft232r0 を使ってくれている人を発見

      Tiny 系だと 書き込みと ソフトシリアル を配線を切り替えずに使えて便利だそうだ。ただし、シリアルで接続すると 普通 DTR が L になるので リセットがかかる。対処するには、FT_PROG(または MProg)で DTR の極性を反転させるのが良いとのこと。

  • -P ポートの指定方法の追加

    通常 1つしかないと思うので、ft0 で良いのだが、複数になると 混乱するので、シリアル番号や プロダクト名も使えるようにした。

    シリアル番号や プロダクト名は、Mprog ユーティリティで自由に変更できる。ちなみに シリアル番号は数字である必要はなく 文字列。

      例:

      プロダクト名:AVR-Programmer
      シリアル番号:AE232001


    ついでに書いておくと、CBUS の機能を変更できて、6MHz,12MHz,24MHz,48MHz のクロック出力にできる。(クロック出力には、一応 CBUS4 を推奨)

    外部クリスタルに変更したチップも、XTAL1 にクロックをつなげることで、プログラムできる。

  • 終了時の状態設定の見直し。

    いままで、sck , mosi, reset は出力のままで、reset は L レベルだった。この 3 つ以外は入力。

    まず、sck , mosi は 終了時 入力(HI-Z) にすることにした。

    reset は 出力 L を維持するが、-E reset で 入力(HI-Z)にする。

    PC が、シリアルポートを Open するまでは、この状態が維持されるはず。Open した場合でも 出力は、TXD , RTS, DTR のみだから、diecimila = ft232r1 なら 出力がぶつかるような問題はでない。

    入力はどうなんだろう? 検討してなかった。

    フロー制御なし(デフォルト)なら、CTS は関係ない。DSR/DCD/RI は、モデム制御だから モデムの設定をしない限り関係ないような気がする。ポートの詳細設定に ドライバ固有の設定があり、いくつか項目があるようなので、変更すれば良いのかも。

    実際のところよくわからない。


sck, mosi の制御について


終了時は、入力にしたので、-E reset で書き込んだプログラムを実行しても出力がぶつかることはない(はず)。

初期化時は、どうなのか検証してみた。

手順は次のようになっている。

  • (1) Synchronous BitBang Mode にできるかどうか確認する。(全ピン入力)
  • (2) モードを一旦リセット
  • (3) Synchronous BitBang Mode にする。(全ピン入力)
  • (4) sck = L, mosi = L, reset = L を出力して出力の初期状態を設定。
  • (5) sck, mosi, reset を出力に。
  • (6) sck = L, mosi = L, reset = L を出力
  • (7) reset = H→L を出力 (パルス幅 1.2 ms)

データシートには、

  • sck = L にした後、reset = L にする。
  • リトライ時には、reset に 正パルスを入れる

というようなことが書いてある。時間に関する記述は、デバイスによって違う。

で、出力がぶつかる可能性があるのは、

  • (7) の期間中に、AVR が起動してしまって、プログラムが出力したとき。

たぶん、これだけ。AVR で 14CLK でリセットから抜ける高速起動の設定をして、できるだけ早くポートに出力するようなプログラムをわざわざ書くと 最大 1.2 ms だけ出力がぶつかる可能性がある。

ただ、(2) モードを一旦リセット としているので、ft232r0 を使った場合 ひょっとしたら設定が元にもどって mosi,sck が出力になっているかも知れない。デフォルトでも入力の ft232r1 なら関係ないはず。

電流制限抵抗について


出力がぶつかる可能性がある場合、sck,mosi に電流制限抵抗を入れた方が良い。

ただし、ブレットボードで組むような場合、へたに抵抗を入れて接触不良になったり抵抗自体がショートしたりして失敗する危険性を増やすぐらいなら、ダイレクトに接続したほうがマシ。
それでも安全性を少しでも求めるなら、抵抗入りケーブルを作ったら良いと思う。

さて、抵抗値は、どれぐらいが良いのだろう。

FT232R のデータシートを見ると、絶対最大定格は、24 mA だそうだ。AVR は、40mA ぐらい。ただし、1 つのピンのみに電流を流した場合。

出力がぶつかった場合、それぞれのデバイスの内部抵抗で電圧降下とかが起きると思うので、電圧差 = 電源電圧ではないはずだが、仮に 3.3V の電圧差で 24mA 流すとすれば、138 Ω。5.0V なら 208 Ω。

一応 220 Ωを入れとくのが安全とは言える。ただし、抵抗値が大きいと波形が鈍り、高速クロックに対応できない場合が出てくる。

どれぐらい鈍るかについては、入力側にコンデンサがあって、電流制限抵抗 とコンデンサで RC ローパスフィルタになっていると考えれば良い。

コンデンサの容量がいくつか分からないのだが、仮に 10 pF だとして 電流制限抵抗 が 100 Ωだとすると cut-off 周波数は 160 MHz 。 220 Ωなら 72 MHz 。この 1/10 以下なら安全? ビットレートは デフォルトが 0.230 Mhz , 最大でも 0.460 MHz なので 220 Ωでも まぁ問題なさそう。
    ちなみに、74HC シリーズの入力容量は、5 pF 程度だそうだ。AVR ではよくわからないものの Mega88PA の TWI の 入力容量は、最大 10 pF だそうだ。

ビットレートについて


新品の AVR をはじめてつかう場合、-B 4800 として ビットレートを 4.8 KHz にした方が良い。.... としている。

それについての考察。シリアルプログラミングでは、CPU クロックの 1/41/6 以下のビットレートでないといけない。(高クロックでは、もっと厳しく 1/61/8 以下。)

    (訂正) HI/LO とも 2CLK 保証しないといけない = 3CLK 必要 。

デフォルトのビットレートは 230K Hz で、CPU クロックが 1MHz 以上なら問題ない。最近の普通の AVR は、8 MHz 内蔵 RC クロック + 1/8 分周 で、一応条件を満たすはず。

ただ、以前 これを作ったとき テストに ATtiny2313V を使ったのだが、全然ダメだった。クロックをだいぶ落として認識できた覚えがある。

Tiny系 には、128 kHz 内蔵 RC クロックがある。 これに設定してしまうと 32 KHz が最大のビットレートになる。忘れてしまったが、Tiny2313V がダメだったのは、これに設定されていたからかも。

こういうことがあるので、よくわからないものを使う場合、サポートしている最低のビットクロックである 4.8 KHz に設定するのを推奨している。

  • ATmega168P を 試してみた。
    新品の状態では、内蔵 8MHz 1/8 分周 = 1MHz 。最近の AVR は 1MHz が多いので 標準的な 周波数。

    この場合、デフォルトの 230400 (Hz) では動作しなかった。115200 もダメ。動作する最高の ビットレート は、 76800 だった。

    1/8 分周 しないようにヒューズビットを書き換えると、 460800 Hz でも OK 。

    -B 4800 は、ちょっとひどすぎるかも知れない。これからは、-B 76800 を推奨しよう。

    ところで、1MHz でも -B 76800 だとすれば、128KHz 1/8 分周 = 16 KHz ではどうなるのだろう? 比率だけで判断すると、-B 1200 。04e では、そこまでビットレートを落とせるようにしてある。

    (追記) -B の値について

    -B は、SCK の周波数のつもりで設計しましたが、実際の(最大の)周波数は、もっと高い値のようです。
    (ちなみに、平均の 周波数 は、-B の値 前後です)

    最大周波数は、おそらく -B の値の 4/3 です。

    -B の値   最大周波数  AVRの最低周波数(x6)

    76800 102.4 KHz 614.4 kHz
    115200 153.6 KHz 921.6 kHz

    -B 115200 が AVRの最低周波数 をクリアしているのに動かない理由は、AVR内蔵オシレータの精度の問題と、えるむ:AVR内蔵オシレータのジッタの問題の 2 つの要素があるためだと思います。ジッタのため、随分(20-30% ?) CLK パルス幅が変動するようです。

追記:avrdude-serjtag04e.zip 

    変更点:
  • 最低ビットレートを 1200 Hz に引き下げた。
  • ISP に入るときの手順を厳格化
  • led 制御を入れてみた。


次のように指定すると 機能が使えるようになる。ただし、PIN番号には、0 (D0 / TXD ) は指定できない。

buff = PIN番号;
rdyled = PIN番号;
pgmled = PIN番号;



  • rdyled の制御は、初期化すると 入力(Hi-Z)→L になる。終了時 RESET を H にする指定(-E reset)で 入力(HI-Z)。noreset (デフォルト)の場合は L のまま。

  • pgmled は、FLASH の upload 中 L 。終了で、入力(HI-Z) 。
    プログラムをアボートさせた場合、点等したままになる場合があるが、RESET を H にする指定(-E reset)で消灯できる。入力(HI-Z)。

  • LED は L で点灯。通常
     
      VCC(3.3V) - 電流制限抵抗 - LED - LEDピン

    とする。VIO が 3.3V 〜 5V の場合、問題はない。電流制限抵抗は、270 Ω。Vf が高い LED を使用するときは、より小さくても良いが、6mA 程度で設計すること。

    VIO は、1.8V まで下げられる。この場合 電圧差が 1.5V ある。課赤LEDでも Vf は 1.7V なので LEDピンを通して VIO に電流は流れ込む問題はないはず。... だが一応は、より Vf が高い LED を使用するのを推奨しておく。

    buffer を入れたい場合、rdyled を VCC(or VIO) にプルアップして、buffer 制御に使用できるよう設計した。( buff = PIN番号 は、別の用途に使用するので 使えない )

    PIN番号 の指定には、8-11 が指定できる。8(CBUS0) .. 11(CBUS3)
    の意味。

    CBUS を使うためには、MProg で CBUS の設定を I/O に変更する必要がある。CBUS は、終了時に自動的に入力(HI-Z)になるようだ。

    設定しなければ、なにも起きないので、デフォルトで CBUS2 に rdyled を割り当ててある。


    (設定例:TX LED を TX & RX LED に変更して、RX LED を I/O mode に変更。ついでに CBUS4 を 12MHz のクロック出力に)

追記:avrdude の USBasp 改造について

最近 USBaspLoader を移植しているのだが、実に具合が悪い。

avrdude のオリジナルでは、必ず reset する。-- avrdude.exe を動かすたびに reset してアプリケーションを動かそうとする。

ライタの USBasp は まだ良い。USBaspLoader でアプリケーションを実行すると、必ず 手でリセットしなければならなくてとても面倒なことになる。

それが嫌ならば、ブートローダのスイッチを操作するようにするとかしなければならない。

... というわけで、デフォルトでは reset せずに -E reset を指定した場合のみ reset するようにした。

まぁ、気に入らない人もいると思うが、基本は自分用なので 強引に変更することにした。

気に入らない人は、WinAVR の環境に上書きせずに、avrdude.exe と avrdude.conf を avrdude-serjtag.exe と avrdude-serjtag.conf にリネームしてからインストールして欲しい。

追記: 書き込みできるデバイスについて(04e)

senshu さんが評価してくれました

    -- 90Sシリーズ
    × AT90S2313(認識せず)
    △ AT90S8515(ちょっと不安定)
    〇 AT90S4433
    -- Tinyマイコン
    〇 ATtiny26L
    〇 ATtiny2313
    -- Mega
    〇 ATmega88
    〇 ATmega168
    〇 ATmega328P
    〇 ATmega644P
    〇 ATmega128

もともと 128KB までの tiny/mega シリーズしか意識していなかったので、90S シリーズの結果はやむなしという所です。

ですが、動いたり動かなかったり、惜しい所までは行っている模様。秋月に置いてあるデータシートを確認したところ、ISP モードに入るときの delay が足りないだけのように思えます。(現状は 5ms / 要求は 20ms 以上)

    古いソースを見てしまいました。間違い。

    senshu さんの指摘どおりで、古いデバイスでは、同期が取れない 場合 1 bit づつずらして 32 回までリトライせよと データシートに書いてあります。(新しいデバイスは RESET からやり直せば良い)

    一応作ってみた → ft245r.c

    90S シリーズも OK になったそうです。

というわけで 暫定リリース → avrdude-serjtag04f.zip 

    変更点:
  • AT90S2313,AT90S8515,AT90S4433 に対応。
  • -E reset の仕様変更 (bitbang モード自体もリセットする)
    → (windows 版では)シリアルが使用可能に (senshu さんの改良)
    注意点: パッチと avrdude.exe を差し替えただけ。バイナリも動作未確認。


追記:avrdude-serjtag04g.zip

こちらの環境(Windows XP, Linux) でテストしてみたところ 問題なさそうなので、暫定リリース。

変更点 (avrdude-serjtag04e.zip から)

  • AT90S2313,AT90S8515 など古い AVR の対応
  • flash/eeprom の read のバグ修正
  • flash/eeprom の read の高速化
  • eeprom の write の高速化
     - LatancyTimer を デフォルトから 2ms に変更
     - pagewrite はあきらめ、コード削除

    以上 senshu さん とのやりとりで修正 (コメント参照)


-B オプションについて

-B 38400 での 16KB の読み込み でテストすると

ft245r: bitclk 38400 -> ft baud 19200

という風に 19200 bps を設定しています。マニュアル通りならば 19200 x 16 / 2(H/L) = 153k bps になるはずですが、実際にやってみると

  • Windows XP 16.67 秒
  • Linux 16.39 秒

となります。1 バイトの読み込みに 4 バイト分 32 クロック必要なので、平均クロックは

16 * 1024 * 32 / 16.67 = 31450 (Hz)

ということになります。-B 4800 とすると 4800 bps にかなり近い値になるので、マニュアルのほうが間違っていると判断しています。

追記: 上にも書きましたが -B は、低速での平均クロックの目安です。実際の ビットクロックは、
 -B の指定値 x 4/3
だと思われます。また、内蔵 RC 発信器を使用する場合は、ジッタのためかなりのマージンを取る必要があります。

追記:avrdude-serjtag04l.zip (2011/06/14)

pgmled を CBUS に割り当てると動作しないというバグレポートがあり修正。

バージョン番号が飛んでいますが、04f - 04k までは、USBasp の改造が主で ft245r には修正がありません。

    その間に関する記事は、『Teensy(1.0)互換ボード』『TPI/PDI』『AE-UM232Rピン互換ボード』あたり。

    紹介すると、自作 ATMEGA32U2/ATMEGA32U4 ボードで USBasp プロトコル を拡張した ライタを作っています。 USBasp プロトコル 対応 のブートローダも作成済み。USBasp プロトコル の拡張は、XMEGA の PDI と TINY10 の TPI に対応したこと。ライタ側の ファームウェアは、あと一息で完成というところで放置状態になっています。

    04L では、この USBasp プロトコル 拡張が 入っています。

修正したのは、次の機能。この機能を使わないならば、影響はありません。

    rdyled/pgmled 次のように指定すると 機能が使えるようになる。

    rdyled = PIN番号;
    pgmled = PIN番号;

     PIN番号の割り当て
    # FT245R FT232R
    0 D0 TXD
    1 D1 RXD
    2 D2 RTS
    3 D3 CTS
    4 D4 DTR
    5 D5 DSR
    6 D6 DCD
    7 D7 RI
    8 - CBUS0
    9 - CBUS1
    10 - CBUS2
    11 - CBUS3
    (注意)rdyled/pgmled は 0 (D0 / TXD ) を指定できない。


この機能の定義を次のように変更し、PIN番号の割り当ての条件も変更します。

    rdyled :
    ライタを 操作すると 点灯。(点灯中は、シリアルが使えません)
    -E reset で 消灯。(シリアルが使える状態)
    D1 - D7 を割り当てた場合 書き込み中 消灯(点滅します)

    pgmled:
    D1 - D7 を割り当てた場合 書き込み中 点灯(点滅します)

    PIN番号の割り当て:
    rdyled : 1-11
    pgmled : 1-7

    信号の操作:
    点灯: L
     消灯: Hi-Z

(注意) 仕様が変わったので、rdyled は、buffer 操作には使えなくなりました。FT232R/FT245R の場合 VccIO(VIO) を使うことで、1.8V 〜 5V まで対応できるので外付け buffer は不要なはずで、外付け buffer を使う人はいないと考え、非互換は気にしないことにしました。

仕様を変えたのは、1 つの LED で rdyled と pgmled の役割を果たすためです。D0-D7 のうち 通信に 3 本 / ライタに 4 本 使うとして 1本だけ空いています。

"diecimila" の設定を使うなら

# FT245R FT232R
2 D2 RTS

RTS が空いています。これに LED を付けることを想定しています。M_Prog/FT_Prog の設定なしに使えるので、お勧めかも。

追記:avrdude-serjtag04m.zip (2011/06/18)


pgmled の 定義変更 : アクセスランプ ということにした。

pgmled/rdyled を 1-7 (DBUS) に割り当てたときの操作を L(点灯)/H(消灯)とした。
(-E reset での終了時は Hi-Z にするのは従来通り)

詳しくはコメント参照。

追記:avrdude-serjtag04n.zip (2011/06/24)


テスト版(動作しないかも)

内部の delay を ft232r_delay で実装。delay 中は、pgmled 点灯 (コードは点滅 だが周期が長すぎて 点灯で終わる) (6/24 バグ修正)

read/write 中は pgmled 点滅 (page mode がある AVR のみ)

write のロジック変更 (USE_INLINE_WRITE_PAGE enable)

FT232H/FT2232H 向けにチューニング。(6/24 新規)

    FTDI のドキュメントを見て、1 回に Write する単位が重要だと分かったので対応。

    まず 12 Mbps の FT232R は、62 バイトの整数倍が良いらしい。いままで 512B としていたところを (62 * 4) に変更。

    FT2232H では、FIFO が 4KB あり (62 * 64) = 3968 の整数倍が良いらしい。あまり大きくとるのもどうかと思うので、バッファを 3968 バイトにすることにした。
    ちなみに、FT232H は、1KB 。記述はないが (62 * 16) の整数倍だろう。FT2232Hと区別しないでも問題ない。

    別件で FT2232H の テストをしたところ 最大 2.3 MHz の平均ビットクロックになった。 512B 単位だと 最大 0.55 MHz だった。 使用できた帯域は、480 Mbps に対して 76 Mbps (2.3 M x 32 x (64/62)) ほど。

    もっと高い性能を出すには、FT_SetUSBParameters() を使って InTransferSize を 64KB にまで大きくして、1 回の Write サイズも (62 x 64 x 16) にすれば良いらしい。ただ、 AVR で 2 MHz 以上のビットクロックは無用 なのでそこまではやっていない。



追記:PDI サポートの可能性

どうも avrdude-5.8 は、PDI をサポートしているようだ。avrdude.conf に XMEGA の 定義がある。

コードさえ書けば、avrdude-serjtag で PDI をサポートできるかも知れない。

ただ、PDI は、信号線である PDI_DATA が 双方向 になっている、Synchronous BitBang は 入出力の切り替えが遅いので、どうしようと思っていたのだが ... PDI には、REPEAT 命令があって、同じ操作を N 回繰り返すことができるらしい。-- FLASH の読み書きなどでは、入出力の切り替え を頻繁にしなくても良いように設計しているような気がする。

それであれば、なんとかなりそう。

ちなみに、PDI では、ISP のソケットは 普通の AVR とおなじものを使う。接続は、reset = PDI_CLK, miso = PDI_DATA , mosi と sck は NC 。

あと、クロックパルスが約 10kHz以下になると自動的に PDIモードを終了するらしい。連続して操作する場合は問題ないと思うが、ターミナルモードとかだと、接続しなおさないとダメ。なんか処理が面倒そう。

PDI のことをちょっと調べた。

まず、基本は、 startbit=1,dara 8bit, parity even 1bit, stopbit=2 でやりとりする。シリアルと違うのは、クロックが必要なのと、入出力が 1 本なこと。あと、パリティも 普通とちがうところがちょっとあるらしい。

    LD で データの前に、0xDB(P=1) が来る場合がある。そのときは、読み飛ばす。REPEAT 命令だと、命令毎に 0xDB(P=1) が来る場合も。


で、コマンドを送ってデータを受け取るようなやり取りをするわけだが、コマンドは 8 種類ある。


4bit 2bit 2 bit
LDS 0x00 | addrwidth-1 | datawidth -1 | 直接アドレス指定
STS 0x40 | addrwidth-1 | datawidth -1 | 〃
LD 0x20 | ptr | datawidth -1 | 間接アドレス指定
ST 0x60 | ptr | datawidth -1 | 〃
LDCS 0x80 | | cs |制御レジスタ指定
STCS 0xc0 | | cs | 〃
REPEAT 0xa0 | | datawidth -1 |
KEY 0xe0 | |

ptr: 0 *(ptr), 1 *(ptr++), 2 ptr
cs: 0-2 register N


KEY は enable にするための命令。あとは、LDS(STS), LD(ST) で空間を読み書きする。この空間のなかに、NVM という装置があり、 間接アドレス指定用の ptr も NVM の中にある。NVM のアドレスは、0x01c0 。制御レジスタは PDI 自体を制御するためのもので LDCS(STCS) で読み書きする。

制御レジスタの#2 には、GUARDTIME がある。送受信の切り替え時に挿入するクロック数で、制御のしかたによっては、先ずこれを設定しないとマズい。

    USART で使う場合は、XCK を常に出力しておいて ... 送信が終わったら、(必要なら)受信に切り替える。GUARDTIME を大きな値にしておけば、タイミングの制御が楽になる。

    逆に、BitBang のような処理だと、startbit 検出しないといけないのでかえって面倒。



NVM: base addr 0x1c0

+0 ADDR0
+1 ADDR1
+2 ADDR2

+10 CMD
+11 CTRLA
+12 CTRLB

+15 STATUS
+16 LOCKBITS


ポインタは、NVM の ADDR0-ADDR2 レジスタ。ここに STS で書き込むこともできるが、普通は ST で ptr(2) を指定して書き込むのだろう。あとは、LD(ST) の *(ptr++)で連続領域の読み書きができる。

REPEAT 命令は、REPEAT, 繰り返し回数-1, 命令, を送った後、 繰り返し回数 だけデータの送受信をする。ただし、NVM の CMD に適切な値をセットしないといけない。

こんな感じ。

さて、初期化のシーケンスについて

  • 初期状態は、clk = H, data = H 。この状態を数クロック分?保ち、clk を 16 回(以上?) ↓↑する。

      これで、制御レジスタにはアクセスできるようになるらしい。

  • STCS 1 + 0x59

      CPU を RESET 状態にする。(= 止める)。

  • STCS 2 + 0x07

      GUARDTIME を 0 にする。

  • KEY コマンド + 0xFF 0x88 0xD8 0xCD 0x45 0xAB 0x89 0x12

      NVM を enable (?) 。


これを一気に送ってしまえば、良い。

シグネチャ読み出し。

avrdude.conf に 

    memory "signature"
    size = 3;
    offset = 0x1000090;
    ;

なんて定義があるので、それを見て、LD すれば良い。定義には、

    memory "eeprom"
    memory "application"
    memory "apptable"
    memory "boot"
    memory "flash"
    memory "prodsig"
    memory "usersig"
    memory "signature"
    memory "fuse0"
    memory "fuse1"
    memory "fuse2"
    memory "fuse4"
    memory "fuse5"
    memory "lock"

がある。読み出すのは簡単で、REPEAT + LD を使えばいい。

書き込みはちょっと面倒。PAGE 分書いたら、なんか操作しないといけない。

こんな感じだから、作るのにはそれほど苦労しなくて良さそう。

XMAGA64A4 を共立で買って対応してみようと思う。

posted by すz at 22:44| Comment(109) | TrackBack(0) | SERJTAG

2009年02月23日

FT245R/FT232R で avrdude (Linux)

FTDI の D2XX ドライバが Mac やら Linux(i386/x86_64) に対応していることを今更ながら知ったので、ビルドだけしてみた。

用意するもの

ビルド

    1. serjtag-0.3/avrdude-serjtag/README.txt にしたがってパッチを当てる。
    2. avrdude-5.3.1 ディレクトリに libftd2xx0.4.16/ftd2xx.h と WinType.h あと static_lib/libftd2xx.a.0.4.16 をコピー。
    3. configure 実行
    4. Makefile に以下の 変更を行う。

    CFLAGS = -g -O2 -DSUPPORT_FT245R
    ================ 追加
    LIBS = -lreadline -lncurses -ltermcap libftd2xx.a.0.4.16 -lrt
    ===================== 追加
    5. make

こういう手順で ビルドが出来るみたい。

コンフィグファイル

    1. libftd2xx0.4.16/ftd2xx.cfg を /usr/local/lib か /usr/lib にコピー
    2. avrdude.conf を /etc にコピーするか、$HOME/.avrduderc に 置く。


今テストできる環境を持っていないので、動くかどうか分かりませんが、こんな感じです。Mac は知りませんが、同じようにすれば出来そうな気がします。

なお、avrdude は GPL なので、バイナリの配布には注意が必要です。
ちなみに、バイナリを配布する際は、上のように スタティックライブラリをリンクするのではなくダイナミックライブラリにした方良さそう。(D2XX の バージョンが上がったときに入れ替えられるから)

追記:
FT245RL_Linuxのページを参考にすると ダイナミックライブラリを使う場合

1. libftd2xx.so.0.4.16 を /usr/lib か /usr/local/lib ( 以下 LIBDIR)にコピー
2. cd LIBDIR
3. ln -s libftd2xx.so.0.4.16 libftd2xx.so ( リンクに必要)
4. ln -s libftd2xx.so.0.4.16 libftd2xx.so.0 ( 実行に必要 )

とすれば良いらしい。

注意点としては、 /proc/bus/usb が見えているか確認すること。

FT245RL_MacOSXでは Mac で使うときの例も書いてあるので、Mac 使う人は参考になるはず。

ちなみに、私の USB での 基本の環境は、玄箱/HG (PPC) なので、ftd2xx 版は使えない。libftdiを使おうと思っているんだが、 そうなると avrdude も 最新版に対応したいし ... みたいな感じで面倒になっていて 結局放置中。

5/11 追記 Coffeebot Labs(英文)で Linux 版の動かし方が紹介されています。参考まで。

2011/03/10 追記:

FT245R/FT232R で avrdude (2)』 に最新版があり、avrdude-5.10 に対応しています。eeprom の書き込みの問題があり修正していますので、そちらも参照してください。
posted by すz at 20:31| Comment(7) | TrackBack(0) | SERJTAG

2008年07月30日

linux で BitBang

以前 FT245R/FT232R で avrdudeの記事で、BitBang は Linux で使えないと書いたのだが、コメントを頂いた機会に今でもそうなのかどうか調べてみることにした。

FTDI のページの 3rd Party Driversのページを見てみたら、Intra2net: libFTDIなんてページがリンクされている。

で、あらためて、libftdi でググってみると... こんなページを発見。なんと、FT245RL で あたりまえのように BitBang Mode が使えている。

上の記事は 非同期の BitBang Mode を使っているが、コードをみてみると、同期 BitBang Mode も問題なく使えそう。


Linux でも BitBang Mode が使えるということで、FT232RL/245RL でいろいろやりたくなってきた。
posted by すz at 22:50| Comment(1) | TrackBack(0) | SERJTAG

2007年06月19日

USB910の拡張と Windows でのテスト

FT245R 版 SERJTAG は、もともと USB910 のプロトコル拡張をして、それを移植したものだ。FT245R でだいたいの評価ができたので、USB910 へコードをフィードバックして、評価をしてみることにする。

ちなみに、TypeA はプログラム領域が余っていたのでプロトコルの追加で問題ないのだが、TypeB は、AVR910 プロトコルの部分を削らないと入らない...それはすでに USB910 とはいい難いのだが、typeJ44 として作ることにした。この、AVR910 プロトコルを削ってしまったものは、'S' コマンドが返すソフトウェア名を USB910B ではなく SERJTAG に変更した。

Linux での性能評価

同じバイナリ(usb910j44.hex) 4072 バイトの書き込みにどれぐらい時間がかかるか、評価を兼ねて調べてみた。


書き込み ベリファイ  実効性能(bps)
FT245R 版 (SERJTAG) 1.27 秒 0.27 秒 482607
USB910A AVR910     3.99 秒 1.41 秒
USB910A SERJTAG 7.00 秒 6.39 秒 20391
注)実効性能 は、バイト数 x 4 バイト/ベリファイ時間


これを見ると、SERJTAG が全然遅い。AVR910 での書き込みでは、2 バイトの送信 + 1 バイトの受信なのだが、SERJTAG では、4 バイトの送信になる。
また、ベリファイでは、AVR910 は、1バイトの送信と 2バイトの受信で 2 バイト読める。それに対して SERJTAG は 1バイトを読むのに、4 バイトの送信と 4バイトの受信が必要。転送性能が限界の場合 4 倍ぐらい遅くとも妥当ではある。

Windows での性能評価

Windows でも同じような傾向なのだろうか? FT245R 版 SERJTAG と一緒に Windows で評価してみることにする。

準備1: ドライバのインストール
FT245R 版を動かすにはドライバが必要。VCPドライバをダウンロードして展開しておく、ハードウェアウイザードが出たら、展開したディレクトリを指定してインストールする。

準備2:avrdude のビルド
avrdude もビルドする。前に 高速化 USB910 版を作ったが、それに SERJTAG のパッチを当ててビルドした。

さて準備はできた。同じ 4072 バイトのバイナリを書き込んでみる。

書き込み ベリファイ  実効性能(bps)
FT245R 版 (SERJTAG) 1.03 秒 0.73 秒 178498
USB910A AVR910     4.72 秒 1.66 秒
USB910A SERJTAG 2.66 秒 3.55 秒 36705


AVR910 は、Linux より遅くなったが、SERJTAG は速くなった。特にWrite は速く Linux AVR910 より速い。Windows では、転送性能には余裕があり、遅延が性能ネックだったことを示している。

FT245R 版については、書き込みが若干速くなったものの、ベリファイは 2 倍以上遅い結果になった。AVR のプログラマとしては問題ないぐらい速いが、JTAG Cable としては、速ければ速いほど良く Linux より 2 倍も遅いのは問題だ。

送信と受信が ずれ N の値は 10 にしているが、これをさらに大きくすればどうなるか調べてみた。


   N
10 0.73 秒
20 0.50 秒
30 0.47 秒
40 0.41 秒
50
60 0.38 秒
70 0.31 秒
80 動作せず


10 から 70 まで増やせて、性能がゆるやかに上がっていく結果になった。しかし、0.27 秒に肉薄するほどの性能にはならない。

ドライバの設定をみてみることにする。デバイスマネージャからドライバのプロパティを開き、Port Settings の Advanced を開いて見ると ... Read/Write のバッファサイズは 4096 バイトで、Latancy Timer は 16ms だった。ちなみに N = 80 で動作しないのは、受信バッファが FULL になったためだろう。

Latancy Timer を 5ms にしてみる

Windows で遅いのは、遅延が原因なので、16 ms を 5ms にしたらどうなるか見てみた。

まず、書き込み時間が 1.03 秒 から 0.5 秒まで高速化した。


   N
10 0.73 秒 0.44 秒
20 0.50 秒 0.36 秒
30 0.47 秒 0.34 秒
40 0.41 秒 0.34 秒


ベリファイ時間も短くなる。Timer を 5ms にするのは有効だ。ただし、N=30 程度で頭打ちになっていてこれ以上性能は上がらなさそうだ。

どうも遅延を短くすると、スループットが落ちる。良いところ取りはできないらしい。一般的にいってもそうだが、USB でもまたそうであった。

ソースコード

最新版 usb910-0.6.tar.gz  と usb910-0.6.zip  あと更新した serjtag-0.2.tar.gz と serjtag-0.2.zip

今回から、avrdudeのパッチと Windows 版 avrdude バイナリを同梱することにした。serjtag にも同じものを同梱する。

USB910-0.6 での変更点

o typeA SERJTAG プロトコルの追加
o typeJ44 サポート
(typeB ハードの AVR910⇔SERJTAG 入れ替え版)
o AVR-CDC のバージョンダウン
0.5 でバージョンアップしたが、不具合が出たので、
バージョンダウンして、パッチを notyet/verup.patch に
   置くことにした。
o (AVR910) 初期化での SCK クロック自動変更をやめた。
初期化で SCK クロックを変更してたまたま動いても、
意味がないことがわかったのでクロックを妥当な値で固定。
  222 kHz で 8M RC x 1/8 向け。(それ以下は危険。)
o avrdude-5.3.1 へのパッチの同梱(Windows 版バイナリも)


おわりに

FT245R 版 SERJTAG は、なかなか高速で良いものができたと思う。このプロトコル用に JTAG のソフトウェアをそろえていきたい。
まずは、DWM付録用を xilprg でなんとかして、あと玄箱の FLASH 書き換え用もなんとかしたい。ちなみに 玄箱用の JTAG ソフトであれば、OpenWinCE のJTAGツール を改造したものが実績がある。→ FLASH 書き換え成功 (MOTOUJTAG未使用)。以前FLASH を書き換えたときは、この記事を見て、某所から CVS 版を落として... 自作のシリアルJTAG変換ケーブルに対応させて... とやったのだが、ひょっとしたら今はもっといいものがあるかも知れない。
posted by すz at 20:31| Comment(0) | TrackBack(0) | SERJTAG

2007年06月18日

製作とavrdude改造..そしてチューニング

SERJTAG FT245RL USBパラレル変換モジュール版 を製作し、動作の確認を行った。確認には avrdude に対応させて、AVR へのプログラミングを行って確認している。だいたいの機能は確認できたはずだが、8bit 単位でない転送など確認できていない機能もある。

製作編


ほぼ、前回の記事の回路図通り、違う点は 2 つで、PWREN# を無接続にしたのと、電圧調整用ダイオードのうち 2連になっているところを 1 つにした。

例によって、SW-55 に入れるつもりで作ったのだが ... (作ってから)モジュールが高すぎて、入らないことがわかった。IC ソケットを使わないようにしないと、13mm (20mm - 上 2mm/下 5mm) に収まらないので注意。

ケーブルは、カモン USB-05を切って作った。


シールドも使うと コネクタ付きの線が 5 本になるので、JTAG/AVR ISP に使える。コネクタが 1pin 単位なので、いろんな PIN 配置に対応できて便利。しかも安い。千石で通販しているし、店頭でも売っている。PC関係のパーツ屋でも扱っていると思うが、千石だと 263円と安い。
ちなみに、3.3V 出力を外に出している。全部で 50 mA しか流せないが、AVR プログラミング用には十分。

avrdude 改造

作ったからには、AVR のプログラミングもできるようにしたい。テストも兼ねて、avrdude を改造することにした。

avr910.c と usbasp.c の2つをにらみながら serjtag.h と serjtag.c を作った。シリアルの制御と初期化でのコマンド発行は、 avr910.c をベースにして、chip_erase の処理は、usbasp.c をベースにしたうえで、他の処理も参考にした。avrdude は、基本的に cmd を使って いろんな処理をしてくれるので、paged_write と paged_load に注力すればよく、作るのは楽だった。( paged_write/paged_load を作らなくても動く。ただし、汎用の cmd() を使うのですごく遅い。) 。ただ、paged_write と paged_load は、FLASH だけではなく、EEPROM にも対応しなければならない。EEPROM までまじめに作るのは面倒なので、avr.c の共通ルーチンをベースにした。

新しいプログラマを組み込むには、Makefile.in を修正するのはもちろんだが、それ以外に config_gram.y , lexer.l , avrdude.conf.in にも修正が必要だった。

テストとデバッグ

動かすまでは大変ではあったが、ざっくり省略。1つだけ教訓がある。

それは、ぎりぎりの SCK クロックで動かすなということ。途中でコマンドが化けて FUSE BIT を書き換えてしまうかも知れない。

avrdude は良くできていて、最後に FUSE BIT をチェックしてくれて、FUSE BIT が(意図に反して)書き換わってしまったら、元に戻すか聞いてくれる。メッセージをよく読まないでアボートしてしまうと、高電圧プログラミングでないと戻せない状態になってしまう場合がある。(ターゲットに ATtiny44 を使っていたのだが、アボートしてしまい、書き込みできない状態にしてしまった。2 つダメにして、そういうことかと後で気が付いた。)

簡単にダメにしてしまったのは、もうひとつ原因がある。CPU クロックを 1/8 にする設定がデフォルトだが、これだと 1MHz で、ISP 書き込みのクロックは、1/4 の 250kHz を超えないようにしなければならない。 1/8 にするのを DISABLE にすれば、2MHz まで OKで、高速化しない限りなかなかその周波数にまではいかない。

ちなみに、HSV で元に戻すボードとプログラムはあるので、ダメにした ATtiny44 は元に戻せるはずだが、ちょっと面倒。

チューニング

paged_write と paged_load を作らないバージョンは、4072 バイトの書き込みに、66.54 秒、ベリファイに 63.13 秒もかかった。1バイトの書き込みに 4バイトの送信と受信をするので、(転送量はともかく)受信の遅延のために時間がかかるのだ。(計算すると遅延は、15 ms ぐらい)

さて、paged_write と paged_load を すなおなコードで作ってみた。書き込み時間は、1.72 秒、ベリファイ時間は、4.66 秒になった。SERJTAG では、SPI の結果を(デバイスが)送信しないようにできるため 1ページ分は受信が必要なく送信を連続してできる。なので、書き込みは結構速い。しかし、ベリファイが予想以上に遅い。

そこで、paged_load については、
AVR-CDCの性能(2)で書いたように ソフトウェアパイプライニングを使ったチューニングをすることにした。

ちょっと長いが、ポイントとなるコードを載せて説明しようと思う。


static struct serjtag_request {
int addr;
int bytes;
int n;
struct serjtag_request *next;
} *req_head,*req_tail,*req_pool;

static void put_request(int addr, int bytes, int n)
{
struct serjtag_request *p;
if (req_pool) {
p = req_pool;
req_pool = p->next;
} else {
p = malloc(sizeof(struct serjtag_request));
if (!p) {
fprintf(stderr, "can't alloc memory\n");
exit(1);
}
}
memset(p, 0, sizeof(struct serjtag_request));
p->addr = addr;
p->bytes = bytes;
p->n = n;
if (req_tail) {
req_tail->next = p;
req_tail = p;
} else {
req_head = req_tail = p;
}
}

static int do_request(PROGRAMMER * pgm, AVRMEM *m)
{
struct serjtag_request *p;
int addr, bytes, j, n;
char buf[128];

if (!req_head) return 0;
p = req_head;
req_head = p->next;
if (!req_head) req_tail = req_head;

addr = p->addr;
bytes = p->bytes;
n = p->n;
memset(p, 0, sizeof(struct serjtag_request));
p->next = req_pool;
req_pool = p;

serjtag_recv_j(pgm, buf, bytes + 3, 0);
for (j=0; j<n; j++) {
m->buf[addr++] = buf[3 + 4*j + 3];
}
return 1;
}


受信のリクエストを出したら、put_request() を使って、受信処理(のパラメータ)を登録(キューイング)する。で、do_request() は、キューから1つ取り出して、受信処理を行う。

put_request()を出したその後ですぐ do_request()を call するならば、普通の処理と変わらない。コードで書くならこう。

for (i=0; i< LOOP_COUNT; i++) {
:
put_request(...);
do_request(...);
}

そこから、最初の N 回は、put_request()を出しておくが、do_request() を call しないようにする。そして、最後に do_request() が 1 を返す間 call してキューイングされた分を刈り取る。

for (i=0; i< LOOP_COUNT; i++) {
:
put_request(...);
if (i >= N) do_request(...);
}
while (do_request(...))
;

こうするわけだ。これで送信と受信が N ずれる。

N を 0 から増やしていくと .. ベリファイ時間は次のようになった。

   N
0 4.66 秒
1 2.79 秒
2 1.93 秒
3 1.50 秒
4 1.22 秒
5
6 0.94 秒
7 0.87 秒
8 0.48 秒
9 0.28 秒
10 0.27 秒
11
12 0.27 秒
13
14 0.27 秒


こうすることで、4.66 秒が、最終的に、0.27 秒まで高速化できたのだ。1バイト書くのに 32bit の送信と受信をしている。JTAG 的には 片側 480 Kbps (帯域的には、960kbps) が出ていることになる。FT245R の BitBangMode の想定性能の 2 倍ぐらい?(8Mbps / 16 / 2 = 250 Kbps ) が実効性能として出ているし、目標とした性能(500kbps 〜 1Mbps) のレンジにかなり近い。性能的には満足だ。

ちなみに 480kbps 出たとして、玄箱の FLASH を書き換えるとすればどうなるか ...
480000 / (507 * 3) = 315 (byte/sec) 。... 64KB 書き換えるのに 209 秒 、 4MB なら 3.7 時間。
JTAG Cable としても、使える範囲に入ってきていると思う。


ベリファイはこれだけ速くなるが、書き込みの高速化は難しい。1ページ書き込み毎に delay を保証しないといけない。write を直接出すのではなく、バッファリングすることで、1.72 秒が、1.28 秒にまで短縮したが、それ以上は無理そうだ。

なお、これらのテストは、Linux (2.4.31) で行った。avrdude のパラメータは、

avrdude -pt44 -c serjtag -P /dev/ttyUSB0 -b 3000000 \
-B 4000000 -U flash:w:usb910j44.hex

としている。-b は、ボーレートの指定。あまり関係なさそうだが、avrdude も改造して、できるだけ大きくした。-B は、SCK のクロック値。4Mhz 以上に設定すると、(プロトコル上) 一切の遅延をしないようになる。(といっても、テストのために、serjtag のプログラム側で nop() などで遅延して、2MHz 以上にしないようにしている。serjtag は USI を使っていて、本当は 4Mhz。)ちなみに、-B を指定しないと、250 kHz 以下になり、8Mhz RC クロックの 1/8 の設定でも問題ないようにしている。

ちなみに、usb910j44.hex は、USB910版。ATtiny44 の typeB の回路ベース。FLASH が足りないので、 AVR910 プロトコルは サポートしていない。すでに USB910 と言えないが、それはさておき、USB910版は、書き込み 7.00 秒・ベリファイ 7.19 秒だった。詳しくは次回に書く予定。


以上のプログラムは、serjtag-0.2.tar.gzに置いた。avrdude-5.3.1 へのパッチも同梱している。
posted by すz at 23:13| Comment(0) | TrackBack(0) | SERJTAG

2007年06月15日

DWM付録FPGA基板用USB-JTAGケーブルの構想

デザインウェーブマガジン 2007年7月号 (2480円)には、付録に 250K ゲート相当 のFPGA Spartan-3E XC3S250E 基板が付いて来る。こいつで使え、簡単に作れる USB-JTAG ケーブルを設計してみようと思う。

私にとって簡単なのは、USB910A に JTAG 機能を付けることが最も簡単だ。Spartan-3E の JTAG の電圧は 2.5V だが、前に Spartan-3 がDWM付録になったときのなひたふさんのコメント -- Spartan3 の使い方 によると、3.3V I/O電圧 でも 100Ωぐらいの抵抗を入れれば OK らしい。... USB910A は 3.3V モードがあって、150Ωの抵抗もすでに入っているので改造をする必要がなく、FW のソフトと書き込みソフトだけをなんとかすればよいのだ。

それはもちろんやるとして、部品の入手性に問題がなく、もっと簡単に作れて、さらに速いものにしたい。もちろん AVR を使い、FWは (拡張した)USB910 のサプセットにする。
補足:
JTAG 用なので、速くなければ使いにくい/使えない場合がある。
端的な例がバウンダリスキャンを使っての FLASH 書き込み。以前 玄箱の FW を壊してしまって、簡単な Serial-JTAG ケーブルを作って書き換えたのだが、バスの状態を設定するのに、507 ビットの転送が必要、書き込むために、バスの状態を 3 回変更するので、1500 bit ほどの転送をする。これで FLASH の 1 バイトしか書き込めないのだから、実に 187 倍もの転送量になるのだ。 作ったやつはスループットも出なかったので日が暮れるどころの騒ぎではなく、実に大変な目にあった。

USB910が遅いのは、ひとつには LOW SPEED であることが原因だ。AVR-CDC ではなく、専用のチップを使えば転送速度があがるはずだ。USB-シリアル変換だと シリアル自体が性能ネックになりそうなので、パラレルの FT245RL を使う。データシートによれば、専用ドライバで 1MB/sec 、汎用のシリアルドライバでも 300KB/sec 出るそうだ。もちろんこれだけが速くなっても性能は出ない。プロトコルとか、AVR のコードも最適化する必要がある。がんばりたいとは思うが、AVR の限界もあって、市販のものと比べる程の性能は出ない(かも知れない)。

簡単に作れるようにするために、FT245RL USBパラレル変換モジュールを使う。同種のモジュールと比べても安価な方だと思うし、USB コネクタも付いている。

本体のAVRは、ATtiny2313V を使う。秋月で入手できるし、安価だ。
プログラムメモリは 2KB しかないが、JTAG とI2C の機能だけなら、問題なく移植できる。ATtiny2313V、FT245RL ともに 1.8V まで動作電圧(FT245RL の場合は I/O電圧) を下げることができる。2.5V の場合は 3.3V +抵抗でもなんとかなるが、今後のためにもっと低い電圧もサポートしておきたい。

.. というようなことを考えて回路を考えてみたのが↓



回路図といえるほどのものではなく、配線図という感じだ。ただ、ATtiny2313V のピンは全部使うので、配線は面倒かも知れない。


製作例:

ダイオードは、2個連のところを1つだけにしてみた。あと PWREN# は無接続

書き込みソフトについて

オープンソースで、xilprgというものがある。これは、Digilent の
JTAG-USB
を サポートしていて、コンフィグレーションできるだけではなく、CableServer を使うと Xilinx のツールである iMPACT から直接書き込みできるようなるものらしい。

こいつに作った SERJTAG のコードを追加して、JTAG として使えるようにする予定。(その状況もこのカテゴリに書いていく。)

プロトコルは、Digilent の JTAG-USB用のコードを研究して、決めた。当然ながら、Digilent の プロトコルに(論理的には)似ていて、JTAG-USB用のコードを改造して作るのも容易(なはずだ)。
補足:
Digilent の プロトコルは、バルク転送向けなので同じようにはできない。また AVR で性能を出すために変更しなければならない所もある。さらに、USB910 に組み込む前提なので、USB910 のプロトコルともすり合わせる必要があった。
ちなみに、決めたプロトコルは、シリアル向けのものなので、Serial Jtag という意味で SERJTAG と名づけた。SERJTAG はプロトコル名のつもりなので、USB910 の拡張の話題もこのカテゴリに書くつもり。


(FT245RL版 )SERJTAG は、USB910 の I2C 機能も入れる。なので、I2CSND でも使える予定。
あと、JTAG ケーブルというのは、汎用 SPI にも使えるので、AVR ISP にも対応可能だ。AVRDUDE とか UISP とかの AVRライタソフトにも対応させようと思う。
デバッグ前だが、プログラム → serjtag-0.1.tar.gz
チューニングできるところはしたつもり、サイズは、1.8KB ほどなのでまだ余裕がある。(ちなみに WinAVR の gcc-4.1.1 だと 1654 バイトと 1 割近く小さくなる。)

DWM付録FPGA基板に関するその他の話題

●クロックについて
ググっていて、Sim's blog というところを見つけた。FPGA の話題も多く参考になりそうだ。FPGA でなにかを作ろうとすれば、クロックは必要だが ... DWM付録基板のクロックによると、SG-645PCP(33MHz) (4個 300円) が使えるそうだ。そういえば、FT245R に OSCO というピンがある。12MHz でよければ 供給できるかも知れない。

OSCO は無接続だったのでクロック供給は、無理そうだ。以前 現品.com で5個200円で入手した KOYO(光陽精密)の KCO-700シリーズ (pdf) 32.000 Mhz を接続した。


●BitBangModeについて
FT245R(など) は、何もつけなくとも I2C/JTAG/SPI として使えるらしい。Programming Guidesに、それらのAPI が載っている。...こんなモノ(SERJTAG)を付けるよりずっと性能が良かったりするかも知れない。それはともかく、SPI もサポートしているから、FT245RL USBパラレル変換モジュールはそのままでAVRライタになるわけか。

訂正:
I2C/JTAG/SPI として使えるのは、the Multi-Protocol Synchronous Serial Engine (MPSSE) を持っている FT2232 だけということが判った。秋月でこのチップを扱っているもののモジュールはない。APIも MPSSE 専用。

補足:
ガセを書いてしまって申し訳ないので、D2XXのプログラミングガイドと FT232R/FT245R の BitBangModes のドキュメントを読んでみた。
これと FT2232 は、同期 BitBangMode というのを持っている。なにが同期かというと、FT_Write で値を変更する前の状態を(自動で)取り込み、FT_Read で読める。WriteとRead が同期しているわけだ。もちろん、入力ピン出力ビンの設定もできるから、I2Cは無理としても、JTAG や SPI には使えそうだ。ちなみに、非同期モードは、同期しないと、正しい状態が読めない。だから更新前の情報が必要な JTAG/SPI は遅い。
あと、転送レートを FT_SetBaudRate で指定する。この値 x 16 のデータが流れる(8bit x 往復?) ので、最大で 500kbps 。CLK 上げ下げとデータセットが必要そうだから、JTAG/SPI のビットレートは最大で 166kbps 。最大性能だと 8Mbps の帯域を使ってしまうから、 80kbps ぐらいが実効性能として妥当だろう。...これぐらいなら USB910版の SERJTAG でも出せそうだ。... といっても AVR のライタとしては十分な性能。avrdude に移植されているか..といえばされていないわけでもないらしい。→ ftbb.c。ただし、非同期モードを使っているので、すごく遅いはずだ。 この ftbb.c を同期モードで書き直せば、一応実用的な速度で動きそうだ。これだけ調べたけれども I2C もサポートする SERJTAGを作りたいので、これには手を出さない(かもしれない)。

追記:設計メモ
FT245R/FT232R は BitBangMode を持っているわけだが、FT232R の方は、入出力の初期状態が決まっている。なので、BitBangMode を使う場合 FT232R にあわせて設計したほうが良い。
ELM COMポート制御ISPアダプタ のピン配置を参考にすると

chip pin# BitBang bit
( = FT245R D#)
MISO RxD 5 1
SCK RTS 3 0
MOSI TxD 1 2
RESET DTR 2 4

あたりが妥当か。ただし、avrdude では、avrdude.conf で ピンの配置を自由に設定できるので、単にデフォルトと思えばよい。

●オプション5Vレギュレータについて
DWM付録FPGA基板を5Vで使うときは、LM317系の可変型3端子レギュレータを付けられるが、秋月で扱っているのは、どれも大きい。ひょっとして、AZ1117H−ADJ (表面実装型、10個300円)が付くのではないだろうか? FT245Rを注文したついでに買ったので、試してみたい。

追記:接続はできるようだ↓。(ただし未通電)


posted by すz at 18:46| Comment(14) | TrackBack(0) | SERJTAG