Fork of Edoardo De Marchi's ov7670 library. Works very similar, only few modification were made to support other boards.

Dependents:   OV7670 application over USB with KL25Z

Fork of ov7670 by Edoardo De Marchi

Revision:
0:810d59d0b843
Child:
1:d82dbad9c06b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ov7670.cpp	Sun Mar 10 13:01:45 2013 +0000
@@ -0,0 +1,224 @@
+#include "ov7670.h"   
+
+    
+OV7670::OV7670(PinName sda, PinName scl, PinName vs, PinName hr, PinName we, PortName port, int mask, PinName rt, PinName o, PinName rc) : _i2c(sda,scl),vsync(vs),href(hr),wen(we),data(port,mask),rrst(rt),oe(o),rclk(rc)
+{
+        _i2c.stop();
+        _i2c.frequency(OV7670_I2CFREQ);
+        vsync.fall(this,&OV7670::VsyncHandler);     // interrupt fall edge
+        href.rise(this,&OV7670::HrefHandler);       // interrupt rise edge
+        CaptureReq = false;
+        Busy = false;
+        Done = false;
+        LineCounter = 0;
+        rrst = 1;
+        oe = 1;
+        rclk = 1;
+        wen = 0;
+}
+
+OV7670::~OV7670()
+{
+
+}
+
+// capture request
+void OV7670::CaptureNext(void)
+{
+    CaptureReq = true ;
+    Busy = true ;
+}
+
+// capture done? (with clear)
+bool OV7670::CaptureDone(void)
+{
+    bool result ;
+    if (Busy) {
+        result = false ;
+    } else {
+        result = Done ;
+        Done = false ;
+    }
+    return result ;
+}
+
+// write to camera
+void OV7670::WriteReg(int addr,int data)
+{
+    _i2c.start() ;
+    _i2c.write(OV7670_WRITE) ;
+    wait_us(OV7670_WRITEWAIT);
+    _i2c.write(addr) ;
+    wait_us(OV7670_WRITEWAIT);
+    _i2c.write(data) ;
+    _i2c.stop() ;
+}
+
+// read from camera
+int OV7670::ReadReg(int addr)
+{
+    int data ;
+    
+    _i2c.start() ;
+    _i2c.write(OV7670_WRITE) ;
+    wait_us(OV7670_WRITEWAIT);
+    _i2c.write(addr) ;
+    _i2c.stop() ;
+    wait_us(OV7670_WRITEWAIT);    
+
+    _i2c.start() ;
+    _i2c.write(OV7670_READ) ;
+    wait_us(OV7670_WRITEWAIT);
+    data = _i2c.read(OV7670_NOACK) ;
+    _i2c.stop() ;
+
+    return data ;
+}
+
+void OV7670::Reset(void) {    
+    WriteReg(0x12,0x80) ;       // RESET CAMERA
+    wait_ms(200) ;
+}
+
+int OV7670::Init(char c) 
+{
+    
+    if (ReadReg(REG_PID) != 0x76)       // check id camera
+    {
+        return 0;
+    }
+    
+    Reset();                        // Resets all registers to default values
+ 
+    WriteReg(REG_CLKRC,0x80);
+    WriteReg(REG_COM11,0x0A) ;
+    WriteReg(REG_TSLB,0x04);        // 0D = UYVY  04 = YUYV     
+    WriteReg(REG_COM13,0x88);       // connect to REG_TSLB
+    
+    //WriteReg(REG_COM7,0x01) ;     // output format: raw
+    WriteReg(REG_RGB444, 0x00);     // Disable RGB444    
+    WriteReg(REG_HSTART,0x16) ;
+    WriteReg(REG_HSTOP,0x04) ;
+    WriteReg(REG_HREF,0x24) ;
+    WriteReg(REG_VSTART,0x02) ;
+    WriteReg(REG_VSTOP,0x7a) ;
+    WriteReg(REG_VREF,0x0a) ;
+    WriteReg(REG_COM10,0x02) ;          // 0x02   VSYNC negative (http://nasulica.homelinux.org/?p=959)
+    WriteReg(REG_MVFP,0x27) ;
+  
+        if(c == 'y')
+        {
+            WriteReg(REG_COM7,0x00);            // YUV
+            WriteReg(REG_COM17,0x00);           // color bar disable
+            WriteReg(REG_COM3, 0x04);
+            WriteReg(REG_COM14, 0x1a);          // by 4
+            WriteReg(REG_COM15, 0xC0);          // Set normal rgb
+            WriteReg(0x70, 0x3A);
+            WriteReg(0x71, 0x35);
+            WriteReg(0x72, 0x22);
+            WriteReg(0x73, 0xf2);
+            WriteReg(0xA2, 0x02);
+        }else{                                  // RGB565
+            WriteReg(REG_COM7,0x04);            // RGB + color bar disable 
+            WriteReg(REG_RGB444, 0x00);         // Disable RGB444
+            WriteReg(REG_COM15, 0xD0);          // Set rgb565 0xD0 or rgb555 0xD8 
+            WriteReg(REG_COM3, 0x04);
+            WriteReg(REG_COM14, 0x1a);          // by 4
+            WriteReg(0x70, 0x3A);
+            WriteReg(0x71, 0x35);
+            WriteReg(0x72, 0x22);
+            WriteReg(0x73, 0xf2);
+            WriteReg(0xA2, 0x02);
+        }
+         
+    // COLOR SETTING
+    
+    WriteReg(REG_COM8,0x8F);        // AGC AWB AEC Enab
+    WriteReg(REG_BRIGHT,0x00);      // 0x00(Brightness 0) - 0x18(Brightness +1) - 0x98(Brightness -1)
+
+    WriteReg(MTX1,0x80);
+    WriteReg(MTX2,0x80);
+    WriteReg(MTX3,0x00);
+    WriteReg(MTX4,0x22);
+    WriteReg(MTX5,0x5e);
+    WriteReg(MTX6,0x80);
+    WriteReg(REG_CONTRAS,0x40);     // 0x40(Contrast 0) - 0x50(Contrast +1) - 0x38(Contrast -1)
+    WriteReg(MTXS,0x9e);
+    WriteReg(AWBC7,0x88);
+    WriteReg(AWBC8,0x88);
+    WriteReg(AWBC9,0x44);
+    WriteReg(AWBC10,0x67);
+    WriteReg(AWBC11,0x49);
+    WriteReg(AWBC12,0x0e);
+    WriteReg(REG_GFIX,0x00);
+    WriteReg(GGAIN,0x40);
+    WriteReg(DBLV,0x0a);
+    WriteReg(AWBCTR3,0x0a);
+    WriteReg(AWBCTR2,0x55);
+    WriteReg(AWBCTR1,0x11);
+    WriteReg(AWBCTR0,0x9f);
+
+    WriteReg(0xb0,0x84);
+    
+    return 1;
+}    
+
+// vsync handler
+void OV7670::VsyncHandler(void)
+{
+    
+    // Capture Enable
+    if (CaptureReq) {
+        wen = 1 ;
+        Done = false ;
+        CaptureReq = false ;
+    } else {
+        wen = 0 ;
+        if (Busy) {
+            Busy = false ;
+            Done = true ;
+        }
+    }
+    
+    // Hline Counter
+    LastLines = LineCounter ;
+    LineCounter = 0 ;
+}
+
+// href handler
+void OV7670::HrefHandler(void)
+{
+    LineCounter++ ;
+}
+
+// Data Read
+int OV7670::ReadOnebyte(void)
+{
+        int B1;
+        rclk = 1;
+        B1 = (((data&0x07800000)>>19)|((data&0x078000)>>15));
+        //B1 = data;                  // BusIn data(d0,d1,d2,d3,d4,d5,d6,d7)
+        rclk = 0;
+        return B1; 
+}
+
+// Data Start read from FIFO
+void OV7670::ReadStart(void)
+{        
+    rrst = 0 ;
+    oe = 0 ;
+    wait_us(1) ;
+    rclk = 0 ;
+    wait_us(1) ;
+    rclk = 1 ;
+    wait_us(1) ;        
+    rrst = 1 ;
+}
+
+// Data Stop read from FIFO
+void OV7670::ReadStop(void)
+{
+    oe = 1 ;
+    ReadOnebyte() ;
+    rclk = 1 ;
+}
\ No newline at end of file