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

📄 spi.c

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