📄 hspi.c
字号:
//-------------------------------------------------------------------------------------------------------------------------
// 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 + -