PORTS Forum

Ports and Interfaces => USB => Topic started by: ulao on August 27, 2017, 05:01:06 pm

Title: usb interruptions, I think?
Post by: ulao on August 27, 2017, 05:01:06 pm
Can anyone tell me what this means? Every once in a while my usb device stops and this is shown in my scanner.

The longer I extend my control data transfer lengthen (i.e 64 instead of 16), the more often this occurs.
Title: Re: usb interruptions, I think?
Post by: Jan Axelson on August 27, 2017, 08:09:16 pm
It appears to be responding to the fact that a Get Report request failed to complete. So you need to figure out why. Is the endpoint:

sending ACK in the Setup stage?

sending data in the Data stage?

sending ACK in the Status stage?



Title: Re: usb interruptions, I think?
Post by: ulao on August 27, 2017, 10:01:18 pm
I guess I was curios more so of the orange highlight. But after a reboot you are right, it's the control transfer ding. I know why but I just can't find the solution. I have a catch 22 chase here. If I disable the IRQ for my USB when I do my sensitive read, the control transfer seems to trip up because the KA single was not there. If I in-turn make sure that the sensitive code runs just after a USB poll and not disable interrupts, the control transfer seems to step on the USB poll read.

So what I did was in my USB code I sync the sensitive code after the 8ms USB poll.
In my software I get the USB poll event (16 bytes so two USB polls 1.1 (8 bytes max), and immediately do the controller transfer.
  - based on theory it should be after the second poll but shows after the first, not a big deal but confusing.
I also no longer disable interrupts around my sensitive code. Since it is in-sync and not over stepping my KA signals, all should be fine.

See image for details.
blue my control transfer
red my USB poll (every 8 ms)
green my sensitive code

So in theory it all fits in to place, but some how every once in a while I get the controller transfer to fail or currupt USB poll data. If I remove the disable IRQ's the USB poll data (every 8 ms) is corrupt if I leave the disabled IRQ in place the controller transfer trips up.. To make matter worse, I tried to capture this on my analyzer and would you belie it... no errors. As a matter a fact, I can run my scope for 20 seconds and while running, no issue.  This is no joke and driving my nuts.  It's almost like the usb needs additional Resistance on the wire but this hardware has ran the test of time.



Title: Re: usb interruptions, I think?
Post by: ulao on August 27, 2017, 10:17:32 pm
Also wanted to add this and I'm not sure this is normal, its like it plays hell syncing. It is very long, lets see if it shows up on here.
Yeah its good just scroll.

It does eventually sync and sends all the correct data. This seems to take about 4 ms.

Title: Re: usb interruptions, I think?
Post by: Jan Axelson on August 28, 2017, 09:47:38 pm
Most critical is to be sure to set up the endpoint to ACK all Setup packets, return NAK or data in the Data stage (control IN transfer), and return NAK or ACK in the Status stage.

Except for Setup packets, it's OK for the endpoint to NAK for a while until it's ready, but the endpoint must return _something_ when the host communicates for it no matter what is going on with other sensitive code, etc.
Title: Re: usb interruptions, I think?
Post by: ulao on August 28, 2017, 10:00:33 pm
Ok, maybe there is something I'm missing. I attached one more image to show what is going on here. And now I see that the issue is where the control is taking too long to complete.

So based on your reply.


Quote
Most critical is to be sure to set up the endpoint to ACK all Setup packets, return NAK or data in the Data stage (control IN transfer), and return NAK or ACK in the Status stage.
I belie I follow you here.

I currently only have 3 paths

set reports return USB_NO_MSG - used to tell the driver a set report is greater then 8, so that it calls my usbFunctionWrite function.
get reports return the size -   In all cases it should match the input length. So I normally just returns rq->wLength.word;
neither, not sure. I currently return rq->wLength.word; Maybe I need to return a -1 or 0? I think the driver handles all NAK and ACK.

Title: Re: usb interruptions, I think?
Post by: ulao on August 28, 2017, 10:25:29 pm
yeah looks like the only thing I can return from usbFunctionSetup  is a length

the driver does the NAK

    if(usbRxToken == (uchar)USBPID_SETUP){
        if(len != 8)    /* Setup size must be always 8 bytes. Ignore otherwise. */
            return;
        usbMsgLen_t replyLen;
        usbTxBuf[0] = USBPID_DATA0;         /* initialize data toggling */
        usbTxLen = USBPID_NAK;              /* abort pending transmit */
        usbMsgFlags = 0;
        uchar type = rq->bmRequestType & USBRQ_TYPE_MASK;
        if(type != USBRQ_TYPE_STANDARD){    /* standard requests are handled by driver */
            replyLen = usbFunctionSetup(data);
        }else{
            replyLen = usbDriverSetup(rq);
        }

I'm new to the usb signal, can anyone tell me if the driver is failing to NAK/ACK? This 2-8ms for sending a control transfer has to be wrong.
Title: Re: usb interruptions, I think?
Post by: ulao on August 29, 2017, 08:57:40 pm
Ok I caught it in action. It is doing exactly what I thought it was doing. The control transfer just goes on for ever.

The usb driver and software are not working together. For some reason in this case 2 seconds. I can not image the driver woudl not send it NAK/ACK for that amount of time but... whatever this "syncing" is looking for is just not there. I don't know enough about the usb signal to know what it is looking for and Jan has pointed out the importance of  NAK/ACK. Though 2 seconds? Something clearly is wrong here. Controller transfers should only take a few ms, not 4 and certainly not 2 seconds.

Can anyone shed light on what "should" go on here.
Title: Re: usb interruptions, I think?
Post by: Jan Axelson on August 30, 2017, 10:58:21 am
The driver doesn't send ACK/NAK; you need to be sure the endpoint is configured to return ACK, NAK, or data immediately, as appropriate, for every transaction. How to do that varies with the controller chip architecture. Check the data sheet.

A control transfer can take as long as 5 seconds to complete, but the individual transactions must complete quickly, no time for firmware intervention.
Title: Re: usb interruptions, I think?
Post by: ulao on August 30, 2017, 12:59:44 pm
Oh sorry, this is a software based USB (vusb), Bit banging but really well know, Of course there is the possibility that this is a downfall of this 1.1 driver but I tend to doubt that.  I have checked the code over well and there are no holes, it always returns something. No calculation need to be done as the data is already ready.

--------update------------
Ok I see what is causing the ACK/NAK to fail. There is some ASM code getting frozen causing the USB to stall. This was easy to band-aid but the real issue needs to be dealt with.

A quick guess is that the code is getting stuck. It seem to get stuck because the control transfer is running during this ASM. At the moment I can't quite understand why unless this control transfer syncing is firing interrupts? <pretty sure this is the clients responsibility? see note below>  This ASM code is very tight, 100ns off and it will trip up. So I really need to know how the hardware level of the usb control transfer works. '

added an image to show bad(right)/good(left).

Things that would help to know.
What is the syncing looking for?
Can a controller transfer be bulk or interrupt?
If bulk is possible will it only send once ever 8 ms?
Can one put a time out on the transfer so it does not try longer then 8 ms.
Is there a write up, book or any info that explains this at signal level.

So interrupts... I see an 8 ms signal I think comes from the OS AKA USB poll rate (should be 10 ms but windows and most operating system use 8 for 1.1) and a 900us signal I think comes from the device (hey I'm ready sending me something). A control transfer I would guess dose not sending a signal of any kind. It just starts the transfer waiting for something, hence the up to 5 seconds. Looks like it connects on one of the 900us signals. I think is is called bulk transfers. Timing can be loose but at times faster then the interrupt transfer. Or at least how I understand it.

As you can see by the image I place the sensitive code in side the 900 us signals. For some unknown reason to me, the control transfer over stepping this sensitive code is causing my problem. I just need to figure out why. I would think the design is to do nothing with the control transfer until the interrupt fires. It's not like the chip is multi threaded? So AFAICT that code is just going over the wire and not disturbing the firmware. If  I'm wrong, what takes place here?


Title: Re: usb interruptions, I think?
Post by: Jan Axelson on August 30, 2017, 08:41:29 pm
I don't know what you mean by "a software based USB (vusb)."

USB defines four types of transfers: control, bulk, interrupt, and isochronous.

A control transfer is not a bulk transfer or an interrupt transfer; it is a control transfer.

Title: Re: usb interruptions, I think?
Post by: ulao on August 30, 2017, 10:10:59 pm
https://www.obdev.at/products/vusb/index.html
its a firmware only usb driver (no hardware).

Ok, I can read up on the 4 types and see if this helps. Do all feature reports need to be control transfers>

Title: Re: usb interruptions, I think?
Post by: ulao on August 31, 2017, 10:55:21 pm
Ok a bit more understanding and investigation and now I'm closer to the problem. I don't think this is USB related and I'm leaning more on a HIDAPI bug. Tough, what are your thoughts? Am I thinking right?

What is going on here is the control transfer is running overtime and stepping on a interrupt transfer. From what I have read the interrupt transfer is of a higher importance. So during the the control transfer and in the case of a collision, should the control transfer not surrender?

In my case this is not happening, the control transfer is continuing to run and the interrupt transfer is surrendering. In this case the data from the interrupt transfer is corrupt.

I think this guy has my same issue
https://stackoverflow.com/questions/20980984/usb-2-0-frame-sof-collision
Title: Re: usb interruptions, I think?
Post by: Jan Axelson on September 01, 2017, 05:57:15 pm
Interrupt transfers have guaranteed maximum latency (time between transactions).

The host reserves a portion of the bus bandwidth for control transfers.

The host controller manages the bandwidth, scheduling interrupt transfers according to the maximum latency requested in the endpoint descriptor and scheduling control transfers in the remaining bandwidth. These are the only two transfer types for low-speed devices.  The firmware driver you referenced is low speed only.

Because the host controls all bus traffic, there are no "collisions."

Yes, Feature reports must use control transfers.
Title: Re: usb interruptions, I think?
Post by: ulao on September 04, 2017, 04:43:12 pm
this was very helpful info. Would you agree that this (captured on low speed). is not possible? Based on the info you mentioned (and I would have no place to argue)  it is not possible to get a collision from low speed. low speed or not, I read you should never get collisions from these types of transfers.  Though here you have it happening. I simply must be explaining something wrong or misunderstanding.

This snap shows the control transfer overstepping the interrupt transfer.

Could it be that I somehow have my endpoints messed up?
Code: [Select]

Endpoint Descriptor 81 1 In, Interrupt, 8 ms
Offset Field Size Value Description
0 bLength 1 07h 
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 81h 1 In
3 bmAttributes 1 03h Interrupt
 1..0: Transfer Type  ......11  Interrupt
 7..2: Reserved  000000..   
4 wMaxPacketSize 2 0008h 8 bytes
6 bInterval 1 08h 8 ms

Endpoint Descriptor 01 1 Out, Interrupt, 8 ms
Offset Field Size Value Description
0 bLength 1 07h 
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 01h 1 Out
3 bmAttributes 1 03h Interrupt
 1..0: Transfer Type  ......11  Interrupt ---(I tried changing to a 0 and it didn't help.) ---
 7..2: Reserved  000000..   
4 wMaxPacketSize 2 0008h 8 bytes
6 bInterval 1 08h 8 ms

};
My interrupt transfers are on Endpoint 1 as I can see on the wire (shown in image).
and my controls are on Endpoint 0.

seem backwards to how I set it up, maybe EP are counted backwards?

Title: Re: usb interruptions, I think?
Post by: Jan Axelson on September 05, 2017, 09:32:18 pm
Endpoint 0 is always the default endpoint for control transfers.

I don't know what you mean by "overstepping the interrupt transfer," couldn't make sense of the attached image.

Be aware that a control transfer has two or three stages that each require one or more transactions. So the host might schedule interrupt transactions interwoven with the stages of a control transfer, for example:

EP0 Setup stage ACKed
EP1 interrupt transaction
EP0 Data stage NAKed
EP1 interrupt transaction
EPO Data stage ACKed
EP1 Status stages ACKed

Title: Re: usb interruptions, I think?
Post by: ulao on September 06, 2017, 08:56:53 am
I see the stages of the control but the main USB poll is missing when the control transfer fires at the same time.

Image explained.
If you open up the image in a new window and maximize it you will see the image is broken in to 4 parts. The top most image is a zoomed out look. You can very clearly see the USB polls on channel 2.  Every time (8ms) the USB host gets data from the device (interrupt transfer) that spike appears. at +50 ms it appears to be hidden in the blob (the control transfer).

The next image is a blow up of the red square selection, (part of the control transfer) for reference (where the poll should have been). 

Next, a zoom in of this section (again the red square outline). Showing there is absolutely no interrupt transfer taking place. All that can be seen is a control transfer.

The last image is what an interrupt transfer would look like.

What I'm trying to point out in the images here, is that the control transfer took place where the interrupt transfer should have been. I'm trying to figure out how that is even possible.


Title: Re: usb interruptions, I think?
Post by: Jan Axelson on September 06, 2017, 09:41:00 pm
Why do you think the host is using interrupt transfers? It sounds like the host using control transfers only.
Title: Re: usb interruptions, I think?
Post by: ulao on September 07, 2017, 10:07:48 am
This is a gamepad usb device that uses a normal poll. In my code I use a
while (!usbInterruptIsReady()) usbPoll(); usbSetInterrupt( reportBuffer, 8);
this needs to happen ever 8 ms, or the device can not work right. The control transfer is cause this very issue. Somehow it prevents this poll (not very often) when it over steps.
Title: Re: usb interruptions, I think?
Post by: Jan Axelson on September 07, 2017, 10:19:36 am
The host is obligated to attempt an interrupt transfer with a low-speed device every 10 ms (or longer as specified in the endpont descriptor). If the host is neglecting to do this, it's a bug in the host controller.

In fact, to be compliant, you should change bInterval to 10 (0ah) though I doubt that this is source of any problem.

However, the host may schedule a transfer attempt at more frequent intervals, such as 8 ms.

Of course, the host will not receive any interrupt data unless the device has it ready to send on receiving an IN token packet.

Title: Re: usb interruptions, I think?
Post by: ulao on September 07, 2017, 01:51:40 pm
This does make sense to me but correct me if I'm wrong? The host in this case is windows 7, is the OS not the host? I could try a 10ms poll but from what I have seen windows ignores that and does 8 anyways. I tend to doubt windows has a bug that has gone unseen.

If I can rule out a host bug, the only possible issue then, is that the device is, as you said, not ready. My only guess is during the transfer of the control data the device is incapable of replying to the interrupt transfer. I guess ill try to debug that.
Title: Re: usb interruptions, I think?
Post by: Bret on September 07, 2017, 02:08:27 pm
I'm not sure if this will help or not, but here goes.  Remember that the USB bus is a master/slave architecture.  The Host is the master, and the device (in this case, your device) is the slave.  You must do what the host tells you to do, when the host tells you to do it.  Period.

As Jan eluded to earlier, when the host sends you a packet requesting something, you must respond immediately with something, even if it is simply a NAK.  The host will only send one packet at a time down the bus.  The packet could be an interrupt packet, one of the control packets (control transactions always involve more than one packet), or something else.  The host cannot send you a control packet and an interrupt packet at the same time -- it is a serial bus (it only sends one bit at a time).

Also, exactly when you are sent each packet is not consistent.  A packet can be sent to you any time within a frame (frames are 1 ms long in USB 1).  You can get it at the beginning, middle, or end of the frame, and you have to respond appropriately and quickly no matter what.  The host decides exactly which packets get sent when inside each frame.
Title: Re: usb interruptions, I think?
Post by: ulao on September 07, 2017, 02:45:53 pm
ret is does help but there is one issue.

Quote
The host cannot send you a control packet and an interrupt packet at the same time -- it is a serial bus (it only sends one bit at a time).

I know studding screen shots is no fun... but if you take a closer look at mine you will see this issue.
channel 4 are my frames
channel 2 are my data (small data is the interrupt longer the control transfer)
channel 3 is just debug
Based on our collective knowledge, we all agree, it can not happen. The Host can not send a control transfer if the interrupt transfer is scheduled. It "seems" to be doing just that.  If the host knows it has a interrupt scheduled, why would it send the control transfer?

Outside this issue yes, this does help. I didn't know why the 1 ms interrupts were on the line. So this is the frames. The more I learn the better I will be at figuring this out.

Correct me if I'm wrong, but the host is software, the USB OS driver, yes? My software tells the host to send a control transfer and the host should know better then to send it out when an interrupt transfer is scheduled.
Title: Re: usb interruptions, I think?
Post by: Bret on September 07, 2017, 05:33:02 pm
Correct me if I'm wrong, but the host is software, the USB OS driver, yes?

No, that's not right.  It's a combination of hardware and software.

The software places transactions in memory that it wants the hardware to perform.  The hardware reads those transactions from memory and sends them across the bus in an autonomous fashion, and then the hardware places the results of the transaction into memory (and generates hardware interrupts if the software wants it to) to notify the software of what happened.  The software builds a queue of transactions it wants the hardware to perform.  The hardware starts at the top of the queue, sends the packet it needs to out across the bus, waits for the device to send a return packet across the bus, and then tells the software what the device sent back (using memory and hardware interrupts).  Then, the hardware goes to the next transaction in the queue and does the same thing again.

Exactly what happens behind the scenes in memory between the host hardware and software is very complicated, and even varies significantly depending on the type of host it is (UHCI, OHCI, EHCI, xHCI, WHCI, ...).  There is also a priority mechanism inherent to the queuing process to make sure isochronous and interrupt transactions get precedence over control and bulk transactions.   But the basic concept of the software queuing transactions in memory and the hardware issuing the transactions one at a time across the bus doesn't change.
Title: Re: usb interruptions, I think?
Post by: ulao on September 08, 2017, 08:28:44 am
So my software does need to "not" send two transfer at once? This was clearly my misunderstanding. I figure the HID API I'm using was taking care of that. I'll follow up though angle. Thx.
Title: Re: usb interruptions, I think?
Post by: Jan Axelson on September 14, 2017, 10:02:26 am
Control transfers have multiple stages. The host can schedule interrupt transfers between the stages or between transactions within a stage where that applies.
Title: Re: usb interruptions, I think?
Post by: ulao on September 19, 2017, 07:31:35 pm
One more question here. Per the previous discussion, as I mentioned, I have both interrupts and control transfers. In my software I control the 'control' transfers. Though the interrupt transfers happen all the time. By that I mean whenever the OS is up and running. These transfers start the minute I pug in my device. So I'm guessing the HID/game controller driver handles these? More to the point, can I stop/pause this?

Title: Re: usb interruptions, I think?
Post by: Jan Axelson on September 20, 2017, 09:22:18 am
The host driver schedules periodic transfer attempts for interrupt IN endpoints. The device endpoint needs to be set up to NAK all IN token packets unless there is data to send.
Title: Re: usb interruptions, I think?
Post by: ulao on September 20, 2017, 10:40:14 am
Is there a way to pause or start/stop this from software?
Title: Re: usb interruptions, I think?
Post by: Jan Axelson on September 22, 2017, 08:28:07 pm
A low-level filter driver might be able, but not application software.