#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "SimpleAec.h"
#include <sipp.h>
#include "OpipeApps.h"
//Macro define
#define MIN_SENSOR_EXP 10 //10us
#define MAX_SENSOR_EXP 33300 //us
#define MIN_SENSOR_GAIN 1
#define MAX_SENSOR_GAIN 16
#define TARGETBRI 45
#define HISNUM 6
#define WAVE_THRESHOLD 4
#define AE_COERD_TSHD 8
//Global variable
SAE AeInArgs __attribute__((section(".ddr_direct.data"))) =
{
3000,
1,
};
SAE AeOutArgs __attribute__((section(".ddr_direct.data")));
//the stats are from raw HW filter
extern AeAwbPatchStats aeStats[AE_PATCHES_NO];
extern AeAwbPatchStats aeStatsBackup[AE_PATCHES_NO];
double sum __attribute__((section(".ddr_direct.data"))) = 0.0;
double avg __attribute__((section(".ddr_direct.data"))) = 0.0;
UInt32 a[AE_VPATCHES_NO*AE_HPATCHES_NO] __attribute__((section(".ddr_direct.data")));
double aHistoryY[HISNUM] ={ -999999.0, -999999.0, -999999.0, -999999.0, -999999.0, -999999.0};
double CalAvgY(AeAwbPatchStats * ae) {
UInt32 i, j, t, tw, tmp;
int patchnum = 0;
sum = 0.0;
avg = 0.0;
for (i = 0; i < AE_VPATCHES_NO*AE_HPATCHES_NO; i++) {
a[i] = 2*( ae[i].accum[1]+ae[i].accum[2]); //GR,GB
//printf("accu: %d\n", a[i]);
}
//排序,大在前
for(i=0;i<AE_VPATCHES_NO*AE_HPATCHES_NO;i++){
if(a[i] < a[i+1]){
tmp = a[i];
a[i] = a[i+1];
a[i + i] = tmp;
}
}
//取最佳区段
for (i = (AE_VPATCHES_NO * AE_HPATCHES_NO)/18; i < 7*(AE_VPATCHES_NO * AE_HPATCHES_NO)/18; i++) {
sum += a[i];
// printf("sum value:%f,g value:%d\n",sum,a[i]);
}
//计算亮度均值
avg = sum / ((AE_PATCH_WIDTH*AE_PATCH_HEIGHT) * (AE_VPATCHES_NO * AE_HPATCHES_NO) / 3);
// printf("average: %.2f\n", avg);
return avg;
}
static void AE_CORE_Process(SAE* AeInArgs, SAE* AeOutArgs)
{
int i ,y;
int iStable = 0;
double sum = 0.0;
double avgY = 0.0;
unsigned int total = 0;
double avgBrightness;
double dRatio;
double tmpSensorGain;
double tmpExposureTime;
double tmpLDCurrent;
// AvgParamAlt* pal = NULL;
double newExposureTime = AeInArgs->exposureTime;
double newSensorGain = AeInArgs->sensorGain;
//ddd++;
// Skip over Cache
//pIcCtrl = (icCtrl *)(((uint32_t)&lrt_gIcCtrl) | BYPASS_CACHE);
// uint32_t *statsAeNoCache = (uint32_t *) ((uint32_t)statPatchesBuffer | 0x40000000);
avgBrightness = CalAvgY(aeStatsBackup);
// printf("avgBrightness %f\n", avgBrightness);
for( i = 0; i < HISNUM; ++i)
avgY += aHistoryY[i];
if(abs(avgBrightness * HISNUM - avgY) < AE_COERD_TSHD * HISNUM && avgY >= 0)
{
for(i = HISNUM - 1; i > 0; i-- )
aHistoryY[i] = aHistoryY[i-1];
aHistoryY[0] = avgBrightness;
iStable = TRUE;
}
else
{
for(i = 0; i < HISNUM; i ++)
aHistoryY[i] = avgBrightness;
iStable = FALSE;
}
if((abs(avgBrightness - TARGETBRI) < AE_COERD_TSHD) && iStable)
{
//printf(" return \n");
return ;
}
printf("avgBrightness %f total:%d \n", avgBrightness, total);
dRatio = (float)TARGETBRI / avgBrightness;
tmpSensorGain = newSensorGain * dRatio;
tmpExposureTime = newExposureTime * dRatio;
// printf("newSensorGain:%f\n",newSensorGain);
if(avgBrightness > TARGETBRI)
{
if (newSensorGain > MIN_SENSOR_GAIN && tmpSensorGain >= MIN_SENSOR_GAIN)
{
newSensorGain = tmpSensorGain;
}
else if(newSensorGain > MIN_SENSOR_GAIN && tmpSensorGain < MIN_SENSOR_GAIN)
{
newSensorGain = MIN_SENSOR_GAIN;
}
else // Gain minimized, exposure time should be decreased
{
newExposureTime = tmpExposureTime;
// printf("newExposureTime :%d\n", newExposureTime);
}
// printf("dRatio (TARGETBRI_LD / avgBrightness):%.2f , tmpSensorGain :%f, newSensorGain :%f newExposureTime :%f\n", \
// dRatio, tmpSensorGain, newSensorGain, newExposureTime);
}
else
{
if (newExposureTime < MAX_SENSOR_EXP && tmpExposureTime <= MAX_SENSOR_EXP)
{
newExposureTime = tmpExposureTime;
}
else if(newExposureTime < MAX_SENSOR_EXP && tmpExposureTime > MAX_SENSOR_EXP)
{
// printf("newExposureTime = MAX_SHUTTER_WIDTH\n");
newExposureTime = MAX_SENSOR_EXP;
}
else
{
if (newSensorGain < MAX_SENSOR_GAIN && tmpSensorGain <= MAX_SENSOR_GAIN)
{
newSensorGain = tmpSensorGain;
}
else if(newSensorGain < MAX_SENSOR_GAIN && tmpSensorGain > MAX_SENSOR_GAIN)
{
newSensorGain = MAX_SENSOR_GAIN;
}
}
}
if (newExposureTime > MAX_SENSOR_EXP)
{
newExposureTime = MAX_SENSOR_EXP;
}
else if (newExposureTime < MIN_SENSOR_EXP)
{
newExposureTime = MIN_SENSOR_EXP;
}
if (newSensorGain > MAX_SENSOR_GAIN)
{
newSensorGain = MAX_SENSOR_GAIN;
}
else if (newSensorGain < MIN_SENSOR_GAIN)
{
newSensorGain = MIN_SENSOR_GAIN;
}
AeOutArgs->exposureTime = newExposureTime + 5;
AeOutArgs->sensorGain = newSensorGain;
printf("OUT: tmpSenExp: %d, tmpSenGain: %d\n", AeOutArgs->exposureTime, AeOutArgs->sensorGain);
return;
}
void AutoExpAlg()
{
#define SKIP_FRAME 3
static int InitSkipFrame = 0;
u16 regAddr;
u8 regValue;
u8 regValueh, regValuel;
if(InitSkipFrame < SKIP_FRAME)
{
InitSkipFrame++;
AeOutArgs.exposureTime = AeInArgs.exposureTime;
AeOutArgs.sensorGain = AeInArgs.sensorGain;
WriteExposureTime(AeOutArgs.exposureTime);
WriteGain(AeOutArgs.sensorGain);
return;
}
//AE ALG call
// printf("\naaaaaaaaaaaa\n");
AE_CORE_Process(&AeInArgs, &AeOutArgs);
//Do the comparison of exposure
if (AeOutArgs.exposureTime != AeInArgs.exposureTime) {
WriteExposureTime(AeOutArgs.exposureTime);
AeInArgs.exposureTime = AeOutArgs.exposureTime;
}
// get the ata
//printf("read exp vals: %x %x %x\n", GetSensorRegValue(REG_EXP_MSB), GetSensorRegValue(REG_EXP_MID), GetSensorRegValue(REG_EXP_LSB));
//Do the comparison of gain
if (AeOutArgs.sensorGain != AeInArgs.sensorGain) {
WriteGain(AeOutArgs.sensorGain);
AeInArgs.sensorGain = AeOutArgs.sensorGain;
}
//printf("%d %d\n", AeOutArgs.exposureTime, AeOutArgs.sensorGain);
}