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

📄 sdcontrol.c

📁 PXA27x/ MainstionIII平台下SDIO驱动完整代码 Windows CE 6.0嵌入式操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
                SDHCDSetMaxClockRate(pSlotInfo, pController->dwMaximumSDClockFrequency);

                // 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 = pController->pCurrentRequest;

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

    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")));

    IndicateBusRequestComplete(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)
{   
    ULONG MaxBytesToRead;
    PBYTE pCurPtr;
    DWORD dwTotalRead;

    volatile UCHAR *pMMC_RX_Fifo = (volatile UCHAR *)&(pController->pSDMMCRegisters->rxfifo);
    volatile DWORD *pMMC_RX_FifoDW = (volatile DWORD *)&(pController->pSDMMCRegisters->rxfifo);


    MaxBytesToRead = MaxBytes - pRequest->HCParam;
    pCurPtr = pRequest->pBlockBuffer+pRequest->HCParam;
    
    if( ByteCount > MaxBytesToRead )
    {
        ByteCount = MaxBytesToRead;
    }
    dwTotalRead = ByteCount;
    
    // we are touching the block buffer, we must set the process permissions

            // empty the FIFO
        while (ByteCount) {
            if( ByteCount >= 4 )
            {
                union {
                    BYTE    dataByte[4];
                    DWORD   dataLong;
                } data;
                register PBYTE pSrc = data.dataByte;
                // read in the dword from the FIFO
                data.dataLong = *pMMC_RX_FifoDW;
                *(pCurPtr++) = *(pSrc++);
                *(pCurPtr++) = *(pSrc++);
                *(pCurPtr++) = *(pSrc++);
                *(pCurPtr++) = *(pSrc++);
                ByteCount -= 4;
                
            }
            else while (ByteCount)  {
               // read in the byte from the FIFO
                *(pCurPtr++) = *pMMC_RX_Fifo;
                ByteCount--;
            }
        };
    pRequest->HCParam += dwTotalRead;
}

///////////////////////////////////////////////////////////////////////////////
//  HandleTransferDone- Handle transfer done interrupt 
//  Input:  pController - the controller that is interrupting
//          fForceTimeout - if true, we reached a timeout during transfer
//  Output: 
//  Return:
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID HandleTransferDone(PSDH_HARDWARE_CONTEXT pController, BOOL fForceTimeout)
{
    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);
        // turn off data error interrupt
    PROGRAM_DATA_ERROR_INTERRUPT_OFF(pController);
      
    pController->dwControllerIstTimeout = INFINITE;

        // get the current request  
    pRequest = pController->pCurrentRequest; 

        // this should never happen because we mark the request as un-cancelable
    DEBUG_ASSERT(NULL != pRequest);
    if( !pRequest ) 
    {
        RX_FIFO_INTERRUPT_OFF(pController);
        TX_FIFO_INTERRUPT_OFF(pController);
        return;
    }

    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 = READ_MMC_REGISTER_DWORD(pController, MMC_STAT);

        // check for errors
    if (regValue & MMC_STAT_FLASH_ERROR) {
        ASSERT(0);
        DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleTransferDone reports FLASH ERROR\n")));
        IndicateBusRequestComplete(pController->pHCContext,
                                        pRequest ,
                                        SD_API_STATUS_DATA_ERROR);
        return;
    }

    if (regValue & MMC_STAT_SPI_WR_ERROR) {
        ASSERT(0);
    }

    if (regValue & MMC_STAT_RD_STALLED) {
        ASSERT(0);
    }

    if ( ( regValue & MMC_STAT_READ_TIMEOUT ) || fForceTimeout ) {
        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")));
        IndicateBusRequestComplete(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")));
        IndicateBusRequestComplete(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
            SDClockOff(pController);
        }
        DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleTransferDone reports CRC ERROR\n")));
        IndicateBusRequestComplete(pController->pHCContext,
                                        pRequest ,
                                        SD_API_STATUS_CRC_ERROR);
        return;
    }

    
#ifdef DEBUG
    ASSERT( pController->fDMATransferInProgress == FALSE );
#endif

    if(pController->fDMATransfer)
    {
        pRequest->HCParam = pRequest->NumBlocks * pRequest->BlockSize;
    }


    if (TRANSFER_IS_READ(pRequest)) {

        if( pController->fDMATransfer ) {
            if( pController->fDMAUsingDriverBuffer )
            {
                // copy data from our DMA buffer into client buffer
                if( !SDPerformSafeCopy(pRequest->pBlockBuffer,
                                       pController->pDMABuffer,
                                       pRequest->BlockSize * pRequest->NumBlocks) )
                {
                    ASSERT(0);

                    DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("HandleTransferDoneInterrupt: Access Violation\n")));
    
                    if( !( pController->fClockAlwaysOn || 
                           ( pController->fClockOnIfInterruptsEnabled && pController->fSDIOEnabled ) ) )
                    {
                            // turn off the clock
                        SDClockOff(pController);
                    }

                    DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleTransferDone reports Access Violation\n")));
                    IndicateBusRequestComplete(pController->pHCContext,
                                                    pRequest ,
                                                    SD_API_STATUS_ACCESS_VIOLATION);
                    return;
                }
            }

        } else {
                // why are we doing this here? If the remaining read data is less than a Fifo's worth (32)
                // we won't get the RX Fifo Read Request interrupt because the fifo won't be full.
                // also even if it is full or if this isn't the case the TRANSFER_DONE bit seems to mask it out
                // anyways this prevents the problem where there are bytes stuck in the Fifo
            maxBytes = pRequest->NumBlocks * pRequest->BlockSize;

            if (pRequest->HCParam < maxBytes) {
                DbgPrintZo(SDH_RECEIVE_ZONE, (TEXT("HandleTransferDoneInterrupt: Fifo contains remaining data, Max: %d, current count %d  \n"),
                    maxBytes, pRequest->HCParam));
                    // get the remaining bytes out of the FIFO
                    __try {
                        EmptyReceiveFifo(pController, 
                                 pRequest, 
                                 (maxBytes - pRequest->HCParam), 
                                 maxBytes);
                    }__except(EXCEPTION_EXECUTE_HANDLER) {
                    }
            }
        }

        SetCurrentState(pController, ReadDataDone);

        if( !( pController->fClockAlwaysOn || 
               ( pController->fClockOnIfInterruptsEnabled && pController->fSDIOEnabled ) ) )
        {
                // now it is safe to turn off the clock
            SDClockOff(pController);
        }

        DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("Bytes read: [%S]\n"), HexDisplay( pRequest->pBlockBuffer, TRANSFER_SIZE(pRequest) ) ) );
    }


    if (TRANSFER_IS_WRITE(pRequest)) {

        if (!IS_PROGRAM_DONE(pController)) {
            SetCurrentState(pController, ProgramWait);
            
                // turn on programming done interrupt
            PROGRAM_DONE_INTERRUPT_ON(pController); 
            //Sleep(500);

                // check to see if programming is finished
            if (!IS_PROGRAM_DONE(pController)) {
                DbgPrintZo(SDH_TRANSMIT_ZONE, (TEXT("HandleTransferDoneInterrupt: Programming Not Complete \n")));   
            }

            // if we wait on the programming done interrupt this could
            // go on forever because now it is up to the memory card, 
            // we may have to make this request cancelable at this point
            
            return;
        }
    } 

    DEBUG_ASSERT((pRequest->HCParam >= (pRequest->NumBlocks * pRequest->BlockSize)));
        // complete the request
   

⌨️ 快捷键说明

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