Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: bInterval values for BULK-IN and BULK-OUT Decriptors

  1. #1
    Junior Member
    Join Date
    Aug 2017
    Posts
    12

    bInterval values for BULK-IN and BULK-OUT Decriptors

    Hi,

    I am working on a USB Mass Storage Bulk Only driver for a SanDisk 8gb cruzer flash drive. This is the descriptor dump for it.

    BULK-ONLY Data Interface | Bulk-In Endpoint | Bulk-Out Endpoint
    09 04 00 00 02 08 06 50 00 | 07 05 81 02 00 02 00 | 07 05 02 02 00 02 01

    Bulk transfer intervals are not used. But in the Bulk-Out Endpoint it is showing 01h. Is this ignored during a transfer or should it be set to 00h.

    Thanks

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,338
    For 12 MBit/sec speed, the bInterval ignored.

    At 480 Mbit/sec, it's supposed to specify the maximum number of NAK responses per 125 us microframe, or zero if the endpoint isn't supposed to respond with NAK tokens.

    Details are on page 271 of the USB 2.0 spec.

  3. #3
    Junior Member
    Join Date
    Aug 2017
    Posts
    12
    Hi all,

    I have been working on a Mass Storage driver for the Teensy 3.6. it is in a usable state but there are a couple of issues I can't seem to resolve.

    First issue:
    When reading and dumping multiple sectors using Serial.printf() I get what seem to be incomplete Command Status Wrapper (CSW) errors.
    The CSW should return the tag number of the Command Block Wrapper (CBW) and the status byte of zero if no error has happened or an error
    code if there was an error. When it fails I get a CSW with zero in the tag field and zero in the status field. The signature field is correct. This leads
    me to think the 'IN' transfer was cut off before it was complete. This also happens more with USB external hard drives than with USB thumb or
    flash drives. It does not fail when not doing a hex dump. Writing to sectors has not failed.

    Examples of good read with no hexdump:
    Code:
    USB Mass Storage Testing
    
    Waiting for device to become available.
    
    msReset()
    
    msGetMaxLun(): 0
    
    msDeviceInquiry()
    Passed
    BYTE      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
    ---------------------------------------------------------
    0000      00 00 04 02 33 00 20 00 4d 61 78 74 6f 72 20 20   ....3. .Maxtor  
    0010      4f 6e 65 54 6f 75 63 68 20 20 20 20 20 20 20 20   OneTouch        
    0020      30 31 32 35 00 00 00 00 00 00 00 00 00 00 00 00   0125............
    Removable Device: NO
    VendorID: Maxtor  
    ProductID: OneTouch        
    RevisionID: 0125
    
    msReadDeviceCapacity()
    Passed
    Number of sectors = 488397167
    Sector size = 512
    
    msReadBlocks(): Took 11ms to read 4 sectors
    4 Sectors Read.
    Done...
    Examples of read fail with hexdump:
    Code:
    USB Mass Storage Testing
    
    Waiting for device to become available.
    
    msReset()
    
    msGetMaxLun(): 0
    
    msDeviceInquiry()
    Passed
    BYTE      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
    ---------------------------------------------------------
    0000      00 00 04 02 33 00 20 00 4d 61 78 74 6f 72 20 20   ....3. .Maxtor  
    0010      4f 6e 65 54 6f 75 63 68 20 20 20 20 20 20 20 20   OneTouch        
    0020      30 31 32 35 00 00 00 00 00 00 00 00 00 00 00 00   0125............
    Removable Device: NO
    VendorID: Maxtor  
    ProductID: OneTouch        
    RevisionID: 0125
    
    msReadDeviceCapacity()
    Passed
    Number of sectors = 488397167
    Sector size = 512
    
    msReadBlocks(): 
    BYTE      00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
    ---------------------------------------------------------
    0000      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0010      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0020      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0030      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0040      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0050      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0060      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0070      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0080      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0090      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00a0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00b0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00c0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00d0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00e0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    00f0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0100      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0110      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0120      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0130      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0140      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0150      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0160      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0170      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0180      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    0190      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    01a0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    01b0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    01c0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    01d0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    01e0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    01f0      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
    Failed: 3
    Code 3 is CSW tag error. Did not return the CBW tag. It returned a zero. The CSW status code is always zero as well.

    Second issue:
    Code:
    //---------------------------------------------------------------------------
    // Get Command Status Wrapper
    //---------------------------------------------------------------------------
    uint8_t msController::msGetCSW() {
    	uint8_t CSWResult = 0;
    	msCommandStatusWrapper_t CSW = (msCommandStatusWrapper_t)
    	{
    		.Signature = CSWSIGNATURE,
    		.Tag = 0,
    		.DataResidue = 0,
    		.Status = 0
    	};
    	queue_Data_Transfer(datapipeIn, &CSW, sizeof(CSW), this);
    	while(!msInCompleted){
    delay(0); // Why is this delay needed??
    //TODO: Do a timeout check.
    	}
    	msInCompleted = false;
    	print("CommandStatusWrapper: ");
    	print_hexbytes(&CSW, sizeof(CSW));
    	CSWResult = checkCSW(&CSW);
    	if(CSWResult) {
    		return CSWResult;
    	}
    	return CSW.Status;
    }
    I am expecting 'msInCompleted' to signal that the transfer is complete but without the delay it fails?

    Other than these problems the driver works well. I am using it with several programs including a structured BASIC.
    Attached Files Attached Files

  4. #4
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,653
    As for the delay(0) - Not sure?
    A delay of 0 more or less does nothing, other than do the call, which then calls micros...
    Code:
    void delay(uint32_t ms)
    {
    	uint32_t start = micros();
    
    	if (ms > 0) {
    		while (1) {
    			while ((micros() - start) >= 1000) {
    				ms--;
    				if (ms == 0) return;
    				start += 1000;
    			}
    			yield();
    		}
    	}
    }
    I was going to suggest that maybe it was calling yield(), but without looking through your zip file I wonder if
    msInCompleted is marked as volatile?

  5. #5
    Junior Member
    Join Date
    Aug 2017
    Posts
    12
    Kurt,

    The msInCompleted flag is not marked volatile. I tried the delay() function without yield(). No change. If I use a delay of 1 I get the same results. if I use a delay of 6 or more I get the same results a using 0 as a delay value.
    When the data in endpoint transfer completes it calls the data in callback member. This is where I set the msInCompleted flag to true. The token IOC flag is set. But when the transfer fails The Command Status Wrapper is
    incomplete. Because the status flag indicates no error and the tag numbers do not match in the the Command Block Wrapper and Command Status Wrapper I seems like I am cutting the IN transfer short. Maybe.
    I remember a situation with the Teensy 3.6 VGA driver that caused flickering of the display when Serial.print was used. It was improved by using serial ports that have a FIFO. Something to do with the interrupts. I am going
    to try the test program with a TFT display and see what the results are. I also noticed that the problem is more pronounced with an external USB hard drive than with a USB thumb drive.

Posting Permissions

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