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

📄 i2saudio.cpp

📁 EP9315开发板的Wince6.0的BSP包文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    //
    // Enable the I2S transmitt channel 0.
    //
    *SAI_TX0_EN     = 1;

    Sleep(1);
    ulCount2 = 0;
    ulTemp = 0x800000;
    for(ulCount = 0; ;ulCount ++)
    {
        if(ulCount& 0x40)
        {
            ulTemp = ulMax;
        }
        else
        {
            ulTemp = ulMin;
        }
        ulJunk          = *SAI_TX0_LEFT;
        ulJunk          = *SAI_TX0_RIGHT;

        while(!( *SAI_GSR & GSR_TX0_FIFO_HALF_EMPTY))
        {
            if(ulCount2++>10000000)
            {
                *SAI_GSR = 0;
                Initialize();
                *SAI_TX0_EN     = 1;
                Sleep(1);
                break;
            }
        };
        *SAI_TX0_LEFT   = ulTemp;
        *SAI_TX0_RIGHT  = ulTemp;

    }
}

//****************************************************************************
// I2SCodec::ReadAllCodecReg
//****************************************************************************
// For Debug only.
// 
// Reads all of the I2C registers.
void I2SCodec::ReadAllCodecReg(void)
{
    UCHAR ucCodecReg, ucValue;
    for(ucCodecReg = 1; ucCodecReg < 0xE; ucCodecReg++)
    {
        ReadCodecReg(ucCodecReg, &ucValue);
    }
}

//****************************************************************************
// DelayuS
//****************************************************************************
// Delays a certian number of microseconds.
// 
//
void DelayuS(ULONG ulMicroSec)
{
    LARGE_INTEGER liStart, liCurrent;
    BOOL b;
    b = QueryPerformanceCounter(&liStart);
    ASSERT(b);
    
    do
    {
        Sleep(0);
        b = QueryPerformanceCounter(&liCurrent);
        ASSERT(b);
    } while((liStart.QuadPart + (LONGLONG)ulMicroSec) >=liCurrent.QuadPart);
}



//****************************************************************************
// I2SCodec::WriteCodecSPI
//****************************************************************************
// Writes a codec register using SPI.
// 
//
MMRESULT I2SCodec::WriteCodecReg(UCHAR ucRegAddr, UCHAR ucRegValue)
{
    ULONG   ulSPIStatus;
    ULONG   ulTimeOut;

#ifdef CS4288_TWO_READ_MODE
	if( m_bTwoWire )
	{
		return WriteCodecRegNOSPI( ucRegAddr, ucRegValue);
	}
	else
#endif
	{
		// Wait for the the fifo to be empty.
		//       
		for(ulTimeOut = 0;;ulTimeOut++)
		{
			ulSPIStatus = *SPI_SR;
			if(ulSPIStatus & SPISR_TFE)
				break;

			Sleep(2);

			if(ulTimeOut >50)
			{
				ERRMSG
				((
					L"I2SCodec::WriteCodecSSP Write timeout on register 0x%02x\r\n",  
					(ULONG)ucRegAddr 
				));
			}
		}
		//
		// Write out the chip address for the CS4228.
		//
		*SPI_DR = 0x20;
		*SPI_DR = (ULONG)ucRegAddr;
		*SPI_DR = (ULONG)ucRegValue;

		//
		// Wait for the the fifo to be empty.
		//       
		for(ulTimeOut = 0;;ulTimeOut++)
		{
			ulSPIStatus = *SPI_SR;

			Sleep(2);

			if(ulSPIStatus & SPISR_TFE)
				break;

			if(ulTimeOut >50)
			{
				ERRMSG
				((
					L"I2SCodec::WriteCodecSSP Write timeout on register 0x%02x\r\n",  
					(ULONG)ucRegAddr 
				));
			}
		}

		return (MMSYSERR_NOERROR);
	}
}


//****************************************************************************
// SetSPIToI2S
//****************************************************************************
// This is currently a hack to get audio working on the Videon Central
// board.  I need to fix this later.
// 
//
void SetSPIToI2S(unsigned long ulCodec)
{
#if (EP93XX_PLATFORM_TYPE== EDB9307) ||  (EP93XX_PLATFORM_TYPE== EDB9312)  || (EP93XX_PLATFORM_TYPE== EDB9315) 

    ULONG   ulTemp;
    //
    // Set GPIO pins 12 and 14 as outputs.  They are used in the ps2 keyboard 
    // interface.  

    ulTemp           = *GPIO_PBDDR;
    *GPIO_PBDDR      = 0x50 | ulTemp;

    //
    // Clear GPIO pins 12 and 14.
    //    
    ulTemp           = *GPIO_PBDR;
    *GPIO_PBDR       = 0x50 | ulTemp ;

#endif 
    if(ulCodec == 4228)
    {
        //
        // Configure EGPIO7 as an output and set it.  This selects
        // I2S codec as the device on the SSP output instead of 
        // the serial flash (on an EP9312).
        // 
        HalWriteCommonReg(GPIO_PADDR,0x80,0x80);

        HalWriteCommonReg(GPIO_PADR,0x80,0x80);
        //
        // Configure EGPIO8 as an output and set it.  This selects
        // I2S codec as the device on the SSP output (on an EP9315 & EP9307).
        // 
        HalWriteCommonReg(GPIO_PBDDR,0x1,0x1);

        HalWriteCommonReg(GPIO_PBDR,0x1,0x0);
    }

    if(ulCodec == 4271)
    {
        //
        // Configure EGPIO6 as an output and set it.  This selects
        // I2S codec as the device on the SSP (on an EP9301).
        // 
        HalWriteCommonReg(GPIO_PADDR,0x40,0x40);

        HalWriteCommonReg(GPIO_PADR,0x40,0x00);
    }

    //
    // Sleep a couple Milliseconds.  Hopefully the keyboard will get
    // any characters in the fifo.
    //
    Sleep(2);
    
    //
    // SPICR0_SPO - SCLKOUT Polarity
    // SPICR0_SPH - SCLKOUT Phase
    // Motorola format, 10 bit, one start, 8 data, one bit for parity, 
    // one stop bit.
    //
    *SPI_CR0        = SPICR0_SPO| SPICR0_SPH |SPICR0_FRF_MOTOROLA  | 
                      (SPICR0_DSS_MASK & (8 -1));
    //
    // Configure the device as a slave, enable interrupts and 
    // reset the device.
    //
    *SPI_CR1        = 0;  
    *SPI_CR1        = SPICR1_SSE;  
}


//****************************************************************************
// SetSPIToPS2
//****************************************************************************
// This is currently a hack to get audio working on the Videon Central
// board.  I need to fix this later.
// 
//
void SetSPIToPS2(unsigned long ulCodec)
{
#if (EP93XX_PLATFORM_TYPE== EDB9307) ||  (EP93XX_PLATFORM_TYPE== EDB9312)  || (EP93XX_PLATFORM_TYPE== EDB9315) 
    ULONG   ulTemp;

    //
    // Clear GPIO pins 12 and 14.
    
    ulTemp           = *GPIO_PBDR;
    *GPIO_PBDR       = (~0x50) & ulTemp ;
#endif 

    if(ulCodec == 4228)
    {
        //
        // Clear EGPIO7.  This de-selects
        // I2S codec as the device on the SSP output (on an EP9312).
        // 
        HalWriteCommonReg (GPIO_PADDR,0x80,0x00);

        HalWriteCommonReg(GPIO_PADR,0x80,0x00);
        //
        // Set EGPIO8.  This de-selects I2S codec as the device on the SSP 
        // output (on an EP9315 & EP9307).
        // 
        HalWriteCommonReg(GPIO_PBDDR,0x1,0x1);

        HalWriteCommonReg(GPIO_PBDR,0x1,0x1);
    }

    if(ulCodec == 4271)
    {
        //
        // Clear EGPIO6.  This de-selects I2S codec as the device on the SSP 
        // output (on an EP9301).
        // 
        HalWriteCommonReg(GPIO_PADDR,0x40,0x00);

        HalWriteCommonReg(GPIO_PADR,0x40,0x40);
    }
    //
    // SPICR0_SPO - SCLKOUT Polarity
    // SPICR0_SPH - SCLKOUT Phase
    // Motorola format, 10 bit, one start, 8 data, one bit for parity, 
    // one stop bit.
    //
    *SPI_CR0        = SPICR0_SPO| SPICR0_SPH |SPICR0_FRF_MOTOROLA  | 
                      (SPICR0_DSS_MASK & (11 -1));
    
    //
    // Configure the device as a slave, enable interrupts and 
    // reset the device.
    //
    *SPI_CR1        = SPICR1_MS | SPICR1_RIE;
    *SPI_CR1        = SPICR1_MS | SPICR1_RIE | SPICR1_SSE;  
}





void I2SReset( void )
{
    HalWriteCommonReg
    (
        CSC_DEVCFG, 
        DEVCFG_I2SONSSP | DEVCFG_I2SONAC97,
        DEVCFG_I2SONAC97
    );

    //
    // Disable all transmit audio channels.
    // Disable all recieve audio channels.
    // Set the global configuration register to Disable PCLK to it.
    //
    *SAI_TX0_EN = *SAI_TX1_EN =* SAI_TX2_EN   = 0;
    *SAI_RX0_EN = *SAI_RX1_EN =* SAI_RX2_EN   = 0;
    *SAI_GCR                                  = 0;

    //
    // Initialize the SAI interface. 
    //
    *SAI_TX_CLKCFG = CLKCFG_MST | CLKCFG_TREL ;  //the right-left channel is reversed if setting this bit.
//    *SAI_TX_CLKCFG = CLKCFG_MST | CLKCFG_TREL | CLKCFG_POLARITY;
//    *SAI_RX_CLKCFG = CLKCFG_MST | CLKCFG_TREL | CLKCFG_NBCG | CLKCFG_POLARITY;
    *SAI_RX_CLKCFG = CLKCFG_MST | CLKCFG_TREL | CLKCFG_NBCG ;

    //
    // Left justified, MSB first, Repeat zero if underflow.
    // Outputing zero's will cause the dac to mute.
    //
//    *SAI_TX_LCR     = TX_LCR_UNDERFLOW_ZERO;
    *SAI_TX_LCR     = 0;
    
    //
    // Generate a Interrupt on Halfempty
    // (Don't think this makes a difference for DMA.)
    //
    *SAI_TX_CR     = TX_CR_TXUFIE;

    //
    // Transmit word length. I don't think this matters in Left Justified
    // mode.
    //
    *SAI_TX_WL      = WL_24BIT;

    //
    // Left justified, MSB first.
    //
    *SAI_RX_LCR     = 0;

    //
    // Generate a Interrupt on Half full
    // (Don't think this makes a difference for DMA.)
    //
    *SAI_RX_CR     = RX_CR_OVERFLOW_INT;

    //
    // Receive word length. I don't think this matters in Left Justified
    // mode.
    //
    *SAI_RX_WL      = WL_24BIT;

    //
    // Set the global configuration register to enable PCLK to it.
    //
    *SAI_GCR        = GCR_PCLK;


    *SPI_CR0        = SPICR0_SPO| SPICR0_SPH |SPICR0_FRF_MOTOROLA  | 
                      (SPICR0_DSS_MASK & (11 -1));
    
    //
    // Configure the device as a slave, enable interrupts and 
    // reset the device.
    //
    *SPI_CR1        = SPICR1_MS | SPICR1_RIE;
    *SPI_CR1        = SPICR1_MS | SPICR1_RIE | SPICR1_SSE;  

}

#define ZONE_MIXER	1

DWORD  I2SCodec::	MixerVolumeSettings( DWORD dwCode ,DWORD dwControl, DWORD dwSetting)
{
	DWORD *pdwSetting=(DWORD *)dwSetting;
	DWORD dwRet= MMSYSERR_NOERROR;

	if( dwCode == WPDM_GETMIXERVAL )
	{
		switch (dwControl) {
			case WPDMX_MASTER_VOL:
				RETAILMSG(ZONE_MIXER, (TEXT("WPDMX_MASTER_VOL\r\n")));
				*pdwSetting=m_VolumeSettings.dwMasterVolume;
				break;
			case WPDMX_MASTER_MUTE:
				RETAILMSG(ZONE_MIXER, (TEXT("WPDMX_MASTER_MUTE\r\n")));
				*pdwSetting = m_VolumeSettings.fMasterMute;
				break;
			case WPDMX_LINEIN_VOL:
				RETAILMSG(ZONE_MIXER, (TEXT("WPDMX_LINEIN_VOL\r\n")));
				*pdwSetting = m_VolumeSettings.dwLineInVolume;
				break;
			case WPDMX_LINEIN_MUTE:
				RETAILMSG(ZONE_MIXER, (TEXT("WPDMX_LINEIN_MUTE\r\n")));
				*pdwSetting = m_VolumeSettings.fLineInMute;
				break;
			case WPDMX_MIC_VOL:
				RETAILMSG(ZONE_MIXER, (TEXT("WPDMX_MIC_VOL\r\n")));
				*pdwSetting = m_VolumeSettings.dwMicVolume;
				break;
			case WPDMX_MIC_MUTE:
				RETAILMSG(ZONE_MIXER, (TEXT("WPDMX_MIC_MUTE\r\n")));
				*pdwSetting = m_VolumeSettings.fMicMute;
				break;
			case WPDMX_INPUT_MUX:
				RETAILMSG(ZONE_MIXER, (TEXT("WPDMX_INPUT_MUX\r\n")));
				*pdwSetting = m_VolumeSettings.dwInputSelect;
				break;
			default:
				RETAILMSG(1, (TEXT("private_GetMixerValue: unrecognized control %d"), dwControl));
				dwRet= MMSYSERR_NOTSUPPORTED;
				break;
		}
		RETAILMSG(1, (TEXT("private_GetMixerValue(%04x, %08x)\r\n"), dwControl, *pdwSetting));
	}
	else if( dwCode ==	WPDM_SETMIXERVAL )
	{
		//ULONG   ulRight, ulLeft;

		RETAILMSG(1, (TEXT("private_SetMixerValue(%04x, %08x)\r\n"), dwControl, dwSetting));
   
		switch (dwControl) {
			// volume controls
			case WPDMX_MASTER_VOL:
				SetVolume( dwSetting>>16 , dwSetting&0xFFFF, 0 );
				m_VolumeSettings.dwMasterVolume =dwSetting;
				break;
			case WPDMX_LINEIN_VOL:
				m_Volum

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -