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

📄 genport.c

📁 win2000下ISA接口的串口板卡的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	DebugPrint ((">>>Port%x  %d-%d-%d!\n",pLDI->ComBase[pComSetMode->ComNum],pComSetMode->ComNum ,pComSetMode->Baud,pComSetMode->Data ));
	switch(pComSetMode->ComNum)
	{
	case 0:case 1:case 2:case 3:
	case 4:case 5:case 6:case 7:
	case 8:case 9:case 10:case 11:
		ComIndex = pComSetMode->ComNum;
		break;
	default:
		return STATUS_UNSUCCESSFUL;
	}
	//-----------                       初始化串口                        ------------// 
  	
	//复位
	WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],CSR);					//WritePort(m_SPR,m_CSR);
	WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],0x00);					//WritePort(m_LCR,0x00);
	DebugPrint ((">>>  复位!\t"));

//	WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],TCR);					//WritePort(m_SPR,m_CSR);
//	OldACR = READ_INDEX_REGISTER(pLDI->ComBase[ComIndex]);
//	DebugPrint ((">>>  TCR = %X!\t",OldACR));
//	OldACR = READ_MODEM_CONTROL(pLDI->ComBase[ComIndex]);
//	DebugPrint ((">>>  MCR = %X!\n",OldACR));
	//设置波特率
	if(ComIndex >= 0 && ComIndex <=3)
    	divisor =(USHORT)(614400/pComSetMode->Baud);						// Input frequency is 9.8432Mhz 20060907
	else
    	divisor =(USHORT)(691200/pComSetMode->Baud);						// Input frequency is 11.0592Mhz 20060907
//  WRITE_LINE_CONTROL(pLDI->ComBase[ComIndex],0xBF);					//WritePort(m_LCR, 0xBF) ;				// Enable access to the EFR, DLL and DLM registers 
//	WRITE_DIVISOR_LATCH(pLDI->ComBase[ComIndex],divisor);				//WritePort( m_DLL,parameter);			// DLL 
//    UCHAR LineControl;                                            \
//    LineControl = READ_PORT_UCHAR((PUCHAR)((ULONG_PTR)Address+LCR));					  
    WRITE_PORT_UCHAR((PUCHAR)((ULONG_PTR)pLDI->ComBase[ComIndex]+LCR),(UCHAR)(0xBF));                                                        
    WRITE_PORT_UCHAR((PUCHAR)((ULONG_PTR)pLDI->ComBase[ComIndex]+DLL),(UCHAR)(divisor & 0xff));                                                        
    WRITE_PORT_UCHAR((PUCHAR)((ULONG_PTR)pLDI->ComBase[ComIndex]+DLM),(UCHAR)((divisor & 0xff00) >> 8));                                                        
 	DebugPrint ((">>>  divisor = 0x%X!\t",divisor));

	//设置模式选择
	WRITE_ENHANCED_FEATURE_REGISTER(pLDI->ComBase[ComIndex],0x10);		//WritePort( m_EFR, 0x10);				// EFR, enhance mode select,disnable RTS CTS flow control
	DebugPrint ((">>>  非自动流控制!\n"));

	//设置数据位,校验位,停止位
    parameter  = ((pComSetMode->Data - 5) & 0x03) + (((pComSetMode->Stop-1) & 0x01) << 2) ;		//	数据位LCR[1:0]和停止位		
	parameter |= (pComSetMode->Parity & 0x07) << 3;
	WRITE_LINE_CONTROL(pLDI->ComBase[ComIndex],parameter);				//WritePort( m_LCR, parameter) ;			// LCR ,设置数据位,停止位,校验位
	DebugPrint ((">>>  parameter = %X !\n",parameter));

	//设置工作模式
    parameter = (pComSetMode->Mode << 4 ) | 0xa;				//0xa 开RTS
    WRITE_MODEM_CONTROL(pLDI->ComBase[ComIndex],parameter);				//WritePort( m_MCR, parameter) ;			//设置模式mode=0正常,mode=1循环,out2=1,out1=0,RTS=1,DTR=0
	DebugPrint ((">>>  模式 = %X!\n",parameter));

	if(pComSetMode->Count > 0)
	{
		WRITE_FIFO_CONTROL(pLDI->ComBase[ComIndex],0x07);				//WritePort( m_FCR ,0x07	);		//	Enable FIFO, Flush THR and RHR			
		WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],ACR);				//WritePort( m_SPR ,m_ACR	);		//	SPR = 0, PT ACR										
		WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],0x60);				//WritePort( m_ICR ,0x60	);		//	ACR, enable 950 mode,ICR read enable				
		WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],TTL);				//WritePort( m_SPR ,m_TTL	);		//	SPR = 4, PT TTL							
		WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],1);					//WritePort( m_ICR ,Count	);		//	Transmit trigger level					
		WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],RTL);				//WritePort( m_SPR ,m_RTL	);		//	SPR = 5, PT RTL							
		WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],pComSetMode->Count);//WritePort( m_ICR ,Count	);		//	Receive trigger level					
		WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],FCL);				//WritePort( m_SPR ,m_FCL	);		//	SPR = 6, PT FCL							
		WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],0x01);				//WritePort( m_ICR ,1		);
		WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],FCH);				//WritePort( m_SPR ,m_FCH	);
		WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],pComSetMode->Count);//WritePort( m_ICR ,Count	);
	}
	DebugPrint ((">>>  FifoLevel = %d!\n",pComSetMode->Count));

	//读空接收Fifo
	for(i = 0 ;i < 128;i++)
	{
		READ_RECEIVE_BUFFER(pLDI->ComBase[ComIndex]);								//ReadPort(m_RHR,&ReadData);
	}
	DebugPrint ((">>>  清空接收Fifo!\n"));
	//开接收中断
	if(pComSetMode->bInterrupt == 1 && pLDI->FoundInterrupt)//如果有中断就置为COM_HAVE_IRQ
	{
		WRITE_INTERRUPT_ENABLE(pLDI->ComBase[ComIndex],0x01);			//WritePort( m_IER ,0x01		);	//	IER, enable receive interrupt			
		pLDI->Com_Have_IRQ = ComIndex;
		DebugPrint ((">>>Com%d  开接收中断 %d!\n",ComIndex,pLDI->Com_Have_IRQ));
	}
	else
	{
		WRITE_INTERRUPT_ENABLE(pLDI->ComBase[ComIndex],0x00);			//WritePort( m_IER ,0x01		);	//	IER, enable receive interrupt			
		DebugPrint ((">>>  关接收,发送空中断 %d!\n",pLDI->Com_Have_IRQ));
	}
/**/
//	DebugPrint ((">>>Inited[ComIndex] = TRUE %X!\n",pLDI));
	pLDI->Inited[ComIndex] = TRUE;
	p1 = (UCHAR*)&pLDI->ComState[ComIndex];
	p2 = (UCHAR*)pComSetMode;
	for(i = 0;i < sizeof(COM_SET_MODE);i++)
		p1[i] = p2[i];
	//-----------                     结束  初始化串口                        ------------// 
	//结束设置
    //
    pIrp->IoStatus.Information = InBufferSize;

    return STATUS_SUCCESS;
}
NTSTATUS
SerialReadData(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp,
	IN PIO_STACK_LOCATION IrpStack,
	IN USHORT ComIndex
    )
/*++

Routine Description:

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    If the io is zero length then it will return STATUS_SUCCESS,
    otherwise this routine will return the status returned by
    the actual start read routine.

--*/
{
    PLOCAL_DEVICE_INFO pLDI = (PLOCAL_DEVICE_INFO)DeviceObject->DeviceExtension;
	// NOTE:  Use METHOD_BUFFERED ioctls.
	PCOM_SET_MODE pComSetMode;	//指向InBuffer中的COM_SET_MODE结构体
    PUCHAR pIOBuffer;           // Pointer to transfer buffer
                                //      (treated as an array of longs).
    ULONG InBufferSize;         // Amount of data avail. from caller.
    ULONG OutBufferSize;        // Max data that caller can accept.
    ULONG nPort;                // Port number to read
	int i,RealReadSize;
    PAGED_CODE();
//	DebugPrint ((">>>Entered SerialReadData! Com%d\n",ComIndex));

    // Size of buffer containing data from application
    InBufferSize  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
    OutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    // NT copies inbuf here before entry and copies this to outbuf after
    // return, for METHOD_BUFFERED IOCTL's.
    pIOBuffer     = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;

	RealReadSize = InBufferSize < pLDI->Buf[REC_INDEX][ComIndex] .Number ? 
	(InBufferSize): pLDI->Buf[REC_INDEX][ComIndex] .Number;

	pIrp->IoStatus.Information = RealReadSize;
	if(pIOBuffer == NULL)
	{
		DebugPrint (("pIOBuffer == NULL InBufferSize=%d RealReadSize=%d\n",InBufferSize,RealReadSize));
		return STATUS_UNSUCCESSFUL;
	}
	else
	{
//		DebugPrint (("InBufferSize=%d RealReadSize=%d pIOBuffer[3]=%X\n",InBufferSize,RealReadSize,pIOBuffer[3]));
	}
	if(RealReadSize > 0)
	{
			
		for(i = 0;i < RealReadSize;i++)
		{
			BufPopByte(&pLDI->Buf[REC_INDEX][ComIndex] ,&(UCHAR)pIOBuffer[i]);
//			DebugPrint (("%X ",(UCHAR)pIOBuffer[i]));
		}
		DebugPrint (("Com%d 读 %d \t缓 %d \n",ComIndex,RealReadSize,pLDI->Buf[REC_INDEX][ComIndex].Number));
	}
	else
	{
		IoRequestDpc(pLDI->DeviceObject,0,NULL);
	}
    // Check to ensure input buffer is big enough to hold a port number and
    // the output buffer is at least as big as the port data width.
    //
	

    return STATUS_SUCCESS;
}
NTSTATUS
SerialWriteData(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP pIrp,
	IN PIO_STACK_LOCATION IrpStack,
	IN USHORT ComIndex
    )
/*++

Routine Description:

Arguments:

    DeviceObject - Pointer to the device object for this device

    Irp - Pointer to the IRP for the current request

Return Value:

    If the io is zero length then it will return STATUS_SUCCESS,
    otherwise this routine will return the status returned by
    the actual start read routine.

--*/
{
    PLOCAL_DEVICE_INFO pLDI = (PLOCAL_DEVICE_INFO)DeviceObject->DeviceExtension;
	// NOTE:  Use METHOD_BUFFERED ioctls.
    PUCHAR pIOBuffer;           // Pointer to transfer buffer
                                //      (treated as an array of longs).
    ULONG InBufferSize;         // Amount of data avail. from caller.
    ULONG OutBufferSize;        // Max data that caller can accept.
	UCHAR OldACR,AL;
	int i,RealWriteSize,Count;
    PAGED_CODE();
//	DebugPrint ((">>>entered SerialWriteData! Com%d\n",ComIndex));

    // Size of buffer containing data from application
    InBufferSize  = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

    // Size of buffer for data to be sent to application
    OutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

    // NT copies inbuf here before entry and copies this to outbuf after
    // return, for METHOD_BUFFERED IOCTL's.
    pIOBuffer     = (PUCHAR)pIrp->AssociatedIrp.SystemBuffer;

    // Check to ensure input buffer is big enough to hold a port number and
    // the output buffer is at least as big as the port data width.
    //
 
	RealWriteSize = InBufferSize < (pLDI->Buf[SEND_INDEX][ComIndex] .MaxSize - pLDI->Buf[SEND_INDEX][ComIndex] .Number) ? 
	(InBufferSize):(pLDI->Buf[SEND_INDEX][ComIndex] .MaxSize - pLDI->Buf[SEND_INDEX][ComIndex] .Number);

	pIrp->IoStatus.Information = RealWriteSize;
	if(pIOBuffer == NULL || (unsigned long)RealWriteSize < InBufferSize || RealWriteSize == 0)
	{
		DebugPrint (("pIOBuffer == NULL InBufferSize=%d RealWriteSize=%d\n",InBufferSize,RealWriteSize));
		return STATUS_UNSUCCESSFUL;
	}
	else
	{
//		DebugPrint (("InBufferSize=%d RealWriteSize=%d pIOBuffer[3]=%X\n",InBufferSize,RealWriteSize,pIOBuffer[3]));
	}
	if(RealWriteSize > 0)
	{
			
		for(i = 0;i < RealWriteSize;i++)
		{
			KeWaitForSingleObject(&pLDI->BufSemaphore[SEND_INDEX][ComIndex], Executive, KernelMode,FALSE, NULL);
			BufPushByte(&pLDI->Buf[SEND_INDEX][ComIndex] ,(UCHAR)pIOBuffer[i]);//隐患:如果此时发送空中断发生,有可能同时访问发送BUF
			KeReleaseSemaphore(&pLDI->BufSemaphore[SEND_INDEX][ComIndex], 0, 1, FALSE);
			//			DebugPrint (("%X ",(UCHAR)pIOBuffer[i]));
		}
//		DebugPrint (("Buf[SEND_INDEX][%d].Number = %d\n",ComIndex,pLDI->Buf[SEND_INDEX][ComIndex].Number));
		DebugPrint (("Com%d 写 %d \t缓 %d \n",ComIndex,RealWriteSize,pLDI->Buf[SEND_INDEX][ComIndex].Number));

/*		if(ComIndex == COM_HAVE_IRQ)
		{
			//读取发送Fifo中,数据个数,如果没有数,则发送一个,激活发送空中断
			
			WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],ACR);
			OldACR = READ_INDEX_REGISTER(pLDI->ComBase[ComIndex]);					
			WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],(UCHAR)(OldACR|0x80));		                              
			Count = READ_TRANSMITTER_FIFO_LEVEL(pLDI->ComBase[ComIndex]);				
			//Count2 = READ_RECIEVER_FIFO_LEVEL(pLDI->ComBase[ComIndex]);				
			OldACR = READ_INDEX_REGISTER(pLDI->ComBase[ComIndex]);					
			WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],(UCHAR)(OldACR & 0x7F));
			if(Count == 0)
			{
				BufPopByte(&(pLDI->Buf[SEND_INDEX][ComIndex]) ,&AL);
				WRITE_TRANSMIT_BUFFER(pLDI->ComBase[ComIndex],AL);
	//			DebugPrint (("%X ",AL));
			}
		}
*/	}
	else
	{
		DebugPrint (("SendBuf 满 Num = %d 或InBuffSize=%d OutBufferSize=%d\n",pLDI->Buf[SEND_INDEX][ComIndex].Number,InBufferSize,OutBufferSize));
		return STATUS_UNSUCCESSFUL;
	}

    return STATUS_SUCCESS;
}
//读串口硬件的数据
NTSTATUS
SerialReadPort(
    IN PDEVICE_OBJECT DeviceObject,
	IN USHORT ComIndex,
	IN UCHAR *Buf,
	IN USHORT BufSize,
	OUT USHORT *RealReadSize
    )
{
    PLOCAL_DEVICE_INFO pLDI = (PLOCAL_DEVICE_INFO)DeviceObject->DeviceExtension;
	UCHAR OldACR,AL,CurrentISR;
	int Count1,Count2,i;
	//test
//    PAGED_CODE();
	//test end
	if((!pLDI->Inited[ComIndex])|| 
		(ComIndex == pLDI->Com_Have_IRQ && pLDI->FoundInterrupt) || 
		Buf == NULL || 
		BufSize == 0)
//	if((!pLDI->Inited[ComIndex])|| Buf == NULL || BufSize == 0)
	{
		*RealReadSize = 0;
		return STATUS_UNSUCCESSFUL;
	}
	//读取接收Fifo中,数据个数
	WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],ACR);
	OldACR = READ_INDEX_REGISTER(pLDI->ComBase[ComIndex]);					
	WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],(UCHAR)(OldACR|0x80));		                              
	Count1 = READ_RECIEVER_FIFO_LEVEL(pLDI->ComBase[ComIndex]);				
	Count2 = READ_RECIEVER_FIFO_LEVEL(pLDI->ComBase[ComIndex]);				
	OldACR = READ_INDEX_REGISTER(pLDI->ComBase[ComIndex]);					
	WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],(UCHAR)(OldACR & 0x7F));
	if(Count1 == 0 || Count2 == 0)
	{
		*RealReadSize = 0;
		return STATUS_UNSUCCESSFUL;
	}
	if((Count1 != Count2))
	{
		//AL = (UCHAR)READ_RECEIVE_BUFFER(pLDI->ComBase[ComIndex]);
		DebugPrint (("Count1 != Count2 %d %d\n",Count1,Count2));
		Count1 = Count1 < Count2 ? Count1 : Count2;
	}
	*RealReadSize = Count1 <= BufSize ? Count1 : BufSize;
	if(*RealReadSize > 0)
	{
		//test
//		DebugPrint (("Com%d 开始读Port %d 个数%d\n",ComIndex,*RealReadSize,pLDI->Com_Have_IRQ));
		//test end
		for(i = 0;i < *RealReadSize;i++)
		{
			AL = (UCHAR)READ_RECEIVE_BUFFER(pLDI->ComBase[ComIndex]);
			Buf[i] = AL;
			//test
//			DebugPrint ((" %X ",AL));
			//test end
		}
//		DebugPrint (("Com%d ReadPort %d 完成!\n",ComIndex,*RealReadSize));
	}
    return STATUS_SUCCESS;
}
//写串口硬件的数据
NTSTATUS
SerialWritePort(
    IN PDEVICE_OBJECT	DeviceObject,
	IN USHORT			ComIndex,
	IN UCHAR				*Buf,
	IN USHORT				BufSize,
	OUT USHORT			*RealWriteSize
    )
{
    PLOCAL_DEVICE_INFO pLDI = (PLOCAL_DEVICE_INFO)DeviceObject->DeviceExtension;
	UCHAR OldACR,AL,CurrentISR;
	int Count,i;
//    PAGED_CODE();
//	if((pLDI->Inited[ComIndex] == FALSE) || ComIndex == COM_HAVE_IRQ || Buf == NULL || BufSize == 0)
	if((pLDI->Inited[ComIndex] == FALSE)|| Buf == NULL || BufSize == 0)
	{
		*RealWriteSize = 0;
		return STATUS_UNSUCCESSFUL;
	}
	WRITE_SELECT_REGISTER(pLDI->ComBase[ComIndex],ACR);
	OldACR = READ_INDEX_REGISTER(pLDI->ComBase[ComIndex]);					
	WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],(UCHAR)(OldACR|0x80));		                              
	Count = READ_TRANSMITTER_FIFO_LEVEL(pLDI->ComBase[ComIndex]);				
	OldACR = READ_INDEX_REGISTER(pLDI->ComBase[ComIndex]);					
	WRITE_INDEX_REGISTER(pLDI->ComBase[ComIndex],(UCHAR)(OldACR & 0x7F));
	if(Count == 0)
	{
		*RealWriteSize = BufSize <= 128 ? BufSize : 128;
//		DebugPrint (("Com%d 开始写 %d ",ComIndex,*RealWriteSize));
		for(i = 0;i < *RealWriteSize;i ++)
		{
			WRITE_TRANSMIT_BUFFER(pLDI->ComBase[ComIndex],Buf[i]);
//			DebugPrint ((" %X ",Buf[i]));
		}
	}
	else
	{
		*RealWriteSize = 0;
		return STATUS_UNSUCCESSFUL;
	}
    return STATUS_SUCCESS;
}
BOOLEAN
SerialIsS

⌨️ 快捷键说明

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