/*
 * AXMImageSensorState.cpp
 */

#include "AXMCommon/AXMCommonConfig.hpp"
#include "AXMCommon/AXMCommonSetParam.hpp"
#include "AXMCommon/AXMCommonStruct.hpp"

#include "AXMImageSensor/AXMImageSensor.hpp"
#include "AXMIsp/AXMIsp.hpp"
#include "../../project/refkit/AXMIspConfig.hpp"

#include "AXMIspAe/AXMIspAe.hpp"
#include "AXMIspAe/AXMIspAeAlgorithm.hpp"
#include "AXMIspAf/AXMIspAfAlgorithm.hpp"
#include "AXMIspAwb/AXMIspAwb.hpp"
#include "AXMPixcessor/AXMPixcessorInt/AXMPixcessorInt.hpp"
#include "AXMIspTest/adrs_base.h"
#include "AXMIspTest/spad_map.h"

#include "AXMIspTest/reg_imageif.h"

#include "imageSensorDrv.h"
#include "AXHSpec.hpp"
extern ST_SPEC    g_spec;

#include    <iostream>
#include <sstream>
#include <string>
#include    <iomanip>

extern "C" {
	#include "AXMIspTest/proc_def_cmos_eval.h"
	#include "AXMIspTest/proc_def_sio.h"
	#include "AXMIspTest/reg_gpio.h"
	#include "AXMIspTest/reg_isp.h"

	void	init_i2c_master(unsigned int	id_I);
}

// for i2c debug
#define REG_I2C0_BASE (0x40000000 + 0x00001400)	//(0x30000000 + 0x00210000)
#define REG_I2C1_BASE (0x40000000 + 0x00001800)	//(0x30000000 + 0x00211000)
#define REG_PWM_BASE  (0x30000000 + 0x00255000)
#define PWMCH			(1)				// PWM1 を使用する
#define FOCUS_PWMCH		(2)				// PWM2 を使用する
#define ZOOM_PWMCH		(3)				// PWM3 を使用する

#define PIRIS_FAST_PULSE	 6	// 12	// P-Iris 高速駆動パルス
#define PIRIS_SLOW_PULSE	18	// 24	// P-Iris 低速駆動パルス
#define FOCUS_FAST_PULSE	 4	// FOCUS 高速駆動パルス
#define FOCUS_SLOW_PULSE	12	// FOCUS 低速駆動パルス
#define ZOOM_FAST_PULSE		 2	// ZOOM 高速駆動パルス
#define ZOOM_SLOW_PULSE		10	// ZOOM 低速駆動パルス

#include "reg_i2c.h"

extern "C" {
#include "register_top.h"
#include "i2c.h"
}

// Iris制御種類定義

static IrisKind irisCont;
#include "reg_pwm.h"

static UInt32 get_pwm_ch_addr_base(UInt8 ch);
static void set_pwm_enable(UInt8 ch);
static void set_pwm_disable(UInt8 ch);
static void set_pwm_period(UInt8 ch, UInt16 high_value, UInt16 low_value);
static void set_pwm(UInt8 ch, UInt16 high_value, UInt16 low_value);

void AXMImageSensor::set_iris_control(unsigned char lens){
	irisCont = lens & 0x03;
	static ST_MSG imsg;
	imsg.cmd = lens;
	// レンズ情報不要のため不要
	/*
#ifndef PARASOFT_CPPTEST
	if (0 > send(nameIsp, AXFEVENT_MODEL(AXMIsp::EVENT_NOTIFY_LENS),
  											&imsg, sizeof(ST_MSG) )) {
													;
  	}
#endif
	*/
}

extern "C" {
void    init_iris_control(void){
	irisCont = E_IRISCONT_NONE;
}

void	init_i2c_master( unsigned int id_I ) {
	// リリースされたドライバ側の関数を使用するため不要
	/*
	const UInt32	P_slave_adr	= DC_IRIS_TX_SLAVE_ADDR;	// 0x01;
	const UInt32	P_fs_scl_hcnt	= 29; // SCL=400kHz @CORE_CLK=28.8MHz
	const UInt32	P_fs_scl_lcnt	= 35; // SCL=400kHz @CORE_CLK=28.8MHz
	const UInt32	P_unit_data_size = 8;
	
	SetReg32(REG_I2C_ENABLE(id_I), 0
		|(0		<<  0) // ENABLE
		);

	SetReg32(REG_I2C_CON(id_I), 0
		|(1		<<  6) // SLAVE_DISABLE
		|(2		<<  1) // SPEED
		|(1		<<  0) // MASTER_MODE
		);

	SetReg32(REG_I2C_TAR(id_I), 0
		|(P_slave_adr	<<  0) // TAR
		);

	SetReg32(REG_I2C_FS_SCL_HCNT(id_I), 0
		|(P_fs_scl_hcnt	<<  0) // FS_SCL_HCNT
		);

	SetReg32(REG_I2C_FS_SCL_LCNT(id_I), 0
		|(P_fs_scl_lcnt	<<  0) // FS_SCL_LCNT
		);

	SetReg32(REG_I2C_INTR_MASK(id_I), 0
	//	//|(1		<<  4) // M_TX_EMPTY
	//	|(1		<<  2) // M_RX_FULL
		);

	SetReg32(REG_I2C_TX_TL(id_I), 0
		|(0		<<  0) // TX_TL
		);

	SetReg32(REG_I2C_RX_TL(id_I), 0
		|((P_unit_data_size-1)	<<  0) // RX_TL
		);

	SetReg32(REG_I2C_ENABLE(id_I), 0
		|(1		<<  0) // ENABLE
		);
		*/
}
}	// end of extern "C"

void	i2c_tx(
	UInt32	id_I,
	UInt32	byte_num_I, // 1 - 8
	UInt32	stop_flag_I,
	UInt8	*tx_data_I
) {
	// リリースされたドライバ側の関数を使用するため不要
	/*
	UInt8	tx_data;
	UInt32	stop_flag;
	UInt32	i;
	
	for (i=0; i<byte_num_I; i=i+1) {
		tx_data = *(tx_data_I + i);
		stop_flag = stop_flag_I & (i==(byte_num_I-1));

		SetReg32(REG_I2C_DATA_CMD(id_I), 0
			|(stop_flag	<<  9) // STOP
			|(0		<<  8) // CMD
			|(tx_data	<<  0) // DAT
			);
	}
	*/
}

void iris_tx_i2c_reg_write(UInt8 addr, UInt8 data)
{
	// 今回IRISは無いため不要
	/*
    UInt8  buf[2];
	buf[0] = (data >> 4) & 0x0F;          // 1バイト目 これはレジスタアドレスだがアイリスではデータ	// 右シフト見直しdata >= 0 なので問題なし
	buf[1] = (data << 4) & 0xF0;          // 2バイト目 これはデータがアイリスではデータ（後半）

    UInt8 size      = 2;
    UInt8 stop_flag = 1;

    SetReg32(REG_I2C_ENABLE(DC_IRIS_TX_I2C_PORT), 0);                         // Disable
    SetReg32(REG_I2C_TAR(DC_IRIS_TX_I2C_PORT), DC_IRIS_TX_SLAVE_ADDR); // set slave addr
    SetReg32(REG_I2C_ENABLE(DC_IRIS_TX_I2C_PORT), 1);                         // Enable
    i2c_tx(DC_IRIS_TX_I2C_PORT, size, stop_flag, buf);                        // set send data
	*/
}

#ifdef IMX662
static unsigned int st_shutt = Exposure1PER60S;
#elif IMX415	// IMX662
// IMX415用
static unsigned int st_shutt = Exposure1PER30S;
#else	// IMX662
// IMX412
static unsigned int st_shutt = Exposure1PER15S;
#endif	// IMX662
static unsigned int st_frame_info = 0;

static ImageSensorParam imageSensorParam;
	

#define STTIMELOGSIZ 1024
#ifdef DEBUG_EXPOSURE
static USHORT st_histogram_log2[19][STTIMELOGSIZ];
static USHORT st_histogram_log[18][STTIMELOGSIZ];

static ULONG st_mode_log[STTIMELOGSIZ];
static ULONG st_regRPU_log[STTIMELOGSIZ];
static ULONG st_regSPU_log[STTIMELOGSIZ];
static ULONG st_regMIX_log[STTIMELOGSIZ];
static ULONG st_nochgcnt_log[STTIMELOGSIZ];
static ULONG st_th1_log[STTIMELOGSIZ];
static ULONG st_th2_log[STTIMELOGSIZ];
static ULONG st_MainLv_log[STTIMELOGSIZ];
static ULONG st_OtherLv_log[STTIMELOGSIZ];
static ULONG st_Weight_log[STTIMELOGSIZ];
static unsigned int st_shutt_log[STTIMELOGSIZ];
static unsigned int st_time_log[STTIMELOGSIZ];
static unsigned int st_gain_log[STTIMELOGSIZ];
static unsigned int st_vmax_log[STTIMELOGSIZ];
static LONG st_aediff[STTIMELOGSIZ];
static LONG st_aediff_ave[STTIMELOGSIZ];
static LONG st_opdY_ave[STTIMELOGSIZ];
static LONG st_AeControlValue[STTIMELOGSIZ];
static LONG st_iris[STTIMELOGSIZ];
static unsigned int st_time_log_idx = (STTIMELOGSIZ-1);
#endif

// 3rdリリースから、「モデルイベント」と「デバイスイベント」の
// 登録が可能となる。
//
// 状態テーブルは、状態ごとに定義し、イベントIDとメンバ関数の紐付けを行う。
// ※状態テーブルの最後は、必ず{0,NULL}で終了する必要がある。

// STATUS_RUNNING状態の状態テーブル定義
//      {イベントID, メンバ関数ポインタ}
//      ...
//     {0,NULL}
const AXMImageSensor::StateTable AXMImageSensor::state_waiting[] = {
    { AXMImageSensor::EVENT_SPEC_ADDR,
      (AXMImageSensor::StateFuncPtr) &AXMImageSensor::funcSpecAddr },   //  設定値保存先アドレス通知
    {0,NULL}
};

const AXMImageSensor::StateTable AXMImageSensor::state_running[] = {
    { AXMImageSensor::ISP_EVENT_IMAGESENSOR,                              //  
      (AXMImageSensor::StateFuncPtr) &AXMImageSensor::funcImageSensor },
    { AXMImageSensor::ISP_EVENT_IRISCONTROL,                              //  
      (AXMImageSensor::StateFuncPtr) &AXMImageSensor::funcIrisControl },
    { AXMImageSensor::ISP_EVENT_FOCUSCONTROL,                              //  
      (AXMImageSensor::StateFuncPtr) &AXMImageSensor::funcFocusControl },
    {0,NULL}
};

	
ax::actorFuncStatus AXMImageSensor::funcSpecAddr(const void *pParam, int size) {
  if((0 < size) && (pParam != 0x00000000ul)) {
    ST_MSG *msg = (ST_MSG *)pParam;
    p_spec = (ST_SPEC *)msg->data;

  	checkComm();

    state = STATE_RUNNING;
#ifndef PARASOFT_CPPTEST
    setNextState(state);
#endif  //  PARASOFT_CPPTEST
  }
  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMImageSensor::funcImageSensor(const void* pParam, int size) {
	  unsigned int tmp_timeline = 0;
	  unsigned int tmp_time = 0;
  unsigned int tmp_gain = 0;
  unsigned int ims_shutt = 0;
  unsigned int ims_gain = 0;
  unsigned int ims_vmax = 0;
	checkComm();

  m_log.write(AXFLOG_DEBUG, "ImageSensorDrv funcImageSensor()");
	ST_MSG  *msg = (ST_MSG *)pParam;
	ST_ISMSG imsg;
	imsg.frame = 1;
	imsg.time = 0;
	imsg.gain = 0;	//klocwork指摘#458に対応

	if(msg){
		ST_ISMSG *tmp_imsg = static_cast<ST_ISMSG *>(msg->data);
		if(tmp_imsg) {
			imsg = *tmp_imsg;
		}
#ifdef DEBUG_EXPOSURE
		st_mode_log[st_time_log_idx] |= (msg->cmd << 16);
#endif
	}
	ST_ISMSG *stims = &imsg;	// klocwork指摘#276に対応
		imageSensorParam.st_change_sts = E_ISCHANG_none;

	st_frame_info  = stims->frame;	// WDR実装時に追加
	st_shutt  = stims->time;
	if(st_shutt == 0) {
		st_shutt = 1;
	}
#ifdef GAIN_TUNE
	tmp_gain = stims->gain;	// IMX136では10倍する
#else
	tmp_gain = stims->gain  * 10;		// ※コンパイラ都合によりenumから数値に変更（_TEN -> 10）
#endif

#ifdef IMX662
	// 掃き捨てライン数計算
	imageSensorParam.st_frm = (st_shutt + (Exposure1PER60S - 1)) / Exposure1PER60S;

	// SHS設定が１フレームライン数より大きくなる不具合を修正
	tmp_timeline = ((Exposure1PER60S * 10) + (ExposureTimeLine>>1)) / ExposureTimeLine;		// ※コンパイラ都合によりenumから数値に変更（_TEN -> 10）
	tmp_time = ((Exposure1PER60S * imageSensorParam.st_frm) - st_shutt) * 10;		// ※コンパイラ都合によりenumから数値に変更（_TEN -> 10）
	if(tmp_timeline > 1) {
		tmp_time = (tmp_time + (tmp_timeline >> 1)) / tmp_timeline;
	}
	tmp_time += 4;				// imx662用
#elif IMX415	// IMX662
	// IMX415用
	// 掃き捨てライン数計算
#if 0
	imageSensorParam.st_frm = (st_shutt + (Exposure1PER30S - 4)) / Exposure1PER30S;

	// SHS設定が１フレームライン数より大きくなる不具合を修正
	tmp_timeline = ((Exposure1PER30S * 10) + (ExposureTimeLine>>1)) / ExposureTimeLine;		// ※コンパイラ都合によりenumから数値に変更（_TEN -> 10）
	tmp_time = ((Exposure1PER30S * imageSensorParam.st_frm) - st_shutt) * 10;		// ※コンパイラ都合によりenumから数値に変更（_TEN -> 10）
	if(tmp_timeline > 1) {
		tmp_time = (tmp_time + (tmp_timeline >> 1)) / tmp_timeline;
	}
#endif	
	
	tmp_time = (Exposure1PER30S - st_shutt) * ExposureTimeLine / Exposure1PER30S;
	
	if (tmp_time < 8) {
		tmp_time = 8;				// imx415用
	}
	if(tmp_time > (ExposureTimeLine-4)){
		tmp_time = (ExposureTimeLine-4);
	}
#else	// IMX662
	// IMX412用
	// 掃き捨てライン数計算
	imageSensorParam.st_frm = (st_shutt + (Exposure1PER15S - 1)) / Exposure1PER15S;

	// SHS設定が１フレームライン数より大きくなる不具合を修正
	tmp_timeline = ((Exposure1PER15S * 10) + (ExposureTimeLine>>1)) / ExposureTimeLine;		// ※コンパイラ都合によりenumから数値に変更（_TEN -> 10）
	tmp_time = ((Exposure1PER15S * imageSensorParam.st_frm) - st_shutt) * 10;		// ※コンパイラ都合によりenumから数値に変更（_TEN -> 10）
	if(tmp_timeline > 1) {
		tmp_time = (tmp_time + (tmp_timeline >> 1)) / tmp_timeline;
	}
	if (tmp_time < ExposureTimeLine) {
		tmp_time = ExposureTimeLine - tmp_time;
	} else {
		tmp_time = 0;
	}
#endif	// IMX662

	//ims_shutt = get_sio_cmos_register(REG_CMOS_CID0_SHS10) | (get_sio_cmos_register(REG_CMOS_CID0_SHS11) << 8) | (get_sio_cmos_register(REG_CMOS_CID0_SHS12) << 16);
	unsigned char rd_shutt_h;
	unsigned char rd_shutt_l;
#ifdef IMX662
	i2c_reg16_read(LISOC_I2C0, 0x3051, &rd_shutt_h);
	i2c_reg16_read(LISOC_I2C0, 0x3050, &rd_shutt_l);
#elif IMX415	// IMX662
	// IMX415用
	i2c_reg16_read(LISOC_I2C0, 0x3051, &rd_shutt_h);
	i2c_reg16_read(LISOC_I2C0, 0x3050, &rd_shutt_l);
#else	// IMX662
	// IMX412用
	i2c_reg16_read(LISOC_I2C0, 0x202, &rd_shutt_h);
	i2c_reg16_read(LISOC_I2C0, 0x203, &rd_shutt_l);
#endif	// IMX662
	ims_shutt	= ((unsigned int)rd_shutt_h << 8) | ((unsigned int)rd_shutt_l);
#ifdef DEBUG_EXPOSURE
	st_shutt_log[st_time_log_idx] = st_shutt;
	st_time_log[st_time_log_idx] = ims_shutt;	// tmp_time;
#endif

	if(tmp_time != ims_shutt){
		imageSensorParam.st_change_sts |= E_ISCHANG_shutter;
		// Send to image sensor
		unsigned char tmp_time_h = (unsigned char)((tmp_time >> 8) & 0x000000FF);
		unsigned char tmp_time_l = (unsigned char)(tmp_time & 0x000000FF); 
#ifdef IMX662
		i2c_reg16_write(LISOC_I2C0, 0x3051, tmp_time_h);
		i2c_reg16_write(LISOC_I2C0, 0x3050, tmp_time_l);
#elif IMX415	// IMX662
		// IMX415用
		i2c_reg16_write(LISOC_I2C0, 0x3051, tmp_time_h);
		i2c_reg16_write(LISOC_I2C0, 0x3050, tmp_time_l);
#else	// IMX662
		// IMX412用
		i2c_reg16_write(LISOC_I2C0, 0x202, tmp_time_h);
		i2c_reg16_write(LISOC_I2C0, 0x203, tmp_time_l);
#endif	// IMX662
	}

	//ims_gain = get_sio_cmos_register(REG_CMOS_CID0_GAIN0) | (get_sio_cmos_register(REG_CMOS_CID0_GAIN1) << 8) ;
#ifdef IMX662
	unsigned char rd_gain_8;
	i2c_reg16_read(LISOC_I2C0, 0x3070, &rd_gain_8);
	ims_gain = (unsigned int)rd_gain_8;
#ifdef DEBUG_EXPOSURE
	st_gain_log[st_time_log_idx] = ims_gain; // tmp_gain;
#endif
	tmp_gain /= 3;	// IMX662はレジスタ値×0.3[dB]となっているため1/3する
	if(tmp_gain != ims_gain){
#elif IMX415	// IMX662
	// IMX415用
	unsigned char rd_gain_8;
	i2c_reg16_read(LISOC_I2C0, 0x3090, &rd_gain_8);
	ims_gain = (unsigned int)rd_gain_8;
#ifdef DEBUG_EXPOSURE
	st_gain_log[st_time_log_idx] = ims_gain; // tmp_gain;
#endif
	tmp_gain /= 3;	// IMX415はレジスタ値×0.3[dB]となっているため1/3する
	if(tmp_gain != ims_gain){
#else	// IMX662
	// IMX412用
	unsigned char rd_gain_h8;
	unsigned char rd_gain_l8;
	i2c_reg16_read(LISOC_I2C0, 0x204, &rd_gain_h8);
	i2c_reg16_read(LISOC_I2C0, 0x205, &rd_gain_l8);
	ims_gain = (unsigned int)(((rd_gain_h8 << 8) & 0xFF00) | (rd_gain_l8 & 0x00FF));
	if (tmp_gain > 0xF0) tmp_gain = 0xF0;
	// AXGain設定値をIMX412Gain設定値に調整（IMX412Gain設定最大値978/AXGain設定最大値0xF0(240)≒4を掛ける）
	unsigned int wt_gain = tmp_gain * 4;
#ifdef DEBUG_EXPOSURE
	st_gain_log[st_time_log_idx] = ims_gain; // tmp_gain;
#endif
	if(wt_gain != ims_gain){
#endif	// IMX662
		imageSensorParam.st_change_sts |= E_ISCHANG_gain;
		// Send to image sensor
#ifdef IMX662
		unsigned char tmp_gain_8 = (unsigned char)(tmp_gain & 0x000000FF); 
		i2c_reg16_write(LISOC_I2C0, 0x3070, tmp_gain_8);
#elif IMX415	// IMX662
		// IMX415用
		unsigned char tmp_gain_8 = (unsigned char)(tmp_gain & 0x000000FF); 
		i2c_reg16_write(LISOC_I2C0, 0x3090, tmp_gain_8);
#else	// IMX662
		// IMX412用
		unsigned char wt_gain_h8 = (unsigned char)((wt_gain >> 8) & 0x000000FF);
		unsigned char wt_gain_l8 = (unsigned char)(wt_gain & 0x000000FF);
		i2c_reg16_write(LISOC_I2C0, 0x204, wt_gain_h8);
		i2c_reg16_write(LISOC_I2C0, 0x205, wt_gain_l8);
#endif	// IMX662
	}

	// vmaxは初期状態から変化することが無いため設定不要
	//ims_vmax = get_sio_cmos_register(REG_CMOS_CID0_VMAX0) | (get_sio_cmos_register(REG_CMOS_CID0_VMAX1) << 8) | (get_sio_cmos_register(REG_CMOS_CID0_VMAX2) << 16);
	imageSensorParam.st_frm *= ExposureTimeLine;
#ifdef DEBUG_EXPOSURE
	st_vmax_log[st_time_log_idx] = imageSensorParam.st_frm;
#endif

	//if(imageSensorParam.st_frm != ims_vmax){
	//	imageSensorParam.st_change_sts |= E_ISCHANG_vmax;
	//}

		imageSensorParam.st_time = tmp_time;
		imageSensorParam.st_gain = tmp_gain;

	static ST_MSG smsg;
	smsg.data = &imageSensorParam;
  if (0 > send(namePixessorInt, AXFEVENT_MODEL(AXMPixcessorInt::PIXCESSORINT_EVENT_NOTIFY_ISR_DATA), 
  											&smsg, sizeof(ST_MSG) )) {
													;
  } 

  return ax::AXFACTOR_SUCCESS;
}

ax::actorFuncStatus AXMImageSensor::funcIrisControl(const void* pParam, int size) {
  m_log.write(AXFLOG_DEBUG, "ImageSensorDrv funcIrisControl()");

	ST_MSG  *msg = (ST_MSG *)pParam;
	ST_ISMSG *stims;
	int	cmd = 0;
	int iris = 0;
	if(msg) {
		cmd = msg->cmd;
		stims = static_cast<ST_ISMSG *>(msg->data);
		if(stims) {
			iris = stims->iris;
		}
#ifdef DEBUG_EXPOSURE
		st_mode_log[st_time_log_idx] |= (cmd << 16);
#endif
	}
	checkComm();

	switch(irisCont) {
// DC-Iris
	case E_IRISCONT_DC:
		if(cmd == E_AeManualMode) {
			iris_tx_i2c_reg_write(0, iris);
		} else {
			switch(iris){
			case IRIS_CONT_STOP:			// 停止電圧
			default:
				iris_tx_i2c_reg_write(0, irisContStop);
				break;
			case IRIS_CONT_CLOSE_SLOW:		// ③ アイリス閉低速電圧
				iris_tx_i2c_reg_write(0, irisContCloseSlow);
				break;
			case IRIS_CONT_CLOSE_FAST:      // ④ アイリス閉高速電圧
				iris_tx_i2c_reg_write(0, irisContCloseFast);
				break;
			case IRIS_CONT_OPEN_SLOW:       // ⑤ アイリス開低速電圧
				iris_tx_i2c_reg_write(0, irisContOpenSlow);
				break;
			case IRIS_CONT_OPEN_FAST:       // ⑥ アイリス開高速電圧
				iris_tx_i2c_reg_write(0, irisContOpenFast);
		break;
			}
		}
		break;
// P-Iris
	case E_IRISCONT_P:
			set_pwm_disable(PWMCH);
	// 開/閉の処理
		switch(iris){	// klocwork指摘#456,#457に対応
		case IRIS_CONT_STOP:			// 停止電圧
		default:
			set_pwm_disable(PWMCH);
			break;
		case IRIS_CONT_CLOSE_SLOW:		// ③ アイリス閉低速電圧
		case IRIS_CONT_CLOSE_FAST:      // ④ アイリス閉高速電圧
			// アイリスは使用しないため不要
			/*
		    SetRegFld32(REG_GPIO_1_GPIODATA+4, 1);
			*/
			break;
		case IRIS_CONT_OPEN_SLOW:       // ⑤ アイリス開低速電圧
		case IRIS_CONT_OPEN_FAST:       // ⑥ アイリス開高速電圧
			// アイリスは使用しないため不要
			/*
		    ClrRegFld32(REG_GPIO_1_GPIODATA+4, 1);
			*/
			break;
		}
	//高速/低速の処理
		switch(iris){
		default:						// 停止電圧
			break;
		case IRIS_CONT_CLOSE_SLOW:		// ③ アイリス閉低速電圧
		case IRIS_CONT_OPEN_SLOW:       // ⑤ アイリス開低速電圧
			set_pwm(PWMCH, PIRIS_SLOW_PULSE, PIRIS_SLOW_PULSE);		// 高速 開⇔閉4秒
			break;
		case IRIS_CONT_CLOSE_FAST:      // ④ アイリス閉高速電圧
		case IRIS_CONT_OPEN_FAST:       // ⑥ アイリス開高速電圧
			set_pwm(PWMCH, PIRIS_FAST_PULSE, PIRIS_FAST_PULSE);		// 高速 開⇔閉2秒
			break;
		}
		break;
	case E_IRISCONT_NONE:
	default:
		break;
	}
#ifdef DEBUG_EXPOSURE
	st_iris[st_time_log_idx] = iris;
#endif

	return ax::AXFACTOR_SUCCESS;
}

void hndlImageSensorDrv(void)
{
	//if((imageSensorParam.st_change_sts & E_ISCHANG_shutter) != 0){
	//	set_sio_cmos_shutter(REG_CMOS_CID0_SHS10,  imageSensorParam.st_time);
	//}
	//if((imageSensorParam.st_change_sts & E_ISCHANG_gain) != 0){
	//	set_sio_cmos_gain(REG_CMOS_CID0_GAIN0,  imageSensorParam.st_gain);
	//}
	//if((imageSensorParam.st_change_sts & E_ISCHANG_vmax) != 0){
	//	set_sio_cmos_shutter(REG_CMOS_CID0_VMAX0,  imageSensorParam.st_frm);
	//}
}
void setAECalcData(LONG aediff_ave)
{
#ifdef DEBUG_EXPOSURE
	st_aediff_ave[st_time_log_idx] = aediff_ave;
#endif

}

void setAECalcData1(LONG opdY_ave)
{
#ifdef DEBUG_EXPOSURE
	st_opdY_ave[st_time_log_idx] = opdY_ave;
#endif
}

void setAECalcData2(LONG aediff)
{
#ifdef DEBUG_EXPOSURE
	st_aediff[st_time_log_idx] = aediff;
#endif
}

void setAEControlValue(LONG AeControlValue)
{
#ifdef DEBUG_EXPOSURE
	st_AeControlValue[st_time_log_idx] = AeControlValue;
#endif
}

void setIrisThValue(long absTh1 , long absTh2 , unsigned char noChangeCnt)
{
#ifdef DEBUG_EXPOSURE
	st_th1_log[st_time_log_idx] = absTh1;
	st_th2_log[st_time_log_idx] = absTh2;
	st_nochgcnt_log[st_time_log_idx] = noChangeCnt;
	
#endif
	
}

void setAEMainObj(unsigned long OpdYMainObjectAve , unsigned long OpdYNonMainObjectAve , unsigned long NonMainObjectAreaWeight)
{
#ifdef DEBUG_EXPOSURE
	st_MainLv_log[st_time_log_idx] = OpdYMainObjectAve;
	st_OtherLv_log[st_time_log_idx] = OpdYNonMainObjectAve;
	st_Weight_log[st_time_log_idx] = NonMainObjectAreaWeight;
#endif
}

void setRegLog(unsigned long regSPU0 , unsigned long regMIX_ACT )
{
#ifdef DEBUG_EXPOSURE
	st_regSPU_log[st_time_log_idx] = regSPU0;
	st_regMIX_log[st_time_log_idx] = regMIX_ACT;
#endif
}

void setRegLog3(unsigned long regRPU , unsigned long frame)
{
#ifdef DEBUG_EXPOSURE
	st_regRPU_log[st_time_log_idx] = regRPU;
#endif

}

void setRegLog4(int id)
{
#ifdef DEBUG_EXPOSURE
	if(id &0x01) {
		st_time_log_idx = (st_time_log_idx + 1) & (STTIMELOGSIZ-1);
		st_mode_log[st_time_log_idx] = g_spec.Mode;
		st_regRPU_log[st_time_log_idx] = GetReg32(RPU_DMAR0_OFS);
		st_regSPU_log[st_time_log_idx] = GetReg32(RegSPU_C);
		st_regMIX_log[st_time_log_idx] = GetReg32(RegMIX_ACT);
		st_nochgcnt_log[st_time_log_idx] = GetReg32(RegMIX_EXP_RATIO);
		st_th1_log[st_time_log_idx] = 0;
		st_th2_log[st_time_log_idx] = 0;
		st_MainLv_log[st_time_log_idx] = 0;
		st_OtherLv_log[st_time_log_idx] = 0;
		st_Weight_log[st_time_log_idx] = 0;
		st_shutt_log[st_time_log_idx] = 0;
		st_time_log[st_time_log_idx] = 0;
		st_gain_log[st_time_log_idx] = 0;
		st_vmax_log[st_time_log_idx] = 0;
		st_aediff[st_time_log_idx] = 0;
		st_aediff_ave[st_time_log_idx] = 0;
		st_opdY_ave[st_time_log_idx] = 0;
		st_AeControlValue[st_time_log_idx] = 0;
		st_iris[st_time_log_idx] = 0;

	}
#endif

}

void setHistogramLog(int bin ,  short weight)
{
#ifdef DEBUG_EXPOSURE
	st_histogram_log[bin][st_time_log_idx] = weight;
#endif
}

void setHistogramLog2(int bin ,  short pv_flag)
{
#ifdef DEBUG_EXPOSURE
	st_histogram_log2[bin][st_time_log_idx] = pv_flag;
#endif
}

void clrDrvLog(void)
{
#ifdef DEBUG_EXPOSURE
	st_shutt_log[st_time_log_idx] = 0;
	st_time_log[st_time_log_idx] = 0;	// tmp_time;
	st_gain_log[st_time_log_idx] = 0; // tmp_gain;
	st_vmax_log[st_time_log_idx] = 0;
	st_iris[st_time_log_idx] = 0;
#endif
}
// proc_def_pwm.c 

extern "C" {

void	init_pwm() {
	// PWMはAFに使用されるが今回AF非対応のため不要
	/*
    SetRegFld32(REG_GPIO_1_GPIODIR, 1+8);
    ClrRegFld32(REG_GPIO_1_GPIODATA+4, 1);	// 全開にする

    set_pwm(PWMCH, 6, 6);
	*/
}
#define FOCUS_GPIO_DATA	(0x02)	// 2
#define ZOOM_GPIO_DATA	(0x04)	// 4

void	init_focus_pwm() {
	// PWMはAFに使用されるが今回AF非対応のため不要
	/*
    SetRegFld32(REG_GPIO_1_GPIODIR, FOCUS_GPIO_DATA+ZOOM_GPIO_DATA);
	*/
}
}
	
static UInt32 get_pwm_ch_addr_base(UInt8 ch)
{
    // ch 0 - 6
    return (ch << 4);
}


static void set_pwm_enable(UInt8 ch)
{
	// PWMはAFに使用されるが今回AF非対応のため不要
	/*
    // REG_PWMn_CNT
    SetReg32((REG_PWM_BASE + get_pwm_ch_addr_base(ch)), 1);
	*/
}

static void set_pwm_disable(UInt8 ch)
{
	// PWMはAFに使用されるが今回AF非対応のため不要
	/*
    // REG_PWMn_CNT
    SetReg32((REG_PWM_BASE + get_pwm_ch_addr_base(ch)), 0);
	*/
}

static void set_pwm_period(UInt8 ch, UInt16 high_value, UInt16 low_value)
{
	// PWMはAFに使用されるが今回AF非対応のため不要
	/*
    // REG_PWMn_PERIOD
    SetReg32((REG_PWM_BASE + get_pwm_ch_addr_base(ch) + 0x4), ((((UInt32)low_value) << 16) | high_value));
	*/
}

static void set_pwm(UInt8 ch, UInt16 high_value, UInt16 low_value)
{
	// PWMはAFに使用されるが今回AF非対応のため不要
	/*
    set_pwm_period(ch, high_value, low_value);
    set_pwm_enable(ch);
	*/
}

ax::actorFuncStatus AXMImageSensor::funcFocusControl(const void* pParam, int size) {
  m_log.write(AXFLOG_DEBUG, "ImageSensorDrv funcFocusControl()");

	ST_MSG  *msg = (ST_MSG *)pParam;
	unsigned int lensControl = 0;
	unsigned int zoomControl = 0;
	if(msg) {
		ST_CONTROL_AF *controlAf = static_cast<ST_CONTROL_AF *>(msg->data);
		if(controlAf) {
			lensControl = controlAf->lensMove & 0x0F;
			zoomControl = controlAf->lensMove & 0xF0;
		}
	}
		checkComm();

	if(lensControl != 0) {
		set_pwm_disable(FOCUS_PWMCH);
	}
	if(zoomControl != 0) {
		set_pwm_disable(ZOOM_PWMCH);
	}
	
	switch(lensControl){
	case AF_CONT_STOP:				// ⑤レンズ駆動停止
		set_pwm_disable(FOCUS_PWMCH);
		break;
	case AF_CONT_TOMACRO_SLOW:		// ②レンズ低速駆動(マクロ方向)
	case AF_CONT_TOMACRO_FAST:      // ①レンズ高速駆動(マクロ方向)
		// 今回AF非対応のため不要
		/*
	    SetRegFld32(REG_GPIO_1_GPIODATA+8, FOCUS_GPIO_DATA);
		*/
		break;
	case AF_CONT_TOINF_SLOW:		// ③レンズ低速駆動(無限遠方向)
	case AF_CONT_TOINF_FAST:		// ④レンズ高速駆動(無限遠方向)
		// 今回AF非対応のため不要
		/*
	    ClrRegFld32(REG_GPIO_1_GPIODATA+8, FOCUS_GPIO_DATA);
		*/
		break;
	default:
		break;
	}
	
//高速/低速の処理
	switch(lensControl){
	default:						// 停止電圧
		break;
	case AF_CONT_TOMACRO_SLOW:		// ②レンズ低速駆動(マクロ方向)
	case AF_CONT_TOINF_SLOW:		// ③レンズ低速駆動(無限遠方向)
		set_pwm(FOCUS_PWMCH, FOCUS_SLOW_PULSE, FOCUS_SLOW_PULSE);		// 低速 遠⇔近3秒
		break;
	case AF_CONT_TOMACRO_FAST:      // ①レンズ高速駆動(マクロ方向)
	case AF_CONT_TOINF_FAST:		// ④レンズ高速駆動(無限遠方向)
		set_pwm(FOCUS_PWMCH, FOCUS_FAST_PULSE, FOCUS_FAST_PULSE);		// 高速 遠⇔近1秒
		break;
	}
	
	switch(zoomControl){
	case ZOOM_CONT_STOP:				// ⑤レンズ駆動停止
		set_pwm_disable(ZOOM_PWMCH);
		break;
	case ZOOM_CONT_ZOOMOUT_SLOW:		// ②レンズ低速駆動(マクロ方向)
	case ZOOM_CONT_ZOOMOUT_FAST:      // ①レンズ高速駆動(マクロ方向)
		// 今回AF非対応のため不要
		/*
	    ClrRegFld32(REG_GPIO_1_GPIODATA+16, ZOOM_GPIO_DATA);
		*/
		break;
	case ZOOM_CONT_ZOOMIN_SLOW:		// ③レンズ低速駆動(無限遠方向)
	case ZOOM_CONT_ZOOMIN_FAST:		// ④レンズ高速駆動(無限遠方向)
		// 今回AF非対応のため不要
		/*
	    SetRegFld32(REG_GPIO_1_GPIODATA+16, ZOOM_GPIO_DATA);
		*/
		break;
	default:
		break;
	}
	
//高速/低速の処理
	switch(zoomControl){
	default:						// 停止電圧
		break;
	case ZOOM_CONT_ZOOMOUT_SLOW:		// ②レンズ低速駆動(マクロ方向)
	case ZOOM_CONT_ZOOMIN_SLOW:		// ③レンズ低速駆動(無限遠方向)
		set_pwm(ZOOM_PWMCH, ZOOM_SLOW_PULSE, ZOOM_SLOW_PULSE);		// 低速 遠⇔近3秒
		break;
	case ZOOM_CONT_ZOOMOUT_FAST:      // ①レンズ高速駆動(マクロ方向)
	case ZOOM_CONT_ZOOMIN_FAST:		// ④レンズ高速駆動(無限遠方向)
		set_pwm(ZOOM_PWMCH, ZOOM_FAST_PULSE, ZOOM_FAST_PULSE);		// 高速 遠⇔近1秒
		break;
	}

	return ax::AXFACTOR_SUCCESS;
}

#ifdef PARASOFT_CPPTEST
// C++test sendスタブ
int AXMImageSensor::send(AXFObjectName& name, AXFEvent_t eventId, void* data, int size)
{
	return return_stub_send;
}

// C++test setStateInfoスタブ
int AXMImageSensor::setStateInfo(AXFActor* obj, int initState, int maxState)
{
	return return_stub_setStateInfo;
}

void AXMImageSensor::setStateTable(int registState, const StateTable* stateTable)
{
	return;
}

#endif	// PARASOFT_CPPTEST

