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.

Dependencies:   mbed

Committer:
mshoemaker
Date:
Wed Jan 13 01:29:30 2010 +0000
Revision:
0:0826fcc5d020

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mshoemaker 0:0826fcc5d020 1 /*
mshoemaker 0:0826fcc5d020 2 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 3 * NXP USB Host Stack
mshoemaker 0:0826fcc5d020 4 *
mshoemaker 0:0826fcc5d020 5 * (c) Copyright 2008, NXP SemiConductors
mshoemaker 0:0826fcc5d020 6 * (c) Copyright 2008, OnChip Technologies LLC
mshoemaker 0:0826fcc5d020 7 * All Rights Reserved
mshoemaker 0:0826fcc5d020 8 *
mshoemaker 0:0826fcc5d020 9 * www.nxp.com
mshoemaker 0:0826fcc5d020 10 * www.onchiptech.com
mshoemaker 0:0826fcc5d020 11 *
mshoemaker 0:0826fcc5d020 12 * File : usbhost_fat.c
mshoemaker 0:0826fcc5d020 13 * Programmer(s) : Ravikanth.P
mshoemaker 0:0826fcc5d020 14 * Version :
mshoemaker 0:0826fcc5d020 15 *
mshoemaker 0:0826fcc5d020 16 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 17 */
mshoemaker 0:0826fcc5d020 18
mshoemaker 0:0826fcc5d020 19 /*
mshoemaker 0:0826fcc5d020 20 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 21 * INCLUDE HEADER FILES
mshoemaker 0:0826fcc5d020 22 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 23 */
mshoemaker 0:0826fcc5d020 24
mshoemaker 0:0826fcc5d020 25 #include "usbhost_fat.h"
mshoemaker 0:0826fcc5d020 26
mshoemaker 0:0826fcc5d020 27 /*
mshoemaker 0:0826fcc5d020 28 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 29 * GLOBAL VARIABLES
mshoemaker 0:0826fcc5d020 30 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 31 */
mshoemaker 0:0826fcc5d020 32
mshoemaker 0:0826fcc5d020 33 #define MAX_FILE_DESCRIPTORS 2
mshoemaker 0:0826fcc5d020 34 static BOOT_SEC FAT_BootSec;
mshoemaker 0:0826fcc5d020 35 static FILE_ENTRY FAT_FileEntry[MAX_FILE_DESCRIPTORS];
mshoemaker 0:0826fcc5d020 36
mshoemaker 0:0826fcc5d020 37 /*
mshoemaker 0:0826fcc5d020 38 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 39 * INITIALIZE THE FILE SYSTEM
mshoemaker 0:0826fcc5d020 40 *
mshoemaker 0:0826fcc5d020 41 * Description: This function initializes the FAT16 file system
mshoemaker 0:0826fcc5d020 42 *
mshoemaker 0:0826fcc5d020 43 * Arguments : None
mshoemaker 0:0826fcc5d020 44 *
mshoemaker 0:0826fcc5d020 45 * Returns : OK if Success
mshoemaker 0:0826fcc5d020 46 * ERR_INVALID_BOOTSIG if Failed
mshoemaker 0:0826fcc5d020 47 *
mshoemaker 0:0826fcc5d020 48 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 49 */
mshoemaker 0:0826fcc5d020 50
mshoemaker 0:0826fcc5d020 51 USB_INT32S FAT_Init (void)
mshoemaker 0:0826fcc5d020 52 {
mshoemaker 0:0826fcc5d020 53 USB_INT16U boot_sig;
mshoemaker 0:0826fcc5d020 54 USB_INT32S rc, i;
mshoemaker 0:0826fcc5d020 55 FILE_ENTRY *entry;
mshoemaker 0:0826fcc5d020 56
mshoemaker 0:0826fcc5d020 57 for (i=0;i<MAX_FILE_DESCRIPTORS;i++) {
mshoemaker 0:0826fcc5d020 58 entry = &FAT_FileEntry[i];
mshoemaker 0:0826fcc5d020 59 entry->CurrClus = 0;
mshoemaker 0:0826fcc5d020 60 entry->CurrClusOffset = 0;
mshoemaker 0:0826fcc5d020 61 entry->FileSize = 0;
mshoemaker 0:0826fcc5d020 62 entry->EntrySec = 0;
mshoemaker 0:0826fcc5d020 63 entry->EntrySecOffset = 0;
mshoemaker 0:0826fcc5d020 64 entry->FileStatus = 0;
mshoemaker 0:0826fcc5d020 65 }
mshoemaker 0:0826fcc5d020 66
mshoemaker 0:0826fcc5d020 67 MS_BulkRecv(0, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 68 boot_sig = ReadLE16U(&FATBuffer[510]);
mshoemaker 0:0826fcc5d020 69 if (boot_sig != 0xAA55) {
mshoemaker 0:0826fcc5d020 70 rc = ERR_INVALID_BOOT_SIG;
mshoemaker 0:0826fcc5d020 71 } else {
mshoemaker 0:0826fcc5d020 72 if (FATBuffer[0] != 0xEB && FATBuffer[0] != 0xE9) {
mshoemaker 0:0826fcc5d020 73 FAT_BootSec.BootSecOffset = ReadLE32U(&FATBuffer[454]);
mshoemaker 0:0826fcc5d020 74 MS_BulkRecv(FAT_BootSec.BootSecOffset, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 75 }
mshoemaker 0:0826fcc5d020 76 FAT_BootSec.BytsPerSec = ReadLE16U(&FATBuffer[11]); /* Bytes per cluster */
mshoemaker 0:0826fcc5d020 77 FAT_BootSec.SecPerClus = FATBuffer[13]; /* Sectors per cluster */
mshoemaker 0:0826fcc5d020 78 /* Reserved sector count */
mshoemaker 0:0826fcc5d020 79 FAT_BootSec.RsvdSecCnt = ReadLE16U(&FATBuffer[14]) + FAT_BootSec.BootSecOffset;
mshoemaker 0:0826fcc5d020 80 FAT_BootSec.NumFATs = FATBuffer[16]; /* Number of FAT copies */
mshoemaker 0:0826fcc5d020 81 FAT_BootSec.RootEntCnt = ReadLE16U(&FATBuffer[17]); /* Root entry count */
mshoemaker 0:0826fcc5d020 82 FAT_BootSec.TotSec16 = ReadLE16U(&FATBuffer[19]); /* Total FAT16 sectors */
mshoemaker 0:0826fcc5d020 83 FAT_BootSec.TotSec32 = ReadLE32U(&FATBuffer[32]); /* Total FAT32 sectors */
mshoemaker 0:0826fcc5d020 84 FAT_BootSec.FATSz16 = ReadLE16U(&FATBuffer[22]); /* Size of the FAT table */
mshoemaker 0:0826fcc5d020 85 /* Bytes per cluster */
mshoemaker 0:0826fcc5d020 86 FAT_BootSec.BytsPerClus = (FAT_BootSec.BytsPerSec * FAT_BootSec.SecPerClus);
mshoemaker 0:0826fcc5d020 87 /* Root directory starting sector */
mshoemaker 0:0826fcc5d020 88 FAT_BootSec.RootDirStartSec = FAT_BootSec.RsvdSecCnt + (FAT_BootSec.FATSz16 * FAT_BootSec.NumFATs);
mshoemaker 0:0826fcc5d020 89 /* Sectors occupied by root directory */
mshoemaker 0:0826fcc5d020 90 FAT_BootSec.RootDirSec = ((FAT_BootSec.RootEntCnt * 32) + (FAT_BootSec.BytsPerSec - 1)) /
mshoemaker 0:0826fcc5d020 91 (FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 92 /* First data sector */
mshoemaker 0:0826fcc5d020 93 FAT_BootSec.FirstDataSec = FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec;
mshoemaker 0:0826fcc5d020 94 FAT_BootSec.FATType = FAT_GetFATType(); /* Type of FAT */
mshoemaker 0:0826fcc5d020 95 if (FAT_BootSec.FATType == FAT_16) {
mshoemaker 0:0826fcc5d020 96 rc = OK;
mshoemaker 0:0826fcc5d020 97 } else {
mshoemaker 0:0826fcc5d020 98 rc = ERR_FAT_NOT_SUPPORTED;
mshoemaker 0:0826fcc5d020 99 PRINT_Err(rc);
mshoemaker 0:0826fcc5d020 100 }
mshoemaker 0:0826fcc5d020 101 }
mshoemaker 0:0826fcc5d020 102 return (rc);
mshoemaker 0:0826fcc5d020 103 }
mshoemaker 0:0826fcc5d020 104
mshoemaker 0:0826fcc5d020 105 /*
mshoemaker 0:0826fcc5d020 106 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 107 * GET FILE SYSTEM TYPE
mshoemaker 0:0826fcc5d020 108 *
mshoemaker 0:0826fcc5d020 109 * Description: This function returns the file system type with which the disk is formatted
mshoemaker 0:0826fcc5d020 110 *
mshoemaker 0:0826fcc5d020 111 * Arguments : None
mshoemaker 0:0826fcc5d020 112 *
mshoemaker 0:0826fcc5d020 113 * Returns : FAT16 On Success
mshoemaker 0:0826fcc5d020 114 * ERR_FAT_TYPE On Failure
mshoemaker 0:0826fcc5d020 115 *
mshoemaker 0:0826fcc5d020 116 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 117 */
mshoemaker 0:0826fcc5d020 118
mshoemaker 0:0826fcc5d020 119 USB_INT08U FAT_GetFATType (void)
mshoemaker 0:0826fcc5d020 120 {
mshoemaker 0:0826fcc5d020 121 USB_INT08U fat_type;
mshoemaker 0:0826fcc5d020 122 USB_INT32U tot_sec;
mshoemaker 0:0826fcc5d020 123 USB_INT32U tot_data_clus;
mshoemaker 0:0826fcc5d020 124
mshoemaker 0:0826fcc5d020 125
mshoemaker 0:0826fcc5d020 126 if (FAT_BootSec.TotSec16 != 0) { /* Get total sectors in the disk */
mshoemaker 0:0826fcc5d020 127 tot_sec = FAT_BootSec.TotSec16;
mshoemaker 0:0826fcc5d020 128 } else {
mshoemaker 0:0826fcc5d020 129 tot_sec = FAT_BootSec.TotSec32;
mshoemaker 0:0826fcc5d020 130 }
mshoemaker 0:0826fcc5d020 131
mshoemaker 0:0826fcc5d020 132 tot_data_clus = tot_sec / (FAT_BootSec.SecPerClus); /* Get total data clusters in the disk */
mshoemaker 0:0826fcc5d020 133 /* If total data clusters >= 4085 and */
mshoemaker 0:0826fcc5d020 134 /* < 65525, then it is FAT16 file system */
mshoemaker 0:0826fcc5d020 135 if (tot_data_clus >= 4085 && tot_data_clus < 65525) {
mshoemaker 0:0826fcc5d020 136 fat_type = FAT_16;
mshoemaker 0:0826fcc5d020 137 } else {
mshoemaker 0:0826fcc5d020 138 fat_type = 0;
mshoemaker 0:0826fcc5d020 139 }
mshoemaker 0:0826fcc5d020 140
mshoemaker 0:0826fcc5d020 141 return (fat_type);
mshoemaker 0:0826fcc5d020 142 }
mshoemaker 0:0826fcc5d020 143
mshoemaker 0:0826fcc5d020 144 /*
mshoemaker 0:0826fcc5d020 145 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 146 * OPENING A FILE
mshoemaker 0:0826fcc5d020 147 *
mshoemaker 0:0826fcc5d020 148 * Description: This function stores the attributes of a file, such as starting cluster, file size,
mshoemaker 0:0826fcc5d020 149 * sector where the file entry is stored and offset of the entry in that sector
mshoemaker 0:0826fcc5d020 150 *
mshoemaker 0:0826fcc5d020 151 * Arguments : file_name Name of the file. The file must be in root directory.
mshoemaker 0:0826fcc5d020 152 *
mshoemaker 0:0826fcc5d020 153 * Returns : pointer to the entry On Success
mshoemaker 0:0826fcc5d020 154 * NULL On Failure
mshoemaker 0:0826fcc5d020 155 *
mshoemaker 0:0826fcc5d020 156 * Modifed 6/9/08 WCB returns a file descriptor which is the INDEX+1 to the entry.
mshoemaker 0:0826fcc5d020 157 * returning the entry address itself could be interpreted as a negative number --
mshoemaker 0:0826fcc5d020 158 * and thus an error -- for memory locations of 0x80000000 and above. We return
mshoemaker 0:0826fcc5d020 159 * INDEX+1 instead of just the index to avoid returning a file descriptor of zero,
mshoemaker 0:0826fcc5d020 160 * which could be potentially confused with an error.
mshoemaker 0:0826fcc5d020 161 *
mshoemaker 0:0826fcc5d020 162 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 163 */
mshoemaker 0:0826fcc5d020 164
mshoemaker 0:0826fcc5d020 165 USB_INT32S FILE_Open (USB_INT08U *file_name,
mshoemaker 0:0826fcc5d020 166 USB_INT08U flags)
mshoemaker 0:0826fcc5d020 167 {
mshoemaker 0:0826fcc5d020 168 USB_INT32S rc;
mshoemaker 0:0826fcc5d020 169 FILE_ENTRY *entry = 0;
mshoemaker 0:0826fcc5d020 170 USB_INT32S fd = -1;
mshoemaker 0:0826fcc5d020 171
mshoemaker 0:0826fcc5d020 172 do {
mshoemaker 0:0826fcc5d020 173 if (FAT_FileEntry[++fd].FileStatus == 0)
mshoemaker 0:0826fcc5d020 174 entry = &FAT_FileEntry[fd];
mshoemaker 0:0826fcc5d020 175 } while ((entry == 0) && (fd < MAX_FILE_DESCRIPTORS-1));
mshoemaker 0:0826fcc5d020 176 if (entry == 0) {
mshoemaker 0:0826fcc5d020 177 return (ERR_OPEN_LIMIT_REACHED);
mshoemaker 0:0826fcc5d020 178 }
mshoemaker 0:0826fcc5d020 179 if (flags == RDONLY) { /* Search for a file. If it doesn't exist, don't create it */
mshoemaker 0:0826fcc5d020 180 rc = FAT_FindEntry(file_name, entry);
mshoemaker 0:0826fcc5d020 181 if (rc == MATCH_FOUND) {
mshoemaker 0:0826fcc5d020 182 entry->FileStatus = 1;
mshoemaker 0:0826fcc5d020 183 rc = fd+1;
mshoemaker 0:0826fcc5d020 184 }
mshoemaker 0:0826fcc5d020 185 } else { /* Search for a file. If it doesn't exist, create it */
mshoemaker 0:0826fcc5d020 186 rc = FAT_CreateEntry(file_name, entry);
mshoemaker 0:0826fcc5d020 187 if (rc == MATCH_FOUND) {
mshoemaker 0:0826fcc5d020 188 entry->FileStatus = 1;
mshoemaker 0:0826fcc5d020 189 rc = fd+1;
mshoemaker 0:0826fcc5d020 190 }
mshoemaker 0:0826fcc5d020 191 }
mshoemaker 0:0826fcc5d020 192 return (rc);
mshoemaker 0:0826fcc5d020 193 }
mshoemaker 0:0826fcc5d020 194
mshoemaker 0:0826fcc5d020 195 /*
mshoemaker 0:0826fcc5d020 196 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 197 * FINDING AN ENTRY
mshoemaker 0:0826fcc5d020 198 *
mshoemaker 0:0826fcc5d020 199 * Description: This function searches for a file name in the root directory
mshoemaker 0:0826fcc5d020 200 *
mshoemaker 0:0826fcc5d020 201 * Arguments : ent_name_given Pointer to the file name to be searched.
mshoemaker 0:0826fcc5d020 202 * entry Pointer to the entry structure. The attributes of the file are stored in this
mshoemaker 0:0826fcc5d020 203 * structure if the file was found in the root directory.
mshoemaker 0:0826fcc5d020 204 *
mshoemaker 0:0826fcc5d020 205 * Returns : MATCH_FOUND if the file was found in the root directory.
mshoemaker 0:0826fcc5d020 206 * MATCH_NOT_FOUND if the file was not found in the root directory.
mshoemaker 0:0826fcc5d020 207 *
mshoemaker 0:0826fcc5d020 208 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 209 */
mshoemaker 0:0826fcc5d020 210
mshoemaker 0:0826fcc5d020 211 USB_INT32S FAT_FindEntry (USB_INT08U *ent_name_given,
mshoemaker 0:0826fcc5d020 212 FILE_ENTRY *entry)
mshoemaker 0:0826fcc5d020 213 {
mshoemaker 0:0826fcc5d020 214 USB_INT32U sec_num;
mshoemaker 0:0826fcc5d020 215 volatile USB_INT08U *buf;
mshoemaker 0:0826fcc5d020 216 USB_INT08U ent_type;
mshoemaker 0:0826fcc5d020 217 USB_INT08U ent_name_read[13];
mshoemaker 0:0826fcc5d020 218
mshoemaker 0:0826fcc5d020 219
mshoemaker 0:0826fcc5d020 220 for (sec_num = FAT_BootSec.RootDirStartSec; /* For all the sectors in root directory */
mshoemaker 0:0826fcc5d020 221 sec_num < (FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec);
mshoemaker 0:0826fcc5d020 222 sec_num++) {
mshoemaker 0:0826fcc5d020 223
mshoemaker 0:0826fcc5d020 224
mshoemaker 0:0826fcc5d020 225 MS_BulkRecv(sec_num, 1, FATBuffer); /* Read one sector */
mshoemaker 0:0826fcc5d020 226 buf = FATBuffer;
mshoemaker 0:0826fcc5d020 227 while (buf < (FATBuffer + FAT_BootSec.BytsPerSec)) {
mshoemaker 0:0826fcc5d020 228 ent_type = FAT_ChkEntType(buf); /* Check for the entry type */
mshoemaker 0:0826fcc5d020 229 if (ent_type == SFN_ENTRY) { /* If it is short entry get short file name */
mshoemaker 0:0826fcc5d020 230 FAT_GetSFN(buf, ent_name_read);
mshoemaker 0:0826fcc5d020 231 /* Compare given name with this name case insensitively */
mshoemaker 0:0826fcc5d020 232 if (FAT_StrCaseCmp(ent_name_given, ent_name_read) == MATCH_FOUND) {
mshoemaker 0:0826fcc5d020 233 entry->CurrClus = ReadLE16U(&buf[26]); /* If they are same, get starting cluster */
mshoemaker 0:0826fcc5d020 234 entry->FileSize = ReadLE32U(&buf[28]); /* Get file size */
mshoemaker 0:0826fcc5d020 235 entry->EntrySec = sec_num; /* Get sector number where the filename is located */
mshoemaker 0:0826fcc5d020 236 /* Get offset in this sector where the filename is located */
mshoemaker 0:0826fcc5d020 237 entry->EntrySecOffset = buf - FATBuffer;
mshoemaker 0:0826fcc5d020 238 return (MATCH_FOUND);
mshoemaker 0:0826fcc5d020 239 }
mshoemaker 0:0826fcc5d020 240 }
mshoemaker 0:0826fcc5d020 241 if (ent_type == LAST_ENTRY) { /* If it is the last entry, no more entries will exist. Return */
mshoemaker 0:0826fcc5d020 242 return (MATCH_NOT_FOUND);
mshoemaker 0:0826fcc5d020 243 }
mshoemaker 0:0826fcc5d020 244 buf = buf + 32; /* Move to the next entry */
mshoemaker 0:0826fcc5d020 245 }
mshoemaker 0:0826fcc5d020 246 }
mshoemaker 0:0826fcc5d020 247 return (MATCH_NOT_FOUND);
mshoemaker 0:0826fcc5d020 248 }
mshoemaker 0:0826fcc5d020 249
mshoemaker 0:0826fcc5d020 250 /*
mshoemaker 0:0826fcc5d020 251 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 252 * GET SHORT FILE NAME AND EXTENSION OF A FILE
mshoemaker 0:0826fcc5d020 253 *
mshoemaker 0:0826fcc5d020 254 * Description: This function reads the short file name and extension corresponding to a file
mshoemaker 0:0826fcc5d020 255 *
mshoemaker 0:0826fcc5d020 256 * Arguments : ent_buf buffer which contains the 32 byte entry of a file
mshoemaker 0:0826fcc5d020 257 * name buffer to store the file name and extension of a file
mshoemaker 0:0826fcc5d020 258 *
mshoemaker 0:0826fcc5d020 259 * Returns : None
mshoemaker 0:0826fcc5d020 260 *
mshoemaker 0:0826fcc5d020 261 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 262 */
mshoemaker 0:0826fcc5d020 263
mshoemaker 0:0826fcc5d020 264 void FAT_GetSFN (volatile USB_INT08U *entry,
mshoemaker 0:0826fcc5d020 265 USB_INT08U *name)
mshoemaker 0:0826fcc5d020 266 {
mshoemaker 0:0826fcc5d020 267 USB_INT08U ext[4]; /* Buffer to store the extension of a file */
mshoemaker 0:0826fcc5d020 268 USB_INT08U *ext_ptr;
mshoemaker 0:0826fcc5d020 269
mshoemaker 0:0826fcc5d020 270
mshoemaker 0:0826fcc5d020 271 ext_ptr = ext;
mshoemaker 0:0826fcc5d020 272
mshoemaker 0:0826fcc5d020 273 FAT_GetSfnName(entry, name); /* Get file name into "name" buffer */
mshoemaker 0:0826fcc5d020 274 FAT_GetSfnExt(entry, ext_ptr); /* Get extension into "ext" buffer */
mshoemaker 0:0826fcc5d020 275
mshoemaker 0:0826fcc5d020 276 while (*name) { /* Goto the end of the filename */
mshoemaker 0:0826fcc5d020 277 name++;
mshoemaker 0:0826fcc5d020 278 }
mshoemaker 0:0826fcc5d020 279 if (*ext_ptr) { /* If the extension exists, put a '.' charecter */
mshoemaker 0:0826fcc5d020 280 *name = '.';
mshoemaker 0:0826fcc5d020 281 name++;
mshoemaker 0:0826fcc5d020 282 }
mshoemaker 0:0826fcc5d020 283 while (*ext_ptr) { /* Append the extension to the file name */
mshoemaker 0:0826fcc5d020 284 *name = *ext_ptr;
mshoemaker 0:0826fcc5d020 285 name++;
mshoemaker 0:0826fcc5d020 286 ext_ptr++;
mshoemaker 0:0826fcc5d020 287 }
mshoemaker 0:0826fcc5d020 288 *name = '\0';
mshoemaker 0:0826fcc5d020 289 }
mshoemaker 0:0826fcc5d020 290
mshoemaker 0:0826fcc5d020 291 /*
mshoemaker 0:0826fcc5d020 292 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 293 * GET SHORT FILE NAME OF A FILE
mshoemaker 0:0826fcc5d020 294 *
mshoemaker 0:0826fcc5d020 295 * Description: This function reads the short file name of a file
mshoemaker 0:0826fcc5d020 296 *
mshoemaker 0:0826fcc5d020 297 * Arguments : ent_buf buffer which contains the 32 byte entry of a file
mshoemaker 0:0826fcc5d020 298 * name buffer to store the short file name of a file
mshoemaker 0:0826fcc5d020 299 *
mshoemaker 0:0826fcc5d020 300 * Returns : None
mshoemaker 0:0826fcc5d020 301 *
mshoemaker 0:0826fcc5d020 302 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 303 */
mshoemaker 0:0826fcc5d020 304
mshoemaker 0:0826fcc5d020 305 void FAT_GetSfnName (volatile USB_INT08U *entry,
mshoemaker 0:0826fcc5d020 306 USB_INT08U *name)
mshoemaker 0:0826fcc5d020 307 {
mshoemaker 0:0826fcc5d020 308 USB_INT32U cnt;
mshoemaker 0:0826fcc5d020 309
mshoemaker 0:0826fcc5d020 310
mshoemaker 0:0826fcc5d020 311 cnt = 0;
mshoemaker 0:0826fcc5d020 312 while (cnt < 8) {
mshoemaker 0:0826fcc5d020 313 *name = *entry; /* Get first 8 charecters of an SFN entry */
mshoemaker 0:0826fcc5d020 314 name++;
mshoemaker 0:0826fcc5d020 315 entry++;
mshoemaker 0:0826fcc5d020 316 cnt++;
mshoemaker 0:0826fcc5d020 317 }
mshoemaker 0:0826fcc5d020 318 *name = 0;
mshoemaker 0:0826fcc5d020 319 name--;
mshoemaker 0:0826fcc5d020 320 while (*name == 0x20) { /* If any spaces exist after the file name, replace them with 0 */
mshoemaker 0:0826fcc5d020 321 *name = 0;
mshoemaker 0:0826fcc5d020 322 name--;
mshoemaker 0:0826fcc5d020 323 }
mshoemaker 0:0826fcc5d020 324 }
mshoemaker 0:0826fcc5d020 325
mshoemaker 0:0826fcc5d020 326 /*
mshoemaker 0:0826fcc5d020 327 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 328 * GET EXTENSION OF A FILE
mshoemaker 0:0826fcc5d020 329 *
mshoemaker 0:0826fcc5d020 330 * Description: This function reads the extension of a file
mshoemaker 0:0826fcc5d020 331 *
mshoemaker 0:0826fcc5d020 332 * Arguments : ent_buf buffer which contains the 32 byte entry of a file
mshoemaker 0:0826fcc5d020 333 * ext_ptr buffer to store the extension of a file
mshoemaker 0:0826fcc5d020 334 *
mshoemaker 0:0826fcc5d020 335 * Returns : None
mshoemaker 0:0826fcc5d020 336 *
mshoemaker 0:0826fcc5d020 337 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 338 */
mshoemaker 0:0826fcc5d020 339
mshoemaker 0:0826fcc5d020 340 void FAT_GetSfnExt (volatile USB_INT08U *entry,
mshoemaker 0:0826fcc5d020 341 USB_INT08U *ext_ptr)
mshoemaker 0:0826fcc5d020 342 {
mshoemaker 0:0826fcc5d020 343 USB_INT32U cnt;
mshoemaker 0:0826fcc5d020 344
mshoemaker 0:0826fcc5d020 345
mshoemaker 0:0826fcc5d020 346 cnt = 0;
mshoemaker 0:0826fcc5d020 347 while (cnt < 8) { /* Goto the beginning of the file extension */
mshoemaker 0:0826fcc5d020 348 entry++;
mshoemaker 0:0826fcc5d020 349 cnt++;
mshoemaker 0:0826fcc5d020 350 }
mshoemaker 0:0826fcc5d020 351 cnt = 0;
mshoemaker 0:0826fcc5d020 352 while (cnt < 3) { /* Get 3 charecters from there */
mshoemaker 0:0826fcc5d020 353 *ext_ptr = *entry;
mshoemaker 0:0826fcc5d020 354 ext_ptr++;
mshoemaker 0:0826fcc5d020 355 entry++;
mshoemaker 0:0826fcc5d020 356 cnt++;
mshoemaker 0:0826fcc5d020 357 }
mshoemaker 0:0826fcc5d020 358 *ext_ptr = 0;
mshoemaker 0:0826fcc5d020 359 ext_ptr--;
mshoemaker 0:0826fcc5d020 360 while (*ext_ptr == ' ') { /* If any spaces exist after the file extension, replace them with 0 */
mshoemaker 0:0826fcc5d020 361 *ext_ptr = 0;
mshoemaker 0:0826fcc5d020 362 ext_ptr--;
mshoemaker 0:0826fcc5d020 363 }
mshoemaker 0:0826fcc5d020 364 }
mshoemaker 0:0826fcc5d020 365
mshoemaker 0:0826fcc5d020 366 /*
mshoemaker 0:0826fcc5d020 367 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 368 * CASE INSENSITIVE COMPARISION OF STRINGS
mshoemaker 0:0826fcc5d020 369 *
mshoemaker 0:0826fcc5d020 370 * Description: This function compares two strings case insensitively
mshoemaker 0:0826fcc5d020 371 *
mshoemaker 0:0826fcc5d020 372 * Arguments : str1 Pointer to the first string
mshoemaker 0:0826fcc5d020 373 * str2 Pointer to the second string
mshoemaker 0:0826fcc5d020 374 *
mshoemaker 0:0826fcc5d020 375 * Returns : MATCH_FOUND if both the strings are same
mshoemaker 0:0826fcc5d020 376 * NATCH_NOT_FOUND if both the strings are different
mshoemaker 0:0826fcc5d020 377 *
mshoemaker 0:0826fcc5d020 378 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 379 */
mshoemaker 0:0826fcc5d020 380
mshoemaker 0:0826fcc5d020 381 USB_INT32S FAT_StrCaseCmp (USB_INT08U *str1,
mshoemaker 0:0826fcc5d020 382 USB_INT08U *str2)
mshoemaker 0:0826fcc5d020 383 {
mshoemaker 0:0826fcc5d020 384 while (*str1 && *str2) {
mshoemaker 0:0826fcc5d020 385 if (*str1 == *str2 || *str1 == (*str2 + 32) || *str1 == (*str2 - 32)) {
mshoemaker 0:0826fcc5d020 386 str1++;
mshoemaker 0:0826fcc5d020 387 str2++;
mshoemaker 0:0826fcc5d020 388 continue;
mshoemaker 0:0826fcc5d020 389 } else {
mshoemaker 0:0826fcc5d020 390 return (MATCH_NOT_FOUND);
mshoemaker 0:0826fcc5d020 391 }
mshoemaker 0:0826fcc5d020 392 }
mshoemaker 0:0826fcc5d020 393 if (*str1 == 0 && *str2 == 0) {
mshoemaker 0:0826fcc5d020 394 return (MATCH_FOUND);
mshoemaker 0:0826fcc5d020 395 } else {
mshoemaker 0:0826fcc5d020 396 return (MATCH_NOT_FOUND);
mshoemaker 0:0826fcc5d020 397 }
mshoemaker 0:0826fcc5d020 398 }
mshoemaker 0:0826fcc5d020 399
mshoemaker 0:0826fcc5d020 400 /*
mshoemaker 0:0826fcc5d020 401 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 402 * CHECK TYPE OF THE ENTRY
mshoemaker 0:0826fcc5d020 403 *
mshoemaker 0:0826fcc5d020 404 * Description: This function checks the type of file entry.
mshoemaker 0:0826fcc5d020 405 *
mshoemaker 0:0826fcc5d020 406 * Arguments : ent Pointer to the buffer containing the entry
mshoemaker 0:0826fcc5d020 407 *
mshoemaker 0:0826fcc5d020 408 * Returns : LAST_ENTRY if the entry is last entry
mshoemaker 0:0826fcc5d020 409 * FREE_ENTRY if the entry is free entry
mshoemaker 0:0826fcc5d020 410 * LFN_ENTRY if the entry is long file name entry
mshoemaker 0:0826fcc5d020 411 * SFN_ENTRY if the entry is short file name entry
mshoemaker 0:0826fcc5d020 412 *
mshoemaker 0:0826fcc5d020 413 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 414 */
mshoemaker 0:0826fcc5d020 415
mshoemaker 0:0826fcc5d020 416 USB_INT32U FAT_ChkEntType (volatile USB_INT08U *ent)
mshoemaker 0:0826fcc5d020 417 {
mshoemaker 0:0826fcc5d020 418 if (ent[0] == 0x00) { /* First byte is 0 means it is the last entry */
mshoemaker 0:0826fcc5d020 419 return (LAST_ENTRY);
mshoemaker 0:0826fcc5d020 420 }
mshoemaker 0:0826fcc5d020 421
mshoemaker 0:0826fcc5d020 422 if (ent[0] == 0xE5) { /* First byte is 0xE5 means it is the free entry */
mshoemaker 0:0826fcc5d020 423 return (FREE_ENTRY);
mshoemaker 0:0826fcc5d020 424 }
mshoemaker 0:0826fcc5d020 425
mshoemaker 0:0826fcc5d020 426 if (0x0F == ent[11]) { /* If 11th byte of an entry is 0x0F, it is LFN */
mshoemaker 0:0826fcc5d020 427 return (LFN_ENTRY);
mshoemaker 0:0826fcc5d020 428
mshoemaker 0:0826fcc5d020 429 } else {
mshoemaker 0:0826fcc5d020 430 return (SFN_ENTRY); /* Else it is the SFN */
mshoemaker 0:0826fcc5d020 431 }
mshoemaker 0:0826fcc5d020 432 }
mshoemaker 0:0826fcc5d020 433
mshoemaker 0:0826fcc5d020 434 /*
mshoemaker 0:0826fcc5d020 435 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 436 * READ DATA REQUESTED BY THE USER
mshoemaker 0:0826fcc5d020 437 *
mshoemaker 0:0826fcc5d020 438 * Description: This function reads data requested by the application from the file pointed by file descriptor.
mshoemaker 0:0826fcc5d020 439 *
mshoemaker 0:0826fcc5d020 440 * Arguments : fd file descriptor that points to a file
mshoemaker 0:0826fcc5d020 441 * buffer buffer into which the data is to be read
mshoemaker 0:0826fcc5d020 442 * num_bytes number of bytes requested by the application
mshoemaker 0:0826fcc5d020 443 *
mshoemaker 0:0826fcc5d020 444 * Returns : total_bytes_read Total bytes actually read.
mshoemaker 0:0826fcc5d020 445 *
mshoemaker 0:0826fcc5d020 446 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 447 */
mshoemaker 0:0826fcc5d020 448
mshoemaker 0:0826fcc5d020 449 USB_INT32U FILE_Read ( USB_INT32S fd,
mshoemaker 0:0826fcc5d020 450 volatile USB_INT08U *buffer,
mshoemaker 0:0826fcc5d020 451 USB_INT32U num_bytes)
mshoemaker 0:0826fcc5d020 452 {
mshoemaker 0:0826fcc5d020 453 USB_INT32U total_bytes_to_read; /* Total bytes requested by the application */
mshoemaker 0:0826fcc5d020 454 USB_INT32U total_bytes_read; /* Total bytes read */
mshoemaker 0:0826fcc5d020 455 USB_INT32U bytes_read; /* Bytes read from one cluster */
mshoemaker 0:0826fcc5d020 456 USB_INT32U bytes_to_read; /* Bytes to be read in one cluster */
mshoemaker 0:0826fcc5d020 457 FILE_ENTRY *entry; /* Entry that contains the file attribute information */
mshoemaker 0:0826fcc5d020 458 USB_INT16U next_clus; /* Next cluster of the current cluster in the cluster chain */
mshoemaker 0:0826fcc5d020 459
mshoemaker 0:0826fcc5d020 460 entry = &FAT_FileEntry[fd-1]; /* Get file entry from file descriptor */
mshoemaker 0:0826fcc5d020 461 total_bytes_read = 0;
mshoemaker 0:0826fcc5d020 462
mshoemaker 0:0826fcc5d020 463 if (entry->FileSize == 0) {
mshoemaker 0:0826fcc5d020 464 return (0);
mshoemaker 0:0826fcc5d020 465 }
mshoemaker 0:0826fcc5d020 466 if (num_bytes < entry->FileSize) {
mshoemaker 0:0826fcc5d020 467 total_bytes_to_read = num_bytes;
mshoemaker 0:0826fcc5d020 468 } else {
mshoemaker 0:0826fcc5d020 469 total_bytes_to_read = entry->FileSize;
mshoemaker 0:0826fcc5d020 470 }
mshoemaker 0:0826fcc5d020 471 do {
mshoemaker 0:0826fcc5d020 472 next_clus = FAT_GetNextClus(entry->CurrClus); /* Get next cluster */
mshoemaker 0:0826fcc5d020 473 if (next_clus == 0) { /* If the current cluster is the last cluster */
mshoemaker 0:0826fcc5d020 474 /* If the offset is at the end of the file */
mshoemaker 0:0826fcc5d020 475 if (entry->CurrClusOffset == (entry->FileSize % FAT_BootSec.BytsPerClus)) {
mshoemaker 0:0826fcc5d020 476 return (0); /* No more bytes to read */
mshoemaker 0:0826fcc5d020 477 } /* If requested number is > remaining bytes in the last cluster */
mshoemaker 0:0826fcc5d020 478 if (total_bytes_to_read > ((entry->FileSize % FAT_BootSec.BytsPerClus) - entry->CurrClusOffset)) {
mshoemaker 0:0826fcc5d020 479 total_bytes_to_read = (entry->FileSize % FAT_BootSec.BytsPerClus) - entry->CurrClusOffset;
mshoemaker 0:0826fcc5d020 480 }
mshoemaker 0:0826fcc5d020 481 bytes_to_read = total_bytes_to_read;
mshoemaker 0:0826fcc5d020 482 /* If requested number is > remaining bytes in the current cluster */
mshoemaker 0:0826fcc5d020 483 } else if (total_bytes_to_read > (FAT_BootSec.BytsPerClus - entry->CurrClusOffset)) {
mshoemaker 0:0826fcc5d020 484 bytes_to_read = FAT_BootSec.BytsPerClus - entry->CurrClusOffset;
mshoemaker 0:0826fcc5d020 485 } else {
mshoemaker 0:0826fcc5d020 486 bytes_to_read = total_bytes_to_read;
mshoemaker 0:0826fcc5d020 487 }
mshoemaker 0:0826fcc5d020 488 bytes_read = FAT_ClusRead(entry->CurrClus, /* Read bytes from a single cluster */
mshoemaker 0:0826fcc5d020 489 entry->CurrClusOffset,
mshoemaker 0:0826fcc5d020 490 buffer,
mshoemaker 0:0826fcc5d020 491 bytes_to_read);
mshoemaker 0:0826fcc5d020 492 buffer += bytes_read;
mshoemaker 0:0826fcc5d020 493 total_bytes_read += bytes_read;
mshoemaker 0:0826fcc5d020 494 total_bytes_to_read -= bytes_read;
mshoemaker 0:0826fcc5d020 495 /* If the cluster offset reaches end of the cluster, make it 0 */
mshoemaker 0:0826fcc5d020 496 if (entry->CurrClusOffset + bytes_read == FAT_BootSec.BytsPerClus) {
mshoemaker 0:0826fcc5d020 497 entry->CurrClusOffset = 0;
mshoemaker 0:0826fcc5d020 498 } else {
mshoemaker 0:0826fcc5d020 499 entry->CurrClusOffset += bytes_read; /* Else increment the cluster offset */
mshoemaker 0:0826fcc5d020 500 }
mshoemaker 0:0826fcc5d020 501 if (entry->CurrClusOffset == 0) {
mshoemaker 0:0826fcc5d020 502 entry->CurrClus = (next_clus > 0) ? next_clus : entry->CurrClus;
mshoemaker 0:0826fcc5d020 503 }
mshoemaker 0:0826fcc5d020 504 } while (total_bytes_to_read);
mshoemaker 0:0826fcc5d020 505 return (total_bytes_read);
mshoemaker 0:0826fcc5d020 506 }
mshoemaker 0:0826fcc5d020 507
mshoemaker 0:0826fcc5d020 508 /*
mshoemaker 0:0826fcc5d020 509 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 510 * READ FROM ONE CLUSTER
mshoemaker 0:0826fcc5d020 511 *
mshoemaker 0:0826fcc5d020 512 * Description: This function reads the data from a single cluster.
mshoemaker 0:0826fcc5d020 513 *
mshoemaker 0:0826fcc5d020 514 * Arguments : curr_clus Current cluster from which the data has to read
mshoemaker 0:0826fcc5d020 515 * clus_offset Position in the current cluster from which the data has to read
mshoemaker 0:0826fcc5d020 516 * buffer Buffer into which the data has to read
mshoemaker 0:0826fcc5d020 517 * num_bytes Number of bytes to read
mshoemaker 0:0826fcc5d020 518 *
mshoemaker 0:0826fcc5d020 519 * Returns : tot_bytes_read Total bytes read from the current cluster
mshoemaker 0:0826fcc5d020 520 *
mshoemaker 0:0826fcc5d020 521 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 522 */
mshoemaker 0:0826fcc5d020 523
mshoemaker 0:0826fcc5d020 524 USB_INT32U FAT_ClusRead ( USB_INT16U curr_clus,
mshoemaker 0:0826fcc5d020 525 USB_INT32U clus_offset,
mshoemaker 0:0826fcc5d020 526 volatile USB_INT08U *buffer,
mshoemaker 0:0826fcc5d020 527 USB_INT32U num_bytes)
mshoemaker 0:0826fcc5d020 528 {
mshoemaker 0:0826fcc5d020 529 USB_INT32U tot_bytes_read; /* total bytes read in the current cluster */
mshoemaker 0:0826fcc5d020 530 USB_INT32U n_bytes; /* Bytes to read in the current sector */
mshoemaker 0:0826fcc5d020 531 USB_INT32U start_sec; /* Starting sector of the current cluster */
mshoemaker 0:0826fcc5d020 532 USB_INT32U sec_num; /*Current sector number */
mshoemaker 0:0826fcc5d020 533 USB_INT16U num_sec; /* Number of sectors to be read */
mshoemaker 0:0826fcc5d020 534 USB_INT32U sec_offset; /* Offset in the current sector */
mshoemaker 0:0826fcc5d020 535 USB_INT32U cnt;
mshoemaker 0:0826fcc5d020 536
mshoemaker 0:0826fcc5d020 537
mshoemaker 0:0826fcc5d020 538 tot_bytes_read = 0;
mshoemaker 0:0826fcc5d020 539 start_sec = ((curr_clus - 2) * FAT_BootSec.SecPerClus) + FAT_BootSec.FirstDataSec;
mshoemaker 0:0826fcc5d020 540 sec_num = start_sec + (clus_offset / FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 541 num_sec = num_bytes / FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 542 sec_offset = clus_offset % FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 543
mshoemaker 0:0826fcc5d020 544 if (sec_offset) { /* If the sector offset is at the middle of a sector */
mshoemaker 0:0826fcc5d020 545 MS_BulkRecv(sec_num, 1, FATBuffer); /* Read the first sector */
mshoemaker 0:0826fcc5d020 546 n_bytes = (FAT_BootSec.BytsPerSec - sec_offset <= num_bytes) ?
mshoemaker 0:0826fcc5d020 547 (FAT_BootSec.BytsPerSec - sec_offset) : num_bytes;
mshoemaker 0:0826fcc5d020 548 for (cnt = sec_offset; cnt < sec_offset + n_bytes; cnt++) {
mshoemaker 0:0826fcc5d020 549 *buffer = FATBuffer[cnt]; /* Copy the required bytes to user buffer */
mshoemaker 0:0826fcc5d020 550 buffer++;
mshoemaker 0:0826fcc5d020 551 }
mshoemaker 0:0826fcc5d020 552 tot_bytes_read += n_bytes;
mshoemaker 0:0826fcc5d020 553 clus_offset += n_bytes;
mshoemaker 0:0826fcc5d020 554 num_bytes -= n_bytes;
mshoemaker 0:0826fcc5d020 555 sec_num++;
mshoemaker 0:0826fcc5d020 556 }
mshoemaker 0:0826fcc5d020 557
mshoemaker 0:0826fcc5d020 558 if (num_bytes / FAT_BootSec.BytsPerSec) { /* Read all the remaining full sectors */
mshoemaker 0:0826fcc5d020 559
mshoemaker 0:0826fcc5d020 560 num_sec = num_bytes / FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 561 MS_BulkRecv(sec_num, num_sec, buffer);
mshoemaker 0:0826fcc5d020 562 buffer += (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 563 tot_bytes_read += (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 564 clus_offset += (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 565 num_bytes -= (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 566 sec_num += num_sec;
mshoemaker 0:0826fcc5d020 567 }
mshoemaker 0:0826fcc5d020 568
mshoemaker 0:0826fcc5d020 569 if (num_bytes) { /* Read the last sector for the remaining bytes */
mshoemaker 0:0826fcc5d020 570 MS_BulkRecv(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 571 for (cnt = 0; cnt < num_bytes; cnt++) {
mshoemaker 0:0826fcc5d020 572 *buffer = FATBuffer[cnt]; /* Copy the required bytes to user buffer */
mshoemaker 0:0826fcc5d020 573 buffer++;
mshoemaker 0:0826fcc5d020 574 }
mshoemaker 0:0826fcc5d020 575 tot_bytes_read += num_bytes;
mshoemaker 0:0826fcc5d020 576 }
mshoemaker 0:0826fcc5d020 577
mshoemaker 0:0826fcc5d020 578 return (tot_bytes_read);
mshoemaker 0:0826fcc5d020 579 }
mshoemaker 0:0826fcc5d020 580
mshoemaker 0:0826fcc5d020 581 /*
mshoemaker 0:0826fcc5d020 582 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 583 * WRITE THE DATA REQUESTED BY THE USER
mshoemaker 0:0826fcc5d020 584 *
mshoemaker 0:0826fcc5d020 585 * Description: This function writes data requested by the application to the file pointed by file descriptor
mshoemaker 0:0826fcc5d020 586 *
mshoemaker 0:0826fcc5d020 587 * Arguments : fd file descriptor that points to a file
mshoemaker 0:0826fcc5d020 588 * buffer buffer from which the data is to be written
mshoemaker 0:0826fcc5d020 589 * num_bytes number of bytes requested by the application
mshoemaker 0:0826fcc5d020 590 *
mshoemaker 0:0826fcc5d020 591 * Returns : total_bytes_written Total bytes actually written
mshoemaker 0:0826fcc5d020 592 *
mshoemaker 0:0826fcc5d020 593 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 594 */
mshoemaker 0:0826fcc5d020 595
mshoemaker 0:0826fcc5d020 596 USB_INT32U FILE_Write ( USB_INT32S fd,
mshoemaker 0:0826fcc5d020 597 volatile USB_INT08U *buffer,
mshoemaker 0:0826fcc5d020 598 USB_INT32U num_bytes)
mshoemaker 0:0826fcc5d020 599 {
mshoemaker 0:0826fcc5d020 600 USB_INT32U total_bytes_to_write; /* Total bytes requested by application */
mshoemaker 0:0826fcc5d020 601 USB_INT32U total_bytes_written; /* Total bytes written */
mshoemaker 0:0826fcc5d020 602 USB_INT32U bytes_written; /* Bytes written in a single cluster */
mshoemaker 0:0826fcc5d020 603 USB_INT32U bytes_to_write; /* Bytes to write in a single cluster */
mshoemaker 0:0826fcc5d020 604 FILE_ENTRY *entry; /* Entry that contains the file attribute information */
mshoemaker 0:0826fcc5d020 605 USB_INT16U free_clus; /* Free cluster available in the disk */
mshoemaker 0:0826fcc5d020 606
mshoemaker 0:0826fcc5d020 607
mshoemaker 0:0826fcc5d020 608 entry = &FAT_FileEntry[fd-1]; /* Get file entry from file descriptor */
mshoemaker 0:0826fcc5d020 609 total_bytes_written = 0;
mshoemaker 0:0826fcc5d020 610 total_bytes_to_write = num_bytes;
mshoemaker 0:0826fcc5d020 611
mshoemaker 0:0826fcc5d020 612 if (num_bytes) {
mshoemaker 0:0826fcc5d020 613 if (entry->FileSize == 0) {
mshoemaker 0:0826fcc5d020 614 free_clus = FAT_GetFreeClus();
mshoemaker 0:0826fcc5d020 615 FAT_UpdateFAT(free_clus, 0xFFFF);
mshoemaker 0:0826fcc5d020 616 entry->CurrClus = free_clus;
mshoemaker 0:0826fcc5d020 617 MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 618 WriteLE16U(&FATBuffer[(entry->EntrySecOffset) + 26], free_clus);
mshoemaker 0:0826fcc5d020 619 MS_BulkSend(entry->EntrySec, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 620 }
mshoemaker 0:0826fcc5d020 621 } else {
mshoemaker 0:0826fcc5d020 622 return (0);
mshoemaker 0:0826fcc5d020 623 }
mshoemaker 0:0826fcc5d020 624 entry->CurrClus = FAT_GetEndClus(entry->CurrClus); /* Make the current cluster as end cluster */
mshoemaker 0:0826fcc5d020 625 entry->CurrClusOffset = entry->FileSize % FAT_BootSec.BytsPerClus; /* Move cluster offset to file end */
mshoemaker 0:0826fcc5d020 626 do {
mshoemaker 0:0826fcc5d020 627 if (total_bytes_to_write > FAT_BootSec.BytsPerClus - entry->CurrClusOffset) {
mshoemaker 0:0826fcc5d020 628 bytes_to_write = FAT_BootSec.BytsPerClus - entry->CurrClusOffset;
mshoemaker 0:0826fcc5d020 629 } else {
mshoemaker 0:0826fcc5d020 630 bytes_to_write = total_bytes_to_write;
mshoemaker 0:0826fcc5d020 631 }
mshoemaker 0:0826fcc5d020 632 bytes_written = FAT_ClusWrite(entry->CurrClus,
mshoemaker 0:0826fcc5d020 633 entry->CurrClusOffset,
mshoemaker 0:0826fcc5d020 634 buffer,
mshoemaker 0:0826fcc5d020 635 bytes_to_write);
mshoemaker 0:0826fcc5d020 636 buffer += bytes_written;
mshoemaker 0:0826fcc5d020 637 total_bytes_written += bytes_written;
mshoemaker 0:0826fcc5d020 638 total_bytes_to_write -= bytes_written;
mshoemaker 0:0826fcc5d020 639 entry->FileSize += bytes_written;
mshoemaker 0:0826fcc5d020 640 if (entry->CurrClusOffset + bytes_written == FAT_BootSec.BytsPerClus) {
mshoemaker 0:0826fcc5d020 641 entry->CurrClusOffset = 0;
mshoemaker 0:0826fcc5d020 642 } else {
mshoemaker 0:0826fcc5d020 643 entry->CurrClusOffset += bytes_written;
mshoemaker 0:0826fcc5d020 644 }
mshoemaker 0:0826fcc5d020 645 if (entry->CurrClusOffset == 0) {
mshoemaker 0:0826fcc5d020 646 free_clus = FAT_GetFreeClus();
mshoemaker 0:0826fcc5d020 647 if (free_clus == 0) {
mshoemaker 0:0826fcc5d020 648 return (total_bytes_written);
mshoemaker 0:0826fcc5d020 649 }
mshoemaker 0:0826fcc5d020 650 FAT_UpdateFAT(entry->CurrClus, free_clus);
mshoemaker 0:0826fcc5d020 651 FAT_UpdateFAT(free_clus, 0xFFFF);
mshoemaker 0:0826fcc5d020 652 entry->CurrClus = free_clus;
mshoemaker 0:0826fcc5d020 653 }
mshoemaker 0:0826fcc5d020 654 } while (total_bytes_to_write);
mshoemaker 0:0826fcc5d020 655 return (total_bytes_written);
mshoemaker 0:0826fcc5d020 656 }
mshoemaker 0:0826fcc5d020 657
mshoemaker 0:0826fcc5d020 658 /*
mshoemaker 0:0826fcc5d020 659 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 660 * WRITE TO ONE CLUSTER
mshoemaker 0:0826fcc5d020 661 *
mshoemaker 0:0826fcc5d020 662 * Description: This function writes the data to a single cluster.
mshoemaker 0:0826fcc5d020 663 *
mshoemaker 0:0826fcc5d020 664 * Arguments : curr_clus Current cluster into which the data has to write
mshoemaker 0:0826fcc5d020 665 * clus_offset Position in the current cluster from which the data has to write
mshoemaker 0:0826fcc5d020 666 * buffer Buffer from which the data has to write
mshoemaker 0:0826fcc5d020 667 * num_bytes Number of bytes to write
mshoemaker 0:0826fcc5d020 668 *
mshoemaker 0:0826fcc5d020 669 * Returns : tot_bytes_read Total bytes written into the current cluster
mshoemaker 0:0826fcc5d020 670 *
mshoemaker 0:0826fcc5d020 671 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 672 */
mshoemaker 0:0826fcc5d020 673
mshoemaker 0:0826fcc5d020 674 USB_INT32U FAT_ClusWrite ( USB_INT16U curr_clus,
mshoemaker 0:0826fcc5d020 675 USB_INT32U clus_offset,
mshoemaker 0:0826fcc5d020 676 volatile USB_INT08U *buffer,
mshoemaker 0:0826fcc5d020 677 USB_INT32U num_bytes)
mshoemaker 0:0826fcc5d020 678 {
mshoemaker 0:0826fcc5d020 679 USB_INT32U tot_bytes_written;
mshoemaker 0:0826fcc5d020 680 USB_INT32U n_bytes;
mshoemaker 0:0826fcc5d020 681 USB_INT32U start_sec;
mshoemaker 0:0826fcc5d020 682 USB_INT32U sec_num;
mshoemaker 0:0826fcc5d020 683 USB_INT16U num_sec;
mshoemaker 0:0826fcc5d020 684 USB_INT32U sec_offset;
mshoemaker 0:0826fcc5d020 685 USB_INT32U cnt;
mshoemaker 0:0826fcc5d020 686
mshoemaker 0:0826fcc5d020 687
mshoemaker 0:0826fcc5d020 688 tot_bytes_written = 0;
mshoemaker 0:0826fcc5d020 689 start_sec = ((curr_clus - 2) * FAT_BootSec.SecPerClus) + FAT_BootSec.FirstDataSec;
mshoemaker 0:0826fcc5d020 690 sec_num = start_sec + (clus_offset / FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 691 num_sec = num_bytes / FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 692 sec_offset = clus_offset % FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 693
mshoemaker 0:0826fcc5d020 694 if (sec_offset) {
mshoemaker 0:0826fcc5d020 695 MS_BulkRecv(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 696 n_bytes = (FAT_BootSec.BytsPerSec - sec_offset <= num_bytes) ?
mshoemaker 0:0826fcc5d020 697 (FAT_BootSec.BytsPerSec - sec_offset) : num_bytes;
mshoemaker 0:0826fcc5d020 698 for (cnt = sec_offset; cnt < (sec_offset + n_bytes); cnt++) {
mshoemaker 0:0826fcc5d020 699 FATBuffer[cnt] = *buffer;
mshoemaker 0:0826fcc5d020 700 buffer++;
mshoemaker 0:0826fcc5d020 701 }
mshoemaker 0:0826fcc5d020 702 MS_BulkSend(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 703 tot_bytes_written += n_bytes;
mshoemaker 0:0826fcc5d020 704 clus_offset += n_bytes;
mshoemaker 0:0826fcc5d020 705 num_bytes -= n_bytes;
mshoemaker 0:0826fcc5d020 706 sec_num++;
mshoemaker 0:0826fcc5d020 707 }
mshoemaker 0:0826fcc5d020 708 if (num_bytes / FAT_BootSec.BytsPerSec) {
mshoemaker 0:0826fcc5d020 709 num_sec = num_bytes / FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 710 MS_BulkSend(sec_num, num_sec, buffer);
mshoemaker 0:0826fcc5d020 711 buffer += (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 712 tot_bytes_written += (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 713 clus_offset += (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 714 num_bytes -= (num_sec * FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 715 sec_num += num_sec;
mshoemaker 0:0826fcc5d020 716 }
mshoemaker 0:0826fcc5d020 717 if (num_bytes) {
mshoemaker 0:0826fcc5d020 718 MS_BulkRecv(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 719
mshoemaker 0:0826fcc5d020 720 for (cnt = 0; cnt < num_bytes; cnt++) {
mshoemaker 0:0826fcc5d020 721 FATBuffer[cnt] = *buffer;
mshoemaker 0:0826fcc5d020 722 buffer++;
mshoemaker 0:0826fcc5d020 723 }
mshoemaker 0:0826fcc5d020 724 MS_BulkSend(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 725 tot_bytes_written += num_bytes;
mshoemaker 0:0826fcc5d020 726 }
mshoemaker 0:0826fcc5d020 727 return (tot_bytes_written);
mshoemaker 0:0826fcc5d020 728 }
mshoemaker 0:0826fcc5d020 729
mshoemaker 0:0826fcc5d020 730 /*
mshoemaker 0:0826fcc5d020 731 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 732 * GET NEXT CLUSTER
mshoemaker 0:0826fcc5d020 733 *
mshoemaker 0:0826fcc5d020 734 * Description: This function returns next cluster of the current cluster in the cluster chain. If the current
mshoemaker 0:0826fcc5d020 735 * cluster is the last cluster then this function returns 0
mshoemaker 0:0826fcc5d020 736 *
mshoemaker 0:0826fcc5d020 737 * Arguments : clus_no The cluster number for which the next cluster to be found
mshoemaker 0:0826fcc5d020 738 *
mshoemaker 0:0826fcc5d020 739 * Returns : next_clus if the current cluster is not the last cluster
mshoemaker 0:0826fcc5d020 740 * 0 if the current cluster is the last cluster
mshoemaker 0:0826fcc5d020 741 * Note: In practical cluster number 0 doesn't exist
mshoemaker 0:0826fcc5d020 742 *
mshoemaker 0:0826fcc5d020 743 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 744 */
mshoemaker 0:0826fcc5d020 745
mshoemaker 0:0826fcc5d020 746 USB_INT16U FAT_GetNextClus (USB_INT16U clus_no)
mshoemaker 0:0826fcc5d020 747 {
mshoemaker 0:0826fcc5d020 748 USB_INT32U sec_num;
mshoemaker 0:0826fcc5d020 749 USB_INT32U ent_offset;
mshoemaker 0:0826fcc5d020 750 USB_INT16U next_clus;
mshoemaker 0:0826fcc5d020 751
mshoemaker 0:0826fcc5d020 752 /* Get the sector number in the FAT that contains current cluster */
mshoemaker 0:0826fcc5d020 753 sec_num = FAT_BootSec.RsvdSecCnt + ((clus_no * 2) / FAT_BootSec.BytsPerSec);
mshoemaker 0:0826fcc5d020 754 /* Get the sector offset in the FAT where the current cluster is located */
mshoemaker 0:0826fcc5d020 755 ent_offset = (clus_no * 2) % FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 756 MS_BulkRecv(sec_num, 1, FATBuffer); /* Read that sector */
mshoemaker 0:0826fcc5d020 757 next_clus = ReadLE16U(&FATBuffer[ent_offset]); /* Read the next cluster */
mshoemaker 0:0826fcc5d020 758 if (next_clus >= 0xFFF8 && next_clus <= 0xFFFF) { /* If that value is in between 0xFFF8 and 0xFFFF */
mshoemaker 0:0826fcc5d020 759 next_clus = 0; /* Current cluster is the end cluster */
mshoemaker 0:0826fcc5d020 760 }
mshoemaker 0:0826fcc5d020 761 return (next_clus);
mshoemaker 0:0826fcc5d020 762
mshoemaker 0:0826fcc5d020 763 }
mshoemaker 0:0826fcc5d020 764
mshoemaker 0:0826fcc5d020 765 /*
mshoemaker 0:0826fcc5d020 766 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 767 * GET FREE CLUSTER
mshoemaker 0:0826fcc5d020 768 *
mshoemaker 0:0826fcc5d020 769 * Description: This function returns the free cluster if available
mshoemaker 0:0826fcc5d020 770 *
mshoemaker 0:0826fcc5d020 771 * Arguments : None
mshoemaker 0:0826fcc5d020 772 *
mshoemaker 0:0826fcc5d020 773 * Returns : free_clus if available
mshoemaker 0:0826fcc5d020 774 * 0 if not available(means the disk is full)
mshoemaker 0:0826fcc5d020 775 *
mshoemaker 0:0826fcc5d020 776 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 777 */
mshoemaker 0:0826fcc5d020 778
mshoemaker 0:0826fcc5d020 779 USB_INT16U FAT_GetFreeClus (void)
mshoemaker 0:0826fcc5d020 780 {
mshoemaker 0:0826fcc5d020 781 USB_INT32U num_sec;
mshoemaker 0:0826fcc5d020 782 USB_INT32U cnt;
mshoemaker 0:0826fcc5d020 783 USB_INT32U sec_num;
mshoemaker 0:0826fcc5d020 784 USB_INT16U free_clus;
mshoemaker 0:0826fcc5d020 785
mshoemaker 0:0826fcc5d020 786
mshoemaker 0:0826fcc5d020 787 sec_num = FAT_BootSec.RsvdSecCnt;
mshoemaker 0:0826fcc5d020 788 num_sec = FAT_BootSec.FATSz16;
mshoemaker 0:0826fcc5d020 789 while (sec_num < (FAT_BootSec.RsvdSecCnt + num_sec)) {
mshoemaker 0:0826fcc5d020 790 MS_BulkRecv(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 791 for (cnt = 0; cnt < FAT_BootSec.BytsPerSec; cnt += 2) {
mshoemaker 0:0826fcc5d020 792 if (ReadLE16U(&FATBuffer[cnt]) == 0) {
mshoemaker 0:0826fcc5d020 793 free_clus = (((sec_num - FAT_BootSec.RsvdSecCnt) * FAT_BootSec.BytsPerSec) + cnt) / 2;
mshoemaker 0:0826fcc5d020 794 return (free_clus);
mshoemaker 0:0826fcc5d020 795 }
mshoemaker 0:0826fcc5d020 796 }
mshoemaker 0:0826fcc5d020 797 sec_num++;
mshoemaker 0:0826fcc5d020 798 }
mshoemaker 0:0826fcc5d020 799 return (0);
mshoemaker 0:0826fcc5d020 800 }
mshoemaker 0:0826fcc5d020 801
mshoemaker 0:0826fcc5d020 802 /*
mshoemaker 0:0826fcc5d020 803 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 804 * UPDATE FILE ALLOCATION TABLE
mshoemaker 0:0826fcc5d020 805 *
mshoemaker 0:0826fcc5d020 806 * Description: This function updates the file allocation table
mshoemaker 0:0826fcc5d020 807 *
mshoemaker 0:0826fcc5d020 808 * Arguments : curr_clus Offset of the current cluster number in the file allocation table
mshoemaker 0:0826fcc5d020 809 * value Value with which this offset to be updated
mshoemaker 0:0826fcc5d020 810 *
mshoemaker 0:0826fcc5d020 811 * Returns : None
mshoemaker 0:0826fcc5d020 812 *
mshoemaker 0:0826fcc5d020 813 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 814 */
mshoemaker 0:0826fcc5d020 815
mshoemaker 0:0826fcc5d020 816 void FAT_UpdateFAT (USB_INT16U curr_clus,
mshoemaker 0:0826fcc5d020 817 USB_INT16U value)
mshoemaker 0:0826fcc5d020 818 {
mshoemaker 0:0826fcc5d020 819 USB_INT32U sec_num;
mshoemaker 0:0826fcc5d020 820 USB_INT32U sec_offset;
mshoemaker 0:0826fcc5d020 821
mshoemaker 0:0826fcc5d020 822 sec_num = FAT_BootSec.RsvdSecCnt + (curr_clus * 2) / FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 823 sec_offset = (curr_clus * 2) % FAT_BootSec.BytsPerSec;
mshoemaker 0:0826fcc5d020 824
mshoemaker 0:0826fcc5d020 825 MS_BulkRecv(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 826 WriteLE16U(&FATBuffer[sec_offset], value);
mshoemaker 0:0826fcc5d020 827 MS_BulkSend(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 828 }
mshoemaker 0:0826fcc5d020 829
mshoemaker 0:0826fcc5d020 830 /*
mshoemaker 0:0826fcc5d020 831 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 832 * UPDATE THE FILE ENTRY
mshoemaker 0:0826fcc5d020 833 *
mshoemaker 0:0826fcc5d020 834 * Description: This function updates the file entry that is located in the root directory
mshoemaker 0:0826fcc5d020 835 *
mshoemaker 0:0826fcc5d020 836 * Arguments : entry Pointer to the FILE ENTRY structure which contains the information about the file
mshoemaker 0:0826fcc5d020 837 *
mshoemaker 0:0826fcc5d020 838 * Returns : None
mshoemaker 0:0826fcc5d020 839 *
mshoemaker 0:0826fcc5d020 840 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 841 */
mshoemaker 0:0826fcc5d020 842
mshoemaker 0:0826fcc5d020 843 void FAT_UpdateEntry (FILE_ENTRY *entry)
mshoemaker 0:0826fcc5d020 844 {
mshoemaker 0:0826fcc5d020 845 USB_INT32U sec_num;
mshoemaker 0:0826fcc5d020 846 USB_INT32U offset;
mshoemaker 0:0826fcc5d020 847
mshoemaker 0:0826fcc5d020 848 sec_num = entry->EntrySec;
mshoemaker 0:0826fcc5d020 849 offset = entry->EntrySecOffset;
mshoemaker 0:0826fcc5d020 850 MS_BulkRecv(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 851 WriteLE32U(&FATBuffer[offset + 28], entry->FileSize);
mshoemaker 0:0826fcc5d020 852 MS_BulkSend(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 853 }
mshoemaker 0:0826fcc5d020 854
mshoemaker 0:0826fcc5d020 855 /*
mshoemaker 0:0826fcc5d020 856 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 857 * CREATING AN ENTRY
mshoemaker 0:0826fcc5d020 858 *
mshoemaker 0:0826fcc5d020 859 * Description: This function creates a file entry in the root directory if the file does not exist
mshoemaker 0:0826fcc5d020 860 *
mshoemaker 0:0826fcc5d020 861 * Arguments : ent_name_given The file name with which the entry is to be created
mshoemaker 0:0826fcc5d020 862 * entry Pointer to FILE ENTRY structure
mshoemaker 0:0826fcc5d020 863 *
mshoemaker 0:0826fcc5d020 864 * Returns : OK If the entry already exists or successfully created if it doesn't exists
mshoemaker 0:0826fcc5d020 865 * ERROR If failed to create the entry
mshoemaker 0:0826fcc5d020 866 *
mshoemaker 0:0826fcc5d020 867 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 868 */
mshoemaker 0:0826fcc5d020 869
mshoemaker 0:0826fcc5d020 870 USB_INT32S FAT_CreateEntry (USB_INT08U *ent_name_given,
mshoemaker 0:0826fcc5d020 871 FILE_ENTRY *entry)
mshoemaker 0:0826fcc5d020 872 {
mshoemaker 0:0826fcc5d020 873 USB_INT32S rc;
mshoemaker 0:0826fcc5d020 874
mshoemaker 0:0826fcc5d020 875
mshoemaker 0:0826fcc5d020 876 rc = FAT_FindEntry(ent_name_given, entry); /* Find for the given file name in the root directory */
mshoemaker 0:0826fcc5d020 877 if (rc == MATCH_FOUND) { /* If match found, return */
mshoemaker 0:0826fcc5d020 878 return (rc);
mshoemaker 0:0826fcc5d020 879 } else {
mshoemaker 0:0826fcc5d020 880 rc = FAT_GetFreeEntry(entry); /* Else get a free entry from the root directory */
mshoemaker 0:0826fcc5d020 881 if (rc != OK) {
mshoemaker 0:0826fcc5d020 882 return (rc);
mshoemaker 0:0826fcc5d020 883 } else {
mshoemaker 0:0826fcc5d020 884 FAT_PutSFN(ent_name_given, entry); /* Store the given short file name in that entry */
mshoemaker 0:0826fcc5d020 885 return (rc);
mshoemaker 0:0826fcc5d020 886 }
mshoemaker 0:0826fcc5d020 887 }
mshoemaker 0:0826fcc5d020 888 }
mshoemaker 0:0826fcc5d020 889
mshoemaker 0:0826fcc5d020 890 /*
mshoemaker 0:0826fcc5d020 891 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 892 * GET GREE ENTRY
mshoemaker 0:0826fcc5d020 893 *
mshoemaker 0:0826fcc5d020 894 * Description: This function searches for a free entry in the root directory. If a free entry is found, the
mshoemaker 0:0826fcc5d020 895 * sector number and sector offset where the entry is located will be stored
mshoemaker 0:0826fcc5d020 896 *
mshoemaker 0:0826fcc5d020 897 * Arguments : entry Pointer to FILE_ENTRY structure
mshoemaker 0:0826fcc5d020 898 *
mshoemaker 0:0826fcc5d020 899 * Returns : OK If a free entry is found
mshoemaker 0:0826fcc5d020 900 * ERROR If no free entry is found
mshoemaker 0:0826fcc5d020 901 *
mshoemaker 0:0826fcc5d020 902 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 903 */
mshoemaker 0:0826fcc5d020 904
mshoemaker 0:0826fcc5d020 905 USB_INT32S FAT_GetFreeEntry (FILE_ENTRY *entry)
mshoemaker 0:0826fcc5d020 906 {
mshoemaker 0:0826fcc5d020 907 USB_INT32U sec_num;
mshoemaker 0:0826fcc5d020 908 volatile USB_INT08U *buf;
mshoemaker 0:0826fcc5d020 909 USB_INT08U ent_type;
mshoemaker 0:0826fcc5d020 910
mshoemaker 0:0826fcc5d020 911
mshoemaker 0:0826fcc5d020 912 for (sec_num = FAT_BootSec.RootDirStartSec;
mshoemaker 0:0826fcc5d020 913 sec_num < (FAT_BootSec.RootDirStartSec + FAT_BootSec.RootDirSec);
mshoemaker 0:0826fcc5d020 914 sec_num++) {
mshoemaker 0:0826fcc5d020 915
mshoemaker 0:0826fcc5d020 916 MS_BulkRecv(sec_num, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 917 buf = FATBuffer;
mshoemaker 0:0826fcc5d020 918 while (buf < (FATBuffer + FAT_BootSec.BytsPerSec)) {
mshoemaker 0:0826fcc5d020 919 ent_type = FAT_ChkEntType(buf);
mshoemaker 0:0826fcc5d020 920 if (ent_type == FREE_ENTRY) {
mshoemaker 0:0826fcc5d020 921 entry->EntrySec = sec_num;
mshoemaker 0:0826fcc5d020 922 entry->EntrySecOffset = buf - FATBuffer;
mshoemaker 0:0826fcc5d020 923 return (OK);
mshoemaker 0:0826fcc5d020 924 }
mshoemaker 0:0826fcc5d020 925 if (ent_type == LAST_ENTRY) {
mshoemaker 0:0826fcc5d020 926 return (ERR_ROOT_DIR_FULL);
mshoemaker 0:0826fcc5d020 927 } else {
mshoemaker 0:0826fcc5d020 928 buf += 32;
mshoemaker 0:0826fcc5d020 929 }
mshoemaker 0:0826fcc5d020 930 }
mshoemaker 0:0826fcc5d020 931 }
mshoemaker 0:0826fcc5d020 932 return (ERR_ROOT_DIR_FULL);
mshoemaker 0:0826fcc5d020 933 }
mshoemaker 0:0826fcc5d020 934
mshoemaker 0:0826fcc5d020 935 /*
mshoemaker 0:0826fcc5d020 936 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 937 * PUT SHORT FILE NAME
mshoemaker 0:0826fcc5d020 938 *
mshoemaker 0:0826fcc5d020 939 * Description: This function fills the file entry with the short file name given by the user
mshoemaker 0:0826fcc5d020 940 *
mshoemaker 0:0826fcc5d020 941 * Arguments : ent_name_given File name given by the user
mshoemaker 0:0826fcc5d020 942 * entry Pointer to the FILE_ENTRY structure
mshoemaker 0:0826fcc5d020 943 *
mshoemaker 0:0826fcc5d020 944 * Returns : None
mshoemaker 0:0826fcc5d020 945 *
mshoemaker 0:0826fcc5d020 946 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 947 */
mshoemaker 0:0826fcc5d020 948
mshoemaker 0:0826fcc5d020 949 void FAT_PutSFN (USB_INT08U *ent_name_given,
mshoemaker 0:0826fcc5d020 950 FILE_ENTRY *entry)
mshoemaker 0:0826fcc5d020 951 {
mshoemaker 0:0826fcc5d020 952 USB_INT32U idx;
mshoemaker 0:0826fcc5d020 953
mshoemaker 0:0826fcc5d020 954 /* Read the sector from root directory containing the free entry */
mshoemaker 0:0826fcc5d020 955 MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 956 for (idx = 0; idx < 8; idx++) { /* Fill the first eight charecters of the entry with file name */
mshoemaker 0:0826fcc5d020 957 if (*ent_name_given == '.') {
mshoemaker 0:0826fcc5d020 958 while (idx < 8) {
mshoemaker 0:0826fcc5d020 959 FATBuffer[entry->EntrySecOffset + idx] = 0x20;
mshoemaker 0:0826fcc5d020 960 idx++;
mshoemaker 0:0826fcc5d020 961 }
mshoemaker 0:0826fcc5d020 962 ent_name_given++;
mshoemaker 0:0826fcc5d020 963 } else {
mshoemaker 0:0826fcc5d020 964 FATBuffer[entry->EntrySecOffset + idx] = *ent_name_given;
mshoemaker 0:0826fcc5d020 965 ent_name_given++;
mshoemaker 0:0826fcc5d020 966 }
mshoemaker 0:0826fcc5d020 967 }
mshoemaker 0:0826fcc5d020 968
mshoemaker 0:0826fcc5d020 969 for (idx = 8; idx < 11; idx++) { /* Fill the next 3 charecters with file extension */
mshoemaker 0:0826fcc5d020 970 if (*ent_name_given == '.') {
mshoemaker 0:0826fcc5d020 971 while (idx < 11) {
mshoemaker 0:0826fcc5d020 972 FATBuffer[entry->EntrySecOffset + idx] = 0x20;
mshoemaker 0:0826fcc5d020 973 idx++;
mshoemaker 0:0826fcc5d020 974 }
mshoemaker 0:0826fcc5d020 975 } else {
mshoemaker 0:0826fcc5d020 976 FATBuffer[entry->EntrySecOffset + idx] = *ent_name_given;
mshoemaker 0:0826fcc5d020 977 ent_name_given++;
mshoemaker 0:0826fcc5d020 978 }
mshoemaker 0:0826fcc5d020 979 }
mshoemaker 0:0826fcc5d020 980 FATBuffer[entry->EntrySecOffset + idx] = 0x20;
mshoemaker 0:0826fcc5d020 981 for (idx = 12; idx < 32; idx++) { /* Fill all the remaining bytes with 0's */
mshoemaker 0:0826fcc5d020 982 FATBuffer[entry->EntrySecOffset + idx] = 0;
mshoemaker 0:0826fcc5d020 983 }
mshoemaker 0:0826fcc5d020 984 MS_BulkSend(entry->EntrySec, 1, FATBuffer); /* Write the sector into the root directory */
mshoemaker 0:0826fcc5d020 985 }
mshoemaker 0:0826fcc5d020 986
mshoemaker 0:0826fcc5d020 987 /*
mshoemaker 0:0826fcc5d020 988 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 989 * FILE CLOSE
mshoemaker 0:0826fcc5d020 990 *
mshoemaker 0:0826fcc5d020 991 * Description: This function closes the opened file by making all the elements of FILE_ENTRY structure to 0
mshoemaker 0:0826fcc5d020 992 *
mshoemaker 0:0826fcc5d020 993 * Arguments : fd File descriptor which points to the file to be closed
mshoemaker 0:0826fcc5d020 994 *
mshoemaker 0:0826fcc5d020 995 * Returns : None
mshoemaker 0:0826fcc5d020 996 *
mshoemaker 0:0826fcc5d020 997 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 998 */
mshoemaker 0:0826fcc5d020 999
mshoemaker 0:0826fcc5d020 1000 void FILE_Close (USB_INT32S fd)
mshoemaker 0:0826fcc5d020 1001 {
mshoemaker 0:0826fcc5d020 1002 FILE_ENTRY *entry;
mshoemaker 0:0826fcc5d020 1003
mshoemaker 0:0826fcc5d020 1004
mshoemaker 0:0826fcc5d020 1005 entry = &FAT_FileEntry[fd-1];
mshoemaker 0:0826fcc5d020 1006 MS_BulkRecv(entry->EntrySec, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 1007 WriteLE32U(&FATBuffer[entry->EntrySecOffset + 28], entry->FileSize); /* Update the file size */
mshoemaker 0:0826fcc5d020 1008 MS_BulkSend(entry->EntrySec, 1, FATBuffer);
mshoemaker 0:0826fcc5d020 1009 entry->CurrClus = 0;
mshoemaker 0:0826fcc5d020 1010 entry->CurrClusOffset = 0;
mshoemaker 0:0826fcc5d020 1011 entry->FileSize = 0;
mshoemaker 0:0826fcc5d020 1012 entry->EntrySec = 0;
mshoemaker 0:0826fcc5d020 1013 entry->EntrySecOffset = 0;
mshoemaker 0:0826fcc5d020 1014 entry->FileStatus = 0;
mshoemaker 0:0826fcc5d020 1015 }
mshoemaker 0:0826fcc5d020 1016
mshoemaker 0:0826fcc5d020 1017 /*
mshoemaker 0:0826fcc5d020 1018 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 1019 * GET END CLUSTER
mshoemaker 0:0826fcc5d020 1020 *
mshoemaker 0:0826fcc5d020 1021 * Description: This function end cluster in the cluster chain of a cluster
mshoemaker 0:0826fcc5d020 1022 *
mshoemaker 0:0826fcc5d020 1023 * Arguments : clus_no Starting cluster of the cluster chain in which end cluster to be found
mshoemaker 0:0826fcc5d020 1024 *
mshoemaker 0:0826fcc5d020 1025 * Returns : End cluster in the cluster chain
mshoemaker 0:0826fcc5d020 1026 *
mshoemaker 0:0826fcc5d020 1027 **************************************************************************************************************
mshoemaker 0:0826fcc5d020 1028 */
mshoemaker 0:0826fcc5d020 1029
mshoemaker 0:0826fcc5d020 1030 USB_INT16U FAT_GetEndClus (USB_INT16U clus_no)
mshoemaker 0:0826fcc5d020 1031 {
mshoemaker 0:0826fcc5d020 1032 USB_INT16U next_clus;
mshoemaker 0:0826fcc5d020 1033
mshoemaker 0:0826fcc5d020 1034
mshoemaker 0:0826fcc5d020 1035 next_clus = clus_no;
mshoemaker 0:0826fcc5d020 1036 while (next_clus) {
mshoemaker 0:0826fcc5d020 1037 next_clus = FAT_GetNextClus(clus_no);
mshoemaker 0:0826fcc5d020 1038 if (next_clus) {
mshoemaker 0:0826fcc5d020 1039 clus_no = next_clus;
mshoemaker 0:0826fcc5d020 1040 }
mshoemaker 0:0826fcc5d020 1041 }
mshoemaker 0:0826fcc5d020 1042 return (clus_no);
mshoemaker 0:0826fcc5d020 1043 }