Dependencies:   mbed

Committer:
iva2k
Date:
Thu Jan 21 01:15:42 2010 +0000
Revision:
0:1802fb31b938

        

Who changed what in which revision?

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