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

📄 sdiocontrollerbase.cpp

📁 S3C2440A的windows ce 5.0 bsp包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - timeout waiting for DMA transfer completion!\r\n")));
                    status = SD_API_STATUS_DATA_TIMEOUT;
                    goto TRANSFER_DONE;
                }

                if( !IsCardPresent() )
                {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Card ejected!\r\n")));
                    status = SD_API_STATUS_DEVICE_REMOVED;
                    goto TRANSFER_DONE;
                }
                if((vm_pSDIReg->SDIFSTA & FIFO_FAIL_ERROR))
                {
                    vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH;
                    vm_pSDIReg->SDIFSTA &= FIFO_FAIL_ERROR;
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - FIFO Error waiting for DMA transfer completion!\r\n")));
                    status = SD_API_STATUS_DATA_ERROR;
                    goto TRANSFER_DONE;
                }
                if((vm_pSDIReg->SDIDSTA & DATA_TRANSMIT_CRC_ERROR))
                {
                    vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TRANSMIT_CRC_ERROR;
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Transmit CRC Error waiting for DMA transfer completion!\r\n")));
                    status = SD_API_STATUS_DATA_ERROR;
                    goto TRANSFER_DONE;
                }
                if((vm_pSDIReg->SDIDSTA & DATA_RECEIVE_CRC_ERROR))
                {
                    vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_RECEIVE_CRC_ERROR;
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Receive CRC Error waiting for DMA transfer completion!\r\n")));
                    status = SD_API_STATUS_DATA_ERROR;
                    goto TRANSFER_DONE;
                }
                if((vm_pSDIReg->SDIDSTA & DATA_TIME_OUT))
                {
                    vm_pSDIReg->SDIDSTA = BUSY_CHECKS_FINISH | DATA_TIME_OUT;
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SDHControllerIstThread() - Data timeout waiting for DMA transfer completion!\r\n")));
                    status = SD_API_STATUS_DATA_TIMEOUT;
                    goto TRANSFER_DONE;
                }
            }

            vm_pSDIReg->SDIDSTA = DATA_TRANSMIT_FINISHED;

            //----- 14. For READ requests, be sure to copy the data read from the DMA memory into the caller's buffer -----
            if(pRequest->TransferClass == SD_READ)
            {
                BOOL fNoException;
                DEBUGCHK(m_dwNumBytesToTransfer <= MAXIMUM_DMA_TRANSFER_SIZE);
            
                SD_SET_PROC_PERMISSIONS_FROM_REQUEST( pRequest ) {               
                    fNoException = SDPerformSafeCopy( pRequest->pBlockBuffer, m_pDMABuffer, m_dwNumBytesToTransfer );
                } SD_RESTORE_PROC_PERMISSIONS();

                if (fNoException == FALSE) {
                    status = SD_API_STATUS_ACCESS_VIOLATION;
                    goto TRANSFER_DONE;
                }
            }

            //----- 15. I/O is complete.  Finish the bus request! -----
            status = SD_API_STATUS_SUCCESS;
        }

TRANSFER_DONE:
        if( !( Is_SDIO_Interrupt_Enabled() && ( Get_SDI_Bus_Width() == WIDE_BUS_ENABLE ) ) )
        {
            Stop_SDI_Clock();
        }
        m_CurrentState = CommandComplete;   
        SDHCDIndicateBusRequestComplete(m_pHCContext, pRequest, status);
        pRequest = NULL;
    }

    return TRUE;
}



///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::IOInterruptIstThread - IST thread for SDIO Interrupts
//  Input:  pHCDevice - the controller instance
//  Output: 
//  Return: thread exit code
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
DWORD CSDIOControllerBase::IOInterruptIstThread()
{

    if( m_nSDIOIstThreadPriority != 0xffffffff && !CeSetThreadPriority( GetCurrentThread(), m_nSDIOIstThreadPriority ) ) 
    {
        DEBUGMSG(SDCARD_ZONE_WARN,(TEXT("SDHCDriver:SDIOInterruptIstThread(): warning, failed to set CEThreadPriority \r\n")));
    }
    
    for(;;)
    {
        //----- 1. Wait for a SDIO interrupt -----
        if(WaitForSingleObject(m_hSDIOInterruptEvent, INFINITE) != WAIT_OBJECT_0)
        {
            DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:SDIOInterruptIstThread(): Wait Failed!\r\n")));
            return FALSE;
        }
        
        if(m_bDriverShutdown) 
        {
            DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCD:SDIOInterruptIstThread(): Thread Exiting\r\n")));
            return FALSE;
        }

        if(m_bDevicePresent && IsCardPresent())
        {
            // indicate that the card is interrupting
            SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceInterrupting);
        }

        // NOTE: SDHCDIndicateSlotStateChange() is called above to inform the bus driver
        //       that the SDIO card has generated an interrupt.  After this notification, the
        //       bus driver will eventually call back SDHCDSlotOptionHandler() to enable/disable
        //       and ACK the SDIO interrupt as necessary.  Consequently, we DO NOT acknowledge 
        //       the interrupt here...

    }
}



///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::CardDetectThread - thread for card insert/removal detection
//  Input:  
//  Output: 
//
//  Return: thread exit code
///////////////////////////////////////////////////////////////////////////////
DWORD CSDIOControllerBase::CardDetectThread()
{
    BOOL  bSlotStateChanged = FALSE;
    DWORD dwWaitResult  = WAIT_TIMEOUT;

    if( m_nCardDetectIstThreadPriority != 0xffffffff && !CeSetThreadPriority( GetCurrentThread(), m_nCardDetectIstThreadPriority ) )
    {
        DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCDriver:CardDetectThread(): warning, failed to set CEThreadPriority \r\n")));
    }

    for(;;)
    {
        //----- 1. Wait for the next insertion/removal interrupt -----
        dwWaitResult = WaitForSingleObject(m_hCardInsertInterruptEvent, m_dwPollingTimeout);
        
        if(m_bDriverShutdown) 
        {
            DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SDHCardDetectIstThread: Thread Exiting\r\n")));
            return FALSE;
        }

        // Test if a card is present
        if( IsCardPresent() == m_bDevicePresent )
        {
            bSlotStateChanged = FALSE;
        }
        else
        {
            bSlotStateChanged = TRUE;
        }

        if( bSlotStateChanged || m_bReinsertTheCard )
        {
            m_bReinsertTheCard = FALSE;

            // If a card is inserted, unload the driver...
            if(m_bDevicePresent == TRUE)
            {
                m_fCardInTheSlot = FALSE;
                // indicate the slot change 
                SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceEjected); 
                m_bDevicePresent = FALSE;

                Stop_SDI_Clock();
            }

            if(IsCardPresent())
            {
                m_fCardInTheSlot = TRUE;
                m_bDevicePresent = TRUE;

                //----- 5. Reset the clock to the ID rate -----
                vm_pSDIReg->SDICON     |= LITTLE_ENDIAN_BYTE_ORDER;    // Windows CE is always Little Endian.
                vm_pSDIReg->SDIFSTA     |= FIFO_RESET;                  // Reset the FIFO
                vm_pSDIReg->SDIBSIZE    = BYTES_PER_SECTOR; 
                vm_pSDIReg->SDIDTIMER   = MAX_DATABUSY_TIMEOUT;        // Data/busy timeout
                SetClockRate(SD_DEFAULT_CARD_ID_CLOCK_RATE);

                // give the card enough time for initialization
                Start_SDI_Clock();
                Wait_80_SDI_Clock_Cycles();

                //----- 6. Inform the bus handler that this is the first command sent -----
                m_bSendInitClocks = TRUE;

                //----- 7. Indicate the slot change -----
                SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceInserted);
            }
        } // if
    } // for

    return TRUE;
}


//-------------------------------------------- Helper Functions ---------------------------------------

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       CSDIOControllerBase::SendCommand()

Description:    Issues the specified SDI command

Returns:        SD_API_STATUS status code.
-------------------------------------------------------------------*/
SD_API_STATUS CSDIOControllerBase::SendCommand(UINT16 Cmd, UINT32 Arg, UINT16 respType, BOOL bDataTransfer)
{
    unsigned int uiNewCmdRegVal = 0;
    DWORD dwWaitCount = 0;

    DEBUGMSG (SDHC_SEND_ZONE,(TEXT("SendCommand (0x%08x, 0x%04x, 0x%08x, 0x%04x, 0x%x) starts\r\n"), 
                this, Cmd, Arg, respType, bDataTransfer));
    //----- 1. Reset any pending status flags -----
    vm_pSDIReg->SDICSTA = (CRC_CHECK_FAILED | COMMAND_SENT | COMMAND_TIMED_OUT | RESPONSE_RECEIVED);

    //----- 2. Specify the command's argument -----
    vm_pSDIReg->SDICARG = Arg;

    //----- 3. Specify the command's data transfer requirements -----
    if(bDataTransfer == TRUE)
    {
        vm_pSDIReg->SDICCON  |= SDIO_COMMAND_WITH_DATA;
    }else
    {
        vm_pSDIReg->SDICCON  &= ~SDIO_COMMAND_WITH_DATA;
    }

    //----- 4. Send the command to the MMC controller -----
    switch(respType)
    {
    case NoResponse:                // Response is not required, but make sure the command was sent
        DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("SendCommand no response required\r\n")));
        vm_pSDIReg->SDICCON = START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);

        while(!(vm_pSDIReg->SDICSTA & COMMAND_SENT))
        {
            dwWaitCount++;
            if( dwWaitCount > WAIT_TIME )
            {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SendCommand() - timeout waiting for command completion!\r\n")));
                return SD_API_STATUS_RESPONSE_TIMEOUT;
            }

            if( !IsCardPresent() )
            {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SendCommand() - Card ejected!\r\n")));
                return SD_API_STATUS_DEVICE_REMOVED;
            }
            if(vm_pSDIReg->SDICSTA & COMMAND_TIMED_OUT)
            {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:SendCommand() - Command 0x%04x timed out!\r\n"), Cmd));
                vm_pSDIReg->SDICSTA = COMMAND_TIMED_OUT;                // Clear the error
                return SD_API_STATUS_RESPONSE_TIMEOUT;
            }
        }
        vm_pSDIReg->SDICSTA = COMMAND_SENT;                         // Clear the status 
        break;

    case ResponseR1:                // Short response required
    case ResponseR1b:
    case ResponseR3:
    case ResponseR4:
    case ResponseR5:                
    case ResponseR6:    
        DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("sendSDICommand short response required\r\n")));
//      vm_pSDIReg->SDICCON = uiNewCmdRegVal | WAIT_FOR_RESPONSE | START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);
        vm_pSDIReg->SDICCON = WAIT_FOR_RESPONSE | START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);
        break;

    case ResponseR2:                // Long response required       
        DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("sendSDICommand long response required\r\n")));
//      vm_pSDIReg->SDICCON = uiNewCmdRegVal | LONG_RESPONSE | WAIT_FOR_RESPONSE | START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);
        vm_pSDIReg->SDICCON = LONG_RESPONSE | WAIT_FOR_RESPONSE | START_COMMAND | COMMAND_START_BIT | (Cmd & MAX_CMD_VALUE);
        break;

    default:    
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCD:sendSDICommand() - Invalid response type.  Command not sent!\r\n")));
        return SD_API_STATUS_NOT_IMPLEMENTED;
        break;
    }
    
    return SD_API_STATUS_SUCCESS;
}

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function:       CSDIOControllerBase::GetCommandResponse()

Description:    Retrieves the response info for the last SDI command
                issues.

Notes:          This routine assumes that the caller has already locked
                the current request and checked for errors.

Returns:        SD_API_STATUS status code.
-------------------------------------------------------------------*/
SD_API_STATUS CSDIOControllerBase::GetCommandResponse(PSD_BUS_REQUEST pRequest)
{
    DEBUGMSG (SDHC_RESPONSE_ZONE,(TEXT("GetCommandResponse started\r\n")));

⌨️ 快捷键说明

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