# [Connect Camera to Zedboard](https://www.instructables.com/Connect-Camera-to-Zybo-Board/) ### Development Environment + Board: Zynq-7000 Zedboard(xc7z020clg484-1) + Camera: OV7670 + IDE: Vivado 2023.1 --- ### Introduction + **OV7670** + Communication protocol: SCCB + Photosensitive Array: 640 x 480 (307200 pixels) + Output format: RawRGB, RGB(GRB 4:2:2, RGB565/555/444), YUV(4:2:2), and YCbCr(4:2:2) + pins: | Signal name | Input/Output | Description | | ----------- | ------------ | ------------------------------------- | | SIOC | input | SCCB serial interface clock | | SIOD | inout | SCCB serial interface data I/O | | VS | output | vertical sync | | HS | output | horizontal sync | | PLK | output | pixel clock | | XLK | input | system clock | | D7 | output | YUV/RGB video component output bit[7] | | D6 | output | YUV/RGB video component output bit[6] | | D5 | output | YUV/RGB video component output bit[5] | | D4 | output | YUV/RGB video component output bit[4] | | D3 | output | YUV/RGB video component output bit[3] | | D2 | output | YUV/RGB video component output bit[2] | | D1 | output | YUV/RGB video component output bit[1] | | D0 | output | YUV/RGB video component output bit[0] | | RET | input | reset | | PWDN | input | power down mode selection | + **<font color="#656898"> VHDL hierarchy**</font> _______ <font color="#82a1ba">**ov7670_top**</font> |_____________ <font color="#82a1ba">**clocking**</font> |_____________ <font color="#82a1ba">**debounce**</font> |_____________ <font color="#82a1ba">**ov7670_capture**</font> |_____________ <font color="#82a1ba">**vga**</font> |_____________ <font color="#82a1ba">**blk_mem_gen_0**</font> |_____________ <font color="#82a1ba">**ov7670_controller**</font> <font color="white"> _____________ </font> | _______ <font color="#aab8d6">**i2c_sender**</font> <font color="white"> _____________ </font> | _______ <font color="#aab8d6">**ov7670_registers**</font> + <font color="#82a1ba">**ov7670_top.vhd:**</font> + The top-level module for this project, which implements an image processing project with the OV7670 camera, displaying the results on a VGA monitor. + The button input is used for camera configuration, and the LED indicates the completion status of the configuration. + <font color="#82a1ba">**clocking.vhd:**</font> + It defines a clocking module using the Clocking Wizard IP core (clk_wiz_v3_6) to configure the Mixed-Mode Clock Manager (MMCM) clocking resources. + Generating multiple output clocks with specific frequencies and phases based on an input clock (CLK_100). + <font color="#82a1ba">**debounce.vhd:**</font> + Implementing a button debounce circuit to suppress mechanical vibrations and bouncing effects of the button, ensuring the stability of the output signal. + <font color="#82a1ba">**ov7670_capture.vhd:**</font> + Capturing pixels from the OV7670 camera and storing them in block RAM. + <font color="#82a1ba">**vga.vhd:**</font> + Generating VGA signals for a 640x480 display resolution using a frame buffer. + The timing of the signals is controlled by counters and constants, and synchronization signals are generated accordingly. + <font color="#82a1ba">**blk_mem_gen_0.vhd:**</font> + The instantiation and configuration of a Block Memory Generator module using Xilinx's provided Intellectual Property (IP) core. + <font color="#82a1ba">**ov7670_controller.vhd:**</font> + Sending commands to the OV7670 camera via the I2C bus, configuring various parameters of the camera to correctly capture image data. + <font color="#82a1ba">**i2c_sender.vhd:**</font> + Simulating an I2C-like interface used to send commands to the OV7670 camera. + With the counting of divider, it progressively generates changes in the I2C clock and data lines. + <font color="#82a1ba">**ov7670_registers.vhd:**</font> + Generating configuration commands that will be sent to the OV7670 camera. + Depending on the application, we need to customize these values to suit the requirements. --- ### Steps #### 1. Import VHDL Code > (1) Create a project and add VHDL fies > > ![image](https://hackmd.io/_uploads/HyJG6feEp.png) > > (2) Choose the board > > ![image](https://hackmd.io/_uploads/BJ456feVa.png) + VHDL files: + [ov7670_top.vhd](https://content.instructables.com/FZT/EBUM/ILV7T646/FZTEBUMILV7T646.vhd) + [clocking.vhd](https://content.instructables.com/FLW/9TWW/ILV7T64G/FLW9TWWILV7T64G.vhd) + [debounce.vhd](https://content.instructables.com/F5I/R32H/ILV7T64J/F5IR32HILV7T64J.vhd) + [ov7670_capture.vhd](https://content.instructables.com/F6S/JNRT/ILV7T642/F6SJNRTILV7T642.vhd) + [vga.vhd](https://content.instructables.com/FN0/FBA2/ILV7T649/FN0FBA2ILV7T649.vhd) + [ov7670_controller.vhd](https://content.instructables.com/F0U/U05J/ILV7T644/F0UU05JILV7T644.vhd) + [i2c_sender.vhd](https://content.instructables.com/FQT/SFQ5/ILV7T63Z/FQTSFQ5ILV7T63Z.vhd) + [ov7670_registers.vhd](https://content.instructables.com/FNT/SDZZ/ILV7T645/FNTSDZZILV7T645.vhd) --- #### 2. Add Block Memory + PROJECT MANAGER > IP Catalog > Search: Block Memory Generator ![image](https://hackmd.io/_uploads/BJZrz7gEa.png) ![image](https://hackmd.io/_uploads/SyiLG7x4T.png) ![image](https://hackmd.io/_uploads/rJvjG7lNp.png) + Then "blk_mem_gen_0.vhd" is automatically generated. --- #### 3. Add Constraints File + PROJECT MANAGER > Add sources Add or create constraints ![image](https://hackmd.io/_uploads/B1JKY7g4T.png) Create File ![image](https://hackmd.io/_uploads/SynctmeEa.png) + Then we can locate "zed_board.xdc" ubder Sources > Constraints > constrs_1, which is currently an empty file. ![image](https://hackmd.io/_uploads/rkJKc7eEp.png) + **zed_board.xdc** Copy these contents to "zed_board.xdc". ```tcl set_property PACKAGE_PIN Y9 [get_ports { clk100 } ] set_property PACKAGE_PIN Y21 [get_ports { vga_blue[0] } ] set_property PACKAGE_PIN Y20 [get_ports { vga_blue[1] } ] set_property PACKAGE_PIN AB20 [get_ports { vga_blue[2] } ] set_property PACKAGE_PIN AB19 [get_ports { vga_blue[3] } ] set_property PACKAGE_PIN AB22 [get_ports { vga_green[0] } ] set_property PACKAGE_PIN AA22 [get_ports { vga_green[1] } ] set_property PACKAGE_PIN AB21 [get_ports { vga_green[2] } ] set_property PACKAGE_PIN AA21 [get_ports { vga_green[3] } ] set_property PACKAGE_PIN V20 [get_ports { vga_red[0] } ] set_property PACKAGE_PIN U20 [get_ports { vga_red[1] } ] set_property PACKAGE_PIN V19 [get_ports { vga_red[2] } ] set_property PACKAGE_PIN V18 [get_ports { vga_red[3] } ] set_property PACKAGE_PIN AA19 [get_ports { vga_hsync } ] set_property PACKAGE_PIN Y19 [get_ports { vga_vsync } ] set_property PACKAGE_PIN Y11 [get_ports { OV7670_PWDN } ] set_property PACKAGE_PIN AB11 [get_ports { OV7670_RESET } ] set_property PACKAGE_PIN AA11 [get_ports { OV7670_D[0] } ] set_property PACKAGE_PIN AB10 [get_ports { OV7670_D[1] } ] set_property PACKAGE_PIN Y10 [get_ports { OV7670_D[2] } ] set_property PACKAGE_PIN AB9 [get_ports { OV7670_D[3] } ] set_property PACKAGE_PIN AA9 [get_ports { OV7670_D[4] } ] set_property PACKAGE_PIN AA8 [get_ports { OV7670_D[5] } ] set_property PACKAGE_PIN W12 [get_ports { OV7670_D[6] } ] set_property PACKAGE_PIN V12 [get_ports { OV7670_D[7] } ] set_property PACKAGE_PIN W11 [get_ports { OV7670_XCLK } ] set_property PACKAGE_PIN W10 [get_ports { OV7670_PCLK } ] set_property PACKAGE_PIN V10 [get_ports { OV7670_HREF } ] set_property PACKAGE_PIN V9 [get_ports { OV7670_VSYNC } ] set_property PACKAGE_PIN W8 [get_ports { OV7670_SIOD } ] set_property PACKAGE_PIN V8 [get_ports { OV7670_SIOC } ] set_property PACKAGE_PIN T22 [get_ports { LED[0] } ] set_property PACKAGE_PIN T21 [get_ports { LED[1] } ] set_property PACKAGE_PIN U22 [get_ports { LED[2] } ] set_property PACKAGE_PIN U21 [get_ports { LED[3] } ] set_property PACKAGE_PIN V22 [get_ports { LED[4] } ] set_property PACKAGE_PIN W22 [get_ports { LED[5] } ] set_property PACKAGE_PIN U19 [get_ports { LED[6] } ] set_property PACKAGE_PIN U14 [get_ports { LED[7] } ] set_property PACKAGE_PIN T18 [get_ports { btn } ] # Voltage levels set_property IOSTANDARD LVTTL [get_ports btn] set_property IOSTANDARD LVTTL [get_ports {LED[*]}] set_property IOSTANDARD LVTTL [get_ports OV7670_PCLK] set_property IOSTANDARD LVTTL [get_ports OV7670_SIOC] set_property IOSTANDARD LVTTL [get_ports OV7670_VSYNC] set_property IOSTANDARD LVTTL [get_ports OV7670_RESET] set_property IOSTANDARD LVTTL [get_ports OV7670_PWDN] set_property IOSTANDARD LVTTL [get_ports OV7670_HREF] set_property IOSTANDARD LVTTL [get_ports OV7670_XCLK] set_property IOSTANDARD LVTTL [get_ports OV7670_SIOD] set_property IOSTANDARD LVTTL [get_ports {OV7670_D[*] }] set_property IOSTANDARD LVCMOS33 [get_ports {vga_blue[*]}] set_property IOSTANDARD LVCMOS33 [get_ports {vga_green[*]}] set_property IOSTANDARD LVCMOS33 [get_ports {vga_red[*]}] set_property IOSTANDARD LVCMOS33 [get_ports vga_hsync] set_property IOSTANDARD LVCMOS33 [get_ports vga_vsync] set_property IOSTANDARD LVCMOS33 [get_ports clk100] # Magic set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets OV7670_PCLK_IBUF] ``` + We have to connect the pins according to this .xdc file. Also, we need to connect OV7760's 3.3V and DGND to the Zedboard. > + pins used on Zedboard > ![image](https://hackmd.io/_uploads/B1WkEbx4T.png) > > + OV7670 pins > ![image](https://hackmd.io/_uploads/BkKlh-gN6.png) > > + | Zedboard signal name | Zynq EPP pin | OV7760 signal name | > | -------------------- | ------------ | ------------------ | > | JA1 | Y11 | PWDN | > | JA7 | AB11 | RESET | > | JA2 | AA11 | D[0] | > | JA8 | AB10 | D[1] | > | JA3 | Y10 | D[2] | > | JA9 | AB9 | D[3] | > | JA4 | AA9 | D[4] | > | JA10 | AA8 | D[5] | > | JB1 | W12 | D[6] | > | JB7 | V12 | D[7] | > | JB2 | W11 | XCLK | > | JB8 | W10 | PCLK | > | JB3 | V10 | HREF | > | JB9 | V9 | VSYNC | > | JB4 | W8 | SIOD | > | JB10 | V8 | SIOC | --- #### 4. Generate Bitstream + PROJECT MANAGER > PROGRAM AND DEBUG > Generate Bitstream --- #### 5. Connect to Monitor and Program It + Connect Zedboard to a monitor through the VGA port + PROJECT MANAGER > Open Hardware Manager > Open Target > Auto Detect + An message bar may appear, press "Program device" and then program it. ![image](https://hackmd.io/_uploads/B1Z8ZEx46.png) --- #### 6. Result + Original: ![S__135610371](https://hackmd.io/_uploads/By9WKhx4a.jpg) + Result: ![S__135602180 (1)](https://hackmd.io/_uploads/HJMWq3eNa.jpg) --- #### 7. Conclusion + In this project, we set "RGB 565" mode as the image output format of the camera. However, it also supports many other modes. > + RGB 565 is a color encoding format that uses 16 bits (2 bits for red, 6 bits for green, and 5 bits for blue) to represent the color of a single pixel. > + The advantage of this format lies in its relatively efficient use of memory, as each pixel only requires 2 bytes (16 bits), while still providing reasonably good color representation. This is beneficial for applications with limited storage and transmission resources, such as embedded systems and mobile devices. > + It's important to note that while RGB 565 offers higher color depth, the sensitivity to detail in the green channel is higher due to the allocation of more bits. In contrast, the precision of the red and blue channels is relatively lower. + If we change the camera to output YUV and record only the Y component, it would store a greyscale version of the image and reduce the memory block width from 14 bits to 8 bits. Therefore, it could decrease resource utilization. > + YUV is a color encoding scheme that separates brightness (Y) and chrominance (U, V) components --- ### Related resources + [Zedboard Hardware User's Guide](https://digilent.com/reference/_media/zedboard:zedboard_ug.pdf) + [OV7670 Datasheet](https://content.instructables.com/F5N/MVN2/ILV7T7P5/F5NMVN2ILV7T7P5.pdf) + [OV7670 Implementation Guide](https://content.instructables.com/F1V/9NR7/ILV7T7Q6/F1V9NR7ILV7T7Q6.pdf) + [DCM / DLL / PLL / MMCM 區別](https://xilinx.eetrend.com/blog/2019/100046618.html) + [接口協議學習(三):SCCB(與 I2C 比較)](https://blog.csdn.net/qq_40483920/article/details/108207765) + [深入 AXI4匯流排(四):RAM 讀取實戰](https://www.getit01.com/p20181129546672113/) + [維基百科 - YUV](https://zh.wikipedia.org/zh-tw/YUV) + [維基百科 - YCbCr](https://zh.wikipedia.org/zh-tw/YCbCr) + [圖像處理 —— 傳感器原始圖像格式:Bayer RGB 和 RGB RAW](https://blog.csdn.net/u014470361/article/details/88800874) + [攝像頭基礎知識(二):Bayer、Raw 與 ISP](https://blog.csdn.net/wwws1994/article/details/126910855) + [MIPI CSI-2 筆記 (17) -- 數據格(RGB 圖像數據)](https://blog.csdn.net/vivo01/article/details/126781624)