/*
 * @file   AXHPixcessorMemConfig.cpp
 * @brief  Source file of AXHPixcessorMemConfig class.
 * @par    Programming Language
 *         C++
 */
#include "AXHPixcessorMemConfig.hpp"
#include "AXHRegAddr.hpp"
//#define CONNECT_TEST
#ifdef CONNECT_TEST
#include <iostream>
#endif
static unsigned int g_picID   __attribute__ ((at (0x20059400)));		//今回セクション名では無く直接アドレス指定を行う ((section ("ispParam1")));
// 6バンクを有効にする場合は下記のシンボルを有効にする
//#define ENABLE_PIXCESSOR_MEM_BANK_6
const unsigned int  SET_SPPSHTWB0_NORMAL = 0x00000007ul;      // RPU 出力データシフト量(通常モード時)
const unsigned int  SET_SPPSHTWB0_LINEAR = 0x00000005ul;      // RPU 出力データシフト量(Linearモード時)
const unsigned char INIT_PIC_NUM_FOR_COUNT_END = 16;
const unsigned char INIT_PIC_NUM_FROM_ADJUST   =  2;          // isp調整モードから通常モードへ復帰時に開始するカウンタ値

unsigned char g_picNum = 0;

const unsigned int SCL_BANK_ADR_LIST[][4] = {
	  { AXH_DRAM_OFST_ISP_SCL0_0, AXH_DRAM_OFST_ISP_SCL1_0, AXH_DRAM_OFST_ISP_SCL2_0, AXH_DRAM_OFST_ISP_SCL3_0 }
	, { AXH_DRAM_OFST_ISP_SCL0_1, AXH_DRAM_OFST_ISP_SCL1_1, AXH_DRAM_OFST_ISP_SCL2_1, AXH_DRAM_OFST_ISP_SCL3_1 }
	, { AXH_DRAM_OFST_ISP_SCL0_2, AXH_DRAM_OFST_ISP_SCL1_2, AXH_DRAM_OFST_ISP_SCL2_2, AXH_DRAM_OFST_ISP_SCL3_2 }
	, { AXH_DRAM_OFST_ISP_SCL0_3, AXH_DRAM_OFST_ISP_SCL1_3, AXH_DRAM_OFST_ISP_SCL2_3, AXH_DRAM_OFST_ISP_SCL3_3 }
	, { AXH_DRAM_OFST_ISP_SCL0_4, AXH_DRAM_OFST_ISP_SCL1_4, AXH_DRAM_OFST_ISP_SCL2_4, AXH_DRAM_OFST_ISP_SCL3_4 }
	, { AXH_DRAM_OFST_ISP_SCL0_5, AXH_DRAM_OFST_ISP_SCL1_5, AXH_DRAM_OFST_ISP_SCL2_5, AXH_DRAM_OFST_ISP_SCL3_5 }
};

AXHPixcessorMemConfig::AXHPixcessorMemConfig() :
	  EXEC_BANK_SWITCH_MASK      (0x01ul)
	, SECOND_BANK_SWITCHING_MASK (0x02ul)
	, picID                      (0)
	, m_linearMode               (1)
	, m_setFirstFrame            (false)
{
	// 現状ハードとは異なるため不要
	/*
	// TODO 自動生成されたコンストラクター・スタブ
	init();
	*/
}

AXHPixcessorMemConfig::~AXHPixcessorMemConfig() {
	// TODO Auto-generated destructor stub
}

void AXHPixcessorMemConfig::init() {
	// 現状ハードとは異なるため不要
	/*
	p_SPP_SHT1                  = (unsigned int*)AXH_SPP_SHT1;
	p_REG_ISP_SCL_DMA0          = (unsigned int*)AXH_REG_ISP_SCL_DMA0;
	p_REG_ISP_SCL_DMA1          = (unsigned int*)AXH_REG_ISP_SCL_DMA1;
	p_REG_ISP_SCL_DMA2          = (unsigned int*)AXH_REG_ISP_SCL_DMA2;
	p_REG_ISP_SCL_DMA3          = (unsigned int*)AXH_REG_ISP_SCL_DMA3;
	p_REG_ISP_SCL_DMA4          = (unsigned int*)AXH_REG_ISP_SCL_DMA4;
	p_REG_ISP_SCL_IMG_ID        = (unsigned int*)AXH_REG_ISP_SCL_IMG_ID;
	p_RPU_DMAR0_OFS             = (unsigned int*)AXH_RPU_DMAR0_OFS;
	p_RPU_DMAW1_OFS             = (unsigned int*)AXH_RPU_DMAW1_OFS;
	p_NR_DMAR_OFS               = (unsigned int*)AXH_NR_DMAR_OFS;
	*p_SPP_SHT1                 = SET_SPPSHTWB0_NORMAL;
	*/
}

void AXHPixcessorMemConfig::setLinearMode(unsigned char imageIFOpeMode) {
	// 現状ハードとは異なるため不要
	/*

	if (m_linearMode != imageIFOpeMode) {
		g_picNum = 0;
		if (imageIFOpeMode == 1) {
			*p_SPP_SHT1 = SET_SPPSHTWB0_LINEAR;
			m_linearMode = 1;
		}
		else {
			*p_SPP_SHT1 = SET_SPPSHTWB0_NORMAL;
			m_linearMode = 0;
		}
	}
	*/
}

int AXHPixcessorMemConfig::switch_pixcessor_mem_bank() {
	// 現状ハードとは異なるため不要
	/*

	int buffno = -1;

	if (g_picNum == 0xFF) {
		g_picNum = INIT_PIC_NUM_FOR_COUNT_END;
	}
	else {
		g_picNum++;
	}

	// isp調整モードから通常モードへの復帰時、1フレーム目に復帰するので、
	// バンク切り替え用カウンタをそれに合わせた値[INIT_PIC_NUM_FROM_ADJUST]に設定する
	if (m_setFirstFrame) {
		g_picNum = INIT_PIC_NUM_FROM_ADJUST;

		m_setFirstFrame = false;
	}

#ifdef CONNECT_TEST
	std::cout << "AXHPixcessorMemConfig:" << (int)g_picNum << std::endl;
#endif

	if (m_linearMode == 1) {
		buffno = select_mem_bank_linear(g_picNum);
	}
	else {
		buffno = select_mem_bank_normal(g_picNum);
	}
	g_picID = picID;
	return buffno;
	*/
	return 0;
}

inline int AXHPixcessorMemConfig::select_mem_bank_linear(unsigned char picNum) {
	// 現状ハードとは異なるため不要
	/*

#ifdef ENABLE_PIXCESSOR_MEM_BANK_6
	int buffno = picNum % 6;
#else
	int buffno = picNum & 0x01;
#endif // ENABLE_PIXCESSOR_MEM_BANK_6

#ifdef CONNECT_TEST
	std::cout << "linear mem set bank = " << buffno << std::endl;
#endif
	// 60fpsモード
	// IVA(ch5)用の画像IDを設定
	picID++;
	*p_REG_ISP_SCL_IMG_ID = picID;

	if (buffno & 0x01) {
		*p_RPU_DMAR0_OFS    = AXH_DRAM_OFST_IMG_SPU_1;
#ifdef USE_NON_ROM_ENV
		*p_RPU_DMAW1_OFS    = AXH_DRAM_OFST_ISP_3A_1;
#endif  //  USE_NON_ROM_ENV
		*p_REG_ISP_SCL_DMA4 = AXH_DRAM_OFST_ISP_NR_1;
		*p_NR_DMAR_OFS      = AXH_DRAM_OFST_ISP_NR_0;
	}
	else {
		*p_RPU_DMAR0_OFS    = AXH_DRAM_OFST_IMG_SPU_0;
#ifdef USE_NON_ROM_ENV
		*p_RPU_DMAW1_OFS    = AXH_DRAM_OFST_ISP_3A_0;
#endif  //  USE_NON_ROM_ENV
		*p_REG_ISP_SCL_DMA4 = AXH_DRAM_OFST_ISP_NR_0;
		*p_NR_DMAR_OFS      = AXH_DRAM_OFST_ISP_NR_1;
	}

	*p_REG_ISP_SCL_DMA0 = SCL_BANK_ADR_LIST[buffno][0];
	*p_REG_ISP_SCL_DMA1 = SCL_BANK_ADR_LIST[buffno][1];
	*p_REG_ISP_SCL_DMA2 = SCL_BANK_ADR_LIST[buffno][2];
	*p_REG_ISP_SCL_DMA3 = SCL_BANK_ADR_LIST[buffno][3];

	return buffno;
	*/
	return 0;
}

inline int AXHPixcessorMemConfig::select_mem_bank_normal(unsigned char picNum) {
	// 現状ハードとは異なるため不要
	/*
	int buffno = -1;

	// 30fpsモード
	if ((picNum & EXEC_BANK_SWITCH_MASK) != EXEC_BANK_SWITCH_MASK) {
		// IVA(ch5)用の画像IDを設定
		picID++;
		*p_REG_ISP_SCL_IMG_ID = picID;

		// WDRモード
		if ((picNum & SECOND_BANK_SWITCHING_MASK) == SECOND_BANK_SWITCHING_MASK) {
			*p_RPU_DMAR0_OFS    = AXH_DRAM_OFST_IMG_MIX_0;
#ifdef USE_NON_ROM_ENV
			*p_RPU_DMAW1_OFS    = AXH_DRAM_OFST_ISP_3A_0;
#endif  //  USE_NON_ROM_ENV
			*p_REG_ISP_SCL_DMA4 = AXH_DRAM_OFST_ISP_NR_0;
			*p_NR_DMAR_OFS      = AXH_DRAM_OFST_ISP_NR_1;
		}
		else {
			*p_RPU_DMAR0_OFS    = AXH_DRAM_OFST_IMG_MIX_1;
#ifdef USE_NON_ROM_ENV
			*p_RPU_DMAW1_OFS    = AXH_DRAM_OFST_ISP_3A_1;
#endif  //  USE_NON_ROM_ENV
			*p_REG_ISP_SCL_DMA4 = AXH_DRAM_OFST_ISP_NR_1;
			*p_NR_DMAR_OFS      = AXH_DRAM_OFST_ISP_NR_0;
		}
#ifdef ENABLE_PIXCESSOR_MEM_BANK_6
		buffno = (picNum - 1) % 12;
		buffno = buffno >> 1;
#else
		buffno = (picNum >> 1) - 1;
		buffno = buffno & 0x01;
#endif // ENABLE_PIXCESSOR_MEM_BANK_6

		*p_REG_ISP_SCL_DMA0 = SCL_BANK_ADR_LIST[buffno][0];
		*p_REG_ISP_SCL_DMA1 = SCL_BANK_ADR_LIST[buffno][1];
		*p_REG_ISP_SCL_DMA2 = SCL_BANK_ADR_LIST[buffno][2];
		*p_REG_ISP_SCL_DMA3 = SCL_BANK_ADR_LIST[buffno][3];
	}
#ifdef CONNECT_TEST
	std::cout << "normal mem set bank = " << buffno << std::endl;
#endif

	return buffno;
	*/
	return 0;
}

void AXHPixcessorMemConfig::setBankCounterAtFirstFrame(bool set) {
	// 現状ハードとは異なるため不要
	/*
	m_setFirstFrame = set;
	*/
}
