First release
Dependencies: EthernetInterface HTTPServer TextLCD mbed-rpc mbed-rtos mbed
Sample code of section 5 in Oct 2014 issue of the Interface Magazine, published by CQ publishing in Japan. CQ出版社インターフェース誌 2014年10月号5章に掲載のサンプルコードです.
LPC1768にトラ技OV7670モジュールとサーボを接続したうえで,リモート操作可能なネットワーク・カメラにしています.このコードのうちカメラ制御部には,Sadaei Osakabe氏のコードを流用させていただいています.
また,次のHTMLファイルをダウンロードして,LPC1768のフラッシュメモリに置いてください.ネットワーク経由で,このHTMLにアクセスをします(ブラウザで開く). /media/uploads/smorioka/netcam.htm
Revision 0:993f719c9352, committed 2014-08-26
- Comitter:
- smorioka
- Date:
- Tue Aug 26 16:49:26 2014 +0000
- Commit message:
- Sample code of section 5 in Oct 2014 issue of the Interface Magazine, published by CQ publishing in Japan.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/EthernetInterface/#097a9996f8d5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/HTTPServer.lib Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/leihen/code/HTTPServer/#cc3f5c53d0d5
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TextLCD.lib Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/TextLCD/#308d188a2d3a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2014, Sumio Morioka + * All rights reserved. + * + * This source code was originally written by Dr.Sumio Morioka for use in the Oct 2014 issue of + * "the Interface magazine", published by CQ publishing Co.Ltd in Japan (http://www.cqpub.co.jp). + * The author has no responsibility on any results caused by using this code. + * + * - Distribution date of this code: Aug 26, 2014 + * - Author: Dr.Sumio Morioka (http://www002.upp.so-net.ne.jp/morioka) + * + * + * IMPORTANT NOTICE: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "mbed.h" +#include "mbed_rpc.h" + +#include "TextLCD.h" +#include "LocalFileSystem.h" + +#include "EthernetInterface.h" +#include "HTTPServer.h" +#include "FsHandler.h" +#include "RpcHandler.h" + +#include "ov7670.h" + +TextLCD lcd(p24, p26, p27, p28, p29, p30); + + +//#define USE_RPCOUT +#undef USE_RPCOUT + +#ifndef USE_RPCOUT +DigitalOut led1(LED1), led2(LED2), led3(LED3), led4(LED4); +PwmOut sv0(p21), sv1(p22), sv2(p23); +#else +RpcDigitalOut led1(LED1, "led1"); +RpcDigitalOut led2(LED2, "led2"); +RpcDigitalOut led3(LED3, "led3"); +RpcDigitalOut led4(LED4, "led4"); + +RpcPwmOut sv0(p21, "sv0"); +RpcPwmOut sv1(p22, "sv1"); +RpcPwmOut sv2(p23, "sv2"); +#endif + + +LocalFileSystem local("webfs"); + +OV7670 camera( + p9,p10, // SDA,SCL(I2C / SCCB) + p5,p6,p7, // VSYNC,HREF,WEN(FIFO) + p20,p19,p18,p17,p16,p15,p14,p13, // D7-D0 + p8,p11,p12); // RRST,OE,RCLK + +//Timer tmr; + +#define QQVGA +//#define QVGA +//#define VGA34 + +#ifdef QQVGA +#define SIZEX 160 +#define SIZEY 120 +#endif + +#ifdef QVGA +#define SIZEX 320 +#define SIZEY 240 +#endif + +#ifdef VGA34 +#define SIZEX 480 +#define SIZEY 360 +#endif + + +//void cam_cap(void); +void cam_cap(Arguments* input, Reply* output); +RPCFunction rpcFunc(&cam_cap, "cam_cap"); + +#ifndef USE_RPCOUT +float sv0_rpc; +float sv1_rpc; +float sv2_rpc; + +RPCVariable<float> rpc_sv0_val(&sv0_rpc, "sv0"); +RPCVariable<float> rpc_sv1_val(&sv1_rpc, "sv1"); +RPCVariable<float> rpc_sv2_val(&sv2_rpc, "sv2"); +#endif + +int cap_flag; +RPCVariable<int> rpc_cap_flag(&cap_flag, "cap_flag"); + + +int memfree(void) +{ + int ret = 1; + while (1) { + char *p = (char *)malloc(ret); + if (p == NULL) + break; + free(p); + ret++; + } + return (ret); +} + + +float deg_to_pulsewidth(float deg) +{ + // limit range + if (deg < -90.0f) + deg = -90.0f; + else if (deg > 90.0f) + deg = 90.0f; + + // return result + return (0.00145f + 0.001f * (deg / 90.0f)); +} + +int main() +{ + float sv0_val, sv1_val, sv2_val; + +#ifndef USE_RPCOUT + led1 = 0; + led2 = 0; + led3 = 0; + led4 = 0; +#else + led1.write(0); + led2.write(0); + led3.write(0); + led4.write(0); +#endif + +#ifdef USE_RPCOUT + sv0_val = 0.00045f; // unit: sec + sv1_val = 0.00145f; // unit: sec + sv2_val = 0.00245f; // unit: sec + + sv0.period(0.02f); // unit: sec + sv0.pulsewidth(sv0_val); + + sv1.period(0.02f); // unit: sec + sv1.pulsewidth(sv1_val); + + sv2.period(0.02f); // unit: sec + sv2.pulsewidth(sv2_val); + +#else + sv0_val = 0.0f; // unit: deg + sv1_val = 0.0f; // unit: deg + sv2_val = 0.0f; // unit: deg + + sv0.period(0.02f); // unit: sec + sv0.pulsewidth(deg_to_pulsewidth(sv0_val)); + + sv1.period(0.02f); // unit: sec + sv1.pulsewidth(deg_to_pulsewidth(sv1_val)); + + sv2.period(0.02f); // unit: sec + sv2.pulsewidth(deg_to_pulsewidth(sv2_val)); + + sv0_rpc = sv0_val; + sv1_rpc = sv1_val; + sv2_rpc = sv2_val; +#endif + + cap_flag = 0; + + //////////////////////////////////////////////////////////////////////////// + camera.WriteReg(0x12, 0x80); // com7; reset + wait_ms(200); + + camera.InitDefaultReg(); + + // negate vsync + camera.WriteReg(0x15, 0x02); // com10; negative vsync + +#ifdef QQVGA + camera.InitQQVGA(); +#endif +#ifdef QVGA + camera.InitQVGA(); +#endif +#ifdef VGA34 + camera.InitVGA_3_4(); +#endif + + // data format + camera.WriteReg(0x12, 0x04 + 0); // com7 RGB (bit1...test pattern) + camera.WriteReg(0x40, 0xD0); // com15 RGB565 + camera.WriteReg(0x8c, 0x00); // RGB444 + + wait_ms(300); + +//{ +//FILE *f = fopen("/webfs/REG.TXT", "wt"); +//for (int i = 0; i < 256; i++) { +// int val = camera.ReadReg(i); +// fprintf(f, "%02X ", val); +// if ((i % 16) == 15) +// fprintf(f, "\n"); +//} +//fclose(f); +//} + + ////////////////////////////////////////////////// + + // network + EthernetInterface eth; // locate here + +// //Static IP +// char *ip = "192.168.0.20"; +// char *mask = "255.255.255.0"; +// char *gateway = "192.168.0.1"; +// eth.init(ip, mask, gateway); + //DHCP + eth.init(); + + eth.connect(); + + lcd.locate(0, 0); + lcd.printf("IP %s", eth.getIPAddress()); + + // rcp +#ifdef USE_RPCOUT +// RPC::add_rpc_class<RpcDigitalIn>(); // read + RPC::add_rpc_class<RpcDigitalOut>(); // read,write +// RPC::add_rpc_class<RpcDigitalInOut>(); // read,write,input,output + RPC::add_rpc_class<RpcPwmOut>(); // read,write,period,period_ms,pulsewidth,pulsewidth_ms +// RPC::add_rpc_class<RpcAnalogIn>(); // read,read_u16 +// RPC::add_rpc_class<RpcAnalogOut>(); // read,write,write_u16 +// RPC::add_rpc_class<RpcSPI>(); // format,frequency,write +// RPC::add_rpc_class<RpcSerial>(); // baud,readable,writeable(SPELL?),putc,getc,puts +// RPC::add_rpc_class<RpcTimer>(); // start,stop,reset,read,read_ms,read_us +#endif + + // http + HTTPServer svr; // locate here + HTTPFsRequestHandler::mount("/webfs/", "/"); + svr.addHandler<HTTPFsRequestHandler>("/"); + svr.addHandler<HTTPRpcRequestHandler>("/rpc"); + + svr.start(80, ð); + +// lcd.locate(0, 1); +// lcd.printf("mem %d", memfree()); + +#ifndef USE_RPCOUT + led1 = 1; +#else + led1.write(1); +#endif + + while (1) { + svr.poll(); + +#ifndef USE_RPCOUT + if (sv0_val != sv0_rpc) { + sv0_val = sv0_rpc; + // limit + if (sv0_val < -90.0f) + sv0_val = -90.0f; + else if (sv0_val > 90.0f) + sv0_val = 90.0f; + + sv0_rpc = sv0_val; + sv0.pulsewidth(deg_to_pulsewidth(sv0_val)); + + lcd.locate(0, 1); + lcd.printf("0:%f ", sv0_val); + } + + if (sv1_val != sv1_rpc) { + sv1_val = sv1_rpc; + // limit + if (sv1_val < -90.0f) + sv1_val = -90.0f; + else if (sv1_val > 90.0f) + sv1_val = 90.0f; + + sv1_rpc = sv1_val; + sv1.pulsewidth(deg_to_pulsewidth(sv1_val)); + + lcd.locate(0, 1); + lcd.printf("1:%f ", sv1_val); + } + + if (sv2_val != sv2_rpc) { + sv2_val = sv2_rpc; + // limit + if (sv2_val < -90.0f) + sv2_val = -90.0f; + else if (sv2_val > 90.0f) + sv2_val = 90.0f; + + sv2_rpc = sv2_val; + sv2.pulsewidth(deg_to_pulsewidth(sv2_val)); + + lcd.locate(0, 1); + lcd.printf("2:%f ", sv2_val); + } +#endif + + wait_ms(10); + } +} + + +//void cam_capture(char *input, char *output) // compile error +void cam_cap(Arguments* input, Reply* output) +//void cam_cap(void) +{ + FILE *fp_bmp; + unsigned int d1, d2; + unsigned char sort[3]; + +#ifndef USE_RPCOUT + led2 = 1; +#else + led2.write(1); +#endif + + cap_flag = 0; + + fp_bmp = fopen("/webfs/cam.bmp", "wb"); + + ///////////////////////// + // file header + ///////////////////////// + fprintf(fp_bmp, "BM"); + int val = 14 + 40 + SIZEX * SIZEY * 3; // file size + fprintf(fp_bmp, "%c%c%c%c", val % 0x100, val / 0x100, val / 0x10000, val / 0x1000000); + fprintf(fp_bmp, "%c%c%c%c%c%c%c%c", 0, 0, 0, 0, 0x36, 0, 0, 0); + + ///////////////////////// + // information header + ///////////////////////// + fprintf(fp_bmp, "%c%c%c%c", 0x28, 0, 0, 0); // header size + fprintf(fp_bmp, "%c%c%c%c", SIZEX % 0x100, SIZEX / 0x100, SIZEX / 0x10000, SIZEX / 0x1000000); + fprintf(fp_bmp, "%c%c%c%c", SIZEY % 0x100, SIZEY / 0x100, SIZEY / 0x10000, SIZEY / 0x1000000); + fprintf(fp_bmp, "%c%c", 1, 0); // # of plane + fprintf(fp_bmp, "%c%c", 24, 0); // bit count + fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); // compression + val = SIZEX * SIZEY * 3; // data size + fprintf(fp_bmp, "%c%c%c%c", val % 0x100, val / 0x100, val / 0x10000, val / 0x1000000); + fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); + fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); + fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); + fprintf(fp_bmp, "%c%c%c%c", 0, 0, 0, 0); + + camera.CaptureNext(); // sample start! + + while(camera.CaptureDone() == false) + ; + + camera.ReadStart(); // reset pointer + +#ifndef USE_RPCOUT + led3 = 1; +#else + led3.write(1); +#endif + + for (int y = 0;y < SIZEY;y++) { + for (int x = 0;x < SIZEX;x++) { + d1 = camera.ReadOneByte() ; // upper nibble is XXX , lower nibble is B + d2 = camera.ReadOneByte() ; // upper nibble is G , lower nibble is R + + // RGB565 + sort[0] = ((d1 & 0xF8) >> 3) << 3; // R + sort[1] = ( ((d1 & 0x07) << 3) + ((d2 & 0xE0) >> 5) ) << 2; // G + sort[2] = (d2 & 0x1F) << 3; // B + + fprintf(fp_bmp, "%c%c%c", sort[2], sort[1], sort[0]); // B,G,R + } + } + + camera.ReadStop(); + fclose(fp_bmp); + +#ifndef USE_RPCOUT + led2 = 0; + led3 = 0; + led4 = 0; +#else + led2.write(0); + led3.write(0); + led4.write(0); +#endif + + cap_flag = 1; +} + +// end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rpc.lib Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rpc/#4490a0d9cb2a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#5dfe422a963d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/8a40adfe8776 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ov7670.h Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,584 @@ +// This code was written by Mr.Sadaei Osakabe. +// Original code is located at +// https://mbed.org/users/diasea/code/OV7670_with_AL422B_Color_Size_test/ + +#include "mbed.h" +#include "ov7670reg.h" + +#define OV7670_WRITE (0x42) +#define OV7670_READ (0x43) +#define OV7670_WRITEWAIT (20) +#define OV7670_NOACK (0) +#define OV7670_REGMAX (201) +#define OV7670_I2CFREQ (50000) + +// +// OV7670 + FIFO AL422B camera board test +// +class OV7670 +{ +public: + I2C camera; + InterruptIn vsync,href; + DigitalOut wen; + BusIn data; + DigitalOut rrst,oe,rclk; + volatile int LineCounter; + volatile int LastLines; + volatile bool CaptureReq; + volatile bool Busy; + volatile bool Done; + + OV7670( + PinName sda,// Camera I2C port + PinName scl,// Camera I2C port + PinName vs, // VSYNC + PinName hr, // HREF + PinName we, // WEN + PinName d7, // D7 + PinName d6, // D6 + PinName d5, // D5 + PinName d4, // D4 + PinName d3, // D3 + PinName d2, // D2 + PinName d1, // D1 + PinName d0, // D0 + PinName rt, // /RRST + PinName o, // /OE + PinName rc // RCLK + ) : camera(sda,scl),vsync(vs),href(hr),wen(we),data(d0,d1,d2,d3,d4,d5,d6,d7),rrst(rt),oe(o),rclk(rc) + { + camera.stop(); + camera.frequency(OV7670_I2CFREQ); + vsync.fall(this,&OV7670::VsyncHandler); + href.rise(this,&OV7670::HrefHandler); + CaptureReq = false; + Busy = false; + Done = false; + LineCounter = 0; + rrst = 1; + oe = 1; + rclk = 1; + wen = 0; + } + + // capture request + void CaptureNext(void) + { + CaptureReq = true; + Busy = true; + } + + // capture done? (with clear) + bool CaptureDone(void) + { + bool result; + if (Busy) { + result = false; + } else { + result = Done; + Done = false; + } + return result; + } + + // write to camera + void WriteReg(int addr,int data) + { + // WRITE 0x42,ADDR,DATA + camera.start(); + camera.write(OV7670_WRITE); + wait_us(OV7670_WRITEWAIT); + camera.write(addr); + wait_us(OV7670_WRITEWAIT); + camera.write(data); + camera.stop(); + } + + // read from camera + int ReadReg(int addr) + { + int data; + + // WRITE 0x42,ADDR + camera.start(); + camera.write(OV7670_WRITE); + wait_us(OV7670_WRITEWAIT); + camera.write(addr); + camera.stop(); + wait_us(OV7670_WRITEWAIT); + + // WRITE 0x43,READ + camera.start(); + camera.write(OV7670_READ); + wait_us(OV7670_WRITEWAIT); + data = camera.read(OV7670_NOACK); + camera.stop(); + + return data; + } + + // print register + void PrintRegister(void) { + printf("AD : +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F"); + for (int i=0;i<OV7670_REGMAX;i++) { + int data; + data = ReadReg(i); // READ REG + if ((i & 0x0F) == 0) { + printf("\r\n%02X : ",i); + } + printf("%02X ",data); + } + printf("\r\n"); + } + + void Reset(void) { + WriteReg(REG_COM7,COM7_RESET); // RESET CAMERA + wait_ms(200); + } + + void InitForFIFOWriteReset(void) { + WriteReg(REG_COM10, COM10_VS_NEG); + } + + void InitSetColorbar(void) { + int reg_com7 = ReadReg(REG_COM7); + // color bar + WriteReg(REG_COM17, reg_com7|COM17_CBAR); + } + + void InitDefaultReg(void) { + // Gamma curve values + WriteReg(0x7a, 0x20); + WriteReg(0x7b, 0x10); + WriteReg(0x7c, 0x1e); + WriteReg(0x7d, 0x35); + WriteReg(0x7e, 0x5a); + WriteReg(0x7f, 0x69); + WriteReg(0x80, 0x76); + WriteReg(0x81, 0x80); + WriteReg(0x82, 0x88); + WriteReg(0x83, 0x8f); + WriteReg(0x84, 0x96); + WriteReg(0x85, 0xa3); + WriteReg(0x86, 0xaf); + WriteReg(0x87, 0xc4); + WriteReg(0x88, 0xd7); + WriteReg(0x89, 0xe8); + + // AGC and AEC parameters. Note we start by disabling those features, + //then turn them only after tweaking the values. + WriteReg(REG_COM8, COM8_FASTAEC | COM8_AECSTEP | COM8_BFILT); + WriteReg(REG_GAIN, 0); + WriteReg(REG_AECH, 0); + WriteReg(REG_COM4, 0x40); + // magic reserved bit + WriteReg(REG_COM9, 0x18); + // 4x gain + magic rsvd bit + WriteReg(REG_BD50MAX, 0x05); + WriteReg(REG_BD60MAX, 0x07); + WriteReg(REG_AEW, 0x95); + WriteReg(REG_AEB, 0x33); + WriteReg(REG_VPT, 0xe3); + WriteReg(REG_HAECC1, 0x78); + WriteReg(REG_HAECC2, 0x68); + WriteReg(0xa1, 0x03); + // magic + WriteReg(REG_HAECC3, 0xd8); + WriteReg(REG_HAECC4, 0xd8); + WriteReg(REG_HAECC5, 0xf0); + WriteReg(REG_HAECC6, 0x90); + WriteReg(REG_HAECC7, 0x94); + WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC); + + // Almost all of these are magic "reserved" values. + WriteReg(REG_COM5, 0x61); + WriteReg(REG_COM6, 0x4b); + WriteReg(0x16, 0x02); + WriteReg(REG_MVFP, 0x07); + WriteReg(0x21, 0x02); + WriteReg(0x22, 0x91); + WriteReg(0x29, 0x07); + WriteReg(0x33, 0x0b); + WriteReg(0x35, 0x0b); + WriteReg(0x37, 0x1d); + WriteReg(0x38, 0x71); + WriteReg(0x39, 0x2a); + WriteReg(REG_COM12, 0x78); + WriteReg(0x4d, 0x40); + WriteReg(0x4e, 0x20); + WriteReg(REG_GFIX, 0); + WriteReg(0x6b, 0x0a); + WriteReg(0x74, 0x10); + WriteReg(0x8d, 0x4f); + WriteReg(0x8e, 0); + WriteReg(0x8f, 0); + WriteReg(0x90, 0); + WriteReg(0x91, 0); + WriteReg(0x96, 0); + WriteReg(0x9a, 0); + WriteReg(0xb0, 0x84); + WriteReg(0xb1, 0x0c); + WriteReg(0xb2, 0x0e); + WriteReg(0xb3, 0x82); + WriteReg(0xb8, 0x0a); + + // More reserved magic, some of which tweaks white balance + WriteReg(0x43, 0x0a); + WriteReg(0x44, 0xf0); + WriteReg(0x45, 0x34); + WriteReg(0x46, 0x58); + WriteReg(0x47, 0x28); + WriteReg(0x48, 0x3a); + WriteReg(0x59, 0x88); + WriteReg(0x5a, 0x88); + WriteReg(0x5b, 0x44); + WriteReg(0x5c, 0x67); + WriteReg(0x5d, 0x49); + WriteReg(0x5e, 0x0e); + WriteReg(0x6c, 0x0a); + WriteReg(0x6d, 0x55); + WriteReg(0x6e, 0x11); + WriteReg(0x6f, 0x9f); + // "9e for advance AWB" + WriteReg(0x6a, 0x40); + WriteReg(REG_BLUE, 0x40); + WriteReg(REG_RED, 0x60); + WriteReg(REG_COM8, COM8_FASTAEC|COM8_AECSTEP|COM8_BFILT|COM8_AGC|COM8_AEC|COM8_AWB); + + // Matrix coefficients + WriteReg(0x4f, 0x80); + WriteReg(0x50, 0x80); + WriteReg(0x51, 0); + WriteReg(0x52, 0x22); + WriteReg(0x53, 0x5e); + WriteReg(0x54, 0x80); + WriteReg(0x58, 0x9e); + + WriteReg(REG_COM16, COM16_AWBGAIN); + WriteReg(REG_EDGE, 0); + WriteReg(0x75, 0x05); + WriteReg(0x76, 0xe1); + WriteReg(0x4c, 0); + WriteReg(0x77, 0x01); + WriteReg(0x4b, 0x09); + WriteReg(0xc9, 0x60); + WriteReg(REG_COM16, 0x38); + WriteReg(0x56, 0x40); + + WriteReg(0x34, 0x11); + WriteReg(REG_COM11, COM11_EXP|COM11_HZAUTO_ON); + WriteReg(0xa4, 0x88); + WriteReg(0x96, 0); + WriteReg(0x97, 0x30); + WriteReg(0x98, 0x20); + WriteReg(0x99, 0x30); + WriteReg(0x9a, 0x84); + WriteReg(0x9b, 0x29); + WriteReg(0x9c, 0x03); + WriteReg(0x9d, 0x4c); + WriteReg(0x9e, 0x3f); + WriteReg(0x78, 0x04); + + // Extra-weird stuff. Some sort of multiplexor register + WriteReg(0x79, 0x01); + WriteReg(0xc8, 0xf0); + WriteReg(0x79, 0x0f); + WriteReg(0xc8, 0x00); + WriteReg(0x79, 0x10); + WriteReg(0xc8, 0x7e); + WriteReg(0x79, 0x0a); + WriteReg(0xc8, 0x80); + WriteReg(0x79, 0x0b); + WriteReg(0xc8, 0x01); + WriteReg(0x79, 0x0c); + WriteReg(0xc8, 0x0f); + WriteReg(0x79, 0x0d); + WriteReg(0xc8, 0x20); + WriteReg(0x79, 0x09); + WriteReg(0xc8, 0x80); + WriteReg(0x79, 0x02); + WriteReg(0xc8, 0xc0); + WriteReg(0x79, 0x03); + WriteReg(0xc8, 0x40); + WriteReg(0x79, 0x05); + WriteReg(0xc8, 0x30); + WriteReg(0x79, 0x26); + } + + void InitRGB444(void){ + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7, reg_com7|COM7_RGB); + WriteReg(REG_RGB444, RGB444_ENABLE|RGB444_XBGR); + WriteReg(REG_COM15, COM15_R01FE|COM15_RGB444); + + WriteReg(REG_COM1, 0x40); // Magic reserved bit + WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit + WriteReg(0x4f, 0xb3); // "matrix coefficient 1" + WriteReg(0x50, 0xb3); // "matrix coefficient 2" + WriteReg(0x51, 0x00); // vb + WriteReg(0x52, 0x3d); // "matrix coefficient 4" + WriteReg(0x53, 0xa7); // "matrix coefficient 5" + WriteReg(0x54, 0xe4); // "matrix coefficient 6" + WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2); // Magic rsvd bit + + WriteReg(REG_TSLB, 0x04); + } + + void InitRGB555(void){ + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7, reg_com7|COM7_RGB); + WriteReg(REG_RGB444, RGB444_DISABLE); + WriteReg(REG_COM15, COM15_RGB555|COM15_R00FF); + + WriteReg(REG_TSLB, 0x04); + + WriteReg(REG_COM1, 0x00); + WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit + WriteReg(0x4f, 0xb3); // "matrix coefficient 1" + WriteReg(0x50, 0xb3); // "matrix coefficient 2" + WriteReg(0x51, 0x00); // vb + WriteReg(0x52, 0x3d); // "matrix coefficient 4" + WriteReg(0x53, 0xa7); // "matrix coefficient 5" + WriteReg(0x54, 0xe4); // "matrix coefficient 6" + WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT); + } + + void InitRGB565(void){ + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7, reg_com7|COM7_RGB); + WriteReg(REG_RGB444, RGB444_DISABLE); + WriteReg(REG_COM15, COM15_R00FF|COM15_RGB565); + + WriteReg(REG_TSLB, 0x04); + + WriteReg(REG_COM1, 0x00); + WriteReg(REG_COM9, 0x38); // 16x gain ceiling; 0x8 is reserved bit + WriteReg(0x4f, 0xb3); // "matrix coefficient 1" + WriteReg(0x50, 0xb3); // "matrix coefficient 2" + WriteReg(0x51, 0x00); // vb + WriteReg(0x52, 0x3d); // "matrix coefficient 4" + WriteReg(0x53, 0xa7); // "matrix coefficient 5" + WriteReg(0x54, 0xe4); // "matrix coefficient 6" + WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT); + } + + void InitYUV(void){ + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7, reg_com7|COM7_YUV); + WriteReg(REG_RGB444, RGB444_DISABLE); + WriteReg(REG_COM15, COM15_R00FF); + + WriteReg(REG_TSLB, 0x04); +// WriteReg(REG_TSLB, 0x14); +// WriteReg(REG_MANU, 0x00); +// WriteReg(REG_MANV, 0x00); + + WriteReg(REG_COM1, 0x00); + WriteReg(REG_COM9, 0x18); // 4x gain ceiling; 0x8 is reserved bit + WriteReg(0x4f, 0x80); // "matrix coefficient 1" + WriteReg(0x50, 0x80); // "matrix coefficient 2" + WriteReg(0x51, 0x00); // vb + WriteReg(0x52, 0x22); // "matrix coefficient 4" + WriteReg(0x53, 0x5e); // "matrix coefficient 5" + WriteReg(0x54, 0x80); // "matrix coefficient 6" + WriteReg(REG_COM13, COM13_GAMMA|COM13_UVSAT|COM13_UVSWAP); + } + + void InitBayerRGB(void){ + int reg_com7 = ReadReg(REG_COM7); + + // odd line BGBG... even line GRGR... + WriteReg(REG_COM7, reg_com7|COM7_BAYER); + // odd line GBGB... even line RGRG... + //WriteReg(REG_COM7, reg_com7|COM7_PBAYER); + + WriteReg(REG_RGB444, RGB444_DISABLE); + WriteReg(REG_COM15, COM15_R00FF); + + WriteReg(REG_COM13, 0x08); /* No gamma, magic rsvd bit */ + WriteReg(REG_COM16, 0x3d); /* Edge enhancement, denoise */ + WriteReg(REG_REG76, 0xe1); /* Pix correction, magic rsvd */ + + WriteReg(REG_TSLB, 0x04); + } + + void InitVGA(void) { + // VGA + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7,reg_com7|COM7_VGA); + + WriteReg(REG_HSTART,HSTART_VGA); + WriteReg(REG_HSTOP,HSTOP_VGA); + WriteReg(REG_HREF,HREF_VGA); + WriteReg(REG_VSTART,VSTART_VGA); + WriteReg(REG_VSTOP,VSTOP_VGA); + WriteReg(REG_VREF,VREF_VGA); + WriteReg(REG_COM3, COM3_VGA); + WriteReg(REG_COM14, COM14_VGA); + WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA); + WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA); + WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA); + WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA); + WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA); + } + + void InitFIFO_2bytes_color_nealy_limit_size(void) { + // nealy FIFO limit 544x360 + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7,reg_com7|COM7_VGA); + + WriteReg(REG_HSTART,HSTART_VGA); + WriteReg(REG_HSTOP,HSTOP_VGA); + WriteReg(REG_HREF,HREF_VGA); + WriteReg(REG_VSTART,VSTART_VGA); + WriteReg(REG_VSTOP,VSTOP_VGA); + WriteReg(REG_VREF,VREF_VGA); + WriteReg(REG_COM3, COM3_VGA); + WriteReg(REG_COM14, COM14_VGA); + WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA); + WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA); + WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA); + WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA); + WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA); + + WriteReg(REG_HSTART, 0x17); + WriteReg(REG_HSTOP, 0x5b); + WriteReg(REG_VSTART, 0x12); + WriteReg(REG_VSTOP, 0x6c); + } + + void InitVGA_3_4(void) { + // VGA 3/4 -> 480x360 + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7,reg_com7|COM7_VGA); + + WriteReg(REG_HSTART,HSTART_VGA); + WriteReg(REG_HSTOP,HSTOP_VGA); + WriteReg(REG_HREF,HREF_VGA); + WriteReg(REG_VSTART,VSTART_VGA); + WriteReg(REG_VSTOP,VSTOP_VGA); + WriteReg(REG_VREF,VREF_VGA); + WriteReg(REG_COM3, COM3_VGA); + WriteReg(REG_COM14, COM14_VGA); + WriteReg(REG_SCALING_XSC, SCALING_XSC_VGA); + WriteReg(REG_SCALING_YSC, SCALING_YSC_VGA); + WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_VGA); + WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_VGA); + WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_VGA); + + WriteReg(REG_HSTART, 0x1b); + WriteReg(REG_HSTOP, 0x57); + WriteReg(REG_VSTART, 0x12); + WriteReg(REG_VSTOP, 0x6c); + } + + void InitQVGA(void) { + // QQVGA + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7,reg_com7|COM7_QVGA); + + WriteReg(REG_HSTART,HSTART_QVGA); + WriteReg(REG_HSTOP,HSTOP_QVGA); + WriteReg(REG_HREF,HREF_QVGA); + WriteReg(REG_VSTART,VSTART_QVGA); + WriteReg(REG_VSTOP,VSTOP_QVGA); + WriteReg(REG_VREF,VREF_QVGA); + WriteReg(REG_COM3, COM3_QVGA); + WriteReg(REG_COM14, COM14_QVGA); + WriteReg(REG_SCALING_XSC, SCALING_XSC_QVGA); + WriteReg(REG_SCALING_YSC, SCALING_YSC_QVGA); + WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QVGA); + WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QVGA); + WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QVGA); + } + + void InitQQVGA(void) { + // QQVGA + int reg_com7 = ReadReg(REG_COM7); + + WriteReg(REG_COM7,reg_com7|COM7_QQVGA); + + WriteReg(REG_HSTART,HSTART_QQVGA); + WriteReg(REG_HSTOP,HSTOP_QQVGA); + WriteReg(REG_HREF,HREF_QQVGA); + WriteReg(REG_VSTART,VSTART_QQVGA); + WriteReg(REG_VSTOP,VSTOP_QQVGA); + WriteReg(REG_VREF,VREF_QQVGA); + WriteReg(REG_COM3, COM3_QQVGA); + WriteReg(REG_COM14, COM14_QQVGA); + WriteReg(REG_SCALING_XSC, SCALING_XSC_QQVGA); + WriteReg(REG_SCALING_YSC, SCALING_YSC_QQVGA); + WriteReg(REG_SCALING_DCWCTR, SCALING_DCWCTR_QQVGA); + WriteReg(REG_SCALING_PCLK_DIV, SCALING_PCLK_DIV_QQVGA); + WriteReg(REG_SCALING_PCLK_DELAY, SCALING_PCLK_DELAY_QQVGA); + } + + // vsync handler + void 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 HrefHandler(void) + { + LineCounter++; + } + + // Data Read + int ReadOneByte(void) + { + int result; + rclk = 1; +// wait_us(1); + result = data; + rclk = 0; + return result; + } + + // Data Start + void ReadStart(void) + { + rrst = 0; + oe = 0; + wait_us(1); + rclk = 0; + wait_us(1); + rclk = 1; + wait_us(1); + rrst = 1; + } + + // Data Stop + void ReadStop(void) + { + oe = 1; + ReadOneByte(); + rclk = 1; + } +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ov7670reg.h Tue Aug 26 16:49:26 2014 +0000 @@ -0,0 +1,259 @@ +// This code was written by Mr.Sadaei Osakabe. +// Original code is located at +// https://mbed.org/users/diasea/code/OV7670_with_AL422B_Color_Size_test/ + +// size register +#define REG_COM7 0x12 /* Control 7 */ +#define REG_HSTART 0x17 /* Horiz start high bits */ +#define REG_HSTOP 0x18 /* Horiz stop high bits */ +#define REG_HREF 0x32 /* HREF pieces */ +#define REG_VSTART 0x19 /* Vert start high bits */ +#define REG_VSTOP 0x1a /* Vert stop high bits */ +#define REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ +#define REG_COM3 0x0c /* Control 3 */ +#define REG_COM14 0x3e /* Control 14 */ +#define REG_SCALING_XSC 0x70 +#define REG_SCALING_YSC 0x71 +#define REG_SCALING_DCWCTR 0x72 +#define REG_SCALING_PCLK_DIV 0x73 +#define REG_SCALING_PCLK_DELAY 0xa2 + +// VGA setting +#define COM7_VGA 0x00 +#define HSTART_VGA 0x13 +#define HSTOP_VGA 0x01 +#define HREF_VGA 0x36 //0xb6 0x36 +#define VSTART_VGA 0x02 +#define VSTOP_VGA 0x7a +#define VREF_VGA 0x0a +#define COM3_VGA 0x00 +#define COM14_VGA 0x00 +#define SCALING_XSC_VGA 0x3a +#define SCALING_YSC_VGA 0x35 +#define SCALING_DCWCTR_VGA 0x11 +#define SCALING_PCLK_DIV_VGA 0xf0 +#define SCALING_PCLK_DELAY_VGA 0x02 + +// QVGA setting +#define COM7_QVGA 0x00 +#define HSTART_QVGA 0x16 +#define HSTOP_QVGA 0x04 +#define HREF_QVGA 0x00 +#define VSTART_QVGA 0x02 +#define VSTOP_QVGA 0x7a +#define VREF_QVGA 0x0a +#define COM3_QVGA 0x04 +#define COM14_QVGA 0x19 +#define SCALING_XSC_QVGA 0x3a +#define SCALING_YSC_QVGA 0x35 +#define SCALING_DCWCTR_QVGA 0x11 +#define SCALING_PCLK_DIV_QVGA 0xf1 +#define SCALING_PCLK_DELAY_QVGA 0x02 + +// QQVGA setting +#define COM7_QQVGA 0x00 +#define HSTART_QQVGA 0x16 +#define HSTOP_QQVGA 0x04 +#define HREF_QQVGA 0xa4 //0x24? 0xa4? +#define VSTART_QQVGA 0x02 +#define VSTOP_QQVGA 0x7a +#define VREF_QQVGA 0x0a +#define COM3_QQVGA 0x04 +#define COM14_QQVGA 0x1a +#define SCALING_XSC_QQVGA 0x3a +#define SCALING_YSC_QQVGA 0x35 +#define SCALING_DCWCTR_QQVGA 0x22 +#define SCALING_PCLK_DIV_QQVGA 0xf2 +#define SCALING_PCLK_DELAY_QQVGA 0x02 + +// CIF setting no tested linux src 2.6.29-rc5 ov7670_soc.c +#define COM7_CIF 0x00 +#define HSTART_CIF 0x15 +#define HSTOP_CIF 0x0b +#define HREF_CIF 0xb6 +#define VSTART_CIF 0x03 +#define VSTOP_CIF 0x7b +#define VREF_CIF 0x02 +#define COM3_CIF 0x08 +#define COM14_CIF 0x11 +#define SCALING_XSC_CIF 0x3a +#define SCALING_YSC_CIF 0x35 +#define SCALING_DCWCTR_CIF 0x11 +#define SCALING_PCLK_DIV_CIF 0xf1 +#define SCALING_PCLK_DELAY_CIF 0x02 + +// QCIF setting no tested no tested linux src 2.6.29-rc5 ov7670_soc.c +#define COM7_QCIF 0x00 +#define HSTART_QCIF 0x39 +#define HSTOP_QCIF 0x03 +#define HREF_QCIF 0x80 +#define VSTART_QCIF 0x03 +#define VSTOP_QCIF 0x7b +#define VREF_QCIF 0x02 +#define COM3_QCIF 0x0c +#define COM14_QCIF 0x11 +#define SCALING_XSC_QCIF 0x3a +#define SCALING_YSC_QCIF 0x35 +#define SCALING_DCWCTR_QCIF 0x11 +#define SCALING_PCLK_DIV_QCIF 0xf1 +#define SCALING_PCLK_DELAY_QCIF 0x52 + +// YUV +#define REG_COM13 0x3d /* Control 13 */ +#define REG_TSLB 0x3a /* lots of stuff */ + +#define COM7_YUV 0x00 /* YUV */ +#define COM13_UV 0x00 /* U before V - w/TSLB */ +#define COM13_UVSWAP 0x01 /* V before U - w/TSLB */ +#define TSLB_VLAST 0x00 /* YUYV - see com13 */ +#define TSLB_ULAST 0x00 /* YVYU - see com13 */ +#define TSLB_YLAST 0x08 /* UYVY or VYUY - see com13 */ + +// RGB +#define COM7_RGB 0x04 /* bits 0 and 2 - RGB format */ + +// RGB444 +#define REG_RGB444 0x8c /* RGB 444 control */ +#define REG_COM15 0x40 /* Control 15 */ + +#define RGB444_ENABLE 0x02 /* Turn on RGB444, overrides 5x5 */ +#define RGB444_XBGR 0x00 +#define RGB444_BGRX 0x01 /* Empty nibble at end */ +#define COM15_RGB444 0x10 /* RGB444 output */ + +// RGB555 +#define RGB444_DISABLE 0x00 /* Turn off RGB444, overrides 5x5 */ +#define COM15_RGB555 0x30 /* RGB555 output */ + +// RGB565 +#define COM15_RGB565 0x10 /* RGB565 output */ + +// Bayer RGB +#define COM7_BAYER 0x01 /* Bayer format */ +#define COM7_PBAYER 0x05 /* "Processed bayer" */ + + +// data format +#define COM15_R10F0 0x00 /* Data range 10 to F0 */ +#define COM15_R01FE 0x80 /* 01 to FE */ +#define COM15_R00FF 0xc0 /* 00 to FF */ + +// Night mode, flicker, banding / +#define REG_COM11 0x3b /* Control 11 */ +#define COM11_NIGHT 0x80 /* NIght mode enable */ +#define COM11_NIGHT_MIN_RATE_1_1 0x00 /* Normal mode same */ +#define COM11_NIGHT_MIN_RATE_1_2 0x20 /* Normal mode 1/2 */ +#define COM11_NIGHT_MIN_RATE_1_4 0x40 /* Normal mode 1/4 */ +#define COM11_NIGHT_MIN_RATE_1_8 0x60 /* Normal mode 1/5 */ +#define COM11_HZAUTO_ON 0x10 /* Auto detect 50/60 Hz on */ +#define COM11_HZAUTO_OFF 0x00 /* Auto detect 50/60 Hz off */ +#define COM11_60HZ 0x00 /* Manual 60Hz select */ +#define COM11_50HZ 0x08 /* Manual 50Hz select */ +#define COM11_EXP 0x02 + +#define REG_MTX1 0x4f +#define REG_MTX2 0x50 +#define REG_MTX3 0x51 +#define REG_MTX4 0x52 +#define REG_MTX5 0x53 +#define REG_MTX6 0x54 +#define REG_BRIGHT 0x55 /* Brightness */ +#define REG_CONTRAS 0x56 /* Contrast control */ +#define REG_CONTRAS_CENTER 0x57 +#define REG_MTXS 0x58 +#define REG_MANU 0x67 +#define REG_MANV 0x68 +#define REG_GFIX 0x69 /* Fix gain control */ +#define REG_GGAIN 0x6a +#define REG_DBLV 0x6b + +#define REG_COM9 0x14 // Control 9 - gain ceiling +#define COM9_AGC_2X 0x00 +#define COM9_AGC_4X 0x10 +#define COM9_AGC_8X 0x20 +#define COM9_AGC_16X 0x30 +#define COM9_AGC_32X 0x40 +#define COM9_AGC_64X 0x50 +#define COM9_AGC_128X 0x60 +#define COM9_AGC_MASK 0x70 +#define COM9_FREEZE 0x01 +#define COM13_GAMMA 0x80 /* Gamma enable */ +#define COM13_UVSAT 0x40 /* UV saturation auto adjustment */ +#define REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ +#define REG_BLUE 0x01 /* blue gain */ +#define REG_RED 0x02 /* red gain */ +#define REG_COM1 0x04 /* Control 1 */ +#define COM1_CCIR656 0x40 /* CCIR656 enable */ +#define REG_BAVE 0x05 /* U/B Average level */ +#define REG_GbAVE 0x06 /* Y/Gb Average level */ +#define REG_AECHH 0x07 /* AEC MS 5 bits */ +#define REG_RAVE 0x08 /* V/R Average level */ +#define REG_COM2 0x09 /* Control 2 */ +#define COM2_SSLEEP 0x10 /* Soft sleep mode */ +#define REG_PID 0x0a /* Product ID MSB */ +#define REG_VER 0x0b /* Product ID LSB */ +#define COM3_SWAP 0x40 /* Byte swap */ +#define COM3_SCALEEN 0x08 /* Enable scaling */ +#define COM3_DCWEN 0x04 /* Enable downsamp/crop/window */ +#define REG_COM4 0x0d /* Control 4 */ +#define REG_COM5 0x0e /* All "reserved" */ +#define REG_COM6 0x0f /* Control 6 */ +#define REG_AECH 0x10 /* More bits of AEC value */ +#define REG_CLKRC 0x11 /* Clocl control */ +#define CLK_EXT 0x40 /* Use external clock directly */ +#define CLK_SCALE 0x3f /* Mask for internal clock scale */ +#define COM7_RESET 0x80 /* Register reset */ +#define COM7_FMT_MASK 0x38 +#define COM7_FMT_VGA 0x00 +#define COM7_FMT_CIF 0x20 /* CIF format */ +#define COM7_FMT_QVGA 0x10 /* QVGA format */ +#define COM7_FMT_QCIF 0x08 /* QCIF format */ +#define REG_COM8 0x13 /* Control 8 */ +#define COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ +#define COM8_AECSTEP 0x40 /* Unlimited AEC step size */ +#define COM8_BFILT 0x20 /* Band filter enable */ +#define COM8_AGC 0x04 /* Auto gain enable */ +#define COM8_AWB 0x02 /* White balance enable */ +#define COM8_AEC 0x01 /* Auto exposure enable */ +#define REG_COM9 0x14 /* Control 9 - gain ceiling */ +#define REG_COM10 0x15 /* Control 10 */ +#define COM10_HSYNC 0x40 /* HSYNC instead of HREF */ +#define COM10_PCLK_HB 0x20 /* Suppress PCLK on horiz blank */ +#define COM10_HREF_REV 0x08 /* Reverse HREF */ +#define COM10_VS_LEAD 0x04 /* VSYNC on clock leading edge */ +#define COM10_VS_NEG 0x02 /* VSYNC negative */ +#define COM10_HS_NEG 0x01 /* HSYNC negative */ +#define REG_PSHFT 0x1b /* Pixel delay after HREF */ +#define REG_MIDH 0x1c /* Manuf. ID high */ +#define REG_MIDL 0x1d /* Manuf. ID low */ +#define REG_MVFP 0x1e /* Mirror / vflip */ +#define MVFP_MIRROR 0x20 /* Mirror image */ +#define MVFP_FLIP 0x10 /* Vertical flip */ +#define REG_AEW 0x24 /* AGC upper limit */ +#define REG_AEB 0x25 /* AGC lower limit */ +#define REG_VPT 0x26 /* AGC/AEC fast mode op region */ +#define REG_HSYST 0x30 /* HSYNC rising edge delay */ +#define REG_HSYEN 0x31 /* HSYNC falling edge delay */ +#define REG_COM12 0x3c /* Control 12 */ +#define COM12_HREF 0x80 /* HREF always */ +#define COM14_DCWEN 0x10 /* DCW/PCLK-scale enable */ +#define REG_EDGE 0x3f /* Edge enhancement factor */ +#define REG_COM16 0x41 /* Control 16 */ +#define COM16_AWBGAIN 0x08 /* AWB gain enable */ +#define REG_COM17 0x42 /* Control 17 */ +#define COM17_AECWIN 0xc0 /* AEC window - must match COM4 */ +#define COM17_CBAR 0x08 /* DSP Color bar */ +#define REG_CMATRIX_BASE 0x4f +#define CMATRIX_LEN 6 +#define REG_REG76 0x76 /* OV's name */ +#define R76_BLKPCOR 0x80 /* Black pixel correction enable */ +#define R76_WHTPCOR 0x40 /* White pixel correction enable */ +#define REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ +#define REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ +#define REG_BD50MAX 0xa5 /* 50hz banding step limit */ +#define REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ +#define REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ +#define REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ +#define REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ +#define REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ +#define REG_BD60MAX 0xab /* 60hz banding step limit */