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

📄 hspi.c

📁 SMDK2416_BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
		RETAILMSG(1,(TEXT("Can't not allocate for SPI Context\n")));
		return (DWORD)NULL;
	}
    
	do 
	{
		pSpiPrivate->State				= STATE_INIT;
		
		pSpiPrivate->pSpiPublic			= pSpiPublic;
		

		pSpiPrivate->bUseRxDMA  		= FALSE;
		pSpiPrivate->bUseRxIntr		= FALSE;
		pSpiPrivate->bUseTxDMA		= FALSE;
		pSpiPrivate->bUseTxIntr		= FALSE;
		
	} while(FALSE);
	
	
	if(bResult) return (DWORD) pSpiPrivate;
	else		return (DWORD) NULL;
}


DWORD 
HSP_Read(
	DWORD 	hOpenContext, 
	LPVOID 	pBuffer, 
	DWORD 	Count) 
{
	PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;
	PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;
//	DWORD dwReadSize;
	
	
	//param check
	if(pSpiPrivate->State != STATE_IDLE) {
		RETAILMSG(1,(TEXT("READ ERROR : STATE IS NOT IDLE\n")));
		return 0;
	}
	RETAILMSG(1,(TEXT("pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));
	

	if(pSpiPrivate->bUseRxDMA)
	{
		PDMA_BUFFER pDmaBuffer = (PDMA_BUFFER) pBuffer;
		pSpiPrivate->pRxBuffer 		= pDmaBuffer->VirtualAddress;
		pSpiPrivate->pRxDMABuffer 	= pDmaBuffer->PhysicalAddress;
	}
	else 
	{
		pSpiPrivate->pRxBuffer = (LPVOID)pBuffer;
	} 
	
	pSpiPrivate->dwRxCount = Count;
	pSpiPublic->pSpiPrivate = pSpiPrivate;
	SetEvent(pSpiPublic->hRxEvent);
	WaitForSingleObject(pSpiPublic->hRxDoneEvent, INFINITE);	
	
	
	pSpiPrivate->State = STATE_IDLE;

	RETAILMSG(1,(TEXT("Return Value : %d\n"),pSpiPrivate->dwRxCount));
	
	
	return pSpiPrivate->dwRxCount ;
}


DWORD 
HSP_Write(
	DWORD 	hOpenContext, 
	LPVOID 	pBuffer, 
	DWORD 	Count) 
{
	PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;
	PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;
	
	
	//param check
	if(pSpiPrivate->State != STATE_IDLE) {
		RETAILMSG(1,(TEXT("WRITE ERROR : STATE IS NOT IDLE\n")));
		return 0;
	}
	RETAILMSG(1,(TEXT("pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));
	


	
	if(pSpiPrivate->bUseTxDMA)
	{
		PDMA_BUFFER pDmaBuffer = (PDMA_BUFFER) pBuffer;
		pSpiPrivate->pTxBuffer 		= pDmaBuffer->VirtualAddress;
		pSpiPrivate->pTxDMABuffer 	= pDmaBuffer->PhysicalAddress;
	}
	else 
	{
		pSpiPrivate->pTxBuffer = (LPVOID)pBuffer; 
	}
	
	pSpiPrivate->dwTxCount = Count;
	pSpiPublic->pSpiPrivate = pSpiPrivate;
	SetEvent(pSpiPublic->hTxEvent);
	WaitForSingleObject(pSpiPublic->hTxDoneEvent, INFINITE);	
	
	
	pSpiPrivate->State = STATE_IDLE;

	RETAILMSG(1,(TEXT("Return Value : %d\n"),pSpiPrivate->dwTxCount));
	
	
	return pSpiPrivate->dwTxCount;
}




BOOL 
HSP_IOControl(
	DWORD dwInst, 
	DWORD dwIoControlCode, 
	PBYTE lpInBuf, 
	DWORD nInBufSize, 
	PBYTE lpOutBuf, 
	DWORD nOutBufSize, 
	LPDWORD lpBytesRetruned) 
{
	PSPI_PRIVATE_CONTEXT 	pSpiPrivate 	= (PSPI_PRIVATE_CONTEXT)dwInst;
	PSPI_PUBLIC_CONTEXT		pSpiPublic 	= pSpiPrivate->pSpiPublic; 
	volatile S3C2450_HSSPI_REG 	*pSPIregs   	= pSpiPublic->pHSSPIregs;		// for HS-SPI
	volatile S3C2450_HSSPI_REG   	*pRxSPIregs = &pSpiPrivate->RxSPIregs;	// for HS-SPI
	volatile S3C2450_HSSPI_REG   	*pTxSPIregs = &pSpiPrivate->TxSPIregs;	// for HS-SPI

	PSET_CONFIG 			pSetConfig;
	BOOL					bResult = TRUE;
	
	
	switch(dwIoControlCode)
	{
		case SPI_IOCTL_SET_CONFIG:
			if( nInBufSize != sizeof(SET_CONFIG) ) 
			{
				bResult = FALSE;
				break;
			}
			pSetConfig = (PSET_CONFIG) lpInBuf;
			
//===========================================COMMON PART===========================================
			pSpiPrivate->dwTimeOutVal 		= pSetConfig->dwTimeOutVal;
			pSpiPrivate->dwMode 			= pSetConfig->dwMode;
			pSpiPrivate->dwPrescaler    		= pSetConfig->dwPrescaler;			

			pSpiPrivate->bUseRxDMA 		= pSetConfig->bUseRxDMA;
			pSpiPrivate->bUseRxIntr		= pSetConfig->bUseRxIntr;
			
			pSpiPrivate->bUseTxDMA 		= pSetConfig->bUseTxDMA;
			pSpiPrivate->bUseTxIntr		= pSetConfig->bUseTxIntr;


			pRxSPIregs->CH_CFG		= CPOL_RISING|CPHA_FORMAT_A;
#if (BSP_TYPE == BSP_SMDK2443)
			pRxSPIregs->CLK_CFG		= CLKSEL_EPLL|(pSpiPrivate->dwPrescaler);
#elif (BSP_TYPE == BSP_SMDK2450)
			pRxSPIregs->CLK_CFG		= CLKSEL_PCLK|(pSpiPrivate->dwPrescaler);
#endif
			//pRxSPIregs->MODE_CFG	= (0x3ff<<19)|(0<<2);
			pRxSPIregs->MODE_CFG	= MODE_DEFAULT;

			pTxSPIregs->CH_CFG		= pRxSPIregs->CH_CFG;	
			pTxSPIregs->CLK_CFG		= pRxSPIregs->CLK_CFG;	
			pTxSPIregs->MODE_CFG	= pRxSPIregs->MODE_CFG;
			
			if(pSpiPrivate->dwMode == SPI_MASTER_MODE) {
				pRxSPIregs->CH_CFG	|= SPI_MASTER;
				pRxSPIregs->CLK_CFG	|= ENCLK_ENABLE;
				
				pTxSPIregs->CH_CFG	|= SPI_MASTER;
				pTxSPIregs->CLK_CFG	|= ENCLK_ENABLE;
			} else if(pSpiPrivate->dwMode == SPI_SLAVE_MODE) {
				pRxSPIregs->CH_CFG	|= SPI_SLAVE;
				pRxSPIregs->CLK_CFG	|= ENCLK_DISABLE;
				
				pTxSPIregs->CH_CFG	|= SPI_SLAVE;
				pTxSPIregs->CLK_CFG	|= ENCLK_DISABLE;
			} else {
				RETAILMSG(1,(TEXT("it's not supported MODE\n")));
				pSpiPrivate->State = STATE_ERROR;
				break;
			}
			
//===========================================RX PART============================================


			if(pSpiPrivate->bUseRxIntr)
			//INTR
			{

			}
			else if(pSpiPrivate->bUseRxDMA)
			//DMA
			{

			}
			else 
			//Polling
			{

			}
										
//===========================================TX PART============================================			
			

			if(pSpiPrivate->bUseTxIntr) 
			// INTR
			{

			}
			else if(pSpiPrivate->bUseTxDMA)
			// DMA 
			{

			}
			else 
			//Polling
			{

			}

			break;
		case SPI_IOCTL_GET_CONFIG:
			break;
		case SPI_IOCTL_CLR_TXBUFF:
			break;
		case SPI_IOCTL_CLR_RXBUFF:
			break;
		case SPI_IOCTL_STOP:
			break;

		case SPI_IOCTL_START:
			if(pSpiPrivate->State == STATE_ERROR) {
				RETAILMSG(1,(TEXT("SPI_IOCTL_START ERROR\n")));
				bResult = FALSE;
				break;
			}
			pSpiPrivate->State = STATE_IDLE;
			RETAILMSG(1,(TEXT("SPI STATE : SPI_IOCTL_START\n")));
			break;
		default:
			break;
	}
	
	return bResult;
}


DWORD ThreadForTx(PSPI_PUBLIC_CONTEXT pSpiPublic)
{
	volatile S3C2450_HSSPI_REG 	*pSPIregs   	= pSpiPublic->pHSSPIregs;	// for HS-SPI
	volatile S3C2450_INTR_REG 	*pINTRregs 	= pSpiPublic->pINTRregs;
	volatile S3C2450_DMA_REG 	*pDMAregs   	= pSpiPublic->pDMAregs;
	PSPI_PRIVATE_CONTEXT 	pSpiPrivate;
	DWORD 	dwTxCount;
	PBYTE 	pTxBuffer;
	DWORD 	dwOldPerm;

	PBYTE 	pTestBuffer;
	DWORD 	dwTestCount;

	
	do
	{
		WaitForSingleObject(pSpiPublic->hTxEvent, INFINITE);
		
		
		pSpiPrivate 	= (PSPI_PRIVATE_CONTEXT) pSpiPublic->pSpiPrivate;
		dwTestCount 	= dwTxCount = pSpiPrivate->dwTxCount;
		dwOldPerm 	= SetProcPermissions((DWORD)-1);
		pTestBuffer 	= pTxBuffer = (PBYTE) MapPtrToProcess(pSpiPrivate->pTxBuffer, (HANDLE) GetCurrentProcessId());

		RETAILMSG(1,(TEXT("pTxBuffer : 0x%X, dwTxCount : %d \r\n"), pTxBuffer, dwTxCount));

		//Reset
		pSPIregs->CH_CFG |= SW_RST;
		RETAILMSG(1,(TEXT("\n HS SPI reset\n")));
		pSPIregs->CH_CFG &= ~SW_RST;	



		if(pSpiPrivate->bUseTxIntr)
		// INT  + TX
		{
			RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : USE INT \r\n")));
			pSpiPrivate->State = STATE_TXINTR;
/*
			if(pSpiPrivate->dwMode == SPI_MASTER_MODE) {
				pSPIregs->CH_CFG 	= 0x0;
				pSPIregs->CLK_CFG  	= pSpiPrivate->TxSPIregs.CLK_CFG;	
				pSPIregs->MODE_CFG	= (TX_TRIG_LEVEL<<5);
			} else {
				pSPIregs->CH_CFG 	= (0x1<<4);
				pSPIregs->CLK_CFG  	= pSpiPrivate->TxSPIregs.CLK_CFG;
				pSPIregs->MODE_CFG	= (TX_TRIG_LEVEL<<5);
			}	


			pSPIregs->SP_INT_EN			=	(1<<0);
			pSPIregs->PENDING_CLR_REG	=	(0x1f);
			pSPIregs->CH_CFG			= 	(1<<0);

			if(pSpiPrivate->dwMode == SPI_MASTER_MODE) {
				RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : MASTER MODE \r\n")));
				pSPIregs->SLAVE_SELECTION_REG = 0;
			} 
			else{ 
				RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : SLAVE MODE \r\n")));
			}

			WaitForSingleObject(pSpiPublic->hTxIntrDoneEvent, INFINITE);

			while(((pSPIregs ->SPI_STATUS>>6) & 0x7f));
			while(!((pSPIregs ->SPI_STATUS>>21) & 0x1));
*/
		}
		else if(pSpiPrivate->bUseTxDMA)
		// DMA + TX
		{
			DWORD dwDmaLen			= dwTxCount & 0xFFFFF ;

			RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : USE DMA (TxCount : %d) \r\n"),dwDmaLen));
			
			pSpiPrivate->State = STATE_TXDMA;
			VirtualCopy((PVOID)pSpiPrivate->pTxBuffer, (PVOID)((ULONG) pSpiPrivate->pTxDMABuffer>>8), sizeof(dwTxCount), PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL);

			if(pSpiPrivate->dwMode == SPI_MASTER_MODE) 
			{
				pSPIregs->CH_CFG 	= pSpiPrivate->TxSPIregs.CH_CFG;
				pSPIregs->CLK_CFG  	= pSpiPrivate->TxSPIregs.CLK_CFG;
				pSPIregs->MODE_CFG  = pSpiPrivate->TxSPIregs.MODE_CFG;
			}else {
				pSPIregs->CH_CFG 	= pSpiPrivate->TxSPIregs.CH_CFG;
				pSPIregs->CLK_CFG  	= pSpiPrivate->TxSPIregs.CLK_CFG;
				pSPIregs->MODE_CFG  = pSpiPrivate->TxSPIregs.MODE_CFG;
			}	

		
			if(dwDmaLen > 0)
			{

				pSPIregs->MODE_CFG		|=	TX_DMA_ON|DMA_SINGLE;
				pSPIregs->CH_CFG 		|=	TX_CH_ON;
				
				pDMAregs->DISRC4      	= (UINT)pSpiPrivate->pTxDMABuffer;
				pDMAregs->DISRCC4     	= ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS); 
				pDMAregs->DIDST4      	= (UINT)SPI_TX_DATA_PHY_ADDR;
				pDMAregs->DIDSTC4     	= (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS); 
//				pDMAregs->DCON4  		= HANDSHAKE_MODE |GENERATE_INTERRUPT |PADDRFIX |NO_DMA_AUTO_RELOAD | dwDmaLen;
				pDMAregs->DCON4  		= HANDSHAKE_MODE |GENERATE_INTERRUPT |NO_DMA_AUTO_RELOAD | dwDmaLen;
				pDMAregs->DMAREQSEL4 	= ( DMAREQSEL_SPI_0TX | DMA_TRIGGERED_BY_HARDWARE );


				if(pSpiPrivate->dwMode == SPI_MASTER_MODE) 
				{
					RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : MASTER MODE \r\n")));
					MASTER_CS_ENABLE;
				} 
				else
				{ 
					RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : SLAVE MODE \r\n")));
				}

				pDMAregs->DMASKTRIG4 	= ENABLE_DMA_CHANNEL; 	
				
				WaitForSingleObject(pSpiPublic->hTxDmaDoneDoneEvent, INFINITE);
				

				pSpiPrivate->dwTxCount -= dwDmaLen;
				pSpiPrivate->pTxBuffer = (((PUINT) pSpiPrivate->pTxBuffer) + dwDmaLen);
			}
			VirtualFree((PVOID)pTxBuffer, 0, MEM_RELEASE);

⌨️ 快捷键说明

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