Forums

Omnivision OV7640 SCCB (I2C?) bus problem

Started by Unknown May 24, 2005
Hello,

I am hoping someone can assist me with the SCCB (I2C?) bus of an
Omnivision OV7640 image sensor.

I am unable to get the OV7640 to respond to commands on the SCCB bus.

Preliminary :

I have connected the OV7640 to a SRAM, and feed VSYNC and HREF to an
Altera 7032S CPLD which controls and address counter and the SRAM.  I
can successfully capture an image frame, and transfer it (slowly) over
RS232 to a PC.

If I treat each pixel as a luminance value, I get a good monochrome
photograph, 640 x 480.

I find this surprising, since I was expecting bayer encoded data.

Looking at (on the data sheet) Register COMH, at Address HEX 28, the
default value is HEX 20, so that the device selected (bit 6) is a
colour OV7640, not a monochrome, OV7141.

COMA's default is HEX 14, making bit 3 =3D 0, so I would expect YUV/YCbCr
data out.

Since the datasheet I have is watermarked "preliminary" I want to read
back the register values in the OV7640 to see what the defaults are.

SCCB Problem :

I am not reading back valid data from the OV7640 on the SCCB bus.

My development board contains a PIC 18F8620, running at 20MHz, 5V power
supply.  I use the technique described on the following Philips website
to level shift between 5V and 3.3V :
http://www.semiconductors.philips.com/markets/mms/protocols/i2c/facts/
(the diagram just below the section titled : Level-shifting I=B2C)
The data rate of the SCCB clock is 100kHz

The data sequence is as follows : (an attempt to READ the contents of
register HEX 0A - the product ID, which according to the datashete
should be HEX 76)

START (of WRITE)
1 (address a7)
0 (address a6)
0 (address a5)
0 (address a4)
0 (address a3)
1 (address a2)
0 (address a1)
0 (R/!W) (=3Dwrite)
1 (acknowledge) (ie : apparently not acknowledged by OV7640)
0 (d7)
0 (d6)
0 (d5)
0 (d4)
1 (d3)
0 (d2)
1 (d1)
0 (d0)
1 (acknowledge) (ie : apparently not acknowledged by OV7640)
STOP

START (of READ)
1 (address a7)
0 (address a6)
0 (address a5)
0 (address a4)
0 (address a3)
1 (address a2)
1 (address a1)
1 (R/!W) (=3Dread)
1 (acknowledge) (ie : apparently not acknowledged by OV7640)
1 (d7)
1 (d6)
1 (d5)
1 (d4)
1 (d3)
1 (d2)
1 (d1)
1 (d0)
0 (acknowledge) (generated by PIC acting as I2C Master)
STOP

START and STOP refer to I2C conditions.

According to the datasheet, the address to use for writing to the
OV7640 is 42, and for read, 43.  It does not explicity say that this is
in HEX, but based on the rest of the datasheet and a remark I saw
somewhere else (can't recall where), I believe it to be HEX 42, HEX 43.

(1) My first question then is, am I correctly using HEX 42 in the first
part of the cycle and HEX 43 in the second?

(2) The Omnivision description of the SCCB
(http://www.ovt.com/pdfs/ds_note.pdf) states the following :

3=2E2.1.3 2-Phase Read Transmission Cycle
There must be either a 3-phase or a 2-phase write transmission cycle
asserted ahead of a 2-phase
read transmission cycle. The 2-phase read transmission cycle (see
Figure 3-7) has no ability to
identify the sub-address. The 2-phase write transmission cycle contains
read data of 8 bits and a
ninth Don't-Care bit or NA bit. The master must drive the NA bit at
logical 1.

I understand an acknowledge to mean taking the data line to ground.
However, this section of the datasheet suggests that in order to
acknowledge receipt of data from the OV7640 I need to send an
acknowledge of VCC.

Should I be sending 1 or 0 ?

(3) In the above document the following statement is made :

3=2E2.2.1 Phase 1 - ID Address

[snip]

The master asserts the ID address, but de-asserts the ninth bit
(Don't-Care bit). The master must
mask the input of SIO_D during the period of the Don't-Care bit and
force the input to 0 to avoid
propagating an unknown bus state.

This statement confuses me because, "de-asserting the ninth bit"
suggests to me that the data line should be released, but in the next
sentence it refers to forcing the input to 0.  Forcing the input to 0,
does not imply to me that the ninth bit is de-asserted.

By looking at all the rest of the information in the datasheet, I
conclude that for Don't care bits, the master should not assert a value
on the data line.

Is this interpretation correct?

(4) Other potential pitfalls :

Through not paying sufficient attention to the datasheet initially, I
have omitted the conflict protection resistor mentioned in section 4.3
of the datasheet.  There does not seem to be a value suggested for this
resistor.  No doubt I could estimate a value.

Lastly, my method for viewing the bus on my analogue (non storage
oscilloscope) is to continuously cycle the above write / read cycles.
The datasheet mentions the following parameter, which I do not appear
to be violating :

tBUF Bus free time before new START 1.3 =B5s

I have checked that the clock and data lines are soldered onto the
device, all seems OK from that point of view.

Any suggestions as to what I might be doing wrong would be very
welcome.

Many thanks,
Paul.

In sci.electronics.design may_2005@olley.com wrote:
> Hello, > > I am hoping someone can assist me with the SCCB (I2C?) bus of an > Omnivision OV7640 image sensor. > > I am unable to get the OV7640 to respond to commands on the SCCB bus. > > Preliminary : > > I have connected the OV7640 to a SRAM, and feed VSYNC and HREF to an > Altera 7032S CPLD which controls and address counter and the SRAM. I > can successfully capture an image frame, and transfer it (slowly) over > RS232 to a PC. > > If I treat each pixel as a luminance value, I get a good monochrome > photograph, 640 x 480. > > I find this surprising, since I was expecting bayer encoded data. >
Neglecting the rest of the post (sorry, can't answer it), bayer encoded data looks OK, unless you look really closely. For example, look at a very red object, and you'll see when you zoom in that only a quarter of the dots are lit. If you don't look closely, then it's broadly a greyscale image, dominated by the green in the original image.
On 24 May, in article
     <1116941245.739497.215050@g14g2000cwa.googlegroups.com>
     may_2005@olley.com wrote:
>Hello, > >I am hoping someone can assist me with the SCCB (I2C?) bus of an >Omnivision OV7640 image sensor. > >I am unable to get the OV7640 to respond to commands on the SCCB bus. > >Preliminary : > >I have connected the OV7640 to a SRAM, and feed VSYNC and HREF to an >Altera 7032S CPLD which controls and address counter and the SRAM. I >can successfully capture an image frame, and transfer it (slowly) over >RS232 to a PC. > >If I treat each pixel as a luminance value, I get a good monochrome >photograph, 640 x 480.
Depending on the data format that sounds about right.
>I find this surprising, since I was expecting bayer encoded data.
As per other post, you probably have 565 format which gives grren dominance, of you are getting Y dominance in the data values.
>Looking at (on the data sheet) Register COMH, at Address HEX 28, the >default value is HEX 20, so that the device selected (bit 6) is a >colour OV7640, not a monochrome, OV7141. > >COMA's default is HEX 14, making bit 3 = 0, so I would expect YUV/YCbCr >data out.
So you are getting Y dominance in your data.
>Since the datasheet I have is watermarked "preliminary" I want to read >back the register values in the OV7640 to see what the defaults are. > >SCCB Problem : > >I am not reading back valid data from the OV7640 on the SCCB bus. > >My development board contains a PIC 18F8620, running at 20MHz, 5V power >supply. I use the technique described on the following Philips website >to level shift between 5V and 3.3V : >http://www.semiconductors.philips.com/markets/mms/protocols/i2c/facts/ >(the diagram just below the section titled : Level-shifting I&#2013266098;C) >The data rate of the SCCB clock is 100kHz
You driving something as open-collector/drain configuration for the port pin? If not you will NOT see acknowledge bits properly.
>The data sequence is as follows : (an attempt to READ the contents of >register HEX 0A - the product ID, which according to the datashete >should be HEX 76) > >START (of WRITE) >1 (address a7) >0 (address a6) >0 (address a5) >0 (address a4) >0 (address a3) >1 (address a2) >0 (address a1) >0 (R/!W) (=write) >1 (acknowledge) (ie : apparently not acknowledged by OV7640)
You are letting the output of the port pin FLOAT, and an external pullup resistor pull the value to rail, then READING the bit setting to determine if the slave device has pulled down the SDA line to give you a proper ACK. When you have no acknowledge at this point you have not addressed the device correctly or actually got your signal to the sensor. With a scope measure the signals at the OV7640 pins, if necessary set another port pin high at start of I2C bit banging to trigger the scope on stop conditions and low on stop conditions. Anything beyond this point is pointless until your address is acknowledged correctly as I doubt you are properly allowing the ACK bit to get back to the PIC through your level translators. You are sure that your level translators used are BI-directional? ...
>(1) My first question then is, am I correctly using HEX 42 in the first >part of the cycle and HEX 43 in the second?
As far as I know yes. I think you have a hardware problem, or not bit banging correctly.
>(2) The Omnivision description of the SCCB >(http://www.ovt.com/pdfs/ds_note.pdf) states the following : > >3.2.1.3 2-Phase Read Transmission Cycle >There must be either a 3-phase or a 2-phase write transmission cycle >asserted ahead of a 2-phase >read transmission cycle. The 2-phase read transmission cycle (see >Figure 3-7) has no ability to >identify the sub-address. The 2-phase write transmission cycle contains >read data of 8 bits and a >ninth Don't-Care bit or NA bit. The master must drive the NA bit at >logical 1. > >I understand an acknowledge to mean taking the data line to ground. >However, this section of the datasheet suggests that in order to >acknowledge receipt of data from the OV7640 I need to send an >acknowledge of VCC.
You need to let an open collector/drain output turn OFF to allow the line to be pulled up by an EXTERNAL resistor to all the slave device to drive the line low, which you then READ in the Master device.
>Should I be sending 1 or 0 ? > >(3) In the above document the following statement is made : > >3.2.2.1 Phase 1 - ID Address > >[snip] > >The master asserts the ID address, but de-asserts the ninth bit >(Don't-Care bit). The master must >mask the input of SIO_D during the period of the Don't-Care bit and >force the input to 0 to avoid >propagating an unknown bus state. > >This statement confuses me because, "de-asserting the ninth bit" >suggests to me that the data line should be released, but in the next >sentence it refers to forcing the input to 0. Forcing the input to 0, >does not imply to me that the ninth bit is de-asserted.
The MASTER deasserts (floats) the line, to be pulled up by external resistor, the slave (OV7640) drives the line low, the MASTER (PIC etc) READS the line to see if pulled low. ...
>(4) Other potential pitfalls : > >Through not paying sufficient attention to the datasheet initially, I >have omitted the conflict protection resistor mentioned in section 4.3 >of the datasheet. There does not seem to be a value suggested for this >resistor. No doubt I could estimate a value. > >Lastly, my method for viewing the bus on my analogue (non storage >oscilloscope) is to continuously cycle the above write / read cycles. >The datasheet mentions the following parameter, which I do not appear >to be violating :
Use another port pin toggled by your start/stop functions to trigger the scope.
>tBUF Bus free time before new START 1.3 &#2013266101;s > >I have checked that the clock and data lines are soldered onto the >device, all seems OK from that point of view.
You have got pull up resistors BOTH sides of your level translators? You have measured the signals and timing relationships at the OV7640?
>Any suggestions as to what I might be doing wrong would be very >welcome. > >Many thanks, >Paul. > >
-- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
Hello Ian & Paul,

Many thanks for your input on the data I'm seeing coming out of the
sensor.  I will work on this once I've got the I2C going.

I expect I can set the registers such that I get RGB data out, which is
then easy for me to manipulate.

Turning to Paul's response :

I am using the PIC's I2C port on Pins RC4 (data) and RC3 (clock), in an
open-collector configuration with pull-up resistors (as part of the
level translation).

The level translation circuit is bi-directional.  Maxim has a detailed
description of this circuit and how it works here :
http://www.maxim-ic.com/appnotes.cfm/appnote_number/1159

However, I will check with the BSN20 MOSFET's I've used, whether the
voltage levels (resulting from level shifting) are within the tolerance
of both the PIC and OV7640.

I've put an extract of my circuit on the web here :
http://homepage.ntlworld.com/paul.olley/ in case you want to see
exactly what I've drawn.

Certainly, when I looked at the waveforms on the copper track connected
directly to the OV7640, qualitiatively they looked like the waveforms
on the PIC side, just with a lower amplitude.  Your comments have
triggered another possibility in my mind.  The slew rate of the level
translation may be a factor.  I will look in more detail at that as
well.

Is there a MINIMUM speed one can run I2C at?  ie: If I ran the I2C
clock at 10kHz, should it work?  This would allow me to negate the
effect of the rise time of the level shifter.

Regarding cycling the read/write repetitively, I was wonderfing if the
OV7640 could "keep up".  For example, I know with I2C EEPROMs, the time
taken to write a byte is significant relative to the maximum speed of
an I2C bus, and therefore, the master has to "poll" the EEPROM until it
gets an acknowledge.  I was wondering if a similar situation held true
for the OV7640. (I wouldn't have thought it would on a read cycle)

I will start by looking in more detail at the voltage levels on both
sides of the translator.  Then I will write code that controls the
clock and data pins directly, rather than using the PIC's internal I2C
registers, and see where that gets me.

Paul.

On 25 May, in article
     <1117023565.189087.189460@f14g2000cwb.googlegroups.com>
     may_2005@olley.com "Paul Olley" wrote:

>Hello Ian & Paul, > >Many thanks for your input on the data I'm seeing coming out of the >sensor. I will work on this once I've got the I2C going. > >I expect I can set the registers such that I get RGB data out, which is >then easy for me to manipulate. > >Turning to Paul's response : > >I am using the PIC's I2C port on Pins RC4 (data) and RC3 (clock), in an >open-collector configuration with pull-up resistors (as part of the >level translation). > >The level translation circuit is bi-directional. Maxim has a detailed >description of this circuit and how it works here : >http://www.maxim-ic.com/appnotes.cfm/appnote_number/1159 > >However, I will check with the BSN20 MOSFET's I've used, whether the >voltage levels (resulting from level shifting) are within the tolerance >of both the PIC and OV7640. > >I've put an extract of my circuit on the web here : >http://homepage.ntlworld.com/paul.olley/ in case you want to see >exactly what I've drawn.
Nothing obviously wrong with it, but I have not looked at the MOSFET spec.
>Certainly, when I looked at the waveforms on the copper track connected >directly to the OV7640, qualitiatively they looked like the waveforms >on the PIC side, just with a lower amplitude. Your comments have >triggered another possibility in my mind. The slew rate of the level >translation may be a factor. I will look in more detail at that as >well.
You could always lower the pullup value from 4k7 to 1k to see faster rise times.
>Is there a MINIMUM speed one can run I2C at? ie: If I ran the I2C >clock at 10kHz, should it work? This would allow me to negate the >effect of the rise time of the level shifter.
Not that I have come across as it is state/clock driven, you could run it at less than 1Hz.
>Regarding cycling the read/write repetitively, I was wonderfing if the >OV7640 could "keep up". For example, I know with I2C EEPROMs, the time >taken to write a byte is significant relative to the maximum speed of >an I2C bus, and therefore, the master has to "poll" the EEPROM until it >gets an acknowledge. I was wondering if a similar situation held true >for the OV7640. (I wouldn't have thought it would on a read cycle)
Firstly never send the I2C stop until the whole read and write transaction (address, data,....) has completed. Otherwise you abort transactions and the next data read/write would be considered as an address sequence. Secondly EEPROMs take a long time to write internally and I am sure you don't have to wait a long time for an acknowledge to the address as that should be next 'clock' cycle. Thirdly I have not seen any Omnivision chips that could not handle I2C as normal, no long wait times as it is writing to and reading from registers, not special memory.
>I will start by looking in more detail at the voltage levels on both >sides of the translator. Then I will write code that controls the >clock and data pins directly, rather than using the PIC's internal I2C >registers, and see where that gets me.
Try - 1/ Lower the pullup resistor values I often use 1k to 2k7 2/ Slowing the speed down of I2C to 10KHz 3/ Check the code at the address acknowledge time to ensure it is actually addressing the device. 4/ After a set of tests ensure you RESET the camera to ensure you have not locked I2C interface into a strange stop and set I2C to STOP then IDLE state. 5/ Then think about you own code for controlling I2C directly. -- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
Hello Paul,

Very many thanks for your reply and advice.

Working slightly backwards in your order of suggestions, I finished
writing the code to drive the I2C directly around 11PM last night and
found a couple of errors in it this morning.

The most glaring problem on testing it was that I was unable to get SDA
to go low ; not wanting to desolder the SMD components I set up a PIC
on a breadboard and have recreated the problem.  I must have a mistake
where I set up the port for I/O.  My breadboard was simply a PIC18F448
with two resistors connected to RC3 and RC4, so my problem must be
software.

Thank you for your suggestion about resetting the OV7640 after each
test ; I haven't been doing that ; I will incorporate that into the
code.

Paul.

Paul Olley wrote:
> Hello Paul, > > Very many thanks for your reply and advice. > > Working slightly backwards in your order of suggestions, I finished > writing the code to drive the I2C directly around 11PM last night and > found a couple of errors in it this morning. > > The most glaring problem on testing it was that I was unable to get SDA > to go low ; not wanting to desolder the SMD components I set up a PIC > on a breadboard and have recreated the problem. I must have a mistake > where I set up the port for I/O. My breadboard was simply a PIC18F448 > with two resistors connected to RC3 and RC4, so my problem must be > software. > > Thank you for your suggestion about resetting the OV7640 after each > test ; I haven't been doing that ; I will incorporate that into the > code. > > Paul. >
Please note that you cannot write ones to the I2C bus, you have to disable the output instead to get a passive one, like an open-drain output. -- Tauno Voipio tauno voipio (at) iki fi
On Thursday, in article <Urmle.230$d13.177@read3.inet.fi>
     tauno.voipio@iki.fi.NOSPAM.invalid "Tauno Voipio" wrote:

>Paul Olley wrote: >> Hello Paul, >> >> Very many thanks for your reply and advice. >> >> Working slightly backwards in your order of suggestions, I finished >> writing the code to drive the I2C directly around 11PM last night and >> found a couple of errors in it this morning. >> >> The most glaring problem on testing it was that I was unable to get SDA >> to go low ; not wanting to desolder the SMD components I set up a PIC >> on a breadboard and have recreated the problem. I must have a mistake >> where I set up the port for I/O. My breadboard was simply a PIC18F448 >> with two resistors connected to RC3 and RC4, so my problem must be >> software. >> >> Thank you for your suggestion about resetting the OV7640 after each >> test ; I haven't been doing that ; I will incorporate that into the >> code. >> >> Paul. >> > >Please note that you cannot write ones to the I2C bus, you have to >disable the output instead to get a passive one, like an open-drain >output.
CHECK THE HIGH THTRESHOLDS FOR THE PIC I2C PORT PIN INPUTS BEFORE DOING THIS. ====== Which reminds me if the ONLY thing on your I2C bus is the OV7640 and the PIC thresholds allow for 3V levels on the I2C bus, drive the I2C with 1k pullups to 3V and NO level translators IF THE OUTPUTS CAN BE GUARANTEED TO ALWAYS BE OPEN-DRAIN (especially during reset). With a low pull-up value you will have fast slew rates and minimal components. You could always put clamping diodes on the lines to protect the OV7640 by ensuring the pins do not drive more than 3V3 out from the PIC. -- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
Hi 

I'm happy I'm not the only one in the world to have proble
configuring these cameras...

I'm using a OV7141, so the same camera but B&W. I'm configurin
the camera with a PIC core intergrated on a SPARTAN IIE FPGA. I hav
2 1k resistors on SDA/SCL, I checked the signals and timings sent b
the FPGA to the camera and they are exactly like the ones on th
Omnivision datasheet 

I supplied the camera with 2,5V as it is indicated in the datashee
(and not 3V3 which is too high for some input voltages) and the FPG
is 3V3

The only difference I notice from I2C is that the camera "may not
answer to the ack(called don't care bit) ! And it doesn't wih what 
can observe on my scope

In the datasheet 

"The Don&#2013266066;t-Care bit is the 9th bit of a master-issue
transmission; ID address, sub-address and write data. The master wil
continue to assert transmission phases until the transmission cycle i
complete. The master also assumes that there is no transmission erro
during data transmissions. The purpose of the Don&#2013266066;t-Care 9th bit i
to indicate the completion of the transmission
When there is more than one slave on the bus, the slave(s) may respon
to the Don&#2013266066;t-Care bit in one of two ways. If slave 1 is selected an
data is written to this specific slave, slave 1 will drive SIO_D t
logical 0 for the Don&#2013266066;t-Care bit. In this case, the SIO_D signal ma
conflict at the beginning of the Don&#2013266066;t-Care bit, while it may b
floating at the end of the Don&#2013266066;t-Care bit
Alternately, it is possible that the slave(s) do not respond to th
Don&#2013266066;t-Care bit of the current phase. In this situation, the SIO_D bu
remains at float for the whole Don&#2013266066;t-Care bit."


If someone managed to configure a Omnivision camera yet, it woul
really help me a lot 

Thanks 

Thank you for the additional suggestions.

I'm sorry if I wasn't clear in my description.  I was releasing the
tri-state to form a passive "1" rather than driving the output high.

Turns out that for a PIC18F8620 V Input High = 0.7Vdd for RC3 and RC4
That equals 3.5V and since the OV7640 has its IO fed at 3.3V, clearly a
simple resistor configration fails.  Pity, it was a simple solution
with the clamping diodes.  Still the BSN20 devices are not very
expensive.

So, many code trials later, bit-banging problem fixed, and my problem
is solved.

I wasn't getting an acknowledge from the OV7640 because I was not
addressing it correctly.

The datasheet states : "The device slave addresses for the
OV7640/OV7141 are 42 for write and 43 for read."

I took this to mean that the address was 01000010

So when addressing the device, one needed to send 10000100

(Shift the bits one to the left, and set the LSB to 0 to indicate a
read.)

However, it appears the datasheet means that the bit sequence one uses
for the addressing byte is 01000010, the LSB being 0 indicating a
write.

For a read, the bit sequence is 01000011 this time the LSB is 1
indicating a read.

I have read out some of the read only register locations, obtaining the
default values specified in the datasheet.

I will soon return to working on the image data which will no doubt
throw up some more questions.

Paul.