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

📄 sdcontrol.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

        DEBUGMSG(ZONE_INTERRUPT, (TEXT("Wait For Interrupt ... \r\n")));
        if (WaitForSingleObject(pHCDevice->hControllerInterruptEvent, INFINITE) != WAIT_OBJECT_0)
        {
            // bail out
            ERRORMSG(ZONE_ERROR, (TEXT("SDControllerIstThread: Wait Failed!  \r\n")));
            return 0;
        }

        if (pHCDevice->DriverShutdown)
        {
            DEBUGMSG(ZONE_WARN, (TEXT("SDControllerIstThread: Thread Exiting\r\n")));
            return 0;
        }

		SDHCDAcquireHCLock(pHCDevice->pHCContext);
        
        // Handle card insert/remove
        SDCardPresenceDetect(pHCDevice);
        if (pHCDevice->fDeviceStatusChange)
        {
            DEBUGMSG(ZONE_INTERRUPT, (TEXT("SDControllerIstThread: Device present %d\r\n"), pHCDevice->fDevicePresent));
            if (pHCDevice->fDevicePresent)
            {
                ProcessCardInsertion(pHCDevice);
            }
            else
            {
                ProcessCardRemoval(pHCDevice);
            }

            goto _done;
        }

        if (pHCDevice->fFakeCardRemoval)
        {
            pHCDevice->fFakeCardRemoval = FALSE;
            DEBUGMSG(ZONE_WARN, (TEXT("SDControllerIstThread:Fake card removal ... \r\n")));
            ProcessCardRemoval(pHCDevice); // Upper layer should be notified of a card removal

            pHCDevice->fDevicePresent = TRUE; //Device is present
            ProcessCardInsertion(pHCDevice);
            goto _done;
        }

        // If we are in the IST only because of a SDIO card interrupt, clocks to 
        // the controller could be cut off if clock gating between cmds is supported.
        // Inorder to read the controller registers, should enable clocks here.
        if ((pHCDevice->fClockGatedOff == TRUE) && (pHCDevice->fClockGatingSupported == TRUE))
        {
            // Controller clocks needs to be enabled
            BSPSdhcSetClockGatingMode(TRUE, pHCDevice->ControllerIndex);
            pHCDevice->fClockGatedOff = FALSE; // controller clocks are enabled
        }

        //Print STATUS and INT_CNT registers
        DEBUGMSG(ZONE_INFO, (TEXT("IST: STATUS 0x%08X INT_CNT 0x%08X\r\n"), 
                                   INREG32(&pHCDevice->pSDMMCRegisters->STATUS), 
                                   INREG32(&pHCDevice->pSDMMCRegisters->INT_CNTR)));

        if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQ))
        {
            if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_SDIOINT))
            {
                //Disable the SDIO interrupt controller bit before servicing SDIO interrupt 
                INSREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQ, 0);
                // Disable the wakeup intr
                INSREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_SDIOIRQWKP, 0);

                pHCDevice->fSDIOEnabled = FALSE;
                //Clear SDIO interrupt status by writing 1 
                OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_SDIOINT, 1));

                // We do not clock gate the controller here, because a CMD52 is going to follow
                // to get the card interrupt status register

                //Indicate to upper layer that SDIO is interrupting
                SDHCDIndicateSlotStateChange(pHCDevice->pHCContext, 0, DeviceInterrupting);
                goto _done;
            }
        }

        if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_ECR))
        {
            if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_ECR))
            {
                //Negate End Command Response interrupt 
                INSREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_ECR, 0);

                // Clear interrupt status by writing 1 to the corresponsing bit only
                OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_ECR, 1));

                HandleCommandComplete(pHCDevice);
                goto _done;
            }
        }

        // If DMA transfer is active
        if (pHCDevice->fDMATransfer == TRUE)
        {

            // Check DMA status for each buffer in the chain
            UINT32 dmaStatus;
            pHCDevice->fDmaBusy = FALSE;
            
            for (UINT32 i = 0; i < pHCDevice->DmaChainSize; i++)
            {
                DDKSdmaGetBufDescStatus(pHCDevice->ChanSDHC, i, &dmaStatus);

                if (dmaStatus & DDK_DMA_FLAGS_BUSY)
                {
                    pHCDevice->fDmaBusy = TRUE;
                }
                
                if (dmaStatus & DDK_DMA_FLAGS_ERROR)
                {
                    // there was an error during DMA transfer
                    pHCDevice->fDmaError = TRUE;
                }
            }

            HandleTransferDone(pHCDevice);
            DEBUGMSG(ZONE_INFO, (TEXT("SDControllerIstThread: Transfer Done ...\r\n"))); 

            goto _done;
        }
        else
        {
            if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_WODONE))
            {
                if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_WODONE) )
                {
                    //Negate Write Operation Done interrupt 
                    INSREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_WODONE, 0);
            
                    // Clear interrupt status by writing 1 
                    OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_WODONE, 1));
            
                    HandleTransferDone(pHCDevice);
                    DEBUGMSG(ZONE_INTERRUPT, (TEXT("SDControllerIstThread:write done ...\r\n")));
                    
                    goto _done;
                }
            }
            
            if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_RODONE))
            {
                if (EXTREG32BF(&pHCDevice->pSDMMCRegisters->STATUS, SDHC_SR_RODONE))
                {
                    //Negate Write Operation Done interrupt 
                    INSREG32BF(&pHCDevice->pSDMMCRegisters->INT_CNTR, SDHC_INT_RODONE, 0);
            
                    // Clear interrupt status by writing 1 
                    OUTREG32(&pHCDevice->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_RODONE, 1));
            
                    HandleTransferDone(pHCDevice);
                    DEBUGMSG(ZONE_INTERRUPT, (TEXT("SDControllerIstThread:read done ...\r\n")));

                    goto _done;
                }
            }
        }
        
        // Spurious interrupt. Print STATUS and INT_CNT registers
        RETAILMSG(1, (TEXT("SDControllerIstThread: Spurious Interrupt??? STATUS 0x%08X INT_CNT 0x%08X\r\n"), 
                              INREG32(&pHCDevice->pSDMMCRegisters->STATUS), 
                              INREG32(&pHCDevice->pSDMMCRegisters->INT_CNTR)));
            
        _done:
        InterruptDone(pHCDevice->dwSysintrSDHC);
		SDHCDReleaseHCLock(pHCDevice->pHCContext);
    }
}
//------------------------------------------------------------------------------
//
// Function: IndicateBusRequestComplete
//
// indicates to upper layer that command is done and its status
//
// Parameters:
//      	pHardwareContext[in] - hardware context
//          pRequest[in] - the request
//          status[in] - the status
//
// Returns:
//      none
//
//------------------------------------------------------------------------------
static void IndicateBusRequestComplete(PSDH_HARDWARE_CONTEXT pController,
                                       PSD_BUS_REQUEST pRequest,
                                       SD_API_STATUS status)
{

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+IndicateBusRequestComplete\r\n")));

    if (pRequest->CommandCode == SD_CMD_APP_CMD)
        pController->fAppCommandSent = TRUE;
    else
        pController->fAppCommandSent = FALSE;

    // Soft reset host on cmd response and data errors
    if (status != SD_API_STATUS_SUCCESS)
    {
        if (status == SD_API_STATUS_RESPONSE_TIMEOUT ||
            status == SD_API_STATUS_CRC_ERROR ||
            status == SD_API_STATUS_DATA_ERROR ||
            status == SD_API_STATUS_DATA_TIMEOUT )
        {
            // Soft reset but do not change any previous clock setting
            SoftwareReset(pController, FALSE);
        }
    }

    // Check whether clock gating between commands is supported
    if (pController->fClockGatingSupported == TRUE)
    {
        // Cut off clocks to the  controller
        BSPSdhcSetClockGatingMode(FALSE, pController->ControllerIndex);
        pController->fClockGatedOff = TRUE; // controller clocks are disabled
    }

#if !VPMX31
    SDHCDIndicateBusRequestComplete(pController->pHCContext, pRequest, status);
#else
    if (pRequest->CommandCode == SD_CMD_IO_OP_COND)
    {
        SDHCDIndicateBusRequestComplete(pController->pHCContext, pRequest, SD_API_STATUS_RESPONSE_TIMEOUT);
    } else
    {
        SDHCDIndicateBusRequestComplete(pController->pHCContext, pRequest, status);
    }
#endif //VPMX31
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("-IndicateBusRequestComplete\r\n")));
}
//------------------------------------------------------------------------------
//
// Function: HandleCommandComplete
//
// Handles an END_CMD_RESP event
//
// Parameters:
//      	pController - hardware context
//
// Returns:
//      returns TRUE is command is completed. FALSE otherwise
//
//------------------------------------------------------------------------------
static BOOL HandleCommandComplete(PSDH_HARDWARE_CONTEXT pController)
{
    PSD_BUS_REQUEST pRequest;
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+HandleCommandComplete\r\n")));
    pRequest = SDHCDGetAndLockCurrentRequest(pController->pHCContext, 0);
    
    //Check for response time-out
    if (EXTREG32BF(&pController->pSDMMCRegisters->STATUS, SDHC_SR_TORESP))
    {
        ERRORMSG(ZONE_ERROR, (TEXT(" Cmd %d: Command Response timeout! Status 0x%08X\r\n"), 
                              pRequest->CommandCode, (INREG32(&pController->pSDMMCRegisters->STATUS))));

        // Clear status by writing 1 
        OUTREG32(&pController->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_TORESP, 1));

        
        if (pRequest->CommandCode == SD_CMD_IO_OP_COND)
        {
            // Memory cards do not respond for CMD5.
            pController->fClockGatingSupported = BspSdhcIsClockGatingBetweenCmdsSupported(pController->ControllerIndex);
        }

        IndicateBusRequestComplete(pController, pRequest, SD_API_STATUS_RESPONSE_TIMEOUT);
        return TRUE;
    }
    else if (pRequest->CommandCode == SD_CMD_IO_OP_COND)
    {
        // Only SDIO cards will respond for CMD5
        pController->fClockGatingSupported = FALSE;
    }
    
    //Check for crc error
    if (EXTREG32BF(&pController->pSDMMCRegisters->STATUS, SDHC_SR_RSPCERR))
    {
        ERRORMSG(ZONE_ERROR, (TEXT("Cmd %d: Command Response CRC error! Status 0x%08X\r\n"), 
                                 pRequest->CommandCode, (INREG32(&pController->pSDMMCRegisters->STATUS))));

        // Clear status by writing 1 
        OUTREG32(&pController->pSDMMCRegisters->STATUS, CSP_BITFVAL(SDHC_SR_RSPCERR, 1));
        IndicateBusRequestComplete(pController, pRequest, SD_API_STATUS_CRC_ERROR);
        return TRUE;
    }
    
    if (pRequest)
    {
        LONG     ii;             // loop variable  
        LONG     startingOffset;     // starting offset in response buffer
        USHORT   responseBuffer[SDH_RESPONSE_FIFO_DEPTH]; // response buffer

        

        if (NoResponse != pRequest->CommandResponse.ResponseType)
        {
            if (ResponseR2 == pRequest->CommandResponse.ResponseType)
            {
                // 8 words - 128 bits
                startingOffset = SDH_RESPONSE_FIFO_DEPTH - 1;
            } else
            {
                // 3 WORDS - 48 bits
                startingOffset = 2;
            }

            // read in the response words from the response fifo.
            for (ii = startingOffset; ii >= 0; ii--)
            {
                // read from the fifo
                responseBuffer[ii] =INREG16(&pController->pSDMMCRegisters->RES_FIFO);
                DEBUGMSG(ZONE_INFO, (TEXT("responseBuffer[%d]=0x%x\r\n"),ii,responseBuffer[ii]));       
            }
            
            memcpy(pRequest->CommandResponse.ResponseBuffer, responseBuffer, (sizeof(USHOR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -