CLEON  Version 1
Cloud-Offloaded GPS Receiver
ff.c File Reference
#include "fs_define.h"
#include "hal_define.h"
Include dependency graph for ff.c:

Go to the source code of this file.

Macros

#define SS(fs)   ((fs)->ssize) /* Variable sector size */
 
#define ENTER_FF(fs)
 
#define LEAVE_FF(fs, res)   return res
 
#define ABORT(fs, res)   { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }
 
#define IsUpper(c)   (((c)>='A')&&((c)<='Z'))
 
#define IsLower(c)   (((c)>='a')&&((c)<='z'))
 
#define IsDigit(c)   (((c)>='0')&&((c)<='9'))
 
#define IsDBCS1(c)   0
 
#define IsDBCS2(c)   0
 
#define NS   11 /* Index of name status byte in fn[] */
 
#define NS_LOSS   0x01 /* Out of 8.3 format */
 
#define NS_LFN   0x02 /* Force to create LFN entry */
 
#define NS_LAST   0x04 /* Last segment */
 
#define NS_BODY   0x08 /* Lower case flag (body) */
 
#define NS_EXT   0x10 /* Lower case flag (ext) */
 
#define NS_DOT   0x20 /* Dot entry */
 
#define MIN_FAT16   4086 /* Minimum number of clusters for FAT16 */
 
#define MIN_FAT32   65526 /* Minimum number of clusters for FAT32 */
 
#define BS_jmpBoot   0 /* Jump instruction (3) */
 
#define BS_OEMName   3 /* OEM name (8) */
 
#define BPB_BytsPerSec   11 /* Sector size [byte] (2) */
 
#define BPB_SecPerClus   13 /* Cluster size [sector] (1) */
 
#define BPB_RsvdSecCnt   14 /* Size of reserved area [sector] (2) */
 
#define BPB_NumFATs   16 /* Number of FAT copies (1) */
 
#define BPB_RootEntCnt   17 /* Number of root dir entries for FAT12/16 (2) */
 
#define BPB_TotSec16   19 /* Volume size [sector] (2) */
 
#define BPB_Media   21 /* Media descriptor (1) */
 
#define BPB_FATSz16   22 /* FAT size [sector] (2) */
 
#define BPB_SecPerTrk   24 /* Track size [sector] (2) */
 
#define BPB_NumHeads   26 /* Number of heads (2) */
 
#define BPB_HiddSec   28 /* Number of special hidden sectors (4) */
 
#define BPB_TotSec32   32 /* Volume size [sector] (4) */
 
#define BS_DrvNum   36 /* Physical drive number (2) */
 
#define BS_BootSig   38 /* Extended boot signature (1) */
 
#define BS_VolID   39 /* Volume serial number (4) */
 
#define BS_VolLab   43 /* Volume label (8) */
 
#define BS_FilSysType   54 /* File system type (1) */
 
#define BPB_FATSz32   36 /* FAT size [sector] (4) */
 
#define BPB_ExtFlags   40 /* Extended flags (2) */
 
#define BPB_FSVer   42 /* File system version (2) */
 
#define BPB_RootClus   44 /* Root dir first cluster (4) */
 
#define BPB_FSInfo   48 /* Offset of FSInfo sector (2) */
 
#define BPB_BkBootSec   50 /* Offset of backup boot sector (2) */
 
#define BS_DrvNum32   64 /* Physical drive number (2) */
 
#define BS_BootSig32   66 /* Extended boot signature (1) */
 
#define BS_VolID32   67 /* Volume serial number (4) */
 
#define BS_VolLab32   71 /* Volume label (8) */
 
#define BS_FilSysType32   82 /* File system type (1) */
 
#define FSI_LeadSig   0 /* FSI: Leading signature (4) */
 
#define FSI_StrucSig   484 /* FSI: Structure signature (4) */
 
#define FSI_Free_Count   488 /* FSI: Number of free clusters (4) */
 
#define FSI_Nxt_Free   492 /* FSI: Last allocated cluster (4) */
 
#define MBR_Table   446 /* MBR: Partition table offset (2) */
 
#define SZ_PTE   16 /* MBR: Size of a partition table entry */
 
#define BS_55AA   510 /* Boot sector signature (2) */
 
#define DIR_Name   0 /* Short file name (11) */
 
#define DIR_Attr   11 /* Attribute (1) */
 
#define DIR_NTres   12 /* NT flag (1) */
 
#define DIR_CrtTimeTenth   13 /* Created time sub-second (1) */
 
#define DIR_CrtTime   14 /* Created time (2) */
 
#define DIR_CrtDate   16 /* Created date (2) */
 
#define DIR_LstAccDate   18 /* Last accessed date (2) */
 
#define DIR_FstClusHI   20 /* Higher 16-bit of first cluster (2) */
 
#define DIR_WrtTime   22 /* Modified time (2) */
 
#define DIR_WrtDate   24 /* Modified date (2) */
 
#define DIR_FstClusLO   26 /* Lower 16-bit of first cluster (2) */
 
#define DIR_FileSize   28 /* File size (4) */
 
#define LDIR_Ord   0 /* LFN entry order and LLE flag (1) */
 
#define LDIR_Attr   11 /* LFN attribute (1) */
 
#define LDIR_Type   12 /* LFN type (1) */
 
#define LDIR_Chksum   13 /* Sum of corresponding SFN entry */
 
#define LDIR_FstClusLO   26 /* Filled by zero (0) */
 
#define SZ_DIR   32 /* Size of a directory entry */
 
#define LLE   0x40 /* Last long entry flag in LDIR_Ord */
 
#define DDE   0xE5 /* Deleted directory entry mark in DIR_Name[0] */
 
#define NDDE   0x05 /* Replacement of the character collides with DDE */
 
#define DEF_NAMEBUF   BYTE sfn[12]
 
#define INIT_BUF(dobj)   (dobj).fn = sfn
 
#define FREE_BUF()
 

Functions

DWORD clust2sect (FATFS *fs, DWORD clst)
 
DWORD get_fat (FATFS *fs, DWORD clst)
 
FRESULT put_fat (FATFS *fs, DWORD clst, DWORD val)
 
FRESULT scan_files (char *path)
 
FRESULT f_mount (BYTE vol, FATFS *fs)
 
FRESULT f_open (FIL *fp, const TCHAR *path, BYTE mode)
 
FRESULT f_read (FIL *fp, void *buff, UINT btr, UINT *br)
 
FRESULT f_write (FIL *fp, const void *buff, UINT btw, UINT *bw)
 
FRESULT f_sync (FIL *fp)
 
FRESULT f_close (FIL *fp)
 
FRESULT f_lseek (FIL *fp, DWORD ofs)
 
FRESULT f_opendir (DIR *dj, const TCHAR *path)
 
FRESULT f_readdir (DIR *dj, FILINFO *fno)
 
FRESULT f_stat (const TCHAR *path, FILINFO *fno)
 
FRESULT f_getfree (const TCHAR *path, DWORD *nclst, FATFS **fatfs)
 
FRESULT f_truncate (FIL *fp)
 
FRESULT f_unlink (const TCHAR *path)
 
FRESULT f_mkdir (const TCHAR *path)
 
FRESULT f_chmod (const TCHAR *path, BYTE value, BYTE mask)
 
FRESULT f_utime (const TCHAR *path, const FILINFO *fno)
 
FRESULT f_rename (const TCHAR *path_old, const TCHAR *path_new)
 

Macro Definition Documentation

#define ABORT (   fs,
  res 
)    { fp->flag |= FA__ERROR; LEAVE_FF(fs, res); }

Definition at line 135 of file ff.c.

#define BPB_BkBootSec   50 /* Offset of backup boot sector (2) */

Definition at line 421 of file ff.c.

#define BPB_BytsPerSec   11 /* Sector size [byte] (2) */

Definition at line 399 of file ff.c.

#define BPB_ExtFlags   40 /* Extended flags (2) */

Definition at line 417 of file ff.c.

#define BPB_FATSz16   22 /* FAT size [sector] (2) */

Definition at line 406 of file ff.c.

#define BPB_FATSz32   36 /* FAT size [sector] (4) */

Definition at line 416 of file ff.c.

#define BPB_FSInfo   48 /* Offset of FSInfo sector (2) */

Definition at line 420 of file ff.c.

#define BPB_FSVer   42 /* File system version (2) */

Definition at line 418 of file ff.c.

#define BPB_HiddSec   28 /* Number of special hidden sectors (4) */

Definition at line 409 of file ff.c.

#define BPB_Media   21 /* Media descriptor (1) */

Definition at line 405 of file ff.c.

#define BPB_NumFATs   16 /* Number of FAT copies (1) */

Definition at line 402 of file ff.c.

#define BPB_NumHeads   26 /* Number of heads (2) */

Definition at line 408 of file ff.c.

#define BPB_RootClus   44 /* Root dir first cluster (4) */

Definition at line 419 of file ff.c.

#define BPB_RootEntCnt   17 /* Number of root dir entries for FAT12/16 (2) */

Definition at line 403 of file ff.c.

#define BPB_RsvdSecCnt   14 /* Size of reserved area [sector] (2) */

Definition at line 401 of file ff.c.

#define BPB_SecPerClus   13 /* Cluster size [sector] (1) */

Definition at line 400 of file ff.c.

#define BPB_SecPerTrk   24 /* Track size [sector] (2) */

Definition at line 407 of file ff.c.

#define BPB_TotSec16   19 /* Volume size [sector] (2) */

Definition at line 404 of file ff.c.

#define BPB_TotSec32   32 /* Volume size [sector] (4) */

Definition at line 410 of file ff.c.

#define BS_55AA   510 /* Boot sector signature (2) */

Definition at line 433 of file ff.c.

#define BS_BootSig   38 /* Extended boot signature (1) */

Definition at line 412 of file ff.c.

#define BS_BootSig32   66 /* Extended boot signature (1) */

Definition at line 423 of file ff.c.

#define BS_DrvNum   36 /* Physical drive number (2) */

Definition at line 411 of file ff.c.

#define BS_DrvNum32   64 /* Physical drive number (2) */

Definition at line 422 of file ff.c.

#define BS_FilSysType   54 /* File system type (1) */

Definition at line 415 of file ff.c.

#define BS_FilSysType32   82 /* File system type (1) */

Definition at line 426 of file ff.c.

#define BS_jmpBoot   0 /* Jump instruction (3) */

Definition at line 397 of file ff.c.

#define BS_OEMName   3 /* OEM name (8) */

Definition at line 398 of file ff.c.

#define BS_VolID   39 /* Volume serial number (4) */

Definition at line 413 of file ff.c.

#define BS_VolID32   67 /* Volume serial number (4) */

Definition at line 424 of file ff.c.

#define BS_VolLab   43 /* Volume label (8) */

Definition at line 414 of file ff.c.

#define BS_VolLab32   71 /* Volume label (8) */

Definition at line 425 of file ff.c.

#define DDE   0xE5 /* Deleted directory entry mark in DIR_Name[0] */

Definition at line 454 of file ff.c.

#define DEF_NAMEBUF   BYTE sfn[12]

Definition at line 487 of file ff.c.

#define DIR_Attr   11 /* Attribute (1) */

Definition at line 436 of file ff.c.

#define DIR_CrtDate   16 /* Created date (2) */

Definition at line 440 of file ff.c.

#define DIR_CrtTime   14 /* Created time (2) */

Definition at line 439 of file ff.c.

#define DIR_CrtTimeTenth   13 /* Created time sub-second (1) */

Definition at line 438 of file ff.c.

#define DIR_FileSize   28 /* File size (4) */

Definition at line 446 of file ff.c.

#define DIR_FstClusHI   20 /* Higher 16-bit of first cluster (2) */

Definition at line 442 of file ff.c.

#define DIR_FstClusLO   26 /* Lower 16-bit of first cluster (2) */

Definition at line 445 of file ff.c.

#define DIR_LstAccDate   18 /* Last accessed date (2) */

Definition at line 441 of file ff.c.

#define DIR_Name   0 /* Short file name (11) */

Definition at line 435 of file ff.c.

#define DIR_NTres   12 /* NT flag (1) */

Definition at line 437 of file ff.c.

#define DIR_WrtDate   24 /* Modified date (2) */

Definition at line 444 of file ff.c.

#define DIR_WrtTime   22 /* Modified time (2) */

Definition at line 443 of file ff.c.

#define ENTER_FF (   fs)

Definition at line 131 of file ff.c.

#define FREE_BUF ( )

Definition at line 489 of file ff.c.

#define FSI_Free_Count   488 /* FSI: Number of free clusters (4) */

Definition at line 429 of file ff.c.

#define FSI_LeadSig   0 /* FSI: Leading signature (4) */

Definition at line 427 of file ff.c.

#define FSI_Nxt_Free   492 /* FSI: Last allocated cluster (4) */

Definition at line 430 of file ff.c.

#define FSI_StrucSig   484 /* FSI: Structure signature (4) */

Definition at line 428 of file ff.c.

#define INIT_BUF (   dobj)    (dobj).fn = sfn

Definition at line 488 of file ff.c.

#define IsDBCS1 (   c)    0

Definition at line 371 of file ff.c.

#define IsDBCS2 (   c)    0

Definition at line 372 of file ff.c.

#define IsDigit (   c)    (((c)>='0')&&((c)<='9'))

Definition at line 353 of file ff.c.

#define IsLower (   c)    (((c)>='a')&&((c)<='z'))

Definition at line 352 of file ff.c.

#define IsUpper (   c)    (((c)>='A')&&((c)<='Z'))

Definition at line 351 of file ff.c.

#define LDIR_Attr   11 /* LFN attribute (1) */

Definition at line 448 of file ff.c.

#define LDIR_Chksum   13 /* Sum of corresponding SFN entry */

Definition at line 450 of file ff.c.

#define LDIR_FstClusLO   26 /* Filled by zero (0) */

Definition at line 451 of file ff.c.

#define LDIR_Ord   0 /* LFN entry order and LLE flag (1) */

Definition at line 447 of file ff.c.

#define LDIR_Type   12 /* LFN type (1) */

Definition at line 449 of file ff.c.

#define LEAVE_FF (   fs,
  res 
)    return res

Definition at line 132 of file ff.c.

#define LLE   0x40 /* Last long entry flag in LDIR_Ord */

Definition at line 453 of file ff.c.

#define MBR_Table   446 /* MBR: Partition table offset (2) */

Definition at line 431 of file ff.c.

#define MIN_FAT16   4086 /* Minimum number of clusters for FAT16 */

Definition at line 389 of file ff.c.

#define MIN_FAT32   65526 /* Minimum number of clusters for FAT32 */

Definition at line 390 of file ff.c.

#define NDDE   0x05 /* Replacement of the character collides with DDE */

Definition at line 455 of file ff.c.

#define NS   11 /* Index of name status byte in fn[] */

Definition at line 378 of file ff.c.

#define NS_BODY   0x08 /* Lower case flag (body) */

Definition at line 382 of file ff.c.

#define NS_DOT   0x20 /* Dot entry */

Definition at line 384 of file ff.c.

#define NS_EXT   0x10 /* Lower case flag (ext) */

Definition at line 383 of file ff.c.

#define NS_LAST   0x04 /* Last segment */

Definition at line 381 of file ff.c.

#define NS_LFN   0x02 /* Force to create LFN entry */

Definition at line 380 of file ff.c.

#define NS_LOSS   0x01 /* Out of 8.3 format */

Definition at line 379 of file ff.c.

#define SS (   fs)    ((fs)->ssize) /* Variable sector size */

Definition at line 117 of file ff.c.

#define SZ_DIR   32 /* Size of a directory entry */

Definition at line 452 of file ff.c.

#define SZ_PTE   16 /* MBR: Size of a partition table entry */

Definition at line 432 of file ff.c.

Function Documentation

DWORD clust2sect ( FATFS fs,
DWORD  clst 
)

Definition at line 802 of file ff.c.

{
clst -= 2;
if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */
return clst * fs->csize + fs->database;
}

Here is the caller graph for this function:

FRESULT f_chmod ( const TCHAR path,
BYTE  value,
BYTE  mask 
)

Definition at line 3435 of file ff.c.

{
FRESULT res;
DIR dj;
BYTE *dir;
res = chk_mounted(&path, &dj.fs, 1);
if (res == FR_OK) {
INIT_BUF(dj);
res = follow_path(&dj, path); /* Follow the file path */
if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
if (res == FR_OK) {
dir = dj.dir;
if (!dir) { /* Is it a root directory? */
} else { /* File or sub directory */
mask &= AM_RDO|AM_HID|AM_SYS|AM_ARC; /* Valid attribute mask */
dir[DIR_Attr] = (value & mask) | (dir[DIR_Attr] & (BYTE)~mask); /* Apply attribute change */
dj.fs->wflag = 1;
res = sync(dj.fs);
}
}
}
LEAVE_FF(dj.fs, res);
}
FRESULT f_close ( FIL fp)

Definition at line 2728 of file ff.c.

{
FRESULT res;
#if _FS_READONLY
res = validate(fp);
{
#if _FS_REENTRANT
FATFS *fs = fp->fs;
#endif
if (res == FR_OK) fp->fs = 0; /* Discard file object */
LEAVE_FF(fs, res);
}
#else
res = f_sync(fp); /* Flush cached data */
#if _FS_LOCK
if (res == FR_OK) { /* Decrement open counter */
#if _FS_REENTRANT
FATFS *fs = fp->fs;;
res = validate(fp);
if (res == FR_OK) {
res = dec_lock(fp->lockid);
unlock_fs(fs, FR_OK);
}
#else
res = dec_lock(fp->lockid);
#endif
}
#endif
if (res == FR_OK) fp->fs = 0; /* Discard file object */
return res;
#endif
}

Here is the call graph for this function:

FRESULT f_getfree ( const TCHAR path,
DWORD nclst,
FATFS **  fatfs 
)

Definition at line 3177 of file ff.c.

{
FRESULT res;
FATFS *fs;
DWORD n, clst, sect, stat;
UINT i;
BYTE fat, *p;
/* Get drive number */
res = chk_mounted(&path, fatfs, 0);
fs = *fatfs;
if (res == FR_OK) {
/* If free_clust is valid, return it without full cluster scan */
if (fs->free_clust <= fs->n_fatent - 2) {
*nclst = fs->free_clust;
} else {
/* Get number of free clusters */
fat = fs->fs_type;
n = 0;
if (fat == FS_FAT12) {
clst = 2;
do {
stat = get_fat(fs, clst);
if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
if (stat == 1) { res = FR_INT_ERR; break; }
if (stat == 0) n++;
} while (++clst < fs->n_fatent);
} else {
clst = fs->n_fatent;
sect = fs->fatbase;
i = 0; p = 0;
do {
if (!i) {
res = move_window(fs, sect++);
if (res != FR_OK) break;
p = fs->win;
i = SS(fs);
}
if (fat == FS_FAT16) {
if (LD_WORD(p) == 0) n++;
p += 2; i -= 2;
} else {
if ((LD_DWORD(p) & 0x0FFFFFFF) == 0) n++;
p += 4; i -= 4;
}
} while (--clst);
}
fs->free_clust = n;
if (fat == FS_FAT32) fs->fsi_flag = 1;
*nclst = n;
}
}
LEAVE_FF(fs, res);
}

Here is the call graph for this function:

FRESULT f_lseek ( FIL fp,
DWORD  ofs 
)

Definition at line 2897 of file ff.c.

{
FRESULT res;
res = validate(fp); /* Check validity of the object */
if (res != FR_OK) LEAVE_FF(fp->fs, res);
if (fp->flag & FA__ERROR) /* Check abort flag */
#if _USE_FASTSEEK
if (fp->cltbl) { /* Fast seek */
DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
if (ofs == CREATE_LINKMAP) { /* Create CLMT */
tbl = fp->cltbl;
tlen = *tbl++; ulen = 2; /* Given table size and required table size */
cl = fp->sclust; /* Top of the chain */
if (cl) {
do {
/* Get a fragment */
tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */
do {
pcl = cl; ncl++;
cl = get_fat(fp->fs, cl);
if (cl <= 1) ABORT(fp->fs, FR_INT_ERR);
if (cl == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
} while (cl == pcl + 1);
if (ulen <= tlen) { /* Store the length and top of the fragment */
*tbl++ = ncl; *tbl++ = tcl;
}
} while (cl < fp->fs->n_fatent); /* Repeat until end of chain */
}
*fp->cltbl = ulen; /* Number of items used */
if (ulen <= tlen)
*tbl = 0; /* Terminate table */
else
res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */
} else { /* Fast seek */
if (ofs > fp->fsize) /* Clip offset at the file size */
ofs = fp->fsize;
fp->fptr = ofs; /* Set file pointer */
if (ofs) {
fp->clust = clmt_clust(fp, ofs - 1);
dsc = clust2sect(fp->fs, fp->clust);
if (!dsc) ABORT(fp->fs, FR_INT_ERR);
dsc += (ofs - 1) / SS(fp->fs) & (fp->fs->csize - 1);
if (fp->fptr % SS(fp->fs) && dsc != fp->dsect) { /* Refill sector cache if needed */
#if !_FS_TINY
#if !_FS_READONLY
if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
fp->flag &= ~FA__DIRTY;
}
#endif
if (disk_read(fp->fs->drv, fp->buf, dsc, 1) != RES_OK) /* Load current sector */
#endif
fp->dsect = dsc;
}
}
}
} else
#endif
/* Normal Seek */
{
DWORD clst, bcs, nsect, ifptr;
if (ofs > fp->fsize /* In read-only mode, clip offset with the file size */
&& !(fp->flag & FA_WRITE)
#endif
) ofs = fp->fsize;
ifptr = fp->fptr;
fp->fptr = nsect = 0;
if (ofs) {
bcs = (DWORD)fp->fs->csize * SS(fp->fs); /* Cluster size (byte) */
if (ifptr > 0 &&
(ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
fp->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */
ofs -= fp->fptr;
clst = fp->clust;
} else { /* When seek to back cluster, */
clst = fp->sclust; /* start from the first cluster */
#if !_FS_READONLY
if (clst == 0) { /* If no cluster chain, create a new chain */
clst = create_chain(fp->fs, 0);
if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
fp->sclust = clst;
}
#endif
fp->clust = clst;
}
if (clst != 0) {
while (ofs > bcs) { /* Cluster following loop */
#if !_FS_READONLY
if (fp->flag & FA_WRITE) { /* Check if in write mode or not */
clst = create_chain(fp->fs, clst); /* Force stretch if in write mode */
if (clst == 0) { /* When disk gets full, clip file size */
ofs = bcs; break;
}
} else
#endif
clst = get_fat(fp->fs, clst); /* Follow cluster chain if not in write mode */
if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
if (clst <= 1 || clst >= fp->fs->n_fatent) ABORT(fp->fs, FR_INT_ERR);
fp->clust = clst;
fp->fptr += bcs;
ofs -= bcs;
}
fp->fptr += ofs;
if (ofs % SS(fp->fs)) {
nsect = clust2sect(fp->fs, clst); /* Current sector */
if (!nsect) ABORT(fp->fs, FR_INT_ERR);
nsect += ofs / SS(fp->fs);
}
}
}
if (fp->fptr % SS(fp->fs) && nsect != fp->dsect) { /* Fill sector cache if needed */
#if !_FS_TINY
#if !_FS_READONLY
if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
fp->flag &= ~FA__DIRTY;
}
#endif
if (disk_read(fp->fs->drv, fp->buf, nsect, 1) != RES_OK) /* Fill sector cache */
#endif
fp->dsect = nsect;
}
#if !_FS_READONLY
if (fp->fptr > fp->fsize) { /* Set file change flag if the file size is extended */
fp->fsize = fp->fptr;
fp->flag |= FA__WRITTEN;
}
#endif
}
LEAVE_FF(fp->fs, res);
}

Here is the call graph for this function:

FRESULT f_mkdir ( const TCHAR path)

Definition at line 3362 of file ff.c.

{
FRESULT res;
DIR dj;
BYTE *dir, n;
DWORD dsc, dcl, pcl, tim = get_fattime();
res = chk_mounted(&path, &dj.fs, 1);
if (res == FR_OK) {
INIT_BUF(dj);
res = follow_path(&dj, path); /* Follow the file path */
if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */
if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NS] & NS_DOT))
if (res == FR_NO_FILE) { /* Can create a new directory */
dcl = create_chain(dj.fs, 0); /* Allocate a cluster for the new directory table */
res = FR_OK;
if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */
if (dcl == 1) res = FR_INT_ERR;
if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;
if (res == FR_OK) /* Flush FAT */
res = move_window(dj.fs, 0);
if (res == FR_OK) { /* Initialize the new directory table */
dsc = clust2sect(dj.fs, dcl);
dir = dj.fs->win;
mem_set(dir, 0, SS(dj.fs));
mem_set(dir+DIR_Name, ' ', 8+3); /* Create "." entry */
dir[DIR_Name] = '.';
dir[DIR_Attr] = AM_DIR;
ST_DWORD(dir+DIR_WrtTime, tim);
st_clust(dir, dcl);
mem_cpy(dir+SZ_DIR, dir, SZ_DIR); /* Create ".." entry */
dir[33] = '.'; pcl = dj.sclust;
if (dj.fs->fs_type == FS_FAT32 && pcl == dj.fs->dirbase)
pcl = 0;
st_clust(dir+SZ_DIR, pcl);
for (n = dj.fs->csize; n; n--) { /* Write dot entries and clear following sectors */
dj.fs->winsect = dsc++;
dj.fs->wflag = 1;
res = move_window(dj.fs, 0);
if (res != FR_OK) break;
mem_set(dir, 0, SS(dj.fs));
}
}
if (res == FR_OK) res = dir_register(&dj); /* Register the object to the directoy */
if (res != FR_OK) {
remove_chain(dj.fs, dcl); /* Could not register, remove cluster chain */
} else {
dir = dj.dir;
dir[DIR_Attr] = AM_DIR; /* Attribute */
ST_DWORD(dir+DIR_WrtTime, tim); /* Created time */
st_clust(dir, dcl); /* Table start cluster */
dj.fs->wflag = 1;
res = sync(dj.fs);
}
}
}
LEAVE_FF(dj.fs, res);
}

Here is the call graph for this function:

FRESULT f_mount ( BYTE  vol,
FATFS fs 
)

Definition at line 2288 of file ff.c.

{
FATFS *rfs;
if (vol >= _VOLUMES) /* Check if the drive number is valid */
rfs = FatFs[vol]; /* Get current fs object */
if (rfs) {
#if _FS_LOCK
clear_lock(rfs);
#endif
#if _FS_REENTRANT /* Discard sync object of the current volume */
if (!ff_del_syncobj(rfs->sobj)) return FR_INT_ERR;
#endif
rfs->fs_type = 0; /* Clear old fs object */
}
if (fs) {
fs->fs_type = 0; /* Clear new fs object */
#if _FS_REENTRANT /* Create sync object for the new volume */
if (!ff_cre_syncobj(vol, &fs->sobj)) return FR_INT_ERR;
#endif
}
FatFs[vol] = fs; /* Register new fs object */
return FR_OK;
}
FRESULT f_open ( FIL fp,
const TCHAR path,
BYTE  mode 
)

Definition at line 2328 of file ff.c.

{
FRESULT res;
DIR dj;
BYTE *dir;
if (!fp) return FR_INVALID_OBJECT;
fp->fs = 0; /* Clear file object */
#if !_FS_READONLY
res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));
#else
mode &= FA_READ;
res = chk_mounted(&path, &dj.fs, 0);
#endif
if (res == FR_OK) {
INIT_BUF(dj);
res = follow_path(&dj, path); /* Follow the file path */
dir = dj.dir;
#if !_FS_READONLY /* R/W configuration */
if (res == FR_OK) {
if (!dir) /* Current dir itself */
#if _FS_LOCK
else
res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
#endif
}
/* Create or Open a file */
DWORD dw, cl;
if (res != FR_OK) { /* No file, create new */
if (res == FR_NO_FILE) /* There is no file to open, create a new entry */
#if _FS_LOCK
res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
#else
res = dir_register(&dj);
#endif
mode |= FA_CREATE_ALWAYS; /* File is created */
dir = dj.dir; /* New entry */
}
else { /* Any object is already existing */
if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */
res = FR_DENIED;
} else {
if (mode & FA_CREATE_NEW) /* Cannot create as new file */
res = FR_EXIST;
}
}
if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */
dw = get_fattime(); /* Created time */
dir[DIR_Attr] = 0; /* Reset attribute */
ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */
cl = ld_clust(dj.fs, dir); /* Get start cluster */
st_clust(dir, 0); /* cluster = 0 */
dj.fs->wflag = 1;
if (cl) { /* Remove the cluster chain if exist */
dw = dj.fs->winsect;
res = remove_chain(dj.fs, cl);
if (res == FR_OK) {
dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */
res = move_window(dj.fs, dw);
}
}
}
}
else { /* Open an existing file */
if (res == FR_OK) { /* Follow succeeded */
if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */
res = FR_NO_FILE;
} else {
if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
res = FR_DENIED;
}
}
}
if (res == FR_OK) {
if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */
mode |= FA__WRITTEN;
fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */
fp->dir_ptr = dir;
#if _FS_LOCK
fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
if (!fp->lockid) res = FR_INT_ERR;
#endif
}
#else /* R/O configuration */
if (res == FR_OK) { /* Follow succeeded */
dir = dj.dir;
if (!dir) { /* Current dir itself */
} else {
if (dir[DIR_Attr] & AM_DIR) /* It is a directory */
res = FR_NO_FILE;
}
}
#endif
if (res == FR_OK) {
fp->flag = mode; /* File access mode */
fp->sclust = ld_clust(dj.fs, dir); /* File start cluster */
fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
fp->fptr = 0; /* File pointer */
fp->dsect = 0;
#if _USE_FASTSEEK
fp->cltbl = 0; /* Normal seek mode */
#endif
fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */
}
}
LEAVE_FF(dj.fs, res);
}

Here is the call graph for this function:

FRESULT f_opendir ( DIR dj,
const TCHAR path 
)

Definition at line 3055 of file ff.c.

{
FRESULT res;
FATFS *fs;
if (!dj) return FR_INVALID_OBJECT;
res = chk_mounted(&path, &dj->fs, 0);
fs = dj->fs;
if (res == FR_OK) {
INIT_BUF(*dj);
res = follow_path(dj, path); /* Follow the path to the directory */
if (res == FR_OK) { /* Follow completed */
if (dj->dir) { /* It is not the root dir */
if (dj->dir[DIR_Attr] & AM_DIR) { /* The object is a directory */
dj->sclust = ld_clust(fs, dj->dir);
} else { /* The object is not a directory */
res = FR_NO_PATH;
}
}
if (res == FR_OK) {
dj->id = fs->id;
res = dir_sdi(dj, 0); /* Rewind dir */
}
}
if (res == FR_NO_FILE) res = FR_NO_PATH;
if (res != FR_OK) dj->fs = 0; /* Invalidate the dir object if function faild */
} else {
dj->fs = 0;
}
LEAVE_FF(fs, res);
}

Here is the caller graph for this function:

FRESULT f_read ( FIL fp,
void *  buff,
UINT  btr,
UINT br 
)

Definition at line 2460 of file ff.c.

{
FRESULT res;
DWORD clst, sect, remain;
UINT rcnt, cc;
BYTE csect, *rbuff = buff;
*br = 0; /* Clear read byte counter */
res = validate(fp); /* Check validity */
if (res != FR_OK) LEAVE_FF(fp->fs, res);
if (fp->flag & FA__ERROR) /* Aborted file? */
if (!(fp->flag & FA_READ)) /* Check access mode */
remain = fp->fsize - fp->fptr;
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
for ( ; btr; /* Repeat until all data read */
rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
if (!csect) { /* On the cluster boundary? */
if (fp->fptr == 0) { /* On the top of the file? */
clst = fp->sclust; /* Follow from the origin */
} else { /* Middle or end of the file */
#if _USE_FASTSEEK
if (fp->cltbl)
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
else
#endif
clst = get_fat(fp->fs, fp->clust); /* Follow cluster chain on the FAT */
}
if (clst < 2) ABORT(fp->fs, FR_INT_ERR);
if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
fp->clust = clst; /* Update current cluster */
}
sect = clust2sect(fp->fs, fp->clust); /* Get current sector */
if (!sect) ABORT(fp->fs, FR_INT_ERR);
sect += csect;
cc = btr / SS(fp->fs); /* When remaining bytes >= sector size, */
if (cc) { /* Read maximum contiguous sectors directly */
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
cc = fp->fs->csize - csect;
if (disk_read(fp->fs->drv, rbuff, sect, (BYTE)cc) != RES_OK)
#if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
#if _FS_TINY
if (fp->fs->wflag && fp->fs->winsect - sect < cc)
mem_cpy(rbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), fp->fs->win, SS(fp->fs));
#else
if ((fp->flag & FA__DIRTY) && fp->dsect - sect < cc)
mem_cpy(rbuff + ((fp->dsect - sect) * SS(fp->fs)), fp->buf, SS(fp->fs));
#endif
#endif
rcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
continue;
}
#if !_FS_TINY
if (fp->dsect != sect) { /* Load data sector if not in cache */
#if !_FS_READONLY
if (fp->flag & FA__DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
fp->flag &= ~FA__DIRTY;
}
#endif
if (disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK) /* Fill sector cache */
}
#endif
fp->dsect = sect;
}
rcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs)); /* Get partial sector data from sector buffer */
if (rcnt > btr) rcnt = btr;
#if _FS_TINY
if (move_window(fp->fs, fp->dsect)) /* Move sector window */
mem_cpy(rbuff, &fp->fs->win[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
#else
mem_cpy(rbuff, &fp->buf[fp->fptr % SS(fp->fs)], rcnt); /* Pick partial sector */
#endif
}
LEAVE_FF(fp->fs, FR_OK);
}

Here is the call graph for this function:

FRESULT f_readdir ( DIR dj,
FILINFO fno 
)

Definition at line 3102 of file ff.c.

{
FRESULT res;
res = validate(dj); /* Check validity of the object */
if (res == FR_OK) {
if (!fno) {
res = dir_sdi(dj, 0); /* Rewind the directory object */
} else {
INIT_BUF(*dj);
res = dir_read(dj); /* Read an directory item */
if (res == FR_NO_FILE) { /* Reached end of dir */
dj->sect = 0;
res = FR_OK;
}
if (res == FR_OK) { /* A valid entry is found */
get_fileinfo(dj, fno); /* Get the object information */
res = dir_next(dj, 0); /* Increment index for next */
if (res == FR_NO_FILE) {
dj->sect = 0;
res = FR_OK;
}
}
}
}
LEAVE_FF(dj->fs, res);
}

Here is the caller graph for this function:

FRESULT f_rename ( const TCHAR path_old,
const TCHAR path_new 
)

Definition at line 3518 of file ff.c.

{
FRESULT res;
DIR djo, djn;
BYTE buf[21], *dir;
DWORD dw;
res = chk_mounted(&path_old, &djo.fs, 1);
if (res == FR_OK) {
djn.fs = djo.fs;
INIT_BUF(djo);
res = follow_path(&djo, path_old); /* Check old object */
if (_FS_RPATH && res == FR_OK && (djo.fn[NS] & NS_DOT))
#if _FS_LOCK
if (res == FR_OK) res = chk_lock(&djo, 2);
#endif
if (res == FR_OK) { /* Old object is found */
if (!djo.dir) { /* Is root dir? */
res = FR_NO_FILE;
} else {
mem_cpy(buf, djo.dir+DIR_Attr, 21); /* Save the object information except for name */
mem_cpy(&djn, &djo, sizeof (DIR)); /* Check new object */
res = follow_path(&djn, path_new);
if (res == FR_OK) res = FR_EXIST; /* The new object name is already existing */
if (res == FR_NO_FILE) { /* Is it a valid path and no name collision? */
/* Start critical section that an interruption or error can cause cross-link */
res = dir_register(&djn); /* Register the new entry */
if (res == FR_OK) {
dir = djn.dir; /* Copy object information except for name */
mem_cpy(dir+13, buf+2, 19);
dir[DIR_Attr] = buf[0] | AM_ARC;
djo.fs->wflag = 1;
if (djo.sclust != djn.sclust && (dir[DIR_Attr] & AM_DIR)) { /* Update .. entry in the directory if needed */
dw = clust2sect(djo.fs, ld_clust(djo.fs, dir));
if (!dw) {
res = FR_INT_ERR;
} else {
res = move_window(djo.fs, dw);
dir = djo.fs->win+SZ_DIR; /* .. entry */
if (res == FR_OK && dir[1] == '.') {
dw = (djo.fs->fs_type == FS_FAT32 && djn.sclust == djo.fs->dirbase) ? 0 : djn.sclust;
st_clust(dir, dw);
djo.fs->wflag = 1;
}
}
}
if (res == FR_OK) {
res = dir_remove(&djo); /* Remove old entry */
if (res == FR_OK)
res = sync(djo.fs);
}
}
/* End critical section */
}
}
}
}
LEAVE_FF(djo.fs, res);
}

Here is the call graph for this function:

FRESULT f_stat ( const TCHAR path,
FILINFO fno 
)

Definition at line 3144 of file ff.c.

{
FRESULT res;
DIR dj;
res = chk_mounted(&path, &dj.fs, 0);
if (res == FR_OK) {
INIT_BUF(dj);
res = follow_path(&dj, path); /* Follow the file path */
if (res == FR_OK) { /* Follow completed */
if (dj.dir) /* Found an object */
get_fileinfo(&dj, fno);
else /* It is root dir */
}
}
LEAVE_FF(dj.fs, res);
}
FRESULT f_sync ( FIL fp)

Definition at line 2680 of file ff.c.

{
FRESULT res;
DWORD tim;
BYTE *dir;
res = validate(fp); /* Check validity of the object */
if (res == FR_OK) {
if (fp->flag & FA__WRITTEN) { /* Has the file been written? */
#if !_FS_TINY /* Write-back dirty buffer */
if (fp->flag & FA__DIRTY) {
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
fp->flag &= ~FA__DIRTY;
}
#endif
/* Update the directory entry */
res = move_window(fp->fs, fp->dir_sect);
if (res == FR_OK) {
dir = fp->dir_ptr;
dir[DIR_Attr] |= AM_ARC; /* Set archive bit */
ST_DWORD(dir+DIR_FileSize, fp->fsize); /* Update file size */
st_clust(dir, fp->sclust); /* Update start cluster */
tim = get_fattime(); /* Update updated time */
ST_DWORD(dir+DIR_WrtTime, tim);
fp->flag &= ~FA__WRITTEN;
fp->fs->wflag = 1;
res = sync(fp->fs);
}
}
}
LEAVE_FF(fp->fs, res);
}

Here is the call graph for this function:

Here is the caller graph for this function:

FRESULT f_truncate ( FIL fp)

Definition at line 3244 of file ff.c.

{
FRESULT res;
DWORD ncl;
if (!fp) return FR_INVALID_OBJECT;
res = validate(fp); /* Check validity of the object */
if (res == FR_OK) {
if (fp->flag & FA__ERROR) { /* Check abort flag */
res = FR_INT_ERR;
} else {
if (!(fp->flag & FA_WRITE)) /* Check access mode */
res = FR_DENIED;
}
}
if (res == FR_OK) {
if (fp->fsize > fp->fptr) {
fp->fsize = fp->fptr; /* Set file size to current R/W point */
fp->flag |= FA__WRITTEN;
if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */
res = remove_chain(fp->fs, fp->sclust);
fp->sclust = 0;
} else { /* When truncate a part of the file, remove remaining clusters */
ncl = get_fat(fp->fs, fp->clust);
res = FR_OK;
if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;
if (ncl == 1) res = FR_INT_ERR;
if (res == FR_OK && ncl < fp->fs->n_fatent) {
res = put_fat(fp->fs, fp->clust, 0x0FFFFFFF);
if (res == FR_OK) res = remove_chain(fp->fs, ncl);
}
}
}
if (res != FR_OK) fp->flag |= FA__ERROR;
}
LEAVE_FF(fp->fs, res);
}

Here is the call graph for this function:

FRESULT f_unlink ( const TCHAR path)

Definition at line 3294 of file ff.c.

{
FRESULT res;
DIR dj, sdj;
BYTE *dir;
DWORD dclst;
res = chk_mounted(&path, &dj.fs, 1);
if (res == FR_OK) {
INIT_BUF(dj);
res = follow_path(&dj, path); /* Follow the file path */
if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
res = FR_INVALID_NAME; /* Cannot remove dot entry */
#if _FS_LOCK
if (res == FR_OK) res = chk_lock(&dj, 2); /* Cannot remove open file */
#endif
if (res == FR_OK) { /* The object is accessible */
dir = dj.dir;
if (!dir) {
res = FR_INVALID_NAME; /* Cannot remove the start directory */
} else {
if (dir[DIR_Attr] & AM_RDO)
res = FR_DENIED; /* Cannot remove R/O object */
}
dclst = ld_clust(dj.fs, dir);
if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */
if (dclst < 2) {
res = FR_INT_ERR;
} else {
mem_cpy(&sdj, &dj, sizeof (DIR)); /* Check if the sub-dir is empty or not */
sdj.sclust = dclst;
res = dir_sdi(&sdj, 2); /* Exclude dot entries */
if (res == FR_OK) {
res = dir_read(&sdj);
if (res == FR_OK /* Not empty dir */
|| dclst == dj.fs->cdir /* Current dir */
#endif
) res = FR_DENIED;
if (res == FR_NO_FILE) res = FR_OK; /* Empty */
}
}
}
if (res == FR_OK) {
res = dir_remove(&dj); /* Remove the directory entry */
if (res == FR_OK) {
if (dclst) /* Remove the cluster chain if exist */
res = remove_chain(dj.fs, dclst);
if (res == FR_OK) res = sync(dj.fs);
}
}
}
}
LEAVE_FF(dj.fs, res);
}
FRESULT f_utime ( const TCHAR path,
const FILINFO fno 
)

Definition at line 3477 of file ff.c.

{
FRESULT res;
DIR dj;
BYTE *dir;
res = chk_mounted(&path, &dj.fs, 1);
if (res == FR_OK) {
INIT_BUF(dj);
res = follow_path(&dj, path); /* Follow the file path */
if (_FS_RPATH && res == FR_OK && (dj.fn[NS] & NS_DOT))
if (res == FR_OK) {
dir = dj.dir;
if (!dir) { /* Root directory */
} else { /* File or sub-directory */
dj.fs->wflag = 1;
res = sync(dj.fs);
}
}
}
LEAVE_FF(dj.fs, res);
}
FRESULT f_write ( FIL fp,
const void *  buff,
UINT  btw,
UINT bw 
)

Definition at line 2561 of file ff.c.

{
FRESULT res;
DWORD clst, sect;
UINT wcnt, cc;
const BYTE *wbuff = buff;
BYTE csect;
*bw = 0; /* Clear write byte counter */
res = validate(fp); /* Check validity */
if (res != FR_OK) LEAVE_FF(fp->fs, res);
if (fp->flag & FA__ERROR) /* Aborted file? */
if (!(fp->flag & FA_WRITE)) /* Check access mode */
if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0; /* File size cannot reach 4GB */
for ( ; btw; /* Repeat until all data written */
wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
if ((fp->fptr % SS(fp->fs)) == 0) { /* On the sector boundary? */
csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1)); /* Sector offset in the cluster */
if (!csect) { /* On the cluster boundary? */
if (fp->fptr == 0) { /* On the top of the file? */
clst = fp->sclust; /* Follow from the origin */
if (clst == 0) /* When no cluster is allocated, */
fp->sclust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */
} else { /* Middle or end of the file */
#if _USE_FASTSEEK
if (fp->cltbl)
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
else
#endif
clst = create_chain(fp->fs, fp->clust); /* Follow or stretch cluster chain on the FAT */
}
if (clst == 0) break; /* Could not allocate a new cluster (disk full) */
if (clst == 1) ABORT(fp->fs, FR_INT_ERR);
if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
fp->clust = clst; /* Update current cluster */
}
#if _FS_TINY
if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0)) /* Write-back sector cache */
#else
if (fp->flag & FA__DIRTY) { /* Write-back sector cache */
if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
fp->flag &= ~FA__DIRTY;
}
#endif
sect = clust2sect(fp->fs, fp->clust); /* Get current sector */
if (!sect) ABORT(fp->fs, FR_INT_ERR);
sect += csect;
cc = btw / SS(fp->fs); /* When remaining bytes >= sector size, */
if (cc) { /* Write maximum contiguous sectors directly */
if (csect + cc > fp->fs->csize) /* Clip at cluster boundary */
cc = fp->fs->csize - csect;
if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK)
#if _FS_TINY
if (fp->fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
fp->fs->wflag = 0;
}
#else
if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
fp->flag &= ~FA__DIRTY;
}
#endif
wcnt = SS(fp->fs) * cc; /* Number of bytes transferred */
continue;
}
#if _FS_TINY
if (fp->fptr >= fp->fsize) { /* Avoid silly cache filling at growing edge */
if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);
fp->fs->winsect = sect;
}
#else
if (fp->dsect != sect) { /* Fill sector cache with file data */
if (fp->fptr < fp->fsize &&
disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
}
#endif
fp->dsect = sect;
}
wcnt = SS(fp->fs) - ((UINT)fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */
if (wcnt > btw) wcnt = btw;
#if _FS_TINY
if (move_window(fp->fs, fp->dsect)) /* Move sector window */
mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */
fp->fs->wflag = 1;
#else
mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt); /* Fit partial sector */
fp->flag |= FA__DIRTY;
#endif
}
if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */
fp->flag |= FA__WRITTEN; /* Set file change flag */
LEAVE_FF(fp->fs, FR_OK);
}

Here is the call graph for this function:

DWORD get_fat ( FATFS fs,
DWORD  clst 
)

Definition at line 820 of file ff.c.

{
UINT wc, bc;
BYTE *p;
if (clst < 2 || clst >= fs->n_fatent) /* Check range */
return 1;
switch (fs->fs_type) {
case FS_FAT12 :
bc = (UINT)clst; bc += bc / 2;
if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
wc = fs->win[bc % SS(fs)]; bc++;
if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
wc |= fs->win[bc % SS(fs)] << 8;
return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
case FS_FAT16 :
if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
p = &fs->win[clst * 2 % SS(fs)];
return LD_WORD(p);
case FS_FAT32 :
if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
p = &fs->win[clst * 4 % SS(fs)];
return LD_DWORD(p) & 0x0FFFFFFF;
}
return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */
}

Here is the caller graph for this function:

FRESULT put_fat ( FATFS fs,
DWORD  clst,
DWORD  val 
)

Definition at line 863 of file ff.c.

{
UINT bc;
BYTE *p;
FRESULT res;
if (clst < 2 || clst >= fs->n_fatent) { /* Check range */
res = FR_INT_ERR;
} else {
switch (fs->fs_type) {
case FS_FAT12 :
bc = (UINT)clst; bc += bc / 2;
res = move_window(fs, fs->fatbase + (bc / SS(fs)));
if (res != FR_OK) break;
p = &fs->win[bc % SS(fs)];
*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
bc++;
fs->wflag = 1;
res = move_window(fs, fs->fatbase + (bc / SS(fs)));
if (res != FR_OK) break;
p = &fs->win[bc % SS(fs)];
*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
break;
case FS_FAT16 :
res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
if (res != FR_OK) break;
p = &fs->win[clst * 2 % SS(fs)];
ST_WORD(p, (WORD)val);
break;
case FS_FAT32 :
res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
if (res != FR_OK) break;
p = &fs->win[clst * 4 % SS(fs)];
val |= LD_DWORD(p) & 0xF0000000;
ST_DWORD(p, val);
break;
default :
res = FR_INT_ERR;
}
fs->wflag = 1;
}
return res;
}

Here is the caller graph for this function:

FRESULT scan_files ( char *  path)

Definition at line 2242 of file ff.c.

{
FRESULT res;
FILINFO fno;
DIR dir;
int i;
char *fn; /* This function is assuming non-Unicode cfg. */
#if _USE_LFN
static char lfn[_MAX_LFN + 1];
fno.lfname = lfn;
fno.lfsize = sizeof lfn;
#endif
res = f_opendir(&dir, path); /* Open the directory */
if (res == FR_OK) {
i = strlen(path);
for (;;) {
res = f_readdir(&dir, &fno); /* Read a directory item */
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
if (fno.fname[0] == '.') continue; /* Ignore dot entry */
#if _USE_LFN
fn = *fno.lfname ? fno.lfname : fno.fname;
#else
fn = fno.fname;
#endif
if (fno.fattrib & AM_DIR) { /* It is a directory */
sprintf(&path[i], "/%s", fn);
res = scan_files(path);
if (res != FR_OK) break;
path[i] = 0;
} else { /* It is a file. */
printf("%s/%s\n", path, fn);
}
}
}
return res;
}

Here is the call graph for this function:

Here is the caller graph for this function: