FT232HのACBUS8、ACBUS9の使い方
FTDI社のUSBインタフェースICにはMPSSEといってUSB-JTAGやUSB-SPIなどを容易に作るための機能があります。FT232HはUSB2.0 HighSppedモードに対応しておりFT2232Dなどより高速で、秋月電子で630円くらい入手できます。もちろんワンボード化されたモジュールもあります。
FT232Hはこのような小型のパッケージで高速で非常に使い勝手がよいデバイスです。(写真はAdafluit社のもの)
さて、FT232Hの出力バスはADBUS[7:0]とACBUS[9:0]というのがあります。
ADBUSの下位4bitはJTAGの信号として、ADBUSの上位4bitははGPIOL、ACBUSの下位8bitはGPIOHとしてMPSSEの中から操作することができます。
MPSSEモードでADBUSやACBUSを個別に動かすには0x80もしくは0x82のコマンドを使います。アプリケーションノートAN108によればLowByteがADBUS[7:0]に対応していて、HighByteというのがACBUS[7:0]に対応しているそうです。
さて、これでACBUSを動かそうとしたのですが、この0x82のコマンドには引数が1バイトしかないのです。
ACBUS[9:8]を動かしたい場合はどうしたらよいのでしょうか??
・・
苦労しましたが、やり方を発見しました。
まず、FT_Progで書き込むときにC8とC9をI/O Modeにします。したがってEEPROMは必須です。
そして、SetBitModeを呼び出すときの第二引数にFT_BIT_MODE_CBUS_BITBANGを指定します。
FTDI ft = new FTDI();
ft.OpenByIndex(0);
ft.ResetDevice();
ft.SetBitMode(0x00, FTDI.FT_BIT_MODES.FT_BIT_MODE_RESET);
// CBUS_BITBANGでACBUS9,8,6,5を操作できる。
ft.SetBitMode(mask, FTDI.FT_BIT_MODES.FT_BIT_MODE_CBUS_BITBANG);
// 普通にMPSSEの初期化を行う
ft.SetBitMode(0x00, FTDI.FT_BIT_MODES.FT_BIT_MODE_MPSSE);
ft.SetLatency(16);
ft.SetTimeouts(1000, 1000); // 1秒、1秒
ft.SetCharacters(0, false, 0, false);
ft.Purge(FTDI.FT_PURGE.FT_PURGE_RX | FTDI.FT_PURGE.FT_PURGE_TX);
・・・
普通のBitBangモードだと、SetBitModeの第二引数をFT_BIT_MODE_SYNC_BITBANGやFT_BIT_MODE_ASYNC_BITBANGにして、ft.Writeでデータを垂れ流しにすると思います。
しかし、SYNC_BITBANGというフラグ(0x20)を指定すると、SetBitModeの時のMaskがそのまま出力ポートのDirとValueとなります。Writeは不要です。
そのビット割り当ては
- bit7・・・ACBUS9のDIR (1:出力 0:入力)
- bit6・・・ACBUS8のDIR (1:出力 0:入力)
- bit5・・・ACBUS6のDIR (1:出力 0:入力)
- bit4・・・ACBUS5のDIR (1:出力 0:入力)
- bit3・・・ACBUS9のVALUE (1:H 0:L)
- bit2・・・ACBUS8のVALUE (1:H 0:L)
- bit1・・・ACBUS6のVALUE (1:H 0:L)
- bit0・・・ACBUS5のVALUE (1:H 0:L)
であると思われます。
「思われます」というのはドキュメントがどこにもないので実験してみた結果からそのように推測したためです。この機能を有効にするにはFT_ProgでC9,C8,C6,C5をI/O Modeにプログラムする必要があるので注意してください。FT232HでCBUS_BITBANGが使えるのはおそらくACBUS9,8,6,5のみだと思います。それ以外のACBUS0やACBUS1や2はそもそもGPIOHなので、0x82コマンドで操作できるはずです。
次の図に、ループ中でSetBitModeを繰り返し読んでポートをパタパタさせた波形を示します。
ちゃんと動いていますね。
素晴らしいことに、このSetBitModeでFT_BIT_MODE_SYNC_BITBANGを付けて出力した値は、FT_BIT_MODE_RESETやFT_BIT_MODE_CBUS_BITBANG、さらにはft.ResetDevice();を呼び出しても解除されません。再びFT_BIT_MODE_SYNC_BITBANGをするまではその値を保持してくれるようです。
つまり、MPSSEとCBUS_BITBANGは独立して使えるようです。
そもそも何でACBUS8を動かしたかったかというと、最近実験用に作っているMPSSEのJTAGケーブルがありまして、FT232Hの後ろのLatticeのCPLDを乗せているのです。
実は、FT232Hは電源投入時に変な波形が出るので、その波形をブロックしたりするためにCPLDを使おうとしています。
この波形はまだおとなしいほうで、FT2232Dのときにはカウンタが動くような波形が出ていました。
さて、このCPLDを書き込むためにJTAGケーブルを挿すのは不格好なので、FT232HからCPLDにも書き込みができて、CPLDの先のJTAGターゲットにも書き込みができるようにと思い、CPLDのJTAGピンを一般ピンとして使えるようJTAGENで切り替えようとしました。
JTAGENBをHにするとTCK/TDI/TMS/TDOはCPLDのJTAGとなり、JTAGENBをLにするとこれらの端子はI/OポートになってターゲットのJTAGにつながるというしくみです。
このJTAGENBの切り替えをACBUS8でやろうとして、あれどうやって動かすんだろう・・と、大ハマりしたというわけです。
最近のコメント