📄 spi.c
字号:
{
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);
CleanUp:
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 = NULL;
PSPI_PRIVATE_CONTEXT pSpiPrivate = NULL;
BOOL bResult = TRUE;
if(pContext != 0)
{
pSpiPublic = (PSPI_PUBLIC_CONTEXT) pContext;
}
else
{
bResult = FALSE;
goto CleanUp;
}
if ( !(pSpiPrivate = (PSPI_PRIVATE_CONTEXT)LocalAlloc( LPTR, sizeof(SPI_PRIVATE_CONTEXT) )) )
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] Can't not allocate for SPI Context\n")));
bResult = FALSE;
goto CleanUp;
}
pSpiPrivate->State = STATE_INIT;
pSpiPrivate->pSpiPublic = pSpiPublic;
pSpiPrivate->bUseRxDMA = FALSE;
pSpiPrivate->bUseRxIntr = FALSE;
pSpiPrivate->bUseTxDMA = FALSE;
pSpiPrivate->bUseTxIntr = FALSE;
CleanUp:
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;
BOOL bResult = TRUE;
ULONG BytesRead = 0;
HRESULT hr;
PBYTE MappedEmbedded;
PBYTE Marshalled;
if((PSPI_PRIVATE_CONTEXT)hOpenContext == NULL)
{
bResult = FALSE;
goto CleanUp;
}
//param check
if(pSpiPrivate->State != STATE_IDLE)
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] READ ERROR : STATE IS NOT IDLE\n")));
bResult = FALSE;
goto CleanUp;
}
RETAILMSG(SPI_MSG,(TEXT("[SPI] pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));
hr = CeOpenCallerBuffer((PVOID*) &MappedEmbedded, pBuffer, Count, ARG_IO_PTR, FALSE);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
hr = CeAllocAsynchronousBuffer((PVOID*) &Marshalled, MappedEmbedded, Count, ARG_IO_PTR);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
if(pSpiPrivate->bUseRxDMA)
{
pSpiPrivate->pRxBuffer = pVirtDmaDstBufferAddr;
pSpiPrivate->pRxDMABuffer = (LPVOID)DmaDstAddress;
}
else
{
pSpiPrivate->pRxBuffer = Marshalled;
}
RETAILMSG(SPI_MSG,(TEXT("[SPI] MappedEmbedded 0x%x\n"),MappedEmbedded));
RETAILMSG(SPI_MSG,(TEXT("[SPI] Marshalled 0x%x\n"),Marshalled));
pSpiPrivate->dwRxCount = Count;
pSpiPublic->pSpiPrivate = pSpiPrivate;
SetEvent(pSpiPublic->hRxEvent);
//Thread call
WaitForSingleObject(pSpiPublic->hRxDoneEvent, INFINITE);
pSpiPrivate->State = STATE_IDLE;
if(pSpiPrivate->bUseRxDMA)
{
memcpy(Marshalled, pVirtDmaDstBufferAddr,Count);
}
hr = CeFreeAsynchronousBuffer((PVOID)Marshalled, MappedEmbedded, Count, ARG_IO_PTR);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
hr = CeCloseCallerBuffer((PVOID) MappedEmbedded, pBuffer, Count, ARG_IO_PTR);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
CleanUp:
BytesRead = Count - pSpiPrivate->dwRxCount;
RETAILMSG(SPI_MSG,(TEXT("[SPI] SPI_Read : Return Value : %d\n\n"), BytesRead));
if(bResult)
{
return BytesRead;
}
else
{
return -1;
}
}
DWORD
SPI_Write(
DWORD hOpenContext,
LPVOID pBuffer,
DWORD Count)
{
PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;
PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;
BOOL bResult = TRUE;
ULONG BytesWritten = 0;
HRESULT hr;
PBYTE MappedEmbedded;
PBYTE Marshalled;
if((PSPI_PRIVATE_CONTEXT)hOpenContext == NULL)
{
bResult = FALSE;
goto CleanUp;
}
//param check
if(pSpiPrivate->State != STATE_IDLE)
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] WRITE ERROR : STATE IS NOT IDLE\n")));
bResult = FALSE;
goto CleanUp;
}
RETAILMSG(SPI_MSG,(TEXT("[SPI] pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));
hr = CeOpenCallerBuffer((PVOID*) &MappedEmbedded, pBuffer, Count, ARG_IO_PTR, FALSE);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
hr = CeAllocAsynchronousBuffer((PVOID*) &Marshalled, MappedEmbedded, Count, ARG_IO_PTR);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
if(pSpiPrivate->bUseTxDMA)
{
memcpy(pVirtDmaSrcBufferAddr,Marshalled, Count);
pSpiPrivate->pTxBuffer = pVirtDmaSrcBufferAddr;
pSpiPrivate->pTxDMABuffer = (LPVOID)DmaSrcAddress;
}
else
{
pSpiPrivate->pTxBuffer = (LPVOID)Marshalled;
}
RETAILMSG(SPI_MSG,(TEXT("[SPI] MappedEmbedded 0x%x\n"),MappedEmbedded));
RETAILMSG(SPI_MSG,(TEXT("[SPI] Marshalled 0x%x\n"),Marshalled));
pSpiPrivate->dwTxCount = Count;
pSpiPublic->pSpiPrivate = pSpiPrivate;
SetEvent(pSpiPublic->hTxEvent);
//Thread call
WaitForSingleObject(pSpiPublic->hTxDoneEvent, INFINITE);
pSpiPrivate->State = STATE_IDLE;
hr = CeFreeAsynchronousBuffer((PVOID)Marshalled, MappedEmbedded, Count, ARG_IO_PTR);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
hr = CeCloseCallerBuffer((PVOID) MappedEmbedded, pBuffer, Count, ARG_IO_PTR);
if(hr != S_OK)
{
bResult = FALSE;
goto CleanUp;
}
CleanUp:
BytesWritten = Count - pSpiPrivate->dwTxCount;
RETAILMSG(SPI_MSG,(TEXT("[SPI] SPI_Write : Return Value : %d\n"), BytesWritten));
if(bResult)
{
return BytesWritten;
}
else
{
return -1;
}
}
BOOL
SPI_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 S3C6410_SPI_REG *pSPIregs = pSpiPublic->pSPIregs;
volatile S3C6410_SPI_REG *pRxSPIregs = &pSpiPrivate->RxSPIregs;
volatile S3C6410_SPI_REG *pTxSPIregs = &pSpiPrivate->TxSPIregs;
PSET_CONFIG pSetConfig;
BOOL bResult = TRUE;
PVOID pMarshalledInBuf = NULL;
//if caller is not kernel mode, do not allow setting power state
if (GetDirectCallerProcessId() != GetCurrentProcessId()){
return FALSE;
}
if((PSPI_PRIVATE_CONTEXT)dwInst == NULL)
{
bResult = FALSE;
goto CleanUp;
}
if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, lpInBuf, nInBufSize, ARG_I_PTR, TRUE)))
{
RETAILMSG(1, (TEXT("SPI_IOControl: CeOpenCallerBuffer failed for input buffer.\r\n")));
return FALSE;
}
switch(dwIoControlCode)
{
case SPI_IOCTL_SET_CONFIG:
__try
{
if( nInBufSize != sizeof(SET_CONFIG) )
{
bResult = FALSE;
break;
}
pSetConfig = (PSET_CONFIG) lpInBuf;
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;
//Slave TX output time control
pRxSPIregs->CH_CFG &= ~(HIGH_SPEED_MASK);
pRxSPIregs->CH_CFG |= (HIGH_SPEED_EN);
pRxSPIregs->CLK_CFG = CLKSEL|(pSpiPrivate->dwPrescaler);
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(SPI_MSG,(TEXT("[SPI] It's not supported MODE\n")));
pSpiPrivate->State = STATE_ERROR;
}
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
RETAILMSG( 1, ( _T("SPI_IOControl: exception occurred\n")) );
return FALSE;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -