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

📄 hssi.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 5 页
字号:
		SSICR_TX.bits.DEL  = 1;	// Serial Data no Delay
		SSICR_TX.bits.BREN = 0;	// Burst Mode Disable
		SSICR_TX.bits.CKDV = 3; // Serial Oversample Clock Divide Ratio
		SSICR_TX.bits.MUEN = 0;	// Mute disable
		SSICR_TX.bits.CPEN = 0;	// Compress mode disable
		SSICR_TX.bits.TRMD = 1;	// Transmit mode
		SSICR_TX.bits.EN   = 0;	// SSI Disable
		RegValue = SSICR_TX.AsDWORD;
		WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
	}

	data_count = 0;

	FUNC_WPDD("-hssi_txstart");
	return;
}


/*****************************************************************************
*   FUNCTION :  	module_rxstart
*   DESCRIPTION :	HSSI Rx Start
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
VOID
module_rxstart(
   VOID
   )
{
	ULONG	RegValue;
unsigned char DSPmaster[5][2] = {
//{Register Pointer, Value}
{CODEC_CMB, 	0x00},		//*0:(01h)Clock Mode Byte(CO1乣CO0,CI1乣CI0)
							//		if 11.025kHz then ch0:0x52,ch1:0x50,ch2/3:0x40
{CODEC_DSP_PMB,	0xe8},		//*1:(0Eh)DSP Port Mode Byte(DCK1乣DCK0,DSCK)
							//		slave:0xc8,master:0xe8
{CODEC_APMB,	0xe8},		//*2:(0Fh)Auxiliary Port Mode Byte(ACK1乣ACK0,AMS1乣AMS0,ASCK)
							//		slave:0x00,master:0xe8
{CODEC_DAC_CB,	0x3f},		//*3:(03h)DAC Control Byte(ZCD,MUTC)
{CODEC_NONE,	0x00}};		// 4:delimiter

	FUNC_WPDD("+hssi_rxstart");

	DSPmaster[0][1] = CS4226_REC_CMB;
	DSPmaster[1][1] = CS4226_REC_DSP_PMB;
	DSPmaster[2][1] = CS4226_REC_APMB;
	if(PlayOpenFlag == 0){
		DSPmaster[3][1] = CS4226_DACCB_MUTE;
	}
	else{
		DSPmaster[3][1] = CS4226_DACCB_NORMAL;
	}

	//Stop SSI
	WRITE_REGISTER_ULONG((PULONG)pSSI_CR_RX, (ULONG)(SSICR_RX.AsDWORD & SSI_DISABLE_MASK) );	// Disable SSI

	if(CS4226_ReadADDR == SSI1_CS4226_ReadADDR){
		// stop playback only ch1
		WRITE_REGISTER_ULONG((PULONG)pSSI_CR_TX, (ULONG)(0x00000000) );	// Disable SSI for TX
	}

	if ( ulDSPMode != DSPmaster[1][1] || ulDACControl != DSPmaster[3][1] ){
		if(I2C_SetCODEC(DSPmaster)){
			ulDSPMode = DSPmaster[1][1];
			ulDACControl = DSPmaster[3][1];
		}
	}

	// Set SSI Control Register
	if(CS4226_ReadADDR == SSI2_CS4226_ReadADDR){
		if(PlayOpenFlag == 0){
			// ch3 need ch2's clock
			SSICR_TX.bits.Reserved = 0;
			SSICR_TX.bits.DMEN = 0;	// DMA Disable
			SSICR_TX.bits.UIEN = 0;	// Underflow IRQ disable
			SSICR_TX.bits.OIEN = 0;	// Overflow IRQ disable
			SSICR_TX.bits.IIEN = 0;	// Idle Mode IRQ disable
			SSICR_TX.bits.DIEN = 0;	// Data IRQ disable
			SSICR_TX.bits.CHNL = 0;	// Channels
			SSICR_TX.bits.DWL  = 3;	// Data Word Length 20 bit
			SSICR_TX.bits.SWL  = 3;	// System Word Length 32 bit
			SSICR_TX.bits.SCKD = SSI_PLAY_MODE;	// Serial Clock Output(Master)
			SSICR_TX.bits.SWSD = SSI_PLAY_MODE;	// Serial WS Output(Master)
			SSICR_TX.bits.SCKP = 1;	// Serial Clock Polarity falling edge
			SSICR_TX.bits.SWSP = 1;	// Serial WS Polarity High for Left
			SSICR_TX.bits.SPDP = 0;	// Serial Padding Polarity Low
			SSICR_TX.bits.SDTA = 1;	// Serial Data Alignment Right
			SSICR_TX.bits.PDTA = 1;	// Parallel Data Alignment Right
			SSICR_TX.bits.DEL  = 1;	// Serial Data no Delay
			SSICR_TX.bits.BREN = 0;	// Burst Mode Disable
			SSICR_TX.bits.CKDV = 3; // Serial Oversample Clock Divide Ratio
			SSICR_TX.bits.MUEN = 0;	// Mute disable
			SSICR_TX.bits.CPEN = 0;	// Compress mode disable
			SSICR_TX.bits.TRMD = 1;	// Transmit mode
			SSICR_TX.bits.EN   = 0;	// SSI Disable
			RegValue = SSICR_TX.AsDWORD;
			WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
		}
	}

	SSICR_RX.bits.Reserved = 0;
	SSICR_RX.bits.DMEN = 0;	// DMA Disable
	SSICR_RX.bits.UIEN = 0;	// Underflow IRQ disable
	SSICR_RX.bits.OIEN = 0;	// Overflow IRQ disable
	SSICR_RX.bits.IIEN = 0;	// Idle Mode IRQ disable
	SSICR_RX.bits.DIEN = 0;	// Data IRQ disable
	SSICR_RX.bits.CHNL = 0;	// Channels
	SSICR_RX.bits.DWL  = 3; // Data Word Length 20 bit
	SSICR_RX.bits.SWL  = 3;	// System Word Length 32 bit
	SSICR_RX.bits.SCKD = SSI_REC_MODE;	// Serial Clock Output
	SSICR_RX.bits.SWSD = SSI_REC_MODE;	// Serial WS Output
	SSICR_RX.bits.SCKP = 1;	// Serial Clock Polarity falling edge
	SSICR_RX.bits.SWSP = 1;	// Serial WS Polarity High for Left
	SSICR_RX.bits.SPDP = 0;	// Serial Padding Polarity Low
	SSICR_RX.bits.SDTA = 1;	// Serial Data Alignment Right
	SSICR_RX.bits.PDTA = 1;	// Parallel Data Alignment Right
	SSICR_RX.bits.DEL  = 1;	// Serial Data no Delay
	SSICR_RX.bits.BREN = 0;	// Burst Mode Disable
	SSICR_RX.bits.CKDV = 3;	// Serial Oversample Clock Divide Ratio
	SSICR_RX.bits.MUEN = 0;	// Mute disable
	SSICR_RX.bits.CPEN = 0;	// Compress mode disable
	SSICR_RX.bits.TRMD = 0;	// Receive mode
	SSICR_RX.bits.EN   = 0;	// SSI Disable
	RegValue = SSICR_RX.AsDWORD;
	WRITE_REGISTER_ULONG(pSSI_CR_RX, RegValue);

	FUNC_WPDD("-hssi_rxstart");
	return;
}

/*****************************************************************************
*   FUNCTION :  	private_ChangeSampleRate
*   DESCRIPTION :   Change sampling rate for DAC
*   INPUTS :		SampleRate - Sampling Rate
*   OUTPUTS :     	Return TRUE for success, FALSE for failure
*   DESIGN NOTES :
*   CAUTIONS :		
*****************************************************************************/
BOOL private_ChangeSampleRate(
		ULONG SampleRate
		)
{
	// do nothing
	return TRUE;
}


/*****************************************************************************
*   FUNCTION :  	private_ChangeRecSampleRate
*   DESCRIPTION :   Change sampling rate for ADC
*   INPUTS :		SampleRate - Sampling Rate
*   OUTPUTS :     	Return TRUE for success, FALSE for failure
*   DESIGN NOTES :
*   CAUTIONS :		
*****************************************************************************/
BOOL private_ChangeRecSampleRate(
		ULONG SampleRate
		)
{
	// do nothing
	return TRUE;
}

/*****************************************************************************
*   FUNCTION :  	AudioFillBuffer_M8
*   DESCRIPTION :	convert sample and fill audio DMA buffer(8bit Mono)
*   INPUTS :		pSrcPtr - wave audio data Address
*                   pDstPtr - Audio Buffer Address
*                   ulSrcSampleCount - Sampling count
*                   nIncreasing - The coefficient for increasing data
*   OUTPUTS :     	None
*   DESIGN NOTES :  Soft-ware Sampling Rate Convert
*                   (11.025kHz and 22.05kHz to 44.1kHz)
*                   convert 8bit to 20bit and mono to stereo
*   CAUTIONS :		
*****************************************************************************/
VOID
AudioFillBuffer_M8 (
	PBYTE pSrcPtr,
	PULONG pDstPtr,
	ULONG ulSrcSampleCount,
	ULONG nIncreasing
    )
{
    ULONG       sample;
	ULONG n;

    while (ulSrcSampleCount > 0) {
        sample = *pSrcPtr++;
		sample -= 128;
		sample <<= 12;
		for(n=0; n<nIncreasing; n++){
			*pDstPtr++ = sample;
	        *pDstPtr++ = sample;
		}
		ulSrcSampleCount--;
    }
}

/*****************************************************************************
*   FUNCTION :  	AudioFillBuffer_S8
*   DESCRIPTION :	convert sample and fill audio DMA buffer(8bit Stereo)
*   INPUTS :		pSrcPtr - wave audio data Address
*                   pDstPtr - Audio Buffer Address
*                   ulSrcSampleCount - Sampling count
*                   nIncreasing - The coefficient for increasing data
*   OUTPUTS :     	None
*   DESIGN NOTES :  Soft-ware Sampling Rate Convert
*                   (11.025kHz and 22.05kHz to 44.1kHz)
*                   convert 8bit to 20bit
*   CAUTIONS :		
*****************************************************************************/
VOID
AudioFillBuffer_S8 (
	PBYTE pSrcPtr,
	PULONG pDstPtr,
	ULONG ulSrcSampleCount,
	ULONG nIncreasing
    )
{
    ULONG       l_sample, r_sample;
	ULONG n;

    while (ulSrcSampleCount > 0) {
        l_sample = *pSrcPtr++;
		l_sample -= 128;
		l_sample <<=  12;
        r_sample = *pSrcPtr++;
		r_sample -= 128;
		r_sample <<=  12;
		for(n=0; n<nIncreasing; n++){
			*pDstPtr++ = l_sample;
			*pDstPtr++ = r_sample;
		}
		ulSrcSampleCount--;
    }
}

/*****************************************************************************
*   FUNCTION :  	AudioFillBuffer_M16
*   DESCRIPTION :	convert sample and fill audio DMA buffer(16bit Mono)
*   INPUTS :		pSrcPtr - wave audio data Address
*                   pDstPtr - Audio Buffer Address
*                   ulSrcSampleCount - Sampling count
*                   nIncreasing - The coefficient for increasing data
*   OUTPUTS :     	None
*   DESIGN NOTES :  Soft-ware Sampling Rate Convert
*                   (11.025kHz and 22.05kHz to 44.1kHz)
*                   convert 16bit to 20bit and mono to stereo
*   CAUTIONS :		
*****************************************************************************/
VOID
AudioFillBuffer_M16 (
	PUSHORT pSrcPtr,
	PULONG pDstPtr,
	ULONG ulSrcSampleCount,
	ULONG nIncreasing
    )
{
	ULONG n;
	ULONG sample;

    while (ulSrcSampleCount > 0) {
		sample = *pSrcPtr++;
		sample <<= 4;
		for(n=0; n<nIncreasing; n++){
			*pDstPtr++ = sample;
			*pDstPtr++ = sample;
		}
		ulSrcSampleCount--;
    }
}

/*****************************************************************************
*   FUNCTION :  	AudioFillBuffer_S16
*   DESCRIPTION :	convert sample and fill audio DMA buffer(16bit Stereo)
*   INPUTS :		pSrcPtr - wave audio data Address
*                   pDstPtr - Audio Buffer Address
*                   ulSrcSampleCount - Sampling count
*                   nIncreasing - The coefficient for increasing data
*   OUTPUTS :     	None
*   DESIGN NOTES :  Soft-ware Sampling Rate Convert
*                   (11.025kHz and 22.05kHz to 44.1kHz)
*                   convert 16bit to 20bit
*   CAUTIONS :		
*****************************************************************************/
VOID
AudioFillBuffer_S16 (
	PUSHORT pSrcPtr,
	PULONG pDstPtr,
	ULONG ulSrcSampleCount,
	ULONG nIncreasing
    )
{
	ULONG n;
    ULONG       l_sample, r_sample;

    while (ulSrcSampleCount > 0) {
		l_sample = *pSrcPtr++;
		l_sample = l_sample<<4;
		r_sample = *pSrcPtr++;
		r_sample = r_sample<<4;
		for(n=0; n<nIncreasing; n++){
			*pDstPtr++ = l_sample;
			*pDstPtr++ = r_sample;
		}
		ulSrcSampleCount--;
    }
}

/*****************************************************************************
*   FUNCTION :  	private_AudioFillBuffer
*   DESCRIPTION :   fills next buffer from given wave
*					toggles ready/empty pointers to double buffer
*   INPUTS :		wave
*   OUTPUTS :     	None
*   DESIGN NOTES :
*   CAUTIONS :
*****************************************************************************/
VOID
private_AudioFillBuffer (
    PWAVEHDR pwh
    )
{
	const PPCMWAVEFORMAT pFormat = (PPCMWAVEFORMAT) g_pwfx[WAPI_OUT];
	ULONG		samplingRate;
	ULONG		*lpAudioBuffer;
	LONG nDstLen, nSrcLen;
	ULONG nSampleCount,nSampleUnit;
	LONG	nIncreasing = 1;
	ULONG	CODEC_SAMPLING_RATE;
    volatile DWORD dwDummy; // used to synchronize data fill and DMA

	FUNC_VERBOSE("+PDD_AudioFillBuffer");

	//Set terminal condition for double-buffer and exit if no data remains

	if (pwh == NULL) 
	{
		pDriverGlobals->aud[AUDIO_NO].play_address = (ULONG)NULL;
		return;
	}

	//
	// For this line, the number of bytes from this audio stream
	// depends on the dma_buffer_size and the sample rate of the stream
	//
	// What's the maximum number of samples from this stream are needed
	// to fill the DMA buffer?
	//
	switch (g_pcmtype[WAPI_OUT])
	{
	case PCM_TYPE_S16:
        nSampleUnit = 4; // 2 words per sample unit
		break;

	case PCM_TYPE_M16:
        nSampleUnit = 2; // 1 word per sample unit
		break;

	case PCM_TYPE_S8:
        nSampleUnit = 2;  // 2 bytes per sample unit
		break;

	case PCM_TYPE_M8:
        nSampleUnit = 1;  // 1 byte per sample unit
		break;

	}  // end switch

	samplingRate = pFormat->wf.nSamplesPerSec;
	CODEC_SAMPLING_RATE = get_CODEC_SAMPLING_RATE(pDriverGlobals->aud[AUDIO_NO].PLAY_CH);
	nIncreasing = CODEC_SAMPLING_RATE / samplingRate;	// The coefficient for increasing data
	lpAudioBuffer = (ULONG *)(pAudioBufferBase  + v_nNextPage * AUDIO_DMA_PAGE_SIZE);

    nDstLen = AUDIO_DMA_PAGE_SIZE / (sizeof(ULONG) * 2 * nIncreasing);

	//
	// For each sample in the buffer...
	//
    while (nDstLen > 0) {
        nSrcLen = pwh->dwBufferLength - pwh->dwBytesRecorded;
		if (nSrcLen <= 0)
		{
			pwh = pwh->lpNext;
            if (pwh == NULL)
				break; // The rest of the buffer will be cleared later.
		}
		else
		{
            nSampleCount = nSrcLen  / nSampleUnit;
            if (nDstLen < (LONG)nSampleCount) nSampleCount = nDstLen;

			switch (g_pcmtype[WAPI_OUT])
			{
			case PCM_TYPE_S16:
				AudioFillBuffer_S16((PUSHORT)(pwh->lpData + pwh->dwBytesRecorded), (PULONG)lpAudioBuffer,
									nSampleCount, nIncreasing);
				break;

			case PCM_TYPE_M16:
				AudioFillBuffer_M16((PUSHORT)(pwh->lpData + pwh->dwBytesRecorded), (PULONG)lpAudioBuffer,
									nSampleCount, nIncreasing);
				break;

			case PCM_TYPE_S8:
				AudioFillBuffer_S8((PBYTE)(pwh->lpData + pwh->dwBytesRecorded), (PULONG)lpAudioBuffer,
									nSampleCount, nIncreasing);
				break;

			case PCM_TYPE_M8:
				AudioFillBuffer_M8((PBYTE)(pwh->lpData + pwh->dwBytesRecorded), (PULONG)lpAudioBuffer,
									nSampleCount, nIncreasing);
				break;

			}  // end switch
			pwh->dwBytesRecorded += (nSampleCount * nSampleUnit)  ;

            nDstLen -= nSampleCount;
            lpAudioBuffer += (2 * nSampleCount * nIncreasing);
		}
	}

    // pad with silence if necessary
    memset(lpAudioBuffer, 0, nDstLen * sizeof(ULONG) * 2 * nIncreasing);

⌨️ 快捷键说明

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