インターフェイスチップは、I2Cインターフェイス(I2Sと混同しないでください!)での操作をサポートします。MPSSE(マルチプロトコル同期シリアルエンジン)モードで。 I2Cに加えて、このモードはSPI、JTAGなどの標準シリアルインターフェイスの全リストをサポートします。必要に応じて独自のインターフェイスを実装することができます。 この説明では、I2Cインターフェースをサポートすることのいくつかのニュアンスについて説明し、関連するトピックについてチャットする機会も提供します。
免責事項:この記事は作業資料について書かれており、主に元の文書を紛失した場合の記事の著者を対象としています。 同時に、以下の情報は専門家の狭い輪にとって興味深いかもしれません。 読者がソフトウェアとハードウェアのデバッグの世界に簡単に飛び込むことを望まない限り、読者の幅広いサークルに読むことは推奨されません。 研究は1年以上前に実施されましたが、製造元のウェブサイトのライブラリが更新されていないため、現時点ではこの情報は引き続き重要です。 検出された問題に関する情報はメーカーに送信されましたが、フィードバックは受信されませんでした。 投稿はこれに基づいて書かれ、著者は特別な感謝を表明します2つのI2Cチャネルの独立した動作がサポートされています(FT232Hの1つのチャネル)。 スイッチング回路の例はAN113に記載されています-例として、FT2232Hと不揮発性メモリチップ24LC256間の通信が使用されます。
I2Cインターフェースに直接関連する信号は、SCL(図ではSCCと呼ばれるクロック信号)とSDA(送信データ)の2つだけです。 仕様によると、これらの信号はそれぞれ双方向である場合がありますが、多くの場合、バス上にはマスターデバイス(マスター)が1つしかなく、これがクロック信号を設定します。 いずれの場合でも、データは双方向です-送信データの8ビットごとに、1つの確認ビットが続きます。
ソフトウェアレベルでは、2つの方法でI2Cバスを操作できます。
- D2XXドライバーから直接。 この場合、AN108で説明されている一連のコマンドに従って、MPSSEモードの手動プログラミングを実行する必要があります。 すべての作業は、FT_Read()およびFT_Write()関数、およびデバイスを開く/閉じるなどの関連関数を経由します。
- LibMPSSE-I2Cライブラリを使用します。 このライブラリは、MPSSEモードのプログラミングの問題をすべて解決し、I2C_DeviceWrite()およびI2C_DeviceRead()呼び出しを使用して、I2Cバスで指定されたバイト数の読み取りと書き込みを行うことができます。 ライブラリの説明はAN177に記載されています。
利用可能なボードの1つを使用して研究が行われました。 INA219電力計は、I2Cバスのスレーブデバイスとして使用されました。 ボードは手元にあったので、FT2232HとINA219チップの間にFPGAがありました(
幸運だったので、少し後で実現しました )。 最初は、3線FT2232Hインターフェイスを2線I2Cバスインターフェイスに変換するためにのみ使用する予定でした。通常のデバイスでは、このような変換は回路によって発生します。上の図を参照してください。
すでに述べたように、8ビットの送信情報ごとにデータを送信する場合、確認(ACK)が続きます。信号は受信デバイスから状態0に転送されます。 送信側のデバイスがこの確認を見ると、それを聞いて続行できることを意味します。 確認がない場合、続行を続けることは役に立たず、交換を停止できます。研究の過程で、LibMPSSE-I2Cライブラリにエラーがあり、ほとんどの場合、バス上の複数バイトを読み取る機能をブロックしていることがわかりました。 このエラーは、FT2232H側からバスへの最初の読み取りバイトのACK確認を発行する前に、クロック信号にグリッチが現れることで明らかになります。 グリッチの長さは、12 MHz(約8 ns)の周波数の1周期です。 このグリッチは、バス上のスレーブデバイスによって、ACKフラグがまだ設定されていない瞬間に現れるクロック信号として認識されます。 その後、スレーブデバイスはトランザクションを中止します。 デバイスから2バイトを読み取ろうとするこのようなトランザクションの例を図に示します(データキャプチャは120 MHzの周波数で実行され、タイムサンプル20968-20967にグリッチが存在します)。 Alter FPGA用の組み込みSignalTapロジックアナライザーを使用してタイミング図が取得されました(
ここでは、散らかったFPGAで初めて嬉しかったです )。 写真は、DIラインでデバイスから最初のバイトが読み取られ、その後デバイスが落ち(マスターから誤った確認を受信した)、2番目のバイトの代わりに0xFFが読み取られることを示しています。

このパルスをフィルタリングする場合、バス上の正しい読み取り手順が提供されました。 テスト環境では、FPGAでフィルタリングがデジタルで実行されました(
VHDLで記述された小さなモジュールは、入力信号のグリッチを拒否します )。 別の可能な方法は、SCLバスでRCチェーンを使用してフィルタリングすることですが、これ
により最大バス周波数が制限
されます(
何らかの狂気のため、このソリューションは深く分析されていません )。 正常なトランザクションの例(グリッチフィルタリングの対象)を次の図に示します。 これで、DIバスで、2バイトの正しい読み取り値が表示されます。
当然、この振る舞いの本当の理由を知りたいです。 残念ながら、LibMPSSE-I2Cライブラリのソースコードは利用できません。バイナリ逆アセンブリは私たちの専門ではありません。 しかし、オープンなプロトコル記述の存在下でUSBデータ交換を分析するのに5分かかります。 さて、1時間。 まあ、たった一日。詳細な調査により、LibMPSSE-I2Cライブラリによって生成されたMPSSEコントローラー用のコマンドの生成に問題があることが示されました。 以下は、バス上の2バイトを読み取るために使用されるコマンドのセットです(ストップビットは最後に設定されません)。 強調表示されたコマンドは、問題の場所とその解決方法を示しています(1への切り替えを禁止するか、ACKフラグに供給されたクロック信号の位相を変更することを禁止します)。
0x80, 0x03, 0x13, 0x80, 0x03, 0x13, 0x80, 0x03, 0x13, 0x80, 0x03, 0x13, 0x80, 0x03, 0x13,
したがって、問題はローカライズされ、解決策が見つかり、苦しんでいるすべてが3つのフローに分割されます。
- 上記の保留中の明確化に関してFTDIと通信します。
- バイナリライブラリは、対応するチームが形成され、それを管理する場所を探して分解されます。
- LibMPSSE-I2Cライブラリを使用せずに書き込み、上記と同様の制御シーケンスを直接送信することにより、ライブラリをバイパスしてMPSSEモードをプログラミングします。
研究プロセスでは、FTDIが提供する例に基づいて、2つのテストソフトウェアプロジェクトが作成されました。 LibMPSSE-I2Cライブラリに基づくプロジェクトはi2c_directと呼ばれます(メインファイルはi2c_direct.cppです)。 MPSSEモードを個別にプログラミングするプロジェクトはI2CTESTです(メインファイルはI2CTEST.cppです)。 ご希望の方は、投稿の最初の写真にあるrarjpegのようなアーカイブでソースファイルの例を見つけるでしょう。
参照:
AN108コマンドプロセッサ、MPSSEおよびMCUホストバスエミュレーションモード用AN113 FT2232H高速デバイスとI2CバスのインターフェースLibMPSSE-I2CのAN177ユーザーガイドI2CバスへのインターフェイスFT2232H高速デバイスの例(D2XX経由)LibMPSSE-I2Cの例