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

📄 iis_dual.c

📁 s3c24a0固件测试代码 ? ? ? ? ?啊 
💻 C
字号:
/*************************************************
  NAME: iis_dual.c
  DESC: S3C2410 IIS (UDA1341) simultaneous record & play test 
  HISTORY:
  OCT.17.2002:purnnamu: first release
  NOV.05.2002:purnnamu: Rec start/stop randomly.
  APR.01.2003:ky.shim: minor modification.
  MAY.08.2003:ky.shim: migration to S3C24A0X
 *************************************************/

#include <math.h>
#include <stdlib.h>
 
#include "24a0addr.h"
#include "24a0lib.h"
#include "def.h"
#include "iis.h"
//#include "iis_dual.h"

//declarations of some functions in iis.c
void IIS_PortSetting(void);
void _WrL3Addr(U8 data);
void _WrL3Data(U8 data,int halt);


void Init1341RecPlay(void);

void AudioInit(void);
void AudioBufCopy(void);
void AudioInStart(void);
void AudioInStop(void);
void AudioOutStart(void);
void AudioOutStop(void);
void AudioOutRandom(void);

void __irq IsrAudioInOut(void);
void __irq IsrAudioMute(void);

void InterruptLatencyStart(void);
void InterruptLatencyStop(void);
void __irq IsrTimer0_InterruptLatency(void);


#define MAX_INDEX_AUDIO_BUF	(200)    
#define AUDIO_BUF_SIZE		(1000)	 //500 stereo samples

U16 (*playBuf)[AUDIO_BUF_SIZE];
U16 (*recBuf)[AUDIO_BUF_SIZE];
volatile int indexPlayBuf,indexRecBuf;
volatile int stopPlay,stopRec;
volatile int audioOutActive,audioInActive;


//**************************************************
//                     IIS test
//**************************************************

void Test_IisRecPlay(void)
{
	
    int i;
    int ranPlay=FALSE;
    char key;
    
    srand(0);

    Uart_Printf("[ IIS (Master Mode,Rec&Play) Test(UDA1341) ]\n");
    Uart_TxEmpty(0);
    ChangeMPllValue(82,4,1);  //FCLK=90.316800MHz, PCLK=45.158400MHz <-- 5.644800MHz*8
    ChangeClockDivider(0,1);		  // 1:1:2    
    ChangeSdramParameter(HCLK);   
    Uart_Init(45158400,115200);

    IIS_PortSetting();
    Init1341RecPlay();
    
    playBuf=(U16 (*)[AUDIO_BUF_SIZE])0x11000000;
    recBuf = (U16 (*)[AUDIO_BUF_SIZE])(0x11000000+sizeof(U16)*AUDIO_BUF_SIZE*MAX_INDEX_AUDIO_BUF);
    
    indexPlayBuf=indexRecBuf=0;
    audioOutActive=audioInActive=FALSE;
    stopPlay=stopRec=FALSE;
    
    //for(i=0x31000000;i<0x31100000;i+=4)*((U32 *)i)=0;
    
    AudioInit();
    pISR_DMA  = (U32)IsrAudioInOut;
    pISR_EINT0_2 = (U32)IsrAudioMute;
        
    Uart_Printf("If you want to mute or no mute push the 'EIN9' key repeatedly\n");
    Uart_Printf("Sampling Frequency = %d Hz\n",22050);

    // Clear Int Pending and Unmask    
    ClearPending(BIT_EINT0_2);    
    rINTMSK    = ~(BIT_EINT0_2);   
	
    ClearPending(BIT_DMA);
    rINTMSK=~(BIT_DMA);
    rSUBSRCPND=(BIT_SUB_DMA0|BIT_SUB_DMA2);    
    rINTSUBMSK=~(BIT_SUB_DMA0|BIT_SUB_DMA2);
    
    while(1)
    {
    	Uart_Printf("\n[Select Menu] (Rec Play Begin End Toggle Random)\n"
    	            "1:R_B 2:R_E 3:PR_T 4:P_B 5:P_E 6:Copy:R->P 7:IL_B 8:IL_E 9:Exit\n");
//    	Uart_Printf("\n[Select Menu] (Rec Play Begin End)\n"
//    	            "1:R_B 2:R_E 3:P_B 4:P_E 5:Copy_R->P 6:Exit\n");		
    	            
    	while((key=Uart_GetKey())==0)
    	{
    	    if(ranPlay==TRUE)
    	    	AudioOutRandom();
    	}

    	switch(key)
    	{
    	case '1':
    	    AudioInStart();
    	    break;
    	case '2':
    	    AudioInStop();
    	    break;
    	case '3':
			

    	    if(ranPlay==FALSE)
    	    {
    	    	ranPlay=TRUE;
    	    	Uart_Printf("Random Play Stop/Start begins.\n");
    	    }
    	    else
    	    {
    	    	ranPlay=FALSE;
    	    	Uart_Printf("Random Play Stop/Start ends.\n");
    	    }

	    break;
    	case '4':
    	    AudioOutStart();
    	    break;
    	case '5':
    	    AudioOutStop();
    	    break;
    	case '6':
    	    AudioBufCopy();
            break;
        case '7':
            InterruptLatencyStart();
	    break;
        case '8':
            InterruptLatencyStop();
   	    break;
    	case '9':
	    rINTSUBMSK|=(BIT_SUB_DMA0|BIT_SUB_DMA2);
	    rINTMSK|=(BIT_DMA|BIT_EINT7_10);
	    //(0,0)=1:1:1, (0,1)=1:1:2, (1,0)=1:2:2 (1,1)=1:2:4, (2,0)=1:4:5, (2,1)=1:4:8
	    ChangeClockDivider(1,1);
	    //(76,4,1)=84Mhz,  (93,4,1)=101Mhz, (54,1,1)=124Mhz, (68,4,0)=152Mhz
	    //(93,4,0)=202Mhz, (47,1,0)=220Mhz, (72,2,0)=240Mhz, (79,2,0)=261Mhz
	    //(60.2.0)=204MHz	
	    ChangeMPllValue(60,2,0);// FCLK=204Mhz 
	    ChangeSdramParameter(HCLK);
	    Uart_Init(0,115200);
    	    return;
    	default:
    	    break;    
    	}
    }
}


void AudioBufCopy(void)
{
    int i,j;
    Uart_Printf("[Audio Buffer Copy recBuf -> playBuf]\n");    
    
    if(audioInActive==TRUE)
    {
    	Uart_Printf("Rec is ongoing. Please Stop Recording.\n");
    	return;
    }
    
    for(i=0;i<MAX_INDEX_AUDIO_BUF;i++)
        for(j=0;j<AUDIO_BUF_SIZE;j++)
            playBuf[i][j]=recBuf[i][j];
}


void InterruptLatencyStart(void)
{
    Uart_Printf("[Random Interrupt Latency Start]\n");	
    pISR_TIMER0 = (U32)IsrTimer0_InterruptLatency;  //to make a worst condition
    rTCFG0=(3<<0);  //Timer0&1Prescaler=(3+1)
    rTCFG1=(3<<0);  //Timer0=PCLK/4/16
    rTCNTB0=1;
    rTCON=(1<<1); //T0ManualUpdate
    rTCON=(1<<0); //T0Start
    
    rINTMSK&=~(BIT_TIMER0);
}

void InterruptLatencyStop(void)
{
    rINTMSK|=BIT_TIMER0;
     
    Uart_Printf("[Random Interrupt Latency Stop]\n");	
}


void AudioInit(void)
{
    //DMA0 for AudioIn
    rDMASKTRIG0 = (1<<2);  	//Dma0Stop

    //DMA2 for AudioOut
    rDMASKTRIG2 = (1<<2);	//Dma2Stop 

    //IIS
    rIISCON=(1<<5)|(1<<4)|(1<<1);
        //TxDMAReqEn,RxDMAReqEn,IISPrescalerEn    
    rIISMOD=(0<<8)|(3<<6)|(0<<4)|(1<<3)|(0<<2)|(1<<0);
        //Master,Tx&Rx,IisFormat,16bit,256fs,32fs

    rIISPSR = (7<<5) + 7;   
    //Prescaler A,B=7 <- (PCLK = 45MHz)/8 = 5.625MHz    
	
    rIISFCON=(1<<15)|(1<<14)|(1<<13)|(0<<12);
    	//TxFifo=DMA,RxFifo=DMA,TxFifoEn,RxFifoDis
    rIISCON|=(1<<0);
        //IIS Enable;
        //IIS will not start because DMA is not ready.
}


//**************************************************
//                     AudioOut
//**************************************************


void AudioOutStart(void)
{
    if(audioOutActive!=FALSE)
    {
    	Uart_Printf("[N/A]");
    	return;
    }
    	
    Uart_Printf("[AudioOut Start]\n");    	
    stopPlay=FALSE;
    audioOutActive=TRUE;	
    indexPlayBuf=0;
    
    //Init DMA Ch 2
    rDISRC2 = (U32)(playBuf[indexPlayBuf++]);
    
    rDISRCC2 = (0<<1)|(0<<0); //Src=AHB,Increment
    rDIDST2 = (U32)IISFIFO;  // Tx FIFO address
    rDIDSTC2 = (1<<1)|(1<<0); //Dst=APB,Fixed;
    rDCON2 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(1<<20)|(AUDIO_BUF_SIZE);
        //handshake,Sync=APB,IntEn,unit,single,dst=I2SSDO,HwReqMode,NoAutoReload,Halfword,
    rDMASKTRIG2 = (1<<1); 	//DMA2En
 

    //IIS will start to work.
}


#define DMA_OFF_TIMEOUT		(1000)

void AudioOutStop(void)
{
    Uart_Printf("\n[AudioOut Stop]\n");    	
    stopPlay=TRUE;
}


void AudioOutRandom(void)
{
    static state=0;
    if( (rand()/(RAND_MAX/2000000)) < 1 )
    {
   	switch(state++)
   	{
   	case 0:
   	    AudioOutStart();
   	    state=1;
   	    break;
   	case 1:
   	    state=2;
   	    break;
   	case 2:
   	    AudioOutStop();
   	    state=0;
   	    break;
   	default:
	    break;
	}
    } 
}


void  __sub_IsrAudioOut(void)  //DMA2 done interrupt subroutine
{
    int timeOut=0;
    
    //NMI doesn't using auto-reload.	
	
//    ClearPending(BIT_DMA2);

    if(stopPlay==TRUE)
    {	    
    #if 1
    	rDMASKTRIG2|= (1<<2);  //NMI 
    #else 
    	rDMASKTRIG2= (1<<2);   //StopDMA2  //recommended
    #endif	

    	while (rDMASKTRIG2&(1<<1) && (timeOut++ < DMA_OFF_TIMEOUT));
    	if(timeOut >= DMA_OFF_TIMEOUT)
      	    Uart_Printf("ERROR: DMA2 Stop timed out\n");
	rDMASKTRIG2 &= ~(1<<2); //not needed.... remove!!!
	audioOutActive=FALSE;
	//Uart_Printf("<PE>");
    }  
    else
    {
	rDISRC2 = (U32)(playBuf[indexPlayBuf++]);
    	if(indexPlayBuf==MAX_INDEX_AUDIO_BUF)
    	{
    	    indexPlayBuf=0;
     	}
    	rDMASKTRIG2 |= (1<<1);   //enable DMA2  
 
     	if((indexPlayBuf%10)==0)
    	{
    	    if(indexPlayBuf==0)WrUTXH0(';');
    	    else WrUTXH0(',');
    	}
     }
}


//**************************************************
//                     AudioIn
//**************************************************

void AudioInStart(void)
{
    if(audioInActive!=FALSE)
    {
    	Uart_Printf("[N/A]");
    	return;
    }
        	
    Uart_Printf("[AudioIn Start]\n");    
    stopRec=FALSE;
    audioInActive=TRUE;	
    indexRecBuf=0;    
    
    //Init DMA Ch 0
    rDISRC0 = (U32)IISFIFO;  // Rx FIFO address
    rDISRCC0 = (1<<1)|(1<<0); //Src=APB,Fixed;
    rDIDST0 = (U32)(recBuf[indexRecBuf++]);
    rDIDSTC0 = (0<<1)|(0<<0); //DSt=AHB,Increment
    rDCON0 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(2<<24)|(1<<23)|(0<<22)|(1<<20)|(AUDIO_BUF_SIZE);
        //handshake,Sync=APB,IntEn,unit,single,dst=I2SSDI,HwReqMode,AutoReload,Halfword,
    rDMASKTRIG0 = (1<<1); //DMA1En
  
    rIISFCON|=(1<<12);  //RxFifoEn
    rIISCON|=(1<<4);    //RxDmaServiceRequestEn
    
    while((rDSTAT0&0xFFFFF) == 0);   
    
    rDIDST0 = (U32)(recBuf[indexRecBuf++]);
    
    //IIS will start to work.
}




void AudioInStop(void)
{
    Uart_Printf("\n[AudioIn Stop]\n");    	
    stopRec=TRUE;
}




void __sub_IsrAudioIn(void) //DMA0 done interrupt
{
    int timeOut=0;
    
//    ClearPending(BIT_DMA0);                 //Clear pending bit

    while((rDSTAT0 & 0xFFFFF) == 0);  //wait until the current autoreload is completed

    if(stopRec==TRUE)
    {
    	rIISCON&=~(1<<4);    //RxDmaServiceRequestDis
        rIISFCON&=~(1<<12);   //RxFifoDis	
    #if 1
    	rDMASKTRIG0|= (1<<2);  //NMI
    #else 
    	rDMASKTRIG0= (1<<2);   //recommended
    #endif	
    	while (rDMASKTRIG0&(1<<1) && (timeOut++ < DMA_OFF_TIMEOUT));
    
    	if(timeOut >= DMA_OFF_TIMEOUT)
      	    Uart_Printf("ERROR: DMA0 Stop timed out\n");

    	rDMASKTRIG0 &= ~(1<<2); //not needed.... remove!!!

    	audioInActive=FALSE;
    	//Uart_Printf("[RE]");
    }
    else
    {
    	rDIDST0 = (U32)(recBuf[indexRecBuf++]);
    	if(indexRecBuf==MAX_INDEX_AUDIO_BUF)
    	{
    	    indexRecBuf=0;
    	}
    	if((indexRecBuf%10)==0)
    	{
    	    if(indexRecBuf==0)WrUTXH0(':');
    	    else WrUTXH0('.');
    	}
    }
    
}


//*************************************************
//                    Audio In/Out IRQ 
//*************************************************

void __irq IsrAudioInOut(void)
{
    rINTSUBMSK|=(BIT_SUB_DMA0|BIT_SUB_DMA2);
    if(rSUBSRCPND&BIT_SUB_DMA0) __sub_IsrAudioIn();
    else __sub_IsrAudioOut();
    ClearPending(BIT_DMA); 
    rSUBSRCPND=(BIT_SUB_DMA0|BIT_SUB_DMA2);	// Clear Sub int pending    
    rINTSUBMSK&=~(BIT_SUB_DMA0|BIT_SUB_DMA2);    
}

void __irq IsrAudioMute(void)
{
    static int mute=0;
    
    ClearPending(BIT_EINT7_10);

    if(mute)    //Mute
    {
        _WrL3Addr(0x14 + 0);            //DATA0 (000101xx+00)
        _WrL3Data(0xa4,0);              //10,1,00,1,00 : after, no de-emp, mute, flat 
        mute = 0;
        Uart_Printf("\n[Mute]\n");
    }
    else        //No mute
    {
        _WrL3Addr(0x14 + 0);            //DATA0 (000101xx+00)
        _WrL3Data(0xa0,0);              //10,1,00,0,00 : after, no de-emp, no mute, flat 
        mute = 1;
        Uart_Printf("\n[No Mute]\n");
    }
}

//The following ISR makes an interrupt latency random time for audioIn and audioOut
void __irq IsrTimer0_InterruptLatency(void)
{
    static U16 count=0;
    ClearPending(BIT_TIMER0);
    count++;
    if(count==0x0)count=1;
    Delay(count&0x7f);
    Led_Display(count);

    rTCNTB0=count;
    rTCON=(1<<1); //T0ManualUpdate
    rTCON=(1<<0);  //T0Start  
    
}



//**************************************************
//                     UDA1341
//**************************************************

#define L3D (1<<16)            //GPDAT[16] = L3DATA
#define L3C (1<<17)            //GPDAT[17] = L3CLOCK
#define L3M (1<<18)            //GPDAT[18] = L3MODE

void Init1341RecPlay(void)
{
/*
    //Port Initialize
    //----------------------------------------------------------
    //   PORT B GROUP
    //Ports  :   GPB4    GPB3   GPB2  
    //Signal :  L3CLOCK L3DATA L3MODE
    //Setting:   OUTPUT OUTPUT OUTPUT 
    //           [9:8]   [7:6}  [5:4]
    //Binary :     01  ,   01    01 
    //----------------------------------------------------------    
    rGPBDAT = rGPBDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //Start condition : L3M=H, L3C=H
    rGPBUP  = rGPBUP  & ~(0x7<<2) |(0x7<<2);       //The pull up function is disabled GPB[4:2] 1 1100    
    rGPBCON = rGPBCON & ~(0x3f<<4) |(0x15<<4);     //GPB[4:2]=Output(L3CLOCK):Output(L3DATA):Output(L3MODE)
*/
		//Port Initialize for 24A0X
	//----------------------------------------------------------
	//	 GPCON_M GROUP
	//Ports  :	 GP18	 GP17	GP16  
	//Signal :	L3MODE L3CLOCK L3DATA
	//Setting:	 OUTPUT OUTPUT OUTPUT 
	//			 [15:14]   [13:12]	[11:10]
	//Binary :	   01  ,   01	 01 
	//----------------------------------------------------------	
		rGPDAT = rGPDAT & ~(L3M|L3C|L3D) |(L3M|L3C); //Start condition : L3M=H, L3C=H
		rGPPU  = rGPPU	& ~(0x7<<15) |(0x7<<15);	   //The pull up function is disabled GPUP[17:15] 0011 1000 0000 0000 0000	  
		rGPCON_M = rGPCON_M & ~(0x3f<<8) |(0x15<<8);	   //GPCON_M[13:8]=Output(L3MODE):Output(L3CLOCK):Output(L3DATA)


    //L3 Interface
    _WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
    _WrL3Data(0x60,0);       //0,1,10,000,0 : Reset,256fs,no DCfilter,iis

    _WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
    _WrL3Data(0x20,0);       //0,0,10,000,0 : No reset,256fs,no DCfilter,iis
    
/*    
    //play
    _WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
    _WrL3Data(0x81,0);       //1,0,0,0,0,0,01 : OGS=0,IGS=0,ADC_NI,DAC_NI,sngl speed,AoffDon
        
    //record
    if(mode)
    {
        _WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
        _WrL3Data(0xa2,0);       //1,0,1,0,0,0,10 : OGS=0,IGS=1,ADC_NI,DAC_NI,sngl speed,AonDoff

        _WrL3Addr(0x14 + 0);     //DATA0 (000101xx+00)
        _WrL3Data(0xc2,0);       //11000,010  : DATA0, Extended addr(010) 
        _WrL3Data(0x4d,0);       //010,011,01 : DATA0, MS=9dB, Ch1=on Ch2=off, 
    }
*/
    _WrL3Addr(0x14 + 2);     //STATUS (000101xx+10)
    _WrL3Data(0xa3,0);       //1,0,1,0,0,0,11 : OGS=0,IGS=1,ADC_NI,DAC_NI,sngl speed,AonDon

    _WrL3Addr(0x14 + 0);     //DATA0 (000101xx+00)
    _WrL3Data(0xc2,0);       //11000,010  : DATA0, Extended addr(010) 
    _WrL3Data(0x4d,0);       //010,011,01 : DATA0, MS=9dB, Ch1=on Ch2=off, 
}

⌨️ 快捷键说明

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