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

📄 comm.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 3 页
字号:
/*

  Copyright(c) 1998,1999 SIC/Hitachi,Ltd.

	Module Name:

		comm.c

	Revision History:

		26th May   1999		Released
		8th  July  1999		Modified value of pTOCR
		1999-Oct-22 cea		Removed setup of TMU2
*/
//#define OUTMSG

#include "nsc.h"
#include "firregs.h"		
/******************************************************************************
 * Modification Done by Maneesh Gupta
 *
 * S1.h has been replaced by platform.h 
 * Mobytel.h has been removed as it is no longer needed.
 *****************************************************************************/
//#include "platform.h"			
/******************************************************************************
 * End of modification Done by Maneesh Gupta
 *****************************************************************************/
#include "cc.h"				
#include "hw16550.h"		
#include "Settings.h"		
//#include "oalintr.h"

/*
 *  These arrays give default IO/IRQ settings by COM port number.
 */
USHORT comPortIOBase[] = { 0xFFFF, 0x3F8, 0x2F8, 0x3E8, 0x2E8 };
USHORT comPortIRQ[]	= { 0xFFFF, 4, 3, 9, 11 };	

/*
 *************************************************************************
 *  SetRegInit   	
 *************************************************************************
 */

VOID SetRegInit()
{
USHORT currentVal;
UCHAR imstcr;

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

	currentVal = READ_REGISTER_USHORT(pNIMR);
	if(currentVal & CC_INTC_NIMR_IRDAM_MASK){
		WRITE_REGISTER_USHORT(pNIMR,currentVal & CC_INTC_NIMR_IRDAM_UNMASK);//unmask irda interrupts
	}

	currentVal = READ_REGISTER_USHORT(pSMSCR);
	if(currentVal & CC_SYS_SMSCR_IRDAST){
		WRITE_REGISTER_USHORT(pSMSCR,currentVal & ~CC_SYS_SMSCR_IRDAST);//wakeup irda
	}

//
// Set up the transceiver.
// 
// This code assumes that the IrDA transceiver is the Hewlett-Packard HSDL-3600
//
// The HSDL-3600 mode pins are connected to the HD64465 port D bits 0 and 1.
//
// Note: The IrDA dongle is also connected to port D bits 0, 1 and 2.
//
// This code does the following:
//   reset the IrDA peripherial controller in the HD64465.
//   set HD64465 port D bits 0 and 1 as output bits.
//   set the HDSL-3600 mode bits for full power mode.
//   set the HD64465 FIR/SIR interface into SIR mode.
// 
	while (READ_REGISTER_USHORT(pSPSRCR) & CC_SYS_SMSCR_IRDAST);	// wait for reset to clear
	WRITE_REGISTER_USHORT(pSPSRCR, CC_SYS_SMSCR_IRDAST);			// reset IrDA module
	while (READ_REGISTER_USHORT(pSPSRCR) & CC_SYS_SMSCR_IRDAST);	// wait for reset to clear

	WRITE_REGISTER_USHORT(pGPDCR ,(READ_REGISTER_USHORT(pGPDCR) & 0xFFF0) | 0x05);	// Set port D bits 0 and 1 as output
	WRITE_REGISTER_UCHAR((PBYTE)pGPDDR ,(READ_REGISTER_UCHAR((PBYTE)pGPDDR) & 0x03) | 0x00);	// Select full power for the HSDL-3600 tranceiver from HP

	WRITE_REGISTER_UCHAR(pITMCR, CC_FIR_ITMCR_TMCR_66);	// CKIO:66MHz

	WRITE_REGISTER_UCHAR(pISIRR ,0x00); // Select FIR mode
	WRITE_REGISTER_UCHAR(pIFIRCR, READ_REGISTER_UCHAR(pIFIRCR) | CC_FIR_IFIRCR_TMODE);//Select IBM-like transceiver mode

	imstcr = READ_REGISTER_UCHAR(pIMSTCR);
	WRITE_REGISTER_UCHAR(pIMSTCR, imstcr | CC_FIR_IMSTCR_BANK2);//Select Bank2
	WRITE_REGISTER_UCHAR(pIIRTCR, READ_REGISTER_UCHAR(pIIRTCR) & ~CC_FIR_IIRTCR_MODSEL);//MODESEL pin to LOW

	WRITE_REGISTER_UCHAR(pIMSTCR, imstcr);//Select original Bank

	WRITE_REGISTER_UCHAR(pISIRR ,CC_FIR_ISIRR_SIRMOD);//HP-SIR

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

/*
 *************************************************************************
 *  SetFIFOCR   /	
 *************************************************************************
 */
VOID SetFIFOCR(IrDevice *thisDev,BOOLEAN enable)
{
	UCHAR newVal;

	DBGOUT((TEXT("==>SetFIFOCR")));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("SetFIFOCR -->\r\n")));

	if(enable){
		if(thisDev->currentSpeed > MAX_SIR_SPEED){
			WRITE_REGISTER_UCHAR(pIMSTCR, CC_FIR_IMSTCR_IEN|CC_FIR_IMSTCR_TXEN|CC_FIR_IMSTCR_RXEN);	/* IEN, TXEN, RXEN On */
			WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_RXFIFO);	/* Rx FIFO Pointer Reaet */
			WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_TXFIFO);	/* Tx FIFO Pointer Reaet */
		}else{
			WRITE_REGISTER_UCHAR(pIrFCR, SERIAL_FCR_ENABLE | SERIAL_1_BYTE_HIGH_WATER 
											| SERIAL_FCR_RCVR_RESET | SERIAL_FCR_TXMT_RESET);
				DEBUGMSG(ZONE_SIRMODE,  (TEXT("  pIrFCR [0x%x(0x%x)]\r\n"),
							(UCHAR)READ_REGISTER_UCHAR(pIrFCR), SERIAL_FCR_ENABLE
																| SERIAL_1_BYTE_HIGH_WATER
																| SERIAL_FCR_RCVR_RESET
																| SERIAL_FCR_TXMT_RESET
						));
		}
	}else{
		if(thisDev->currentSpeed > MAX_SIR_SPEED){
		    newVal = newVal & ~CC_FIR_IMSTCR_TXEN;
		    newVal = newVal & ~CC_FIR_IMSTCR_RXEN;
	    	//SetComPort(comBase, pIMSTCR, newVal);
			WRITE_REGISTER_UCHAR(pIMSTCR, 0x00);	/* IEN, TXEN, RXEN Off */


		}else{
			WRITE_REGISTER_UCHAR(pIrFCR, 0x0000);
				DEBUGMSG(ZONE_SIRMODE,  (TEXT("  pIrFCR [0x%x(0x0000)]\r\n"),
						(UCHAR)READ_REGISTER_UCHAR(pIrFCR)));
		}
	}

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

}

/*
 *************************************************************************
 *  SetCOMInterrupts
 *************************************************************************
 */
VOID SetCOMInterrupts(IrDevice *thisDev, BOOLEAN enable)
{
	UCHAR newMask;

    DBGISR((TEXT("Enable interrupts = %s"), enable ? TEXT("TRUE") : TEXT("FALSE")));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("SetCOMMInterrupt -->\r\n")));

	if(thisDev->currentSpeed > MAX_SIR_SPEED){
		newMask = READ_REGISTER_UCHAR(pIMSTCR);
		if (enable){
/******************************************************************************
 * Modification Done by Maneesh Gupta
 *
 * While interrupt enabling of FIR interrupt RX is also enabled.
 *****************************************************************************/
			WRITE_REGISTER_UCHAR(pIMSTCR, newMask | CC_FIR_IMSTCR_IEN | CC_FIR_IMSTCR_RXEN );
/******************************************************************************
 * End of modification Done by Maneesh Gupta
 *****************************************************************************/

		}else{
			WRITE_REGISTER_UCHAR(pIMSTCR, newMask & ~CC_FIR_IMSTCR_IEN );
		}
	}else{
		if (enable){
			if(thisDev->portInfo.writePending){
				WRITE_REGISTER_UCHAR(pIrIER, SERIAL_IER_THR|SERIAL_IER_RDA);
			}else{
				WRITE_REGISTER_UCHAR(pIrIER, SERIAL_IER_RDA);
			}
		}else{
			WRITE_REGISTER_UCHAR(pIrIER, 0x00);
		}
	}

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

}

/*
 *************************************************************************
 *  IsCommReadyForTransmit
 *************************************************************************
 *
 *
 */
BOOLEAN IsCommReadyForTransmit(IrDevice *thisDev)
{
	DEBUGMSG(ZONE_FIRMODE, (TEXT("IsCommReadyForTransmit <-->\r\n")));
	return !thisDev->portInfo.writePending;
}




/*
 *************************************************************************
 *  DoOpen
 *************************************************************************
 *
 *  Open COMM port
 *
 */
BOOLEAN DoOpen(IrDevice *thisDev)  
{
	BOOLEAN result;

	DBGOUT((TEXT("DoOpen(%d)"), thisDev->portInfo.ioBase));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("DoOpen -->\r\n")));

#ifdef UNDER_CE    
    // Windows CE. We get a chunk of memory from our contiguous physical
    // buffer. See externs.h for detailed information.

    ASSERT(g_pvDmaVirtualBase);
    thisDev->portInfo.readBuf  = LIST_ENTRY_TO_RCV_BUF(
        (PUCHAR)g_pvDmaVirtualBase + PORTINFO_OFFSET);
    thisDev->portInfo.writeBuf = 
        (PUCHAR)g_pvDmaVirtualBase + PORTINFO_OFFSET + RCV_BUFFER_SIZE;
#else // UNDER_CE
	/*
	 *  This buffer gets swapped with the rcvBuffer data pointer
	 *  and must be the same size.
	 */
	thisDev->portInfo.readBuf = LIST_ENTRY_TO_RCV_BUF(MyMemAlloc(RCV_BUFFER_SIZE, TRUE));  // Was FALSE -SWA
	if (!thisDev->portInfo.readBuf){
		return FALSE;
	}

	/*
	 *  The write buffer is also used as a DMA buffer.
	 */
	thisDev->portInfo.writeBuf = MyMemAlloc(MAX_IRDA_DATA_SIZE * 8, TRUE);
	if (!thisDev->portInfo.writeBuf){
		return FALSE;
	}
#endif // !UNDER_CE
	
    /*
	 *  Initialize send/receive FSMs before OpenCOM(), which enables rcv interrupts.
	 */
	thisDev->portInfo.rcvState = STATE_INIT;
	thisDev->portInfo.writePending = FALSE;
	DBGOUT((TEXT("writePending = FALSE")));

	result = OpenCOM(thisDev);

	DBGOUT((TEXT("DoOpen %s"), (CHAR *)(result ? "succeeded" : "failed")));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("DoOpen <--\r\n")));
	return result;

}



/*
 *************************************************************************
 *  DoClose
 *************************************************************************
 *
 *  Close COMM port
 *
 */
VOID DoClose(IrDevice *thisDev)
{
	DBGOUT((TEXT("DoClose(COM%d)"), thisDev->portInfo.ioBase));
	DEBUGMSG(ZONE_FIRMODE, (TEXT("DoClose -->\r\n")));

#ifdef UNDER_CE
    // Windows CE. Don't need to free since it is just a pointer in our
    // reserved physical memory.
    thisDev->portInfo.readBuf  = NULL;
    thisDev->portInfo.writeBuf = NULL;
#else // UNDER_CE
	if (thisDev->portInfo.readBuf){
		MyMemFree(RCV_BUF_TO_LIST_ENTRY(thisDev->portInfo.readBuf), 
                  RCV_BUFFER_SIZE, TRUE);  // Was FALSE -SWA
		thisDev->portInfo.readBuf = NULL;
	}
	if (thisDev->portInfo.writeBuf){
		MyMemFree(thisDev->portInfo.writeBuf, MAX_IRDA_DATA_SIZE * 8, TRUE);
		thisDev->portInfo.writeBuf = NULL;
	}
#endif //!UNDER_CE

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



/*
 *************************************************************************
 *  SetUARTSpeed
 *************************************************************************
 *
 *
 */
VOID SetUARTSpeed(IrDevice *thisDev, UINT bitsPerSec)
{
USHORT		divisor;	
UINT		i;
NDIS_STATUS stat;

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

	if (bitsPerSec <= MAX_SIR_SPEED){
		if(thisDev->currentSpeed > MAX_SIR_SPEED){//change from MIR/FIR to SIR
			if(READ_REGISTER_UCHAR(pISIRR) & CC_FIR_ISIRR_SIRMOD){//unexpected status
			}else{
	       	 	if (thisDev->AdapterState==ADAPTER_RX) {
   	    	    	NdisMCompleteDmaTransfer(&stat, thisDev->DmaHandle,
       	    	    	thisDev->rcvDmaBuffer, 
           	    		thisDev->rcvDmaOffset,
           	     		thisDev->rcvDmaSize, FALSE);
       			}
				WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_HW);
				NdisStallExecution( 50 );

#ifdef OUTMSG
		RETAILMSG(1,(TEXT("NdisStallExecution\r\n")));
#endif


				WRITE_REGISTER_UCHAR(pIMSTCR,CC_FIR_IMSTCR_BANK0);//Switch Bank 0
				i=0;
				while(i<10000){//Clean up FIR Tx_FIFO
					if(READ_REGISTER_UCHAR(pITSR) & CC_FIR_ITSR_EOM){
						break;
					}else{
					}
					i++;
				}
				i=0;
				while(i<10000){//Clean up FIR Rx_FIFO
					if(READ_REGISTER_UCHAR(pIRSR) & CC_FIR_IRSR_RFEM){
						READ_REGISTER_UCHAR(pIRFR);
					}else{
						break;
					}
					i++;
				}

				WRITE_REGISTER_UCHAR(pIMSTCR,CC_FIR_IMSTCR_BANK2);//Switch Bank 2
				WRITE_REGISTER_UCHAR(pIIRC2R,READ_REGISTER_UCHAR(pIIRC2R) & 0xfc | CC_FIR_IIRC2R_DFIRI);//FIR to SIR
				WRITE_REGISTER_UCHAR(pIIRC1R,CC_FIR_IIRC1R_IRMOD_HPSIR);
				WRITE_REGISTER_UCHAR(pISIRR,CC_FIR_ISIRR_SIRMOD);
			}
		}else{// SIR to SIR
		}

		i=0;
		while(i<10000){//Clean up UART Tx_FIFO
			if((READ_REGISTER_UCHAR(pIrLSR) & (SERIAL_LSR_TEMT|SERIAL_LSR_THRE))==(SERIAL_LSR_TEMT|SERIAL_LSR_THRE)){
				break;
			}else{
			}
			i++;
		}
		i=0;
		while(i<10000){//Clean up UART Rx_FIFO
			if(READ_REGISTER_UCHAR(pIrLSR) & SERIAL_LSR_DR){
				READ_REGISTER_UCHAR(pIrRBR);
			}else{
				break;
			}
			i++;
		}

		/*
		 *  Set speed in the standard UART divisor latch
		 *
		 *  1.	Set up to access the divisor latch.
		 *
		 *	2.	In divisor-latch mode:
		 *			the transfer register doubles as the low divisor latch
		 *			the int-enable register doubles as the hi divisor latch
		 *
		 *		Set the divisor for the given speed.
		 *		The divisor divides the maximum Slow IR speed of 115200 bits/sec.
		 *
		 *  3.	Take the transfer register out of divisor-latch mode.
		 *
		 */
		if (!bitsPerSec){
			bitsPerSec = 9600;
		}
		divisor = DivisorOfRate(bitsPerSec);												
		if ( divisor ){																		
			WRITE_REGISTER_UCHAR(pIrLCR, SERIAL_LCR_DLAB|SERIAL_8_DATA );					
			WRITE_REGISTER_UCHAR(pIrDLL, divisor & 0xff);									
			WRITE_REGISTER_UCHAR(pIrDLM, (divisor >> 8) & 0xff);							
			WRITE_REGISTER_UCHAR(pIrLCR, SERIAL_8_DATA);									
		}else{																				
			DEBUGMSG(ZONE_ERROR,(TEXT("-SetUARTSpeed - Bad BaudRate %d\r\n"),bitsPerSec));
		}																					

		NdisStallExecution(5000);

#ifdef OUTMSG
		RETAILMSG(1,(TEXT("NdisStallExecution\r\n")));
#endif


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


		

USHORT DivisorOfRate( ULONG   BaudRate )
{
    ULONG   errorcode = 0;
    USHORT  divisor;    

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

    divisor = (USHORT)LookUpValue(BaudRate, &errorcode);

    if ( errorcode )
        divisor = 0;

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

    return divisor;
}


		

ULONG LookUpValue( ULONG Key,PULONG	pErrorCode )
{
ULONG val;

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

    *pErrorCode = 0;

	switch(Key){
		case 50:		val = 2307;	break;
		case 75:		val = 1538;	break;
		case 110:		val = 1049;	break;
		case 135:		val = 858;	break;

⌨️ 快捷键说明

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