USB programming: PIC16F1455 with multiple endpoints

Hi all

I am working on a USB device, that will have 2-3 endpoints for reading data.

I am able to get one endpoint working, but not more than that.

Endpoint0 is a system endpoint, and Endpoint1 is for sending data from the device. I want to add endpoints 2 and 3 to return more data. Here is my issue - just figuring out how the USB protocol is, is a challange.

As of now, I know that my SIE is probably set up correctly. I think that my configuration descriptor is wrong. It as 2 interface, 1 and 2 (also 0x81 and 0x82), but next the host computer ask for the Interface 1 report descriptor, but it does not ask for the second. This tells me, that probably my configuration descriptor is not correct about my second interface.

I have been around google for some time, I have been reading quite a bit, but it is really hard to find any knowledge about this.

Are there anyone here, who knows or know where I can find further information? I guess that this is mostly about the USB protocol.

Reply to
sonnic...
Loading thread data ...

I believe it has something to do with hubs. Negotiations between devices with a hub inserted adds a layer of complexity

Cheers

Reply to
Martin Rid

The PIC library has to support it. If it does not, you have to write your own protocol stack.

Reply to
Ed Lee

On a sunny day (Mon, 14 Mar 2022 09:07:04 -0700 (PDT)) it happened " snipped-for-privacy@gmail.com" snipped-for-privacy@gmail.com wrote in snipped-for-privacy@googlegroups.com:

I do not know that type PIC but I use a lot of USB with my 18F14K22 and use things like this:

formatting link
One serial port you already have and you can do it in software from I/O pins for more. It is logic level RS232 so no problems there, example:
formatting link

Reply to
Jan Panteltje

OP is talking about multiple end points from one physical usb port, not serial ports.

Reply to
Ed Lee

Or the report descriptor is invalid, and the OS is bailing because of that.

One diagnostic strategy would be to remove interface 1 entirely, and see whether it will then recognise interface 2.

Sylvia.

Reply to
Sylvia Else

Thanks Sylvia, that was a very good idea.

When I change back to one end point, using address 02 and 82, which should be UEP2 to my understanding, nothing works. When I try one at a time, in/out to be UEP1/UEP2 or vv, then it only works one way.

I config UEP2 the same way as UEP1, so both UEP1 and UEP2 are configured.

My configuration descriptor is as follows:

// Configuration descriptor const ConfigStruct ConfigurationDescriptor = { { // Configuration descriptor 0x09, // Size of this descriptor in bytes 0x02, // CONFIGURATION descriptor type 0x29, // Total length of data for this cfg LSB // was 29 // 49 for 2 end points 0x00, // Total length of data for this cfg MSB 1,//INTF, // Number of interfaces in this cfg 0x01, // Index value of this configuration SCON, // Configuration string index 0xA0, // Attributes (USB powered, wake-up)) 0x32, // Max power consumption (in 2 mA steps) }, { // Generic HID Interface descriptor 0x09, // Size of this descriptor in bytes 0x04, // INTERFACE descriptor type IHID, // Interface Number //<- I assume that it stays 1 just using UEP2. Cannot start from 2 0x00, // Alternate Setting Number 0x02, // Number of endpoints in this interface 0x03, // Class code (HID) 0x00, // Subclass code 0x00, // Protocol code 0-none, 1-Keyboard, 2- Mouse 0x00, // Interface string index

// Generic Hid Class-Specific descriptor 0x09, // Size of this descriptor in bytes 0x21, // HID descriptor type 0x11, // HID Spec Release Number in BCD format (1.11) LSB 0x01, // HID Spec Release Number in BCD format (1.11) MSB 0x00, // Country Code (0x00 for Not supported) 0x01, // Number of class descriptors 0x22, // Report descriptor type 0x2F, // Report Size LSB (47 bytes) 0x00, // Report Size MSB

// Generic HID Endpoint 1 In 0x07, // Size of this descriptor in bytes 0x05, // ENDPOINT descriptor type 0x81, // Endpoint Address //<----- changing to 82 will not work 0x03, // Attributes (Interrupt) HRBC, // Max Packet Size LSB 0x00, // Max Packet Size MSB 0x01, // Interval (1 millisecond)

// Generic HID Endpoint 1 Out 0x07, // Size of this descriptor in bytes 0x05, // ENDPOINT descriptor type 0x01, // Endpoint Address //<--------changing on 02 will not work 0x03, // Attributes (Interrupt) HRBC, // Max Packet Size LSB 0x00, // Max Packet Size MSB 0x01, // Interval (1 millisecond)

Here I could add a copy for UEP, with the only change of IHID - interface number is now 2, and addresses are 02 and 82 And setting interface count to 2in the header and lenght to 49.

The system accepts all this, but when I check on the PIC side I can only see that UEP2 is owned bu the Serial Interface Engine, and I cannot do much.

So - UEP1 works. UEP2 does not work, but the setup can handle it, just no action.

Reply to
sonnic...

It's been a while since I did any USB programming, and that was on a PIC24F. Still, finding UEP2 owned by the serial interface engine (SIE) seems odd. The SIE will only ever clear the UOWN bit, not set it. So if it's set, it must be either that your code set it, or that it was never cleared after a reset.

One gotcha I've been caught by more than once (probably only twice - I've learned that lesson) is forgetting that the watch dog timer is enabled by default (on the PIC24s, at least), that lead to unexpected behaviour.

Check that the ping-pong UCFG.PPB setting is the way you want it.

Sylvia.

Reply to
Sylvia Else

I found the mistake to be in the reply of reports - or descriptors. It would only allow to reply for endpoint 0 (endpoint 1 in hw), meaning when the host would ask for next descriptor, it would not get answer.

if((SetupPacket.bmRequestType & 0x1F) != 0x01 || (SetupPacket.wIndex0 != 0x00)) return;

needs to be

if((SetupPacket.bmRequestType & 0x1F) != 0x01 || (SetupPacket.wIndex0 > (InterfaceCount - 1))) return;

Then it works Next step is that in PC host side, every end point is a connection by itself, hence I have to update both device and PC SW as well

Reply to
sonnic...

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.