FPGAでI2CのRead/Writeしてみました。
IPを使ってC言語で動かしています。
FPGAへの実装方法から、実際にオシロスコープで波形の確認まで紹介します。
FPGAのI2CをIP使って実装してみた
FPGAでI2CのRead/Writeをしてみました。
FPGAはXilinxのSpartan7で、通信先のI2CのデバイスはカメラIC(OV5647)です。
FPGAでIPを使ったブロックデザインからC言語による実装までテストしています。
最後にはオシロスコープ使って実際のI2Cの波形測定まで実施しました。
プログラムで指定したスレーブアドレス(0x36)、レジスタ(0x300B)にWriteしています。
そして、必要なデータ(0x47)をReadできています。
実際に測定した下記動画含めて、一連の流れを紹介していきます。
XilinxのFPGAの評価ボードを使用
XilinxのFPGAの中でもスペックの低いSpartan7の評価ボードでテストしています。
I2CとUARTの2つのIFを試しています。
- I2C…カメラIF(MIPI CSI-2)の初期設定用
- UART…デバッグ用のシリアル通信(FPGAとPC間)用
今回使った評価ボードに関しては下記記事で紹介しています。(リンク先はこちら)
カメラIF(MIPI CSI-2)のI2Cと通信
カメラIF(MIPI CSI-2)のデバイスは初期設定でI2Cを使うケースが多いです。
FPGAの評価ボードに取り付ける、汎用的なラズパイ用のカメラもI2Cを使っています。
今回はカメラ動作までは実施しませんが、簡単にI2C通信テストをしてみます。
今回は紹介していませんが、MIPI CSI-2に関しては下記記事で紹介しています。
I2CはXilinxのIP Coreを使用
I2Cに関してはXilinxのIP Coreを使って(楽して)通信しました。
デフォルトで使えるIPのため、誰でも自由に使用することができます。
AXIバスを使う必要があるため、ソフトCPU(MicroBlaze)からI2Cを制御します。
IPコアを使ったハードウェア構築方法・配線に関しては下記記事に記載しています。
デバッグ用にシリアル(UART)通信も使用
デバッグ用のシリアル(UART)通信はUSBシリアル通信ケーブルを使用しています。
ボードにはTXD,RXDとGNDを接続している形となります。
FPGAの書き込みはJTAGケーブル
FPGAのプログラム書き込みはJTAGケーブルで行います。
ソフトウェア開発環境の「Vitis」でも自動認識して、書き込むことが可能です。
※USB経由でFPGAに書き込める評価ボードならJTAGケーブルは必要ありません。
専用のJTAG-USBケーブルについては下記をご参考ください。(リンク先はこちら)
FPGAの開発環境を用意
C言語でプログラムするためにも、XilinxのFPGAのソフト開発環境(Vitis)を用意します。
本来VitisはOS,メモリなどにインストール要件があります。
但し、今回のテストレベルならば家庭用のノートPCでも十分に実施可能でした。
Vitisの簡単な使い方・インストールに関しては下記記事に記載しています。
XilinxのIPを使ってI2C通信
開発環境VivadoのIPの検索画面で「IIC」と入力すれば、I2CのIPが設置できます。
XilinxのIPの設定に関してはデフォルトで使用しています。
通信速度としても標準的な100KHzです。
I2Cのピンを内部プルアップに設定
FPGAのピン設定であるXDC(制約)ファイルに関しては下記設定をしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
set_property -dict {PACKAGE_PIN N14 IOSTANDARD LVCMOS33} [get_ports uart_rtl_0_rxd] set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports uart_rtl_0_txd] set_property -dict {PACKAGE_PIN J1 IOSTANDARD LVCMOS33} [get_ports {gpio_rtl_0_tri_o[0]}] set_property -dict {PACKAGE_PIN A13 IOSTANDARD LVCMOS33} [get_ports {gpio_rtl_0_tri_o[1]}] set_property -dict {PACKAGE_PIN K11 IOSTANDARD LVCMOS33} [get_ports iic_rtl_0_scl_io] set_property -dict {PACKAGE_PIN K12 IOSTANDARD LVCMOS33} [get_ports iic_rtl_0_sda_io] set_property PULLUP true [get_ports iic_rtl_0_scl_io] set_property PULLUP true [get_ports iic_rtl_0_sda_io] set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports clk_100M] set_property -dict {PACKAGE_PIN M12 IOSTANDARD LVCMOS33} [get_ports cam_gpio] |
カメラコネクタのI2Cピン箇所は13ピン(SCL)、14ピン(SDA)となります。
今回のFPGA評価ボードだけではなく、ラズパイでも同じです。
FPGAの評価ボード・カメラ両方にプルアップ抵抗が搭載されていました。
FPGAの内臓プルアップしなくても動作すると思いますが、(一応)設定をしときます。
※XDCファイルの「set_property PULLUP true [get_ports~]」の箇所です
カメラIFのリセットを対応
今回ハードウェアのデザインとして、特に難しいことはしていません。
IPの接続方法を紹介した下記記事から基本変更無しです。
差分としては、今回カメラIFを使っているのリセット信号を1本追加しただけです。
C言語でI2Cの通信テスト
実際に使ったC言語のI2C通信のテストプログラムは下記となります。
Xilinxのソフトウェア開発環境であるVitisで実行しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include "xparameters.h" #include "XIic.h" u8 readReg(u16 reg_addr) { u8 write_buf[3]; write_buf[0] = (reg_addr >> 8) & 0xff; write_buf[1] = reg_addr & 0xff; u8 read_buf; XIic_Send(0x40800000, 0x36, write_buf, 2, 0); XIic_Recv(0x40800000, 0x36, &read_buf, 1, 0); return read_buf; } int main() { //usleep(10000000); // 10sec sleep u8 data; data = readReg(0x300b); xil_printf("%x\r\n", data); return 0; } |
実行結果として、I2CでReadしたレジスタ値(0x47)がシリアル出力できています。
プログラムの概要
今回のテストでは1つのレジスタ値を確認しているだけです。ご注意下さい。
(本来カメラを動かすためには、多くのレジスタ値を書き込む必要が有ります。)
レジスタ値をReadするために、確認したいレジスタのアドレスをWriteしています。
- I2Cでスレーブアドレス(0x36)にWrite ※確認したいアドレスは0x300B
- I2Cでスレーブアドレス(0x36)にRead →確認したレジスタ値は0x47
参考にさせていただいた記事
I2Cのプログラム、OV5647のデータシート含めて下記記事を参考にさせていただきました。
運営者様・管理者様にはこの場を借りて深くお礼申し上げます。
https://xilinx.github.io/embeddedsw.github.io/iic/doc/html/api/index.html
https://cdn.sparkfun.com/datasheets/Dev/RaspberryPi/ov5647_full.pdf
FPGAのI2Cの波形測定
今回レジスタ値が0x47と読み取れたI2C通信を回路からも確認してみます。
FPGAとカメラのI2C通信箇所でオシロスコープにて測定します。
実際にプローブ当てた箇所はカメラ基板の裏側のTP(テストポイント)です。
CH1をSCL(I2Cのクロック)、CH2をSDA(I2Cのデータ)として測定しました。
冒頭でも紹介しましたが、下記動画でも紹介しています。
プログラム通りのI2C波形
波形でもFPGAのプログラム通りのI2C波形になっていることが分かります。
先ほど紹介したC言語のプログラム概要通りの形です。
オシロスコープのデコード機能を使って、レジスタ値が0x47のReadも確認しています。
I2Cの波形の詳細(Read/Write、ACK/NACK)に関しては下記記事で説明しています。
I2Cの通信速度100KHzも確認
波形をアップしてI2Cの通信速度(クロック)を確認すると100KHzでした。
IPのデフォルト設定どおりとなっています。
まとめ
今回はFPGAでI2CのIPに関して紹介させていただきました。
記事をまとめますと下記になります。
I2CでカメラICの初期設定を完了して、画像信号(MIPI CSI-2)も確認してみました。
是非一緒にご覧ください。(リンクはこちら)
FPGAでMIPI CSI-2のカメラを動かしてみた。準備編!
コメント