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

📄 sdio.c

📁 AU1100嵌入式处理器SD卡驱动程序源码
💻 C
📖 第 1 页 / 共 5 页
字号:

    DbgPrintZo(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP0: 0x%08X \n"),response[0]));
    DbgPrintZo(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP1: 0x%08X \n"),response[1]));
    DbgPrintZo(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP2: 0x%08X \n"),response[2]));
    DbgPrintZo(SDIO_RESPONSE_ZONE, (TEXT("HandleResponseDone SD_RESP3: 0x%08X \n"),response[3]));

    if (NoResponse != pRequest->CommandResponse.ResponseType) {
            // Copy response over to request structure
        PUCHAR pResponseBuffer = &(pRequest->CommandResponse.ResponseBuffer[1]);
        int ii;

        for (ii=0; ii<4; ii++) {
            *pResponseBuffer++ = (UCHAR)(response[ii]);
            *pResponseBuffer++ = (UCHAR)(response[ii] >> 8);
            *pResponseBuffer++ = (UCHAR)(response[ii] >> 16);
            *pResponseBuffer++ = (UCHAR)(response[ii] >> 24);
        }
    }

        // check for command/response only
    if (SD_COMMAND == pRequest->TransferClass) {
            // check for and handle errors
        if (FALSE==HandleTransferErrors(pSlot,pRequest,SD_Int_Response_CRC_Error)) {
                // no errors, complete request with success
            CompleteRequest(pSlot, SD_API_STATUS_SUCCESS);
        }
    } else {

#ifdef USE_DMA
        if (!pSlot->UsingDmaThisCmd) {
#endif // #ifdef USE_DMA

                // handle data phase transfer
                // set blocks transferred to 0
            pRequest->HCParam = 0;
         
            if (TRANSFER_IS_READ(pRequest)) {
                    // Enable buffer read enable interrupt
                SD_INTERRUPTS_ENABLE(pSlot, SD_Int_Rx_FIFO_Not_Empty | 
                                            SD_Int_Data_Timeout);
            } else {
                    // Enable buffer write enable interrupt
                SD_INTERRUPTS_ENABLE(pSlot, SD_Int_Tx_Empty | 
                                            SD_Int_Data_Timeout);  
            }
#ifdef USE_DMA
        }
#endif // #ifdef USE_DMA
    }
}

///////////////////////////////////////////////////////////////////////////////
//  HandleRxFifoNotEmpty - handle Rx FIFO not empty interrupt
//  Input:  pSlot  - slot context
//  Output: 
//  Return:
//  Notes:  Completes the following requests:
//             Requests with a CRC/timeout error in the read data phase
///////////////////////////////////////////////////////////////////////////////
VOID HandleRxFifoNotEmpty(PSDIO_SLOT pSlot)
{
    PSD_BUS_REQUEST pRequest;   // current request
    ULONG           regValue;   // reg value

        // get the current request  
    pRequest = pSlot->pCurrentRequest;
        
    if (NULL==pRequest) {
        return;
    }

    if (pRequest->HCParam == (pRequest->BlockSize*pRequest->NumBlocks)) {
        return;
    }
        
        // we are touching the block buffer, we must set the process permissions
    SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
            // Get byte from fifo
        regValue = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->rxport);
        pRequest->pBlockBuffer[pRequest->HCParam] = (UCHAR)(regValue&0xFF);
        pRequest->HCParam++;
    } SD_RESTORE_PROC_PERMISSIONS();

    if (pRequest->HCParam == (pRequest->BlockSize*pRequest->NumBlocks)) {
        SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Rx_FIFO_Not_Empty);
        DbgPrintZo(SDIO_INTERRUPT_ZONE,(TEXT("SDIO: RxFifoNotEmpty completing request, HCParam=%d\r\n"),pRequest->HCParam));
            // check for and handle errors
        if (FALSE==HandleTransferErrors(pSlot,pRequest,SD_Int_Read_CRC_Error)) {
                // no errors, complete request with success
            CompleteRequest(pSlot, SD_API_STATUS_SUCCESS);
        }
    }
}
        
///////////////////////////////////////////////////////////////////////////////
//  HandleTxEmpty - handle Tx empty interrupt
//  Input:  pSlot  - slot context
//  Output: 
//  Return: TRUE if the request has been completed
//  Notes:  Completes the following requests:
//             Requests with a CRC/timeout error in the read data phase
///////////////////////////////////////////////////////////////////////////////
VOID HandleTxEmpty(PSDIO_SLOT pSlot)
{
    PSD_BUS_REQUEST pRequest;   // current request
    ULONG           dataValue;  // reg value

        // get the current request  
    pRequest = pSlot->pCurrentRequest;
        
        // check the request hasn't already been completed
    if ((NULL==pRequest) || (pRequest->HCParam == (pRequest->BlockSize*pRequest->NumBlocks))) {
        SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Tx_Empty);
        return;
    }
        
        // we are touching the block buffer, we must set the process permissions
    SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
            // Get byte from buffer
        dataValue = pRequest->pBlockBuffer[pRequest->HCParam];
        WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->txport,dataValue);
        pRequest->HCParam++;
    } SD_RESTORE_PROC_PERMISSIONS();

    if (pRequest->HCParam == (pRequest->BlockSize*pRequest->NumBlocks)) {
        SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Tx_Empty);
            // check for and handle errors
            if (FALSE==HandleTransferErrors(pSlot,pRequest,SD_Int_Write_CRC_Error)) {
                    // no errors, complete request with success
                CompleteRequest(pSlot, SD_API_STATUS_SUCCESS);
            }
    }
}
       
///////////////////////////////////////////////////////////////////////////////
//  GetInterrupts - get current pending interrupts
//  Input:  pSlot - slot context
//  Output: pInterrupts - active, unmasked, controller interrupts
//  Return: TRUE if there is an active unmasked interrupt
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
BOOL GetInterrupts(PSDIO_SLOT pSlot,
                   PULONG     pInterrupts) 
{
    ULONG  interrupts;      // controller interrupts

        // read interrupts from hardware
    interrupts = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status);
        // the hardware masks interrupts sources from causing an interrupt,
        // but not from showing up in the status register. Mask them here.
    interrupts &= pSlot->InterruptMask;

    *pInterrupts = interrupts;

        // Return TRUE if any unmasked interrupts are active
    return (0 != interrupts);
}

///////////////////////////////////////////////////////////////////////////////
//  SDIOInsertionIstThread - IST thread for driver
//  Input:  pSlot - slot context
//  Output: 
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
DWORD SDIOInsertionIstThread(PSDIO_SLOT pSlot)
{
    DWORD waitStatus;       // wait status
    DWORD initRate = 200000;
    int   debounceCount;
    BOOL  cardInserted;

    if (!CeSetThreadPriority(GetCurrentThread(), pSlot->InsertionIstThreadPriority)) {
        DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDIOInsertionIstThread[%d]: warning, failed to set CEThreadPriority \n"),pSlot->SlotNumber));
    }

    while(1) {

        waitStatus = WaitForSingleObject(pSlot->hInsertionInterruptEvent, INFINITE);

        if (WAIT_OBJECT_0 != waitStatus) {
            DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDIOInsertionIstThread[%d]: Wait Failed! 0x%08X \n"),pSlot->SlotNumber, waitStatus));
                // bail out
            return 0;
        }

        if (pSlot->pController->DriverShutdown) {
            DbgPrintZo(1, (TEXT("SDIOInsertionIstThread[%d]: Thread Exiting\n"),pSlot->SlotNumber));
            return 0;
        }

            // check slot on startup for inserted cards
        if (pSlot->CheckSlotOnStartUp) {
            DbgPrintZo(SDIO_INTERRUPT_ZONE,(TEXT("SDIOInsertionIstThread[%d]: Removing device after powerdown\r\n"),pSlot->SlotNumber));
                // this case is hit when we suspend and resume while there is a
                // card in the slot, because we remove power we have
                // to indicate a device removal first
            RemoveDevice(pSlot);

				// Reset the slot
			ResetSlot(pSlot, FALSE);

#ifdef DEBUG
				// Dump the state of the slot
			DumpSlot(pSlot);
#endif

                // Now check to see if the card is still present, if so
                // handle as per device insertion
       
            if (SDIOPlatCardInserted(pSlot->pController,pSlot->SlotNumber)) {
                pSlot->CardPresent = TRUE;
				pSlot->CardInitialised = FALSE;

                    // indicate device arrival
                SDHCDIndicateSlotStateChange(pSlot->pController->pHCContext,
                                             pSlot->SlotNumber,
                                             DeviceInserted );
            } else {
                pSlot->CardPresent = FALSE;
            }
            pSlot->CheckSlotOnStartUp = FALSE;

            InterruptDone(pSlot->InsertionSysIntr);
            continue;
        }

        DbgPrintZo(SDIO_INTERRUPT_ZONE, (TEXT("SDIOInsertionIstThread[%d]: interrupt!\n"),pSlot->SlotNumber));
         
            // start debounce logic
        debounceCount = 0;
        cardInserted = FALSE;

            // stay in this loop until the insertion state has been the same for
            // ten consecutive debounce sampling intervals
        while(debounceCount < SDIO_DEBOUNCE_COUNT) {
            if (SDIOPlatCardInserted(pSlot->pController,pSlot->SlotNumber)) {
                if (cardInserted) {
                    debounceCount++;
                } else {
                    cardInserted = TRUE;
                    debounceCount = 0;
                }
            } else {
                if (cardInserted) {
                    cardInserted = FALSE;
                    debounceCount = 0;
                } else {
                    debounceCount++;
                }
            }
            Sleep(SDIO_DEBOUNCE_INTERVAL);
        }

        if (cardInserted && !pSlot->CardPresent) {
                // set clock to 100 kHz for card initialisation
            SDIOSetRate(pSlot, &initRate);

            pSlot->CardPresent = TRUE;
            pSlot->CardInitialised = FALSE;

            DbgPrintZo(SDIO_INTERRUPT_ZONE,(TEXT("SDIOInsertionIstThread[%d]: Card Insertion Interrupt\r\n"),pSlot->SlotNumber));
                // indicate device arrival
            SDHCDIndicateSlotStateChange(pSlot->pController->pHCContext,
                                         pSlot->SlotNumber,
                                         DeviceInserted );
        } else if (!cardInserted && pSlot->CardPresent) {
            DbgPrintZo(SDIO_INTERRUPT_ZONE,(TEXT("SDIOInsertionIstThread[%d]: Card Removal Interrupt\r\n"),pSlot->SlotNumber));
                // remove device
            RemoveDevice(pSlot);

            pSlot->CardPresent = FALSE;
        }

        InterruptDone(pSlot->InsertionSysIntr);
    }
}

///////////////////////////////////////////////////////////////////////////////
//  SDIOControllerIstThread - IST thread for driver
//  Input:  pController - controller context
//  Output: 
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
DWORD SDIOControllerIstThread(PSDIO_HW_CONTEXT pController)
{
    DWORD waitStatus;       // wait status
    ULONG interrupts;       // current interrupts
    UCHAR slot;             // slot number
    PSDIO_SLOT pSlot;       // the slot

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

    while(1) {

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

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

        if (pController->DriverShutdown) {
                // shut the thread down
            DbgPrintZo(1, (TEXT("SDIOControllerIstThread: Thread Exiting\n")));
            return 0;
        }
        
            // check each slot in turn
        for (slot=0; slot<SDIOPlatNumSlots(); slot++) {
            pSlot = &pController->Slots[slot];
                // loop until all interrupts are serviced
            while (GetInterrupts(pSlot,&interrupts)) {

                DbgPrintZo(SDIO_INTERRUPT_ZONE,(TEXT("Int: %08X\r\n"),interrupts));

                if (interrupts & SD_Int_Response_Timeout) {
                        // clear the interrupt
                    SD_INTERRUPTS_CLEAR(pSlot, SD_Int_Response_Timeout);
                    DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO - Response Timeout Interrupt\r\n")));
                    HandleResponseTimeout(pSlot);
                }
                
                if (interrupts & SD_Int_Data_Timeout) {
                        // clear the interrupt
                    SD_INTERRUPTS_CLEAR(pSlot, SD_Int_Data_Timeout);
                    DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO - Data Transfer Timeout Interrupt\r\n")));
                    HandleDataTimeout(pSlot);
                }

                if (interrupts & SD_Int_Response_Done) {
                        // clear the interrupt
                    SD_INTERRUPTS_CLEAR(pSlot, SD_Int_Response_Done);
                    DbgPrintZo(SDIO_INTERRUPT_ZONE,(TEXT("SDIO - Response Done Interrupt\r\n")));
                    HandleRespons

⌨️ 快捷键说明

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