• AVR Freaks

USB, DATA0/1 toggling, Bulk transfer

Page: 12 > Showing page 1 of 2
Author
ee_martin
Starting Member
  • Total Posts : 56
  • Reward points : 0
  • Joined: 2007/10/18 13:20:44
  • Location: 0
  • Status: offline
2010/01/26 09:31:06 (permalink)
0

USB, DATA0/1 toggling, Bulk transfer

Folks,
 
I need a definitive answer for what must be a silly question.
 
If I use usb_bulk_read from the libusb suite to read, say, 192 bytes, and I set a maximum packet
size of 64 bytes, the host will read the 192 bytes as three 64-byte packets (192 = 3x64).
Each time a packet is sent DAT0/1 will be toggled so if it started as 0 it will become 1, 0, 1,
and will be 1 at the end of the exercise.
 
If I do the same thing *again*, calling usb_bulk_read for a second time, should I start
with DATA0/1 = 1 or 0?
 
I suppose the question is whether the DATA0/1 toggling sequence starts when the
device is first enumerated, and carries on from there, or it starts at zero at the
start of every sequence of packets generated by a new usb_bulk_read call.
 
I suspect the former, but I am becoming unsure.  I have some really weird things
going on here!!
 
Any help much appreciated.
 
Martin
#1

21 Replies Related Threads

    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/26 10:33:47 (permalink)
    0
    I suppose the question is whether the DATA0/1 toggling sequence starts when the device is first enumerated, and carries on from there, or it starts at zero at the start of every sequence of packets generated by a new usb_bulk_read call.

    "the DATA0/1 toggling sequence starts when the device is first enumerated" is the right answer.

    More exactly, data toggle is reset to '0' at Set_Configuration request on all interrupt and bulk endpoints in enumeration. And then, it toggles every time when the endpoint exchange a packet, regardless of transfer termination. It continues until the device is re-enumerated by bus reset.

    Tsuneo
    #2
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/26 11:36:48 (permalink)
    0
    Thanks.  I suspected that, but wanted to be certain.
     
    I seem to have now cracked the problem, but I'm still not absolutely sure whether it is by happy accident, or by design.
     
    Do you happen to know what happens if usb_bulk_read (from the libusb-win32 libraries) sends a read request and the DATA0/1 toggle in the PIC is wrong?  Does it just return no data?
     
    The code I am using is:
     
       ret = usb_bulk_read(dev, EP_IN, tmp1, sizeof(tmp1), 2000);
       if(ret != sizeof(tmp1))
        {
         printf("Error %d: bulk read (IN) failed\n", ret);
        }
    but I've never seen this error message being printed and I'm sure I've got DATA0/1 on the PIC wrong sometimes!
     
    Martin
     
    #3
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/26 17:00:13 (permalink)
    0
    It all depends on how "wrong" your data toggling is. As Chinzei said, it is often reset to the correct state.

    The symptom is often when you run the program twice, the 2nd time it will fail, at least under Linux. But sometimes the host seems to ignore it, especially under Windows. 

      USB_Links and libusb
    #4
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/26 17:07:07 (permalink)
    0
    On the host side, data toggle is handled automatically by host controller. It doesn't depend on PC device driver, host app, or even OS.

    When a device sends a packet in wrong data toggle for IN transaction, host returns ACK to the transaction, but the data is ignored. After the next packet, data toggle is synchronized and no data drop occurs. Just the first one drops.

    Tsuneo
    #5
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/26 18:57:29 (permalink)
    0
    ORIGINAL: chinzei
    On the host side, data toggle is handled automatically by host controller. It doesn't depend on PC device driver, host app, or even OS.

    When a device sends a packet in wrong data toggle for IN transaction, host returns ACK to the transaction, but the data is ignored. After the next packet, data toggle is synchronized and no data drop occurs. Just the first one drops.


    Yes the problem is that the data get silently dropped.

    The OS sometimes matters because of this. For example, under Linux, especially for some kernel version, the device may not proper handle set_interface command and the interaction between the kernel and the device firmware will cause data toggle problem. The symptom is often that the program works the first time and the second time the program will fail.

    Some discussions here:
    http://old.nabble.com/Set-Alternative-Configuration-td23093350.html#a23116432

    Linux kernel patch here:
    https://kerneltrap.org/mailarchive/linux-usb/2008/11/28/4259374/thread
    http://marc.info/?l=linux-usb&m=123074111001861&w=2


      USB_Links and libusb
    #6
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/26 22:45:50 (permalink)
    0
    For example, under Linux, especially for some kernel version, the device may not proper handle set_interface command and the interaction between the kernel and the device firmware will cause data toggle problem.


    Ah, I didn't mention about Set_Interface request on above post.
    Set_Interface also makes the data toggle reset to '0'.
    But it is device's problem, not OS's.

    Another request which resets data toggle is Clear_Feature( ENDPOINT ).

    Tsuneo
    #7
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/27 01:27:42 (permalink)
    0
    Folks,
     
    Thanks for your replies - very helpful as always.
     
    I have now got everything working consistently, so from that (more) strong basis I can do an experiment.
     
    I am using Windows XP with the libusb-win32 library, latest version (0.1.12.2?).  I haven't tried Linux, but
    it has to work on Linux too eventually.
     
    I have purposefully made the DATA0/1 toggle wrong and tried to READ data (an IN transaction).  What
    happens is unfortunate, because data appears to be read successfully - there is no indication of an error.
    What I actually get is an array full of rubbish that is treated as good data.
     
    I see no mechanism for detecting that the data is wrong, which makes the whole idea of the DATA0/1 toggling
    completely pointless.  If the system continues regardless of the error, and gives no sign that there was an
    error, what's the point of using the DATA0/1 toggle in the first place?  Why not just turn it off and save
    hassle?
     
    Martin
     
    #8
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/27 08:14:27 (permalink)
    0
    You may want to read some introduction of USB site to understand the use of Data Toggle. Basically it is for data integrity over the device side.

    http://www.usbmadesimple.co.uk/ums_3.htm

    As Tsuneo said, "On the host side, data toggle is handled automatically by host controller. It doesn't depend on PC device driver, host app, or even OS. When a device sends a packet in wrong data toggle for IN transaction, host returns ACK to the transaction, but the data is ignored. After the next packet, data toggle is synchronized and no data drop occurs. Just the first one drops."

    So you can not expect the host driver to help you. It is your firmware's responsibility to handle data toggle correctly.
    post edited by xiaofan - 2010/01/27 08:17:03

      USB_Links and libusb
    #9
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/27 08:55:19 (permalink)
    0
    Xiaofan,
     
    Hello again!  I think I have understood the Data Toggle scheme, but I am having trouble more at a conceptual
    level.  The PIC end is fine - I've got that.  (I think!).  It's the PC end.
     
    If a PC sends off a read request, so an IN setup packet, and the PIC firmware is wrong, what comes back is an ACK, and a lot of rubbish in the array that was to collect the data.  The return value is equal to the number of
    bytes requested, so no error is visible.  Essentially I got some data and I can't tell it's rubbish.
     
    So far as I can see, there is no way the PC can know there was a problem, and I think that's a poor scheme.
    Couldn't the usb_bulk_read be written so that it gave an error if it just got an ACK but no data?
     
    Of course if the USB device is perfect we should never see an error, but then if everything was always perfect the word "error" wouldn't exist!!
     
    By the way, please don't suggest that it's open-source software and I should just fix it myself - that's WAY beyond my ability!!  The authors of libusb-win32 are doing a great job - it's appreciated.
     
    Martin
    #10
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/28 12:26:40 (permalink)
    0
    Firstly, host controllers follow the data toggle scheme for bulk and interrupt EPs as suggested on USB spec.
    It is guaranteed on each host controller spec, as follows.
    OHCI - hcir1_0a.pdf
    4.3.1.3.6.1 Transmission Errors
    Data toggle mismatches on input data are counted as transmission errors. The cause of a data toggle mismatch is either failure of the endpoint to receive an ACK or a broken device. Data received when the data toggle mismatches is discarded and never written to host memory.

    UHCI - UHCI11D.pdf
    3.2.3 TD TOKEN (DWORD 2: 08-0Bh)
    Data Toggle (D).
    This bit determines which data PID is sent or expected (0=DATA0 and 1=DATA1). The Data Toggle bit provides a 1-bit sequence number to check whether the previous packet completed. See section 8.6 of the USB specification for a more detailed description of Data Toggle Synchronization.

    EHCI - ehci-r10.pdf
    4.12.1.2 Asynchronous - Do Complete Split
    If the PidCode indicates an IN, then any of following responses are expected:
    - DATA0/1
    If the data sequence PID does not match the expected, the data is ignored, the transfer state is not advanced and this state is exited.

    OHCI, UHCI and EHCI specs are linked in this USB.org page
    http://www.usb.org/developers/resources/


    Therefore, you cannot do without data toggle on the device side, anyway wink


    The return value is equal to the number of bytes requested, so no error is visible.

    Usually, shorter number is returned.
    How do you call usb_bulk_read() ?
    Post your code exactly as you wrote.

    Tsuneo
    #11
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/29 01:00:25 (permalink)
    0
    Tsuneo,
     
    Yes, I've seen that too.  However, reality seems to differ.
     
    As you will know one can turn off the DATA0/1 toggling and testing in the PIC.  I have not done
    so, but since the facility is there it must be useable in some way, I would have thought.
    Maybe I should try turning it off and see if usb_bulk_read complains ...
     
    The key block of my code is as follows:
     

    for(block = 0; block < 128; block++) {
       k = block * 16;  //   (4096/256)
       tmp1[0] = k % 256; // IN packet start, Mid-byte
       tmp1[1] = k/256; // IN packet start, MSByte
       tmp1[2] = OUT_L; // OUT packet start, Mid-byte
       tmp1[3] = OUT_H; // OUT packet start, MSByte
       ret = usb_control_msg(dev, 0x40, SET_BLOCK_NUMBER, block, 0, tmp1, 4, 100);
       if (ret < 0) {
        printf("Unable to send vendor request to set block number, ret = %d...\n", ret);
        }
     
       ret = usb_bulk_read(dev, EP_IN, tmp1, sizeof(tmp1), 2000);
       if(ret != sizeof(tmp1))
        {
         printf("Error %d: bulk read (IN) failed\n", ret);
        }
     
       for(j = 0; j < READ_SIZE; j++) {
        raw[i] = tmp1[j];
        i++;
       }
      }

     
    If "ret" is negative, which I believe is the usual way that errors are notified, I should get
    a message printed on my screen.  I have never seen that message, even when I have
    purposefully made the DATA0/1 flag wrong.
     
    Any thoughts would be appreciated - I would really like to be able to tell on the PC when I have
    got things wrong on the PIC and set DATA0/1 is wrongly.
     
    Martin
     
    #12
    chinzei
    Super Member
    • Total Posts : 2250
    • Reward points : 0
    • Joined: 2003/11/07 12:39:02
    • Location: Tokyo, Japan
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/29 02:49:20 (permalink)
    0
    you are requesting sizeof(tmp1) bytes in usb_bulk_read()
    Is the firmware aware of this number?

    a) If the firmware always fills 64 bytes to the bulk IN EP, regardless of this requested size, usb_bulk_read() will get the requested size without reporting any error. But the resulting data is not fine, because of packet drop by data toggle error.

    b) If the firmware doesn't send any data after it transmits the requested size, usb_bulk_read() returns timeout error, ETIMEDOUT (-116).

    c) If the firmware puts a short packet (less than 64 bytes, including Zero-Length Packet), to cut off the transfer before the transferred size reaches to the requested size, usb_bulk_read() returns smaller number than requested size, without any error. Packet drop by data toggle error reduces the returned number less than transferred number by the device.

    That is, the behavior of usb_bulk_read() depends on the firmware code.
    Maybe, you take a) strategy. Then, you can't see any error.

    Tsuneo
    #13
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/29 05:47:14 (permalink)
    0
    Tsuneo,
     
    Yes, the firmware is aware of this number, in that I am aware of it and make it all fit.  The data being collected is a multiple of 64, and perhaps I should just use "64" in the code.  Even better, the "if" statement should just check for negative values so
     

    ret = usb_bulk_read(dev, EP_IN, tmp1, sizeof(tmp1), 2000);
      if(ret < 0)
       {
        printf("Error %d: bulk read (IN) failed\n", ret);
       }

     
    instead of what I have above.
     
    But the point stands.  I always get a returned value of 64, so I never get a negative value.
     
    If DATA0/1 is wrong in the firmware I still get 64 bytes of data, and "ret" in my code is still 64 (so it's not negative) so no error.  However, the returned data is rubbish.  The firmware did *not* fill the buffer (and it should not) so
    it is behaving correctly when it gets a DATA0/1 flag it thinks is wrong.  I have no idea where the data that is returned actually came from - it's just noise.  The next packet is fine as DATA0/1 has been toggled by the PC and has become correct.
     
    I still see no mechanism for the PC to recognise that something went wrong.
     
    Martin
    #14
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/29 20:39:32 (permalink)
    0

    ORIGINAL: ee_martin
    I have no idea where the data that is returned actually came from - it's just noise. 

    Maybe that is the real issue. Once you find this out, you probably get the answer. I will tend to think that your firmware sends the rubbish. But there is a slight chance that libusb-win32 is at fault.

      USB_Links and libusb
    #15
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/01/30 16:07:15 (permalink)
    0
    Xiaofan,
     
    At that point in the experiment I knew exactly what was in both  internal and external memory and I couldn't find the data I got back from usb_bulk_read anywhere.
     
    Anyway, I don't really care!  The data I get back *should* be wrong - the DATA0/1 flag was wrong.  What I  want is some sort of marker telling me that it's wrong.
     
    I am coming to the conclusion that usb_bulk_read just doesn't have that capability.
     
    Must get back to working on the isochronous stuff - I'm going to crack that some day.  Maybe it'll be something to do in my retirement ...
     
    Martin
     
     
     
    #16
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/02/01 04:34:17 (permalink)
    0
    ORIGINAL: ee_martin
    Must get back to working on the isochronous stuff - I'm going to crack that some day.  Maybe it'll be something to do in my retirement ...


    Maybe you can read this thread and decide that you'd better go with bulk transfer.
    http://www.microchip.com/forums/tm.aspx?m=474992

      USB_Links and libusb
    #17
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/02/01 05:02:26 (permalink)
    0
    Xiaofan,
     
    Yes, I've seen that one.
     
    I need a guarantee of bandwidth.  I only need 256 bytes downloaded and 128 bytes uploaded per 1ms frame, and I know that isn't much.  However I am competing with other kit on the USB bus and I know I won't get enough bandwidth even for that small amount of data if I use Bulk transfer which, as you know, has the lowest priority.
     
    If it wasn't for this bandwidth problem I wouldn't even think of isochronous.
     
    I've seen your code for isochronous transfer and I don't know why you use three of everything (context, buffer, etc).  In fact, to be honest, I don't understand why you use the loops, etc, at all.  I appreciate that your code is old, and that you don't pretend to be big on the "C" programming front, but could you spare the time to explain your code, as least as much as you can?
     
    Martin
    #18
    xiaofan
    Super Member
    • Total Posts : 6247
    • Reward points : 0
    • Joined: 2005/04/14 07:05:25
    • Location: Singapore
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/02/01 05:16:44 (permalink)
    0
    You do not need to use the loops or the 3 times thingy. It was just a test program. I want to see if the data comes back in correct sequence.

    The following is from the Post 27 of the following thread. It is using libusb-win32's not-well-documented
    asynchronous API for isochronous transfer.

    http://www.microchip.com/forums/tm.aspx?m=270049&mpage=2


    #include <usb.h>

    #define VERSION "0.1.0"
    #define VENDOR_ID 0x04D8
    #define PRODUCT_ID 0x0080
    #define INTERFACE 0
    #define BUFFER_SIZE 65

    usb_dev_handle *find_pickit2_isoc();

    usb_dev_handle* setup_libusb_access() {
        usb_dev_handle *pickit2_isoc;

        usb_set_debug(255);
        usb_init();
        usb_find_busses();
        usb_find_devices();
               
        if(!(pickit2_isoc = find_pickit2_isoc())) {
            printf("Couldn't find the mouse, Exiting\n");
            return NULL;
        }
     
        if (usb_set_configuration(pickit2_isoc, 1) < 0) {
            printf("Could not set configuration 1 : %s\n");
            return NULL;
        }
       
        if (usb_claim_interface(pickit2_isoc, INTERFACE) < 0) {
            printf("Could not claim interface: %s\n");
            return NULL;
        }

        return pickit2_isoc;
    }

    usb_dev_handle *find_pickit2_isoc()
    {
        struct usb_bus *bus;
        struct usb_device *dev;

        for (bus = usb_busses; bus; bus = bus->next) {
            for (dev = bus->devices; dev; dev = dev->next) {
                   if (dev->descriptor.idVendor == VENDOR_ID &&
                      dev->descriptor.idProduct == PRODUCT_ID ) {
                    usb_dev_handle *handle;
                      printf("pickit2_isoc with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID);
                    if (!(handle = usb_open(dev))) {
                        printf("Could not open USB device\n");
                        return NULL;
                    }

                    return handle;
                }
          
            }
        }
       
        return NULL;
    }

     void test_isochronous_async(usb_dev_handle *dev)
     {
       unsigned char buf0[640];
       unsigned char buf1[640];
       unsigned char buf2[640];
     
       int i;
     
       /* use three contexts for this example (more can be used) */
       void *context0 = NULL;
       void *context1 = NULL;
       void *context2 = NULL;
     
       /* write transfer (stream) */
    /*
       usb_isochronous_setup_async(dev, &context0, 0x01);
       usb_isochronous_setup_async(dev, &context1, 0x01);
       usb_isochronous_setup_async(dev, &context2, 0x01);
     
       usb_submit_async(context0, buf0, sizeof(buf0));
       usb_submit_async(context1, buf1, sizeof(buf1));
       usb_submit_async(context2, buf2, sizeof(buf2));
     
       for(i = 0; i < 10; i++)
         {
           usb_reap_async(context0, 5000);
           usb_submit_async(context0, buf0, sizeof(buf0));
     
           usb_reap_async(context1, 5000);
           usb_submit_async(context1, buf1, sizeof(buf1));
     
           usb_reap_async(context2, 5000);
           usb_submit_async(context2, buf2, sizeof(buf2));
         }
     
       usb_reap_async(context0, 5000);
       usb_reap_async(context1, 5000);
       usb_reap_async(context2, 5000);
     
       usb_free_async(&context0);
       usb_free_async(&context1);
       usb_free_async(&context2);
     
    */
     
       /* read transfer (stream) */
       usb_isochronous_setup_async(dev, &context0, 0x81,64);
       usb_isochronous_setup_async(dev, &context1, 0x81,64);
       usb_isochronous_setup_async(dev, &context2, 0x81,64);
     
       usb_submit_async(context0, buf0, sizeof(buf0));
       usb_submit_async(context1, buf1, sizeof(buf1));
       usb_submit_async(context2, buf2, sizeof(buf2));
     
       for(i = 0; i < 10; i++)
         {
           usb_reap_async(context0, 5000);
           usb_submit_async(context0, buf0, sizeof(buf0));
     
           usb_reap_async(context1, 5000);
           usb_submit_async(context1, buf1, sizeof(buf1));
     
           usb_reap_async(context2, 5000);
           usb_submit_async(context2, buf2, sizeof(buf2));
         }

       for(i = 0; i < 640; i++) {
            printf(" %02x, %02x, %02x ", buf0[i],buf1[i],buf2[i]);
    //        printf(" %02x, %02x, %02x ", buf0[i]);
            }
     
       usb_reap_async(context0, 5000);
       usb_reap_async(context1, 5000);
       usb_reap_async(context2, 5000);
       usb_free_async(&context0);
       usb_free_async(&context1);
       usb_free_async(&context2);
     
       /* release interface */
       usb_set_altinterface(dev, 0);
       usb_release_interface(dev, 0);
     }


    int main( int argc, char **argv)
    {
        usb_dev_handle *pickit2_isoc;
        if ((pickit2_isoc = setup_libusb_access()) == NULL) {
            exit(-1);
        }
        test_isochronous_async(pickit2_isoc);
        usb_close(pickit2_isoc);

        return 0;
    }

      USB_Links and libusb
    #19
    ee_martin
    Starting Member
    • Total Posts : 56
    • Reward points : 0
    • Joined: 2007/10/18 13:20:44
    • Location: 0
    • Status: offline
    RE: USB, DATA0/1 toggling, Bulk transfer 2010/02/01 05:35:06 (permalink)
    0
    Xiaofan,
     
    Thanks for the code.  That's a lot like what I am using, but I don't understand the high-level features of either.
     
    For example, at it's most basic,  you have the lines:
     
    [code]
    usb_reap_async(context0, 5000);
      usb_reap_async(context1, 5000);
      usb_reap_async(context2, 5000);
      usb_free_async(&context0);
      usb_free_async(&context1);
      usb_free_async(&context2);

    [\code]
     
    That the "3 times thingy" I meant, along with having buf0, buf1 and buf2.  Why?  And why are the buffers so long?  OK, so they don't over-run, but why should they do that?
     
    As you see, it's the high-level stuff I'm missing.
     
    Martin
     
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5