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

📄 sir.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
//
//  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, Motorola Inc. All Rights Reserved
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004, 2005, 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.
//
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
//  File:  sir.cpp
//
//   This file implements the device specific functions for zeus fir device.
//
//------------------------------------------------------------------------------
#include "IrFir.h"


//------------------------------------------------------------------------------
// External Functions

//------------------------------------------------------------------------------
// External Variables

//------------------------------------------------------------------------------
// Defines

//------------------------------------------------------------------------------
// Types

//------------------------------------------------------------------------------
// Global Variables

//------------------------------------------------------------------------------
// Local Variables

//------------------------------------------------------------------------------
// Local Functions

//-----------------------------------------------------------------------------
//
// Function: DumpUart2Reg
//
// Dump Uart2 registers
//
// Parameters:
//		None.
//
// Returns:  
//		None.
//
//-----------------------------------------------------------------------------
VOID DumpUart2Reg(VOID)	
{
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: UCR1 is 0x%08x\r\n"), g_pVSIRReg->UCR1));
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: UCR2 is 0x%08x\r\n"), g_pVSIRReg->UCR2));
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: UCR3 is 0x%08x\r\n"), g_pVSIRReg->UCR3));
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: UCR4 is 0x%08x\r\n"), g_pVSIRReg->UCR4));
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: UFCR is 0x%08x\r\n"), g_pVSIRReg->UFCR));	
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: USR1 is 0x%08x\r\n"), g_pVSIRReg->USR1));
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: USR2 is 0x%08x\r\n"), g_pVSIRReg->USR2));	
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: UBIR is 0x%08x\r\n"), g_pVSIRReg->UBIR));	
	DEBUGMSG(ZONE_ERROR, (TEXT("DumpUart2Reg: UBMR is 0x%08x\r\n"), g_pVSIRReg->UBMR));	
}
//-----------------------------------------------------------------------------
//
// Function: SirHwWrite
//
// Step the send fsm to send a few more bytes of an IR frame.
//
// Parameters:
//		thisDev 
//          [in] pFirDevice_t.
//
// Returns:  
//		This function returns packet send status.
//
//-----------------------------------------------------------------------------
static BOOLEAN SirHwWrite(pFirDevice_t thisDev)
{
	UINT i, bytesAtATime, startPos = thisDev->portInfo.sendBufPos;
	BOOLEAN result;
	UINT maxLoops;

	//  Ordinarily, we want to fill the send FIFO once per interrupt.
	//  However, at high speeds the interrupt latency is too slow and
	//  we need to poll inside the ISR to send the whole packet during
	//  the first interrupt.

	if(thisDev->newSpeed > 115200)
		maxLoops = REG_TIMEOUT_LOOPS;
	else 
		maxLoops = REG_POLL_LOOPS;

	// Temporarily disable receiver first to avoid receiving data from ourselves
	CSP_BITFINS(g_pVSIRReg->UCR2, UART_UCR2_RXEN, UART_UCR2_RXEN_DISABLE);

    // Write databytes as long as we have them and the UART's FIFO hasn't filled up.
	while (thisDev->portInfo.sendBufPos < thisDev->writeBufLen) 
	{
        // send up to the FIFO size.
		bytesAtATime = MIN(SER_FIFO_DEPTH, (thisDev->writeBufLen - thisDev->portInfo.sendBufPos));

		// Wait for ready-to-send.
		while (!(g_pVSIRReg->USR2 & CSP_BITFMASK(UART_USR2_TXFE))) 
			Sleep(0);
		// Send the next byte or FIFO-volume of bytes.
        while (bytesAtATime)
        {
            DEBUGMSG(ZONE_SEND, (TEXT("Sir: Send 0x%x\r\n"), thisDev->writeBuf[thisDev->portInfo.sendBufPos]));
			g_pVSIRReg->UTXD = thisDev->writeBuf[thisDev->portInfo.sendBufPos++];
            bytesAtATime--;
        }
	}

	// Wail until transmission complete
	i = 0;
	while ((!(g_pVSIRReg->USR2 & CSP_BITFMASK(UART_USR2_TXDC))) && (++i < REG_TIMEOUT_LOOPS)) 
		Sleep(0);

	// Re-enable receiver once again.
	CSP_BITFINS(g_pVSIRReg->UCR2, UART_UCR2_RXEN, UART_UCR2_RXEN_ENABLE);

	if (i >= REG_TIMEOUT_LOOPS) 
	{
		DEBUGMSG(ZONE_ERROR, (TEXT("Sir: Wait for tansmitting complete timeout!!"), i));
		return FALSE;
	}

	if (thisDev->portInfo.sendBufPos >= thisDev->writeBufLen)
		result = TRUE;
	else
		result = FALSE;

	DEBUGMSG(ZONE_SEND, (TEXT("Sir: SirHwWrite wrote %d bytes (%s): LOOP TIMES %d"), (UINT)(thisDev->portInfo.sendBufPos-startPos), (PUCHAR)(result ? "Successful" : "Failed"), i));

	return result;
}

//-----------------------------------------------------------------------------
//
// Function: SirHwRead
//
//  Read up to maxBytes bytes from the UART's receive FIFO.
//
// Parameters:
//      thisDev 
//          [in] .
//      maxBytes
//          [in] .
//
// Returns:  
//    This function returns number of bytes read.
//
//-----------------------------------------------------------------------------
static UINT SirHwRead(UCHAR *data, UINT maxBytes)
{
	UINT bytesRead = 0;
	UINT32 tempData;

	while (bytesRead < maxBytes) 
	{
        //  Wait for data-ready
        if(!(g_pVSIRReg->USR2 & CSP_BITFVAL(UART_USR2_RDR, UART_USR2_RDR_SET)))
            break;

		tempData = g_pVSIRReg->URXD;

        //  The UART reports framing and break errors as the effected
        //  characters appear on the stack.  We drop these characters,
        //  which will probably result in a bad frame checksum.
		if (tempData & SIR_RCV_ERROR) 
		{
			return (UINT)-1;
        }
		else 
		{
			data[bytesRead] = tempData & UART_URXD_RX_DATA_MSK;
		}

        DEBUGMSG(ZONE_RECV, (TEXT("Sir: Receive 0x%x\r\n"), data[bytesRead]));
		bytesRead++;
	}

	return bytesRead;
}

//-----------------------------------------------------------------------------
//
// Function: NdisToSirPacket
//
//  This function reads the NDIS packet into a contiguous buffer.
//
// Parameters:
//      Packet
//          [in] .
//      irPacketBuf
//          [in] .
//      irPacketBufLen
//          [in] .
//      irPacketLen
//          [in] .
//
// Returns:
//    This function returns TRUE if the packet check is successful.
//
//-----------------------------------------------------------------------------
BOOLEAN NdisToSirPacket( PNDIS_PACKET Packet, UCHAR *irPacketBuf,
    UINT irPacketBufLen, UINT *irPacketLen )
{
	static UCHAR contigPacketBuf[MAX_IRDA_DATA_SIZE];
	PNDIS_BUFFER ndisBuf;
	UINT i, ndisPacketBytes = 0, I_fieldBytes, totalBytes = 0;
	UINT ndisPacketLen, numExtraBOFs;
	SLOW_IR_FCS_TYPE fcs, tmpfcs;
	UCHAR fcsBuf[SLOW_IR_FCS_SIZE*2];
	UINT fcsLen=0;
	PNDIS_IRDA_PACKET_INFO packetInfo = GetPacketInfo(Packet);
	UCHAR nextChar;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: +NdisToSirPacket\r\n")));

    //  Get the packet's entire length and its first NDIS buffer
	NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);

    //  Make sure that the packet is big enough to be legal.
    //  It consists of an A, C, and variable-length I field.
	if (ndisPacketLen < IR_ADDR_SIZE + IR_CONTROL_SIZE) 
	{
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: packet too short in NdisToSirPacket (%d bytes)\r\n"), ndisPacketLen));
		return FALSE;
    }
	else 
	{
		I_fieldBytes = ndisPacketLen - IR_ADDR_SIZE - IR_CONTROL_SIZE;
	}

    //  Make sure that we won't overwrite our contiguous buffer.
    //  Make sure that the passed-in buffer can accomodate this packet's
    //  data no matter how much it grows through adding ESC-sequences, etc.
	if ((ndisPacketLen > MAX_IRDA_DATA_SIZE) ||
		(MAX_POSSIBLE_IR_PACKET_SIZE_FOR_DATA(I_fieldBytes) > irPacketBufLen)) 
	{
        //  The packet is too large
        //  Tell the caller to retry with a packet size large
        //  enough to get past this stage next time.
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: Packet too large in NdisToSirPacket (%d=%xh bytes), MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d.\r\n"),
            ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
		*irPacketLen = ndisPacketLen;
		return FALSE;
	}

    //  First, read the NDIS packet into a contiguous buffer.
    //  We have to do this in two steps so that we can compute the
    //  FCS BEFORE applying escape-byte transparency.
	while (ndisBuf) 
	{
		UCHAR *bufData;
		UINT bufLen;

		NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);

		if (ndisPacketBytes + bufLen > ndisPacketLen) 
		{
            //  Packet was corrupt -- it misreported its size.
			*irPacketLen = 0;
			return FALSE;
		}

		NdisMoveMemory((PVOID)(contigPacketBuf+ndisPacketBytes), (PVOID)bufData, bufLen);
		ndisPacketBytes += bufLen;

		NdisGetNextBuffer(ndisBuf, &ndisBuf);
	}

    //  Do a sanity check on the length of the packet.
	if (ndisPacketBytes != ndisPacketLen) 
	{
        //  Packet was corrupt -- it misreported its size.
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: acket corrupt in NdisToSirPacket (buffer lengths don't add up to packet length).\r\n")));
		*irPacketLen = 0;
		return FALSE;
	}

    //  Compute the FCS on the packet BEFORE applying transparency fixups.
    //  The FCS also must be sent using ESC-char transparency, so figure
    //  out how large the fcs will really be.
	fcs = ComputeFCS(contigPacketBuf, ndisPacketBytes);

	for (i = 0, tmpfcs = fcs, fcsLen = 0; i < SLOW_IR_FCS_SIZE; tmpfcs >>= 8, i++) 
	{
		UCHAR fcsbyte = tmpfcs & 0x00ff;
		switch (fcsbyte) 
		{
			case SLOW_IR_BOF:
			case SLOW_IR_EOF:
			case SLOW_IR_ESC:
				fcsBuf[fcsLen++] = SLOW_IR_ESC; 
				fcsBuf[fcsLen++] = fcsbyte ^ SLOW_IR_ESC_COMP;
				break;

			default:
				fcsBuf[fcsLen++] = fcsbyte; 
				break;
		}
	}

    //  Now begin building the IR frame.
    //
    //  This is the final format:
    //
    //    BOF (1)
    //    extra BOFs ...
    //    NdisMediumIrda packet (what we get from NDIS):
    //        Address (1)
    //        Control (1)
    //    FCS (2)
    //    EOF (1)

    //  Prepend BOFs (extra BOFs + 1 actual BOF)
	numExtraBOFs = packetInfo->ExtraBOFs;

	if (numExtraBOFs > MAX_NUM_EXTRA_BOFS) 
		numExtraBOFs = MAX_NUM_EXTRA_BOFS;

	for (i = totalBytes = 0; i < numExtraBOFs; i++) 
	{
		*(SLOW_IR_BOF_TYPE *)(irPacketBuf+totalBytes) = SLOW_IR_EXTRA_BOF;
		totalBytes += SLOW_IR_EXTRA_BOF_SIZE;
	}
	*(SLOW_IR_BOF_TYPE *)(irPacketBuf+totalBytes) = SLOW_IR_BOF;
	totalBytes += SLOW_IR_BOF_SIZE;

    //  Copy the NDIS packet from our contiguous buffer, 
    //  applying escape-char transparency.
	for (i = 0; i < ndisPacketBytes; i++) 
	{
		nextChar = contigPacketBuf[i];
        switch (nextChar)
        {
			case SLOW_IR_BOF: 
			case SLOW_IR_EOF: 
			case SLOW_IR_ESC: 
				irPacketBuf[totalBytes++] = SLOW_IR_ESC;
				irPacketBuf[totalBytes++] = nextChar ^ SLOW_IR_ESC_COMP;
				break;

			default:
				irPacketBuf[totalBytes++] = nextChar;
				break;
		}
	}

    //  Add FCS, EOF.
	NdisMoveMemory((PVOID)(irPacketBuf+totalBytes), (PVOID)fcsBuf, fcsLen);
	totalBytes += fcsLen;
	*(SLOW_IR_EOF_TYPE *)(irPacketBuf+totalBytes) = (UCHAR)SLOW_IR_EOF;
	totalBytes += SLOW_IR_EOF_SIZE;

	*irPacketLen = totalBytes;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: ... NdisToSirPacket converted %d-byte ndis pkt to %d-byte irda pkt:\r\n"),
		ndisPacketLen, *irPacketLen));

	return TRUE;
}


//-----------------------------------------------------------------------------
//
// Function: SirDoSend
//
//  This function setup send packet.
//
// Parameters:
//      thisDev 
//          [in] .
//      packetToSend
//          [in] .
//
// Returns:  
//    This function returns packet send status.
//
//-----------------------------------------------------------------------------
BOOLEAN SirDoSend(pFirDevice_t thisDev, PNDIS_PACKET packetToSend)
{
    BOOLEAN stat;
    DEBUGMSG(ZONE_SEND, (TEXT("Sir: +SirDoSend\r\n")));

	DEBUGMSG(ZONE_SEND, (TEXT("Sir: SirDoSend()")));
    stat = NdisToSirPacket(packetToSend,
        (UCHAR *)thisDev->writeBuf, MAX_IRDA_DATA_SIZE, &thisDev->writeBufLen);


	if (stat) 
	{
		// Disable interrupts while setting up the send FSM.
		SirDisableInterrupt(thisDev);

		// Finish initializing the send FSM.
		thisDev->portInfo.sendBufPos = 0;
		thisDev->writePending = TRUE;
		thisDev->nowReceiving = FALSE;   

		// Enable Tx interupt
		CSP_BITFINS(g_pVSIRReg->UCR1, UART_UCR1_TXMPTYEN, UART_UCR1_TXMPTYEN_ENABLE);
	} 
	else  
	{
        DEBUGMSG(ZONE_SEND, (TEXT("Sir: Couldn't convert packet in SirDoSend()\r\n")));
	}

    DEBUGMSG(ZONE_SEND, (TEXT("Sir: -SirDoSend\r\n")));

    return stat;
}
//-----------------------------------------------------------------------------
//
// Function: SirSetSpeed
//
// This function sets the Sir baudrate.
//

⌨️ 快捷键说明

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