📄 fir.cpp
字号:
while(iDataInRxFIFO--)
{
*(UINT8 *)((UINT32)thisDev->readBuf + thisDev->rcvOffset++) =\
*(UINT8 *)(&(g_pVFiriReg->FIRI_RXFIFO));
}
// Disable FIRI receiver
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RE, FIRI_RCR_RE_DISABLE);
DEBUGMSG(ZONE_RECV, (TEXT("Fir: FirReceivePacket offset 0x%x:\r\n"),thisDev->rcvOffset));
ASSERT(thisDev->rcvOffset < RCV_BUFFER_SIZE);
// Chop off FCS
thisDev->rcvOffset -= fcsSize;
if (thisDev->rcvOffset <= MAX_NDIS_DATA_SIZE &&
thisDev->rcvOffset >= IR_ADDR_SIZE + IR_CONTROL_SIZE)
{
ASSERT(!IsListEmpty(&thisDev->rcvBufBuf));
// Queue this rcv packet.
QueueReceivePacket(thisDev, thisDev->readBuf, thisDev->rcvOffset);
// The protocol has our buffer. Get a new one.
pListEntry = RemoveHeadList(&thisDev->rcvBufBuf);
thisDev->readBuf = (PUCHAR) LIST_ENTRY_TO_RCV_BUF(pListEntry);
thisDev->rcvOffset = 0;
}
else
DEBUGMSG(ZONE_RECV, (TEXT("Fir: invalid packet size in FirReceivePacket; %xh > %xh\r\n"),
thisDev->rcvOffset, MAX_RCV_DATA_SIZE));
done:
DEBUGMSG(ZONE_RECV, (TEXT("Fir: -FirReceivePacket\r\n")));
return result;
}
//-----------------------------------------------------------------------------
//
// Function: FirClearInterrupt
//
// This function clears Fir interrupts.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirClearInterrupt( VOID )
{
// Clear the interrupt status registers
g_pVFiriReg->FIRI_TSR= XMIT_INTR_MASK;
g_pVFiriReg->FIRI_RSR= RCV_INTR_MASK;
}
//-----------------------------------------------------------------------------
//
// Function: FirEnableInterrupt
//
// This function denables Fir interrupts.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirEnableInterrupt( pFirDevice_t thisDev )
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: +FirEnableInterrupt\r\n")));
// Enabling the interrupts in the interrupt handler itself
#if 0
// Enable Interrupts from FIRI
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_TE, FIRI_TCR_TE_ENABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TFUIE, FIRI_TCR_TFUIE_ENABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RPEIE, FIRI_RCR_RPEIE_ENABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_PAIE, FIRI_RCR_PAIE_ENABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RFOIE, FIRI_RCR_RFOIE_ENABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RE, FIRI_RCR_RE_ENABLE);
#endif
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: -FirEnableInterrupt\r\n")));
}
//-----------------------------------------------------------------------------
//
// Function: FirDisableInterrupt
//
// This function disables Fir interrupts.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirDisableInterrupt( pFirDevice_t thisDev )
{
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: +FirDisableInterrupt\r\n")));
// Disable Interrupts from FIRI
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TCIE, FIRI_TCR_TCIE_DISABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TPEIE, FIRI_TCR_TPEIE_DISABLE);
//CSP_BITFINS(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TFUIE, FIRI_TCR_TFUIE_DISABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RPEIE, FIRI_RCR_RPEIE_DISABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_PAIE, FIRI_RCR_PAIE_DISABLE);
CSP_BITFINS(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RFOIE, FIRI_RCR_RFOIE_DISABLE);
DEBUGMSG(ZONE_FUNCTION, (TEXT("Fir: -FirDisableInterrupt\r\n")));
}
//-----------------------------------------------------------------------------
//
// Function: FirInitialize
//
// This function initializes the Fir device.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// This function returns initialization status.
//
//-----------------------------------------------------------------------------
BOOLEAN FirInitialize(pFirDevice_t thisDev)
{
PHYSICAL_ADDRESS Addr = {thisDev->FirPhyAddr, 0};
DEBUGMSG(ZONE_INIT, (TEXT("Fir: +FirInitialize\r\n")));
// Map peripheral physical address to virtual address
if(g_pVFiriReg == NULL)
{
g_pVFiriReg = (PCSP_FIRI_REG) MmMapIoSpace(Addr, sizeof(CSP_FIRI_REG), FALSE);
// Check if virtual mapping failed
if (g_pVFiriReg == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Fir: MmMapIoSpace failed!\r\n")));
return FALSE;
}
}
// Use kernel IOCTL to translate the FIR base address into an IRQ since
// the IRQ value differs based on the SoC. Note that DEVICE_LOCATION
// fields except IfcType and LogicalLoc are ignored for internal SoC
// components.
DEVICE_LOCATION devLoc;
devLoc.IfcType = Internal;
devLoc.LogicalLoc = thisDev->FirPhyAddr;
if (!KernelIoControl(IOCTL_HAL_REQUEST_IRQ, &devLoc, sizeof(devLoc),
&thisDev->sysIntrFir, sizeof(thisDev->sysIntrFir), NULL))
{
ERRORMSG(1, (_T("Cannot obtain FIR IRQ!\r\n")));
return FALSE;
}
DEBUGMSG(ZONE_INIT, (TEXT("Fir: -FirInitialize\r\n")));
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: FirDeinitialize
//
// This function deinitializes the Fir device.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirDeinitialize( pFirDevice_t thisDev )
{
DEBUGMSG(ZONE_DEINIT, (TEXT("Fir: +FirDeinitialize\r\n")));
// Free FIRI register
if(g_pVFiriReg)
{
MmUnmapIoSpace(g_pVFiriReg, sizeof(CSP_FIRI_REG));
g_pVFiriReg = NULL;
}
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &thisDev->sysIntrFir, sizeof(DWORD), NULL, 0, NULL);
thisDev->sysIntrFir = SYSINTR_UNDEFINED;
DEBUGMSG(ZONE_DEINIT, (TEXT("Fir: -FirDeinitialize\r\n")));
}
//-----------------------------------------------------------------------------
//
// Function: FirClose
//
// This function closes the Fir device.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
VOID FirClose( pFirDevice_t thisDev )
{
DWORD dwDataInFifo = 0;
DEBUGMSG(ZONE_CLOSE, (TEXT("Fir: +FirClose\r\n")));
// Disable Transmitter and receiver
CSP_BITFCLR(g_pVFiriReg->FIRI_TCR, FIRI_TCR_TE);
CSP_BITFCLR(g_pVFiriReg->FIRI_RCR, FIRI_RCR_RE);
g_pVFiriReg->FIRI_TSR = 0xFF;
g_pVFiriReg->FIRI_RSR = 0xFF;
g_pVFiriReg->FIRI_CR = 0;
g_pVFiriReg->FIRI_TCR = 0;
g_pVFiriReg->FIRI_RCR = 0;
// Flush the fifo
dwDataInFifo = CSP_BITFEXT(g_pVFiriReg->FIRI_RSR, FIRI_RSR_RFP);
if (dwDataInFifo > 0)
{
for (UINT i = 0; i < dwDataInFifo; i++)
*(UINT8 *)(&(g_pVFiriReg->FIRI_RXFIFO));
}
while (CSP_BITFEXT(g_pVFiriReg->FIRI_TSR, FIRI_TSR_TFP) > 0)
Sleep(0);
// Free the buffers
thisDev->writeBuf = NULL;
thisDev->readBuf = NULL;
// BSP level diabling
BSPFirEnableClock(FALSE); // Disable Fir Clock
BSPSirSetIOMUX(); // Set the IOMUX for SIR
BSPIrdaEnable(FALSE); // Disable IRDA
BSPIrdaSetMode(SIR_MODE); // Set IRDA mode to SIR
DEBUGMSG(ZONE_CLOSE, (TEXT("Fir: -FirClose\r\n")));
}
//-----------------------------------------------------------------------------
//
// Function: FirOpen
//
// This function opens the Fir device.
//
// Parameters:
// thisDev
// [in] .
//
// Returns:
// This function returns status of open device.
//
//-----------------------------------------------------------------------------
BOOLEAN FirOpen( pFirDevice_t thisDev )
{
PLIST_ENTRY pListEntry;
DEBUGMSG(ZONE_OPEN, (TEXT("Fir: +FirOpen\r\n")));
if (!thisDev->writeBuf)
thisDev->writeBuf = (PUCHAR)MyMemAlloc(MAX_IRDA_DATA_SIZE);
pListEntry = MyRemoveHeadList(&thisDev->rcvBufBuf);
if (pListEntry)
thisDev->readBuf = (PUCHAR) LIST_ENTRY_TO_RCV_BUF(pListEntry);
// BSP Initialization code
BSPFirEnableClock(TRUE); // Enable Fir Clock
BSPFirSetClock(); // Set Fir clock to 48 MHz
BSPFirSetIOMUX(); // Set the IOMUX for FIR
BSPIrdaEnable(TRUE); // Enable IRDA
BSPIrdaSetMode(FIR_MODE); // Set IRDA mode to FIR
// Setup FIRI speed
FirSetSpeed(thisDev);
// Setup FIRICR
g_pVFiriReg->FIRI_CR |= CSP_BITFVAL(FIRI_CR_BL, BURST_LENGTH_DEFAULT);
// Setup FIRITCR (transmitter)
g_pVFiriReg->FIRI_TCR = \
CSP_BITFVAL(FIRI_TCR_TDT, FIRI_TCR_TDT_96) | //Set DMA request level as 96 byte
CSP_BITFVAL(FIRI_TCR_TPP, FIRI_TCR_TPP_NO_INVERT) | // Set the Transmitter Polarity to normal.
CSP_BITFVAL(FIRI_TCR_TM, FIRI_TCR_TM_FIR) | // FIR mode
CSP_BITFVAL(FIRI_TCR_TE, FIRI_TCR_TE_DISABLE); // Disable Transmitter
// Clear FIRITCTR
g_pVFiriReg->FIRI_TCTR = 0;
// Setup FIRIRCR (receiver)
g_pVFiriReg->FIRI_RCR = \
CSP_BITFVAL(FIRI_RCR_RPEDE, FIRI_RCR_RPEDE_ENABLE) | // Receiver Packet End DMA Request is enabled
CSP_BITFVAL(FIRI_RCR_RDT, FIRI_RCR_RDT_32) | // Set DMA request level as 32 byte
CSP_BITFVAL(FIRI_RCR_RFOIE, FIRI_RCR_RFOIE_ENABLE) | // Receiver FIFO Overrun Interrupt is enabled
CSP_BITFVAL(FIRI_RCR_RPP, FIRI_RCR_RPP_INVERT)| // RM RPP not inverted
CSP_BITFVAL(FIRI_RCR_RM, FIRI_RCR_RM_FIR) | // RM FIR
CSP_BITFVAL(FIRI_RCR_RE, FIRI_RCR_RE_DISABLE); // Disable Transmitter
// Clear FIRITSR and FIRIRSR
g_pVFiriReg->FIRI_TSR = XMIT_INTR_MASK;
g_pVFiriReg->FIRI_RSR = RCV_INTR_MASK;
thisDev->rcvOffset = 0;
thisDev->writePending = FALSE;
//FirDumpReg();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -