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

📄 sdcontrol.c

📁 老外的一个开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
            } else {
                    // we should never get here because the only interface mode we reported was 1-bit
                DEBUG_ASSERT(FALSE);
            }
                // shut off clock first
            SDClockOff(pController);
                // set rate
            SDSetRate(pController, &((PSD_CARD_INTERFACE)pData)->ClockRate);
            
            break;

        case SDHCDEnableSDIOInterrupts:
            
            DbgPrintZo(SDCARD_ZONE_INIT, 
                (TEXT("SDHSlotOptionHandler - called - EnableSDIOInterrupts : on slot %d  \n"),
                SlotNumber));

                // by default the detection is enabled, normally we could
                // enable the Edge detect bit, but without a GPIO manager this cannot be done in 
                // thread safe way.
            break;

        case SDHCDAckSDIOInterrupt:

                // acquire the lock to block the SDIO interrupt thread
            ACQUIRE_LOCK(pController);

            if ( ( pController->pSDMMCRegisters->STAT & 0x8000 ) &&
                 ( pController->pSDMMCRegisters->IREG & 0x0800 ) &&
                 pController->fSDIOEnabled )
            {
                DbgPrintZo(/*SDCARD_ZONE_INIT*/SDH_INTERRUPT_ZONE, (TEXT("SDIO INT (still)!\n")));
                SDHCDIndicateSlotStateChange(pController->pHCContext, 
                                                0,
                                                DeviceInterrupting);
            }

            RELEASE_LOCK(pController);

            break;

        case SDHCDDisableSDIOInterrupts:
            DbgPrintZo(SDCARD_ZONE_INIT, 
                (TEXT("SDHSlotOptionHandler - called - DisableSDIOInterrupts : on slot %d  \n"),
                SlotNumber));

                // by default the detection always enabled, normally we could
                // disable the Edge detect bit, but without a GPIO manager this cannot be done in 
                // thread safe way.

            break;

        case SDHCDGetWriteProtectStatus:
            
            DbgPrintZo(SDCARD_ZONE_INIT, 
                (TEXT("SDHSlotOptionHandler - called - SDHCDGetWriteProtectStatus : on slot %d  \n"),
                 SlotNumber)); 
            
            if( IsCardWriteProtected() ) {
                ((PSD_CARD_INTERFACE)pData)->WriteProtected = TRUE;
                DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDHSlotOptionHandler - Card is write protected \n"))); 
            } else {
                ((PSD_CARD_INTERFACE)pData)->WriteProtected = FALSE;
                DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDHSlotOptionHandler - Card is write enabled \n"))); 
            }

            break;

         case SDHCDQueryBlockCapability:
            pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;

             DbgPrintZo(SDCARD_ZONE_INIT, 
             (TEXT("SDHSlotOptionHandler: Read Block Length: %d , Read Blocks: %d\n"), 
                pBlockCaps->ReadBlockSize, 
                pBlockCaps->ReadBlocks));
             DbgPrintZo(SDCARD_ZONE_INIT, 
             (TEXT("SDHSlotOptionHandler: Write Block Length: %d , Write Blocks: %d\n"), 
                pBlockCaps->WriteBlockSize, 
                pBlockCaps->WriteBlocks));

                // the PXA27x controller can only handle up to 1024 bytes
                // with a minimum of 32 bytes per transfer
            if (pBlockCaps->ReadBlockSize > SDH_MAX_BLOCK_SIZE) {
                pBlockCaps->ReadBlockSize = SDH_MAX_BLOCK_SIZE;
            }

            if (pBlockCaps->ReadBlockSize < SDH_MIN_BLOCK_SIZE ) {
                pBlockCaps->ReadBlockSize = SDH_MIN_BLOCK_SIZE;
            }

            if (pBlockCaps->WriteBlockSize > SDH_MAX_BLOCK_SIZE) {
                pBlockCaps->WriteBlockSize = SDH_MAX_BLOCK_SIZE;
            }
            
            if (pBlockCaps->WriteBlockSize < SDH_MIN_BLOCK_SIZE ) {
                pBlockCaps->WriteBlockSize = SDH_MIN_BLOCK_SIZE;
            }

                // the PXA27x controller can handle 64K blocks,
                // we leave the number of blocks alone
             
            break;

        case SDHCDGetSlotInfo:
            if( OptionSize != sizeof(SDCARD_HC_SLOT_INFO) || pData == NULL )
            {
                status = SD_API_STATUS_INVALID_PARAMETER;
            }
            else
            {
                PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO)pData;

                // set the slot capabilities
                SDHCDSetSlotCapabilities(pSlotInfo, SD_SLOT_SD_1BIT_CAPABLE);
//																			| 
//                                                  SD_SLOT_SD_4BIT_CAPABLE |
//                                                    SD_SLOT_SDIO_CAPABLE);

                SDHCDSetVoltageWindowMask(pSlotInfo, (SD_VDD_WINDOW_3_2_TO_3_3 | SD_VDD_WINDOW_3_3_TO_3_4)); 

                // Set optimal voltage
                SDHCDSetDesiredSlotVoltage(pSlotInfo, SD_VDD_WINDOW_3_2_TO_3_3);

                SDHCDSetMaxClockRate(pSlotInfo, 20000000);  

                // Set power up delay. We handle this in SetVoltage().
                SDHCDSetPowerUpDelay(pSlotInfo, 300);
            }
            break;

        default:
           status = SD_API_STATUS_INVALID_PARAMETER;

    }

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  HandleProgramDone - Handle program done interrupt
//  Input:  pController - the controller that is interrupting
//  Output: 
//  Return:
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID HandleProgramDone(PSDH_HARDWARE_CONTEXT pController)
{
    PSD_BUS_REQUEST pRequest;       // current request

    PROGRAM_DONE_INTERRUPT_OFF(pController);

        // get the current request  
    pRequest = SDHCDGetAndLockCurrentRequest(pController->pHCContext, 0);

        // this should never happen because we mark the request as un-cancelable.
    DEBUG_ASSERT(NULL != pRequest);

    SetCurrentState(pController, WriteDataDone);

        // notice there is no status to check for a programming error
        // this is up to the upper level drivers to send a card status command
    DbgPrintZo(SDH_TRANSMIT_ZONE, (TEXT("HandleProgramDone: Programming Complete \n")));

    if( !( pController->fClockAlwaysOn || ( pController->fClockOnIfInterruptsEnabled && pController->fSDIOEnabled ) ) )
    {
            // turn off the clock
        SDClockOff(pController);
            // complete the request
    }

    DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleProgramDone reports Bus Request Succeeded\n")));

    SDHCDIndicateBusRequestComplete(pController->pHCContext,
                                    pRequest ,
                                    SD_API_STATUS_SUCCESS);
}

///////////////////////////////////////////////////////////////////////////////
//  EmptyReceiveFifo - Empty the receive Fifo
//  Input:  pController - the controller instance
//          pRequest - the request to get the data from
//          ByteCount - number of bytes to read
//          MaxBytes - limit of this transfer
//  Output: 
//  Return:
//  Notes:  
//      
///////////////////////////////////////////////////////////////////////////////
VOID EmptyReceiveFifo(PSDH_HARDWARE_CONTEXT pController, 
                      PSD_BUS_REQUEST         pRequest,
                      ULONG                   ByteCount,
                      ULONG                   MaxBytes)
{   
    DWORD dwTmp;
    ULONG   receiveBufferIndex = 0; // receive buffer index

    volatile UCHAR *pMMC_RX_Fifo = (volatile UCHAR *)&(pController->pSDMMCRegisters->RXFIFO);

            // empty the FIFO
        while (ByteCount) {
            if( !IsCardPresent() )
            {
                DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("EmptyReceiveFifo: Card ejected!\n")));     
                break;
            }

            dwTmp = pController->pSDMMCRegisters->IREG;

                // fill up the receive buffer
            if (receiveBufferIndex < MMC_RXFIFO_SIZE) {

                    // read in the byte from the FIFO
                pController->RcvBuffer[receiveBufferIndex] = *pMMC_RX_Fifo;

                receiveBufferIndex++;
                ByteCount--;

                    // check to see if we've read enough
                if ((pRequest->HCParam + receiveBufferIndex) >= MaxBytes) {
                    break;
                }

            } else {

                    // receive buffer is full, now transfer the data safely
                SDPerformSafeCopy(&pRequest->pBlockBuffer[pRequest->HCParam],
                                  pController->RcvBuffer,
                                  receiveBufferIndex);
                    // bump the running count
                pRequest->HCParam += receiveBufferIndex;
                    // reset receive buffer index
                receiveBufferIndex = 0;
            }
              
        } // while

            // check for any left over data
        if (receiveBufferIndex) {
                // safely copy the data
            SDPerformSafeCopy(&pRequest->pBlockBuffer[pRequest->HCParam],
                              pController->RcvBuffer,
                              receiveBufferIndex);
                // bump the running count
            pRequest->HCParam += receiveBufferIndex;
        }
}

///////////////////////////////////////////////////////////////////////////////
//  HandleTransferDone- Handle transfer done interrupt 
//  Input:  pController - the controller that is interrupting
//  Output: 
//  Return:
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID HandleTransferDone(PSDH_HARDWARE_CONTEXT pController)
{
    PSD_BUS_REQUEST pRequest;       // current request
    DWORD           regValue;       // intermediate byte value
    ULONG           maxBytes;       // max bytes

        // turn off the transfer done interrupt
    TRANSFER_DONE_INTERRUPT_OFF(pController);
      
        // get the current request  
    pRequest = SDHCDGetAndLockCurrentRequest(pController->pHCContext, 0);

        // this should never happen because we mark the request as un-cancelable
    DEBUG_ASSERT(NULL != pRequest);

    if (TRANSFER_IS_READ(pRequest)) {
            // make sure RX fifo interrupt is off 
        RX_FIFO_INTERRUPT_OFF(pController);
    } else if (TRANSFER_IS_WRITE(pRequest)) {
            // make sure TX fifo interrupt is off 
        TX_FIFO_INTERRUPT_OFF(pController);
            // can't turn off the clock until the prog done interrupt!
    } else {
        DEBUG_ASSERT(FALSE);
    }

        // check the transfer status
    regValue = pController->pSDMMCRegisters->STAT;

        // check for errors
    if (regValue & MMC_STAT_READ_TIMEOUT) {
        DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("HandleTransferDoneInterrupt: Read Data TimedOut \n")));     
        
        if( !( pController->fClockAlwaysOn || 
               ( pController->fClockOnIfInterruptsEnabled && pController->fSDIOEnabled ) ) )
        {
                // turn off the clock
            SDClockOff(pController);
        }

        DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleTransferDone reports DATA TIMEOUT\n")));
        SDHCDIndicateBusRequestComplete(pController->pHCContext,
                                        pRequest ,
                                        SD_API_STATUS_DATA_TIMEOUT);
        return;

    } else if (regValue & MMC_STAT_READ_DATA_CRC_ERROR) {

        DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("HandleTransferDoneInterrupt: Read Data Contains CRC error \n"))); 
        if( !( pController->fClockAlwaysOn || 
               ( pController->fClockOnIfInterruptsEnabled && pController->fSDIOEnabled ) ) )
        {
                // turn off the clock
            SDClockOff(pController);
        }
        DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleTransferDone reports CRC ERROR\n")));
        SDHCDIndicateBusRequestComplete(pController->pHCContext,
                                        pRequest ,
                                        SD_API_STATUS_CRC_ERROR);
        return;
    } else if (regValue & MMC_STAT_WRITE_DATA_CRC_ERROR) {

        DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("HandleTransferDoneInterrupt: Card received Write Data with CRC error \n"))); 
        if( !( pController->fClockAlwaysOn || 
               ( pController->fClockOnIfInterruptsEnabled && pController->fSDIOEnabled ) ) )
        {
                // turn off the clock

⌨️ 快捷键说明

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