⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s3c6400_iis_interface.c

📁 Samsung公司S3C6400芯片的BSP源码包
💻 C
字号:
#include <windows.h>
#include <bsp_cfg.h>
#include <s3c6400.h>
#include "s3c6400_iis_interface_macro.h"
#include "s3c6400_iis_interface.h"

#ifdef	REMOVE_BEFORE_RELEASE
#define IIS_MSG(x)
#define IIS_INF(x)
#define IIS_ERR(x)	RETAILMSG(TRUE, x)
#else
#define IIS_MSG(x)	RETAILMSG(TRUE, x)
//#define IIS_MSG(x)
#define IIS_INF(x)	RETAILMSG(TRUE, x)
//#define IIS_INF(x)
#define IIS_ERR(x)	RETAILMSG(TRUE, x)
//#define IIS_ERR(x)
#endif

#define DELAY_LOOP_COUNT	(S3C6400_FCLK/100000)
#define CONTROL_DELAY		(10)
#define CMD_DELAY			(3)

static volatile S3C6400_GPIO_REG * g_pGPIOReg = NULL;
static volatile S3C6400_IIS_REG * g_pIISReg = NULL;

IIS_ERROR IIS_initialize_register_address(void *pIISReg, void *pGPIOReg)
{
	IIS_ERROR error = IIS_SUCCESS;

	IIS_MSG((_T("[IIS]++IIS_initialize_register_address(0x%08x, 0x%08x)\n\r"), pIISReg, pGPIOReg));

	if (pIISReg == NULL || pGPIOReg == NULL)
	{
		IIS_ERR((_T("[IIS:ERR] IIS_initialize_register_address() : NULL pointer parameter\n\r")));
		error = IIS_ERROR_NULL_PARAMETER;
	}
	else
	{
		g_pIISReg = (S3C6400_IIS_REG *)pIISReg;
		g_pGPIOReg = (S3C6400_GPIO_REG *)pGPIOReg;
		IIS_INF((_T("[IIS:INF] g_pIISReg = 0x%08x\n\r"), g_pIISReg));
		IIS_INF((_T("[IIS:INF] g_pGPIOReg = 0x%08x\n\r"), g_pGPIOReg));
	}

	IIS_MSG((_T("[IIS]--IIS_initialize_register_address() : %d\n\r"), error));

	return error;
}

void IIS_initialize_interface(void)
{
	IIS_MSG((_T("[IIS] ++IIS_initialize_interface()\n\r")));

	IIS_set_active_off();

	// Initialize IIS Interface
	IIS_port_initialize(IIS_CH_0);

#if	1	// Sampling Rate 44.1 KHz with EPLL 84,666,667 Hz
	// Configurre IIS clock prescale value
	IIS_set_prescale_value(4);			// EPLL Fout/(4+1) = 84,666,667 Hz / 5 = 16,933,334 Hz
	IIS_set_prescale_enable();

	// Flush IIS fifo
	IIS_fifo_flush(IIS_TX_FIFO_FLUSH);
	IIS_fifo_flush(IIS_TX_FIFO_NOFLUSH);
	IIS_fifo_flush(IIS_RX_FIFO_FLUSH);
	IIS_fifo_flush(IIS_RX_FIFO_NOFLUSH);

	//
	IIS_set_transfer_mode(IIS_TRANSFER_TX);

	//rI2SMOD : TxOnlyMode, I2SRootClk, BitClk, BitLength
	//IIS_set_interface_mode(ISS_TRANSFER_TX, eLEFT_LOW_RIGHT_HIGH, eI2S_DATA_I2S, ucCODECLK, ucBCLK, ucBLTH);

	IIS_set_interface_codec_clock_source(IIS_INTERNEL_CDCLK);
	IIS_set_interface_master_slave_mode(IIS_MASTER_BYPASS_MODE);
	IIS_set_interface_tranmit_receive_mode(IIS_TRANSFER_BOTH);
	IIS_set_interface_clock_polarity(LOW_FOR_LEFT);
	IIS_set_interface_serial_data_format(IIS_FORMAT);
	IIS_set_interface_codec_clock_frequency(IIS_CODEC_CLOCK_384FS);
	IIS_set_interface_bit_clock_frequency(IIS_BIT_CLOCK_32FS);
	IIS_set_interface_bit_length(IIS_BIT_LENGTH_16BIT);
#else
	// Configurre IIS clock prescale value
	IIS_set_prescale_value(1);
	IIS_set_prescale_enable();

	// Flush IIS fifo
	IIS_fifo_flush(IIS_TX_FIFO_FLUSH);
	IIS_fifo_flush(IIS_TX_FIFO_NOFLUSH);
	IIS_fifo_flush(IIS_RX_FIFO_FLUSH);
	IIS_fifo_flush(IIS_RX_FIFO_NOFLUSH);

	//
	IIS_set_transfer_mode(IIS_TRANSFER_TX); //IIS_TRANSFER_TX);

	//rI2SMOD : TxOnlyMode, I2SRootClk, BitClk, BitLength
	//IIS_set_interface_mode(ISS_TRANSFER_TX, eLEFT_LOW_RIGHT_HIGH, eI2S_DATA_I2S, ucCODECLK, ucBCLK, ucBLTH);

	IIS_set_interface_codec_clock_source(IIS_TRANSFER_BOTH); //IIS_TRANSFER_BOTH);
	IIS_set_interface_master_slave_mode(IIS_MASTER_DIVIDE_MODE);
	IIS_set_interface_tranmit_receive_mode(IIS_TRANSFER_BOTH); //IIS_TRANSFER_BOTH
	IIS_set_interface_clock_polarity(LOW_FOR_LEFT);
	IIS_set_interface_serial_data_format(IIS_FORMAT);
	IIS_set_interface_codec_clock_frequency(IIS_CODEC_CLOCK_384FS);
	IIS_set_interface_bit_clock_frequency(IIS_BIT_CLOCK_32FS);
	IIS_set_interface_bit_length(IIS_BIT_LENGTH_16BIT);
#endif

	IIS_MSG((_T("[IIS] --IIS_initialize_interface()\n\r")));
}

unsigned int IIS_get_output_physical_buffer_address(IIS_CHANNEL mChannel)
{
	unsigned int m_physical_buffer_address = 0;
	if (mChannel == IIS_CH_0) m_physical_buffer_address = (unsigned int)(0x7F002010);
	if (mChannel == IIS_CH_1) m_physical_buffer_address = (unsigned int)(0x7F003010);
	return m_physical_buffer_address;
}

unsigned int IIS_get_input_physical_buffer_address(IIS_CHANNEL mChannel)
{
	unsigned int m_physical_buffer_address = 0;
	if (mChannel == IIS_CH_0) m_physical_buffer_address = (unsigned int)(0x7F002014);
	if (mChannel == IIS_CH_1) m_physical_buffer_address = (unsigned int)(0x7F003014);
	return m_physical_buffer_address;
}

PRIVATE void IIS_port_initialize(IIS_CHANNEL mChnNum)
{
	IIS_MSG((_T("[IIS] IIS_port_initialize()\n\r")));

	ASSERT( (mChnNum == IIS_CH_0) || (mChnNum == IIS_CH_1));

	// IIS CLK		: GPD[0], GPE[0]
	// IIS CDCLK	: GPD[1], GPE[1]
	// IIS LRCLK	: GPD[2], GPE[2]
	// IIS DI		: GPD[3], GPE[3]
	// IIS DO		: GPD[4], GPE[4]

	if (mChnNum == IIS_CH_0)
	{
		// IIS CH 0 Use GPD Port
		g_pGPIOReg->GPDPUD &= ~(0x3ff);	// Pull-Up/Down Disable
		g_pGPIOReg->GPDCON = 0x33333; 		// GPD -> IIS
	}
	else if (mChnNum == IIS_CH_1)
	{
		// IIS CH 1 Use GPE Port
		g_pGPIOReg->GPEPUD &= ~(0x3ff);	// Pull-Up/Down Disable
		g_pGPIOReg->GPECON = 0x33333; 		// GPD -> IIS
	}

}

PRIVATE void IIS_set_prescale_value(DWORD mPrescaleValue)
{
	mPrescaleValue = mPrescaleValue & PRESCALER_A_DIVISION_VALUE_MASK; // PSVALA[9:0]

	IIS_MSG((_T("[IIS] Prescale Value = %d\r\n"), mPrescaleValue));
	IIS_MSG((_T("[IIS] Masked Prescale Value = %d\r\n"), (mPrescaleValue&PRESCALER_A_DIVISION_VALUE_MASK)));

	g_pIISReg->IISPSR = (g_pIISReg->IISPSR & ~(PRESCALER_A_DIVISION_VALUE_MASK<<PRESCALER_A_DIVISION_VALUE_SHIFT));
	g_pIISReg->IISPSR |= (mPrescaleValue<<PRESCALER_A_DIVISION_VALUE_SHIFT);
}

PRIVATE void IIS_set_prescale_enable()
{
	IIS_MSG((_T("[IIS] Prescale Enabled\r\n")));

	g_pIISReg->IISPSR |= PRESCALER_A_ACTIVE;
}

PRIVATE void IIS_set_prescale_disable()
{
	IIS_MSG((_T("[IIS] Prescale Disabled\r\n")));

	g_pIISReg->IISPSR &= ~(PRESCALER_A_ACTIVE);
}


PRIVATE void IIS_fifo_flush(IIS_FIFO_FLUSH mFlushMode)
{
	ASSERT( mFlushMode <= IIS_RX_FIFO_NOFLUSH );

	IIS_MSG((_T("[IIS] FIFO Flush Mode [%d] -> [%s][%s]\r\n"), mFlushMode,
		((mFlushMode/2)? _T("RX") : _T("TX")), ((mFlushMode%2)? _T("NOFLUSH") : _T("FLUSH"))));

	switch(mFlushMode)
	{
		case IIS_TX_FIFO_FLUSH: g_pIISReg->IISFIC |= (TX_FIFO_FLUSH); break;
		case IIS_TX_FIFO_NOFLUSH: g_pIISReg->IISFIC &= ~(TX_FIFO_FLUSH); break;
		case IIS_RX_FIFO_FLUSH: g_pIISReg->IISFIC |= (RX_FIFO_FLUSH); break;
		case IIS_RX_FIFO_NOFLUSH: g_pIISReg->IISFIC &= ~(RX_FIFO_FLUSH); break;
		default: break;
	}
}

PRIVATE void IIS_set_transfer_mode(IIS_TRANSFER_MODE mTransferMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_transfer_mode [%d]\r\n"), mTransferMode));

	uRegValue = g_pIISReg->IISCON & ~(TX_MOD_MASK|RX_MOD_MASK);

	// IISCON : TxDMAPause(6), RxDMAPause(5), TxCHPause(4), RxCHPause(3), TxDMAActive(2), RxDMAActive(1)
	switch(mTransferMode)
	{
		case IIS_TRANSFER_TX :
			uRegValue = uRegValue |(TX_DMA_NOPAUSE) | (RX_DMA_PAUSE) | (TX_CHANNEL_NOPAUSE) | (RX_CHANNEL_PAUSE) | (TX_DMA_ACTIVE) | (RX_DMA_INACTIVE);
			break;
		case IIS_TRANSFER_RX :
			uRegValue = uRegValue | (TX_DMA_PAUSE) | (RX_DMA_NOPAUSE) | (TX_CHANNEL_PAUSE) | (RX_CHANNEL_NOPAUSE) | (TX_DMA_INACTIVE) | (RX_DMA_ACTIVE);
			break;
		case IIS_TRANSFER_BOTH :
			uRegValue = uRegValue | (TX_DMA_NOPAUSE) | (RX_DMA_NOPAUSE) | (TX_CHANNEL_NOPAUSE) | (RX_CHANNEL_NOPAUSE) | (TX_DMA_ACTIVE) | (RX_DMA_ACTIVE);
			break;
		default :
			break;
	}

	g_pIISReg->IISCON = uRegValue;
}

void IIS_set_tx_mode_control(IIS_TRANSFER_PAUSE_CONTROL mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_tx_mode_control [%d]\r\n"), mMode));

	uRegValue = g_pIISReg->IISCON & ~(TX_MOD_MASK);

	switch(mMode)
	{
		case IIS_TRANSFER_NOPAUSE :
			uRegValue = uRegValue |(TX_DMA_NOPAUSE) | (TX_CHANNEL_NOPAUSE) | (TX_DMA_ACTIVE);
			break;
		case IIS_TRANSFER_PAUSE :
			uRegValue = uRegValue | (TX_DMA_PAUSE) | (TX_CHANNEL_PAUSE) | (TX_DMA_INACTIVE);
			break;
		default :
			break;
	}

	g_pIISReg->IISCON = uRegValue;
}

void IIS_set_rx_mode_control(IIS_TRANSFER_PAUSE_CONTROL mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_rx_mode_control [%d]\r\n"), mMode));

	uRegValue = g_pIISReg->IISCON & ~(RX_MOD_MASK);

	switch(mMode)
	{
		case IIS_TRANSFER_NOPAUSE :
			uRegValue = uRegValue | (RX_DMA_NOPAUSE) | (RX_CHANNEL_NOPAUSE) | (RX_DMA_ACTIVE);
			break;
		case IIS_TRANSFER_PAUSE :
			uRegValue = uRegValue | (RX_DMA_PAUSE) | (RX_CHANNEL_PAUSE) | (RX_DMA_INACTIVE);
			break;
		default :
			break;
	}

	g_pIISReg->IISCON = uRegValue;
}


PRIVATE void IIS_set_interface_codec_clock_source(IIS_CODEC_CLOCK_MODE mCodecClockSource)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_mode_codec_clock_source(%d)\r\n"), mCodecClockSource));

	uRegValue = (g_pIISReg->IISMOD & ~(CODEC_CLOCK_SOURCE_MASK));
	if (mCodecClockSource == IIS_INTERNEL_CDCLK) uRegValue |= CODEC_CLK_USE_INTERNEL_CLK;
	if (mCodecClockSource == IIS_EXTERNEL_CDCLK) uRegValue |= CODEC_CLK_USE_EXTERNEL_CLK;
	g_pIISReg->IISMOD = uRegValue;
}

PRIVATE void IIS_set_interface_master_slave_mode(IIS_MASTER_SLAVE_MODE mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_master_slave_mode(%d)\r\n"), mMode));

	uRegValue = (g_pIISReg->IISMOD & ~(IIS_CLK_MASTER_SLAVE_MASK));
	if (mMode == IIS_MASTER_DIVIDE_MODE) uRegValue |= IIS_CLK_MASTER_PCLK_DIV_MODE;
	if (mMode == IIS_MASTER_BYPASS_MODE) uRegValue |= IIS_CLK_MASTER_IISCLK_BYPASS_MODE;
	if (mMode == IIS_SLAVE_MODE) uRegValue |= IIS_CLK_SLAVE_MODE;

	g_pIISReg->IISMOD = uRegValue;
}

PRIVATE void IIS_set_interface_tranmit_receive_mode(IIS_TRANSFER_MODE mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_tranmit_receive_mode(%d)\r\n"), mMode));

	uRegValue = (g_pIISReg->IISMOD & ~(TRANSFER_MODE_MASK));
	if (mMode == IIS_TRANSFER_TX) uRegValue |= TRANSFER_MODE_TX_ONLY;
	if (mMode == IIS_TRANSFER_RX) uRegValue |= TRANSFER_MODE_RX_ONLY;
	if (mMode == IIS_TRANSFER_BOTH) uRegValue |= TRANSFER_MODE_BOTH;

	g_pIISReg->IISMOD = uRegValue;
}

PRIVATE void IIS_set_interface_clock_polarity(IIS_CLOCK_POLARITY mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_clock_polarity(%d)\r\n"), mMode));

	uRegValue = (g_pIISReg->IISMOD & ~(LR_CH_POL_MASK));
	if (mMode == LOW_FOR_LEFT) uRegValue |= LR_CH_POL_LOW_FOR_LEFT_HIGH_FOR_RIGHT;
	if (mMode == HIGH_FOR_LEFT) uRegValue |= LR_CH_POL_HIGH_FOR_LEFT_LOW_FOR_RIGHT;

	g_pIISReg->IISMOD = uRegValue;
}

PRIVATE void IIS_set_interface_serial_data_format(IIS_DATA_FORMAT mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_serial_data_format(%d)\r\n"), mMode));

	uRegValue = (g_pIISReg->IISMOD & ~(SERIAL_DATA_FORMAT_MASK));
	if (mMode == IIS_FORMAT) uRegValue |= SERIAL_DATA_FORMAT_IIS;
	if (mMode == MSB_JUSTIFIED_FORMAT) uRegValue |= SERIAL_DATA_FORMAT_MSB_JUSTIFIED;
	if (mMode == LSB_JUSTIFIED_FORMAT) uRegValue |= SERIAL_DATA_FORMAT_LSB_JUSTIFIED;

	g_pIISReg->IISMOD = uRegValue;
}

PRIVATE void IIS_set_interface_codec_clock_frequency(IIS_CODEC_CLOCK_MODE mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_codec_clock_frequency(%d)\r\n"), mMode));

	uRegValue = (g_pIISReg->IISMOD & ~(IIS_CODEC_CLOCK_FREQUENCY_MASK));
	if (mMode == IIS_CODEC_CLOCK_256FS) uRegValue |= IIS_CODEC_CLOCK_FREQUENCY_256FS;
	if (mMode == IIS_CODEC_CLOCK_512FS) uRegValue |= IIS_CODEC_CLOCK_FREQUENCY_512FS;
	if (mMode == IIS_CODEC_CLOCK_384FS) uRegValue |= IIS_CODEC_CLOCK_FREQUENCY_384FS;
	if (mMode == IIS_CODEC_CLOCK_768FS) uRegValue |= IIS_CODEC_CLOCK_FREQUENCY_768FS;

	g_pIISReg->IISMOD = uRegValue;
}

PRIVATE void IIS_set_interface_bit_clock_frequency(IIS_BIT_CLOCK_MODE mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_bit_clock_frequency(%d)\r\n"), mMode));

	uRegValue = (g_pIISReg->IISMOD & ~(BIT_CLOCK_FREQUENCY_MASK));
	if (mMode == IIS_BIT_CLOCK_32FS) uRegValue |= BIT_CLOCK_FREQUENCY_32FS;
	if (mMode == IIS_BIT_CLOCK_48FS) uRegValue |= BIT_CLOCK_FREQUENCY_48FS;
	if (mMode == IIS_BIT_CLOCK_16FS) uRegValue |= BIT_CLOCK_FREQUENCY_16FS;
	if (mMode == IIS_BIT_CLOCK_24FS) uRegValue |= BIT_CLOCK_FREQUENCY_24FS;

	g_pIISReg->IISMOD = uRegValue;
}

PRIVATE void IIS_set_interface_bit_length(IIS_BIT_LENGTH mMode)
{
	DWORD uRegValue = 0;

	IIS_MSG((_T("[IIS] IIS_set_interface_bit_length(%d)\r\n"), mMode));

	uRegValue = (g_pIISReg->IISMOD & ~(BIT_LENGTH_PER_CHANNEL_MASK));
	if (mMode == IIS_BIT_LENGTH_16BIT) uRegValue |= BIT_LENGTH_PER_CHANNEL_16BIT;
	if (mMode == IIS_BIT_LENGTH_8BIT) uRegValue |= BIT_LENGTH_PER_CHANNEL_8BIT;

	g_pIISReg->IISMOD = uRegValue;
}


PRIVATE void IIS_set_active_on(void)
{
	IIS_MSG((_T("[IIS] IIS_set_active_on()\n\r")));

	if (g_pIISReg->IISCON & IIS_ACTIVE)
		IIS_MSG((_T("IIS is already active\r\n")));
	else
		g_pIISReg->IISCON |= IIS_ACTIVE;
}

PRIVATE void IIS_set_active_off(void)
{
	IIS_MSG((_T("[IIS] IIS_set_active_off()\n\r")));

	g_pIISReg->IISCON &= ~IIS_ACTIVE;
}

PRIVATE void DelayLoop(unsigned int count)
{
	volatile int i, j=0;

	for(;count > 0;count--)
		for(i=0;i < DELAY_LOOP_COUNT; i++) { j++; }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -