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

📄 hspdif.c

📁 WinCE5.0BSP for Renesas SH7770
💻 C
📖 第 1 页 / 共 2 页
字号:
		// DMA Enable & Next Request Enable

		dwValue = DCMDR_DMEN;
		dma_SetCommand(pOpen->pTxDma, dwValue);

		pOpen -> pInfo -> dwStatus |= SPDIF_TRANSMITTING;
	}
	return dwWritten;
}

/*++

StopTransmitting :

The DMA controller is stopped.
Then, SPDIF transmitting is canceled.

--*/
BOOL
StopTransmitting(
	PSPDIF_OPEN_INFO pOpen
	)
{
SPDIFControlRegister cr;
	if ( pOpen -> pInfo -> dwStatus & SPDIF_TRANSMITTING ){
		cr.AsDWORD = READ_REGISTER_ULONG(pOpen -> pInfo -> pvControl);
		cr.bits.TME = 0;
		cr.bits.TDE = 0;
		WRITE_REGISTER_ULONG(pOpen -> pInfo -> pvControl, cr.AsDWORD);
		pOpen -> pInfo -> dwStatus &= ~SPDIF_TRANSMITTING;

		dma_Stop(pOpen->pTxDma);

		DEBUGMSG(SPDIF_TEST, (TEXT("SPDIF:Transmission was stopped.\r\n")));
	}
	return TRUE;
}

#pragma optimize("", off)
/*++

SPDIF_FillBuffer :

Copy transmit data to a transmitting buffer.

--*/
BOOL
SPDIF_FillBuffer(
	PSPDIF_OPEN_INFO pOpen
	)
{
//DWORD	dwLastDataSize;
//DWORD	dwCopyDataSize;
DWORD	dwFillOffset = 0;
PVBYTE	pvOutBuff = (pOpen -> pvOutBufferBase + (pOpen -> dwTxFlipBuff * SPDIF_OUT_DMA_PAGE_SIZE));
BOOL	bReturn = TRUE;
DWORD	dmy;

	EnterCriticalSection( &(pOpen -> TxCS) );

//	DEBUGMSG(SPDIF_TEST, (TEXT("SPDIF:++FillBuffer BufferRemainder[%x] Size[%x] TransmittedSize[%x]\r\n"),
//			 pOpen -> dwTxRemainOffset, pOpen -> dwOutReqSize, pOpen -> dwTransmitted));
	
	if ( pOpen -> dwOutWorkWPtr != pOpen -> dwOutWorkTPtr ){
		ConvertTo32Bits(pOpen);
		if ( pOpen -> dwOutWorkWPtr == pOpen -> dwOutWorkTPtr ){
			bReturn = FALSE;
		}
		pOpen -> dwTxFlipBuff = 1 - pOpen -> dwTxFlipBuff;
	}else{
		memset((PVOID)pvOutBuff, 0, SPDIF_OUT_DMA_PAGE_SIZE);
		bReturn = FALSE;
		pOpen -> dwTxFlipBuff = 1 - pOpen -> dwTxFlipBuff;
		pOpen -> dwTxWork = 0;
		pOpen -> dwTxShiftPtr = 0;

		DEBUGMSG(SPDIF_TEST, (TEXT("SPDIF:Writing 0 to a transmitting buffer.\r\n")));
//		RETAILMSG(1, (TEXT("SPDIF:Writing 0 to a transmitting buffer.\r\n")));
	}
	dmy = *(pvOutBuff + SPDIF_OUT_DMA_PAGE_SIZE - sizeof(DWORD));
//	DEBUGMSG(SPDIF_TEST, (TEXT("SPDIF:--FillBuffer BufferRemainder[%x] Size[%x] TransmittedSize[%x]\r\n"),
//			 pOpen -> dwTxRemainOffset, pOpen -> dwOutReqSize, pOpen -> dwTransmitted));
	LeaveCriticalSection( &(pOpen -> TxCS) );
	return bReturn;
}
#pragma optimize("", on)

/*++

FillWorkBuffer :

Write PCM data passed from application

--*/
DWORD
FillWorkBuffer(
	PSPDIF_OPEN_INFO pOpen,
	PVOID pBuff,
	DWORD dwSize
	)
{
DWORD i = 0;

	if ( pOpen -> dwTxSampleSize == SPDIF_SAMPLE_BIT_SIZE_16 ){
		PUSHORT	pSrc = (PUSHORT)pBuff;
		for( i=0;i < dwSize; ){
			if ( ((pOpen -> dwOutWorkWPtr+2) & (SPDIF_WORK_OBUFFER_SIZE-1)) == pOpen -> dwOutWorkTPtr ){
				ResetEvent( pOpen -> hTxWaitEvent );
				if ( WaitForSingleObject(pOpen -> hTxWaitEvent, 1000) == WAIT_TIMEOUT ){
					break;
				}
			}
			WRITE_REGISTER_USHORT((pOpen -> pvOutWorkBuffer + pOpen -> dwOutWorkWPtr), *(pSrc++));
			pOpen -> dwOutWorkWPtr += sizeof(USHORT);
			pOpen -> dwOutWorkWPtr &= (SPDIF_WORK_OBUFFER_SIZE-1);
			i += sizeof(USHORT);
		}
	}else{
		PDWORD	pSrc = (PDWORD)pBuff;
		for( i=0;i < dwSize; ){
			if ( ((pOpen -> dwOutWorkWPtr+4) & (SPDIF_WORK_OBUFFER_SIZE-1)) == pOpen -> dwOutWorkTPtr ){
				ResetEvent( pOpen -> hTxWaitEvent );
				if ( WaitForSingleObject(pOpen -> hTxWaitEvent, 1000) == WAIT_TIMEOUT ){
					break;
				}
			}
			WRITE_REGISTER_ULONG((PVBYTE)(pOpen -> pvOutWorkBuffer + pOpen -> dwOutWorkWPtr), *(pSrc++));
			pOpen -> dwOutWorkWPtr += sizeof(DWORD);
			pOpen -> dwOutWorkWPtr &= (SPDIF_WORK_OBUFFER_SIZE-1);
			i += sizeof(DWORD);
		}
	}
	return i;
}


DWORD
SPDIFInterruptThread(
	PSPDIF_DRIVER_INFO pSpdif
	)
{

	while( TRUE ){

		if ( WaitForSingleObject(pSpdif -> hInterrupt, INFINITE) == WAIT_TIMEOUT ){
			continue;
		}

		if ( pSpdif -> pvGlobal -> dwTxStatus ){
			if ( pSpdif -> hTxEvent ){
				SetEvent( pSpdif -> hTxEvent );
			}
			pSpdif -> pvGlobal -> dwTxStatus = 0;
		}
		if ( pSpdif -> pvGlobal -> dwRxStatus ){
			if ( pSpdif -> hRxEvent ){
				SetEvent( pSpdif -> hRxEvent );
			}
			pSpdif -> pvGlobal -> dwRxStatus = 0;
		}
		InterruptDone(SYSINTR_HSPDIF);
	}
	DEBUGMSG(SPDIF_TEST, (TEXT("End an interruption thread.\r\n")));

	return 0;
}

/*++

SPDIFInterruptThreadTx :

Interrupt service thread for TX

--*/

DWORD
SPDIFInterruptThreadTx(
	PSPDIF_OPEN_INFO pOpen
	)
{

	while( pOpen -> bTxThread == TRUE ){
		if ( WaitForSingleObject(pOpen -> pInfo -> hTxEvent, 3000) == WAIT_TIMEOUT ){
			continue;
		}
		if ( pOpen -> bTxThread != TRUE ){
			break;
		}
		if ( SPDIF_FillBuffer( pOpen ) == FALSE ){
		}
		SetEvent( pOpen -> hTxWaitEvent );

		DEBUGMSG(SPDIF_TEST, (TEXT("SPDIF:Transmit interrupt occurred.\r\n")));

	}
	DEBUGMSG(SPDIF_TEST, (TEXT("End an interruption thread.\r\n")));

	return 0;
}



/*++

SPDIF_ReceivingData :

Perform data reception.
When receiving for the first time, start DMA and SPDIF.

--*/
DWORD
SPDIF_ReceivingData(
	PSPDIF_OPEN_INFO pOpen,
	PVOID pBuff,
	DWORD dwSize
	)
{
DWORD	dwLoop = 0;
DWORD	dwValue;
	if ( !(pOpen -> dwAccess & GENERIC_READ) ){
		return 0;
	}

	if ( !(pOpen -> pInfo -> dwStatus & SPDIF_RECEIVING) ){
		SPDIFControlRegister cr;

		pOpen -> dwRxShiftPtr = 0;
		pOpen -> dwRxWork = 0;
		pOpen -> dwRxFlipBuff = 0;
		if ( pOpen -> dwRxSampleSize == SPDIF_SAMPLE_BIT_SIZE_20 ){
			pOpen -> RxBits = &ConvBitsRx20[0];
		}else if ( pOpen -> dwRxSampleSize == SPDIF_SAMPLE_BIT_SIZE_24 ){
			pOpen -> RxBits = &ConvBitsRx24[0];
		}

		// DMA Control Register Setting

		dwValue		=	DCR_DTAMD_PIN		|
						DCR_DTAC_DISABLE	|
						DCR_DTAU_BYTE		|
						DCR_BTMD_DISABLE	|
						DCR_PKMD_DISABLE	|
						DCR_CT_ENABLE		|
						DCR_ACMD_ENABLE		|
						DCR_DIP_2PAGE		|
						DCR_SMDL_PERIPHERAL	|
						DCR_SPDAM_FIX		|
						DCR_SDRMD_MODULE	|
						DCR_SPDS_32BIT		|
						DCR_DMDL_MEMORY		|
						DCR_DPDAM_INCREMENT	|
						DCR_DDRMD_MODULE	|
						DCR_DPDS_32BIT		;

		dma_SetControl(pOpen->pRxDma, dwValue);

		// DMA-TransferCompleteInterrupt Enable

		dma_InterruptEnable(pOpen->pRxDma);

		cr.AsDWORD = READ_REGISTER_ULONG(pOpen -> pInfo -> pvControl);
		cr.bits.AOS  = 1; // Audio only samples
//		cr.bits.NCSI = 1; // New channel status information
		cr.bits.RME  = 1; // Recieve module enable
		cr.bits.RDE  = 1; // Recieve dma enable
		cr.bits.RASS = pOpen -> dwRxSampleSize; // Recieve audio samlple bit size

		WRITE_REGISTER_ULONG(pOpen -> pInfo -> pvControl, cr.AsDWORD);

		// DMA Enable & Next Request Enable

		dwValue = DCMDR_DMEN;
		dma_SetCommand(pOpen->pRxDma, dwValue);

		pOpen -> pInfo -> dwStatus |= SPDIF_RECEIVING;
	}

	return GetWorkBuffer(pOpen, pBuff, dwSize);

}

/*++

GetWorkBuffer :



--*/
DWORD
GetWorkBuffer(
	PSPDIF_OPEN_INFO pOpen,
	PVOID pBuff,
	DWORD dwSize
	)
{
DWORD i = 0;

	if ( pOpen -> dwTxSampleSize == SPDIF_SAMPLE_BIT_SIZE_16 ){
		PUSHORT	pSrc = (PUSHORT)pBuff;
		for( i=0;i < dwSize; ){
			if ( pOpen -> dwInWorkRPtr == pOpen -> dwInWorkWPtr ){
				ResetEvent( pOpen -> hRxWaitEvent );
				if ( WaitForSingleObject(pOpen -> hRxWaitEvent, 1000) == WAIT_TIMEOUT ){
					break;
				}
				if ( pOpen -> dwInWorkRPtr == pOpen -> dwInWorkWPtr ){
					break;
				}
			}
			*(pSrc++) = READ_REGISTER_USHORT((pOpen -> pvInWorkBuffer + pOpen -> dwInWorkRPtr));
			pOpen -> dwInWorkRPtr += sizeof(USHORT);
			pOpen -> dwInWorkRPtr &= (SPDIF_WORK_IBUFFER_SIZE-1);
			i += sizeof(USHORT);
		}
	}else{
		PDWORD	pSrc = (PDWORD)pBuff;
		for( i=0;i < dwSize; ){
			if ( pOpen -> dwInWorkRPtr == pOpen -> dwInWorkWPtr ){
				ResetEvent( pOpen -> hRxWaitEvent );
				if ( WaitForSingleObject(pOpen -> hRxWaitEvent, 1000) == WAIT_TIMEOUT ){
					break;
				}
				if ( pOpen -> dwInWorkRPtr == pOpen -> dwInWorkWPtr ){
					break;
				}
			}
			*(pSrc++) = READ_REGISTER_USHORT((pOpen -> pvInWorkBuffer + pOpen -> dwInWorkRPtr));
			pOpen -> dwInWorkRPtr += sizeof(DWORD);
			pOpen -> dwInWorkRPtr &= (SPDIF_WORK_IBUFFER_SIZE-1);
			i += sizeof(DWORD);
		}
	}
	return i;
}


/*++

StopReceiving :

The DMA controller is stopped.
Then, SPDIF receiving is canceled.

--*/
BOOL
StopReceiving(
	PSPDIF_OPEN_INFO pOpen
	)
{
SPDIFControlRegister cr;
	if ( pOpen -> pInfo -> dwStatus & SPDIF_RECEIVING ){

		cr.AsDWORD = READ_REGISTER_ULONG(pOpen -> pInfo -> pvControl);
		cr.bits.RME = 0;
		cr.bits.RDE = 0;
		WRITE_REGISTER_ULONG(pOpen -> pInfo -> pvControl, cr.AsDWORD);
        
		dma_Stop(pOpen->pRxDma);

		pOpen -> pInfo -> dwStatus &= ~SPDIF_RECEIVING;

		DEBUGMSG(SPDIF_TEST, (TEXT("SPDIF:Reception was stopped.\r\n")));
	}
	return TRUE;
}

/*++

SPDIF_GetData :

Copy receive data from a receiving buffer.

--*/

BOOL
SPDIF_GetData(
	PSPDIF_OPEN_INFO pOpen
	)
{
PVBYTE	pvInBuff = (pOpen -> pvInBufferBase + (pOpen -> dwRxFlipBuff * SPDIF_IN_DMA_PAGE_SIZE));

	EnterCriticalSection( &(pOpen -> RxCS) );
	ConvertFrom32Bits(pOpen);
	pOpen -> dwRxFlipBuff = 1 - pOpen -> dwRxFlipBuff;
	LeaveCriticalSection( &(pOpen -> RxCS) );
	return TRUE;

}


/*++

SPDIFInterruptThreadRx :

Interrupt service thread for RX

--*/

DWORD
SPDIFInterruptThreadRx(
	PSPDIF_OPEN_INFO pOpen
	)
{

	while( pOpen -> bRxThread == TRUE ){
		if ( WaitForSingleObject(pOpen -> pInfo -> hRxEvent, 3000) == WAIT_TIMEOUT ){
			continue;
		}
		if ( pOpen -> bRxThread != TRUE ){
			break;
		}
		if ( SPDIF_GetData( pOpen ) == FALSE ){
		}
		SetEvent( pOpen -> hRxWaitEvent );
	}
	return 0;
}



/*++

SPDIF_StopTransmit :

Perform transmitting processing.
Execution of this function stops a transmitting clock.

--*/
VOID
SPDIF_StopTransmit(
	PSPDIF_OPEN_INFO pOpen
	)
{

	DEBUGMSG(SPDIF_TEST, (TEXT("SPDIF:Stop transmitting\r\n")));
	StopTransmitting(pOpen);
}

/*++

SPDIF_StopReceive :

Perform receiving processing.
Execution of this function stops a receiving clock.

--*/
VOID
SPDIF_StopReceive(
	PSPDIF_OPEN_INFO pOpen
	)
{
	StopReceiving(pOpen);
}

/*++

ConvertTo32Bits :

Data to transmit is 32 bits although demand data is 16, 20, and 24 bits.
So, perform data conversion to 32 bits.

--*/
VOID
ConvertTo32Bits(
	PSPDIF_OPEN_INFO pOpen
	)
{
PVDWORD	pOutBuff = (PVDWORD)(pOpen -> pvOutBufferBase + (pOpen -> dwTxFlipBuff * SPDIF_OUT_DMA_PAGE_SIZE));
DWORD	i;

	if ( pOpen -> dwTxSampleSize == SPDIF_SAMPLE_BIT_SIZE_16 ){
		for( i=0;i < SPDIF_OUT_DMA_PAGE_SIZE; ){
			if ( pOpen -> dwOutWorkTPtr != pOpen -> dwOutWorkWPtr ){
				*(pOutBuff++) = (DWORD)(READ_REGISTER_USHORT(((PVBYTE)(pOpen -> pvOutWorkBuffer+pOpen -> dwOutWorkTPtr))));
				pOpen -> dwOutWorkTPtr += 2;
				pOpen -> dwOutWorkTPtr &= (SPDIF_WORK_OBUFFER_SIZE-1);
			}else{
				*(pOutBuff++) = 0;
			}
			i += sizeof(DWORD);
		}
	}else{
		PBITS_CONVERSION Convert;
		Convert = pOpen -> TxBits + pOpen -> dwTxShiftPtr;
		for( i=0;i < SPDIF_OUT_DMA_PAGE_SIZE;){
			if ( pOpen -> dwOutWorkTPtr != pOpen -> dwOutWorkWPtr ){
				if ( Convert -> dwDirection == SHIFT_N ){
					DWORD	dwWork = READ_REGISTER_ULONG(((PVBYTE)(pOpen -> pvOutWorkBuffer + pOpen -> dwOutWorkTPtr)));
					pOpen -> dwTxWork |= dwWork & Convert -> dwData;
				}else if ( Convert -> dwDirection == SHIFT_L ){
					DWORD	dwWork = READ_REGISTER_ULONG(((PVBYTE)(pOpen -> pvOutWorkBuffer + pOpen -> dwOutWorkTPtr)));
					pOpen -> dwTxWork |= (dwWork & Convert -> dwData) << Convert -> dwShift;
				}else{
					DWORD	dwWork = READ_REGISTER_ULONG(((PVBYTE)(pOpen -> pvOutWorkBuffer + pOpen -> dwOutWorkTPtr)));
					pOpen -> dwTxWork |= (dwWork & Convert -> dwData) >> Convert -> dwShift;
				}
			}else{
//				pOpen -> dwTxWork = 0;
				*(pOutBuff++) = 0;
				i += sizeof(DWORD);
				continue;
			}
			if ( Convert -> dwInc & INC_SRC ){
				pOpen -> dwOutWorkTPtr += sizeof(DWORD);
				pOpen -> dwOutWorkTPtr &= (SPDIF_WORK_OBUFFER_SIZE-1);
			}
			if ( Convert -> dwInc & INC_DST ){
				*(pOutBuff++) = pOpen -> dwTxWork;
				pOpen -> dwTxWork = 0;
				i += sizeof(DWORD);
			}
			if ( Convert -> dwInc == (INC_SRC|INC_DST) ){
				pOpen -> dwTxShiftPtr = 0;
				Convert = pOpen -> TxBits;
			}else{
				Convert++;
				pOpen -> dwTxShiftPtr ++;
			}
		}
	}
}

/*++

ConvertFrom32Bits :

Although data to receive is 32 bits, data to return is 16, 20 or 24 bits.
So, perform data conversion to 16, 20 or 24 bits.

--*/
VOID
ConvertFrom32Bits(
	PSPDIF_OPEN_INFO pOpen
	)
{
PVDWORD	pInBuff = (PVDWORD)(pOpen -> pvInBufferBase + (pOpen -> dwRxFlipBuff * SPDIF_IN_DMA_PAGE_SIZE));
DWORD	i;
	if ( pOpen -> dwRxSampleSize == SPDIF_SAMPLE_BIT_SIZE_16 ){
		for( i=0;i < SPDIF_IN_DMA_PAGE_SIZE; ){
			WRITE_REGISTER_USHORT(((PVBYTE)(pOpen -> pvInWorkBuffer + pOpen -> dwInWorkWPtr)), (USHORT)*(pInBuff++));
			pOpen -> dwInWorkWPtr += sizeof(USHORT);
			pOpen -> dwInWorkWPtr &= (SPDIF_WORK_IBUFFER_SIZE-1);
			i += sizeof(DWORD);
		}
	}else{
		PBITS_CONVERSION Convert;
		Convert = pOpen -> RxBits + pOpen -> dwRxShiftPtr;
		for( i=0;i < SPDIF_IN_DMA_PAGE_SIZE;){
			if ( Convert -> dwDirection == SHIFT_N ){
				pOpen -> dwRxWork |= *pInBuff & Convert -> dwData;
			}else if ( Convert -> dwDirection == SHIFT_L ){
				pOpen -> dwRxWork |= (*pInBuff & Convert -> dwData) << Convert -> dwShift;
			}else{
				pOpen -> dwRxWork |= (*pInBuff & Convert -> dwData) >> Convert -> dwShift;
			}
			if ( Convert -> dwInc & INC_SRC ){
				pInBuff ++;
				i += sizeof(DWORD);
			}
			if ( Convert -> dwInc & INC_DST ){
				WRITE_REGISTER_ULONG(((PVBYTE)(pOpen -> pvInWorkBuffer + pOpen -> dwInWorkWPtr)), pOpen -> dwRxWork);
				pOpen -> dwInWorkWPtr += sizeof(DWORD);
				pOpen -> dwInWorkWPtr &= (SPDIF_WORK_IBUFFER_SIZE-1);
				pOpen -> dwRxWork = 0;
			}
			if ( Convert -> dwInc == (INC_SRC|INC_DST) ){
				pOpen -> dwRxShiftPtr = 0;
				Convert = pOpen -> RxBits;
			}else{
				Convert++;
				pOpen -> dwRxShiftPtr ++;
			}
		}
	}
}



⌨️ 快捷键说明

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