Maker Pro
Maker Pro

Omnivision OV7640 SCCB (I2C?) bus problem

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 = 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²C)
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) (=write)
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) (=read)
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.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.

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.

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 µs

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.
 
I

Ian Stirling

Jan 1, 1970
0
In said:
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.
 
P

Paul Carpenter

Jan 1, 1970
0
On 24 May, in article
<[email protected]>
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²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 µ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?
 
P

Paul Olley

Jan 1, 1970
0
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.
 
P

Paul Carpenter

Jan 1, 1970
0
On 25 May, in article
<[email protected]>
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.
 
P

Paul Olley

Jan 1, 1970
0
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.
 
T

Tauno Voipio

Jan 1, 1970
0
Paul said:
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.
 
P

Paul Carpenter

Jan 1, 1970
0
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.[/QUOTE]

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.
 
P

Paul Olley

Jan 1, 1970
0
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.
 
P

Paul Carpenter

Jan 1, 1970
0
On 27 May, in article
<[email protected]>
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.

Well worth a look...
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.

As I think we all suspected earlier.
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.

Forgot to check that, glad you have the problem solved.
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.

Well at least you are progressing in the right direction. Good to hear
things are starting to work.
 
P

Paul Olley

Jan 1, 1970
0
Hello Paul and Vinch,

Just to clarify, the bit sequence I used to address the OV7640 was

READ 01000010x (0x42)

WRITE 01000011x (0x43)

ie : I didn't shift the bits one to the left. I really believed given
the way the information was presented in the datasheet that I needed to
shift the bits one to the left, but empirically I found this not to be
the case.

Paul.
 

Similar threads

Top