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

📄 sdio.c

📁 AU1100嵌入式处理器SD卡驱动程序源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                             pSlot->hDmaInterruptEvent,
                             NULL,
                             0)) {
        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Call to InterruptInitialize failed\r\n"),
                   pSlot->SlotNumber));
    }

    pSlot->DmaIstThreadPriority = SDIO_CARD_CONTROLLER_IST_PRIORITY;

        // create the interrupt thread for controller interrupts
    pSlot->hDmaInterruptThread = CreateThread(NULL,
                                              0,
                                              (LPTHREAD_START_ROUTINE)SDIODmaIstThread,
                                              pSlot,
                                              0,
                                              &threadID);

    if (NULL == pSlot->hDmaInterruptThread) {
        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO[%d]: Can't create DMA interrupt thread\r\n"),
                   pSlot->SlotNumber));
        goto ErrorReturn;
    }

    return TRUE;
     
        // post error clean-up from here on...
ErrorReturn:
    SDIODeinitializeDMA(pSlot);

    return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
//  SDIODeinitializeDMA - De-Initialize the DMA channel
//  Input:  pSlot - slot context
//  Output: 
//  Return: 
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID SDIODeinitializeDMA(PSDIO_SLOT pSlot)
{
    InterruptDisable(pSlot->DmaSysIntr);

        // free the Tx Channel
    if (NULL!=pSlot->TxDmaChannel) {
        HalFreeDMAChannel(pSlot->TxDmaChannel);
        pSlot->TxDmaChannel = NULL;
    }
                              
        // free the Rx Channel
    if (NULL!=pSlot->RxDmaChannel) {
        HalFreeDMAChannel(pSlot->RxDmaChannel);
        pSlot->RxDmaChannel = NULL;
    }
                              
        // clean up DMA IST
    if (NULL != pSlot->hDmaInterruptThread) {
            // wake up the IST
        SetEvent(pSlot->hDmaInterruptEvent);
            // wait for the thread to exit
        WaitForSingleObject(pSlot->hDmaInterruptThread, INFINITE); 
        CloseHandle(pSlot->hDmaInterruptThread);
        pSlot->hDmaInterruptThread = NULL;
    }
        
        // free DMA interrupt event
    if (NULL != pSlot->hDmaInterruptEvent) {
        CloseHandle(pSlot->hDmaInterruptEvent);
        pSlot->hDmaInterruptEvent = NULL;
    }
}

#endif // #ifdef USE_DMA

///////////////////////////////////////////////////////////////////////////////
//  SendStopTransmission - sends a CMD12 to terminate a write transaction
//  Input:  pSlot -   slot context
//  Output: 
//  Return: 
//  Notes:  This needs to be called in the event of a CRC failure during a
//          multiblock write. The Bus Driver will resend the write request
//          but the controller state machine needs to receive a CMD12 to
//          get it out of the data write state.
///////////////////////////////////////////////////////////////////////////////
VOID SendStopTransmission(PSDIO_SLOT pSlot)
{
	ULONG tmp;

        // check that data busy is active
    if (!(READ_REGISTER_ULONG((PULONG)&pSlot->pSD->status)&SD_STATUS_DB)) {
        return;
    }
    
    SD_INTERRUPTS_DISABLE(pSlot,SD_Int_Response_Done );

        // disable clock freezing
	tmp = READ_REGISTER_ULONG((PULONG)&pSlot->pSD->config2);
	tmp |= SD_CONFIG2_DF;
	WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->config2,tmp);
        // write stop transmission command
    WRITE_REGISTER_ULONG((PULONG)&pSlot->pSD->cmd, 0x00810C71);
        // wait for response ready
    while(!(READ_REGISTER_ULONG((PULONG)&pSlot->pSD->cmd)&SD_CMD_RY)) {};
        // read response registers
    (void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp0);
    (void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp1);
    (void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp2);
    (void) READ_REGISTER_ULONG((PULONG)&pSlot->pSD->resp3);
}

///////////////////////////////////////////////////////////////////////////////
//  CompleteRequest - complete a bus reqeust
//  Input:  pSlot -   slot context
//          CompletionStatus - status of completing request
//  Output: 
//  Return: 
//  Notes:
///////////////////////////////////////////////////////////////////////////////
VOID CompleteRequest(PSDIO_SLOT    pSlot,
                     SD_API_STATUS CompletionStatus)
{
    PSD_BUS_REQUEST pRequest;   // the completed request

    pRequest = pSlot->pCurrentRequest;

    if (NULL==pRequest) {
        return;
    }

    pSlot->pCurrentRequest = NULL;
            // turn the clock off
    SDIOClockOff(pSlot);
        // complete the request
    SDHCDIndicateBusRequestComplete(pSlot->pController->pHCContext,
                                    pRequest,
                                    CompletionStatus);
}

///////////////////////////////////////////////////////////////////////////////
//  SDIOInitializeSlot - Initialize SD slot
//  Input:  pSlot - slot context
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOInitializeSlot(PSDIO_SLOT pSlot)
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    DWORD         threadID;                         // thread ID
	PHYSICAL_ADDRESS PhysAddr;

		// enable slot power
	SDIOPlatPower(pSlot->pController,
	              TRUE,
				  pSlot->SlotNumber);
	
        // allocate the interrupt event for the slot
    pSlot->hInsertionInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
    if (NULL == pSlot->hInsertionInterruptEvent) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

        // initialize the interrupt event for the slot
    if (!InterruptInitialize (pSlot->InsertionSysIntr,
                              pSlot->hInsertionInterruptEvent,
                              NULL,
                              0)) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    pSlot->InsertionIstThreadPriority = SDIO_CARD_CONTROLLER_IST_PRIORITY;
    
        // create the interrupt thread for insertion interrupts
    pSlot->hInsertionInterruptThread = CreateThread(NULL,
                                                      0,
                                                      (LPTHREAD_START_ROUTINE)SDIOInsertionIstThread,
                                                      pSlot,
                                                      0,
                                                      &threadID);

    if (NULL == pSlot->hInsertionInterruptThread) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

	PhysAddr.HighPart = 0;
	PhysAddr.LowPart = AuSdConfig[pSlot->SlotNumber].SDPhysAddr;

        // map the controller registers
    pSlot->pSD = MmMapIoSpace(PhysAddr,
                              sizeof(*pSlot->pSD),
                              FALSE);

    if (NULL == pSlot->pSD) {
        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIOInitialize - failed to map registers\n")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;    
        goto exitInit;
    }

#ifdef USE_DMA
       // do the dma...
    if (pSlot->UsingDma) {
        pSlot->DmaBufferSize = DMA_BUFFER_SIZE;
        if (!SDIOInitializeDMA(pSlot)) {
			pSlot->UsingDma = FALSE;
		}
    }
#endif

        // set the slot to its initial SW state
    pSlot->CardPresent = FALSE;
    pSlot->pCurrentRequest = NULL;

        // reset the slot to its initial state
	ResetSlot(pSlot, TRUE);

exitInit:
	return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDIODeInitializeSlot - De-Initialize SD slot
//  Input:  pSlot - slot context
//  Output: 
//  Return: 
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID SDIODeinitializeSlot(PSDIO_SLOT pSlot)
{
    InterruptDisable(pSlot->InsertionSysIntr);

        // check for cards in slots
    if (pSlot->CardPresent) {
        pSlot->CardPresent = FALSE;
            // handle remove device
        RemoveDevice(pSlot);
     }

        // clean up insertion IST
    if (NULL != pSlot->hInsertionInterruptThread) {
            // wake up the IST
        SetEvent(pSlot->hInsertionInterruptEvent);
            // wait for the thread to exit
        WaitForSingleObject(pSlot->hInsertionInterruptThread, INFINITE); 
        CloseHandle(pSlot->hInsertionInterruptThread);
        pSlot->hInsertionInterruptThread = NULL;
    }
        
        // free insertion interrupt event
    if (NULL != pSlot->hInsertionInterruptEvent) {
        CloseHandle(pSlot->hInsertionInterruptEvent);
        pSlot->hInsertionInterruptEvent = NULL;
    }

        // unmap registers
    if (NULL != pSlot->pSD) {
        MmUnmapIoSpace((PVOID)pSlot->pSD, SD_CONTROL_REGISTERS_LENGTH);
        pSlot->pSD = NULL;
    }

#ifdef USE_DMA
        // deinitialize DMA stuff
    if (pSlot->UsingDma) {
        SDIODeinitializeDMA(pSlot);
    }
#endif
}

///////////////////////////////////////////////////////////////////////////////
//  SDIOInitialize - Initialize the controller
//  Input:  pHCContext -  host controller context
//  Output: 
//  Return: SD_API_STATUS
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDIOInitialize(PSDCARD_HC_CONTEXT pHCContext)
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    DWORD         threadID;                         // thread ID
    PSDIO_HW_CONTEXT pController;                   // hardware instance
	int           i;

    pController = GetExtensionFromHCDContext(PSDIO_HW_CONTEXT, pHCContext);

    pController->DriverShutdown = FALSE;

    pController->Slots[0].pController = pController;
    pController->Slots[0].SlotNumber = 0;
    pController->Slots[1].pController = pController;
    pController->Slots[1].SlotNumber = 1;

        // initialize the critical section
    InitializeCriticalSection(&(pController->CriticalSection));

        // initialize the GPIO driver
    pController->hGPIO = GPIO_Init();

    if (INVALID_HANDLE_VALUE == pController->hGPIO) {
        DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDIO: Unable to opne GPIO device\r\n")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

	status = SDIOPlatInit(pController);

	if (SD_API_STATUS_SUCCESS != status) {
		goto exitInit;
	}

        // allocate the controller interrupt event
    pController->hControllerInterruptEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
    if (NULL == pController->hControllerInterruptEvent) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

        // initialize the controller interrupt event
    if (!InterruptInitialize (pController->SysIntr,
                              pController->hControllerInterruptEvent,
                              NULL,
                              0)) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    pController->ControllerIstThreadPriority = SDIO_CARD_CONTROLLER_IST_PRIORITY;
    
        // create the interrupt thread for controller interrupts
    pController->hControllerInterruptThread = CreateThread(NULL,
                                                      0,
                                                      (LPTHREAD_START_ROUTINE)SDIOControllerIstThread,
                                                      pController,
                                                      0,

⌨️ 快捷键说明

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