From: Nuno S. <ns...@ed...> - 2009-07-06 18:51:32
|
Hi, Today I was doing some experiments on control transfers with libusb. I was setting a custom request to process on the device side, and then invoking a control transfer on the host side to activate that request. I was getting pipe error on the transaction. My device is only composed by a unique custom endpoint but I was assuming the use of the default control endpoint. Why could this not be working? What can possibly be the most direct cause? Any tips? Thanks, Nuno |
From: Tim R. <ti...@pr...> - 2009-07-06 19:15:56
|
Nuno Santos wrote: > Today I was doing some experiments on control transfers with libusb. I > was setting a custom request to process on the device side, > and then invoking a control transfer on the host side to activate that > request. > > I was getting pipe error on the transaction. > > My device is only composed by a unique custom endpoint but I was > assuming the use of the default control endpoint. > > Why could this not be working? What can possibly be the most direct > cause? > What exactly was the request you were trying? One of the bit fields in the request code (in bmRequestType) says whether the request is aimed at the device, the interface, the endpoint, or "other". If you pick "interface" or "endpoint", then you must have claimed the interface number that is specified in the request. This trips up some people, because the Windows kernel does not enforce this. The Linux kernel does. However, I think that reports an EACCESS error, so I could be blowing smoke. How large was the transfer? Control transfers are quite limited in size. -- Tim Roberts, ti...@pr... Providenza & Boekelheide, Inc. |
From: Nuno S. <ns...@ed...> - 2009-07-07 16:09:21
|
Hi again, I'm claiming interface before setting mode: This is my device side control packets handling (LUFA syntax): case 0x12: if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE)) { Endpoint_ClearSetupReceived(); PORTD ^=0xff; /* Send the flag to the host */ Endpoint_ClearSetupOUT(); } break; And my libusb transfer request: uint8_t data = 0x00; int r; r = libusb_control_transfer(handle, 0x40, 0x12, 0, 0, &data, 1, 1000); 0x12 is my request... i choose 0x12 as I could choose 0x00 as I'm trying to set up vendor request, right? then I'm looking for a request type from host to device, from vendor type, which target is the device itself REQDIR_HOSTTODEVICE -> 0 at bit 7 REQTYPE_VENDOR -> 2 at bit 5 means 10 starting at bit 5 REQREC_DEVICE -> 00000 starting at bit 0 Results in 0100 0000 which is 0x40! I have a -9 error an endpoint error Still haven't found the problem... Thx, Nuno Tim Roberts wrote: > Nuno Santos wrote: > >> Today I was doing some experiments on control transfers with libusb. I >> was setting a custom request to process on the device side, >> and then invoking a control transfer on the host side to activate that >> request. >> >> I was getting pipe error on the transaction. >> >> My device is only composed by a unique custom endpoint but I was >> assuming the use of the default control endpoint. >> >> Why could this not be working? What can possibly be the most direct >> cause? >> >> > > What exactly was the request you were trying? One of the bit fields in > the request code (in bmRequestType) says whether the request is aimed at > the device, the interface, the endpoint, or "other". If you pick > "interface" or "endpoint", then you must have claimed the interface > number that is specified in the request. This trips up some people, > because the Windows kernel does not enforce this. The Linux kernel does. > > However, I think that reports an EACCESS error, so I could be blowing > smoke. How large was the transfer? Control transfers are quite limited > in size. > > |
From: Tim R. <ti...@pr...> - 2009-07-07 17:01:40
|
Nuno Santos wrote: > > I'm claiming interface before setting mode: > That shouldn't be necessary, strictly speaking, although it won't hurt, either. > This is my device side control packets handling (LUFA syntax): > > case 0x12: > if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | > REQREC_DEVICE)) > { > Endpoint_ClearSetupReceived(); > > PORTD ^=0xff; > > /* Send the flag to the host */ > Endpoint_ClearSetupOUT(); > } > > break; > There are apparently several different versions of the LUFA library, so I can't actually verify whether this is the intended sequence or not. Quite a number of the existing samples use Endpoint_ClearSetupIN(); for a host-to-device request. This is backwards from intuition, because in USB the terms "IN" and "OUT" are almost exclusively used from the point of view of the host. The LUFA documentation from June 2009 only shows Endpoint_ClearSETUP, with no distinction between IN and OUT. -- Tim Roberts, ti...@pr... Providenza & Boekelheide, Inc. |
From: Nuno S. <ns...@ed...> - 2009-07-07 17:18:35
|
Hi Tim, I have this working already. I couldn't really found the problem. I started to use some leds to see the value of the bmRequestType and it was delivering the right value sent by the host. Then i started to make the inverse process, and putting it right in place. I have this fully working now. Just for the records: EVENT_HANDLER(USB_UnhandledControlPacket) { // Handle specific control requests switch (bRequest) { case REQ_MY_REQUEST: if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE) ) { // do stuff // Acknowedge the SETUP packet, ready for data transfer Endpoint_ClearSetupReceived(); // Send an empty packet to acknowedge the command Endpoint_ClearSetupIN(); } break; } In the libusb side: int sendRequest(uint8_t request) { int r; r = libusb_control_transfer(handle, CTR_OUT, request, 0, 0, NULL, 0, 1000); if (r < 0) { fprintf(stderr, "set mode error %d\n", r); return r; } return 0; } Where #define CTR_OUT 0x40 #define REQ_MY_REQUEST 0x00 Thank you very much, With my best regards, Nuno Tim Roberts wrote: > Nuno Santos wrote: > >> I'm claiming interface before setting mode: >> >> > > That shouldn't be necessary, strictly speaking, although it won't hurt, > either. > > >> This is my device side control packets handling (LUFA syntax): >> >> case 0x12: >> if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | >> REQREC_DEVICE)) >> { >> Endpoint_ClearSetupReceived(); >> >> PORTD ^=0xff; >> >> /* Send the flag to the host */ >> Endpoint_ClearSetupOUT(); >> } >> >> break; >> >> > > There are apparently several different versions of the LUFA library, so > I can't actually verify whether this is the intended sequence or not. > Quite a number of the existing samples use Endpoint_ClearSetupIN(); > for a host-to-device request. This is backwards from intuition, because > in USB the terms "IN" and "OUT" are almost exclusively used from the > point of view of the host. > > The LUFA documentation from June 2009 only shows Endpoint_ClearSETUP, > with no distinction between IN and OUT. > > |
From: Alan S. <st...@ro...> - 2009-07-07 03:25:36
|
On Mon, 6 Jul 2009, Nuno Santos wrote: > Hi, > > Today I was doing some experiments on control transfers with libusb. I > was setting a custom request to process on the device side, > and then invoking a control transfer on the host side to activate that > request. > > I was getting pipe error on the transaction. > > My device is only composed by a unique custom endpoint but I was > assuming the use of the default control endpoint. > > Why could this not be working? What can possibly be the most direct > cause? Passing an incorrect pipe value to the library seems like the most obvious possibility. Alan Stern |
From: Nuno S. <ns...@ed...> - 2009-07-07 13:28:29
|
Well, What i'm doing is: r = libusb_control_transfer(handle, 0x40, 0x12, 0, 0, &data, 1, 1000); Where 0x40 means that I want to send a packet from the host to the device (OUT), bit 7 =0, and that the requst is a vendor specific (10), and that it is directed to the device (00000). My request number is 0x12 which was what I defined in the event handler in the device firmware. The result is a -9 error which is a LIBUSB_ERROR_PIPE <http://libusb.sourceforge.net/api-1.0/group__misc.html#ggb2323aa0f04bc22038e7e1740b2f29ef1406e98370900156484f5fe609270837> But now, i don't know for sure if the request should be directed to the device, or to a determined endpoint or interface! :) Nuno Alan Stern wrote: > On Mon, 6 Jul 2009, Nuno Santos wrote: > > >> Hi, >> >> Today I was doing some experiments on control transfers with libusb. I >> was setting a custom request to process on the device side, >> and then invoking a control transfer on the host side to activate that >> request. >> >> I was getting pipe error on the transaction. >> >> My device is only composed by a unique custom endpoint but I was >> assuming the use of the default control endpoint. >> >> Why could this not be working? What can possibly be the most direct >> cause? >> > > Passing an incorrect pipe value to the library seems like the most > obvious possibility. > > Alan Stern > > |
From: Alan S. <st...@ro...> - 2009-07-07 15:06:16
|
On Tue, 7 Jul 2009, Nuno Santos wrote: > Well, > > What i'm doing is: > > r = libusb_control_transfer(handle, 0x40, 0x12, 0, 0, &data, 1, 1000); > > Where 0x40 means that I want to send a packet from the host to the > device (OUT), bit 7 =0, and that the requst is a vendor specific (10), > and that it is directed to the device (00000). > > My request number is 0x12 which was what I defined in the event handler > in the device firmware. May you didn't define it correctly. > The result is a -9 error which is a LIBUSB_ERROR_PIPE > <http://libusb.sourceforge.net/api-1.0/group__misc.html#ggb2323aa0f04bc22038e7e1740b2f29ef1406e98370900156484f5fe609270837> That means the device returned a STALL. You can verify this by using usbmon. > But now, i don't know for sure if the request should be directed to the > device, or to a determined endpoint or interface! :) It depends on what the request is supposed to do. As the device implementor, that decision is up to you. Alan Stern |