📄 ov2640.c
字号:
0x7d, 0xe0, 0xff,
0x00, 0x00, 0x00
};
const static u8 OV2640_SPECIALEFFECT_GREENISH[]=
{
0xFF, 0x00, 0xff,
0x7c, 0x00, 0xff,
0x7d, 0x18, 0xf8,
0x7c, 0x05, 0xff,
0x7d, 0x53, 0xff,
0x7d, 0x4e, 0xff,
0x00, 0x00, 0x00
};
const static u8 OV2640_SPECIALEFFECT_ALLFIXED[]=
{
0xFF, 0x00, 0xff,
0x7c, 0x00, 0xff,
0x7d, 0x98, 0xf8,
0x7c, 0x05, 0xff,
0x7d, 0x33, 0xff,
0x7d, 0xcc, 0xff,
0x7d, 0x99, 0xff,
0x00, 0x00, 0x00
};
const static u8 *OV_SETTING_SPECIALEFFECT[]=
{
OV2640_SPECIALEFFECT_NEGATIVE,
OV2640_SPECIALEFFECT_GRAY,
OV2640_SPECIALEFFECT_SEPIA,
OV2640_SPECIALEFFECT_BLUISH,
OV2640_SPECIALEFFECT_REDDISH,
OV2640_SPECIALEFFECT_GREENISH,
OV2640_SPECIALEFFECT_ALLFIXED
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const static u8 OV2640_AUTOEXPOSURE_LEVEL0[]=
{
0xFF, 0x01, 0xff,
0x24, 0x20, 0xff,
0x25, 0x18, 0xff,
0x26, 0x60, 0xff,
0x00, 0x00, 0x00
};
const static u8 OV2640_AUTOEXPOSURE_LEVEL1[]=
{
0xFF, 0x01, 0xff,
0x24, 0x34, 0xff,
0x25, 0x1c, 0xff,
0x26, 0x70, 0xff,
0x00, 0x00, 0x00
};
const static u8 OV2640_AUTOEXPOSURE_LEVEL2[]=
{
0xFF, 0x01, 0xff,
0x24, 0x3e, 0xff,
0x25, 0x38, 0xff,
0x26, 0x81, 0xff,
0x00, 0x00, 0x00
};
const static u8 OV2640_AUTOEXPOSURE_LEVEL3[]=
{
0xFF, 0x01, 0xff,
0x24, 0x48, 0xff,
0x25, 0x40, 0xff,
0x26, 0x81, 0xff,
0x00, 0x00, 0x00
};
const static u8 OV2640_AUTOEXPOSURE_LEVEL4[]=
{
0xFF, 0x01, 0xff,
0x24, 0x58, 0xff,
0x25, 0x50, 0xff,
0x26, 0x92, 0xff,
0x00, 0x00, 0x00
};
const static u8 *OV_SETTING_AUTOEXPOSURE[]=
{
OV2640_AUTOEXPOSURE_LEVEL0,
OV2640_AUTOEXPOSURE_LEVEL1,
OV2640_AUTOEXPOSURE_LEVEL2,
OV2640_AUTOEXPOSURE_LEVEL3,
OV2640_AUTOEXPOSURE_LEVEL4
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const static u8 OV2640_YUV422[]=
{
0xFF, 0x00,
0x05, 0x00,
0xDA, 0x01,
0xD7, 0x01,
0x33, 0xa0, //version 1.01
0xe1, 0x67, //version 1.01
0x00, 0x00
};
const static u8 OV2640_YUV420[]=
{
0xFF, 0x00,
0x05, 0x00,
0xDA, 0x01,
0xD7, 0x1D,
0x00, 0x00
};
const static u8 OV2640_RGB565[]=
{
0xFF, 0x00,
0x05, 0x00,
0xDA, 0x08,
0x98, 0x00,
0x99, 0x00,
0x00, 0x00
};
const static u8 OV2640_RAW_SENSOR[]=
{
0x05, 0x01,
0x00, 0x00
};
const static u8 OV2640_RAW_PROCESSED[]=
{
0x05, 0x00,
0xDA, 0x04,
0x00, 0x00
};
const static u8 OV2640_JPEG[]=
{
0xFF, 0x00,
0x05, 0x00,
0xDA, 0x10,
0xD7, 0x03,
0xDF, 0x00,
0x33, 0x80,
0x3C, 0x40,
0xe1, 0x77,
0x00, 0x00
};
const static u8 *OV_SETTING_FORMAT[]=
{
OV2640_YUV422,
OV2640_YUV420,
OV2640_RGB565,
OV2640_JPEG,
NULL,
NULL,
NULL,
OV2640_RAW_SENSOR,
OV2640_RAW_PROCESSED,
NULL,
NULL
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const static u8 OV_REGS_PREVIEW[] =
{
0xFF, 0x01,
0x3D, REG3DA_SVGA,
0x11, 0x01,
0x12, 0x40,
0x17, 0x11,
0x18, 0x43,
0x19, 0x00,
0x1A, 0x4B,
0x32, 0x09,
0xFF, 0x00,
0xC0, 0x64,
0xC1, 0x4B,
0x8C, 0x00,
0x86, 0x3D,
0x00, 0x00
};
const static u8 OV_REGS_STILLIMAGE[] =
{
0xFF, 0x01,
0x12, 0x00,
0x3D, REG3DA_UXGA,
0x11, REG11A_UXGA,
0x17, 0x11,
0x18, 0x75,
0x19, 0x01,
0x1A, 0x97,
0x32, 0x36,
0x37, 0x42,
0x4f, 0xbb,
0x50, 0x9c,
0x6d, 0x80,
0x35, 0x88,
0x22, 0x0a,
0x6d, 0x80,
0xFF, 0x00,
0xC0, 0xC8,
0xC1, 0x96,
0x8C, 0x00,
0x86, 0x35,
0x00, 0x00
};
const static u8 OV_REGS_COLORMATRIX_YUV[] =
{
0x96, 0x00,
0x97, 0x08,
0x97, 0x19,
0x97, 0x02,
0x97, 0x0c,
0x97, 0x24,
0x97, 0x30,
0x97, 0x28,
0x97, 0x26,
0x97, 0x02,
0x97, 0x98,
0x97, 0x80,
0x97, 0x00,
0x97, 0x00,
0x00, 0x00
};
const static u8 OV_REGS_COLORMATRIX_YCbCr[] =
{
0x96, 0x00,
0x97, 0x08,
0x97, 0x19,
0x97, 0x02,
0x97, 0x0c,
0x97, 0x24,
0x97, 0x30,
0x97, 0x28,
0x97, 0x26,
0x97, 0x02,
0x97, 0x98,
0x97, 0x80,
0x97, 0x00,
0x97, 0x00,
0x00, 0x00
};
const static u8 OV_REGS_DEBUG[] =
{
0xff,0x00,
0xe0,0x14,
0xe1,0x77,
0xe5,0x1f,
0xd7,0x03,
0xda,0x10,
0xd3,0x04,
0xeb,0x31,
0xdd,0x7f,
0xe0,0x00,
0x00,0x00
};
static int table_write(const u8* ptab)
{
u8 address;
u8 value;
const u8 *pdata=ptab;
if ( NULL==pdata )
return -1;
while(1)
{
address=*pdata++;
value=*pdata++;
if ( (0==address) && (0==value) )
{
break;
}
ovcamerachip_reg8_write(address,value);
}
return 0;
}
static int table_mask_write(const u8* ptab)
{
u8 address;
u8 value,orgval;
u8 mask;
const u8 *pdata=ptab;
if ( NULL==pdata )
return -1;
while(1)
{
address =*pdata++;
value = *pdata++;
mask = *pdata++;
if ( (0==address) && (0==value) &&(0==mask) )
{
break;
}
if(mask != 0xFF)
{
ovcamerachip_reg8_read( address, &orgval);
orgval &= (~mask);
value &= mask;
value |=orgval;
}
ov2640print("adress = %8x value = %8x \n", address,value);
ovcamerachip_reg8_write(address,value);
}
return 0;
}
static u32 getchipclock( void )
{
u32 fclk;
u8 reg;
ovcamerachip_reg8_write(0xff,0x01);
ovcamerachip_reg8_read( 0x3D, ®);
reg = reg & 0x3F;
reg = 0x40 - reg;
fclk = g_ovcamerachip.mclock * reg /2;
ovcamerachip_reg8_read( 0x11, ®);
reg = reg & 0x3F;
reg = (reg +1)*2;
fclk = fclk / reg;
ov2640print("Current OV2640 chip clock is %8dHz\n", fclk);
return fclk;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Remove Banding
//
//
// Set all the clock related function of OV2640 before call this function
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int setBandingFilter(int lightfrequency)
{
long val;
u32 maxlines;
u32 scale;
u8 reg;
u8 reg4A;
if( (lightfrequency !=50) && (lightfrequency !=60) )
{
return -1;
}
//internal clock
val = getchipclock();
val /= 1000; //KHz
maxlines = g_ovcamerachip.stream ? 1248 : 672;
val *= maxlines;
val *= 5;
scale = g_ovcamerachip.stream ? 3 : 1;
scale *=8*2;
scale *=lightfrequency;
val = val / scale;
val += 500;
val /=1000;
ovcamerachip_reg8_write(0xff,0x01);
ovcamerachip_reg8_read(0x0c,®);
ovcamerachip_reg8_read(0x4A,®4A);
reg4A &= 0x0F;
if(lightfrequency ==50)
{
reg |= 0x04;
ovcamerachip_reg8_write(0x0C,reg);
reg = val;
ovcamerachip_reg8_write(0x4F,reg);
reg = (val>>2) & 0xC0;
}
else
{
reg &= 0xFC;
ovcamerachip_reg8_write(0x0C,reg);
reg = val;
ovcamerachip_reg8_write(0x50,reg);
reg = (val >>4) & 0x30;
}
reg4A |=reg;
ovcamerachip_reg8_write(0x4A,reg);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Gain & Exposure
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
static u32 gainreg2real16m ( u32 gainreg )
{
u32 real;
ov2640print("gainreg =%d\n",gainreg);
real = gainreg & 0x000f;
real+=16;
if( gainreg & 0x10 )
{
real = real <<1;
}
if( gainreg & 0x20 )
{
real = real <<1;
}
if( gainreg & 0x40 )
{
real = real <<1;
}
if( gainreg & 0x80 )
{
real = real <<1;
}
ov2640print("gainreal =%d\n",real);
return real;
}
static int gainreal16m2reg(u32 gainreal)
{
u32 gain;
gain = 0;
if( gainreal >31 )
{
gain |= 0x10;
gainreal = gainreal >>1;
}
if( gainreal >31 )
{
gain |= 0x20;
gainreal = gainreal >>1;
}
if( gainreal >31 )
{
gain |= 0x40;
gainreal = gainreal >>1;
}
if( gainreal >31 )
{
gain |= 0x80;
gainreal = gainreal >>1;
}
if( gainreal >16 )
{
gain |= (( gainreal -16 ) & 0x0f );
}
return gain;
}
static u32 getVideoExposureGain( void )
{
u8 reg;
u32 exposure;
u32 gain;
u32 gainreal;
ov2640print("getVideoExposureGain( + )\n");
ovcamerachip_reg8_write(0xff,0x01);
ovcamerachip_reg8_read(0x45,®);
exposure = reg & 0x3f;
exposure <<= 8;
gain = reg & 0xc0;
gain <<=2;
ovcamerachip_reg8_read(0x10,®);
exposure +=reg;
exposure <<=2;
ovcamerachip_reg8_read(0x04,®);
exposure +=(reg & 0x03);
ovcamerachip_reg8_read(0x11,®);
exposure *= (reg+1);
ovcamerachip_reg8_read(0x00,®);
gain += reg;
gainreal = gainreg2real16m( gain );
ov2640print("getVideoExposureGain( - )\n");
return exposure*gainreal;
}
static int setStillimageExposure(u32 preexpgain, u8 reg11)
{
u32 val32;
u32 wlines10ms;
u32 exposure,gain;
u8 reg8;
u64 expgain = preexpgain;
ov2640print("setStillimageExposure ( + )\n");
expgain *= 1248;
expgain *= (0x40 - REG3DA_UXGA);
val32 = 672 * (reg11+1);
val32 *= ( 0x40 - REG3DA_SVGA ); //0x3D setting of preview
val32 *= 3;
expgain += (val32/2);
expgain /=val32;
expgain = expgain *2;
wlines10ms = (65*(0x40 - REG3DA_UXGA) * (g_ovcamerachip.mclock/1000) )/(reg11+1);
wlines10ms = (wlines10ms +50000)/100000;
if( expgain < (1248 *16) )
{
exposure = expgain/16;
if(exposure > wlines10ms)
{
exposure /= wlines10ms;
exposure *= wlines10ms;
}
}
else
{
exposure =1248;
}
gain = ( expgain * 2/exposure +1 ) / 2;
gain = gainreal16m2reg ( gain );
ovcamerachip_reg8_write(0xFF,0x01);
reg8 = gain & 0xFF;
ovcamerachip_reg8_write(0x00,reg8);
ovcamerachip_reg8_read(0x45,®8);
reg8 = reg8 & 0xC0;
reg8 += (exposure >>10) & 0x3F;
ovcamerachip_reg8_write(0x45,reg8);
reg8 = exposure >>2;
ovcamerachip_reg8_write(0x10,reg8);
ovcamerachip_reg8_read(0x04,®8);
reg8 = reg8 & 0xFC;
reg8 += (u8)(exposure & 0x03);
ovcamerachip_reg8_write(0x04,reg8);
ov2640print("setStillimageExposure ( - )\n");
return 0;
}
static void agcaecswitch(int onoff)
{
u8 reg13;
ovcamerachip_reg8_write(0xff,0x01);
if(onoff ==0)
{
reg13 = 0xA0;
}
else
{
reg13 = 0xE5;
}
ovcamerachip_reg8_write(0x13,reg13);
return;
}
static int videoformat ( int format )
{
ov2640print("videoformat( + )\n");
if (( format < 0 ) || ( OVCAMERACHIP_SFT_MAX <= format ))
{
return -1;
}
if ( NULL ==OV_SETTING_FORMAT[ format ] )
{
return -1;
}
table_write((u8*)OV_SETTING_FORMAT[format]);
g_ovcamerachip.format = format;
ov2640print("videoformat( - )\n");
return 0;
}
static int camerasize ( unsigned int width, unsigned int height )
{
//u8 regval;
ov2640print("camerasize( + )\n");
if ( ( width & 0x0003 ) || (height & 0x0003))
{
return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -