Shop OBEX P1 Docs P2 Docs Learn Events
SCCB Driver Help — Parallax Forums

SCCB Driver Help

mynet43mynet43 Posts: 644
edited 2012-03-02 13:57 in Propeller 1
I'm writing a driver to interface with an autofocus camera module. The OmniVision OV3640.

It has a serial interface for command I/O. At first I thought it was a standard i2c interface. But no.

It turns out they have their own serial interface. It's called the SCCB (Serial Camera Control Bus). Instead of an 8-bit interface, it has a 9-bit interface.

I was wondering if anyone has experience with this or has written a driver to support it.

I've attached a copy of the SCCB Spec Sheet.

Any help or suggestions will be greatly appreciated. I can write it, but I'd rather not re-invent the wheel.

Thank you for your help and support.

Jim

Comments

  • KyeKye Posts: 2,200
    edited 2012-03-02 11:47
    Its actually exactly the same as I2C except they say that the ACK bit is optional. But, most of their devices do send the ACK bit. They did that most likely because the I2C bus had to be licensed until recently. So they made a bus that is "similar" to I2C to avoid patent issues.
    PRI SCCBWriteRegister(register, data) ' Writes a camera register.
    
    ' Notes:
    '
    ' Register - The register number to write.
    ' Data - The value to write.
    '
    ' Returns true on success and false on failure.
    
      I2CStart
      result := I2CWrite(_SCCB_CAMERA_WRITE_ADDRESS) 
      result and= I2CWrite(register)
      result and= I2CWrite(data)  
      I2CStop
      
    PRI SCCBReadRegister(register, longDataAddress) ' Reads a camera register.
    
    ' Notes:
    '
    ' Register - The register number to read.
    ' LongDataAddress - The address of the value to store data to.
    '
    ' Returns true on success and false on failure.
    
      I2CStart
      result := I2CWrite(_SCCB_CAMERA_WRITE_ADDRESS)
      result and= I2CWrite(register)
      I2CStop
      if(result)
      
        I2CStart 
        result := I2CWrite(_SCCB_CAMERA_READ_ADDRESS)
        long[longDataAddress] := I2CRead(0)
        I2CStop
      
    PRI I2CWrite(data) ' Write out data.
    
    ' Notes:
    '
    ' Data - The 8 bit packet to transmit.
    '
    ' Returns true if the receiving device ACK'ed and false if not.
    
      data := ((!data) >< 8)
      
      repeat 8 ' Write out all 8 data bits. Leave with clock low.
      
        dira[_I2C_DATA_PIN] := data
        dira[_I2C_CLOCK_PIN] := 0
        dira[_I2C_CLOCK_PIN] := 1
        data >>= 1
    
      ' Leave with clock low and data low.
        
      dira[_I2C_DATA_PIN] := 0
      dira[_I2C_CLOCK_PIN] := 0
      result := not(ina[_I2C_DATA_PIN])
      dira[_I2C_CLOCK_PIN] := 1
      dira[_I2C_DATA_PIN] := 1
       
    PRI I2CRead(aknowledge) ' Read in data.
    
    ' Notes:
    '
    ' Aknowledge - True to send the transmitting device an ACK and false to not send a NCK.
    '
    ' Returns the received 8 bit packet. 
    
      dira[_I2C_DATA_PIN] := 0
      
      repeat 8 ' Read in all 8 data bits. Leave with clock low.
      
        result <<= 1
        dira[_I2C_CLOCK_PIN] := 0
        result |= ina[_I2C_DATA_PIN]
        dira[_I2C_CLOCK_PIN] := 1
    
      ' Leave with the clock low and the data low.
        
      dira[_I2C_DATA_PIN] := (not(not(aknowledge)))
      dira[_I2C_CLOCK_PIN] := 0
      dira[_I2C_CLOCK_PIN] := 1
      dira[_I2C_DATA_PIN] := 1
    
    PRI I2CStart ' Cause the I2C start condition.
    
      outa[_I2C_DATA_PIN] := 0
      dira[_I2C_DATA_PIN] := 1
      
      outa[_I2C_CLOCK_PIN] := 0
      dira[_I2C_CLOCK_PIN] := 1
    
    PRI I2CStop ' Cause the I2C stop condition.   
                                                                                              
      dira[_I2C_CLOCK_PIN] := 0
      dira[_I2C_DATA_PIN] := 0
    
    
  • mynet43mynet43 Posts: 644
    edited 2012-03-02 12:43
    Hi Kye,

    Thanks for getting back to me. I'm still coming up to speed on this camera, so I have a couple of questions:

    1. I looked over your code. It looks great. It seems to send an 8-bit i2c address byte, followed by an 8-bit register number, followed by 8-bits of data. The spec sheet for this camera seems to have 16-bit register addresses (see attached page). Do you know what's going on here? Should I change the code to send the two bytes of the register address? Or am I missing something.

    2. I ran the i2c register scan program by James Burrows from the OBEX. It has no trouble finding the serial EEPROM. But it doesn't see the camera read or write addresses at all. It's like the ACK status is never set. Do you have any thoughts on this?

    Thank you for your help.

    Jim
  • KyeKye Posts: 2,200
    edited 2012-03-02 13:42
    The first numbers are most likely the address of the device. So the 0x30 is the I2C address for writing. Maybe 0x31 is the read address? It should state these both clearly in the data sheet.

    The SCCB bus takes an 8 bit sub address only.

    ---

    Yes, its possible the device never ACKs. Use a bus pirate to check. If so, then remove the ACK checks that are in the code I gave you.
  • mynet43mynet43 Posts: 644
    edited 2012-03-02 13:57
    Hi Kye,

    The 16 bit addresses go from 0x3000 up to 0x3709 and everything in between. So I'm still not sure what's going on.

    I think I'll start by sending the last byte of the register address and ignoring the ACK to see what I get.

    Let me know if you think of something else.

    Thanks!

    Jim
Sign In or Register to comment.