Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISO-transfer and USB HUB #41

Open
KasperLJ1 opened this issue Oct 19, 2022 · 2 comments
Open

ISO-transfer and USB HUB #41

KasperLJ1 opened this issue Oct 19, 2022 · 2 comments
Labels

Comments

@KasperLJ1
Copy link

KasperLJ1 commented Oct 19, 2022

Hi

I developing both the device and host end for an embedded system, where the host will serve as a control "panel" for the device.

I am using C# binding for libusbK, where i am having some issues, which i now believe i have point pointed to somewhere in my host application.

The issue:
I am using iso-transfers between the host and device to "steam" process data. This works fine without a hub attached, but once the host and device communicates through any usb HUB i get issues. Based on my USB analysis tool (Beagle 480), it seems that the following code generates 2 iso-transfer requests:

public int SubmitNextRead()
        {
            // Pull from head of Completed list and push to end of Outstanding list
            IsoTransferItem isoTransferItem = Completed.First.Value;
            Completed.RemoveFirst();
            Outstanding.AddLast(isoTransferItem);

            // Prepare the OvlK handle to be submitted.
            OvlK.ReUse(isoTransferItem.Ovl);

            // Set the frame number this transfer will be submitted on (used for logging only)

            //isoTransferItem.FrameNumber = isoTransferItem.Container.FrameNumber;
            uint currentFrameNumber = 0;
            this.Usb.GetCurrentFrameNumber(out currentFrameNumber);
            //Program.Test.LogLn("#StartFrame={0:X8}h, currentFrame={1:X8}h", isoTransferItem.Container.FrameNumber, currentFrameNumber);
            currentFrameNumber += 10;
            // submit the transfer. use 0 for length and 0 for number of packets to use the values the isoch handle was initialized with
            //Usb.IsochReadPipe(isoTransferItem.Iso.Handle, 0, ref isoTransferItem.Container.FrameNumber, 0, isoTransferItem.Ovl);
            Usb.IsochReadPipe(isoTransferItem.Iso.Handle, 0, ref currentFrameNumber, 1, isoTransferItem.Ovl);
            //Usb.IsochReadPipe();

            //byte[] test = new byte[1500];
            //Usb.IsoReadPipe(0x82, ref test, 1500, isoTransferItem.Iso.Handle, null);
            // IsochReadPipe will always return false so we need to check the error code
            int errorCode = Marshal.GetLastWin32Error();

            // 997 is ERROR_IO_PENDING. For async, this means so far so good.
            // IE: The transfer is submitted but we won't know if a problem occurs until it is completed.
            if (errorCode != ErrorCodes.IoPending)
            {
                //Completed.RemoveFirst();
                //Outstanding.AddLast(isoTransferItem);
                Completed.AddFirst(isoTransferItem);
                Outstanding.RemoveLast();
                return errorCode;
            }

            return 0;
        }

I came to that conclusion by placing a breakpoint right after this line, but the USB-sniffer report that the request was made twice. see the screenshot below. Because 2 requests are quickly after each other, the device if unable to re-arm the endpoint in time, and the resulting in a data payload of 0-bytes for the following transfer request. How, this does not always happens.
image

The issues get worse with large data payload, and do not occur for every transfer. I am really puzzled by this, and it might not be related to libusbK, but i was hoping someone might have an idea. Does anyone know if there exists some tool/software where i could quickly test this issue?

The screenshot below shows that this "double" event does not always occur. Ideally, I am trying to send a request every 10 frames, which can also be seen on the timestamp. However, when i have the double event the second event is always right after the first..

image

The device: microchip DSPIC33.

If this is outside the scope of this library, i am sorry.

@mcuee mcuee added the question label Oct 20, 2022
@KasperLJ1
Copy link
Author

I am really confused by this..

I used both wireshark and beagle sniffer to investigate and in my eyes i get very different results.

When connected using an USB HUB (3 different ones, same result), I am atteemping to send an ISO IN request every 100ms:

Beagle sniffer attached between the HUB and the USB device:
it see
0ms : iso transfer
1ms: iso transfer
101ms: iso transfer
102ms: iso transfer
ect.
So at least the it sees 2 transfer for every single one i am attempting to make.... to me this is strange.
image

Wireshark see something very different:
it sees 3 request for every one i try to make with the code show in the previous post.
1 of the three comes back with data, and remaining have some errors, eg: ISO USBD status Unknow, and iso not accessed by HW.

image

I had the idea that when i set the frame number for the request that it might cause some event to trigger more the once, but changing the iso pipe policy to ASAP had no effect, it seems i could not get that to work.

@KasperLJ1
Copy link
Author

KasperLJ1 commented Oct 20, 2022

Furthermore, i also see 2 request being generated using pyusb, so it might being an driver issue?

import usb.core
import usb.util
# find our device
dev = usb.core.find(idVendor=0x04D8, idProduct=0xEF5D)

# was it found?
if dev is None:
    raise ValueError('Device not found')
    
    
dev.set_configuration()
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep = usb.util.find_descriptor(
    intf,
    # match the first IN endpoint
    custom_match = \
    lambda e: \
        e.bEndpointAddress == 0x82)


dat = "A" * 1024
test = ep.read(1024)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants