Hi
I was involved in project a MIPI camera, and then I remember that the DECA does have a MIPI CSI-2 port on board and wanted to play a bit with a camera to FPGA
The DECA MIPI port does have an 30 pin connector and was original made for an AR0833 camera which you can't find anymore for the DECA layout.
So I have a IMX219 (RPI V2.1) Cam using a 15 pin FFC connector with 3V3 and I2C, enable, and the 1x CSI clk and 2 X CSI data lanes.
I did solder some thin wire on the diff pair DHPY term resistors (see schematic on page 15 of the DECA board) and the to to a small 15 pin FFC (made from a FFC to FFC connection board cut into half.
The I2C was just connect to the GPIO header as well as the GND and 3V3
Some search on the internet and I found a place where the I2C for 640x480 was used in a FPGA implementation
https://purisa.me/blog/mipi-camera-progress/I used the imx219.sv for the I2C
https://github.com/hdl-util/mipi-ccswhich basic does the the 640x480 driver part from the linux and it works fine on the DECA and the camera.
I also added in the camera.sv from
https://github.com/hdl-util/mipi-csi-2I did expect to get a "frame_start", "frame_end", "line_start", "line_end", "image_data_enable"
Those signal are not steady
So when measuring on the MIPI clk lane I see it's sending in bursts as well on the 2 data lanes.
My scope is a 200Mhz one, so the signal get very weak above 200Mhz.
In the datasheet for the IMX219 I can see what registers does and what the FPGA set it to.
The Camera is a a
Max. 30 frame/s in all-pixel scan mode
Pixel rate: 280 [Mpixel/s] (All-pixels mode)
180 frame/s @720p with 2x2 analog (special) binning, 60 frame/s @1080p with V-crop
Data rate: Max. 755 Mbps/lane(@4lane), 912Mbps/Lane(@2lane)
Total number of pixels : 3296 (H) × 2512 (V) approx. 8.28 M pixels
Number of effective pixels : 3296 (H) × 2480 (V) approx. 8.17 M pixels
Number of active pixels : 3280 (H) × 2464 (V) approx. 8.08 M pixels
The Cam module does have a local 24Mhz osc and the there is a few PLL in the cam to generate the right pixel clk and MIPI clk
There is a register 0x030d which set the "PLL Output System multiplier Value", if I lower that one to 0x20 I the get 128Mhz on the MIPI clk and clk get continues and I get frame start and end.
So my question:
If the camera does have a total area of 3280x2464=8M pixels/frame and only 640x480= 0.3Moixels/frame are set as Point Of Interest.
Can that be clocked out on the MIPI with a lower clk?
So when you have the first line of 640 will the 640 need to clocked by the speed of the 3280 or will it be possible to clk it slower.
I understand the it will require the the cam does hold 1 line of date, in the datasheet I see there is a FIFO in the cam but I cant see if it does only hold the active pixel of a line or not.
Cam data sheet says says 912Mbps/Lane(@2lane) and MAX10 data sheet the the LVDS mode on the MAX10 it says 800Mhz.
That's why I want to reduce the speed on the MIPI clk lane but still get the 640x480
Let me hear what you think?
{1'b0, 16'h0100, 8'h00}, // Stop Streaming
//--Access command sequence Seq. No. Address (Hex) data---
{1'b0, 16'h30eb, 8'h05}, // init seq
{1'b0, 16'h30eb, 8'h0c}, // init seq
{1'b0, 16'h300a, 8'hff}, // init seq
{1'b0, 16'h300b, 8'hff}, // init seq
{1'b0, 16'h30eb, 8'h05}, // init seq
{1'b0, 16'h30eb, 8'h09}, // init seq
//--Output Set-up Registers--
{1'b0, 16'h0114, 8'h01}, //CSI_lane_mode 0: Reserved, 1: 2-Lane, 2: Reserved, 3: 4-Lane
{1'b0, 16'h0128, 8'h00}, //DPHY_CTRL MIPI Global timing setting 0: auto mode, 1: manual mode
{1'b0, 16'h012a, 8'h18}, //EXCK_FREQ[15:8] RW INCK frequency [MHz] defauls 0x0C // 24 = 0x18
{1'b0, 16'h012b, 8'h00}, //EXCK_FREQ[7:0] RW INCK frequency [MHz]
{1'b0, 16'h0162, 8'h0d}, // LINE_LENGTH_A[15:8] 0x0d78 = 3.443 pixels
{1'b0, 16'h0163, 8'h78}, // LINE_LENGTH_A[7:0]
//----offset X-----------
{1'b0, 16'h0164, 8'h03}, // X_ADD_STA_A[11:8] x_addr_start 0x03e8 = 1.000
{1'b0, 16'h0165, 8'he8}, // X_ADD_STA_A[7:0]
{1'b0, 16'h0166, 8'h08}, // X_ADD_END_A[11:8] x _addr_end = 2.279
{1'b0, 16'h0167, 8'he7}, // X_ADD_END_A[7:0]
//----offset Y-----------
{1'b0, 16'h0168, 8'h02}, // Y_ADD_STA_A[11:8] y_addr_start 0x02F0= 752
{1'b0, 16'h0169, 8'hf0}, // Y_ADD_STA_A[7:0]
{1'b0, 16'h016a, 8'h06}, // Y_ADD_END_A[11:8] y_addr_end 0x06af = 1.711
{1'b0, 16'h016b, 8'haf}, // Y_ADD_END_A[7:0]
//----output size----------
{1'b0, 16'h016c, 8'h02}, // x_output_size[11:8] 0x0280 = 640
{1'b0, 16'h016d, 8'h80}, // x_output_size[7:0]
{1'b0, 16'h016e, 8'h01}, // y_output_size[11:8] 0x01e0 = 480
{1'b0, 16'h016f, 8'he0}, // y_output_size[7:0]
{1'b0, 16'h0170, 8'h01},
{1'b0, 16'h0171, 8'h01},
{1'b0, 16'h0174, 8'h03},
{1'b0, 16'h0175, 8'h03},
//---Clock Set-up----------
{1'b0, 16'h0301, 8'h05},
{1'b0, 16'h0303, 8'h01},
{1'b0, 16'h0304, 8'h03},
{1'b0, 16'h0305, 8'h03},
{1'b0, 16'h0306, 8'h00},
{1'b0, 16'h0307, 8'h39},
// {1'b0, 16'h0307, 8'h2b},
{1'b0, 16'h030b, 8'h01},
{1'b0, 16'h030c, 8'h00},
// {1'b0, 16'h030d, 8'h72},
{1'b0, 16'h030d, 8'h40},
// {1'b0, 16'h030d, 8'h10}, // 0x10=63Mhz ok , 0x20 =128Mhz ok, 0x40 = 256Mhz
//---Test Pattern Registers----
{1'b0, 16'h0624, 8'h06}, //1640
{1'b0, 16'h0625, 8'h68},
{1'b0, 16'h0626, 8'h04}, //1232
{1'b0, 16'h0627, 8'hd0},
{1'b0, 16'h455e, 8'h00},
{1'b0, 16'h471e, 8'h4b},
{1'b0, 16'h4767, 8'h0f},
{1'b0, 16'h4750, 8'h14},
{1'b0, 16'h4540, 8'h00},
{1'b0, 16'h47b4, 8'h14},
{1'b0, 16'h4713, 8'h30},
{1'b0, 16'h478b, 8'h10},
{1'b0, 16'h478f, 8'h10},
{1'b0, 16'h4793, 8'h10},
{1'b0, 16'h4797, 8'h0e},
{1'b0, 16'h479b, 8'h0e},
{1'b0, 16'h0100, 8'h01} // Start streaming