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

📄 sdcardio.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

// Copyright (c) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

// SD Bus driver Card I/O request implementation

#include "SDCardDDK.h"
#include "SDbusdriver.h"

#define SD_GET_IO_RW_DIRECT_RESPONSE_FLAGS(pResponse) (pResponse)->ResponseBuffer[SD_IO_R5_RESPONSE_FLAGS_BYTE_OFFSET]   
#define SD_GET_IO_RW_DIRECT_DATA(pResponse)           (pResponse)->ResponseBuffer[SD_IO_R5_RESPONSE_DATA_BYTE_OFFSET]  


SD_API_STATUS SetCardInterface(PSDCARD_DEVICE_CONTEXT pDevice, PSD_CARD_INTERFACE pInterface); 

///////////////////////////////////////////////////////////////////////////////
//  SDReadWriteRegistersDirect - Read/Write I/O register(s) direct
//  Input:  hDevice     - the device
//          ReadWrite   - read write flag 
//          Function    - Function number
//          Address     -  starting address
//          ReadAfterWrite - flag to instruct card to read after write
//          pBuffer      -   buffer to hold value of registers
//          BufferLength - number of bytes to read/write
//      
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
//          This function can be called to read or write multiple contigous registers synchronously
//          using the SDIO RW_DIRECT command. This function issues multiple commands to transfer
//          to or from the user's buffer
//          If ReadAfterWrite is set to 1, the operation will instruct the card
//          to return the new value of the register in the response.  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDReadWriteRegistersDirect__X(SD_DEVICE_HANDLE       hDevice,
                                            SD_IO_TRANSFER_TYPE    ReadWrite,
                                            UCHAR                  Function,
                                            DWORD                  Address,
                                            BOOLEAN                ReadAfterWrite,
                                            PUCHAR                 pBuffer,
                                            ULONG                  BufferLength)
{
    SD_API_STATUS   status = SD_API_STATUS_SUCCESS; // intermediate status
    PSD_SYNCH_REQUEST_INFO pSynchInfo;  // synch information
    CSDBusDriver    *pBusDriver;        // the bus driver
    UCHAR           responseStatus;     // IO response status
    ULONG           ii;                 // loop count

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SDReadWriteRegistersDirect+\n")));

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

    if (NULL == pBuffer) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDReadWriteRegistersDirect- NULL buffer passed \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    // get the bus driver
    pBusDriver =  SDDCGetBusDriver(pDevice);
    PREFAST_DEBUGCHK(pBusDriver);

    // allocate a synch info structure to use for the response buffer
    // we do not use the event 
    pSynchInfo = pBusDriver->AllocateSyncInfo();

    if (NULL == pSynchInfo) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDReadWriteRegistersDirect- failed to allocate sync info \n")));
        return SD_API_STATUS_INSUFFICIENT_RESOURCES;
    }


    // transfer the buffer
    for (ii = 0; ii < BufferLength; ii++) {

        // send the request
        status = SDSynchronousBusRequest__X(hDevice, 
            SD_IO_RW_DIRECT,
            BUILD_IO_RW_DIRECT_ARG((UCHAR)ReadWrite,      
            ReadAfterWrite,
            Function,
            (Address + ii),
            pBuffer[ii]),
            SD_COMMAND,
            ResponseR5,
            &pSynchInfo->TempResponse,  // use the synch info for the response buffer
            0,
            0,
            NULL,
            0);
        if (!SD_API_SUCCESS(status)) {
            break;
        }

        responseStatus = SD_GET_IO_RW_DIRECT_RESPONSE_FLAGS(&pSynchInfo->TempResponse);

        // mask out the previous CRC error, the command is retried on CRC errors
        // so this bit will reflect the previous command instead
        responseStatus &= ~SD_IO_COM_CRC_ERROR;

        if (!SD_IO_R5_RESPONSE_ERROR(responseStatus)) {
            status = SD_API_STATUS_SUCCESS;
            // check to see if read after write or just a read
            if (ReadAfterWrite || (SD_IO_READ == ReadWrite)) {
                pBuffer[ii] = SD_GET_IO_RW_DIRECT_DATA(&pSynchInfo->TempResponse);
            }

        } else {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDReadWriteRegistersDirect- R5 response returned error code : 0x%02X \n"),responseStatus));
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
            break;
        }
    }

    pBusDriver->FreeSyncInfo(pSynchInfo);

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SDReadWriteRegistersDirect-\n")));

    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDReadWriteRegistersDirect: Request Failed at address : 0x%08X status:0x%08X \n"),(Address + ii), status));
    }

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDIOConnectDisconnectInterrupt  - connect/disconnect an interrupt service routine 
//                                    for an SDIO peripheral interrupt
//                                    
//  Input:  hDevice   - SD device handle
//          pIsrFunction - the interrupt service routine 
//          Connect - connect , if TRUE, pIsrFunction must not be NULL
//  Output: 
//  Return: SD_API_STATUS code
//          
//  Notes: 
///////////////////////////////////////////////////////////////////////////////
static
SD_API_STATUS SDIOConnectDisconnectInterrupt(SD_DEVICE_HANDLE         hDevice, 
                                             PSD_INTERRUPT_CALLBACK   pIsrFunction,
                                             BOOL                     Connect)
{
    PSDCARD_DEVICE_CONTEXT      pParentDevice;      // parent device
    UCHAR                       regValue;           // intermediate register value
    SD_API_STATUS               status;             // intermediate status

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

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

    if ( Connect && (NULL == pIsrFunction) ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDIOConnectInterrupt: callback function is NULL \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

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

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

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

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

    if (Connect) {
        // set the interrupt function
        pDevice->SDCardInfo.SDIOInformation.pInterruptCallBack = pIsrFunction;
        // update shadow register , we automatically enable the master interrupt enable bit
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable |= 
            ((1 << pDevice->SDCardInfo.SDIOInformation.Function) | SD_IO_INT_ENABLE_MASTER_ENABLE);
    } else {
        DEBUGCHK(pIsrFunction == NULL);
        pDevice->SDCardInfo.SDIOInformation.pInterruptCallBack = NULL;
        // mask out this function
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable &= 
            ~(1 << pDevice->SDCardInfo.SDIOInformation.Function);
    }

    // get a copy
    regValue = pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable;

    // check to see if there are interrupts to keep enabled
    if (!(regValue & SD_IO_INT_ENABLE_ALL_FUNCTIONS)) {
        // if none, then clear out master enable
        regValue &= ~SD_IO_INT_ENABLE_MASTER_ENABLE;
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable = regValue;
    }

    // set status
    status = SD_API_STATUS_SUCCESS; 

    // now check and see if we need to enable/disable interrupts in the host controller
    if (Connect) {
        // check to see if the interrupt logic is already on
        if (!IS_SLOT_SDIO_INTERRUPT_ON(pDevice->pSlot)) {
            // enable it in the host controller
            status = SDEnableSDIOInterrupts(pDevice->pSlot);

            if (SD_API_SUCCESS(status)) {
                // flag it as on
                FLAG_SD_SLOT_INTERRUPTS_ON(pDevice->pSlot);
            }
        }

    } else {
        // check to see if all the interrupts have been turned off
        if (0 == regValue) {
            // disable interrupts, we don't really care about the result
            SDDisableSDIOInterrupts(pDevice->pSlot);
            // flag it off
            FLAG_SD_SLOT_INTERRUPTS_OFF(pDevice->pSlot);
        } 
    }

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

    // update the INT Enable register
    status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
        SD_IO_WRITE,          
        0,      // all from function 0
        SD_IO_REG_INT_ENABLE,
        FALSE,
        &regValue,   // reg
        1);           

    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDIOConnectDisconnectInterrupt: failed to write INT_ENABLE register for function %d \n"),
            pDevice->SDCardInfo.SDIOInformation.Function));                
        pDevice->SDCardInfo.SDIOInformation.pInterruptCallBack = NULL;
    } else {
        if (Connect) {
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDIOConnectDisconnectInterrupt: Interrupt enabled for function %d \n"),
                pDevice->SDCardInfo.SDIOInformation.Function));
        } else {
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDIOConnectDisconnectInterrupt: Interrupt disabled for function %d \n"),
                pDevice->SDCardInfo.SDIOInformation.Function)); 
        }
    }

    SDDCReleaseDeviceLock(pParentDevice);

    return status;

}

///////////////////////////////////////////////////////////////////////////////
//  SDIOConnectInterrupt  - Associate an interrupt service routine for an SDIO
//                          peripheral interrupt
//  Input:  hDevice   - SD device handle
//          pIsrFunction - the interrupt service routine
//  Output: 
//  Return: SD_API_STATUS code
//          
//  Notes: This function is provided for an SDIO peripheral driver to 
//         register an interrupt routine for the device. 
//         The interrupt function has the form of PSD_INTERRUPT_CALLBACK.
//         The caller should call SDIODisconnectInterrupt when cleaning up
//         the device. The bus driver will enable the interrupt for the function in the
//         card's CCCR area prior to returning from this function. 
//         The interrupt callback is called whenever the device function is 
//         interrupting. The bus driver will determine the interrupting function,
//         disable the interrupt on the card and call the callback.  Upon return 
//         from the callback the bus driver will reenable the interrupt in the
//         card's CCR.
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOConnectInterrupt__X(SD_DEVICE_HANDLE         hDevice, 
                                      PSD_INTERRUPT_CALLBACK   pIsrFunction)
{
    // All error checking is done in SDIOConnectDisconnectInterrupt.
    return SDIOConnectDisconnectInterrupt(hDevice, 
        pIsrFunction,
        TRUE);
}

///////////////////////////////////////////////////////////////////////////////
//  SDIODisconnectInterrupt  - disconnect the interrupt 
//  Input:  hDevice   - SD device handle
//  Output: 
//  Return: 
//          
//  Notes: This function should be called to disconnect the interrupt
//         from the device. The bus driver will disable the interrupt in the
//         card's CCCR area
///////////////////////////////////////////////////////////////////////////////
VOID SDIODisconnectInterrupt__X(SD_DEVICE_HANDLE hDevice)
{
    // All error checking is done in SDIOConnectDisconnectInterrupt.
    SDIOConnectDisconnectInterrupt(hDevice, 
        NULL,
        FALSE);
}


///////////////////////////////////////////////////////////////////////////////
//  SDSetFunctionBlockSize  - set the block size of the function
//  Input:  pDevice   - the device 
//          BlockSize - block size to set
//  Output: 
//  Return: SD_API_STATUS code
//          

⌨️ 快捷键说明

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