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

📄 sdhc.cpp

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//  Input:  Slot - slot the request is going on
//          pRequest - the request to be cancelled
//          
//  Output: 
//  Return: TRUE if I/O was cancelled
//  Notes:  
//          the HC lock is taken before entering this cancel handler
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN CSDIOControllerBase::SDHCCancelIoHandlerImpl( UCHAR Slot, PSD_BUS_REQUEST pRequest)
{
    // for now, we should never get here because all requests are non-cancelable
    // the hardware supports timeouts so it is impossible for the controller to get stuck
    DEBUGCHK(FALSE);

    return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::SDHCBusRequestHandlerImpl - bus request ha     ndler 
//  Input:  pRequest - the request
//          
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  The request passed in is marked as uncancelable, this function
//          has the option of making the outstanding request cancelable    
//          returns status pending
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::SDHCBusRequestHandlerImpl( PSD_BUS_REQUEST pRequest ) 
{
    DEBUGCHK(pRequest);

    SD_API_STATUS   status;
    BOOL            fWriteTransferMode = FALSE;

    DEBUGMSG(SHC_SEND_ZONE, (L"CSDIOControllerBase::SDHCBusRequestHandlerImpl: "
        L"CMD: [%d]\r\n", pRequest->CommandCode
    ));

    // acquire the device lock to protect from device removal
    SDHCDAcquireHCLock(m_pHCContext);

    if ( m_pCurrentRequest) {
        IndicateBusRequestComplete(pRequest, SD_API_STATUS_CANCELED);
        m_pCurrentRequest = NULL;
    }

    m_fCurrentRequestFastPath = FALSE;
    m_pCurrentRequest = pRequest ;
    // if no data transfer involved, use FAST PATH
    if (pRequest->SystemFlags & SD_FAST_PATH_AVAILABLE && 
            !( SD_COMMAND != pRequest->TransferClass && 
                pRequest->NumBlocks * pRequest->BlockSize >=  NUM_BYTE_FOR_POLLING_MODE)){   // We do fast path here.
        m_fCurrentRequestFastPath = TRUE;
        InterruptMask(m_dwControllerSysIntr,TRUE);
        status = SendCommand(pRequest);
        if ( status == SD_API_STATUS_PENDING ) { // Polling for completion.
            while (m_pCurrentRequest) {
                if( Read_MMC_STAT() & INREG16(&m_vpSDIOReg->MMC_IE) & (MMC_IE_EOC|MMC_STAT_CERR|MMC_STAT_CCRC|MMC_STAT_CTO)) {
                    CommandCompleteHandler();
                }
            }               
            status = FastPathStatus;
        }

        InterruptMask(m_dwControllerSysIntr,FALSE);
        ASSERT(m_fCurrentRequestFastPath);
    }
    else 
    {
        pRequest->SystemFlags &= ~SD_FAST_PATH_AVAILABLE ;
        status = SendCommand(pRequest);
        if(!SD_API_SUCCESS(status))
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::SDHCBusRequestHandlerImpl: "
                L"Error sending command:0x%02x\r\n", pRequest->CommandCode
            ));
            goto EXIT;      
        }
    }


EXIT:
    SDHCDReleaseHCLock(m_pHCContext);
    return status;
}

//  CommandCompleteHandler
//  Input:
//  Output: 
//  Notes:  
BOOL CSDIOControllerBase::CommandCompleteHandler()
{
    DWORD               dwCurrentTickCount;
    DWORD               dwTimeout;
    DWORD               dwCountStart;
    BOOL                fTimeoutOverflow = FALSE;
    PSD_BUS_REQUEST     pRequest = NULL;       // the request to complete
    SD_API_STATUS       status = SD_API_STATUS_PENDING;

    DEBUGMSG(SHC_INTERRUPT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
        L"Got the command response\r\n"
    ));
    
#ifdef SDIO_INAB_INTERRUPT_WORKAROUND
    if( m_fINABworkaroundEnabled )
    {
        if( m_CurrentState == SendingINAB )
            goto PROCESS_INAB_STATE;
    }
#endif

    // get and lock the current bus request
    if((pRequest = SDHCDGetAndLockCurrentRequest(m_pHCContext, 0)) == NULL)
    {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
            L"Unable to get/lock current request!\r\n"
        ));
        status = SD_API_STATUS_INVALID_DEVICE_REQUEST;
        goto TRANSFER_DONE;
    } 

#ifdef DEBUG
    EnterCriticalSection( &m_critSec );
    DEBUGMSG(SDCARD_ZONE_INIT, (L"+DebugSDHCRegs-------------------------\r\n"));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_CMD 0x%04X \r\n", m_vpSDIOReg->MMC_CMD    ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_ARG1 0x%04X \r\n", m_vpSDIOReg->MMC_ARG1  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_ARG2 0x%04X \r\n", m_vpSDIOReg->MMC_ARG2  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_CON  0x%04X \r\n", m_vpSDIOReg->MMC_CON   ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_STAT 0x%04X \r\n", m_vpSDIOReg->MMC_STAT  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_IE 0x%04X \r\n", m_vpSDIOReg->MMC_IE  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_CTO 0x%04X \r\n", m_vpSDIOReg->MMC_CTO    ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_DTO 0x%04X \r\n", m_vpSDIOReg->MMC_DTO    ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_BLEN 0x%04X \r\n", m_vpSDIOReg->MMC_BLEN  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_NBLK 0x%04X \r\n", m_vpSDIOReg->MMC_NBLK  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_BUF 0x%04X \r\n", m_vpSDIOReg->MMC_BUF    ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_SDIO 0x%04X \r\n", m_vpSDIOReg->MMC_SDIO  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_REV 0x%04X \r\n", m_vpSDIOReg->MMC_REV    ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP0 0x%04X \r\n", m_vpSDIOReg->MMC_RSP0  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP1 0x%04X \r\n", m_vpSDIOReg->MMC_RSP1  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP2 0x%04X \r\n", m_vpSDIOReg->MMC_RSP2  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP3 0x%04X \r\n", m_vpSDIOReg->MMC_RSP3  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP4 0x%04X \r\n", m_vpSDIOReg->MMC_RSP4  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP5 0x%04X \r\n", m_vpSDIOReg->MMC_RSP5  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP6 0x%04X \r\n", m_vpSDIOReg->MMC_RSP6  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP7 0x%04X \r\n", m_vpSDIOReg->MMC_RSP7  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_IOSR 0x%04X \r\n", m_vpSDIOReg->MMC_IOSR  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_SYSC 0x%04X \r\n", m_vpSDIOReg->MMC_SYSC  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_SISS 0x%04X \r\n", m_vpSDIOReg->MMC_SISS  ));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_WKEN1 0x%04X \r\n", m_vpPRCMReg->ulPM_WKEN1_CORE));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_WKST1 0x%04X \r\n", m_vpPRCMReg->ulPM_WKST1_CORE));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_AUTOIDEL1 0x%04X \r\n", m_vpPRCMReg->ulCM_AUTOIDLE1_CORE));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_FCLKEN1 0x%04X \r\n", m_vpPRCMReg->ulCM_FCLKEN1_CORE));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_ICLKEN1 0x%04X \r\n", m_vpPRCMReg->ulCM_ICLKEN1_CORE));
    DEBUGMSG(SDCARD_ZONE_INIT, (L"-DebugSDHCRegs-------------------------\r\n"));
    LeaveCriticalSection( &m_critSec );
#endif
    
    WORD MMC_STAT = Read_MMC_STAT();
    if( MMC_STAT & MMC_STAT_CB )
    {
        ASSERT( pRequest->CommandResponse.ResponseType == ResponseR1b );

        if( pRequest->CommandResponse.ResponseType == ResponseR1b )
        {
            DEBUGMSG(SHC_BUSY_STATE_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
                L"Card in busy state after command!  Delaying...\r\n"));

            // calculate timeout conditions
            dwCountStart = GetTickCount();
            dwTimeout = dwCountStart + m_dwMaxTimeout;
            if( dwTimeout < dwCountStart )
                fTimeoutOverflow = TRUE;

            do {
                MMC_STAT = Read_MMC_STAT();

                // check for card ejection
                if( !SDCardDetect() )
                { 
                    DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
                        L"Card removed!\r\n"));
                    status = SD_API_STATUS_DEVICE_REMOVED;
                    goto TRANSFER_DONE;
                }

                // check for a timeout
                dwCurrentTickCount = GetTickCount();
                if( fTimeoutOverflow ? ( dwTimeout < dwCurrentTickCount && dwCurrentTickCount < dwCountStart )
                    : ( dwTimeout < dwCurrentTickCount || dwCurrentTickCount < dwCountStart ) )
                {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
                        L"Card BUSY timeout!\r\n"));
                    status = SD_API_STATUS_RESPONSE_TIMEOUT;
                    goto TRANSFER_DONE;
                }
            } while( !( MMC_STAT & ( MMC_STAT_EOFB | MMC_STAT_CCRC | MMC_STAT_CTO | MMC_STAT_DCRC | MMC_STAT_DTO ) ) );

            DEBUGMSG(SHC_BUSY_STATE_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
                L"Card exited busy state.\r\n"));
            ASSERT( MMC_STAT & MMC_STAT_EOFB );
            Write_MMC_STAT( MMC_STAT_CB | MMC_STAT_EOFB );
        }
    }
    //    }

    WORD MMC_STAT_OVERWRITE = 0;
    if( MMC_STAT & MMC_STAT_CCRC ) // command CRC error
    {
        status = SD_API_STATUS_CRC_ERROR;
        MMC_STAT_OVERWRITE |= MMC_STAT_CCRC;
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
            L"Got command CRC error!\r\n"));
    }
    if( MMC_STAT & MMC_STAT_CTO ) // command response timeout
    {
        status = SD_API_STATUS_RESPONSE_TIMEOUT;
        MMC_STAT_OVERWRITE |= MMC_STAT_CTO;
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
            L"Got command response timeout!\r\n"));
    }

    if( MMC_STAT_OVERWRITE ) // clear the status error bits
    {
        Write_MMC_STAT(MMC_STAT_OVERWRITE);
        goto TRANSFER_DONE;
    }

    // get the response information
    if(pRequest->CommandResponse.ResponseType == NoResponse)
    {
        DEBUGMSG (SHC_SDBUS_INTERACT_ZONE,(L"CSDIOControllerBase::CommandCompleteHandler: "
            L"GetCmdResponse returned no response (no response expected)\r\n"));
        goto TRANSFER_DONE;
    }
    else{

        status =  GetCommandResponse(pRequest);

        if(!SD_API_SUCCESS(status))
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
                L"Error getting response for command:0x%02x\r\n", pRequest->CommandCode
            ));
            goto TRANSFER_DONE;     
        }
    }

    if (SD_COMMAND != pRequest->TransferClass) // data transfer
    {
        DWORD cbTransfer = TRANSFER_SIZE(pRequest);
        BOOL     fRet;

        switch(pRequest->TransferClass)
        {
        case SD_READ:
            __try {
                fRet = SDIReceive(pRequest->pBlockBuffer, cbTransfer);
            }
            __except(SDProcessException(GetExceptionInformation())) {
                fRet = FALSE;
            }

            if(!fRet)
            {
                DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
                    L"SDIPollingReceive() failed\r\n"
                ));
                goto TRANSFER_DONE;
            }
            else
            {
#ifdef ENABLE_DEBUG
                DWORD dwTemp = 0;
                while( dwTemp < cbTransfer && (dwTemp < (HEXBUFSIZE / 2 - 1) ) )
                {
                    szHexBuf[dwTemp*2] = pRequest->pBlockBuffer[dwTemp] / 16;
                    szHexBuf[dwTemp*2+1] = pRequest->pBlockBuffer[dwTemp] % 16;

                    if( szHexBuf[dwTemp*2] < 10 )
                        szHexBuf[dwTemp*2] += '0';
                    else
                        szHexBuf[dwTemp*2] += 'a' - 10;

                    if( szHexBuf[dwTemp*2+1] < 10 )
                        szHexBuf[dwTemp*2+1] += '0';
                    else
                        szHexBuf[dwTemp*2+1] += 'a' - 10;

                    dwTemp++;
                }
                szHexBuf[dwTemp*2] = 0;
                DEBUGMSG (SHC_SDBUS_INTERACT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
                    L"PollingReceive succesfully received %d bytes {%S}\r\n", cbTransfer, szHexBuf
                ));
#endif
            }
            break;

        case SD_WRITE:
            {
#ifdef ENABLE_DEBUG
                DWORD dwTemp = 0;
                while( dwTemp < cbTransfer && (dwTemp < (HEXBUFSIZE / 2 - 1) ) )
                {
                    szHexBuf[dwTemp*2] = pRequest->pBlockBuffer[dwTemp] / 16;
                    szHexBuf[dwTemp*2+1] = pRequest->pBlockBuffer[dwTemp] % 16;

                    if( szHexBuf[dwTemp*2] < 10 )
                        szHexBuf[dwTemp*2] += '0';
                    else
                        szHexBuf[dwTemp*2] += 'a' - 10;

                    if( szHexBuf[dwTemp*2+1] < 10 )
                        szHexBuf[dwTemp*2+1] += '0';
                    else
                        szHexBuf[dwTemp*2+1] += 'a' - 10;

                    dwTemp++;
                }
                szHexBuf[dwTemp*2] = 0;
#endif
            }

            __try {
                fRet = SDITransmit(pRequest->pBlockBuffer, cbTransfer);
            }
            __except(SDProcessException(GetExceptionInformation())) {
                fRet = FALSE;
            }

            if( !fRet )
            {
                DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
                    L"SDIPollingTransmit() failed\r\n"));
                DEBUGMSG (SHC_SDBUS_INTERACT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
                    L"PollingTransmit failed to send %d bytes {%S}\r\n", cbTransfer, szHexBuf
                ));
                goto TRANSFER_DONE;
            }
            else
            {
                DEBUGMSG (SHC_SDBUS_INTERACT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
                    L"PollingTransmit succesfully sent %d bytes {%S}\r\n", cbTransfer, szHexBuf
                ));
            }

            break;
        }
        status = SD_API_STATUS_SUCCESS;
    }

TRANSFER_DONE:
    if( pRequest != NULL )
    {
        if ( ( !( m_fAppCmdMode ) ) && 
            ( (pRequest->CommandCode == SD_CMD_IO_RW_DIRECT) || 
            (pRequest->CommandCode == SD_CMD_IO_RW_EXTENDED) ) )
        {
            Write_MMC_SDIO( Read_MMC_SDIO() & ~( BIT15 | BIT6 ) );
        }

        if( pRequest->CommandResponse.ResponseType == ResponseR4 )
        {
            Write_MMC_SDIO( Read_MMC_SDIO() & ~( BIT7 ) );
        }
    }

    if( status == SD_API_STATUS_SUCCESS )
    {
        if( m_fAppCmdMode )
        {
            m_fAppCmdMode = FALSE;
            DEBUGMSG(SHC_SEND_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
                L"Switched to Sta

⌨️ 快捷键说明

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