?? pcm.c
字號(hào):
u32 i;
u8 uI2cData[2];
s32 uI2cDataCount, uI2cPt;
#if (PCM_CODEC_NAME == AK2430)
uI2cData[0] = (unsigned char)uAddr;
uI2cData[1] = uData;
uI2cDataCount = 2;
uI2cPt = 0;
IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0xf)); //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
IICOutp32(rIICSTAT, 0x10); //IIC bus data output enable(Rx/Tx)
IICOutp32(rIICLC, (1<<2)|(1)); //Filter enable, 5 clocks SDA output delay
//Data Write Phase
IICOutp32(rIICDS, uSlaveAddr); //0xa0
IICOutp32(rIICSTAT, 0xf0);
while(uI2cDataCount != -1)
{
if(IICInp32(rIICCON)& 0x10)
{
if((uI2cDataCount--)==0)
{
IICOutp32(rIICSTAT, 0xd0); //stop MasTx condition
IICOutp32(rIICCON, 0xaf); //resumes IIC operation.
Delay(1); //wait until stop condtion is in effect.
break;
}
IICOutp32(rIICDS, uI2cData[uI2cPt++]);
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
IICOutp32(rIICCON, 0xaf); //resumes IIC operation.
}
}
IICOutp32(rIICSTAT, 0xd0); //Master Tx condition, Stop(Write), Output Enable
IICOutp32(rIICCON, 0xaf); //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
#elif (PCM_CODEC_NAME == WM8753)
uI2cData[0] = (unsigned char)uAddr;
uI2cData[1] = uData;
uI2cDataCount = 2;
uI2cPt = 0;
IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0xf)); //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
IICOutp32(rIICSTAT, 0x10); //IIC bus data output enable(Rx/Tx)
IICOutp32(rIICLC, (1<<2)|(3)); //Filter enable, 15 clocks SDA output delay
//Data Write Phase
IICOutp32(rIICDS, uSlaveAddr); //0xa0
IICOutp32(rIICSTAT, 0xf0);
while(uI2cDataCount != -1)
{
if(IICInp32(rIICCON)& 0x10)
{
if((uI2cDataCount--)==0)
{
IICOutp32(rIICSTAT, 0xd0); //stop MasTx condition
IICOutp32(rIICCON, 0xaf); //resumes IIC operation.
Delay(1); //wait until stop condtion is in effect.
break;
}
IICOutp32(rIICDS, uI2cData[uI2cPt++]);
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
IICOutp32(rIICCON, 0xaf); //resumes IIC operation.
}
}
IICOutp32(rIICSTAT, 0xd0); //Master Tx condition, Stop(Write), Output Enable
IICOutp32(rIICCON, 0xaf); //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
#else
Assert(0);
#endif
}
u8 PCM_CODEC_IICRead(u32 uSlaveAddr, u8 uAddr)
{
u8 uI2cData;
s32 uI2cDataCount, i;
#if (PCM_CODEC_NAME== AK2430)
uI2cData = uAddr;
uI2cDataCount = 1;
//Register Address Write Phase
IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
IICOutp32(rIICSTAT, 0x10); //IIC bus data output enable(Rx/Tx)
IICOutp32(rIICLC, (1<<2)|(1)); //Filter enable, 15 clocks SDA output delay
IICOutp32(rIICDS, uSlaveAddr);
IICOutp32(rIICSTAT, 0xf0); //MasTx,Start
while(uI2cDataCount!=-1)
{
if(IICInp32(rIICCON) & 0x10)
{ //Tx/Rx Interrupt Enable
if((uI2cDataCount--)==0)
{
break;
}
IICOutp32(rIICDS, uI2cData);
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
IICOutp32(rIICCON, 0xaf); //resumes IIC operation.
}
}
uI2cDataCount = 1;
IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));
//Register Data Read Phase
IICOutp32(rIICDS, uSlaveAddr);
IICOutp32(rIICSTAT, 0xb0); //Master Rx,Start
while(uI2cDataCount!=-1)
{
if(IICInp32(rIICCON) & 0x10) //Interrupt pending
{
if((uI2cDataCount--)==0)
{
uI2cData = IICInp32(rIICDS);
IICOutp32(rIICSTAT, 0x90); //Stop MasRx condition
IICOutp32(rIICCON, 0xaf); //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//Too long time...
//The pending bit will not be set after issuing stop condition.
break;
}
if((uI2cDataCount)==0)
IICOutp32(rIICCON, 0x2f); //Resumes IIC operation with NOACK.
else
IICOutp32(rIICCON, 0xaf); //Resumes IIC operation with ACK
}
}
return uI2cData;
#elif (PCM_CODEC_NAME == WM8753)
uI2cData = uAddr;
uI2cDataCount = 1;
//Register Address Write Phase
IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));//Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
IICOutp32(rIICSTAT, 0x10); //IIC bus data output enable(Rx/Tx)
IICOutp32(rIICLC, (1<<2)|(1)); //Filter enable, 15 clocks SDA output delay
IICOutp32(rIICDS, uSlaveAddr);
IICOutp32(rIICSTAT, 0xf0); //MasTx,Start
while(uI2cDataCount!=-1)
{
if(IICInp32(rIICCON) & 0x10)
{ //Tx/Rx Interrupt Enable
if((uI2cDataCount--)==0)
{
break;
}
IICOutp32(rIICDS, uI2cData);
for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
IICOutp32(rIICCON, 0xaf); //resumes IIC operation.
}
}
uI2cDataCount = 1;
IICOutp32(rIICCON, (1<<7) | (0<<6) | (1<<5) | (0<<4) | (0xf));
//Register Data Read Phase
IICOutp32(rIICDS, uSlaveAddr);
IICOutp32(rIICSTAT, 0xb0); //Master Rx,Start
while(uI2cDataCount!=-1)
{
if(IICInp32(rIICCON) & 0x10) //Interrupt pending
{
if((uI2cDataCount--)==0)
{
uI2cData = IICInp32(rIICDS);
IICOutp32(rIICSTAT, 0x90); //Stop MasRx condition
IICOutp32(rIICCON, 0xaf); //Resumes IIC operation.
Delay(1); //Wait until stop condtion is in effect.
//Too long time...
//The pending bit will not be set after issuing stop condition.
break;
}
if((uI2cDataCount)==0)
IICOutp32(rIICCON, 0x2f); //Resumes IIC operation with NOACK.
else
IICOutp32(rIICCON, 0xaf); //Resumes IIC operation with ACK
}
}
return uI2cData;
#else
Assert(0);
#endif
}
void PCM_SelClkSrc(PCM_PORT ePort, PCM_CLKSRC eClkSrc)
{
u32 uClkSrc, uEpllCon0;
uClkSrc = Inp32SYSC(0x1C);
uEpllCon0 = Inp32SYSC(0x14);
if(ePort == PCM_PORT0)
{
if(eClkSrc == PCM_MOUT_EPLL)
{
Outp32SYSC(0x14, uEpllCon0 |(1u<<31));
Delay(100);
Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7) |(1<<2));
}
else if (eClkSrc == PCM_DOUT_MPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7)|(1<<7));
else if (eClkSrc == PCM_FIN_EPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7)|(2<<7));
else if (eClkSrc == PCM_PCMCDCLK) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<7)|(4<<7));
}
else if(ePort == PCM_PORT1)
{
if(eClkSrc == PCM_MOUT_EPLL)
{
Outp32SYSC(0x14, uEpllCon0 |(1u<<31));
Delay(100);
Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(1<<2));
}
else if (eClkSrc == PCM_DOUT_MPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(1<<10));
else if (eClkSrc == PCM_FIN_EPLL) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(2<<10));
else if (eClkSrc == PCM_PCMCDCLK) Outp32SYSC(0x1C, uClkSrc & ~(0x7<<10)|(4<<10));
}
}
void PCM_GetClkValAndClkDir(u32* uSclkDiv, u32* uSyncDiv, PCM_CLKSRC ePcmClkSrc)
{
double dTmpVal, dVclkSrc;
if(ePcmClkSrc == PCM_MOUT_EPLL)
dVclkSrc = 97700000; //should be changed according to your system clock condition
else if(ePcmClkSrc == PCM_DOUT_MPLL)
dVclkSrc = 100000000; //should be changed according to your system clock condition
else if(ePcmClkSrc == PCM_FIN_EPLL)
dVclkSrc = 12000000; //should be changed according to your system clock condition
else if(ePcmClkSrc == PCM_PCMCDCLK)
dVclkSrc = 512000;
else if(ePcmClkSrc == PCM_PCLK)
dVclkSrc = 25000000; //should be changed according to your system clock condition
dTmpVal = dVclkSrc/(double)(2*PCMSCLK) - 1;
dTmpVal = (dTmpVal+0.5)*10;
*uSclkDiv = (int)(dTmpVal/10.0);
dTmpVal = PCMSCLK/(double)(PCM_FS) - 1;
dTmpVal = (dTmpVal+0.5)*10;
*uSyncDiv = (int)(dTmpVal/10.0);
}
///////////////////////////////////////////////
void __irq Isr_PCM_PCMIn_DMADone(void)
{
INTC_Disable(oPcm.m_uNumDma);
Disp("\nPCM In DMA Done.\n");
uPcmRecDone = 1;
DMACH_ClearIntPending(&oPcmDma);
DMACH_ClearErrIntPending(&oPcmDma);
INTC_ClearVectAddr();
}
void __irq Isr_PCM_PCMOut_DMADone(void)
{
INTC_Disable(oPcm.m_uNumDma);
DMAC_InitCh(oPcm.m_eDmaUnit, oPcm.m_eDmaCh, &oPcmDma);
DMACH_ClearIntPending(&oPcmDma);
DMACH_ClearErrIntPending(&oPcmDma);
INTC_ClearVectAddr();
Disp("\n~~~");
INTC_Enable(oPcm.m_uNumDma);
DMACH_Setup(oPcm.m_eDmaCh, 0x0, (u32)PCM_REC_BUF, false, oPcm.m_uPcmRxFifoAddr, true, HWORD, PCM_REC_LEN/2, HANDSHAKE, MEM, oPcm.m_eDreqSrc , SINGLE, &oPcmDma);
DMACH_Start(&oPcmDma);
}
void __irq Isr_PCM_PCMIn(void)
{
u32 i, uPcmFifoStat;
INTC_Disable(oPcm.m_uNumInt);
INTC_ClearVectAddr();
PCM_ClearInt();
uPcmFifoStat = PCMInp32(rPCMFIFOSTAT);
for(i=0; i< ((uPcmFifoStat & 0x3f0)>>4); i++)
{
*(uPcmRecBuffer++) = (u16) PCMInp32(rPCMRXFIFO);
if(uPcmRecBuffer ==uPcmEndRecBuffer)
break;
}
if(uPcmRecBuffer ==uPcmEndRecBuffer)
uPcmRecDone=1;
INTC_Enable(oPcm.m_uNumInt);
}
void __irq Isr_PCM_PCMOut(void)
{
u32 i, uPcmFifoStat;
INTC_Disable(oPcm.m_uNumInt);
INTC_ClearVectAddr();
PCM_ClearInt();
uPcmFifoStat = PCMInp32(rPCMFIFOSTAT);
for(i=0; i< (32-((uPcmFifoStat & 0xfc000)>>14)); i++)
{
PCMOutp32(rPCMTXFIFO, *(uPcmRecBuffer++));
if(uPcmRecBuffer ==uPcmEndRecBuffer)
break;
}
if(uPcmRecBuffer ==uPcmEndRecBuffer)
uPcmPlayDone=1;
INTC_Enable(oPcm.m_uNumInt);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -