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
この記事へのコメント
すzさん、お久しぶりです。

現在、avrdudeの拡張を行っており、
すzさんのFTDI BitBangドライバを含んだ
avrdude-5.10svnをベースにしたものを
作成しました。

http://www-ice.yamagata-cit.ac.jp/ken/senshu/sitedev/index.php?AVR%2Fnews56#j35549c5

独自に改良を加えたavrdude-GUIとペアで評価用に公開しています。
(不具合がなければ、別途、パッケージングは考えます。今は
ソース差分も付けておりません)

現在確認している問題点は、FTDI BitBang でISP後、仮想COMポートでの
通信が上手く機能しません。USBコネクタの抜差しで回復しますが、改善
したいと思っています。

お忙しいところ恐縮ですがアドバイスをいただけると幸いです。


Posted by senshu at 2010年06月29日 11:29
上記の問題を解決しました。

詳細は、以下をご覧ください。

http://www-ice.yamagata-cit.ac.jp/ken/senshu/sitedev/index.php?AVR%2Fnews56#p3105d33
Posted by senshu at 2010年06月30日 10:06
返事が遅れてすいません。

新版では、-E reset ( / noreset ) で 終了時の状態を 決めるようにしたわけですが、第三の状態が必要ということになりそうです。

でも -E reset ( / noreset ) は標準の機能を使っているので、拡張するのが面倒というのが問題です。

悩んだのですが、この際 -E reset を "元の状態に戻す" と 定義することにしましょう。

reset ピンが入力か 出力でも H がデフォルトなら影響ないはず。L がデフォルトなら影響あるわけですが、そもそも そういうケースでは自動実行しようとは思わないはず。
Posted by すz at 2010年07月07日 23:27
すzさん、コメントをありがとうございます。

ターゲットのAVRの動作もそうですが、仮想COMポートによる
通信が出来ない点が最大の問題と感じているのです。

BitBang modeを解除しないと、通信に不具合が生じると
理解しています。

>この際 -E reset を "元の状態に戻す" と
>定義することにしましょう。

この文の意味が理解できないのですが、-E resetと書けば、
私の意図する動作になる、ということでしょうか。

Posted by senshu at 2010年07月10日 21:10
変更した部分の すぐ上の if 文が -E reset で 動作する所です。

同じように if 文で括ってください。

こちらでも更新するときに直しておきますが、いつになるか ...
Posted by すz at 2010年07月12日 04:23
-E resetを指示したときには、BitBang modeをresetする、
という仕様にするわけですね。

了解しました。5.10svn版にその修正を行い、公開します。
Posted by senshu at 2010年07月12日 09:47
すzさんのアドバイスをありがとうございました。

「-E reset」に限定して機能するように修正し、シリアル番号の
自動取得機能などを追加した、avrdude-GUIと共に暫定的に公開し
ています。

http://www-ice.yamagata-cit.ac.jp/ken/senshu/sitedev/index.php?AVR%2Favrdude04#d35cf338

興味があれば、使ってみてください。



Posted by enshu at 2010年07月12日 19:52
FTDI BitBangライタを製作し、動作テストを行っています。

現在、90S8515, 90S2313といった旧タイプのAVRマイコンで
エラーになる現象を確認しました。

t2313, t26L, m88, m168, m328P では問題なく動作します。

私が手を入れた部分で副作用が起きた可能性もありますが、
すzさんのところで 90S2313などで動作確認したことがあれば
教えてください。

当面は、それらを利用しないという後ろ向きの方法で対応し
ようと考えています。
Posted by senshu at 2010年07月14日 21:55
対応しているのは、tiny/mega 以降で 128KB までだったと思います。

古いのがダメなのは、page 書き込みしか対応しなかったためだったような ... 初期化も怪しいですが。
Posted by すz at 2010年07月15日 06:23
ソースコードを確認してみました。

page 書き込みの件は OK 。 AT902313 などは、avrdude.conf で page 書き込みしないような指定になっています。

問題は初期化(program_enable) ですが、delay を増やせば対応できそうな感じ。

具体的には、isp モードに入るためにリセットパルスを出しますが、その後の usleep(5000) (3つめのやつ)を usleep(20000) にすれば良さそう。
Posted by すz at 2010年07月15日 20:59
>問題は初期化(program_enable) ですが、delay を増やせば対応できそう
>な感じ。

>具体的には、isp モードに入るためにリセットパルスを出しますが、
>その後の usleep(5000) (3つめのやつ)を usleep(20000) にすれ
>ば良さそう。

ソースを確認してみましたが、ご指摘の個所は既にusleep(20000)に
なっています。HIDaspxではAT90S2313でも正常に認識しますが、この
時のコードは、以下のように、もう一捻りしています。
単純にパルスを出すだけでは、旧タイプのAVRマイコンには対応でき
ず、SCK信号を操作する必要がありました。

static  void ispConnect(void)
{
  /* all ISP pins are inputs before */
  /* now set output pins */
  ISP_DDR = (1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI) | ISP_DDR_DEFAULT;

  /* reset device */
  ISP_OUT &= ~(1 << ISP_RST);    /* RST low */
  ISP_OUT &= ~(1 << ISP_SCK);    /* SCK low */

  /* positive reset pulse > 2 SCK (target) */
  delay_10us(6);          //@@x ispDelay();
  ISP_OUT |= (1 << ISP_RST);    /* RST high */
  delay_10us(100);        //@@x ispDelay(); -> 1ms
  ISP_OUT &= ~((1 << ISP_RST)|(1 << ISP_RDY));  /* RST low , LED Low*/
}
Posted by senshu at 2010年07月16日 09:26
すいません。古いソースを見てました。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r.c

対応したのを作ってみたので試してみて頂けませんでしょうか?
Posted by すz at 2010年07月16日 20:19
貴重なコードをありがとうございます。

AT90S2313, 90S8515での動作を確認しました。

BitModeのリセットの戻り値を確認し表示
するコードを追加し、適用しました。

機能を
Posted by senshu at 2010年07月17日 11:36
手持ちのAVRマイコンは全て動作を確認しましたので、
テスト結果も更新しました。

なお、私の名前は「senshu」と称していますので、
よろしくお願いいたします。
Posted by senshu at 2010年07月17日 15:56
動作確認ありがとうございます。最新版として avdude-serjtag-04f.zip を暫定リリースしました。

> なお、私の名前は「senshu」と称していますので、よろしくお願いいたします。

大変申し訳ない。これから気をつけます。
Posted by すz at 2010年07月17日 19:15
すzさん、こんばんは。

2点ほど教えてください。

(1) 予想よりも遅い
-Bでは MHz単位でbaud rateを設定していますが、
指定した値にならないので調べてみると上限値は
460800になっています。921600や3000000のような大き
な値にも対応できそうなのですが、上限を制限する必要
はありますか?

(2) TX, RXの信号線を接続してISPを行うと、書き込んで
いるプログラムによっては、信号同士が競合し、FUSEの
読み出しに失敗する、との報告があります。
プログラムに0.5秒ほどの停止を入れると問題は収まると
のことです。なお、この状態でもフラッシュ書込みは可能
です。

先の現象が起きる場合でも、TX, RXの信号線を切り離せば
問題は解決するのですが、Arduinoのように切り離すのが
困難な環境もあります。解決方法は無いでしょうか。
FTDIチップのDDR操作で解決できそうな気もするのです
が、、。

以上、2点のアドバイスを戴ければ幸いです。


Posted by senshu at 2010年07月19日 02:39
>(2) …FUSEの読み出しに失敗する
の件は、私が追加した「Bitbangモード」の
リセットでシリアル通信が行われ、「FT232
内のUARTにデータが入力される事により生じ
る不具合では、との指摘がありました。

そこで、BitBangモードに移行したときに、
過去のシリアル通信データによる影響を
回避するため、データを捨てる処理を追加
したいと考えています。

アドバイスをいただければ幸です。
Posted by senshu at 2010年07月19日 10:42
もう一度、FTDI社のマニュアルを読んでみました。

以下の資料(AN232R-01_FT232RBitBangModes.pd 7ページ)によれ
ば、1MHz未満が無難で、実際のビットレートは、baud rateの16倍
となっています。

実際の利用を考慮すると -Bによる指定では、実際のSCKレートを
指定できた方が混乱が少ないと思います。

例えば76.8kでは1,228,800Hzとなり、SCK クロックを動作周波数の
1/4とすれば、1MHz動作用としては、かなりのオーバースペックです。

現行のコードでは指定した値を1/2にして適用していますが、実際に
は1/16にすべきではと思いますが、いかがでしょうか。

なお、現行よりももう一段高速な921.6kHzの指定も可能ですが、AVR
マイコンの動作クロック1/4以内とすれば、指定できるAVRマイコンが
ありません。

省略値の 230.4kHzでも 230kHz*16*4 = 14.72MHzです。これが事実上の
最大値になるのでしょうか。

実際には、baudrateはもっと柔軟に指定できます。230.4kHzではなく
250kHzなどを指定すれば効率もあがり、シンプルなコードにできそう
です。

FT232について知らない者が、データシートを片手に意見を書いて
います。誤りがあれば、ご指摘ください。

> FT_SetBaudRate
>
> The rate of data transfer can be controlled
> by using the FT_SetBaudRate command. The
> maximum Baud rate is 3MBaud, but to allow
> time for the data to be setup and held
> around the WR# strobe the Baud rate should
> be less than 1MBaud.
>
> The clock for the Synchronous Bit Bang mode
> is actually 16 times the Baud rate. A
> value of 9600 Baud would transfer the data
> at (9600x16) = 153600 bytes per second,
> or 1 every 6.5 mS.
Posted by senshu at 2010年07月19日 16:09
SPAMのような書き込みですみません。

9600 * 16 = 153,600バイト!です。

この表記は、「baudrateの16倍のバイト転送ができる」
ことを意味しているのですね。MISO, MOSI, SCKによる
シリアル転送なので、この値にはなりませんが、-Bに
よる指定は、Baudrateの値指定を変更する方が誤解が
無くなると思います。(計算が合わなくて、かなり
悩みましたので)

> The clock for the Synchronous Bit Bang mode
> is actually 16 times the Baud rate.
> A value of 9600 Baud would transfer the data
> at (9600x16) = 153600 bytes per second,
> or 1 every 6.5 mS.
Posted by sebshu at 2010年07月19日 18:36
設定可能なこととその実力には違いが
あることがわかりました。

http://einst.hp.infoseek.co.jp/PICerFT/PICerFT.html

↑の「■FTDIの基本動作確認」の項を
ご覧ください。

この解説で、ようやく予想との乖離の
理由が理解できました。

多大な期待はせずに、現状で満足する
ことになりそうです。

Posted by senshu at 2010年07月19日 19:19
-B 指定と性能については、前記事

http://suz-avr.sblo.jp/article/30760403.html

を見てください。-B は正確に SCK のクロックです。転送が間に合わなければ性能は落ちます。

自由な値に設定しないようにしているのは、期待どおりに動かなかったためです。

もっと高いクロックに対応するのは、avrdude-5.8-baud.patch を参考にしてください。FT232RL では無意味ですが、FT2232 あたりだと意味が出てきます。

TX, RXの信号線は、普通なら入力にしているので信号はぶつからないはずです。あと、drain で buffer から吸い出しているつもりですが、不十分だとすればこの関数内で対処すべきです。待てば解決するのであれば、usleep を入れてみるのも手です。
Posted by すz at 2010年07月20日 04:02
すzさん、アドバイスをありがとうございます。

FUSEの件は、avrdude-GUI側で対処しました。FUSE読み出しでは、
-E resetを行わない、という方法で解決しました。

ビットレートに関しては、もう少しデータを整備し、実際に計測を
行うなどして、検証を行いたいと思います。

いくつかの改良を行った「avrdude.exe, avrdude-GUI.exe」を暫定的に
公開中です。

http://www-ice.yamagata-cit.ac.jp/ken/senshu/sitedev/index.php?AVR%2Favrdude05#r3d2a227
Posted by senshu at 2010年07月20日 19:22
avrdude-GUI でどういう使い方をしているのか知らないのですが、もし avrdude を複数回実行するなら、最後だけ -E reset が正しい(想定している)使い方です。close 的に使いたいならオペレーションなしの -E reset もあり。
Posted by すz at 2010年07月21日 06:51
いつも有益なアドバイスをありがとうございます。

今、BitBangライタを評価中ですが、一点、どうしても納得でき
ない結果で困っています。

EEPROMの読み出しが極端に遅いのです。mega644pの2kBの
EEPROMで表書いていますが、Atmel純正のAVRISP-mkIIでは
0.38秒ですが、BitBangライタでは、30秒以上を要します。

これは、GUIの操作は無関係で、手入力したコマンドでも
同じ結果です。

以下のURLにテスト結果を書きました。
何らかのヒントをいただければ幸いです。

http://www-ice.yamagata-cit.ac.jp/ken/senshu/sitedev/index.php?AVR%2Favrdude05#x9a2d270

Posted by senshu at 2010年07月21日 19:10
eeprom は 1バイトづつ読み込みますが、1回ごとに USB による遅延が入ります。30,000 ms/2048 = 14.6 ms で オーダ的にはおかしくなさそうです。90S2313 の FLASH 読み込みと大差ないはず。

FLASH の読み込みは、ブロック単位なうえ 数ブロックをオーバラップさせているので高速です。eeprom はそこまでやる必要はなく、ページ単位での読み書きを追加すれば 1秒以内になりそうです。
Posted by すz at 2010年07月21日 22:18
現状では、この速度は妥当な結果ということ
なるわけですね。ちょっと残念ですが了解です。

時間をみて、EEPROM用のPAGE単位のR/W機能を
追加してみます。

不明な点が出てくれば、また質問するかも
知れませんが、よろしくお願いいたします。
Posted by senshu at 2010年07月22日 07:51
paged_load_flash をコピーしたら簡単そうに思えたので作ってみました。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04g.c
http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04f.c (変更前)

ところで -B の件ですが、次のようにして検証して頂けませんでしょうか?

1) 低速 ( -B 4800 とか -B 36400 ) とかで read 性能を測定する。

-- 低速ならば、実効性能が理論性能に近くなります。

2) 得られた性能値 (bytes/sec) x32 が いくつになるかを調べる。

-- 1 バイトに対して 32 クロックかかるのでこの値が SCK クロックです。

Posted by すz at 2010年07月22日 20:00
すzさん、有用なコードをありがとうございます。

ft245r-04g.c で導入されたeepromのページ対応で34秒から、
1.9秒と劇的な速度向上が得られました。

ただし、EEPROMの読み出しには別の問題を確認しました。
原因は特定していませんが、常に 0xffが読み出されるのです。

読み出し操作で do_request関数には意図した値が渡されます
が、ファイルに書き出す段階では 0xffとなり、その結果
:00000001FF のみの内容になります。

ちなみにAVRISP-mkIIでは正常に出力されます。

また、書込みは110秒と長大な時間を要しましたが、別のハード
で読み出したところ、正常に書き込まれていました。

何か勘違いしている可能性もありますが、修正の前後でもこの
不具合は変わりません。

アドバイスをいただければ幸いです。

P.S.
-Bの件は、この件が解決後に調査いたします。
Posted by senshu at 2010年07月23日 09:43
原因がわかりました。

正常終了時、読み出したバイト数を返す
部分が「常に0」を返していました。

修正し、OKになりました。
Posted by senshu at 2010年07月23日 16:46
paged_load の戻り値の 仕様が read した バイト数だったわけですね。"flash" が 0 でも動いたのは、後で細工しているから -- なるほど。

eeprom の write は変更が面倒そうです。上記のバグ修正するとき検討はしてみますが、ちょっと時間がかかるかも。
Posted by すz at 2010年07月24日 03:04
>eeprom の write は変更が面倒そうです。上記のバグ修正
>するとき検討はしてみますが、ちょっと時間がかかるかも。

私も、勢いで修正版を書いてみましたが、ページ対応の
コマンドの使い方を誤解しているようで、書込みできない
という状況です。(実行時間はかなり短縮されるのですが)

ぜひ書き込みも改良したいので、よろしくお願いいたします。
Posted by senshu at 2010年07月24日 06:59
作ってみました。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04g2.c

作ったコードは通常 undefine されている USE_INLINE_WRITE_PAGE 部分のコードをベースにしています。動かない場合 ベースのコードがバグっている可能性があるので、USE_INLINE_WRITE_PAGE を define しても FLASH への書き込みができるか確認してください。


Posted by すz at 2010年07月25日 00:22
すzさん、ありがとうございます。

私が書いてみたコードは USE_INLINE_WRITE_PAGE では無い
方法でしたが、0xC1といったEEPROM操作のコマンド部分が
怪しいコードでした。今回提示していただいたコードで
試して、その結果を報告いたします。

なお、 serjtag.c でも同様のコードですので、EEPROM読み
出しの不具合が残っていると思われます。今回の改良で得ら
れた成果を導入してはいかがでしょうか。

Posted by senshu at 2010年07月25日 07:14
>作ったコードは ...
>動かない場合 ベースのコードがバグっている可能性があるので、
>USE_INLINE_WRITE_PAGE をdefine しても FLASH への書き込みが
>できるか確認してください。

試してみました。動作は完了しますが、ブロックごとの先頭バイト
の書き換えしかできません。

もう少し粘ってみますが、USE_INLINE_WRITE_PAGEを有効にすると
Flash書込みでも類似のエラーになります。USE_INLINE_WRITE_PAGE
は使えないと考え、使わない方法で修正を行ってみます。

アドバイスをいただければと思います。

Posted by senshu at 2010年07月26日 10:25
> USE_INLINE_WRITE_PAGEを有効にすると
> Flash書込みでも類似のエラーになります。

困りました。

ちょっと見ているんですが、(define する/しないで) ロジックの違いはないように見えてます。これが動かないなら タイミングの問題 かも知れません。

そうなると usleep を疑うことになってしまいますが、avrdude は ... なんか変なコード使ってますね。... マルチコアで問題でそうな。

最初のコードを作ったのは 3年前なので記憶が定かではないのですが USE_INLINE_WRITE_PAGE は動かないから undef にしたのではなかったように思います。

性能が同じだったので、より安全そうなのを選んだような覚えがあります。

> なお、 serjtag.c でも同様のコードですので、EEPROM読み出しの不具合が残っていると思われます。

そうですね、忘れてました。コメントありがとうございます。
Posted by すz at 2010年07月27日 02:53
現時点でわかったことを報告します。

(1) EEPROMではm->paged == no です。

avrdude.confを読んでみると、ほぼ全てが "no"です。
これは、1バイト単位の書込み可能を意味するようです。
そのため、現行のコードではページ単位の処理が行われ
ていませんでした。

そこで、「if (m->page_size) { // m->paged 」のように
修正してみると、エラーが起きますが、読み出してみると
(インクリメントデータを書いています)

0000 00 01 02 03 04 05 06 07 FF FF FF FF FF FF FF FF
00 01 02 03 04 05 06 07 FF FF FF FF FF FF FF FF

のように、8バイト毎に書き込まれます(おしい!)

もう一息なのですが、アドバイスをいただければと思います。
Posted by senshu at 2010年07月27日 14:14
EEPROMの書き込み高速化にはデータシートを熟読していますが、
AVRマイコンでは、512/1k/2kと異なるサイズのEEPROMを一つの
表で表している場合が多く、誤読してしまうのが難点です。

何度も読み直して、ようやく仕様が見えてきました。
わかってしまえば難解とはいえませんが、誤解を生み易い
部分があると感じました。

私なりに書いていますが、すzさんのアドバイスもお待ちして
います。
Posted by senshu at 2010年07月27日 22:41
> (1) EEPROMではm->paged == no です。
> これは、1バイト単位の書込み可能を意味するようです。
そうでしたか。pgmled の処理もまずかったので、直したものを

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04g3.c

に置いておきます。すいませんがこれをベースにしてください。

> エラーが起きますが、読み出してみると(インクリメントデータを書いています)
> 0000 00 01 02 03 04 05 06 07 FF FF FF FF FF FF FF FF

ページおきということは、遅延が足りないから次が無視されるとか...

タイミングの問題かどうか切り分けるために
1) usleep で Sleep 関数を使う。
2) avrdude.conf の eeprom の max_delay を 仮に 10 倍にする。
3) -B で指定するクロックを 遅くする。
をやってもらえませんでしょうか?

もしそれで動くのなら、タイミングの問題です。
Posted by すz at 2010年07月27日 23:56
ft245r-04g3.c を試してみました。結果を報告します。

× Sleep関数に置き換える
× max_delay を 10 倍にして適用
× -B 600, 1200 でNG

という具合で、まだ不完全です。

さらに遅くすれば、データ化けの確率は低下しますがページの先頭
バイトが化ける確率が高いようです。しかし、これ以上のディレィ
の追加は、1バイト書込みよりも遅くなる(1バイト書込みは正常に
機能する)ので、意味がありません。

Atmel社の AVRISP-mkIIが2048バイトの書込みで2秒未満なので、
せめて10秒未満になればと思うのですが、現状では34秒ほど
かかります。

でも、高速動作よりも確実性を重視すべきであり、当面はこれで
行くことにします。

コードを読む限り、問題点は無いように思えるのですが、、、。
Posted by senshu at 2010年07月28日 10:54
やって頂きたかったことは、1),2),3) 全部を適用したとき、正しく書き込めるかどうかです。

もし、正しく書き込める(ことがある)ならば、送り出すデータ列そのものは正しいと言えます。
そうすると余計なことを考えずに済むわけです。

ちなみに、USE_INLINE_WRITE_PAGE が define されるかどうかによって、送り出すデータ列が変わることはないはずです。違いは、ページ内データの書き込みと FLASH WRITE の間に遅延があるかないかです。

もしそれが原因なら eeprom の方も undef USE_INLINE_WRITE_PAGE 相当のコードにすることで動作するはずですが、そういう風には思えません。

とは言え、煮詰まったので、コードを修正してみることにします。




Posted by すz at 2010年07月28日 19:43
作ってみました。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04g4.c

USE_WRITE_PAGE_EEPROM と USE_INLINE_WRITE_PAGE_EEPROM を追加しました。

USE_WRITE_PAGE_EEPROM を undef すると、従来互換。
USE_INLINE_WRITE_PAGE_EEPROM を define すると 04g3 相当。undef のままなら FLASH と同じロジック。
Posted by すz at 2010年07月28日 20:38
すzさん、どうもありがとうござます。

ft245r-04g4.cの評価は明日、行います。
0xc0のようなコマンドは、AVRマイコンによって
異なることがあるので、avrdude.confに書かれ
ている値を適用するのがよいと思います。

また、書き込みエラーの件でFENG3さんから
コメントがあり、検討を行っています。

↑のURLもご覧ください。

Posted by senshu at 2010年07月29日 18:19
pagesize が 4 や 8 にもかかわらず writepage のコマンドがない AVR もあるということですね。
mega64 や mega128 が該当するので対応しておいたほうが良さそうですね。

あと mega644p はくせがありそうなので、mega328p とか新しめのもので 確認した後に 対応したほうが良さそうに思えます。

ついでに書きますが、USB の遅延はドライバでも行っていて プロパティに設定があります。5ms にすると eeprom の書き込みが (多少)高速化されると思います。API にもあったと思うので プログラムで対応したほうが良いかも知れません。

なお 私は明日以降しばらくアクセスできないと思います。あしからず。
Posted by すz at 2010年07月29日 22:49
すzさん、了解しました。

アドバイスをいただいた件を参考に、試行錯誤結果を私の
サイトに書いておきます。時間があればご覧ください。

現状でも素晴らしいのですが、更に完成度を高めたいと
思っています。
Posted by senshu at 2010年07月30日 00:55
LatencyTimerを2msecに設定したら、約1/8に時間が短縮
されました。この時間短縮の不具合をもたらす可能性を
検討する必要があり、今の所mISP中の数十秒間に限定し
てこの値に設定する(ISP完了時に元に戻す)ことにしま
した。

その結果、EEPROM 2kBの書込みが34秒→5秒まで、高速化
できました。Pageモードでの書込みは、どちらを指定して
も、正しく書き込めず、適用を保留しています。

Posted by senshu at 2010年07月30日 11:22
一連の改良により性能のバランスに優れた avrdudeになったと
思います。

ただし、何時の改定が原因になっているのかがはっきりしない
のですが、AT90S2313の操作でエラーになることが増えました。

プログラムモードに移行できるのですが、以下の部分で
signatureが正しく読めないというエラーになります。
if (saved_signature[0] == 0x1e) { // success
return 0;
}
AT90S8515ではこの問題はありません。通電後の一回目では
正常で、2回目以降でエラーになる場合がほとんどです。

積極的なサポートは予定していませんが、ちょっとだけ
残念な点です。

Posted by senshu at 2010年07月31日 07:28
FTDI社のドライバがインストールされていない場合でも、
それを必要としないライタでは使えるようにして欲しい、
との声に応え、loadlibraryを使って、動的にDLLをロード
する方式に切り替えました。

試用結果をみて、ソースを公開したいと思います。
Posted by senshu at 2010年08月11日 18:46
FTDI社のドライバとlibusb-win32の両方を
明示的にリンクするように変更しました。

この変更により、工場出荷直後のパソコンでも
最小限の利用が可能になります。

↓のURLにて、改造したソース(ft245r.c)を含むアー
カイブを公開していました。
Posted by senshu at 2010年08月16日 14:53
すzさん、こんばんは。

先日はアドバイスをありがとうございました。

FT232Rを使ったライタで、「avrdude.confに、rdyledとpgmledを
設定すると書き込みエラーが発生する(再現性あり)」、という
不具合を対処療法で解決しました。本来の動作ではありません。

時間が取れるときに、アドバイスをいただければ幸いです。


Posted by senshu at 2011年06月13日 21:12
バグの原因まで解析していただきありがとうございます。

ひとつは、変数の間違いで、もうひとつは、set_led() で、動作中に CBUS を操作することに起因する問題ですね。

FT_SetBitMode() で CBUS mode にしているので、元に戻さなくてはと考えて Synchronuse BitBang に再設定していますが、それではダメなのでしょうね。

もともとダメかもと書いたのは、mode の切り替えで意図しない動作になるのを危惧したように覚えています。

CBUS の FT_SetBitMode() は、実際は mode ではなくて 1 オペレーションで 設定して戻り値を得ています。ひょっとしたら再設定のほうが、不要なのかも ... と思っています。

ダメもとで 後ろの FT_SetBitMode() - set_reset() までを外したものを 一度試してみてもらえませんでしょうか?
Posted by すz at 2011年06月13日 23:18
おはようございます。

アドバイスの内容を試してみましたが、
該当部分をカットするとハングアップし
て、動作が完了しません。

また、YCIT版にて、別の不具合を確認しました。
この辺りは、ほとんど変更を行っていないので
serjtag-0.4にも共通だと思います。

詳細は、URL(↓)をご覧ください。
Posted by senshu at 2011年06月14日 09:49
テストありがとうございます。

DBUS(?) での Bitbang を使っているときは、CBUS は操作できないと考えたほうが無難ですね。

ただ、pgmled などは、DBUS への割り当ても可能で その場合は 想定した機能も使えます。

機能を削ってしまうのは面白くないので、Bitbang 中は、CBUS は操作しない。(ピカピカしない) という仕様で直したいと思います。
Posted by すz at 2011年06月14日 18:15
すzさん、了解です。

LEDの明滅ができると、動作している実感があり、
私も何とかしたいと思って取り組みました。

しかし、予想よりも内部のコードは複雑で、理解
には時間がかかりました。DBUS以外への割り付け
は私も考えていました。

実験には時間を捻り出して協力しますので、何なり
とお申し付けください。



Posted by senshu at 2011年06月14日 20:13
修正しました。説明が長くなるので、記事中に説明を追記しています。

さも動作するように書いていますが、動作未確認です。

rdyled = 2; # RTS

の設定がお勧めです。rdyled を CBUS に付けているのであれば

pgmled = 2; # RTS

この 2 つと 以前のバグのケースが直っているかのテストをお願いします。
Posted by すz at 2011年06月14日 23:49
すzさん、こんにちは。

作成していただいたソースで正常に機能することを
確認しました。CBUS, DBUS の両方に割り当てても
異常なく動作します。

なお、現在は FT_SetLatencyTimer関数で、動的に2msに
再設定していますが、これを行うと AT90Sシリーズの
IDがうまく読めない、という現象に悩まされています。

動的な変更を行わずに、Default値の16msなら正常に
機能しますが、書き込み(特にEEPROM)は遅くなります。

関係する場所に usleepを埋め込んでも上手くいきません。
仕方がないので、オプションでも追加しようかと考えて
います。

この件について、すzさんのご意見をお聞きしたいです。



Posted by senshu at 2011年06月15日 13:50
LEDの点滅に興味を持っていただいたラジオ少年さんの
協力を得て、点灯/消灯の確認を行いました。

その結果、-E Resetの値に関係なく、LEDを制御するように
変更しました。すzさんのご意見を伺いたいと思います。

詳しくは、↓のURLをご覧ください。
Posted by senshu at 2011年06月15日 18:39
複数回 avrdude を動かして、最後に -E reset で クローズ (ライタモード終了) というのが、私の意図するところで、-E reset なしだと rdyled が点灯しているのが、正しいと考えています。

点灯していれば、RESET のままで AVR のプログラムはスタートしていないし、シリアルの open もすべきではないです。

あと、pgmled の挙動がなにかおかしいのは、

690 ft245r_ddr |= ft245r_rdyled | ft245r_pgmled;
691

初期化で点灯させてしまっているせいですね。690 行目は削除してください。

2つ目の件: 私のコードは、FT_SetLatencyTimer() は、open/close の時しか call していませんが、同じでしょうか?
これでダメだとすると、いったいどうして良いのか ちょっと分からないです。

ところで、『バーが2/3位で消灯』というのは気持ち悪いですね。表示が遅いだけ?

ちょっと調べてみると ... report_progress() の使い方が間違っていました。原因はこれかも。
Posted by すz at 2011年06月15日 23:09
訂正: report_progress() の使い方は合っていました。

update_progress_no_tty()/update_progress_tty() で 表示するみたいですが、表示の遅延が結構あるのかも。
Posted by すz at 2011年06月15日 23:23
すzさん、お手数をおかけします。

アドバイスに従い、明日?、修正したものでテスト
してみます。

また報告します。

Posted by senshu at 2011年06月16日 00:23
すzさん、こんにちは。

LEDの制御について、重大な制約を確認しました。

AT90Sシリーズのように、ブロックR/Wをサポートしていない
マイコンでは、LED制御が機能しません。

FUSE操作でも、大半のLED制御が無効でした。その関係でLED
の点灯が遅れがあるように見えていました。

そこで、以下の関数をフックして、LED制御を追加してみました。
その結果、LEDは絶妙な明滅をしてくれるようになりました。

なお、ブロックR/W時にも同様に組み込みたかったのですが、
内部の理解ができておらず、組み込むと本来のR/Wに支障が
起きるという塩梅です。仕方なく、これは今のままとしました。

#if 0
pgm->read_byte = avr_read_byte_default;
pgm->write_byte = avr_write_byte_default;
#else // senshu
pgm->read_byte = ft245r_read_byte;
pgm->write_byte = ft245r_write_byte;
#endif

この経過は↓のURLをご覧ください。
Posted by senshu at 2011年06月16日 12:11
なかなか、思うようなものになりませんね。

いっそのこと、次のようにしましょうか?

pgmled : アクセスランプ : アクセスしているとき 点滅
rdyled : ライタモード・インジケータ + アクセスランプ
  ( CBUS を指定した場合 はライタモード・インジケータのみ )

で、LED の点灯 : L
LED の消灯 : Hi-Z もしくは H
と定義すると、(DBUS については)自由に 点灯 / 消灯をさせることができます。

pgmled は、ft245_cmd 実行中点灯、read/write は 基本点灯 最後に 消灯。
( read/write は、内部で ft245r_cmd を使用すると 点灯→消灯が入ります。)
( rdyled(DBUS) は逆論理 )

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l2.c

一応作ってみました。
Posted by すz at 2011年06月16日 23:50
すzさん、こんばんは。

ft245r-04l2.cを拝見しました。このコードは私には書けません。

この方法を使えば、block read/write中にLEDを点滅できそうで、参考
にさせていただきます。何度見ても、このコードは読み切れません。

なお、旧AVRは、paged関係のコードは利用されないので現在のコード
でもPGMLEDの制御は無効だと思います。

Posted by senshu at 2011年06月17日 00:24
paged_xx 以外の 操作は、ft245r_cmd を必ず使うので大丈夫です。

ただ、作っただけなので バグがあるかも知れません。
Posted by すz at 2011年06月17日 00:43
すzさん、こんばんは。

今日はLED制御ではなく、AVRマイコンの認識度の向上と、
処理速度の向上に取り組みました。

確認したことを書きます。

1. Latency timeは 16ms未満では、認識が不安定
→ Latency timeを18ms(+2msはマージン)に設定し、
  認識が成功した場合に 1msに変更する。
これで処理速度が格段に向上する

2. ただし、書込みエラーが起きやすくなる
→ Flash_write時の待ち時間を追加

という経過です。理解していない部分も多いのですが、
この変更で安定で高速な動作が可能になりました。

↓のURLに経過を書いています。
Posted by senshu at 2011年06月17日 19:38
avrdude-serjtag-04m を置きました。
ft245r-04l2.cからの変更は、buufer のサイズ見直しのみ。バグったらまったく動かないはずなので、まぁ大丈夫だろうと判断しています。

Latency timer 周りは保留です。Mac や Linux でも動かないといけないので、影響が見えない修正は躊躇われます。(ちなみに dll 動的 Link をいれなかったのも 同じような理由です。)

ところで今回の修正ですが、ちょっと説明しておきます。

FT245 に対しての オペレーションは 4 つだけです。この 4ヶ所で ft245r_send するデータの 先頭と最後に led 操作を挿入しています。

ただ、そうするためには、現在の bit の状態を覚えておかないといけないので、ft245r_data という変数を 復活させました。

また、1 バイト余計に入っているので ft245r_recv したデータから取り出すところで、位置をずらしています。
Posted by すz at 2011年06月17日 23:46
すzさん、avrdude-serjtag04mの作成、お疲れ様でした。

serjtag-04l2との違いも確認しました。

私の行った修正は、実験から得られた結果を元に勘と経験
で修正した箇所もありますが、AT90Sの利用者には大いに
メリットがあります。

今後は、serjtag04mとYCIT版と比較を行ってみます。
Posted by senshu at 2011年06月18日 00:54
すzさん、おはようございます。

serjtag-04mを使った方から、エラーの報告がありました。
serjtag-04gではエラーは起きず、LED制御以外は正常に
利用できていたことから、オペミスは考えにくいです。

↓のURLに詳細な報告があります。

アドバイスをいただければ、幸いです。
Posted by senshu at 2011年06月18日 10:07
URL を入力失敗しました。

正しくは、こちらです。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude17#o2dcc16f

Posted by senshu at 2011年06月18日 10:09
serjtag-04l2 をテストした頂いたのかと勘違いしていました。

serjtag-04l2/04m は、動作に影響する変更が入っているので、変更をミスしたら、全く動かない可能性が大きいです。コードを見直します。

Latency timer についてですが、やはり これの設定によって、動作したりしなかったりするのは、まずいです。『もともとのコードに Delay を入れるべきところがある』 か 『もともとのコードの Delay のやりかたが悪い』と考えるべきです。

問題が AT90S だけだとすると、最初の signature を 取るところのシーケンスに Delay が足りないはず。

で、完了待ちのusleep 関数の追加の件ですが、AT90S 以外で起きるのでしょうか?

ひょっとしたら、usleep() の動作が期待どおりでない可能性も含めて検討しないといけないかも知れません。これもコードを見直してみます。
Posted by すz at 2011年06月18日 13:12
すzさん、こんにちは。

>Latency timer についてですが、やはり これの設定によって、動作
>したりしなかったりするのは、まずいです。『もともとのコードに
>Delay を入れるべきところがある』 か 『もともとのコードの Delay
>のやりかたが悪い』と考えるべきです。

私もそう考えています。そこで、FT232Rを操作する関数の付近にusleep
関数を挿入しましたが、数時間の試行錯誤でも改善できませんでした。

そこで、報告の手法を採用しました。usleep関数では、正確な時間を
確保できないかもしれません。

>問題が AT90S だけだとすると、最初の signature を 取るところの
>シーケンスに Delay が足りないはず。

AT90Sで顕著に現れます。ATmegaシリーズでは、まだこのエラーは経験が
ありません。

>で、完了待ちの usleep 関数の追加の件ですが、AT90S 以外で起き
>るのでしょうか?

はい、Latency timerを1msに設定した時には、頻度は異なりますが
全てのAVRマイコンで確認しました。

>ひょっとしたら、usleep() の動作が期待どおりでない可能性も含め
>て検討しないといけないかも知れません。これもコードを見直して
>みます。

私も usleep関数の動作は疑っています。+1000などの値を追加したのは
それを考慮した暫定措置です。

よろしくお願いいたします。
Posted by senshu at 2011年06月18日 13:48
以前、usleep関数の精度を評価したことがあります。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude17#i6bf6f7e

参考まで。

Posted by senshu at 2011年06月18日 14:15
usleep ですが、avrdude では QueryPerformanceCounter() を使って自分で再定義しています。

Linux などでは、OS で標準で提供されたものを使います。指定した以上 待つことになっているはずですが、カーネルのバージョンや設定によって、10ms (かそれ以上) が待つ単位になる場合があります。

2 回 call すると 値が 0 でも 20ms 以上待つ場合があるわけです。

一方 QueryPerformanceCounter() は、正確ですが注意点が多数あるようです。

http://msdn.microsoft.com/ja-jp/library/bb173458%28v=vs.85%29.aspx

SetThreadAffinityMask で 1 つの CPU でしか動かさないように 設定しろ という注意書きがあり、avrdude では、それを守っていないようです。守らないと何がおきるかというと、たぶん 数 ms のぶれが出ることになるんじゃないかと思います。

出来たら ft245r の中だけで解決したいし、Linux や Mac と共通のコードにしたいので とても悩ましい問題です。

案としては、『追加の delay は、ピンの状態を変更しない データ列を追加する 』という手があります。

ただ、この対応と LED の対応を同時にやると バグの修正が大変になります。LED の対応が終わってからの着手にしようと思います。



Posted by すz at 2011年06月18日 15:05
すzさん、了解しました。

1ミリ秒の精度を要求する処理は、PC以外に受け持たせる
べきと考えますが、FT232Rライタではそうもいきません。

私も複数のOSで動作するコードを書いた時にいつも類似の
ことに悩まされています。私の公開しているソフトでは、
単一のCPUで動作させるフラグをセットして公開している
ものもあります。

その意味では、Latency Timerを遅くしてタイミングを取る
方法はOSの依存性もなく、悪くない方法だと思っています。

まずは、LED関連の実現するのが先決ですね。
Posted by senshu at 2011年06月18日 15:20
709 ft245r_ddr |= ft245r_rdyled | ft245r_pgmled;
710 ft245r_data |= ft245r_rdyled | ft245r_pgmled;
711 ft245r_sck = 0; (これ)
712 if (((verbose>=1) || FT245R_DEBUG) &&

変なのが紛れ込んでいましたよ。これが原因ではないかな。

あと udealy の件ですが、やはり avrdude のバグだと思うのでパッチを作りました。

パッチは 04m の avrdude-5.10-ppiwin.patch です。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l4.c

ft245r.c の変更ですが、ちょっといくつか変更しました。ほとんど影響ないと思いますが、ダメなら、ft245r-04l3.c に戻って LED修正のバグを取ることにします。

修正内容ですが、ひとつは、FT2232H/FT232H とかで 最大 bitrate を引き上げる変更。

もうひとつは、signature を読むところで、Latency タイマが関係しそうなところに udelay を入れる変更。-- 最初から 1ms にして 動かすことを想定しています。

あと、専用の delay 関数。ft245r_delay を作りました。これは未使用です。Windows の usleep は直したので不要なはずですが、消さずに置いておきます。
Posted by すz at 2011年06月18日 22:23
すzさん、改定をありがとうございます。

改定されたserjtag-04m.zipに関する報告です。

AT90S2313とATmega644で書き込みができ、
LEDの点灯に関する意見交換も行っています。

詳しくは以下のURLをご覧ください。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude17#tf6d317d

Posted by senshu at 2011年06月19日 11:51
動いたようで、安心しました。

さて、LED の操作ですが、read 中は ずっと READ しているので、点滅にはなりません。

BLOCK 分 READ/WRITE したら トグル する という仕様なら、対応可能だと思います。

問題は、cmd での LED 操作。周期が早すぎて微妙な明るさでしか判断できないようです。これの対応は難しいです。本末転倒になりかねません。

あと ft245r_delay を使えば、dealy 中の led 操作が可能ですね。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l5.c
http://nmj.sumomo.ne.jp/suz-avr/serjtag/avrdude-serjtag-04n.zip

これらの修正をしたものを置きました。

#define USE_INLINE_WRITE_PAGE
#define USE_LOCAL_DELAY

としています。USE_LOCAL_DELAY を undef すると usleep を使うようになります。

USE_INLINE_WRITE_PAGE は、paged_write で ft245r_delay を使うために入れましたが、しばらく使っていないので、ダメかも。

そもそも、ft245r_delay は動かないかも知れないので、04n は、ダメもとで試していただきたいです。




Posted by すz at 2011年06月19日 16:01
私の環境(MinGW)では、./configureでac_cfg.hを生成しています。

その中には
#define HAVE_USLEEP 1
が定義されています。

つまり、usleep関数はライブラリの内部で処理されているのです。
自前で書いても、適用されない場合があるという報告でした。



Posted by senshu at 2011年06月19日 20:00
MinGWが提供する usleep関数を評価し、あまりの結果に絶句しました。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude17#ce2a202a

#define HAVE_USLEEP 1

今後は↑の定義は無効にして、実行ファイルを作ることにします。いくつかの不安定動作は、これが関係していたかもしれません。

気づくのが遅すぎました。


Posted by senshu at 2011年06月19日 21:01
すzさん、こんにちは。

0.4mで行われた修正を、YCIT版にも適用しました。

ただし、以下の定義を行うと、書込みエラーになります。
(チップの認識はできます)

#define USE_INLINE_WRITE_PAGE
#define USE_LOCAL_DELAY

また、利用者から、0.4mは AT90S2313に連続して書込みを
行うと2回目でエラーになる、との報告がありました。

これは、私のところで起きていた不具合と同じものです。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude18#r858761e

現時点では、0.4n 版の適用は中断しています。

また、ft245r_paged_write_eeprom関数には存在する
usleepによる時間待ちが ft245r_paged_write_flash関数
に無いのは、やはりおかしいと思います。

usleep関数がないと、Latency Timer 1msで動作させると、
必ずエラー(誤書込み)になります。

以上、報告まで。
Posted by senshu at 2011年06月20日 11:04
すzさん、こんばんは。

serjtag-04n.zipの件です。

公開していただいたアーカイブのavrdude.exeを
試しましたが、FUSE操作、書き込み共にエラーが
発生します。

私だけではなく、他の方も同じ内容でした。現在のとこ
ろ、以下の定義は不具合を生じるようです。

#define USE_INLINE_WRITE_PAGE
#define USE_LOCAL_DELAY

http://blog.goo.ne.jp/flute9332/e/be33d50d2db5b24141f98449fdcf18cd
Posted by senshu at 2011年06月20日 23:52
すzさん、こんばんは。

serjtag-04mに付属する usbasp用のパッチを適用しましたが、
以前は使えていた USBaspでエラーが起きる、という報告が
ありました。

patchを適用しなければ、正常に使えます。

何か注意点はあるのでしょうか。

【参考URL】
http://www-ice.yamagata-cit.ac.jp/ken/senshu/sitedev/index.php?AVR%2Favrdude19#ye969d34

Posted by senshu at 2011年06月21日 21:14
何度もすみません。

URLを貼り損ねました。正しくは、以下のURLです。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude19#ye969d34

Posted by senshu at 2011年06月21日 21:59
まずは、usleep の件について。

私の環境(avrdude-5.10)だと、HAVE_USLEEP は存在しないようです。新しい版で入ったのでしょうね。

ちなみに usleep() 自体は、MinGW は提供していません。MicroSoft が提供しているライブラリを使っているはず。

精度ですが、システムが 10ms 刻みで動いていて 引数の値以上の待ちを保証するなら、1ms を指定しても 待ちの期待値は 15ms 前後になります。

コードを作る立場だと、このような精度しかない OS も多数あるので、そういうものだと想定する必要があります。

> また、ft245r_paged_write_eeprom関数には存在する
> usleepによる時間待ちが ft245r_paged_write_flash関数
に無いのは、やはりおかしいと思います。

ft245r_paged_write_eeprom は いまのコードではありません。また、avr_write_page() の中で usleep() しているので、ft245r_paged_write_flash() で usleep() すべきではありません。

さて、0.4n の件。

// #define USE_INLINE_WRITE_PAGE
// #define USE_LOCAL_DELAY

だと 0.4m に read 時の LED 操作が加わった程度の変更になります。当面はこれで使ってください。

チップの認識は出来ているなら、ft242r_delay 自体は動いているようです。ですが、実際に遅延する時間が 正しいかどうかが問題なのだと思います。QueryPerformanceCounter() を使って検証する必要があるかも知れません。

あと USBasp の件。USBasp 互換になるよう 配慮したつもりですが、実際動かないとなると問題ですね。

改造内容は、私が作った mega32u2/32u4 でのライタ/Bootloader 向けなので、オリジナルの USBasp を使っている人には、まったくメリットがありません。当面 04g のものを使ってください。
Posted by すz at 2011年06月22日 07:57
2回目がエラーになる件ですが、最初に 再 RESET せずに、signature が 読めるかどうか試して見るのが良いと思っています。

RESET から抜けてしまうと、書き込んだ FUSE が有効になってしまいますが、RESET から抜けないと 書き込む前の FUSE が有効なのです。

外部クロックに設定した後の ベリファイや、間違えたときの再設定が可能になるのは、大きなメリットです。

ちょっとこのやりかたを考えてみました。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l5.c
http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l6.c

の diff で見てください。

あと レイテンシタイマの件。AT90S2313 の性能は 重要ではないと思っています。AT90S2313に頻繁に書き換える人がいったいどれだけいるのでしょう? 0 かも知れません。

mega644P などで eeprom の書き込みが遅い というのなら分かります。でも、eeprom を書き換える人は少数派だと思います。serjtag-03 では動かないのにまったく問題になっていません。

レイテンシタイマは、OS のドライバが関係するので、あまり短くするのは、どうかと思っています。2ms は Mac でも動く実績ができたので、良いですが、1ms はトラブルが多いようで 不安を感じます。

YCIT版で 1ms にするのは 構いません。その設定で十分テストされるはずですから。ですが、私のコードは 2ms のままにしたいと思っています。
Posted by すz at 2011年06月22日 17:30
ft245r_delay にバグがありました。バグの修正と共に bitrate の変更をやめることにしました。

修正版は 04l7
http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l6.c
http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l7.c
diff で見てください。

delay 4ms = 5.236 ms
delay 9ms = 10.714 ms
delay 20ms = 32.126 ms
delay 200ms = 196.625 ms
delay 400ms = 398.153 ms
delay 600ms = 580.844 ms

これを 別件で使っている FT2232H で試して見ました。
長い時間を指定すると、短めの 時間で 終わってしまいます。問題はありますが、とりあえずは使えそうになりました。

あと、QueryPerformanceCounter にも問題があることが判りました。
Note PC などで Power Saving Mode にして クロックを落としても、Freq の値は 規定の値なので、avrdude の usleep の実装だと sleep 時間が長くなります。
逆に Super Performance Mode などで オーバークロックにすると sleep 時間が短くなります。
Posted by すz at 2011年06月23日 06:35
すzさん、おはようございます。

このたびは多数の修正をしていただき、大変お世話になりました。

本日の修正分は対応ができておりませんが、-iオプションでLatency
Timerを指定可能にし、省略時解釈は2msにしました。

pgm->ispdelay で指定値が得られるので、open時に設定値を評価
し、適正なら再設定し、完了時に初期値に戻します。これにより、
従来版との違いは最小限になると思います。けしてAT90Sに拘って
いるわけではなく、いくらかでも快適に使いたい、との思いで取り
組んでいます。

以下に経過を書いています。 diecimila以外のLED設定が上手く
いかないという報告があるのですが、そうした動作にするの
は却って難しく、不思議に思っています。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude19#cdd90771
Posted by senshu at 2011年06月23日 09:35
ft245r-04l7.cを組み込んで、動作テストを行いました。

AT90S2313で起きていた、2回目以降の認識エラーが
なくなり、快適です。またRD/WR時のLED点滅も秀逸です。
単なる点灯に比べ、遥かに視覚効果があります。

すzさんの報告をお聞きし、usleepの不具合を解決す
るためにも、YCIT版にも組み込みたいと思います。

どうもありがとうございました。


Posted by senshu at 2011年06月23日 10:41
訂正します。

ft245r-04l7.c を適用した avrdude.exeでAT90S2313で
テストを繰り返していたら、

ft245r: bitclk 460800 -> ft baud 230400
avrdude-m.exe: ft245r_program_enable: failed
avrdude-m.exe: initialization failed, rc=-1

のエラーが起きる場合がありました。このエラーが
起きた後、 -E resetを追加するとエラーは回避でき
るのも以前と同様です。
Posted by senshu at 2011年06月23日 10:46
-iオプションでLatencyTimerを指定可能にするのは良いアイディアだと思います。不具合があれば、16ms で動くかどうか 依頼することも出来ますし、1ms と 2ms の安定性の 比較がしやすくなります。

2回目以降の認識エラーについてですが、RESET せずに 使えるようにするのはメリットがあるので、できるだけ 再 RESET せずに 認識させたいですね。いまは 5 回のリトライで諦めますが、もし 10回,15回ぐらいで ほとんど認識するのであれば、リトライ回数を増やすことで対処した方が良いと思います。

あと、よく見たら ft245r_drain がまずいです。RESET を解除してしまっています。FT_Purge を使うよう書き換えることにしました。

http://nmj.sumomo.ne.jp/suz-avr/serjtag/ft245r-04l8.c

その他 typo も含めて、修正したものを 置いておきます。
Posted by すz at 2011年06月23日 22:29
すzさん、いつも大変お世話になっております。

ft245r_drain関数は私もFT_Purge を利用して、独自に変更して
いました。

その理由は、書込み終了後にターゲットが実行を開始し、USART
から大量のデータが送りこまれると不具合が起きていました。

Mega88PのFuseを、Lo:0x62 Hi:0xDF Ex:01 設定し、読み書きを
行う場合、-B 38400以下に設定しないと、書き込みエラーに
なります。ただし、読み出しなら -B 230400でOKです。

すzさんの公開している実行ファイルでも同様でした。

これは、どうすれば改善できるでしょうか。

参考URL

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude20#qb5b8c3b
Posted by senshu at 2011年06月24日 14:29
変更したところが、怪しい... となれば、2 回目の認識のために RESET しない所。あと drain のやり方。のどちらかという気がしますが...

ゆっくり進む場合があるのが腑に落ちないですね。これは delay の方法か 実際に設定する baudrate かどちらかの問題に思えます。

まずは、USE_LOCAL_DELAY を undef して問題を切り分けた方が良さそうに思えます。
Posted by すz at 2011年06月24日 18:19
すzさん、アドバイスをありがとうございます。

私が報告した件は、serjtag-04e や -04m に含まれる
avrdude.exeでも発生します。

最近の変更で生じたものではないと考えます。

使えないわけではないのですが、-B 9600を指定して
利用すると、AVRマイコン用のライタとしては、やや
遅い印象があります。

なんとか、もう少し高めのクロックで利用したいと
思い、質問しました。




Posted by senshu at 2011年06月24日 19:28
2回目でエラーになる件は、何とか解決しました。

後は、低速クロックでの計算値とズレが生じる
件を修正できればと思っています。

これは、私にとっては一年前から気になっていた
懸案事項です。


Posted by senshu at 2011年06月24日 19:35
WRITE でエラーになる件は、2回目でエラーになる件と同じではないですか? READ ができて WRITE が出来ないなら delay が足りない ぐらいしか理由がないです。

あと、低速クロックでの計算値とズレが生じるというのは、何を差していますか?

低速ではありませんが、ft245r_delay で
delay 600ms = 580.844 ms
と微妙に短くなるのが私は気になっています。

普通は長くなるものですが、短いということは、bitclock が 想定より短いことを示しています。ただ微妙に短いだけなのが変です。
Posted by すz at 2011年06月24日 23:03
すzさん、こんばんは。

上手く説明できないので、すzさんの説明を引用します。

ビットレートについてから引用します。
> ATmega168P を 試してみた。
>
> 新品の状態では、内蔵 8MHz 1/8 分周 = 1MHz 。最近の
> AVR は 1MHz が多いので 標準的な 周波数。
>
> この場合、デフォルトの 230400 (Hz) では動作しなかっ
> た。115200 もダメ。動作する最高の ビットレート は、
> 76800 だった。

私も同様の件を確認しました。ただし、読み出しは76800で
OKでも、書き込みでは さらに低い38400以下でないとエラー
になります。

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

これも確認しました。

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

書込みでは、-B 76800でもエラーになり、さらにビット
レートを落とす必要があります。これは、以前の経過を
考えると、どこかでdelayが不足していると考えました。
Posted by senshu at 2011年06月25日 00:23
計算が合わない、という件は、とあるサイトの情報で
解決できそうです。実測してみるのが重要と感じました。

以下をご覧ください。

http://202.35.250.1/ken/senshu/sitedev/index.php?AVR%2Favrdude21#n342275b
Posted by senshu at 2011年06月25日 01:15
そのデータを見ても納得いかないのです。baudrate x 16 それが正しいとすると、bitclock から計算される 性能の 1/4 の性能しか出ないことになる。bitclock をいくら落としてもほぼ 1/4 です。

baudrate x 16/3 ならまだ理解できるのです。baudrate x 16 のクロックで動いていて 両脇に RD# , WR# が入るとすれば、 x 16/3 になる。baudrate x 4 ぐらいの平均性能しか出ないのは、いろんなオーバヘッドのためということであれば。

例の最小パルスは、RD# or WR# だったというオチではないでしょうか? ON/OFF が 1:2 になっています。BitBang で生成するパルスなら 1:1 にするはずなのです。
Posted by すz at 2011年06月25日 06:14
delay についてですが、bitclock と delay 時間は無関係です。38400 なら OK で 76800 ならダメというのは、なにか変です。

また、Write での エラーは普通起こりません。Verify で値が違うのならわかりますが、そうなったという記述がないので判断できていません。
Posted by すz at 2011年06月25日 07:01
すzさん、おはようございます。

貴重なコメントをありがとうございました。
たしかにbaudrate x 16 は誤認があるようです。

ターゲットのAVRマイコンの動作クロックとの対応表を
書いてみました。これがあれば、適切な値を指定できます。

安全のために常に低めの値を指定することもできますが、
私は適切な値を指定して、快適に使いたいと思います。
Posted by senshu at 2011年06月25日 07:18
ひとつだけ。
平均ビットレートは、250k あたりで で頭打ちになるはずです。BitBang では、1 bit を作るのに、8bit を 2 回 書き、同じだけ読み込みます。250k でも x32 になるので 8MBps の帯域が必要です。実際にはこんなに出なかったと思います。

帯域的な意味で、標準は -B 115200 で少しでも 速い方がよいとしても -B 230400 にしておくのを推奨しておきます。
Posted by すz at 2011年06月25日 09:54
>帯域的な意味で、標準は -B 115200 で少しでも 速い方がよい
>としても -B 230400 にしておくのを推奨しておきます。

了解しました。

現在のft245r.cでは、-B 指定を大きくしても、430800以上の値
にはならないようにコーディングされている理由が理解できました。

-Bオプション指定(目安)を以下のように提示したいと思います。
いかがでしょうか。

Bオプション マイコンのクロック 
9600 250kHz以上
19200 500kHz以上
38400 1MHz以上
76800 2MHz以上
115200 3MHz以上
230400 6MHz以上

Posted by senshu at 2011年06月26日 13:59
senshu版 RC2 でなにかバグを入れていませんか?

-B 1000000 での挙動はあきらかにおかしいし、
AVR が、1MHz のとき -B 76800 で動かないのも、変だと思えます。(本文の訂正を参照)
Posted by すz at 2011年06月27日 11:02
すzさん、こんばんは。

1MHzでは -B 76800で動作するはず、とのアドバイス
をありがとうございます。

このアドバイスを聞いて、安心しました。

RC2では小細工せずに、すzさんのコードをできるだけ
そのまま利用しているのですが、再度、確認してみます。
Posted by senshu at 2011年06月27日 22:31
RC2, RC3に同梱した avrdude.exe の挙動がおかしい
件は原因がわかりました。

最近の変更で、ft245r_restore_bitclock関数の呼び出し
箇が変更されているのですが、その適用が漏れていました。

すzさんの版と同じ場所に修正したところ、1MHz動作の
マイコンに -B 1000000 を指定すると、確実にエラーを
検出します。

アドバイスに感謝いたします。
Posted by senshu at 2011年06月28日 16:44
別件ですが、CBUS3は、LED制御に利用できない、
という報告があります。

BitBang用のIOに設定できないためです。
これが正しければ、説明を変更する必要が
あると思いますが、いかがでしょうか。

また、すzさんの説明で rdyledがldyledに
なっているものがあります。

可能なら訂正をお願いいたします。
Posted by senshu at 2011年06月28日 16:46
> 最近の変更で、ft245r_restore_bitclock関数の呼び出し
箇が変更されているのですが、その適用が漏れていました。

なにはともあれ、原因が見つかって安心しました。

> 別件ですが、CBUS3は、LED制御に利用できない、
という報告があります。
CBUS4 のことではないかと思います。そして、CBUS4 が使えるとはどこにも書いていません。

FT232R について詳しくない人が間違えやすい内容ではあると思いますが、そもそも私の記事を読んで間違えたとは思えません。できましたら、senshu さんのところで解説して頂けたらと思います。
Posted by すz at 2011年06月28日 23:28
CBUS0〜CBUS3までが利用可能の件、了解です。

相談を受けた時、CBUS3が特殊なのかと思い込み、
先の書き込みをしてしまいました。

私もまったく同じ回答をしていたことを思い出しました。

質問者には「DBUS 0〜7とCBUS0〜CBUS3の計12本」が
制御可能(CBUS4は制御対象外)と伝えました。

どうも手数をおかけしました。
Posted by senshu at 2011年06月29日 00:07
avrdude 側の仕様の関係で、DBUS 0も利用できません。間違えないようお願いいたします。
Posted by すz at 2011年06月29日 00:47
貴重な情報ありがとうございます。確かに出力の抵抗付加は安全かもしれませんね。

avrdudeのアップストリームにマージされftdi_syncbbをv6からサポートしだしていますね。

どうもthread library関係を新しくするとsertagで聞くのと同じ問題があったようです。これにタイミング関係のパッチを適用して解決しています。
https://savannah.nongnu.org/bugs/?40086

GNU/Linux (Debian/Ubuntu系) だと6.1-2以降で解決しています。

参考まで。
Posted by 青木 修 at 2014年09月14日 15:03
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/33907127
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック