1
Discussion - Drivers / VNC2 - How to select an alternate setting in a USB interface
« 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:
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.
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.