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

📄 i2s_control.c

📁 realtek562x系列驱动源码。wince
💻 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 + -