📄 pcm_test.c
字号:
/*======================================================================
Project Name : S3C2450
Copyright 2007 by Samsung Electronics, Inc.
All rights reserved.
Project Description :
This software is only for verifying functions of the S3C2450.
Anybody can use this code without our permission.
File Name : pcm_test.c
Description : S3C2450 PCM module test code
Author : Dongjin Kim
Dept : AP
Created Date : 2007.11.28
Version : 0.0
History :
0.1 (2007/03/16) Y.H.Lee
- Available with AK2440 PCM Codec.
- S3C2450 PCM test code is derived from S3C6400 PCM test code.
0.11 (2007/11/28)
- changes source structure according to 2450
=======================================================================*/
#include "System.h"
#include "pcm.h"
#include "ac97.h"
#include "iis.h"
#include "audiolibrary.h"
/////////////////////////////////////////////////////
// Global variable
/////////////////////////////////////////////////////
PCM_State g_oPCMState;
extern int g_interrupt_cnt;
extern PCM_IRQstat g_pcmirqstat[PCM_IRQ_STAT_MAX];;
/////////////////////////////////////////////////////
// Externs SFR & IP Functions
/////////////////////////////////////////////////////
extern bool PCM_SFR_testsub(int Port);
extern bool PCM_DATA_2chpattern_making( unsigned int* destsizeByte,
unsigned int destaddr, unsigned int totrepeat, int eachrepeat, int BitperCh);
/////////////////////////////////////////////////////
// Test Functions
/////////////////////////////////////////////////////
static void PCM_SFR_test(void);
static void PCMSet(void);
static void PCMCodecRegWR(void);
static void PCMOut(bool buserinput, int autoselect);
static void PCMInOut(bool buserinput, int autoselect);
static void PCMmemOut(void);
static void PCMInOutSametime(void);
static void PCMLinkSclkTest(void);
static void PCMDMATest(void);
static void PCMEXTTest1(void);
static void PCMEXTTest2(void);
static void PCMMSBTest1(void);
static void PCMMSBTest2(void);
static bool PCMDMATxEnableTest(void);
static bool PCMDMARxEnableTest(void);
static bool PCMDMATxFULLDetailTest(void);
static bool PCMDMARxFULLDetailTest(void);
static bool PCMDMATxEMPTYDetailTest(void);
static bool PCMDMARxEMPTYDetailTest(void);
//detail tests
//TX
static bool PCM_Detail_PCM_TX_DMA_EN(void);
static bool PCM_Detail_PCM_PCM_ENABLE_TX(void);
static bool PCM_Detail_PCM_FIFOENABLE_TX(void);
static bool PCM_Detail_CTL_SERCLK_EN_TX(void);
static bool PCM_Detail_PCM_IRQ_TXALMOSTFULL(void);
static bool PCM_Detail_PCM_IRQ_TXFULL(void);
static bool PCM_Detail_PCM_IRQ_TXOVERFLOW(void);
static bool PCM_Detail_PCM_IRQ_NOTPENDING_TXFULL(void);
static bool PCM_Detail_PCM_IRQ_TXALMOSTEMPTY(void);
static bool PCM_Detail_PCM_IRQ_TXEMPTY(void);
static bool PCM_Detail_PCM_IRQ_TXSTARVE(void);
static bool PCM_Detail_PCM_IRQ_NOTPENDING_TXEMPTY(void);
//RX
static bool PCM_Detail_PCM_RX_DMA_EN(void);
static bool PCM_Detail_PCM_PCM_ENABLE_RX(void);
static bool PCM_Detail_PCM_FIFOENABLE_RX(void);
static bool PCM_Detail_CTL_SERCLK_EN_RX(void);
static bool PCM_Detail_PCM_IRQ_RXALMOSTFULL(void);
static bool PCM_Detail_PCM_IRQ_RXFULL(void);
static bool PCM_Detail_PCM_IRQ_RXOVERFLOW(void);
static bool PCM_Detail_PCM_IRQ_NOTPENDING_RXFULL(void);
static bool PCM_Detail_PCM_IRQ_RXALMOSTEMPTY(void);
static bool PCM_Detail_PCM_IRQ_RXEMPTY(void);
static bool PCM_Detail_PCM_IRQ_RXSTARVE(void);
static bool PCM_Detail_PCM_IRQ_NOTPENDING_RXEMPTY(void);
/////////////////////////////////////////////////////
// Test functions Lists & Calls routine
/////////////////////////////////////////////////////
void * func_pcm_test[][2]=
{
// "123456789012345678901"
(void *)PCM_SelectPort, "Select PCM port",
//IIS Function Test Item
(void *)PCM_SFR_test, "PCM SFR reset & read/write test ",//1
(void *)PCMSet, "Configuration",
(void *)PCMOut, "PCM Out Test",
(void *)PCMInOut, "PCM In/Out Test",
(void *)PCMInOutSametime , "recording/playing at same time\n",
(void *)PCMmemOut, "just playing at memory\n",
(void *)PCMLinkSclkTest, "sync, sclock test (test pattern)",
(void *)PCMDMATest, "dma in/out",
(void *)PCMEXTTest1, "EXT clock test(test pattern)",
(void *)PCMEXTTest2, "EXT clock test in/out",
(void *)PCMMSBTest1, "PCM MSB Test out(test pattern)",
(void *)PCMMSBTest2, "PCM MSB Test in/out\n",
(void *)PCMDMATxEnableTest, "PCM TX enable Detail test",
(void *)PCMDMATxFULLDetailTest, "PCM IRQ tx FULL Detail test",
(void *)PCMDMATxEMPTYDetailTest, "PCM IRQ tx EMPTY Detail test\n",
(void *)PCMDMARxEnableTest, "PCM RX enable Detail test",
(void *)PCMDMARxFULLDetailTest, "PCM IRQ rx FULL Detail test",
(void *)PCMDMARxEMPTYDetailTest, "PCM IRQ rx EMPTY Detail test",
// (void *)PCMInOut_Test2, "Manual Test PCM1",
0,0
};
void * pcmset_function[][2]=
{
(void *)PCM_SelectPCMCLKSOURCE, "PCMCLK Source Selecte",
(void *)PCM_SelectPCMSYNC_SCLK, "PCMSYNC Frequency(Sampling rate) & PCMSCLK Frequency",
(void *)PCM_SelectSyncPosition, "MSB Position",
0, 0
};
char* PCM_CODECname_string[]=
{
"","","WM9713","", "AK2430","WM8753"
};
// 2 4 5
/*
//ac97 codec
#define STAC9767 1
#define AC97WM9713 2
//i2s codec
#define WM_8450 3
#define WM8580 WM_8450
//pcm codec
#define AK2430 4 //SMDK board has not this CODEC
#define WM9713 AC97WM9713 2 //There is some noise in WM9713 ADC Path
#define WM9714 WM97 2 13 //identically same with 9713 in sw side
#define WM8753 5
*/
char* PCM_CLKSRC_string[]=
{
"PCMEXTCDCLK(D)","PCLK"
};
char* PCM_MSBPOS_string[]=
{
"DURING HIGH Mode (DSP Mode B)",
"AFTER HIGH Mode(DSP Mode A)"
};
static void PCM_Display(PCM_State test)
{
printf("\n");
printf("================================================================================\n");
printf("\nPCM Configuration\n");
printf("PCM Codec : %s Port #: %d MSB Position : %s\n",
(PCM_CODECname_string[test.CodecID]),
(test.PCMPort),
PCM_MSBPOS_string[test.PCMMSBPosition] );
printf("Source_Clk : %s PCM_SCLK : %dKHz Sync Rate(Sampling Frquency) : %dKHz\n\n",
(PCM_CLKSRC_string[test.PCMClkSrc]),(test.PCMSClk)/1000,(test.PCMSync)/1000);
printf("source clk speed : %f\n",(test.PCMClkSrc == PCM_PCLK)?(double)PCLK:(double)test.EXTCDCLKFreq );
printf("Board configuration : %s\n",(AUDIOPORT1_SEL==INVERTED_R194_DEFAULT)?"AUDIO1 SEL-INVERTED_R194_DEFAULT":"AUDIO1 SEL-NORMAL_R196_BOARDCHANGED");
//clock gating information
printf("pclk to pcm0,1 gating %d\n", ( (rPCLKCON & (1<<19) )==(1<<19) )?1:0 );
printf("extclk to pcm0 gating %d\n", ( (rSCLKCON & (1<<17) )==(1<<17) )?1:0 );
printf("extclk to pcm1 gating %d\n", ( (rSCLKCON & (1<<18) )==(1<<18) )?1:0 );
}
void Test_PCM(void)
{
int i;
//init
PCM_Init();
while(1)
{
PCM_Display(g_oPCMState);
i=0;
printf("\n\n================== PCM Function Test =====================\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,func_pcm_test[i][1]);
i++;
if((int)(func_pcm_test[i][0])==0)
{
printf("\n");
break;
}
if((i%1)==0)
printf("\n");
}
printf("\n==========================================================\n");
printf("Select #Item or Press Enter key to exit : ");
i = GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(func_pcm_test)-1)/8)) ) // select and execute...
( (void (*)(void)) (func_pcm_test[i][0]) )();
}
}
static void PCM_SFR_test(void)
{
/*
unsigned int* addr32 = (unsigned int *)0x5c000000;
unsigned short* addr16 = (unsigned short *)0x5c000000;
unsigned char* addr8 = (unsigned char *)0x5c000000;
unsigned char value8=*addr8;
unsigned short value16=*addr16;
unsigned int value32=*addr32;
printf("test byte read :%d at 0x%x", value8);
printf("test byte read :%d at 0x%x", value16);
printf("test byte read :%d at 0x%x", value32);
*/ //data region over 5b100000 is fault area in mmu define
PCM_SFR_testsub(g_oPCMState.PCMPort);
}
static void PCMSet(void)
{
int i;
while(1)
{
i=0;
printf("\n\n================== Select the function =====================\n\n");
while(1)
{ //display menu
printf("%2d:%s",i,pcmset_function[i][1]);
i++;
if((int)(pcmset_function[i][0])==0)
{
printf("\n");
break;
}
if((i%1)==0)
printf("\n");
}
printf("\n==========================================================\n");
printf("Select #Item or Press Enter key to exit : ");
i = GetIntNum();
if(i==-1) break; // return.
if(i>=0 && (i<((sizeof(pcmset_function)-1)/8)) ) // select and execute...
( (void (*)(void)) (pcmset_function[i][0]) )();
}
}
static void PCMOut(bool buserinput, int autoselect)
{
int i;
unsigned int destsizeByte;
bool bauto=0;
bool bret;
//init
PCM_DATA_2chpattern_making( &destsizeByte,
(unsigned int)(PCM_REC_BUF), (unsigned int)6,4400, 16);
bret=PCM_CodecInitPCMOut(g_oPCMState.PCMSync, g_oPCMState.PCMMSBPosition, g_oPCMState.PCMSClk, g_oPCMState.PCMClkSrc);
PCM_SetPort(g_oPCMState.PCMPort);
//select mode
printf("\nSelect PCM In/Out Operation Mode\n");
printf("0: Interrupt, 1: DMA(D)\n");
if(buserinput!=1) i = GetIntNum();
else i = autoselect;
//interrupt
if(i==0)
{
g_oPCMState.Playmode = PCM_INTERRUPT;
printf("set auto [a] to continue test 10 times\n");
if(getchar() =='a') bauto = 1;
while(1)
{
printf("\nListen to Sound via Speak Out Connector.\n");
if(!bauto)
{
printf("Press any key to play.x to exit\n");
if( getchar() == 'x')break;
}
PCM_PCMOutInt2(PCM_REC_BUF, destsizeByte);
//PCM_PCMOutInt2(PCM_REC_BUF, 4*32);
if(i>10) break;
i++;
}
}
else //dma
{
g_oPCMState.Playmode = PCM_DMA;
PCM_PCMSetting();
PCM_PCMOutDMA(PCM_REC_BUF, destsizeByte, NULL);
}
//deinit
PCM_CodecExitPCMOut();
}
static void PCMmemOut(void)
{
int i;
unsigned int destsizeByte=g_oPCMState.PCMSync*2*10;
bool bret;
bool bauto=0;
//init
bret=PCM_CodecInitPCMOut(g_oPCMState.PCMSync, g_oPCMState.PCMMSBPosition, g_oPCMState.PCMSClk, g_oPCMState.PCMClkSrc);
PCM_SetPort(g_oPCMState.PCMPort);
//select mode
printf("\nSelect PCM In/Out Operation Mode\n");
printf("0: Interrupt, 1: DMA(D)\n");
i = GetIntNum();
//interrupt
if(i==0)
{
g_oPCMState.Playmode = PCM_INTERRUPT;
printf("set auto [a] to continue test 10 times\n");
if(getchar() =='a') bauto = 1;
while(1)
{
printf("\nListen to Sound via Speak Out Connector.\n");
if(!bauto)
{
printf("Press any key to play.x to exit\n");
if( getchar() == 'x')break;
}
PCM_PCMOutInt2(PCM_REC_BUF, destsizeByte);
if(i>10) break;
i++;
}
}
else //dma
{
g_oPCMState.Playmode = PCM_DMA;
PCM_PCMSetting();
PCM_PCMOutDMA(PCM_REC_BUF, destsizeByte, NULL);
}
//deinit
PCM_CodecExitPCMOut();
}
static void PCMInOut(bool buserinput, int autoselect)
{
int i;
bool bret;
printf("\nSelect PCM In/Out Operation Mode\n");
printf("0: Interrupt, 1: DMA(D) : ");
if(buserinput!=1)
i = GetIntNum();
else
i = autoselect;
printf("%d\n", i);
if(i==0)
{
g_oPCMState.Playmode = PCM_INTERRUPT;
PCM_CodecInitPCMIn(g_oPCMState.PCMSync, g_oPCMState.PCMMSBPosition, g_oPCMState.PCMSClk, g_oPCMState.PCMClkSrc);
PCM_PCMSetting();
PCM_PCMInInt(PCM_REC_BUF, (g_oPCMState.PCMSync*2*10) );
PCM_CodecExitPCMIn();
PCM_CodecInitPCMOut(g_oPCMState.PCMSync, g_oPCMState.PCMMSBPosition, g_oPCMState.PCMSClk, g_oPCMState.PCMClkSrc);
PCM_PCMOutInt(PCM_REC_BUF, (g_oPCMState.PCMSync*2*10) );
}
else
{
g_oPCMState.Playmode = PCM_DMA;
//record
bret = PCM_CodecInitPCMIn(g_oPCMState.PCMSync, g_oPCMState.PCMMSBPosition, g_oPCMState.PCMSClk, g_oPCMState.PCMClkSrc); //set external codec
//Digital I/F off
//printf("\n=>Digital I/F off PR4\n");
//AC97_Codec_Cmd(0,0x26,(1<<8)|(1<<9)|(1<<10)|(1<<12));
PCM_SetPort(g_oPCMState.PCMPort);
PCM_PCMSetting();
PCM_PCMInDMA(PCM_REC_BUF, (g_oPCMState.PCMSync*2*20) , NULL); //set internal interface controller
PCM_CodecExitPCMIn();
//play
PCM_CodecInitPCMOut(g_oPCMState.PCMSync, g_oPCMState.PCMMSBPosition, g_oPCMState.PCMSClk, g_oPCMState.PCMClkSrc);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -