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

📄 sir.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        //  then hand the sent packet back to the protocol.
        //  Otherwise, we're just delivering it synchronously from SirSend.
		if (firstBufIsPending)
		{
            DEBUGMSG(ZONE_SEND, (TEXT("Sir: Send Packet Pending!\r\n")));

			NdisMSendComplete(thisDev->ndisAdapterHandle, packetToSend, 
				(NDIS_STATUS)(sendSucceeded ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE));

			// If the packet was pended, it means this packet was not just
			// received in MiniportSend.  If we're being called from there,
			// we want them to pend the packet they just did receive, so we
			// return PENDING.
			Result = NDIS_STATUS_PENDING;
		} 
		else 
		{
            DEBUGMSG(ZONE_SEND, (TEXT("Sir: Send result!!!\r\n")));
			Result = sendSucceeded ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE;
		}
	}

    DEBUGMSG(ZONE_SEND, (TEXT("Sir: -SirSendPacketQ\r\n")));
	return Result;	
}


//-----------------------------------------------------------------------------
//
// Function: SirSend
//
// This function inserts packet to send queue and setup device to send.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//		Packet
//			[in] PNDIS_PACKET.
//
// Returns:  
//		This function returns packet send status.
//
//-----------------------------------------------------------------------------
NDIS_STATUS SirSend(pFirDevice_t thisDev, PNDIS_PACKET Packet)
{
	NDIS_STATUS result;

    DEBUGMSG(ZONE_SEND, (TEXT("Sir: +SirSend(thisDev=0x%x)\r\n"), (UINT)thisDev));

	// Use MiniportReserved as a LIST_ENTRY.  First check so no one
	// ever changes the size of these the wrong way.
	ASSERT(sizeof(Packet->MiniportReserved)>=sizeof(LIST_ENTRY));
	InsertTailList(&thisDev->SendQueue, (PLIST_ENTRY)Packet->MiniportReserved);	

    if(thisDev->writePending)
    {
        DEBUGMSG(ZONE_SEND, (TEXT("Sir: SirSend already pending!!!\r\n")));
        result = NDIS_STATUS_PENDING;
    }
    else
    {
		BOOLEAN firstBufIsPending = (BOOLEAN)(Packet != HEAD_SEND_PACKET(thisDev));
		result = SirSendPacketQ(thisDev, firstBufIsPending);
	}
    DEBUGMSG(ZONE_SEND, (TEXT("Sir: -SirSend [%s]\r\n"), DBG_NDIS_RESULT_STR(result)));
	return result;
}


//-----------------------------------------------------------------------------
//
// Function: SirReceive
//
// Setup for SIR receive.
//
// Parameters:
//		thisDev
//			[in] .
//
// Returns:  
//		None.
//
//-----------------------------------------------------------------------------
VOID SirReceive(pFirDevice_t thisDev)
{
    DEBUGMSG(ZONE_RECV, (TEXT("Sir: +SirReceive, 0x%0x8.\r\n"), thisDev));

	// Disable Transmitter and interrupt first
	SirDisableInterrupt(thisDev);
	
	thisDev->AdapterState = ADAPTER_RX;

    // Enable Transmit interrupt first
	CSP_BITFINS(g_pVSIRReg->UCR4, UART_UCR4_DREN, UART_UCR4_DREN_ENABLE);

    DEBUGMSG(ZONE_RECV, (TEXT("Sir: -SirReceive 0x%x\r\n"),g_pVSIRReg->USR2));
}


//-----------------------------------------------------------------------------
//
// Function: SirReceivePacket
//
//  This function receives and analyze the raw IR data.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//
// Returns:  
//		This function returns true or false.
//
//-----------------------------------------------------------------------------
static BOOLEAN SirReceivePacket(pFirDevice_t thisDev)
{
	UINT rawBufPos, rawBytesRead;
	BOOLEAN result;
	UCHAR thisch;
	PLIST_ENTRY pListEntry;

    DEBUGMSG(ZONE_RECV, (TEXT("Sir: +SirReceivePacket\r\n")));

    //  Read in and process groups of incoming bytes from the FIFO.
    //  NOTE:  We have to loop once more after getting MAX_RCV_DATA_SIZE
    //         bytes so that we can see the 'EOF'; hence <= and not <.
	while ((thisDev->portInfo.rcvState != STATE_SAW_EOF) && (thisDev->portInfo.rcvBufPos <= MAX_RCV_DATA_SIZE)) 
	{
		if (thisDev->portInfo.rcvState == STATE_CLEANUP) 
		{
            //  We returned a complete packet last time, but we had read some
            //  extra bytes, which we stored into the rawBuf after returning
            //  the previous complete buffer to the user.  
            //  So instead of calling DoRcvDirect in this first execution of this loop, 
            //  we just use these previously-read bytes.
            //  (This is typically only 1 or 2 bytes).
			rawBytesRead = thisDev->portInfo.rcvBufPos;
			thisDev->portInfo.rcvState = STATE_INIT;
			thisDev->portInfo.rcvBufPos = 0;
		} 
		else  
		{
			rawBytesRead = SirHwRead(thisDev->portInfo.rawBuf, SER_FIFO_DEPTH);
			if (rawBytesRead == (UINT)-1) 
			{
				// Error. Reset the state
				thisDev->portInfo.rcvState = STATE_INIT;
				thisDev->portInfo.rcvBufPos = 0;
				continue;
			} 
			else if (rawBytesRead == 0) 
			{
                DEBUGMSG(ZONE_RECV, (TEXT("Sir: 0 byte read, break\r\n")));
				break;
			}
		}

        //  Let the receive state machine process this group of characters
        //  we got from the FIFO.
        //  NOTE:  We have to loop once more after getting MAX_RCV_DATA_SIZE
        //         bytes so that we can see the 'EOF'; hence <= and not <.        
		for (rawBufPos = 0; 
			 ((thisDev->portInfo.rcvState != STATE_SAW_EOF) && 
			  (rawBufPos < rawBytesRead) && 
			  (thisDev->portInfo.rcvBufPos <= MAX_RCV_DATA_SIZE)); 
			 rawBufPos++) 
		{
			thisch = thisDev->portInfo.rawBuf[rawBufPos];
            DEBUGMSG(ZONE_RECV, (TEXT("Sir: cur state=%d, data=0x%x\r\n"),thisDev->portInfo.rcvState,thisch));
			switch (thisDev->portInfo.rcvState) 
			{
				case STATE_INIT:
					switch (thisch) 
					{
						case SLOW_IR_BOF:
							thisDev->portInfo.rcvState = STATE_GOT_BOF;
							break;
						case SLOW_IR_EOF:
						case SLOW_IR_ESC:
						default:
							 //  This is meaningless noise.  Scan past it.
							break;
					}
					break;

				case STATE_GOT_BOF:
					switch (thisch) 
					{
						case SLOW_IR_BOF:
							break;
						case SLOW_IR_EOF:
							DEBUGMSG(ZONE_ERROR, (TEXT("EOF in absorbing-BOFs state in DoRcv")));
							thisDev->portInfo.rcvState = STATE_INIT;
							break;
						case SLOW_IR_ESC:
							thisDev->portInfo.rcvBufPos = 0;
							thisDev->portInfo.rcvState = STATE_ESC_SEQUENCE;
							break;
						default:
							thisDev->portInfo.readBuf[0] = thisch;
							thisDev->portInfo.rcvBufPos = 1;
							thisDev->portInfo.rcvState = STATE_ACCEPTING;
							break;
					}
					break;

				case STATE_ACCEPTING:
					switch (thisch) 
					{
						case SLOW_IR_BOF:  
							DEBUGMSG(ZONE_WARN, (TEXT("WARNING: BOF during accepting state in DoRcv")));
							thisDev->portInfo.rcvState = STATE_INIT;
							thisDev->portInfo.rcvBufPos = 0;
							break;
							
						case SLOW_IR_EOF:
							if (thisDev->portInfo.rcvBufPos < 
								IR_ADDR_SIZE + IR_CONTROL_SIZE + SLOW_IR_FCS_SIZE) 
							{
								thisDev->portInfo.rcvState = STATE_INIT;
								thisDev->portInfo.rcvBufPos = 0;
							} 
							else  
							{
								thisDev->portInfo.rcvState = STATE_SAW_EOF;
							}
							break;
							
						case SLOW_IR_ESC:
							thisDev->portInfo.rcvState = STATE_ESC_SEQUENCE;
							break;
							
						default:
							thisDev->portInfo.readBuf[thisDev->portInfo.rcvBufPos++] = thisch;
							break;
					}
					break;

				case STATE_ESC_SEQUENCE:
					switch (thisch) 
					{
						case SLOW_IR_EOF:
						case SLOW_IR_BOF:
						case SLOW_IR_ESC:
                            //  ESC + {EOF|BOF|ESC} is an abort sequence
							DEBUGMSG(ZONE_ERROR, (TEXT("DoRcv - abort sequence; ")
									TEXT("ABORTING IR PACKET: (got following ")
									TEXT("packet + ESC,%xh)"), 
									(UINT)thisch));
							thisDev->portInfo.rcvState = STATE_INIT;
							thisDev->portInfo.rcvBufPos = 0;
							break;

						case SLOW_IR_EOF^SLOW_IR_ESC_COMP:
						case SLOW_IR_BOF^SLOW_IR_ESC_COMP:
						case SLOW_IR_ESC^SLOW_IR_ESC_COMP:
							thisDev->portInfo.readBuf[thisDev->portInfo.rcvBufPos++] = thisch ^ SLOW_IR_ESC_COMP;
							thisDev->portInfo.rcvState = STATE_ACCEPTING;
							break;

						default:
							DEBUGMSG(ZONE_ERROR, (TEXT("Unnecessary escape sequence: (got following packet + ESC,%xh"), (UINT)thisch));
							thisDev->portInfo.readBuf[thisDev->portInfo.rcvBufPos++] = thisch ^ SLOW_IR_ESC_COMP;
							thisDev->portInfo.rcvState = STATE_ACCEPTING;
							break;
					}
					break;

				case STATE_SAW_EOF:
				default:
					DEBUGMSG(ZONE_ERROR, (TEXT("Illegal state in DoRcv")));
					thisDev->portInfo.rcvBufPos = 0;
					thisDev->portInfo.rcvState = STATE_INIT;
					return 0;
			}
		}
	}



    //  Set result and do any post-cleanup.
	switch (thisDev->portInfo.rcvState) 
	{
		case STATE_SAW_EOF:
			//  We've read in the entire packet.
			//  Queue it and return TRUE.
			DEBUGMSG(ZONE_RECV, (TEXT("Sir:  *** DoRcv returning with COMPLETE packet, read %d bytes ***"), 
				thisDev->portInfo.rcvBufPos));

			ASSERT(!IsListEmpty(&thisDev->rcvBufBuf));

			//QueueReceivePacket(thisDev, thisDev->portInfo.readBuf, thisDev->portInfo.rcvBufPos, FALSE);
			QueueReceivePacket(thisDev, thisDev->portInfo.readBuf, thisDev->portInfo.rcvBufPos);

			// The protocol has our buffer.  Get a new one.
			pListEntry = RemoveHeadList(&thisDev->rcvBufBuf);
			thisDev->portInfo.readBuf = (PUCHAR) LIST_ENTRY_TO_RCV_BUF(pListEntry);

			result = TRUE;

			if (rawBufPos < rawBytesRead) 
			{
                //  We have some more unprocessed bytes in the raw buffer.
                //  Move these to the beginning of the raw buffer
                //  go to the CLEANUP state, which indicates that these
                //  bytes be used up during the next call.
                //  (This is typically only 1 or 2 bytes).
                //  Note:  We can't just leave these in the raw buffer because
                //         we might be supporting connections to multiple COM ports.
				memcpy(thisDev->portInfo.rawBuf, &thisDev->portInfo.rawBuf[rawBufPos], rawBytesRead-rawBufPos);
				thisDev->portInfo.rcvBufPos = rawBytesRead-rawBufPos;
				thisDev->portInfo.rcvState = STATE_CLEANUP;
			} 
			else  
			{
				thisDev->portInfo.rcvState = STATE_INIT;
			}
			break;

		default:
			if (thisDev->portInfo.rcvBufPos > MAX_RCV_DATA_SIZE) 
			{
				DEBUGMSG(ZONE_ERROR, (TEXT("Sir: Overrun in DoRcv : read %d=%xh bytes:"), 
					thisDev->portInfo.rcvBufPos, thisDev->portInfo.rcvBufPos));
				thisDev->portInfo.rcvBufPos = 0;
				thisDev->portInfo.rcvState = STATE_INIT;
			} 
			else 
			{
				DEBUGMSG(ZONE_RECV, (TEXT("Sir: DoRcv returning with partial packet, read %d bytes"), 
					thisDev->portInfo.rcvBufPos));
			}
			result = FALSE;
			break;
	}
    DEBUGMSG(ZONE_RECV, (TEXT("Sir: -SirReceivePacket\r\n")));
	return result;
}


//-----------------------------------------------------------------------------
//
// Function: SirInterruptHandler
//
// This function is the interrupt handler for Sir device.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//
// Returns:  
//		None.
//
//-----------------------------------------------------------------------------
VOID SirInterruptHandler(pFirDevice_t thisDev)
{
	UINT32 tempRegData = 0, loops = 0;;
	
    DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: +SirInterruptHandler, 0x%08x\r\n"), thisDev));
	// Get interrupt status
	tempRegData = g_pVSIRReg->USR2;

	if (tempRegData & SIR_INTR_MASK) 
	{
		if (thisDev->writePending) 
		{
			// Tx
			DEBUGMSG(ZONE_THREAD, (TEXT("Sir: COM INTERRUPT: xmit reg empty, 0x%08x."), tempRegData));

			if (tempRegData & CSP_BITFMASK(UART_USR2_TXFE)) 
			{
				SirHwWrite(thisDev);

				thisDev->writePending = FALSE;

                //  If we just sent the last frame to be sent at the old speed,
                //  set the hardware to the new speed.
				if (thisDev->setSpeedAfterCurrentSendPacket) 
				{
					thisDev->setSpeedAfterCurrentSendPacket = FALSE;
                        DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: set new speed\r\n")));
					SetSpeed(thisDev);
				}
			}
            // Any more Tx packets?
			if (!IsListEmpty(&thisDev->SendQueue))  
			{
                // Kick off another Tx
				SirSendPacketQ(thisDev, TRUE);
			}
			else 
			{
                //  There are no more bytes to send; 
                //  reset interrupts for receive mode.
				SirReceive(thisDev);
			}
		} 
		else if(tempRegData & CSP_BITFMASK(UART_USR2_RDR)) 
		{
			// Rx
			DEBUGMSG(ZONE_THREAD, (TEXT("COM INTERRUPT: rcv data available! 0x%08x\r\n"), tempRegData));

			thisDev->nowReceiving = TRUE;

			if (!thisDev->mediaBusy) 
			{
                // If we have just started receiving a packet, indicate media-busy
                // to the protocol.
				thisDev->mediaBusy = TRUE;
                DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: HandleInterrupt indicating media busy\r\n")));

				NdisReleaseSpinLock(&thisDev->Lock);
				NdisMIndicateStatus(thisDev->ndisAdapterHandle, NDIS_STATUS_MEDIA_BUSY, NULL, 0);
				NdisMIndicateStatusComplete(thisDev->ndisAdapterHandle);
				NdisAcquireSpinLock(&thisDev->Lock);
			}

			if (SirReceivePacket(thisDev)) 
			{
                //  The receive engine has accumulated an entire frame.
                //  Request a deferred callback so we can deliver the frame
                //  when not in interrupt context.
				DeliverFullBuffers(thisDev);
			}
        }
		else 
		{
            DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: COM INTERRUPT: dummy interrupt, 0x%08x, ignored.\r\n"), tempRegData));
		}
    }
	else 
	{
        DEBUGMSG(ZONE_ERROR, (TEXT("Sir: SirInterruptHandler: unexpected interrupt comes, 0x%08x.\r\n"), tempRegData));
		return;
	}
}

⌨️ 快捷键说明

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