Hello,
I have been using rockbox for some time now but recently I start hacking rockbox and I am more precisely interested in USB code. I tried to add a usb driver that would eventually implement the CDC-ACM class (I know there is a GSoC to implement usb classes in plugins but it's not ready yet).
The main point is that CDC-ACM requires two pipes:
1) One interrupt pipe (dir IN)
2) One bulk pipe (dir IN/OUT)
So I naturally wrote this code:
int usb_cdc_acm_request_endpoints(struct usb_class_driver *drv)
{
/* Communication Class interrupt endpoint */
comm_ep_int=usb_core_request_endpoint(USB_ENDPOINT_XFER_INT,USB_DIR_IN,drv);
if(comm_ep_int<0)
{
logf("cdc_acm: unable to request interrupt endpoint");
return -1;
}
/* Data Class bulk endpoints */
data_ep_in=usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK,USB_DIR_IN,drv);
if(data_ep_in<0)
{
logf("cdc_acm: unable to request bulk in endpoint");
usb_core_release_endpoint(comm_ep_int);
return -1;
}
data_ep_out=usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK,USB_DIR_OUT,drv);
if(data_ep_out<0)
{
logf("cdc_acm: unable to request bulk out endpoint");
usb_core_release_endpoint(comm_ep_int);
usb_core_release_endpoint(data_ep_in);
return -1;
}
return 0;
}
But it failed to work on my Sansa e200. It took me some time to understand that sansa e200 had only 3 endpoints and that I had to deactivate other drivers in order to make it works.
But even after that, it continue to failed.
I finally decided to reverse the order:
int usb_cdc_acm_request_endpoints(struct usb_class_driver *drv)
{
/* Data Class bulk endpoints */
data_ep_in=usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK,USB_DIR_IN,drv);
if(data_ep_in<0)
{
logf("cdc_acm: unable to request bulk in endpoint");
usb_core_release_endpoint(comm_ep_int);
return -1;
}
data_ep_out=usb_core_request_endpoint(USB_ENDPOINT_XFER_BULK,USB_DIR_OUT,drv);
if(data_ep_out<0)
{
logf("cdc_acm: unable to request bulk out endpoint");
usb_core_release_endpoint(comm_ep_int);
usb_core_release_endpoint(data_ep_in);
return -1;
}
/* Communication Class interrupt endpoint */
comm_ep_int=usb_core_request_endpoint(USB_ENDPOINT_XFER_INT,USB_DIR_IN,drv);
if(comm_ep_int<0)
{
logf("cdc_acm: unable to request interrupt endpoint");
return -1;
}
return 0;
}
And...it worked !
I'm wondering why it fails when I first request the INT endpoint whereas it suceeds when I first request the BULK one. Does the order matter or is it driver specific ?
Thank you