📄 fir.cpp
字号:
//------------------------------------------------------------------------------
//
// 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: fir.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: FirDumpReg
//
// This function dump the value of registers of Fir device.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
static VOID FirDumpReg(VOID)
{
DEBUGMSG(ZONE_ERROR, (TEXT("FIRITCR 0x%08x\r\n"), g_pVFiriReg->FIRI_TCR));
DEBUGMSG(ZONE_ERROR, (TEXT("FIRITCTR 0x%08x\r\n"), g_pVFiriReg->FIRI_TCTR));
DEBUGMSG(ZONE_ERROR, (TEXT("FIRIRCR 0x%08x\r\n"), g_pVFiriReg->FIRI_RCR));
DEBUGMSG(ZONE_ERROR, (TEXT("FIRITSR 0x%08x\r\n"), g_pVFiriReg->FIRI_TSR));
DEBUGMSG(ZONE_ERROR, (TEXT("FIRIRSR 0x%08x\r\n"), g_pVFiriReg->FIRI_RSR));
DEBUGMSG(ZONE_ERROR, (TEXT("FIRICR 0x%08x\r\n"), g_pVFiriReg->FIRI_CR));
}
//
// Function: NdisToFirPacket
//
// 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 NdisToFirPacket( pFirDevice_t thisDev, PNDIS_PACKET Packet,
UCHAR * irPacketBuf, UINT irPacketBufLen, UINT * irPacketLen )
{
PNDIS_BUFFER ndisBuf;
UINT ndisPacketBytes = 0;
UINT ndisPacketLen;
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: +NdisToFirPacket(0x%x)\r\n"), (UINT) thisDev));
// Get the packet's entire length and its first NDIS buffer
NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: NdisToFirPacket, number of bytes: %d\r\n"), 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("Fir: packet too short in NdisToFirPacket (%d bytes)\r\n"), ndisPacketLen));
return FALSE;
}
// Make sure that we won't overwrite our contiguous buffer.
if (ndisPacketLen > 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("Fir: Packet too large in NdisToIrPacket (%d=%xh bytes), MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d\r\n"),
ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
*irPacketLen = ndisPacketLen;
return FALSE;
}
// 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)(irPacketBuf+ndisPacketBytes), (PVOID)bufData, (ULONG)bufLen);
ndisPacketBytes += bufLen;
NdisGetNextBuffer(ndisBuf, &ndisBuf);
}
// Do a validity check on the length of the packet
if (ndisPacketBytes != ndisPacketLen)
{
// Packet was corrupt -- it misreported its size.
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: Packet corrupt in NdisToIrPacket\r\n")));
*irPacketLen = 0;
return FALSE;
}
*irPacketLen = ndisPacketBytes;
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: -NdisToFirPacket\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: FirSendPacketComplete
//
// This function stops Fir transmitter when transmission completed.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirSendPacketComplete( pFirDevice_t thisDev )
{
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
PLIST_ENTRY ListEntry;
PNDIS_PACKET Packet;
UINT32 tempRegVal;
DEBUGMSG(ZONE_SEND, (TEXT("Fir: +FirSendPacketComplete(0x%x)\r\n"), (UINT) thisDev));
ListEntry = MyRemoveHeadList(&thisDev->SendQueue);
if (!ListEntry)
ASSERT(0);
else
{
Packet = CONTAINING_RECORD(ListEntry, NDIS_PACKET, MiniportReserved);
// Check whether transmission error
tempRegVal = g_pVFiriReg->FIRI_TSR;
// Clear interrupt status
g_pVFiriReg->FIRI_TSR = XMIT_INTR_MASK;
// Disable FIRI transmitter
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TE, FIRI_TCR_TE_DISABLE);
if (tempRegVal & CSP_BITFMASK(FIRI_TSR_TFU))
{
status = NDIS_STATUS_FAILURE;
thisDev->HangChk = TRUE;
DEBUGMSG(ZONE_SEND, (TEXT("FIRI: FirSendPacketComplete: Transmit Underrun, 0x%08x, Data size is %d"), tempRegVal, thisDev->writeBufLen));
}
else if (tempRegVal & (CSP_BITFMASK(FIRI_TSR_TPE) | CSP_BITFMASK(FIRI_TSR_TC)))
{
status = NDIS_STATUS_SUCCESS;
DEBUGMSG(ZONE_SEND, (TEXT("FIRI: FirSendPacketComplete: Transfer completed!!! IntrStatus: 0x%08x"), tempRegVal));
}
else
{
status = NDIS_STATUS_FAILURE;
DEBUGMSG(ZONE_ERROR, (TEXT("FIRI: FirSendPacketComplete: Unexpected interrupt, 0x%08x"), tempRegVal));
}
// Notify NDIS of TX complete
NdisReleaseSpinLock(&thisDev->Lock);
NdisMSendComplete(thisDev->ndisAdapterHandle, Packet, status);
NdisAcquireSpinLock(&thisDev->Lock);
}
DEBUGMSG(ZONE_SEND, (TEXT("Fir: -FirSendPacketComplete\r\n")));
}
#if 0
//-----------------------------------------------------------------------------
//
// Function: FirReceiveThread
//
// This function is the Fir receiving thread.
//
// Parameters:
// lpParameter
// [in] .
//
// Returns:
// This function returns TRUE when exiting.
//
//-----------------------------------------------------------------------------
DWORD WINAPI FirReceiveThread(LPVOID lpParameter)
{
pFirDevice_t thisDev = (pFirDevice_t)lpParameter;
UINT iDataInRxFIFO = 0;
DEBUGMSG(ZONE_THREAD, (TEXT("Fir: +FirReceiveThread\r\n")));
SetProcPermissions(0xFFFFFFFF);
//FirDumpReg();
while (!thisDev->m_bTerminate)
{
WaitForSingleObject(thisDev->m_hEvent, INFINITE);
while (thisDev->nowReceiving)
{
iDataInRxFIFO = g_pVFiriReg->FIRI_RSR>>8;
while(iDataInRxFIFO--)
{
*(UINT8 *)((UINT32)thisDev->readBuf + thisDev->rcvOffset++) =\
*(UINT8 *)(&(g_pVFiriReg->FIRI_RXFIFO));
}
}
}
thisDev->m_hThread = NULL;
DEBUGMSG(ZONE_THREAD, (TEXT("Fir: -FirReceiveThread\r\n")));
return TRUE;
}
#endif
//-----------------------------------------------------------------------------
//
// Function: FirReceivePacket
//
// This function queue the received packet.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// This function returns TRUE if the packet receiving is successful.
//
//-----------------------------------------------------------------------------
BOOLEAN FirReceivePacket( pFirDevice_t thisDev )
{
UINT32 iIntrTemp;
const UINT fcsSize = FAST_IR_FCS_SIZE;
BOOLEAN result = TRUE;
UINT iDataInRxFIFO = 0;
PLIST_ENTRY pListEntry;
DEBUGMSG(ZONE_RECV, (TEXT("Fir: +FirReceivePacket(0x%x)\r\n"), (UINT) thisDev));
// Check interrupt status of FIRI
iIntrTemp = g_pVFiriReg->FIRI_RSR;
// Clear Rx itnerrupt status
g_pVFiriReg->FIRI_RSR = RCV_INTR_MASK;
// Suspend thread
//thisDev->nowReceiving=FALSE;
// Disable FIRI receiver
//CSP_BITFCLR(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RE);
if(iIntrTemp &
(CSP_BITFVAL(FIRI_RSR_CRCE, FIRI_RSR_CRCE_FAILURE) |
CSP_BITFVAL(FIRI_RSR_DDE, FIRI_RSR_DDE_ILLEGAL) |
CSP_BITFVAL(FIRI_RSR_RFO, FIRI_RSR_RFO_OVERRUN)))
{
DEBUGMSG(ZONE_RECV, (TEXT("Fir: FirReceivePacket(Firi error), 0x%08x"), iIntrTemp));
thisDev->HangChk = TRUE;
result = FALSE;
goto done;
}
iDataInRxFIFO = g_pVFiriReg->FIRI_RSR>>8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -