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

📄 isp1581device_buf.cpp

📁 这是一个用ISP1581 USB2.0接口芯片作为图像采集接口的驱动程序。该驱动程序支持Endpoint1 Bulk方式 数据输入传输。实际传输速度可以达到24MBYTE/S
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	// If the IRP's IOCTL handler deferred processing using some driver
	// specific scheme, the status variable is set to STATUS_PENDING.
	// In this case we simply return that status, and the IRP will be
	// completed later.  Otherwise, complete the IRP using the status
	// returned by the IOCTL handler.
	if (status == STATUS_PENDING)
	{
		return status;
	}
	else
	{
		return I.PnpComplete(this, status);
	}
}

////////////////////////////////////////////////////////////////////////
//	Routine Description:	Handler for IO Control Code FzGdi_IOCTL_SetDeviceCommands
NTSTATUS GnganfgDevice::KBUSBDEV_IOCTL_SetDeviceCommands_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;
	PURB   pUrb = NULL;
	USHORT wSetCommandParameter;
	UCHAR  bSetCommandData, bSetCommandIndex;
	USHORT  wIndex;
	wIndex  = KAIBO_USB_DEVICE_INDEX; 
	
	if( I.IoctlInputBufferSize(CURRENT) != sizeof(USHORT) )
	{
		status = STATUS_INVALID_BUFFER_SIZE;
		return status;
	}

	wSetCommandParameter = *(USHORT*)(I.IoctlBuffer());
	bSetCommandData = (CHAR)wSetCommandParameter;
	wSetCommandParameter >>= 8;
	bSetCommandIndex = (CHAR)wSetCommandParameter;

	if ( ( bSetCommandIndex == 0 ) || ( bSetCommandIndex == 1 ) )
	{
		I.Information() = sizeof(USHORT);
		return status;
	}

	if ( ( bSetCommandIndex == 2 ) || ( bSetCommandIndex == 3 ) )
	{
		I.Information() = sizeof(USHORT);
		return status;
	}

	wIndex  |= bSetCommandIndex; 

	pUrb = m_Lower.BuildVendorRequest(
						&bSetCommandData,				// transfer buffer
						1,								// transfer buffer size
						0,								// request reserved bits(The recipient is Device)
						0x0C,							// request
						0,								// Value
						FALSE,							// Out 
						TRUE,							// Short Ok
						NULL,							// link urb
						wIndex,							// index
						URB_FUNCTION_VENDOR_DEVICE		// function
						);

	if ( pUrb == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	status = m_Lower.SubmitUrb( pUrb );
	delete pUrb; // end of " setup DMA request "  

	I.Information() = sizeof(USHORT);
	return status;
}

///////////////////////////////////////////////////////////////////////////////////
//	Routine Description:	Handler for IO Control Code FzGdi_IOCTL_GetDeviceStatus
NTSTATUS GnganfgDevice::KBUSBDEV_IOCTL_GetDeviceStatus_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;
	PURB	pUrb = NULL;
	UCHAR   bGetStatusIndex; 
	USHORT  wIndex;
	wIndex  = KAIBO_USB_DEVICE_INDEX; 

	if( (I.IoctlInputBufferSize(CURRENT) != sizeof(UCHAR)) || (I.IoctlOutputBufferSize(CURRENT) != sizeof(UCHAR)) )
	{
		status = STATUS_INVALID_BUFFER_SIZE;
		return status;
	}

	bGetStatusIndex = *(UCHAR*)(I.IoctlBuffer());

	wIndex |= bGetStatusIndex;

	pUrb = m_Lower.BuildVendorRequest(
						(PUCHAR)(I.IoctlBuffer()),		// transfer buffer
						1,								// transfer buffer size
						0,								// request reserved bits(The recipient is Device)
						0x0C,							// request
						0,								// Value
						TRUE,							// In 
						TRUE,							// Short Ok
						NULL,							// link urb
						wIndex,							// index
						URB_FUNCTION_VENDOR_DEVICE		// function
						);

	if ( pUrb == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	status = m_Lower.SubmitUrb( pUrb );
	delete pUrb; // end of " get status request "  

	I.Information() = sizeof(UCHAR);

	return status;
}

//	Routine Description:	Handler for IO Control Code FzGdi_IOCTL_GetDeviceID
NTSTATUS GnganfgDevice::KBUSBDEV_IOCTL_GetDeviceID_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;
	PURB	pUrb = NULL;
	USHORT	wCofigIdex = GET_DEVICE_ID_TOTAL;
	ULONG  	dwGetIdLength = I.IoctlOutputBufferSize(CURRENT);

	if ( I.IoctlInputBufferSize(CURRENT) == sizeof(USHORT) )
	{
		wCofigIdex = *(USHORT*)(I.IoctlBuffer());
	}

	if( dwGetIdLength == 0 )
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_SUCCESS);
	}

	pUrb = m_Lower.BuildClassRequest(
					(PUCHAR)(I.IoctlBuffer()),	// PUCHAR TransferBuffer,
					dwGetIdLength,				// ULONG TransferBufferLength,
					1,							// UCHAR RequestTypeReservedBits(USB Device Class-Print),
					0,							// UCHAR Request(USB Device Class-Print),	
					wCofigIdex,					// USHORT Value(See IEEE-1284),
					TRUE,						// BOOLEAN bIn=FALSE,
					TRUE,						// BOOLEAN bShortOk=FALSE,
					NULL,						// PURB Link=NULL,
					0,							// ** USHORT Index=0 (Our Printer controller only an interface),
					URB_FUNCTION_CLASS_DEVICE,  // USHORT Function=URB_FUNCTION_CLASS_DEVICE,
					NULL						// PURB pUrb=NULL
					);

	if ( pUrb == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	status = m_Lower.SubmitUrb( pUrb );
	delete pUrb; // end of " get status request "  

	I.Information() = pUrb->UrbControlTransfer.TransferBufferLength;
	return status;
}

//	Routine Description:	Handler for IO Control Code FzGdi_IOCTL_GetPortStatus
NTSTATUS GnganfgDevice::KBUSBDEV_IOCTL_GetPortStatus_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;
	PURB	pUrb = NULL;

	if ( I.IoctlOutputBufferSize(CURRENT) != sizeof(UCHAR) )
	{
		status = STATUS_INVALID_BUFFER_SIZE;
		return status;
	}

	// No data is transferred for this request.
	pUrb = m_Lower.BuildClassRequest(
					(PUCHAR)(I.IoctlBuffer()),	// PUCHAR TransferBuffer,	
					sizeof(UCHAR),				// ULONG TransferBufferLength,
					1,							// UCHAR RequestTypeReservedBits(USB Device Class-Print),
					1,							// UCHAR Request(USB Device Class-Print),	
					0,							// USHORT Value(See IEEE-1284),
					FALSE,						// BOOLEAN bIn=FALSE,
					TRUE,						// BOOLEAN bShortOk=FALSE,
					NULL,						// PURB Link=NULL,
					0,							// ** USHORT Index=0 (Our Printer controller only an interface),
					URB_FUNCTION_CLASS_DEVICE,  // USHORT Function=URB_FUNCTION_CLASS_DEVICE,
					NULL						// PURB pUrb=NULL
					);

	if ( pUrb == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	status = m_Lower.SubmitUrb( pUrb );
	delete pUrb; // end of " get status request "  

	I.Information() = sizeof(UCHAR);
	return status;

}

//	Routine Description:	Handler for IO Control Code FzGdi_IOCTL_SoftReset
NTSTATUS GnganfgDevice::KBUSBDEV_IOCTL_SoftReset_Handler(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;
	PURB	pUrb = NULL;

	// No data is transferred for this request.
	pUrb = m_Lower.BuildClassRequest(
					NULL,						// PUCHAR TransferBuffer,	
					0,							// ULONG TransferBufferLength,
					3,							// UCHAR RequestTypeReservedBits(USB Device Class-Print),
					2,							// UCHAR Request(USB Device Class-Print),	
					0,							// USHORT Value(See IEEE-1284),
					FALSE,						// BOOLEAN bIn=FALSE,
					TRUE,						// BOOLEAN bShortOk=FALSE,
					NULL,						// PURB Link=NULL,
					0,							// ** USHORT Index=0 (Our Printer controller only an interface),
					URB_FUNCTION_CLASS_DEVICE,  // USHORT Function=URB_FUNCTION_CLASS_DEVICE,
					NULL						// PURB pUrb=NULL
					);

	if ( pUrb == NULL)
	{
		I.Information() = 0;
		return I.PnpComplete(this, STATUS_INSUFFICIENT_RESOURCES);
	}

	status = m_Lower.SubmitUrb( pUrb );
	delete pUrb; // end of " get status request "  

	I.Information() = 0;
	return status;
}

// KernelModeSetDeviceCommand(), Set command that is dependented on device( USB-D12 ).
// wIndex from 0x0400  to 0x0403;
// wIndex = 0x0400 ( SET_FPGA_CONFIG_REQUEST )
// wIndex = 0x0401 ( SET_FPGA_CONFIG_COMPLETE )
// wIndex = 0x0402 ( READ_PRINTER_STATUS_PACKET )
// wIndex = 0x0403 ( READ_VIDEO_FIFO_DATA )
NTSTATUS GnganfgDevice::KernelModeSetDeviceCommand(USHORT wIndex )
{
	NTSTATUS status = STATUS_SUCCESS;
	PURB   pUrb = NULL;

	UCHAR  bSetCommandData = 0;

	pUrb = m_Lower.BuildVendorRequest(
						&bSetCommandData,				// transfer buffer
						1,								// transfer buffer size
						0,								// request reserved bits(The recipient is Device)
						0x0C,							// request
						0,								// Value
						FALSE,							// Out 
						TRUE,							// Short Ok
						NULL,							// link urb
						wIndex,							// index
						URB_FUNCTION_VENDOR_DEVICE		// function
						);

	if ( pUrb == NULL)
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
		return status;
	}

	status = m_Lower.SubmitUrb( pUrb );
	delete pUrb;  

	return status;
}

////////////////////////////////////////////////////////////////////////
// KernelModeGetDeviceStatus Get status that is dependented on device( USB-D12 ).
// wIndex = 0x0400 ( GET_FPGA_CONFIG_REQUEST )
NTSTATUS GnganfgDevice::KernelModeGetDeviceStatus( USHORT wIndex, PUCHAR bDevStatus )
{
	NTSTATUS status = STATUS_SUCCESS;
	PURB	pUrb = NULL;

	pUrb = m_Lower.BuildVendorRequest(
						bDevStatus,			// transfer buffer
						1,								// transfer buffer size
						0,								// request reserved bits(The recipient is Device)
						0x0C,							// request
						0,								// Value
						TRUE,							// In 
						TRUE,							// Short Ok
						NULL,							// link urb
						wIndex,							// index
						URB_FUNCTION_VENDOR_DEVICE		// function
						);

	if ( pUrb == NULL)
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
		return status;
	}

	status = m_Lower.SubmitUrb( pUrb );
	delete pUrb;  

	return status;
}

NTSTATUS GnganfgDevice::ConfigFpga( VOID )
{
	NTSTATUS status = STATUS_SUCCESS;
	ULONG dwConfigLength = 0x20000;				// 128k byte.
	ULONG	dwTotalSize;
	PURB    pUrb;
	ULONG   tempWriteSize, dwWaittime;
	CHAR    bStringCom[16] = { 0x00, 0x1b, 0x46, 0x54, 0x50, 0x4a, 0x4c, 0x5f, 
								   0x46, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };


	PVOID lpBuffer =  ExAllocatePool( NonPagedPool,				// IN POOL_TYPE  PoolType,
									  (SIZE_T)dwConfigLength );	// IN SIZE_T  NumberOfBytes.

	if ( lpBuffer == NULL )
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
		return status;
	}

	// The name of the file to open is passed in the input buffer.
	// KUstring name = L"\\??\\C:\\FtA65U2.rbf";
	KUstring name = L"\\DosDevices\\C:\\TestHw.rbf";

	status = m_File.OpenCreate(	name,
								NULL,
								FILE_GENERIC_READ | SYNCHRONIZE,
								OBJ_CASE_INSENSITIVE,
								0,
								FILE_SHARE_READ,
								FILE_OPEN,
								FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

	if (status != STATUS_SUCCESS)	
	{
		goto Clearup;
	}

	status = m_File.Read( (PUCHAR)lpBuffer,
						  dwConfigLength,
						  &dwTotalSize,
						  NULL	);

	m_File.Close();

	if (status != STATUS_SUCCESS)	
		goto Clearup;

	/////////////////////////////////////////////////////////////
	// Perform configuration operation.
	// Submit Config FPGA Command -- Start Config.
		// status = KernelModeSetDeviceCommand( SET_FPGA_CONFIG_REQUEST );
	
	bStringCom[9] = CONFIG_FPGA_START_COMMAND;
	tempWriteSize = CONFIG_FPGA_COMMAND_LENGTH;
	pUrb = NULL;
	pUrb = m_Endpoint4.BuildBulkTransfer(
   							&bStringCom,      	// Where is data coming from?
							tempWriteSize, 	    // How much data to write?
							FALSE,         		// direction (TRUE = IN)
							NULL,				// Link to next URB
							FALSE);  
					
	if (pUrb == NULL)
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto Clearup;
	}
	// Submit the URB to our USB device
	dwWaittime = 30;
	status = m_Endpoint4.SubmitUrb(pUrb, NULL, NULL, dwWaittime);	
				
	// if successful then calculate the amount of the read bytes
	if ( NT_SUCCESS(status) ) 
		delete pUrb;

	// Submit config file to usb device.
	if ( NT_SUCCESS(status) )
	{
		ULONG	dwMaxTransferSize = m_Endpoint4.MaximumTransferSize();
		ULONG	i, dwWriteTimes;

		// Added 0xFF to end of the file.
		PVOID lpTmpBuf = (char*)lpBuffer + dwTotalSize;
		*(char*)(lpTmpBuf) = (CHAR)(0xff);
		for ( i = 0; i < 88; i++ )
		{
			lpTmpBuf = (char*)lpTmpBuf + sizeof(CHAR);
			*(char*)(lpTmpBuf) = (CHAR)(0xff);
		}

		dwTotalSize += 80;	

		dwWaittime = ( dwMaxTransferSize/64 ) * 30;
		lpTmpBuf = lpBuffer;	

		// calculate the Write times needed to complete this read request
		dwWriteTimes = dwTotalSize/dwMaxTransferSize;
		if( dwTotalSize%dwMaxTransferSize ) dwWriteTimes++;

		for( i = 0; i < dwWriteTimes; i ++ )
		{
			// Create an URB to do actual Bulk read from the pipe
			tempWriteSize = dwMaxTransferSize;
			if( (i == (dwWriteTimes - 1 )) && (dwTotalSize%dwMaxTransferSize) ) // last read and read length less than dwMaxTransferSize
			{
				tempWriteSize = dwTotalSize%dwMaxTransferSize;
			}

			pUrb = NULL;
			pUrb = m_Endpoint4.BuildBulkTransfer(
	    							lpTmpBuf,      		// Where is data coming from?
									tempWriteSize, 	    // How much data to write?
									FALSE,         		// direction (TRUE = IN)
									NULL,				// Link to next URB
									FALSE);  
					
			if (pUrb == NULL)
			{
				status = STATUS_INSUFFICIENT_RESOURCES;
				goto Clearup;
			}

				
			// Submit the URB to our USB device
			status = m_Endpoint4.SubmitUrb(pUrb, NULL, NULL, dwWaittime);	
				
			// if successful then calculate the amount of the read bytes
			if ( NT_SUCCESS(status) ) 
			{
				delete pUrb;
				// adjust the buffer pointer
				lpTmpBuf = (char*)lpTmpBuf + tempWriteSize;
			}
			else
			{
				goto Clearup;
			}
		}

		/////////////////////////////////////////////////////////////
		// Submit Config FPGA Command -- end Config.
			// status = KernelModeSetDeviceCommand( SET_FPGA_CONFIG_COMPLETE );
		
		bStringCom[9] = CONFIG_FPGA_END_COMMAND;
		tempWriteSize = CONFIG_FPGA_COMMAND_LENGTH;
		pUrb = NULL;
		pUrb = m_Endpoint4.BuildBulkTransfer(
   								&bStringCom,      	// Where is data coming from?
								tempWriteSize, 	    // How much data to write?
								FALSE,         		// direction (TRUE = IN)
								NULL,				// Link to next URB
								FALSE);  
		if (pUrb == NULL)
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			goto Clearup;
		}
		// Submit the URB to our USB device
		dwWaittime = 30;
		status = m_Endpoint4.SubmitUrb(pUrb, NULL, NULL, dwWaittime);	
					
		// if successful then calculate the amount of the read bytes
		if ( NT_SUCCESS(status) ) 
			delete pUrb;
	}
		
Clearup:

	if (lpBuffer) 
	{
		ExFreePool(lpBuffer);
		lpBuffer = NULL;
	}

	return status;
}

⌨️ 快捷键说明

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