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

📄 hssi.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 5 页
字号:
	BOOL bPrint	)
{
	DWORD	dwSize;
	BYTE	bData;
	unsigned char Buffer[2];

	dwSize = 2;
	Buffer[0] = CS4226_WriteADDR;
	Buffer[1] = codec_Map;
	WriteFile(hCom, (LPVOID)Buffer, dwSize, &dwSize, NULL);
	if ( !dwSize ){
		DEBUGMSG(ZONE_ERROR, (TEXT("I2C_ReadCODEC(Write) Error! : <I2C 0x%02x> %02x (%d)\r\n"), CS4226_WriteADDR, codec_Map, GetLastError()));
	}

	dwSize = 1;
	Buffer[0] = CS4226_ReadADDR;
	ReadFile(hCom, (LPVOID)Buffer, dwSize, &dwSize, NULL);
	if ( !dwSize ){
		DEBUGMSG(ZONE_ERROR, (TEXT("I2C_ReadCODEC(Read) Error! : <I2C 0x%02x> %02x (%d)\r\n"), CS4226_ReadADDR, codec_Map, GetLastError()));
	}
	else{
		bData = Buffer[0];
		if ( bPrint == TRUE ){
			DEBUGMSG(ZONE_TEST, (TEXT("<I2C 0x%02x> Address : 0x%02x  Data : 0x%02x\r\n"), CS4226_ReadADDR, codec_Map, bData));
		}
	}
	return bData;
}

/*****************************************************************************
*   FUNCTION :  	I2C_SetCODEC
*   DESCRIPTION :   set data to cs4226 codec
*   INPUTS :		I2Cdata    [][0] cs4226 register address
*                              [][1] cs4226 register data
*                                    last entry must be (CODEC_NONE, 0)
*   OUTPUTS :     	Return TRUE for success, FALSE for failure
*   DESIGN NOTES :
*   CAUTIONS :		
*****************************************************************************/
BOOL
I2C_SetCODEC(
   unsigned char I2Cdata[][2]
   )
{
	DWORD	n;
	HANDLE	hI2C;
	DWORD	dwData;
	DWORD	dwRet;

	FUNC_WPDD("+I2C_SetCODEC");

	// Get I2C Channel for contol CS4226
	hI2C = CreateFile(	TEXT("I2C1:"),
						GENERIC_READ|GENERIC_WRITE,
						0,
						NULL,
						OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL,
						NULL);
	if ( hI2C == INVALID_HANDLE_VALUE ){
//		RETAILMSG(ZONE_TEST, (TEXT("Error: I2C open %d\r\n"), GetLastError()));
		return FALSE;
	}

	dwData = I2C_MASTER_MODE;
	DeviceIoControl(hI2C, IOCTL_I2C_SET_MODE,
		(PVOID)&dwData, sizeof(DWORD), NULL, 0, &dwRet, NULL);

    // Set I2C to standard speed mode. (100kbps)
#ifdef I2C_STANDARD_SPEED
	// 100kHz
	dwData  = 19<<2;	// SCGD
	dwData |= 2;		// CDF
#else
	// 400kHz
	dwData  = 3<<2;	// SCGD
	dwData |= 2;		// CDF
#endif

	DeviceIoControl(hI2C, IOCTL_I2C_SET_BAUDRATE,
		(PVOID)&dwData, sizeof(DWORD), NULL, 0, &dwRet, NULL);

	dwData = I2C_SINGLE_STAGE;
	DeviceIoControl(hI2C, IOCTL_I2C_SET_BUFFER_MODE,
		(PVOID)&dwData, sizeof(DWORD), NULL, 0, &dwRet, NULL);

	for(n=0;;n++){
		if ( I2Cdata[n][0] == CODEC_NONE )
			break;
		do {
			if ( I2C_WriteCODEC(hI2C, I2Cdata[n][0], I2Cdata[n][1]) == FALSE ){
				CloseHandle( hI2C );
				return FALSE;
			}
		}while( I2C_ReadCODEC(hI2C, I2Cdata[n][0], FALSE) != I2Cdata[n][1] );
		I2C_ReadCODEC(hI2C, I2Cdata[n][0], TRUE);
	}

	BusyWait(AdjustMicroSecondsToLoopCount( I2C_WAIT_COUNT ));					// wait 10ms

	// read codec status
	I2C_ReadCODEC(hI2C, CODEC_DAC_SRB, TRUE);	// DAC Status Report Byte(Read Only)(0Ah)
	I2C_ReadCODEC(hI2C, CODEC_ADC_SRB, TRUE);	// ADC Status Report Byte(Read Only)(0Dh)
	I2C_ReadCODEC(hI2C, CODEC_RSB, TRUE);		// Receiver Status Byte(Read Only)(11h)

	CloseHandle( hI2C );

	FUNC_WPDD("-I2C_SetCODEC");
	return TRUE;
}

/*****************************************************************************
*   FUNCTION :  	hssi2_dmastart
*   DESCRIPTION :   DMA(HSSI2 Tx) Start
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :	
*   CAUTIONS :		
*****************************************************************************/
void hssi2_dmastart()
{
	DWORD	value;		// value for register setting

	FUNC_WPDD("+hssi2_dmastart");

	// clear play DMA buffer
	memset(pAudioBufferBase, 0, AUDIO_DMA_PAGE_SIZE * 2);

	// DMA Control Register Setting
	value = DCR_DPDS_32BIT		|
		DCR_DDRMD_MODULE	|
		DCR_DPDAM_FIX		|
		DCR_DMDL_PERIPHERAL	|
		DCR_SPDS_32BIT		|
		DCR_SDRMD_MODULE	|
		DCR_SPDAM_INCREMENT	|
		DCR_SMDL_MEMORY		|
		DCR_DIP_2PAGE		|
		DCR_ACMD_ENABLE		|
		DCR_CT_ENABLE		|
		DCR_PKMD_DISABLE	|
		DCR_BTMD_DISABLE	|
		DCR_DTAU_BYTE		|
		DCR_DTAC_DISABLE	|
		DCR_DTAMD_PIN		;
	dma_SetControl(pDMA_out, value);

	// DMA-TransferCompleteInterrupts Enable
	dma_InterruptEnable(pDMA_out);

	// DMA Enable & Next Request Enable
	value =	DCMDR_DMEN;
	dma_SetCommand(pDMA_out, value);

	FUNC_WPDD("-hssi2_dmastart");
}

/*****************************************************************************
*   FUNCTION :  	hssi2_dmastop
*   DESCRIPTION :   DMA(HSSI2 Tx) Stop
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :	
*   CAUTIONS :		
*****************************************************************************/
void hssi2_dmastop()
{
	FUNC_WPDD("+hssi2_dmastop");

	// DMA Transfer Stop
	dma_Stop(pDMA_out);

	FUNC_WPDD("+hssi2_dmastop");
}

/*****************************************************************************
*   FUNCTION :  	check_PlayInRec
*   DESCRIPTION :	Check Playback in Recording(simultaneously)
*   INPUTS :		PlayFlag - device open flag for playback
*                   RecFlag - device open flag for recording
*   OUTPUTS :     	Return MMSYSERR_NOERROR for success, other for failure
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
MMRESULT
check_PlayInRec(
	int PlayFlag,
	int RecFlag
)
{
	MMRESULT mmRet = MMSYSERR_NOERROR;

	if (CS4226_ReadADDR == SSI1_CS4226_ReadADDR && RecFlag == 1 ){
		mmRet = MMSYSERR_NOMEM;
	}

	return	mmRet;
}

/*****************************************************************************
*   FUNCTION :  	check_RecInPlay
*   DESCRIPTION :	Check Recording in Playback(simultaneously)
*   INPUTS :		PlayFlag - device open flag for playback
*                   RecFlag - device open flag for recording
*   OUTPUTS :     	Return MMSYSERR_NOERROR for success, other for failure
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
MMRESULT
check_RecInPlay(
	int PlayFlag,
	int RecFlag
)
{
	MMRESULT mmRet = MMSYSERR_NOERROR;

#if ENABLE_HAC == 1
	// HSSI0 only for HAC&HSSI
	return(MMSYSERR_BADDEVICEID);
#endif

	if (CS4226_ReadADDR == SSI1_CS4226_ReadADDR && PlayFlag == 1 ){
		mmRet = MMSYSERR_NOMEM;
	}

	return	mmRet;
}

/*****************************************************************************
*   FUNCTION :  	MuteSSI
*   DESCRIPTION :	Mute SSI codec
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
void MuteSSI(BOOL bMute)
{
unsigned char I2CMute[2][2] = {
{CODEC_DAC_CB,	CS4226_DACCB_NORMAL},	// 0:(03h)DAC Control Byte
{CODEC_NONE,	0x00}};					// 1:delimiter

	DEBUGMSG(ZONE_TEST,(TEXT("MuteSSI %d\r\n"),bMute));

	if(bMute){
		I2CMute[0][1] = CS4226_DACCB_MUTE;
	}
	else{
		I2CMute[0][1] = CS4226_DACCB_NORMAL;
	}

	if(ulDACControl == I2CMute[0][1]){
		return;
	}

	if(I2C_SetCODEC(I2CMute)){
		ulDACControl = I2CMute[0][1];
	}
}

/*****************************************************************************
*   FUNCTION :  	UpdateInputSelect
*   DESCRIPTION :   UpdateInputSelect
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
void UpdateInputSelect(void)
{
    ULONG volume, regval;
	unsigned char ulLVol, ulRVol;

    switch (g_VolumeSettings.dwInputSelect) {
        case WPDMX_LINE_MIC:
            if (g_VolumeSettings.fMicMute) {
                volume = 0;
            }
            else {
                volume = g_VolumeSettings.dwMicVolume & 0xffff;
                volume = volume | (volume << 16); // incoming volume is mono, cvt. to stereo
            }
            break;
        case WPDMX_LINE_IN:
            if (g_VolumeSettings.fLineInMute) {
                volume = 0;
            }
            else {
                volume = g_VolumeSettings.dwLineInVolume;
            }
            break;
        default:
            DEBUGMSG(ZONE_ERROR, (TEXT("UpdateInputSelect: illegal setting %04x\r\n"), g_VolumeSettings.dwInputSelect));
            return;
    }
	ulLVol = (unsigned char)((LOWORD(volume) & 0xc000)>>14);
	ulRVol = (unsigned char)((HIWORD(volume) & 0xc000)>>12);

    regval = ulLVol | ulRVol;
    DEBUGMSG(ZONE_TEST, (TEXT("UpdateInputSelect: vol=%04x\r\n"), regval));

    codec_updateRecordGain( regval );
}

/*****************************************************************************
*   FUNCTION :  	private_SetMixerValue
*   DESCRIPTION :   Set Mixer Value
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
MMRESULT
private_SetMixerValue(DWORD dwControl, DWORD dwSetting)
{
    DWORD dwControlType = dwSetting & WPDMX_CTL_MASK;
    DWORD dwLine = dwSetting & WPDMX_LINE_MASK;

    DEBUGMSG(ZONE_TEST, (TEXT("private_SetMixerValue(%04x, %08x)\r\n"), dwControl, dwSetting));

    switch (dwControl) {
        // volume controls
        case WPDMX_MASTER_VOL:
            private_waveOutSetVolume(dwSetting);
            break;
        case WPDMX_LINEIN_VOL:
			if (CS4226_ReadADDR == SSI1_CS4226_ReadADDR){
	            return MMSYSERR_NOTSUPPORTED;
			}
            g_VolumeSettings.dwLineInVolume = dwSetting;
            UpdateInputSelect();
            break;
        case WPDMX_MIC_VOL:
            return MMSYSERR_NOTSUPPORTED;

        // Mute controls
        case WPDMX_MASTER_MUTE:
            g_VolumeSettings.fMasterMute = dwSetting;
            SetMute(g_VolumeSettings.fMasterMute);
            break;
        case WPDMX_LINEIN_MUTE:
			if (CS4226_ReadADDR == SSI1_CS4226_ReadADDR){
	            return MMSYSERR_NOTSUPPORTED;
			}
            g_VolumeSettings.fLineInMute = dwSetting;
            UpdateInputSelect();
            break;
        case WPDMX_MIC_MUTE:
			//CODEC does not have a function
            return MMSYSERR_NOTSUPPORTED;
        // The input Mux
        case WPDMX_INPUT_MUX:
			if ((CS4226_ReadADDR == SSI1_CS4226_ReadADDR && dwSetting == WPDMX_LINE_IN) ||
				(CS4226_ReadADDR == SSI2_CS4226_ReadADDR && dwSetting == WPDMX_LINE_MIC)){
	            return MMSYSERR_NOTSUPPORTED;
			}
            g_VolumeSettings.dwInputSelect = dwSetting;
            UpdateInputSelect();
            break;
        default:
            DEBUGMSG(ZONE_ERROR, (TEXT("private_SetMixerValue: unsupported control %d\r\n"), dwControl));
            return MMSYSERR_NOTSUPPORTED;
    }
    return MMSYSERR_NOERROR;
}

VOID	codec_updateRecordGain( ULONG regval )
{
unsigned char I2CGain[2][2] = {
{CODEC_ICB,		0x0f},				// 0:(0Ch)Input Control Byte(GNL1乣GNL0,GNR1乣GNR0)
{CODEC_NONE,	0x00}};				// 1:delimiter

	DEBUGMSG(ZONE_TEST,(TEXT("codec_updateRecordGain 0x%08x\r\n"),regval));

	I2CGain[0][1] = (unsigned char)regval;
	I2C_SetCODEC(I2CGain);
	return;
}

/*****************************************************************************
*   FUNCTION :  	private_SetDefaultVolume
*   DESCRIPTION :   Set master volume and default input
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
void private_SetDefaultVolume()
{
	if (CS4226_ReadADDR == SSI1_CS4226_ReadADDR){

#if !(ENABLE_HAC == 1)
	    // Set the global master volume to max 
		private_waveOutSetVolume(0xffffffff);

	    // set default for input
		private_SetMixerValue(WPDMX_INPUT_MUX, WPDMX_LINE_MIC);
	    private_SetMixerValue(WPDMX_MIC_VOL,     0xAAAAAAAA);
	    private_SetMixerValue(WPDMX_MIC_MUTE,    0);
#else
	    // Set the global master volume to WinCE default(same as HAC)
		private_waveOutSetVolume(0xAC85AC85);
#endif
	}
	else{
	    // Set the global master volume to WinCE default
		private_waveOutSetVolume(0x99999999);

	    // set default for input
		private_SetMixerValue(WPDMX_INPUT_MUX, WPDMX_LINE_IN);
	    private_SetMixerValue(WPDMX_LINEIN_VOL,  0xAAAAAAAA);
	    private_SetMixerValue(WPDMX_LINEIN_MUTE, 0);
	}
}

void waitSSIStatus(PVULONG pSSI_SR, ULONG stat)
{
	ULONG	RegValue;

	do{
		RegValue = READ_REGISTER_ULONG(pSSI_SR);
	}while((RegValue & stat) != stat);
}

⌨️ 快捷键说明

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