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

📄 sdiocontrollerbase.cpp

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//

// Copyright (c) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <s3c2410x.h>
#include <s3c2410x_dmatransfer.h>
#include <creg.hxx>
#include <ddkreg.h>
#include <SDCardDDK.h>
#include <SDHCD.h>
#include "SDIOControllerBase.h"

#define SDIO_DMA_PHYSICAL_MEMORY_SIZE	  0x00010000

#define MMCFIF_PHYS 0x5A00003C
#define FCLK                            (203000000)
#define UCLK                            (50331648)  // 48 MHz
#define HCLK                            (FCLK / 2)
#define PCLK                            (FCLK / 4)

/////////////////////////////////////////////////////////////////////////

#define WAIT_TIME                       0x200000        // while loop delay

#define START_BIT                           0x00
#define TRANSMISSION_BIT                    0x00
#define START_RESERVED                      0x3F
#define END_RESERVED                        0xFE
#define END_BIT                             0x01

#define MAXIMUM_DMA_TRANSFER_SIZE               SDIO_DMA_PHYSICAL_MEMORY_SIZE

#define MAXIMUM_BLOCK_TRANSFER_SIZE             0xfff
#define MINIMUM_BLOCK_TRANSFER_SIZE             1

#define IS_BUFFER_DWORD_ALIGNED(x)              ((((DWORD)x) % 4) == 0)

#define IS_BUFFER_SIZE_A_DWORD_MULTPLE(x)       ((((DWORD)x) % 4 )== 0)

#define DMA_CHANNEL_TEXT TEXT("DMAChannel")
#define DMA_IRQ_TEXT TEXT("DMAIrq")
#define DMA_IST_PRIORITY_TEXT TEXT("DMA_IST_Priority")

#define SDIO_IRQ_TEXT TEXT("SDIOIrq")
#define SDIO_IST_PRIORITY_TEXT TEXT("SDIO_IST_Priority")

#define POLLING_TIMEOUT_TEXT TEXT("PollingTimeout")
#define CARD_DETECT_THREAD_PRIORITY_TEXT TEXT("CardDetect_Thread_Priority")
#define HANDLE_BUSY_FINISH_ON_COMMAND38_TEXT TEXT("HandleBusyFinishOnCommand38")
#define DMA_TRANSFER_TIMEOUT_FACTOR_TEXT TEXT("DmaTransferTimeoutFactor")
#define DMA_TRANSFER_TIMEOUT_CONSTANT_TEXT TEXT("DmaTransferTimeoutConstant")


///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::CSDIOControllerBase - CSDIOControllerBase constructor
//  Input:  pHCContext - hardware context
//  Notes:  
//          
///////////////////////////////////////////////////////////////////////////////
CSDIOControllerBase::CSDIOControllerBase( PSDCARD_HC_CONTEXT pHCContext )
{
    vm_pSDIReg = NULL;
    vm_pIOPreg = NULL;
    vm_pCLKPWR = NULL;
    vm_pDMAreg = NULL;
    m_pDMABuffer = NULL;
    m_dwDMAChannel = 0;

    m_pHCContext = pHCContext;

    m_hResponseReceivedEvent = NULL;
    m_nCardDetectIstThreadPriority = 0;
    m_hCardInsertInterruptEvent = NULL;
    m_hCardInsertInterruptThread = NULL;

    m_nSDIOIstThreadPriority = 0;
    m_hSDIOInterruptEvent = NULL;
    m_hSDIOInterruptThread = NULL;

    m_DMAIstThreadPriority = 0;
    m_hDMAInterruptEvent = NULL;
    m_hDMAInterruptThread = NULL;

    m_bUseDMAForTransfer = FALSE;
    m_bDriverShutdown = FALSE;

    m_bDevicePresent = FALSE;
    m_CurrentState = Idle;
    m_bSendInitClocks = TRUE;
    m_dwLastTypeOfTransfer = SD_READ;

    m_dwNumBytesToTransfer = 0;
    m_dwNumBytesUnaligned = 0;
    m_dwNumBytesExtra = 0;

    m_rgchRegPath[0] = 0;
    m_dwSDIBusWidth = 0;

    m_bReinsertTheCard = FALSE;

    m_fHandleBusyCheckOnCommand38 = FALSE;
    m_dwDMATransferTimeoutFactor = 8;
    m_dwDMATransferTimeoutConstant = 3000;

    m_fCardInTheSlot = FALSE;

    m_fInitialized = FALSE;
    m_pszRegistryPath = NULL;
}

///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::~CSDIOControllerBase - CSDIOControllerBase destructor
//  Input:  
//  Notes:  
//          
///////////////////////////////////////////////////////////////////////////////
CSDIOControllerBase::~CSDIOControllerBase()
{
}

///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::PreDeinit() - PreDeinit routine
//  Input:  
//  Notes:  
//          
///////////////////////////////////////////////////////////////////////////////
void CSDIOControllerBase::PreDeinit()
{
    if( !m_bDriverShutdown )
    {
        Deinitialize();
    }
}

///////////////////////////////////////////////////////////////////////////////
//  CSDIOControllerBase::Initialize - Initializes the the SDIO Host Controller
//  Input:  pHCContext - newly allocated hardware context
//          
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
//          
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::Initialize()
{
    DEBUGMSG (SDCARD_ZONE_INIT,(TEXT("SDHCDInitialize starts")));
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    DWORD         threadID;                         // thread ID
    ULONG fInIOSpace = FALSE;
    PHYSICAL_ADDRESS S3C2410X_IOPORT_Base = {S3C2410X_BASE_REG_PA_IOPORT};
    PHYSICAL_ADDRESS S3C2410X_SDI_Base = {S3C2410X_BASE_REG_PA_SDI};
    PHYSICAL_ADDRESS S3C2410X_CLOCK_POWER_Base = {S3C2410X_BASE_REG_PA_CLOCK_POWER};
    PHYSICAL_ADDRESS S3C2410X_DMA_Base = {S3C2410X_BASE_REG_PA_DMA};

    InitializeCriticalSection(&m_ControllerCriticalSection);
    m_fInitialized = TRUE;

    //----- 1. Map the GPIO registers needed to enable the SDI controller -----

    HANDLE hBusHandle = CreateBusAccessHandle( m_pszRegistryPath );
    if( hBusHandle == NULL )
    {
        DEBUGMSG (1,(TEXT("Failed to create parent bus access handle!")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    if( !BusTransBusAddrToVirtual( hBusHandle, Internal, 0, S3C2410X_IOPORT_Base, sizeof(S3C2410X_IOPORT_REG), &fInIOSpace, (PPVOID)&vm_pIOPreg ) )
    {
        DEBUGMSG (1,(TEXT("GPIO registers not allocated")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    DEBUGMSG (1,(TEXT("GPIO registers mapped to %x"), vm_pIOPreg));

    //----- 2. Map the SDI control registers into the device drivers address space -----
    if( !BusTransBusAddrToVirtual( hBusHandle, Internal, 0, S3C2410X_SDI_Base, sizeof(S3C2410X_SDI_REG), &fInIOSpace, (PPVOID)&vm_pSDIReg ) )
    {
        DEBUGMSG (1,(TEXT("SDI control registers not allocated\n\r")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    DEBUGMSG (1,(TEXT("SDI control registers mapped to %x\n\r"), vm_pSDIReg));

    if( !BusTransBusAddrToVirtual( hBusHandle, Internal, 0, S3C2410X_CLOCK_POWER_Base, sizeof(S3C2410X_CLKPWR_REG), &fInIOSpace, (PPVOID)&vm_pCLKPWR ) )
    {
        DEBUGMSG (1,(TEXT("Clock & Power Management Special Register not allocated\n\r")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    DEBUGMSG (1,(TEXT("Clock & Power Management Special Register mapped to %x\n\r"), vm_pCLKPWR));

    if( m_dwDMAChannel != 0xffffffff )
    {
        //----- 3. Map the DMA control registers used for SDI data transfers -----
        if( !BusTransBusAddrToVirtual( hBusHandle, Internal, 0, S3C2410X_DMA_Base, sizeof(S3C2410X_DMA_REG), &fInIOSpace, (PPVOID)&vm_pDMAreg ) )
        {
            DEBUGMSG (1,(TEXT("DMA Register not allocated\n\r")));
            status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
            goto INIT_ERROR;
        }
        DEBUGMSG (1,(TEXT("DMA Register mapped to %x\n\r"), vm_pDMAreg));

        //----- 4. Allocate a block of memory for DMA transfers -----
        DMA_ADAPTER_OBJECT dmaAdapter;
        dmaAdapter.ObjectSize = sizeof(dmaAdapter);
        dmaAdapter.InterfaceType = Internal;
        dmaAdapter.BusNumber = 0;
        m_pDMABuffer = (PBYTE)HalAllocateCommonBuffer( &dmaAdapter, MAXIMUM_DMA_TRANSFER_SIZE, &m_pDMABufferPhys, FALSE );
        if( m_pDMABuffer == NULL )
        {
            RETAILMSG(1, (TEXT("SHCDriver: - Unable to allocate memory for DMA buffers!\r\n")));
            status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
            goto INIT_ERROR;
        }
    }

    //  Supply the clock to the SDI controller
    MMC_Hardware_PowerUp();

    //----- 6. Configure the GPIO lines for SDI mode and enable the pullup resistor -----
    vm_pIOPreg->GPEUP  &= 0xF83F;
    vm_pIOPreg->GPECON |= 0x2AA800;

    //----- 7. Set the SD/SDI controller to some reasonable default values -----
    SetClockRate(SD_DEFAULT_CARD_ID_CLOCK_RATE);        // 100Khz

    vm_pSDIReg->SDICON     |= LITTLE_ENDIAN_BYTE_ORDER;    // Windows CE is always Little Endian.
    vm_pSDIReg->SDICON     |= RESET_FIFO;                  // Reset the FIFO
    vm_pSDIReg->SDIBSIZE    = BYTES_PER_SECTOR; 
    vm_pSDIReg->SDIDTIMER   = MAX_DATABUSY_TIMEOUT;        // Data/busy timeout

    //----- 8. Setup the thread for detecting card insertion/deletion -----
    m_hCardInsertInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    
    if(NULL == m_hCardInsertInterruptEvent) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    m_bDevicePresent                    = FALSE;

    m_hCardInsertInterruptThread = CreateThread(NULL, 0, 
                                                (LPTHREAD_START_ROUTINE)SD_CardDetectThread,
                                                this, 0, &threadID);
    
    if(NULL == m_hCardInsertInterruptThread) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }


    //----- 9 . Setup an event used for signaling our response thread -----
    m_hResponseReceivedEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    
    if(NULL == m_hResponseReceivedEvent) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }


    //----- 10. Setup the IST for handling SDIO data transfer interrupts -----
    m_hSDIOInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    
    if(NULL == m_hSDIOInterruptEvent) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    // initialize the card insertion interrupt event
    if(!InterruptInitialize (m_dwSDIOSysIntr, m_hSDIOInterruptEvent,
                             NULL, 0)) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    m_hSDIOInterruptThread = CreateThread(NULL, 0,
                                          (LPTHREAD_START_ROUTINE)SD_IOInterruptIstThread,
                                          this, 0, &threadID);
    
    if(NULL == m_hSDIOInterruptThread) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    //----- 11. Setup the interrupt event for handling SDIO DMA data transfers -----
    m_hDMAInterruptEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
    
    if(NULL == m_hDMAInterruptEvent) 
    {
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }

    // initialize the dma transfer interrupt event

⌨️ 快捷键说明

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