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

📄 comm.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
		case 150:		val = 769;	break;
		case 300:		val = 384;	break;
		case 600:		val = 192;	break;
		case 1200:		val = 96;	break;
		case 1800:		val = 64;	break;
		case 2000:		val = 58;	break;
		case 2400:		val = 48;	break;
		case 3600:		val = 32;	break;
		case 4800:		val = 24;	break;
		case 7200:		val = 16;	break;
		case 9600:		val = 12;	break;
		case 12800:		val = 9;	break;
		case 14400:		val = 8;	break;
		case 19200:		val = 6;	break;
		case 23040:		val = 5;	break;
		case 28800:		val = 4;	break;
		case 38400:		val = 3;	break;
		case 57600:		val = 2;	break;
		case 115200:	val = 1;	break;
		default:
			*pErrorCode = (ULONG)-1;
			val = 0;
	}

	DEBUGMSG(ZONE_FIRMODE, (TEXT("LookUpValue <--\r\n")));
    return val;
}

/*
 *************************************************************************
 *  SetSpeed
 *************************************************************************
 *
 *
 */
BOOLEAN SetSpeed(IrDevice *thisDev)
{
	UINT bitsPerSec = thisDev->linkSpeedInfo->bitsPerSec;
	BOOLEAN dongleSet, result = TRUE;

	DBGWARN((TEXT(" **** SetSpeed(%xh, %d bps) ***************************"), thisDev->portInfo.ioBase, bitsPerSec));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("SetSpeed -->\r\n")));

    NdisAcquireSpinLock(&thisDev->QueueLock);
	if (!IsListEmpty(&thisDev->SendQueue)){
		/*
		 *  We can't set speed in the hardware while 
		 *  send packets are queued.
		 */

        DEBUGMSG(DBG_ERR, (TEXT("Warning: delaying set speed until all packets sent!\r\n")));

        if (thisDev->SendQueue.Blink==thisDev->SendQueue.Flink)
        {
            // Only one.  We need to change after this one.
            thisDev->setSpeedAfterCurrentSendPacket = TRUE;
        }
        else
        {
            thisDev->lastPacketAtOldSpeed = CONTAINING_RECORD(thisDev->SendQueue.Blink,
                                                              NDIS_PACKET,
                                                              MiniportReserved);
        }
        NdisReleaseSpinLock(&thisDev->QueueLock);
		DBGOUT((TEXT("delaying set-speed because send pkts queued")));
		return TRUE;
	}
	else if (thisDev->portInfo.writePending){
		thisDev->setSpeedAfterCurrentSendPacket = TRUE;
        NdisReleaseSpinLock(&thisDev->QueueLock);
		DBGOUT((TEXT("will set speed after current write pkt")));
		return TRUE;
	}
    else
    {
        NdisReleaseSpinLock(&thisDev->QueueLock);
    }

	/*
	 *  Disable interrupts while changing speed.
	 *  (This is especially important for the ADAPTEC dongle;
	 *   we may get interrupted while setting command mode
	 *   between writing 0xff and reading 0xc3).
	 */
	SetCOMInterrupts(thisDev, FALSE);		

	/*
	 *  First, set the UART's speed to 9600 baud.
	 *  Some of the dongles need to receive their command sequences at this speed.
	 */
//	SetUARTSpeed(thisDev, 9600);

	dongleSet = NSC_DEMO_SetSpeed(thisDev, thisDev->portInfo.ioBase, bitsPerSec, thisDev->portInfo.dongleContext);
	//
	// debug info.
	//
	thisDev->portInfo.PacketsReceived_DEBUG = 0;
	if (!dongleSet){
		DBGERR((TEXT("Dongle set-speed failed")));
		result = FALSE;
	}

	/*
	 *  Now set the speed for the COM port
	 */
	SetUARTSpeed(thisDev, bitsPerSec);

	thisDev->currentSpeed = bitsPerSec;

#ifdef OUTMSG
	RETAILMSG(1,(TEXT("%d bps\r\n"), bitsPerSec));
#endif

	if(thisDev->currentSpeed > MAX_SIR_SPEED) {
		SetFirMode();
	} else {
		SetSirMode();
	}

	SetCOMInterrupts(thisDev, TRUE);		

	DEBUGMSG(ZONE_FIRMODE, (TEXT("SetSpeed <--\r\n")));
	return result;
}



/*
 *************************************************************************
 *  DoSend
 *************************************************************************
 *
 *
 *  Send an IR packet which has already been formatted with IR header
 *  and escape sequences.
 *
 *  Return TRUE iff the send succeeded.
 */
BOOLEAN DoSend(IrDevice *thisDev, PNDIS_PACKET packetToSend)
{
	BOOLEAN convertedPacket;

	LOG(TEXT("DoSend, poll bit:"), 0);
	DBGOUT((TEXT("DoSend(%xh)"), thisDev->portInfo.ioBase));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("DoSend -->\r\n")));

	/*
	 *  Convert the NDIS packet to an IRDA packet.
	 */
	convertedPacket = NdisToIrPacket(thisDev, 
							packetToSend,
							(UCHAR *)thisDev->portInfo.writeBuf,
							MAX_IRDA_DATA_SIZE,
							&thisDev->portInfo.writeBufLen);
	if (convertedPacket){

		LOG(TEXT("Send conversion complete; bytes: "), thisDev->portInfo.writeBufLen);
		DBGPRINTBUF(thisDev->portInfo.writeBuf, thisDev->portInfo.writeBufLen);

		/*
		 *  Disable interrupts while setting up the send FSM.
		 */
		SetCOMInterrupts(thisDev, FALSE);

		/*
		 *  Finish initializing the send FSM.
		 */
		thisDev->portInfo.writeBufPos = 0;
		thisDev->portInfo.writePending = TRUE;
		DBGOUT((TEXT("writePending = TRUE")));
		thisDev->nowReceiving = FALSE;   

		SetCOMInterrupts(thisDev, TRUE);

		/*
		 *  Just enable transmit interrupts to start the ball rolling.
		 */

		LOG(TEXT("DoSend - staging complete; POLL bit:"), (UINT)(thisDev->portInfo.writeBuf[1] & (UCHAR)0x10));
	}
	else {
		DBGERR((TEXT("Couldn't convert packet in DoSend()")));
	}

	DEBUGMSG(ZONE_FIRMODE, (TEXT("DoSend <--\r\n")));
	return convertedPacket;
}



/*
 *************************************************************************
 *  StepSendFSM
 *************************************************************************
 *
 *
 *  Step the send fsm to send a few more bytes of an IR frame.
 *  Return TRUE only after an entire frame has been sent.
 *
 */
BOOLEAN StepSendFSM(IrDevice *thisDev)
{
	UINT i, bytesAtATime, startPos = thisDev->portInfo.writeBufPos;
	UCHAR lineStatReg;
	BOOLEAN result;
	UINT maxLoops;

	DEBUGMSG(ZONE_FIRMODE, (TEXT("StepSendFSM -->\r\n")));
	/*   
	 *  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->currentSpeed > 115200){
		maxLoops = REG_TIMEOUT_LOOPS;
	}
	else {
		maxLoops = REG_POLL_LOOPS;
	}


	/*
	 *  Write databytes as long as we have them and the UART's FIFO hasn't filled up.
	 */
	while (thisDev->portInfo.writeBufPos < thisDev->portInfo.writeBufLen){

		/*
		 *  If this COM port has a FIFO, we'll send up to the FIFO size (16 bytes).
		 *  Otherwise, we can only send one byte at a time.
		 */
		if (thisDev->portInfo.haveFIFO){
			bytesAtATime = MIN(FIFO_SIZE, (thisDev->portInfo.writeBufLen - thisDev->portInfo.writeBufPos));
		}
		else {
			bytesAtATime = 1;
		}


		/*
		 *  Wait for ready-to-send.
		 */
		i = 0;
		do {
			lineStatReg = READ_REGISTER_UCHAR(pIrLSR);	
		} while (!(lineStatReg & LINESTAT_XMIT_HOLDING_REG_EMPTY) && (++i < maxLoops));
		if (!(lineStatReg & LINESTAT_XMIT_HOLDING_REG_EMPTY)){
			break;
		}

		/*
		 *  Send the next byte or FIFO-volume of bytes.
		 */
		for (i = 0; i < bytesAtATime; i++){
			WRITE_REGISTER_UCHAR(pIrTBR,											
				thisDev->portInfo.writeBuf[thisDev->portInfo.writeBufPos++]);		
		}

	}

	/*
	 *  The return value will indicate whether we've sent the entire frame.
	 */
	if (thisDev->portInfo.writeBufPos >= thisDev->portInfo.writeBufLen){

		if (thisDev->setSpeedAfterCurrentSendPacket){
			/*
			 *  We'll be changing speeds after this packet, 
			 *  so poll until the packet bytes have been completely sent out the FIFO.
			 *  After the 16550 says that it is empty, there may still be one remaining
			 *  byte in the FIFO, so flush it out by sending one more BOF.
			 */
			i = 0;
			do {
				lineStatReg = (UCHAR)READ_REGISTER_UCHAR(pIrLSR);	
			} while (!(lineStatReg & SERIAL_LSR_THRE) && (++i < REG_TIMEOUT_LOOPS));

			WRITE_REGISTER_UCHAR(pIrTBR,(UCHAR)SLOW_IR_EXTRA_BOF);		
			i = 0;
			do {
				lineStatReg = (UCHAR)READ_REGISTER_UCHAR(pIrLSR);	
			} while (!(lineStatReg & SERIAL_LSR_THRE) && (++i < REG_TIMEOUT_LOOPS));
		}

		result = TRUE;
	}
	else {
		result = FALSE;
	}

	RETAILMSG(0, (TEXT("StepSendFSM wrote %d bytes (%s):\r\n"), (UINT)(thisDev->portInfo.writeBufPos-startPos), (PUCHAR)(result ? "DONE" : "not done")));

	DEBUGMSG(ZONE_FIRMODE, (TEXT("StepSendFSM <--\r\n")));

	return result;
	
}


/*
 *************************************************************************
 *  StepReceiveFSM
 *************************************************************************
 *
 *
 *  Step the receive fsm to read in a piece of an IR frame;
 *  strip the BOFs and EOF, and eliminate escape sequences.
 *  Return TRUE only after an entire frame has been read in.
 *
 */
BOOLEAN StepReceiveFSM(IrDevice *thisDev)
{
	UINT rawBufPos, rawBytesRead;
	BOOLEAN result;
	UCHAR thisch;
    PLIST_ENTRY pListEntry;

	DBGOUT((TEXT("StepReceiveFSM(%xh)"), thisDev->portInfo.ioBase));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("StepReceiveFSM -->\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.readBufPos <= 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.readBufPos;
			thisDev->portInfo.rcvState = STATE_INIT;
			thisDev->portInfo.readBufPos = 0;
		}
		else {
			rawBytesRead = DoRcvDirect(thisDev->portInfo.ioBase, thisDev->portInfo.rawBuf, FIFO_SIZE);
			if (rawBytesRead == (UINT)-1){
				/*
				 *  Receive error occurred.  Go back to INIT state.
				 */
				thisDev->portInfo.rcvState = STATE_INIT;
				thisDev->portInfo.readBufPos = 0;
				continue;
			}	
			else if (rawBytesRead == 0){
				/*
				 *  No more receive bytes.  Break out.
				 */
				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.readBufPos <= MAX_RCV_DATA_SIZE)); 
			 rawBufPos++){

			thisch = thisDev->portInfo.rawBuf[rawBufPos];

			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 garbage.  Scan past it.
							 */
							break;
					}
					break;

				case STATE_GOT_BOF:
					switch (thisch){
						case SLOW_IR_BOF:
							break;
						case SLOW_IR_EOF:
							/*
							 *  Garbage
							 */
							DBGERR((TEXT("EOF in absorbing-BOFs state in DoRcv")));
							thisDev->portInfo.rcvState = STATE_INIT;
							break;
						case SLOW_IR_ESC:
							/*
							 *  Start of data.  
							 *  Our first data byte happens to be an ESC sequence.
							 */
							thisDev->portInfo.readBufPos = 0;
							thisDev->portInfo.rcvState = STATE_ESC_SEQUENCE;
							break;
						default:
							thisDev->portInfo.readBuf[0] = thisch;
							thisDev->portInfo.readBufPos = 1;
							thisDev->portInfo.rcvState = STATE_ACCEPTING;
							break;
					}
					break;

				case STATE_ACCEPTING:
					switch (thisch){
						case SLOW_IR_BOF:  
							/*
							 *  Meaningless garbage
							 */
							DBGWARN((TEXT("WARNING: BOF during accepting state in DoRcv")));
							thisDev->portInfo.rcvState = STATE_INIT;
							thisDev->portInfo.readBufPos = 0;
							break;
						case SLOW_IR_EOF:
							if (thisDev->portInfo.readBufPos < 
									IR_ADDR_SIZE+IR_CONTROL_SIZE+SLOW_IR_FCS_SIZE){
								thisDev->portInfo.rcvState = STATE_INIT;
								thisDev->portInfo.readBufPos = 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.readBufPos++] = 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
							 */
							DBGERR((TEXT("DoRcv - abort sequence; ")
                                    TEXT("ABORTING IR PACKET: (got following ")
                                    TEXT("packet + ESC,%xh)"), 

⌨️ 快捷键说明

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