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

📄 hspi.c

📁 SMDK2416_BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
//-------------------------------------------------------------------------------------------------------------------------
// Copyright (c) Samsung Electronics Co., Ltd.  All rights reserved.
//-------------------------------------------------------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 
// INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
//
// Module Name :    HSPI.C
//
// Abstract     :   HS-SPI Interface Routines for Samsung SC2450 CPU
//
// Environment :    Samsung SC2450 / CE5.0
//
// 2007/03/05
//
//-------------------------------------------------------------------------------------------------------------------------

#include <windows.h>
//#include <types.h>	//
#include <nkintr.h>

//#include <ceddk.h>	//For DMA Buffer Alloc

//#include <memory.h> //070205
//#include <bsp_cfg.h>  //070205 
#include <s3c2450.h>	//070205


//#include <excpt.h>
//#include <tchar.h>
//#include <cardserv.h>
//#include <cardapi.h>
//#include <tuple.h>
//#include <devload.h>
//#include <diskio.h>
//#include <windev.h>

#include "hspi.h"  //070307

#define MASTER_CS_ENABLE		pSPIregs->SLAVE_SELECTION_REG = 0
#define MASTER_CS_DISABLE		pSPIregs->SLAVE_SELECTION_REG = 1

#define TRAIL_CNT(n)				(((n)&0x3FF)<<19)


DWORD HW_Init(PSPI_PUBLIC_CONTEXT pPublicSpi);

DWORD ThreadForTx(PSPI_PUBLIC_CONTEXT pPublicSpi);
DWORD ThreadForRx(PSPI_PUBLIC_CONTEXT pPublicSpi);
DWORD ThreadForSpi(PSPI_PUBLIC_CONTEXT pPublicSpi);
DWORD ThreadForRxDmaDone(PSPI_PUBLIC_CONTEXT pPublicSpi);
DWORD ThreadForTxDmaDone(PSPI_PUBLIC_CONTEXT pPublicSpi);



BOOL
DllEntry(
    HINSTANCE   hinstDll,            
    DWORD   	dwReason,               
    LPVOID  	lpReserved)
{
    if ( dwReason == DLL_PROCESS_ATTACH ) {
        DEBUGMSG (1, (TEXT("SPI: Process Attach\r\n")));
    }

    if ( dwReason == DLL_PROCESS_DETACH ) {
        DEBUGMSG (1, (TEXT("SPI: Process Detach\r\n")));
    }

    return(TRUE);
}

DWORD
HW_Init(
    PSPI_PUBLIC_CONTEXT pPublicSpi
    )
{

	BOOL bResult = TRUE;


	if ( !pPublicSpi ) {
	    return FALSE;
	}
	


	// GPIO Virtual alloc
	pPublicSpi->pGPIOregs = (volatile S3C2450_IOPORT_REG *) VirtualAlloc(0,sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
	if(pPublicSpi->pGPIOregs == NULL) {
		RETAILMSG(1,(TEXT("For pGPIOregs: VirtualAlloc failed!\r\n")));
		bResult = FALSE;
	}
	else {
		if(!VirtualCopy((PVOID)pPublicSpi->pGPIOregs,(PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8),sizeof(S3C2450_IOPORT_REG),PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE )) {
			RETAILMSG(1,(TEXT("For pGPIOregs: VirtualCopy failed!\r\n")));
			bResult = FALSE;
		}
	}

	// HS-SPI Virtual alloc
	pPublicSpi->pHSSPIregs = (volatile S3C2450_HSSPI_REG *) VirtualAlloc(0,sizeof(S3C2450_HSSPI_REG), MEM_RESERVE, PAGE_NOACCESS);
	if(pPublicSpi->pHSSPIregs == NULL) {
		RETAILMSG(1,(TEXT("For pHS SPIregs: VirtualAlloc failed!\r\n")));
		bResult = FALSE;
	}
	else {
#if (BSP_TYPE == BSP_SMDK2443)
		if(!VirtualCopy((PVOID)pPublicSpi->pHSSPIregs,(PVOID)(S3C2450_BASE_REG_PA_HSSPI >> 8),sizeof(S3C2450_HSSPI_REG),PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE )) {
#elif (BSP_TYPE == BSP_SMDK2450)
		if(!VirtualCopy((PVOID)pPublicSpi->pHSSPIregs,(PVOID)(S3C2450_BASE_REG_PA_HSSPI0 >> 8),sizeof(S3C2450_HSSPI_REG),PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE )) {
#endif
			RETAILMSG(1,(TEXT("For pSPIregs: VirtualCopy failed!\r\n")));
			bResult = FALSE;
		}
	}

	// Interrupt Virtual alloc
	pPublicSpi->pINTRregs = (volatile S3C2450_INTR_REG *) VirtualAlloc(0,sizeof(S3C2450_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
	if(pPublicSpi->pINTRregs == NULL) {
		RETAILMSG(1,(TEXT("For pINTRregs: VirtualAlloc failed!\r\n")));
		bResult = FALSE;
	}
	else {
		if(!VirtualCopy((PVOID)pPublicSpi->pINTRregs,(PVOID)(S3C2450_BASE_REG_PA_INTR >> 8),sizeof(S3C2450_INTR_REG),PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE )) {
			RETAILMSG(1,(TEXT("For pINTRregs: VirtualCopy failed!\r\n")));
			bResult = FALSE;
		}
	}

	// Clock Virtual alloc
	pPublicSpi->pCLKPWRregs = (volatile S3C2450_CLKPWR_REG *) VirtualAlloc(0,sizeof(S3C2450_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
	if(pPublicSpi->pCLKPWRregs == NULL) {
		RETAILMSG(1,(TEXT("For pSPIregs: VirtualAlloc failed!\r\n")));
		bResult = FALSE;
	}
	else {
		if(!VirtualCopy((PVOID)pPublicSpi->pCLKPWRregs,(PVOID)(S3C2450_BASE_REG_PA_CLOCK_POWER >> 8),sizeof(S3C2450_CLKPWR_REG),PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE )) {
			RETAILMSG(1,(TEXT("For pSPIregs: VirtualCopy failed!\r\n")));
			bResult = FALSE;
		}
	}
	// DMA Virtual alloc
	pPublicSpi->pDMAregs = (volatile S3C2450_DMA_REG *) VirtualAlloc(0,sizeof(S3C2450_DMA_REG), MEM_RESERVE, PAGE_NOACCESS);
	if(pPublicSpi->pDMAregs == NULL) {
		RETAILMSG(1,(TEXT("For pSPIregs: VirtualAlloc failed!\r\n")));
		bResult = FALSE;
	}
	else {
		if(!VirtualCopy((PVOID)pPublicSpi->pDMAregs,(PVOID)(S3C2450_BASE_REG_PA_DMA >> 8),sizeof(S3C2450_DMA_REG),PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE )) {
			RETAILMSG(1,(TEXT("For pSPIregs: VirtualCopy failed!\r\n")));
			bResult = FALSE;
		}
	}

	if (!bResult)
	{
		if(pPublicSpi->pGPIOregs) VirtualFree((PVOID) pPublicSpi->pGPIOregs, 0,   MEM_RELEASE);
		if(pPublicSpi->pHSSPIregs) VirtualFree((PVOID) pPublicSpi->pHSSPIregs, 0,    MEM_RELEASE);		// for HS-SPI
		if(pPublicSpi->pINTRregs) VirtualFree((PVOID) pPublicSpi->pINTRregs, 0,   MEM_RELEASE);
		if(pPublicSpi->pDMAregs) VirtualFree((PVOID) pPublicSpi->pDMAregs, 0,   MEM_RELEASE);

		pPublicSpi->pGPIOregs     = NULL;
		pPublicSpi->pHSSPIregs      = NULL;		// for HS-SPI
		pPublicSpi->pINTRregs     = NULL;
		pPublicSpi->pDMAregs      = NULL;
		
		return FALSE;
	}


	//Set GPIO for MISO, MOSI, SPICLK, SS
	pPublicSpi->pGPIOregs->MISCCR |= (1<<31);	// HS-SPI Select
#if (BSP_TYPE == BSP_SMDK2443)
	pPublicSpi->pGPIOregs->GPEUDP = pPublicSpi->pGPIOregs->GPEUDP & ~(0x3f<<22) | (2<<22) | (2<<24) | (0<<26); // SPICLK0, SPIMOSI0, SPIMISO0
	pPublicSpi->pGPIOregs->GPLUDP = pPublicSpi->pGPIOregs->GPLUDP & ~(0x3ff<<20) | (2<<20) | (2<<22) | (2<<24) | (2<<26) | (2<<28); // SS1, SS0, SPIMISO1, SPIMOSI1, SPICLK1
#elif (BSP_TYPE == BSP_SMDK2450)
	pPublicSpi->pGPIOregs->GPEUDP = pPublicSpi->pGPIOregs->GPEUDP & ~(0x3f<<22);
	pPublicSpi->pGPIOregs->GPLUDP = pPublicSpi->pGPIOregs->GPLUDP & ~(0x3ff<<20);
#endif

	pPublicSpi->pGPIOregs->GPECON = pPublicSpi->pGPIOregs->GPECON & ~(0x3f<<22) | (1<<27) | (1<<25) | (1<<23); // SPICLK0, SPIMOSI0, SPIMISO0
	pPublicSpi->pGPIOregs->GPLCON = pPublicSpi->pGPIOregs->GPLCON & ~(0x3ff<<20) | (1<<29) | (1<<27) | (1<<25) | (1<<23) | (1<<21); // SS1, SS0, SPIMISO1, SPIMOSI1, SPICLK1


	// Clock On
	pPublicSpi->pCLKPWRregs->SCLKCON |= (1<<14);		// For HS-SPI
	pPublicSpi->pCLKPWRregs->PCLKCON |= (1<<6);			// For HS-SPI

	// Set EPLL

#if 0
	pPublicSpi->pCLKPWRregs->LOCKCON1=0x800; 
	pPublicSpi->pCLKPWRregs->CLKSRC|= (1<<6);  // EPLL Output
	pPublicSpi->pCLKPWRregs->EPLLCON  = (40<<16) | (1<<8) | 1;	//96MHz
	pPublicSpi->pCLKPWRregs->EPLLCON &= ~(1<<24);  // EPLL ON 
	pPublicSpi->pCLKPWRregs->CLKDIV1 = (pPublicSpi->pCLKPWRregs->CLKDIV1 & ~(0x3<<24)) | (0x0<<24);	// SPI Clk Divider
	pPublicSpi->pGPIOregs->MISCCR = pPublicSpi->pGPIOregs->MISCCR & ~(0x7<<8) | (1<<8);	// CLKOUT1 pad :  EPLL Output
#endif




	
	return TRUE;

}



PSPI_PUBLIC_CONTEXT HSP_Init(PVOID Context) 
{
	LPTSTR          				ActivePath = (LPTSTR) Context; // HKLM\Drivers\Active\xx
	PSPI_PUBLIC_CONTEXT		pPublicSpi = NULL;
	BOOL            				bResult = TRUE;
	DWORD           			dwHwIntr=0;

	RETAILMSG(1,(TEXT("++HSP_Init Function\r\n")));
	RETAILMSG(1,(TEXT("Active Path : %s\n"), ActivePath));

	if ( !(pPublicSpi = (PSPI_PUBLIC_CONTEXT)LocalAlloc( LPTR, sizeof(SPI_PUBLIC_CONTEXT) )) )
	{
		RETAILMSG(1,(TEXT("Can't not allocate for SPI Context\n")));
		return NULL;
	}


    if(!HW_Init(pPublicSpi)) 
    {
    	RETAILMSG(1,(TEXT("HW_Init is failed\n")));
    	return NULL;
    } else {
    	RETAILMSG(1,(TEXT("HW_Init is completed\n")));
    }
    
	do 
	{
		InitializeCriticalSection(&(pPublicSpi->CsRxAccess));
		InitializeCriticalSection(&(pPublicSpi->CsTxAccess));

		//Rx Thread
		pPublicSpi->hRxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
		
		pPublicSpi->hRxThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForRx, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwRxThreadId);
		if (pPublicSpi->hRxThread == NULL)
		{
			RETAILMSG(1,(TEXT("SPI Rx Thread creation error!!!\n")));
			bResult = FALSE;
			break;
		}
		
		pPublicSpi->hRxDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);		
		pPublicSpi->hRxIntrDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
		
		//Tx Thread
		pPublicSpi->hTxEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
		
		pPublicSpi->hTxThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForTx, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwTxThreadId);
		if (pPublicSpi->hTxThread == NULL)
		{
			RETAILMSG(1,(TEXT("SPI Dma Thread creation error!!!\n")));
			bResult = FALSE;
			break;
		}
		
		pPublicSpi->hTxDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);		
		pPublicSpi->hTxIntrDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
		
		//Spi ISR
		pPublicSpi->dwSpiSysIntr = SYSINTR_NOP;
		dwHwIntr = IRQ_SPI1;		//HS-SPI

		pPublicSpi->hSpiEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
		
		if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &pPublicSpi->dwSpiSysIntr, sizeof(DWORD), NULL))
		{
			RETAILMSG(1,(TEXT("Failed to request the SPI sysintr.\n")));
			pPublicSpi->dwSpiSysIntr = SYSINTR_UNDEFINED;
			bResult = FALSE;
			break;
		}

		if (!InterruptInitialize(pPublicSpi->dwSpiSysIntr, pPublicSpi->hSpiEvent, NULL, 0))
		{
			RETAILMSG(1,(TEXT("SPI Interrupt Initialization failed!!!\n")));
			bResult = FALSE;
			break;
		}

		pPublicSpi->hSpiThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForSpi, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwSpiThreadId);
		if (pPublicSpi->hSpiThread == NULL)
		{
			RETAILMSG(1,(TEXT("SPI ISR Thread creation error!!!\n")));
			bResult = FALSE;
			break;
		}
		
		
		//Rx DMA Done ISR
		pPublicSpi->dwRxDmaDoneSysIntr = SYSINTR_NOP;	
		dwHwIntr = IRQ_DMA3;	

		pPublicSpi->hRxDmaDoneDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
		pPublicSpi->hRxDmaDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);


		if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &pPublicSpi->dwRxDmaDoneSysIntr, sizeof(DWORD), NULL))
		{
			RETAILMSG(1,(TEXT("Failed to request the SPI_DMA sysintr.\n")));
			pPublicSpi->dwRxDmaDoneSysIntr = SYSINTR_UNDEFINED;
			bResult = FALSE;
			break;
		}

		if (!InterruptInitialize(pPublicSpi->dwRxDmaDoneSysIntr, pPublicSpi->hRxDmaDoneEvent, NULL, 0))
		{
			RETAILMSG(1,(TEXT("DMA Interrupt Initialization failed!!!\n")));
			bResult = FALSE;
			break;
		}

		pPublicSpi->hRxDmaDoneThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForRxDmaDone, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwRxDmaDoneThreadId);
		if (pPublicSpi->hRxDmaDoneThread == NULL)
		{
			RETAILMSG(1,(TEXT("SPI Dma Thread creation error!!!\n")));
			bResult = FALSE;
			break;
		}
		
		//Tx DMA Done ISR
		pPublicSpi->dwTxDmaDoneSysIntr = SYSINTR_NOP;
		dwHwIntr = IRQ_DMA4;		
		
		pPublicSpi->hTxDmaDoneDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
		pPublicSpi->hTxDmaDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);


		if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &pPublicSpi->dwTxDmaDoneSysIntr, sizeof(DWORD), NULL))
		{
			RETAILMSG(1,(TEXT("Failed to request the SPI_DMA sysintr.\n")));
			pPublicSpi->dwTxDmaDoneSysIntr = SYSINTR_UNDEFINED;
			bResult = FALSE;
			break;
		}

		if (!InterruptInitialize(pPublicSpi->dwTxDmaDoneSysIntr, pPublicSpi->hTxDmaDoneEvent, NULL, 0))
		{
			RETAILMSG(1,(TEXT("DMA Interrupt Initialization failed!!!\n")));
			bResult = FALSE;
			break;
		}

		pPublicSpi->hTxDmaDoneThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ThreadForTxDmaDone, (LPVOID)pPublicSpi, 0, (LPDWORD)&pPublicSpi->dwTxDmaDoneThreadId);
		if (pPublicSpi->hTxDmaDoneThread == NULL)
		{
			RETAILMSG(1,(TEXT("SPI Dma Thread creation error!!!\n")));
			bResult = FALSE;
			break;
		}
	} while (0);
	
	
	if(bResult) return pPublicSpi;
	else 		return NULL;
}

DWORD
HSP_Open(
   DWORD 		pContext,   
   DWORD        AccessCode,
   DWORD        ShareMode)
{
	PSPI_PUBLIC_CONTEXT		pSpiPublic  = (PSPI_PUBLIC_CONTEXT) pContext;
	PSPI_PRIVATE_CONTEXT	pSpiPrivate = NULL;
	BOOL            		bResult 	= TRUE;
	

	if ( !(pSpiPrivate = (PSPI_PRIVATE_CONTEXT)LocalAlloc( LPTR, sizeof(SPI_PRIVATE_CONTEXT) )) )
	{

⌨️ 快捷键说明

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