Solved

WinCE USB Driver Problem Setting Configuration

Posted on 2006-06-20
6
1,882 Views
Last Modified: 2013-12-27
Project: Driver for USB to Serial device in WinCE
IDE: Platform Builder for Win CE 5.0

So far, we are able to get the device to enumerate properly (Getting device, configuration descriptors etc..) However, we are unable to set the configuration. In the Device descriptor, there are 2 Configurations. Config1 with only 1 bulk out pipe. Config2 one with 1 bulk out, 1 bulk in and 1 interrupt. The problem we are having is setting the configuration to Config2.

Descriptors:
// Device Descriptor
-      pDevice      0x005114dc
      dwCount      0x00000020
-      Descriptor      {...}
      bLength      0x12 '?'
      bDescriptorType      0x01 '?'
      bcdUSB      0x0110
      bDeviceClass      0xff 'ÿ'
      bDeviceSubClass      0x00
      bDeviceProtocol      0x00
      bMaxPacketSize0      0x08 '?'
      idVendor      0x0451
      idProduct      0x3410
      bcdDevice      0x0101
      iManufacturer      0x01 '?'
      iProduct      0x02 '?'
      iSerialNumber      0x03 '?'
      bNumConfigurations      0x02 '?'

//Config1      
-      lpActiveConfig      0x002bc1e0
      dwCount      0x0000001c
-      Descriptor      {...}
      bLength      0x09 '?'
      bDescriptorType      0x02 '?'
      wTotalLength      0x0019
      bNumInterfaces      0x01 '?'
      bConfigurationValue      0x01 '?'
      iConfiguration      0x00
      bmAttributes      0x80 '€'
      MaxPower      0x32 '2'
      lpvExtended      0x00000000
      dwNumInterfaces      0x00000001
+      lpInterfaces      0x005113e0

//Config2
-      pConfigDesc      0x002bc1fc
      dwCount      0x0000001c
-      Descriptor      {...}
      bLength      0x09 '?'
      bDescriptorType      0x02 '?'
      wTotalLength      0x0027
      bNumInterfaces      0x01 '?'
      bConfigurationValue      0x02 '?'
      iConfiguration      0x00
      bmAttributes      0xa0 ' '
      MaxPower      0x32 '2'
      lpvExtended      0x00000000
      dwNumInterfaces      0x00000001
+      lpInterfaces      0x00511440


This is what we used to set the Configuration:

// This SET configuration was completed successfully
USB_DEVICE_REQUEST usbDevReq;
usbDevReq.bmRequestType = USB_REQUEST_HOST_TO_DEVICE | USB_REQUEST_STANDARD | USB_REQUEST_FOR_DEVICE;
usbDevReq.bRequest = USB_REQUEST_SET_CONFIGURATION;
usbDevReq.wValue = (pDevice->lpConfigs + *ConfigIndex)->Descriptor.bConfigurationValue;
usbDevReq.wIndex = 0;
usbDevReq.wLength = 0;
USB_TRANSFER usbTrans = UsbFuncs->lpIssueVendorTransfer(hUsbDevice, NULL,
                                                0, USB_OUT_TRANSFER | USB_SHORT_TRANSFER_OK,
                                                                        &usbDevReq, NULL, NULL);

// This GET configuration was able to verify that the Configuration was Set to Config2      (ConfigValue = 2)
int Configvalue = 0;
      usbDevReq.bmRequestType = 0x80;
      usbDevReq.bRequest = USB_REQUEST_GET_CONFIGURATION;
      usbDevReq.wValue = 0;
      usbDevReq.wIndex = 0;
      usbDevReq.wLength = 1;
      usbTrans = UsbFuncs->lpIssueVendorTransfer(hUsbDevice, NULL,
                                                      0, USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK,
                                                      &usbDevReq, &Configvalue, NULL);
                                                      
// However, Using lpGetDeviceInfo, the lpActiveConfig->Descriptor->bConfigurationValue is still 1(Config1)      
pDevice = UsbFuncs->lpGetDeviceInfo( hUsbDevice );

Another indication that the lpActiveConfig has not been set properly is that we are unable to open the bulk in pipe which is only present in Config2.

Is there something we are missing here?
0
Comment
Question by:ceoconsultancy
  • 2
  • 2
6 Comments
 
LVL 6

Expert Comment

by:umahesh
ID: 17029196
Your lpActiveConfig looks fine.

check with this,

pUsbDevice = pUsbFuncs->lpGetDeviceInfo(hDevice);
        if (pUsbDevice != NULL) {
            pUsbInterfaceToUse = pUsbDevice->lpActiveConfig->lpInterfaces;
        }      

The driver should get the device information (pointer to USB_DEVICE) and use the lpActiveConfig parameter to get a pointer to an array of interfaces (lpInterfaces). The first interface is lpInterfaces[0].

Check with USB descriptors here..
http://www.beyondlogic.org/usbnutshell/usb5.htm#DeviceDescriptors

For more details on USB driver development, check
http://www.beyondlogic.org/usb/usbdevdrvs.htm

0
 

Author Comment

by:ceoconsultancy
ID: 17029767
We have managed to solve the problem. We tried letting the driver set the correct config automatically by setting the registry. From there we found that our firmware does not display the correct number of configurations in the device descriptor.

Thanks for your response, umahesh
0
 
LVL 6

Expert Comment

by:umahesh
ID: 17034596
Thats gr8.
please share your success, how you did that, to the community.

0
 

Author Comment

by:ceoconsultancy
ID: 17056050
Our firmware shows 2 configurations, however the value of lpDeviceInfo->lpConfigs[bIndex].Descriptor.iConfiguration for both the configurations was 0. And we want to select the 2nd configuration.
We had 2 choices:
1. To change the firmware such that the iConfiguration would show the correct value
2. Modify the HcdSelectConfiguration() to select the correct configuration in usbddrv.
We chose the 2nd approach which isnt the correct way but due to our limited resources(we do not have the source for the firmware) was the best approach.

We set it in the .reg file so that the 2nd configuration was to be selected with this entry "iConfiguration"=dword:1
and the modification to HcdSelectConfiguration as follows:
extern "C" BOOL HcdSelectConfiguration(LPCUSB_DEVICE lpDeviceInfo, LPBYTE lpbConfigure)
{
    if (lpbConfigure && lpDeviceInfo) {
        BOOL bReturn = FALSE;
        TCHAR RegPath[MAX_PATH];    
        HKEY hClientRegKey;
        DWORD dwData = 0;
        if (!bReturn && ConvertToClientRegistry(RegPath,MAX_PATH,lpDeviceInfo,NULL,TRUE,TRUE,FALSE,NULL)) {
            DWORD dwType = 0;
            DWORD dwLength = sizeof(DWORD);
            if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegPath,0,0,&hClientRegKey) == ERROR_SUCCESS ) { // We found Registry
                if (RegQueryValueEx( hClientRegKey,gcszUsbConfigureEntry, NULL,&dwType, (LPBYTE)&dwData, &dwLength) == ERROR_SUCCESS)
                    bReturn = TRUE;
                RegCloseKey( hClientRegKey );
            }
        }
        if (!bReturn && ConvertToClientRegistry(RegPath,MAX_PATH,lpDeviceInfo,NULL,TRUE,FALSE,FALSE,NULL)) {
            DWORD dwType = 0;
            DWORD dwLength = sizeof(DWORD);
            if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegPath,0,0,&hClientRegKey) == ERROR_SUCCESS ) { // We found Registry
                if (RegQueryValueEx( hClientRegKey,gcszUsbConfigureEntry, NULL,&dwType, (LPBYTE)&dwData, &dwLength) == ERROR_SUCCESS)
                    bReturn = TRUE;
                RegCloseKey( hClientRegKey );
            }
        }
        if (!bReturn && ConvertToClientRegistry(RegPath,MAX_PATH,lpDeviceInfo,NULL,FALSE,TRUE,FALSE,NULL)) {
            DWORD dwType = 0;
            DWORD dwLength = sizeof(DWORD);
            if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegPath,0,0,&hClientRegKey) == ERROR_SUCCESS ) { // We found Registry
                if (RegQueryValueEx( hClientRegKey,gcszUsbConfigureEntry, NULL,&dwType, (LPBYTE)&dwData, &dwLength) == ERROR_SUCCESS)
                    bReturn = TRUE;
                RegCloseKey( hClientRegKey );
            }
        }
        if (bReturn) { // We have Return. We need search for the index.
            for (BYTE bIndex= 0; lpDeviceInfo->lpConfigs != NULL && bIndex < lpDeviceInfo->Descriptor.bNumConfigurations ; bIndex ++) {
   /***Changes here***/           //  if (lpDeviceInfo->lpConfigs[bIndex].Descriptor.iConfiguration == (BYTE)dwData) {
                     *lpbConfigure = (BYTE)dwData;//bIndex;
                     return TRUE;
               // }
               
            }
        }
       
    }
    return FALSE;
}
0
 

Accepted Solution

by:
CetusMOD earned 0 total points
ID: 17583059
PAQed with points refunded (500)

CetusMOD
Community Support Moderator
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Progress means simplifying, not complicating. Bruno Munari Preface How to detect the name of the internal storage or an SD-card on Windows Mobile device from the desktop application? I got this question, when I was working on a PC applicati…
Preface: This article is part of a series focused on cross platform mobile app development (specifically Android and iOS) using the Alloy framework and Titanium Studio made by Appcelerator (https://www.appcelerator.com/). This article presumes a wor…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question