#ifndef PARASOFT_CPPTEST

#ifndef _PROC_DEF_INTC_H_
#define _PROC_DEF_INTC_H_

#include "audio_dsp_com.h"
#include "AXMImageSensor/imageSensorDrv.h"		// K.Kawachi add
#include "AXMCommon/AXMCommonConfig.hpp"
#include "AXMCommon/AXMCommonBridgeParam.hpp"
#include "AXMCommon/AXMCommonStruct.hpp"
#ifndef BB_TMP_PASS	/* 一旦コンパイルを通す用 */
#include "proc_def_sio.h"


// DSP PARAM
//xt_xtensa側のregs/dsp.hヘッダを参照
#define AUDIODSP_HOST_INT_BIT           (AUDIO_DSP_INT_HOST)
#define AUDIODSP_IMAGEIF_ISI_INT_BIT    (AUDIO_DSP_INT_IMAGEIF_ISI)
#define AUDIODSP_IMAGEIF_SPU_INT_BIT    (AUDIO_DSP_INT_IMAGEIF_SPU)
#define AUDIODSP_IMAGEIF_MIX_INT_BIT    (AUDIO_DSP_INT_IMAGEIF_MIX)
#define AUDIODSP_IMAGEIF_DMAW_INT_BIT   (AUDIO_DSP_INT_IMAGEIF_DMAW)
#define AUDIODSP_IMAGEIF_DMAR_INT_BIT   (AUDIO_DSP_INT_IMAGEIF_DMAR)
#define AUDIODSP_ISP_RPU_INT_BIT        (AUDIO_DSP_INT_ISP_RPU)
#define AUDIODSP_ISP_SCL_INT_BIT        (AUDIO_DSP_INT_ISP_SCL)
#define AUDIODSP_ISP_DMAW_INT_BIT       (AUDIO_DSP_INT_ISP_DMAW)
#define AUDIODSP_ISP_DMAR_INT_BIT       (AUDIO_DSP_INT_ISP_DMAR)
#define AUDIODSP_APCKT_INT_BIT          (AUDIO_DSP_INT_APKT)
#define AUDIODSP_I2C0_INT_BIT           (AUDIO_DSP_INT_I2C0)
#define AUDIODSP_I2C1_INT_BIT           (AUDIO_DSP_INT_I2C1)
#define AUDIODSP_SIO0_INT_BIT           (AUDIO_DSP_INT_SIO0)
#define AUDIODSP_SIO1_INT_BIT           (AUDIO_DSP_INT_SIO1)
#define AUDIODSP_SIO2_INT_BIT           (AUDIO_DSP_INT_SIO2)

//static void timer0Isr(void);
//static void timer1Isr(void);

void audio_dsp_int_proc(void);
void audio_init_isp_mode(void);

void recv_host_int(void);
void recv_imageif_isi_int(void);
void recv_imageif_spu_int(void);
void recv_imageif_mix_int(void);
void recv_imageif_dmaw_int(void);
void recv_imageif_dmar_int(void);
void recv_isp_rpu_int(void);
void recv_isp_scl_int(void);
void recv_isp_dmaw_int(void);
void recv_isp_dmar_int(void);
void recv_gdu_core_int(void);
void recv_i2c0_int(void);
void recv_i2c1_int(void);
void recv_sio0_int(void);
void recv_sio1_int(void);
void recv_sio2_int(void);
void hndlImageSensorDrv(void);
void start_gdu(void);
void switch_gdu();
void proc_linear(UInt32 id);

static  UInt32 g_AXMExtIntInit = 0; //割り込みハンドラ動作開始フラグ
//static  UInt32 g_ImgPicCt;
UInt32 g_ImgPicCt;
static  UInt32 g_MixPicCt;
static  UInt32 g_IspPicCt;
static  UInt32 g_IspStartCt;
static  UInt32 g_IspStartCt_pre;
static  UInt32 g_DispPicCt;
static  UInt32 g_DispPicSwCt;
//static  UInt32 g_I2sBufCt;
//static  UInt32 g_i2s_x32B_unit;
//static bool wdrMode;	// wdr対応で追加

//// external interrupt
//static void exIsr(void)
//{
//    audio_dsp_int_proc();
//    return;
//}

// interrupt handlar
void audio_dsp_int_proc(void){
    UInt32 status;
    status = GetReg32(REG_AUDIO_DSP_INT_STATUS);
    
    if((status & AUDIODSP_HOST_INT_BIT)==AUDIODSP_HOST_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_HOST_INT_BIT);
	recv_host_int();
    }
    if((status & AUDIODSP_IMAGEIF_ISI_INT_BIT)==AUDIODSP_IMAGEIF_ISI_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_ISI_INT_BIT);
	recv_imageif_isi_int();
    }
    if((status & AUDIODSP_IMAGEIF_SPU_INT_BIT)==AUDIODSP_IMAGEIF_SPU_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_SPU_INT_BIT);
	recv_imageif_spu_int();
    }
    if((status & AUDIODSP_IMAGEIF_MIX_INT_BIT)==AUDIODSP_IMAGEIF_MIX_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_MIX_INT_BIT);
	recv_imageif_mix_int();
    }
    if((status & AUDIODSP_IMAGEIF_DMAW_INT_BIT)==AUDIODSP_IMAGEIF_DMAW_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_DMAW_INT_BIT);
	recv_imageif_dmaw_int();
    }
    if((status & AUDIODSP_IMAGEIF_DMAR_INT_BIT)==AUDIODSP_IMAGEIF_DMAR_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_DMAR_INT_BIT);
	recv_imageif_dmar_int();
    }
    if((status & AUDIODSP_ISP_RPU_INT_BIT)==AUDIODSP_ISP_RPU_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_RPU_INT_BIT);
	recv_isp_rpu_int();
    }
    if((status & AUDIODSP_ISP_SCL_INT_BIT)==AUDIODSP_ISP_SCL_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_SCL_INT_BIT);
	recv_isp_scl_int();
    }
    if((status & AUDIODSP_ISP_DMAW_INT_BIT)==AUDIODSP_ISP_DMAW_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_DMAW_INT_BIT);
	recv_isp_dmaw_int();
    }
    if((status & AUDIODSP_ISP_DMAR_INT_BIT)==AUDIODSP_ISP_DMAR_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_DMAR_INT_BIT);
	recv_isp_dmar_int();
    }
    if((status & AUDIODSP_APCKT_INT_BIT)==AUDIODSP_APCKT_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_APCKT_INT_BIT);
	recv_gdu_core_int();
    }
    if((status & AUDIODSP_I2C0_INT_BIT)==AUDIODSP_I2C0_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_I2C0_INT_BIT);
	recv_i2c0_int();
    }
    if((status & AUDIODSP_I2C1_INT_BIT)==AUDIODSP_I2C1_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_I2C1_INT_BIT);
	recv_i2c1_int();
    }
    if((status & AUDIODSP_SIO0_INT_BIT)==AUDIODSP_SIO0_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_SIO0_INT_BIT);
	recv_sio0_int();
    }
    if((status & AUDIODSP_SIO1_INT_BIT)==AUDIODSP_SIO1_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_SIO1_INT_BIT);
	recv_sio1_int();
    }
    if((status & AUDIODSP_SIO2_INT_BIT)==AUDIODSP_SIO2_INT_BIT){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_SIO2_INT_BIT);
	recv_sio2_int();
    }

    return;
}

void audio_dsp_int_enable(UInt32 flag){
    SetReg32(REG_AUDIO_DSP_INT_MASK, flag);
}

#if 1
void audio_init_isp_mode(void) {
    
    g_AXMExtIntInit = 1;  //外部割込みハンドラ動作開始
    //-- initial global value
    g_ImgPicCt = 0;
    g_MixPicCt = 0;
    g_IspPicCt = 0;
    g_IspStartCt = 0;
    g_IspStartCt_pre = 0;
    g_DispPicCt = 0;
    g_DispPicSwCt = 0;

    return;
}
#endif

// sub routin (host int)
void recv_host_int(void){

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_HOST_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }
	return;
}

// sub routin (isp int)
void recv_imageif_isi_int(void){
	UInt32 id;

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_ISI_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }
	id = GetReg32(ISI_DSP_IC_STATUS);
	SetReg32(ISI_DSP_IC_STATUS, id); // int clr

	hndlImageSensorDrv();			// K.Kawachi add

#ifndef DISABLE_LINEAR_MODE
	unsigned char opemode = p_AXMPixcessorInt->getImageIFOpeMode();

	// ImageIF動作モード変更チェック
	if (p_AXMPixcessorInt->getImageIFOpeModeUpd()) {
	    g_MixPicCt = g_IspPicCt;
	}

	// linearモード時
	if (opemode == 1) {
		proc_linear(id);
//		setRegLog4(id);
		return;
	}
#endif  //  DISABLE_LINEAR_MODE
	// カウンタ最大時の初期化処理
	if (g_MixPicCt == 0xffffffff) {
		if (g_MixPicCt == g_IspPicCt) {
			g_IspPicCt = g_MixPicCt = 1;
		}
		else {
			g_MixPicCt = 1;
			g_IspPicCt = 0;
		}
	}


	if(id&0x1){
		p_AXMPixcessorInt->getAfEval();
		g_ImgPicCt++;
		//  AXMIspへイベント通知
	    p_AXMPixcessorInt->frameIsrHandler();
//		setRegLog4(id);

	    // MIXが処理された事を確認してから、ISPフレーム開始フラグを立てる
		if (g_IspPicCt < g_MixPicCt) {
			p_AXMPixcessorInt->startIsp();
			g_IspStartCt = g_MixPicCt;
			if (g_DispPicCt == 0) {
				g_DispPicCt++;
				start_gdu();
			}
		}
	}

	if((id&0x2)==0x2){
		if (g_IspPicCt < g_MixPicCt) {
			switch_gdu();
		}
	}

	return;
}

void recv_imageif_spu_int(void){

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_SPU_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    return;
}

void recv_imageif_mix_int(void){
	UInt32 id;

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_MIX_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    id = GetReg32(RegMIX_INT_STATUS);
    SetReg32(RegMIX_INT_STATUS, id); // int clr

    if((id&0x2)==2){
	  g_MixPicCt ++;
    }

    return;
}

void recv_imageif_dmaw_int(void){
	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_DMAW_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    return;
}

void recv_imageif_dmar_int(void){

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_IMAGEIF_DMAR_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    return;
}

void recv_isp_rpu_int(void){

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_RPU_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    return;
}

void recv_isp_scl_int(void){
    UInt32 id;

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_SCL_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    id = GetReg32(REG_ISP_SCL_INT_STATUS);
    SetReg32(REG_ISP_SCL_INT_STATUS, id);  // int clr

    ClrRegFld32(NR_ISP_MODE, 1);  // isp frame end

    g_IspPicCt ++;
    
    return;
}

void recv_isp_dmaw_int(void){

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_DMAW_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    return;
}

void recv_isp_dmar_int(void){

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_ISP_DMAR_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    return;
}

void recv_gdu_core_int(void){

	SetReg32(REG_AUDIO_DSP_INT_STATUS, AUDIODSP_APCKT_INT_BIT);
  if(g_AXMExtIntInit == 0){
    return;
  }

    return;
}

void recv_i2c0_int(void){
  if(g_AXMExtIntInit == 0){
    return;
  }
    return;
}

void recv_i2c1_int(void){
  if(g_AXMExtIntInit == 0){
    return;
  }
    return;
}

void recv_sio0_int(void){
  if(g_AXMExtIntInit == 0){
    return;
  }
    return;
}

void recv_sio1_int(void){
  if(g_AXMExtIntInit == 0){
    return;
  }
    return;
}

void recv_sio2_int(void){
  if(g_AXMExtIntInit == 0){
    return;
  }
    return;
}

void hndlImageSensorDrv()
{
	if(p_AXMPixcessorInt) {
		if((p_AXMPixcessorInt->imageSensorParam.st_change_sts & E_ISCHANG_shutter) != 0){
			set_sio_cmos_shutter(REG_CMOS_CID0_SHS10, p_AXMPixcessorInt->imageSensorParam.st_time);
		}
		if((p_AXMPixcessorInt->imageSensorParam.st_change_sts & E_ISCHANG_gain) != 0){
			set_sio_cmos_shutter(REG_CMOS_CID0_GAIN0, p_AXMPixcessorInt->imageSensorParam.st_gain);
		}
		if((p_AXMPixcessorInt->imageSensorParam.st_change_sts & E_ISCHANG_vmax) != 0){
			set_sio_cmos_shutter(REG_CMOS_CID0_VMAX0, p_AXMPixcessorInt->imageSensorParam.st_frm);
		}
	}
}
void start_gdu(void) {
#ifdef USE_AXBRIDGE
	//フレーム生成完了通知(DSP->ARM)通知ハンドラ
	p_AXMPixcessorInt->frameGenHandler(EVENT_ISPTONVR_GDU_START);
#else  /* USE_AXBRIDGE */
	p_AXMPixcessorInt->startGdu();
#endif /* USE_AXBRIDGE */

}

void switch_gdu() {
#ifdef USE_AXBRIDGE
	int complex = GetReg32(REG_ISP_SCL_DIO_SATD8X8);
	//complex = p_AXMPixcessorInt->getScalerSatd();
	//フレーム生成完了通知(DSP->ARM)通知ハンドラ
	p_AXMPixcessorInt->frameGenHandler(EVENT_ISPTONVR_GDU_BANK_SWITCH, (g_MixPicCt & 0x01), complex);
#else  /* USE_AXBRIDGE */
	p_AXMPixcessorInt->switchGduBankNo();
#endif /* USE_AXBRIDGE */

}

void proc_linear(UInt32 id) {
	static bool pastPreFrame = false;
	if (pastPreFrame == false) {
		if (3 < g_ImgPicCt) {
			pastPreFrame = true;
		}
	}

	if (id & 0x1) {
		p_AXMPixcessorInt->getAfEval();
		g_ImgPicCt++;

		//  AXMIspへイベント通知
		p_AXMPixcessorInt->frameIsrHandler();

		// 準備フレームを超えたところからPixcessorを開始する
		if (pastPreFrame) {
			p_AXMPixcessorInt->startIsp();
			if (g_DispPicCt == 0) {
				g_DispPicCt++;
				start_gdu();
			}
		}
	}

	if ((id&0x2) == 0x2) {
		if (pastPreFrame) {
			switch_gdu();
		}
	}
}

#endif // _PROC_DEF_INTC_H_

#endif  //  PARASOFT_CPPTEST

#endif //  BB_TMP_PASS