📄 fir.cpp
字号:
DEBUGMSG(ZONE_OPEN, (TEXT("Fir: -FirOpen\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: FirSendPacketQ
//
// This function sends the packet from the send queue.
//
// Parameters:
// thisDev
// [in] .
// firstBufIsPending
// [in] .
//
// Returns:
// This function returns status of send packet.
//
//-----------------------------------------------------------------------------
NDIS_STATUS FirSendPacketQ( pFirDevice_t thisDev, BOOLEAN firstBufIsPending )
{
NDIS_STATUS Result = NDIS_STATUS_PENDING;
PNDIS_PACKET packetToSend;
PNDIS_IRDA_PACKET_INFO packetInfo;
DEBUGMSG(ZONE_SEND, (TEXT("Fir: +FirSendPacketQ\r\n"), (UINT) thisDev));
if (IsListEmpty(&thisDev->SendQueue))
{
// Don't remove this branch, I do see it goes to this branch
// when hardware hang.
thisDev->HangChk = TRUE;
Result = NDIS_STATUS_FAILURE;
}
else
{
packetToSend = HEAD_SEND_PACKET(thisDev);
// Check for min turnaround time set.
packetInfo = GetPacketInfo(packetToSend);
//
// NOTE: Don't use NdisStallExecution for turnaround delay since
// you shouldn't stall for more than 60 us. Calling
// NdisStallExecution for large times will degrade system
// performance.
//
if (packetInfo->MinTurnAroundTime)
{
UINT usecToWait = packetInfo->MinTurnAroundTime;
UINT msecToWait;
packetInfo->MinTurnAroundTime = 0;
// Ndis timer has a 1ms granularity (in theory). Let's round off.
msecToWait = (usecToWait<=1000) ? 1 : (usecToWait+500)/1000;
NdisMSetTimer(&thisDev->TurnaroundTimer, msecToWait);
DEBUGMSG(ZONE_SEND, (TEXT("Fir: FirSendPacketQ - do min TAT wait\r\n")));
return NDIS_STATUS_PENDING; // Say we're successful. We'll come back here.
}
NdisToFirPacket(thisDev, packetToSend, (UCHAR *) thisDev->writeBuf,
MAX_IRDA_DATA_SIZE, &thisDev->writeBufLen);
// Disable all interrupt first
FirDisableInterrupt(thisDev);
// Disable FIRI receiver
CSP_BITFCLR(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RE);
//thisDev->nowReceiving = FALSE;
thisDev->writePending = TRUE;
// Setup FIRI data size
CSP_BITFINS(g_pVFiriReg->FIRI_TCTR, FIRI_TCTR_TPL, TPL_VALUE(thisDev->writeBufLen));
// Enable FIRI transmitter and transmitting interrupt
g_pVFiriReg->FIRI_TCR |=
CSP_BITFVAL(FIRI_TCR_TCIE, FIRI_TCR_TCIE_ENABLE) |
CSP_BITFVAL(FIRI_TCR_TPEIE, FIRI_TCR_TPEIE_ENABLE) |
CSP_BITFVAL(FIRI_TCR_TFUIE, FIRI_TCR_TFUIE_ENABLE) |
CSP_BITFVAL(FIRI_TCR_TE, FIRI_TCR_TE_ENABLE);
//for(UINT i=0; i < MIN(thisDev->writeBufLen, FIRI_FIFO_SIZE); i++)
for(UINT i=0; i < thisDev->writeBufLen; i++)
*(UINT8 *)(&(g_pVFiriReg->FIRI_TXFIFO)) = *(thisDev->writeBuf + i);
#if 0
// Enable FIRI transmitter
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TE, FIRI_TCR_TE_ENABLE);
// Write databytes as long as we have them and the UART's FIFO hasn't filled up.
while (i < thisDev->writeBufLen)
{
if (g_pVFiriReg->FIRI_TSR & 0xFF00)
g_pVFiriReg->FIRI_TXFIFO= thisDev->writeBuf[i++];
}
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TCIE, FIRI_TCR_TCIE_ENABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TPEIE, FIRI_TCR_TPEIE_ENABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TFUIE, FIRI_TCR_TFUIE_ENABLE);
#endif
DEBUGMSG(ZONE_SEND, (TEXT("Fir: FirSendPacketQ sent 0x%x bytes of data.\r\n"), thisDev->writeBufLen));
}
DEBUGMSG(ZONE_SEND, (TEXT("Fir: -FirSendPacketQ\r\n")));
return Result;
}
//-----------------------------------------------------------------------------
//
// Function: FirSend
//
// This function inserts packet to send queue and setup device to send.
//
// Parameters:
// thisDev
// [in] .
// Packet
// [in] .
//
// Returns:
// This function returns packet send status.
//
//-----------------------------------------------------------------------------
NDIS_STATUS FirSend( pFirDevice_t thisDev, PNDIS_PACKET Packet )
{
NDIS_STATUS stat;
BOOLEAN TxWasActive = (thisDev->AdapterState == ADAPTER_TX);
DEBUGMSG(ZONE_SEND, (TEXT("Fir: +FirSend\r\n")));
thisDev->AdapterState = ADAPTER_TX;
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_PENDING);
InsertTailList(&thisDev->SendQueue, (PLIST_ENTRY)Packet->MiniportReserved);
if (TxWasActive)
{
// Just idle here, the packete will be handled later
stat = NDIS_STATUS_PENDING;
}
else
{
DEBUGMSG(ZONE_SEND, (TEXT("Fir: FirSend TX idle, send\r\n")));
stat = FirSendPacketQ(thisDev, TRUE);
}
DEBUGMSG(ZONE_SEND, (TEXT("Fir: -FirSend\r\n")));
return stat;
}
//-----------------------------------------------------------------------------
//
// Function: FirReceive
//
// This function setup device to receive data.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirReceive( pFirDevice_t thisDev )
{
DEBUGMSG(ZONE_RECV, (TEXT("Fir: +FirReceive\r\n")));
thisDev->AdapterState = ADAPTER_RX;
thisDev->nowReceiving=TRUE;
//thisDev->rcvOffset = 0;
// Diable FIRI Transmitter
//g_pVFiriReg->FIRI_RCR |= CSP_BITFVAL(FIRI_TCR_TE, FIRI_TCR_TE_DISABLE);
// Enable FIRI receiver
g_pVFiriReg->FIRI_RCR |=
CSP_BITFVAL(FIRI_RCR_RPEIE, FIRI_RCR_RPEIE_ENABLE) |
CSP_BITFVAL(FIRI_RCR_PAIE, FIRI_RCR_PAIE_ENABLE) |
CSP_BITFVAL(FIRI_RCR_RFOIE, FIRI_RCR_RFOIE_ENABLE) |
CSP_BITFVAL(FIRI_RCR_RE, FIRI_RCR_RE_ENABLE);
DEBUGMSG(ZONE_RECV, (TEXT("Fir: -FirReceive\r\n")));
}
//-----------------------------------------------------------------------------
//
// Function: FirSetSpeed
//
// This function sets the Fir baudrate.
//
// Parameters:
// speed
// [in] .
//
// Returns:
// This function returns the actually baudrate set.
//
//-----------------------------------------------------------------------------
baudRates FirSetSpeed( pFirDevice_t thisDev )
{
baudRates rate = BAUDRATE_INVALID;
UINT speed = thisDev->newSpeed;
//ULONG speed = thisDev->linkSpeedInfo->bitsPerSec;
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: +FirSetSpeed %d\r\n"), speed ));
if(speed > MAX_SIR_SPEED)
{
switch (speed)
{
case 4000000:
//BSPFirSetClock(); // Setting the clock to 48MHz //done in open
//BSPFirEnableClock(TRUE); // Enable Fir Clock // done in open
CSP_BITFINS(g_pVFiriReg->FIRI_CR, FIRI_CR_OSF, OSF_VALUE(6));
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TM, FIRI_TCR_TM_FIR);
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TPP, FIRI_TCR_TPP_NO_INVERT);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RM, FIRI_RCR_RM_FIR);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RPP, FIRI_RCR_RPP_INVERT);
rate = BAUDRATE_4000000;
break;
case 1152000:
#if 1
ERRORMSG(TRUE, (TEXT("Mir clock enable failed! Speed not supported\r\n")));
#else
SET_BITS(g_pVFiriReg->FIRICR, FIRI_FIRICR_OSF, OSF_VALUE(2));
SET_BITS(g_pVFiriReg->FIRITCR, FIRI_FIRITCR_TM, MIR_1_152);
SET_BITS(g_pVFiriReg->FIRIRCR, FIRI_FIRIRCR_RM, MIR_1_152);
rate = BAUDRATE_1152000;
#endif
break;
case 576000:
#if 1
ERRORMSG(TRUE, (TEXT("Mir clock enable failed! Speed not supported\r\n")));
#else
CSP_BITFINS(g_pVFiriReg->FIRI_CR, FIRI_CR_OSF, OSF_VALUE(5));
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TM, FIRI_TCR_TM_576_MIR);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RM, FIRI_RCR_RM_576_MIR);
rate = BAUDRATE_576000;
#endif
break;
default:
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: FirSetSpeed, unsupported speed: %d\r\n"), speed));
}
}
else
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: FirSetSpeed, unsupported speed: %d, NOT FIR/MIR\r\n"), speed));
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: -FirSetSpeed\r\n")));
return rate;
}
//-----------------------------------------------------------------------------
//
// Function: FirInterruptHandler
//
// This function is the interrupt handler for Fir device.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirInterruptHandler( pFirDevice_t thisDev )
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: +FirInterruptHandler, 0x%08x\r\n"), thisDev));
// if 1st packet not yet finished. continue to send
if(thisDev->writePending)
{
FirSendPacketComplete(thisDev);
thisDev->writePending = FALSE;
if (thisDev->setSpeedAfterCurrentSendPacket)
{
thisDev->setSpeedAfterCurrentSendPacket = FALSE;
SetSpeed(thisDev);
// check return condition
if(thisDev->linkSpeedInfo->bitsPerSec <= MAX_SIR_SPEED)
return;
}
// Any more Tx packets?
if (!IsListEmpty(&thisDev->SendQueue))
{
// Kick off another Tx
FirSendPacketQ(thisDev, TRUE);
}
else
{
// No more Tx packet, enable Rx hardware again.
g_pVFiriReg->FIRI_RCR |=
CSP_BITFVAL(FIRI_RCR_RPEIE, FIRI_RCR_RPEIE_ENABLE) |
CSP_BITFVAL(FIRI_RCR_PAIE, FIRI_RCR_PAIE_ENABLE) |
CSP_BITFVAL(FIRI_RCR_RFOIE, FIRI_RCR_RFOIE_ENABLE) |
CSP_BITFVAL(FIRI_RCR_RE, FIRI_RCR_RE_ENABLE);
//FirReceive(thisDev);
}
}
else
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: INTERRUPT: rcv packet end!\r\n")));
if(FirReceivePacket(thisDev))
{
FirReceive(thisDev);
DeliverFullBuffers(thisDev);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -