USB String Descriptor

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USB String Descriptor

3,598 Views
FarhanH
Contributor III

Is there any code that shows how to use ch9 functions to retrieve a string based on its index from a connected device? The ch9 function documentation isn't very good and I can't seem to find an example of that anywhere (including the forums).

Thanks!

0 Kudos
10 Replies

1,993 Views
DerekLau
Contributor IV

You can dowload Freescale USB stack at USB Stack Product Summary Page which contains many USB example codes. There are host and device examples and I suggest you to take a look at the HID examples. In the device example "usb_descriptor.c" file includes USB_STR_0, USB_STR_1 and USB_STR_2 decriptors corresponding to the string index 0,1 and 2. In the "usb_framework.c' file, look at the USB_Strd_Req_Get_Descriptor() function. In the host example "host_ch9.c" file, look at the _usb_host_ch9_get_descriptor() function.

0 Kudos

1,993 Views
FarhanH
Contributor III

Hi Derek,

Thank you for the quick reply. I was indeed referencing the USB stack. I am using the Host API.

According the the stack source, I have to use _usb_host_ch9_get_descriptor() to get a string descriptor, which is fine. However, the API documentation only mentions that it gets a descriptor and returns USB_OK on success. This is apparently incorrect as the source shows it will return USB_STATUS_TRANSFER_QUEUED. What is the next step? Is there something that indicates whether the transfer was successful or not? I can see _usb_host_get_transfer_status() in the Host API but that requires a pipe_handle and transfer number. Or, do I need to set up the bus somehow before I call _usb_host_ch9_get_descriptor()?

I have looked at the dev_list function but that also just checks for USB_STATUS_TRANSFER_QUEUED then exits.

The Host level API has _usb_host_send_setup(), but that is more primitive than the ch9 functions. I don't mind creating my own setup packet to get a string descriptor but I don't know why there isn't a HOST example of this (or I am clearly missing it somehow).

Based on what you said about HID, it looks like maybe I need to have a control callback registered in order to work with string descriptors. I will try setting that up.

Thanks!

0 Kudos

1,993 Views
FarhanH
Contributor III

Ok, I tried a few other options with the ch9 functions, and also tried _usb_hostdev_cntrl_request as shown in the msd example. It looks like callbacks get registered ok but they never get called. Is there something else that needs to be done? I really need to be able to read the string descriptors from a device.

I should clarify:

I want to be able to read the string descriptors without having to select an interface (and without using a class, just send and receive control requests). From the code, it looks like the ch9 get descriptor function will override the callback if the device hasn't moved into DEVSTATE_ENUM_OK state. It will enter the DEVSTATE_ENUM_OK state when it has interfaced. Also, _usb_hostdev_cntrl_request will give a device not found error if not in DEVSTATE_ENUM_OK state.

Thanks again!

0 Kudos

1,993 Views
FarhanH
Contributor III

Here is some code that only calls the callback on detach for some reason, and returns error 97, meaning TR failed. I still haven't been able to successfully create a control command or retrieve a string index from the device.

This is in the main device callback, under the attached event.

case USB_DEVICE_ATTACHED:

  printf( "Device Attached\n" );

  dev_ptr = (DEV_INSTANCE_PTR)usb_dev.dev_handle;

  usb_dev.dev_state = USB_DEVICE_OTHER;

  dev_ptr->state = DEVSTATE_ENUM_OK;

  status = _usb_host_register_ch9_callback(

  usb_dev.dev_handle,

  usb_host_mass_device_cntrl,

  usb_dev.intf_handle);

  if(status != USB_OK) {

  printf("Control callback registration ERROR: 0x%x\n", status);

  }

  /* Read device status to push it into DEVSTATE_ENUM_OK */

  status = _usb_host_ch9_get_descriptor(usb_dev.dev_handle,

  (REQ_GET_DESCRIPTOR << 8) | 3, 0x0409 , 0x40, buffer);

  if(status != USB_STATUS_TRANSFER_QUEUED) {

  printf("Get descriptor ERROR: 0x%x\n", status);

  }

  break;

This is the ch9 registered callback, that seems to only fire on detach (or on attach if I change the get_descriptor call to ..0, 0, 2, buffer, which is getstatus):

void usb_host_mass_device_cntrl

(

      /* [IN] pointer to pipe */

      _usb_pipe_handle  pipe_handle,

      /* [IN] user-defined parameter */

      pointer           user_parm,

      /* [IN] buffer address */

      uchar_ptr         buffer,

      /* [IN] length of data transferred */

      uint_32           length_data_transfered,

      /* [IN] status, hopefully USB_OK or USB_DONE */

      uint_32           status

   )

{

  uint_8 count;

  if(status == USB_OK) {

       printf("Serial Number: ");

  for(count = 0; count < length_data_transfered; count++) {

  printf("%x-", buffer[count]);

  }

  printf("\n");

  }

  else {

  printf("Callback Error: 0x%x\n", status);

  }

}

0 Kudos

1,993 Views
DerekLau
Contributor IV

Hello Farhan,

To make it quick, I have just changed the get device descriptor to get string descriptor

Here is what I have done in the host example of HID mouse in USB Stack 4.0.3 (seems 4.1.1 has some issues).


In the usb_host_cntrl_transaction_done()

      case DEVSTATE_ADDR_SET:     /* address set */

     .............

// Get device descriptor

/*          status = _usb_host_ch9_get_descriptor((pointer)dev_inst_ptr,

            USB_DESC_TYPE_DEV << 8,

            0,

            USB_DESC_LEN_DEV,

            (uchar_ptr)&dev_inst_ptr->dev_descriptor);

*/

// change get device descriptor to get string descriptor       

         static uint_8 string[0xFF];    

         uint_8 index;

         index = 1;

        

         status = _usb_host_ch9_get_descriptor((pointer)dev_inst_ptr,

            USB_DESC_TYPE_STR << 8 | index,

            0x0409,

            0xFF,

            (uchar_ptr)&string);

// end of get string descriptor 

      case DEVSTATE_DEV_DESC:     /* full device descriptor received */

         /* Now lets get the first 9 bytes of the configuration

         ** descriptor

         */

         desc.pntr = &dev_inst_ptr->buffer;     <----- set a break point here to see the data in string[]

0 Kudos

1,993 Views
FarhanH
Contributor III

Ok, looked into it a little further. When a ch9 command for a string descriptor is sent, the program gets stuck inside khci_kinetis.c when Poll is called in the main loop. I checked the running code a few times and it keeps looping back to label "try_again" (line 334). This infinite loop prevents the program from getting to the attach event and when the device is detached, it breaks the loop and gives an error (because the rest of the program flow continues).

EDIT

Just for the heck of it, I tried a few different devices.

Sony 4GB USB drive (USM4GM) = Stuck in loop

Samsung Omnia 7 = Correctly gets strings

IBM USB Mouse = Correctly gets strings

0 Kudos

1,993 Views
DerekLau
Contributor IV

Hello Farhan,

I have modified the code so that you can get the string descriptor by using _usb_hostdev_get_descriptor. Please see my message to you.

0 Kudos

1,993 Views
rickbronson
Contributor II

Could you share the code that you got working above?  I'm in need of this feature.

  Thanks much.

  RIck

0 Kudos

1,993 Views
FarhanH
Contributor III

If I modify the library the way you have stated then it won't pull the device descriptor anymore. Plus, I need the device descriptor in order to check the string descriptor index. I also tried inserting another level in-between DEVSTATE_DEV_DESC and DEVSTATE_GET_CFG9 to pull in the string descriptors, without disrupting the stack's ability to get device descriptor. It seems to always run into an issue, specifically, the callback isn't fired until the device is detached.

I don't understand what exactly is going on but it seems like any time I try to do a get descriptor on a string, the endpoint stalls or has some other problems even when using the code you described above. This probably translates to the callback firing on detach with an error. If I try any other control control command, it seems to work.

0 Kudos

1,993 Views
FarhanH
Contributor III

I can try that. So is there a normal way to access the string descriptors in the main program without having to modify the library? I am surprised at how difficult it is to do a simple string descriptor request.

0 Kudos