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

📄 sdcontrol.c

📁 老外的一个开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:

    if (NoResponse != pRequest->CommandResponse.ResponseType) {

            // read in the response words from the response fifo.
        for (ii = startingOffset; ii >= 0; ii--) {
                // read from the fifo
            responseBuffer[ii] = (USHORT)(pController->pSDMMCRegisters->RES);
        }

         
        if (ResponseR2 == pRequest->CommandResponse.ResponseType)  {
                // since the response Fifo is only 16 bytes, the R2 response which is normally 17 bytes
                // gets crammed into 16 bits, this offset the whole R2 response by 1 byte so when
                // copy the data to the response buffer, bump over the place holder for the CRC
            memcpy(&pRequest->CommandResponse.ResponseBuffer[1], 
                   responseBuffer, 
                   (sizeof(USHORT)) * (startingOffset + 1));
        } else {
                // all other responses are nicely aligned to 6 bytes, the CRC value in the last 
                // dword is not set, but we copy it anyways to the response buffer
            memcpy(pRequest->CommandResponse.ResponseBuffer, 
                   responseBuffer, 
                   (sizeof(USHORT)) * (startingOffset + 1));
        }
    }

        // check for command/response only
    if (SD_COMMAND == pRequest->TransferClass) {

            // check to see if this request was a response with busy
        if (ResponseR1b == pRequest->CommandResponse.ResponseType) { 

            while( ( !( statRegister & MMC_STAT_PROGRAM_DONE ) ) &&
                   ( !( pController->DriverShutdown ) ) &&
                   IsCardPresent() )
            {
                statRegister = pController->pSDMMCRegisters->STAT;
            }
        }

        if( !( pController->fClockAlwaysOn || 
               ( pController->fClockOnIfInterruptsEnabled && pController->fSDIOEnabled ) ) )
        {
                // complete the current request here, there's no data phase
                // turn off the clock
            SDClockOff(pController);
        }

        SetCurrentState(pController, CommandComplete);
        DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleEndCommandInterrupt reports Bus Request Completed\n")));
        SDHCDIndicateBusRequestComplete(pController->pHCContext,
                                        pRequest ,
                                        SD_API_STATUS_SUCCESS);    
    } else {
          
        if (TRANSFER_IS_READ(pRequest)){   
            DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleEndCommandInterrupt starting READ TRANSFER of %d blocks of %d bytes\n"), pRequest->NumBlocks, pRequest->BlockSize ));
                // turn on RX Fifo interrupts
            RX_FIFO_INTERRUPT_ON(pController);
            SetCurrentState(pController, ReadDataTransfer);
                // turn on the transfer done interrupt to check for timeout on reads
                // the receive handler will turn this off after getting the first byte
            TRANSFER_DONE_INTERRUPT_ON(pController);
        } else {
            DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("HandleEndCommandInterrupt starting WRITE TRANSFER of %d blocks of %d bytes\n"), pRequest->NumBlocks, pRequest->BlockSize ));
            DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("Bytes wrtn: [%S]\n"), HexDisplay( pRequest->pBlockBuffer, TRANSFER_SIZE(pRequest) )) );
            SetCurrentState(pController, WriteDataTransfer);
                // turn on Fifo interrupts
            TX_FIFO_INTERRUPT_ON(pController);
                // turn on transfer interrupts
            TRANSFER_DONE_INTERRUPT_ON(pController);
            SDLoadXmitFifo(pController, pRequest);
            
        }
    }
    
}

///////////////////////////////////////////////////////////////////////////////
//  GetMMCInterrupts - Get MMC interrupts
//  Input:  pHCDevice - the controller 
//  Output: 
//  Return: bit mask of the interrupts
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
DWORD GetMMCInterrupts(PSDH_HARDWARE_CONTEXT pHCDevice)
{
    DWORD intr;
    DWORD interrupts;    // current interrupts
    DWORD interruptMask; // interrupt mask
    DWORD stat;

        // get interrupts
    intr = pHCDevice->pSDMMCRegisters->IREG & MMC_IREG_INTERRUPTS;

    // get the interrupt masks so we know which ones we don't care about
        // the handlers will turn off (mask) interrupts 
    interruptMask = (~(pHCDevice->pSDMMCRegisters->IMASK)) & MMC_IREG_INTERRUPTS;

        // mask it
    interrupts = intr & interruptMask;

    stat = pHCDevice->pSDMMCRegisters->STAT;
                                     
    if( pHCDevice->fSDIOEnabled )
    {
        DbgPrintZo(SDH_INTERRUPT_ZONE, 
            (TEXT("S=%04X I=%04X M=%04X R=%04X\n"), 
                stat, intr, interruptMask, interrupts));
    }
    return interrupts;
}

///////////////////////////////////////////////////////////////////////////////
//  SDControllerIstThread - IST thread for MMC Controller driver
//  Input:  pHCDevice - the controller instance
//  Output: 
//  Return: Thread exit code
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
DWORD SDControllerIstThread(PSDH_HARDWARE_CONTEXT pHCDevice)
{
    DWORD waitStatus;    // wait status
    DWORD interrupts;    // current interrupts

    if (!CeSetThreadPriority(GetCurrentThread(), 
        pHCDevice->ControllerIstThreadPriority)) {
        DbgPrintZo(SDCARD_ZONE_WARN, 
            (TEXT("SDControllerIstThread: warning, failed to set CEThreadPriority \n")));
    }

    while(1) {

        waitStatus = WaitForSingleObject(pHCDevice->hControllerInterruptEvent, INFINITE);

        if (WAIT_OBJECT_0 != waitStatus) {
            DbgPrintZo(SDCARD_ZONE_WARN, 
                (TEXT("SDControllerIstThread: Wait Failed! 0x%08X \n"), waitStatus));
                // bail out
            return 0;
        }

        if (pHCDevice->DriverShutdown) {
            DbgPrintZo(1, (TEXT("SDControllerIstThread: Thread Exiting\n")));
            return 0;
        }
        
        DbgPrintZo(SDH_INTERRUPT_ZONE, (TEXT("SDIst+++++++++++++ \n")));

            // loop until all interrupts are serviced
        while (interrupts = GetMMCInterrupts(pHCDevice)) {

            DbgPrintZo(SDH_INTERRUPT_ZONE, 
                (TEXT("SDControllerIstThread: Controller Interrupt: 0x%08X \n"),interrupts));

            if (interrupts & MMC_IREG_CLOCK_IS_OFF) {
                    // no one should be turning this on
                DEBUG_ASSERT(FALSE);
                    // mask the interrupt
                CLOCK_OFF_INTERRUPT_OFF(pHCDevice);
            }
   
            if (interrupts & MMC_IREG_END_CMD) {
                DbgPrintZo(SDH_INTERRUPT_ZONE, 
                    (TEXT("SDControllerIstThread: MMC_IREG_END_CMD \n")));
                HandleEndCommandInterrupt(pHCDevice);
            }
            
            if (interrupts & MMC_IREG_STOP_CMD) {
                DbgPrintZo(SDH_INTERRUPT_ZONE, 
                    (TEXT("SDControllerIstThread: MMC_IREG_STOP_CMD \n")));
                DEBUG_ASSERT(FALSE);
            }
            
            if (interrupts & MMC_IREG_RXFIFO_REQ ) {
                DbgPrintZo(SDH_INTERRUPT_ZONE, 
                    (TEXT("SDControllerIstThread: MMC_IREG_RXFIFO_REQ \n")));
                HandleReceiveInterrupt(pHCDevice);
            }
            
            if (interrupts & MMC_IREG_TXFIFO_REQ) {
                DbgPrintZo(SDH_INTERRUPT_ZONE, 
                    (TEXT("SDControllerIstThread: MMC_IREG_TXFIFO_REQ \n")));
                HandleXmitInterrupt(pHCDevice);
            }
            
            if (interrupts & MMC_IREG_PROG_DONE) {
                DbgPrintZo(SDH_INTERRUPT_ZONE, 
                    (TEXT("SDControllerIstThread: MMC_IREG_PROG_DONE \n")));
                HandleProgramDone(pHCDevice);
            } 
                // DATA transfer done should be checked last so that the 
                // HandleReceive and HandleTransmit
                // have a chance to finish copying from the fifos
            if (interrupts & MMC_IREG_DATA_TRAN_DONE) {
                DbgPrintZo(SDH_INTERRUPT_ZONE, 
                    (TEXT("SDControllerIstThread: MMC_IREG_DATA_TRAN_DONE \n")));
                HandleTransferDone(pHCDevice);
            }
        }
#if 0
        if( pHCDevice->CurrentState == ReadDataTransfer )
        {
            if (!CLOCK_IS_ON(pHCDevice)) 
            {
                //DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("CLOCK IS OFF during transfer!\n")));
                SDClockOn(pHCDevice);
            }
        }
#endif
        DbgPrintZo(SDH_INTERRUPT_ZONE, (TEXT("SDIst-------------- \n")));
        InterruptDone(pHCDevice->dwSysintrSDMMC);
    }

}


void ProcessCardInsertion( void *pContext )
{
    DWORD initializationClock = SD_DEFAULT_CARD_ID_CLOCK_RATE;

    PSDH_HARDWARE_CONTEXT pHCDevice = (PSDH_HARDWARE_CONTEXT)pContext;
    if (!pHCDevice->DevicePresent) {
            // if we have stable insertion and there wasn't a device mark it
        DbgPrintZo(SDH_INTERRUPT_ZONE, 
            (TEXT("CardDetectIstThread: Device Fully Inserted ! \n"))); 
            // mark that the card is in the slot
        pHCDevice->DevicePresent = TRUE;
    
            // flag that this is the first command sent
        pHCDevice->SendInitClocks = TRUE;

            // turn the Multimedia Card power on
        MMCPowerControl( TRUE );

            // reset the clock to the ID rate
            // shut off clock first
        SDClockOff(pHCDevice);
            // set rate
        SDSetRate(pHCDevice, &initializationClock);

            // give the card some time for initialization
        Sleep(100);

            // indicate the slot change
        SDHCDIndicateSlotStateChange(pHCDevice->pHCContext, 
                                        0,
                                        DeviceInserted);
    }
}

void ProcessCardRemoval( void *pContext )
{
    PSDH_HARDWARE_CONTEXT pHCDevice = (PSDH_HARDWARE_CONTEXT)pContext;
    if( pHCDevice->DevicePresent )
    {
        DbgPrintZo(SDH_INTERRUPT_ZONE, 
            (TEXT("CardDetectIstThread: Card Removal Detected! \n"))); 
            // mark that the card has been removed
        pHCDevice->DevicePresent = FALSE;
            
            // indicate the slot change 
        SDHCDIndicateSlotStateChange(pHCDevice->pHCContext, 
                                        0,
                                        DeviceEjected); 

            // shut off clock first
        SDClockOff(pHCDevice);

            // turn the Multimedia Card power on
        MMCPowerControl( FALSE );
    }
}

BOOL DriverShutdown(void *pContext)
{
    PSDH_HARDWARE_CONTEXT pHCDevice = (PSDH_HARDWARE_CONTEXT)pContext;
    return pHCDevice->DriverShutdown;
}

#ifdef DEBUG

void DumpRegisters(PSDH_HARDWARE_CONTEXT pController)
{
    BOOL fQuit = TRUE;
#ifdef EXTENSIVE_DEBUGGING
    fQuit = FALSE;
#endif
    if( !fQuit )
    {
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SD/MMC Registers Dump Begin\r\n")));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("STRPC =0x%08X\n"), pController->pSDMMCRegisters->STRPC));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("STAT  =0x%08X\n"), pController->pSDMMCRegisters->STAT));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("CLKRT =0x%08X\n"), pController->pSDMMCRegisters->CLKRT));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SPI   =0x%08X\n"), pController->pSDMMCRegisters->SPI));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("CMDAT =0x%08X\n"), pController->pSDMMCRegisters->CMDAT));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("RESTO =0x%08X\n"), pController->pSDMMCRegisters->RESTO));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("RDTO  =0x%08X\n"), pController->pSDMMCRegisters->RDTO));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("BLKLE =0x%08X\n"), pController->pSDMMCRegisters->BLKLE));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("NOB   =0x%08X\n"), pController->pSDMMCRegisters->NOB));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("PRTBU =0x%08X\n"), pController->pSDMMCRegisters->PRTBUF));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("IMASK =0x%08X\n"), pController->pSDMMCRegisters->IMASK));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("IREG  =0x%08X\n"), pController->pSDMMCRegisters->IREG));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("CMD   =0x%08X\n"), pController->pSDMMCRegisters->CMD));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("ARGH  =0x%08X\n"), pController->pSDMMCRegisters->ARGH));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("ARGL  =0x%08X\n"), pController->pSDMMCRegisters->ARGL));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("RES   =0x%08X\n"), pController->pSDMMCRegisters->RES));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("RXFIFO=----------\n")/*, pController->pSDMMCRegisters->RXFIFO*/));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("TXFIFO=----------\n")/*, pController->pSDMMCRegisters->TXFIFO*/));
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SD/MMC Registers Dump End\r\n")));
    }
}


#endif

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

⌨️ 快捷键说明

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