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

📄 cspiclass.cpp

📁 BGW211针对freescale的MX21的无线WIFI驱动(WINCE5.0)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved
//  THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
//  BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
//  FREESCALE SEMICONDUCTOR, INC.
//
//------------------------------------------------------------------------------
//
//  Module: CspiClass.cpp
//
//  Interface to CSPI services.
//
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// INCLUDE FILES  
//------------------------------------------------------------------------------
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include "csp.h"
#include "cspddk.h"

//------------------------------------------------------------------------------
// GLOBAL DEFINITIONS  
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// GLOBAL OR STATIC VARIABLES  
//------------------------------------------------------------------------------

// this global counter records how many modules are using the cspi
static UINT8 CspiOpenedCounter[] = {0, 0};
static UINT8 CspiSSInit[2][CSPISSMAX] = { 0 };

// set the default CSPI status
static CSPIAVAILSTATUS_C CspiAvailableStatus[] = {CSPIAVAILABLE, CSPIAVAILABLE};

static DWORD CspiSystemInterrupt[] = { SYSINTR_NOP, SYSINTR_NOP };

//------------------------------------------------------------------------------
// STATIC FUNCTION PROTOTYPES  
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// EXPORTED FUNCTIONS
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
//  FUNCTION:   CspiClass
//
//  DESCRIPTION: This is the constructor of the CSPI class. It memory 
//              maps the CSPI memory space using VirtualAlloc and 
//              VirtualCopy functions.
//
//  PARAMETERS:     
//      CspiId - 
//          The id of cspi set requested in cspiId_c format.
//      status - 
//          returns TRUE/FALSE depending on whether initialzation i
//          is successful. If FALSE, the user should delete the class
//          to release resources even if the class instance is created.
//
//  RETURNS:        
//      None
//
//------------------------------------------------------------------------------
CspiClass::CspiClass(CSPIID_C CspiId)
{
    PHYSICAL_ADDRESS phyAddr;
    
	DRV_FUNCTION_ENTRY();
    // Check if the CSPI selected by user is valid or not
    if ((CspiId != CSPI1) && (CspiId != CSPI2)){
    	DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Input id error!\r\n")));
        return;
    }
    
    // Check if the CSPI selected by user is available or not
    if (CspiAvailableStatus[CspiId] == CSPINOTAVAILABLE){
        DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Request cspi not available!\r\n")));
        return;
    }

    Id = CspiId; // save the id
    
    switch (CspiId)
    {
        case CSPI1:
            phyAddr.QuadPart = CSP_BASE_REG_PA_CSPI1;
            break;

        case CSPI2:
            phyAddr.QuadPart = CSP_BASE_REG_PA_CSPI2;
            break;

        default:
            DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: cspi id error!\r\n")));
            return;     // invalid id, should not come here
    }
    
    pCspiReg = (CSP_CSPI_REGS *)MmMapIoSpace(phyAddr, sizeof(CSP_CSPI_REGS), FALSE);
    if (pCspiReg == NULL)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: CSPI%d NULL pointer!\r\n"), CspiId+1));        
        return;
    }
    
    IsGetLock = FALSE;
    
    if(Id == CSPI1)
    {
        csMutex[Id]  = CreateMutex (
                            NULL,                       // No security descriptor
                            FALSE,                      // Mutex object not owned
                            TEXT("cspi1Mutex")); // Object name

        csEvent[Id] = CreateEvent(NULL, FALSE, FALSE, L"cspi1Event");

    }
    else
    {
        csMutex[Id]  = CreateMutex (
                            NULL,                       // No security descriptor
                            FALSE,                      // Mutex object not owned
                            TEXT("cspi2Mutex")); // Object name

        csEvent[Id] = CreateEvent(NULL, FALSE, FALSE, L"cspi2Event");

    }

    if (CspiOpenedCounter[Id]==0){ 
        Initialize();
        CspiOpenedCounter[Id]=1;
    }
    else // if already inited, increase the counter
        CspiOpenedCounter[Id]++;
	
    DRV_FUNCTION_EXIT();
    return;
}


//------------------------------------------------------------------------------
//
//  FUNCTION:   ~CspiClass
//
//  DESCRIPTION: This is the destructor of the CSPI class. It frees 
//              the reserved memory space using VirtualFree function 
//              and free other resource used. It will also check the  
//              CspiOpenedCounter, if no other module is using cspi, 
//              power down the module. 
//
//  PARAMETERS:     
//          None
//
//  RETURNS:        
//          None
//------------------------------------------------------------------------------
CspiClass::~CspiClass(void)
{
    DRV_FUNCTION_ENTRY();

    CspiOpenedCounter[Id]--;
    if (CspiOpenedCounter[Id]==0)
    {

        InterruptDisable(CspiSystemInterrupt[Id]);

        // Release sysintr
        if (!KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &CspiSystemInterrupt[Id], sizeof(DWORD), NULL, 0, NULL))
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Failed to release sysintr.\r\n")));

        GPIO_IOCTL_CFG  cfg;
        HWCLOCK_ID clockId;
        DWORD dwTransferred;

        // Disable CSPI module pins and hw clocks
        if(Id == CSPI1)
        {
            GPIO_SET_IOCTL_STRUCT(cfg, CSPI1);
            clockId = HWCLOCK_ID_CSPI1;
        }
        else
        {
            GPIO_SET_IOCTL_STRUCT(cfg, CSPI2);
            clockId = HWCLOCK_ID_CSPI2;
        }
        KernelIoControl(IOCTL_HAL_DISABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred);
        KernelIoControl(IOCTL_HAL_SHUTDOWN_HW_CLK, &clockId, sizeof(clockId), NULL, 0, &dwTransferred);

        //CSPISSPORTID_C PortId;
		unsigned int PortId;
        for(PortId = CSPISS0; PortId < CSPISSMAX; PortId++)
        {
            if(CspiSSInit[Id][PortId] != 0)
            {
                ConfigureSSPin((CSPISSPORTID_C)PortId, FALSE);
                CspiSSInit[Id][PortId] = 0;
            }
        }
    }

    // Delete mutex and interrupt event    
    if(csMutex[Id])
        CloseHandle(csMutex[Id]);

    if(csEvent[Id])
        CloseHandle(csEvent[Id]);
        
    if (pCspiReg != NULL) 
    {
        MmUnmapIoSpace((void *)pCspiReg, 0);
        pCspiReg = NULL;
    }
   DRV_FUNCTION_EXIT();
    return;
}



//------------------------------------------------------------------------------
//
//  FUNCTION:   Configure
//
//  DESCRIPTION: This function is used to configure the cspi register.
//
//  PARAMETERS:     
//      pData -
//          It is the pointer including cspi configure data.
//
//  RETURNS:        
//      TRUE -
//          Success to configure 
//
//      FALSE -
//          Not get the cspi resource lock, fail to configure
//
//------------------------------------------------------------------------------
BOOL CspiClass::Configure(PCSPICONFIGDATA_T pData)
{
    UINT tempRate = 0;
    UINT tempRdyCtl = 0;
    
    DRV_FUNCTION_ENTRY();

    if (!IsGetLock)
        return FALSE;
        
    if (pData->CSPIBITLENGTH < 1)
        pData->CSPIBITLENGTH = 1;
    else if (pData->CSPIBITLENGTH > 32)
        pData->CSPIBITLENGTH = 32;
    
    if (pData->CSPIMODE == CSPI_CONTROLREG_MODE_MASTER)
            tempRate = CalculateDivRate(pData->CSPIFREQUENCY);
        
    // set control register
    if (tempRate == CSPI_CONTROLREG_DATARATE_DIV3)
        OUTREG32(&pCspiReg->CONTROLREG,
            CSP_BITFVAL(CSPI_CONTROLREG_MODE, pData->CSPIMODE) |
            CSP_BITFVAL(CSPI_CONTROLREG_BITCOUNT, pData->CSPIBITLENGTH-1) |
            CSP_BITFVAL(CSPI_CONTROLREG_DATARATE, tempRate ) |
            CSP_BITFVAL(CSPI_CONTROLREG_DRCTL, pData->CSPIDRCTL) |
            CSP_BITFVAL(CSPI_CONTROLREG_POL, pData->CSPIPOL) |
            CSP_BITFVAL(CSPI_CONTROLREG_PHA, pData->CSPIPHA) |
            CSP_BITFVAL(CSPI_CONTROLREG_SSCTL, pData->CSPISSCTL) |
            CSP_BITFVAL(CSPI_CONTROLREG_SSPOL, pData->CSPISSPOL) |
            CSP_BITFVAL(CSPI_CONTROLREG_XCH, CSPI_CONTROLREG_XCH_IDLE) |
            CSP_BITFVAL(CSPI_CONTROLREG_SDHC_SPIEN, CSPI_CONTROLREG_SDHC_SPIEN_ENABLE) |
            CSP_BITFVAL(CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_DISABLE));
    else
        OUTREG32(&pCspiReg->CONTROLREG,
            CSP_BITFVAL(CSPI_CONTROLREG_MODE, pData->CSPIMODE) |
            CSP_BITFVAL(CSPI_CONTROLREG_BITCOUNT, pData->CSPIBITLENGTH-1) |
            CSP_BITFVAL(CSPI_CONTROLREG_DATARATE, tempRate ) |
            CSP_BITFVAL(CSPI_CONTROLREG_DRCTL, pData->CSPIDRCTL) |
            CSP_BITFVAL(CSPI_CONTROLREG_POL, pData->CSPIPOL) |
            CSP_BITFVAL(CSPI_CONTROLREG_PHA, pData->CSPIPHA) |
            CSP_BITFVAL(CSPI_CONTROLREG_SSCTL, pData->CSPISSCTL) |
            CSP_BITFVAL(CSPI_CONTROLREG_SSPOL, pData->CSPISSPOL) |
            CSP_BITFVAL(CSPI_CONTROLREG_XCH, CSPI_CONTROLREG_XCH_IDLE) |
            CSP_BITFVAL(CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_DISABLE));
        
    DRV_FUNCTION_EXIT();
    return TRUE;                   
}

//------------------------------------------------------------------------------
//
//  FUNCTION:   ChipSelect
//
//  DESCRIPTION: This function is used to select the cspi port.
//
//  PARAMETERS:     
//      PortId -
//          It is the port id.
//  
//  RETURNS:        
//      TRUE -
//          Chip select success
//
//      FALSE -
//          Not get the cspi resource lock, chip select fail
//          configure chip select pin fail
//          invalid chip select
//      
//------------------------------------------------------------------------------
BOOL CspiClass::ChipSelect(CSPISSPORTID_C PortId)
{
    DRV_FUNCTION_ENTRY();

    if (!IsGetLock || PortId >= CSPISSMAX)
        return FALSE;
    
    // Enable SS pins first time if required.
    if(CspiSSInit[Id][PortId] == 0)
    {
        if(ConfigureSSPin(PortId, TRUE) != TRUE)
            return FALSE;

        CspiSSInit[Id][PortId] = 1;
    }

    INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_CS, PortId);
 
    DRV_FUNCTION_EXIT();
    return TRUE;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:   CspiHwResourceLock
//
//  DESCRIPTION: This is the function to lock cspi hardware resource. 
//
//  PARAMETERS:     
//          TRUE -
//              try to lock the cspi hardware resource
//
//          FALSE -
//              release the hardware resource
//
//  RETURNS:        
//          None
//------------------------------------------------------------------------------
void CspiClass::CspiHwResourceLock(BOOL bLock)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CspiHwResourceLock+: bLock(%c)\r\n"), bLock? 'T':'F'));

    if(bLock)
    {
        WaitForSingleObject (csMutex[Id], INFINITE); 
        IsGetLock = TRUE;
    }
    else
    {
        ReleaseMutex(csMutex[Id]);
        IsGetLock = FALSE;
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CspiHwResourceLock-\r\n")));
    return;
}


//------------------------------------------------------------------------------
//
//  FUNCTION:       Exchange
//
//  DESCRIPTION:    This is the function to exchange data.
//
//  PARAMETERS:     
//          pTxBuf -
//              Pointer to the buffer which store the transmite data
//
//          pRxBuf -
//              Pointer to the buffer which store the receive data
//
//          NumOfWords -
//              Number of words to be sent
//
//  RETURNS:        
//          NumOfWords -
//              The number of words sent
//          
//          FALSE -
//              Not get the cspi resource lock, exchange fail               
//   
//------------------------------------------------------------------------------
UINT8 CspiClass::Exchange (UINT32 *pTxBuf, UINT32 *pRxBuf, UINT8 NumOfWords)
{
    UINT i;
 
    DEBUGMSG(ZONE_FUNCTION, (TEXT("Exchange+: pTxBuf(0x%x) pRxBuf(0x%x) NumOfWords(%d)\r\n"), pTxBuf, pRxBuf, NumOfWords));

#ifdef DEBUG
    for(i = 0; i < NumOfWords; i++)
        DEBUGMSG(ZONE_INFO, (TEXT("TxBuf[%d]:(0x%08x)\r\n"), i, pTxBuf[i]));
#endif

    if (!IsGetLock)
        return FALSE;
    
    // make sure not doing exchange
    INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_XCH, CSPI_CONTROLREG_XCH_IDLE);

    // enable cspi
    INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_ENABLE);

    if (NumOfWords > CSPI_FIFO_SLOT_MAX)
        NumOfWords = CSPI_FIFO_SLOT_MAX;

    for (i = 0; i<NumOfWords; i++)
        pCspiReg->TXDATA = *pTxBuf++;
    
    // Enable TSHFEEN
    INSREG32BF(&pCspiReg->INT, CSPI_INT_TSHFEEN, CSPI_INT_TSHFEEN_ENABLE);

    // start exchange
    INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_XCH, CSPI_CONTROLREG_XCH_EN);

    // Block while waiting for transfer done if transfer is not yet done
    // to avoid unneccessary thread context switches.
    if((pCspiReg->INT & CSP_BITFMASK(CSPI_INT_TSHFE)) == 0) 
        WaitForSingleObject(csEvent[Id], INFINITE);

    // Disable TSHFEEN
    INSREG32BF(&pCspiReg->INT, CSPI_INT_TSHFEEN, CSPI_INT_TSHFEEN_DISABLE);

    InterruptDone(CspiSystemInterrupt[Id]);
    
    // wait until the exchange is finsihed
    while ((pCspiReg->CONTROLREG & CSP_BITFMASK(CSPI_CONTROLREG_XCH)) != CSPI_CONTROLREG_XCH_IDLE)
        Sleep(0);

    for (i=0; i<NumOfWords; i++)
        *pRxBuf++ = pCspiReg->RXDATA;

    // disable cspi 

⌨️ 快捷键说明

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