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

📄 hssi.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 5 页
字号:

	ch = globals->aud[i].REC_CH - CH_TX_HSSI_1;
	pSSI_RegBase = (PBYTE)(pSSI0_RegBase + (SSI_CH_REGBASE_OFFSET * ch));
	pSSI_CR_RX      = (PVULONG) ( pSSI_RegBase + SSI_CR_OFFSET );
	pSSI_SR_RX      = (PVULONG) ( pSSI_RegBase + SSI_SR_OFFSET );
	pSSI_RDR        = (PVULONG) ( pSSI_RegBase + SSI_RDR_OFFSET );

	DEBUGMSG(ZONE_TEST, (TEXT("SSI_CR_TX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_CR_TX )));
	DEBUGMSG(ZONE_TEST, (TEXT("SSI_SR_TX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_SR_TX )));

	DEBUGMSG(ZONE_TEST, (TEXT("SSI_CR_RX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_CR_RX )));
	DEBUGMSG(ZONE_TEST, (TEXT("SSI_SR_RX=%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pSSI_SR_RX )));

	// SSI Seting
	WRITE_REGISTER_ULONG((PULONG)pSSI_CR_TX, (ULONG)0x00000000 );		// Disable module
	DEBUGMSG( 1, (TEXT("SSI_TX Control Register (%08x) = %08x\r\n"), pSSI_CR_TX, 0x00000000));
	WRITE_REGISTER_ULONG((PULONG)pSSI_SR_TX, (ULONG)0x00000000 );		// Clear 26,27 bits
	DEBUGMSG( 1, (TEXT("SSI_TX Status  Register (%08x) = %08x\r\n"), pSSI_SR_TX, 0x00000000));

	WRITE_REGISTER_ULONG((PULONG)pSSI_CR_RX, (ULONG)0x00000000 );		// Disable module
	DEBUGMSG( 1, (TEXT("SSI_RX Control Register (%08x) = %08x\r\n"), pSSI_CR_RX, 0x00000000));
	WRITE_REGISTER_ULONG((PULONG)pSSI_SR_RX, (ULONG)0x00000000 );		// Clear 26,27 bits
	DEBUGMSG( 1, (TEXT("SSI_RX Status  Register (%08x) = %08x\r\n"), pSSI_SR_RX, 0x00000000));

	if(globals->aud[i].PLAY_CH == CH_TX_HSSI_1){
		SSI_PLAY_MODE = SSI1_PLAY_MODE;
		SSI_REC_MODE = SSI1_REC_MODE;
		CS4226_ReadADDR = SSI1_CS4226_ReadADDR;
		CS4226_WriteADDR = SSI1_CS4226_WriteADDR;
		CS4226_PLAY_CMB = SSI1_CS4226_PLAY_CMB;
		CS4226_REC_CMB = SSI1_CS4226_REC_CMB;
		CS4226_PLAY_DSP_PMB = SSI1_CS4226_PLAY_DSP_PMB;
		CS4226_REC_DSP_PMB = SSI1_CS4226_REC_DSP_PMB;
		CS4226_PLAY_DACCB = SSI1_CS4226_PLAY_DACCB;
		CS4226_REC_DACCB = SSI1_CS4226_REC_DACCB;
		CS4226_ADCCB = 0x03;
	}
	else{
		SSI_PLAY_MODE = SSI2_PLAY_MODE;
		SSI_REC_MODE = SSI2_REC_MODE;
		CS4226_ReadADDR = SSI2_CS4226_ReadADDR;
		CS4226_WriteADDR = SSI2_CS4226_WriteADDR;
		CS4226_PLAY_CMB = SSI2_CS4226_PLAY_CMB;
		CS4226_REC_CMB = SSI2_CS4226_REC_CMB;
		CS4226_PLAY_DSP_PMB = SSI2_CS4226_PLAY_DSP_PMB;
		CS4226_REC_DSP_PMB = SSI2_CS4226_REC_DSP_PMB;
		CS4226_PLAY_DACCB = SSI2_CS4226_PLAY_DACCB;
		CS4226_REC_DACCB = SSI2_CS4226_REC_DACCB;
		CS4226_ADCCB = 0x04;
	}

	return	ret;
}


/*****************************************************************************
*   FUNCTION :  	module_deinit	
*   DESCRIPTION :	HSSI Deinitialize
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
VOID
module_deinit(
   VOID
   )
{
	VirtualFree((PVOID)pSSI0_RegBase, 0, MEM_RELEASE);
	pSSI0_RegBase = NULL;
}

/*****************************************************************************
*   FUNCTION :  	codec_init	
*   DESCRIPTION :	CODEC Initialize
*   INPUTS :		None
*   OUTPUTS :     	Return TRUE for success, FALSE for failure
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
BOOL
codec_init(
   VOID
   )
{
	DWORD	a;
	DWORD	dwData;
	DWORD	dwRet;
	HANDLE	hI2C;
unsigned char I2Cdata[14][2] = {
//{Register Pointer, Value}
{CODEC_CMB, 	0x00},				//*00:(01h)Clock Mode Byte(CO1乣CO0,CI1乣CI0)
									//		if 11.025kHz then ch0:0x52,ch1:0x50,ch2/3:0x40
{CODEC_DAC_CB,	0xc0},				//*01:(03h)DAC Control Byte(ZCD,MUTC)
{CODEC_OADB_1,	0x00},				// 02:(04h)Output Attenuator Data Byte(left ch)
{CODEC_OADB_2,	0x00},				// 03:(05h)Output Attenuator Data Byte(right ch)
{CODEC_OADB_3,	0x00},				// 04:(06h)Output Attenuator Data Byte(no use)
{CODEC_OADB_4,	0x00},				// 05:(07h)Output Attenuator Data Byte(no use)
{CODEC_OADB_5,	0x00},				// 06:(08h)Output Attenuator Data Byte(no use)
{CODEC_OADB_6,	0x00},				// 07:(09h)Output Attenuator Data Byte(no use)
{CODEC_ADC_CB,	0x00},				// 08:(0Bh)ADC Control Byte
{CODEC_ICB,		0x0f},				// 09:(0Ch)Input Control Byte(GNL1乣GNL0,GNR1乣GNR0)
{CODEC_DSP_PMB,	0xc8},				//*10:(0Eh)DSP Port Mode Byte(DCK1乣DCK0,DSCK)
									//		slave:0xc8,master:0xe8
{CODEC_APMB,	0x00},				//*11:(0Fh)Auxiliary Port Mode Byte(ACK1乣ACK0,ASCK)
									//		slave:0x00,master:0xe8
{CODEC_APCB,	0x58},				// 12:(10h)Auxilliary Port Control Byte(HPC,MOH,DEM24)
{CODEC_NONE,	0x00}};				// 13:delimiter

	I2Cdata[0][1] = CS4226_PLAY_CMB;
	I2Cdata[10][1] = CS4226_PLAY_DSP_PMB;
	I2Cdata[11][1] = CS4226_PLAY_APMB;
	I2Cdata[1][1] = CS4226_PLAY_DACCB;
	I2Cdata[8][1] = CS4226_ADCCB;

	ulDSPMode = I2Cdata[10][1];
	ulDACControl = I2Cdata[1][1];

	// 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 ){
		goto error_ret;
	}

	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);

	// reset codec
	I2C_ReadCODEC(hI2C, CODEC_CCB, FALSE);
	do {
		if ( I2C_WriteCODEC(hI2C, CODEC_CCB, CODEC_CCB_RS_RESET) == FALSE )
			goto error_ret1;
	}while( !(I2C_ReadCODEC(hI2C, CODEC_CCB, FALSE) & CODEC_CCB_RS_MASK) );

	// configure codec
	for(a=0;;a++){
		if ( I2Cdata[a][0] == CODEC_NONE )
			break;
		do {
			if ( I2C_WriteCODEC(hI2C, I2Cdata[a][0], I2Cdata[a][1]) == FALSE )
				goto error_ret1;
		}while( I2C_ReadCODEC(hI2C, I2Cdata[a][0], FALSE) != I2Cdata[a][1] );
		I2C_ReadCODEC(hI2C, I2Cdata[a][0], TRUE);
	}

	// finish configure codec
	do {
		if ( I2C_WriteCODEC(hI2C, CODEC_CCB, CODEC_CCB_RS_NORESET) == FALSE )
			goto error_ret1;
	}while( (I2C_ReadCODEC(hI2C, CODEC_CCB, FALSE) & CODEC_CCB_RS_MASK) );

	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 );

	return	TRUE;

error_ret1:
	CloseHandle( hI2C );
error_ret:
	RETAILMSG(1, (TEXT("HSSI codec_init: Error!\r\n")));
	return	FALSE;
}


/*****************************************************************************
*   FUNCTION :  	module_txdmastart
*   DESCRIPTION :	HSSI Tx Start
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
VOID
module_txdmastart(
   VOID
   )
{
	ULONG	RegValue;

	FUNC_WPDD("+hssi_txdmastart");

	if(CS4226_ReadADDR == SSI1_CS4226_ReadADDR){
		MuteSSI(FALSE);
	}

	if (RecOpenFlag == 0){
		SSICR_TX.bits.DMEN = 1;	// DMA Enable
		SSICR_TX.bits.UIEN = 1;	// Underflow IRQ enable
		SSICR_TX.bits.OIEN = 1;	// Overflow IRQ enable
		SSICR_TX.bits.EN   = 1;	// SSI Enable
		RegValue = SSICR_TX.AsDWORD;
		WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
	}

	FUNC_WPDD("-hssi_txdmastart");
}


/*****************************************************************************
*   FUNCTION :  	module_txstop
*   DESCRIPTION :	HSSI Tx Stop
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
VOID
module_txstop(
   VOID
   )
{
	ULONG	RegValue;

	FUNC_WPDD("+hssi_txstop");

	if (CS4226_ReadADDR == SSI2_CS4226_ReadADDR && RecOpenFlag == 1){
		// on recording...

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

		// MuteSSI
		if(CS4226_ReadADDR == SSI1_CS4226_ReadADDR){
			MuteSSI(TRUE);
		}
	}
	else{
		if(SSICR_TX.bits.EN == 1){
			// Stop SSI
			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.EN   = 0;	// SSI Disable
			RegValue = SSICR_TX.AsDWORD;
			WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
			waitSSIStatus(pSSI_SR_TX, SSI_SR_IIRQ_IDLE);
		}
	}

	FUNC_WPDD("-hssi_txstop");
	return;
}


/*****************************************************************************
*   FUNCTION :  	module_rxdmastart
*   DESCRIPTION :	HSSI Rx Start
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
VOID
module_rxdmastart(
   VOID
   )
{
	ULONG	RegValue;

	FUNC_WPDD("+hssi_rxdmastart");

	// Set SSI Control Register
	if(CS4226_ReadADDR == SSI2_CS4226_ReadADDR){
		if(PlayOpenFlag == 0){
			// not playing, dymmy playback start
			// ch3 need ch2's clock
			hssi2_dmastart();

			SSICR_TX.bits.DMEN = 1;	// DMA Enable
			SSICR_TX.bits.UIEN = 1;	// Underflow IRQ enable
			SSICR_TX.bits.OIEN = 1;	// Overflow IRQ enable
			SSICR_TX.bits.EN   = 1;	// SSI Enable
			RegValue = SSICR_TX.AsDWORD;
			WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);
		}
	}

	SSICR_RX.bits.DMEN = 1;	// DMA Enable
	SSICR_RX.bits.UIEN = 1;	// Underflow IRQ enable
	SSICR_RX.bits.OIEN = 1;	// Overflow IRQ enable
	SSICR_RX.bits.EN   = 1;	// SSI Enable
	RegValue = SSICR_RX.AsDWORD;
	WRITE_REGISTER_ULONG(pSSI_CR_RX, RegValue);

	FUNC_WPDD("-hssi_rxdmastart");
}


/*****************************************************************************
*   FUNCTION :  	module_rxstop
*   DESCRIPTION :	HSSI Rx Stop
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
VOID
module_rxstop(
   VOID
   )
{
	ULONG	RegValue;

	FUNC_WPDD("+hssi_rxstop");

	if(SSICR_RX.bits.EN == 1){
		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.EN   = 0;	// SSI Disable
		RegValue = SSICR_RX.AsDWORD;
		WRITE_REGISTER_ULONG(pSSI_CR_RX, RegValue);

		waitSSIStatus(pSSI_SR_RX, SSI_SR_IIRQ_IDLE);
	}

	if(CS4226_ReadADDR == SSI2_CS4226_ReadADDR){
		if(PlayOpenFlag == 0){
			// not playing, stop dummy playback
			// ch3 need ch2's clock
			if(SSICR_TX.bits.EN == 1){
				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.EN   = 0;	// SSI Disable
				RegValue = SSICR_TX.AsDWORD;
				WRITE_REGISTER_ULONG(pSSI_CR_TX, RegValue);

				waitSSIStatus(pSSI_SR_TX, SSI_SR_IIRQ_IDLE);

				hssi2_dmastop();
			}
		}
	}

	FUNC_WPDD("-hssi_rxstop");
}


/*****************************************************************************
*   FUNCTION :  	module_txstart
*   DESCRIPTION :	HSSI Tx Start
*   INPUTS :		None
*   OUTPUTS :     	None
*   DESIGN NOTES :  
*   CAUTIONS :		
*****************************************************************************/
VOID
module_txstart(
   VOID
   )
{
	ULONG	RegValue;
unsigned char DSPslave[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,	0xc8},		//*1:(0Eh)DSP Port Mode Byte(DCK1乣DCK0,DSCK)
							//		slave:0xc8,master:0xe8
{CODEC_APMB,	0x00},		//*2:(0Fh)Auxiliary Port Mode Byte(ACK1乣ACK0,AMS1乣AMS0,ASCK)
							//		slave:0x00,master:0xe8
{CODEC_DAC_CB,	0xc0},		//*3:(03h)DAC Control Byte(ZCD,MUTC) not mute?
{CODEC_NONE,	0x00}};		// 4:delimiter

	FUNC_WPDD("+hssi_txstart");

	DSPslave[0][1] = CS4226_PLAY_CMB;
	DSPslave[1][1] = CS4226_PLAY_DSP_PMB;
	DSPslave[2][1] = CS4226_PLAY_APMB;
	DSPslave[3][1] = CS4226_PLAY_DACCB;

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

	if (RecOpenFlag == 0){
		// Set SSI Control Register
		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

⌨️ 快捷键说明

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