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

📄 sdiocontrollerbase.cpp

📁 SBC2410 WinCE 5.0 BSP.绝大多数驱动已经调通。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

// 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 <s2410.h>
#include <oalintr.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                            (48000000)  // 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_nControllerIstThreadPriority = 0;
    m_hControllerInterruptEvent = NULL;
    m_hControllerInterruptThread = 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;
}

///////////////////////////////////////////////////////////////////////////////
//  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")));
    RETAILMSG (1,(TEXT("SDHCDInitialize starts")));
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;   // intermediate status
    DWORD         threadID;                         // thread ID

    InitializeCriticalSection(&m_ControllerCriticalSection);

    //----- 1. Map the GPIO registers needed to enable the SDI controller -----
    vm_pIOPreg = (IOPreg*)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
    if (vm_pIOPreg == NULL) 
    {
        RETAILMSG (1,(TEXT("GPIO registers not allocated")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    if (!VirtualCopy((PVOID)vm_pIOPreg, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE)) {
        RETAILMSG (1,(TEXT("GPIO registers not mapped")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    RETAILMSG (1,(TEXT("GPIO registers mapped to %x"), vm_pIOPreg));

    //----- 2. Map the SDI control registers into the device drivers address space -----
    vm_pSDIReg = (MMCreg*)VirtualAlloc(0, sizeof(MMCreg), MEM_RESERVE, PAGE_NOACCESS);
    if (vm_pSDIReg == NULL) 
    {
        RETAILMSG (1,(TEXT("SDI control registers not allocated\n\r")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    if (!VirtualCopy((PVOID)vm_pSDIReg, (PVOID)(MMC_BACE), sizeof(MMCreg), PAGE_READWRITE | PAGE_NOCACHE)) {
        RETAILMSG (1,(TEXT("SDI control registers not mapped\n\r")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    RETAILMSG (1,(TEXT("SDI control registers mapped to %x\n\r"), vm_pSDIReg));

    vm_pCLKPWR = (CLKPWRreg*)VirtualAlloc(0, sizeof(CLKPWRreg), MEM_RESERVE, PAGE_NOACCESS);
    if (vm_pCLKPWR == NULL) 
    {
        RETAILMSG (1,(TEXT("Clock & Power Management Special Register not allocated\n\r")));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto INIT_ERROR;
    }
    if (!VirtualCopy((PVOID)vm_pCLKPWR, (PVOID)(CLKPWR_BASE), sizeof(CLKPWRreg), PAGE_READWRITE | PAGE_NOCACHE)) {
        RETAILMSG (1,(TEXT("Clock & Power Management Special Register not mapped\n\r")));
        goto INIT_ERROR;
    }
    RETAILMSG (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 -----
        vm_pDMAreg = (DMAreg*)VirtualAlloc(0, sizeof(DMAreg), MEM_RESERVE, PAGE_NOACCESS);
        if (vm_pDMAreg == NULL) 
        {
            RETAILMSG (1,(TEXT("DMA Register not allocated\n\r")));
            status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
            goto INIT_ERROR;
        }
        if (!VirtualCopy((PVOID)vm_pDMAreg, (PVOID)(DMA_BASE), sizeof(DMAreg), PAGE_READWRITE | PAGE_NOCACHE)) {
            RETAILMSG (1,(TEXT("DMA Register not mapped\n\r")));
            status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
            goto INIT_ERROR;
        }
        RETAILMSG (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->rGPEUP  &= 0xF83F;
    vm_pIOPreg->rGPECON |= 0x2AA800;

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

    vm_pSDIReg->rSDICON     |= LITTLE_ENDIAN_BYTE_ORDER;    // Windows CE is always Little Endian.
    vm_pSDIReg->rSDICON     |= RESET_FIFO;                  // Reset the FIFO
    vm_pSDIReg->rSDIBSIZE    = BYTES_PER_SECTOR; 
    vm_pSDIReg->rSDIDTIMER   = 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;
    }

⌨️ 快捷键说明

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