chipKIT® Development Platform

Inspired by Arduino™

USB MSD Host Library

Created Thu, 08 Mar 2012 00:29:23 +0000 by MarkHoskins


MarkHoskins

Thu, 08 Mar 2012 00:29:23 +0000

I am currently using the USB MSD Host with MDDFS to write files to a USB Pen Drive.

I've got my application up and running, and everything seems to work ( does a bit more than usb writing ), and am currently looking for ways to improve performance.

I've found that the USB file transfer speed tops out at about 75KB/s. It's not TOO slow, I mean I can live with it. But I expect a much higher transfer rate.

Here's my example code:

#include <chipKITUSBHost.h>
#include <chipKITUSBMSDHost.h>
#include <chipKITMDDFS.h>

/************************************************************************/
/*									*/
/*	USBHIDHost.pde	-- USB HID Mouse HOST Sketch example            */
/*									*/
/************************************************************************/
/*	Author: 	Keith Vogel 					*/
/*	Copyright 2011, Digilent Inc.					*/
/************************************************************************/
/*
  This sketch is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This sketch is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
/************************************************************************/
/*  Module Description: 						*/
/*  A demonstration of a thumb drive MSD USB Host device      		*/
/*	After inserting a thumb drive into the USB Host Port            */
/*  wait about 30 seconds and a file named TEST.TXT                     */
/*	should be written on the Thumb drive with			*/
/*	the contents of							*/
/*	"This is a test."						*/
/************************************************************************/
/*  Revision History:							*/
/*									*/
/*	9/07/2011(KeithV): Created					*/
/*									*/
/************************************************************************/

//******************************************************************************
//******************************************************************************
// Global Variables
//******************************************************************************
//******************************************************************************

FSFILE * myFile;
uint8_t myData[1024];
size_t numBytes;
BOOL deviceAttached = FALSE;

//******************************************************************************
//******************************************************************************
// USB Support Functions
//******************************************************************************
//******************************************************************************

/****************************************************************************
  Function:
    BOOL MyMSDEventHandler( uint8_t address, USB_EVENT event, void *data, DWORD size )

  Description:
    Handles all of the events for the HID device

  Precondition:
    None

  Parameters:
        address  Address of the USB device generating the event  
        event  Event that occurred  
        data  Optional pointer to data for the event  
        size  Size of the data pointed to by *data  

  Return Values:
    True if handled, false otherwise

  Remarks:
    We call the default one here so things like VBUS is automatically handled.

***************************************************************************/
BOOL MyMSDEventHandler( uint8_t address, USB_EVENT event, void *data, DWORD size )
{
    BOOL fRet = FALSE;

    // call the default handler for common host controller stuff
    fRet = USBHost.DefaultEventHandler(address, event, data, size);

    switch( event )
    {
        case EVENT_VBUS_RELEASE_POWER:

            //This means that the device was removed
            // this will get us out of the while loop
            // and start looking for a new thumb drive to be
            // plugged in.
            deviceAttached = FALSE;
            return TRUE;
            break;

        default:
            break;
    }

    return(fRet);
}

/****************************************************************************
  Function:
    void RunUSBTasks(void)

  Description:
    Runs periodic tasks to keep the USB stack alive and well

  Precondition:
    None

  Parameters:
    None
  Return Values:
    None

  Remarks:
    Call this at least once through the loop, or when we want the 
    USB Host controller to update itself internally

***************************************************************************/
void RunUSBTasks(void)
{
    USBHost.Tasks();
    USBMSDHost.Tasks();
}

//******************************************************************************
//******************************************************************************
// Required Sketch functions
//******************************************************************************
//******************************************************************************
void setup() {
  // put your setup code here, to run once:

    // initialize the USB HOST controller
    USBHost.Begin(MyMSDEventHandler);
    Serial.begin( 9600 );
}

void loop() {
  // put your main code here, to run repeatedly: 
  
    //USB stack process function
    RunUSBTasks();

    //if thumbdrive is plugged in
    if(USBMSDHost.SCSIMediaDetect())
    {
        deviceAttached = TRUE;

        //now a device is attached
        //See if the device is attached and in the right format
        if(MDDFS.Init())
        {
            //Opening a file in mode "w" will create the file if it doesn't
            //  exist.  If the file does exist it will delete the old file
            //  and create a new one that is blank.
            myFile = MDDFS.fopen("test.txt","w");

            //Write some data to the new file.
            while( true )
            {
              uint32_t iStartTime = millis();
              MDDFS.fwrite(myData,1024,1,myFile);
              //MDDFS.flush( myFile );
              //MDDFS.fwrite(myData,1,256,myFile);
              //MDDFS.fwrite(myData,1,256,myFile);
              //MDDFS.fwrite(myData,1,256,myFile);
              Serial.println( millis() - iStartTime );
            }
                
            //Always make sure to close the file so that the data gets
            //  written to the drive.
            MDDFS.fclose(myFile);

            //Just sit here until the device is removed.
            while(deviceAttached == TRUE)
            {
                RunUSBTasks();
            }
        }
    }   
}

I found it interesting that the following topic seems to indicate a topping out of the throughput at 75KB/s as well. http://www.chipkit.org/forum/viewtopic.php?f=7&t=503

However, since I'm using a library instead of doing manual transfers, I don't expect such a limitation to be present in the library itself.

Is there something I can do to increase my USB throughput using MDDFS?


MarkHoskins

Fri, 09 Mar 2012 21:51:38 +0000

Things I've done:

Converted the library to use FatFS. This increased the throughput to about 87 KB/s. ( Also allowed me to use normal file names, rather than 8.3, which is a nice feature ).

Changed the code to accumulate 16 KB buffers and transfer them all at once. Reduced bit rate to about 64 KB/s, so I don't think this is the problem.

I've read all over people getting higher throughput out of these PIC processors, so I don't know what's going on here.