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

📄 sdcontrol.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 5 页
字号:
    // Configure GPIO_92 as Alternate Function 1 (MMC_DAT0)
    
    // assume that the MMC_CLK is active-high signal driven
    dwRegVal = pHardwareContext->pGPIORegisters->GPSR2;
    dwRegVal |= 0x10000000;
    pHardwareContext->pGPIORegisters->GPSR2 = dwRegVal;
    // change the direction to OUT
    dwRegVal = pHardwareContext->pGPIORegisters->GPDR2;
    dwRegVal |= 0x10000000;
    pHardwareContext->pGPIORegisters->GPDR2 = dwRegVal;
    // change to Alternate Function 1
    dwRegVal = pHardwareContext->pGPIORegisters->GAFR2_U;
    dwRegVal = ( dwRegVal & 0xfcffffff ) | 0x01000000;
    pHardwareContext->pGPIORegisters->GAFR2_U = dwRegVal;
    
    //////////////////////////////////////////////////////////
    // Configure GPIO_109-GPIO_111 as Alternate Function 1 (MMC_DAT1-MMC_DAT3)

    // assume that the MMC_CLK is active-high signal driven
    dwRegVal = pHardwareContext->pGPIORegisters->GPSR3;
    dwRegVal |= 0x0000e000;
    pHardwareContext->pGPIORegisters->GPSR3 = dwRegVal;
    // change the direction to OUT
    dwRegVal = pHardwareContext->pGPIORegisters->GPDR3;
    dwRegVal |= 0x0000e000;
    pHardwareContext->pGPIORegisters->GPDR3 = dwRegVal;
    // change to Alternate Function 1
    dwRegVal = pHardwareContext->pGPIORegisters->GAFR3_L;
    dwRegVal = ( dwRegVal & 0x03ffffff ) | 0x54000000;
    pHardwareContext->pGPIORegisters->GAFR3_L = dwRegVal;

#ifdef DEBUG
    DumpRegisters( pHardwareContext );
    DumpGPIORegisters( pHardwareContext );
#endif

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

        // convert the hardware SD/MMC controller interrupt IRQ into a logical SYSINTR value
    dwSDIOIrq = pHardwareContext->dwSDMMCIrq;
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwSDIOIrq, sizeof(DWORD), &(pHardwareContext->dwSysintrSDMMC), sizeof(DWORD), NULL))
    {
        // invalid SDIO SYSINTR value!
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("Error obtaining SDIO SYSINTR value!\n")));
        pHardwareContext->dwSysintrSDMMC = SYSINTR_UNDEFINED;
        goto exitInit;
    }

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

    if( pHardwareContext->dwDmaChannel != 0xffffffff )
    {
        // allocate the DMA interrupt event
        pHardwareContext->hDMAInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);

        if( pHardwareContext->dwDmaSysIntr == SYSINTR_UNDEFINED )
        {
                // convert the hardware DMA controller interrupt IRQ into a logical SYSINTR value
            DWORD dwDMAIrq = pHardwareContext->dwDmaIRQ;
            if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwDMAIrq, sizeof(DWORD), &(pHardwareContext->dwDmaSysIntr), sizeof(DWORD), NULL))
            {
                // invalid SDIO SYSINTR value!
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("Error obtaining DMA SYSINTR value!\n")));
                pHardwareContext->dwDmaSysIntr = SYSINTR_UNDEFINED;
                status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
                goto exitInit;
            }
        }

        // allocate the DMA data & descriptors buffers
        if( pHardwareContext->dwDmaBufferSize )
        {
            DMA_ADAPTER_OBJECT dmaAdapter;
            dmaAdapter.ObjectSize = sizeof(dmaAdapter);
            dmaAdapter.InterfaceType = Internal;
            dmaAdapter.BusNumber = 0;
            pHardwareContext->pDMABuffer = (PBYTE)HalAllocateCommonBuffer( &dmaAdapter, 
                                                                           pHardwareContext->dwDmaBufferSize,
                                                                           &pHardwareContext->pDMABufferPhys,
                                                                           FALSE );
            if( pHardwareContext->pDMABuffer == NULL )
            {
                DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SHCDriver: - Unable to allocate memory for DMA buffers!\r\n")));
                pHardwareContext->dwDmaBufferSize = 0;
            }
            else
            { // allocate DMA descriptors
                DWORD dwDescriptorsSize = pHardwareContext->dwDmaBufferSize / pHardwareContext->systemInfo.dwPageSize;
                if( pHardwareContext->dwDmaBufferSize % pHardwareContext->systemInfo.dwPageSize )
                {
                    dwDescriptorsSize++;
                }
                dwDescriptorsSize *= sizeof(DMADescriptorChannelType);
                
                pHardwareContext->pDMADescriptors = (volatile DMADescriptorChannelType*)HalAllocateCommonBuffer( &dmaAdapter, 
                                                                               dwDescriptorsSize,
                                                                               &pHardwareContext->pDMADescriptorsPhys,
                                                                               FALSE );
                if( pHardwareContext->pDMADescriptors == NULL )
                {
                    DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("SHCDriver: - Unable to allocate memory for DMA descriptors!\r\n")));
                    HalFreeCommonBuffer( &dmaAdapter, 
                                           pHardwareContext->dwDmaBufferSize,
                                           pHardwareContext->pDMABufferPhys,
                                           pHardwareContext->pDMABuffer,
                                           FALSE );
                    pHardwareContext->pDMABuffer = NULL;
                    pHardwareContext->dwDmaBufferSize = 0;
                }
            }
        }

            // install the DMA ISR handler
        if( pHardwareContext->wszDmaIsrDll[0] )
        {
            GIISR_INFO Info;
            PVOID PhysAddr;
            DWORD inIoSpace = 0;    // io space
            PHYSICAL_ADDRESS DmaRegisterAddress = {DMA_INTERRUPT_REGISTER, 0}; 
            
            pHardwareContext->hDMAIsrHandler = LoadIntChainHandler(pHardwareContext->wszDmaIsrDll, 
                                                                     pHardwareContext->wszDmaIsrHandler,
                                                                     (BYTE)pHardwareContext->dwDmaIRQ);
            if (pHardwareContext->hDMAIsrHandler == NULL) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("LoadIntChainHandler (%s, %s, %d) failed!\r\n"),
                                            pHardwareContext->wszDmaIsrDll, 
                                            pHardwareContext->wszDmaIsrHandler,
                                            (BYTE)pHardwareContext->dwDmaIRQ));
                status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
                goto exitInit;
            }

            if (!BusTransBusAddrToStatic(pHardwareContext->hBusAccessHandle, Internal, 0, DmaRegisterAddress, sizeof(DWORD), &inIoSpace, &PhysAddr)) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (L"SDHC: Failed TransBusAddrToStatic\r\n"));
                status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
                goto exitInit;
            }
            
            DEBUGMSG(SDCARD_ZONE_INIT, (L"SDHC: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d, PhysAddr = 0x%x\r\n", 
                pHardwareContext->wszDmaIsrDll, pHardwareContext->wszDmaIsrHandler, pHardwareContext->dwDmaIRQ, PhysAddr));

            // Set up ISR handler
            Info.SysIntr = pHardwareContext->dwDmaSysIntr;
            Info.CheckPort = TRUE;
            Info.PortIsIO = FALSE;
            Info.UseMaskReg = FALSE;
            Info.PortAddr = (DWORD)PhysAddr;
            Info.PortSize = sizeof(DWORD);
            Info.Mask = 1 << pHardwareContext->dwDmaChannel;
            
            if (!KernelLibIoControl(pHardwareContext->hDMAIsrHandler, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (L"SDHC: KernelLibIoControl call failed.\r\n"));
            }
        }

            // initialize the DMA interrupt event
        if (!InterruptInitialize (pHardwareContext->dwDmaSysIntr,
                                  pHardwareContext->hDMAInterruptEvent,
                                  NULL,
                                  0)) {
            status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
            goto exitInit;
        }

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

        if (NULL == pHardwareContext->hDmaInterruptThread) {
            status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
            goto exitInit;
        }
    }

        // create the interrupt thread for controller interrupts
    pHardwareContext->hControllerInterruptThread = CreateThread(NULL,
                                                      0,
                                                      (LPTHREAD_START_ROUTINE)SDControllerIstThread,
                                                      pHardwareContext,
                                                      0,
                                                      &threadID);

    if (NULL == pHardwareContext->hControllerInterruptThread) {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto exitInit;
    }

    if (!SetupCardDetectIST(pHardwareContext))
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
    }

exitInit:

    if (!SD_API_SUCCESS(status)) {
            // just call the deinit handler directly to cleanup
        SDDeinitialize(pHCContext);
    }

    return status;

}

///////////////////////////////////////////////////////////////////////////////
//  SDHCancelIoHandler - io cancel handler 
//  Input:  pHostContext - host controller context
//          Slot - slot the request is going on
//          pRequest - the request to be cancelled
//          
//  Output: 
//  Return: TRUE if the request was cancelled
//  Notes:  
//          
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN SDHCancelIoHandler(PSDCARD_HC_CONTEXT pHCContext, 
                             DWORD              Slot, 
                             PSD_BUS_REQUEST    pRequest)
{
    PSDH_HARDWARE_CONTEXT    pController;

        // 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(PSDH_HARDWARE_CONTEXT, pHCContext);

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

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

    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//  SDBusIssueRequest - bus request handler 
//  Input:  pHostContext - host controller context
//          Slot - slot the request is going on
//          pRequest - the request
//          
//  Output: 
//  Return: SD_API_STATUS Code
//  Notes:  The request passed in is marked as uncancelable, this function
//          has the option of making the outstanding request cancelable    
//          
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDBusIssueRequest(PSDCARD_HC_CONTEXT pHCContext, 
                                     DWORD              Slot, 
                                     PSD_BUS_REQUEST    pRequest) 
{

    BOOL fExtraDelay = FALSE;
    PSDH_HARDWARE_CONTEXT    pController;     // our controller
    DWORD                      cmdatRegister;   // CMDAT register

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

    DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("SDBusIssueRequest - pRequest = %x, CMD: 0x%02X DATA: 0x%08X, TC: %d\n"),
            pRequest,pRequest->CommandCode, pRequest->CommandArgument, pRequest->TransferClass));


        // stop the clock
    SDClockOff(pController);

        // set the command
    WRITE_MMC_REGISTER_DWORD(pController, MMC_CMD, pRequest->CommandCode);
        // set the argument,  high part
    WRITE_MMC_REGISTER_DWORD(pController, MMC_ARGH, (pRequest->CommandArgument >> 16));
        // set the argument,  high part
    WRITE_MMC_REGISTER_DWORD(pController, MMC_ARGL, (pRequest->CommandArgument & 0x0000FFFF));


    switch (pRequest->CommandResponse.ResponseType) {

        case NoResponse:
            cmdatRegister = MMC_CMDAT_RESPONSE_NONE;
            break;
        case ResponseR1b:
                // response1 with busy signalling
            cmdatRegister = MMC_CMDAT_RESPONSE_R1 | MMC_CMDAT_EXPECT_BUSY;
            break;
        case ResponseR1:
        case ResponseR5:
        case ResponseR6:
        case ResponseR7:
                // on an MMC controller R5 and R6 are really just an R1 response (CRC protected)
            cmdatRegister = MMC_CMDAT_RESPONSE_R1;
            break;
        case ResponseR2:    
            cmdatRegister = MMC_CMDAT_RESPONSE_R2;
            break;
        case ResponseR3:
        case ResponseR4:    
                // R4 is really same as an R3 response on an MMC controller (non-CRC)
            cmdatRegister = MMC_CMDAT_RESPONSE_R3;
            break;

        default:
            DbgPrintZo(SDH_SDBUS_INTERACTION_ZONE, (TEXT("SDBusIssueRequest failed (Invalid parameter)\n")));
            return SD_API_STATUS_INVALID_PARAMETER;
    }

    pController->fDMATransfer = FALSE;
    pController->fDMATransferCancelled = FALSE;

        // check for Command Only

⌨️ 快捷键说明

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