Re: Missing isochronous packets

Tim Hutt <[email protected]> Thu, 23 Jul 2015 20:04:30 +0100
Newsgroups gmane.comp.lib.libusb.devel.windows
Message-ID <CAKuVd4CXNJ-H9xJ9x4zuv-nobCL1Bo0+UFP-w1nBZ1AYw_NiCQ@mail.gmail.com>
Hi Chris,

I suspected as much. I didn't want to use the callback because I suspected
it would be too slow (I suspect the whole ASF USB stack might be relatively
slow actually). Anyway tried using it as follows (I couldn't set the
buffers to volatile, but it doesn't seem to matter; also is this what you
meant by double buffering?)

volatile int count = 0;

uint8_t bufferA[UDI_VENDOR_EPS_SIZE_ISO_HS]; // 64 bytes.

uint8_t bufferB[UDI_VENDOR_EPS_SIZE_ISO_HS]; // 64 bytes.

bool bufferPol = false;

void IsoTransferCallback(udd_ep_status_t status, iram_size_t
nb_transfered, udd_ep_id_t ep)

{

	bufferPol = !bufferPol;

	++count;

	if (bufferPol)

	{

		bufferA[0] = count & 0xFF;

		bufferA[1] = (count >> 8) & 0xFF;

		udi_vendor_iso_in_run(bufferA, sizeof(bufferA), IsoTransferCallback);

	}

	else

	{

		bufferB[0] = count & 0xFF;

		bufferB[1] = (count >> 8) & 0xFF;

		udi_vendor_iso_in_run(bufferB, sizeof(bufferB), IsoTransferCallback);

	}

}


This now means I don't have any dropped packets. The problem is that the
throughput is only about 500 kB/s which is orders of magnitude below what
it should be. Any ideas? What speed do you get?

You might be right about this not being the right forum, but I'm still not
100% sure whether the problem is with the SAM3X or libusbK. I reckon there
are way more USB experts on this list than any Arduino forum!

Cheers,

Tim



On 23 July 2015 at 08:50, Chris E <[email protected]> wrote:

> G'day Tim.
> I recently did a similar project: a 375 byte iso packets using an XMEGA,
> also in ASF!
> (The same one I posted about before, Xiaofan, and I got it to work!)
>
> udi_vendor_iso_in_run(buffer, sizeof(buffer), nullptr) does not cause the
> microcontroller to wait!  It just tells the USB controller "on the next iso
> request, I want you to transmit sizeof(buffer) bytes, starting at address
> buffer and then do nothing when the transaction finishes".  (Note: if a
> transaction has already been requested, the function may simply return
> without doing anything.  I'm not 100% sure but I think I remember the
> source code implying that.)
> So your increments a huge number of times between transactions, since
> there's nothing blocking it!
>
> To fix this, take everything out of the loop!
> Run udi_vendor_iso_in_run() only once, and pass in a callback to a
> function rather than the NULL ptr.
> Then, in the callback function, increment the number and then call
> udi_vendor_iso_in_run() again - also with callback!
> The callback function will only run once per transaction, after it's
> complete.
>
> Also, you'll want the buffer to be volatile.  If it's not volatile, the
> CPU might not write back the data to memory when it's done.  This will
> cause hell with the USB's DMA!
> One last thing: this probably isn't a LibUSBK question.  An Atmel forum
> such as AVRFreaks (or possibly an Arduino forum) would be much more
> helpful.  Although, that being said, I get an email notification if you
> post here and I've probably just been through the same stuff that you're
> going through.  :P
>
> Oh, and P.P.S: If you run into problem with data transfer not being smooth
> in the future: double buffer things on both the micro and PC side, and run
> two separate, interleaved Iso Contexts and OvlK Handles PC side.  The
> callback method works fine for continuous streaming on my XMEGA, just make
> sure you swap buffers each time!
>
> Good luck, mate!
> ~Chris
>
> On 23 July 2015 at 17:12, Tim Hutt <[email protected]> wrote:
>
>> I'm trying to transmit 64 byte isochronous USB packets over a USB high
>> speed link from a SAM3X (in an Arduino Due) to a libusbk program (basically
>> the example benchmark program it comes with).
>>
>> I have one isochronous endpoint on the device and it sends data in a
>> tight loop like this (using Atmel's SDK):
>>
>> uint8_t buffer[UDI_VENDOR_EPS_SIZE_ISO_HS]; // 64 bytes.for (int i = 0; i < sizeof(buffer); ++i)
>>     buffer[i] = i;for (;;){
>>     led = !led;
>>     udi_vendor_iso_in_run(buffer, sizeof(buffer), nullptr);
>>     // TODO: How to wait until it is finished?
>>     buffer[0]++;
>>     if (buffer[0] == 0)
>>         buffer[1]++;}
>>
>> The receiving program is basically the example iso read program from
>> libusbk. It writes data to a log file, including the first two bytes of
>> each packet which I increment as shown above. It requests 128 packets per
>> frame, and outputs data like this:
>>
>> #6: StartFrame=00DDE360h LastFrameCount=16 TransferLength=8192 BPS-average:390409.30
>>   #0000: Length=64 C0h 3Dh
>>   #0001: Length=64 E1h 3Dh
>>   #0002: Length=64 01h 3Eh
>>   #0003: Length=64 23h 3Eh
>>   #0004: Length=64 44h 3Eh
>>   #0005: Length=64 64h 3Eh
>>   #0006: Length=64 85h 3Eh
>>   #0007: Length=64 A6h 3Eh
>>   #0008: Length=64 C7h 3Eh
>>  ... snip ...
>>   #0120: Length=64 34h 4Dh
>>   #0121: Length=64 55h 4Dh
>>   #0122: Length=64 76h 4Dh
>>   #0123: Length=64 97h 4Dh
>>   #0124: Length=64 B8h 4Dh
>>   #0125: Length=64 D9h 4Dh
>>   #0126: Length=64 FAh 4Dh
>>   #0127: Length=64 1Bh 4Eh
>>
>> As you can see, it works but is skipping loads of the packets. I'd like
>> to know why! The data rate is really low compared to what USB 2 can do. I'm
>> kind of at a loss here as I don't know how to wait until a transfer is
>> completed in a tight loop on the SAM3X. Also... it should work right?
>>
>> Here are the USB descriptors (I snipped some unused endpoints):
>>
>> Device Power State:               PowerDeviceD0
>>
>>        ---===>Device Information<===---English product name: ""
>> ConnectionStatus:                  Current Config Value:              0x01  -> Device Bus Speed: HighDevice Address:                    0x05Open Pipes:                           0*!*ERROR:  No open pipes!
>>
>>           ===>Device Descriptor<===
>> bLength:                           0x12
>> bDescriptorType:                   0x01
>> bcdUSB:                          0x0200
>> bDeviceClass:                      0x00  -> This is an Interface Class Defined Device
>> bDeviceSubClass:                   0x00
>> bDeviceProtocol:                   0x00
>> bMaxPacketSize0:                   0x40 = (64) Bytes
>> idVendor:                        0x1111 = Dade Behring, Inc.  // Screw the USB-IF!
>> idProduct:                       0x2223
>> bcdDevice:                       0x0100
>> iManufacturer:                     0x01
>>      English (United States)  ""
>> iProduct:                          0x02
>>      English (United States)  ""
>> iSerialNumber:                     0x00
>> bNumConfigurations:                0x01
>>
>>        ---===>Full Configuration Descriptor<===---
>>
>>           ===>Configuration Descriptor<===
>> bLength:                           0x09
>> bDescriptorType:                   0x02
>> wTotalLength:                    0x0045  -> Validated
>> bNumInterfaces:                    0x01
>> bConfigurationValue:               0x01
>> iConfiguration:                    0x00
>> bmAttributes:                      0x80  -> Bus PoweredMaxPower:                          0x32 = 100 mA
>>
>>           ===>Interface Descriptor<===
>> bLength:                           0x09
>> bDescriptorType:                   0x04
>> bInterfaceNumber:                  0x00
>> bAlternateSetting:                 0x00
>> bNumEndpoints:                     0x00
>> bInterfaceClass:                   0xFF  -> Interface Class Unknown to USBView
>> bInterfaceSubClass:                0xFF
>> bInterfaceProtocol:                0xFF
>> iInterface:                        0x00
>>
>>           ===>Interface Descriptor<===
>> bLength:                           0x09
>> bDescriptorType:                   0x04
>> bInterfaceNumber:                  0x00
>> bAlternateSetting:                 0x01
>> bNumEndpoints:                     0x06
>> bInterfaceClass:                   0xFF  -> Interface Class Unknown to USBView
>> bInterfaceSubClass:                0xFF
>> bInterfaceProtocol:                0xFF
>> iInterface:                        0x00
>> (snipped irrelevant endpoints)
>>
>>           ===>Endpoint Descriptor<===       <---- This is the endpoint I'm using.
>> bLength:                           0x07
>> bDescriptorType:                   0x05
>> bEndpointAddress:                  0x81  -> Direction: IN - EndpointID: 1
>> bmAttributes:                      0x01  -> Isochronous Transfer Type, Synchronization Type = No Synchronization, Usage Type = Data Endpoint
>> wMaxPacketSize:                  0x0040 = 1 transactions per microframe, 0x40 max bytes
>> bInterval:                         0x01
>>
>> Does anyone have any ideas?
>>
>> Cheers,
>>
>> Tim
>>
>>
>> ------------------------------------------------------------------------------
>>
>> _______________________________________________
>> Libusb-win32-devel mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/libusb-win32-devel
>>
>>
>
>
> ------------------------------------------------------------------------------
>
> _______________________________________________
> Libusb-win32-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/libusb-win32-devel
>
>

------------------------------------------------------------------------------

_______________________________________________
Libusb-win32-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libusb-win32-devel