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 :

formatting link
(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

formatting link
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.

Reply to
may_2005
Loading thread 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.

Reply to
Ian Stirling

Depending on the data format that sounds about right.

As per other post, you probably have 565 format which gives grren dominance, of you are getting Y dominance in the data values.

So you are getting Y dominance in your data.

You driving something as open-collector/drain configuration for the port pin? If not you will NOT see acknowledge bits properly.

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?

...

As far as I know yes. I think you have a hardware problem, or not bit banging correctly.

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.

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.

...

Use another port pin toggled by your start/stop functions to trigger the scope.

You have got pull up resistors BOTH sides of your level translators?

You have measured the signals and timing relationships at the OV7640?

--
Paul Carpenter          | paul@pcserviceselectronics.co.uk
    PC Services
              GNU H8 & mailing list info
             For those web sites you hate
Reply to
Paul Carpenter

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 :

formatting link

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 :

formatting link
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.

Reply to
Paul Olley

Nothing obviously wrong with it, but I have not looked at the MOSFET spec.

You could always lower the pullup value from 4k7 to 1k to see faster rise times.

Not that I have come across as it is state/clock driven, you could run it at less than 1Hz.

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.

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
    PC Services
              GNU H8 & mailing list info
             For those web sites you hate
Reply to
Paul Carpenter

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.

Reply to
Paul Olley

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
Reply to
Tauno Voipio

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
    PC Services
              GNU H8 & mailing list info
             For those web sites you hate
Reply to
Paul Carpenter

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.

Reply to
Paul Olley

Well worth a look...

As I think we all suspected earlier.

Forgot to check that, glad you have the problem solved.

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

--
Paul Carpenter          | paul@pcserviceselectronics.co.uk
    PC Services
              GNU H8 & mailing list info
             For those web sites you hate
Reply to
Paul Carpenter

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.

Reply to
Paul Olley

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.