OV7670 Library

Dependents:   OV7670_Test_Code OV7670_Test_Code_with_ethernet Practica4_Camara

You can find the original files here: http://mbed.org/users/mio/notebook/ov7670_with_al422b_qqvga_test/

Committer:
edodm85
Date:
Sun Mar 10 13:01:45 2013 +0000
Revision:
0:810d59d0b843
Child:
1:d82dbad9c06b
First Version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
edodm85 0:810d59d0b843 1 #include "ov7670.h"
edodm85 0:810d59d0b843 2
edodm85 0:810d59d0b843 3
edodm85 0:810d59d0b843 4 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)
edodm85 0:810d59d0b843 5 {
edodm85 0:810d59d0b843 6 _i2c.stop();
edodm85 0:810d59d0b843 7 _i2c.frequency(OV7670_I2CFREQ);
edodm85 0:810d59d0b843 8 vsync.fall(this,&OV7670::VsyncHandler); // interrupt fall edge
edodm85 0:810d59d0b843 9 href.rise(this,&OV7670::HrefHandler); // interrupt rise edge
edodm85 0:810d59d0b843 10 CaptureReq = false;
edodm85 0:810d59d0b843 11 Busy = false;
edodm85 0:810d59d0b843 12 Done = false;
edodm85 0:810d59d0b843 13 LineCounter = 0;
edodm85 0:810d59d0b843 14 rrst = 1;
edodm85 0:810d59d0b843 15 oe = 1;
edodm85 0:810d59d0b843 16 rclk = 1;
edodm85 0:810d59d0b843 17 wen = 0;
edodm85 0:810d59d0b843 18 }
edodm85 0:810d59d0b843 19
edodm85 0:810d59d0b843 20 OV7670::~OV7670()
edodm85 0:810d59d0b843 21 {
edodm85 0:810d59d0b843 22
edodm85 0:810d59d0b843 23 }
edodm85 0:810d59d0b843 24
edodm85 0:810d59d0b843 25 // capture request
edodm85 0:810d59d0b843 26 void OV7670::CaptureNext(void)
edodm85 0:810d59d0b843 27 {
edodm85 0:810d59d0b843 28 CaptureReq = true ;
edodm85 0:810d59d0b843 29 Busy = true ;
edodm85 0:810d59d0b843 30 }
edodm85 0:810d59d0b843 31
edodm85 0:810d59d0b843 32 // capture done? (with clear)
edodm85 0:810d59d0b843 33 bool OV7670::CaptureDone(void)
edodm85 0:810d59d0b843 34 {
edodm85 0:810d59d0b843 35 bool result ;
edodm85 0:810d59d0b843 36 if (Busy) {
edodm85 0:810d59d0b843 37 result = false ;
edodm85 0:810d59d0b843 38 } else {
edodm85 0:810d59d0b843 39 result = Done ;
edodm85 0:810d59d0b843 40 Done = false ;
edodm85 0:810d59d0b843 41 }
edodm85 0:810d59d0b843 42 return result ;
edodm85 0:810d59d0b843 43 }
edodm85 0:810d59d0b843 44
edodm85 0:810d59d0b843 45 // write to camera
edodm85 0:810d59d0b843 46 void OV7670::WriteReg(int addr,int data)
edodm85 0:810d59d0b843 47 {
edodm85 0:810d59d0b843 48 _i2c.start() ;
edodm85 0:810d59d0b843 49 _i2c.write(OV7670_WRITE) ;
edodm85 0:810d59d0b843 50 wait_us(OV7670_WRITEWAIT);
edodm85 0:810d59d0b843 51 _i2c.write(addr) ;
edodm85 0:810d59d0b843 52 wait_us(OV7670_WRITEWAIT);
edodm85 0:810d59d0b843 53 _i2c.write(data) ;
edodm85 0:810d59d0b843 54 _i2c.stop() ;
edodm85 0:810d59d0b843 55 }
edodm85 0:810d59d0b843 56
edodm85 0:810d59d0b843 57 // read from camera
edodm85 0:810d59d0b843 58 int OV7670::ReadReg(int addr)
edodm85 0:810d59d0b843 59 {
edodm85 0:810d59d0b843 60 int data ;
edodm85 0:810d59d0b843 61
edodm85 0:810d59d0b843 62 _i2c.start() ;
edodm85 0:810d59d0b843 63 _i2c.write(OV7670_WRITE) ;
edodm85 0:810d59d0b843 64 wait_us(OV7670_WRITEWAIT);
edodm85 0:810d59d0b843 65 _i2c.write(addr) ;
edodm85 0:810d59d0b843 66 _i2c.stop() ;
edodm85 0:810d59d0b843 67 wait_us(OV7670_WRITEWAIT);
edodm85 0:810d59d0b843 68
edodm85 0:810d59d0b843 69 _i2c.start() ;
edodm85 0:810d59d0b843 70 _i2c.write(OV7670_READ) ;
edodm85 0:810d59d0b843 71 wait_us(OV7670_WRITEWAIT);
edodm85 0:810d59d0b843 72 data = _i2c.read(OV7670_NOACK) ;
edodm85 0:810d59d0b843 73 _i2c.stop() ;
edodm85 0:810d59d0b843 74
edodm85 0:810d59d0b843 75 return data ;
edodm85 0:810d59d0b843 76 }
edodm85 0:810d59d0b843 77
edodm85 0:810d59d0b843 78 void OV7670::Reset(void) {
edodm85 0:810d59d0b843 79 WriteReg(0x12,0x80) ; // RESET CAMERA
edodm85 0:810d59d0b843 80 wait_ms(200) ;
edodm85 0:810d59d0b843 81 }
edodm85 0:810d59d0b843 82
edodm85 0:810d59d0b843 83 int OV7670::Init(char c)
edodm85 0:810d59d0b843 84 {
edodm85 0:810d59d0b843 85
edodm85 0:810d59d0b843 86 if (ReadReg(REG_PID) != 0x76) // check id camera
edodm85 0:810d59d0b843 87 {
edodm85 0:810d59d0b843 88 return 0;
edodm85 0:810d59d0b843 89 }
edodm85 0:810d59d0b843 90
edodm85 0:810d59d0b843 91 Reset(); // Resets all registers to default values
edodm85 0:810d59d0b843 92
edodm85 0:810d59d0b843 93 WriteReg(REG_CLKRC,0x80);
edodm85 0:810d59d0b843 94 WriteReg(REG_COM11,0x0A) ;
edodm85 0:810d59d0b843 95 WriteReg(REG_TSLB,0x04); // 0D = UYVY 04 = YUYV
edodm85 0:810d59d0b843 96 WriteReg(REG_COM13,0x88); // connect to REG_TSLB
edodm85 0:810d59d0b843 97
edodm85 0:810d59d0b843 98 //WriteReg(REG_COM7,0x01) ; // output format: raw
edodm85 0:810d59d0b843 99 WriteReg(REG_RGB444, 0x00); // Disable RGB444
edodm85 0:810d59d0b843 100 WriteReg(REG_HSTART,0x16) ;
edodm85 0:810d59d0b843 101 WriteReg(REG_HSTOP,0x04) ;
edodm85 0:810d59d0b843 102 WriteReg(REG_HREF,0x24) ;
edodm85 0:810d59d0b843 103 WriteReg(REG_VSTART,0x02) ;
edodm85 0:810d59d0b843 104 WriteReg(REG_VSTOP,0x7a) ;
edodm85 0:810d59d0b843 105 WriteReg(REG_VREF,0x0a) ;
edodm85 0:810d59d0b843 106 WriteReg(REG_COM10,0x02) ; // 0x02 VSYNC negative (http://nasulica.homelinux.org/?p=959)
edodm85 0:810d59d0b843 107 WriteReg(REG_MVFP,0x27) ;
edodm85 0:810d59d0b843 108
edodm85 0:810d59d0b843 109 if(c == 'y')
edodm85 0:810d59d0b843 110 {
edodm85 0:810d59d0b843 111 WriteReg(REG_COM7,0x00); // YUV
edodm85 0:810d59d0b843 112 WriteReg(REG_COM17,0x00); // color bar disable
edodm85 0:810d59d0b843 113 WriteReg(REG_COM3, 0x04);
edodm85 0:810d59d0b843 114 WriteReg(REG_COM14, 0x1a); // by 4
edodm85 0:810d59d0b843 115 WriteReg(REG_COM15, 0xC0); // Set normal rgb
edodm85 0:810d59d0b843 116 WriteReg(0x70, 0x3A);
edodm85 0:810d59d0b843 117 WriteReg(0x71, 0x35);
edodm85 0:810d59d0b843 118 WriteReg(0x72, 0x22);
edodm85 0:810d59d0b843 119 WriteReg(0x73, 0xf2);
edodm85 0:810d59d0b843 120 WriteReg(0xA2, 0x02);
edodm85 0:810d59d0b843 121 }else{ // RGB565
edodm85 0:810d59d0b843 122 WriteReg(REG_COM7,0x04); // RGB + color bar disable
edodm85 0:810d59d0b843 123 WriteReg(REG_RGB444, 0x00); // Disable RGB444
edodm85 0:810d59d0b843 124 WriteReg(REG_COM15, 0xD0); // Set rgb565 0xD0 or rgb555 0xD8
edodm85 0:810d59d0b843 125 WriteReg(REG_COM3, 0x04);
edodm85 0:810d59d0b843 126 WriteReg(REG_COM14, 0x1a); // by 4
edodm85 0:810d59d0b843 127 WriteReg(0x70, 0x3A);
edodm85 0:810d59d0b843 128 WriteReg(0x71, 0x35);
edodm85 0:810d59d0b843 129 WriteReg(0x72, 0x22);
edodm85 0:810d59d0b843 130 WriteReg(0x73, 0xf2);
edodm85 0:810d59d0b843 131 WriteReg(0xA2, 0x02);
edodm85 0:810d59d0b843 132 }
edodm85 0:810d59d0b843 133
edodm85 0:810d59d0b843 134 // COLOR SETTING
edodm85 0:810d59d0b843 135
edodm85 0:810d59d0b843 136 WriteReg(REG_COM8,0x8F); // AGC AWB AEC Enab
edodm85 0:810d59d0b843 137 WriteReg(REG_BRIGHT,0x00); // 0x00(Brightness 0) - 0x18(Brightness +1) - 0x98(Brightness -1)
edodm85 0:810d59d0b843 138
edodm85 0:810d59d0b843 139 WriteReg(MTX1,0x80);
edodm85 0:810d59d0b843 140 WriteReg(MTX2,0x80);
edodm85 0:810d59d0b843 141 WriteReg(MTX3,0x00);
edodm85 0:810d59d0b843 142 WriteReg(MTX4,0x22);
edodm85 0:810d59d0b843 143 WriteReg(MTX5,0x5e);
edodm85 0:810d59d0b843 144 WriteReg(MTX6,0x80);
edodm85 0:810d59d0b843 145 WriteReg(REG_CONTRAS,0x40); // 0x40(Contrast 0) - 0x50(Contrast +1) - 0x38(Contrast -1)
edodm85 0:810d59d0b843 146 WriteReg(MTXS,0x9e);
edodm85 0:810d59d0b843 147 WriteReg(AWBC7,0x88);
edodm85 0:810d59d0b843 148 WriteReg(AWBC8,0x88);
edodm85 0:810d59d0b843 149 WriteReg(AWBC9,0x44);
edodm85 0:810d59d0b843 150 WriteReg(AWBC10,0x67);
edodm85 0:810d59d0b843 151 WriteReg(AWBC11,0x49);
edodm85 0:810d59d0b843 152 WriteReg(AWBC12,0x0e);
edodm85 0:810d59d0b843 153 WriteReg(REG_GFIX,0x00);
edodm85 0:810d59d0b843 154 WriteReg(GGAIN,0x40);
edodm85 0:810d59d0b843 155 WriteReg(DBLV,0x0a);
edodm85 0:810d59d0b843 156 WriteReg(AWBCTR3,0x0a);
edodm85 0:810d59d0b843 157 WriteReg(AWBCTR2,0x55);
edodm85 0:810d59d0b843 158 WriteReg(AWBCTR1,0x11);
edodm85 0:810d59d0b843 159 WriteReg(AWBCTR0,0x9f);
edodm85 0:810d59d0b843 160
edodm85 0:810d59d0b843 161 WriteReg(0xb0,0x84);
edodm85 0:810d59d0b843 162
edodm85 0:810d59d0b843 163 return 1;
edodm85 0:810d59d0b843 164 }
edodm85 0:810d59d0b843 165
edodm85 0:810d59d0b843 166 // vsync handler
edodm85 0:810d59d0b843 167 void OV7670::VsyncHandler(void)
edodm85 0:810d59d0b843 168 {
edodm85 0:810d59d0b843 169
edodm85 0:810d59d0b843 170 // Capture Enable
edodm85 0:810d59d0b843 171 if (CaptureReq) {
edodm85 0:810d59d0b843 172 wen = 1 ;
edodm85 0:810d59d0b843 173 Done = false ;
edodm85 0:810d59d0b843 174 CaptureReq = false ;
edodm85 0:810d59d0b843 175 } else {
edodm85 0:810d59d0b843 176 wen = 0 ;
edodm85 0:810d59d0b843 177 if (Busy) {
edodm85 0:810d59d0b843 178 Busy = false ;
edodm85 0:810d59d0b843 179 Done = true ;
edodm85 0:810d59d0b843 180 }
edodm85 0:810d59d0b843 181 }
edodm85 0:810d59d0b843 182
edodm85 0:810d59d0b843 183 // Hline Counter
edodm85 0:810d59d0b843 184 LastLines = LineCounter ;
edodm85 0:810d59d0b843 185 LineCounter = 0 ;
edodm85 0:810d59d0b843 186 }
edodm85 0:810d59d0b843 187
edodm85 0:810d59d0b843 188 // href handler
edodm85 0:810d59d0b843 189 void OV7670::HrefHandler(void)
edodm85 0:810d59d0b843 190 {
edodm85 0:810d59d0b843 191 LineCounter++ ;
edodm85 0:810d59d0b843 192 }
edodm85 0:810d59d0b843 193
edodm85 0:810d59d0b843 194 // Data Read
edodm85 0:810d59d0b843 195 int OV7670::ReadOnebyte(void)
edodm85 0:810d59d0b843 196 {
edodm85 0:810d59d0b843 197 int B1;
edodm85 0:810d59d0b843 198 rclk = 1;
edodm85 0:810d59d0b843 199 B1 = (((data&0x07800000)>>19)|((data&0x078000)>>15));
edodm85 0:810d59d0b843 200 //B1 = data; // BusIn data(d0,d1,d2,d3,d4,d5,d6,d7)
edodm85 0:810d59d0b843 201 rclk = 0;
edodm85 0:810d59d0b843 202 return B1;
edodm85 0:810d59d0b843 203 }
edodm85 0:810d59d0b843 204
edodm85 0:810d59d0b843 205 // Data Start read from FIFO
edodm85 0:810d59d0b843 206 void OV7670::ReadStart(void)
edodm85 0:810d59d0b843 207 {
edodm85 0:810d59d0b843 208 rrst = 0 ;
edodm85 0:810d59d0b843 209 oe = 0 ;
edodm85 0:810d59d0b843 210 wait_us(1) ;
edodm85 0:810d59d0b843 211 rclk = 0 ;
edodm85 0:810d59d0b843 212 wait_us(1) ;
edodm85 0:810d59d0b843 213 rclk = 1 ;
edodm85 0:810d59d0b843 214 wait_us(1) ;
edodm85 0:810d59d0b843 215 rrst = 1 ;
edodm85 0:810d59d0b843 216 }
edodm85 0:810d59d0b843 217
edodm85 0:810d59d0b843 218 // Data Stop read from FIFO
edodm85 0:810d59d0b843 219 void OV7670::ReadStop(void)
edodm85 0:810d59d0b843 220 {
edodm85 0:810d59d0b843 221 oe = 1 ;
edodm85 0:810d59d0b843 222 ReadOnebyte() ;
edodm85 0:810d59d0b843 223 rclk = 1 ;
edodm85 0:810d59d0b843 224 }