📄 i2s_control.c
字号:
#include <windows.h>
#include <xllp_i2s.h>
#include <xllp_i2c.h>
#include <bulverde.h>
#include <ceddk.h>
#include "i2s_control.h"
static volatile BULVERDE_IIS_REG *g_pI2sRegs = NULL;
static volatile BULVERDE_IICBUS_REG *g_pI2cRegs = NULL;
static volatile BULVERDE_OST_REG *g_pOSTRegs = NULL;
static volatile BULVERDE_INTR_REG *g_pICRegs = NULL;
static volatile BULVERDE_GPIO_REG *g_pGPIORegs = NULL;
static volatile BULVERDE_CLKMGR_REG *g_pClockRegs = NULL;
static BOOL g_IsI2SConfigured = FALSE;
BOOL InitializeI2S(BOOL InPowerHandler)
{
// Allocate I2S control resources.
//
if (!AllocateI2SResources())
{
return(FALSE);
}
if (!ConfigureI2SControl())
{
return(FALSE);
}
return(TRUE);
}
BOOL DeInitializeI2S(BOOL InPowerHandler)
{
if (!DeAllocateI2SResources())
{
return(FALSE);
}
return(TRUE);
}
BOOL AllocateI2SResources(void)
{
PHYSICAL_ADDRESS RegPA;
if (g_pICRegs == NULL)
{
RegPA.QuadPart = BULVERDE_BASE_REG_PA_INTC;
g_pICRegs = (volatile BULVERDE_INTR_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
}
if (g_pI2sRegs == NULL)
{
RegPA.QuadPart = BULVERDE_BASE_REG_PA_I2S;
g_pI2sRegs = (volatile BULVERDE_IIS_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
}
if (g_pI2cRegs == NULL)
{
RegPA.QuadPart = BULVERDE_BASE_REG_PA_I2C;
g_pI2cRegs = (volatile BULVERDE_IICBUS_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
}
if (g_pClockRegs == NULL)
{
RegPA.QuadPart = BULVERDE_BASE_REG_PA_CLKMGR;
g_pClockRegs = (volatile BULVERDE_CLKMGR_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
}
if (g_pGPIORegs == NULL)
{
RegPA.QuadPart = BULVERDE_BASE_REG_PA_GPIO;
g_pGPIORegs = (volatile BULVERDE_GPIO_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
}
if (g_pOSTRegs == NULL)
{
RegPA.QuadPart = BULVERDE_BASE_REG_PA_OST;
g_pOSTRegs = (volatile BULVERDE_OST_REG *) MmMapIoSpace(RegPA, 0x400, FALSE);
}
if (hI2cControlMutex == NULL)
{
hI2cControlMutex = CreateMutex(NULL, FALSE, I2C_MUTEX_NAME);
}
if (!g_pICRegs || !g_pI2sRegs || !g_pI2cRegs || !g_pClockRegs || !g_pGPIORegs || !g_pOSTRegs || !hI2cControlMutex)
{
DEBUGMSG(TRUE, (TEXT("ERROR: Failed to allocate I2S resources.\r\n")));
DeAllocateI2SResources();
return(FALSE);
}
return(TRUE);
}
BOOL DeAllocateI2SResources(void)
{
if (g_pI2sRegs)
{
VirtualFree((void *)g_pI2sRegs, 0, MEM_RELEASE);
g_pI2sRegs = NULL;
}
if (g_pI2cRegs)
{
VirtualFree((void *)g_pI2cRegs, 0, MEM_RELEASE);
g_pI2cRegs = NULL;
}
if (g_pICRegs)
{
VirtualFree((void *)g_pICRegs, 0, MEM_RELEASE);
g_pICRegs = NULL;
}
if (g_pClockRegs)
{
VirtualFree((void *)g_pClockRegs, 0, MEM_RELEASE);
g_pClockRegs = NULL;
}
if (g_pGPIORegs)
{
VirtualFree((void *)g_pGPIORegs, 0, MEM_RELEASE);
g_pGPIORegs = NULL;
}
if (g_pOSTRegs)
{
VirtualFree((void *)g_pOSTRegs, 0, MEM_RELEASE);
g_pOSTRegs = NULL;
}
if (hI2cControlMutex)
{
CloseHandle(hI2cControlMutex);
}
return(TRUE);
}
BOOL ConfigureI2SControl(void)
{
if (g_IsI2SConfigured)
{
return(TRUE);
}
if(g_pGPIORegs==NULL)
{
return (FALSE);
}
// clearing the GPIO's value to write the correct value in
g_pGPIORegs->GAFR0_U &= ~( XLLP_GPIO_AF_BIT_I2SBITCLK_IN_MASK |
( XLLP_GPIO_AF_BIT_I2S_SDATA_IN_MASK)|
( XLLP_GPIO_AF_BIT_I2S_SDATA_OUT_MASK)|
( XLLP_GPIO_AF_BIT_I2S_SYNC_MASK) );
g_pGPIORegs->GAFR3_U &= ~( XLLP_GPIO_AF_BIT_I2S_SYSCLK_MASK | XLLP_GPIO_AF_BIT_SCL_MASK |XLLP_GPIO_AF_BIT_SDA_MASK );
g_pGPIORegs->GPDR0 |= (XLLP_GPIO_BIT_I2SBITCLK|XLLP_GPIO_BIT_I2S_SDATA_OUT|XLLP_GPIO_BIT_I2S_SYNC);
g_pGPIORegs->GPDR0 &= ~XLLP_GPIO_BIT_I2S_SDATA_IN;
g_pGPIORegs->GPDR3 |= (XLLP_GPIO_BIT_I2S_SYSCLK );
// sets the alternate function to make the processor the master and the codec the slave
// and to generate the bit clock output
g_pGPIORegs->GAFR0_U |= ( ( XLLP_GPIO_AF_BIT_I2SBITCLK_OUT ) |
( XLLP_GPIO_AF_BIT_I2S_SDATA_IN )|
( XLLP_GPIO_AF_BIT_I2S_SDATA_OUT )|
( XLLP_GPIO_AF_BIT_I2S_SYNC) );
g_pGPIORegs->GAFR3_U |= ( XLLP_GPIO_AF_BIT_I2S_SYSCLK );
// ensuring the I2S clock is on
g_pClockRegs->cken |= XLLP_CLKEN_I2S;
//config i2c bus
if(!ConfigureI2CControl())
{
return(FALSE);
}
//enable I2S LINK
if(g_pI2sRegs)
{
g_pI2sRegs->saimr|= XLLP_SAIMR_RFS | XLLP_SAIMR_TFS;
g_pI2sRegs->sacr0|=XLLP_SACR0_BCKD;
g_pI2sRegs->sacr0|=XLLP_SACR0_ENB;
}
g_IsI2SConfigured = TRUE;
return(TRUE);
}
BOOL UnConfigureI2SControl(void)
{
if (!g_IsI2SConfigured)
{
return(TRUE);
}
g_IsI2SConfigured = FALSE;
return(TRUE);
}
BOOL GetI2cLock(void)
{
if (WaitForSingleObject(hI2cControlMutex, 3000) == WAIT_OBJECT_0)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
BOOL ReleaseI2cLock(void)
{
ReleaseMutex(hI2cControlMutex);
return(TRUE);
}
BOOL ReadI2SCodecRaw(UINT8 Offset, UINT16 *pData, UINT8 DevId)
{
XLLP_UINT8_T bytesBuf[2];
bytesBuf[0]=(UINT8)Offset;
if (XllpI2CWrite((P_XLLP_I2C_T) g_pI2cRegs,
(P_XLLP_OST_T) g_pOSTRegs,
(XLLP_UINT8_T) DevId,
(XLLP_UINT8_T *) bytesBuf,
1,
TRUE)!=XLLP_FALSE)
{
return (FALSE);
}
if (XllpI2CRead((P_XLLP_I2C_T) g_pI2cRegs,
(P_XLLP_OST_T)g_pOSTRegs,
(XLLP_UINT8_T) DevId,
(XLLP_UINT8_T *)bytesBuf,
2,
TRUE)!=XLLP_FALSE)
{
return(FALSE);
}
*pData=(bytesBuf[0]<<8) | (bytesBuf[1]);
return(TRUE);
}
BOOL ReadI2SCodec(UINT8 Offset, UINT16 *pData, UINT8 DevId)
{
BOOL retVal = FALSE;
if (GetI2cLock() == TRUE)
{
retVal = ReadI2SCodecRaw(Offset, pData, DevId);
ReleaseI2cLock();
}
return(retVal);
}
BOOL WriteI2SCodecRaw(UINT8 Offset, UINT16 Data, UINT8 DevId)
{
XLLP_UINT8_T bytesBuf[3];
bytesBuf[0]=(UINT8)(Offset);
bytesBuf[1]=(UINT8)((Data&0xff00)>>8);
bytesBuf[2]=(UINT8)(Data&0xff);
if (XllpI2CWrite((P_XLLP_I2C_T) g_pI2cRegs,
(P_XLLP_OST_T) g_pOSTRegs,
(XLLP_UINT8_T) DevId,
(XLLP_UINT8_T *) bytesBuf,
3,
TRUE)!=XLLP_FALSE)
{
return (FALSE);
}
return(TRUE);
}
BOOL WriteI2SCodec(UINT8 Offset, UINT16 Data, UINT8 DevId)
{
BOOL retVal = FALSE;
if (GetI2cLock() == TRUE)
{
retVal = WriteI2SCodecRaw(Offset, Data, DevId);
ReleaseI2cLock();
}
return(retVal);
}
BOOL ConfigureI2CControl(void)
{
if(XllpI2cInit((P_XLLP_I2C_T)g_pI2cRegs,
(P_XLLP_GPIO_T)g_pGPIORegs,
(P_XLLP_CLKMGR_T)g_pClockRegs,
XLLP_I2C_SLAVE_ID)==XLLP_TRUE)
{
return(FALSE);
}
return TRUE;
}
BOOL UnConfigureI2CControl(void)
{
return TRUE;
}
////Set the sample rate for the I2S interface.
BOOL SetI2sSampleRate(UINT16 SampleRate)
{
if(g_pI2sRegs==NULL)
return FALSE;
switch(SampleRate) {
case SR_8000:
g_pI2sRegs->sadiv = 0x48; //appx 8 khz
break;
case SR_11025:
g_pI2sRegs->sadiv = 0x34; //appx 11.025 khz
break;
case SR_16000:
g_pI2sRegs->sadiv = 0x24; //appx 16 khz
break;
case SR_22050:
g_pI2sRegs->sadiv = 0x1a; //appx 22.05 khz
break;
case SR_44100:
g_pI2sRegs->sadiv = 0xd; //appx 44.1khz
break;
case SR_48000:
g_pI2sRegs->sadiv = 0xc; //appx 48khz
break;
default:
return(FALSE);
break;
}
return TRUE;
}
//Get the sample rate for the I2S interface.
BOOL GetI2sSampleRate(UINT16 *SampleRate)
{
if(g_pI2sRegs==NULL)
return FALSE;
switch(g_pI2sRegs->sadiv) {
case 0x48:
*SampleRate=SR_8000; //8k
break;
case 0x34:
*SampleRate=SR_11025; //11k
break;
case 0x24:
*SampleRate=SR_16000; //16k
break;
case 0x1a:
*SampleRate=SR_22050; //22.05KHZ
break;
case 0xd:
*SampleRate=SR_44100; //44.100KHZ
break;
case 0xc:
*SampleRate=SR_48000; //48KHZ
break;
default:
return(FALSE);
break;
}
return (TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -