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

📄 sdcontrol.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    }

    while (1)
    {

        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;
        }

        if (pHCDevice->fFakeCardRemoval)
        {
            pHCDevice->fFakeCardRemoval = FALSE;
            DEBUGMSG(ZONE_WARN, (TEXT("SDControllerIstThread:Fake card removal ... \r\n")));
            ProcessCardRemoval(pHCDevice);

            //Function ResetCard() will be called if hardware does not reset the card after waking up.
            //If during power down (D0 to D4) hardware has set slot voltage to 0 and waking up  
            //(D4 to D0) hardware has set voltage to optimum voltage, then calling ResetCard() will 
            //not be necessary
            //ResetCard(pHCDevice);

            // Check for card presence again
            ProcessCardInsertion(pHCDevice);
        }

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

        // Handle card insert/remove
        // Wait for cmds to complete cos SDHC don't take reset very well.
        // status register contents are not reset.
        if (pHCDevice->fDeviceStatusChange)
        {
            EnterCriticalSection(&pHCDevice->ControllerCriticalSection);
            DEBUGMSG(ZONE_INTERRUPT, (TEXT("SDControllerIstThread: Device present %d\r\n"), pHCDevice->fDevicePresent));
            if (pHCDevice->fDevicePresent)
                ProcessCardInsertion(pHCDevice);
            else
                ProcessCardRemoval(pHCDevice);
            pHCDevice->fDeviceStatusChange = FALSE;
            LeaveCriticalSection(&pHCDevice->ControllerCriticalSection);
	   goto _done;
        }

        // Check for INT_CNTR because SDIO status bit will be always set until
        // the card deasserts the SDIO int.
        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));

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

                DEBUGMSG(ZONE_INTERRUPT, (TEXT("SDControllerIstThread:IO Int\r\n")));
            }
        }

	// Check End Command Response interrupt
        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));

                if(pHCDevice->SDCommandStatus == SD_COMMAND_STATUS_CMD)		
                			HandleCommandComplete(pHCDevice);
            }
        }

	// Check write operation done interrupt
        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));

		if(pHCDevice->SDCommandStatus == SD_COMMAND_STATUS_WRITE)
                	HandleTransferDone(pHCDevice);
                DEBUGMSG(ZONE_INTERRUPT, (TEXT("SDControllerIstThread:write done ...\r\n")));
            }
        }

	// Check read operation done interrupt
        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));

	        if(pHCDevice->SDCommandStatus == SD_COMMAND_STATUS_READ)
                	HandleTransferDone(pHCDevice);
                DEBUGMSG(ZONE_INTERRUPT, (TEXT("SDControllerIstThread:read done ...\r\n")));
            }
        }

_done:
        InterruptDone(pHCDevice->dwSysintrSDHC);
    }
}
//------------------------------------------------------------------------------
//
// 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;

    //TODO: done in Mx21. is this really required???
    // 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);
        }
    }

 //SetClock(pController, FALSE);

    SDHCDIndicateBusRequestComplete(pController->pHCContext, pRequest, status);

    
    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))
    {
        DEBUGMSG(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));
        IndicateBusRequestComplete(pController, pRequest, SD_API_STATUS_RESPONSE_TIMEOUT);
        return TRUE;
    }

    //Check for crc error
    if (EXTREG32BF(&pController->pSDMMCRegisters->STATUS, SDHC_SR_RSPCERR))
    {
        DEBUGMSG(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(USHORT)) * (startingOffset + 1));
        }

        ////////////////////////////////////////////////////////////////////////////
        //If this is a data transfer, start the I/O operation; otherwise, finish the request -----
        ///////////////////////////////////////////////////////////////////////////
        if (pRequest->TransferClass == SD_COMMAND)
        {
            IndicateBusRequestComplete(pController, pRequest, status);
            return TRUE;
        }
        else if (pRequest->TransferClass == SD_WRITE)
        {

            DWORD   m_dwNumBytesToTransfer ;
            m_dwNumBytesToTransfer = pRequest->NumBlocks * pRequest->BlockSize;

            pController->SDCommandStatus = SD_COMMAND_STATUS_WRITE;
            //Check whether DMA or CPU transfer
            if (pController->fDMATransfer == TRUE)
            {
                DDKDmacSetTransCount(pController->DmaReqTxCH, m_dwNumBytesToTransfer);
                // Start the output DMA
                DDKDmacStartChan(pController->DmaReqTxCH);
            } 
            else
            {
                BYTE* tempBuff = pRequest->pBlockBuffer ;
                DWORD no_of_fill_fifo, j, k, remainder, tempData ; 
                
                DWORD byteCount = 0; //count the bytes written

                no_of_fill_fifo     = (m_dwNumBytesToTransfer)/(pController->Bytes_in_fifo);
                //remaining bytes which are less than FIFO size
                remainder = (m_dwNumBytesToTransfer)-(pController->Bytes_in_fifo)*no_of_fill_fifo; 

                DEBUGMSG(ZONE_INFO, (TEXT("m_dwNumBytesToTransfer:%d  Bytes_in_fifo:%d no_of_fill_fifo:%d\r\n")
                                         ,m_dwNumBytesToTransfer, pController->Bytes_in_fifo, no_of_fill_fifo));
		
                for (j=0; j<no_of_fill_fifo; j++)
                {
                    //Wait till buffer ready
                    while (!EXTREG32BF(&pController->pSDMMCRegisters->STATUS, SDHC_SR_BWR))Sleep(0);
                    for (k=0; k<pController->Units_in_fifo; k++)
                    {
                        tempData = ((tempBuff[0]) | (tempBuff[1] << 8) | (tempBuff[2] << 16) | (tempBuff[3] << 24));
                        OUTREG32(&pController->pSDMMCRegisters->BUFFER_ACCESS, tempData);
                        tempBuff+=4 ; 
                        byteCount+=4; //count the bytes written
                    }
                }

                if (remainder)
                {
                    //Wait till buffer ready
                    while (!EXTREG32BF(&pController->pSDMMCRegisters->STATUS, SDHC_SR_BWR))Sleep(0);
			
                    for (j=0;j<remainder/4;j++)
                    {
                        tempData = ((tempBuff[0]) | (tempBuff[1] << 8) | (tempBuff[2] << 16) | (tempBuff[3] << 24));
                        OUTREG32(&pController->pSDMMCRegisters->BUFFER_ACCESS, tempData);
                        tempBuff+=4 ; 
                        byteCount+=4; //count the bytes written
                    }
                    if ((remainder%4)==1)
                    {
                        tempData = tempBuff[0];
                        OUTREG32(&pController->pSDMMCRegisters->BUFFER_ACCESS, tempData);
                        byteCount++; //count the bytes written

⌨️ 快捷键说明

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