VHDL Light Source Detection : OV7670 Camera Control(register) and Pixel Capture

by wilsonwardhana.w in Circuits > Cameras

1917 Views, 3 Favorites, 0 Comments

VHDL Light Source Detection : OV7670 Camera Control(register) and Pixel Capture

title.PNG
block d.PNG
pixel capt.PNG

NOTE: This page is one part of a larger build. Please ensure you start HERE, so you understand where the following fits in within the larger project.

Camera control is the part which controls the camera's setting. When the device is turned on the first thing the board does is set up the camera. How the camera is set up depends on how the register is made.

Pixel control is the part where pixel data is received to then relay to other parts of the system.

Camera Control can be divided into 5 parts, the Controller, Counter, Shift-register(shifter), Flip-Flop, and The register itself.

Everything will then be combined and connected by the board using the code from the TopLevel.

Note :

  • Left block diagram = Camera Control

  • Right block diagram = Pixel capture

Registers

reg.PNG
register.PNG

The register is where you list all the command you want to give to the camera. To know which is which and what to change, refer to your camera datasheet.

Here we used an Ov7670 camera so we will refer to the ov7670 datasheet.

In the code example " when x"06" => sreg <= x"8C00"; -- RGB444 Set RGB format,disabled."

8C refers to the hex address while 00 is the hexadecimal of the setting we want to set.

The format used was YCbCr thus this setting will be disabled.

The default Hex is actually 00 so this line of code is actually unnecessary.

Register code : Registers.vhd

The purpose of the code is to provide which address and data to send to the camera. When one setting(sreg) is done, the controller will send an advance signal will be sent to signal the register to go to the next setting.

Controller

controller.PNG
diagram.PNG

The controller is the part which continuously gives out instruction to other parts depending on which state it is in right now.

In this example, we used the case function to create a state machine.

The controller will keep on repeating the "shift", "Set_sioc" , and "Reset_sioc" state until the stop condition is received.

when there is a stop_it will then advance to the next state "stop and stop2"

Controller code : Controller.vhd

Counter

counter.PNG

This part determines whether all bits have been transferred and when it has, it will generate the stop condition to signal the controller that the current cycle is done.

Counter Code : Counter.vhd

Downloads

Shift Register

shift.PNG
shift reg.PNG

The shift register shifts data from MSB (27) to LSB(0) and adds '1' at the LSB when Shift enable is 1 and Loads the parallel 27 bit into the shift register when Load enable is 1. The "1" added at the end is to ensure that when we want to generate the stop condition, the last bit is always 1.

The data being shifted here is the SIOD, which is going to be sent to the camera, which consisted of '0' + camera address(8 bit) + '1' + Command(first 8 bit) + '1' + Command(last 8 bit) + '0'.

Shift register : ShiftRegister.Vhd

Start and Stop Condition

stopcond.PNG

The camera recognize a specific and unique set of Sioc and Siod as the start and stop condition. To signal to the camera that it is the start of a cycle, the Siod needs to be set from high to low (1 to 0) while the Sioc is still high(1). Similarly, to signal that it is the end of a cycle, the Siod needs to be set from low to high(0 to 1) while the Sioc is high(1). This will normally never occur in the cycle as the Siod is always changed when the Sioc is low.

In the Top level code, the Most Significant Bit(MSB) is set to 0 so that when the first bit is shifted while the sioc is still high during the start1 state of the controller, the start condition is triggered.

Likewise, in the shift register code, the Least Signifcant Bit(LSB) is always set to 1 and from the top level code the second to last LSB is set to 0 so that when the bit is shifted during the stop 2 the stop condition is triggered.

Flip-Flop

flipflop.PNG

This part is straight-forward. When set enable is 1, it will set SIOC to 1, and when reset enable is 1 , it will set SIOC to 0. Make sure Set enable and Reset enable is not 1 at the same time.

flipflop code : flipflop.vhd

Ov7670 Camera

ov7670 cam.jpg
resistor.PNG

The Module contain 18 pins. Sda is usually referred as Siod and Scl is referred as Sioc.

Camera Input pins :

  • Sioc
  • Siod
  • Pwdn
  • Mclk
  • Reset

Camera output pins:

  • D0-d7
  • Href
  • Vsync
  • Pixel clock

When connecting the camera to the board, it is important to add a pull up resistor connecting Sioc and Siod to vcc. The resistor value can be calculated as shown on the picture.

Pixel Capture

timing.png
pixel capt.PNG

After the camera is fully set up, it can begin taking pictures and sending the data to the pixel capture part.

Pixel capture only receives data when Vsync is low and Href is high.

In this example we are using the YCbCr/YUV(chroma Sampling) 4:2:2 which means that the pixel is divided into 3 parts. The Y or Luminanance, Cb, and Cr. Cb and Cr together makes up the chrominance or colour part while Y makes up the brightness/grayscale part of the pixel. The camera sends the value of Y, Cb, and Cr in this order :

First byte (Cb1) -> Second byte(Y1) -> Third byte(Cr1) -> Fourth byte (Y2) -> Fifth byte (Cb3) -> Sixth byte(Y3) and so on.

Note that the number on the right represents which pixel each value corresponds to ( Y1 belongs to pixel 1, Y2 belongs to pixel 2) and each Y value corresponds to each pixel but the value of Cb and Cr is shared among 2 pixels (Pixel 1 and 2 both uses the Cb1 and Cr1 value).

The byte which contains the Y part of the YCbCr is the even numbered byte. Thus we will only be taking the data once every 2 bytes. To get the data every 2 bytes all we need to do is make a clock that has half the frequency.

if rising_edge(pclk) then
Q <= not Q;

In the sample code we made a clock Q that switches bits everytime the clock turns to 1.

Pixel Capture Code: Capture.vhd

Top Level

Capture.PNG
portmap.PNG
signal.PNG

When all the components are done, it is time to connect everything into one top level vhd file.

The top level is the part of the code which binds everything together. It refers to other part of the code as its Component and it connects the entities between those components. To connect the entities you need to declare the Portmap.

NOTE: To connect an IN type entity with an OUT type entity, you need to add an internal Signal as some sort of bridge.

The 28 bit data being sent to the camera labeled Data_In is a combination of bit with the following formula :

Data_In (27 down to 0) is equal to '0' + Camera address(8 bit) + '1' + Command(15 down to 8) + '1' + Command(7 down to 0) + '0'.

TopLevel code : Toplevel.vhd

Contributor

Untitled-3.jpg
(Left to right)
  • Beryl Steward
  • Christian Bennett
  • Muhammad Shafaa U D
  • Wilson Wardhana
  • Winary Wira Theo