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

📄 irdahw.cpp

📁 收集到的orion_ep93xx_wince_bsp_1-3-507红外收发驱动源码,未作测试
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 2.  If we are in Send mode, send bytes and discard bytes received.
// 3.  If we are in recieve mode, recieve bytes and give the bytes
//     back to the OS.
//
DWORD WINAPI SIRInterruptHandler(LPVOID Handle)
{
    DEBUGMSG(ZONE_IRDAHW, (TEXT("+SIRInterruptHandler")));

    DWORD                   ulUART2FLAGS;
    UCHAR                   ucRecievedByte;
    IRMiniport              *pIrMiniport = (IRMiniport *)Handle;
    PRX_BUFFER              pRxBuf;

    
    //
    // Get the first free item.
    //
    pRxBuf = pIrMiniport->m_ReceivePacketList.GetFree();
    
    //
    // Set the next buffer location.
    //
    pIrMiniport->m_SirState.SetNextBuffer(pRxBuf);        
    
    
    while(1)
    {
        //
        // Wait until the interrupt for the serial port occurs.
        //                        
        WaitForSingleObject(pIrMiniport->m_hSirEvent, INFINITE);
        
        //
        // Set the Media busy flag.
        //
        pIrMiniport->m_fMediaBusy = TRUE;
        
        //
        // Check if we are exiting the loop.
        //
        if(pIrMiniport->m_bSirExiting)
        {
            break;
        }
        
        
        //
        // If we have bytes to send and the fifo is not full,
        // then fill up the fifo.
        //
        while(pIrMiniport->m_pSIRTransmitNDisPacket && !(*UART2_FR & FR_TXFF))
        {
            //                
            // Send the next byte out.
            //
            *UART2_DR = pIrMiniport->m_pSendBuf[pIrMiniport->m_ulSendCurPos++];
            
            //
            // Check to see if the packet has been completely transmitted.
            //
            if(pIrMiniport->m_ulSendCurPos == pIrMiniport->m_ulSendBufSize)
            {            
            
                //
                // This is to protect the transmit list and when baud
                // rates are changed.
                //
                EnterCriticalSection( &pIrMiniport->m_ListCriticalSection);

                //
                // Send the packet back to the OS.
                //
                CompleteSentPacket
                (
                    pIrMiniport->m_pSIRTransmitNDisPacket,
                    pIrMiniport->m_hNdisAdapter,
                    NDIS_STATUS_SUCCESS
                );                

                //
                // Really, All I need to zero out is the first item.
                // Lets Zero out all the items just in case.
                //
                pIrMiniport->m_pSIRTransmitNDisPacket   = 0;
                pIrMiniport->m_ulSendCurPos             = 0;                  
                
                //
                // Incremented the transmited packet count.
                //
                pIrMiniport->m_ulPacketsTx++;
                DEBUGMSG(ZONE_SEND,
                         (TEXT("Tx: sent %d byte IR packet.\r\n"),
                          pIrMiniport->m_ulSendBufSize)
                        );
                        
                //
                // We need to change the baud rate at the end of 
                // a frame.
                //
                if(pIrMiniport->m_ulNextBaudRate)
                {
                    pIrMiniport->SetHWBaudRate( pIrMiniport->m_ulNextBaudRate);
                    pIrMiniport->m_fMinTATRequired = TRUE;
                }
                
                //
                // Get the next SIR packet if there is one.
                //
                pIrMiniport->GetNextSirPacket();
                
                //
                // This is to protect the transmit list and when baud
                // rates are changed.
                //
                LeaveCriticalSection( &pIrMiniport->m_ListCriticalSection);
            }            
        }
        
        
        //
        // Check to see if we have bytes in the recieve queue.
        //
        while(!(*UART2_FR & FR_RXFE))
        {
            //
            // Get the next byte.
            //
            ucRecievedByte = (UCHAR) *UART2_DR;

            //
            // Process the byte through the SIR state machine.
            //            
            pIrMiniport->m_SirState.ProcessByte(ucRecievedByte);
            
            //
            // Check to see if we have a packet. 
            //
            if(pIrMiniport->m_SirState.PacketAvailable())
            {
                //
                // Fix up some packet fields.
                //
                NDIS_SET_PACKET_HEADER_SIZE
                (
                    pRxBuf->pPacket,
                    SLOW_IR_ADDR_SIZE + SLOW_IR_CONTROL_SIZE
                );
                
                //
                // Process the frame
                //
                pIrMiniport->m_ReceivePacketList.ProcessFrame( pRxBuf );
                
                //
                // Get the next free item.
                //
                pRxBuf = pIrMiniport->m_ReceivePacketList.GetFree();
    
                //
                // Set the next buffer location.
                //
                pIrMiniport->m_SirState.SetNextBuffer(pRxBuf);        
            }
        }
        
        
        //
        // Renable the UART interrupt.
        //
        InterruptDone(SYSINTR_UART2);
    }        

    DEBUGMSG(ZONE_IRDAHW, (TEXT("-SIRInterruptHandler")));
    
    return(0);
}


//****************************************************************************
// IRMiniport::GetNextSirPacket
//****************************************************************************
// Get the next SIR packet.  This function must be protected by the
// Critical Section.
// 
//
void IRMiniport::GetNextSirPacket()
{
    PNDIS_IRDA_PACKET_INFO  pIrdaInfo;
    DWORD                   cbTatBofs;
    ULONG                   ulTemp;

    while(!m_pSIRTransmitNDisPacket)
    {
        //
        // Get the next item on the list.
        //
        if(m_SendPacketList.MorePackets())
        {
            //
            // Remove the next packet and put it into the current packet.
            //
            m_pSIRTransmitNDisPacket = m_SendPacketList.RemoveNextPacket();
                        
            //
            // Get irda media specific info.
            //
            pIrdaInfo = GetIrdaPacketInfo( m_pSIRTransmitNDisPacket );
            
            ASSERT(pIrdaInfo != NULL);
            ASSERT(pIrdaInfo->MinTurnAroundTime <= MAX_TAT_usec);
        
            //
            // TAT BOFS.
            //
            if ((m_fMinTATRequired == TRUE) && 
                  (pIrdaInfo->MinTurnAroundTime > 0))
            {
                //          BitsPerSecond       uSecDelay
                //    TAT = -------------  * --------------
                //            BitsPerChar     uSecPerSecond
                cbTatBofs = (GetCurrentBaudRate() * pIrdaInfo->MinTurnAroundTime)/8000000;
                m_fMinTATRequired = FALSE;
            }                
            else
            {
                cbTatBofs = 0;
            }

            //                    
            // Need to convert NdisPacket to an IR packet.
            //
            if (!NdisToIrPacket(
                    m_pSIRTransmitNDisPacket,
                    cbTatBofs,
                    m_pSendBuf,
                    &m_ulSendBufSize))
            {
                //
                // Complete the packet with a failure.
                //
                CompleteSentPacket
                (
                    m_pSIRTransmitNDisPacket,
                    m_hNdisAdapter,
                    NDIS_STATUS_FAILURE
                );                
                
                //
                // Increment the packets dropped count.
                //
                m_ulPacketsTxDropped++;

                DEBUGMSG(ZONE_WARN,
                     (TEXT("Tx:Packets dropped = %d\r\n"),
                      m_ulPacketsTxDropped)
                     );
                
                                
                //
                // Really, All I need to zero out is the first item.
                // Lets Zero out all the items just in case.
                //
                m_pSIRTransmitNDisPacket   = 0;
                m_ulSendCurPos             = 0;  
            }
            else
            {
                //
                // Enable the interrupt for transmitting.
                //
                *UART2_CR    |= CR_TIE;
                //ulTemp      = *UART2_CR;
                //*UART2_CR   = (ulTemp & ~CR_RIE) | CR_TIE;
                //ulTemp      = *IRDA_IRCON;
                //*IRDA_IRCON = (ulTemp *~IRCON_RXE) | IRCON_TXE;
            }
        }                    
        else
        {
            //
            // We are switching from sending to recieving
            // packets.
            // 
            // Set Flag to send out BOFs packets for timing purposes.
            //
            m_fMinTATRequired = TRUE;
                                
            //
            // Disable the interrupt for transmitting.
            //
            *UART2_CR    &= ~CR_TIE;
            break;
            //ulTemp      = *UART2_CR;
            //*UART2_CR   = (ulTemp & ~CR_TIE) | CR_RIE;
            //ulTemp      = *IRDA_IRCON;
            //*IRDA_IRCON = (ulTemp *~IRCON_TXE) | IRCON_RXE;
        }
    }
}    


//****************************************************************************
// CompleteSentPacket
//****************************************************************************
// This completes a sent packet.
// 
//
void CompleteSentPacket
(
    PNDIS_PACKET    pNdisPacket,
    NDIS_HANDLE     hNdisAdapter,
    NDIS_STATUS     status
)
{
    DEBUGMSG(ZONE_SEND, (TEXT("+CompleteSentPacket")));

    NDIS_HANDLE     hSwitchToMiniport;
    BOOL            fSwitchSuccessful;
    
    //
    // Need to give the NDIS packet back to the protocol.
    // Since this is an intermediate miniport, we must call 
    // NdisIMSwitchToMiniport to grab the NDIS miniport lock.
    //
    fSwitchSuccessful = NdisIMSwitchToMiniport
    (
        hNdisAdapter,
        &hSwitchToMiniport
    );

    if (fSwitchSuccessful == FALSE)
    {
        // WinCE's NdisIMSwitchToMiniport should not fail.
        ASSERT(FALSE);
    }

    //
    // Indicate ownership of packet along with status of send.
    //
    NdisMSendComplete
    (
        hNdisAdapter,
        pNdisPacket,
        status
    );

    NdisIMRevertBack
    (
        hNdisAdapter,
        hSwitchToMiniport
    );

    DEBUGMSG(ZONE_SEND, (TEXT("-CompleteSentPacket")));
}    

































#if 0
#define IRDA_GPIO_A_DATA_REG 0x80840000                      // GPIO A Data port.
#define IRDA_GPIO_A_DATA_TYPE_IR 1

#define IRDA_GPIO_A_DATA_DIR_REG 0x80840008
#define IRDA_GPIO_A_DATA_REG_OUT 0x1
#define IRDA_GPIO_LOCK_REG 0x80840120
#define IRDA_GPIO_LOCK_KEY 0xaa

//****************************************************************************
// InitIrdaGPIO
//****************************************************************************
//
// Notice:  This may be board specific.  Also the GPIO bits should be a seprate
//          driver to prevent contention!
//
// The TFDS6501E does not power on with a default mode, therefore the data 
// transfer rate has to be set by a pro-gramming sequence using the Txd and 
// SD/ Mode inputs as described below or selected by setting the Mode Pin. 
// The Mode Pin can be used to statically set the mode 
// (Mode Pin: LOW: SIR, HIGH: 0.576 Mbit/s to 4.0 Mbit/s). When using the Mode 
// Pin, the standby current may increase to about 50 to 60 A when high
// or low. If not used or in standby mode, the mode input should float to 
// minimize standby current. The low frequency mode covers speeds up to 
// 115.2 kbit/s. Signals with higher data rates should be detected in the
// high frequency mode. Lower frequency data can also be received in the 
// high frequency mode but with reduced sensitivity. To switch the transceivers 
// from low frequency mode to the high frequency mode and vice versa, 
// the programming sequences described below  are required.
//
void InitIrdaGPIO(void)
{
  unsigned int ulPortDirection;                                          
    //  
    // Make port output. Set output bit to a "1".
    // Lock bit. The LOCK bit is set to one when this register is written 
    // with a value of 0xAA. The lock bit is cleared by any access to the 
    // GPIO address space. When the LOCK bit is one, the GPIO direction 
    // register are unlocked for write access. The write operation to the
    // direction registers will clear the LOCK bit.
    //
    ulPortDirection = *((unsigned int *)IRDA_GPIO_A_DATA_DIR_REG);   
    ulPortDirection |= IRDA_GPIO_A_DATA_REG_OUT;                    
    *((unsigned int *)IRDA_GPIO_LOCK_REG) = IRDA_GPIO_LOCK_KEY;     
    *((unsigned int *)IRDA_GPIO_A_DATA_DIR_REG) = ulPortDirection;  

}
//****************************************************************************
// 
//****************************************************************************
// 
// 
//

//
//
// Synopsis: Init GPIO registers for the IRDA interface.
void Set_IrDA_With_GPIO(unsigned int value)                                     
{
  if(value)
    *((unsigned int *)IRDA_GPIO_A_DATA_REG) |= 0x000000001;
  else
    *((unsigned int *)IRDA_GPIO_A_DATA_REG) &= 0x0FFFFFFFE;
// GPIO Port A data register. GPIO Port A corresponds to EGPIO[7:0] pins.
// bit 0 = 1 
}

#endif // 0

⌨️ 快捷键说明

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