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

📄 sdcardio.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//  Notes: 
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDSetFunctionBlockSize(PSDCARD_DEVICE_CONTEXT pDevice,
                                     DWORD                  BlockSize)
{
    USHORT bytesPerBlock = (USHORT)BlockSize; // desired block size
    DWORD                  FBROffset;         // FBR offset
    SD_API_STATUS          status;

    DEBUGCHK(0 != pDevice->SDCardInfo.SDIOInformation.Function);

    // calculate the FBR offset based on the function number
    FBROffset = SD_IO_FBR_1_OFFSET + (pDevice->SDCardInfo.SDIOInformation.Function - 1) *
        SD_IO_FBR_LENGTH;

    // update the register
    status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
        SD_IO_WRITE,          
        0,      // all from function 0
        FBROffset + SD_IO_FBR_IO_BLOCK_SIZE,
        FALSE,
        (PUCHAR)&bytesPerBlock,   // reg
        sizeof(USHORT));           // two bytes    


    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDEnableFunction  - enable/disable the device function 
//  Input:  pDevice   - the device 
//          pInfo   - enable info (required if Enable is TRUE)
//          Enable  - enable
//  Output: 
//  Return: SD_API_STATUS code
//          
//  Notes: 
///////////////////////////////////////////////////////////////////////////////
static
SD_API_STATUS SDEnableDisableFunction(PSDCARD_DEVICE_CONTEXT      pDevice,
                                      PSD_IO_FUNCTION_ENABLE_INFO pInfo,
                                      BOOL                        Enable)
{
    PREFAST_DEBUGCHK(pDevice);

    PSDCARD_DEVICE_CONTEXT      pParentDevice;  // parent device
    UCHAR                       regValue;       // temp register value
    ULONG                       retryCount;     // ready retry count
    SD_API_STATUS               status;         // intermediate status

    // get the parent device
    pParentDevice = pDevice->pParentDevice;

    if (NULL == pParentDevice) {
        DEBUGCHK(FALSE);
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDEnableDisableFunction: Enabling/Disabling SDIO Device Function %d \n"),
        pDevice->SDCardInfo.SDIOInformation.Function));

    // must interlock this request with the parent device to update the shadow register
    SDDCAcquireDeviceLock(pParentDevice);

    // update the parent device shadow register
    if (Enable) {     
        DEBUGCHK(pInfo);
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable 
            |= (1 <<  pDevice->SDCardInfo.SDIOInformation.Function);
    } else {
        DEBUGCHK(pInfo == NULL);
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable &= 
            ~(1 <<  pDevice->SDCardInfo.SDIOInformation.Function);
    }
    // get a copy
    regValue = pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable;

    // release the parent lock
    SDDCReleaseDeviceLock(pParentDevice);
    // update the register
    status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
        SD_IO_WRITE,          
        0,      // all from function 0
        SD_IO_REG_ENABLE,
        FALSE,
        &regValue,   // reg
        1);         // one byte

    if (!SD_API_SUCCESS(status)) {
        return status;
    }

    // if enabling we check for I/O ready
    if (Enable) { 
        retryCount = pInfo->ReadyRetryCount;

        while (retryCount) {
            // delay the interval time
            Sleep(pInfo->Interval);

            // read the I/O ready register
            status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
                SD_IO_READ,          
                0,      // all from function 0
                SD_IO_REG_IO_READY,
                FALSE,
                &regValue,   // reg
                1);         // one byte
            if (!SD_API_SUCCESS(status)) {
                break;
            }

            // see if it is ready
            if (regValue & (1 << pDevice->SDCardInfo.SDIOInformation.Function)) {
                DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDEnableDisableFunction: Card Function %d is now ready \n"),
                    pDevice->SDCardInfo.SDIOInformation.Function));
                break;
            }
            // decrement the count
            retryCount--; 
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDEnableDisableFunction: Card Function %d, Not Ready, re-checking (%d) \n"),
                pDevice->SDCardInfo.SDIOInformation.Function, retryCount));
        }

        if (0 == retryCount) {
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDEnableDisableFunction: Card Function %d, Not ready , exceeded retry count\n"),
                pDevice->SDCardInfo.SDIOInformation.Function));
            status = SD_API_STATUS_DEVICE_NOT_RESPONDING;
        }
    }

    return status;
} 

///////////////////////////////////////////////////////////////////////////////
//  SDSetCardFeature       - Set card feature
//  Input:  hDevice        - SD Device Handle
//          CardFeature    - Card Feature to set
//          StructureSize  - size of card feature structure
//  Output: pCardInfo      - Information for the feature
//  Return: SD_API_STATUS code
//  Notes:  This function is provided to set various card features
//          in a thread safe manner.  SDIO cards utilize shared register sets
//          between functions. This requires that the 
//          register state be preserved between functions that can be 
//          controlled in separate thread contexts.
//          This function can potentially block by issuing synchronous bus 
//          request.  This function must not be called from a bus request callback
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDSetCardFeature__X(SD_DEVICE_HANDLE     hDevice,
                                  SD_SET_FEATURE_TYPE  CardFeature,
                                  PVOID                pCardInfo,
                                  ULONG                StructureSize)
{
    SD_API_STATUS               status = SD_API_STATUS_SUCCESS;  // intermediate status
    PSD_DATA_TRANSFER_CLOCKS    pClocks;                         // data transfer clocks variable  

    PSDCARD_DEVICE_CONTEXT pDevice = (PSDCARD_DEVICE_CONTEXT) hDevice;
    if (!ValidateClientHandle(pDevice)) {
        return SD_API_STATUS_INVALID_HANDLE;
    }

    if (NULL == pDevice) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: device handle is NULL \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    switch (CardFeature) {

        case SD_IO_FUNCTION_ENABLE:
            if ((sizeof(SD_IO_FUNCTION_ENABLE_INFO) != StructureSize) || 
                (NULL == pCardInfo)) {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: SD_IO_FUNCTION_ENABLE - Invalid params \n")));
                    return SD_API_STATUS_INVALID_PARAMETER;
                }

                if (Device_SD_IO != pDevice->DeviceType) {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: device is not SDIO ! \n")));
                    return SD_API_STATUS_INVALID_PARAMETER;
                }

                status = SDEnableDisableFunction(pDevice, (PSD_IO_FUNCTION_ENABLE_INFO)pCardInfo, TRUE);

                break;

        case SD_IO_FUNCTION_DISABLE:
            if (Device_SD_IO != pDevice->DeviceType) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: device is not SDIO ! \n")));
                return SD_API_STATUS_INVALID_PARAMETER;
            }

            status = SDEnableDisableFunction(pDevice, NULL, FALSE);

            break;

        case SD_IO_FUNCTION_SET_BLOCK_SIZE:
            if ((sizeof(DWORD) != StructureSize) || 
                (NULL == pCardInfo)) {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: SD_IO_FUNCTION_SET_BLOCK_SIZE - Invalid params \n")));
                    return SD_API_STATUS_INVALID_PARAMETER;
                }

                if (Device_SD_IO != pDevice->DeviceType) {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: device is not SDIO ! \n")));
                    return SD_API_STATUS_INVALID_PARAMETER;
                }

                status = SDSetFunctionBlockSize(pDevice, *((DWORD *)pCardInfo));
                break;

        case SD_SET_DATA_TRANSFER_CLOCKS:
            if ((sizeof(SD_DATA_TRANSFER_CLOCKS) != StructureSize) || 
                (NULL == pCardInfo)) {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: SD_SET_DATA_TRANSFER_CLOCKS - Invalid params \n")));
                    return SD_API_STATUS_INVALID_PARAMETER;
                }

                pClocks = (PSD_DATA_TRANSFER_CLOCKS)pCardInfo;
                pDevice->SDCardInfo.SDMMCInformation.DataAccessReadClocks = pClocks->ReadClocks;
                pDevice->SDCardInfo.SDMMCInformation.DataAccessWriteClocks = pClocks->WriteClocks;

                status = SD_API_STATUS_SUCCESS;
                break;

        case SD_SET_CARD_INTERFACE: {
            if ((sizeof(SD_CARD_INTERFACE) != StructureSize) || 
                (NULL == pCardInfo)) {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: SD_SET_CARD_INTERFACE - Invalid params \n")));
                    return SD_API_STATUS_INVALID_PARAMETER;
                }

                // Check this is NOT a multi function card
                if(IS_DEVICE_MULTIFUNCTION(pDevice)) {
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDSetCardFeature: SD_SET_CARD_INTERFACE - Device is multi function\n")));
                    return SD_API_STATUS_INVALID_DEVICE_REQUEST;
                }

                PSD_CARD_INTERFACE pCardInterface = (PSD_CARD_INTERFACE) pCardInfo;

                // Changing the bus width is tricky when SDIO interrupts are 
                // enabled. In 1-bit mode, DAT[1] is used as the interrupt line.
                // In 4-bit mode, DAT[1] is used for data and interrupts. If
                // we change from 1-bit mode to 4-bit mode while interrupts are 
                // occurring (like when a BTH mouse is being moved franticly), we
                // need to disable SDIO interrupts while we are changing the mode
                // on both the host controller and the card. Otherwise an interrupt in
                // the middle could confuse the host controller.

                // Acquire lock so that we are not interrupted.
                SDAcquireDeviceLock(pDevice->pParentDevice);

                PSD_INTERRUPT_CALLBACK pInterruptCallBack = NULL;

                if ( (Device_SD_IO == pDevice->DeviceType) && 
                     IS_SLOT_SDIO_INTERRUPT_ON(pDevice->pSlot) && 
                     (pDevice->CardInterface.InterfaceMode != pCardInterface->InterfaceMode) ) {
                    // Temporarily disable SDIO interrupts
                    pInterruptCallBack = pDevice->SDCardInfo.SDIOInformation.pInterruptCallBack;
                    DEBUGCHK(pInterruptCallBack);
                    SDIOConnectDisconnectInterrupt(hDevice, NULL, FALSE);
                }
                
                // set the card interface for device's slot
                status = pDevice->pSlot->pHostController->pSlotOptionHandler(pDevice->pSlot->pHostController,
                    pDevice->pSlot->SlotIndex, 
                    SDHCDSetSlotInterface,
                    pCardInterface,                
                    sizeof(*pCardInterface));
                // check for success
                if (SD_API_SUCCESS(status)) {
                    // now set the interface in the card, this issues bus commands
                    status = SetCardInterface(pDevice, pCardInterface);
                    // check status
                    if (SD_API_SUCCESS(status)) {
                        // update the relevent information, keep write protect
                        // intact
                        pDevice->CardInterface.InterfaceMode = pCardInterface->InterfaceMode;
                        pDevice->CardInterface.ClockRate = pCardInterface->ClockRate;
                    }
                }

                if (pInterruptCallBack) {
                    // Re-enable SDIO interrupts
                    DEBUGCHK(!IS_SLOT_SDIO_INTERRUPT_ON(pDevice->pSlot));
                    DEBUGCHK(Device_SD_IO == pDevice->DeviceType);
                    SDIOConnectDisconnectInterrupt(hDevice, pInterruptCallBack, TRUE);
                }

                SDReleaseDeviceLock(pDevice->pParentDevice);

                break;
            }

        case SD_SET_CLOCK_STATE_DURING_IDLE:
            if ( (sizeof(BOOL) != StructureSize) || (NULL == pCardInfo) ) {
                DEBUGMSG(SDCARD_ZONE_ERROR, 
                    (TEXT("SDSetCardFeature: SD_SET_CLOCK_ON_DURING_IDLE - Invalid params \n")));
                return SD_API_STATUS_INVALID_PARAMETER;
            }

            // prompt the host to turn on or off the clock during the idle state based on the client's
            // request.
            status = pDevice->pSlot->pHostController->pSlotOptionHandler(
                pDevice->pSlot->pHostController,
                pDevice->pSlot->SlotIndex, 
                SDHCDSetClockStateDuringIdle,
                pCardInfo,                
                StructureSize);
 
            DEBUGMSG(SDCARD_ZONE_INFO, 
                (TEXT("SDSetCardFeature: SDHCDSetClockStateDuringIdle finished with status: %x\n"),
                status));
            break;


        default:
            status = SD_API_STATUS_INVALID_PARAMETER;
    }

    return status;
}

// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE

⌨️ 快捷键说明

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