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

📄 sdio.c

📁 AU1100嵌入式处理器SD卡驱动程序源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//  Return: TRUE if request cancelled
//  Notes:  the HC lock is taken before entering this cancel handler
///////////////////////////////////////////////////////////////////////////////
BOOLEAN SDIOCancelIoHandler(PSDCARD_HC_CONTEXT pHCContext, DWORD Slot, PSD_BUS_REQUEST pRequest)
{
    PSDIO_HW_CONTEXT    pController;     // the controller

        // for now, we should never get here because all requests are non-cancelable
        // the hardware supports timeouts so it is impossible for the controller to get stuck
    DEBUG_ASSERT(FALSE);

        // get our extension 
    pController = GetExtensionFromHCDContext(PSDIO_HW_CONTEXT, pHCContext);

        // TODO --- Stop hardware, cancel the request!

        // release the lock before we complete the request
    SDHCDReleaseHCLock(pHCContext);
 
        // complete the request with a cancelled status
    SDHCDIndicateBusRequestComplete(pHCContext,
                                    pRequest,
                                    SD_API_STATUS_CANCELED);

    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//  SDIOSlotOptionHandler - handler for slot option changes
//  Input:  pHostContext - host controller context
//          Slot         - the slot the change is being applied to
//          Option       - the option code
//          pData        - data associated with the option
//          OptionSize   - size of option data
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOSlotOptionHandler(PSDCARD_HC_CONTEXT    pHCContext,
                                    DWORD                 Slot, 
                                    SD_SLOT_OPTION_CODE   Option, 
                                    PVOID                 pData,
                                    ULONG                 OptionSize)
{
    SD_API_STATUS    status = SD_API_STATUS_SUCCESS; // status
    PSDIO_HW_CONTEXT pController;                    // the controller
	PSD_HOST_BLOCK_CAPABILITY  pBlockCaps;           // queried block capabilities
	ULONG tmp;
    
        // get our extension 
    pController = GetExtensionFromHCDContext(PSDIO_HW_CONTEXT, pHCContext);

    switch (Option) {

        case SDHCDSetSlotPower:
                // can't set power so ignore this
            DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotPower : 0x%08X  \n"), *((PDWORD)pData)));
            break;

        case SDHCDSetSlotInterface:
                // shut off clock first
            SDIOClockOff(&pController->Slots[Slot]);
            DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotInterface : Clock Setting: %d \n"), 
                                         ((PSD_CARD_INTERFACE)pData)->ClockRate));
            
            if (SD_INTERFACE_SD_MMC_1BIT == ((PSD_CARD_INTERFACE)pData)->InterfaceMode) {
                DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotInterface : setting for 1 bit mode \n")));
				tmp = READ_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2);
				tmp &= ~SD_CONFIG2_WB;
				WRITE_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2,tmp);
            } else if (SD_INTERFACE_SD_4BIT == ((PSD_CARD_INTERFACE)pData)->InterfaceMode) {
                DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SetSlotInterface : setting for 4 bit mode \n"))); 
				tmp = READ_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2);
				tmp |= SD_CONFIG2_WB;
				WRITE_REGISTER_ULONG((PULONG)&pController->Slots[Slot].pSD->config2,tmp);
            } else {
                DEBUG_ASSERT(FALSE);
            }
                // set rate
            SDIOSetRate(&pController->Slots[Slot], &((PSD_CARD_INTERFACE)pData)->ClockRate);
            break;

        case SDHCDEnableSDIOInterrupts:
                // enable SDIO interrupt detection
            DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - EnableSDIOInterrupts : on slot %d  \n"),Slot));
            SD_INTERRUPTS_ENABLE(&pController->Slots[Slot],SD_Int_SDIO_Interrupt);
            break;

        case SDHCDAckSDIOInterrupt:
                 // re-enable SDIO interrupt detection
            SD_INTERRUPTS_ENABLE(&pController->Slots[Slot],SD_Int_SDIO_Interrupt);
            break;

        case SDHCDDisableSDIOInterrupts:
                // disable SDIO interrupt detection
            DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - DisableSDIOInterrupts : on slot %d  \n"),Slot));
			SD_INTERRUPTS_DISABLE(&pController->Slots[Slot],SD_Int_SDIO_Interrupt);
            break;

        case SDHCDGetWriteProtectStatus:
				// get the write protect status
            DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SDHCDGetWriteProtectStatus : on slot %d  \n"),Slot)); 
            if (SDIOPlatCardWriteProteced(pController,Slot)) {
                DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - Card is Write Protected\n"))); 
                ((PSD_CARD_INTERFACE)pData)->WriteProtected = TRUE;
            } else {
                DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - Card is NOT Write Protected\n"))); 
                ((PSD_CARD_INTERFACE)pData)->WriteProtected = FALSE;
            }
            break;

        case SDHCDQueryBlockCapability:
                // set the block capability
            DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("SDIOSDSlotOptionHandler - called - SDHCDQueryBlockCapability : on slot %d  \n"),Slot));             
            pBlockCaps = (PSD_HOST_BLOCK_CAPABILITY)pData;

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

			// the Au1100 SD controller can only handle up to 2048 bytes for each block.
            if (pBlockCaps->ReadBlockSize > SD_MAX_BLOCK_SIZE) {

				RETAILMSG(1, 
						(TEXT("SDIOSDSlotOptionHandler: Read Block Length: %d is out of the range!\n"), 
						pBlockCaps->ReadBlockSize));
                pBlockCaps->ReadBlockSize = SD_MAX_BLOCK_SIZE;
            }
            if (pBlockCaps->WriteBlockSize > SD_MAX_BLOCK_SIZE) {

				RETAILMSG(1, 
						(TEXT("SDIOSDSlotOptionHandler: Write Block Length: %d is out of the range!\n"), 
						pBlockCaps->WriteBlockSize));
                pBlockCaps->WriteBlockSize = SD_MAX_BLOCK_SIZE;
            }
            
                // the Au1100 SD controller can only handle up to 511 blocks per transfer
            if (pBlockCaps->ReadBlocks > SD_MAX_BLOCK_COUNT ) {

				RETAILMSG(1, 
						(TEXT("SDIOSDSlotOptionHandler: Read Block count: %d is out of the range!\n"), 
						pBlockCaps->ReadBlocks));
                pBlockCaps->ReadBlocks = SD_MAX_BLOCK_COUNT;
            }
            if (pBlockCaps->WriteBlocks > SD_MAX_BLOCK_COUNT ) {

				RETAILMSG(1, 
						(TEXT("SDIOSDSlotOptionHandler: Write Block count: %d is out of the range!\n"), 
						pBlockCaps->WriteBlocks));
                pBlockCaps->WriteBlocks = SD_MAX_BLOCK_COUNT;
            }             
            break;

		case SDHCDGetSlotInfo:
			{
				PSDCARD_HC_SLOT_INFO pSlotInfo = pData;

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

					// set voltage window mask  +- 10%
				SDHCDSetVoltageWindowMask(pSlotInfo, ( SD_VDD_WINDOW_3_1_TO_3_2 | 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 );     
					// set max clock rate
				SDHCDSetMaxClockRate(pSlotInfo, 25000000);
					// set power up delay
				SDHCDSetPowerUpDelay(pSlotInfo, 200 ); 
			}
			break;
			

        default:
           status = SD_API_STATUS_INVALID_PARAMETER;
    }

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  RemoveDevice - remove the device in the slot
//  Input:  pSlot - slot context
//  Output:
//  Return:
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID RemoveDevice(PSDIO_SLOT pSlot)
{
    PSD_BUS_REQUEST pRequest; // request to cancel

        // indicate the slot change
    SDHCDIndicateSlotStateChange(pSlot->pController->pHCContext, 
                                 pSlot->SlotNumber,
                                 DeviceEjected);

    DbgPrintZo(SDCARD_ZONE_INIT, (TEXT("RemoveDevice: Card Removal Detected - \n"))); 
            
        // get the current request  
    pRequest = pSlot->pCurrentRequest;
    
#ifdef DEBUG
    DumpSlot(pSlot);
#endif

    if (pRequest != NULL) {
        CompleteRequest(pSlot, SD_API_STATUS_DEVICE_REMOVED);
    }

    ResetSlot(pSlot, FALSE);
}

///////////////////////////////////////////////////////////////////////////////
//  HandleTransferErrors - Check for and handle transfer error conditions
//  Input:  pSlot        - slot context
//          pRequest     - the request
//  Output:
//  Return: TRUE if an error condition occurred and the request got completed
//  Notes:  If an error is detected the request will be completed.
///////////////////////////////////////////////////////////////////////////////
BOOL HandleTransferErrors(PSDIO_SLOT      pSlot,
                          PSD_BUS_REQUEST pRequest,
                          ULONG           CRCMask)
{
    ULONG status;

    status = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status);
    SD_INTERRUPTS_CLEAR(pSlot,CRCMask|SD_Int_Data_Timeout|SD_Int_Response_Timeout);

    if (status & CRCMask) {
        ResetSlot(pSlot, FALSE);
        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: CRC Error %08X\r\n"),pSlot->SlotNumber,status));
        CompleteRequest(pSlot,SD_API_STATUS_CRC_ERROR);
        return TRUE;
    }

    if (status & SD_Int_Data_Timeout) {
        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Data Timeout %08X\r\n"),pSlot->SlotNumber,status));
        CompleteRequest(pSlot,SD_API_STATUS_DATA_TIMEOUT);
        return TRUE;
    }

    if (status & SD_Int_Response_Timeout) {
        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Response Timeout %08X\r\n"),pSlot->SlotNumber,status));
        CompleteRequest(pSlot,SD_API_STATUS_RESPONSE_TIMEOUT);
        return TRUE;
    }

    return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
//  HandleResponseTimeout - handle response timeout interrupt
//  Input:  pSlot  - slot context
//  Output: 
//  Return:
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID HandleResponseTimeout(PSDIO_SLOT pSlot)
{
        // this should never happen because we mark the request as un-cancelable
    if (NULL==pSlot->pCurrentRequest) {
        return;
    }

        // turn off response end / response timeout interrupts
    SD_INTERRUPTS_DISABLE(pSlot, SD_Int_Response_Done | SD_Int_Response_Timeout);
        // clear
    SD_INTERRUPTS_CLEAR(pSlot, SD_Int_Response_Done | SD_Int_Response_Timeout);

        // complete request with timeout indication
    CompleteRequest(pSlot, SD_API_STATUS_RESPONSE_TIMEOUT);
}

///////////////////////////////////////////////////////////////////////////////
//  HandleDataTimeout - handle data timeout interrupt
//  Input:  pSlot  - slot context
//  Output: 
//  Return:
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID HandleDataTimeout(PSDIO_SLOT pSlot)
{
        // this should never happen because we mark the request as un-cancelable
    if (NULL==pSlot->pCurrentRequest) {
        return;
    }

        // turn off interrupts
    SD_INTERRUPTS_DISABLE(pSlot, ( SD_Int_Rx_FIFO_Not_Empty 
                                 | SD_Int_Tx_Empty 
                                 | SD_Int_Data_Timeout ));
        // clear interrupts
    SD_INTERRUPTS_CLEAR(pSlot, ( SD_Int_Rx_FIFO_Not_Empty 
                               | SD_Int_Tx_Empty 
                               | SD_Int_Data_Timeout ));

        // complete request with timeout indication
    CompleteRequest(pSlot, SD_API_STATUS_DATA_TIMEOUT);
}

///////////////////////////////////////////////////////////////////////////////
//  HandleResponseDone - handle response done interrupt
//  Input:  pSlot  - slot context
//  Output: 
//  Return:
//  Notes:  Completes the following requests:
//             Requests with no data phase
//             Requests with a CRC/timeout error in command/response phase
///////////////////////////////////////////////////////////////////////////////
VOID HandleResponseDone(PSDIO_SLOT pSlot)
{
    PSD_BUS_REQUEST pRequest;       // current request
    ULONG           response[4];
    
    pRequest = pSlot->pCurrentRequest;   

    if (NULL==pRequest) {
        return;
    }

        // Turn off response end interrupt
    SD_INTERRUPTS_DISABLE(pSlot, SD_Int_Response_Done);
        // Clear interrupt
    SD_INTERRUPTS_CLEAR(pSlot, SD_Int_Response_Done);

    response[0] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp0);
    response[1] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp1);
    response[2] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp2);
    response[3] = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp3);

⌨️ 快捷键说明

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