A program that records images from the OV7670 camera and displays them on a SPI TFT display. Working at 15fps

Dependencies:   mbed TFT_fonts_old

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ov7670.h Source File

ov7670.h

00001 #include "mbed.h"
00002 #include "ov7670reg.h"
00003 
00004 #define OV7670_WRITE (0x42)
00005 #define OV7670_READ  (0x43)
00006 #define OV7670_WRITEWAIT (20)
00007 #define OV7670_NOACK (0)
00008 #define OV7670_REGMAX (201)
00009 #define OV7670_I2CFREQ (50000)
00010 
00011 //
00012 // OV7670 + FIFO AL422B camera board test
00013 //
00014 class OV7670 : public Base
00015 {
00016 public:
00017     I2C camera ;
00018     InterruptIn vsync,href;
00019     DigitalOut wen ;
00020     //BusIn data ;
00021     PortIn data;
00022     DigitalOut rrst,oe,rclk ;
00023     volatile int LineCounter ;
00024     volatile int LastLines ;
00025     volatile bool CaptureReq ;
00026     volatile bool Busy ;
00027     volatile bool Done ;    
00028         
00029     OV7670(
00030         PinName sda,// Camera I2C port
00031         PinName scl,// Camera I2C port
00032         PinName vs, // VSYNC
00033         PinName hr, // HREF
00034         PinName we, // WEN
00035         
00036         /*
00037         PinName d7, // D7
00038         PinName d6, // D6
00039         PinName d5, // D5
00040         PinName d4, // D4
00041         PinName d3, // D3
00042         PinName d2, // D2
00043         PinName d1, // D1
00044         PinName d0, // D0
00045         */
00046         PortName port, // 8bit bus port
00047         int mask, // 0b0000_0M65_4000_0321_L000_0000_0000_0000 = 0x07878000
00048         
00049         PinName rt, // /RRST
00050         PinName o,  // /OE
00051         PinName rc  // RCLK      
00052         //) : camera(sda,scl),vsync(vs),href(hr),wen(we),data(d0,d1,d2,d3,d4,d5,d6,d7),rrst(rt),oe(o),rclk(rc)
00053         ) : camera(sda,scl),vsync(vs),href(hr),wen(we),data(port,mask),rrst(rt),oe(o),rclk(rc)
00054     {
00055         camera.stop() ;
00056         camera.frequency(OV7670_I2CFREQ) ;
00057         vsync.fall(this,&OV7670::VsyncHandler) ;
00058         href.rise(this,&OV7670::HrefHandler) ;
00059         CaptureReq = false ;
00060         Busy = false ;
00061         Done = false ;
00062         LineCounter = 0 ;
00063         rrst = 1 ;
00064         oe = 1 ;
00065         rclk = 1 ;
00066         wen = 0 ;
00067     }
00068 
00069     // capture request
00070     void CaptureNext(void)
00071     {
00072         CaptureReq = true ;
00073         Busy = true ;
00074     }
00075     
00076     // capture done? (with clear)
00077     bool CaptureDone(void)
00078     {
00079         bool result ;
00080         if (Busy) {
00081             result = false ;
00082         } else {
00083             result = Done ;
00084             Done = false ;
00085         }
00086         return result ;
00087     }
00088 
00089     // write to camera
00090     void WriteReg(int addr,int data)
00091     {
00092         // WRITE 0x42,ADDR,DATA
00093         camera.start() ;
00094         camera.write(OV7670_WRITE) ;
00095         wait_us(OV7670_WRITEWAIT);
00096         camera.write(addr) ;
00097         wait_us(OV7670_WRITEWAIT);
00098         camera.write(data) ;
00099         camera.stop() ;
00100     }
00101 
00102     // read from camera
00103     int ReadReg(int addr)
00104     {
00105         int data ;
00106 
00107         // WRITE 0x42,ADDR
00108         camera.start() ;
00109         camera.write(OV7670_WRITE) ;
00110         wait_us(OV7670_WRITEWAIT);
00111         camera.write(addr) ;
00112         camera.stop() ;
00113         wait_us(OV7670_WRITEWAIT);    
00114 
00115         // WRITE 0x43,READ
00116         camera.start() ;
00117         camera.write(OV7670_READ) ;
00118         wait_us(OV7670_WRITEWAIT);
00119         data = camera.read(OV7670_NOACK) ;
00120         camera.stop() ;
00121     
00122         return data ;
00123     }
00124 
00125     void Reset(void) {    
00126         WriteReg(0x12,0x80) ; // RESET CAMERA
00127         wait_ms(200) ;
00128     }
00129     
00130     void InitQQVGA() {
00131         // QQVGA RGB444
00132         WriteReg(REG_CLKRC,0x80);
00133         WriteReg(REG_COM11,0x0A) ;
00134         WriteReg(REG_TSLB,0x04);
00135         WriteReg(REG_COM7,0x04) ;
00136         
00137         //WriteReg(REG_RGB444, 0x02);
00138         //WriteReg(REG_COM15, 0xd0);
00139         WriteReg(REG_RGB444, 0x00);     // Disable RGB 444?
00140         WriteReg(REG_COM15, 0xD0);      // Set RGB 565?
00141         
00142         WriteReg(REG_HSTART,0x16) ;
00143         WriteReg(REG_HSTOP,0x04) ;
00144         WriteReg(REG_HREF,0x24) ;
00145         WriteReg(REG_VSTART,0x02) ;
00146         WriteReg(REG_VSTOP,0x7a) ;
00147         WriteReg(REG_VREF,0x0a) ;
00148         WriteReg(REG_COM10,0x02) ;
00149         WriteReg(REG_COM3, 0x04);
00150         WriteReg(REG_COM14, 0x1a);
00151         WriteReg(REG_MVFP,0x27) ;
00152         WriteReg(0x72, 0x22);
00153         WriteReg(0x73, 0xf2);
00154 
00155         // COLOR SETTING
00156         WriteReg(0x4f,0x80);
00157         WriteReg(0x50,0x80);
00158         WriteReg(0x51,0x00);
00159         WriteReg(0x52,0x22);
00160         WriteReg(0x53,0x5e);
00161         WriteReg(0x54,0x80);
00162         WriteReg(0x56,0x40);
00163         WriteReg(0x58,0x9e);
00164         WriteReg(0x59,0x88);
00165         WriteReg(0x5a,0x88);
00166         WriteReg(0x5b,0x44);
00167         WriteReg(0x5c,0x67);
00168         WriteReg(0x5d,0x49);
00169         WriteReg(0x5e,0x0e);
00170         WriteReg(0x69,0x00);
00171         WriteReg(0x6a,0x40);
00172         WriteReg(0x6b,0x0a);
00173         WriteReg(0x6c,0x0a);
00174         WriteReg(0x6d,0x55);
00175         WriteReg(0x6e,0x11);
00176         WriteReg(0x6f,0x9f);
00177 
00178         WriteReg(0xb0,0x84);
00179     }    
00180 
00181 
00182 
00183     // vsync handler
00184     void VsyncHandler(void)
00185     {
00186         // Capture Enable
00187         if (CaptureReq) {
00188             wen = 1 ;
00189             Done = false ;
00190             CaptureReq = false ;
00191         } else {
00192             wen = 0 ;
00193             if (Busy) {
00194                 Busy = false ;
00195                 Done = true ;
00196             }
00197         }
00198 
00199         // Hline Counter
00200         LastLines = LineCounter ;
00201         LineCounter = 0 ;
00202     }
00203     
00204     // href handler
00205     void HrefHandler(void)
00206     {
00207         LineCounter++ ;
00208     }
00209     
00210     // Data Read
00211     int ReadOneByte(void)
00212     {
00213         int result;
00214         rclk = 1;
00215         result = data;
00216 
00217         // Shift the bits around to form the byte
00218         int top = result >> 19;         // Isolate the top nibble
00219         int middle = result >> 2;       // Isolate bits 2 & 3
00220         result = result & 0x00000003;   // Isolate bits 0 & 1
00221         
00222         result += middle;
00223         result += top;
00224        
00225         rclk = 0;
00226         return result;
00227     }
00228     
00229     // Data Start
00230     void ReadStart(void)
00231     {        
00232         rrst = 0 ;
00233         oe = 0 ;
00234         wait_us(1) ;
00235         rclk = 0 ;
00236         wait_us(1) ;
00237         rclk = 1 ;
00238         wait_us(1) ;        
00239         rrst = 1 ;
00240     }
00241     
00242     // Data Stop
00243     void ReadStop(void)
00244     {
00245         oe = 1 ;
00246         ReadOneByte() ;
00247         rclk = 1 ;
00248     }
00249 };