Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 15 FirstFirst 1 2 3 4 12 ... LastLast
Results 26 to 50 of 351

Thread: USBHost_t36 USB Mass Storage Driver Experiments

  1. #26
    Senior Member
    Join Date
    Jul 2014
    Posts
    2,366
    Quote Originally Posted by KurtE View Post
    The newer drive does not work either (I also just tried reformat on windows 10 Fat system... to see if that would change it). Again does not get to the CD... But instead of endless messages it just hangs...
    One thing I noticed, that Win10 exFAT formatting did dot work here. used the SDFormatter (the official one) and it worked.
    Reason (I believe) is that Win10 does not add a boot-record anymore, formats only a single volume (first record starts with 'exFAT')

  2. #27
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    @WMXZ Will try. Note I tried SDFormatter, including allowing resize... and it still does not read... But it now acts more like the other disk in that it does not repeat.... Just stops...

  3. #28
    Senior Member
    Join Date
    Aug 2017
    Posts
    139
    @WMXZ, @Kutre, @mjs513

    One thing that I see in sd_msc.cpp, in the "MSC_disk_read(BYTE *buff, DWORD sector, UINT count)" and "MSC_disk_write(const BYTE *buff, DWORD sector, UINT count)" functions is
    "WaitDriveReady()". I probably did not comment that out in the library I sent. Comment them out in sd_msc.cpp and see if the library stabalises. It did on my side. Not as many hangs as
    before. Only when I try copy a 4.3MB file from one file to another file on the same USB drive and that seems to be due to buffer size which is using multi sector reads and writes.

  4. #29
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    Thanks @wwatson,

    Will try it.

    As I mentioned in the T4 thread, with my two thumb drives the call to mscInit is hanging, in the call to msDeviceInquiry, which has called msDoCommand,
    msDoCommand has the flags of CMDDIRDATAIN so it queues the command to the datapipeOut pipe and the return buffer to the datapipeIn pipe and we make it through the two loops waiting for msOutCompleted and msInCompleted.. It then go to call msGetCSW, which queues a prefilled in buffer on the datapipeIN pipe and waits for a callback (which waits for msInCompleted which is never cleared (Callback is not called....

    The last stuff in my debug output:
    Code:
    ## mscInit before DeviceInquiry
    ## msDeviceInquiry before do command 36
    msController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)
    msDoCommand after msOutCompleted loop
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msDoCommand after msInCompleted loop
    msGetCSW before QDT
    msGetCSW after QDT
    Questions I have include:

    The msGetCSW is setting up transfer from the datapipeIn, and it is also prefilling the buffer it sets up to some values. Who is it that triggers something to actually be returned on this pipe?
    I understand when I setup to send an INQUIRY command (setup on output pipe), that the device will respond with a Inquiry response, which will come back on the input pipe.

    But does it also automatically respond with a second packet of the status block?

    Do you have a link to some PDF or the like that you have been using to understand the SCSI stuff?
    Maybe something like: https://www.usb.org/sites/default/fi...assbulk_10.pdf ?

    Thanks and again good stuff!

  5. #30
    Senior Member
    Join Date
    Aug 2017
    Posts
    139
    Just setup TD 1.47B2 and ran uSDFS_test.ino on the T3.6 at 180MHZ and 240MHZ. Tested good on Kingston 16G flash drive and a Seagate 250GB hard drive with "WaitDriveReady()" enabled. But when I disabled "WaitDriveReady()" at 240MHZ it fails on writing to a file. On my other T3.6 system it still works at 240MHZ. There are lots of other USB drivers involved on that system. I am going to port this latest version of uSDFS over to that system and see if it reacts the same way.
    Need to be able to better detect errors. "msController::checkCSW(msCommandStatusWrapper _t *CSW)" is where it is done".

  6. #31

  7. #32
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    Thanks @wwatson - Lots of information in there about the different commands and structures!

    The Document I linked to in #29 from the USB Spec documents did not have any of those details, but does have some interesting stuff about CBW and CSW usages and about the handshaking between host and device and things like if a device does not like something it may stall the pipes...

    For the fun of it I may try some other type of disk to see if they get beyond the INQUIRY command.

  8. #33
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    @PaulStoffregen - Wondering how best to do something using usbhost_t36 library. I have done some stuff in the library, but am unsure about some of the low level stuff and how best to do it...

    Example: The USB document for USB Bulk storage talking about Data transfer conditions (Section 5.3) has a simple Flow chart that shows what you should do to output the next CBW.

    First step after Enter: Attemt to read CSW from Bulk-In-endpoint And then a conditional box (STALL Bulk-In -OR- Bulk Error) ...


    Question is how do we properly do this with our Pipes/Transfers - Currently the code simply queues up a buffer to the input pipe and waits for a response to happen (Callback function sets a completed variable)
    Code:
    uint8_t msController::msGetCSW() {
    	uint8_t CSWResult = 0;
    	msCommandStatusWrapper_t StatusBlockWrapper = (msCommandStatusWrapper_t)
    	{
    		.Signature = CSWSIGNATURE,
    		.Tag = 0,
    		.DataResidue = 0, // TODO: Proccess this if received.
    		.Status = 0
    	};
    	println("msGetCSW before QDT");
    	if (!queue_Data_Transfer(datapipeIn, &StatusBlockWrapper, sizeof(StatusBlockWrapper), this)) {
    		println("msController::msGetCSW QDT failed");
    	}
    	println("msGetCSW after QDT");
    	uint16_t timeout_loop_count=32767;
    	while(!msInCompleted /*&& --timeout_loop_count*/);
    	msInCompleted = false;
    	CSWResult = checkCSW(&StatusBlockWrapper);
    	return CSWResult;
    }
    This is a modified version of @wwatson's code in that I print out a few more things, check to see if the queue failed ...

    The current code hangs on my machine with a couple of different USB Sticks after the INQUIRY call... I played around with timeout loop, which is shown semi-commented out...
    This allowed it to continue, but then we still have the transfer structure pending on the pipe so things out of sync...

    Again not sure of how to handle this. I don't know of any normal way to for example cancel a transfer? Or put in timeout? ...

    Suggestions?

    Kurt

    P.S. - I understand you might be busy with a few other things

  9. #34
    Senior Member
    Join Date
    Aug 2017
    Posts
    139
    @Kurte

    That is where I am at with this as well. How to detect a stalled pipe and other errors or conditions that constitute performing a reset recovery.

    This is the code that checks for a valid CSW:
    Code:
    //---------------------------------------------------------------------------
    // Check for valid CSW
    uint8_t msController::checkCSW(msCommandStatusWrapper_t *CSW) {
    
    	if(CSW->Signature != CSWSIGNATURE) return MSCSWSIGERROR; // Signature error
    	if(CSW->Tag != CBWTag) return MSCSWTAGERROR; // Tag mismatch error
    	if(CSW->Status != 0) return CSW->Status; // Actual status from last transaction 
    
    	return MSCOMMANDPASS; // Command transaction success (0)
    }
    The tag mismatch error is the most common error I get. When I hex dump the CSW the signature is there but the tag and status are always zero. Sometimes I get a status byte=1 which is an invalid CBW sent. I have never been able to detect a phase error which is status byte=2.

    Section 6 in the usbmassbulk_10.pdf manual gives lots of information on how to handle error conditions.

  10. #35
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    @wwatson - Understand...

    I did a little more hacking and maybe some of the issue is handling conditions and errors.

    That is I hacked up your function:
    Code:
    void msController::new_dataIn(const Transfer_t *transfer)
    {
    	uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF);
    	println("msController dataIn (static): ", len, DEC);
    	print_hexbytes((uint8_t*)transfer->buffer, (len < 32)? len : 32 );
    	if (len >= 4) {
    		uint32_t l = *(uint32_t*)transfer->buffer;
    		if (l == CBWSIGNATURE) println("** CBWSIGNATURE");
    		else if (l == CSWSIGNATURE) println("** CSWSIGNATURE");
    		else println("** ????");
    	}
    
    
    	msInCompleted = true; // Last in transaction is completed.
    }
    So I can see what data is coming back from the different commands and the like:
    Code:
    Test uSDFS
    2:/
    USB2 PLL running
     reset waited 6
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 20005000
    periodictable = 20005000
    ## mscInit Called
    port change: 10001803
        connect
      begin reset
    port change: 18001205
      port enabled
      end recovery
    new_Device: 480 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 00 02 09 00 01 40 E3 05 08 06 98 32 00 01 00 01 
        VendorID = 05E3, ProductID = 0608, Version = 3298
        Class/Subclass/Protocol = 9(Hub) / 0 / 1(Single-TT)
        Number of Configurations = 1
    enumeration:
    enumeration:
    Product: USB2.0 Hub
    enumeration:
    Config data length = 25
    enumeration:
    Configuration Descriptor:
      09 02 19 00 01 01 00 E0 32 
        NumInterfaces = 1
        ConfigurationValue = 1
      09 04 00 00 01 09 00 00 00 
        Interface = 0
        Number of endpoints = 1
        Class/Subclass/Protocol = 9(Hub) / 0 / 0
      07 05 81 03 01 00 0C 
        Endpoint = 1 IN
        Type = Interrupt
        Max Size = 1
        Polling Interval = 12
    enumeration:
    USBHub memory usage = 960
    USBHub claim_device this=20004660
    found possible interface, altsetting=0
    number of interfaces found = 1
    USBHub control callback
    09 29 04 E0 00 32 64 00 FF 00 00 00 00 00 00 00 
    Hub ports = 4
    USBHub control callback
    USBHub control callback
    USBHub control callback
    USBHub control callback
    power turned on to all ports
    device addr = 1
    new_Pipe
    allocate_interrupt_pipe_bandwidth
      ep interval = 12
      interval = 256
     best_bandwidth = 2, at offset = 0
    pipe cap1 = F0012101
    HUB Callback (member)
    status = 4
    getstatus, port = 2
    USBHub control callback
    01 01 01 00 
    New Port Status
      status=10101  port=2
      state=0
      Device is present: 
      Has Power
    USBHub control callback
    Port Status Cleared, port=2
    timer event (19999 us): Debounce Timer, this = 20004660, timer = 20004978
    ports in use bitmask = 4
    getstatus, port = 2
    USBHub control callback
    01 01 00 00 
    New Port Status
      status=101  port=2
      state=2
      Device is present: 
      Has Power
    timer event (19999 us): Debounce Timer, this = 20004660, timer = 20004978
    ports in use bitmask = 4
    getstatus, port = 2
    USBHub control callback
    01 01 00 00 
    New Port Status
      status=101  port=2
      state=3
      Device is present: 
      Has Power
    timer event (19999 us): Debounce Timer, this = 20004660, timer = 20004978
    ports in use bitmask = 4
    getstatus, port = 2
    USBHub control callback
    01 01 00 00 
    New Port Status
      status=101  port=2
      state=4
      Device is present: 
      Has Power
    timer event (19999 us): Debounce Timer, this = 20004660, timer = 20004978
    ports in use bitmask = 4
    getstatus, port = 2
    USBHub control callback
    01 01 00 00 
    New Port Status
      status=101  port=2
      state=5
      Device is present: 
      Has Power
    timer event (19999 us): Debounce Timer, this = 20004660, timer = 20004978
    ports in use bitmask = 4
    getstatus, port = 2
    USBHub control callback
    01 01 00 00 
    New Port Status
      status=101  port=2
      state=6
      Device is present: 
      Has Power
    sending reset
    send_setreset
    USBHub control callback
    unhandled setup, message = 40323
    timer event (19999 us): Debounce Timer, this = 20004660, timer = 20004978
    ports in use bitmask = 0
    HUB Callback (member)
    status = 4
    getstatus, port = 2
    USBHub control callback
    03 05 10 00 
    New Port Status
      status=100503  port=2
      state=7
      Device is present: 
      Enabled, speed = 480 Mbit/sec
      Has Power
    USBHub control callback
    unhandled setup, message = 140123
    timer event (24999 us): Hello, I'm resettimer, this = 20004660, timer = 20004994
    port_doing_reset = 2
    PORT_RECOVERY
    new_Device: 480 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 00 02 00 00 00 40 0C 09 00 10 00 11 01 02 00 01 
        VendorID = 090C, ProductID = 1000, Version = 1100
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    enumeration:
    Manufacturer: SMI Corporation
    enumeration:
    Product: USB DISK
    enumeration:
    Config data length = 32
    enumeration:
    Configuration Descriptor:
      09 02 20 00 01 01 00 80 FA 
        NumInterfaces = 1
        ConfigurationValue = 1
      09 04 00 00 02 08 06 50 00 
        Interface = 0
        Number of endpoints = 2
        Class/Subclass/Protocol = 8(Mass Storage) / 6(SCSI) / 80(Bulk Only)
      07 05 81 02 00 02 FF 
        Endpoint = 1 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 255
      07 05 02 02 00 02 FF 
        Endpoint = 2 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 255
    enumeration:
    msController claim this=20004A40
    Descriptor 4 = INTERFACE
    msController claim this=20004A40
    09 04 00 00 02 08 06 50 00 07 05 81 02 00 02 FF 07 05 02 02 00 02 FF 
    endpointType = 2
    numendpoint=2
    endpointIn=81
    endpointOut=2
    packet size in (msController) = 512
    packet size out (msController) = 512
    polling intervalIn = 255
    polling intervalOut = 255
    new_Pipe
    new_Pipe
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT
    ## mscInit after available
    ## mscInit after reset
    control CallbackIn (msController)
    00 00 00 00 00 00 00 00 
    ## mscInit after msgGetMaxLun
    control CallbackIn (msController)
    00 00 00 00 00 00 00 00 
    ## mscInit before startstopunit
    msController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)
    msGetCSW before QDT
    msGetCSW after QDT
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 02 00 00 00 00 00 00 00 00 
    ** CSWSIGNATURE
    ## mscInit before media ready
    msController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)
    msGetCSW before QDT
    msGetCSW after QDT
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 03 00 00 00 00 00 00 00 00 
    ** CSWSIGNATURE
    ## mscInit before DeviceInquiry
    ## msDeviceInquiry before do command 36
    msController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)
    msDoCommand after msOutCompleted loop
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 04 00 00 00 00 00 00 00 00 
    ** CSWSIGNATURE
    msDoCommand after msInCompleted loop
    msGetCSW before QDT
    msGetCSW after QDT
    Notice the ending, that the data returned from the INQUIRY command was a CSW message not a data message. So you already received the status... But thought it was result of inqury.

    Kurt

  11. #36
    Senior Member
    Join Date
    Aug 2017
    Posts
    139
    @Kurte

    I think I see what you are getting at. For each CBW sent there needs to be a corresponding CSW read in and checked. My code is only getting the CSW at the end of "msDoCommand()" which is probably causing things to get out of sync.

    Thanks, When I get back from work today I am going to redo the msDoCommand()" and "msGetCSW()" functions.

    You are really good at this.

  12. #37
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    Hi @wwatson,

    Thanks,

    Not sure yet what is the correct way of programming this yet - Still just starting to trace my way through...

    But so far it looks like for each command you output you are receiving a CSWSignature message back... Not sure about your data that probably should be returned for the INQUIRY command?

    Actually I think there is an issue with the INQUIRY command:

    That is I think you are asking it to not return any data... Page 92 of your SCSI document...
    You are passing in allocation length=0 and I think that is saying don't return anything... So I changed:
    Code:
    uint8_t msController::msDeviceInquiry(msInquiryResponse_t * const Inquiry)
    {
    	msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t)
    	{
    		.Signature          = CBWSIGNATURE,
    		.Tag                = ++CBWTag,
    		.TransferLength     = sizeof(msInquiryResponse_t),
    		.Flags              = CMDDIRDATAIN,
    		.LUN                = 0,
    		.CommandLength      = 6,
    		.CommandData        = {CMDINQUIRY,0x00,0x00,0x00,sizeof(msInquiryResponse_t),0x00}
    	};
    	Serial.printf("## msDeviceInquiry before do command %u\n", sizeof(msInquiryResponse_t) );
    	uint8_t retval =  msDoCommand(&CommandBlockWrapper, Inquiry);
    	Serial.printf("## msDeviceInquiry after do command %u\n", retval );
    	return retval;
    }
    In yours you had .CommandData as all 0's after CMDINQUIRY... I put it to the size of structure you specified.
    Code:
    msController dataOut (static)31
    55 53 42 43 0D 00 00 00 00 02 00 00 80 00 0A 28 00 00 00 40 00 00 00 01 00 00 00 00 00 00 00 
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 512
    53 44 46 4F 52 4D 41 54 45 44 20 08 00 00 00 00 00 00 00 00 00 00 23 5B AA 4E 00 00 00 00 00 00 
    ** ????
    msDoCommand after msOutCompleted loop
    msDoCommand after msInCompleted loop
    msGetCSW before QDT
    msGetCSW after QDT
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 0D 00 00 00 00 00 00 00 00 
    ** CSWSIGNATURE
    And now when the inquiry is called, it now returns a data structure of unknown data...

    Then we get back the status response the code continues...

  13. #38
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    @all - With the one change I mentioned above:
    .CommandData = {CMDINQUIRY,0x00,0x00,0x00,sizeof(msInquiryRespons e_t),0x00}

    One of my Thumbdrives worked...

    Then I removed the debug stuff (it still worked...) Then tried with Cruzer 1GB and it hung.. Doing lots of command transfers...
    Code:
    sController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)31
    55 53 42 43 7C 00 00 00 00 00 00 00 80 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 7C 00 00 00 00 00 00 00 01 
    ** CSWSIGNATURE
    msController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)31
    55 53 42 43 7D 00 00 00 00 00 00 00 80 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 7D 00 00 00 00 00 00 00 01 
    ** CSWSIGNATURE
    So I am pretty sure it is hung calling in:
    Code:
    uint8_t msController::WaitMediaReady() {
    	uint8_t msResult = 0;
    	do {
    		msResult = msTestReady();
    	} while(msResult);
    // TODO: Process a Timeout
    	return msResult;
    }
    Which if I am looking correct: msTestReady will be sending command data: .CommandData = {CMDTESTUNITREADY, 0x00, 0x00, 0x00, 0x00, 0x00}
    Where #define CMDTESTUNITREADY 0x00

    But if I look in the SCSI command PDF it shows opcode=0

    Is write(6) 3.59WRITE (6) command page 248 ... Says obsolete... It is returning error code=1 (fail)...

  14. #39
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,961
    Quote Originally Posted by KurtE View Post
    @all - With the one change I mentioned above:
    .CommandData = {CMDINQUIRY,0x00,0x00,0x00,sizeof(msInquiryRespons e_t),0x00}

    One of my Thumbdrives worked...

    Then I removed the debug stuff (it still worked...) Then tried with Cruzer 1GB and it hung.. Doing lots of command transfers...
    ...
    Sounds like good progress in the right spot … to make more ...

  15. #40
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,213
    Quote Originally Posted by defragster View Post
    Sounds like good progress in the right spot … to make more ...
    @all
    Wow Kurt you made a lot of progress on this - trying to keep up while isolating the FD issue which I think we have it narrowed to the clock or FD timing issue. Had scope on 3 different boards today watching the transfers - yes it does transfer but noting reading the data properly. Think @tonton81 going to have to check FD timings

  16. #41
    Senior Member
    Join Date
    Aug 2017
    Posts
    139

    Smile

    @Kurte

    Nice detective work.

    I saw the ommision you were talking about and changed it on my end as well. I also found the same ommision in msGetMaxLUNS() which has not been implemented yet. The Seagate manual
    (page 179) says "The allocation length should be at least 16". I added a define in the MassStorage.h file #define MAXLUNS 16".

    This is the modified msReportLUNs() function:
    Code:
    //---------------------------------------------------------------------------
    // Report LUNs
    uint8_t msController::msReportLUNs(uint8_t *Buffer)
    {
    	msCommandBlockWrapper_t CommandBlockWrapper = (msCommandBlockWrapper_t)
    	{
    		.Signature          = CBWSIGNATURE,
    		.Tag                = ++CBWTag,
    		.TransferLength     = MAXLUNS,
    		.Flags              = CMDDIRDATAIN,
    		.LUN                = 0,
    		.CommandLength      = 8,
    		.CommandData        = {CMDREPORTLUNS, 0x00, 0x00, 0x00, 0x00, 0x00, MAXLUNS, 0x00}
    	};
    	return msDoCommand(&CommandBlockWrapper, Buffer);
    }
    I also modified msDoCommand() to this:
    Code:
    //---------------------------------------------------------------------------
    // Send SCSI Command
    uint8_t msController::msDoCommand(msCommandBlockWrapper_t *CBW,	void *buffer)
    {
    	uint8_t CSWResult = 0;
    
    	if(CBWTag == 0xFFFFFFFF)
    		CBWTag = 1;
    	if((CBW->Flags == CMDDIRDATAIN)) { // Data from device
    		queue_Data_Transfer(datapipeOut, CBW, sizeof(msCommandBlockWrapper_t), this);
    		while(!msOutCompleted);  // Wait for out transaction to complete.
    		msOutCompleted = false;
    		queue_Data_Transfer(datapipeIn, buffer, CBW->TransferLength, this);
    		while(!msInCompleted);  // Wait for in transaction to complete.
    		msInCompleted = false;
    		if((CSWResult = msGetCSW()) != 0)
    			return CSWResult;
    	} else { // Data to device
    		queue_Data_Transfer(datapipeOut, CBW, sizeof(msCommandBlockWrapper_t), this);
    		while(!msOutCompleted);  // Wait for out transaction to complete.
    		msOutCompleted = false;
    		queue_Data_Transfer(datapipeOut, buffer, CBW->TransferLength, this);
    		while(!msOutCompleted);  // Wait for second out transaction to complete.
    		msOutCompleted = false;
    		if((CSWResult = msGetCSW()) != 0)
    			return CSWResult;
    	}
    	return CSWResult;  // Return CSW status
    }
    So far, I am not getting the occasional lockups I was with the original version.
    I also was able to do copies of large files to the same drive at 240MHZ with buffer sizes up to 8192 bytes without the lockups.
    I tested with several hard drives and two different Kingston flash drives.
    Maybe you can test the modified version and see if it changes anything with your devices.

    One question. Are you testing with T3.6 and T4 or just T4?

    This is the sketch I used to check the Inquiry function:
    Code:
    #include "uSDFS.h"
    #include "MassStorage.h"
    /*
    * for APL see http://elm-chan.org/fsw/ff/00index_e.html
    */
    #define TEST_DRV 2
    //
    #if TEST_DRV == 0
      const char *Dev = "0:/";  // SPI
    #elif TEST_DRV == 1
      const char *Dev = "1:/";  //SDHC
    #elif TEST_DRV == 2
      const char *Dev = "2:/";  //USB
    #endif
    
    FRESULT rc;       /* Result code */
    FATFS fatfs;      /* File system object */
    FIL fil;          /* File object */
    DIR dir;          /* Directory object */
    FILINFO fno;      /* File information object */
    
    msInquiryResponse_t *diskInquiry;
    msSCSICapacity_t *diskCapacity;
    
    void die(const char *text, FRESULT rc)
    { Serial.printf("%s: Failed with rc=%u.\r\n", text,rc);  while(1) asm("wfi"); }
    
    void setup() {
      // put your setup code here, to run once:
      while(!Serial);
      Serial.println("Test Drive Inquiry with uSDFS");
      Serial.print("Waiting For Device: ");
      Serial.println(Dev);
      if((rc = f_mount (&fatfs, Dev, 1))) die("Mount",rc);      /* Mount/Unmount a logical drive */
    
      //-----------------------------------------------------------
      Serial.printf("\nChange drive\n");
      if((rc = f_chdrive(Dev))) die("chdrive",rc);
    
      // Show stats for Mass Storage Device
      Serial.printf("\nDo Device Inquiry\n");
      if(TEST_DRV == 2) {
        diskInquiry = getDriveInquiry();
        Serial.printf("Removable Device: ");
        if(diskInquiry->Removable == 1)
          Serial.printf("YES\n");
        else
          Serial.printf("NO\n");
          Serial.printf("        VendorID: %8.8s\n",diskInquiry->VendorID);
          Serial.printf("       ProductID: %16.16s\n",diskInquiry->ProductID);
          Serial.printf("      RevisionID: %4.4s\n",diskInquiry->RevisionID);
          Serial.printf("\nGet Device Capacity Specs\n");
          diskCapacity = getDriveCapacity();
          Serial.printf("    Sector Count: %ld\n",diskCapacity->Blocks);
          Serial.printf("     Sector size: %ld\n",diskCapacity->BlockSize);
          Serial.printf("   Disk Capacity: %ld * %ld Bytes\n",diskCapacity->Blocks, diskCapacity->BlockSize);
      }
      Serial.printf("\nDevice Inquiry Test Finished.\n");
    }
    
    void loop() {
    	delay(1000);
    }

  17. #42
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,213
    @wwatson and @KurtE

    I just incorporated both yours and Kurt's changes in the lib for two of my thumb drives worked like a charm (Cruzer 2gb and sansdisk 32gb) for the third, a microcenter 1gb thumb drive it failed with the following results, going to try a ssd drive in a bit will let you know how that goes:
    Code:
    Test Drive Inquiry with uSDFS
    Waiting For Device: 2:/
    USB2 PLL running
     reset waited 6
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 20004000
    periodictable = 20004000
    port change: 10001803
        connect
      begin reset
    port change: 18001205
      port enabled
      end recovery
    new_Device: 480 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 00 02 00 00 00 40 07 13 63 01 00 01 01 02 03 01 
        VendorID = 1307, ProductID = 0163, Version = 0100
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    enumeration:
    Manufacturer: USB 2.0
    enumeration:
    Product: Flash Disk
    enumeration:
    Serial Number: 0ee644744fd53c
    enumeration:
    Config data length = 39
    enumeration:
    Configuration Descriptor:
      09 02 27 00 01 01 00 80 28 
        NumInterfaces = 1
        ConfigurationValue = 1
      09 04 00 00 03 08 06 50 00 
        Interface = 0
        Number of endpoints = 3
        Class/Subclass/Protocol = 8(Mass Storage) / 6(SCSI) / 80(Bulk Only)
      07 05 01 02 00 02 01 
        Endpoint = 1 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 1
      07 05 82 02 00 02 01 
        Endpoint = 2 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 1
      07 05 83 03 40 00 08 
        Endpoint = 3 IN
        Type = Interrupt
        Max Size = 64
        Polling Interval = 8
    enumeration:
    msController claim this=20002EE0
    Descriptor 4 = INTERFACE
    msController claim this=20002EE0
    09 04 00 00 03 08 06 50 00 07 05 01 02 00 02 01 07 05 82 02 00 02 01 07 05 83 03 40 00 08 
    endpointType = 2
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT

  18. #43
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,213
    @all

    Hooked up a 120GB SSD and got the following results (buf: didn't work), drive is formatted to exFat:
    Code:
    Test Drive Inquiry with uSDFS
    Waiting For Device: 2:/
    USB2 PLL running
     reset waited 6
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 20004000
    periodictable = 20004000
    port change: 10001803
        connect
      begin reset
    port change: 18001205
      port enabled
      end recovery
    new_Device: 480 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 10 02 00 00 00 40 2D 15 78 05 09 05 01 02 03 01 
        VendorID = 152D, ProductID = 0578, Version = 0509
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    enumeration:
    Manufacturer: JMicron
    enumeration:
    Product: External USB 3.0
    enumeration:
    Serial Number: 0123456789CB
    enumeration:
    Config data length = 85
    enumeration:
    Configuration Descriptor:
      09 02 55 00 01 01 00 80 FA 
        NumInterfaces = 1
        ConfigurationValue = 1
      09 04 00 00 02 08 06 50 00 
        Interface = 0
        Number of endpoints = 2
        Class/Subclass/Protocol = 8(Mass Storage) / 6(SCSI) / 80(Bulk Only)
      07 05 81 02 00 02 00 
        Endpoint = 1 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      07 05 02 02 00 02 00 
        Endpoint = 2 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      09 04 00 01 04 08 06 62 00 
        Interface = 0
        Number of endpoints = 4
        Class/Subclass/Protocol = 8(Mass Storage) / 6(SCSI) / 98(UAS)
      07 05 01 02 00 02 00 
        Endpoint = 1 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      04 24 01 00 
      07 05 82 02 00 02 00 
        Endpoint = 2 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      04 24 02 00 
      07 05 83 02 00 02 00 
        Endpoint = 3 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      04 24 03 00 
      07 05 04 02 00 02 00 
        Endpoint = 4 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 0
      04 24 04 00 
    enumeration:
    msController claim this=20002EE0
    Descriptor 4 = INTERFACE
    msController claim this=20002EE0
    09 04 00 00 02 08 06 50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00 09 04 00 01 04 08 06 62 00 07 05 01 02 00 02 00 04 24 01 00 07 05 82 02 00 02 00 04 24 02 00 07 05 83 02 00 02 00 04 24 03 00 07 05 04 02 00 02 00 04 24 04 00 
    endpointType = 2
    numendpoint=2
    endpointIn=81
    endpointOut=2
    packet size in (msController) = 512
    packet size out (msController) = 512
    polling intervalIn = 0
    polling intervalOut = 0
    new_Pipe
    new_Pipe
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT
    Descriptor 4 = INTERFACE
    Descriptor 5 = ENDPOINT
    Descriptor 36 =  ???
    Descriptor 5 = ENDPOINT
    Descriptor 36 =  ???
    Descriptor 5 = ENDPOINT
    Descriptor 36 =  ???
    Descriptor 5 = ENDPOINT
    Descriptor 36 =  ???
    control CallbackIn (msController)
    00 00 00 00 00 00 00 00 
    control CallbackIn (msController)
    00 00 00 00 00 00 00 00 
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackOut (static)
    transfer->qtd.token = 0
    msController dataOut (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static)
    Mount: Failed with rc=13.

  19. #44
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,213
    @all
    Using the same SSD but with a startech sata/ide converter I pretty much get the same results as in previous post:
    Code:
    Test Drive Inquiry with uSDFS
    Waiting For Device: 2:/
    USB2 PLL running
     reset waited 6
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 20004000
    periodictable = 20004000
    port change: 10001803
        connect
      begin reset
    port change: 18001205
      port enabled
      end recovery
    new_Device: 480 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 10 02 00 00 00 40 75 1F 11 06 06 00 04 05 06 01 
        VendorID = 1F75, ProductID = 0611, Version = 0006
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    enumeration:
    Manufacturer:  
    
    doesn't want to copy rest

  20. #45
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    @mjs513 and @wwatson and others...

    Wonder if your 1GB is hanging the same way as my 1GB...

    Note: I have additional debug stuff turned on:
    Code:
    void msController::new_dataOut(const Transfer_t *transfer)
    {
    	uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF);
    	println("msController dataOut (static)", len, DEC);
    	print_hexbytes((uint8_t*)transfer->buffer, (len < 32)? len : 32 );
    	msOutCompleted = true; // Last out transaction is completed.
    }
    
    void msController::new_dataIn(const Transfer_t *transfer)
    {
    	uint32_t len = transfer->length - ((transfer->qtd.token >> 16) & 0x7FFF);
    	println("msController dataIn (static): ", len, DEC);
    	print_hexbytes((uint8_t*)transfer->buffer, (len < 32)? len : 32 );
    	if (len >= 4) {
    		uint32_t l = *(uint32_t*)transfer->buffer;
    		if (l == CBWSIGNATURE) println("** CBWSIGNATURE");
    		else if (l == CSWSIGNATURE) println("** CSWSIGNATURE");
    		else println("** ????");
    	}
    
    
    	msInCompleted = true; // Last in transaction is completed.
    }
    With this you can see all of the input and output stuff going on. And in my case it was hanging in the loop for media available (WaitMeidaReady)

    Yesterday I was playing iwth the WaitMediaReady to maybe call msRequestSense if the mediaAvailable call fails... To maybe see what the failure codes are...
    Comments embeded ()
    Code:
    (Here we ask for the media ready)
    msController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)31
    55 53 42 43 35 00 00 00 00 00 00 00 80 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    
    
    (Response - ends with 01 - fail)
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 35 00 00 00 00 00 00 00 01 
    ** CSWSIGNATURE
    
    (Now ask for request sense)
    msController CallbackOut (static)
    transfer->qtd.token = 1
    msController dataOut (static)31
    55 53 42 43 36 00 00 00 12 00 00 00 80 00 06 03 00 00 00 12 00 00 00 00 00 00 00 00 00 00 00 
    msController CallbackIn (static)
    transfer->qtd.token = 0
    
    (response of sense)
    msController dataIn (static): 18
    70 00 02 00 00 00 00 0A 00 00 00 00 3A 00 00 00 00 00 
    ** ????
    msDoCommand after msOutCompleted loop
    msDoCommand after msInCompleted loop
    msController CallbackIn (static)
    transfer->qtd.token = 0
    msController dataIn (static): 13
    55 53 42 53 36 00 00 00 00 00 00 00 00 
    ** CSWSIGNATURE
    (I had the waitMedia also dump out the response)...
    WaitMediaReady RSP:70 00 02 00 00 00 00 0A 00 00 00 00 3A 00 
    
    .... Repeats for ever or until I unplug
    Now to look up what the response codes are...

  21. #46
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,213
    @KurtE
    Not even getting that far - hanging before that on endpoints (BTW - Hot swapping works)
    Code:
    Test Drive Inquiry with uSDFS
    Waiting For Device: 2:/
    USB2 PLL running
     reset waited 6
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 20004000
    periodictable = 20004000
    port change: 10001803
        connect
      begin reset
    port change: 18001205
      port enabled
      end recovery
    new_Device: 480 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 00 02 00 00 00 40 07 13 63 01 00 01 01 02 03 01 
        VendorID = 1307, ProductID = 0163, Version = 0100
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    enumeration:
    Manufacturer: USB 2.0
    enumeration:
    Product: Flash Disk
    enumeration:
    Serial Number: 0ee644744fd53c
    enumeration:
    Config data length = 39
    enumeration:
    Configuration Descriptor:
      09 02 27 00 01 01 00 80 28 
        NumInterfaces = 1
        ConfigurationValue = 1
      09 04 00 00 03 08 06 50 00 
        Interface = 0
        Number of endpoints = 3
        Class/Subclass/Protocol = 8(Mass Storage) / 6(SCSI) / 80(Bulk Only)
      07 05 01 02 00 02 01 
        Endpoint = 1 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 1
      07 05 82 02 00 02 01 
        Endpoint = 2 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 1
      07 05 83 03 40 00 08 
        Endpoint = 3 IN
        Type = Interrupt
        Max Size = 64
        Polling Interval = 8
    enumeration:
    msController claim this=20002F00
    Descriptor 4 = INTERFACE
    msController claim this=20002F00
    09 04 00 00 03 08 06 50 00 07 05 01 02 00 02 01 07 05 82 02 00 02 01 07 05 83 03 40 00 08 
    endpointType = 2
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT
    Descriptor 5 = ENDPOINT
    
    DIES AT THIS POINT
    Either that or I am editing the wrong file? (masstoragedriver.cpp)

  22. #47
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    Actually sort of interesting. In particular this one shows 3 end points (The others show 2)
    Code:
      07 05 01 02 00 02 01 
        Endpoint = 1 OUT
        Type = Bulk
        Max Size = 512
        Polling Interval = 1
      07 05 82 02 00 02 01 
        Endpoint = 2 IN
        Type = Bulk
        Max Size = 512
        Polling Interval = 1
      07 05 83 03 40 00 08 
        Endpoint = 3 IN
        Type = Interrupt
        Max Size = 64
        Polling Interval = 8
    If you look at: bool msController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)

    It is assuming that first end point is In and the second endpoint is out, which in this case is reversed, so then the code:
    Code:
    if ((endpointIn & 0xF0) != 0x80) return false; // must be IN direction
    	if ((endpointOut & 0xF0) != 0x00) return false; // must be OUT direction
    Will fail and it won't claim the device...

    The code probably needs to walk the number of end points, and find the IN and the OUT. (The 80 bit).
    The Joystick claim code I believe has the stuff to walk through the endpoints to find the ones it want's ...

  23. #48
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,213
    @KurtE

    I noticed that it was showing 3 endpoints which was kind of strange, like you said.
    The Joystick claim code I believe has the stuff to walk through the endpoints to find the ones it want's ...
    hope its portable enough to transfer.

  24. #49
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    Quote Originally Posted by mjs513 View Post
    @KurtE

    I noticed that it was showing 3 endpoints which was kind of strange, like you said. hope its portable enough to transfer.
    Should be easy enough: Just setup index to first endpoint in buffer set index or like for IN/OUT endpoints in code to something like 0xff , increment by the size (7), and then check the end point, if it is a Bulk OUTPUT, remember it's index (OUT), and if it is input bulk remember it's index... If we ran through all of the end points and either of them is still 0xff then error...

    Then change code that used fixed index for fields of it to use saved index plus offset...
    Things like: uint32_t sizeIn = descriptors[13] | (descriptors[14] << 8);

    would look more like: uint32_t sizeIn = descriptors[in_endpoint_offset+4] | (descriptors[in_endpoint_offset+5] << 8);
    Depending on what you save as the index...

    EDIT: Should I take a crack at it?

  25. #50
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,583
    @mjs513 and @wwatson - follow on to previous post... Maybe something like:
    Code:
    bool msController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
    {
    	println("msController claim this=", (uint32_t)this, HEX);
    	// only claim at interface level
    
    	if (type != 1) return false;
    	if (len < 9+7+7) return false; // Interface descriptor + 2 endpoint decriptors 
    
    	print_hexbytes(descriptors, len);
    
    	uint32_t numendpoint = descriptors[4];
    	if (numendpoint < 1) return false; 
    	if (descriptors[5] != 8) return false; // bInterfaceClass, 8 = MASS Storage class
    	if (descriptors[6] != 6) return false; // bInterfaceSubClass, 6 = SCSI transparent command set (SCSI Standards)
    	if (descriptors[7] != 80) return false; // bInterfaceProtocol, 80 = BULK-ONLY TRANSPORT
    #if 1
    	uint8_t desc_index = 9;
    	uint8_t in_index = 0xff, out_index = 0xff;
    
    	println("numendpoint=", numendpoint, HEX);
    	while (numendpoint--) {
    		if ((descriptors[desc_index] != 7) || (descriptors[desc_index+1] != 5)) return false; // not an end point
    		if (descriptors[desc_index+3] == 2) {  // Bulk end point
    			if (descriptors[desc_index+2] & 0x80)
    				in_index = desc_index;
    			else
    				out_index = desc_index;
    		}
    		desc_index += 7;	// point to next one...
    	}
    	if ((in_index == 0xff) || (out_index == 0xff)) return false;	// did not find end point
    	endpointIn = descriptors[in_index+2]; // bulk-in descriptor 1 81h
    	endpointOut = descriptors[out_index+2]; // bulk-out descriptor 2 02h
    
    	println("endpointIn=", endpointIn, HEX);
    	println("endpointOut=", endpointOut, HEX);
    
    	uint32_t sizeIn = descriptors[in_index+4] | (descriptors[in_index+5] << 8);
    	println("packet size in (msController) = ", sizeIn);
    
    	uint32_t sizeOut = descriptors[out_index+4] | (descriptors[out_index+5] << 8);
    	println("packet size out (msController) = ", sizeOut);
    	packetSizeIn = sizeIn;	
    	packetSizeOut = sizeOut;	
    
    	uint32_t intervalIn = descriptors[in_index+6];
    	uint32_t intervalOut = descriptors[out_index+6];
    
    	println("polling intervalIn = ", intervalIn);
    	println("polling intervalOut = ", intervalOut);
    	datapipeIn = new_Pipe(dev, 2, endpointIn, 1, packetSizeIn, intervalIn);
    	datapipeOut = new_Pipe(dev, 2, endpointOut, 0, packetSizeOut, intervalOut);
    #else	
    
    	if (descriptors[10] != 5 || descriptors[17] != 5) return false; // Must have bulk-in and bulk-out endpoints
    
    	uint8_t endpointType = (descriptors[12] | descriptors[19]) & 0x03; 
    	println("endpointType = ",endpointType);
    	endpointIn = descriptors[11]; // bulk-in descriptor 1 81h
    	endpointOut = descriptors[18]; // bulk-out descriptor 2 02h
    
    	if ((endpointIn & 0xF0) != 0x80) return false; // must be IN direction
    	if ((endpointOut & 0xF0) != 0x00) return false; // must be OUT direction
    	println("numendpoint=", numendpoint, HEX);
    	println("endpointIn=", endpointIn, HEX);
    	println("endpointOut=", endpointOut, HEX);
    
    	uint32_t sizeIn = descriptors[13] | (descriptors[14] << 8);
    	println("packet size in (msController) = ", sizeIn);
    
    	uint32_t sizeOut = descriptors[20] | (descriptors[21] << 8);
    	println("packet size out (msController) = ", sizeOut);
    	packetSizeIn = sizeIn;	
    	packetSizeOut = sizeOut;	
    
    	uint32_t intervalIn = descriptors[15];
    	uint32_t intervalOut = descriptors[22];
    
    	println("polling intervalIn = ", intervalIn);
    	println("polling intervalOut = ", intervalOut);
    	datapipeIn = new_Pipe(dev, 2, endpointIn, 1, packetSizeIn, intervalIn);
    	datapipeOut = new_Pipe(dev, 2, endpointOut, 0, packetSizeOut, intervalOut);
    #endif
    	datapipeIn->callback_function = callbackIn;
    	datapipeOut->callback_function = callbackOut;
    
    	msOutCompleted = false;
    	msInCompleted = false;
    	deviceAvailable = true;
    	return true;
    }
    I may not be printing out everything here as before, but most of it...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •