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

📄 irdahw.cpp

📁 收集到的orion_ep93xx_wince_bsp_1-3-507红外收发驱动源码,未作测试
💻 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 + -