OV7670 Library
ov7670.cpp
- Committer:
- edodm85
- Date:
- 2013-03-16
- Revision:
- 1:d82dbad9c06b
- Parent:
- 0:810d59d0b843
- Child:
- 2:354a00023f79
File content as of revision 1:d82dbad9c06b:
#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, int n) { if (ReadReg(REG_PID) != 0x76) // check id camera { return 0; } Reset(); // Resets all registers to default values Reset(); // Resets all registers to default values WriteReg(REG_RGB444, 0x00); // Disable RGB444 WriteReg(REG_COM10,0x02); // 0x02 VSYNC negative (http://nasulica.homelinux.org/?p=959) WriteReg(REG_MVFP,0x27); // mirror image WriteReg(REG_CLKRC,0x80); // prescaler x1 WriteReg(DBLV,0x0a); // bypass PLL WriteReg(REG_COM11,0x0A) ; WriteReg(REG_TSLB,0x04); // 0D = UYVY 04 = YUYV WriteReg(REG_COM13,0x88); // connect to REG_TSLB if(c == 'b' || c == 'y') // YUV { WriteReg(REG_COM7, 0x00); // YUV WriteReg(REG_COM17, 0x00); // color bar disable WriteReg(REG_COM3, 0x04); WriteReg(REG_COM15, 0xC0); // Set normal rgb with Full range }else if(c == 'r') // RGB565 { WriteReg(REG_COM7, 0x04); // RGB + color bar disable WriteReg(REG_RGB444, 0x00); // Disable RGB444 WriteReg(REG_COM15, 0x10); // Set rgb565 with Full range 0xD0 WriteReg(REG_COM3, 0x04); WriteReg(REG_CLKRC,0x80); // prescaler x1 } WriteReg(0x70, 0x3A); // Scaling Xsc WriteReg(0x71, 0x35); // Scaling Ysc WriteReg(0xA2, 0x02); // pixel clock delay if(n == 19200) // 160*120 { WriteReg(REG_COM14, 0x1a); // divide by 4 WriteReg(0x72, 0x22); // downsample by 4 WriteReg(0x73, 0xf2); // divide by 4 WriteReg(REG_HSTART,0x16); WriteReg(REG_HSTOP,0x04); WriteReg(REG_HREF,0xa4); WriteReg(REG_VSTART,0x02); WriteReg(REG_VSTOP,0x7a); WriteReg(REG_VREF,0x0a); } if(n == 76800) // 320*240 { WriteReg(REG_COM14, 0x19); WriteReg(0x72, 0x11); WriteReg(0x73, 0xf1); WriteReg(REG_HSTART,0x16); WriteReg(REG_HSTOP,0x04); WriteReg(REG_HREF,0x24); WriteReg(REG_VSTART,0x02); WriteReg(REG_VSTOP,0x7a); WriteReg(REG_VREF,0x0a); } if(n == 307200) // 640*480 { WriteReg(REG_COM3,0x00); // REG_COM3 WriteReg(0x3e,0x00); // REG_COM14 WriteReg(0x72,0x11); // WriteReg(0x73,0xf0); // WriteReg(0x32,0xb6); // HREF WriteReg(0x17,0x13); // HSTART WriteReg(0x18,0x01); // HSTOP WriteReg(0x19,0x02); // VSTART WriteReg(0x1a,0x7a); // VSTOP WriteReg(0x03,0x0a); // VREF WriteReg(0x70, 0x3a); // Scaling Xsc WriteReg(0x71, 0x35); // Scaling Ysc WriteReg(0xA2, 0x02); // pixel clock delay WriteReg(REG_COM1, 0x00); } // COLOR SETTING WriteReg(REG_COM8,0x8F); // AGC AWB AEC Enab WriteReg(0xAA,0x14); // Average-based AEC algorithm WriteReg(REG_BRIGHT,0x00); // 0x00(Brightness 0) - 0x18(Brightness +1) - 0x98(Brightness -1) WriteReg(REG_CONTRAS,0x40); // 0x40(Contrast 0) - 0x50(Contrast +1) - 0x38(Contrast -1) WriteReg(0xB1,0xB1); // Automatic Black level Calibration WriteReg(MTX1,0x80); WriteReg(MTX2,0x80); WriteReg(MTX3,0x00); WriteReg(MTX4,0x22); WriteReg(MTX5,0x5e); WriteReg(MTX6,0x80); 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(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)); 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 ; }