USB Host Lite downloaded from NXP web site. Untested! Compiled, dropped on MBED, booted up, and get the console message that it is initializing the stack. I however do not have the ability to connect a USB Memory device to test it.
Revision 0:0826fcc5d020, committed 2010-01-13
- Comitter:
- mshoemaker
- Date:
- Wed Jan 13 01:29:30 2010 +0000
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fat/usbhost_fat.c Wed Jan 13 01:29:30 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 Wed Jan 13 01:29:30 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 Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,794 @@ +/* +************************************************************************************************************** +* 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; + + LPC_SC->PCONP |= (1UL<<31); + LPC_USB->OTGClkCtrl = 0x0000001F; + while ((LPC_USB->OTGClkSt & 0x0000001F) == 0) { /* Host clock is available */ + ; + } + + LPC_USB->OTGStCtrl = 0x3; + + /* P1[18] = USB_UP_LED, 01 */ + /* P1[19] = /USB_PPWR, 10 */ + /* P1[22] = USB_PWRD, 10 */ + /* P1[27] = /USB_OVRCR, 10 */ + LPC_PINCON->PINSEL3 &= ~((3<<4) | (3<<6) | (3<<12) | (3<<22)); + LPC_PINCON->PINSEL3 |= ((1<<4)|(2<<6) | (2<<12) | (2<<22)); // 0x00802080 + + /* 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\n"); + + // For chip revision V01 and later + HostBaseAddr = 0x20080000; + + 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 */ + Host_EDInit(EDCtrl); + Host_EDInit(EDBulkIn); + Host_EDInit(EDBulkOut); + Host_TDInit(TDHead); + Host_TDInit(TDTail); + Host_HCCAInit(Hcca); + + + 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; + + + + /* Enable the USB Interrupt */ + NVIC_EnableIRQ(USB_IRQn); /* enable USB interrupt */ + NVIC_SetPriority (USB_IRQn, 0); /* highest priority */ + + + PRINT_Log("Host Initialized\n"); +} + +/* +************************************************************************************************************** +* INTERRUPT SERVICE ROUTINE +* +* Description: This function services the interrupt caused by host controller +* +* Arguments : None +* +* Returns : None +* +************************************************************************************************************** +*/ + +void USB_IRQHandler (void) +{ + 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 */ + + 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)?\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)?\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 */ + } + 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\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 Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,256 @@ +/* +************************************************************************************************************** +* 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(...) UART_Printf(__VA_ARGS__) +#define PRINT_Err(rc) UART_Printf("ERROR: In %s at Line %u - rc = %d\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); + +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 Wed Jan 13 01:29:30 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 Wed Jan 13 01:29:30 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 Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,36 @@ +/* +************************************************************************************************************** +* 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" + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Main/usbhost_main.c Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,189 @@ +/* +************************************************************************************************************** +* 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_main.c +* Programmer(s) : Ravikanth.P +* Version : +* +************************************************************************************************************** +*/ + +/* +************************************************************************************************************** +* INCLUDE HEADER FILES +************************************************************************************************************** +*/ + +#include "usbhost_main.h" + +/* +************************************************************************************************************** +* MAIN FUNCTION +* +* Description: This function is the main function where the execution begins +* +* Arguments : None +* +* Returns : +* +************************************************************************************************************** +*/ + +int main() +{ + USB_INT32S rc; + USB_INT32U numBlks, blkSize; + USB_INT08U inquiryResult[INQUIRY_LENGTH]; + + SystemInit(); /* initialize clocks */ + + UART_Init(115200); /* Initialize the serial port to view the log messages */ + Host_Init(); /* Initialize the lpc17xx 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 { + return (0); + } + } else { + return (0); + } + } else { + return (0); + } + while(1); +} + +/* +************************************************************************************************************** +* READ DATA FROM DISK +* +* Description: This function is used by the user to read data from the disk +* +* Arguments : None +* +* Returns : None +* +************************************************************************************************************** +*/ + +void Main_Read (void) +{ + USB_INT32S fdr; + USB_INT32U bytes_read; + + + fdr = FILE_Open((char *)FILENAME_R, RDONLY); + if (fdr > 0) { + PRINT_Log("Reading from %s...\n", FILENAME_R); + do { + bytes_read = FILE_Read(fdr, UserBuffer, MAX_BUFFER_SIZE); + } while (bytes_read); + + FILE_Close(fdr); + PRINT_Log("Read Complete\n"); + } else { + PRINT_Log("Could not open file %s\n", FILENAME_R); + return; + } +} + +/* +************************************************************************************************************** +* WRITE DATA TO DISK +* +* Description: This function is used by the user to write data to disk +* +* Arguments : None +* +* Returns : None +* +************************************************************************************************************** +*/ + +void Main_Write (void) +{ + USB_INT32S fdw; + USB_INT32S fdr; + USB_INT32U tot_bytes_written; + USB_INT32U bytes_written; + + + fdr = FILE_Open((char *)FILENAME_R, RDONLY); + if (fdr > 0) { + FILE_Read(fdr, UserBuffer, MAX_BUFFER_SIZE); + fdw = FILE_Open((char *)FILENAME_W, RDWR); + if (fdw > 0) { + tot_bytes_written = 0; + PRINT_Log("Writing to %s...\n", FILENAME_W); + do { + bytes_written = FILE_Write(fdw, UserBuffer, MAX_BUFFER_SIZE); + tot_bytes_written += bytes_written; + } while (tot_bytes_written < WRITE_SIZE); + FILE_Close(fdw); + PRINT_Log("Write completed\n"); + } else { + PRINT_Log("Could not open file %s\n", FILENAME_W); + return; + } + FILE_Close(fdr); + } else { + PRINT_Log("Could not open file %s\n", FILENAME_R); + return; + } +} + +/* +************************************************************************************************************** +* COPYING A FILE +* +* Description: This function is used by the user to copy a file +* +* Arguments : None +* +* Returns : None +* +************************************************************************************************************** +*/ + +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...\n", FILENAME_R, FILENAME_W); + do { + bytes_read = FILE_Read(fdr, UserBuffer, MAX_BUFFER_SIZE); + FILE_Write(fdw, UserBuffer, bytes_read); + } while (bytes_read); + FILE_Close(fdw); + } else { + PRINT_Log("Could not open file %s\n", FILENAME_W); + return; + } + FILE_Close(fdr); + PRINT_Log("Copy completed\n"); + } else { + PRINT_Log("Could not open file %s\n", FILENAME_R); + return; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Main/usbhost_main.h Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,52 @@ +/* +************************************************************************************************************** +* 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_main.h +* Programmer(s) : Ravikanth.P +* Version : +* +************************************************************************************************************** +*/ + +#ifndef USBHOST_MAIN_H +#define USBHOST_MAIN_H + +/* +************************************************************************************************************** +* DEFINITIONS +************************************************************************************************************** +*/ + +#include "usbhost_inc.h" + +/* +************************************************************************************************************** +* DEFINITIONS +************************************************************************************************************** +*/ + +#define FILENAME_R "MSREAD.TXT" +#define FILENAME_W "MSWRITE.TXT" + +#define MAX_BUFFER_SIZE (4000) +#define WRITE_SIZE (10 * 1000000) + +/* +************************************************************************************************************** +* FUNCTION PROTOTYPES +************************************************************************************************************** +*/ + +void Main_Read (void); +void Main_Write(void); +void Main_Copy (void); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MassStorage/usbhost_ms.c Wed Jan 13 01:29:30 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\n"); + return (OK); + } else { + PRINT_Log("Not a Mass Storage device\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 Wed Jan 13 01:29:30 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/Uart/usbhost_uart.c Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,144 @@ +/* +************************************************************************************************************** +* 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_uart.c +* Programmer(s) : Prasad.K.R.S.V +* Version : +* +************************************************************************************************************** +*/ + +/* +************************************************************************************************************** +* INCLUDE HEADER FILES +************************************************************************************************************** +*/ + +#include "usbhost_uart.h" + +/* +************************************************************************************************************** +* INITIALIZE UART +* +* Description: This function initializes UART port, setup pin select, clock, parity, stopbits, FIFO etc +* +* Arguments : baud_rate UART baud rate (115200) +* +* Returns : None +* +************************************************************************************************************** +*/ + +void UART_Init(USB_INT32U baudrate) +{ + USB_INT32U Fdiv; + USB_INT32U pclkdiv, pclk; + uint32_t SystemFrequency = SystemCoreClock; + + LPC_PINCON->PINSEL0 |= 0x00000050; /* RxD0 and TxD0 */ + + LPC_UART0->LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */ + /* Bit 6~7 is for UART0 clock divider. */ + pclkdiv = (LPC_SC->PCLKSEL0 >> 6) & 0x03; + switch ( pclkdiv ) + { + case 0x00: + default: + pclk = SystemFrequency/4; + break; + case 0x01: + pclk = SystemFrequency; + break; + case 0x02: + pclk = SystemFrequency/2; + break; + case 0x03: + pclk = SystemFrequency/8; + break; + } + Fdiv = ( pclk / 16 ) / baudrate ; /*baud rate */ + + LPC_UART0->DLM = Fdiv / 256; + LPC_UART0->DLL = Fdiv % 256; + LPC_UART0->LCR = 0x03; /* DLAB = 0 */ + LPC_UART0->FCR = 0x07; /* Enable and reset TX and RX FIFO. */ +} + +/* +************************************************************************************************************** +* PRINT CHARECTER +* +* Description: This function is used to print a single charecter through UART1. +* +* Arguments : ch charecter to be printed +* +* Returns : None +* +************************************************************************************************************** +*/ + +void UART_PrintChar (USB_INT08U ch) +{ + + while (!(LPC_UART0->LSR & 0x20)); + LPC_UART0->THR = ch; +} + +/* +************************************************************************************************************** +* PRINT STRING +* +* Description: This function is used to print a string +* +* Arguments : str Pointer to the string +* +* Returns : None +* +************************************************************************************************************** +*/ + +void UART_PrintStr (const USB_INT08U * str) +{ + + while ((*str) != 0) { + if (*str == '\n') { + UART_PrintChar(*str++); + UART_PrintChar('\r'); + } else { + UART_PrintChar(*str++); + } + } +} + +/* +************************************************************************************************************** +* PRINT FORMATTED STRING +* +* Description: This function is used to print formatted string. This function takes variable length arguments +* +* Arguments : variable length arguments +* +* Returns : None +* +************************************************************************************************************** +*/ + +void UART_Printf (const USB_INT08U *format, ...) +{ + static USB_INT08U buffer[40 + 1]; + va_list vArgs; + + + va_start(vArgs, format); + vsprintf((char *)buffer, (char const *)format, vArgs); + va_end(vArgs); + UART_PrintStr((USB_INT08U*) buffer); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Uart/usbhost_uart.h Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,51 @@ +/* +************************************************************************************************************** +* 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_uart.h +* Programmer(s) : Prasad.K.R.S.V +* Version : +* +************************************************************************************************************** +*/ + +#ifndef USBHOST_UART_H +#define USBHOST_UART_H + +/* +************************************************************************************************************** +* INCLUDE HEADER FILES +************************************************************************************************************** +*/ + +#include <stdarg.h> +#include <stdio.h> +#include "usbhost_inc.h" + +/* +************************************************************************************************************** +* UART DEFINITIONS +************************************************************************************************************** +*/ +//#define Fcclk 48000000 +//#define Fpclk (Fcclk / 2) + +/* +************************************************************************************************************** +* FUNCTION PROTOTYPES +************************************************************************************************************** +*/ + +void UART_Init ( USB_INT32U baudrate); +void UART_PrintChar ( USB_INT08U ch); +void UART_PrintStr (const USB_INT08U *str); +void UART_Printf(const USB_INT08U *format, ...); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jan 13 01:29:30 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0