Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
iva2k
Date:
Thu Jan 21 01:15:42 2010 +0000
Commit message:

Changed in this revision

Fat/usbhost_fat.c Show annotated file Show diff for this revision Revisions of this file
Fat/usbhost_fat.h Show annotated file Show diff for this revision Revisions of this file
Host/usbhost_lpc17xx.c Show annotated file Show diff for this revision Revisions of this file
Host/usbhost_lpc17xx.h Show annotated file Show diff for this revision Revisions of this file
Include/usbhost_cpu.h Show annotated file Show diff for this revision Revisions of this file
Include/usbhost_err.h Show annotated file Show diff for this revision Revisions of this file
Include/usbhost_inc.h Show annotated file Show diff for this revision Revisions of this file
MassStorage/usbhost_ms.c Show annotated file Show diff for this revision Revisions of this file
MassStorage/usbhost_ms.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Fat/usbhost_fat.c	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,1043 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_fat.c
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+/*
+**************************************************************************************************************
+*                                           INCLUDE HEADER FILES
+**************************************************************************************************************
+*/
+
+#include  "usbhost_fat.h"
+
+/*
+**************************************************************************************************************
+*                                              GLOBAL VARIABLES
+**************************************************************************************************************
+*/
+
+#define MAX_FILE_DESCRIPTORS 2
+static  BOOT_SEC    FAT_BootSec;
+static  FILE_ENTRY  FAT_FileEntry[MAX_FILE_DESCRIPTORS];
+
+/*
+**************************************************************************************************************
+*                                         INITIALIZE THE FILE SYSTEM
+*
+* Description: This function initializes the FAT16 file system
+*
+* Arguments  : None
+*
+* Returns    : OK		              if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  FAT_Init (void)
+{
+    USB_INT16U  boot_sig;
+    USB_INT32S  rc, i;
+    FILE_ENTRY	*entry;
+
+    for (i=0;i<MAX_FILE_DESCRIPTORS;i++) {
+    	entry = &FAT_FileEntry[i];
+        entry->CurrClus       = 0;
+        entry->CurrClusOffset = 0;
+        entry->FileSize       = 0;
+        entry->EntrySec       = 0;
+        entry->EntrySecOffset = 0;
+        entry->FileStatus     = 0;
+    }
+
+    MS_BulkRecv(0, 1, FATBuffer);
+    boot_sig = ReadLE16U(&FATBuffer[510]);
+    if (boot_sig != 0xAA55) {
+        rc = ERR_INVALID_BOOT_SIG;
+    } else {
+        if (FATBuffer[0] != 0xEB && FATBuffer[0] != 0xE9) {
+            FAT_BootSec.BootSecOffset = ReadLE32U(&FATBuffer[454]);
+            MS_BulkRecv(FAT_BootSec.BootSecOffset, 1, FATBuffer);
+        }
+        FAT_BootSec.BytsPerSec      = ReadLE16U(&FATBuffer[11]);          /* Bytes per cluster              */
+        FAT_BootSec.SecPerClus      = FATBuffer[13];                      /* Sectors per cluster            */
+                                                                          /* Reserved sector count          */
+        FAT_BootSec.RsvdSecCnt      = ReadLE16U(&FATBuffer[14]) + FAT_BootSec.BootSecOffset;
+        FAT_BootSec.NumFATs         = FATBuffer[16];                      /* Number of FAT copies           */
+        FAT_BootSec.RootEntCnt      = ReadLE16U(&FATBuffer[17]);          /* Root entry count               */
+        FAT_BootSec.TotSec16        = ReadLE16U(&FATBuffer[19]);          /* Total FAT16 sectors            */
+        FAT_BootSec.TotSec32        = ReadLE32U(&FATBuffer[32]);          /* Total FAT32 sectors            */
+        FAT_BootSec.FATSz16         = ReadLE16U(&FATBuffer[22]);          /* Size of the FAT table          */
+                                                                          /* Bytes per cluster              */
+        FAT_BootSec.BytsPerClus     = (FAT_BootSec.BytsPerSec * FAT_BootSec.SecPerClus);
+                                                                          /* Root directory starting sector */
+        FAT_BootSec.RootDirStartSec = FAT_BootSec.RsvdSecCnt + (FAT_BootSec.FATSz16 * FAT_BootSec.NumFATs);
+                                                                      /* Sectors occupied by root directory */
+        FAT_BootSec.RootDirSec      = ((FAT_BootSec.RootEntCnt * 32) + (FAT_BootSec.BytsPerSec - 1)) /
+                                       (FAT_BootSec.BytsPerSec);
+                                                                          /* First data sector              */
+        FAT_BootSec.FirstDataSec    = FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec;
+        FAT_BootSec.FATType         = FAT_GetFATType();                   /* Type of FAT                    */
+        if (FAT_BootSec.FATType == FAT_16) {
+            rc = OK;
+        } else {
+            rc = ERR_FAT_NOT_SUPPORTED;
+            PRINT_Err(rc);
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                         GET FILE SYSTEM TYPE
+*
+* Description: This function returns the file system type with which the disk is formatted
+*
+* Arguments  : None
+*
+* Returns    : FAT16           On Success
+*              ERR_FAT_TYPE    On Failure
+*
+**************************************************************************************************************
+*/
+
+USB_INT08U  FAT_GetFATType (void)
+{
+    USB_INT08U  fat_type;
+    USB_INT32U  tot_sec;
+    USB_INT32U  tot_data_clus;
+
+
+    if (FAT_BootSec.TotSec16 != 0) {                             /* Get total sectors in the disk           */
+        tot_sec = FAT_BootSec.TotSec16;
+    } else {
+        tot_sec = FAT_BootSec.TotSec32;
+    }
+
+    tot_data_clus = tot_sec / (FAT_BootSec.SecPerClus);          /* Get total data clusters in the disk     */
+                                                                 /* If total data clusters >= 4085 and      */
+                                                                 /* < 65525, then it is FAT16 file system   */
+    if (tot_data_clus >= 4085 && tot_data_clus < 65525) {
+        fat_type = FAT_16;
+    } else {
+        fat_type = 0;
+    }
+
+    return (fat_type);
+}
+
+/*
+**************************************************************************************************************
+*                                                OPENING A FILE
+*
+* Description: This function stores the attributes of a file, such as starting cluster, file size, 
+*              sector where the file entry is stored and offset of the entry in that sector
+*
+* Arguments  : file_name    Name of the file. The file must be in root directory.
+*
+* Returns    : pointer to the entry    On Success
+*              NULL                    On Failure
+* 
+* Modifed 6/9/08 WCB returns a file descriptor which is the INDEX+1 to the entry.
+* returning the entry address itself could be interpreted as a negative number --
+* and thus an error -- for memory locations of 0x80000000 and above.  We return
+* INDEX+1 instead of just the index to avoid returning a file descriptor of zero,
+* which could be potentially confused with an error.
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  FILE_Open (USB_INT08U  *file_name,
+                       USB_INT08U   flags)
+{
+    USB_INT32S   rc;
+    FILE_ENTRY  *entry = 0;
+    USB_INT32S  fd = -1;
+
+    do {
+    	if (FAT_FileEntry[++fd].FileStatus == 0)
+    		entry = &FAT_FileEntry[fd];
+    } while ((entry == 0) && (fd < MAX_FILE_DESCRIPTORS-1));
+    if (entry == 0) {
+        return (ERR_OPEN_LIMIT_REACHED);
+    }
+    if (flags == RDONLY) {                       /* Search for a file. If it doesn't exist, don't create it */
+        rc = FAT_FindEntry(file_name, entry);
+        if (rc == MATCH_FOUND) {
+            entry->FileStatus = 1;
+            rc = fd+1;
+        }
+    } else {                                     /* Search for a file. If it doesn't exist, create it       */
+        rc = FAT_CreateEntry(file_name, entry);
+        if (rc == MATCH_FOUND) {
+            entry->FileStatus = 1;
+            rc = fd+1;
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                                 FINDING AN ENTRY
+*
+* Description: This function searches for a file name in the root directory
+*
+* Arguments  : ent_name_given    Pointer to the file name to be searched.
+*              entry             Pointer to the entry structure. The attributes of the file are stored in this
+*                                structure if the file was found in the root directory.
+*
+* Returns    : MATCH_FOUND       if the file was found in the root directory.
+*              MATCH_NOT_FOUND   if the file was not found in the root directory.
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  FAT_FindEntry (USB_INT08U  *ent_name_given,
+                           FILE_ENTRY  *entry)
+{
+              USB_INT32U   sec_num;
+    volatile  USB_INT08U  *buf;
+              USB_INT08U   ent_type;
+              USB_INT08U   ent_name_read[13];
+
+
+    for (sec_num = FAT_BootSec.RootDirStartSec;              /* For all the sectors in root directory       */
+         sec_num < (FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec);
+         sec_num++) {
+           
+
+        MS_BulkRecv(sec_num, 1, FATBuffer);                  /* Read one sector                             */
+        buf = FATBuffer;
+        while (buf < (FATBuffer + FAT_BootSec.BytsPerSec)) {
+            ent_type = FAT_ChkEntType(buf);                  /* Check for the entry type                    */
+            if (ent_type == SFN_ENTRY) {                     /* If it is short entry get short file name    */
+                FAT_GetSFN(buf, ent_name_read);
+                                                    /* Compare given name with this name case insensitively */
+                if (FAT_StrCaseCmp(ent_name_given, ent_name_read) == MATCH_FOUND) {
+                    entry->CurrClus = ReadLE16U(&buf[26]);   /* If they are same, get starting cluster      */
+                    entry->FileSize  = ReadLE32U(&buf[28]);  /* Get file size                               */
+                    entry->EntrySec = sec_num;           /* Get sector number where the filename is located */
+                                                 /* Get offset in this sector where the filename is located */
+                    entry->EntrySecOffset = buf - FATBuffer;
+                    return (MATCH_FOUND);
+                }
+            }
+            if (ent_type == LAST_ENTRY) {    /* If it is the last entry, no more entries will exist. Return */
+                return (MATCH_NOT_FOUND);
+            }
+            buf = buf + 32;                                  /* Move to the next entry                      */
+        }
+    }
+    return (MATCH_NOT_FOUND);
+}
+
+/*
+**************************************************************************************************************
+*                                       GET SHORT FILE NAME AND EXTENSION OF A FILE
+*
+* Description: This function reads the short file name and extension corresponding to a file
+*
+* Arguments  : ent_buf    buffer which contains the 32 byte entry of a file
+*              name       buffer to store the file name and extension of a file
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  FAT_GetSFN (volatile  USB_INT08U  *entry,
+                            USB_INT08U  *name)
+{
+    USB_INT08U   ext[4];                          /* Buffer to store the extension of a file                */
+    USB_INT08U  *ext_ptr;
+
+
+    ext_ptr = ext;
+
+    FAT_GetSfnName(entry, name);                  /* Get file name into "name" buffer                       */
+    FAT_GetSfnExt(entry, ext_ptr);                /* Get extension into "ext" buffer                        */
+
+    while (*name) {                               /* Goto the end of the filename                           */
+        name++;
+    }
+    if (*ext_ptr) {                               /* If the extension exists, put a '.' charecter           */
+        *name = '.';
+        name++;
+    }
+    while (*ext_ptr) {                            /* Append the extension to the file name                  */
+        *name = *ext_ptr;
+        name++;
+        ext_ptr++;
+    }
+    *name = '\0';
+}
+
+/*
+**************************************************************************************************************
+*                                          GET SHORT FILE NAME OF A FILE
+*
+* Description: This function reads the short file name of a file
+*
+* Arguments  : ent_buf  buffer which contains the 32 byte entry of a file
+*              name     buffer to store the short file name of a file
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  FAT_GetSfnName (volatile  USB_INT08U  *entry,
+                                USB_INT08U  *name)
+{
+    USB_INT32U  cnt;
+
+
+    cnt = 0;
+    while (cnt < 8) {
+        *name = *entry;                     /* Get first 8 charecters of an SFN entry                       */
+        name++;
+        entry++;
+        cnt++;
+    }
+    *name = 0;
+    name--;
+    while (*name == 0x20) {                 /* If any spaces exist after the file name, replace them with 0 */
+        *name = 0;
+        name--;
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                       GET EXTENSION OF A FILE
+*
+* Description: This function reads the extension of a file
+*
+* Arguments  : ent_buf    buffer which contains the 32 byte entry of a file
+*              ext_ptr    buffer to store the extension of a file       
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  FAT_GetSfnExt (volatile  USB_INT08U  *entry,
+                               USB_INT08U  *ext_ptr)
+{
+    USB_INT32U  cnt;
+
+
+    cnt = 0;
+    while (cnt < 8) {                  /* Goto the beginning of the file extension                          */
+        entry++;
+        cnt++;
+    }
+    cnt = 0;
+    while (cnt < 3) {                  /* Get 3 charecters from there                                       */
+        *ext_ptr = *entry;
+        ext_ptr++;
+        entry++;
+        cnt++;
+    }
+    *ext_ptr = 0;
+    ext_ptr--;
+    while (*ext_ptr == ' ') {          /* If any spaces exist after the file extension, replace them with 0 */
+        *ext_ptr = 0;
+        ext_ptr--;
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                       CASE INSENSITIVE COMPARISION OF STRINGS
+*
+* Description: This function compares two strings case insensitively
+*
+* Arguments  : str1               Pointer to the first string
+*              str2               Pointer to the second string
+*
+* Returns    : MATCH_FOUND        if both the strings are same
+*              NATCH_NOT_FOUND    if both the strings are different
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  FAT_StrCaseCmp (USB_INT08U  *str1,
+                            USB_INT08U  *str2)
+{
+    while (*str1 && *str2) {
+        if (*str1 == *str2 || *str1 == (*str2 + 32) || *str1 == (*str2 - 32)) {
+            str1++;
+            str2++;
+            continue;
+        } else {
+            return (MATCH_NOT_FOUND);
+        }
+    }
+    if (*str1 == 0 && *str2 == 0) {
+        return (MATCH_FOUND);
+    } else {
+        return (MATCH_NOT_FOUND);
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                       CHECK TYPE OF THE ENTRY
+*
+* Description: This function checks the type of file entry.
+*
+* Arguments  : ent           Pointer to the buffer containing the entry
+*
+* Returns    : LAST_ENTRY    if the entry is last entry
+*              FREE_ENTRY    if the entry is free entry
+*              LFN_ENTRY     if the entry is long file name entry
+*              SFN_ENTRY     if the entry is short file name entry
+*
+**************************************************************************************************************
+*/
+
+USB_INT32U  FAT_ChkEntType (volatile  USB_INT08U  *ent)
+{
+    if (ent[0] == 0x00) {                              /* First byte is 0 means it is the last entry        */
+        return (LAST_ENTRY);
+    }
+
+    if (ent[0] == 0xE5) {                              /* First byte is 0xE5 means it is the free entry     */
+        return (FREE_ENTRY);
+    }
+
+    if (0x0F == ent[11]) {                             /* If 11th byte of an entry is 0x0F, it is LFN       */
+        return (LFN_ENTRY);
+
+    } else {
+        return (SFN_ENTRY);                            /* Else it is the SFN                                */
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                       READ DATA REQUESTED BY THE USER
+*
+* Description: This function reads data requested by the application from the file pointed by file descriptor.
+*
+* Arguments  : fd                  file descriptor that points to a file
+*              buffer              buffer into which the data is to be read
+*              num_bytes           number of bytes requested by the application
+*
+* Returns    : total_bytes_read    Total bytes actually read.
+*
+**************************************************************************************************************
+*/
+
+USB_INT32U  FILE_Read (          USB_INT32S  fd,
+                       volatile  USB_INT08U  *buffer,
+                                 USB_INT32U   num_bytes)
+{
+    USB_INT32U   total_bytes_to_read;            /* Total bytes requested by the application                */
+    USB_INT32U   total_bytes_read;               /* Total bytes read                                        */
+    USB_INT32U   bytes_read;                     /* Bytes read from one cluster                             */
+    USB_INT32U   bytes_to_read;                  /* Bytes to be read in one cluster                         */
+    FILE_ENTRY  *entry;                          /* Entry that contains the file attribute information      */
+    USB_INT16U   next_clus;                     /* Next cluster of the current cluster in the cluster chain */
+
+    entry = &FAT_FileEntry[fd-1];                /* Get file entry from file descriptor                     */
+    total_bytes_read = 0;
+
+    if (entry->FileSize == 0) {
+        return (0);
+    }
+    if (num_bytes < entry->FileSize) {
+        total_bytes_to_read = num_bytes;
+    } else {
+        total_bytes_to_read = entry->FileSize;
+    }
+    do {
+        next_clus = FAT_GetNextClus(entry->CurrClus);     /* Get next cluster                               */
+        if (next_clus == 0) {                             /* If the current cluster is the last cluster     */
+                                                          /* If the offset is at the end of the file        */
+            if (entry->CurrClusOffset == (entry->FileSize % FAT_BootSec.BytsPerClus)) {
+                return (0);                               /* No more bytes to read                          */
+            }                               /* If requested number is > remaining bytes in the last cluster */
+            if (total_bytes_to_read > ((entry->FileSize % FAT_BootSec.BytsPerClus) - entry->CurrClusOffset)) {
+                total_bytes_to_read = (entry->FileSize % FAT_BootSec.BytsPerClus) - entry->CurrClusOffset;
+            }
+            bytes_to_read = total_bytes_to_read;
+                                         /* If requested number is > remaining bytes in the current cluster */
+        } else if (total_bytes_to_read > (FAT_BootSec.BytsPerClus - entry->CurrClusOffset)) {
+            bytes_to_read = FAT_BootSec.BytsPerClus - entry->CurrClusOffset;
+        } else {
+            bytes_to_read = total_bytes_to_read;
+        }
+        bytes_read = FAT_ClusRead(entry->CurrClus,       /* Read bytes from a single cluster                */
+                                  entry->CurrClusOffset,
+                                  buffer,
+                                  bytes_to_read);
+        buffer              += bytes_read;
+        total_bytes_read    += bytes_read;
+        total_bytes_to_read -= bytes_read;
+                                             /* If the cluster offset reaches end of the cluster, make it 0 */
+        if (entry->CurrClusOffset + bytes_read == FAT_BootSec.BytsPerClus) {
+            entry->CurrClusOffset = 0;
+        } else {
+            entry->CurrClusOffset += bytes_read;        /* Else increment the cluster offset                */
+        }
+        if (entry->CurrClusOffset == 0) {
+            entry->CurrClus = (next_clus > 0) ? next_clus : entry->CurrClus;
+        }
+    } while (total_bytes_to_read);
+    return (total_bytes_read);
+}
+
+/*
+**************************************************************************************************************
+*                                                 READ FROM ONE CLUSTER
+*
+* Description: This function reads the data from a single cluster.
+*
+* Arguments  : curr_clus         Current cluster from which the data has to read
+*              clus_offset       Position in the current cluster from which the data has to read
+*              buffer            Buffer into which the data has to read
+*              num_bytes         Number of bytes to read
+*
+* Returns    : tot_bytes_read    Total bytes read from the current cluster
+*
+**************************************************************************************************************
+*/
+
+USB_INT32U  FAT_ClusRead (          USB_INT16U   curr_clus,
+                                    USB_INT32U   clus_offset,
+                          volatile  USB_INT08U  *buffer,
+                                    USB_INT32U   num_bytes)
+{
+    USB_INT32U  tot_bytes_read;                              /* total bytes read in the current cluster     */
+    USB_INT32U  n_bytes;                                     /* Bytes to read in the current sector         */
+    USB_INT32U  start_sec;                                   /* Starting sector of the current cluster      */
+    USB_INT32U  sec_num;                                     /*Current sector number                        */
+    USB_INT16U  num_sec;                                     /* Number of sectors to be read                */
+    USB_INT32U  sec_offset;                                  /* Offset in the current sector                */
+    USB_INT32U  cnt;
+
+
+    tot_bytes_read = 0;
+    start_sec  = ((curr_clus - 2) * FAT_BootSec.SecPerClus) + FAT_BootSec.FirstDataSec;
+    sec_num    = start_sec + (clus_offset / FAT_BootSec.BytsPerSec);
+    num_sec    = num_bytes / FAT_BootSec.BytsPerSec;
+    sec_offset = clus_offset % FAT_BootSec.BytsPerSec;
+
+    if (sec_offset) {                                 /* If the sector offset is at the middle of a sector  */
+        MS_BulkRecv(sec_num, 1, FATBuffer);           /* Read the first sector                              */
+        n_bytes = (FAT_BootSec.BytsPerSec - sec_offset <= num_bytes) ?
+                  (FAT_BootSec.BytsPerSec - sec_offset) : num_bytes;
+        for (cnt = sec_offset; cnt < sec_offset + n_bytes; cnt++) {
+            *buffer = FATBuffer[cnt];                 /* Copy the required bytes to user buffer             */
+             buffer++;
+        }
+        tot_bytes_read += n_bytes;
+        clus_offset    += n_bytes;
+        num_bytes      -= n_bytes;
+        sec_num++;
+    }
+
+    if (num_bytes / FAT_BootSec.BytsPerSec) {         /* Read all the remaining full sectors                */
+
+        num_sec = num_bytes / FAT_BootSec.BytsPerSec;
+        MS_BulkRecv(sec_num, num_sec, buffer);
+        buffer         += (num_sec * FAT_BootSec.BytsPerSec);
+        tot_bytes_read += (num_sec * FAT_BootSec.BytsPerSec);
+        clus_offset    += (num_sec * FAT_BootSec.BytsPerSec);
+        num_bytes      -= (num_sec * FAT_BootSec.BytsPerSec);
+        sec_num        += num_sec;
+    }
+
+    if (num_bytes) {                                  /* Read the last sector for the remaining bytes       */
+        MS_BulkRecv(sec_num, 1, FATBuffer);
+        for (cnt = 0; cnt < num_bytes; cnt++) {
+            *buffer = FATBuffer[cnt];                 /* Copy the required bytes to user buffer             */
+             buffer++;
+        }
+        tot_bytes_read += num_bytes;
+    }
+
+    return (tot_bytes_read);
+}
+
+/*
+**************************************************************************************************************
+*                                       WRITE THE DATA REQUESTED BY THE USER
+*
+* Description: This function writes data requested by the application to the file pointed by file descriptor
+*
+* Arguments  : fd                     file descriptor that points to a file
+*              buffer                 buffer from which the data is to be written
+*              num_bytes              number of bytes requested by the application
+*
+* Returns    : total_bytes_written    Total bytes actually written
+*
+**************************************************************************************************************
+*/
+
+USB_INT32U  FILE_Write (          USB_INT32S  fd,
+                        volatile  USB_INT08U  *buffer,
+                                  USB_INT32U   num_bytes)
+{
+    USB_INT32U   total_bytes_to_write;                      /* Total bytes requested by application         */
+    USB_INT32U   total_bytes_written;                       /* Total bytes written                          */
+    USB_INT32U   bytes_written;                             /* Bytes written in a single cluster            */
+    USB_INT32U   bytes_to_write;                            /* Bytes to write in a single cluster           */
+    FILE_ENTRY  *entry;                               /* Entry that contains the file attribute information */
+    USB_INT16U   free_clus;                                 /* Free cluster available in the disk           */
+
+
+    entry = &FAT_FileEntry[fd-1];                           /* Get file entry from file descriptor                     */
+    total_bytes_written  = 0;
+    total_bytes_to_write = num_bytes;
+
+    if (num_bytes) {
+        if (entry->FileSize == 0) {
+            free_clus = FAT_GetFreeClus();
+            FAT_UpdateFAT(free_clus, 0xFFFF);
+            entry->CurrClus  = free_clus;
+            MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
+            WriteLE16U(&FATBuffer[(entry->EntrySecOffset) + 26], free_clus);
+            MS_BulkSend(entry->EntrySec, 1, FATBuffer);
+        }
+    } else {
+        return (0);
+    }
+    entry->CurrClus = FAT_GetEndClus(entry->CurrClus);           /* Make the current cluster as end cluster */
+    entry->CurrClusOffset = entry->FileSize % FAT_BootSec.BytsPerClus;   /* Move cluster offset to file end */
+    do {
+        if (total_bytes_to_write > FAT_BootSec.BytsPerClus - entry->CurrClusOffset) {
+            bytes_to_write = FAT_BootSec.BytsPerClus - entry->CurrClusOffset;
+        } else {
+            bytes_to_write = total_bytes_to_write;
+        }
+        bytes_written = FAT_ClusWrite(entry->CurrClus,
+                                      entry->CurrClusOffset,
+                                      buffer,
+                                      bytes_to_write);
+        buffer               += bytes_written;
+        total_bytes_written  += bytes_written;
+        total_bytes_to_write -= bytes_written;
+        entry->FileSize      += bytes_written;
+        if (entry->CurrClusOffset + bytes_written == FAT_BootSec.BytsPerClus) {
+            entry->CurrClusOffset = 0;
+        } else {
+            entry->CurrClusOffset += bytes_written;
+        }
+        if (entry->CurrClusOffset == 0) {
+            free_clus = FAT_GetFreeClus();
+            if (free_clus == 0) {
+                return (total_bytes_written);
+            }
+            FAT_UpdateFAT(entry->CurrClus, free_clus);
+            FAT_UpdateFAT(free_clus, 0xFFFF);
+            entry->CurrClus = free_clus;
+        }
+    } while (total_bytes_to_write);
+    return (total_bytes_written);
+}
+
+/*
+**************************************************************************************************************
+*                                               WRITE TO ONE CLUSTER
+*
+* Description: This function writes the data to a single cluster.
+*
+* Arguments  : curr_clus         Current cluster into which the data has to write
+*              clus_offset       Position in the current cluster from which the data has to write
+*              buffer            Buffer from which the data has to write
+*              num_bytes         Number of bytes to write
+*
+* Returns    : tot_bytes_read    Total bytes written into the current cluster
+*
+**************************************************************************************************************
+*/
+
+USB_INT32U  FAT_ClusWrite (          USB_INT16U   curr_clus,
+                                     USB_INT32U   clus_offset,
+                           volatile  USB_INT08U  *buffer,
+                                     USB_INT32U   num_bytes)
+{
+    USB_INT32U  tot_bytes_written;
+	USB_INT32U  n_bytes;
+	USB_INT32U  start_sec;
+	USB_INT32U  sec_num;
+	USB_INT16U  num_sec;
+	USB_INT32U  sec_offset;
+	USB_INT32U  cnt;
+
+
+	tot_bytes_written = 0;
+	start_sec  = ((curr_clus - 2) * FAT_BootSec.SecPerClus) + FAT_BootSec.FirstDataSec;
+	sec_num    = start_sec + (clus_offset / FAT_BootSec.BytsPerSec);
+	num_sec    = num_bytes / FAT_BootSec.BytsPerSec;
+	sec_offset = clus_offset % FAT_BootSec.BytsPerSec;
+
+	if (sec_offset) {
+        MS_BulkRecv(sec_num, 1, FATBuffer);
+		n_bytes = (FAT_BootSec.BytsPerSec - sec_offset <= num_bytes) ?
+                  (FAT_BootSec.BytsPerSec - sec_offset) : num_bytes;
+		for (cnt = sec_offset; cnt < (sec_offset + n_bytes); cnt++) {
+            FATBuffer[cnt] = *buffer;
+			buffer++;
+		}
+        MS_BulkSend(sec_num, 1, FATBuffer);
+		tot_bytes_written += n_bytes;
+		clus_offset       += n_bytes;
+        num_bytes         -= n_bytes;
+		sec_num++;
+	}
+	if (num_bytes / FAT_BootSec.BytsPerSec) {
+		num_sec = num_bytes / FAT_BootSec.BytsPerSec;
+		MS_BulkSend(sec_num, num_sec, buffer);
+		buffer            += (num_sec * FAT_BootSec.BytsPerSec);
+		tot_bytes_written += (num_sec * FAT_BootSec.BytsPerSec);
+		clus_offset       += (num_sec * FAT_BootSec.BytsPerSec);
+        num_bytes         -= (num_sec * FAT_BootSec.BytsPerSec);
+		sec_num           += num_sec;
+	}
+	if (num_bytes) {
+        MS_BulkRecv(sec_num, 1, FATBuffer);
+
+		for (cnt = 0; cnt < num_bytes; cnt++) {
+			FATBuffer[cnt] = *buffer;
+			buffer++;
+		}
+        MS_BulkSend(sec_num, 1, FATBuffer);
+		tot_bytes_written += num_bytes;
+	}
+	return (tot_bytes_written);
+}
+
+/*
+**************************************************************************************************************
+*                                              GET NEXT CLUSTER
+*
+* Description: This function returns next cluster of the current cluster in the cluster chain. If the current
+*              cluster is the last cluster then this function returns 0
+*
+* Arguments  : clus_no    The cluster number for which the next cluster to be found
+*
+* Returns    : next_clus  if the current cluster is not the last cluster
+*              0          if the current cluster is the last cluster
+*                         Note: In practical cluster number 0 doesn't exist
+*
+**************************************************************************************************************
+*/
+
+USB_INT16U  FAT_GetNextClus (USB_INT16U  clus_no)
+{
+    USB_INT32U  sec_num;
+    USB_INT32U  ent_offset;
+    USB_INT16U  next_clus;
+
+                                          /* Get the sector number in the FAT that contains current cluster */
+    sec_num = FAT_BootSec.RsvdSecCnt + ((clus_no * 2) / FAT_BootSec.BytsPerSec);
+                                   /* Get the sector offset in the FAT where the current cluster is located */
+    ent_offset = (clus_no * 2) % FAT_BootSec.BytsPerSec; 
+    MS_BulkRecv(sec_num, 1, FATBuffer);                          /* Read that sector                        */
+    next_clus = ReadLE16U(&FATBuffer[ent_offset]);               /* Read the next cluster                   */
+    if (next_clus >= 0xFFF8 && next_clus <= 0xFFFF) {      /* If that value is in between 0xFFF8 and 0xFFFF */ 
+        next_clus = 0;                                     /* Current cluster is the end cluster            */
+    }
+    return (next_clus);
+
+}
+
+/*
+**************************************************************************************************************
+*                                               GET FREE CLUSTER
+*
+* Description: This function returns the free cluster if available
+*
+* Arguments  : None
+*
+* Returns    : free_clus    if available
+*              0            if not available(means the disk is full)
+*
+**************************************************************************************************************
+*/
+
+USB_INT16U  FAT_GetFreeClus (void)
+{
+    USB_INT32U  num_sec;
+    USB_INT32U  cnt;
+    USB_INT32U  sec_num;
+    USB_INT16U  free_clus;
+
+
+    sec_num = FAT_BootSec.RsvdSecCnt;
+    num_sec = FAT_BootSec.FATSz16;
+    while (sec_num < (FAT_BootSec.RsvdSecCnt + num_sec)) {
+        MS_BulkRecv(sec_num, 1, FATBuffer);
+        for (cnt = 0; cnt < FAT_BootSec.BytsPerSec; cnt += 2) {
+            if (ReadLE16U(&FATBuffer[cnt]) == 0) {
+                free_clus = (((sec_num - FAT_BootSec.RsvdSecCnt) * FAT_BootSec.BytsPerSec) + cnt) / 2;
+                return (free_clus);
+            }
+        }
+        sec_num++;
+    }
+    return (0);
+}
+
+/*
+**************************************************************************************************************
+*                                       UPDATE FILE ALLOCATION TABLE
+*
+* Description: This function updates the file allocation table
+*
+* Arguments  : curr_clus    Offset of the current cluster number in the file allocation table
+*              value        Value with which this offset to be updated
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  FAT_UpdateFAT (USB_INT16U  curr_clus,
+                     USB_INT16U  value)
+{
+    USB_INT32U  sec_num;
+    USB_INT32U  sec_offset;
+    
+    sec_num = FAT_BootSec.RsvdSecCnt + (curr_clus * 2) / FAT_BootSec.BytsPerSec;
+    sec_offset = (curr_clus * 2) % FAT_BootSec.BytsPerSec;
+    
+    MS_BulkRecv(sec_num, 1, FATBuffer);
+    WriteLE16U(&FATBuffer[sec_offset], value);
+    MS_BulkSend(sec_num, 1, FATBuffer);
+}
+
+/*
+**************************************************************************************************************
+*                                              UPDATE THE FILE ENTRY
+*
+* Description: This function updates the file entry that is located in the root directory
+*
+* Arguments  : entry    Pointer to the FILE ENTRY structure which contains the information about the file
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  FAT_UpdateEntry (FILE_ENTRY  *entry)
+{
+    USB_INT32U  sec_num;
+    USB_INT32U  offset;
+    
+    sec_num = entry->EntrySec;
+    offset  = entry->EntrySecOffset;
+    MS_BulkRecv(sec_num, 1, FATBuffer);
+    WriteLE32U(&FATBuffer[offset + 28], entry->FileSize);
+    MS_BulkSend(sec_num, 1, FATBuffer);
+}
+
+/*
+**************************************************************************************************************
+*                                              CREATING AN ENTRY
+*
+* Description: This function creates a file entry in the root directory if the file does not exist
+*
+* Arguments  : ent_name_given    The file name with which the entry is to be created
+*              entry             Pointer to FILE ENTRY structure
+*
+* Returns    : OK                If the entry already exists or successfully created if it doesn't exists
+*              ERROR             If failed to create the entry
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  FAT_CreateEntry (USB_INT08U  *ent_name_given,
+                             FILE_ENTRY  *entry)
+{
+    USB_INT32S  rc;
+
+
+    rc = FAT_FindEntry(ent_name_given, entry);        /* Find for the given file name in the root directory */
+    if (rc == MATCH_FOUND) {                          /* If match found, return                             */
+        return (rc);
+    } else {
+        rc = FAT_GetFreeEntry(entry);                 /* Else get a free entry from the root directory      */
+        if (rc != OK) {
+            return (rc);
+        } else {
+            FAT_PutSFN(ent_name_given, entry);        /* Store the given short file name in that entry      */
+            return (rc);
+        }
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                                GET GREE ENTRY
+*
+* Description: This function searches for a free entry in the root directory. If a free entry is found, the
+*              sector number and sector offset where the entry is located will be stored
+*
+* Arguments  : entry    Pointer to FILE_ENTRY structure
+*
+* Returns    : OK       If a free entry is found
+*              ERROR    If no free entry is found
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  FAT_GetFreeEntry (FILE_ENTRY  *entry)
+{
+              USB_INT32U   sec_num;
+    volatile  USB_INT08U  *buf;
+              USB_INT08U   ent_type;
+
+
+    for (sec_num = FAT_BootSec.RootDirStartSec; 
+         sec_num < (FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec);
+         sec_num++) {
+
+        MS_BulkRecv(sec_num, 1, FATBuffer);
+        buf = FATBuffer;
+        while (buf < (FATBuffer + FAT_BootSec.BytsPerSec)) {
+            ent_type = FAT_ChkEntType(buf);
+            if (ent_type == FREE_ENTRY) {
+                entry->EntrySec       = sec_num;
+                entry->EntrySecOffset = buf - FATBuffer;
+                return (OK);
+            }
+            if (ent_type == LAST_ENTRY) {
+                return (ERR_ROOT_DIR_FULL);
+            } else {
+                buf += 32;
+            }
+        }
+    }
+    return (ERR_ROOT_DIR_FULL);
+}
+
+/*
+**************************************************************************************************************
+*                                              PUT SHORT FILE NAME
+*
+* Description: This function fills the file entry with the short file name given by the user
+*
+* Arguments  : ent_name_given    File name given by the user
+*              entry             Pointer to the FILE_ENTRY structure
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  FAT_PutSFN (USB_INT08U  *ent_name_given,
+                  FILE_ENTRY  *entry)
+{
+    USB_INT32U  idx;
+
+                                           /* Read the sector from root directory containing the free entry */
+    MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
+    for (idx = 0; idx < 8; idx++) {        /* Fill the first eight charecters of the entry with file name   */
+        if (*ent_name_given == '.') {
+            while (idx < 8) {
+                FATBuffer[entry->EntrySecOffset + idx] = 0x20;
+                idx++;
+            }
+            ent_name_given++;
+        } else {
+            FATBuffer[entry->EntrySecOffset + idx] = *ent_name_given;
+            ent_name_given++;
+        }
+    }
+
+    for (idx = 8; idx < 11; idx++) {                      /* Fill the next 3 charecters with file extension */
+        if (*ent_name_given == '.') {
+            while (idx < 11) {
+                FATBuffer[entry->EntrySecOffset + idx] = 0x20;
+                idx++;
+            }
+        } else {
+            FATBuffer[entry->EntrySecOffset + idx] = *ent_name_given;
+            ent_name_given++;
+        }
+    }
+    FATBuffer[entry->EntrySecOffset + idx] = 0x20;
+    for (idx = 12; idx < 32; idx++) {                           /* Fill all the remaining bytes with 0's    */
+        FATBuffer[entry->EntrySecOffset + idx] = 0;
+    }
+    MS_BulkSend(entry->EntrySec, 1, FATBuffer);                 /* Write the sector into the root directory */
+}
+
+/*
+**************************************************************************************************************
+*                                                  FILE CLOSE
+*
+* Description: This function closes the opened file by making all the elements of FILE_ENTRY structure to 0
+*
+* Arguments  : fd    File descriptor which points to the file to be closed
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  FILE_Close (USB_INT32S  fd)
+{
+    FILE_ENTRY  *entry;
+
+
+    entry = &FAT_FileEntry[fd-1];
+    MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
+    WriteLE32U(&FATBuffer[entry->EntrySecOffset + 28], entry->FileSize);    /* Update the file size         */
+    MS_BulkSend(entry->EntrySec, 1, FATBuffer);
+    entry->CurrClus       = 0;
+    entry->CurrClusOffset = 0;
+    entry->FileSize       = 0;
+    entry->EntrySec       = 0;
+    entry->EntrySecOffset = 0;
+    entry->FileStatus     = 0;
+}
+
+/*
+**************************************************************************************************************
+*                                               GET END CLUSTER
+*
+* Description: This function end cluster in the cluster chain of a cluster
+*
+* Arguments  : clus_no    Starting cluster of the cluster chain in which end cluster to be found
+*
+* Returns    : End cluster in the cluster chain
+*
+**************************************************************************************************************
+*/
+
+USB_INT16U  FAT_GetEndClus (USB_INT16U  clus_no)
+{
+    USB_INT16U  next_clus;
+
+
+    next_clus = clus_no;
+    while (next_clus) {
+        next_clus = FAT_GetNextClus(clus_no);
+        if (next_clus) {
+            clus_no = next_clus;
+        }
+    }
+    return (clus_no);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Fat/usbhost_fat.h	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,146 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_fat.h
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+#ifndef  USBHOST_FAT_H
+#define  USBHOST_FAT_H
+
+/*
+**************************************************************************************************************
+*                                       INCLUDE HEADER FILES
+**************************************************************************************************************
+*/
+
+#include  "usbhost_inc.h"
+
+/*
+**************************************************************************************************************
+*                                      FAT DEFINITIONS
+**************************************************************************************************************
+*/
+
+#define    FAT_16                   1
+
+#define    LAST_ENTRY               1
+#define    FREE_ENTRY               2
+#define    LFN_ENTRY                3
+#define    SFN_ENTRY                4
+
+#define    RDONLY                   1
+#define    RDWR                     2
+
+/*
+**************************************************************************************************************
+*                                       TYPE DEFINITIONS
+**************************************************************************************************************
+*/
+
+typedef struct boot_sec {
+    USB_INT32U    BootSecOffset;             /* Offset of the boot sector from sector 0                     */
+    USB_INT16U    BytsPerSec;                /* Bytes per sector                                            */
+    USB_INT08U    SecPerClus;                /* Sectors per cluster                                         */
+    USB_INT32U    BytsPerClus;               /* Bytes per cluster                                           */
+    USB_INT16U    RsvdSecCnt;                /* Reserved sector count                                       */
+    USB_INT08U    NumFATs;                   /* Number of FAT copies                                        */
+    USB_INT16U    RootEntCnt;                /* Root entry count                                            */
+    USB_INT16U    TotSec16;                  /* Total sectors in the disk. !=0 if TotSec32 = 0              */
+    USB_INT32U    TotSec32;                  /* Total sectors in the disk. !=0 if TotSec16 = 0              */
+    USB_INT16U    FATSz16;                   /* Sectors occupied by single FAT table                        */
+    USB_INT08U    FATType;                   /* File system type                                            */
+    USB_INT32U    RootDirSec;                /* Sectors occupied by root directory                          */
+    USB_INT32U    RootDirStartSec;           /* Starting sector of the root directory                       */
+    USB_INT32U    FirstDataSec;              /* Starting sector of the first data cluster                   */
+} BOOT_SEC;
+
+typedef  struct  file_entry {
+    USB_INT32U  FileSize;                    /* Total size of the file                                      */
+    USB_INT16U  CurrClus;                    /* Current cluster of the cluster offset                       */
+    USB_INT32U  CurrClusOffset;              /* Current cluster offset                                      */
+    USB_INT32U  EntrySec;                    /* Sector where the file entry is located                      */
+    USB_INT32U  EntrySecOffset;              /* Offset in the entry sector from where the file is located   */
+	USB_INT08U  FileStatus;                  /* File's open status                                          */
+} FILE_ENTRY;
+
+/*
+**************************************************************************************************************
+*                                       FUNCTION PROTOTYPES
+**************************************************************************************************************
+*/
+
+USB_INT32S  FAT_Init        (void);
+
+USB_INT08U  FAT_GetFATType  (void);
+void        PrintBootSec    (void);
+
+USB_INT32S  FILE_Open       (          USB_INT08U  *file_name,
+                                       USB_INT08U   flags);
+
+USB_INT32S  FAT_FindEntry   (          USB_INT08U  *ent_name_given,
+                                       FILE_ENTRY  *entry);
+
+void        FAT_GetSFN      (volatile  USB_INT08U  *entry,
+                                       USB_INT08U  *name);
+
+void        FAT_GetSfnName  (volatile  USB_INT08U  *entry,
+                                       USB_INT08U  *name);
+
+void        FAT_GetSfnExt   (volatile  USB_INT08U  *entry,
+                                       USB_INT08U  *ext_ptr);
+
+USB_INT32S  FAT_StrCaseCmp  (          USB_INT08U  *str1,
+                                       USB_INT08U  *str2);
+
+USB_INT32U  FAT_ChkEntType  (volatile  USB_INT08U  *ent);
+
+USB_INT32U  FAT_ClusRead    (          USB_INT16U   curr_clus,
+                                       USB_INT32U   clus_offset,
+                             volatile  USB_INT08U  *buffer,
+                                       USB_INT32U   num_bytes);
+
+USB_INT32U  FILE_Read       (          USB_INT32S   fd,
+                             volatile  USB_INT08U  *buffer,
+                                       USB_INT32U   num_bytes);
+USB_INT16U  FAT_GetNextClus (          USB_INT16U   clus_no);
+
+USB_INT32U  FAT_ClusWrite   (          USB_INT16U   curr_clus,
+                                       USB_INT32U   clus_offset,
+                             volatile  USB_INT08U  *buffer,
+                                       USB_INT32U   num_bytes);
+USB_INT32U  FILE_Write      (          USB_INT32S   fd,
+                             volatile  USB_INT08U  *buffer,
+                                       USB_INT32U   num_bytes);
+
+void        FAT_UpdateEntry (          FILE_ENTRY  *entry);
+
+void        FAT_UpdateFAT   (          USB_INT16U   curr_clus,
+                                       USB_INT16U   value);
+
+USB_INT16U  FAT_GetFreeClus (void);
+
+USB_INT32S  FAT_GetFreeEntry(          FILE_ENTRY  *entry);
+
+void        FAT_PutSFN      (          USB_INT08U  *ent_name_given,
+                                       FILE_ENTRY  *entry);
+
+USB_INT32S  FAT_CreateEntry (          USB_INT08U  *ent_name_given,
+                                       FILE_ENTRY  *entry);
+
+void        FILE_Close      (          USB_INT32S   fd);
+
+USB_INT16U  FAT_GetEndClus  (          USB_INT16U   clus_no);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Host/usbhost_lpc17xx.c	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,839 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_lpc17xx.c
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+ 
+/*
+**************************************************************************************************************
+*                                            INCLUDE HEADER FILES
+**************************************************************************************************************
+*/
+
+#include  "usbhost_lpc17xx.h"
+
+/*
+**************************************************************************************************************
+*                                              GLOBAL VARIABLES
+**************************************************************************************************************
+*/
+int gUSBConnected;
+
+volatile  USB_INT32U   HOST_RhscIntr = 0;         /* Root Hub Status Change interrupt                       */
+volatile  USB_INT32U   HOST_WdhIntr  = 0;         /* Semaphore to wait until the TD is submitted            */
+volatile  USB_INT08U   HOST_TDControlStatus = 0;
+volatile  HCED        *EDCtrl;                    /* Control endpoint descriptor structure                  */
+volatile  HCED        *EDBulkIn;                  /* BulkIn endpoint descriptor  structure                  */
+volatile  HCED        *EDBulkOut;                 /* BulkOut endpoint descriptor structure                  */
+volatile  HCTD        *TDHead;                    /* Head transfer descriptor structure                     */
+volatile  HCTD        *TDTail;                    /* Tail transfer descriptor structure                     */
+volatile  HCCA        *Hcca;                      /* Host Controller Communications Area structure          */ 
+          USB_INT16U  *TDBufNonVol;               /* Identical to TDBuffer just to reduce compiler warnings */
+volatile  USB_INT08U  *TDBuffer;                  /* Current Buffer Pointer of transfer descriptor          */
+volatile  USB_INT08U  *FATBuffer;                 /* Buffer used by FAT file system                         */
+volatile  USB_INT08U  *UserBuffer;                /* Buffer used by application                             */
+
+/*
+**************************************************************************************************************
+*                                         DELAY IN MILLI SECONDS
+*
+* Description: This function provides a delay in milli seconds
+*
+* Arguments  : delay    The delay required
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  Host_DelayMS (USB_INT32U  delay)
+{
+    volatile  USB_INT32U  i;
+
+
+    for (i = 0; i < delay; i++) {
+        Host_DelayUS(1000);
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                         DELAY IN MICRO SECONDS
+*
+* Description: This function provides a delay in micro seconds
+*
+* Arguments  : delay    The delay required
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  Host_DelayUS (USB_INT32U  delay)
+{
+    volatile  USB_INT32U  i;
+
+
+    for (i = 0; i < (4 * delay); i++) {    /* This logic was tested. It gives app. 1 micro sec delay        */
+        ;
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                         INITIALIZE THE HOST CONTROLLER
+*
+* Description: This function initializes lpc17xx host controller
+*
+* Arguments  : None
+*
+* Returns    : 
+*
+**************************************************************************************************************
+*/
+void  Host_Init (void)
+{
+    USB_INT32U HostBaseAddr;
+
+    PRINT_Log("In Host_Init, LPC_USB=0x%08X\r\n", LPC_USB);
+    //NVIC_DisableIRQ(USB_IRQn);                           /* Disable the USB interrupt source           */
+    
+    LPC_SC->PCONP       |= (1UL<<31);   // set PCUSB bit
+#if 1
+    PRINT_Log("1: OTGClkCtrl == %08X, OTGClkSt == %08X\r\n", LPC_USB->OTGClkCtrl, LPC_USB->OTGClkSt);
+    LPC_USB->OTGClkCtrl    = 0x0000001F; 
+    PRINT_Log("2: OTGClkCtrl == %08X, OTGClkSt == %08X\r\n", LPC_USB->OTGClkCtrl, LPC_USB->OTGClkSt);
+    while ((LPC_USB->OTGClkSt & 0x0000001F) == 0) {        /* Host clock is available */
+        ;
+    }
+#else
+    PRINT_Log("1: USBClkCtrl == %08X, USBClkSt == %08X\r\n", LPC_USB->USBClkCtrl, LPC_USB->USBClkSt);
+    LPC_USB->USBClkCtrl |= 0x01;                              /* Enable USB host clock                      */
+    PRINT_Log("2: USBClkCtrl == %08X, USBClkSt == %08X\r\n", LPC_USB->USBClkCtrl, LPC_USB->USBClkSt);
+//    while ((LPC_USB->USBClkSt & 0x00000001) == 0) {        /* Host clock is available */
+//        ;
+//    }
+wait(0.5);
+#endif
+
+PRINT_Log("3: OTGStCtrl=%08X\r\n", LPC_USB->OTGStCtrl);
+#if 1
+    LPC_USB->OTGStCtrl = 1;    // ? 0x3; 
+PRINT_Log("4\r\n");
+#endif
+
+    /* P1[18] = USB_UP_LED, 01 */
+    /* P1[19] = /USB_PPWR,     10 */
+    /* P1[22] = USB_PWRD, 10 */
+    /* P1[27] = /USB_OVRCR, 10 */
+#if 0
+    LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22));  
+    LPC_PINCON->PINSEL3 |=  ((1<<4)|(2<<6) | (2<<12) | (2<<22));   // 0x00802080
+PRINT_Log("5\r\n");
+#endif
+
+    /* P0[29] = USB_D+, 01 */
+    /* P0[30] = USB_D-, 01 */
+    LPC_PINCON->PINSEL1 &= ~((3<<26) | (3<<28));  
+    LPC_PINCON->PINSEL1 |=  ((1<<26)|(1<<28));     // 0x14000000
+        
+    PRINT_Log("Initializing Host Stack\r\n");
+
+    // For chip revision V01 and later
+//    HostBaseAddr = 0x20080000;
+#ifdef TARGET_LPC1768   
+    // mbed's "USB RAM"
+    HostBaseAddr = 0x2007C000;
+#else
+    // USB RAM
+    HostBaseAddr = 0x7FD00000;
+#endif
+
+    Hcca       = (volatile  HCCA       *)(HostBaseAddr+0x000);
+    TDHead     = (volatile  HCTD       *)(HostBaseAddr+0x100);
+    TDTail     = (volatile  HCTD       *)(HostBaseAddr+0x110);
+    EDCtrl     = (volatile  HCED       *)(HostBaseAddr+0x120); 
+    EDBulkIn   = (volatile  HCED       *)(HostBaseAddr+0x130);
+    EDBulkOut  = (volatile  HCED       *)(HostBaseAddr+0x140);
+    TDBuffer   = (volatile  USB_INT08U *)(HostBaseAddr+0x150);
+    FATBuffer  = (volatile  USB_INT08U *)(HostBaseAddr+0x1D0);
+    UserBuffer = (volatile  USB_INT08U *)(HostBaseAddr+0x1000);
+
+                                                              /* Initialize all the TDs, EDs and HCCA to 0  */
+PRINT_Log("6\r\n");
+    Host_EDInit(EDCtrl);
+PRINT_Log("7\r\n");
+    Host_EDInit(EDBulkIn);
+PRINT_Log("8\r\n");
+    Host_EDInit(EDBulkOut);
+PRINT_Log("9\r\n");
+    Host_TDInit(TDHead);
+PRINT_Log("10\r\n");
+    Host_TDInit(TDTail);
+PRINT_Log("11\r\n");
+    Host_HCCAInit(Hcca);
+PRINT_Log("12\r\n");
+
+    
+    Host_DelayMS(50);                                         /* Wait 50 ms before apply reset              */
+    LPC_USB->HcControl       = 0;                                      /* HARDWARE RESET                             */
+    LPC_USB->HcControlHeadED = 0;                                      /* Initialize Control list head to Zero       */
+    LPC_USB->HcBulkHeadED    = 0;                                      /* Initialize Bulk list head to Zero          */
+    
+                                                              /* SOFTWARE RESET                             */
+    LPC_USB->HcCommandStatus = OR_CMD_STATUS_HCR;
+    LPC_USB->HcFmInterval    = DEFAULT_FMINTERVAL;              /* Write Fm Interval and Largest Data Packet Counter */
+
+                                                              /* Put HC in operational state                */
+    LPC_USB->HcControl  = (LPC_USB->HcControl & (~OR_CONTROL_HCFS)) | OR_CONTROL_HC_OPER;
+    LPC_USB->HcRhStatus = OR_RH_STATUS_LPSC;                           /* Set Global Power                           */
+    
+    LPC_USB->HcHCCA = (USB_INT32U)Hcca;
+    LPC_USB->HcInterruptStatus |= LPC_USB->HcInterruptStatus;                   /* Clear Interrrupt Status                    */
+
+
+    LPC_USB->HcInterruptEnable  = OR_INTR_ENABLE_MIE |
+                         OR_INTR_ENABLE_WDH |
+                         OR_INTR_ENABLE_RHSC;
+
+PRINT_Log("15\r\n");
+
+
+#ifdef TARGET_LPC2368
+    NVIC->IntSelect &= ~(1 << USB_IRQn); /* Configure the ISR handler as IRQ */
+    /* Set the vector address */
+    NVIC_SetVector(USB_IRQn, (USB_INT32U)USB_IRQHandler);
+#endif
+    NVIC_SetPriority(USB_IRQn, 0);       /* highest priority */
+    /* Enable the USB Interrupt */
+    NVIC_EnableIRQ(USB_IRQn);               /* enable USB interrupt */
+//    NVIC_SetPriority (USB_IRQn, 0);            /* highest priority */
+    PRINT_Log("Host Initialized\r\n");
+}
+
+/*
+**************************************************************************************************************
+*                                         INTERRUPT SERVICE ROUTINE
+*
+* Description: This function services the interrupt caused by host controller
+*
+* Arguments  : None
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void USB_IRQHandler (void) __irq
+{
+    USB_INT32U   int_status;
+    USB_INT32U   ie_status;
+
+    int_status    = LPC_USB->HcInterruptStatus;                          /* Read Interrupt Status                */
+    ie_status     = LPC_USB->HcInterruptEnable;                          /* Read Interrupt enable status         */
+ 
+//PRINT_Log("In USB_IRQHandler().\r\n");
+    if (!(int_status & ie_status)) {
+        return;
+    } else {
+
+        int_status = int_status & ie_status;
+        if (int_status & OR_INTR_STATUS_RHSC) {                 /* Root hub status change interrupt     */
+            if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CSC) {
+                if (LPC_USB->HcRhStatus & OR_RH_STATUS_DRWE) {
+                    /*
+                     * When DRWE is on, Connect Status Change
+                     * means a remote wakeup event.
+                    */
+                    HOST_RhscIntr = 1;// JUST SOMETHING FOR A BREAKPOINT
+                }
+                else {
+                    /*
+                     * When DRWE is off, Connect Status Change
+                     * is NOT a remote wakeup event
+                    */
+                    if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_CCS) {
+                        if (!gUSBConnected) {
+                            HOST_TDControlStatus = 0;
+                            HOST_WdhIntr = 0;
+                            HOST_RhscIntr = 1;
+                            gUSBConnected = 1;
+                        }
+                        else
+                            PRINT_Log("Spurious status change (connected)?\r\n");
+                    } else {
+                        if (gUSBConnected) {
+                            LPC_USB->HcInterruptEnable = 0; // why do we get multiple disc. rupts???
+                            HOST_RhscIntr = 0;
+                            gUSBConnected = 0;
+                        }
+                        else
+                            PRINT_Log("Spurious status change (disconnected)?\r\n");
+                    }
+                }
+                LPC_USB->HcRhPortStatus1 = OR_RH_PORT_CSC;
+            }
+            if (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRSC) {
+                LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC;
+            }
+        }
+        if (int_status & OR_INTR_STATUS_WDH) {                  /* Writeback Done Head interrupt        */
+            HOST_WdhIntr = 1;
+            HOST_TDControlStatus = (TDHead->Control >> 28) & 0xf;
+        }            
+        LPC_USB->HcInterruptStatus = int_status;                         /* Clear interrupt status register      */
+    }
+#ifdef TARGET_LPC2368
+    NVIC->Address = 0;
+#endif    
+    return;
+}
+
+/*
+**************************************************************************************************************
+*                                     PROCESS TRANSFER DESCRIPTOR
+*
+* Description: This function processes the transfer descriptor
+*
+* Arguments  : ed            Endpoint descriptor that contains this transfer descriptor
+*              token         SETUP, IN, OUT
+*              buffer        Current Buffer Pointer of the transfer descriptor
+*              buffer_len    Length of the buffer
+*
+* Returns    : OK       if TD submission is successful
+*              ERROR    if TD submission fails
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  Host_ProcessTD (volatile  HCED       *ed,
+                            volatile  USB_INT32U  token,
+                            volatile  USB_INT08U *buffer,
+                                      USB_INT32U  buffer_len)
+{
+    volatile  USB_INT32U   td_toggle;
+
+
+    if (ed == EDCtrl) {
+        if (token == TD_SETUP) {
+            td_toggle = TD_TOGGLE_0;
+        } else {
+            td_toggle = TD_TOGGLE_1;
+        }
+    } else {
+        td_toggle = 0;
+    }
+    TDHead->Control = (TD_ROUNDING    |
+                      token           |
+                      TD_DELAY_INT(0) |                           
+                      td_toggle       |
+                      TD_CC);
+    TDTail->Control = 0;
+    TDHead->CurrBufPtr   = (USB_INT32U) buffer;
+    TDTail->CurrBufPtr   = 0;
+    TDHead->Next         = (USB_INT32U) TDTail;
+    TDTail->Next         = 0;
+    TDHead->BufEnd       = (USB_INT32U)(buffer + (buffer_len - 1));
+    TDTail->BufEnd       = 0;
+
+    ed->HeadTd  = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002);
+    ed->TailTd  = (USB_INT32U)TDTail;
+    ed->Next    = 0;
+
+    if (ed == EDCtrl) {
+        LPC_USB->HcControlHeadED = (USB_INT32U)ed;
+        LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF;
+        LPC_USB->HcControl       = LPC_USB->HcControl       | OR_CONTROL_CLE;
+    } else {
+        LPC_USB->HcBulkHeadED    = (USB_INT32U)ed;
+        LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
+        LPC_USB->HcControl       = LPC_USB->HcControl       | OR_CONTROL_BLE;
+    }    
+
+    Host_WDHWait();
+
+//    if (!(TDHead->Control & 0xF0000000)) {
+    if (!HOST_TDControlStatus) {
+        return (OK);
+    } else {      
+        return (ERR_TD_FAIL);
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                       ENUMERATE THE DEVICE
+*
+* Description: This function is used to enumerate the device connected
+*
+* Arguments  : None
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  Host_EnumDev (void)
+{
+    USB_INT32S  rc;
+
+    PRINT_Log("Connect a Mass Storage device:\r\n");
+    while (!HOST_RhscIntr);
+    Host_DelayMS(100);                             /* USB 2.0 spec says atleast 50ms delay beore port reset */
+    LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRS; // Initiate port reset
+    while (LPC_USB->HcRhPortStatus1 & OR_RH_PORT_PRS)
+        ; // Wait for port reset to complete...
+    LPC_USB->HcRhPortStatus1 = OR_RH_PORT_PRSC; // ...and clear port reset signal
+    Host_DelayMS(200);                                                 /* Wait for 100 MS after port reset  */
+
+    EDCtrl->Control = 8 << 16;                                         /* Put max pkt size = 8              */
+                                                                       /* Read first 8 bytes of device desc */
+    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_DEVICE, 0, TDBuffer, 8);
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return (rc);
+    }
+    EDCtrl->Control = TDBuffer[7] << 16;                               /* Get max pkt size of endpoint 0    */
+    rc = HOST_SET_ADDRESS(1);                                          /* Set the device address to 1       */
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return (rc);
+    }
+    Host_DelayMS(2);
+    EDCtrl->Control = (EDCtrl->Control) | 1;                          /* Modify control pipe with address 1 */
+                                                                      /* Get the configuration descriptor   */
+    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, 9);
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return (rc);
+    }
+                                                                       /* Get the first configuration data  */
+    rc = HOST_GET_DESCRIPTOR(USB_DESCRIPTOR_TYPE_CONFIGURATION, 0, TDBuffer, ReadLE16U(&TDBuffer[2]));
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return (rc);
+    }
+    rc = MS_ParseConfiguration();                                      /* Parse the configuration           */
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return (rc);
+    }
+    rc = USBH_SET_CONFIGURATION(1);                                    /* Select device configuration 1     */
+    if (rc != OK) {
+        PRINT_Err(rc);
+    }
+    Host_DelayMS(100);                                               /* Some devices may require this delay */
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                        RECEIVE THE CONTROL INFORMATION
+*
+* Description: This function is used to receive the control information
+*
+* Arguments  : bm_request_type
+*              b_request
+*              w_value
+*              w_index
+*              w_length
+*              buffer
+*
+* Returns    : OK       if Success
+*              ERROR    if Failed
+*
+**************************************************************************************************************
+*/
+   
+USB_INT32S  Host_CtrlRecv (         USB_INT08U   bm_request_type,
+                                    USB_INT08U   b_request,
+                                    USB_INT16U   w_value,
+                                    USB_INT16U   w_index,
+                                    USB_INT16U   w_length,
+                          volatile  USB_INT08U  *buffer)
+{
+    USB_INT32S  rc;
+
+
+    Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
+    rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
+    if (rc == OK) {
+        if (w_length) {
+            rc = Host_ProcessTD(EDCtrl, TD_IN, TDBuffer, w_length);
+        }
+        if (rc == OK) {
+            rc = Host_ProcessTD(EDCtrl, TD_OUT, NULL, 0);
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                         SEND THE CONTROL INFORMATION
+*
+* Description: This function is used to send the control information
+*
+* Arguments  : None
+*
+* Returns    : OK                      if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  Host_CtrlSend (          USB_INT08U   bm_request_type,
+                                     USB_INT08U   b_request,
+                                     USB_INT16U   w_value,
+                                     USB_INT16U   w_index,
+                                     USB_INT16U   w_length,
+                           volatile  USB_INT08U  *buffer)
+{
+    USB_INT32S  rc;
+
+
+    Host_FillSetup(bm_request_type, b_request, w_value, w_index, w_length);
+
+    rc = Host_ProcessTD(EDCtrl, TD_SETUP, TDBuffer, 8);
+    if (rc == OK) {
+        if (w_length) {
+            rc = Host_ProcessTD(EDCtrl, TD_OUT, TDBuffer, w_length);
+        }
+        if (rc == OK) {
+            rc = Host_ProcessTD(EDCtrl, TD_IN, NULL, 0);
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                          FILL SETUP PACKET
+*
+* Description: This function is used to fill the setup packet
+*
+* Arguments  : None
+*
+* Returns    : OK                      if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+void  Host_FillSetup (USB_INT08U   bm_request_type,
+                      USB_INT08U   b_request,
+                      USB_INT16U   w_value,
+                      USB_INT16U   w_index,
+                      USB_INT16U   w_length)
+{
+    int i;
+    for (i=0;i<w_length;i++)
+        TDBuffer[i] = 0;
+    
+    TDBuffer[0] = bm_request_type;
+    TDBuffer[1] = b_request;
+    WriteLE16U(&TDBuffer[2], w_value);
+    WriteLE16U(&TDBuffer[4], w_index);
+    WriteLE16U(&TDBuffer[6], w_length);
+}
+
+
+
+/*
+**************************************************************************************************************
+*                                         INITIALIZE THE TRANSFER DESCRIPTOR
+*
+* Description: This function initializes transfer descriptor
+*
+* Arguments  : Pointer to TD structure
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  Host_TDInit (volatile  HCTD *td)
+{
+
+    td->Control    = 0;
+    td->CurrBufPtr = 0;
+    td->Next       = 0;
+    td->BufEnd     = 0;
+}
+
+/*
+**************************************************************************************************************
+*                                         INITIALIZE THE ENDPOINT DESCRIPTOR
+*
+* Description: This function initializes endpoint descriptor
+*
+* Arguments  : Pointer to ED strcuture
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  Host_EDInit (volatile  HCED *ed)
+{
+
+    ed->Control = 0;
+    ed->TailTd  = 0;
+    ed->HeadTd  = 0;
+    ed->Next    = 0;
+}
+
+/*
+**************************************************************************************************************
+*                                 INITIALIZE HOST CONTROLLER COMMUNICATIONS AREA
+*
+* Description: This function initializes host controller communications area
+*
+* Arguments  : Pointer to HCCA
+*
+* Returns    : 
+*
+**************************************************************************************************************
+*/
+
+void  Host_HCCAInit (volatile  HCCA  *hcca)
+{
+    USB_INT32U  i;
+
+
+    for (i = 0; i < 32; i++) {
+
+        hcca->IntTable[i] = 0;
+        hcca->FrameNumber = 0;
+        hcca->DoneHead    = 0;
+    }
+
+}
+
+/*
+**************************************************************************************************************
+*                                         WAIT FOR WDH INTERRUPT
+*
+* Description: This function is infinite loop which breaks when ever a WDH interrupt rises
+*
+* Arguments  : None
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  Host_WDHWait (void)
+{
+  while (!HOST_WdhIntr) {
+    ;
+  }
+  HOST_WdhIntr = 0;
+}
+
+/*
+**************************************************************************************************************
+*                                         READ LE 32U
+*
+* Description: This function is used to read an unsigned integer from a charecter buffer in the platform
+*              containing little endian processor
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*
+* Returns    : val     Unsigned integer
+*
+**************************************************************************************************************
+*/
+
+USB_INT32U  ReadLE32U (volatile  USB_INT08U  *pmem)
+{
+    USB_INT32U   val;
+
+    ((USB_INT08U *)&val)[0] = pmem[0];
+    ((USB_INT08U *)&val)[1] = pmem[1];
+    ((USB_INT08U *)&val)[2] = pmem[2];
+    ((USB_INT08U *)&val)[3] = pmem[3];
+
+    return (val);
+}
+
+/*
+**************************************************************************************************************
+*                                        WRITE LE 32U
+*
+* Description: This function is used to write an unsigned integer into a charecter buffer in the platform 
+*              containing little endian processor.
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*              val     Integer value to be placed in the charecter buffer
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  WriteLE32U (volatile  USB_INT08U  *pmem,
+                            USB_INT32U   val)
+{
+    pmem[0] = ((USB_INT08U *)&val)[0];
+    pmem[1] = ((USB_INT08U *)&val)[1];
+    pmem[2] = ((USB_INT08U *)&val)[2];
+    pmem[3] = ((USB_INT08U *)&val)[3];
+}
+
+/*
+**************************************************************************************************************
+*                                          READ LE 16U
+*
+* Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
+*              containing little endian processor
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*
+* Returns    : val     Unsigned short integer
+*
+**************************************************************************************************************
+*/
+
+USB_INT16U  ReadLE16U (volatile  USB_INT08U  *pmem)
+{
+    USB_INT16U   val;
+
+    ((USB_INT08U *)&val)[0] = pmem[0];
+    ((USB_INT08U *)&val)[1] = pmem[1];
+
+
+    return (val);
+}
+
+/*
+**************************************************************************************************************
+*                                         WRITE LE 16U
+*
+* Description: This function is used to write an unsigned short integer into a charecter buffer in the
+*              platform containing little endian processor
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*              val     Value to be placed in the charecter buffer
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  WriteLE16U (volatile  USB_INT08U  *pmem,
+                            USB_INT16U   val)
+{
+    pmem[0] = ((USB_INT08U *)&val)[0];
+    pmem[1] = ((USB_INT08U *)&val)[1];
+}
+
+/*
+**************************************************************************************************************
+*                                         READ BE 32U
+*
+* Description: This function is used to read an unsigned integer from a charecter buffer in the platform
+*              containing big endian processor
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*
+* Returns    : val     Unsigned integer
+*
+**************************************************************************************************************
+*/
+
+USB_INT32U  ReadBE32U (volatile  USB_INT08U  *pmem)
+{
+    USB_INT32U   val;
+
+    ((USB_INT08U *)&val)[0] = pmem[3];
+    ((USB_INT08U *)&val)[1] = pmem[2];
+    ((USB_INT08U *)&val)[2] = pmem[1];
+    ((USB_INT08U *)&val)[3] = pmem[0];
+
+    return (val);
+}
+
+/*
+**************************************************************************************************************
+*                                         WRITE BE 32U
+*
+* Description: This function is used to write an unsigned integer into a charecter buffer in the platform
+*              containing big endian processor
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*              val     Value to be placed in the charecter buffer
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  WriteBE32U (volatile  USB_INT08U  *pmem,
+                            USB_INT32U   val)
+{
+    pmem[0] = ((USB_INT08U *)&val)[3];
+    pmem[1] = ((USB_INT08U *)&val)[2];
+    pmem[2] = ((USB_INT08U *)&val)[1];
+    pmem[3] = ((USB_INT08U *)&val)[0];
+
+}
+
+/*
+**************************************************************************************************************
+*                                         READ BE 16U
+*
+* Description: This function is used to read an unsigned short integer from a charecter buffer in the platform
+*              containing big endian processor
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*
+* Returns    : val     Unsigned short integer
+*
+**************************************************************************************************************
+*/
+
+USB_INT16U  ReadBE16U (volatile  USB_INT08U  *pmem)
+{
+    USB_INT16U  val;
+
+
+    ((USB_INT08U *)&val)[0] = pmem[1];
+    ((USB_INT08U *)&val)[1] = pmem[0];
+
+    return (val);
+}
+
+/*
+**************************************************************************************************************
+*                                         WRITE BE 16U
+*
+* Description: This function is used to write an unsigned short integer into the charecter buffer in the
+*              platform containing big endian processor
+*
+* Arguments  : pmem    Pointer to the charecter buffer
+*              val     Value to be placed in the charecter buffer
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+void  WriteBE16U (volatile  USB_INT08U  *pmem,
+                            USB_INT16U   val)
+{
+    pmem[0] = ((USB_INT08U *)&val)[1];
+    pmem[1] = ((USB_INT08U *)&val)[0];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Host/usbhost_lpc17xx.h	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,257 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_lpc17xx.h
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+#ifndef USBHOST_LPC17xx_H
+#define USBHOST_LPC17xx_H
+
+/*
+**************************************************************************************************************
+*                                       INCLUDE HEADER FILES
+**************************************************************************************************************
+*/
+
+#include    "usbhost_inc.h"
+
+/*
+**************************************************************************************************************
+*                                        PRINT CONFIGURATION
+**************************************************************************************************************
+*/
+
+#define  PRINT_ENABLE         1
+
+#if PRINT_ENABLE
+#define  PRINT_Log(...)       printf(__VA_ARGS__)
+#define  PRINT_Err(rc)        printf("ERROR: In %s at Line %u - rc = %d\r\n", __FUNCTION__, __LINE__, rc)
+
+#else 
+#define  PRINT_Log(...)       do {} while(0)
+#define  PRINT_Err(rc)        do {} while(0)
+
+#endif
+
+/*
+**************************************************************************************************************
+*                                        GENERAL DEFINITIONS
+**************************************************************************************************************
+*/
+
+#define  DESC_LENGTH(x)  x[0]
+#define  DESC_TYPE(x)    x[1]
+
+
+#define  HOST_GET_DESCRIPTOR(descType, descIndex, data, length)                      \
+         Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_RECIPIENT_DEVICE, GET_DESCRIPTOR,    \
+         (descType << 8)|(descIndex), 0, length, data)
+
+#define  HOST_SET_ADDRESS(new_addr)                                                  \
+         Host_CtrlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_ADDRESS,       \
+         new_addr, 0, 0, NULL)
+
+#define  USBH_SET_CONFIGURATION(configNum)                                           \
+         Host_CtrlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_DEVICE, SET_CONFIGURATION, \
+         configNum, 0, 0, NULL)
+
+#define  USBH_SET_INTERFACE(ifNum, altNum)                                           \
+         Host_CtrlSend(USB_HOST_TO_DEVICE | USB_RECIPIENT_INTERFACE, SET_INTERFACE,  \
+         altNum, ifNum, 0, NULL)
+
+/*
+**************************************************************************************************************
+*                                  OHCI OPERATIONAL REGISTER FIELD DEFINITIONS
+**************************************************************************************************************
+*/
+
+                                            /* ------------------ HcControl Register ---------------------  */
+#define  OR_CONTROL_CLE                 0x00000010
+#define  OR_CONTROL_BLE                 0x00000020
+#define  OR_CONTROL_HCFS                0x000000C0
+#define  OR_CONTROL_HC_OPER             0x00000080
+                                            /* ----------------- HcCommandStatus Register ----------------- */
+#define  OR_CMD_STATUS_HCR              0x00000001
+#define  OR_CMD_STATUS_CLF              0x00000002
+#define  OR_CMD_STATUS_BLF              0x00000004
+                                            /* --------------- HcInterruptStatus Register ----------------- */
+#define  OR_INTR_STATUS_WDH             0x00000002
+#define  OR_INTR_STATUS_RHSC            0x00000040
+                                            /* --------------- HcInterruptEnable Register ----------------- */
+#define  OR_INTR_ENABLE_WDH             0x00000002
+#define  OR_INTR_ENABLE_RHSC            0x00000040
+#define  OR_INTR_ENABLE_MIE             0x80000000
+                                            /* ---------------- HcRhDescriptorA Register ------------------ */
+#define  OR_RH_STATUS_LPSC              0x00010000
+#define  OR_RH_STATUS_DRWE              0x00008000
+                                            /* -------------- HcRhPortStatus[1:NDP] Register -------------- */
+#define  OR_RH_PORT_CCS                 0x00000001
+#define  OR_RH_PORT_PRS                 0x00000010
+#define  OR_RH_PORT_CSC                 0x00010000
+#define  OR_RH_PORT_PRSC                0x00100000
+
+
+/*
+**************************************************************************************************************
+*                                               FRAME INTERVAL
+**************************************************************************************************************
+*/
+
+#define  FI                     0x2EDF           /* 12000 bits per frame (-1)                               */
+#define  DEFAULT_FMINTERVAL     ((((6 * (FI - 210)) / 7) << 16) | FI)
+
+/*
+**************************************************************************************************************
+*                                       TRANSFER DESCRIPTOR CONTROL FIELDS
+**************************************************************************************************************
+*/
+
+#define  TD_ROUNDING        (USB_INT32U) (0x00040000)        /* Buffer Rounding                             */
+#define  TD_SETUP           (USB_INT32U)(0)                  /* Direction of Setup Packet                   */
+#define  TD_IN              (USB_INT32U)(0x00100000)         /* Direction In                                */
+#define  TD_OUT             (USB_INT32U)(0x00080000)         /* Direction Out                               */
+#define  TD_DELAY_INT(x)    (USB_INT32U)((x) << 21)          /* Delay Interrupt                             */
+#define  TD_TOGGLE_0        (USB_INT32U)(0x02000000)         /* Toggle 0                                    */
+#define  TD_TOGGLE_1        (USB_INT32U)(0x03000000)         /* Toggle 1                                    */
+#define  TD_CC              (USB_INT32U)(0xF0000000)         /* Completion Code                             */
+
+/*
+**************************************************************************************************************
+*                                       USB STANDARD REQUEST DEFINITIONS
+**************************************************************************************************************
+*/
+
+#define  USB_DESCRIPTOR_TYPE_DEVICE                     1
+#define  USB_DESCRIPTOR_TYPE_CONFIGURATION              2
+#define  USB_DESCRIPTOR_TYPE_INTERFACE                  4
+#define  USB_DESCRIPTOR_TYPE_ENDPOINT                   5
+                                                    /*  ----------- Control RequestType Fields  ----------- */
+#define  USB_DEVICE_TO_HOST         0x80
+#define  USB_HOST_TO_DEVICE         0x00
+#define  USB_REQUEST_TYPE_CLASS     0x20
+#define  USB_RECIPIENT_DEVICE       0x00
+#define  USB_RECIPIENT_INTERFACE    0x01
+                                                    /* -------------- USB Standard Requests  -------------- */
+#define  SET_ADDRESS                 5
+#define  GET_DESCRIPTOR              6
+#define  SET_CONFIGURATION           9
+#define  SET_INTERFACE              11
+
+/*
+**************************************************************************************************************
+*                                       TYPE DEFINITIONS
+**************************************************************************************************************
+*/
+
+typedef struct hcEd {                       /* ----------- HostController EndPoint Descriptor ------------- */
+    volatile  USB_INT32U  Control;              /* Endpoint descriptor control                              */
+    volatile  USB_INT32U  TailTd;               /* Physical address of tail in Transfer descriptor list     */
+    volatile  USB_INT32U  HeadTd;               /* Physcial address of head in Transfer descriptor list     */
+    volatile  USB_INT32U  Next;                 /* Physical address of next Endpoint descriptor             */
+} HCED;
+
+typedef struct hcTd {                       /* ------------ HostController Transfer Descriptor ------------ */
+    volatile  USB_INT32U  Control;              /* Transfer descriptor control                              */
+    volatile  USB_INT32U  CurrBufPtr;           /* Physical address of current buffer pointer               */
+    volatile  USB_INT32U  Next;                 /* Physical pointer to next Transfer Descriptor             */
+    volatile  USB_INT32U  BufEnd;               /* Physical address of end of buffer                        */
+} HCTD;
+
+typedef struct hcca {                       /* ----------- Host Controller Communication Area ------------  */
+    volatile  USB_INT32U  IntTable[32];         /* Interrupt Table                                          */
+    volatile  USB_INT32U  FrameNumber;          /* Frame Number                                             */
+    volatile  USB_INT32U  DoneHead;             /* Done Head                                                */
+    volatile  USB_INT08U  Reserved[116];        /* Reserved for future use                                  */
+    volatile  USB_INT08U  Unknown[4];           /* Unused                                                   */
+} HCCA;
+
+/*
+**************************************************************************************************************
+*                                     EXTERN DECLARATIONS
+**************************************************************************************************************
+*/
+
+extern  volatile  HCED        *EDBulkIn;        /* BulkIn endpoint descriptor  structure                    */
+extern  volatile  HCED        *EDBulkOut;       /* BulkOut endpoint descriptor structure                    */
+extern  volatile  HCTD        *TDHead;          /* Head transfer descriptor structure                       */
+extern  volatile  HCTD        *TDTail;          /* Tail transfer descriptor structure                       */
+extern  volatile  USB_INT08U  *TDBuffer;        /* Current Buffer Pointer of transfer descriptor            */
+extern  volatile  USB_INT08U  *FATBuffer;       /* Buffer used by FAT file system                           */
+extern  volatile  USB_INT08U  *UserBuffer;      /* Buffer used by application                               */
+
+/*
+**************************************************************************************************************
+*                                       FUNCTION PROTOTYPES
+**************************************************************************************************************
+*/
+
+void        Host_Init     (void);
+
+//void        USB_IRQHandler(void)  __irq;
+extern "C" void USB_IRQHandler(void)  __irq;
+
+USB_INT32S  Host_EnumDev  (void);
+
+USB_INT32S  Host_ProcessTD(volatile  HCED       *ed,
+                           volatile  USB_INT32U  token,
+                           volatile  USB_INT08U *buffer,
+                                     USB_INT32U  buffer_len);
+
+void        Host_DelayUS  (          USB_INT32U    delay);
+void        Host_DelayMS  (          USB_INT32U    delay);
+
+
+void        Host_TDInit   (volatile  HCTD *td);
+void        Host_EDInit   (volatile  HCED *ed);
+void        Host_HCCAInit (volatile  HCCA  *hcca);
+
+USB_INT32S  Host_CtrlRecv (          USB_INT08U   bm_request_type,
+                                     USB_INT08U   b_request,
+                                     USB_INT16U   w_value,
+                                     USB_INT16U   w_index,
+                                     USB_INT16U   w_length,
+                           volatile  USB_INT08U  *buffer);
+
+USB_INT32S  Host_CtrlSend (          USB_INT08U   bm_request_type,
+                                     USB_INT08U   b_request,
+                                     USB_INT16U   w_value,
+                                     USB_INT16U   w_index,
+                                     USB_INT16U   w_length,
+                           volatile  USB_INT08U  *buffer);
+
+void        Host_FillSetup(          USB_INT08U   bm_request_type,
+                                     USB_INT08U   b_request,
+                                     USB_INT16U   w_value,
+                                     USB_INT16U   w_index,
+                                     USB_INT16U   w_length);
+
+
+void        Host_WDHWait  (void);
+
+
+USB_INT32U  ReadLE32U     (volatile  USB_INT08U  *pmem);
+void        WriteLE32U    (volatile  USB_INT08U  *pmem,
+                                     USB_INT32U   val);
+USB_INT16U  ReadLE16U     (volatile  USB_INT08U  *pmem);
+void        WriteLE16U    (volatile  USB_INT08U  *pmem,
+                                     USB_INT16U   val);
+USB_INT32U  ReadBE32U     (volatile  USB_INT08U  *pmem);
+void        WriteBE32U    (volatile  USB_INT08U  *pmem,
+                                     USB_INT32U   val);
+USB_INT16U  ReadBE16U     (volatile  USB_INT08U  *pmem);
+void        WriteBE16U    (volatile  USB_INT08U  *pmem,
+                                     USB_INT16U   val);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Include/usbhost_cpu.h	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,35 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_cpu.h
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+#ifndef  USBHOST_CPU_H
+#define  USBHOST_CPU_H
+
+/*
+**************************************************************************************************************
+*                                           TYPE DEFINITIONS OF DATA TYPES
+**************************************************************************************************************
+*/
+
+typedef  unsigned int    USB_INT32U;
+typedef  signed   int    USB_INT32S;
+typedef  unsigned short  USB_INT16U;
+typedef  signed   short  USB_INT16S;
+typedef  unsigned char   USB_INT08U;
+typedef  signed   char   USB_INT08S;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Include/usbhost_err.h	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,63 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_err.h
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+#ifndef  USBHOST_ERR_H
+#define  USBHOST_ERR_H
+
+
+/*
+**************************************************************************************************************
+*                                        GENERAL DEFINITIONS
+**************************************************************************************************************
+*/
+
+#define  OK                        0
+#define  MATCH_FOUND               0
+
+/*
+**************************************************************************************************************
+*                                HOST CONTROLLER SPECIFIC ERROR CODES
+**************************************************************************************************************
+*/
+
+#define  ERR_TD_FAIL              -1
+
+/*
+**************************************************************************************************************
+*                                  MASS STORAGE SPECIFIC ERROR CODES
+**************************************************************************************************************
+*/
+
+#define  ERR_MS_CMD_FAILED       -10
+#define  ERR_BAD_CONFIGURATION   -11
+#define  ERR_NO_MS_INTERFACE     -12
+
+/*
+**************************************************************************************************************
+*                                      FAT SPECIFIC ERROR CODES
+**************************************************************************************************************
+*/
+
+#define  MATCH_NOT_FOUND         -20
+#define  ERR_FAT_NOT_SUPPORTED   -21
+#define  ERR_OPEN_LIMIT_REACHED  -22
+#define  ERR_INVALID_BOOT_SIG    -23
+#define  ERR_INVALID_BOOT_SEC    -24
+#define  ERR_ROOT_DIR_FULL       -25
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Include/usbhost_inc.h	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,55 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_inc.h
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+#ifndef  USBHOST_INC_H
+#define  USBHOST_INC_H
+
+/*
+**************************************************************************************************************
+*                                       INCLUDE HEADER FILES
+**************************************************************************************************************
+*/
+
+#include  "usbhost_cpu.h"
+#include  "usbhost_err.h"
+//#include  "Uart/usbhost_uart.h"
+#include  "Host/usbhost_lpc17xx.h"
+#include  "MassStorage/usbhost_ms.h"
+#include  "Fat/usbhost_fat.h"
+//#include  "LPC17xx.h"
+#include  "mbed.h"
+
+#ifdef TARGET_LPC2368
+// [iva2k]
+
+// fix for bad define in LPC23xx.h
+#if LPC_USB_BASE != 0xFFE0C000
+#undef LPC_USB_BASE
+#define LPC_USB_BASE 0xFFE0C000
+#define LPC_USB ((LPC_USB_TypeDef *)LPC_USB_BASE)
+#endif
+
+#endif
+
+#ifdef TARGET_LPC2368
+static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+  NVIC->VectPriority[(uint32_t)(IRQn)] = ((priority) & (1 << __NVIC_PRIO_BITS -1 ) ); 
+}
+#endif
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MassStorage/usbhost_ms.c	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,456 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_ms.c
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+/*
+**************************************************************************************************************
+*                                       INCLUDE HEADER FILES
+**************************************************************************************************************
+*/
+
+#include  "usbhost_ms.h"
+
+/*
+**************************************************************************************************************
+*                                         GLOBAL VARIABLES
+**************************************************************************************************************
+*/
+
+USB_INT32U  MS_BlkSize;
+
+/*
+**************************************************************************************************************
+*                                      INITIALIZE MASS STORAGE INTERFACE
+*
+* Description: This function initializes the mass storage interface
+*
+* Arguments  : None
+*
+* Returns    : OK		              if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S MS_Init (USB_INT32U *blkSize, USB_INT32U *numBlks, USB_INT08U *inquiryResult)
+{
+    USB_INT08U  retry;
+    USB_INT32S  rc;
+
+    MS_GetMaxLUN();                                                    /* Get maximum logical unit number   */
+    retry  = 80;
+    while(retry) {
+        rc = MS_TestUnitReady();                                       /* Test whether the unit is ready    */
+        if (rc == OK) {
+            break;
+        }
+        MS_GetSenseInfo();                                             /* Get sense information             */
+        retry--;
+    }
+    if (rc != OK) {
+        PRINT_Err(rc);
+        return (rc);
+    }
+    rc = MS_ReadCapacity(numBlks, blkSize);                         /* Read capacity of the disk         */
+    MS_BlkSize = *blkSize;						// Set global
+    rc = MS_Inquire (inquiryResult);
+    return (rc);
+}
+/*
+**************************************************************************************************************
+*                                         PARSE THE CONFIGURATION
+*
+* Description: This function is used to parse the configuration
+*
+* Arguments  : None
+*
+* Returns    : OK		              if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  MS_ParseConfiguration (void)
+{
+    volatile  USB_INT08U  *desc_ptr;
+              USB_INT08U   ms_int_found;
+
+
+    desc_ptr     = TDBuffer;
+    ms_int_found = 0;
+
+    if (desc_ptr[1] != USB_DESCRIPTOR_TYPE_CONFIGURATION) {    
+        return (ERR_BAD_CONFIGURATION);
+    }
+    desc_ptr += desc_ptr[0];
+
+    while (desc_ptr != TDBuffer + ReadLE16U(&TDBuffer[2])) {
+//  while (desc_ptr != TDBuffer + *((USB_INT16U *) &TDBuffer[2])) {
+
+        switch (desc_ptr[1]) {
+
+            case USB_DESCRIPTOR_TYPE_INTERFACE:                       /* If it is an interface descriptor   */
+                 if (desc_ptr[5] == MASS_STORAGE_CLASS &&             /* check if the class is mass storage */
+                     desc_ptr[6] == MASS_STORAGE_SUBCLASS_SCSI &&     /* check if the subclass is SCSI      */
+                     desc_ptr[7] == MASS_STORAGE_PROTOCOL_BO) {       /* check if the protocol is Bulk only */
+                     ms_int_found = 1;
+                     desc_ptr    += desc_ptr[0];                      /* Move to next descriptor start      */
+                 }
+                 break;
+
+            case USB_DESCRIPTOR_TYPE_ENDPOINT:                        /* If it is an endpoint descriptor    */
+                 if ((desc_ptr[3] & 0x03) == 0x02) {                  /* If it is Bulk endpoint             */
+                     if (desc_ptr[2] & 0x80) {                        /* If it is In endpoint               */
+                         EDBulkIn->Control =  1                             |      /* USB address           */
+                                              ((desc_ptr[2] & 0x7F) << 7)   |      /* Endpoint address      */
+                                              (2 << 11)                     |      /* direction             */
+                                              (ReadLE16U(&desc_ptr[4]) << 16);     /* MaxPkt Size           */
+                         desc_ptr += desc_ptr[0];                     /* Move to next descriptor start      */
+                     } else {                                         /* If it is Out endpoint              */
+                         EDBulkOut->Control = 1                             |      /* USB address           */
+                                              ((desc_ptr[2] & 0x7F) << 7)   |      /* Endpoint address      */
+                                              (1 << 11)                     |      /* direction             */
+                                              (ReadLE16U(&desc_ptr[4]) << 16);     /* MaxPkt Size           */
+                         desc_ptr += desc_ptr[0];                     /* Move to next descriptor start      */
+                     }
+                 } else {                                             /* If it is not bulk end point        */
+                     desc_ptr += desc_ptr[0];                         /* Move to next descriptor start      */
+                 }
+                 break;
+
+            default:                                 /* If the descriptor is neither interface nor endpoint */
+                 desc_ptr += desc_ptr[0];                             /* Move to next descriptor start      */
+                 break;
+        }
+    }
+    if (ms_int_found) {
+        PRINT_Log("Mass Storage device connected\r\n");
+        return (OK);
+    } else {
+        PRINT_Log("Not a Mass Storage device\r\n");
+        return (ERR_NO_MS_INTERFACE);
+    }
+}
+
+/*
+**************************************************************************************************************
+*                                         GET MAXIMUM LOGICAL UNIT
+*
+* Description: This function returns the maximum logical unit from the device
+*
+* Arguments  : None
+*
+* Returns    : OK		              if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  MS_GetMaxLUN (void)
+{
+    USB_INT32S  rc;
+
+
+    rc = Host_CtrlRecv(USB_DEVICE_TO_HOST | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_INTERFACE,
+                       MS_GET_MAX_LUN_REQ,
+                       0,
+                       0,
+                       1,
+                       TDBuffer);
+    return (rc); 
+}
+
+/*
+**************************************************************************************************************
+*                                          GET SENSE INFORMATION
+*
+* Description: This function is used to get sense information from the device
+*
+* Arguments  : None
+*
+* Returns    : OK       if Success
+*              ERROR    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  MS_GetSenseInfo (void)
+{
+    USB_INT32S  rc;
+
+
+    Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_REQUEST_SENSE, 6);
+    rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
+    if (rc == OK) {
+        rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 18);
+        if (rc == OK) {
+            rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
+            if (rc == OK) {
+                if (TDBuffer[12] != 0) {
+                    rc = ERR_MS_CMD_FAILED;
+                }
+            }
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                           TEST UNIT READY
+*
+* Description: This function is used to test whether the unit is ready or not
+*
+* Arguments  : None
+*
+* Returns    : OK       if Success
+*              ERROR    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  MS_TestUnitReady (void)
+{
+    USB_INT32S  rc;
+
+
+    Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_CMD_TEST_UNIT_READY, 6);
+    rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
+    if (rc == OK) {
+        rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
+        if (rc == OK) {        
+            if (TDBuffer[12] != 0) {
+                rc = ERR_MS_CMD_FAILED;
+            }
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                            READ CAPACITY
+*
+* Description: This function is used to read the capacity of the mass storage device
+*
+* Arguments  : None
+*
+* Returns    : OK       if Success
+*              ERROR    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S MS_ReadCapacity (USB_INT32U *numBlks, USB_INT32U *blkSize)
+{
+    USB_INT32S  rc;
+
+
+    Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_READ_CAPACITY, 10);
+    rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
+    if (rc == OK) {
+        rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, 8);
+        if (rc == OK) {
+            if (numBlks)
+            	*numBlks = ReadBE32U(&TDBuffer[0]);
+            if (blkSize)
+            	*blkSize = ReadBE32U(&TDBuffer[4]);
+            rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
+            if (rc == OK) {
+                if (TDBuffer[12] != 0) {
+                    rc = ERR_MS_CMD_FAILED;
+                }
+            }
+        }
+    }
+    return (rc);
+}
+
+
+
+USB_INT32S MS_Inquire (USB_INT08U *response)
+{
+    USB_INT32S rc;
+	USB_INT32U i;
+
+    Fill_MSCommand(0, 0, 0, MS_DATA_DIR_IN, SCSI_CMD_INQUIRY, 6);
+    rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
+    if (rc == OK) {
+        rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, INQUIRY_LENGTH);
+        if (rc == OK) {
+            if (response) {
+				for ( i = 0; i < INQUIRY_LENGTH; i++ )
+					*response++ = *TDBuffer++;
+#if 0
+            	MemCpy (response, TDBuffer, INQUIRY_LENGTH);
+	        	StrNullTrailingSpace (response->vendorID, SCSI_INQUIRY_VENDORCHARS);
+	        	StrNullTrailingSpace (response->productID, SCSI_INQUIRY_PRODUCTCHARS);
+	        	StrNullTrailingSpace (response->productRev, SCSI_INQUIRY_REVCHARS);
+#endif
+            }
+            rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
+            if (rc == OK) {
+                if (TDBuffer[12] != 0) {	// bCSWStatus byte
+                    rc = ERR_MS_CMD_FAILED;
+                }
+            }
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                         RECEIVE THE BULK DATA
+*
+* Description: This function is used to receive the bulk data
+*
+* Arguments  : None
+*
+* Returns    : OK		              if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+    
+USB_INT32S  MS_BulkRecv (          USB_INT32U   block_number,
+                                   USB_INT16U   num_blocks,
+                         volatile  USB_INT08U  *user_buffer)
+{
+    USB_INT32S  rc;
+    int i;
+    volatile USB_INT08U *c = user_buffer;
+    for (i=0;i<MS_BlkSize*num_blocks;i++)
+    	*c++ = 0;
+
+
+    Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_IN, SCSI_CMD_READ_10, 10);
+
+    rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
+    if (rc == OK) {
+        rc = Host_ProcessTD(EDBulkIn, TD_IN, user_buffer, MS_BlkSize * num_blocks);
+        if (rc == OK) {
+            rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
+            if (rc == OK) {
+                if (TDBuffer[12] != 0) {
+                    rc = ERR_MS_CMD_FAILED;
+                }
+            }
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                         SEND BULK DATA
+*
+* Description: This function is used to send the bulk data
+*
+* Arguments  : None
+*
+* Returns    : OK		              if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+USB_INT32S  MS_BulkSend (          USB_INT32U   block_number,
+                                   USB_INT16U   num_blocks,
+                         volatile  USB_INT08U  *user_buffer)
+{
+    USB_INT32S  rc;
+
+
+    Fill_MSCommand(block_number, MS_BlkSize, num_blocks, MS_DATA_DIR_OUT, SCSI_CMD_WRITE_10, 10);
+
+    rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
+    if (rc == OK) {
+        rc = Host_ProcessTD(EDBulkOut, TD_OUT, user_buffer, MS_BlkSize * num_blocks);
+        if (rc == OK) {
+            rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
+            if (rc == OK) {
+                if (TDBuffer[12] != 0) {
+                    rc = ERR_MS_CMD_FAILED;
+                }
+            }
+        }
+    }
+    return (rc);
+}
+
+/*
+**************************************************************************************************************
+*                                         FILL MASS STORAGE COMMAND
+*
+* Description: This function is used to fill the mass storage command
+*
+* Arguments  : None
+*
+* Returns    : OK		              if Success
+*              ERR_INVALID_BOOTSIG    if Failed
+*
+**************************************************************************************************************
+*/
+
+void  Fill_MSCommand (USB_INT32U   block_number,
+                      USB_INT32U   block_size,
+                      USB_INT16U   num_blocks,
+                      MS_DATA_DIR  direction,
+                      USB_INT08U   scsi_cmd,
+                      USB_INT08U   scsi_cmd_len)
+{
+            USB_INT32U  data_len;
+    static  USB_INT32U  tag_cnt = 0;
+            USB_INT32U  cnt;
+
+
+    for (cnt = 0; cnt < CBW_SIZE; cnt++) {
+         TDBuffer[cnt] = 0;
+    }
+    switch(scsi_cmd) {
+
+        case SCSI_CMD_TEST_UNIT_READY:
+             data_len = 0;
+             break;
+        case SCSI_CMD_READ_CAPACITY:
+             data_len = 8;
+             break;
+        case SCSI_CMD_REQUEST_SENSE:
+             data_len = 18;
+             break;
+        case SCSI_CMD_INQUIRY:
+        	 data_len = 36;
+        	 break;
+        default:
+             data_len = block_size * num_blocks;
+             break;
+    }
+    WriteLE32U(TDBuffer, CBW_SIGNATURE);
+    WriteLE32U(&TDBuffer[4], tag_cnt);
+    WriteLE32U(&TDBuffer[8], data_len);
+    TDBuffer[12]     = (direction == MS_DATA_DIR_NONE) ? 0 : direction;
+    TDBuffer[14]     = scsi_cmd_len;                                   /* Length of the CBW                 */
+    TDBuffer[15]     = scsi_cmd;
+    if ((scsi_cmd     == SCSI_CMD_REQUEST_SENSE)
+     || (scsi_cmd     == SCSI_CMD_INQUIRY)) {
+        TDBuffer[19] = (USB_INT08U)data_len;
+    } else {
+        WriteBE32U(&TDBuffer[17], block_number);
+    }
+    WriteBE16U(&TDBuffer[22], num_blocks);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MassStorage/usbhost_ms.h	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,101 @@
+/*
+**************************************************************************************************************
+*                                                 NXP USB Host Stack
+*
+*                                     (c) Copyright 2008, NXP SemiConductors
+*                                     (c) Copyright 2008, OnChip  Technologies LLC
+*                                                 All Rights Reserved
+*
+*                                                  www.nxp.com
+*                                               www.onchiptech.com
+*
+* File           : usbhost_ms.h
+* Programmer(s)  : Ravikanth.P
+* Version        :
+*
+**************************************************************************************************************
+*/
+
+#ifndef  USBHOST_MS_H
+#define  USBHOST_MS_H
+
+/*
+**************************************************************************************************************
+*                                       INCLUDE HEADER FILES
+**************************************************************************************************************
+*/
+
+#include  "usbhost_inc.h"
+
+/*
+**************************************************************************************************************
+*                               MASS STORAGE SPECIFIC DEFINITIONS
+**************************************************************************************************************
+*/
+
+#define    MS_GET_MAX_LUN_REQ            0xFE
+#define    MASS_STORAGE_CLASS            0x08
+#define    MASS_STORAGE_SUBCLASS_SCSI    0x06
+#define    MASS_STORAGE_PROTOCOL_BO      0x50
+
+#define    INQUIRY_LENGTH                36
+/*
+**************************************************************************************************************
+*                                  SCSI SPECIFIC DEFINITIONS
+**************************************************************************************************************
+*/
+
+#define  CBW_SIGNATURE               0x43425355
+#define  CSW_SIGNATURE               0x53425355
+#define  CBW_SIZE                      31
+#define  CSW_SIZE                      13
+#define  CSW_CMD_PASSED              0x00
+#define  SCSI_CMD_REQUEST_SENSE      0x03
+#define  SCSI_CMD_TEST_UNIT_READY    0x00
+#define  SCSI_CMD_INQUIRY            0x12
+#define  SCSI_CMD_READ_10            0x28
+#define  SCSI_CMD_READ_CAPACITY      0x25
+#define  SCSI_CMD_WRITE_10           0x2A
+
+/*
+**************************************************************************************************************
+*                                       TYPE DEFINITIONS
+**************************************************************************************************************
+*/
+
+typedef enum  ms_data_dir {
+
+    MS_DATA_DIR_IN     = 0x80,
+    MS_DATA_DIR_OUT    = 0x00,
+    MS_DATA_DIR_NONE   = 0x01
+
+} MS_DATA_DIR;
+
+/*
+**************************************************************************************************************
+*                                     FUNCTION PROTOTYPES
+**************************************************************************************************************
+*/
+
+USB_INT32S  MS_BulkRecv          (          USB_INT32U    block_number,
+                                            USB_INT16U    num_blocks,
+                                  volatile  USB_INT08U   *user_buffer);
+
+USB_INT32S  MS_BulkSend          (          USB_INT32U    block_number,
+                                            USB_INT16U    num_blocks,
+                                  volatile  USB_INT08U   *user_buffer);
+USB_INT32S  MS_ParseConfiguration(void);
+USB_INT32S  MS_TestUnitReady     (void);
+USB_INT32S  MS_ReadCapacity (USB_INT32U *numBlks, USB_INT32U *blkSize);
+USB_INT32S  MS_GetMaxLUN         (void);
+USB_INT32S  MS_GetSenseInfo      (void);
+USB_INT32S  MS_Init (USB_INT32U *blkSize, USB_INT32U *numBlks, USB_INT08U *inquiryResult);
+USB_INT32S  MS_Inquire (USB_INT08U *response);
+
+void        Fill_MSCommand       (          USB_INT32U    block_number,
+                                            USB_INT32U    block_size,
+                                            USB_INT16U    num_blocks,
+                                            MS_DATA_DIR   direction,
+                                            USB_INT08U    scsi_cmd,
+                                            USB_INT08U    scsi_cmd_len);
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,116 @@
+#include "mbed.h"
+#include "usbhost_inc.h"
+
+void print_clock()
+{
+    int Fin = 12000000; // 12MHz XTAL
+    
+    printf("PLL Registers:\r\n");
+    printf(" - PLL0STAT   = 0x%08X\r\n", LPC_SC->PLL0STAT);
+    printf(" - CLKCFG     = 0x%08X\r\n", LPC_SC->CCLKCFG);
+    printf(" - USBCLKCFG  = 0x%08X\r\n", LPC_SC->USBCLKCFG);
+    
+    int M = (LPC_SC->PLL0STAT & 0x7FFF) + 1;
+    int N = ((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1;
+    int CCLKDIV = LPC_SC->CCLKCFG + 1;
+    int USBDIV = LPC_SC->USBCLKCFG + 1;
+
+    printf("Clock Variables:\r\n");
+    printf(" - Fin = %d\r\n", Fin);
+    printf(" - M   = %d\r\n", M);
+    printf(" - N   = %d\r\n", N);
+    printf(" - CCLKDIV = %d\r\n", CCLKDIV);
+    printf(" - USBCLKDIV = %d\r\n", USBDIV);
+
+    int Fcco = (2 * M * 12000000) / N;
+    int CCLK = Fcco / CCLKDIV;
+
+    printf("Clock Results:\r\n");    
+    printf(" - Fcco = %d\r\n", Fcco);
+    printf(" - CCLK = %d\r\n", CCLK);  
+    printf(" - USB Clock = %d\r\n", Fcco / USBDIV);  
+    printf("System clock: %d\r\n", SystemCoreClock);
+}
+
+/*
+**************************************************************************************************************
+*                                    COPYING A FILE
+*
+* Description: This function is used by the user to copy a file
+*
+* Arguments  : None
+*
+* Returns    : None
+*
+**************************************************************************************************************
+*/
+
+#define FILENAME_R "input.txt"
+#define FILENAME_W "output.txt"
+#define  MAX_BUFFER_SIZE             (4000)
+void Main_Copy (void)
+{
+    USB_INT32S  fdr;
+    USB_INT32S  fdw;
+    USB_INT32U  bytes_read;
+
+
+    fdr = FILE_Open((char *)FILENAME_R, RDONLY);
+    if (fdr > 0) {
+        fdw = FILE_Open((char *)FILENAME_W, RDWR);
+        if (fdw > 0) {
+            PRINT_Log("Copying from %s to %s...\r\n", FILENAME_R, FILENAME_W);
+            do {
+                bytes_read = FILE_Read(fdr, UserBuffer, MAX_BUFFER_SIZE);
+                FILE_Write(fdw, UserBuffer, bytes_read);
+                PRINT_Log(".");
+            } while (bytes_read);
+            PRINT_Log("\r\n");
+            FILE_Close(fdw);
+        } else {
+            PRINT_Log("Could not open file %s\r\n", FILENAME_W);
+            return;
+        }
+        FILE_Close(fdr);
+        PRINT_Log("Copy completed\r\n");
+    } else {
+        PRINT_Log("Could not open file %s\r\n", FILENAME_R);
+        return;
+    }
+}
+
+int main()
+{
+    USB_INT32S  rc;
+    USB_INT32U  numBlks, blkSize;
+    USB_INT08U  inquiryResult[INQUIRY_LENGTH];
+    
+    print_clock();
+//    UART_Init(115200);         /* Initialize the serial port to view the log messages                       */
+    Host_Init();               /* Initialize the  host controller                                    */
+    rc = Host_EnumDev();       /* Enumerate the device connected                                            */
+    if (rc == OK) {
+        /* Initialize the mass storage and scsi interfaces */
+        rc = MS_Init( &blkSize, &numBlks, inquiryResult );
+        if (rc == OK) {
+            rc = FAT_Init();   /* Initialize the FAT16 file system                                          */
+            if (rc == OK) {
+                Main_Copy();   /* Call the application                                                      */
+            } else {
+printf("ERROR %d in FAT_Init()\r\n", rc);
+                while ( 1 );
+            //    return (0);
+            }
+printf("All OK in main()\r\n");
+        } else {
+printf("ERROR %d in MS_Init()\r\n", rc);
+            while ( 1 );
+//            return (0);
+        }
+    } else {                            
+printf("ERROR %d in Host_EnumDev()\r\n", rc);
+        while ( 1 );
+//        return (0);
+    }
+    while(1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Jan 21 01:15:42 2010 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0