/**
 * @brief           SSP Primitive Header
 * @author          AXELL CORPORATION
 * @description     SSP Primitive提供ヘッダ。<p>SSP Primitive使用時にincludeして下さい。
 * @note            none
 * @history         2017_02_22  初版
 * @history         2017_10_26  Ver2.0
 * @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.
 */

#ifndef _SSPPRM_H_
#define _SSPPRM_H_
/* DOM-IGNORE-END */

#include <stdint.h>
#include "lib_common/AG903_common.h"

#ifdef __cplusplus
extern "C" {
#endif

/** SSPチャンネル数 */
#define AG903_SSP_CH_NUM			(4)

/** データ長 MAX値 [ビット] */
#define AG903_SSP_SDL_MAX			(128)

/** クロック分周比 MIN値 （SSP）*/
#define AG903_SSP_SSPDIV_MIN		(4)

/** クロック分周比 MIN値 （SPI）*/
#define AG903_SSP_SPIDIV_MIN		(2)

/** S/PDIF Uビットレジスタ数 */
#define AG903_SSP_USERBIT_REGMAX	(12)

/** FIFO段数 */
#define AG903_SSP_FIFO_DEPTH		(16)

/** FIFOサイズ */
#define AG903_SSP_FIFO_BITSIZE		(32)

/** フォーマット種別 */
enum _AG903_SspFormatType {
	AG903_SSP_FORMAT_SSP = 0,		/** Texas Instruments Synchronous Serial Port */
	AG903_SSP_FORMAT_SPI,			/** Motorola Serial Peripheral Interface */
	AG903_SSP_FORMAT_MICROWIRE,		/** National Semiconductor MICROWIRE */
	AG903_SSP_FORMAT_I2S,			/** Philips I2S */
	AG903_SSP_FORMAT_RESERVE,		/** reserve */
	AG903_SSP_FORMAT_SPDIF,			/** Sony/Philips Digital Interface Format */
	AG903_SSP_FORMAT_TYPENUM,		/** フォーマット種別数 */
};

/** 処理種別 */
enum _AG903_SspOperationType {
	AG903_SSP_OPM_SLAVE = 0,		/** スレーブ モノラルモード */
	AG903_SSP_OPM_SLAVE_STEREO,		/** スレーブ ステレオモード */
	AG903_SSP_OPM_MASTER,			/** マスタ モノラルモード */
	AG903_SSP_OPM_MASTER_STEREO,	/** マスタ ステレオモード */
	AG903_SSP_OPM_NUM,				/** 処理種別数 */
};

#define AG903_SSP_INTSTS_TFTHIBIT	(1<<3)	/** SSPnIntrStatus TFTHI-bit */
#define AG903_SSP_INTSTS_RFTHIBIT   (1<<2)	/** SSPnIntrStatus RFTHI-bit */
#define AG903_SSP_INTSTS_TFURIBIT   (1<<1)	/** SSPnIntrStatus TFURI-bit */
#define AG903_SSP_INTSTS_RFORIBIT   (1<<0)	/** SSPnIntrStatus RFORI-bit */

/** 制御パラメータ */
typedef struct _AG903_SSPPrmCtrl{
	uint16_t	sclk_div;		/** SCLK divider */
	uint8_t		pdl;			/** Padding data length */
	uint8_t		sdl;			/** Serial data length */
 //	uint8_t		fs_fdbk;		/** FS internal feedback */
 //	uint8_t		sclk_fdbk;		/** SCLK internal feedback */
	uint8_t		spi_fspo;		/** Frame/Sync polarity (SPI) */
	uint8_t		format;			/** Frame format */
	uint8_t		spi_flash;		/** SPI FLASH indicate (SPI)  */
	uint8_t		validity;		/** SPDIF validity (SPDIF)  */
	uint8_t		fsdist;			/** Frame/Sync and data distance (I2S) */
 //	uint8_t		lbm;			/** loopback mode */
	uint8_t		lsb;			/** Bit Sequence indicator (I2S/SPI) */
	uint8_t		fspo;			/** Frame/Sync polarity (I2S) */
	uint8_t		fsjstfy;		/** Data justify (I2S) */
	uint8_t		opm;			/** Operation Mode */
	uint8_t		sclkpo;			/** SCLK polarity (SPI) */
	uint8_t		sclkph;			/** SCLK phase (SPI) */
	uint8_t		reserve;		/** 予約 */
} AG903_SSPPrmCtrl;

/** 制御パラメータ2 */
typedef struct _AG903_SSPPrmCtrl2 {
	uint8_t     fsos;			/** SPIフレーム同期信号の出力ポート (SPI) */
	uint8_t     fs;				/** SPIフレーム同期信号の出力レベル (SPI) */
	uint8_t     txen;			/** 送信機能のイネーブル */
	uint8_t     rxen;			/** 受信機能のイネーブル */
	uint8_t     ssprst;			/** SSPのステートマシンのソフトリセット */
 //	uint8_t     accrst;
 //	uint8_t     acwrst;
	uint8_t     txfclr;			/** 送信FIFOのクリア */
	uint8_t     rxfclr;			/** 受信FIFOのクリア */
	uint8_t     txdoe;			/** 送信データの出力イネーブル */
	uint8_t     sspen;			/** SSPのイネーブル */
} AG903_SSPPrmCtrl2;

/** ステータス */
typedef struct _AG903_SSPPrmStatus{
	uint8_t		txfifo_num;		/** 送信FIFOエントリ数 */
	uint8_t		rxfifo_num;		/** 受信FIFOエントリ数 */
	uint8_t		busy;			/** Busy [true=Busy] */
	uint8_t		txfifo_notfull; /** 送信FIFO Not Full [true=Not Full] */
	uint8_t		rxfifo_full;	/** 受信FIFO Full [true=Full] */
	uint8_t		reserve[3];		/** 予約 */
} AG903_SSPPrmStatus;

	/** 割り込み制御 */
typedef struct _AG903_SSPPrmIntCtrl{
	uint8_t		tfthod;			/** 送信FIFOのしきい値 */
	uint8_t		rfthod;			/** 受信FIFOのしきい値 */
	uint8_t		tfdmaen;		/** 送信DMA要求のイネーブル */
	uint8_t		rfdmaen;		/** 受信DMA要求のイネーブル */
	uint8_t		tfthien;		/** 送信FIFOしきい値割り込みのイネーブル */
	uint8_t		rfthien;		/** 受信FIFOしきい値割り込みのイネーブル */
	uint8_t		tfurien;		/** 送信FIFOアンダーラン割り込みのイネーブル */ 
	uint8_t		rforien;		/** 受信FIFOオーバーラン割り込みのイネーブル */
} AG903_SSPPrmIntCtrl;

void AG903_SSPPrmSetControl(uint8_t ch, AG903_SSPPrmCtrl* param);
void AG903_SSPPrmGetControl2(uint8_t ch, AG903_SSPPrmCtrl2* param);
void AG903_SSPPrmSetControl2(uint8_t ch, AG903_SSPPrmCtrl2* param);
void AG903_SSPPrmEnableOutput(uint8_t ch);
void AG903_SSPPrmDisableOutput(uint8_t ch);
void AG903_SSPPrmEnableTransfer(uint8_t ch);
void AG903_SSPPrmDisableTransfer(uint8_t ch);
void AG903_SSPPrmCheckEnable(uint8_t ch, uint8_t* enable);
void AG903_SSPPrmEnableTxFunc(uint8_t ch);
void AG903_SSPPrmDisbleTxFunc(uint8_t ch);
void AG903_SSPPrmEnableRxFunc(uint8_t ch);
void AG903_SSPPrmDisbleRxFunc(uint8_t ch);
void AG903_SSPPrmGetTxFifoEntry(uint8_t ch, uint8_t* entry);
void AG903_SSPPrmGetRxFifoEntry(uint8_t ch, uint8_t* entry);
void AG903_SSPPrmSetTxFifoThreshold(uint8_t ch, uint8_t val);
void AG903_SSPPrmSetRxFifoThreshold(uint8_t ch, uint8_t val);
void AG903_SSPPrmClearTxFifo(uint8_t ch);
void AG903_SSPPrmClearRxFifo(uint8_t ch);
void AG903_SSPPrmReset(uint8_t ch);
void AG903_SSPPrmSetStatusBit(uint8_t ch, uint32_t status_0, uint32_t status_1);
void AG903_SSPPrmSetUserBit(uint8_t ch, uint8_t offset, uint32_t val);
void AG903_SSPPrmEnableTxInt(uint8_t ch);
void AG903_SSPPrmDisbleTxInt(uint8_t ch);
void AG903_SSPPrmEnableRxInt(uint8_t ch);
void AG903_SSPPrmDisbleRxInt(uint8_t ch);
void AG903_SSPPrmEnableTxDmareq(uint8_t ch);
void AG903_SSPPrmDisableTxDmareq(uint8_t ch);
void AG903_SSPPrmEnableRxDmareq(uint8_t ch);
void AG903_SSPPrmDisableRxDmareq(uint8_t ch);
void AG903_SSPPrmSetData(uint8_t ch, uint32_t val);
void AG903_SSPPrmGetData(uint8_t ch, uint32_t* val);
void AG903_SSPPrmGetStatus(uint8_t ch, AG903_SSPPrmStatus* status);
void AG903_SSPPrmSetIntControl(uint8_t ch, AG903_SSPPrmIntCtrl* param);
void AG903_SSPPrmGetIntControl(uint8_t ch, AG903_SSPPrmIntCtrl* param);
void AG903_SSPPrmGetIntStatus(uint8_t ch, uint32_t* status);


#ifdef __cplusplus
}
#endif
#endif /* _SSPPRM_H_ */
