|
From: Kustaa N. <Kus...@pl...> - 2024-06-10 18:14:35
|
Thanks Tim for taking time to look at this. I’ve now managed get my hands on to an old Beagl 480 Analyzer so will try to hook that up. Mean while couple thoughts your response raised in my mind. From: Tim Roberts <ti...@pr...> Date: Sunday, 9. June 2024 at 21.03 To: lib...@li... <lib...@li...> Subject: Re: [libusb] OT problem with PIC18F45K50 homebrew USB-stack Kustaa Nyholm wrote: > > The device enumerates fine and the HID descriptors are fetched and all > that initial stuff works. > > I only use EP2 to talk to the device, I only send and received 64 byte > reports. So, EP02 and EP82 are both interrupt pipes? These are my descriptors: // http://lists.apple.com/archives/usb/2010/May/msg00007.html __code usb_dev_desc_t device_descriptor = { // sizeof(usb_dev_desc_t), // bLength DSC_DEV, // bDescriptorType 0x0200, // bcdUSB lsb, bcdUSB msb #ifdef USE_IAD 0xEF, // bDeviceClass 0x02, // bDeviceSubClass 0x01, // bDeviceProtocl #else 0x00, // bDeviceClass 0x00,// bDeviceSubClass 0x00,// bDeviceProtocl #endif 8, // bMaxPacketSize USB_VID, // idVendor USB_PID, // idProduct 0x0100, // bcdDevice 0x01, // iManufacturer 0x02, // iProduct 0x03, // iSerialNumber 0x01 // bNumConfigurations }; typedef struct { // usb_cfg_desc_t cd01; // usb_intf_desc_t i01a00; // usb_hid_desc_t hid_01a00; // usb_ep_desc_t ep01i_i01a00; // usb_ep_desc_t ep02i_i01a00; // } config_struct_t; __code config_struct_t config_descriptor = { // { // Configuration Descriptor 0x09,// Size of this descriptor in bytes DSC_CFG, // configurator descriptor type sizeof(config_struct_t), // Total length of data for this configuration 1, // bNumInterfaces 1, // bConfigurationValue 0, // iConfiguration 0x80 | _SELF, // bmAttributes 1, // bMaxPower }, { // Interface Descriptor sizeof(usb_intf_desc_t), // Size of this descriptor in bytes DSC_INTF, // INTERFACE descriptor type 0, // Interface Number 0, // Alternate Setting Number 2, // Number of endpoints in this interfacee HID_INTF, // Class code 0, // Subclass code 0, // Protocol code 0, // Interface string index }, { // HID Class-Specific Descriptor sizeof(usb_hid_desc_t), // Size of this descriptor in bytes DSC_HID, // HID descriptor type 0x0111, // HID Spec Release Number in BCD format (1.11) 0x00, // Country Code (0x00 for Not supported) 1, // Number of class descriptors, see usbcfg.h DSC_RPT, // Report descriptor type sizeof(hid_rpt01), // Size of the report descriptor }, { // Endpoint Descriptor sizeof(usb_ep_desc_t), // Size of this descriptor in bytes DSC_EP, // Endpoint Descriptor _EP02_IN, // Endpoint Address _INT, // Attributes 0x40, // size 0x01, // Interval }, { // Endpoint Descriptor sizeof(usb_ep_desc_t), // Size of this descriptor in bytes DSC_EP, // Endpoint Descriptor _EP02_OUT, // EndpointAddress _INT, // Attributes 0x40, // size 0x01 // Interval } }; // HID report descriptor __code unsigned char hid_rpt01[] = { // 28 bytes 0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1) 0x09, 0x01, // Usage (Vendor Usage 1) 0xA1, 0x01, // Collection (Application) 0x19, 0x01, // Usage Minimum 0x29, 0x40, // Usage Maximum 0x15, 0x00, // Logical Minimum 0x26, 0xFF, 0x00, // Logical Maximum 0x75, 0x08, // Report Size: 8-bit field size 0x95, 0x40, // Report Count: Make sixty-four 8-bit fields 0x81, 0x02, // Input (Data, Array, Abs) 0x19, 0x01, // Usage Minimum 0x29, 0x40, // Usage Maximum 0x91, 0x02, // Output (Data, Array, Abs) 0xC0 // End Collection }; > When it fails I the read polls always timeout. Re-opening the device > restores normal communication. > > Question: am I correct that apart from possible renumeration my device > firmware cannot know > if the device handle is closed or opened on the host side? No. The only thing it will notice is that it stops getting IN or OUT tokens during its scheduled slot time -- it no longer gets a chance to send or receive. OK, as I had understood. > My question is if it is ok to just rely on the assumption that when > ever the SIE in the MCU > signals for the EP2 that the buffer is available not owned by the > firmware > there is a new output report (out EP) or I can fill in the buffer with > next input report (in EP)? That's a question that is very specific to the PIC 18F4550, which has a rather primitive interface. However, the input and output sides of an endpoint are completely unrelated. Activity on one should not impact the other in any way. That's a common misconception in USB. Right. But started a train of though in my mind: Because the input and output are unrelated my protocol always sends (in output report) a message counter (one byte), that is incremented for each message sent. The device always sends (in input report) the last counter value it has received. On the host side I send on output report and the read back messages (input reports) until I get a message that has the same value as the last sent message. I have written the code under the following assumptions: The messages (reports) are not buffered on the host side either way. If this is the wrong assumption I have to think if there is a situation in which the above message counter logic would fail and dead lock. One scenario would be if I manage to send two or more messages before I get a message back, then message I get back would not have the counter value of the last sent message. I don’t see how this could happen but this smells. On other could be if the input reports are buffered and if poll() only ‘returned true’ once for multiple buffered messages. I don’t see how that could happen either, but again this smells. So I guess the questions I would like to know answer to are: 1) Are the input/output reports buffered on the host side? 2) Can poll indicate that there is data to read only once for multiple input reports? > I have assumed that the USB SIE takes care of the communication up to > the transfer level, > transmitting, re-transmitting and ACKing as necessary or NACK:in if my > main loop has > not have time processes the previous transfer. > > Is this correct? In general, yes. The 18F4550 hardware should be handling the wire-level interface, even if your loop is mucked up. Have you done any packet tracing, as suggested on the PIC mailing list? I’m going to now that I have the Beagle available. > I do have an interrupt service that handles all the EP0 control stuff. > But once the > communication with the EP2 has started I should not see any of that > stuff anyway > unless the device gets enumerated? You can't rely on that. Since you are a HID device, the HID driver gets involved here. It might be sending status requests to your control endpoint on its own. I'm just making that up, however -- I don't know whether it actually does. Control requests are handled in the USB interrupt and as they involve only EP0 they should not muck up the EP2 handling in the mainloop? I have now verified that as far as I can tell when the problem occurs the device is not re-enumerated. Wbr Kusti -- Tim Roberts, ti...@pr... Providenza & Boekelheide, Inc. This e-mail may contain confidential or privileged information and is intended solely for the person to whom it is addressed. If you have received this e-mail in error, please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. We will not be liable for direct, indirect, special or consequential damages arising from the alteration of this e-mail, or as a result of any virus being passed on or as of transmission of this e-mail in general. |