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

📄 cspiclass.cpp

📁 BGW211针对freescale的MX21的无线WIFI驱动(WINCE5.0)
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_DISABLE);

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

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

//------------------------------------------------------------------------------
//
//  FUNCTION:       SetSwap
//
//  DESCRIPTION:    This is the function to enable or disbale byte swapping of 
//                  Tx FIFO and RxFIFO data.
//
//  PARAMETERS:     
//          bSwap -
//              To enable or disable byte swapping
//
//  RETURNS:        
//          TRUE -
//              set swap success
//
//          FALSE -
//              Not get the cspi resource lock, set swap fail               
//------------------------------------------------------------------------------
BOOL CspiClass::SetSwap(BOOL bSwap)
{
    if (!IsGetLock)
        return FALSE;

    if (bSwap)
        INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SWAP, CSPI_CONTROLREG_SWAP_SWAPDATA);
    else
        INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SWAP, CSPI_CONTROLREG_SWAP_NOSWAP);

    return TRUE;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       StartDMAExchange
//
//  DESCRIPTION:    This is the function to start the SPI-DMA exchange.
//
//  PARAMETERS:     
//          // bit-mask of the following
//          1 - 
//              TxFIFO Empty DMA Request Enable
//
//          2 -
//              RxFIFO Full DMA Request Enable
//
//          3 - 
//              TxFIFO Half DMA Request Enable
//
//          4 -
//              RxFIFO Half DMA Request Enable
//
//  RETURNS:        
//          TRUE -
//              start DMA exchange success
//
//          FALSE -
//              Not get the cspi resource lock, start DMA exchange fail
//------------------------------------------------------------------------------
BOOL CspiClass::StartDMAExchange(UINT8 mode)
{
    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 (mode & 0x01) // TxFIFO Empty DMA Request Enable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_TEDEN, CSPI_DMA_TEDEN_ENABLE);

    if (mode & 0x02) // RxFIFO Full DMA Request Enable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RFDEN, CSPI_DMA_RFDEN_ENABLE);

    if (mode & 0x04) // TxFIFO Half DMA Request Enable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_THDEN, CSPI_DMA_THDEN_ENABLE);

    if (mode & 0x08) // RxFIFO Half DMA Request Enable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RHDEN, CSPI_DMA_RHDEN_ENABLE);
	
    // start exchange
    INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_XCH, CSPI_CONTROLREG_XCH_EN);
	
    return TRUE;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       StopDMAExchange
//
//  DESCRIPTION:    This is the function to stop the SPI-DMA exchange.
//
//          // bit-mask of the following
//          1 - 
//              TxFIFO Empty DMA Request Disable
//
//          2 -
//              RxFIFO Full DMA Request Disable
//
//          3 - 
//              TxFIFO Half DMA Request Disable
//
//          4 -
//              RxFIFO Half DMA Request Disable
//
//  RETURNS:        
//          TRUE -
//              stop DMA exchange success
//
//          FALSE -
//              Not get the cspi resource lock, stop DMA exchange fail
//------------------------------------------------------------------------------
BOOL CspiClass::StopDMAExchange(UINT8 mode)
{
    if (!IsGetLock)
        return FALSE;

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

    if (mode & 0x01) // TxFIFO Empty DMA Request Disable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_TEDEN, CSPI_DMA_TEDEN_DISABLE);

    if (mode & 0x02) // RxFIFO Full DMA Request Disable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RFDEN, CSPI_DMA_RFDEN_DISABLE);

    if (mode & 0x04) // TxFIFO Half DMA Request Disable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_THDEN, CSPI_DMA_THDEN_DISABLE);

    if (mode & 0x08) // RxFIFO Half DMA Request Disable
        INSREG32BF(&pCspiReg->DMA, CSPI_DMA_RHDEN, CSPI_DMA_RHDEN_DISABLE);
		
    // disable cspi 
    INSREG32BF(&pCspiReg->CONTROLREG, CSPI_CONTROLREG_SPIEN, CSPI_CONTROLREG_SPIEN_DISABLE);
	
    return FALSE;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       ReadRxFifo
//
//  DESCRIPTION:    This is the function to read the top of the 8 × 32 RxFIFO 
//                  received from external CSPI device during data transaction.
//
//  PARAMETERS:     
//          None
//
//  RETURNS:        
//          The data on top of the RXFIFO
//------------------------------------------------------------------------------
UINT32 CspiClass::ReadRxFifo(void)
{
	// assume that the caller that obtained the lock
    // NOTE: It is not a valid value if the RR bit in the Interrupt 
    // control/status register is cleared.
    return (UINT32)(pCspiReg->RXDATA);
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       IsRxFifoDataReady
//
//  DESCRIPTION:    This is the function to check the Data Ready Status of 
//                                  the Rx Fifo.
//
//  PARAMETERS:     
//          None
//
//  RETURNS:        
//          TRUE -
//              At least one data word is ready in Rx FIFO.
//
//          FALSE -
//              RxFIFO is empty.
//------------------------------------------------------------------------------
BOOL CspiClass::IsRxFifoDataReady(void)
{
    // assume that the caller that obtained the lock
    if ((pCspiReg->INT & CSP_BITFMASK(CSPI_INT_RR)) == CSPI_INT_RR_EMPTY)
        return FALSE;

    return TRUE;
}

//------------------------------------------------------------------------------
//
//  FUNCTION:       IsExchangeOngoing
//
//  DESCRIPTION:    This is the function to check the exchange is still ongoing.
//
//  PARAMETERS:     
//          None
//
//  RETURNS:        
//          TRUE -
//              Exchange of data is over.
//
//          FALSE -
//              Exchange of data is still ongoing.
//------------------------------------------------------------------------------
BOOL CspiClass::IsExchangeOngoing(void)
{
    // assume that the caller that obtained the lock
    if ((pCspiReg->CONTROLREG & CSP_BITFMASK(CSPI_CONTROLREG_XCH)) == CSPI_CONTROLREG_XCH_IDLE)
        return FALSE;

    return TRUE;
}

//------------------------------------------------------------------------------
// PRIVATE FUNCTIONS
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
//  FUNCTION:   Initialize
//
//  DESCRIPTION: This function is used to do some initialization.
//              It will only be called once for each cspi set
//
//  PARAMETERS:     
//      None
//
//  RETURNS:        
//      None
//
//------------------------------------------------------------------------------
BOOL CspiClass::Initialize(void)
{
    DWORD dwTransferred;
    DWORD irq;
    HWCLOCK_ID clockId;
    GPIO_IOCTL_CFG  cfg;

    DRV_FUNCTION_ENTRY();

    // Enable CSPI module pins and hw clocks
    if(Id == CSPI1)
    {
        GPIO_SET_IOCTL_STRUCT(cfg, CSPI1);
        clockId = HWCLOCK_ID_CSPI1;
        irq = IRQ_CSPI1;
    }
    else
    {
        GPIO_SET_IOCTL_STRUCT(cfg, CSPI2);
        clockId = HWCLOCK_ID_CSPI2;
        irq = IRQ_CSPI2;
    }
    if(!KernelIoControl(IOCTL_HAL_ENABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to configure GPIO pins for CSPI%d.\r\n"), Id+1));
        return FALSE;
    }
    if(!KernelIoControl(IOCTL_HAL_POWER_HW_CLK, &clockId, sizeof(clockId), NULL, 0, &dwTransferred))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to enable clock for CSPI%d.\r\n"), Id+1));
        return FALSE;
    }
        
    // Request sysintr
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD),
                        &CspiSystemInterrupt[Id], sizeof(DWORD), NULL))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to obtain sysintr value.\r\n")));
        return FALSE;
    }

    if(InterruptInitialize(CspiSystemInterrupt[Id], csEvent[Id], NULL, 0) == FALSE)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("CspiClass: Failed to initialize interrupt sysintr %d (irq %d).\r\n"), 
                    CspiSystemInterrupt[Id], irq));
        return FALSE;
    }

    // Soft reset CSPI module
    INSREG32BF(&pCspiReg->RESET, CSPI_RESET_START, CSPI_RESET_START_SWRESET);

    // Wait for reset done.
    while(pCspiReg->RESET & CSP_BITFVAL(CSPI_RESET_START, CSPI_RESET_START_SWRESET))
        Sleep(0);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Initialize-: csMutex[%d](0x%x)\r\n"), Id, csMutex[Id]));

    return TRUE;
}


//------------------------------------------------------------------------------
//
//  FUNCTION:       CalculateDivRate
//
//  DESCRIPTION:    This is a private function to calculate the data 
//                  rate divider from input frequency.
//
//  PARAMETERS:     
//          dwFrequency -
//              It is the frequency requested.
//
//  RETURNS:        
//          dwDivisor -
//              It's the data rate divisor
//------------------------------------------------------------------------------
UINT32 CspiClass::CalculateDivRate(UINT32 dwFrequency)
{
    DWORD dwtmpRate; // the actual data rate 
    DWORD dwDivisor; // the data rate divisor 
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CalculateDivRate+:dwFrequency(%d)\r\n"), dwFrequency));

    dwtmpRate = BSPDrvlibGetPERCLK2() / dwFrequency;
 
    if (dwtmpRate > CSPI_CONTROLREG_DATARATE_DIV_MAX)
        dwtmpRate = CSPI_CONTROLREG_DATARATE_DIV_MAX;
    else if (dwtmpRate < CSPI_CONTROLREG_DATARATE_DIV_MIN)
        dwtmpRate = CSPI_CONTROLREG_DATARATE_DIV_MIN;

    if(dwtmpRate == 3) {
        dwDivisor = 1;
    } 
    else {      
        for (dwDivisor=0; dwDivisor <= 0x10; dwDivisor++) {
            // For even: 2x2^(n/2), For odd: 3x2^((n-1)/2))
            if((dwDivisor%2) == 0) {
                if( (DWORD)(2 << ((dwDivisor/2))) >= dwtmpRate)
                    break;
            } 
            else {
                if( (DWORD)(3*(2 << (((dwDivisor-1)/2)-1))) >= dwtmpRate)
                    break;
            }
        }
    }
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CalculateDivRate-:dwDivisor(%d) \r\n"), dwDivisor));
    return dwDivisor;

}

//------------------------------------------------------------------------------
//
//  FUNCTION:   ConfigureSSPins
//
//  DESCRIPTION: This function is used to configure required SS pins
//               for a CSPI module.
//
//  PARAMETERS:     
//      PortId -
//          It is the port id.
//      enable -
//          Enable pins if TRUE
//  
//  RETURNS:        
//      TRUE -
//          configuration success
//
//      FALSE -
//          configure chip select pin fail
//          invalid chip select
//      
//------------------------------------------------------------------------------
BOOL CspiClass::ConfigureSSPin(CSPISSPORTID_C PortId, BOOL enable)
{
    GPIO_IOCTL_CFG  cfg;
    DWORD dwTransferred;
    BOOL status;
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("ConfigureSSPin+\r\n")));

    if(PortId > CSPISSMAX)
        return FALSE;

    switch(Id)
    { 
        case CSPI1:
            switch(PortId)
            {
                case CSPISS0:
                    GPIO_SET_IOCTL_STRUCT(cfg, CSPI1_SS0);
                    break;
                
                case CSPISS1:
                    GPIO_SET_IOCTL_STRUCT(cfg, CSPI1_SS1);
                    break;
                
                case CSPISS2:
                    GPIO_SET_IOCTL_STRUCT(cfg, CSPI1_SS2);
                    break;

                default:
                    DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: should not reach here!\r\n")));
                    return FALSE;
            }
        break;
        
        case CSPI2:
            switch(PortId)
            {
                case CSPISS0:
                    GPIO_SET_IOCTL_STRUCT(cfg, CSPI2_SS0);
                    break;
                
                case CSPISS1:
                    GPIO_SET_IOCTL_STRUCT(cfg, CSPI2_SS1);
                    break;
                
                case CSPISS2:
                    GPIO_SET_IOCTL_STRUCT(cfg, CSPI2_SS2);
                    break;

                default:
                    DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: should not reach here!\r\n")));
                    return FALSE;
            }
            break;

        default:
            DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: should not reach here!\r\n")));
            return FALSE;
    }   
    if(enable)
        status = KernelIoControl(IOCTL_HAL_ENABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred);
    else
        status = KernelIoControl(IOCTL_HAL_DISABLE_GPIO, &cfg, sizeof(cfg), NULL, 0, &dwTransferred);

    if(status != TRUE)
        DEBUGMSG(ZONE_ERROR, (TEXT("ConfigureSSPin: failed!\r\n")));
    else
        DEBUGMSG(ZONE_INFO, (TEXT("ConfigureSSPin success!\r\n")));
        
    DEBUGMSG(ZONE_FUNCTION, (TEXT("ConfigureSSPin-\r\n")));

    return status;
}
//------------------------------------------------------------------------------
// END OF FILE
//------------------------------------------------------------------------------

⌨️ 快捷键说明

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