?? aeawb.c
字號:
/********************************************************************************
Copyright (c) 2001 Sunplus Technology Co., Ltd.
Module Name: l1.c
Function : Level-1 function
Environment: Keil C51 Compiler
Creation : 2001/10/25 Max Hsu
***********************************************************************************/
//Note:
//AEAWB example code
//=============================================================================
//Header file
//=============================================================================
#include "general.h"
#include "main.h"
void Set_Edge( void );
#define MaxTidx (SHORT)100
#define MinTidx (SHORT)0
#define IniTidx (SHORT)15
//Video Clip AE
#define VideoEV11_index (SHORT)122
#define VideoEV10_index (SHORT)152
#define VideoMaxTidx (SHORT)375
#define VideoMinTidx (SHORT)0
#define VideoIniTidx (SHORT)232
#define VideoHiSST_1 (SHORT)60
#define VideoHiSST_2 (SHORT)40
#define VideoHiSST_3 (SHORT)30
#define LoopNo_Large (SHORT)7
#define LoopNo_Small (SHORT)3
//AWB
#define MaxAWBGain (SHORT)255
#define MinAWBGain (SHORT)64
#define NSL (SHORT)-10
#define PSL (SHORT)-128
#define NSH (SHORT)10
#define PSH (SHORT)128
#define WB_RH 2
#define WB_RL -2
#define WB_BH 2
#define WB_BL -2
#define LoopNo 3
//richie@ae0226
UCHAR L2_SetIndoorWB(void);
void InitAWB_coeffi(void);
//patch4.3@andrew@0610
void Handle_Iris(int );
void Init_iris(void);
unsigned long AE_GetShutter(int idx);
unsigned short AE_GetGain(int idx);
unsigned short AE_GetEV(int idx);
unsigned short AE_GetIndoorStdLum(void);
unsigned short AE_GetOutdoorStdLum(void);
void SetGamma(int );
xdata int Tidx,Pre_Tidx;
int wLock;
xdata int AEFlag,AWBFlag;
xdata unsigned int Pre_Gain,Gain;
xdata unsigned long Pre_Shutter,Shutter;
xdata unsigned int stdlumi;
xdata unsigned char G_Iris=1;
xdata USHORT Indoor_stdlumi;
xdata USHORT Outdoor_stdlumi;
xdata USHORT AVG_LUM,AVG_LUM2;
xdata long YY[5][5];
xdata char method;
bit AE_ON = 0;
bit AWB_ON = 0;
bit RAW_ON = 0;
//bit AE_stable = 0;
//bit AWB_stable = 0;
bit Outdoor = 0;
bit AE_START=0;
BYTE VIDEO = 0;
BYTE STILL=0; // andrew : preview ae will set this flag , when change to video ae will check this flag then Tidx transfer
xdata long Ylevel,Yreff,Ylayer,Kback;
xdata unsigned int testvalue = 0;
extern UCHAR obvalue;
extern char CAPTURE_FLAG;
extern USHORT G_R_DS, G_Gr_DS,G_B_DS,G_Gb_DS;
extern USHORT G_R_IDS,G_Gr_IDS,G_B_IDS,G_Gb_IDS;
extern USHORT G_R_Off,G_Gr_Off,G_B_Off,G_Gb_Off;
#define AEAWB_DEBUG
UCHAR L1_3A(UCHAR Mode3A)
{
unsigned short i;
UCHAR iris_new=0;
if((XBYTE[0x2000] == 1)||(XBYTE[0x2000] == 2) || (XBYTE[0x2000] == 4 ) || (XBYTE[0x2000] == 3 ))
;
else
return 0;
switch(Mode3A)
{
case 0:
AE_START = 1;
stdlumi=Indoor_stdlumi;
Outdoor = 0;
L1_AWB();
L1_AE(Mode3A);
break;
case 1:
AEFlag=0;
AWBFlag=0;
L1_AWB();
L1_AE(0);
break;
default:
;
}
return 0;
}
UCHAR L1_AE(UCHAR Mode3A)
{
UCHAR iris_new=0;
if( !AE_ON ) return 0;
GetAvgLum(&AVG_LUM);
if((Ylayer<132) && (Ylayer>124))
{
AEFlag=1;
return 0;
}
else if((Pre_Tidx==MaxTidx) && (Tidx==MaxTidx) && (Ylayer>132))
{
AEFlag=1;
return 0;
}
else if((Pre_Tidx==MinTidx) && (Tidx==MinTidx) && (Ylayer<124))
{
AEFlag=1;
return 0;
}
if(1)
{
Pre_Tidx=Tidx;
if(Ylayer > 138)
Tidx += 1;
else if(Ylayer >118)
Tidx += 0;
else
Tidx -= 1;
}
if(Tidx>MaxTidx) Tidx=MaxTidx;
if(Tidx<MinTidx) Tidx=MinTidx;
if(Pre_Tidx!=Tidx)
{
Pre_Shutter=AE_GetShutter(Pre_Tidx) ;
Shutter=AE_GetShutter(Tidx);
Pre_Gain=AE_GetGain(Pre_Tidx);
Gain=AE_GetGain(Tidx);
//patch4.3@andrew@0610
Handle_Iris( Tidx);
if((Pre_Shutter!=Shutter) && (Pre_Gain!=Gain))
{
L2_AdjustGain(Gain, 1);
L2_SetExposureTime (Shutter, 0);
}
else if(Pre_Shutter!=Shutter)
{
L2_SetExposureTime (Shutter, 0);
}
else
{
L2_AdjustGain(Gain, 1);
}
}
return 0;
}
#define AWB_WAIT_VD 0
//patch4.5@andrew@AWB_im // improve AWB
//patch4.3@andrew@0610
void L1_AWB(void)
{
float tmp;
UCHAR WinCnt=0;
long RYSum=0,BYSum=0,pixel_count=0;
ULONG spwnum;
UCHAR spwlum;
CHAR spwry, spwby, i;
CHAR Rflag=0,Bflag=0;
UCHAR lum0clamp, lum1clamp, lum2clamp, lum3clamp, lum4clamp;
float ratio=1;
int SPW_Y[4], SPW_RY[4], SPW_BY[4];
ULONG SPW_CNT[4];
int r_gain,gr_gain,b_gain,gb_gain,min_gain,Reg_Rg,Reg_Grg,Reg_Bg,Reg_Gbg,Reg_Hg ;
int r_off,gr_off,b_off,gb_off;//patch4.3@jhyu@0604
//int r,gr,b,gb;
if( !AWB_ON ) return;
r_off = XBYTE[0x2120];//patch4.3@jhyu@0604
gr_off = XBYTE[0x2121];//patch4.3@jhyu@0604
b_off = XBYTE[0x2122];//patch4.3@jhyu@0604
gb_off = XBYTE[0x2123];//patch4.3@jhyu@0604
Reg_Rg =(XBYTE[0x2124]&0xff);
Reg_Grg =(XBYTE[0x2125]&0xff);
Reg_Bg =(XBYTE[0x2126]&0xff);
Reg_Gbg =(XBYTE[0x2127]&0xff);
Reg_Hg =(XBYTE[0x2128]&0xff);
r_gain = Reg_Rg | ((Reg_Hg&0x08)<<5);
gr_gain= Reg_Grg| ((Reg_Hg&0x04)<<6);
b_gain = Reg_Bg | ((Reg_Hg&0x02)<<7);
gb_gain= Reg_Gbg| ((Reg_Hg&0x01)<<8);
#if (AWB_WAIT_VD)
L2_WaitVD(0,1);
#endif
XBYTE[0x20e8] |= 0x04;
lum0clamp = XBYTE[0x221b];
lum1clamp = XBYTE[0x221c];
lum2clamp = XBYTE[0x221d];
lum3clamp = XBYTE[0x221e];
lum4clamp = XBYTE[0x221f];
XBYTE[0x20e8] |= 0x04;
L2_WaitVD(0,1);
XBYTE[0x221b] = 0;
XBYTE[0x221c] = 0;
XBYTE[0x221d] = 0;
XBYTE[0x221e] = 0;
XBYTE[0x221f] = 0;
for( i =0 ; i< 4; i++)
{
L2_ReadSPW(i, &spwnum, &spwlum, &spwry, &spwby);
SPW_CNT[i] = spwnum;
SPW_Y[i] = spwlum;
SPW_RY[i] = spwry;
SPW_BY[i] = spwby;
//DbgPrint("SPW_RY=%x,SPW_BY=%x\n",SPW_RY[i],SPW_BY[i]);
}
XBYTE[0x20e8] &= 0xfb;
XBYTE[0x221b] = lum0clamp;
XBYTE[0x221c] = lum1clamp;
XBYTE[0x221d] = lum2clamp;
XBYTE[0x221e] = lum3clamp;
XBYTE[0x221f] = lum4clamp;
pixel_count=RYSum = BYSum = WinCnt = 0;
for( i = 0; i< 4; i++)
{
WinCnt++;
pixel_count+=(long)SPW_CNT[i];
RYSum = RYSum+(long)SPW_RY[i]*(long)SPW_CNT[i];
BYSum = BYSum+(long)SPW_BY[i]*(long)SPW_CNT[i];
}
if(pixel_count){
RYSum /= pixel_count;
BYSum /= pixel_count;
}
if(WinCnt==0) //No WB information
{
wLock++;
if(wLock >= 10)
{
wLock = 0;
//WinCnt = 1;
//L2_SetIndoorWB();
}
//PRINT_L1(" L1_AWB: Exit WinCnt=0.\n");
return;
}
else
{
wLock = 0;
if((RYSum >= WB_RH) || (RYSum <= WB_RL)){
if (RYSum > WB_RH ) r_gain-=1;
else if (RYSum < WB_RL) r_gain+=1;
else Rflag=1;
}
else{
Rflag=1;
}
if((BYSum >= WB_BH) || (BYSum <= WB_BL)){
if (BYSum > WB_BH ) b_gain-=1;
else if (BYSum < WB_BL) b_gain+=1;
else Bflag=1;
}
else{
Bflag=1;
}
}
min_gain = r_gain;
if( gr_gain < min_gain ) min_gain = gr_gain;
if( gb_gain < min_gain ) min_gain = gb_gain;
if( b_gain < min_gain ) min_gain = b_gain;
ratio = 64/(float)min_gain;
r_gain *= ratio;
gr_gain *= ratio;
b_gain *= ratio;
gb_gain *= ratio;
if( (r_gain > MaxAWBGain) || (gr_gain >MaxAWBGain ) || (b_gain > MaxAWBGain) || (gb_gain >MaxAWBGain) )
{
AWBFlag = 1;
//DbgPrint(" reach maxmum exit \n",RYSum);
return;
}
if (r_gain>MaxAWBGain) r_gain=MaxAWBGain;
if (r_gain<MinAWBGain) r_gain=MinAWBGain;
if (gr_gain>MaxAWBGain) gr_gain=MaxAWBGain;
if (gr_gain<MinAWBGain) gr_gain=MinAWBGain;
if (b_gain>MaxAWBGain) b_gain=MaxAWBGain;
if (b_gain<MinAWBGain) b_gain=MinAWBGain;
if (gb_gain>MaxAWBGain) gb_gain=MaxAWBGain;
if (gb_gain<MinAWBGain) gb_gain=MinAWBGain;
XBYTE[0x2120] = r_off;//patch4.3@jhyu@0604
XBYTE[0x2121] = gr_off;//patch4.3@jhyu@0604
XBYTE[0x2122] = b_off;//patch4.3@jhyu@0604
XBYTE[0x2123] = gb_off;//patch4.3@jhyu@0604
XBYTE[0x2124] = (r_gain&0xff);
XBYTE[0x2125] = (gr_gain&0xff);
XBYTE[0x2126] = (b_gain&0xff);
XBYTE[0x2127] = (gb_gain&0xff);
XBYTE[0x2128] = ((r_gain&0x100)>>5)|((gr_gain&0x100)>>6)|((b_gain&0x100)>>7)|((gb_gain&0x100)>>8);
AWBFlag=Rflag&&Bflag;
}
//patch4.3@andrew@0610
//patch4.3@andrw@0606
UCHAR L2_InitAEAW(UCHAR CamMode)
{
//Note : return to Monitor Mode need set CamMode to 0
//PRINT_L1(" L2_InitAEAW: Enter.\n");
G_3AFlag = 0;
G_3ACount = 0;
AWB_ON = 1;
AE_ON = 1;
Indoor_stdlumi=AE_GetIndoorStdLum();
Outdoor_stdlumi=AE_GetOutdoorStdLum();
XBYTE[0x2206] = 0x00;
XBYTE[0x2207] = 0xf0;
XBYTE[0x2208] = 0x00; // lum low threshold
XBYTE[0x2209] = 0xff;
/*recover window setting*/
// L2_ConfigWindow(0x00, 0x00, 64, 84);
L2_ConfigSPW(3, 0xa0, 0xf0, 0xb0, 0x50, 0xde, 0x22);
L2_ConfigSPW(2, 0x78, 0xa0, 0xc4, 0x3c, 0xe2, 0x1a);
L2_ConfigSPW(1, 0x50, 0x78, 0xd8, 0x28, 0xee, 0x12);
L2_ConfigSPW(0, 0x28, 0x50, 0xec, 0x14, 0xf6, 0x0a);
InitAWB_coeffi( );
L2_SetLutGamma(2);
Set_Edge();
SetGamma(K_GAMMA_OUTDOOR);
if(CamMode == 0)
{
Outdoor = 0;
/*************************
AE warm start
*************************/
if(AE_START) {
L2_SetIndoorWB( );
Shutter=AE_GetShutter(Tidx);
Gain=AE_GetGain(Tidx);
L2_SetExposureTime(Shutter, 0);
L2_AdjustGain(Gain, 0);
Pre_Tidx = Tidx;
Handle_Iris(Tidx);
}
/*******************
AE Cold start
********************/
else{
Outdoor = 0;
L2_SetIndoorWB( );
Pre_Tidx=Tidx=IniTidx;
stdlumi=Indoor_stdlumi;
Pre_Tidx=Tidx=IniTidx;
Shutter=AE_GetShutter(Tidx);
Gain=AE_GetGain(Tidx);
L2_SetExposureTime(Shutter, 0);
L2_AdjustGain(Gain, 0);
Init_iris();
}
AEFlag=0;
AWBFlag=0;
wLock=0;
}
return 1;
}
void GetAvgLum(PUSHORT Avg)
{
UCHAR pAEval[1];
BYTE satcnt = 0;
int row,col;
long Y[5][5];
satcnt= 0;
for (row=0; row<5; row++)
{
for (col=0; col<5; col++)
{
L2_ReadAEWindow((UCHAR)(row*5+col+1), pAEval);
Y[row][col]=(long)pAEval[0];
YY[row][col]=Y[row][col];
}
}
// Y00 Y01 Y02 Y03 Y04
// Y10 Y11 Y12 Y13 Y14
// Y20 Y21 Y22 Y23 Y24
// Y30 Y31 Y32 Y33 Y34
// Y40 Y41 Y42 Y43 Y44
Ylevel=(Y[0][0]+Y[0][1]+Y[0][2]+Y[0][3]+Y[0][4]+
Y[1][0]+Y[1][1]+Y[1][2]+Y[1][3]+Y[1][4]+
Y[2][0]+Y[2][1]+Y[2][2]+Y[2][3]+Y[2][4]+
Y[3][0]+Y[3][1]+Y[3][2]+Y[3][3]+Y[3][4]+
Y[4][0]+Y[4][1]+Y[4][2]+Y[4][3]+Y[4][4])/25;
Ylayer=Ylevel*128/Yreff;
*Avg=(unsigned short )Ylayer;
}
//patch4.3@andrw@0606
void Set_Edge( void )
{
XBYTE[0x2180] = 0x00;
XBYTE[0x2181] = 0x00;
XBYTE[0x2182] = 0x90;
XBYTE[0x2183] = 0x11;
XBYTE[0x2184] = 0x09;
XBYTE[0x2185] = 0x2A;
XBYTE[0x2186] = 0xA2;
XBYTE[0x2187] = 0x90;
XBYTE[0x2188] = 0x11;
XBYTE[0x2189] = 0x09;
XBYTE[0x218A] = 0x00;
XBYTE[0x218B] = 0x00;
XBYTE[0x218C] = 0x40;
XBYTE[0x2190] = 0x90;
XBYTE[0x2191] = 0x9A;
XBYTE[0x2192] = 0x00;
XBYTE[0x2193] = 0x21;
XBYTE[0x2194] = 0x01;
XBYTE[0x2195] = 0x10;
XBYTE[0x2196] = 0x12;
XBYTE[0x2197] = 0x00;
XBYTE[0x2198] = 0xA9;
XBYTE[0x2199] = 0x09;
XBYTE[0x219A] = 0x00;
XBYTE[0x219B] = 0x00;
XBYTE[0x219C] = 0x40;
XBYTE[0x21A0] = 0x01; //Edge enable
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -