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

📄 ezusbdevice.cpp

📁 EZ_USB cy7c68013的驱动程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
//		This routine will set or clear the 8051 reset bit on the EZUSB chip.
//		It issues the vendor command EZUSB_LOAD_INTERNAL.  byResetBit = 1 will
//		set the bit which will hold the 8051 in reset.  byResetBit = 0 will
//		clear the bit which will start the 8051 running again.
//
NTSTATUS EzUsbDevice::Reset8051(UCHAR byResetBit)
{
	t << "Entering Reset8051\n";

	NTSTATUS status = STATUS_SUCCESS;

	PURB pUrb = m_Lower.BuildVendorRequest(
							&byResetBit,
							1,
							0,
							EZUSB_LOAD_INTERNAL,
							EZUSB_CPU_CONTROL_STATUS_REG,
							FALSE,						//default
							FALSE,						//default
							NULL,						//default
							0,							//default
							URB_FUNCTION_VENDOR_DEVICE	//default
							);

	if( NULL == pUrb )
	{
		return STATUS_NO_MEMORY;
	}

	status = m_Lower.SubmitUrb(pUrb);

	delete pUrb;

	return status;
}

//=============================================================================
// EzUsbDevice::DownloadRAM
//
//		This routine will download firmware to internal or external RAM of the
//		EZUSB.  It uses vendor commands EZUSB_LOAD_EXTERNAL or 
//		EZUSB_LOAD_INTERNAL.
//
NTSTATUS EzUsbDevice::DownloadRAM(PINTEL_HEX_RECORD pHexRecord, bool fExternal)
{
	t << "Entering DownloadRAM\n";

	NTSTATUS status = STATUS_SUCCESS;
	URB Urb;

	while( 0 == pHexRecord->Type )
	{
		if( fExternal ? 
						(! EZUSB_INTERNAL_RAM( pHexRecord->Address )) : 
						(EZUSB_INTERNAL_RAM( pHexRecord->Address ))  
		  )
		{
			m_Lower.BuildVendorRequest(
				pHexRecord->Data,
				pHexRecord->Length,
				0,
				static_cast<UCHAR>( 
					fExternal ? EZUSB_LOAD_EXTERNAL : EZUSB_LOAD_INTERNAL),
				pHexRecord->Address,
				FALSE,						//default
				FALSE,						//default
				NULL,						//default
				0,							//default
				URB_FUNCTION_VENDOR_DEVICE,	//default
				&Urb
				);

			status = m_Lower.SubmitUrb(&Urb);

			if( !NT_SUCCESS(status) )
			{
				break;
			}
		}

		pHexRecord++;
	}

	return status;
}

//=============================================================================
// EzUsbDevice::DownloadIntelHex
//
//		This routine will download firmware to the EZUSB.  
//
NTSTATUS EzUsbDevice::DownloadIntelHex(PINTEL_HEX_RECORD pHexRecord)
{
	t << "Entering DownloadIntelHex\n";

	NTSTATUS status = STATUS_SUCCESS;

	// Download external RAM 
	status = DownloadRAM(pHexRecord, true);

	if( !NT_SUCCESS(status) )
		return status;

	Reset8051(1);

	// Download internal RAM 
	status = DownloadRAM(pHexRecord, false);

	return status;
}

//=============================================================================
// EzUsbDevice::AnchorDownload
//
//		This routine will download firmware to the EZUSB.  The download is
//		accomplished by issuing an _URB_CONTROL_VENDOR_OR_CLASS_REQUEST with
//		vendor specific command EZUSB_LOAD_INTERNAL.  The buffer of firmware
//		to download (pDownloadBuffer) will be split into nTransferLength 
//		requests of size nDownloadSize.
//
NTSTATUS EzUsbDevice::AnchorDownload(
   USHORT wOffset,
   PUCHAR pDownloadBuffer,
   ULONG nDownloadSize,
   ULONG nTransferLength,
   ULONG nTransferCount
   )
{
	t << "Entering AnchorDownload\n";

	NTSTATUS status = STATUS_SUCCESS;
	URB u;
	RtlZeroMemory(&u, sizeof(URB));

	for (ULONG i = 0; i < nTransferCount; i++)
	{
		//Initialize the URB
		 m_Lower.BuildVendorRequest(
			pDownloadBuffer,
			( (i == (nTransferCount - 1)) && 
			  (nDownloadSize % nTransferLength) ) ?
			  (nDownloadSize % nTransferLength) :
			   nTransferLength,
			0,
			static_cast<UCHAR>( EZUSB_LOAD_INTERNAL ),
			static_cast<USHORT>( (i * nTransferLength) + wOffset ),
			FALSE,						//default
			FALSE,						//default
			NULL,						//default
			0,							//default
			URB_FUNCTION_VENDOR_DEVICE,	//default
			&u
			);

		status = m_Lower.SubmitUrb(&u);

		if( !NT_SUCCESS(status) )
		{
			break;
		}

		pDownloadBuffer += nTransferLength;
	}

	return status;
}

//=============================================================================
// EzUsbDevice::InternalDeviceControl - Handler for IRP_MJ_INTERNAL_DEVICE_CONTROL
//
//		This handler is implemented in case there is an upper filter driver
//		which submits URBs to USBD for this USB device.  
//
NTSTATUS EzUsbDevice::InternalDeviceControl(KIrp I)
{ 
	t << "Entering InternalDeviceControl\n";

	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

//=============================================================================
// EzUsbDevice::OnStopDevice - Handler for IRP_MJ_PNP / IRP_MN_STOP_DEVICE
//
//		The system calls this when the device is stopped.  The driver should 
//		unconfigure the USB device. 
//
NTSTATUS EzUsbDevice::OnStopDevice(KIrp I)
{
	NTSTATUS status = STATUS_SUCCESS;

	t << "Entering OnStopDevice\n";

	m_IntXfer.StopPolling();

	m_Lower.DeActivateConfiguration();

	return status;
	
	UNREFERENCED_PARAMETER(I);
}

//=============================================================================
// EzUsbDevice::OnRemoveDevice - Handler for IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE
//
//		The system calls this when the device is removed.
//
NTSTATUS EzUsbDevice::OnRemoveDevice(KIrp I)
{
	t << "Entering OnRemoveDevice\n";

	m_IntXfer.StopPolling();

	return STATUS_SUCCESS;

	UNREFERENCED_PARAMETER(I);
}

//=============================================================================
// EzUsbDevice::Create - Handler for IRP_MJ_CREATE
//
NTSTATUS EzUsbDevice::Create(KIrp I)
{
	t << "Entering Create\n";

	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

//=============================================================================
// EzUsbDevice::Close - Handler for IRP_MJ_CLOSE
//
NTSTATUS EzUsbDevice::Close(KIrp I)
{
	t << "Entering Close\n";

	I.ForceReuseOfCurrentStackLocationInCalldown();
	return m_Lower.PnpCall(this, I);
}

//=============================================================================
// EzUsbDevice::DeviceControl - Handler for IRP_MJ_DEVICE_CONTROL
//
//		The system calls this when an application issues DeviceIoControl
//
NTSTATUS EzUsbDevice::DeviceControl(KIrp I) 
{
	t << "Entering DeviceControl\n";

	NTSTATUS status = STATUS_SUCCESS;
	PVOID pBuffer = I.IoctlBuffer();
	ULONG dwInputBufferSize = I.IoctlInputBufferSize();
	ULONG dwOutputBufferSize = I.IoctlOutputBufferSize();

	I.Information() = 0;
	I.Status() = STATUS_SUCCESS;

	switch( I.IoctlCode() )
	{

///////////////////////////////////////////////////////////////////////////////////////////////////

	case IOCTL_EZUSB_GET_PIPE_INFO:

		t << "IOCTL_EZUSB_GET_PIPE_INFO \n";

		if( m_UsbInterface.m_Information )
		{
			//Copy the USBD_INTERFACE_INFORMATION structure stored in the KUsbInterface object
			//to the user's buffer
			RtlCopyMemory(
				reinterpret_cast<PUCHAR>( pBuffer ),
				reinterpret_cast<PUCHAR>( m_UsbInterface.m_Information ),
				m_UsbInterface.m_Information->Length
				);

			I.Information() = m_UsbInterface.m_Information->Length;
			status = STATUS_SUCCESS;
		}
		else
		{
			status = STATUS_UNSUCCESSFUL;
		}

		break;

///////////////////////////////////////////////////////////////////////////////////////////////////

	case IOCTL_EZUSB_GET_DEVICE_DESCRIPTOR:
	{
		t << "IOCTL_EZUSB_GET_DEVICE_DESCRIPTOR \n";

		status = m_Lower.GetDeviceDescriptor( PUSB_DEVICE_DESCRIPTOR(pBuffer) );

		if( NT_SUCCESS(status) )
		{
			I.Information() = PUSB_DEVICE_DESCRIPTOR(pBuffer)->bLength;
		}

		break;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
		
	case IOCTL_EZUSB_GET_CONFIG_DESCRIPTOR:
	{
		t << "IOCTL_EZUSB_GET_CONFIG_DESCRIPTOR \n";

		// The KUsbLowerDevice object contains a pointer to the configuration descriptor.
		// We simply copy the requested number of bytes from it to the IRP buffer.
		RtlCopyMemory(pBuffer, m_Lower.m_Config, dwOutputBufferSize);
		I.Information() = dwOutputBufferSize;

		break;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
		
	case IOCTL_EZUSB_VENDOR_REQUEST:
	
		t << "IOCTL_EZUSB_VENDOR_REQUEST \n";

		VendorRequest( 
			reinterpret_cast<PVENDOR_REQUEST_IN>(pBuffer), 
			I.Information()
			);

		status = STATUS_SUCCESS; // This prevents error messages in EzMr when downloading firmware
		
		break;

///////////////////////////////////////////////////////////////////////////////////////////////////
		
	case IOCTL_EZUSB_ANCHOR_DOWNLOAD2:

		t << "IOCTL_EZUSB_ANCHOR_DOWNLOAD2 \n";

		status = AnchorDownload(
					0,
					reinterpret_cast<PUCHAR>(pBuffer),
					dwInputBufferSize,
					EZUSB_ANCHOR_DOWNLOAD2_SEGMENT_SIZE,
					dwInputBufferSize / EZUSB_ANCHOR_DOWNLOAD2_SEGMENT_SIZE
					);

		break;

///////////////////////////////////////////////////////////////////////////////////////////////////
		
	case IOCTL_EZUSB_RESET:
	{
		t << "IOCTL_EZUSB_RESET \n";

		ULONG_PTR nInfo = NULL;

		status = m_Lower.DeviceIoControl(
							IOCTL_INTERNAL_USB_RESET_PORT,
							NULL,
							0,
							NULL,
							0,
							TRUE,
							&nInfo
							);
	
		break;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////

	case IOCTL_EZUSB_RESETPIPE:
	{
		t << "IOCTL_EZUSB_RESETPIPE \n";

		ULONG dwPipeNum = *( reinterpret_cast<PULONG>(pBuffer) );

		KUsbPipe* pipe = FindPipe(dwPipeNum);

		if(NULL == pipe)
		{
			status = STATUS_INVALID_PARAMETER;
		}
		else
		{
			status = pipe->Reset();
		}

		break;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
		
	case IOCTL_EZUSB_ABORTPIPE:
	{
		t << "IOCTL_EZUSB_ABORTPIPE \n";

		ULONG dwPipeNum = *( reinterpret_cast<PULONG>(pBuffer) );

		KUsbPipe* pipe = FindPipe(dwPipeNum);

		if(NULL == pipe)
		{
			status = STATUS_INVALID_PARAMETER;
		}
		else
		{
			status = pipe->Abort();
		}

		break;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
		
	case IOCTL_EZUSB_SETINTERFACE:
	{
		t << "IOCTL_EZUSB_SETINTERFACE \n";

		PSET_INTERFACE_IN p = reinterpret_cast<PSET_INTERFACE_IN>(pBuffer);

		SA_STATUS saStatus = m_UsbInterface.SelectAlternate(p->alternateSetting);

		if( SA_SUCCESS != saStatus )
		{
			t << "Error SelectAlternate returns " << static_cast<ULONG>(saStatus) << "\n";
			status = STATUS_UNSUCCESSFUL;
		}
		else
		{
			status = STATUS_SUCCESS;
		}

		break;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////

	case IOCTL_EZUSB_GET_STRING_DESCRIPTOR:

		t << "IOCTL_EZUSB_GET_STRING_DESCRIPTOR \n";

		if( (dwInputBufferSize >= sizeof(GET_STRING_DESCRIPTOR_IN)) &&
			(dwOutputBufferSize > 0)
		  )
		{
			PGET_STRING_DESCRIPTOR_IN p = reinterpret_cast<PGET_STRING_DESCRIPTOR_IN>(pBuffer);
			URB u;

			UsbBuildGetDescriptorRequest(
				&u,
				sizeof(_URB_CONTROL_DESCRIPTOR_REQUEST),
				USB_STRING_DESCRIPTOR_TYPE,
				p->Index,
				p->LanguageId,
				p,
				PMDL(0),
				dwOutputBufferSize,
				NULL
				);

⌨️ 快捷键说明

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