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

📄 comm.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
                                    (UINT)thisch));
							DBGPRINTBUF(thisDev->portInfo.readBuf, thisDev->portInfo.readBufPos);
							thisDev->portInfo.rcvState = STATE_INIT;
							thisDev->portInfo.readBufPos = 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.readBufPos++] = thisch ^ SLOW_IR_ESC_COMP;
							thisDev->portInfo.rcvState = STATE_ACCEPTING;
							break;

						default:
							DBGERR((TEXT("Unnecessary escape sequence: (got following packet + ESC,%xh"), (UINT)thisch));
							DBGPRINTBUF(thisDev->portInfo.readBuf, thisDev->portInfo.readBufPos);

							thisDev->portInfo.readBuf[thisDev->portInfo.readBufPos++] = thisch ^ SLOW_IR_ESC_COMP;
							thisDev->portInfo.rcvState = STATE_ACCEPTING;
							break;
					}
					break;

				case STATE_SAW_EOF:
				default:
					DBGERR((TEXT("Illegal state in DoRcv")));
					thisDev->portInfo.readBufPos = 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.
			 */
			DBGOUT((TEXT(" *** DoRcv returning with COMPLETE packet, read %d bytes ***"), 
                thisDev->portInfo.readBufPos));
            QueueReceivePacket(thisDev, thisDev->portInfo.readBuf, thisDev->portInfo.readBufPos, FALSE);

            // The protocol has our buffer.  Get a new one.

            ASSERT(!IsListEmpty(&thisDev->rcvBufBuf));
#if 1
            pListEntry = RemoveHeadList(&thisDev->rcvBufBuf);
            thisDev->portInfo.readBuf = LIST_ENTRY_TO_RCV_BUF(pListEntry);
#else
            thisDev->portInfo.readBuf = (PVOID)RemoveHeadList(&thisDev->rcvBufBuf);
#endif 

			result = TRUE;

			if (rawBufPos < rawBytesRead){
				/*
				 *  This is ugly.
				 *  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.readBufPos = rawBytesRead-rawBufPos;
				thisDev->portInfo.rcvState = STATE_CLEANUP;
			}
			else {
				thisDev->portInfo.rcvState = STATE_INIT;
			}
			break;

		default:
			if (thisDev->portInfo.readBufPos > MAX_RCV_DATA_SIZE){
				DBGERR((TEXT("Overrun in DoRcv : read %d=%xh bytes:"), 
                    thisDev->portInfo.readBufPos, thisDev->portInfo.readBufPos));
				DBGPRINTBUF(thisDev->portInfo.readBuf, thisDev->portInfo.readBufPos);
				thisDev->portInfo.readBufPos = 0;
				thisDev->portInfo.rcvState = STATE_INIT;
			}
			else {
				DBGOUT((TEXT("DoRcv returning with partial packet, read %d bytes"), 
                    thisDev->portInfo.readBufPos));
			}
			result = FALSE;
			break;
	}

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



/*
 *************************************************************************
 * COM_ISR
 *************************************************************************
 *
 *
 */
VOID COM_ISR(IrDevice *thisDev, BOOLEAN *claimingInterrupt, BOOLEAN *requireDeferredCallback)
{

	/*
	 *  Get the interrupt status register value.
	 */
	UCHAR intId = (UCHAR)READ_REGISTER_UCHAR(pIrIIR);	

	if (intId & INTID_INTERRUPT_NOT_PENDING){
		/*
		 *  This is NOT our interrupt.  
		 *  Set carry bit to pass the interrupt to the next driver in the chain.
		 */
		*claimingInterrupt = *requireDeferredCallback = FALSE;
		DEBUGMSG(1, (TEXT("COM_ISR: INTID_INTERRUPT_NOT_PENDING!!!!!!!!!!!!!!!!!!!!!!! intId = 0x%x\r\n"), intId));
	}
	else {
		/*
		 *  This is our interrupt
		 */

		/*
		 *  In some odd situations, we can get interrupt bits that don't
		 *  get cleared; we don't want to loop forever in this case, so keep a counter.
		 */
		UINT loops = 0;

		*claimingInterrupt = TRUE;
		*requireDeferredCallback = FALSE;

//		DEBUGMSG(1, (TEXT("COM_ISR: intId = 0x%x\r\n"), intId));

		while (!(intId & INTID_INTERRUPT_NOT_PENDING) && (loops++ < 0x10)){

			switch (intId & INTID_INTIDMASK){

				case INTID_MODEMSTAT_INT:
					READ_REGISTER_UCHAR(pIrMSR);	
					break;

				case INTID_XMITREG_INT:
					if (thisDev->portInfo.writePending){

						/*
						 *  Try to send a few more bytes
						 */
						if (StepSendFSM(thisDev)){

							/*
							 *  There are no more bytes to send; 
							 *  reset interrupts for receive mode.
							 */
							thisDev->portInfo.writePending = FALSE;
							SetCOMInterrupts(thisDev, TRUE);

							/*
							 *  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;
								thisDev->setSpeedNow = TRUE;
							}

							/*
							 *  Request a DPC so that we can try
							 *  to send other pending write packets.
							 */
							*requireDeferredCallback = TRUE;
						}
					}

					break;

				case INTID_RCVDATAREADY_INT:
					if(intId & 0x08){
						DBGOUT((TEXT("COM INTERRUPT: Character time out!")));
					}
					thisDev->nowReceiving = TRUE;

					if (!thisDev->mediaBusy){
						thisDev->mediaBusy = TRUE;
						thisDev->haveIndicatedMediaBusy = FALSE;
						*requireDeferredCallback = TRUE;
					}

					if (StepReceiveFSM(thisDev)){
						/*
						 *  The receive engine has accumulated an entire frame.
						 *  Request a deferred callback so we can deliver the frame
						 *  when not in interrupt context.
						 */
						*requireDeferredCallback = TRUE;
						thisDev->nowReceiving = FALSE;
					}

					break;

				case INTID_RCVLINESTAT_INT:
					break;
				default:
					break;
			}

			/*
			 *  After we service each interrupt condition, we read the line status register.
			 *  This clears the current interrupt, and a new interrupt may then appear in
			 *  the interrupt-id register.
			 */
			READ_REGISTER_UCHAR(pIrLSR);	
			intId = (UCHAR)READ_REGISTER_UCHAR(pIrIIR);	
		}
	}
}

/*
 *************************************************************************
 *  OpenCOM
 *************************************************************************
 *
 *  Initialize UART registers
 *
 */
BOOLEAN OpenCOM(IrDevice *thisDev)
{
	BOOLEAN dongleInit;
	USHORT intIdReg;
	UCHAR	val;

	DEBUGMSG(ZONE_FIRMODE, (TEXT("OpenCOM -->\r\n")));

	SetRegInit();
	/*
	 *  Disable all COM interrupts while setting up.
	 */
	SetCOMInterrupts(thisDev, FALSE);

	/*
	 *  Set request-to-send and clear data-terminal-ready.
	 *  Note:  ** Bit 3 must be set to enable interrupts.
	 */
	WRITE_REGISTER_UCHAR(pIrMCR, SERIAL_MCR_IRQ_ENABLE|SERIAL_MCR_RTS);

	/*
	 *  Set dongle- or part-specific info to default
	 */
	thisDev->portInfo.hwCaps.supportedSpeedsMask	= ALL_SLOW_IRDA_SPEEDS;
	thisDev->portInfo.hwCaps.turnAroundTime_usec	= DEFAULT_TURNAROUND_usec;
	thisDev->portInfo.hwCaps.extraBOFsRequired		= 0;

	/*
	 *  Set the COM port speed to the default 9600 baud.
	 *  Some dongles can only receive cmd sequences at this speed.
	 */
	SetUARTSpeed(thisDev, 9600);

	dongleInit = NSC_DEMO_Init( thisDev );		
	if (!dongleInit){
		DBGERR((TEXT("Dongle-specific init failed in OpenCOM")));
		return FALSE;
	}

	/*
	 *  Set request-to-send and clear data-terminal-ready.
	 *  Note:  ** Bit 3 must be set to enable interrupts.
	 */
	WRITE_REGISTER_UCHAR(pIrMCR, SERIAL_MCR_IRQ_ENABLE|SERIAL_MCR_RTS);


	/*
	 *  Set speed to default for the entire part.  
	 *  (This is redundant in most, but not all, cases.)
	 */
	thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];;

	SetSpeed(thisDev);

	/*
	 *  Clear the FIFO control register
	 */
//    SetFIFOCR(thisDev,FALSE);   	
	WRITE_REGISTER_UCHAR(pIrFCR, 0x00);
	/*  
	 *  Set up the FIFO control register to use both read and write FIFOs (if 16650),
	 *  and with a receive FIFO trigger level of 1 byte.
	 */
//    SetFIFOCR(thisDev,TRUE);   	
	WRITE_REGISTER_UCHAR(pIrFCR, SERIAL_FCR_TXMT_RESET|SERIAL_FCR_RCVR_RESET|SERIAL_FCR_ENABLE);

	/*
	 *  Check whether we're running on a 16550,which has a 16-byte write FIFO.
	 *  In this case, we'll be able to blast up to 16 bytes at a time.
	 */
	intIdReg = READ_REGISTER_UCHAR(pIrFCR);
	thisDev->portInfo.haveFIFO = (BOOLEAN)((intIdReg & SERIAL_14_BYTE_HIGH_WATER) == SERIAL_14_BYTE_HIGH_WATER);

	while(1){
		val = READ_REGISTER_UCHAR(pIrIIR);
		if( val & SERIAL_IIR_NO_INTERRUPT_PENDING ){
			break;//no interrupts
		}else{
			switch( val & 0x0e ){
				case SERIAL_IIR_RLS://RLS interrupts
					READ_REGISTER_UCHAR(pIrLSR);
					break;
				case SERIAL_IIR_RDA://Rx available interrupts
				case SERIAL_IIR_CTI://Character timer-out interrupts
					READ_REGISTER_UCHAR(pIrRBR);
					break;
				case SERIAL_IIR_THRE://Tx empty interrupts
					break;
				case SERIAL_IIR_MS://Modem status interrupts
					READ_REGISTER_UCHAR(pIrMSR);
					break;
				default:
					break;
			}
		}
	}

	/*
	 *  Start out in receive mode.
	 *  We always want to be in receive mode unless we're transmitting a frame.
	 */
	SetCOMInterrupts(thisDev, TRUE);

	DBGOUT((TEXT("OpenCOM succeeded")));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("OpenCOM <--\r\n")));
	return TRUE;
}


/*
 *************************************************************************
 *  CloseCOM
 *************************************************************************
 *
 */
VOID CloseCOM(IrDevice *thisDev)
{
	DEBUGMSG(ZONE_FIRMODE, (TEXT("CloseCOM -->\r\n")));
	/*
	 *  Do special deinit for dongles.
	 *  Some dongles can only rcv cmd sequences at 9600, so set this speed first.
	 */
	thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];;

	SetSpeed(thisDev);

	NSC_DEMO_Deinit(thisDev->portInfo.ioBase, thisDev->portInfo.dongleContext);		

	SetCOMInterrupts(thisDev, FALSE);

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



/*
 *************************************************************************
 *  DoRcvDirect
 *************************************************************************
 *
 *  Read up to maxBytes bytes from the UART's receive FIFO.
 *  Return the number of bytes read or (UINT)-1 if an error occurred.
 *
 */
UINT DoRcvDirect(UINT ioBase, UCHAR *data, UINT maxBytes)
{
	USHORT bytesRead;
	UCHAR lineStatReg;
	UINT i;
	BOOLEAN goodChar;

	DEBUGMSG(ZONE_FIRMODE, (TEXT("DoRcvDirect -->\r\n")));

	for (bytesRead = 0; bytesRead < maxBytes; bytesRead++){

		/*
		 *  Wait for data-ready
		 */
		i = 0;
		do {
			lineStatReg = (UCHAR)READ_REGISTER_UCHAR(pIrLSR);	

			/*
			 *  The UART reports framing and break errors as the effected
			 *  characters appear on the stack.  We drop these characters,
			 *  which will probably result in a bad frame checksum.
			 */
			if (lineStatReg & (LINESTAT_BREAK | LINESTAT_FRAMINGERROR)){
				UCHAR badch = (UCHAR)READ_REGISTER_UCHAR(pIrRBR);	
				DBGERR((TEXT("Bad rcv char %xh (lineStat=%xh)"), 
                    (UINT)badch, (UINT)lineStatReg));
				return (UINT)-1;
			}
			else if (lineStatReg & LINESTAT_DATAREADY){
				goodChar = TRUE;
			}
			else {
				/*
				 *  No input char ready
				 */
				goodChar = FALSE;
			}

		} while (!goodChar && (++i < REG_POLL_LOOPS));	
		if (!goodChar){
			break;
		}

		/*
		 *  Read in the next data byte 
		 */
		data[bytesRead] = (UCHAR)READ_REGISTER_UCHAR(pIrRBR);	
	}

	DEBUGMSG(ZONE_FIRMODE, (TEXT("DoRcvDirect <--\r\n")));
	return bytesRead;
}

	/*
	 *************************************************************************
	 *  GetCOMPort
	 *************************************************************************
	 */
	UCHAR GetCOMPort(UINT comBase, comPortRegOffset portOffset)
	{
		UCHAR val;
		DEBUGMSG(ZONE_FIRMODE, (TEXT("GetCOMPort <-->\r\n")));
		NdisRawReadPortUchar(comBase+portOffset, &val);
		return val;
	}

	/*
	 *************************************************************************
	 *  SetCOMPort
	 *************************************************************************
	 */
	VOID SetCOMPort(UINT comBase, comPortRegOffset portOffset, UCHAR val)
	{
		DEBUGMSG(ZONE_FIRMODE, (TEXT("SetCOMPort <-->\r\n")));
		NdisRawWritePortUchar(comBase+portOffset, val);
	}

⌨️ 快捷键说明

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