/**
 * @brief       SPC Primitive
 * @author      AXELL CORPORATION
 * @description SPC Manager Layer
 * @note        none
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
 * @history     2019_03_08  [SDK2.2] SPCBOOTUP_STATUSレジスタのステータスをクリアできない不具合を修正 (#2440)
 * @history     2019_03_08  [SDK2.2] FCS制御が内蔵のCortex-A5で正常に実行できない不具合を修正 (#2441)
 * @history     2019_03_08  [SDK2.2] AG903_SPCPrmSetSdmcMiscCtrlで取得できない値がある不具合を修正 (#2442)
 * @history     2019_03_08  [SDK2.2] SYSでの軽微な不具合修正 (#2443)
 * @history     2019_03_08  [SDK2.2] AG903_SPCPrmGetVideoAdcCtrlでREF_BIAS_UPが取得できない不具合を修正 (#2445)
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by AXELL CORPORATION.
 * Copyright (C) 2017-2019 AXELL CORPORATION, all rights reserved.
 */
/* DOM-IGNORE-END */

#include "AG903_errno.h"
#include "AG903_common.h"
#include "sys/spcprm.h"
#include "register/AG903_spcreg.h"

/**
 * @brief           SPCBOOTUP_STATUSのレジスタRead
 * @param           pwr     [out] PWRビット (1=ブート後)
 * @param           wdt_rst [out] WDRビット (1=WDTによるリセット)
 * @param           hw_rst  [out] HWRビット (1=nRESET端子によるリセット)
 * @return          void
 * @description     SPCBOOTUP_STATUSのレジスタRead
*/
void AG903_SPCPrmGetBootupStatus(uint8_t* pwr, uint8_t* wdt_rst, uint8_t* hw_rst)
{
	uint32_t	val;

	ASSERT(NULL != pwr);
	ASSERT(NULL != wdt_rst);
	ASSERT(NULL != hw_rst);
	
	val = AG903_SPC->BOOTUP_STATUS;
	(*pwr)     = (uint8_t)((val & AG903_SPC_BOOTUP_STATUS_PWR_MSK) >> AG903_SPC_BOOTUP_STATUS_PWR_POS);
	(*wdt_rst) = (uint8_t)((val & AG903_SPC_BOOTUP_STATUS_WDR_MSK) >> AG903_SPC_BOOTUP_STATUS_WDR_POS);
	(*hw_rst)  = (uint8_t)((val & AG903_SPC_BOOTUP_STATUS_HWR_MSK) >> AG903_SPC_BOOTUP_STATUS_HWR_POS);
	
	return;
}

/**
 * @brief           SPCBOOTUP_STATUSのレジスタWrite
 * @param           pwr     [in] PWRビットクリア指定
 * @param           wdt_rst [in] WDRビットクリア指定
 * @param           hw_rst  [in] HWRビットクリア指定
 * @return          void
 * @description     SPCBOOTUP_STATUSのレジスタWrite
 * @note            引数に"1"を指定すると該当ビットをクリアします。
*/
void AG903_SPCPrmClrBootupStatus(uint8_t pwr, uint8_t wdt_rst, uint8_t hw_rst)
{
	uint32_t	val = 0;
	
	ASSERT(0 == pwr     || 1 == pwr);
	ASSERT(0 == wdt_rst || 1 == wdt_rst);
	ASSERT(0 == hw_rst  || 1 == hw_rst);

	val |= (pwr     << AG903_SPC_BOOTUP_STATUS_PWR_POS) & AG903_SPC_BOOTUP_STATUS_PWR_MSK;
	val |= (wdt_rst << AG903_SPC_BOOTUP_STATUS_WDR_POS) & AG903_SPC_BOOTUP_STATUS_WDR_MSK;
	val |= (hw_rst  << AG903_SPC_BOOTUP_STATUS_HWR_POS) & AG903_SPC_BOOTUP_STATUS_HWR_MSK;
	AG903_SPC->BOOTUP_STATUS = val;
	
	return;
}

/**
 * @brief           SPCFCS_CTRLのレジスタWrite
 * @param           slf_refresh	[in] FCSシーケンス中のDDRセルフリフレッシュ制御<p>
 * (true=セルフリフレッシュコマンドを使用する。false=使用しない。)
 * @param           pll0_rst 	[in] FCSシーケンス中のPLL0をリセット制御<p>
 * (true==PLL0をリセットする。falseリセットしない。)
 * @param           cpu_msk 	[in] FCSシーケンスを行っているCPU<p>
 * (2:Cortex-A5 3:外付けCPU その他の値:設定禁止)
 * @param           enable 		[in] FCS制御  (true=実行)
 * @return          void
 * @description     SPCFCS_CTRLのレジスタWrite
 * @note            FCSシーケンスに従って設定して下さい。
 * @note            システム起動の初期段階で実行されることを前提としています。
*/
void AG903_SPCPrmSetFcsCtrl(uint8_t slf_refresh, uint8_t pll0_rst, uint8_t cpu_msk, uint8_t enable)
{
	uint32_t	val = 0;

	ASSERT(2 == cpu_msk || 3 == cpu_msk);

	if(false == slf_refresh) {
		val |= (uint32_t)(1 << AG903_SPC_FCS_CTRL_SELFR_CMD_OFF_POS);	/* 1=使用しない */
	}
	if(false == pll0_rst) {
		val |= (uint32_t)(1 << AG903_SPC_FCS_CTRL_FCS_PLL0_RSTn_POS);	/* 1=リセットしない */
	}
	val |= ((cpu_msk>>0 & 0x1) << AG903_SPC_FCS_CTRL_CPU_MASK_POS);
	val |= ((cpu_msk>>1 & 0x1) << AG903_SPC_FCS_CTRL_CPU_MASK2_POS);
	if(true == enable) {
		val |= (uint32_t)(1 << AG903_SPC_FCS_CTRL_FCS_POS);
	}
	AG903_SPC->FCS_CTRL = val;
	
	return;
}

/**
 * @brief           SPCFCS_CTRLのレジスタRead
 * @param           slf_refresh	[out] FCSシーケンス中のDDRセルフリフレッシュ制御
 * @param           pll0_rst 	[out] FCSシーケンス中のPLL0をリセット制御
 * @param           cpu_msk 	[out] FCSシーケンス中のCPU制御
 * @param           enable 		[out] FCS制御
 * @return          void
 * @description     SPCFCS_CTRLのレジスタRead
 * @note            各パラメータはAG903_SPCPrmSetFcsCtrlを参照して下さい。
*/
void AG903_SPCPrmGetFcsCtrl(uint8_t* slf_refresh, uint8_t* pll0_rst, uint8_t* cpu_msk, uint8_t* enable)
{
	uint32_t	val;

	ASSERT(NULL != slf_refresh);
	ASSERT(NULL != pll0_rst);
	ASSERT(NULL != cpu_msk);
	ASSERT(NULL != enable);

	val = AG903_SPC->FCS_CTRL;
	if(AG903_SPC_FCS_CTRL_SELFR_CMD_OFF_MSK & val) {
		(*slf_refresh) = false;
	}
	else {
		(*slf_refresh) = true;
	}
	if(AG903_SPC_FCS_CTRL_FCS_PLL0_RSTn_MSK & val) {
		(*pll0_rst) = false;
	}
	else {
		(*pll0_rst) = true;
	}
	if(AG903_SPC_FCS_CTRL_CPU_MASK_MSK & val) {
		(*cpu_msk) = 1<<0;
	}
	else {
		(*cpu_msk) = 0<<0;
	}
	if(AG903_SPC_FCS_CTRL_CPU_MASK2_MSK & val) {
		(*cpu_msk) |= 1<<1;
	}
	else {
		(*cpu_msk) |= 0<<1;
	}
	if(AG903_SPC_FCS_CTRL_FCS_MSK & val) {
		(*enable) = true;
	}
	else {
		(*enable) = false;
	}
	return;
}

/**
 * @brief           SPCFCS_CTRLレジスタのSW_RSTビットSet
 * @param           none
 * @return          void
 * @description     SPCFCS_CTRLレジスタのSW_RSTビットSet
 * @note            発行はソフトウェアリセットシーケンスに従って下さい。
*/
void AG903_SPCPrmSwReset(void)
{
	uint32_t val;
	val = AG903_SPC->FCS_CTRL;
	val |= (1 << AG903_SPC_FCS_CTRL_SW_RST_POS);
	AG903_SPC->FCS_CTRL = val;
	return;
}

/**
 * @brief           SPCINT_STATUSのレジスタRead
 * @param           status [out] FCS割込みステータス
 * @return          void
 * @description     SPCINT_STATUSのレジスタRead
*/
void AG903_SPCPrmGetFcsIntStatus(uint8_t* status)
{
	uint32_t	val;
	
	ASSERT(NULL != status);
	
	val = AG903_SPC->INT_STATUS;
	(*status) = (uint8_t)((val & AG903_SPC_INT_STATUS_INT_FCS_MSK) >> AG903_SPC_INT_STATUS_INT_FCS_POS);
	
	return;
}

/**
 * @brief           SPCINT_STATUSのレジスタWrite
 * @param           status [out] FCS割込みステータス
 * @return          void
 * @description     SPCINT_STATUSのレジスタWrite
*/
void AG903_SPCPrmClrFcsIntStatus(void)
{
	AG903_SPC->INT_STATUS = (1 << AG903_SPC_INT_STATUS_INT_FCS_POS);
	return;
}

/**
 * @brief           SPCINT_ENABLEのレジスタWrite
 * @param           enable [in] イネーブル設定 (true=イネーブル)
 * @return          void
 * @description     SPCINT_ENABLEのレジスタWrite
*/
void AG903_SPCPrmSetFcsIntEnable(uint8_t enable)
{
	uint32_t	val = 0;

	if(true == enable) {
		val |= (1 << AG903_SPC_INT_ENABLE_EINT_FCS_POS);
	}
	AG903_SPC->INT_ENABLE = val;
	
	return;
}

/**
 * @brief           SPCINT_ENABLEのレジスタRead
 * @param           enable [out] イネーブル設定状態 (true=イネーブル)
 * @return          void
 * @description     SPCINT_ENABLEのレジスタRead
*/
void AG903_SPCPrmGetFcsIntEnable(uint8_t* enable)
{
	uint32_t	val;
	
	ASSERT(NULL != enable);
	
	val = AG903_SPC->INT_ENABLE;
	if(AG903_SPC_INT_ENABLE_EINT_FCS_MSK & val) {
		(*enable) = true;
	}
	else {
		(*enable) = false;
	}
	
	return;
}

/**
 * @brief           SPCSOFTRESET_SETUPのレジスタWrite
 * @param           wait   [in] リセット発行タイミング (SYS_FTCクロック単位)
 * @param           active [in] リセット発行期間 (SYS_FTCクロック単位)
 * @return          void
 * @description     SPCSOFTRESET_SETUPのレジスタWrite
*/
void AG903_SPCPrmSetSoftResetSetup(uint8_t wait, uint8_t active)
{
	uint32_t	val = 0;
	
	val |= (wait   << AG903_SPC_SOFTRESET_SETUP_SWRST_WAIT_POS)   & AG903_SPC_SOFTRESET_SETUP_SWRST_WAIT_MSK;
	val |= (active << AG903_SPC_SOFTRESET_SETUP_SWRST_ACTIVE_POS) & AG903_SPC_SOFTRESET_SETUP_SWRST_ACTIVE_MSK;
	AG903_SPC->SOFTRESET_SETUP = val;
	
	return;
}

/**
 * @brief           SPCSOFTRESET_SETUPのレジスタRead
 * @param           wait   [out] リセット発行タイミング (SYS_FTCクロック単位)
 * @param           active [out] リセット発行期間 (SYS_FTCクロック単位)
 * @return          void
 * @description     SPCSOFTRESET_SETUPのレジスタRead
*/
void AG903_SPCPrmGetSoftResetSetup(uint8_t* wait, uint8_t* active)
{
	uint32_t	val;
	
	ASSERT(NULL != wait);
	ASSERT(NULL != active);
	
	val = AG903_SPC->SOFTRESET_SETUP;
	(*wait)   = (uint8_t)((val & AG903_SPC_SOFTRESET_SETUP_SWRST_WAIT_MSK)   >> AG903_SPC_SOFTRESET_SETUP_SWRST_WAIT_POS);
	(*active) = (uint8_t)((val & AG903_SPC_SOFTRESET_SETUP_SWRST_ACTIVE_MSK) >> AG903_SPC_SOFTRESET_SETUP_SWRST_ACTIVE_POS);
	
	return;
}

/**
 * @brief           SPCPLL0_CTRLのレジスタWrite
 * @param           param [in] 設定パラメータ
 * @return          void
 * @description     SPCPLL0_CTRLのレジスタWrite
 * @note            FCSシーケンスに従って設定して下さい。
*/
void AG903_SPCPrmSetPll0Ctrl(AG903_SPCPrmPllnParam* param)
{
	uint32_t	val = 0;
	
	ASSERT(NULL != param);

	val |= (param->ns  << AG903_SPC_PLL0_CTRL_NS_POS)  & AG903_SPC_PLL0_CTRL_NS_MSK;
	val |= (param->ms  << AG903_SPC_PLL0_CTRL_MS_POS)  & AG903_SPC_PLL0_CTRL_MS_MSK;
	val |= (param->div << AG903_SPC_PLL0_CTRL_DIV_POS) & AG903_SPC_PLL0_CTRL_DIV_MSK;
	if(true == param->en) {
		val |= (1 << AG903_SPC_PLL0_CTRL_EN_POS);
	}
	AG903_SPC->PLL0_CTRL = val;
	
	return;
}

/**
 * @brief           SPCPLL0_CTRLのレジスタRead
 * @param           param [out] 設定パラメータ
 * @param           status [out] 動作状態
 * @return          void
 * @description     SPCPLL0_CTRLのレジスタRead
*/
void AG903_SPCPrmGetPll0Ctrl(AG903_SPCPrmPllnParam* param, uint8_t* status)
{
	uint32_t	val;
	
	ASSERT(NULL != param);
	ASSERT(NULL != status);

	val = AG903_SPC->PLL0_CTRL;
	param->ns  = (uint8_t)((val & AG903_SPC_PLL0_CTRL_NS_MSK)  >> AG903_SPC_PLL0_CTRL_NS_POS);
	param->ms  = (uint8_t)((val & AG903_SPC_PLL0_CTRL_MS_MSK)  >> AG903_SPC_PLL0_CTRL_MS_POS);
	param->div = (uint8_t)((val & AG903_SPC_PLL0_CTRL_DIV_MSK) >> AG903_SPC_PLL0_CTRL_DIV_POS);
	if(AG903_SPC_PLL0_CTRL_EN_MSK & val) {
		param->en = true;
	}
	else {
		param->en = false;
	}
	(*status) = (uint8_t)((val & AG903_SPC_PLL0_CTRL_STB_MSK)  >> AG903_SPC_PLL0_CTRL_STB_POS);

	return;
}

/**
 * @brief           SPCDDRPHY_PLLSETUPのレジスタWrite
 * @param           enable [in] PLLイネーブル (true=イネーブル)
 * @return          void
 * @description     SPCDDRPHY_PLLSETUPのレジスタWrite
 * @note            FCSシーケンスに従って設定して下さい。
*/
void AG903_SPCPrmSetDdrPhyPll(uint8_t enable)
{
	uint32_t	val;

	val = AG903_SPC->DDRPHY_PLLSETUP;	/* NS,MS,FRANGは変更不可 */
	if(true == enable) {
		val |= (1 << AG903_SPC_DDRPHY_PLLSETUP_PLLEN_POS);
	}
	else {
		val &= ~AG903_SPC_DDRPHY_PLLSETUP_PLLEN_MSK;
	}
	AG903_SPC->DDRPHY_PLLSETUP = val;
	
	return;
}

/**
 * @brief           SPCDDRPHY_PLLSETUPのレジスタRead
 * @param           enable [out] PLLイネーブル (true=イネーブル)
 * @return          void
 * @description     SPCDDRPHY_PLLSETUPのレジスタRead
*/
void AG903_SPCPrmGetDdrPhyPll(uint8_t* enable)
{
	uint32_t	val;
	
	ASSERT(NULL != enable);
	
	val = AG903_SPC->DDRPHY_PLLSETUP;
	if(AG903_SPC_DDRPHY_PLLSETUP_PLLEN_MSK & val) {
		(*enable) = true;
	}
	else {
		(*enable) = false;
	}
	return;
}

/**
 * @brief           SPCDDRPHY_DLLSETUPのレジスタWrite
 * @param           frange [in] 動作レンジ
 * @param           enable [in] DLLイネーブル (true=イネーブル)
 * @return          void
 * @description     SPCDDRPHY_DLLSETUPのレジスタWrite
 * @note            FCSシーケンスに従って設定して下さい。
*/
void AG903_SPCPrmSetDdrPhyDll(uint8_t frange, uint8_t enable)
{
	uint32_t	val = 0;
	
	val |= (frange << AG903_SPC_DDRPHY_DLLSETUP_FRANGE_POS) & AG903_SPC_DDRPHY_DLLSETUP_FRANGE_MSK;
	if(true == enable) {
		val |= (1 << AG903_SPC_DDRPHY_DLLSETUP_DLLEN_POS);
	}
	AG903_SPC->DDRPHY_DLLSETUP = val;
	
	return;
}

/**
 * @brief           SPCDDRPHY_DLLSETUPのレジスタRead
 * @param           frange [out] 動作レンジ
 * @param           enable [out] DLLイネーブル (true=イネーブル)
 * @return          void
 * @description     SPCDDRPHY_DLLSETUPのレジスタRead
*/
void AG903_SPCPrmGetDdrPhyDll(uint8_t* frange, uint8_t* enable)
{
	uint32_t	val;
	
	ASSERT(NULL != frange);
	ASSERT(NULL != enable);

	val = AG903_SPC->DDRPHY_DLLSETUP;
	(*frange) = (uint8_t)((val & AG903_SPC_DDRPHY_DLLSETUP_FRANGE_MSK) >> AG903_SPC_DDRPHY_DLLSETUP_FRANGE_POS);
	if(AG903_SPC_DDRPHY_DLLSETUP_DLLEN_MSK & val) {
		(*enable) = true;
	}
	else {
		(*enable) = false;
	}
	return;
}

/**
 * @brief           SPCAHB_CLK_CTRLのレジスタWrite
 * @param           clk_en [in] クロック供給制御 (ビット指定)
 * @return          void
 * @description     SPCAHB_CLK_CTRLのレジスタWrite
 * @note            設定値がそのままレジスタにWriteされます。
*/
void AG903_SPCPrmSetAhbClkCtrl(uint32_t clk_en)
{
	AG903_SPC->AHB_CLK_CTRL = clk_en;
	return;
}

/**
 * @brief           SPCAHB_CLK_CTRLのレジスタRead
 * @param           clk_en [out] クロック供給状態 (ビット単位)
 * @return          void
 * @description     SPCAHB_CLK_CTRLのレジスタRead
 * @note            クロック供給状態はレジスタRead値そのものです。
*/
void AG903_SPCPrmGetAhbClkCtrl(uint32_t* clk_en)
{
	ASSERT(NULL != clk_en);
	(*clk_en) = AG903_SPC->AHB_CLK_CTRL;
	return;
}

/**
 * @brief           SPCAPB_CLK_CTRLのレジスタWrite
 * @param           clk_en [in] クロック供給制御 (ビット指定)
 * @return          void
 * @description     SPCAPB_CLK_CTRLのレジスタWrite
 * @note            設定値がそのままレジスタにWriteされます。
*/
void AG903_SPCPrmSetApbClkCtrl(uint32_t clk_en)
{
	AG903_SPC->APB_CLK_CTRL = clk_en;
	return;
}

/**
 * @brief           SPCAPB_CLK_CTRLのレジスタRead
 * @param           clk_en [out] クロック供給状態 (ビット単位)
 * @return          void
 * @description     SPCAPB_CLK_CTRLのレジスタRead
 * @note            クロック供給状態はレジスタRead値そのものです。
*/
void AG903_SPCPrmGetApbClkCtrl(uint32_t* clk_en)
{
	ASSERT(NULL != clk_en);
	(*clk_en) = AG903_SPC->APB_CLK_CTRL;
	return;
}

/**
 * @brief           SPCAXI_CLK_CTRL1のレジスタWrite
 * @param           clk_en [in] クロック供給制御 (ビット指定)
 * @return          void
 * @description     SPCAXI_CLK_CTRL1のレジスタWrite
 * @note            設定値がそのままレジスタにWriteされます。
*/
void AG903_SPCPrmSetAxiClkCtrl1(uint32_t clk_en)
{
	AG903_SPC->AXI_CLK_CTRL1 = clk_en;
	return;
}

/**
 * @brief           SPCAXI_CLK_CTRL1のレジスタRead
 * @param           clk_en [out] クロック供給状態 (ビット単位)
 * @return          void
 * @description     SPCAXI_CLK_CTRL1のレジスタRead
 * @note            クロック供給状態はレジスタRead値そのものです。
*/
void AG903_SPCPrmGetAxiClkCtrl1(uint32_t* clk_en)
{
	ASSERT(NULL != clk_en);
	(*clk_en) = AG903_SPC->AXI_CLK_CTRL1;
	return;
}

/**
 * @brief           SPCAXI_CLK_CTRL2のレジスタWrite
 * @param           clk_en [in] クロック供給制御 (ビット指定)
 * @return          void
 * @description     SPCAXI_CLK_CTRL2のレジスタWrite
 * @note            設定値がそのままレジスタにWriteされます。
*/
void AG903_SPCPrmSetAxiClkCtrl2(uint32_t clk_en)
{
	AG903_SPC->AXI_CLK_CTRL2 = clk_en;
	return;
}

/**
 * @brief           SPCAXI_CLK_CTRL2のレジスタRead
 * @param           clk_en [out] クロック供給状態 (ビット単位)
 * @return          void
 * @description     SPCAXI_CLK_CTRL2のレジスタRead
 * @note            クロック供給状態はレジスタRead値そのものです。
*/
void AG903_SPCPrmGetAxiClkCtrl2(uint32_t* clk_en)
{
	ASSERT(NULL != clk_en);
	(*clk_en) = AG903_SPC->AXI_CLK_CTRL2;
	return;
}

/**
 * @brief           SPCPLL1_CTRLのレジスタWrite
 * @param           param  [in] 設定パラメータ
 * @return          void
 * @description     SPCPLL1_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetPll1Ctrl(AG903_SPCPrmPllnParam* param)
{
	uint32_t	val = 0;
	
	val |= (param->src    << AG903_SPC_PLL1_CTRL_SRC_POS) & AG903_SPC_PLL1_CTRL_SRC_MSK;
	val |= (param->ns     << AG903_SPC_PLL1_CTRL_NS_POS)  & AG903_SPC_PLL1_CTRL_NS_MSK;
	val |= (param->ms     << AG903_SPC_PLL1_CTRL_MS_POS)  & AG903_SPC_PLL1_CTRL_MS_MSK;
	val |= (param->div    << AG903_SPC_PLL1_CTRL_DIV_POS) & AG903_SPC_PLL1_CTRL_DIV_MSK;
	val |= (param->frange << AG903_SPC_PLL1_CTRL_FR_POS)  & AG903_SPC_PLL1_CTRL_FR_MSK;
	if(true == param->en) {
		val |= (1 << AG903_SPC_PLL1_CTRL_EN_POS);
	}
	AG903_SPC->PLL1_CTRL = val;
	
	return;
}

/**
 * @brief           SPCPLL1_CTRLのレジスタRead
 * @param           param  [out] 設定パラメータ
 * @return          void
 * @description     SPCPLL1_CTRLのレジスタRead
*/
void AG903_SPCPrmGetPll1Ctrl(AG903_SPCPrmPllnParam* param)
{
	uint32_t	val;
	
	ASSERT(NULL != param);

	val = AG903_SPC->PLL1_CTRL;
	param->src    = (uint8_t)((val & AG903_SPC_PLL1_CTRL_SRC_MSK) >> AG903_SPC_PLL1_CTRL_SRC_POS);
	param->ns     = (uint8_t)((val & AG903_SPC_PLL1_CTRL_NS_MSK)  >> AG903_SPC_PLL1_CTRL_NS_POS);
	param->ms     = (uint8_t)((val & AG903_SPC_PLL1_CTRL_MS_MSK)  >> AG903_SPC_PLL1_CTRL_MS_POS);
	param->div    = (uint8_t)((val & AG903_SPC_PLL1_CTRL_DIV_MSK) >> AG903_SPC_PLL1_CTRL_DIV_POS);
	param->frange = (uint8_t)((val & AG903_SPC_PLL1_CTRL_FR_MSK)  >> AG903_SPC_PLL1_CTRL_FR_POS);
	if(AG903_SPC_PLL1_CTRL_EN_MSK & val) {
		param->en = true;
	}
	else {
		param->en = false;
	}

	return;
}

/**
 * @brief           SPCPLL2_CTRLのレジスタWrite
 * @param           param  [in] 設定パラメータ
 * @return          void
 * @description     SPCPLL2_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetPll2Ctrl(AG903_SPCPrmPllnParam* param)
{
	uint32_t	val = 0;
	
	val |= (param->src    << AG903_SPC_PLL2_CTRL_SRC_POS) & AG903_SPC_PLL2_CTRL_SRC_MSK;
	val |= (param->ns     << AG903_SPC_PLL2_CTRL_NS_POS)  & AG903_SPC_PLL2_CTRL_NS_MSK;
	val |= (param->ms     << AG903_SPC_PLL2_CTRL_MS_POS)  & AG903_SPC_PLL2_CTRL_MS_MSK;
	val |= (param->div    << AG903_SPC_PLL2_CTRL_DIV_POS) & AG903_SPC_PLL2_CTRL_DIV_MSK;
	val |= (param->frange << AG903_SPC_PLL2_CTRL_FR_POS)  & AG903_SPC_PLL2_CTRL_FR_MSK;
	if(true == param->en) {
		val |= (1 << AG903_SPC_PLL2_CTRL_EN_POS);
	}
	AG903_SPC->PLL2_CTRL = val;
	
	return;
}

/**
 * @brief           SPCPLL2_CTRLのレジスタRead
 * @param           param  [out] 設定パラメータ
 * @return          void
 * @description     SPCPLL2_CTRLのレジスタRead
*/
void AG903_SPCPrmGetPll2Ctrl(AG903_SPCPrmPllnParam* param)
{
	uint32_t	val;
	
	ASSERT(NULL != param);

	val = AG903_SPC->PLL2_CTRL;
	param->src    = (uint8_t)((val & AG903_SPC_PLL2_CTRL_SRC_MSK) >> AG903_SPC_PLL2_CTRL_SRC_POS);
	param->ns     = (uint8_t)((val & AG903_SPC_PLL2_CTRL_NS_MSK)  >> AG903_SPC_PLL2_CTRL_NS_POS);
	param->ms     = (uint8_t)((val & AG903_SPC_PLL2_CTRL_MS_MSK)  >> AG903_SPC_PLL2_CTRL_MS_POS);
	param->div    = (uint8_t)((val & AG903_SPC_PLL2_CTRL_DIV_MSK) >> AG903_SPC_PLL2_CTRL_DIV_POS);
	param->frange = (uint8_t)((val & AG903_SPC_PLL2_CTRL_FR_MSK)  >> AG903_SPC_PLL2_CTRL_FR_POS);
	if(AG903_SPC_PLL2_CTRL_EN_MSK & val) {
		param->en = true;
	}
	else {
		param->en = false;
	}

	return;
}

/**
 * @brief           SPCPLL3_CTRLのレジスタWrite
 * @param           param  [in] 設定パラメータ
 * @return          void
 * @description     SPCPLL3_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetPll3Ctrl(AG903_SPCPrmPllnParam* param)
{
	uint32_t	val = 0;
	
	val |= (param->src    << AG903_SPC_PLL3_CTRL_SRC_POS) & AG903_SPC_PLL3_CTRL_SRC_MSK;
	val |= (param->ns     << AG903_SPC_PLL3_CTRL_NS_POS)  & AG903_SPC_PLL3_CTRL_NS_MSK;
	val |= (param->ms     << AG903_SPC_PLL3_CTRL_MS_POS)  & AG903_SPC_PLL3_CTRL_MS_MSK;
	val |= (param->div    << AG903_SPC_PLL3_CTRL_DIV_POS) & AG903_SPC_PLL3_CTRL_DIV_MSK;
	val |= (param->frange << AG903_SPC_PLL3_CTRL_FR_POS)  & AG903_SPC_PLL3_CTRL_FR_MSK;
	if(true == param->en) {
		val |= (1 << AG903_SPC_PLL3_CTRL_EN_POS);
	}
	AG903_SPC->PLL3_CTRL = val;
	
	return;
}

/**
 * @brief           SPCPLL3_CTRLのレジスタRead
 * @param           param  [out] 設定パラメータ
 * @return          void
 * @description     SPCPLL3_CTRLのレジスタRead
*/
void AG903_SPCPrmGetPll3Ctrl(AG903_SPCPrmPllnParam* param)
{
	uint32_t	val;
	
	ASSERT(NULL != param);

	val = AG903_SPC->PLL3_CTRL;
	param->src    = (uint8_t)((val & AG903_SPC_PLL3_CTRL_SRC_MSK) >> AG903_SPC_PLL3_CTRL_SRC_POS);
	param->ns     = (uint8_t)((val & AG903_SPC_PLL3_CTRL_NS_MSK)  >> AG903_SPC_PLL3_CTRL_NS_POS);
	param->ms     = (uint8_t)((val & AG903_SPC_PLL3_CTRL_MS_MSK)  >> AG903_SPC_PLL3_CTRL_MS_POS);
	param->div    = (uint8_t)((val & AG903_SPC_PLL3_CTRL_DIV_MSK) >> AG903_SPC_PLL3_CTRL_DIV_POS);
	param->frange = (uint8_t)((val & AG903_SPC_PLL3_CTRL_FR_MSK)  >> AG903_SPC_PLL3_CTRL_FR_POS);
	if(AG903_SPC_PLL3_CTRL_EN_MSK & val) {
		param->en = true;
	}
	else {
		param->en = false;
	}

	return;
}

/**
 * @brief           SPCPLLA_CTRLのレジスタWrite
 * @param           param [in] 設定パラメータ
 * @return          void
 * @description     SPCPLLA_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetPllACtrl(AG903_SPCPrmPllaParam* param)
{
	uint32_t	val = 0;
	
	val |= (param->src << AG903_SPC_PLLA_CTRL_SRC_POS) & AG903_SPC_PLLA_CTRL_SRC_MSK;
	val |= (param->ns  << AG903_SPC_PLLA_CTRL_NS_POS)  & AG903_SPC_PLLA_CTRL_NS_MSK;
	val |= (param->ms  << AG903_SPC_PLLA_CTRL_MS_POS)  & AG903_SPC_PLLA_CTRL_MS_MSK;
	val |= (param->fr  << AG903_SPC_PLLA_CTRL_FR_POS)  & AG903_SPC_PLLA_CTRL_FR_MSK;
	val |= (param->div << AG903_SPC_PLLA_CTRL_DIV_POS) & AG903_SPC_PLLA_CTRL_DIV_MSK;
	val |= (param->cc  << AG903_SPC_PLLA_CTRL_CC_POS)  & AG903_SPC_PLLA_CTRL_CC_MSK;
	if(true == param->en) {
		val |= (1 << AG903_SPC_PLLA_CTRL_EN_POS);
	}
	AG903_SPC->PLLA_CTRL = val;
	
	return;
}

/**
 * @brief           SPCPLLA_CTRLのレジスタRead
 * @param           param  [out] 設定パラメータ
 * @return          void
 * @description     SPCPLLA_CTRLのレジスタRead
*/
void AG903_SPCPrmGetPllACtrl(AG903_SPCPrmPllaParam* param)
{
	uint32_t	val;
	
	ASSERT(NULL != param);

	val = AG903_SPC->PLLA_CTRL;
	param->src = (uint8_t)((val & AG903_SPC_PLLA_CTRL_SRC_MSK) >> AG903_SPC_PLLA_CTRL_SRC_POS);
	param->ns  = (uint8_t)((val & AG903_SPC_PLLA_CTRL_NS_MSK)  >> AG903_SPC_PLLA_CTRL_NS_POS);
	param->ms  = (uint8_t)((val & AG903_SPC_PLLA_CTRL_MS_MSK)  >> AG903_SPC_PLLA_CTRL_MS_POS);
	param->div = (uint8_t)((val & AG903_SPC_PLLA_CTRL_DIV_MSK) >> AG903_SPC_PLLA_CTRL_DIV_POS);
	param->fr  = (uint8_t)((val & AG903_SPC_PLLA_CTRL_FR_MSK)  >> AG903_SPC_PLLA_CTRL_FR_POS);
	param->cc  = (uint8_t)((val & AG903_SPC_PLLA_CTRL_CC_MSK)  >> AG903_SPC_PLLA_CTRL_CC_POS);
	if(AG903_SPC_PLLA_CTRL_EN_MSK & val) {
		param->en = true;
	}
	else {
		param->en = false;
	}

	return;
}

/**
 * @brief           SPCSOFTRESET_MASKnのレジスタWrite
 * @param           reg_no [in] レジスタ番号 (1〜5)
 * @param           msk    [in] マスク設定 (ビット指定)
 * @return          void
 * @description     SPCSOFTRESET_MASKnのレジスタWrite
*/
void AG903_SPCPrmSetSwResetMask(uint8_t reg_no, uint32_t msk)
{
	ASSERT(0 != reg_no);
	ASSERT(AG903_SPC_SWRSTMSK_REG_NUM >= reg_no);
	
	switch(reg_no) {
		case 1:
			AG903_SPC->SOFTRESET_MASK1 = msk;
			break;
		case 2:
			AG903_SPC->SOFTRESET_MASK2 = msk;
			break;
		case 3:
			AG903_SPC->SOFTRESET_MASK3 = msk;
			break;
		case 4:
			AG903_SPC->SOFTRESET_MASK4 = msk;
			break;
		case 5:
			AG903_SPC->SOFTRESET_MASK5 = msk;
			break;
		default:
			/* ASSERTでチェックしているのでここには来ない。 */
			break;
	}
	
	return;
}

/**
 * @brief           SPCSOFTRESET_MASKnのレジスタRead
 * @param           reg_no [in] レジスタ番号 (1〜5)
 * @param           msk    [out] マスク設定 (ビット単位)
 * @return          void
 * @description     SPCSOFTRESET_MASKnのレジスタRead
*/
void AG903_SPCPrmGetSwResetMask(uint8_t reg_no, uint32_t* msk)
{
	ASSERT(NULL != msk);
	ASSERT(0 != reg_no);
	ASSERT(AG903_SPC_SWRSTMSK_REG_NUM >= reg_no);
	
	switch(reg_no) {
		case 1:
			(*msk) = AG903_SPC->SOFTRESET_MASK1;
			break;
		case 2:
			(*msk) = AG903_SPC->SOFTRESET_MASK2;
			break;
		case 3:
			(*msk) = AG903_SPC->SOFTRESET_MASK3;
			break;
		case 4:
			(*msk) = AG903_SPC->SOFTRESET_MASK4;
			break;
		case 5:
			(*msk) = AG903_SPC->SOFTRESET_MASK5;
			break;
		default:
			/* ASSERTでチェックしているのでここには来ない。 */
			break;
	}
	
	return;
}

/**
 * @brief           SPCAPB_SDMC_CLK_CTRLのレジスタWrite
 * @param           sdmclk [in] SDRAMコントローラ クロック供給 (ビット指定)
 * @param           pclk   [in] APBペリフェラル クロック供給 (ビット指定)
 * @return          void
 * @description     SPCAPB_SDMC_CLK_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetApbSdmcClkCtrl(uint8_t sdmclk, uint32_t pclk)
{
	uint32_t	val = 0;
	
	val |= (sdmclk << AG903_SPC_APB_SDMC_CLK_CTRL_SDMCCLK_EN_POS) & AG903_SPC_APB_SDMC_CLK_CTRL_SDMCCLK_EN_MSK;
	val |= (pclk   << AG903_SPC_APB_SDMC_CLK_CTRL_PCLK_EN_POS)    & AG903_SPC_APB_SDMC_CLK_CTRL_PCLK_EN_MSK;
	AG903_SPC->APB_SDMC_CLK_CTRL = val;
	
	return;
}

/**
 * @brief           SPCAPB_SDMC_CLK_CTRLのレジスタRead
 * @param           sdmclk [out] SDRAMコントローラ クロック供給 (ビット単位)
 * @param           pclk   [out] APBペリフェラル クロック供給 (ビット単位)
 * @return          void
 * @description     SPCAPB_SDMC_CLK_CTRLのレジスタRead
*/
void AG903_SPCPrmGetApbSdmcClkCtrl(uint8_t* sdmclk, uint32_t* pclk)
{
	uint32_t	val;
	
	ASSERT(NULL != sdmclk);
	ASSERT(NULL != pclk);
	
	val = AG903_SPC->APB_SDMC_CLK_CTRL;
	(*sdmclk) = (uint8_t)((val & AG903_SPC_APB_SDMC_CLK_CTRL_SDMCCLK_EN_MSK) >> AG903_SPC_APB_SDMC_CLK_CTRL_SDMCCLK_EN_POS);
	(*pclk)   = (val & AG903_SPC_APB_SDMC_CLK_CTRL_PCLK_EN_MSK) >> AG903_SPC_APB_SDMC_CLK_CTRL_PCLK_EN_POS;
	
	return;
}

/**
 * @brief           SPCMISC_CLK_CTRLのレジスタWrite
 * @param           sclk   [in] 各インターフェース クロック供給 (ビット指定)
 * @return          void
 * @description     SPCMISC_CLK_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetMiscClkCtrl(uint32_t sclk)
{
	AG903_SPC->MISC_CLK_CTRL = sclk;
	return;
}

/**
 * @brief           SPCMISC_CLK_CTRLのレジスタRead
 * @param           sclk   [out] 各インターフェース クロック供給 (ビット単位)
 * @return          void
 * @description     SPCMISC_CLK_CTRLのレジスタRead
*/
void AG903_SPCPrmGetMiscClkCtrl(uint32_t* sclk)
{
	ASSERT(NULL != sclk);
	(*sclk) = AG903_SPC->MISC_CLK_CTRL;
	return;
}

/**
 * @brief           SPCPIN_STATUSのレジスタRead
 * @param           test [out] TEST[0〜3]端子状態
 * @param           mode [out] MODE[0〜3]端子状態
 * @return          void
 * @description     SPCPIN_STATUSのレジスタRead
*/
void AG903_SPCPrmGetPinStatus(uint8_t* test, uint8_t* mode)
{
	uint32_t	val;
	
	ASSERT(NULL != test);
	ASSERT(NULL != mode);

	val = AG903_SPC->PIN_STATUS;
	(*test) = (uint8_t)((val & AG903_SPC_PIN_STATUS_TEST_MSK) >> AG903_SPC_PIN_STATUS_TEST_POS);
	(*mode) = (uint8_t)((val & AG903_SPC_PIN_STATUS_MODE_MSK) >> AG903_SPC_PIN_STATUS_MODE_POS);
	return;
}

/**
 * @brief           SPCSDMC_MISC_CTRLのレジスタWrite
 * @param           param [in] 設定パラメータ
 * @return          void
 * @description     SPCSDMC_MISC_CTRLのレジスタWrite
 * @note            SREF_ACKビットはRead Only
*/
void AG903_SPCPrmSetSdmcMiscCtrl(AG903_SPCPrmSdmcMiscParam* param)
{
	uint32_t	val = 0;
	
	ASSERT(NULL != param);
	
	val |= (param->hclk_sel << AG903_SPC_SDMC_MISC_CTRL_HCLK_SEL_POS) & AG903_SPC_SDMC_MISC_CTRL_HCLK_SEL_MSK;
	val |= (param->rclk_sel << AG903_SPC_SDMC_MISC_CTRL_RCLK_SEL_POS) & AG903_SPC_SDMC_MISC_CTRL_RCLK_SEL_MSK;
	val |= (param->wclk_sel << AG903_SPC_SDMC_MISC_CTRL_WCLK_SEL_POS) & AG903_SPC_SDMC_MISC_CTRL_WCLK_SEL_MSK;
	val |= (param->sref_req << AG903_SPC_SDMC_MISC_CTRL_SREF_REQ_POS) & AG903_SPC_SDMC_MISC_CTRL_SREF_REQ_MSK;
	val |= (param->sref_ack << AG903_SPC_SDMC_MISC_CTRL_SREF_ACK_POS) & AG903_SPC_SDMC_MISC_CTRL_SREF_ACK_MSK;
	val |= (param->clk_sel  << AG903_SPC_SDMC_MISC_CTRL_CLK_SEL_POS)  & AG903_SPC_SDMC_MISC_CTRL_CLK_SEL_MSK;
	AG903_SPC->SDMC_MISC_CTRL = val;
	
	return;
}

/**
 * @brief           SPCSDMC_MISC_CTRLのレジスタRead
 * @param           param [out] 設定パラメータ
 * @return          void
 * @description     SPCSDMC_MISC_CTRLのレジスタRead
*/
void AG903_SPCPrmGetSdmcMiscCtrl(AG903_SPCPrmSdmcMiscParam* param)
{
	uint32_t	val;

	ASSERT(NULL != param);
	
	val = AG903_SPC->SDMC_MISC_CTRL;
	param->hclk_sel = (uint8_t)((val & AG903_SPC_SDMC_MISC_CTRL_HCLK_SEL_MSK) >> AG903_SPC_SDMC_MISC_CTRL_HCLK_SEL_POS);
	param->rclk_sel = (uint8_t)((val & AG903_SPC_SDMC_MISC_CTRL_RCLK_SEL_MSK) >> AG903_SPC_SDMC_MISC_CTRL_RCLK_SEL_POS);
	param->wclk_sel = (uint8_t)((val & AG903_SPC_SDMC_MISC_CTRL_WCLK_SEL_MSK) >> AG903_SPC_SDMC_MISC_CTRL_WCLK_SEL_POS);
	param->sref_ack = (uint8_t)((val & AG903_SPC_SDMC_MISC_CTRL_SREF_ACK_MSK) >> AG903_SPC_SDMC_MISC_CTRL_SREF_ACK_POS);
	param->sref_req = (uint8_t)((val & AG903_SPC_SDMC_MISC_CTRL_SREF_REQ_MSK) >> AG903_SPC_SDMC_MISC_CTRL_SREF_REQ_POS);
	param->clk_sel  = (uint8_t)((val & AG903_SPC_SDMC_MISC_CTRL_CLK_SEL_MSK)  >> AG903_SPC_SDMC_MISC_CTRL_CLK_SEL_POS);
	
	return;
}

/**
 * @brief           SPCDDR_MISC_CTRLレジスタのREFRESHビットSet
 * @param           refresh [in] セルフリフレッシュ制御 (true=有効)
 * @return          void
 * @description     SPCDDR_MISC_CTRLレジスタのREFRESHビットSet
*/
void AG903_SPCPrmSetDdrMiscCtrl(uint8_t refresh)
{
	uint32_t	val;
	
	val = AG903_SPC->DDR_MISC_CTRL;
	if(true == refresh) {
		val |= (1 << AG903_SPC_DDR_MISC_CTRL_REFRESH_POS);
	}
	AG903_SPC->DDR_MISC_CTRL = val;
	
	return;
}

/**
 * @brief           SPCDDR_MISC_CTRLのレジスタRead
 * @param           init    [out] 初期化シーケンス状態 (true=完了)
 * @param           refresh [out] セルフリフレッシュ制御 (true=有効)
 * @return          void
 * @description     SPCDDR_MISC_CTRLのレジスタRead
*/
void AG903_SPCPrmGetDdrMiscCtrl(uint8_t* init, uint8_t* refresh)
{
	uint32_t	val;
	
	ASSERT(NULL != init);
	ASSERT(NULL != refresh);

	val = AG903_SPC->DDR_MISC_CTRL;
	if(AG903_SPC_DDR_MISC_CTRL_INIT_OK_MSK & val) {
		(*init) = true;
	}
	else {
		(*init) = false;
	}
	if(AG903_SPC_DDR_MISC_CTRL_REFRESH_MSK & val) {
		(*refresh) = true;
	}
	else {
		(*refresh) = false;
	}
	
	return;
}

/**
 * @brief           SPCSPIROM_MISC_CTRLのレジスタWrite
 * @param           addr_cyc [in] アドレスサイクル設定
 * @return          void
 * @description     SPCSPIROM_MISC_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetSpiromMiscCtrl(uint8_t addr_cyc)
{
	AG903_SPC->SPIROM_MISC_CTRL = (addr_cyc << AG903_SPC_SPIROM_MISC_CTRL_ADDR_CYC_POS) & AG903_SPC_SPIROM_MISC_CTRL_ADDR_CYC_MSK;
	return;
}

/**
 * @brief           SPCSPIROM_MISC_CTRLのレジスタRead
 * @param           addr_cyc [out] アドレスサイクル設定
 * @return          void
 * @description     SPCSPIROM_MISC_CTRLのレジスタRead
*/
void AG903_SPCPrmGetSpiromMiscCtrl(uint8_t* addr_cyc)
{
	uint32_t	val;

	ASSERT(NULL != addr_cyc);

	val = AG903_SPC->SPIROM_MISC_CTRL;
	(*addr_cyc) = (uint8_t)((val & AG903_SPC_SPIROM_MISC_CTRL_ADDR_CYC_MSK) >> AG903_SPC_SPIROM_MISC_CTRL_ADDR_CYC_POS);

	return;
}

/**
 * @brief           SPCCLK_SEL1のレジスタWrite
 * @param           clk_src [in] クロックソース設定
 * @return          void
 * @description     SPCCLK_SEL1のレジスタWrite
*/
void AG903_SPCPrmSetClkSrc(AG903_SPCPrmClkSel* clk_src)
{
	uint32_t	val = 0;
	
	ASSERT(NULL != clk_src);
	
	val |= (clk_src->cp1  << AG903_SPC_CLK_SEL1_CP1CLK_SEL_POS)  & AG903_SPC_CLK_SEL1_CP1CLK_SEL_MSK;
	val |= (clk_src->cp0  << AG903_SPC_CLK_SEL1_CP0CLK_SEL_POS)  & AG903_SPC_CLK_SEL1_CP0CLK_SEL_MSK;
	val |= (clk_src->lvds << AG903_SPC_CLK_SEL1_LVDSCLK_SEL_POS) & AG903_SPC_CLK_SEL1_LVDSCLK_SEL_MSK;
	val |= (clk_src->dt1  << AG903_SPC_CLK_SEL1_DT1CLK_SEL_POS)  & AG903_SPC_CLK_SEL1_DT1CLK_SEL_MSK;
	val |= (clk_src->dt0  << AG903_SPC_CLK_SEL1_DT0CLK_SEL_POS)  & AG903_SPC_CLK_SEL1_DT0CLK_SEL_MSK;
	val |= (clk_src->hda  << AG903_SPC_CLK_SEL1_HDACLK_SEL_POS)  & AG903_SPC_CLK_SEL1_HDACLK_SEL_MSK;
	AG903_SPC->CLK_SEL1 = val;
	
	return;
}

/**
 * @brief           SPCCLK_SEL1のレジスタRead
 * @param           clk_src [out] クロックソース設定
 * @return          void
 * @description     SPCCLK_SEL1のレジスタRead
*/
void AG903_SPCPrmGetClkSrc(AG903_SPCPrmClkSel* clk_src)
{
	uint32_t	val;
	
	ASSERT(NULL != clk_src);
	
	val = AG903_SPC->CLK_SEL1;
	clk_src->cp1  = (uint8_t)((val & AG903_SPC_CLK_SEL1_CP1CLK_SEL_MSK)  >> AG903_SPC_CLK_SEL1_CP1CLK_SEL_POS);
	clk_src->cp0  = (uint8_t)((val & AG903_SPC_CLK_SEL1_CP0CLK_SEL_MSK)  >> AG903_SPC_CLK_SEL1_CP0CLK_SEL_POS);
	clk_src->lvds = (uint8_t)((val & AG903_SPC_CLK_SEL1_LVDSCLK_SEL_MSK) >> AG903_SPC_CLK_SEL1_LVDSCLK_SEL_POS);
	clk_src->dt1  = (uint8_t)((val & AG903_SPC_CLK_SEL1_DT1CLK_SEL_MSK)  >> AG903_SPC_CLK_SEL1_DT1CLK_SEL_POS);
	clk_src->dt0  = (uint8_t)((val & AG903_SPC_CLK_SEL1_DT0CLK_SEL_MSK)  >> AG903_SPC_CLK_SEL1_DT0CLK_SEL_POS);
	clk_src->hda  = (uint8_t)((val & AG903_SPC_CLK_SEL1_HDACLK_SEL_MSK)  >> AG903_SPC_CLK_SEL1_HDACLK_SEL_POS);
	
	return;
}

/**
 * @brief           SPCCLK_SSP_SELのレジスタWrite
 * @param           clk_src [in] クロックソース設定
 * @return          void
 * @description     SPCCLK_SSP_SELのレジスタWrite
*/
void AG903_SPCPrmSetSspClkSrc(AG903_SPCPrmSspClkSel* clk_src)
{
	uint32_t	val = 0;
	
	ASSERT(NULL != clk_src);
	
	val |= (clk_src->pll3 << AG903_SPC_CLK_SSP_SEL_PLL3CLK_SEL_POS) & AG903_SPC_CLK_SSP_SEL_PLL3CLK_SEL_MSK;
	val |= (clk_src->ssp3 << AG903_SPC_CLK_SSP_SEL_SSP3CLK_SEL_POS) & AG903_SPC_CLK_SSP_SEL_SSP3CLK_SEL_MSK;
	val |= (clk_src->ssp2 << AG903_SPC_CLK_SSP_SEL_SSP2CLK_SEL_POS) & AG903_SPC_CLK_SSP_SEL_SSP2CLK_SEL_MSK;
	val |= (clk_src->ssp1 << AG903_SPC_CLK_SSP_SEL_SSP1CLK_SEL_POS) & AG903_SPC_CLK_SSP_SEL_SSP1CLK_SEL_MSK;
	val |= (clk_src->ssp0 << AG903_SPC_CLK_SSP_SEL_SSP0CLK_SEL_POS) & AG903_SPC_CLK_SSP_SEL_SSP0CLK_SEL_MSK;
	AG903_SPC->CLK_SSP_SEL = val;

	return;
}

/**
 * @brief           SPCCLK_SSP_SELのレジスタRead
 * @param           clk_src [out] クロックソース設定
 * @return          void
 * @description     SPCCLK_SSP_SELのレジスタRead
*/
void AG903_SPCPrmGetSspClkSrc(AG903_SPCPrmSspClkSel* clk_src)
{
	uint32_t	val;
	
	ASSERT(NULL != clk_src);
	
	val = AG903_SPC->CLK_SSP_SEL;
	clk_src->pll3 = (uint8_t)((val & AG903_SPC_CLK_SSP_SEL_PLL3CLK_SEL_MSK) >> AG903_SPC_CLK_SSP_SEL_PLL3CLK_SEL_POS);
	clk_src->ssp3 = (uint8_t)((val & AG903_SPC_CLK_SSP_SEL_SSP3CLK_SEL_MSK) >> AG903_SPC_CLK_SSP_SEL_SSP3CLK_SEL_POS);
	clk_src->ssp2 = (uint8_t)((val & AG903_SPC_CLK_SSP_SEL_SSP2CLK_SEL_MSK) >> AG903_SPC_CLK_SSP_SEL_SSP2CLK_SEL_POS);
	clk_src->ssp1 = (uint8_t)((val & AG903_SPC_CLK_SSP_SEL_SSP1CLK_SEL_MSK) >> AG903_SPC_CLK_SSP_SEL_SSP1CLK_SEL_POS);
	clk_src->ssp0 = (uint8_t)((val & AG903_SPC_CLK_SSP_SEL_SSP0CLK_SEL_MSK) >> AG903_SPC_CLK_SSP_SEL_SSP0CLK_SEL_POS);
	return;
}

/**
 * @brief           SPCCLK_SSP_DIVのレジスタWrite
 * @param           clk_div [in] クロックソース分周設定
 * @return          void
 * @description     SPCCLK_SSP_DIVのレジスタWrite
*/
void AG903_SPCPrmSetSspClkDiv(AG903_SPCPrmSspClkDiv* clk_div)
{
	uint32_t	val = 0;
	
	ASSERT(NULL != clk_div);
	
	val |= (clk_div->ssp3 << AG903_SPC_CLK_SSP_DIV_SSP3CLK_DIV_POS) & AG903_SPC_CLK_SSP_DIV_SSP3CLK_DIV_MSK;
	val |= (clk_div->ssp2 << AG903_SPC_CLK_SSP_DIV_SSP2CLK_DIV_POS) & AG903_SPC_CLK_SSP_DIV_SSP2CLK_DIV_MSK;
	val |= (clk_div->ssp1 << AG903_SPC_CLK_SSP_DIV_SSP1CLK_DIV_POS) & AG903_SPC_CLK_SSP_DIV_SSP1CLK_DIV_MSK;
	val |= (clk_div->ssp0 << AG903_SPC_CLK_SSP_DIV_SSP0CLK_DIV_POS) & AG903_SPC_CLK_SSP_DIV_SSP0CLK_DIV_MSK;
	AG903_SPC->CLK_SSP_DIV = val;
	
	return;
}

/**
 * @brief           SPCCLK_SSP_DIVのレジスタRead
 * @param           clk_div [out] クロックソース分周設定
 * @return          void
 * @description     SPCCLK_SSP_DIVのレジスタRead
*/
void AG903_SPCPrmGetSspClkDiv(AG903_SPCPrmSspClkDiv* clk_div)
{
	uint32_t	val;
	
	ASSERT(NULL != clk_div);
	
	val = AG903_SPC->CLK_SSP_DIV;
	clk_div->ssp3 = (uint8_t)((val & AG903_SPC_CLK_SSP_DIV_SSP3CLK_DIV_MSK) >> AG903_SPC_CLK_SSP_DIV_SSP3CLK_DIV_POS);
	clk_div->ssp2 = (uint8_t)((val & AG903_SPC_CLK_SSP_DIV_SSP2CLK_DIV_MSK) >> AG903_SPC_CLK_SSP_DIV_SSP2CLK_DIV_POS);
	clk_div->ssp1 = (uint8_t)((val & AG903_SPC_CLK_SSP_DIV_SSP1CLK_DIV_MSK) >> AG903_SPC_CLK_SSP_DIV_SSP1CLK_DIV_POS);
	clk_div->ssp0 = (uint8_t)((val & AG903_SPC_CLK_SSP_DIV_SSP0CLK_DIV_MSK) >> AG903_SPC_CLK_SSP_DIV_SSP0CLK_DIV_POS);
	
	return;
}

/**
 * @brief           SPCETH_PHY_SELのレジスタWrite
 * @param           phy [in] PHY設定
 * @return          void
 * @description     SPCETH_PHY_SELのレジスタWrite
*/
void AG903_SPCPrmSetEtherPhy(uint8_t phy)
{
	uint32_t	val = 0;
	
	if(AG903_SPC_ETHER_RMII == phy) {
		val |= (1 << AG903_SPC_ETH_PHY_SEL_RMII_POS);
	}
	AG903_SPC->ETH_PHY_SEL = val;
	
	return;
}

/**
 * @brief           SPCETH_PHY_SELのレジスタRead
 * @param           phy [out] PHY設定
 * @return          void
 * @description     SPCETH_PHY_SELのレジスタRead
*/
void AG903_SPCPrmGetEtherPhy(uint8_t* phy)
{
	uint32_t	val;
	
	ASSERT(NULL != phy);
	
	val = AG903_SPC->ETH_PHY_SEL;
	if(AG903_SPC_ETH_PHY_SEL_RMII_MSK & val) {
		(*phy) = AG903_SPC_ETHER_RMII;
	}
	else {
		(*phy) = AG903_SPC_ETHER_MII;
	}
	return;
}

/**
 * @brief           SPCCA5_MISC_CTRLnのレジスタWrite
 * @param           reg_no [in] レジスタ番号 (1〜11)
 * @param           val [in] 設定値
 * @return          void
 * @description     SPCCA5_MISC_CTRLnのレジスタWrite<p>
 *                  AG903_spcreg.h レジスタヘッダファイルの各SPCCA5_MISC_CTRLnレジスタの定義を<p>
 *                  使用し、整形した値をvalに設定してください.
*/
void AG903_SPCPrmSetCpuMiscCtrl(uint8_t reg_no, uint32_t val)
{
	ASSERT(0 != reg_no);
	ASSERT(AG903_SPC_CA5CTRL_REG_NUM >= reg_no);

	switch(reg_no) {
		case 1:
			AG903_SPC->CA5_MISC_CTRL1 = val;
			break;
		case 2:
			AG903_SPC->CA5_MISC_CTRL2 = val;
			break;
		case 3:
			AG903_SPC->CA5_MISC_CTRL3 = val;
			break;
		case 4:
			AG903_SPC->CA5_MISC_CTRL4 = val;
			break;
		case 5:
			AG903_SPC->CA5_MISC_CTRL5 = val;
			break;
		case 6:
			AG903_SPC->CA5_MISC_CTRL6 = val;
			break;
		case 7:
			AG903_SPC->CA5_MISC_CTRL7 = val;
			break;
		case 8:
			AG903_SPC->CA5_MISC_CTRL8 = val;
			break;
		case 9:
			AG903_SPC->CA5_MISC_CTRL9 = val;
			break;
		case 10:
			AG903_SPC->CA5_MISC_CTRL10 = val;
			break;
		case 11:
			AG903_SPC->CA5_MISC_CTRL11 = val;
			break;
		default:
			/* ASSERTでチェックしているのでここには来ない。 */
			break;
	}
	
	return;
}

/**
 * @brief           SPCCA5_MISC_CTRLnのレジスタRead
 * @param           reg_no [in] レジスタ番号 (1〜11)
 * @param           val [out] 設定値
 * @return          void
 * @description     SPCCA5_MISC_CTRLnのレジスタRead<p>
 *                  bit内容については、AG903_spcreg.h レジスタヘッダファイルの各SPCCA5_MISC_CTRLnレジスタ<p>
 *                  の定義を使用し値を取得してください.
*/
void AG903_SPCPrmGetCpuMiscCtrl(uint8_t reg_no, uint32_t* val)
{
	ASSERT(NULL != val);
	ASSERT(0 != reg_no);
	ASSERT(AG903_SPC_CA5CTRL_REG_NUM >= reg_no);

	switch(reg_no) {
		case 1:
			(*val) = AG903_SPC->CA5_MISC_CTRL1;
			break;
		case 2:
			(*val) = AG903_SPC->CA5_MISC_CTRL2;
			break;
		case 3:
			(*val) = AG903_SPC->CA5_MISC_CTRL3;
			break;
		case 4:
			(*val) = AG903_SPC->CA5_MISC_CTRL4;
			break;
		case 5:
			(*val) = AG903_SPC->CA5_MISC_CTRL5;
			break;
		case 6:
			(*val) = AG903_SPC->CA5_MISC_CTRL6;
			break;
		case 7:
			(*val) = AG903_SPC->CA5_MISC_CTRL7;
			break;
		case 8:
			(*val) = AG903_SPC->CA5_MISC_CTRL8;
			break;
		case 9:
			(*val) = AG903_SPC->CA5_MISC_CTRL9;
			break;
		case 10:
			(*val) = AG903_SPC->CA5_MISC_CTRL10;
			break;
		case 11:
			(*val) = AG903_SPC->CA5_MISC_CTRL11;
			break;
		default:
			/* ASSERTでチェックしているのでここには来ない。 */
			break;
	}
	
	return;
}

/**
 * @brief           SPCVIDEOADC_MISC_CTRLnのレジスタWrite
 * @param           param  [in] 設定パラメータ
 * @param           enable [in] 動作設定
 * @return          void
 * @description     SPCVIDEOADC_MISC_CTRLnのレジスタWrite
*/
void AG903_SPCPrmSetVideoAdcCtrl(AG903_SPCPrmVideoAdcParam* param, AG903_SPCPrmVideoAdcEnable* enable)
{
	uint32_t	val;

	ASSERT(NULL != param);
	ASSERT(NULL != enable);
	
	val  = AG903_SPC->VIDEOADC_MISC_CTRL5;
	val &= ~(AG903_SPC_VIDEOADC_MISC_CTRL5_INPUT_RANGE_MSK |
		     AG903_SPC_VIDEOADC_MISC_CTRL5_REF_BIAS_UP_MSK);
	val |= (param->input_range   << AG903_SPC_VIDEOADC_MISC_CTRL5_INPUT_RANGE_POS) & 
	                                AG903_SPC_VIDEOADC_MISC_CTRL5_INPUT_RANGE_MSK;
	val |= (param->ref_bias_up   << AG903_SPC_VIDEOADC_MISC_CTRL5_REF_BIAS_UP_POS) &
	                                AG903_SPC_VIDEOADC_MISC_CTRL5_REF_BIAS_UP_MSK;
	AG903_SPC->VIDEOADC_MISC_CTRL5 = val;
	
	val  = AG903_SPC->VIDEOADC_MISC_CTRL4;
	val &= ~(AG903_SPC_VIDEOADC_MISC_CTRL4_AAF_CTRL_MSK |
		     AG903_SPC_VIDEOADC_MISC_CTRL4_QUAN_BIAS_UP_MSK |
		     AG903_SPC_VIDEOADC_MISC_CTRL4_CH3_GAIN_MSK);
	val |= (param->aaf_ctrl      << AG903_SPC_VIDEOADC_MISC_CTRL4_AAF_CTRL_POS) &
	                                AG903_SPC_VIDEOADC_MISC_CTRL4_AAF_CTRL_MSK;
	val |= (param->qntzr_bias_up << AG903_SPC_VIDEOADC_MISC_CTRL4_QUAN_BIAS_UP_POS) &
	                                AG903_SPC_VIDEOADC_MISC_CTRL4_QUAN_BIAS_UP_MSK;
	val |= (param->gain3         << AG903_SPC_VIDEOADC_MISC_CTRL4_CH3_GAIN_POS) &
	                                AG903_SPC_VIDEOADC_MISC_CTRL4_CH3_GAIN_MSK;
	AG903_SPC->VIDEOADC_MISC_CTRL4 = val;
	
	val  = AG903_SPC->VIDEOADC_MISC_CTRL3;
	val &= ~(AG903_SPC_VIDEOADC_MISC_CTRL3_CH2_GAIN_MSK |
		     AG903_SPC_VIDEOADC_MISC_CTRL3_CH1_GAIN_MSK |
		     AG903_SPC_VIDEOADC_MISC_CTRL3_CH0_GAIN_MSK |
		     AG903_SPC_VIDEOADC_MISC_CTRL3_CH3_CLAMP_MSK);
	val |= (param->gain2    << AG903_SPC_VIDEOADC_MISC_CTRL3_CH2_GAIN_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL3_CH2_GAIN_MSK;
	val |= (param->gain1    << AG903_SPC_VIDEOADC_MISC_CTRL3_CH1_GAIN_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL3_CH1_GAIN_MSK;
	val |= (param->gain0    << AG903_SPC_VIDEOADC_MISC_CTRL3_CH0_GAIN_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL3_CH0_GAIN_MSK;
	val |= (param->clmp_lv3 << AG903_SPC_VIDEOADC_MISC_CTRL3_CH3_CLAMP_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL3_CH3_CLAMP_MSK;
	AG903_SPC->VIDEOADC_MISC_CTRL3 = val;
	
	val = 0;
	val |= (param->clmp_lv2 << AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_CLAMP_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_CLAMP_MSK;
	val |= (param->clmp_lv1 << AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_CLAMP_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_CLAMP_MSK;
	val |= (param->clmp_lv0 << AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_CLAMP_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_CLAMP_MSK;
	val |= (param->clmp_imp << AG903_SPC_VIDEOADC_MISC_CTRL2_CLAMP_IMP_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CLAMP_IMP_MSK;
	val |= (enable->ch3     << AG903_SPC_VIDEOADC_MISC_CTRL2_CH3_ENABLE_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CH3_ENABLE_MSK;
	val |= (enable->ch2     << AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_ENABLE_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_ENABLE_MSK;
	val |= (enable->ch1     << AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_ENABLE_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_ENABLE_MSK;
	val |= (enable->ch0     << AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_ENABLE_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_ENABLE_MSK;
	AG903_SPC->VIDEOADC_MISC_CTRL2 = val;	/* CH単位Enable設定 */

	val = 0;
	val |= (param->clmp_en3 << AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN3_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN3_MSK;
	val |= (param->clmp_en2 << AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN2_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN2_MSK;
	val |= (param->clmp_en1 << AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN1_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN1_MSK;
	val |= (param->clmp_en0 << AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN0_POS) &
	                           AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN0_MSK;
	val |= (enable->adc     << AG903_SPC_VIDEOADC_MISC_CTRL1_ENABLE_POS) &
		                       AG903_SPC_VIDEOADC_MISC_CTRL1_ENABLE_MSK;
	AG903_SPC->VIDEOADC_MISC_CTRL1 = val;	/* ADC全体Enable設定 */

	return;
}

/**
 * @brief           SPCVIDEOADC_MISC_CTRLnのレジスタRead
 * @param           param  [out] 設定パラメータ
 * @param           enable [out] 動作設定
 * @return          void
 * @description     SPCVIDEOADC_MISC_CTRLnのレジスタRead
*/
void AG903_SPCPrmGetVideoAdcCtrl(AG903_SPCPrmVideoAdcParam* param, AG903_SPCPrmVideoAdcEnable* enable)
{
	uint32_t	val;

	ASSERT(NULL != param);
	ASSERT(NULL != enable);
	
	val = AG903_SPC->VIDEOADC_MISC_CTRL5;
	param->input_range   = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL5_INPUT_RANGE_MSK) >>
		                                    AG903_SPC_VIDEOADC_MISC_CTRL5_INPUT_RANGE_POS);
	param->ref_bias_up   = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL5_REF_BIAS_UP_MSK) >>
		                                    AG903_SPC_VIDEOADC_MISC_CTRL5_REF_BIAS_UP_POS);
	
	val = AG903_SPC->VIDEOADC_MISC_CTRL4;
	param->aaf_ctrl      = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL4_AAF_CTRL_MSK) >>
		                                    AG903_SPC_VIDEOADC_MISC_CTRL4_AAF_CTRL_POS);
	param->qntzr_bias_up = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL4_QUAN_BIAS_UP_MSK) >>
		                                    AG903_SPC_VIDEOADC_MISC_CTRL4_QUAN_BIAS_UP_POS);
	param->gain3         = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL4_CH3_GAIN_MSK) >>
		                                    AG903_SPC_VIDEOADC_MISC_CTRL4_CH3_GAIN_POS);
	
	val = AG903_SPC->VIDEOADC_MISC_CTRL3;
	param->gain2    = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL3_CH2_GAIN_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL3_CH2_GAIN_POS);
	param->gain1    = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL3_CH1_GAIN_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL3_CH1_GAIN_POS);
	param->gain0    = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL3_CH0_GAIN_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL3_CH0_GAIN_POS);
	param->clmp_lv3 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL3_CH3_CLAMP_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL3_CH3_CLAMP_POS);
	
	val = AG903_SPC->VIDEOADC_MISC_CTRL2;
	param->clmp_lv2 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_CLAMP_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_CLAMP_POS);
	param->clmp_lv1 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_CLAMP_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_CLAMP_POS);
	param->clmp_lv0 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_CLAMP_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_CLAMP_POS);
	param->clmp_imp = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CLAMP_IMP_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CLAMP_IMP_POS);
	enable->ch3     = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CH3_ENABLE_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CH3_ENABLE_POS);
	enable->ch2     = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_ENABLE_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CH2_ENABLE_POS);
	enable->ch1     = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_ENABLE_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CH1_ENABLE_POS);
	enable->ch0     = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_ENABLE_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL2_CH0_ENABLE_POS);
	
	val = AG903_SPC->VIDEOADC_MISC_CTRL1;
	param->clmp_en3 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN3_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN3_POS);
	param->clmp_en2 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN2_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN2_POS);
	param->clmp_en1 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN1_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN1_POS);
	param->clmp_en0 = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN0_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL1_CLAMP_EN0_POS);
	enable->adc     = (uint8_t)((val & AG903_SPC_VIDEOADC_MISC_CTRL1_ENABLE_MSK) >>
		                               AG903_SPC_VIDEOADC_MISC_CTRL1_ENABLE_POS);
	
	return;
}

/**
 * @brief           SPCLVDS_TX_SETUPのレジスタWrite
 * @param           rf_ch0 [in] クロック設定 (CH0)
 * @param           rf_ch1 [in] クロック設定 (CH1)
 * @return          void
 * @description     SPCLVDS_TX_SETUPのレジスタWrite
*/
void AG903_SPCPrmSetLvdsTx(uint8_t rf_ch0, uint8_t rf_ch1)
{
	uint32_t	val = 0;
	
	val |= ((rf_ch0 << AG903_SPC_LVDS_TX_SETUP_RF_0_POS) & AG903_SPC_LVDS_TX_SETUP_RF_0_MSK);
	val |= ((rf_ch1 << AG903_SPC_LVDS_TX_SETUP_RF_1_POS) & AG903_SPC_LVDS_TX_SETUP_RF_1_MSK);
	AG903_SPC->LVDS_TX_SETUP = val;
	return;
}

/**
 * @brief           SPCLVDS_TX_SETUPのレジスタRead
 * @param           rf_ch0 [out] クロック設定状態 (CH0)
 * @param           rf_ch1 [out] クロック設定状態 (CH1)
 * @return          void
 * @description     SPCLVDS_TX_SETUPのレジスタRead
*/
void AG903_SPCPrmGetLvdsTx(uint8_t* rf_ch0, uint8_t* rf_ch1)
{
	uint32_t	val;
	
	ASSERT(NULL != rf_ch0);
	ASSERT(NULL != rf_ch1);
	
	val = AG903_SPC->LVDS_TX_SETUP;
	(*rf_ch0) = (uint8_t)((val & AG903_SPC_LVDS_TX_SETUP_RF_0_MSK) >> AG903_SPC_LVDS_TX_SETUP_RF_0_POS);
	(*rf_ch1) = (uint8_t)((val & AG903_SPC_LVDS_TX_SETUP_RF_1_MSK) >> AG903_SPC_LVDS_TX_SETUP_RF_1_POS);
	return;
}

/**
 * @brief           SPCUSB_MISC_CTRL1のレジスタWrite
 * @param           clk_div [in] 分周設定
 * @param           clk_sel [in] クロック設定
 * @return          void
 * @description     SPCUSB_MISC_CTRL1のレジスタWrite
*/
void AG903_SPCPrmSetUsbMiscCtrl1(uint8_t clk_div, uint8_t clk_sel)
{
	uint32_t	val;
	
	val = AG903_SPC->USB_MISC_CTRL1;
	if(true == clk_div) {
		val |= (1 << AG903_SPC_USB_MISC_CTRL1_CLK_DIV_POS);
	}
	if(AG903_SPC_USBCTRL_CLKSEL_XOUT ==clk_sel) {
		val |= (1 << AG903_SPC_USB_MISC_CTRL1_CLK_SEL_POS);
	}
	AG903_SPC->USB_MISC_CTRL1 = val;
	
	return;
}

/**
 * @brief           SPCUSB_MISC_CTRL1のレジスタRead
 * @param           clk_div [out] 分周設定
 * @param           clk_sel [out] クロック設定
 * @param           vbus    [out] USB電源制御状態
 * @param           vprtct  [out] USB電源保護状態
 * @return          void
 * @description     SPCUSB_MISC_CTRL1のレジスタRead
*/
void AG903_SPCPrmGetUsbMiscCtrl1(uint8_t* clk_div, uint8_t* clk_sel, uint8_t* vbus, uint8_t* vprtct)
{
	uint32_t	val;

	ASSERT(NULL != clk_div);
	ASSERT(NULL != clk_sel);
	ASSERT(NULL != vbus);
	ASSERT(NULL != vprtct);
	
	val = AG903_SPC->USB_MISC_CTRL1;
	if(AG903_SPC_USB_MISC_CTRL1_CLK_DIV_MSK & val) {
		(*clk_div) = true;
	}
	else {
		(*clk_div) = false;
	}
	if(AG903_SPC_USB_MISC_CTRL1_CLK_SEL_MSK & val) {
		(*clk_sel) = AG903_SPC_USBCTRL_CLKSEL_XOUT;
	}
	else {
		(*clk_sel) = AG903_SPC_USBCTRL_CLKSEL_MIIRXCLK;
	}
	if(AG903_SPC_USB_MISC_CTRL1_VBUS_outen_MSK & val) {
		(*vbus)    = true;
	}
	else {
		(*vbus)    = false;
	}
	if(AG903_SPC_USB_MISC_CTRL1_VPRTCT_state_MSK & val) {
		(*vprtct)  = true;
	}
	else {
		(*vprtct)  = false;
	}
	
	return;
}

/**
 * @brief           SPCUSB_MISC_CTRL2のレジスタWrite
 * @param           param [in] 設定パラメータ
 * @return          void
 * @description     SPCUSB_MISC_CTRL2のレジスタWrite
*/
void AG903_SPCPrmSetUsbMiscCtrl2(AG903_SPCPrmUsbMiscCtrl* param)
{
	uint32_t	val = 0;
	
	ASSERT(NULL != param);
	
	if(true != param->suspend) {
		val |= (1 << AG903_SPC_USB_MISC_CTRL2_suspendm_POS);
	}
	if(true == param->wakeup) {
		val |= (1 << AG903_SPC_USB_MISC_CTRL2_wakeup_POS);
	}
	val |= (param->squelch  << AG903_SPC_USB_MISC_CTRL2_TC_TB_TA_POS) & AG903_SPC_USB_MISC_CTRL2_TC_TB_TA_MSK;
	if(true == param->pll_aliv) {
		val |= (1 << AG903_SPC_USB_MISC_CTRL2_PLLALIV_POS);
	}
	if(AG903_SPC_USBCTRL_XTLSEL_30MHZ == param->xtl_sel) {
		val |= (1 << AG903_SPC_USB_MISC_CTRL2_XTLSEL_POS);
	}
	if(true == param->oscout) {
		val |= (1 << AG903_SPC_USB_MISC_CTRL2_OSCOUTEN_POS);
	}
	val |= (1 << AG903_SPC_USB_MISC_CTRL2_OUTCLKSEL_POS);	/* 常に"1" */
	AG903_SPC->USB_MISC_CTRL2 = val;
	
	return;
}

/**
 * @brief           SPCUSB_MISC_CTRL2のレジスタRead
 * @param           param [out] 設定パラメータ
 * @return          void
 * @description     SPCUSB_MISC_CTRL2のレジスタRead
*/
void AG903_SPCPrmGetUsbMiscCtrl2(AG903_SPCPrmUsbMiscCtrl* param)
{
	uint32_t	val = 0;
	
	ASSERT(NULL != param);
	
	val = AG903_SPC->USB_MISC_CTRL2;
	if(AG903_SPC_USB_MISC_CTRL2_suspendm_MSK & val) {
		param->suspend = false;
	}
	else {
		param->suspend = true;
	}
	if(AG903_SPC_USB_MISC_CTRL2_wakeup_MSK & val) {
		param->wakeup  = true;
	}
	else {
		param->wakeup  = false;
	}
	param->squelch  = (uint8_t)((val & AG903_SPC_USB_MISC_CTRL2_TC_TB_TA_MSK) >> AG903_SPC_USB_MISC_CTRL2_TC_TB_TA_POS);
	if(AG903_SPC_USB_MISC_CTRL2_PLLALIV_MSK & val) {
		param->pll_aliv = true;
	}
	else {
		param->pll_aliv = false;
	}
	if(AG903_SPC_USB_MISC_CTRL2_XTLSEL_MSK & val) {
		param->xtl_sel = AG903_SPC_USBCTRL_XTLSEL_30MHZ;
	}
	else {
		param->xtl_sel = AG903_SPC_USBCTRL_XTLSEL_12MHZ;
	}
	if(AG903_SPC_USB_MISC_CTRL2_OSCOUTEN_MSK & val) {
		param->oscout = true;
	}
	else {
		param->oscout = false;
	}
	
	return;
}

/**
 * @brief           SPCDDR_PHY_SETUPのレジスタWrite
 * @param           pd_gain  [in] 位相検出ゲイン
 * @param           afl_gain [in] 誤ロック防止用ゲイン
 * @return          void
 * @description     SPCDDR_PHY_SETUPのレジスタWrite
*/
void AG903_SPCPrmSetDdrPhySetup(uint8_t pd_gain, uint8_t afl_gain)
{
	uint32_t	val;
	
	val  = AG903_SPC->DDR_PHY_SETUP;
	val &= ~(AG903_SPC_DDR_PHY_SETUP_AFL_GAIN_MSK | AG903_SPC_DDR_PHY_SETUP_PD_GAIN_MSK);
	val |= (pd_gain  << AG903_SPC_DDR_PHY_SETUP_PD_GAIN_POS)  & AG903_SPC_DDR_PHY_SETUP_PD_GAIN_MSK;
	val |= (afl_gain << AG903_SPC_DDR_PHY_SETUP_AFL_GAIN_POS) & AG903_SPC_DDR_PHY_SETUP_AFL_GAIN_MSK;
	AG903_SPC->DDR_PHY_SETUP = val;
	
	return;
}

/**
 * @brief           SPCDDR_PHY_SETUPのレジスタRead
 * @param           pd_gain  [out] 位相検出ゲイン
 * @param           afl_gain [out] 誤ロック防止用ゲイン
 * @return          void
 * @description     SPCDDR_PHY_SETUPのレジスタRead
*/
void AG903_SPCPrmGetDdrPhySetup(uint8_t* pd_gain, uint8_t* afl_gain)
{
	uint32_t	val;
	
	ASSERT(NULL != pd_gain);
	ASSERT(NULL != afl_gain);
	
	val = AG903_SPC->DDR_PHY_SETUP;
	(*pd_gain)  = (uint8_t)((val & AG903_SPC_DDR_PHY_SETUP_PD_GAIN_MSK)  >> AG903_SPC_DDR_PHY_SETUP_PD_GAIN_POS);
	(*afl_gain) = (uint8_t)((val & AG903_SPC_DDR_PHY_SETUP_AFL_GAIN_MSK) >> AG903_SPC_DDR_PHY_SETUP_AFL_GAIN_POS);
	
	return;
}

/**
 * @brief           SPCBOOT_SWAP_CTRLのレジスタWrite
 * @param           swap [in] スワップ設定 (true/false)<p>
 * true :0x00000000[SRAM], 0x08000000[SPIROM]<p>
 * false:0x08000000[SRAM], 0x00000000[SPIROM]
 * @return          void
 * @description     SPCBOOT_SWAP_CTRLのレジスタWrite
*/
void AG903_SPCPrmSetBootSwapCtrl(uint8_t swap)
{
	uint32_t	val = 0;
	
	if(true==swap) {
		val |= (1 << AG903_SPC_BOOT_SWAP_CTRL_BOOTSWAP_POS);
	}
	AG903_SPC->BOOT_SWAP_CTRL = val;
	
	return;
}

/**
 * @brief           SPCBOOT_SWAP_CTRLのレジスタRead
 * @param           swap [out] スワップ設定 (true/false)<p>
 * true :0x00000000[SRAM], 0x08000000[SPIROM]<p>
 * false:0x08000000[SRAM], 0x00000000[SPIROM]
 * @return          void
 * @description     SPCBOOT_SWAP_CTRLのレジスタRead
*/
void AG903_SPCPrmGetBootSwapCtrl(uint8_t* swap)
{
	uint32_t	val;
	
	ASSERT(NULL != swap);
	
	val = AG903_SPC->BOOT_SWAP_CTRL;
	if(AG903_SPC_BOOT_SWAP_CTRL_BOOTSWAP_MSK & val) {
		(*swap) = true;
	}
	else {
		(*swap) = false;
	}
	return;
}

/**
 * @brief           SPCIDE_CLK_SELのレジスタWrite
 * @param           clk_sel [in] クロック選択
 * @return          void
 * @description     SPCIDE_CLK_SELのレジスタWrite
*/
void AG903_SPCPrmSetIdeClk(uint8_t clk_sel)
{
	uint32_t	val = 0;
	
	val |= (clk_sel << AG903_SPC_IDE_CLK_SEL_IDECLK_SEL_POS) & AG903_SPC_IDE_CLK_SEL_IDECLK_SEL_MSK;
	AG903_SPC->IDE_CLK_SEL = val;
	return;
}

/**
 * @brief           SPCIDE_CLK_SELのレジスタRead
 * @param           clk_sel [out] クロック選択
 * @return          void
 * @description     SPCIDE_CLK_SELのレジスタRead
*/
void AG903_SPCPrmGetIdeClk(uint8_t* clk_sel)
{
	uint32_t	val;
	
	ASSERT(NULL != clk_sel);
	
	val = AG903_SPC->IDE_CLK_SEL;
	(*clk_sel) = (uint8_t)((val & AG903_SPC_IDE_CLK_SEL_IDECLK_SEL_MSK) >> AG903_SPC_IDE_CLK_SEL_IDECLK_SEL_POS);
	return;
}

