色々とビット幅がミスっていたが、(しかし、Verilogはビット幅が間違っていてもエラーがでないものか?)やっとまともにSXGAの画像を表示することができた。ヤッター!

(SXGAです。PCLK 48MHz、15fps)
OV9655は現在の設定では?、暗さに弱いようだ。上の画像は照明が暗いので、明るいところではもっと良い画像になった。

OV7670のS/N Rate は46dB、Dynamic Range は52dBに対して、
OV9655のS/N Rate は42dB、Dynamic Range は50dB なので、OV9655は画素が多い分、大きさが小さいのだろうか?
ともかく、目的は達成した。やはり、SXGAの方が綺麗だ。後は、RGB各4ビットではビット数が少ないので、買ってある
Chrontel のCH7301Cを使って、RGB各8ビットのDVI-Iで出力したい。そのためには、Spartan-3A Starter Kit の拡張ポートの基板を設計して、どこかに作ってもらう必要がある。4層基板で作りたいな?と思っている。
- 2011年01月28日 19:02 |
- OV9655
-
| トラックバック:0
-
| コメント:4
”
OV9655でSXGAを表示1(FIFO容量の再検討)”でFIFO容量の検討をした。その検討結果を元にCoreGenのIPを変更する。更に、SXGAの解像度にタイミングを変更する。
Camera_Controller 用のFIFOのcam_cont_afifoを開いた。下図参照。

Write Widthは16ビットでWrite Depthは64(8ビット換算では128深度)なので、すでに十分な容量がある。これはこのままとする。
次に、VGA_Display_Controller 用のcam_data_afifoを開いた。下図参照。

このFIFOは半分の容量だったので、Write Width 32、Write Depth 256, Read Width 16, Read Depth 512 に変更した。
”
VESA Signal 1280 x 1024 @ 60 Hz timing”を参考にdisp_timing_parameters.vhを変更した。
// 表示タイミングの定義 (1280 x 1024)
parameter H_ACTIVE_VIDEO= 1280;
parameter H_FRONT_PORCH = 48;
parameter H_SYNC_PULSE = 112;
parameter H_BACK_PORCH = 248;
parameter H_SUM = H_ACTIVE_VIDEO + H_FRONT_PORCH + H_SYNC_PULSE + H_BACK_PORCH;
parameter V_ACTIVE_VIDEO = 1024;
parameter V_FRONT_PORCH = 1;
parameter V_SYNC_PULSE = 3;
parameter V_BACK_PORCH = 38;
parameter V_SUM = V_ACTIVE_VIDEO + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH;
parameter H_DISPLAY_SIZE = H_ACTIVE_VIDEO/8; // 横160桁
parameter V_DISPLAY_SIZE = V_ACTIVE_VIDEO/8; // 縦128行
parameter RED_DOT_POS = 9; // 9ビット目がRED
parameter GREEN_DOT_POS = 8; // 8ビット目がGREEN
parameter BLUE_DOT_POS = 7; // 7ビット目がBLUE
後は、カウンタのビット長などを変更している。思ったより、手間がかかりそう。ピクセルクロックは108MHz、フレームレートは60Hzと書いてあったが、62Hz程度だった。
次回は、OV9655の設定を決めて、SXGA画像の表示を試みる。
- 2011年01月26日 05:26 |
- OV9655
-
| トラックバック:0
-
| コメント:0
”
OV9655を使ってみる4(VGAの表示)”でOV9655でVGAを表示できたので、今度はSXGAを表示してみたい。
前回、”
OV9655を使ってみる3(回路の書き換え)”で、Camera_Controller の動作クロックとVGA_Display_Controller のクロックを分離した。SXGAでは、Camera_Controller の動作クロック、つまり、OV9655のPCLKは48MHzで15fps、VGA_Display_Controller のクロックは108MHzとなる(
VESA Signal 1280 x 1024 @ 60 Hz timingを参考にした)。
VGA_Display_Controller の動作クロックがVGAの25MHzから4倍にあがったので、DDR2 SDRAMコントローラの帯域がきつくなることが考えられる。それと、相対的なレイテンシも増加するので、VGA_Display_Controller やCamera_Controller のFIFO容量の考察が必要となる。
”
Spartan-3A Starter KitでCMOSカメラ・ディスプレイ回路2(レイテンシの測定)”を参考に、現在のDDR2 SDRAMの動作クロック125MHzにおけるレイテンシを計算してみた。このレイテンシは、CMOSカメラのデータをSXGAに表示するだけではなく、この表示回路にCPUなどの付加回路を付けたときにでも、ディスプレイの表示が破綻しないことを目指す。
まずは、DDR2 SDRAMの動作クロックが125MHzの時の、DDR2 SDRAMコントローラにコマンドが入っていない状態(初期状態)でのWriteアクセスのレイテンシは、
87nsec * 150MHz / 125MHz = 104 nsec
となる。初期状態でのReadアクセスのレイテンシは、
147nsec * 150MHz / 125MHz = 176 nsec
となる。
リフレッシュによるレイテンシについて検証する。次のバーストのためにプリチャージしてACTコマンドを入れたときにリフレッシュが起きて、また同じACTコマンドを入れ直している場合は、150MHzの時に、180nsec のレイテンシが増加しているので、125MHzでは、
180nsec * 150MHz / 125MHz = 216nsec
となる。以前の150MHzの例を下図に示す。

ROWアドレスやバンクが異なる(つまりプリチャージ、ACTコマンドを入れなければならない)Write, ReadコマンドがFIFOに詰まっている場合のレイテンシについて検討してみる。下図に150MHzの場合を示す。

上図は、DDR2 SDRAMコントローラへのWrite, Read要求用のFIFOがFULLになったところのRead要求を入力してから、Readされた値がoutput_data に出てくるまでの時間を測定している。測定した時間は1340nsec だった。これを125MHzに変換すると、
1340nsec * 150MHz / 125MHz = 1608nsec
となる。以前は考慮しなかったが、最悪の場合として、リフレッシュによる増加分216nsec を加えると、1824nsec となる。これをVGA_Display_Controller の動作周波数108MHzの周期9.26nsec で割ると、197クロックになる。
非同期FIFOが半分の容量になったときに、VGA_Display_Controller はArbiterに表示データの要求を出すので、非同期FIFOの容量は197の倍の394深度となる。ということは、データ幅が16ビットのVGA_Display_Controller側(RGB444)では、512深度のFIFOを実装することにする。DDR2 SDRAMコントローラのデータ幅は32ビットなので、256深度だ。
次に、Camera_Controller のFIFOの容量を計算する。Camera_Controller は優先順位が最低なので、VGA_Display_Controller のバースト転送もレイテンシとして計算する。
Readアクセスのレイテンシ+128Readバーストの時間を計算する。VGA_Display_Controller のFIFOは半分の容量になったときに、半分の容量分のReadリクエストをDDR2 SDRAMコントローラに出す。それは、256バイトのRead要求なので、16ビット幅のDDR2 SDRAMでは、128ワードのReadアクセスとなるからである。128Readバースト時間は、
128 * 1/(250MHz) = 512 nsec
なので、これにリフレッシュによる増加分を加えて、728nsec となる。これに、DRR2 SDRAMコントローラのFIFOが最悪の条件でFULLになっている時のレイテンシ1608nsec を加えると、2336nsec となる。2336nsec をCamera_Controller の動作周波数48MHzの周期20.8nsecで割ると、112クロックとなる。よって、Camera_Controller のFIFOは8ビットデータ幅で128深度のFIFOとする。
DDR2 SDRAMのメモリ帯域をどのくらい占有するか計算してみると、DDR2-250なので、250MHz * 2バイト = 500MB/sec、VGA_Display_Controller では、108MHz * 1バイト = 108MB/sec、Camera_Controller では、48MHz * 1バイト = 48MB/sec なので、
((108MB/sec + 48MB/sec) / 500MB/sec) * 100 = 31.2%
の帯域を使用している。後の70%は、まだ帯域が残っている。VGA_Display_Controller もCamera_Controller もブランク期間があるので、もう少し帯域は抑えられるはずなので、まだCPUなどを付加する余裕があると思われる。
- 2011年01月25日 05:47 |
- OV9655
-
| トラックバック:0
-
| コメント:2
OV9655を使用してVGAを表示させてみた。SCCBレジスタの設定値は”
Surveyor SRV-1 Blackfin Camera”ページの
”Google Code zip archive of the SRV-1/SVS firmware builds”からお借りした。
これを元にRGB555に変更した。このSCCB設定レジスタの設定値は0x11のプリスケーラに0x01が入っているようなので、PLLでX4にしておくと、CMOSカメラのXCLK1に入れたクロック周波数がそのままPCLKに出てくる。
この設定値を使ってディスプレイに出た画像が下だ。

ちょっと緑が強い気がする。OV7670とそう変わらないか?それともOV7670の方が少し良い感じがする。
Pudn.com > Downloads > SourceCode/Document > Embeded-SCM Develop > Embeded Linux > OV9655のif defined(CONFIG_OV9655_OUT_VGA)の設定値を使ってみたところ、横に流れてしまって画像が見えなかった。
本当にCMOSカメラを設定するのは難しいということが改めてわかった。Preliminary Datasheetに書いていないことが多すぎる。。。
今度はCMOSカメラ回路を変更して、SXGAを表示させてみたいと思っているが、その前にNSLの続きをやってみようと思う。
- 2011年01月13日 05:21 |
- OV9655
-
| トラックバック:0
-
| コメント:0
OV9655はSXGA (ピクセルクロックは108MHz) とVGA (ピクセルクロックは25MHz) で使う予定なので、CMOSカメラのドットクロックとVGA Display Controller のドットクロックが合わなくなる。今までは、CMOSカメラに25MHzを入力して帰ってきたPCLKでCamera ControllerとVGA Display Controller を動作させていた。


これらのクロックは、Spartan-3A Starter Kit の50MHzのクロックをDCMで1/2にしてCMOSカメラに入力していたが、ここも独立させてDCMを1個使用することにした。VGA Display Controller のクロックもCMOSカメラのPCLKから取るのやめて、独立にDCMを追加した。
下にdcm_CAM_DDR2_clk.vのVerilog ソースを示す。
// DCM module (dcm_CAM_DDR2_clk.v)
// 50MHzを入力して、DDR2_SDRAM用のclkを生成する。
// 125MHzクロック出力に変更。CMOSカメラ用の25MHzも生成する
// 2011/01/11 : VGA Display Controller のクロックとCAMのクロックを独自のDCMで生成する
`default_nettype none
`timescale 1ns / 1ps
(* KEEP_HIERARCHY = "TRUE" *)module dcm_CAM_DDR2_clk (sysclk, reset, clk_ddr2, clk_cam, clk_vga, dcm_ddr2_locked, dcm_cam_locked, dcm_vga_locked);
`include "ddr2_cont_parameters.vh"
input wire sysclk;
input wire reset;
output wire clk_ddr2;
output wire clk_cam;
output wire clk_vga;
output wire dcm_ddr2_locked;
output wire dcm_cam_locked;
output wire dcm_vga_locked;
wire clk_bufg, clk_node, dcm1_locked;
wire clk_ddr2_node, clk_ddr2_bufg;
wire clk_cam_node, clk_cam_bufg;
wire clkc_bufg, clkc_node, dcmc_locked;
wire clkv_bufg, clkv_node, dcmv_locked;
wire clk_vgadc_node, clk_vgadc_bufg;
wire reset_vc_dcm;
// DDR2 SDRAM用クロック
DCM dcm_DDR2_clk_dcm (
.CLKIN(sysclk),
.CLKFB(clk_bufg),
.DSSEN(1'b0),
.PSINCDEC(1'b0),
.PSEN(1'b0),
.PSCLK(1'b0),
.RST(reset), // 前段のDCMがロックするまでリセット
.CLK0(clk_node),
.CLK90(),
.CLK180(),
.CLK270(),
.CLK2X(),
.CLK2X180(),
.CLKDV(),
.CLKFX(clk_ddr2_node),
.CLKFX180(),
.LOCKED(dcm1_locked),
.PSDONE(),
.STATUS()
);
defparam dcm_DDR2_clk_dcm.CLKIN_PERIOD = 20.0;
defparam dcm_DDR2_clk_dcm.DLL_FREQUENCY_MODE = "LOW";
defparam dcm_DDR2_clk_dcm.DUTY_CYCLE_CORRECTION = "TRUE";
defparam dcm_DDR2_clk_dcm.CLKDV_DIVIDE = 2.0;
defparam dcm_DDR2_clk_dcm.PHASE_SHIFT = 0;
defparam dcm_DDR2_clk_dcm.CLKOUT_PHASE_SHIFT = "NONE";
defparam dcm_DDR2_clk_dcm.STARTUP_WAIT = "FALSE";
defparam dcm_DDR2_clk_dcm.CLKFX_DIVIDE = 2;
defparam dcm_DDR2_clk_dcm.CLKFX_MULTIPLY = 5;
// defparam dcm_DDR2_clk_dcm.FACTORY_JF = 16'hFFFF;
BUFG CLK_BUFG_INST (
.I(clk_node),
.O(clk_bufg)
);
BUFG CLK200_BUFG_INST (
.I(clk_ddr2_node),
.O(clk_ddr2_bufg)
);
assign reset_vc_dcm = ~dcm1_locked;
// CMOSカメラ用クロック(24MHz)
DCM dcm_cam (
.CLKIN(clk_bufg),
.CLKFB(clkc_bufg),
.DSSEN(1'b0),
.PSINCDEC(1'b0),
.PSEN(1'b0),
.PSCLK(1'b0),
.RST(reset_vc_dcm), // 前段のDCMがロックするまでリセット
.CLK0(clkc_node),
.CLK90(),
.CLK180(),
.CLK270(),
.CLK2X(),
.CLK2X180(),
.CLKDV(),
.CLKFX(clk_cam_node),
.CLKFX180(),
.LOCKED(dcmc_locked),
.PSDONE(),
.STATUS()
);
defparam dcm_cam.CLKIN_PERIOD = 20.0;
defparam dcm_cam.DLL_FREQUENCY_MODE = "LOW";
defparam dcm_cam.DUTY_CYCLE_CORRECTION = "TRUE";
defparam dcm_cam.CLKDV_DIVIDE = 2.0;
defparam dcm_cam.PHASE_SHIFT = 0;
defparam dcm_cam.CLKOUT_PHASE_SHIFT = "NONE";
defparam dcm_cam.STARTUP_WAIT = "FALSE";
defparam dcm_cam.CLKFX_DIVIDE = 25;
defparam dcm_cam.CLKFX_MULTIPLY = 12;
// defparam dcm_cam.FACTORY_JF = 16'hFFFF;
BUFG CLKC_BUFG_INST (
.I(clkc_node),
.O(clkc_bufg)
);
BUFG CLK_CAM_BUFG_INST (
.I(clk_cam_node),
.O(clk_cam_bufg)
);
// VGA Display Controller 用クロック(25MHz)
DCM dcm_vgadc (
.CLKIN(clk_bufg),
.CLKFB(clkv_bufg),
.DSSEN(1'b0),
.PSINCDEC(1'b0),
.PSEN(1'b0),
.PSCLK(1'b0),
.RST(reset_vc_dcm), // 前段のDCMがロックするまでリセット
.CLK0(clkv_node),
.CLK90(),
.CLK180(),
.CLK270(),
.CLK2X(),
.CLK2X180(),
.CLKDV(),
.CLKFX(clk_vgadc_node),
.CLKFX180(),
.LOCKED(dcmv_locked),
.PSDONE(),
.STATUS()
);
defparam dcm_vgadc.CLKIN_PERIOD = 20.0;
defparam dcm_vgadc.DLL_FREQUENCY_MODE = "LOW";
defparam dcm_vgadc.DUTY_CYCLE_CORRECTION = "TRUE";
defparam dcm_vgadc.CLKDV_DIVIDE = 2.0;
defparam dcm_vgadc.PHASE_SHIFT = 0;
defparam dcm_vgadc.CLKOUT_PHASE_SHIFT = "NONE";
defparam dcm_vgadc.STARTUP_WAIT = "FALSE";
defparam dcm_vgadc.CLKFX_DIVIDE = 4;
defparam dcm_vgadc.CLKFX_MULTIPLY = 2;
// defparam dcm_vgadc.FACTORY_JF = 16'hFFFF;
BUFG CLKV_BUFG_INST (
.I(clkv_node),
.O(clkv_bufg)
);
BUFG CLK_VGADC_BUFG_INST (
.I(clk_vgadc_node),
.O(clk_vgadc_bufg)
);
assign clk_ddr2 = clk_ddr2_bufg;
assign dcm_ddr2_locked = dcm1_locked;
assign dcm_cam_locked = dcmc_locked;
assign dcm_vga_locked = dcmv_locked;
assign clk_cam = clk_cam_bufg;
assign clk_vga = clk_vgadc_bufg;
endmodule
この構成で、OV7670カメラ回路を動作させたら問題なく動作した。
次に、OV9655に取り替えて、VGAに設定したつもりで、SCCB設定レジスタに以下の項目を設定した。最初の2文字がレジスタのアドレスで、後の2文字が設定データ。FF00は終了の合図。
6B0A
1267
40F0
FF00
aitendoのOV9655モジュールではDVDDの1.8Vは内蔵のレギュレータを使用しているので、設定レジスタ6Bのビット4は0にしておく必要があると思う。設定レジスタ12で30fps VGAとRGBモードに、設定レジスタ40でデータのレンジを00からFFまでにとRGB555に設定したつもりだ。CMOSカメラに入れるクロックは24MHzだ。
これで確かめてみたところ、PCLKには12MHzが出力され、入力したクロックの半分になっていた。VSYNCは3.5Hz程度、HREFは4KHz程度だった。どうもSXGAモードになっているみたいだった。
OV9655のマニュアルを良く読んだら、SCCBインターフェースでアクセスすべきアドレスが違っていた。OV7670のWriteでは42番地だったが、OV9655のWriteでは60番地だそうだ。これでは設定できない。。。
早速、One_Transaction_SCCB.vhdの
constant ID_ADDRESS_PATTERN_SDA : std_logic_vector := "010000100";
を
constant ID_ADDRESS_PATTERN_SDA : std_logic_vector := "011000000";
に変更した。
これでSCCB設定レジスタに設定できるようになったようだが、今度はHREFが30Hz、VSYNCが30Hzになってしまった。おかしい。。。
SXGAモードでは、CMOSカメラの入力周波数を24MHzにして、6BレジスタでPLLをBypassモードからX4モードに設定すると、PCLKは48MHz、VSYNCが15Hz程度、HREFが15KHz程度になって、これでいい感じなのではないか?と思う。
VGAモードを探っていきたいが、サンプルをWebから入手したので、これを設定してVGAモードになるかどうか?を確かめてみたい。
- 2011年01月12日 05:37 |
- OV9655
-
| トラックバック:0
-
| コメント:0
今日はOV9655とSpartan-3A Starter Kit をつなぐ変換基板をFPGA-CAFEで作らせてもらった。すすたわりさんの席で作らせてもらって、ありがたかった。ありがとうございました。
さて、変換基板は、OV7670の変換基板と同じに作ろうと思ったのだが、反対面に作ってしまった。基板がOV7670とはミラーになってしまった。結果として、ヘッダに少しかかってしまったが、ヘッダには取り敢えず使わないので、そのまま行くことにした。失敗。。。
更に家に帰ってきて、テスターチェックしたら、最後の2本を間違えていたので、修正した。
下にOV7670とOV9655の変換基板に実装した状態での写真を示す。左がOV7670、右がOV9655だ。

次の写真は裏だ。

OV9655は18ピンなのだが、16ピンのコネクタしか無かった。それで、D1, D0は浮かせている。この下位ビットはRAWモードでしか使用しないので、無視することにした。Spartan-3A Starter Kit のJ2にもピンの余裕は無いので、仕方がない。(ピンクの四角で囲ってあるところが、浮いているD1, D0ピン)

次はSCCBの初期化データを作成して、取り敢えずVGAで動作させてみよう。
- 2011年01月09日 20:32 |
- OV9655
-
| トラックバック:0
-
| コメント:0
aitendoの
カメラモジュール(OV9655)[CAMERA130W-OV9655]を購入した。

OV9655は、SXGA(1280X1024) 15fps, VGA 30fpsのカメラだ。SXGAで使用してみたいが、最初はVGA 30fpsで使ってみようと思う。そうすれば、いままでの回路がそのまま使用できるはずだ。
取り敢えず、
Spartan-3A Starter Kitにカメラモジュールを接続するための変換基板を作る必要がある。OV7670と同じピン配置だったら、同じ変換基板が使えるんだけど、ピン配置は違っているし、それに18ピンなので、20ピンのピンソケットを買う必要があるかと思った、しかし、D0, D1はRAW RGBでのみ使用して、YUVやRGBモードでは、D9~D2のみ使用するということだった。よく見ると、D1, D0が端にあるので、この部分は浮かせた状態で使用して、16ピンソケットに入れようと思っている。
そうして使った場合の配線表を下に示す。

これで、OV7670の時とSpartan-3Aに対する配線は同じになる。つまり、今までの回路がそのまま使えるはず。ただし、初期化データは変更する必要がある。配線はFPGA-CAFEが始まったらハンダ付けをさせてもらうことにする。
今のところ、出力用のDACが4ビットの抵抗分割なので、これを8ビットのDVI出力にしたいと思っている。そうなると、Spartan-3A Starter Kitの拡張コネクタに刺さる基板を設計する必要があるな。。。
- 2011年01月04日 03:57 |
- OV9655
-
| トラックバック:0
-
| コメント:0