📄 hspi.c
字号:
RETAILMSG(1,(TEXT("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
HSP_Read(
DWORD hOpenContext,
LPVOID pBuffer,
DWORD Count)
{
PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;
PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;
// DWORD dwReadSize;
//param check
if(pSpiPrivate->State != STATE_IDLE) {
RETAILMSG(1,(TEXT("READ ERROR : STATE IS NOT IDLE\n")));
return 0;
}
RETAILMSG(1,(TEXT("pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));
if(pSpiPrivate->bUseRxDMA)
{
PDMA_BUFFER pDmaBuffer = (PDMA_BUFFER) pBuffer;
pSpiPrivate->pRxBuffer = pDmaBuffer->VirtualAddress;
pSpiPrivate->pRxDMABuffer = pDmaBuffer->PhysicalAddress;
}
else
{
pSpiPrivate->pRxBuffer = (LPVOID)pBuffer;
}
pSpiPrivate->dwRxCount = Count;
pSpiPublic->pSpiPrivate = pSpiPrivate;
SetEvent(pSpiPublic->hRxEvent);
WaitForSingleObject(pSpiPublic->hRxDoneEvent, INFINITE);
pSpiPrivate->State = STATE_IDLE;
RETAILMSG(1,(TEXT("Return Value : %d\n"),pSpiPrivate->dwRxCount));
return pSpiPrivate->dwRxCount ;
}
DWORD
HSP_Write(
DWORD hOpenContext,
LPVOID pBuffer,
DWORD Count)
{
PSPI_PRIVATE_CONTEXT pSpiPrivate = (PSPI_PRIVATE_CONTEXT)hOpenContext;
PSPI_PUBLIC_CONTEXT pSpiPublic = pSpiPrivate->pSpiPublic;
//param check
if(pSpiPrivate->State != STATE_IDLE) {
RETAILMSG(1,(TEXT("WRITE ERROR : STATE IS NOT IDLE\n")));
return 0;
}
RETAILMSG(1,(TEXT("pBuffer : 0x%X, Count : %d\n"), pBuffer, Count));
if(pSpiPrivate->bUseTxDMA)
{
PDMA_BUFFER pDmaBuffer = (PDMA_BUFFER) pBuffer;
pSpiPrivate->pTxBuffer = pDmaBuffer->VirtualAddress;
pSpiPrivate->pTxDMABuffer = pDmaBuffer->PhysicalAddress;
}
else
{
pSpiPrivate->pTxBuffer = (LPVOID)pBuffer;
}
pSpiPrivate->dwTxCount = Count;
pSpiPublic->pSpiPrivate = pSpiPrivate;
SetEvent(pSpiPublic->hTxEvent);
WaitForSingleObject(pSpiPublic->hTxDoneEvent, INFINITE);
pSpiPrivate->State = STATE_IDLE;
RETAILMSG(1,(TEXT("Return Value : %d\n"),pSpiPrivate->dwTxCount));
return pSpiPrivate->dwTxCount;
}
BOOL
HSP_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 S3C2450_HSSPI_REG *pSPIregs = pSpiPublic->pHSSPIregs; // for HS-SPI
volatile S3C2450_HSSPI_REG *pRxSPIregs = &pSpiPrivate->RxSPIregs; // for HS-SPI
volatile S3C2450_HSSPI_REG *pTxSPIregs = &pSpiPrivate->TxSPIregs; // for HS-SPI
PSET_CONFIG pSetConfig;
BOOL bResult = TRUE;
switch(dwIoControlCode)
{
case SPI_IOCTL_SET_CONFIG:
if( nInBufSize != sizeof(SET_CONFIG) )
{
bResult = FALSE;
break;
}
pSetConfig = (PSET_CONFIG) lpInBuf;
//===========================================COMMON PART===========================================
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;
#if (BSP_TYPE == BSP_SMDK2443)
pRxSPIregs->CLK_CFG = CLKSEL_EPLL|(pSpiPrivate->dwPrescaler);
#elif (BSP_TYPE == BSP_SMDK2450)
pRxSPIregs->CLK_CFG = CLKSEL_PCLK|(pSpiPrivate->dwPrescaler);
#endif
//pRxSPIregs->MODE_CFG = (0x3ff<<19)|(0<<2);
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(1,(TEXT("it's not supported MODE\n")));
pSpiPrivate->State = STATE_ERROR;
break;
}
//===========================================RX PART============================================
if(pSpiPrivate->bUseRxIntr)
//INTR
{
}
else if(pSpiPrivate->bUseRxDMA)
//DMA
{
}
else
//Polling
{
}
//===========================================TX PART============================================
if(pSpiPrivate->bUseTxIntr)
// INTR
{
}
else if(pSpiPrivate->bUseTxDMA)
// DMA
{
}
else
//Polling
{
}
break;
case SPI_IOCTL_GET_CONFIG:
break;
case SPI_IOCTL_CLR_TXBUFF:
break;
case SPI_IOCTL_CLR_RXBUFF:
break;
case SPI_IOCTL_STOP:
break;
case SPI_IOCTL_START:
if(pSpiPrivate->State == STATE_ERROR) {
RETAILMSG(1,(TEXT("SPI_IOCTL_START ERROR\n")));
bResult = FALSE;
break;
}
pSpiPrivate->State = STATE_IDLE;
RETAILMSG(1,(TEXT("SPI STATE : SPI_IOCTL_START\n")));
break;
default:
break;
}
return bResult;
}
DWORD ThreadForTx(PSPI_PUBLIC_CONTEXT pSpiPublic)
{
volatile S3C2450_HSSPI_REG *pSPIregs = pSpiPublic->pHSSPIregs; // for HS-SPI
volatile S3C2450_INTR_REG *pINTRregs = pSpiPublic->pINTRregs;
volatile S3C2450_DMA_REG *pDMAregs = pSpiPublic->pDMAregs;
PSPI_PRIVATE_CONTEXT pSpiPrivate;
DWORD dwTxCount;
PBYTE pTxBuffer;
DWORD dwOldPerm;
PBYTE pTestBuffer;
DWORD dwTestCount;
do
{
WaitForSingleObject(pSpiPublic->hTxEvent, INFINITE);
pSpiPrivate = (PSPI_PRIVATE_CONTEXT) pSpiPublic->pSpiPrivate;
dwTestCount = dwTxCount = pSpiPrivate->dwTxCount;
dwOldPerm = SetProcPermissions((DWORD)-1);
pTestBuffer = pTxBuffer = (PBYTE) MapPtrToProcess(pSpiPrivate->pTxBuffer, (HANDLE) GetCurrentProcessId());
RETAILMSG(1,(TEXT("pTxBuffer : 0x%X, dwTxCount : %d \r\n"), pTxBuffer, dwTxCount));
//Reset
pSPIregs->CH_CFG |= SW_RST;
RETAILMSG(1,(TEXT("\n HS SPI reset\n")));
pSPIregs->CH_CFG &= ~SW_RST;
if(pSpiPrivate->bUseTxIntr)
// INT + TX
{
RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : USE INT \r\n")));
pSpiPrivate->State = STATE_TXINTR;
/*
if(pSpiPrivate->dwMode == SPI_MASTER_MODE) {
pSPIregs->CH_CFG = 0x0;
pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;
pSPIregs->MODE_CFG = (TX_TRIG_LEVEL<<5);
} else {
pSPIregs->CH_CFG = (0x1<<4);
pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;
pSPIregs->MODE_CFG = (TX_TRIG_LEVEL<<5);
}
pSPIregs->SP_INT_EN = (1<<0);
pSPIregs->PENDING_CLR_REG = (0x1f);
pSPIregs->CH_CFG = (1<<0);
if(pSpiPrivate->dwMode == SPI_MASTER_MODE) {
RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : MASTER MODE \r\n")));
pSPIregs->SLAVE_SELECTION_REG = 0;
}
else{
RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : SLAVE MODE \r\n")));
}
WaitForSingleObject(pSpiPublic->hTxIntrDoneEvent, INFINITE);
while(((pSPIregs ->SPI_STATUS>>6) & 0x7f));
while(!((pSPIregs ->SPI_STATUS>>21) & 0x1));
*/
}
else if(pSpiPrivate->bUseTxDMA)
// DMA + TX
{
DWORD dwDmaLen = dwTxCount & 0xFFFFF ;
RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : USE DMA (TxCount : %d) \r\n"),dwDmaLen));
pSpiPrivate->State = STATE_TXDMA;
VirtualCopy((PVOID)pSpiPrivate->pTxBuffer, (PVOID)((ULONG) pSpiPrivate->pTxDMABuffer>>8), sizeof(dwTxCount), PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL);
if(pSpiPrivate->dwMode == SPI_MASTER_MODE)
{
pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG;
pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;
pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG;
}else {
pSPIregs->CH_CFG = pSpiPrivate->TxSPIregs.CH_CFG;
pSPIregs->CLK_CFG = pSpiPrivate->TxSPIregs.CLK_CFG;
pSPIregs->MODE_CFG = pSpiPrivate->TxSPIregs.MODE_CFG;
}
if(dwDmaLen > 0)
{
pSPIregs->MODE_CFG |= TX_DMA_ON|DMA_SINGLE;
pSPIregs->CH_CFG |= TX_CH_ON;
pDMAregs->DISRC4 = (UINT)pSpiPrivate->pTxDMABuffer;
pDMAregs->DISRCC4 = ~(DESTINATION_PERIPHERAL_BUS | FIXED_DESTINATION_ADDRESS);
pDMAregs->DIDST4 = (UINT)SPI_TX_DATA_PHY_ADDR;
pDMAregs->DIDSTC4 = (SOURCE_PERIPHERAL_BUS | FIXED_SOURCE_ADDRESS);
// pDMAregs->DCON4 = HANDSHAKE_MODE |GENERATE_INTERRUPT |PADDRFIX |NO_DMA_AUTO_RELOAD | dwDmaLen;
pDMAregs->DCON4 = HANDSHAKE_MODE |GENERATE_INTERRUPT |NO_DMA_AUTO_RELOAD | dwDmaLen;
pDMAregs->DMAREQSEL4 = ( DMAREQSEL_SPI_0TX | DMA_TRIGGERED_BY_HARDWARE );
if(pSpiPrivate->dwMode == SPI_MASTER_MODE)
{
RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : MASTER MODE \r\n")));
MASTER_CS_ENABLE;
}
else
{
RETAILMSG(1,(TEXT("[HSPI DD] Thread for TX : SLAVE MODE \r\n")));
}
pDMAregs->DMASKTRIG4 = ENABLE_DMA_CHANNEL;
WaitForSingleObject(pSpiPublic->hTxDmaDoneDoneEvent, INFINITE);
pSpiPrivate->dwTxCount -= dwDmaLen;
pSpiPrivate->pTxBuffer = (((PUINT) pSpiPrivate->pTxBuffer) + dwDmaLen);
}
VirtualFree((PVOID)pTxBuffer, 0, MEM_RELEASE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -