⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi.c

📁 6410BSP3
💻 C
📖 第 1 页 / 共 4 页
字号:
                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 + -