none
WinUSB reading multiple IN endpoints RRS feed

  • Question

  • Hi,

    I am struggling to read data prom 3 IN bulk endpoints. I am able to receive data from my MCu and access it in the application that uses WinUSB functions, however, I always read data only from one pipe. When I use  QueryDeviceEndpoints() function I do recognize more than one IN endpoint but ReadFromBulkEndpoint() receives same data independently with which &PIPEID I call. 

    If I use one IN and one OUT endpoints it works fine.

    I run out of ideas. Any clue?

    Thanks in advance.

    Sunday, September 10, 2017 8:23 PM

All replies

  • post your code.  ReadFromBulkEndpoint and QueryDeviceEndpoints are your own code, reading from multiple endpoints works, you are doing something wrong in your code.


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Monday, September 11, 2017 12:34 AM
  • Thanks for the response. 

    I have also tried using twice function WinUsb_QueryPipe() which is in fact called inside of the QueryDeviceEndpoints() but same result. I read data from one endpoint. I will be thankful for comments and advice.

    Here is the main file:

    #include "pch.h"
    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string>
    #include <sstream>
    
    #include  <Winusbio.h>
    #include "Usbscan.h"
    #include "Winbase.h"
    #include <SetupAPI.h>
    #include <winioctl.h>
    
    using namespace std;
    
    
    BOOL    gResult;
    UCHAR speed;
    UCHAR index = 1;
    UCHAR PID;
    ULONG PCBWRITTEN;
    _USB_INTERFACE_DESCRIPTOR InterfaceDescriptor1;
    UCHAR loop = 1;
    WINUSB_PIPE_INFORMATION Pipe1;
    WINUSB_PIPE_INFORMATION Pipe2;
    
    
    struct PIPE_ID
    {
    	UCHAR  PipeInId1;
    	UCHAR  PipeInId2;
    	UCHAR  PipeOutId;
    };
    
    PIPE_ID pipeid1;
    
    struct PIPE1_ID
    {
    	UCHAR  PipeInId_1;
    };
    
    PIPE1_ID pipe_id1;
    
    
    struct PIPE2_ID
    {
    	UCHAR  PipeInId_2;
    };
    
    
    PIPE2_ID pipe_id2;
    
    BOOL QueryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid)
    {
    	if (hDeviceHandle == INVALID_HANDLE_VALUE)
    	{
    		return FALSE;
    	}
    
    	BOOL bResult = TRUE;
    
    	USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    	ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));
    
    	WINUSB_PIPE_INFORMATION  Pipe;
    	ZeroMemory(&Pipe, sizeof(WINUSB_PIPE_INFORMATION));
    
    
    	bResult = WinUsb_QueryInterfaceSettings(hDeviceHandle, 0, &InterfaceDescriptor);
    
    	if (bResult)
    	{
    		for (char index = 0; index < InterfaceDescriptor.bNumEndpoints; index++)
    		{
    			bResult = WinUsb_QueryPipe(hDeviceHandle, 0, index, &Pipe);
    
    			if (bResult)
    			{
    				if (Pipe.PipeType == UsbdPipeTypeControl)
    				{
    					printf("Endpoint index: %d Pipe type: Control Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
    				}
    				if (Pipe.PipeType == UsbdPipeTypeIsochronous)
    				{
    					printf("Endpoint index: %d Pipe type: Isochronous Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
    				}
    				if (Pipe.PipeType == UsbdPipeTypeBulk)
    				{
    					if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId))
    					{
    						printf("Endpoint index: %d Pipe type in: Bulk Pipe ID: %c.\n", index, Pipe.PipeType, Pipe.PipeId);
    						printf("Endpoint index: %d Pipe type: Pipe Interval: %d.\n", index, Pipe.Interval, Pipe.PipeId);
    						if (index==0)
    						{ 
    						pipeid->PipeInId1 = Pipe.PipeId;
    						}
    						else
    						{
    						pipeid->PipeInId2 = Pipe.PipeId;
    						}
    					}
    					if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId))
    					{
    						printf("Endpoint index: %d Pipe type out: Bulk Pipe ID: %c.\n", index, Pipe.PipeType, Pipe.PipeId);
    						printf("Endpoint index: %d Pipe type: Pipe Interval: %d.\n", index, Pipe.Interval, Pipe.PipeId);
    
    						pipeid->PipeOutId = Pipe.PipeId;
    					}
    
    				}
    				if (Pipe.PipeType == UsbdPipeTypeInterrupt)
    				{
    					printf("Endpoint index: %d Pipe type: Interrupt Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
    				}
    			}
    			else
    			{
    				continue;
    			}
    		}
    	}
    
    	//done:
    	return bResult;
    }
    
    
    
    
    BOOL GetUSBDeviceSpeed(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pDeviceSpeed)
    {
    	if (!pDeviceSpeed || hDeviceHandle == INVALID_HANDLE_VALUE)
    	{
    		return FALSE;
    	}
    
    	BOOL bResult = TRUE;
    
    	ULONG length = sizeof(UCHAR);
    
    	bResult = WinUsb_QueryDeviceInformation(hDeviceHandle, DEVICE_SPEED, &length, pDeviceSpeed);
    	if (!bResult)
    	{
    		printf("Error getting device speed: %d.\n", GetLastError());
    		goto done;
    	}
    
    	if (*pDeviceSpeed == LowSpeed)
    	{
    		printf("Device speed: %d (Low speed).\n", *pDeviceSpeed);
    		goto done;
    	}
    	if (*pDeviceSpeed == FullSpeed)
    	{
    		printf("Device speed: %d (Full speed).\n", *pDeviceSpeed);
    		goto done;
    	}
    	if (*pDeviceSpeed == HighSpeed)
    	{
    		printf("Device speed: %d (High speed).\n", *pDeviceSpeed);
    		goto done;
    	}
    
    done:
    	return bResult;
    }
    
    
    
    
    
    BOOL WriteToBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG* pcbWritten, PUCHAR send)
    {
    
    
    	if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID || !pcbWritten)
    	{
    
    		return FALSE;
    	}
    
    	BOOL bResult = TRUE;
    
    	//UCHAR szBuffer[] = send;
    	ULONG cbSize = 1;
    	ULONG cbSent = 0;
    	//	UCHAR send_data = 'k';
    
    
    	bResult = WinUsb_WritePipe(hDeviceHandle, *pID, send, cbSize, &cbSent, 0);
    	if (!bResult)
    	{
    
    		goto done;
    	}
    
    	printf("Wrote to pipe %d: %s \nActual data transferred: %d.\n", *pID, send, cbSent);
    	*pcbWritten = cbSent;
    
    
    done:
    	return bResult;
    
    }
    
    
    
    
    BOOL ReadFromBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG cbSize)
    {
    	if (hDeviceHandle == INVALID_HANDLE_VALUE)
    	{
    		return FALSE;
    	}
    
    	BOOL bResult = TRUE;
    
    	UCHAR* szBuffer = (UCHAR*)LocalAlloc(LPTR, sizeof(UCHAR)*cbSize);
    
    	ULONG cbRead = 0;
    
    	bResult = WinUsb_ReadPipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbRead, 0);
    	if (!bResult)
    	{
    		goto done;
    	}
    
    	printf("Read from pipe %d: %s \nActual data read: %d.\n", *pID, szBuffer, cbRead);
    
    
    done:
    	LocalFree(szBuffer);
    	return bResult;
    
    }
    
    
    
    
    
    
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    LONG __cdecl
    _tmain(
    LONG     Argc,
    LPTSTR * Argv
    )
    /*++
    
    Routine description:
    
    Sample program that communicates with a USB device using WinUSB
    
    --*/
    {
    	DEVICE_DATA           deviceData;
    	HRESULT               hr;
    	USB_DEVICE_DESCRIPTOR deviceDesc;
    	BOOL                  bResult;
    	BOOL                  noDevice;
    	ULONG                 lengthReceived;
    
    
    	UNREFERENCED_PARAMETER(Argc);
    	UNREFERENCED_PARAMETER(Argv);
    
    	//
    	// Find a device connected to the system that has WinUSB installed using our
    	// INF
    	//
    	hr = OpenDevice(&deviceData, &noDevice);
    
    	if (FAILED(hr)) {
    
    		if (noDevice) {
    
    			printf(_T("Device not connected or driver not installed\n"));
    			cin.get();
    		}
    		else {
    
    			printf(_T("Failed looking for device, HRESULT 0x%x\n"), hr);
    			cin.get();
    		}
    
    		return 0;
    	}
    
    	//
    	// Get device descriptor
    	//
    	bResult = WinUsb_GetDescriptor(deviceData.WinusbHandle,
    		USB_DEVICE_DESCRIPTOR_TYPE,
    		0,
    		0,
    		(PBYTE)&deviceDesc,
    		sizeof(deviceDesc),
    		&lengthReceived);
    
    	if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) {
    
    		printf(_T("Error among LastError %d or lengthReceived %d\n"),
    			FALSE == bResult ? GetLastError() : 0,
    			lengthReceived);
    		cin.get();
    		return 0;
    	}
    
    	//
    	// Print a few parts of the device descriptor
    	//
    	printf(_T("Device found: VID_%04X&PID_%04X; bcdUsb %04X\n"),
    		deviceDesc.idVendor,
    		deviceDesc.idProduct,
    		deviceDesc.bcdUSB);
    
    
    
    	gResult = WinUsb_QueryInterfaceSettings(deviceData.WinusbHandle,
    		0,
    		&InterfaceDescriptor1);
    
    	printf("#: %d. \n", InterfaceDescriptor1.bNumEndpoints);
    
    
    
    
    	gResult = GetUSBDeviceSpeed(deviceData.WinusbHandle,
    		&speed);
    
    
    
    	//gResult = QueryDeviceEndpoints(deviceData.WinusbHandle,
    	//	&pipeid1);
    
    
    
    	gResult = WinUsb_QueryPipe(deviceData.WinusbHandle, 0, 0, &Pipe1);
    	pipe_id1.PipeInId_1 = Pipe1.PipeId;
    
    	gResult = WinUsb_QueryPipe(deviceData.WinusbHandle, 0, 1, &Pipe2);
    	pipe_id2.PipeInId_2 = Pipe2.PipeId;
    
    
    
    	while (loop == 1)
    	{
    
    
    		gResult = ReadFromBulkEndpoint(deviceData.WinusbHandle, &pipe_id1.PipeInId_1, 5);
    		gResult = ReadFromBulkEndpoint(deviceData.WinusbHandle, &pipe_id2.PipeInId_2, 5);
    
    
    	}
    
    
    	cin.get();
    
    	return 0;
    }
    


    Monday, September 11, 2017 4:13 AM
  • Any clues?
    Tuesday, September 12, 2017 8:27 PM