FX3のI2Cを使ってADV7511の設定をしよう~I2C設定編~【2014/01/25】
新製品として、HDMI対応モニターボードSVM-03を発表しました。
このSVM-03はカメラなどの入力画像をHDMIモニターに直接出力することができます。
詳細はSVM-03のページをご確認ください。

SVM-03にはHDMIに出力するためにADV7511を使用しています。
また、USB3.0接続用のFX3も搭載しています。
そこで、今回はFX3のI2C機能を使用して、ADV7511の初期設定を行いたいと思います。

FX3でI2Cを行うために使用するFX3のSDKサンプルは、「serialif_examples」フォルダにある「cyfxusbi2cregmode」です。
このサンプルはI2Cをレジスターモードで行うサンプルになっています。
また、コントロールセンターを使用してI2Cの設定コマンドを送受信することができるようになっています。
ADV7511の設定は、FX3の起動時に1度呼出す形として実装を行います。
本来はエラー処理なども検討して実装を行う必要がありますが、説明のため簡略化しています。
また、その後はPCからのI2C送受信が行えるようになります。
システム構成は次のようになります。

SVM-03はUSB3.0経由でPCと接続します。このPCは次の2つの役割を果たします。

・USBポートからの給電(SVM-03はUSB給電のみ対応。ACアダプタ無し)
・PC上のcontrol center からI2Cの送受信を行う

また、HDMIから正しく映像が出力されていることを確認するために、HDMI接続にてモニターに接続をしています。
モニターに出力される画像はこのボードに搭載されているFPGA(Spartan-6 XC6SLX15)にて1080p、60fpsのYUV形式でのカラーバー画像を作成しています。

では、I2Cを行うサンプルソースを眺めていきましょう。
「cyfxusbi2cregmode」フォルダ内の「cyfxusbi2cregmode.c」を開きます。このファイルにI2Cの初期化や送信などの処理を行うコードが書かれています。

このサンプルの基本的な動作フローを説明します。

まず、FX3起動後に既定の処理を行い、スレッドを起動します。起動したスレットでは次の動作を行います。(既定の処理については以前掲載した「FX3プログラミング Hello Worldを出してみよう」のブログをご覧ください。)

初めにI2Cの初期化を行い、I2Cが使用できるようにします。次にADV7511のレジスタの初期化設定をI2Cにて行います。
その後は、control centerからのI2CのRead/Writeの指令があるまで待機をします。これが一連の動作フローとなります。

今回はADV7511とFX3でI2C通信するためにSDKのソースを一部変更しましたが、変更した関数に絞って変更内容を紹介いたします。


<CyFxUSBSetupCB関数>
主な変更は次の箇所です。

1.関数内で指定されているローカル変数の名前を、「wIndex」→「wSubAddr」に変更します。
これは、わかりやすさのためにそのようにしています。

2.switch (bRequest)の条件CY_FX_RQT_I2C_EEPROM_WRITEとCY_FX_RQT_I2C_EEPROM_READにあるi2cAddrの値を「i2cAddr = 0xA0 | ((wValue &smp; 0x0007) << 1);」→「i2cAddr = 0x7A;」に変更。
これは、ADV7511のメインレジスターアドレスになります。


<CyFxUsbI2cTransfer関数>
主な変更は次の箇所です。

1.「pageCount」と「glI2cPageSize」を使用して繰り返しI2Cを行う作りとなっていますが、不要なので関連する記載を削除します。

2.I2CのRead部分(if (isRead)がTrueの時に呼び出される部分)を以下のように修正します。
preamble.length = 3; // preambleバッファサイズ
preamble.buffer[0] = devAddr; // Slave address.
preamble.buffer[1] = (uint8_t)(byteAddress & 0xFF); // Sub address
preamble.buffer[2] = (devAddr | 0x01); // Read用Slave address.
preamble.ctrlMask = 0x0002; // Read用アドレス格納位置
status = CyU3PI2cReceiveBytes (&preamble, buffer, byteCount, 0);
if (status != CY_U3P_SUCCESS)
{
return status;
}
3.I2CのWrite部分(if (isRead)がTrueの時に呼び出される部分)を以下のように修正します。
preamble.length = 2; // preambleバッファサイズ
preamble.buffer[0] = devAddr; // Slave address
preamble.buffer[1] = (uint8_t)(byteAddress & 0xFF); // Sub address
preamble.ctrlMask = 0x0000; // Read用アドレス格納位置
status = CyU3PI2cTransmitBytes (&preamble, buffer, byteCount, 0);

preamble.ctrlMaskに関しては、Read用アドレスが格納されたpreamble bufferの配列位置を指定するもののようです。
2バイトアドレッシングモード時には、0x04を、1バイトアドレッシングモード時には0x02を指定して読み込み(CyU3PI2cReceiveBytes)を行います。
当然Writeではこの値は0x00となるようです。

詳細はCypressの開発者コミュニティのフォーラム「I2C preamble question」の回答「FX3_I2C_DETAILS.zip」があります。
PDFファイルに詳細が記載されておりますのでご確認ください。

次回は、ADV7511の初期設定について記載をしていきます。

» 記事一覧へ戻る