📄 pcm.c
字号:
/********************************************************************************
*
* Project Name : S3C6400 Validation
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for verifying functions of the S3C6400.
* Anybody can use this software without our permission.
*
*--------------------------------------------------------------------------------
*
* File Name : PCM_test.c
*
* File Description :
*
* Author : Yoh-Han Lee
* Dept. : AP Development Team
* Created Date : 2007/03/16
* Version : 0.2
*
* History
* - Version 0.1 (2007/03/16)
* -> Available with AK2440 PCM Codec.
* - Version 0.2 (2007/04/
* -> Available with
*********************************************************************************/
#include "System.h"
#include "pcm.h"
#include "SfrReadWriten.h"
//#include "ac97.h"
//#include "iis.h"
// Global variables
int g_interrupt_cnt=0;
PCM_IRQstat g_pcmirqstat[PCM_IRQ_STAT_MAX];
// SFR test
REGINFOn sRegInfoPCM0[] =
{
//01234567890123 address reset uPrivateBitMask(1:do check)
// value
{"PCM_CTL0 ", 0x5C000000, 19-1, RW, 0x0 , DPDB, 0,0},
{"PCM_CLKCTL0 ", 0x5C000004, 20-1, RW, 0x0 , DPDB, 0,0},
{"PCM_TXFIFO0(fifo) ", 0x5C000008, 17-1, RO, 0x0 , DPDB, 0,0},//should be check via pcm link
{"PCM_RXFIFO0(fifo) ", 0x5C00000C, 17-1, RO, 0x0 , DPDB, 0,0},//should be check via pcm link
{"PCM_IRQ_CTL0 ", 0x5C000010, 15-1, RW, 0x0 , DPPB, 0x6fff,0},
{"PCM_IRQ_STAT0 ", 0x5C000014, 14-1, RO, 0x0 , DPDB, 0,0},
{"PCM_FIFO_STAT0 ", 0x5C000018, 20-1, RO, 0x0 , DPDB, 0,0},
{"PCM_CLRINT0 ", 0x5C000020, 1-1 , WO, 0x0 , DPDB, 0,0},
};
REGINFOn sRegInfoPCM1[] =
{
//01234567890123 address reset uPrivateBitMask(1:do check)
// value
{"PCM_CTL1 ", 0x5C000100, 19-1, RW, 0x0 , DPDB, 0,0},
{"PCM_CLKCTL1 ", 0x5C000104, 20-1, RW, 0x0 , DPDB, 0,0},
{"PCM_TXFIFO1(fifo) ", 0x5C000108, 17-1, RO, 0x0 , DPDB, 0,0},//should be check via pcm link
{"PCM_RXFIFO1(fifo) ", 0x5C00010C, 17-1, RO, 0x0 , DPDB, 0,0},//should be check via pcm link
{"PCM_IRQ_CTL1 ", 0x5C000110, 15-1, RW, 0x0 , DPPB, 0x6fff,0},
{"PCM_IRQ_STAT1 ", 0x5C000114, 14-1, RO, 0x0 , DPDB, 0,0},
{"PCM_FIFO_STAT1 ", 0x5C000118, 20-1, RO, 0x0 , DPDB, 0,0},
{"PCM_CLRINT1 ", 0x5C000120, 1-1 , WO, 0x0 , DPDB, 0,0},
};
// Externs
extern PCM_State g_oPCMState;
extern unsigned int ARMCLK, HCLK, PCLK;
//extern function
extern void I2SCODEC_WrSerial( unsigned char slave_addr,
char reg_addr,
char data);//codec.cpp
extern unsigned short AC97_Codec_Cmd(unsigned char CMD_Read, unsigned char CMD_Offset, unsigned short CMD_Data);
extern void AC97_Port_Init();
//should execute at first
bool PCM_SFR_testsub(int Port)
{
bool bret;
if(Port == 0)
bret=TestSFRn(sRegInfoPCM0, sizeof(sRegInfoPCM0)/sizeof(REGINFOn));
else if(Port == 1)
bret=TestSFRn(sRegInfoPCM1, sizeof(sRegInfoPCM1)/sizeof(REGINFOn));
return bret;
}
volatile char g_PcmRecDone;
volatile char g_PcmPlayDone;
//extern u16 g_usAC97Setup;
unsigned short* g_uPcmRecBuffer;
unsigned short* g_uPcmEndRecBuffer;
unsigned int* g_uPcmBuffer32;
unsigned int* g_uPcmEndBuffer32;
//////////
// Function Name : PCM_Configure
// Function Desctiption : This fucntion initialize S3C6400 sturct of PCM State.
// Input : None
// Output : ocPCMstate (PCM State Structure)
// Version : 0.0
// Author : Sung-Hyun, Na
void PCM_Init(void)
{
//Codec ID
g_oPCMState.CodecID = PCM_CODEC_NAME;
//Set Gpio Port
g_oPCMState.PCMPort = PCM_PORT1;
//Source CLK(PCMCODEC_CLK) Selection
g_oPCMState.PCMClkSrc = PCM_PCLK;//256fs (2048kHz)
g_oPCMState.EXTCDCLKFreq = EXT_CLOCK_FREQ_A_32_768;
//PCMSCLK Selection
g_oPCMState.PCMSClk= SCLK_128K;//16fs
//Sync CLK Selection
g_oPCMState.PCMSync = SYNC_8K;//fs
//MSB Postion Selection
g_oPCMState.PCMMSBPosition = DURING_PCMSYNC_HIGH;
//Init GPIO Port
PCM_SetPort(g_oPCMState.PCMPort);
//Delay(1000); why?
// #if (PCM_CODEC_NAME == WM9713)
// AC97_SetPort(g_oPCMState.AC97Port);
// #else
// #if ( PCM_CODEC_MASTERCLK )
// //PCMSelectI2SEPLL(g_oPCMState.I2SPort);
// I2S_InitPort(g_oPCMState.I2SPort);
// PCM_WM8753MasterCLKGen(g_oPCMState.PCMPort);
// #endif
// #endif
// //Delay(1000); why?
PCM_SelClkSrc(g_oPCMState.PCMPort, g_oPCMState.PCMClkSrc, 1);
//Delay(1000); why?
}
void PCM_SelectPort(void)
{
unsigned char selTemp;
printf("Select PCM PORT\n");
printf("0. PORT0[D] 1. PORT1\n");
selTemp = GetIntNum();
if (selTemp == 1)
{
g_oPCMState.PCMPort = PCM_PORT1;
}
else
{
g_oPCMState.PCMPort = PCM_PORT0;
}
PCM_SetPort(g_oPCMState.PCMPort);
//Delay(1000); why?
// #if (PCM_CODEC_NAME == WM8753)
//
// #if ( PCM_CODEC_MASTERCLK )
// //PCM_WM8753MasterCLKGen(g_oPCMState.PCMPort);
// I2S_Init(g_oPCMState.I2SPort);
// PCMSelectI2SEPLL(g_oPCMState.I2SPort);
// #endif
//
// #elif ( PCM_CODEC_NAME == WM9713)
// AC97_Port_Init();
// #endif
// Delay(1000);
}
void PCM_AUTO_set( PCM_State setting)
{
g_oPCMState.CodecID = setting.CodecID;
g_oPCMState.PCMPort = setting.PCMPort;
g_oPCMState.PCMClkSrc = setting.PCMClkSrc;
g_oPCMState.EXTCDCLKFreq = setting.EXTCDCLKFreq;
g_oPCMState.PCMSync = setting.PCMSync;
g_oPCMState.PCMSClk = setting.PCMSClk;
g_oPCMState.PCMMSBPosition = setting.PCMMSBPosition;
}
void PCM_SelectPCMCLKSOURCE(void)
{
unsigned char selTemp;
printf("Select PCM Source CLK\n");
printf("0. EXTCDCLK[D] 1. PCLK\n");
selTemp = GetIntNum();
//PCM_PCMCDCLK, PCM_PCLK
switch(selTemp)
{
case 1:
g_oPCMState.PCMClkSrc = PCM_PCLK;
break;
default:
g_oPCMState.PCMClkSrc = PCM_PCMCDCLK;
break;
}
if(selTemp != 1)
{
printf("Select EXTCLK freq.\n");
printf("0. 32.768MHz[D] 1. 16.9344MHz\n");
selTemp = GetIntNum();
if(selTemp !=1)
g_oPCMState.EXTCDCLKFreq = EXT_CLOCK_FREQ_A_32_768;
else
g_oPCMState.EXTCDCLKFreq = EXT_CLOCK_FREQ_B_16_9344;
}
printf("Select selected Clock gating \n");
if(g_oPCMState.PCMClkSrc == PCM_PCMCDCLK)
printf("for port %d\n", g_oPCMState.PCMPort);
printf("0. enable[D] 1. disable\n");
selTemp = GetIntNum();
if(selTemp !=1) PCM_SelClkSrc(g_oPCMState.PCMPort, g_oPCMState.PCMClkSrc, 1);
else PCM_SelClkSrc(g_oPCMState.PCMPort, g_oPCMState.PCMClkSrc, 0);
Delay(1000);//?
}
void PCM_SelectPCMSYNC_SCLK(void)
{
unsigned short i;
unsigned char selTemp;
printf("Select PCMSync(fs)\n");
printf("0. 8Khz[D] 1. 16KHz 2. 32KHz 3. 48KHz\n\
4. 64KHz 5. 96KHz 6. 11.025KHz 7. 22.05KHz\n\
8. 44.1KHz 9. 88.2KHz");
selTemp = GetIntNum();
switch(selTemp)
{
case 1:
g_oPCMState.PCMSync= SYNC_16K;
break;
case 2:
g_oPCMState.PCMSync= SYNC_32K;
break;
case 3:
g_oPCMState.PCMSync= SYNC_48K;
break;
case 4:
g_oPCMState.PCMSync= SYNC_64K;
break;
case 5:
g_oPCMState.PCMSync= SYNC_96K;
break;
case 6:
g_oPCMState.PCMSync= SYNC_11025;
break;
case 7:
g_oPCMState.PCMSync= SYNC_22050;
break;
case 8:
g_oPCMState.PCMSync= SYNC_44100;
break;
case 9:
g_oPCMState.PCMSync= SYNC_88200;
break;
default://0
g_oPCMState.PCMSync= SYNC_8K;
break;
}
i=1;
printf("Select PCM SCLK(time slot concept)\n");
printf("%d. %dfs[16fs*%d] (%d KHz)[D] ", i, i*16, i, (16 * g_oPCMState.PCMSync * i ) / 1000 );
for(i=2; i<=32; i++)
{
printf("%d. %dfs[16fs*%d] (%d KHz) ", i, i*16, i, (16 * g_oPCMState.PCMSync * i) / 1000 );
if(i%3 == 0 ) printf("\n");
}
selTemp = GetIntNum();
selTemp = ( selTemp<1 || selTemp>32 )? 1 : selTemp;
g_oPCMState.PCMSClk = 16*g_oPCMState.PCMSync*selTemp;//16bit mono * time slot
if(g_oPCMState.PCMSClk*1024 < 66000000)
{
printf("adjusting clock is needed\n");
}
}
void PCM_SelectSyncPosition(void)
{
unsigned char selTemp;
printf("\nSelect PCM data MSB Postion\n");
printf("0.DURING_PCMSYNC_HIGH(DSP Mode B)[D]] 1.AFTER_PCMSYNC_HIGH(DSP Mode A)\n ");
selTemp = GetIntNum();
if (selTemp == 1)
g_oPCMState.PCMMSBPosition = AFTER_PCMSYNC_HIGH;
else
g_oPCMState.PCMMSBPosition = DURING_PCMSYNC_HIGH;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//in case of pcm0, it share with ac97.
//so when verifying with 9714 codec, switching is needed from ac97 to pcm0 middle of verifying
void PCM_SetPort(unsigned char ePort)
{
if (ePort == PCM_PORT0)
{
//-------------------------------------------------------------------------------
//PORT E GROUP
//Ports : GPE4 GPE3 GPE2 GPE1 GPE0
//Signal : PCM0_SDO PCM0_SDI PCM0_CDCLK PCM0_SCLK PCM0_FSYNC
//con : xx
//pullup : 11
//Sel : 1 1 1 1 1
//-------------------------------------------------------------------------------
rGPESEL = 0x1f;//GPE select
rGPEUDP = rGPEUDP & ~((U32)(0x3ff)) | ((U32)(0x3ff));//pull_up_down disable (fpga io b'd n/a)
}
else if (ePort == PCM_PORT1)
{
//-------------------------------------------------------------------------------
//PORT L GROUP
//Ports : GPL7 GPL6 GPL5 GPL4
//Signal : PCM1_SDO PCM1_SDI PCM1_CDCLK PCM1_SCLK
//con : xx
//pullup : 11
//Sel : 1 1 1 1
//-------------------------------------------------------------------------------
rGPLSEL = 0xf;
rGPLUDP = rGPLUDP & ~((U32)(0xff<<8)) | ((U32)(0xff<<8)); // pull_up_down disable
//-------------------------------------------------------------------------------
//PORT J GROUP
//Ports : GPJ13
//Signal : PCM1_FSYNC
//con : xx
//pullup : 11
//Sel : 1
//-------------------------------------------------------------------------------
rGPJSEL = 1;
rGPJUDP = rGPJUDP & ~((U32)(0x3<<26)) | ((U32)(0x3<<26));//pull_up_down disable
}
}
//////////
// Function Name :
// Function Desctiption :
// Input : Sync Rate, MSB Position, SCLK, CLKSRC
// Output : None
// Version : 0.0
// Author : Yoh-Han Lee
bool PCM_CodecInitPCMIn(unsigned int eSync, unsigned char eMSBPos, unsigned int eSclk, unsigned char eClkSrc)
{
int i;
unsigned char uCodecSet;
#if ( PCM_CODEC_NAME == AK2430)
if(eSclk == SCLK_128K)
uCodecSet = 0x0;
else if(eSclk == SCLK_256K)
uCodecSet = 0x1;
else if(eSclk == SCLK_512K)
uCodecSet = 0x2;
else
uCodecSet = 0x3;//not supported
if(uCodecSet == 0x3)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -