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

📄 irdahw.cpp

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//**********************************************************************

//                                                                      

// Filename: irdahw.cpp

//                                                                      

// Description: Controls the IRDA hardware.

//

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF

// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO

// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A

// PARTICULAR PURPOSE.

// Copyright(c) Cirrus Logic Corporation 2001, All Rights Reserved                       

//                                                                      

//**********************************************************************



#include <windows.h>

extern "C"

{

    #include <ndis.h>

    #include <ntddndis.h>

}    

#include <linklist.h>

#include <ceddk.h>

#include <hwdefs.h>

#include <clocks.h>

#include <nkintr.h>

#include <oalintr.h>

#include "settings.h"

#include "debugzone.h"

#include "recvlist.h"

#include "sendlist.h"

#include "sirstate.h"

#include "irdahw.h"

#include "miniport.h"

#include "irmacutl.h"



//

// v_rgSupportedBaudRates - Maps speed masks to real value.

// NOTE: The entries in the table must align with the enum BAUDRATES.

//

const BAUDRATE_INFO v_rgSupportedBaudRates[] =

{

//   bps        Serial bit mask

//   ------     ---------------

    {2400,      BAUD_2400    , TEXT("2400   "), 0 },

    {9600,      BAUD_9600    , TEXT("9600   "), 1 },

    {19200,     BAUD_19200   , TEXT("19200  "), 2 },

    {38400,     BAUD_38400   , TEXT("38400  "), 4 },

    {57600,     BAUD_57600   , TEXT("57600  "), 12 },

    {115200,    BAUD_115200  , TEXT("115200 "), 24 },

//  {576000,    BAUD_USER       },

//  {1152000,   BAUD_USER       },

//  {4000000,   BAUD_USER       }

};



//****************************************************************************

// IrdaHW::IrdaHW

//****************************************************************************

// Constructor for IrdaHW.

// 

//

IrdaHW::IrdaHW():

        m_SirState(),

        m_bSirExiting(FALSE),

        eIrdaMode(MODE_SIR),

        m_ulBaudRate(9600),

        m_fMinTATRequired(TRUE),

        m_hSirEvent(0),

        m_hSirInterruptThread(0),

        m_pSIRTransmitNDisPacket(0),

        m_pSendBuf(0),              

        m_ulSendCurPos(0),

        m_ulSendBufSize(0),

        m_ulPacketsTxDropped(0),

        m_ulPacketsTx(0)

{        

}







//****************************************************************************

// IrdaHW::InitializeIRDA

//****************************************************************************

// Initializes the IRDA interface.

// 

//

NDIS_STATUS IrdaHW::InitializeIrdaHW()

{



    DEBUGMSG(ZONE_IRDAHW, (TEXT("+IrdaHW::InitializeIrdaHW")));



    NDIS_STATUS     ulStatus;

    BOOL            b;

    

    ulStatus = SetHWBaudRate(9600);



    //

    // Create the Sir Event.

    //    

    if(ulStatus == NDIS_STATUS_SUCCESS)

    {

        m_hSirEvent = CreateEvent( NULL, FALSE, FALSE, NULL);

        ulStatus = m_hSirEvent? NDIS_STATUS_SUCCESS: NDIS_STATUS_RESOURCES;

    }        

    

    //

    // Hook the SIR interrupt.

    //

    if(ulStatus == NDIS_STATUS_SUCCESS)

    {

        b=InterruptInitialize(SYSINTR_UART2, m_hSirEvent, NULL, 0);

        ASSERT(b);

        ulStatus = b? NDIS_STATUS_SUCCESS: NDIS_STATUS_RESOURCES;

    }        



    //

    // Create the SIR interrupt thread.

    //

    if(ulStatus == NDIS_STATUS_SUCCESS)

    {

        m_hSirInterruptThread  = CreateThread((LPSECURITY_ATTRIBUTES)NULL,

                                              0,

                                              (LPTHREAD_START_ROUTINE)SIRInterruptHandler,

                                              (PVOID)this,

                                              0,

                                              NULL);

        ASSERT( m_hSirInterruptThread);

        ulStatus = m_hSirInterruptThread? NDIS_STATUS_SUCCESS : NDIS_STATUS_RESOURCES;

    }



    if( ulStatus == NDIS_STATUS_SUCCESS)

    {

        //

        // Set the thread priority for the SIR Interrupt handler.

        // 148 should be fine.

        //

        b = CeSetThreadPriority( m_hSirInterruptThread, 148);

        ASSERT( b);

        ulStatus = b? NDIS_STATUS_SUCCESS : NDIS_STATUS_RESOURCES;

    }        





    //

    // Allocate memory for the buffer.

    //

    if(ulStatus == NDIS_STATUS_SUCCESS)

    {

        m_pSendBuf = (PUCHAR) LocalAlloc

        (

            LMEM_FIXED | LMEM_ZEROINIT, 

            MAX_IRDA_DATA_SIZE

        );

        ASSERT(m_pSendBuf);

    }        

                                              

    

    DEBUGMSG(ZONE_IRDAHW, (TEXT("-IrdaHW::InitializeIrdaHW")));

    return(ulStatus);

}



//****************************************************************************

// IrdaHW::~IrdaHW

//****************************************************************************

// Destructor

// 

//

IrdaHW::~IrdaHW()

{

    DEBUGMSG(ZONE_IRDAHW, (TEXT("+IrdaHW::~IrdaHW")));

    //

    // Delete the Send buffer memory.

    //

    if(m_pSendBuf)

    {

        LocalFree(m_pSendBuf);

    }

    

    //

    // Delete the event

    //

    if(m_hSirEvent)

    {

        CloseHandle(m_hSirEvent);

    }



    DEBUGMSG(ZONE_IRDAHW, (TEXT("-IrdaHW::~IrdaHW")));

}



//****************************************************************************

// IrdaHW::BaudRateSupported

//****************************************************************************

// Check to see if the baud rate is supported.

// 

//

NDIS_STATUS IrdaHW::BaudRateSupported( ULONG ulBaudRate)

{

    DEBUGMSG(ZONE_IRDAHW, (TEXT("+IrdaHW::BaudRateSupported")));



    ULONG   ulStatus = NDIS_STATUS_FAILURE;

    ULONG   ulCount;

    

    //

    // Check to see if it is one of the baud rates

    //

    for(ulCount =0; ulCount <= NUM_BAUDRATES;  ulCount++)

    {

        if(v_rgSupportedBaudRates[ulCount].dwBPS == ulBaudRate)

        {

            ulStatus        = NDIS_STATUS_SUCCESS;

            break;

        }

    }

    

    DEBUGMSG(ZONE_IRDAHW, (TEXT("-IrdaHW::BaudRateSupported")));

    return (ulStatus);

}



//****************************************************************************

// IrdaHW::SetBaudRate

//****************************************************************************

// Sets the IRDA baud rate for SIR, MIR and FIR.

// 

//

NDIS_STATUS IrdaHW::SetHWBaudRate( ULONG ulBaudRate)

{



    DEBUGMSG(ZONE_IRDAHW, (TEXT("+IrdaHW::SetHWBaudRate")));

//    ULONG   ulCount;

    ULONG   ulStatus = NDIS_STATUS_SUCCESS;

    ULONG   ulDivisor;

        

    //

    // Check to make sure that the 

    //

    ulStatus = BaudRateSupported(ulBaudRate);

    

    if(ulStatus ==  NDIS_STATUS_SUCCESS)

    {

    

        if(ulBaudRate <= 115200)

        {

            //

            // The Transmit and recieve bits in the IRCON register 

            // must be disabled before disable IRDA in the IRENABLE

            // register.

            //

            *IRDA_IRCON         &= ~(IRCON_TXE | IRCON_RXE);



            //

            // Disable IRDA.

            //

            *IRDA_IRENABLE     = IRENABLE_DISABLE;

          

            //

            // Disable the UART 2.

            //

            *UART2_CR           = 0;



            //

            // Calculate the divisor.

            //

            ulDivisor     = (UART_CLOCK / (16 * ulBaudRate)) - 1;



            //

            // Program the baud rate into the baud rate registers.

            //

            *UART2_LCR_M        = (ulDivisor >> 8) & 0x0FF;

            *UART2_LCR_L        = (ulDivisor & 0x0FF);

                        

            //

            // The documentation is not very clear on this register.

            // It says that this is a divisor of the UART clock rate.

            // The divided frequency should be between 1.42 and 2.12 Mhz

            //

            // If this register is not programmed, UART recieve will not

            // work.

            //

            *UART2_ILPR         = 2;

                                                          

            //

            // Enable Uart for 8bits No parity, one stop bit.

            //                 

            *UART2_LCR_H        = LCR_H_DATABITS_8 | LCR_H_FIFO_ENABLE;



            //

            // Enable SIR in the UART 2 register.  Also Enable

            // the interrupts.

            //

            *UART2_CR           =  CR_UARTE | CR_SIREN | CR_RIE ;



            //

            // Enable SIR.

            //

            *IRDA_IRENABLE      = IRENABLE_SIR;  

            



            //

            // The Transmit and recieve bits in the IRCON register 

            // must be enabled after the IRDA is enabled in the IRENABLE

            // register.

            //

            *IRDA_IRCON         |= IRCON_TXE | IRCON_RXE;

            

            //

            // Set the mode to SIR.

            //

            eIrdaMode           = MODE_SIR;

        }

        //

        // Check to see if it is MIR baud rate.

        //

        else if( ulBaudRate == 576000 || ulBaudRate == 1152000)

        {

            //

            // Disable IRDA.

            //

            *IRDA_IRENABLE     = IRENABLE_DISABLE;

          

            //

            // Disable the UART 2.

            //

            *UART2_CR           = 0;

            *IRDA_IRCON         = 0;  //~(IRCON_TXE | IRCON_RXE);

            

            //

            // Enable MIR.

            //

            *IRDA_IRENABLE      = IRENABLE_MIR;    

            

            //

            // Check to see which baud rate it is.

            //

            if( ulBaudRate == 1152000)

            {

                *IRDA_IRCON     = IRCON_MIR_FAST;

            }

            else

            {

                *IRDA_IRCON     = 0;

            }

            

            //

            // Set the mode to MIR.

            //

            eIrdaMode           = MODE_MIR;

        }

        

        //

        // Check to see if it is FIR baud rate.

        //

        else if( ulBaudRate == 4000000)

        {

            //

            // Disable IRDA.

            //

            *IRDA_IRENABLE     = IRENABLE_DISABLE;

          

            //

            // Disable the UART 2.

            //

            *UART2_CR           = 0;

            *IRDA_IRCON         = ~(IRCON_TXE | IRCON_RXE);

            

            //

            // Enable MIR.

            //

            *IRDA_IRENABLE      = IRENABLE_FIR;    



            //

            // Set the mode to FIR.

            //

            eIrdaMode           = MODE_FIR;

        } 

        else

        {

            ulStatus        = NDIS_STATUS_FAILURE;

        }

    }                    



    //

    // Change the baud rate

    //    

    if(ulStatus ==  NDIS_STATUS_SUCCESS)

    {

        m_ulBaudRate = ulBaudRate;

    }        



    DEBUGMSG(ZONE_IRDAHW, (TEXT("-IrdaHW::SetHWBaudRate")));

    return(ulStatus);

}





//****************************************************************************

//  IrdaHW::IirTransmit

//****************************************************************************

// Only have to change if we are not in SIR mode.

// 

//

void  IrdaHW::IirTransmit( )

{

    ULONG       ulIRCON;

    

    if(eIrdaMode != MODE_SIR)

    {

        ulIRCON     = *IRDA_IRCON;

        *IRDA_IRCON = (ulIRCON & IRCON_MIR_FAST) | IRCON_TXE;

    }

}





//****************************************************************************

// IrdaHW::IirRecieve

//****************************************************************************

// Only have to change if we are not in SIR mode.

// 

//

void IrdaHW::IirRecieve()

{

    ULONG    ulIRCON;

    if(eIrdaMode != MODE_SIR)

    {

        ulIRCON     = *IRDA_IRCON;

        *IRDA_IRCON = (ulIRCON & IRCON_MIR_FAST) | IRCON_RXE;

    }

}





//****************************************************************************

// IrdaHW::ClearStatistics

//****************************************************************************

// Clears the statitistics.

// 

//

void  IrdaHW::ClearStatistics()

{

    //

    // Clear the statistics.

    //

    m_SirState.ClearStats();

    m_ulPacketsTxDropped    = 0;

    m_ulPacketsTx           = 0;



}







#define MAX_TX_WAIT 400



//****************************************************************************

// SIRInterruptHandler

//****************************************************************************

// SIR Interrupt Handler.  

//

// Performs the following:

//

// 1.  Checks to see if we are exiting from the interrupt handler.

⌨️ 快捷键说明

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