2014年03月17日

FX3のI2Cを使ってADV7511の設定をしよう〜I2C通信編〜


初回の「FX3のI2Cを使ってADV7511の設定をしよう〜I2C設定編〜」ではFX3でI2C通信をするための仕組みを組み込みました。
2回目の「FX3のI2Cを使ってADV7511の設定をしよう〜ADV7511設定編〜」ではADV7511の設定を行いました。

前回までの記事でADV7511の初期設定は終了しましたが、今回はSVM-03とUSB接続されたPCから、ADV7511のレジスタ値を読み書きしてみたいと思います。

PC上で使用するアプリケーションはサイプレス社のFX3用SDKにあるcontrol centerを使用します。
SDKをインストールしたディレクトリーの
「\cypress\EZ-USB FX3 SDK\(バージョン番号)\bin\CyControl.exe」
にcontrol centerの実行ファイルがありますのでそれを起動しておきます。

次から、I2Cを書き込む場合と読み込みの場合に分けて、設定方法を説明します。


<ADV7511のレジスタに値を書き込む場合>
control centerの画面が下記になります。その画面上に操作手順を説明するための番号と枠線をつけております。

i2C-send.jpg


以降画面上の番号に沿って操作方法を説明していきます。

@「Cypress USB BulkloopExample」→「Configuration 1」→「Control endpoint(0x00)」を選択します。

A「Data Transfers」タブを選択します。

BDirection、ReqType、Targetを下記の値にそれぞれ設定します。
Direction:Out
ReqType:Vendor
Target:Device

CReqCode、wIndexを下記の値に設定します。ReqCodeは書き込みの場合は「0xba」を指定します。wIndexは書き込み先サブアドレスの設定を行います。(画面は0x00afをサブアドレスに指定している例です。)
ReqCode:0xba
wIndex:0x00af

Dレジスタに書き込む値を「Data to send(Hex)」テキストボックスに入力します。この時「Bytes to Transfer」の値も自動で変化しますが正しくない場合には値を修正します。

E赤枠の「Transfer Date」ボタンを押します。

すると、下の大きなテキストボックスに「CONTROL OUT transfer completed」と表示されれはI2Cの設定がFX3から行われたことになります。

書き込みが正しくできているかどうかは書き込み対象のレジスタの値を読み込んで確認をしてください。

<ADV7511のレジスタから値を読み込む場合>

i2c-Receive.jpg


@「Cypress USB BulkloopExample」→「Configuration 1」→「Control endpoint(0x00)」を選択します。

A「Data Transfers」タブを選択します。

BDirection、ReqType、Targetを下記の値にそれぞれ設定します。
Direction:In
ReqType:Vendor
Target:Device

CReqCode、wIndexを下記の値に設定します。ReqCodeは書き込みの場合は「0xbb」を指定します。wIndexは書き込み先サブアドレスの設定を行います。(画面は0x0043をサブアドレスに指定している例です。)
ReqCode:0xbb
wIndex:0x0043

D「Bytes to Transfer」に読み込みたいバイト数を指定します。開始サブアドレスはwIndexで指定したアドレスになります。(画面は2バイト読み込みの例になります。)

E赤枠の「Transfer Date」ボタンを押します。

下のテキストボックスに指定したサブアドレスのレジスタの値が表示されます。

いかがでしたでしょうか。FX3のI2C機能を利用してADV7511のレジスタの読み書きを行いました。
これにて、FX3を利用してのADV7511の設定のブログ記事は完結です。

また、HDMIモニターボードSVM-03に興味ございましたらSVM-03のページも合わせてご覧ください。

※なおここに掲載したADV7511の設定およびソースコードは製品版のSVM-03では使用してはおりません。ただし、画像が正しく表示されることやI2Cが設定できることを確認しています。あらかじめご了承ください。
posted by デベマネ at 14:48| Comment(0) | FX3/ADV7511

2014年03月10日

FX3のI2Cを使ってADV7511の設定をしよう〜ADV7511設定編〜

前回の「FX3のI2Cを使ってADV7511の設定をしよう〜I2C設定編〜」ではFX3でI2C通信をするための仕組みを組み込みましたので、今回はその仕組みを
使用してADV7511の初期設定をしたいと思います。

まず初めに、前回I2C通信を組み込んだSDKのサンプルにadv7511_initとadv7511_Setup_16bitYuv422toYuv422_registersを追加していきます。

void
adv7511_init(void)
{
// adv7511_Setup_16bitYuv422toYuv422の初期化実施
adv7511_Setup_16bitYuv422toYuv422_registers();

}

void adv7511_Setup_16bitYuv422toYuv422_registers(void)
{
uint16_t wSubAddr;
uint16_t i, t1;

// ADV7511その他初期化処理
for(i=0;;i++){
if(ADV7511_Setup_16bitYuv422toYuv422[i][0] == 0x0 ) break; /* terminate*/
wSubAddr = (uint16_t)ADV7511_Setup_16bitYuv422toYuv422[i][1];
CyFxUsbI2cTransfer (wSubAddr, 0x7a, 1, (uint8_t *)&ADV7511_Setup_16bitYuv422toYuv422[i][2], CyFalse);
}
}


adv7511_init(void)はadv7511_Setup_16bitYuv422toYuv422_registers()を呼び出すための関数になっています。ADV7511_Setup_16bitYuv422toYuv422という配列に格納された設定値を1要素ずつ、ADV7511のレジスタに設定していきます(1バイトずつI2Cによりレジスタ設定を行います)。

では、次ににADV7511の設定値を記載した配列を準備します。

const uint8_t nv_adv7511_start[][3] = {
/*slv, sub, data*/
{0x39, 0x41, 0x10}, // Main Power Up
{0x39, 0x98, 0x03}, // Must be set to0x03 for proper operation
{0x39, 0x9a, 0xe0}, // Must be set to 0b1110000
{0x39, 0x9c, 0x30}, // Must be set to 0x30 for proper operation
{0x39, 0x9d, 0x61}, // Must be set to 0b01[1:0] for proper operation
{0x39, 0xa2, 0xa4}, // Must be set to 0xA4 for proper operation
{0x39, 0xa3, 0xa4}, // Must be set to 0xA4 for proper operation
{0x39, 0xe0, 0xd0}, // Must be set to 0xD0 for proper operation
{0x39, 0xf9, 0x00}, // This should be set to a non-conflicting I2C address (set to 0x00)

{0x39, 0x43, 0x7e}, //EDID Memory Address
{0x39, 0x45, 0x70}, //Packet Memory I2C Map Address
{0x39, 0xe1, 0x78}, //CEC Map Address
{0x39, 0x40, 0x00}, // packet update Disable
{0x39, 0x44, 0x01}, // packet update Disable
{0x39, 0xe2, 0x01}, // CEC(周辺機器と通信できる機能) power down

// link config
{0x39, 0x15, 0x01}, // I2S sampling freq. 44.1KHz, Input format 16b, 4:2:2, YCrCb
{0x39, 0x16, 0xb9}, // Output format 4:2:2, 8-bit, style 2, DDR falling, Output color space = YCrCb

{0x39, 0x17, 0x02}, // 16:9 Aspect Ratio
{0x39, 0x18, 0x46}, // Color Space Conversion(CSC) disable
{0x39, 0x40, 0x80}, // Enable GC Packet
{0x39, 0x48, 0x00}, // Video Input Bus Reverse= Normal Bus Order,Video Input Justification is Evenly Distributed
{0x39, 0xd0, 0x3c}, // Disable DDR Negative Edge CLK Delay, DDR Negative Edge CLK Delay=Nodelay,
// Sync Pulse Select=no sync pulse,sync adjustment then DE generation
{0x39, 0xba, 0x00}, // External HDCP EEPROM,Clock Delay=-1.2ns,Don't Show AKSV,HDCP Ri standard
{0x39, 0xde, 0x10}, // Normal TMDS Clock

// SetConfig
{0x39, 0xaf, 0x06}, // HDCP disabled, HDMI mode

// avi infoFrame Setting
{0x39, 0x55, 0x20}, // Y1Y0 (AVI InfoFrame) = YCbCr 422
{0x39, 0x56, 0x28}, // Picture Aspect Ratio = 16:9 Active Format Aspect Ratio = Same as Aspect Ratio
{0x39, 0x44, 0x78}, // avi infoFrame Packet Enable

{0x00, 0x00, 0x00} // I2C終了フラグ
};


※ここで紹介しているADV7511の設定はLinuxドライバ等の設定を参考に弊社で作成したものです。弊社環境での動作確認はしております。また、SVM-03ではこの設定を利用していません。

1080p、60fpsのYUV形式でのカラーバー画像をFPGAからADV7511に送っていますのでその設定になります。
まず初めに、Main Power UpフラグをOnにします。その後ADV7511は決まりとして、パワーアップ後にいくつかのレジスタを設定する必要があります。それが、{0x39, 0x98, 0x03}から{0x39, 0xf9, 0x00}の値になります。
それ以降は出力の設定や仕様に合わせてレジスタ値を設定します。詳細はADV7511のハードウェアユーザーガイドおよびプログラミングガイドをご確認ください。

またレジスタ設定についてはFPGAの部屋の下記の記事が参考になります。(弊社でも参考にさせていただきました。ありがとうございます!)併せてご覧ください。
ZedBoardでHDMI出力10(ADV7511のピクセル入力レジスタ設定)
またFPGAの部屋のブログ内検索で「ADV7511」で検索すると関連記事が表示されます。


最後に今追加した設定をFX3起動時に行えるようにAppThread_Entry関数にadv7511_init関数を追記します。

このように設定して、USBケーブルでPCとボードを接続すると、HDMIモニターにカラーバーが表示されます。(USBケーブル接続時にFX3の電源がONとなります。)


adv7511-colorbar-Image.jpg


※注意:ADV7511の設定は接続先モニターやADV7511に入力する信号等により変更する必要があります。この設定を適用しても動作しない場合がありますのでご了承ください。

ADV7511を設定しカラーバーが表示されました。これでADV7511の初期設定まで完了しました。
次回は、cypress社から提供されているcontrol centerアプリを使用して、I2C通信を行ってみたいと思います。

タグ:FX3 ADV7511
posted by デベマネ at 12:20| Comment(0) | FX3/ADV7511

2014年03月03日

FX3のI2Cを使ってADV7511の設定をしよう〜I2C設定編〜

新製品として、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送受信が行えるようになります。

システム構成は次のようになります。


I2C-ADV7511-sysConf.jpg

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を出してみよう」のブログをご覧ください。)


adv7511-I2C-Flow.jpg


初めに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 & 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の初期設定について記載をしていきます。
タグ:FX3 I2C ADV7511
posted by デベマネ at 12:37| Comment(0) | FX3/ADV7511