FTDI Community

General Category => Discussion - Drivers => Topic started by: gordlw on October 09, 2019, 01:06:14 PM

Title: VNC2 - How to select an alternate setting in a USB interface
Post by: gordlw on October 09, 2019, 01:06:14 PM
Hi there, I was hoping someone could help me with a particular issue I was having.
I am currently using the VNC2-32 chip as a USB host and I am trying to communicate with a USB device which has two bulk endpoints:
Snippet from USBView:

Configuration Descriptors:
 wTotalLength:             0x0029
 bNumInterfaces:         0x01
 bConfigurationValue:   0x01
 iConfiguration:            0x00
 bmAttributes:              0xc0
 MaxPower:                  0xfa

Interface Descriptors:
 bInterfaceNumber:      0x00
 bAlternateSetting:       0x00
 bNumEndpoints:          0x00
 bInterfaceClass:           ff
 bInterfaceSubClass:      ff
 bInterfaceProtocol:       ff
 iInterface:                   0x00

Interface Descriptors:
 bInterfaceNumber:         0x00
 bAlternateSetting:          0x01
 bNumEndpoints:            0x02
 bInterfaceClass:             0xff
 bInterfaceSubClass:       0xff
 bInterfaceProtocol:        0xff
 iInterface:                    0x00

Endpoint Descriptors:
 bEndpointAddress:         0x81    IN
 Transfer Type:                Bulk
 wMaxPacketSize:            0x0040 (64)
 bInterval:                      0x00

Endpoint Descriptors:
 bEndpointAddress:          0x02   OUT
 Transfer Type:                Bulk
 wMaxPacketSize:            0x0040 (64)
 bInterval:                      0x00

However with my code I am unable to get handles for these two bulk endpoints, both function calls to retrieve the these endpoint handles return USBHOSTGENERIC_NOT_FOUND. I suspect what the issue is, is that this particular device has an interface with an alternate setting (see  bNumInterfaces: 0x01, bAlternateSetting: 0x01) and that needs to be selected to allow access to these two bulk endpoints.
 (see https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/select-a-usb-alternate-setting).

my code is as follows:

Code: [Select]
// attach for IOCTL call
unsigned char usbhostGeneric_attach(usbhostGeneric_ioctl_t *cb, usbhostGeneric_context_t *ctx)
{
int tempIn, tempOut, tempCtrl;
usbhostGeneric_ioctl_cb_attach_t *atInfo;
// ioctl request block
usbhost_ioctl_cb_t hc_ioctl;
usbhost_ioctl_cb_vid_pid_t hc_iocb_vid_pid;

usb_deviceRequest_t set_configuration;
usb_deviceRequest_t set_alt_interface;

unsigned char status = USBHOSTGENERIC_INVALID_PARAMETER;

atInfo = cb->set.data;
ctx->hc = atInfo->hc_handle;

// find VID/PID
hc_iocb_vid_pid.vid = CUSTOM_VID;
hc_iocb_vid_pid.pid = CUSTOM_PID;

// user ioctl to find first hub device
hc_ioctl.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_FIND_HANDLE_BY_VID_PID;
hc_ioctl.handle.dif = NULL;
hc_ioctl.set = &hc_iocb_vid_pid;
hc_ioctl.get = &atInfo->ifDev;

if (vos_dev_ioctl(ctx->hc, &hc_ioctl) != USBHOST_OK)
{
return USBHOSTGENERIC_NOT_FOUND;
}

do
{
// user ioctl to find control endpoint on this device
hc_ioctl.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_CONTROL_ENDPOINT_HANDLE;
hc_ioctl.handle.dif = atInfo->ifDev;
hc_ioctl.get = &ctx->epCtrl;
tempCtrl = ctx->epCtrl;
if (vos_dev_ioctl(ctx->hc, &hc_ioctl) != USBHOST_OK)
{
status = USBHOSTGENERIC_NOT_FOUND;
break;
}


set_configuration.bmRequestType = USB_BMREQUESTTYPE_HOST_TO_DEV |
  USB_BMREQUESTTYPE_STANDARD |
  USB_BMREQUESTTYPE_DEVICE;
set_configuration.bRequest = USB_REQUEST_CODE_SET_CONFIGURATION;
set_configuration.wValue = 1; // "SetConfiguration(1);"
set_configuration.wIndex = 0;
set_configuration.wLength = 0;
hc_ioctl.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_SETUP_TRANSFER;
hc_ioctl.handle.ep = ctx->epCtrl;
hc_ioctl.set = &set_configuration;
if (vos_dev_ioctl(ctx->hc, &hc_ioctl) != USBHOST_OK)
{
status = USBHOSTGENERIC_NOT_FOUND;
break;
}

set_alt_interface.bmRequestType = USB_BMREQUESTTYPE_HOST_TO_DEV |
  USB_BMREQUESTTYPE_STANDARD |
  USB_BMREQUESTTYPE_INTERFACE;
set_alt_interface.bRequest = USB_REQUEST_CODE_SET_INTERFACE;
set_alt_interface.wValue = 1; // "SetAltInterface(1);"
set_alt_interface.wIndex = 1;
set_alt_interface.wLength = 0;
hc_ioctl.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_SETUP_TRANSFER;
hc_ioctl.handle.ep = ctx->epCtrl;
hc_ioctl.set = &set_alt_interface;
if (vos_dev_ioctl(ctx->hc, &hc_ioctl) != USBHOST_OK)
{
status = USBHOSTGENERIC_NOT_FOUND;
break;
}

// user ioctl to find bulk endpoint on this device
hc_ioctl.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_BULK_IN_ENDPOINT_HANDLE;
hc_ioctl.handle.dif = atInfo->ifDev;
hc_ioctl.get = &ctx->epBulkIn;
tempIn = ctx->epBulkIn;
if (vos_dev_ioctl(ctx->hc, &hc_ioctl) != USBHOST_OK)
{
status = USBHOSTGENERIC_NOT_FOUND;
break;
}

// user ioctl to find bulk endpoint on this device
hc_ioctl.ioctl_code = VOS_IOCTL_USBHOST_DEVICE_GET_BULK_OUT_ENDPOINT_HANDLE;
hc_ioctl.handle.dif = atInfo->ifDev;
hc_ioctl.get = &ctx->epBulkOut;
tempOut = ctx->epBulkOut;
if (vos_dev_ioctl(ctx->hc, &hc_ioctl) != USBHOST_OK)
{
status = USBHOSTGENERIC_NOT_FOUND;
break;
}

status = USBHOSTGENERIC_OK;
}
while (0);

return status;
}

Could someone please help explain what I am doing wrong here? The documentation isn't very clear on how to achieve this, and none of the example code does this either.
Regards,

Gord.