PSPI_PUBLIC_CONTEXT SPI_Init(PVOID Context)
{
LPTSTR ActivePath = (LPTSTR) Context; // HKLM\Drivers\Active\xx
PSPI_PUBLIC_CONTEXT pPublicSpi = NULL;
BOOL bResult = TRUE;
DWORD dwHwIntr=0;
RETAILMSG(SPI_INIT,(TEXT("++[SPI] HSP_Init Function\r\n")));
RETAILMSG(SPI_MSG,(TEXT("[SPI] Active Path : %s\n"), ActivePath));
if ( !(pPublicSpi = (PSPI_PUBLIC_CONTEXT)LocalAlloc( LPTR, sizeof(SPI_PUBLIC_CONTEXT) )) )
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] Can't not allocate for SPI Context\n")));
return NULL;
}
if ( !(pRestoreSPIregs = (PS3C6410_SPI_REG)LocalAlloc( LPTR, sizeof(S3C6410_SPI_REG) )) )
{
return NULL;
}
if(!HW_Init(pPublicSpi))
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] HW_Init is failed\n")));
return NULL;
}
else
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] HW_Init is completed\n")));
}
if(!InitializeBuffer())
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] InitializeBuffer is failed\n")));
return NULL;
}
else
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] InitializeBuffer is completed\n")));
}
// Request DMA Channel
// DMA context have Virtual IRQ Number of Allocated DMA Channel
// You Should initialize DMA Interrupt Thread after "Request DMA Channel"
DMA_request_channel(&g_OutputDMA, DMA_SPI0_TX);
DMA_request_channel(&g_InputDMA, DMA_SPI0_RX);
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(SPI_INIT,(TEXT("[SPI] 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(SPI_INIT,(TEXT("[SPI] 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_SPI0; //HS-SPI
pPublicSpi->hSpiEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwHwIntr, sizeof(DWORD), &pPublicSpi->dwSpiSysIntr, sizeof(DWORD), NULL))
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] Failed to request the SPI sysintr.\n")));
pPublicSpi->dwSpiSysIntr = SYSINTR_UNDEFINED;
bResult = FALSE;
break;
}
if (!InterruptInitialize(pPublicSpi->dwSpiSysIntr, pPublicSpi->hSpiEvent, NULL, 0))
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] 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(SPI_INIT,(TEXT("[SPI] SPI ISR Thread creation error!!!\n")));
bResult = FALSE;
break;
}
//Tx DMA Done ISR
pPublicSpi->dwTxDmaDoneSysIntr = SYSINTR_NOP;
dwHwIntr = g_OutputDMA.dwIRQ;
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(SPI_INIT,(TEXT("[SPI] Failed to request the SPI_DMA sysintr.\n")));
pPublicSpi->dwTxDmaDoneSysIntr = SYSINTR_UNDEFINED;
bResult = FALSE;
break;
}
if (!InterruptInitialize(pPublicSpi->dwTxDmaDoneSysIntr, pPublicSpi->hTxDmaDoneEvent, NULL, 0))
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] 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(SPI_INIT,(TEXT("[SPI] SPI Dma Thread creation error!!!\n")));
bResult = FALSE;
break;
}
//Rx DMA Done ISR
pPublicSpi->dwRxDmaDoneSysIntr = SYSINTR_NOP;
dwHwIntr = g_InputDMA.dwIRQ;
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(SPI_INIT,(TEXT("[SPI] Failed to request the SPI_DMA sysintr.\n")));
pPublicSpi->dwRxDmaDoneSysIntr = SYSINTR_UNDEFINED;
bResult = FALSE;
break;
}
if (!InterruptInitialize(pPublicSpi->dwRxDmaDoneSysIntr, pPublicSpi->hRxDmaDoneEvent, NULL, 0))
{
RETAILMSG(SPI_INIT,(TEXT("[SPI] 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(SPI_INIT,(TEXT("[SPI] SPI Dma Thread creation error!!!\n")));
bResult = FALSE;
break;
}
} while (0);
RETAILMSG(SPI_INIT,(TEXT("--[SPI] HSP_Init Function\r\n")));
if(bResult)
{
return pPublicSpi;
}
else
{
return NULL;
}
}
DWORD
SPI_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) )) )
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] 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
SPI_Read(
DWORD hOpenContext,
LPVOID pBuffer,
DWORD Count)
{
PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;
PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;
// DWORD dwReadSize;
HRESULT hr;
PBYTE g_pMappedEmbedded;
PBYTE g_pMarshalled;
//param check
if(pSpiPrivate->State != STATE_IDLE)
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] READ ERROR : STATE IS NOT IDLE\n")));
return 0;
}
RETAILMSG(SPI_MSG,(TEXT("[SPI] pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));
hr = CeOpenCallerBuffer((PVOID*) &g_pMappedEmbedded, pBuffer, Count, ARG_IO_PTR, FALSE);
hr = CeAllocAsynchronousBuffer((PVOID*) &g_pMarshalled, g_pMappedEmbedded, Count, ARG_IO_PTR);
if(pSpiPrivate->bUseRxDMA)
{
pSpiPrivate->pRxBuffer = pVirtDmaDstBufferAddr;
pSpiPrivate->pRxDMABuffer = (LPVOID)DmaDstAddress;
}
else
{
pSpiPrivate->pRxBuffer = g_pMarshalled;
}
RETAILMSG(SPI_MSG,(TEXT("[SPI] g_pMappedEmbedded 0x%x\n"),g_pMappedEmbedded));
RETAILMSG(SPI_MSG,(TEXT("[SPI] g_pMarshalled 0x%x\n"),g_pMarshalled));
pSpiPrivate->dwRxCount = Count;
pSpiPublic->pSpiPrivate = pSpiPrivate;
SetEvent(pSpiPublic->hRxEvent);
//Thread call
WaitForSingleObject(pSpiPublic->hRxDoneEvent, INFINITE);
pSpiPrivate->State = STATE_IDLE;
if(pSpiPrivate->bUseRxDMA)
{
memcpy(g_pMarshalled, pVirtDmaDstBufferAddr,Count);
}
hr = CeFreeAsynchronousBuffer((PVOID)g_pMarshalled, g_pMappedEmbedded, Count, ARG_IO_PTR);
hr = CeCloseCallerBuffer((PVOID) g_pMappedEmbedded, pBuffer, Count, ARG_IO_PTR);
RETAILMSG(SPI_MSG,(TEXT("[SPI] SPI_Read : Return Value : %d\n\n"),pSpiPrivate->dwRxCount));
return pSpiPrivate->dwRxCount ;
}