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

📄 sdhc.cpp

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // set the slot option handler
    SDHCDSetSlotOptionHandler(m_pHCContext, CSDIOControllerBase::SDHCSlotOptionHandler);

    // set maximum block length
    m_usMaxBlockLen = STD_HC_MAX_BLOCK_LENGTH;

    return fRet;
}

///////////////////////////////////////////////////////////////////////////////
//  SDHCControllerIstThread - SDIO/controller IST thread for driver
//  Input:  lpParameter - pController - controller instance
//  Output: 
//  Return: Thread exit status
//  Notes:
///////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CSDIOControllerBase::SDHCControllerIstThread(LPVOID lpParameter)
{
    CSDIOControllerBase *pController = (CSDIOControllerBase*)lpParameter;
    return pController->SDHCControllerIstThreadImpl();
}

///////////////////////////////////////////////////////////////////////////////
//  SDHCControllerIstThreadImpl - implementation of SDIO/controller IST thread 
//                                for driver
//  Input:  
//  Output: 
//  Return: Thread exit status
//  Notes:
///////////////////////////////////////////////////////////////////////////////
DWORD CSDIOControllerBase::SDHCControllerIstThreadImpl()
{
    DWORD dwWaitTime    = INFINITE;

    if (!CeSetThreadPriority(GetCurrentThread(), m_dwSDIOPriority)) {
        DEBUGMSG(SDCARD_ZONE_WARN, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
            L"Warning, failed to set CEThreadPriority\r\n"
        ));
    }

    InterruptDone( m_dwControllerSysIntr );

    while (TRUE) {
        // wait for the SDIO/controller interrupt
        if (WAIT_OBJECT_0 != WaitForSingleObject(m_hControllerISTEvent, dwWaitTime)) 
        {
            DEBUGMSG(SDCARD_ZONE_WARN, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
                L"Wait Failed!\r\n"
            ));
            break;
        }

        if (m_fDriverShutdown) {
            DEBUGMSG(SDCARD_ZONE_WARN, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
                L"Thread exiting!\r\n"
            ));
            break;
        }

        WORD wStat;

        wStat = Read_MMC_STAT() & INREG16(&m_vpSDIOReg->MMC_IE) & 0x7fff;

        if( wStat & (MMC_IE_EOC|MMC_STAT_CERR|MMC_STAT_CCRC|MMC_STAT_CTO) )
        {
            CommandCompleteHandler();
        }

        if( wStat & MMC_STAT_CIRQ )
        {
            ASSERT( m_fSDIOInterruptsEnabled );
            // indicate that the card is interrupting
            DEBUGMSG(SHC_INTERRUPT_ZONE, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
                L"Receibed SDIO interrupt!\r\n"));

            // disable the SDIO interrupt
            CLRREG16(&m_vpSDIOReg->MMC_IE, MMC_IE_CIRQ);
            // notify the SDBusDriver of the SDIO interrupt
            m_fSDIOInterruptInService = TRUE;
            SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceInterrupting);
        }

        InterruptDone( m_dwControllerSysIntr );
    }

    DEBUGMSG(SDCARD_ZONE_FUNC, (L"-CSDIOControllerBase::SDHCControllerIstThreadImpl\r\n"));
    return 0;
}

///////////////////////////////////////////////////////////////////////////////
//  SDHCCardDetectIstThread - card detect IST thread for driver
//  Input:  lpParameter - pController - controller instance
//  Output: 
//  Return: Thread exit status
///////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CSDIOControllerBase::SDHCCardDetectIstThread(LPVOID lpParameter)
{
    CSDIOControllerBase *pController = (CSDIOControllerBase*)lpParameter;
    return pController->SDHCCardDetectIstThreadImpl();
}

///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::SDHCDeinitializeImpl - Deinitialize the SDHC Controller
//  Input:
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
//          
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::SDHCDeinitializeImpl()
{
    // mark for shutdown
    m_fDriverShutdown = TRUE;

    if (m_fInitialized) {
        if( m_dwControllerSysIntr != SYSINTR_UNDEFINED )
        {
            // disable wakeup on SDIO interrupt
            if ( m_dwCurrentWakeupSources & WAKEUP_SDIO )
            {
                KernelIoControl( IOCTL_HAL_DISABLE_WAKE,
                    &m_dwControllerSysIntr,
                    sizeof( m_dwControllerSysIntr ),
                    NULL,
                    0,
                    NULL );
            }

            // disable controller interrupt
            InterruptDisable(m_dwControllerSysIntr);

            // release the SYSINTR value
            KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &m_dwControllerSysIntr, sizeof(DWORD), NULL, 0, NULL);
            m_dwControllerSysIntr = SYSINTR_UNDEFINED;
        }

        if (m_fCardPresent) {
            // remove device
            HandleRemoval(FALSE);
        }

    }

    // clean up controller IST
    if (NULL != m_htControllerIST) {
        // wake up the IST
        SetEvent(m_hControllerISTEvent);
        // wait for the thread to exit
        WaitForSingleObject(m_htControllerIST, INFINITE); 
        CloseHandle(m_htControllerIST);
        m_htControllerIST = NULL;
    }

    // free controller interrupt event
    if (NULL != m_hControllerISTEvent) {
        CloseHandle(m_hControllerISTEvent);
        m_hControllerISTEvent = NULL;
    }

    // clean up card detect IST
    if (NULL != m_htCardDetectIST) {
        // wake up the IST
        SetEvent(m_hCardDetectEvent);
        // wait for the thread to exit
        WaitForSingleObject(m_htCardDetectIST, INFINITE); 
        CloseHandle(m_htCardDetectIST);
        m_htCardDetectIST = NULL;
    }

    if( m_hParentBus != NULL )
    {
        TWLIntrDisable(m_hParentBus, TWL_INTR_CD1);
        TWLIntrDisable(m_hParentBus, TWL_INTR_DL1);
        TWLIntrDisable(m_hParentBus, TWL_INTR_CD2);
        TWLIntrDisable(m_hParentBus, TWL_INTR_DL2);

        TWLClose(m_hParentBus);
        m_hParentBus = NULL;
    }

    // free card detect interrupt event
    if (NULL != m_hCardDetectEvent) {
        CloseHandle(m_hCardDetectEvent);
        m_hCardDetectEvent = NULL;
    }

    return SD_API_STATUS_SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::SDHCInitialize - Initialize the the controller
//  Input:
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
//          
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::SDHCInitializeImpl()
{
    SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES; // intermediate status
    DWORD         threadID;
    unsigned long  ulLong;
    WORD wRegValue;
    DWORD *pdwSDIOIrq;
    DWORD dwSDIOIrqLen;

    m_fDriverShutdown = FALSE;
    SoftwareReset(SOFT_RESET_ALL);

    // activate the clock
    ClockOn();

    // --- Setup MMC config register ---
    // Data Bus width 1 bit - MMC/SD mode - Power Up Up/Normal - Little Endian - Clock Divider
    wRegValue = 0;
    wRegValue |= VALUE_MMC_CON_DW_1BIT | VALUE_MMC_CON_MODE_MMCSD | 
        VALUE_MMC_CON_POWERUP_UP | VALUE_MMC_CON_BE_LITTLEENDIAN;

    ulLong = (MMCSD_CLOCK_INPUT / MMCSD_CLOCK_INIT);
    if (MMCSD_CLOCK_INPUT % MMCSD_CLOCK_INIT) ulLong++;
    wRegValue |= (ulLong & MASK_MMC_CON_CLKD);

    OUTREG16(&m_vpSDIOReg->MMC_CON, wRegValue);
    DEBUGMSG(SDCARD_ZONE_INIT, (L"CSDIOControllerBase::SDHCInitializeImpl: "
        L"MMC1_CON set value = %X\r\n", wRegValue
    ));

    OUTREG16(&m_vpSDIOReg->MMC_IE, 0);

    wRegValue = (SDMMC_DEFAULT_ALMOST_EMPTY - 1) | ((SDMMC_DEFAULT_ALMOST_FULL - 1) << 8);
    OUTREG16(&m_vpSDIOReg->MMC_BUF, wRegValue);

    Write_MMC_SDIO(0);


    // --- Set the timeouts ----
    // Set command timeout of 64 clocks, the max according to OMAP1610 and SD specs
    OUTREG16(&m_vpSDIOReg->MMC_CTO, MMC_CTO_CONTROL_MAX);
    OUTREG16(&m_vpSDIOReg->MMC_DTO, MMC_DTO_CONTROL_MAX);

    // deactivate the clock
    ClockOff();

    // convert the SDIO hardware IRQ into a logical SYSINTR value
    DWORD rgdwSDIOIrq[] = { IRQ_MMC1 };
    pdwSDIOIrq = rgdwSDIOIrq;
    dwSDIOIrqLen = sizeof(rgdwSDIOIrq);

    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, pdwSDIOIrq, dwSDIOIrqLen, &m_dwControllerSysIntr, sizeof(DWORD), NULL))
    {
        // invalid SDIO SYSINTR value!
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::SDHCInitializeImpl: "
            L"Error obtaining SDIO SYSINTR value!\r\n"
        ));
        m_dwControllerSysIntr = SYSINTR_UNDEFINED;
        status = SD_API_STATUS_UNSUCCESSFUL;
        goto exitInit;
    }

    // allocate the interrupt event for the SDIO/controller interrupt
    m_hControllerISTEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

    if (NULL == m_hControllerISTEvent) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    if ( !InterruptInitialize( m_dwControllerSysIntr, m_hControllerISTEvent, NULL, 0 ) ) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    // allocate the interrupt event for card detection
    m_hCardDetectEvent = CreateEvent(NULL, FALSE, FALSE,NULL);

    if (NULL == m_hCardDetectEvent) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    // Open parent bus - triton
    m_hParentBus = TWLOpen();
    if ( m_hParentBus == NULL ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Failed to obtain parent bus handle\r\n"
        ));
        goto exitInit;
    }
 
    // Associate event with TWL TWL_INTR_CD1 interrupt
    if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_CD1, m_hCardDetectEvent)) {
        goto exitInit;
    }

    // Associate event with TWL TWL_INTR_DL1 interrupt
    if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_DL1, m_hCardDetectEvent)) {
        goto exitInit;
    }

    // Associate event with TWL TWL_INTR_CD2 interrupt
    if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_CD2, m_hCardDetectEvent)) {
        goto exitInit;
    }

    // Associate event with TWL TWL_INTR_DL2 interrupt
    if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_DL2, m_hCardDetectEvent)) {
        goto exitInit;
    }

    // Enable TWL_INTR_CD1 event
    if (!TWLIntrEnable(m_hParentBus, TWL_INTR_CD1)) {
        goto exitInit;
    }

    // Enable TWL_INTR_DL1 event
    if (!TWLIntrEnable(m_hParentBus, TWL_INTR_DL1)) {
        goto exitInit;
    }

    // Enable TWL_INTR_CD2 event
    if (!TWLIntrEnable(m_hParentBus, TWL_INTR_CD2)) {
        goto exitInit;
    }

    // Enable TWL_INTR_DL2 event
    if (!TWLIntrEnable(m_hParentBus, TWL_INTR_DL2)) {
        goto exitInit;
    }

    // create the Controller IST thread
    m_htControllerIST = CreateThread(NULL,
        0,
        CSDIOControllerBase::SDHCControllerIstThread,
        this,
        0,
        &threadID);

    if (NULL == m_htControllerIST) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    // create the card detect IST thread
    m_htCardDetectIST = CreateThread(NULL,
        0,
        CSDIOControllerBase::SDHCCardDetectIstThread,
        this,
        0,
        &threadID);

    if (NULL == m_htCardDetectIST) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    m_fInitialized = TRUE;

    // on start we need the IST to check the slot for a card
    // FIXME Menelaus should detect card SetEvent(m_hCardDetectEvent);

    status = SD_API_STATUS_SUCCESS;

exitInit:

    if (!SD_API_SUCCESS(status)) {
        // just call the deinit handler directly to cleanup
        SDHCDeinitializeImpl();
    }

    return status;
}


///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::SDHCSDCancelIoHandlerImpl - io cancel handler 

⌨️ 快捷键说明

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