/**
 * @brief       SSP Primitive
 * @author      AXELL CORPORATION
 * @description SSP Primitive Layer
 * @note        none 
 * @history     2017_02_22  初版
 * @history     2017_10_26  Ver2.0
 * @history     2023_03_31  [SDK3.5] SSPライブラリにI2Sのマスターモードを追加 (#4205)
 * @history     2025_03_06  [SDK3.7] SSPで1ワードの送信ができない不具合を修正 (#5633)
 * @history     2025_03_06  [SDK3.7] SSPライブラリにSPIモードでの送受信アクセス機能を追加 (#5662)
*/
/* DOM-IGNORE-BEGIN */
/*
 * This program was created by Axell Corporation.
 * Copyright (C) 2017-2025 Axell Corporation, all rights reserved.
 */
/* DOM-IGNORE-END */

#include "AG903_errno.h"
#include "AG903_common.h"
#include "ssp/sspprm.h"
#include "register/AG903_sspreg.h"

#define	AG903_SSP_READ_REG(CH,REG)			(AG903_SSPn(CH)->REG)
#define	AG903_SSP_READ_FLD(CH,REG,POS,MSK)	(((AG903_SSPn(CH)->REG)&MSK) >> POS)
#define	AG903_SSP_WRITE_REG(CH,REG,VAL)		(AG903_SSPn(CH)->REG  = (uint32_t)(VAL))
#define	AG903_SSP_CLR_REG(CH,REG,VAL)		(AG903_SSPn(CH)->REG &= (uint32_t)(~VAL))
#define	AG903_SSP_SET_REG(CH,REG,VAL)		(AG903_SSPn(CH)->REG |= (uint32_t)(VAL))
#define AG903_SSP_UNPACK_FLD(V,REG,FLD)     (((V) & AG903_SSPn_##REG##_##FLD##_MSK) >> AG903_SSPn_##REG##_##FLD##_POS)
#define AG903_SSP_PACK_FLD(V,REG,FLD)       (((V) << AG903_SSPn_##REG##_##FLD##_POS) & AG903_SSPn_##REG##_##FLD##_MSK)

/**
 * @brief           SSPnSSPCR0,SSPnSSPCR1のレジスタWrite
 * @param           ch [in] SSPチャネル
 * @param           param [in] 制御パラメータ
 * @return          void
 * @description     SSPnSSPCR0,SSPnSSPCR1のレジスタWrite
*/
void AG903_SSPPrmSetControl(uint8_t ch, AG903_SSPPrmCtrl* param)
{
	uint32_t	ctrl_0=0;
	uint32_t	ctrl_1=0;

	ASSERT(AG903_SSP_CH_NUM > ch);

	if (AG903_SSP_OPM_MASTER == param->opm ||
		AG903_SSP_OPM_MASTER_STEREO == param->opm) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_FSFDBK_POS);
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_SCLKFDBK_POS);
	}

	if(0 != param->spi_fspo) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_SPIFSPO_POS);
	}

	ctrl_0 |= (uint32_t)((param->format << AG903_SSPn_SSPCR0_FFMT_POS) & AG903_SSPn_SSPCR0_FFMT_MSK);

	if(0 != param->spi_flash) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_FLASH_POS);
	}
	if(0 != param->validity) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_Validity_POS);
	}

	ctrl_0 |= (uint32_t)((param->fsdist << AG903_SSPn_SSPCR0_FSDIST_POS) & AG903_SSPn_SSPCR0_FSDIST_MSK);

	if(0 != param->lsb) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_LSB_POS);
	}
	if(0 != param->fspo) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_FSPO_POS);
	}
	if(0 != param->fsjstfy) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_FSJSTFY_POS);
	}
	
	ctrl_0 |= (uint32_t)((param->opm << AG903_SSPn_SSPCR0_OPM_POS) & AG903_SSPn_SSPCR0_OPM_MSK);
	
	if(0 != param->sclkpo) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_SCLKPO_POS);
	}
	if(0 != param->sclkph) {
		ctrl_0 |= (uint32_t)(1 << AG903_SSPn_SSPCR0_SCLKPH_POS);
	}
	
	ctrl_1 |= (uint32_t)((param->pdl << AG903_SSPn_SSPCR1_PDL_POS) & AG903_SSPn_SSPCR1_PDL_MSK);
	ctrl_1 |= (uint32_t)((param->sdl << AG903_SSPn_SSPCR1_SDL_POS) & AG903_SSPn_SSPCR1_SDL_MSK);
	ctrl_1 |= (uint32_t)((param->sclk_div << AG903_SSPn_SSPCR1_SCLKDIV_POS) & AG903_SSPn_SSPCR1_SCLKDIV_MSK);

	AG903_SSP_WRITE_REG(ch,SSPCR0,ctrl_0);
	AG903_SSP_WRITE_REG(ch,SSPCR1,ctrl_1);
	return;
}

/**
 * @brief           SSPnSSPCR2のレジスタRead
 * @param           ch [in] SSPチャネル
 * @param           param [out] 制御パラメータ
 * @return          void
 * @description     SSPnSSPCR2のレジスタWrite
*/
void AG903_SSPPrmGetControl2(uint8_t ch, AG903_SSPPrmCtrl2* param)
{
	uint32_t ctrl_2;

	ASSERT(AG903_SSP_CH_NUM > ch);

	ctrl_2 = AG903_SSP_READ_REG(ch,SSPCR2);
	param->fsos   = AG903_SSP_UNPACK_FLD(ctrl_2, SSPCR2, FSOS);
	param->fs     = AG903_SSP_UNPACK_FLD(ctrl_2, SSPCR2, FS);	
	param->txen   = AG903_SSP_UNPACK_FLD(ctrl_2, SSPCR2, TXEN);
	param->rxen   = AG903_SSP_UNPACK_FLD(ctrl_2, SSPCR2, RXEN);
	param->ssprst = 0;
	param->txfclr = 0;
	param->rxfclr = 0;
	param->txdoe  = AG903_SSP_UNPACK_FLD(ctrl_2, SSPCR2, TXDOE);
	param->sspen  = AG903_SSP_UNPACK_FLD(ctrl_2, SSPCR2, SSPEN);
	return;
}

/**
 * @brief           SSPnSSPCR2のレジスタWrite
 * @param           ch [in] SSPチャネル
 * @param           param [in] 制御パラメータ
 * @return          void
 * @description     SSPnSSPCR2のレジスタWrite
*/
void AG903_SSPPrmSetControl2(uint8_t ch, AG903_SSPPrmCtrl2* param)
{
	uint32_t ctrl_2;

	ASSERT(AG903_SSP_CH_NUM > ch);
	param->fsos = 0;

	ctrl_2 = 0;
	ctrl_2 |= AG903_SSP_PACK_FLD(param->fsos,   SSPCR2, FSOS);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->fs,     SSPCR2, FS);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->txen,   SSPCR2, TXEN);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->rxen,   SSPCR2, RXEN);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->ssprst, SSPCR2, SSPRST);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->txfclr, SSPCR2, TXFCLR);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->rxfclr, SSPCR2, RXFCLR);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->txdoe,  SSPCR2, TXDOE);
	ctrl_2 |= AG903_SSP_PACK_FLD(param->sspen,  SSPCR2, SSPEN);
	AG903_SSP_WRITE_REG(ch,SSPCR2,ctrl_2);
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのTXDOEビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのTXDOEビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableOutput(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_TXDOE_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのTXDOEビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのTXDOEビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisableOutput(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_CLR_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_TXDOE_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのSSPENビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのSSPENビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableTransfer(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_SSPEN_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのSSPENビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのSSPENビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisableTransfer(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_CLR_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_SSPEN_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのSSPENビットRead
 * @param           ch [in] SSPチャネル
 * @param           enable [out] Enable状態
 * @return          void
 * @description     SSPnSSPCR2レジスタのSSPENビットRead
*/
void AG903_SSPPrmCheckEnable(uint8_t ch, uint8_t* enable)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	(*enable) = AG903_SSP_READ_FLD(ch,SSPCR2,AG903_SSPn_SSPCR2_SSPEN_POS,AG903_SSPn_SSPCR2_SSPEN_MSK);
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのTXENビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのTXENビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableTxFunc(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_TXEN_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのTXENビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのTXENビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisbleTxFunc(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_CLR_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_TXEN_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのRXENビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのRXENビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableRxFunc(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_RXEN_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのRXENビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのRXENビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisbleRxFunc(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_CLR_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_RXEN_POS));
	return;
}

/**
 * @brief           SSPnSSPStatusレジスタのTFVEフィールドRead
 * @param           ch [in] SSPチャネル
 * @param           entry [out] エントリ数
 * @return          void
 * @description     SSPnSSPStatusレジスタのTFVEフィールドRead
*/
void AG903_SSPPrmGetTxFifoEntry(uint8_t ch, uint8_t* entry)
{
	(*entry) = AG903_SSP_READ_FLD(ch,SSPStatus,AG903_SSPn_SSPStatus_TFVE_POS,AG903_SSPn_SSPStatus_TFVE_MSK);
	return;
}

/**
 * @brief           SSPnSSPStatusレジスタのRFVEフィールドRead
 * @param           ch [in] SSPチャネル
 * @param           entry [out] エントリ数
 * @return          void
 * @description     SSPnSSPStatusレジスタのRFVEフィールドRead
*/
void AG903_SSPPrmGetRxFifoEntry(uint8_t ch, uint8_t* entry)
{
	(*entry) = AG903_SSP_READ_FLD(ch,SSPStatus,AG903_SSPn_SSPStatus_RFVE_POS,AG903_SSPn_SSPStatus_RFVE_MSK);
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのTFTHODフィールドWrite
 * @param           ch [in] SSPチャネル
 * @param           val [in] 設定値
 * @return          void
 * @description     SSPnIntrCRレジスタのTFTHODフィールドWrite
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmSetTxFifoThreshold(uint8_t ch, uint8_t val)
{
	AG903_SSP_CLR_REG(ch,IntrCR,AG903_SSPn_IntrCR_TFTHOD_MSK);
	AG903_SSP_SET_REG(ch,IntrCR,(val<<AG903_SSPn_IntrCR_TFTHOD_POS));
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのRFTHODフィールドWrite
 * @param           ch [in] SSPチャネル
 * @param           val [in] 設定値
 * @return          void
 * @description     SSPnIntrCRレジスタのRFTHODフィールドWrite
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmSetRxFifoThreshold(uint8_t ch, uint8_t val)
{
	AG903_SSP_CLR_REG(ch,IntrCR,AG903_SSPn_IntrCR_RFTHOD_MSK);
	AG903_SSP_SET_REG(ch,IntrCR,(val<<AG903_SSPn_IntrCR_RFTHOD_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのTXFCLRビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのTXFCLRビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmClearTxFifo(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_TXFCLR_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのRXFCLRビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのRXFCLRビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmClearRxFifo(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_RXFCLR_POS));
	return;
}

/**
 * @brief           SSPnSSPCR2レジスタのSSPRSTビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnSSPCR2レジスタのSSPRSTビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmReset(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,SSPCR2,(1<<AG903_SSPn_SSPCR2_SSPRST_POS));
	return;
}

/**
 * @brief           SSPnSPDIFStatus0,SSPnSPDIFStatus1レジスタWrite
 * @param           ch [in] SSPチャネル
 * @param           status_0 [in] ステータスビットレジスタ0設定値
 * @param           status_1 [in] ステータスビットレジスタ1設定値
 * @return          void
 * @description     SSPnSPDIFStatus0,SSPnSPDIFStatus1レジスタWrite
*/
void AG903_SSPPrmSetStatusBit(uint8_t ch, uint32_t status_0, uint32_t status_1)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_WRITE_REG(ch,SPDIFStatus0,status_0);
	AG903_SSP_WRITE_REG(ch,SPDIFStatus1,status_1);
	return;
}

/**
 * @brief           SSPnSPDIFUsernレジスタWrite
 * @param           ch [in] SSPチャネル
 * @param           offset [in] レジスタオフセット
 * @param           val [in] 設定値
 * @return          void
 * @description     SSPnSPDIFUsernレジスタWrite
*/
void AG903_SSPPrmSetUserBit(uint8_t ch, uint8_t offset, uint32_t val)
{
	uint32_t* reg;
	
	ASSERT(AG903_SSP_CH_NUM > ch);
	
	reg = (uint32_t*)(&AG903_SSPn(ch)->SPDIFUser0);
	(*(reg+offset)) = val;
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのTFTHIEN,TFURIENビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのTFTHIEN,TFURIENビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableTxInt(uint8_t ch)
{
	uint32_t	val;

	ASSERT(AG903_SSP_CH_NUM > ch);
	val =
		1<<AG903_SSPn_IntrCR_TFTHIEN_POS |
		1<<AG903_SSPn_IntrCR_TFURIEN_POS;
	AG903_SSP_SET_REG(ch,IntrCR,val);
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのTFTHIEN,TFURIENビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのTFTHIEN,TFURIENビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisbleTxInt(uint8_t ch)
{
	uint32_t	val;

	ASSERT(AG903_SSP_CH_NUM > ch);
	val =
		1<<AG903_SSPn_IntrCR_TFTHIEN_POS |
		1<<AG903_SSPn_IntrCR_TFURIEN_POS;
	AG903_SSP_CLR_REG(ch,IntrCR,val);
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのRFTHIEN,RFORIENビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのRFTHIEN,RFORIENビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableRxInt(uint8_t ch)
{
	uint32_t	val;

	ASSERT(AG903_SSP_CH_NUM > ch);
	val =
		1<<AG903_SSPn_IntrCR_RFTHIEN_POS |
		1<<AG903_SSPn_IntrCR_RFORIEN_POS;
	AG903_SSP_SET_REG(ch,IntrCR,val);
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのRFTHIEN,RFORIENビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのRFTHIEN,RFORIENビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisbleRxInt(uint8_t ch)
{
	uint32_t	val;

	ASSERT(AG903_SSP_CH_NUM > ch);
	val =
		1<<AG903_SSPn_IntrCR_RFTHIEN_POS |
		1<<AG903_SSPn_IntrCR_RFORIEN_POS;
	AG903_SSP_CLR_REG(ch,IntrCR,val);
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのTFDMAENビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのTFDMAENビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableTxDmareq(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,IntrCR,(1<<AG903_SSPn_IntrCR_TFDMAEN_POS));
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのTFDMAENビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのTFDMAENビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisableTxDmareq(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_CLR_REG(ch,IntrCR,(1<<AG903_SSPn_IntrCR_TFDMAEN_POS));
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのRFDMAENビットSet
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのRFDMAENビットSet
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmEnableRxDmareq(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_SET_REG(ch,IntrCR,(1<<AG903_SSPn_IntrCR_RFDMAEN_POS));
	return;
}

/**
 * @brief           SSPnIntrCRレジスタのRFDMAENビットClear
 * @param           ch [in] SSPチャネル
 * @return          void
 * @description     SSPnIntrCRレジスタのRFDMAENビットClear
 * @note            レジスタをリードモディファイライトします。
*/
void AG903_SSPPrmDisableRxDmareq(uint8_t ch)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_CLR_REG(ch,IntrCR,(1<<AG903_SSPn_IntrCR_RFDMAEN_POS));
	return;
}

/**
 * @brief           SSPnTxRxDRレジスタWrite
 * @param           ch [in] SSPチャネル
 * @param           val [in] データ
 * @return          void
 * @description     SSPnTxRxDRレジスタWrite
*/
void AG903_SSPPrmSetData(uint8_t ch, uint32_t val)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	AG903_SSP_WRITE_REG(ch,TxRxDR,val);
	return;
}

/**
 * @brief           SSPnTxRxDRレジスタRead
 * @param           ch [in] SSPチャネル
 * @param           val [out] データ
 * @return          void
 * @description     SSPnTxRxDRレジスタRead
*/
void AG903_SSPPrmGetData(uint8_t ch, uint32_t* val)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	(*val) = AG903_SSP_READ_REG(ch,TxRxDR);
	return;
}

/**
 * @brief           SSPnSSPStatusレジスタRead
 * @param           ch [in] SSPチャネル
 * @param           status [out] ステータス
 * @return          void
 * @description     SSPnSSPStatusレジスタRead
*/
void AG903_SSPPrmGetStatus(uint8_t ch, AG903_SSPPrmStatus* status)
{
	uint32_t	val;

	ASSERT(AG903_SSP_CH_NUM > ch);
	val = AG903_SSP_READ_REG(ch,SSPStatus);
	
	status->txfifo_num = (uint8_t)((val & AG903_SSPn_SSPStatus_TFVE_MSK) >> AG903_SSPn_SSPStatus_TFVE_POS);
	status->rxfifo_num = (uint8_t)((val & AG903_SSPn_SSPStatus_RFVE_MSK) >> AG903_SSPn_SSPStatus_RFVE_POS);
	if(AG903_SSPn_SSPStatus_BUSY_MSK & val) {
		status->busy = true;
	}
	else {
		status->busy = false;
	}
	if(AG903_SSPn_SSPStatus_TFNF_MSK & val) {
		status->txfifo_notfull = true;
	}
	else {
		status->txfifo_notfull = false;
	}
	if(AG903_SSPn_SSPStatus_RFF_MSK & val) {
		status->rxfifo_full = true;
	}
	else {
		status->rxfifo_full = false;
	}
	
	return;
}

/**
 * @brief           SSPnIntrCRレジスタWrite
 * @param           ch [in] SSPチャネル
 * @param           param [in] 制御パラメータ
 * @return          void
 * @description     SSPnIntrCRレジスタWrite
*/
void AG903_SSPPrmSetIntControl(uint8_t ch, AG903_SSPPrmIntCtrl* param)
{
	uint32_t intr_cr;

	ASSERT(AG903_SSP_CH_NUM > ch);

	intr_cr = 0;
	intr_cr |= AG903_SSP_PACK_FLD(param->tfthod,  IntrCR, TFTHOD);
	intr_cr |= AG903_SSP_PACK_FLD(param->rfthod,  IntrCR, RFTHOD);
	intr_cr |= AG903_SSP_PACK_FLD(param->tfdmaen, IntrCR, TFDMAEN);
	intr_cr |= AG903_SSP_PACK_FLD(param->rfdmaen, IntrCR, RFDMAEN);
	intr_cr |= AG903_SSP_PACK_FLD(param->tfthien, IntrCR, TFTHIEN);
	intr_cr |= AG903_SSP_PACK_FLD(param->rfthien, IntrCR, RFTHIEN);
	intr_cr |= AG903_SSP_PACK_FLD(param->tfurien, IntrCR, TFURIEN);
	intr_cr |= AG903_SSP_PACK_FLD(param->rforien, IntrCR, RFORIEN);
	AG903_SSP_WRITE_REG(ch,IntrCR,intr_cr);
	return;
}

/**
 * @brief           SSPnIntrCRレジスタRead
 * @param           ch [in] SSPチャネル
 * @param           param [out] 制御パラメータ
 * @return          void
 * @description     SSPnIntrCRレジスタRead
*/
void AG903_SSPPrmGetIntControl(uint8_t ch, AG903_SSPPrmIntCtrl* param)
{
	uint32_t intr_cr;

	ASSERT(AG903_SSP_CH_NUM > ch);

	intr_cr = AG903_SSP_READ_REG(ch,IntrCR);
	param->tfthod  = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, TFTHOD);
	param->rfthod  = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, RFTHOD);	
	param->tfdmaen = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, TFDMAEN);
	param->rfdmaen = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, RFDMAEN);
	param->tfthien = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, TFTHIEN);
	param->rfthien = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, RFTHIEN);
	param->tfurien = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, TFURIEN);
	param->rforien = AG903_SSP_UNPACK_FLD(intr_cr, IntrCR, RFORIEN);
	return;
}

/**
 * @brief           SSPnIntrStatusレジスタRead
 * @param           ch [in] SSPチャネル
 * @param           status [out] ステータス
 * @return          void
 * @description     SSPnIntrStatusレジスタRead
*/
void AG903_SSPPrmGetIntStatus(uint8_t ch, uint32_t* status)
{
	ASSERT(AG903_SSP_CH_NUM > ch);
	(*status) = AG903_SSP_READ_REG(ch,IntrStatus);
	return;
}

