📄 spi.c
字号:
pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG;
pSPIregs->PACKET_COUNT = PACKET_CNT_EN | (pSpiPrivate->dwRxCount) ;
}
else
{
pSPIregs->CH_CFG = pSpiPrivate->RxSPIregs.CH_CFG;
pSPIregs->CLK_CFG = pSpiPrivate->RxSPIregs.CLK_CFG;
pSPIregs->MODE_CFG = pSpiPrivate->RxSPIregs.MODE_CFG;
}
pSPIregs->CH_CFG |= RX_CH_ON;
if(pSpiPrivate->dwMode == SPI_MASTER_MODE)
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] Thread for RX : MASTER MODE \r\n")));
MASTER_CS_ENABLE;
}
else
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] Thread for RX : SLAVE MODE \r\n")));
}
TotalTimeOut = READ_TIME_OUT_CONSTANT*100*50 + (READ_TIME_OUT_MULTIPLIER)*dwRxCount;
Count = 0;
do
{
while (((pSPIregs ->SPI_STATUS>>13)&0x7f)==FIFO_EMPTY)
{
Count++;
if(TotalTimeOut == Count)
{
// Timeout
RETAILMSG (TRUE, (TEXT("Read timeout!!!\r\n")));
goto LEAVEREAD;
}
}
*(PBYTE)pSpiPrivate->pRxBuffer = pSPIregs->SPI_RX_DATA;
} while(--pSpiPrivate->dwRxCount > 0 && ++(PBYTE)pSpiPrivate->pRxBuffer);
}
LEAVEREAD:
#ifdef TEST_MODE
do
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] READ BYTE : %02X(dwRxCount %d)\n"), *pTestBuffer, dwTestCount));
} while((--dwTestCount > 0) && ++pTestBuffer);
#endif
RETAILMSG(FALSE,(TEXT("[SPI] RX_CH_OFF \n")));
pSPIregs->CH_CFG &= ~RX_CH_ON;
if(pSpiPrivate->dwMode == SPI_MASTER_MODE)
{
MASTER_CS_DISABLE;
}
SetEvent(pSpiPublic->hRxDoneEvent);
} while(TRUE);
return 0;
}
DWORD ThreadForSpi(PSPI_PUBLIC_CONTEXT pSpiPublic)
{
volatile S3C6410_SPI_REG *pSPIregs = pSpiPublic->pSPIregs; // for HS-SPI
PSPI_PRIVATE_CONTEXT pSpiPrivate;
DWORD dwRxCount;
DWORD dwTxCount;
RETAILMSG(SPI_MSG,(TEXT("[SPI] ThreadForSpi thread is created \r\n")));
do
{
WaitForSingleObject(pSpiPublic->hSpiEvent, INFINITE);
pSpiPrivate = (PSPI_PRIVATE_CONTEXT) pSpiPublic->pSpiPrivate;
if(pSpiPrivate->State == STATE_RXINTR)
{
if(pSpiPrivate->dwMode == SPI_MASTER_MODE)
{
do
{
while (((pSPIregs ->SPI_STATUS>>13)&0x7f)==FIFO_EMPTY);
*(PBYTE)pSpiPrivate->pRxBuffer = pSPIregs->SPI_RX_DATA;
} while(--pSpiPrivate->dwRxCount > 0 && ++(PBYTE)pSpiPrivate->pRxBuffer);
if(pSpiPrivate->dwRxCount ==0)
{
pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);
SetEvent(pSpiPublic->hRxIntrDoneEvent);
}
}
else
{
dwRxCount = ((pSPIregs ->SPI_STATUS>>13) & 0x7f) ;
do
{
*(PBYTE)pSpiPrivate->pRxBuffer = pSPIregs->SPI_RX_DATA;
} while(--pSpiPrivate->dwRxCount > 0 && ++(PBYTE)pSpiPrivate->pRxBuffer && --dwRxCount > 0);
if(pSpiPrivate->dwRxCount ==0)
{
pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);
SetEvent(pSpiPublic->hRxIntrDoneEvent);
}
}
}
else if(pSpiPrivate->State == STATE_TXINTR)
{
if(pSpiPrivate->dwMode == SPI_MASTER_MODE)
{
dwTxCount = FIFO_SIZE -((pSPIregs ->SPI_STATUS>>6) & 0x7f) ;
do
{
pSPIregs->SPI_TX_DATA = *(PBYTE)pSpiPrivate->pTxBuffer;
} while(--pSpiPrivate->dwTxCount > 0 && ++(PBYTE)pSpiPrivate->pTxBuffer && --dwTxCount > 0);
if(pSpiPrivate->dwTxCount ==0)
{
pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);
SetEvent(pSpiPublic->hTxIntrDoneEvent);
}
}
else
{
dwTxCount = FIFO_SIZE -((pSPIregs ->SPI_STATUS>>6) & 0x7f) ;
do
{
pSPIregs->SPI_TX_DATA = *(PBYTE)pSpiPrivate->pTxBuffer;
} while(--pSpiPrivate->dwTxCount > 0 && ++(PBYTE)pSpiPrivate->pTxBuffer && --dwTxCount > 0);
if(pSpiPrivate->dwTxCount ==0)
{
pSPIregs->SPI_INT_EN &= ~(RX_FIFORDY|TX_FIFORDY);
SetEvent(pSpiPublic->hTxIntrDoneEvent);
}
}
}
else
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] UNSOLVED OPERATION\n")));
}
//END_POINT:
InterruptDone(pSpiPublic->dwSpiSysIntr);
} while(TRUE);
return 0;
}
DWORD ThreadForRxDmaDone(PSPI_PUBLIC_CONTEXT pSpiPublic)
{
// volatile S3C6410_SPI_REG *pSPIregs = pSpiPublic->pSPIregs;
// PSPI_PRIVATE_CONTEXT pSpiPrivate;
// DWORD dwOldPerm;
do
{
WaitForSingleObject(pSpiPublic->hRxDmaDoneEvent, INFINITE);
RETAILMSG(SPI_MSG,(TEXT("[SPI] ThreadForRxDmaDone \r\n")));
DMA_set_interrupt_mask(&g_InputDMA);
DMA_clear_interrupt_pending(&g_InputDMA);
SetEvent(pSpiPublic->hRxDmaDoneDoneEvent);
InterruptDone(pSpiPublic->dwRxDmaDoneSysIntr);
DMA_clear_interrupt_mask(&g_InputDMA);
} while(TRUE);
return 0;
}
DWORD ThreadForTxDmaDone(PSPI_PUBLIC_CONTEXT pSpiPublic)
{
// volatile S3C6410_SPI_REG *pSPIregs = pSpiPublic->pSPIregs;
// PSPI_PRIVATE_CONTEXT pSpiPrivate;
// DWORD dwOldPerm;
do
{
WaitForSingleObject(pSpiPublic->hTxDmaDoneEvent, INFINITE);
RETAILMSG(SPI_MSG,(TEXT("[SPI] ThreadForTxDmaDone \r\n")));
DMA_set_interrupt_mask(&g_OutputDMA);
DMA_clear_interrupt_pending(&g_OutputDMA);
SetEvent(pSpiPublic->hTxDmaDoneDoneEvent);
InterruptDone(pSpiPublic->dwTxDmaDoneSysIntr);
DMA_clear_interrupt_mask(&g_OutputDMA);
} while(TRUE);
return 0;
}
void SPI_PowerDown (PSPI_PUBLIC_CONTEXT pPublicSpi)
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] ++PowerDown()\n\r")));
if((PSPI_PUBLIC_CONTEXT)pPublicSpi == NULL)
{
goto CleanUp;
}
//Save SPI Reg
pRestoreSPIregs->CH_CFG = pPublicSpi->pSPIregs->CH_CFG;
pRestoreSPIregs->CLK_CFG = pPublicSpi->pSPIregs->CLK_CFG;
pRestoreSPIregs->MODE_CFG = pPublicSpi->pSPIregs->MODE_CFG;
pRestoreSPIregs->SPI_INT_EN = pPublicSpi->pSPIregs->SPI_INT_EN;
pRestoreSPIregs->SWAP_CFG = pPublicSpi->pSPIregs->SWAP_CFG;
pRestoreSPIregs->FB_CLK_SEL = pPublicSpi->pSPIregs->FB_CLK_SEL;
// Clock Off
pPublicSpi->pSYSCONregs->PCLK_GATE &= ~SPI_POWER_ON;
#if (SPI_CLOCK == EPLL_CLOCK)
pPublicSpi->pSYSCONregs->SCLK_GATE &= ~SPI_SCLK_ON;
#elif (SPI_CLOCK == USB_HOST_CLOCK)
pPublicSpi->pSYSCONregs->SCLK_GATE &= ~SPI_USBHOST_ON;
#endif
RETAILMSG(SPI_MSG,(TEXT("[SPI] --PowerDown()\n\r")));
CleanUp:
return;
}
void SPI_Deinit (PSPI_PUBLIC_CONTEXT pPublicSpi)
{
if((PSPI_PUBLIC_CONTEXT)pPublicSpi == NULL)
{
goto CleanUp;
}
// Delete CS
DeleteCriticalSection(&(pPublicSpi->CsRxAccess));
DeleteCriticalSection(&(pPublicSpi->CsTxAccess));
// Deinitialize Buffer
HalFreeCommonBuffer(0, 0, PhysDmaDstBufferAddr, pVirtDmaDstBufferAddr, FALSE);
HalFreeCommonBuffer(0, 0, PhysDmaSrcBufferAddr, pVirtDmaSrcBufferAddr, FALSE);
// Clear value assigned to DMA physical Address
DmaDstAddress = 0;
DmaSrcAddress = 0;
// DMA Channel Stop
DMA_channel_stop(&g_OutputDMA);
DMA_channel_stop(&g_InputDMA);
DMA_release_channel(&g_OutputDMA);
DMA_release_channel(&g_InputDMA);
// Clock Off
pPublicSpi->pSYSCONregs->PCLK_GATE &= ~SPI_POWER_ON;
#if (SPI_CLOCK == EPLL_CLOCK)
pPublicSpi->pSYSCONregs->SCLK_GATE &= ~SPI_SCLK_ON;
#elif (SPI_CLOCK == USB_HOST_CLOCK)
pPublicSpi->pSYSCONregs->SCLK_GATE &= ~SPI_USBHOST_ON;
#endif
// Assign SYSINTR_NOP value
pPublicSpi->dwSpiSysIntr = SYSINTR_NOP;
// Close Handle
if (pPublicSpi->hRxEvent != NULL)
{
CloseHandle(pPublicSpi->hRxEvent);
}
if (pPublicSpi->hRxDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hRxDoneEvent);
}
if (pPublicSpi->hRxIntrDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hRxIntrDoneEvent);
}
if (pPublicSpi->hTxEvent != NULL)
{
CloseHandle(pPublicSpi->hTxEvent);
}
if (pPublicSpi->hTxDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hTxDoneEvent);
}
if (pPublicSpi->hTxIntrDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hTxIntrDoneEvent);
}
if (pPublicSpi->hSpiEvent != NULL)
{
CloseHandle(pPublicSpi->hSpiEvent);
}
if (pPublicSpi->hTxDmaDoneDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hTxDmaDoneDoneEvent);
}
if (pPublicSpi->hTxDmaDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hTxDmaDoneEvent);
}
if (pPublicSpi->hRxDmaDoneDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hRxDmaDoneDoneEvent);
}
if (pPublicSpi->hRxDmaDoneEvent != NULL)
{
CloseHandle(pPublicSpi->hRxDmaDoneEvent);
}
if (pPublicSpi->hRxThread != NULL)
{
CloseHandle(pPublicSpi->hRxThread);
}
if (pPublicSpi->hTxThread != NULL)
{
CloseHandle(pPublicSpi->hTxThread);
}
if (pPublicSpi->hSpiThread != NULL)
{
CloseHandle(pPublicSpi->hSpiThread);
}
if (pPublicSpi->hTxDmaDoneThread != NULL)
{
CloseHandle(pPublicSpi->hTxDmaDoneThread);
}
if (pPublicSpi->hRxDmaDoneThread != NULL)
{
CloseHandle(pPublicSpi->hRxDmaDoneThread);
}
// VirtualFree
if (pPublicSpi->pGPIOregs)
{
MmUnmapIoSpace((PVOID)pPublicSpi->pGPIOregs, sizeof(S3C6410_GPIO_REG));
pPublicSpi->pGPIOregs = NULL;
}
if (pPublicSpi->pSPIregs)
{
MmUnmapIoSpace((PVOID)pPublicSpi->pSPIregs, sizeof(S3C6410_SPI_REG));
pPublicSpi->pSPIregs = NULL;
}
if (pPublicSpi->pDMAC0regs)
{
MmUnmapIoSpace((PVOID)pPublicSpi->pDMAC0regs, sizeof(S3C6410_DMAC_REG));
pPublicSpi->pDMAC0regs = NULL;
}
if (pPublicSpi->pDMAC1regs)
{
MmUnmapIoSpace((PVOID)pPublicSpi->pDMAC1regs, sizeof(S3C6410_DMAC_REG));
pPublicSpi->pDMAC1regs = NULL;
}
if (pPublicSpi->pSYSCONregs)
{
MmUnmapIoSpace((PVOID)pPublicSpi->pSYSCONregs, sizeof(S3C6410_SYSCON_REG));
pPublicSpi->pSYSCONregs = NULL;
}
// Local Free
LocalFree(pRestoreSPIregs);
LocalFree(pPublicSpi);
CleanUp:
return;
}
void SPI_PowerUp (PSPI_PUBLIC_CONTEXT pPublicSpi)
{
RETAILMSG(SPI_MSG,(TEXT("[SPI] ++PowerUp()\n\r")));
if((PSPI_PUBLIC_CONTEXT)pPublicSpi == NULL)
{
goto CleanUp;
}
// Clock On
pPublicSpi->pSYSCONregs->PCLK_GATE |= SPI_POWER_ON;
#if (SPI_CLOCK == EPLL_CLOCK)
pPublicSpi->pSYSCONregs->SCLK_GATE |= SPI_SCLK_ON;
#elif (SPI_CLOCK == USB_HOST_CLOCK)
pPublicSpi->pSYSCONregs->SCLK_GATE |= SPI_USBHOST_ON;
#endif
//Restore SPI Reg
pPublicSpi->pSPIregs->CH_CFG = pRestoreSPIregs->CH_CFG;
pPublicSpi->pSPIregs->CLK_CFG = pRestoreSPIregs->CLK_CFG;
pPublicSpi->pSPIregs->MODE_CFG = pRestoreSPIregs->MODE_CFG;
pPublicSpi->pSPIregs->SPI_INT_EN = pRestoreSPIregs->SPI_INT_EN;
pPublicSpi->pSPIregs->SWAP_CFG = pRestoreSPIregs->SWAP_CFG;
pPublicSpi->pSPIregs->FB_CLK_SEL = pRestoreSPIregs->FB_CLK_SEL;
RETAILMSG(SPI_MSG,(TEXT("[SPI] --PowerUp()\n\r")));
CleanUp:
return;
}
BOOL SPI_Close (DWORD dwOpen)
{
PSPI_PUBLIC_CONTEXT pSpiPublic = NULL;
BOOL bResult = TRUE;
if(dwOpen != 0)
{
pSpiPublic = (PSPI_PUBLIC_CONTEXT) dwOpen;
}
else
{
bResult = FALSE;
goto CleanUp;
}
// Free all data allocated in open
LocalFree( pSpiPublic );
CleanUp:
return bResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -