ov7670 library
Dependents: Project_test Capture_bw_portin Capture_bw_v3 Project_190659132
Diff: ov7670.cpp
- 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