ov7670 library

Dependents:   Project_test Capture_bw_portin Capture_bw_v3 Project_190659132

Committer:
edodm85
Date:
Sat Mar 16 13:40:36 2013 +0000
Revision:
1:d82dbad9c06b
Parent:
0:810d59d0b843
Child:
2:354a00023f79
Add QVGA and VGA reg

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 1:d82dbad9c06b 83 int OV7670::Init(char c, int n)
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 1:d82dbad9c06b 91 Reset(); // Resets all registers to default values
edodm85 1:d82dbad9c06b 92 Reset(); // Resets all registers to default values
edodm85 1:d82dbad9c06b 93
edodm85 1:d82dbad9c06b 94 WriteReg(REG_RGB444, 0x00); // Disable RGB444
edodm85 1:d82dbad9c06b 95 WriteReg(REG_COM10,0x02); // 0x02 VSYNC negative (http://nasulica.homelinux.org/?p=959)
edodm85 1:d82dbad9c06b 96 WriteReg(REG_MVFP,0x27); // mirror image
edodm85 1:d82dbad9c06b 97
edodm85 1:d82dbad9c06b 98 WriteReg(REG_CLKRC,0x80); // prescaler x1
edodm85 1:d82dbad9c06b 99 WriteReg(DBLV,0x0a); // bypass PLL
edodm85 1:d82dbad9c06b 100
edodm85 0:810d59d0b843 101 WriteReg(REG_COM11,0x0A) ;
edodm85 1:d82dbad9c06b 102 WriteReg(REG_TSLB,0x04); // 0D = UYVY 04 = YUYV
edodm85 1:d82dbad9c06b 103 WriteReg(REG_COM13,0x88); // connect to REG_TSLB
edodm85 0:810d59d0b843 104
edodm85 1:d82dbad9c06b 105
edodm85 1:d82dbad9c06b 106 if(c == 'b' || c == 'y') // YUV
edodm85 1:d82dbad9c06b 107 {
edodm85 1:d82dbad9c06b 108 WriteReg(REG_COM7, 0x00); // YUV
edodm85 1:d82dbad9c06b 109 WriteReg(REG_COM17, 0x00); // color bar disable
edodm85 1:d82dbad9c06b 110 WriteReg(REG_COM3, 0x04);
edodm85 1:d82dbad9c06b 111 WriteReg(REG_COM15, 0xC0); // Set normal rgb with Full range
edodm85 1:d82dbad9c06b 112
edodm85 1:d82dbad9c06b 113 }else
edodm85 1:d82dbad9c06b 114 if(c == 'r') // RGB565
edodm85 1:d82dbad9c06b 115 {
edodm85 1:d82dbad9c06b 116 WriteReg(REG_COM7, 0x04); // RGB + color bar disable
edodm85 1:d82dbad9c06b 117 WriteReg(REG_RGB444, 0x00); // Disable RGB444
edodm85 1:d82dbad9c06b 118 WriteReg(REG_COM15, 0x10); // Set rgb565 with Full range 0xD0
edodm85 1:d82dbad9c06b 119 WriteReg(REG_COM3, 0x04);
edodm85 1:d82dbad9c06b 120 WriteReg(REG_CLKRC,0x80); // prescaler x1
edodm85 1:d82dbad9c06b 121 }
edodm85 1:d82dbad9c06b 122
edodm85 1:d82dbad9c06b 123 WriteReg(0x70, 0x3A); // Scaling Xsc
edodm85 1:d82dbad9c06b 124 WriteReg(0x71, 0x35); // Scaling Ysc
edodm85 1:d82dbad9c06b 125 WriteReg(0xA2, 0x02); // pixel clock delay
edodm85 1:d82dbad9c06b 126
edodm85 1:d82dbad9c06b 127 if(n == 19200) // 160*120
edodm85 1:d82dbad9c06b 128 {
edodm85 1:d82dbad9c06b 129 WriteReg(REG_COM14, 0x1a); // divide by 4
edodm85 1:d82dbad9c06b 130 WriteReg(0x72, 0x22); // downsample by 4
edodm85 1:d82dbad9c06b 131 WriteReg(0x73, 0xf2); // divide by 4
edodm85 1:d82dbad9c06b 132 WriteReg(REG_HSTART,0x16);
edodm85 1:d82dbad9c06b 133 WriteReg(REG_HSTOP,0x04);
edodm85 1:d82dbad9c06b 134 WriteReg(REG_HREF,0xa4);
edodm85 1:d82dbad9c06b 135 WriteReg(REG_VSTART,0x02);
edodm85 1:d82dbad9c06b 136 WriteReg(REG_VSTOP,0x7a);
edodm85 1:d82dbad9c06b 137 WriteReg(REG_VREF,0x0a);
edodm85 1:d82dbad9c06b 138 }
edodm85 1:d82dbad9c06b 139 if(n == 76800) // 320*240
edodm85 1:d82dbad9c06b 140 {
edodm85 1:d82dbad9c06b 141 WriteReg(REG_COM14, 0x19);
edodm85 1:d82dbad9c06b 142 WriteReg(0x72, 0x11);
edodm85 1:d82dbad9c06b 143 WriteReg(0x73, 0xf1);
edodm85 1:d82dbad9c06b 144 WriteReg(REG_HSTART,0x16);
edodm85 1:d82dbad9c06b 145 WriteReg(REG_HSTOP,0x04);
edodm85 1:d82dbad9c06b 146 WriteReg(REG_HREF,0x24);
edodm85 1:d82dbad9c06b 147 WriteReg(REG_VSTART,0x02);
edodm85 1:d82dbad9c06b 148 WriteReg(REG_VSTOP,0x7a);
edodm85 1:d82dbad9c06b 149 WriteReg(REG_VREF,0x0a);
edodm85 1:d82dbad9c06b 150 }
edodm85 1:d82dbad9c06b 151 if(n == 307200) // 640*480
edodm85 1:d82dbad9c06b 152 {
edodm85 1:d82dbad9c06b 153 WriteReg(REG_COM3,0x00); // REG_COM3
edodm85 1:d82dbad9c06b 154 WriteReg(0x3e,0x00); // REG_COM14
edodm85 1:d82dbad9c06b 155 WriteReg(0x72,0x11); //
edodm85 1:d82dbad9c06b 156 WriteReg(0x73,0xf0); //
edodm85 1:d82dbad9c06b 157
edodm85 1:d82dbad9c06b 158 WriteReg(0x32,0xb6); // HREF
edodm85 1:d82dbad9c06b 159 WriteReg(0x17,0x13); // HSTART
edodm85 1:d82dbad9c06b 160 WriteReg(0x18,0x01); // HSTOP
edodm85 1:d82dbad9c06b 161 WriteReg(0x19,0x02); // VSTART
edodm85 1:d82dbad9c06b 162 WriteReg(0x1a,0x7a); // VSTOP
edodm85 1:d82dbad9c06b 163 WriteReg(0x03,0x0a); // VREF
edodm85 1:d82dbad9c06b 164 WriteReg(0x70, 0x3a); // Scaling Xsc
edodm85 1:d82dbad9c06b 165 WriteReg(0x71, 0x35); // Scaling Ysc
edodm85 1:d82dbad9c06b 166 WriteReg(0xA2, 0x02); // pixel clock delay
edodm85 1:d82dbad9c06b 167
edodm85 1:d82dbad9c06b 168 WriteReg(REG_COM1, 0x00);
edodm85 1:d82dbad9c06b 169 }
edodm85 1:d82dbad9c06b 170
edodm85 1:d82dbad9c06b 171
edodm85 0:810d59d0b843 172 // COLOR SETTING
edodm85 1:d82dbad9c06b 173
edodm85 0:810d59d0b843 174 WriteReg(REG_COM8,0x8F); // AGC AWB AEC Enab
edodm85 1:d82dbad9c06b 175 WriteReg(0xAA,0x14); // Average-based AEC algorithm
edodm85 0:810d59d0b843 176 WriteReg(REG_BRIGHT,0x00); // 0x00(Brightness 0) - 0x18(Brightness +1) - 0x98(Brightness -1)
edodm85 0:810d59d0b843 177 WriteReg(REG_CONTRAS,0x40); // 0x40(Contrast 0) - 0x50(Contrast +1) - 0x38(Contrast -1)
edodm85 1:d82dbad9c06b 178 WriteReg(0xB1,0xB1); // Automatic Black level Calibration
edodm85 1:d82dbad9c06b 179
edodm85 1:d82dbad9c06b 180 WriteReg(MTX1,0x80);
edodm85 1:d82dbad9c06b 181 WriteReg(MTX2,0x80);
edodm85 1:d82dbad9c06b 182 WriteReg(MTX3,0x00);
edodm85 1:d82dbad9c06b 183 WriteReg(MTX4,0x22);
edodm85 1:d82dbad9c06b 184 WriteReg(MTX5,0x5e);
edodm85 1:d82dbad9c06b 185 WriteReg(MTX6,0x80);
edodm85 1:d82dbad9c06b 186 WriteReg(MTXS,0x9e);
edodm85 0:810d59d0b843 187 WriteReg(AWBC7,0x88);
edodm85 0:810d59d0b843 188 WriteReg(AWBC8,0x88);
edodm85 0:810d59d0b843 189 WriteReg(AWBC9,0x44);
edodm85 0:810d59d0b843 190 WriteReg(AWBC10,0x67);
edodm85 0:810d59d0b843 191 WriteReg(AWBC11,0x49);
edodm85 0:810d59d0b843 192 WriteReg(AWBC12,0x0e);
edodm85 0:810d59d0b843 193 WriteReg(REG_GFIX,0x00);
edodm85 0:810d59d0b843 194 WriteReg(GGAIN,0x40);
edodm85 0:810d59d0b843 195 WriteReg(AWBCTR3,0x0a);
edodm85 0:810d59d0b843 196 WriteReg(AWBCTR2,0x55);
edodm85 0:810d59d0b843 197 WriteReg(AWBCTR1,0x11);
edodm85 0:810d59d0b843 198 WriteReg(AWBCTR0,0x9f);
edodm85 0:810d59d0b843 199
edodm85 0:810d59d0b843 200 WriteReg(0xb0,0x84);
edodm85 1:d82dbad9c06b 201
edodm85 0:810d59d0b843 202 return 1;
edodm85 0:810d59d0b843 203 }
edodm85 0:810d59d0b843 204
edodm85 0:810d59d0b843 205 // vsync handler
edodm85 0:810d59d0b843 206 void OV7670::VsyncHandler(void)
edodm85 0:810d59d0b843 207 {
edodm85 0:810d59d0b843 208
edodm85 0:810d59d0b843 209 // Capture Enable
edodm85 0:810d59d0b843 210 if (CaptureReq) {
edodm85 0:810d59d0b843 211 wen = 1 ;
edodm85 0:810d59d0b843 212 Done = false ;
edodm85 0:810d59d0b843 213 CaptureReq = false ;
edodm85 0:810d59d0b843 214 } else {
edodm85 0:810d59d0b843 215 wen = 0 ;
edodm85 0:810d59d0b843 216 if (Busy) {
edodm85 0:810d59d0b843 217 Busy = false ;
edodm85 0:810d59d0b843 218 Done = true ;
edodm85 0:810d59d0b843 219 }
edodm85 0:810d59d0b843 220 }
edodm85 0:810d59d0b843 221
edodm85 0:810d59d0b843 222 // Hline Counter
edodm85 0:810d59d0b843 223 LastLines = LineCounter ;
edodm85 0:810d59d0b843 224 LineCounter = 0 ;
edodm85 0:810d59d0b843 225 }
edodm85 0:810d59d0b843 226
edodm85 0:810d59d0b843 227 // href handler
edodm85 0:810d59d0b843 228 void OV7670::HrefHandler(void)
edodm85 0:810d59d0b843 229 {
edodm85 0:810d59d0b843 230 LineCounter++ ;
edodm85 0:810d59d0b843 231 }
edodm85 0:810d59d0b843 232
edodm85 0:810d59d0b843 233 // Data Read
edodm85 0:810d59d0b843 234 int OV7670::ReadOnebyte(void)
edodm85 0:810d59d0b843 235 {
edodm85 0:810d59d0b843 236 int B1;
edodm85 0:810d59d0b843 237 rclk = 1;
edodm85 0:810d59d0b843 238 B1 = (((data&0x07800000)>>19)|((data&0x078000)>>15));
edodm85 0:810d59d0b843 239 rclk = 0;
edodm85 0:810d59d0b843 240 return B1;
edodm85 0:810d59d0b843 241 }
edodm85 0:810d59d0b843 242
edodm85 0:810d59d0b843 243 // Data Start read from FIFO
edodm85 0:810d59d0b843 244 void OV7670::ReadStart(void)
edodm85 0:810d59d0b843 245 {
edodm85 0:810d59d0b843 246 rrst = 0 ;
edodm85 0:810d59d0b843 247 oe = 0 ;
edodm85 0:810d59d0b843 248 wait_us(1) ;
edodm85 0:810d59d0b843 249 rclk = 0 ;
edodm85 0:810d59d0b843 250 wait_us(1) ;
edodm85 0:810d59d0b843 251 rclk = 1 ;
edodm85 0:810d59d0b843 252 wait_us(1) ;
edodm85 0:810d59d0b843 253 rrst = 1 ;
edodm85 0:810d59d0b843 254 }
edodm85 0:810d59d0b843 255
edodm85 0:810d59d0b843 256 // Data Stop read from FIFO
edodm85 0:810d59d0b843 257 void OV7670::ReadStop(void)
edodm85 0:810d59d0b843 258 {
edodm85 0:810d59d0b843 259 oe = 1 ;
edodm85 0:810d59d0b843 260 ReadOnebyte() ;
edodm85 0:810d59d0b843 261 rclk = 1 ;
edodm85 0:810d59d0b843 262 }