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

📄 i2s_test.c

📁 s3c6400 ADS下官方测试程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/**************************************************************************************
* 
*	Project Name : S3C6400 Validation
*
*	Copyright 2006 by Samsung Electronics, Inc.
*	All rights reserved.
*
*	Project Description :
*		This software is only for validating functions of the S3C6400.
*		Anybody can use this software without our permission.
*  
*--------------------------------------------------------------------------------------
* 
*	File Name : i2s_test.c
*  
*	File Description : This file implements i2s test functions.
*
*	Author : Sunil,Roe
*	Dept. : AP Development Team
*	Created Date : 2006/12/26
*	Version : 0.1 
* 
*	History
*	- Created(Sunil,Roe 2006/12/26)
*   
**************************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include "def.h"
#include "option.h"
#include "library.h"
#include "sfr6400.h"
#include "system.h"
#include "sysc.h"
#include "gpio.h"
#include "dma.h"
#include "intc.h"
#include "iic.h"
#include "i2s.h"

#define I2S0	0
#define I2S1	1

// global variables
u8 g_ucI2SPortNum;
volatile I2S_oInform	g_oaI2SInform[I2S_CONNUM];
static	DMAC 	oI2SDma;

/*---------------------------------- ISR Routines Definition ---------------------------------*/
void __irq ISR_I2CINT(void);
void __irq ISR_DMARecDone(void);
void __irq ISR_DMAPlayDone(void);
/*---------------------------------- Function Definition ---------------------------------*/
void I2S_Test(void);
bool	I2S_Init(u8);
void I2S_InitPort(u8);
void I2S_ReturnPort(u8);
void I2S_LoopBackTest(void);
void I2S_PlayWaveInPolling(void);
void I2S_PlayWaveInDMA(void);
void I2S_PlayWaveInDMASlave(void);
void I2S_PlayWaveUsingPolling(u8 , u32 *, u32);
void I2S_PlayWaveUsingDMA(u8, u32 *, u32);
void I2S_RecordInPolling(void);
void I2S_RecordUsingPolling(u8 , u32 *, u32);
void I2S_SelectCDCLK(u8, eI2S_CODEC_MODE);
void I2S_SelectPCLK(u8);
void I2S_SelectEXTCLK(u8);
void I2S_SelectEPLL(u8);
void I2S_SelectMPLL(u8);
void I2S_SelectSysExtCLK(u8);
void I2S_RecordSoundViaLineInPlayIt(void);
void I2S_RecordSoundViaMICInPlayIt(void);
void I2S_RecSoundUsingDMA(u8, u8, u32);
u32	I2S_GetBFS(u8);
u32	I2S_GetRFS(u8);

extern void Test_CLKOUT(void) ;
extern void SYSCT_Clock(void);
extern volatile u32		g_iSeed, g_iNum, g_iARMCLK_DIVN_R, g_iHCLKx2_DIVN_R, g_iPCLK_DIVN_R;

/*---------------------------------- Init Functions  ---------------------------------*/
//////////
// Function Name : I2S_Init
// Function Description : This function initializes a certain I2S Port.
// Input : 	uPort - I2S Port Number 
// Output : 	TRUE - Memory Device is reset
//			FALSE - Memory Device is not reset because of ERROR
// Version : v0.1
bool	I2S_Init(u8 ucCon)
{
	u32 uBaseAddress;

	if(ucCon == I2S0)
	{
		uBaseAddress = I2S0_BASE;
		// using DMAC0
#ifdef I2S_NORMAL_DMA		
		g_oaI2SInform[ucCon].ucDMANum		= NUM_DMA0;
		g_oaI2SInform[ucCon].ucDMACon 		= DMA0;
		g_oaI2SInform[ucCon].ucDMATxSrc	= DMA0_I2S0_TX;
		g_oaI2SInform[ucCon].ucDMARxSrc	= DMA0_I2S0_RX;

		SYSC_SelectDMA(eSEL_I2S0_TX, 1);
		SYSC_SelectDMA(eSEL_I2S0_RX, 1);
#else	// I2S_SECURE_DMA
		g_oaI2SInform[ucCon].ucDMANum		= NUM_SDMA0;
		g_oaI2SInform[ucCon].ucDMACon 		= SDMA0;
		g_oaI2SInform[ucCon].ucDMATxSrc	= DMA0_I2S0_TX;
		g_oaI2SInform[ucCon].ucDMARxSrc	= DMA0_I2S0_RX;

		SYSC_SelectDMA(eSEL_I2S0_TX, 0);
		SYSC_SelectDMA(eSEL_I2S0_RX, 0);
#endif
	}
	else if(ucCon == I2S1)
	{
		uBaseAddress = I2S1_BASE;
		// using DMAC1
#ifdef I2S_NORMAL_DMA		
		g_oaI2SInform[ucCon].ucDMANum		= NUM_DMA1;
		g_oaI2SInform[ucCon].ucDMACon 		= DMA1;
		g_oaI2SInform[ucCon].ucDMATxSrc	= DMA1_I2S1_TX;		
		g_oaI2SInform[ucCon].ucDMARxSrc	= DMA1_I2S1_RX;

		SYSC_SelectDMA(eSEL_I2S1_TX, 1);
		SYSC_SelectDMA(eSEL_I2S1_RX, 1);
#else
		g_oaI2SInform[ucCon].ucDMANum		= NUM_SDMA1;
		g_oaI2SInform[ucCon].ucDMACon 		= SDMA1;
		g_oaI2SInform[ucCon].ucDMATxSrc	= DMA1_I2S1_TX;		
		g_oaI2SInform[ucCon].ucDMARxSrc	= DMA1_I2S1_RX;

		SYSC_SelectDMA(eSEL_I2S1_TX, 0);
		SYSC_SelectDMA(eSEL_I2S1_RX, 0);
#endif
	}
	else
	{
		return FALSE;
	}


	I2S_SetBaseAddr(ucCon, uBaseAddress);	
	g_oaI2SInform[ucCon].puRecBuf = (u32 *)(_DRAM_BaseAddress+0x01000000*(ucCon+1));
	
	I2S_InitPort(ucCon);
	
	return TRUE;
}


//////////
// Function Name : I2S_InitPort
// Function Description : 
//   This function Initialize ports as I2S.
// Input : uPort - I2S port number
// Output : NONE
// Version : 
void I2S_InitPort(u8 ucPort)
{
	switch(ucPort)
	{
		case 0 :
			GPIO_SetFunctionAll(eGPIO_D, 0x33333, 0x0);
			GPIO_SetPullUpDownAll(eGPIO_D, 0x22222);			// pull-up/down disable
			break;
		case 1 :
			GPIO_SetFunctionAll(eGPIO_E, 0x33333, 0x0);
			GPIO_SetPullUpDownAll(eGPIO_E, 0x22222);			// pull-up/down disable
			break;
		default :
			GPIO_SetFunctionAll(eGPIO_D, 0x33333, 0x0);
			GPIO_SetPullUpDownAll(eGPIO_D, 0x22222);			// pull-up/down disable
			break;
	}
}

//////////
// Function Name : I2S_ReturnPort
// Function Description : 
//   This function Initialize ports as default GPIO(input).
// Input : uPort - I2S port number
// Output : NONE
// Version : 
void I2S_ReturnPort(u8 ucPort)
{
	switch(ucPort)
	{
		case 0 :
			GPIO_SetFunctionAll(eGPIO_D, 0x0, 0x0);
			break;
		case 1 :
			GPIO_SetFunctionAll(eGPIO_E, 0x0, 0x0);
			break;
		default :
			GPIO_SetFunctionAll(eGPIO_D, 0x0, 0x0);
			break;
	}
}

//////////
// Function Name : I2S_Init8753
// Function Description : 
//   This function prepares the initialization of WM8753
// Input : 
//		ucPort	- I2S Port Number
//		ucMode	- I2S Operation Mode
//		ucStatus	-I2S Operation Status
// Output : NONE
// Version : 
void I2S_Init8753(u8 ucPort, u8 ucMode, u8 ucStatus, eI2S_CODEC_MODE eCodecMode)
{
	IIC_Open(100000);
	I2S_Init8753Driver(ucPort, ucMode, ucStatus, eCodecMode);
	IIC_Close();
}

/*---------------------------------- ISR Routines ---------------------------------*/
//////////
// Function Name : ISR_DMA1INTRecDone
// Function Description : This function implements ISR of DMA Record Interrupt.
// Input : 	NONE
// Output : 	NONE
// Version : v0.1
void __irq ISR_DMARecDone(void)
{
	INTC_Disable(g_oaI2SInform[g_ucI2SPortNum].ucDMANum);

	// Interrupt Clear
	DMACH_ClearIntPending(&oI2SDma);
	DMACH_ClearErrIntPending(&oI2SDma);

	I2S_SetDMAActive(g_ucI2SPortNum, eI2S_XFER_RX, INACTIVE);
	I2S_SetActive(g_ucI2SPortNum, INACTIVE);

	g_oaI2SInform[g_ucI2SPortNum].uRecCount++;
	Disp(".");
#if 0
	I2S_SetDMAActive(g_ucI2SPortNum, eI2S_XFER_RX, ACTIVE);
	I2S_SetActive(g_ucI2SPortNum, ACTIVE);

	if(g_oaI2SInform[g_ucI2SPortNum].uRecCount < I2S_DMAC0_REC_COUNT)
	{
		DMACH_Setup(DMA_A, 0x0, I2S_GetRegAddr(g_ucI2SPortNum,eI2S_TXD), 1, (u32)(g_oaI2SInform[g_ucI2SPortNum].puRecBuf + I2S_RECORD_LENGTH), 0, WORD, I2S_DMA_TRANSFER_SIZE, DEMAND, (DREQ_SRC)(g_oaI2SInform[g_ucI2SPortNum].ucDMATxSrc), MEM, SINGLE, &oI2SDma);
		INTC_Enable(g_oaI2SInform[g_ucI2SPortNum].ucDMANum);
	}
	else
	{
		g_oaI2SInform[g_ucI2SPortNum].ucRecDone = 1;
	}
	INTC_Enable(g_oaI2SInform[g_ucI2SPortNum].ucDMANum);
#endif

	g_oaI2SInform[g_ucI2SPortNum].ucRecDone = 1;

	INTC_ClearVectAddr();
}

//////////
// Function Name : ISR_DMA1INTPlayDone
// Function Description : This function implements ISR of DMA Play Interrupt.
// Input : 	NONE
// Output : 	NONE
// Version : v0.1
void __irq ISR_DMAPlayDone(void)
{
	Disp("\n TX DMA ISR ~~~\n");
	INTC_Disable(g_oaI2SInform[g_ucI2SPortNum].ucDMANum);

	// Interrupt Clear
	DMACH_ClearIntPending(&oI2SDma);
	DMACH_ClearErrIntPending(&oI2SDma);
#if 0
	I2S_SetDMAActive(g_ucI2SPortNum, eI2S_XFER_TX, INACTIVE);
	I2S_SetActive(g_ucI2SPortNum, INACTIVE);

	I2S_SetDMAActive(g_ucI2SPortNum, eI2S_XFER_TX, ACTIVE);
	I2S_SetActive(g_ucI2SPortNum, ACTIVE);
#else
//	DMACH_Setup(DMA_B, 0x0, (u32)ucStartAddr , 0, I2S_GetRegAddr(ucCon,eI2S_TXD), 1, WORD, I2S_RECORD_LENGTH/4, DEMAND, MEM, (DREQ_SRC)(g_oaI2SInform[ucCon].ucDMATxSrc), SINGLE, &oI2SDma);
//	DMACH_AddrSetup(DMA_B,  (u32)g_oaI2SInform[g_ucI2SPortNum].puRecBuf, I2S_GetRegAddr(g_ucI2SPortNum,eI2S_TXD), &oI2SDma);
	DMACH_Setup(DMA_B, 0x0, (u32)g_oaI2SInform[g_ucI2SPortNum].puRecBuf, 0, I2S_GetRegAddr(g_ucI2SPortNum,eI2S_TXD), 1, WORD, g_oaI2SInform[g_ucI2SPortNum].uRecLength, DEMAND, MEM, (DREQ_SRC)(g_oaI2SInform[g_ucI2SPortNum].ucDMATxSrc), SINGLE, &oI2SDma);
#endif
	Disp("\n TX DMA Done ~~~\n");
	DMACH_Start(&oI2SDma);
		
	I2S_SetActive(g_ucI2SPortNum, INACTIVE);
	I2S_SetActive(g_ucI2SPortNum, ACTIVE);

	INTC_Enable(g_oaI2SInform[g_ucI2SPortNum].ucDMANum);

	INTC_ClearVectAddr();

}

/*---------------------------------- Test Functions -------------------------------*/
//////////
// Function Name : I2S_LoopBackTest
// Function Description : 
//   This function implements I2S Loopback Test function.

//	To execute this test, SMDK6400 must be modified.
//	After eliminating U32 and U35 on the bottom plate, I2S signal line should be connected directly.
//			U32					U35
//		pin3  (BCLK)			pin3  (BCLK)
//		pin7  (CDCLK)			pin7  (CDCLK)  --> These signal should be connected to R249.(Ext.Clock)
//		pin11(LRCK)			pin11(LRCK)
//		pin17(DI)				pin21(DO)
//		pin21(DO)			pin17(DI)
//		
//		Master - I2S0 (Master sends LRCK and BCLK to Slave port.)
//		Slave  - I2S1
//		CDCLK - External Clock
// Input : NONE
// Output : NONE
// Version : 
void I2S_LoopBackTest(void)
{
	u32	uLoopCnt = 0;
	u8 	ucExitKey=0;
	u8	ucCODECLK=0;
	u8	ucBCLK=0;
	u8	ucBLTH=0;
	u32	uCODECFS = 0;
	u32	uBCLKFS	= 0;

	u32 uPcmTxDataSize = 0xC00;
	u32 uPcmRxDataSize = 0xC00;
	u32 uRegValue = 0;
	
	Disp("\n = Loop Back Test =.\n");
	Disp(" Note. To execute this test, SMDK6400 must be modified.\n");
	Disp("    After eliminating U32 and U35 on the bottom plate, I2S signal line should be connected directly.\n");
	
	I2S_FlushFIFO(I2S0, eI2S_FLUSH_TX, FLUSH);
	I2S_FlushFIFO(I2S0, eI2S_FLUSH_TX, NON_FLUSH);

	I2S_FlushFIFO(I2S1, eI2S_FLUSH_RX, FLUSH);
	I2S_FlushFIFO(I2S1, eI2S_FLUSH_RX, NON_FLUSH);

	// Set up the tx buf.
	for (uLoopCnt = 0; uLoopCnt<uPcmTxDataSize; uLoopCnt++)
		*(u8 *)((u8 *)g_oaI2SInform[I2S0].puRecBuf+uLoopCnt) = (u8)(uLoopCnt+2)%0xff;
	// Clear the rx buf.
	for (uLoopCnt = 0; uLoopCnt<uPcmRxDataSize; uLoopCnt++)
		*(u8 *)((u8 *)g_oaI2SInform[I2S1].puRecBuf+uLoopCnt) = 0;

	// select freq.
	Disp("\n Root Frequency Sample ( 0:256fs    1:512fs    2:384fs(D)    3:768fs ) = ");
 	ucCODECLK = GetIntNum(); 
	if (ucCODECLK == 0xff ) ucCODECLK = 2;
	uCODECFS	= I2S_GetRFS(ucCODECLK);
	
	Disp("\n Bit Frequency Sample (0:32fs    1:48fs(D)    2:16fs    3:24fs) = ");
	ucBCLK = GetIntNum(); 
	if (ucBCLK == 0xff ) ucBCLK = 1;
	uBCLKFS		= I2S_GetBFS(ucBCLK);
	
	Disp("\n BLC (0: 16bit(D)    1:8bit ) = ");
	ucBLTH = GetIntNum(); 
	if (ucBLTH == 0xff ) ucBLTH = 0;
	
	Disp("\nuBCLKFS:%d, uCODECFS:%d", uBCLKFS, uCODECFS);
	Disp("\nI2S Bit Clock = %4.4f MHz", g_oaI2SInform[g_ucI2SPortNum].fI2SCodecCLK*uBCLKFS/uCODECFS/1000000);
	Disp("\nI2S Sampling Rate = %4.4f kHz\n", g_oaI2SInform[g_ucI2SPortNum].fI2SCodecCLK/uCODECFS/1000);

	//------------ Master Configuration ------------
	I2S_SelectCDCLK(I2S0, eI2S_CODEC_SLAVE_MODE);

	// rI2SCON : TxDMA
	I2S_SetI2STxerMode(I2S0, eI2S_XFER_TX);
	// rI2SMOD : TxOnlyMode, I2SRootClk, BitClk, BitLength
	I2S_SetInterfaceMode(I2S0, eI2S_XFER_TX, eLEFT_LOW_RIGHT_HIGH, eI2S_DATA_I2S, ucCODECLK, ucBCLK, ucBLTH);
	
	I2S_FlushFIFO(I2S0, eI2S_FLUSH_TX, FLUSH);		// rI2SFIC : TxFIFO Flush(15)	
	I2S_FlushFIFO(I2S0, eI2S_FLUSH_TX, NON_FLUSH);	// rI2SFIC : TxFIFO No Flush(15)
	
	//------------ Slave Configuration ------------
	//IIS Pre-scaler Setting
	I2S_SetPreScaler(I2S1, ENABLE, 2);
	// IIS CDCLKCON
	I2S_SetCodecClkSrc(I2S1, eI2S_CLK_EXTERNAL);
	//IIS Master mode selection
	I2S_SetMasterSlaveMode(I2S1, eI2S_MS_SLAVE_MODE_USING_PCLK);
	// rI2SCON : RxDMA
	I2S_SetI2STxerMode(I2S1, eI2S_XFER_RX);
	// rI2SMOD : RxOnlyMode, I2SRootClk, BitClk, BitLength
	I2S_SetInterfaceMode(I2S1, eI2S_XFER_RX, eLEFT_LOW_RIGHT_HIGH, eI2S_DATA_I2S, ucCODECLK, ucBCLK, ucBLTH);
	
	I2S_FlushFIFO(I2S1, eI2S_FLUSH_RX, FLUSH);		// rI2SFIC : RxFIFO Flush(7)	
	I2S_FlushFIFO(I2S1, eI2S_FLUSH_RX, NON_FLUSH);	// rI2SFIC : RxFIFO No Flush(7)

	//----Step 1. Data should be transmitted from I2S0 to I2S1 in 16 times before I2S0 is activated.
	uRegValue = I2S_GetRegValue(I2S0, eI2S_CON);
	while(!(uRegValue&(1<<8))) {
		I2S_SetRegValue(I2S0, eI2S_TXD, *g_oaI2SInform[I2S0].puRecBuf++);

⌨️ 快捷键说明

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