2017-04-06 17:03:53 +02:00
/*----------------------------------------------------------------------------/
/ FatFs - Generic FAT file system module R0 .12 c /
/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /
2015-04-26 17:54:51 +02:00
/
2017-04-06 17:03:53 +02:00
/ Copyright ( C ) 2017 , ChaN , all right reserved .
2015-04-26 17:54:51 +02:00
/
2017-04-06 17:03:53 +02:00
/ FatFs module is an open source software . Redistribution and use of FatFs in
/ source and binary forms , with or without modification , are permitted provided
/ that the following condition is met :
2015-04-26 17:54:51 +02:00
/ 1. Redistributions of source code must retain the above copyright notice ,
/ this condition and the following disclaimer .
/
/ This software is provided by the copyright holder and contributors " AS IS "
/ and any warranties related to this software are DISCLAIMED .
/ The copyright owner or contributors be NOT LIABLE for any damages caused
/ by use of this software .
2017-04-06 17:03:53 +02:00
/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2015-04-26 17:54:51 +02:00
# ifndef _FATFS
2017-04-06 17:03:53 +02:00
# define _FATFS 68300 /* Revision ID */
2015-04-26 17:54:51 +02:00
# ifdef __cplusplus
extern " C " {
# endif
# include "integer.h" /* Basic integer types */
# include "ffconf.h" /* FatFs configuration options */
2017-04-06 17:03:53 +02:00
2015-04-26 17:54:51 +02:00
# if _FATFS != _FFCONF
# error Wrong configuration file (ffconf.h).
# endif
/* Definitions of volume management */
# if _MULTI_PARTITION /* Multiple partition configuration */
typedef struct {
BYTE pd ; /* Physical drive number */
BYTE pt ; /* Partition: 0:Auto detect, 1-4:Forced partition) */
} PARTITION ;
extern PARTITION VolToPart [ ] ; /* Volume - Partition resolution table */
# endif
/* Type of path name strings on FatFs API */
2017-04-06 17:03:53 +02:00
# if _LFN_UNICODE /* Unicode (UTF-16) string */
# if _USE_LFN == 0
2015-04-26 17:54:51 +02:00
# error _LFN_UNICODE must be 0 at non-LFN cfg.
# endif
# ifndef _INC_TCHAR
typedef WCHAR TCHAR ;
# define _T(x) L ## x
# define _TEXT(x) L ## x
# endif
# else /* ANSI/OEM string */
# ifndef _INC_TCHAR
typedef char TCHAR ;
# define _T(x) x
# define _TEXT(x) x
# endif
2017-04-06 17:03:53 +02:00
# endif
2015-04-26 17:54:51 +02:00
2017-04-06 17:03:53 +02:00
/* Type of file size variables */
# if _FS_EXFAT
# if _USE_LFN == 0
# error LFN must be enabled when enable exFAT
# endif
typedef QWORD FSIZE_t ;
# else
typedef DWORD FSIZE_t ;
2015-04-26 17:54:51 +02:00
# endif
/* File system object structure (FATFS) */
typedef struct {
2017-04-06 17:03:53 +02:00
BYTE fs_type ; /* File system type (0:N/A) */
2015-04-26 17:54:51 +02:00
BYTE drv ; /* Physical drive number */
2017-04-06 17:03:53 +02:00
BYTE n_fats ; /* Number of FATs (1 or 2) */
2015-04-26 17:54:51 +02:00
BYTE wflag ; /* win[] flag (b0:dirty) */
BYTE fsi_flag ; /* FSINFO flags (b7:disabled, b0:dirty) */
WORD id ; /* File system mount ID */
WORD n_rootdir ; /* Number of root directory entries (FAT12/16) */
2017-04-06 17:03:53 +02:00
WORD csize ; /* Cluster size [sectors] */
2015-04-26 17:54:51 +02:00
# if _MAX_SS != _MIN_SS
2017-04-06 17:03:53 +02:00
WORD ssize ; /* Sector size (512, 1024, 2048 or 4096) */
# endif
# if _USE_LFN != 0
WCHAR * lfnbuf ; /* LFN working buffer */
# endif
# if _FS_EXFAT
BYTE * dirbuf ; /* Directory entry block scratchpad buffer */
2015-04-26 17:54:51 +02:00
# endif
# if _FS_REENTRANT
_SYNC_t sobj ; /* Identifier of sync object */
# endif
# if !_FS_READONLY
2017-04-06 17:03:53 +02:00
DWORD last_clst ; /* Last allocated cluster */
DWORD free_clst ; /* Number of free clusters */
2015-04-26 17:54:51 +02:00
# endif
2017-04-06 17:03:53 +02:00
# if _FS_RPATH != 0
2015-04-26 17:54:51 +02:00
DWORD cdir ; /* Current directory start cluster (0:root) */
2017-04-06 17:03:53 +02:00
# if _FS_EXFAT
DWORD cdc_scl ; /* Containing directory start cluster (invalid when cdir is 0) */
DWORD cdc_size ; /* b31-b8:Size of containing directory, b7-b0: Chain status */
DWORD cdc_ofs ; /* Offset in the containing directory (invalid when cdir is 0) */
# endif
2015-04-26 17:54:51 +02:00
# endif
2017-04-06 17:03:53 +02:00
DWORD n_fatent ; /* Number of FAT entries (number of clusters + 2) */
DWORD fsize ; /* Size of an FAT [sectors] */
DWORD volbase ; /* Volume base sector */
DWORD fatbase ; /* FAT base sector */
DWORD dirbase ; /* Root directory base sector/cluster */
DWORD database ; /* Data base sector */
2015-04-26 17:54:51 +02:00
DWORD winsect ; /* Current sector appearing in the win[] */
BYTE win [ _MAX_SS ] ; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
} FATFS ;
2017-04-06 17:03:53 +02:00
/* Object ID and allocation information (_FDID) */
typedef struct {
FATFS * fs ; /* Pointer to the owner file system object */
WORD id ; /* Owner file system mount ID */
BYTE attr ; /* Object attribute */
BYTE stat ; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous (no data on FAT), =3:flagmented in this session, b2:sub-directory stretched) */
DWORD sclust ; /* Object start cluster (0:no cluster or root directory) */
FSIZE_t objsize ; /* Object size (valid when sclust != 0) */
# if _FS_EXFAT
DWORD n_cont ; /* Size of first fragment, clusters - 1 (valid when stat == 3) */
DWORD n_frag ; /* Size of last fragment needs to be written (valid when not zero) */
DWORD c_scl ; /* Containing directory start cluster (valid when sclust != 0) */
DWORD c_size ; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
DWORD c_ofs ; /* Offset in the containing directory (valid when sclust != 0 and non-directory object) */
# endif
# if _FS_LOCK != 0
UINT lockid ; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
# endif
} _FDID ;
2015-04-26 17:54:51 +02:00
/* File object structure (FIL) */
typedef struct {
2017-04-06 17:03:53 +02:00
_FDID obj ; /* Object identifier (must be the 1st member to detect invalid object pointer) */
BYTE flag ; /* File status flags */
2015-04-26 17:54:51 +02:00
BYTE err ; /* Abort flag (error code) */
2017-04-06 17:03:53 +02:00
FSIZE_t fptr ; /* File read/write pointer (Zeroed on file open) */
DWORD clust ; /* Current cluster of fpter (invalid when fptr is 0) */
DWORD sect ; /* Sector number appearing in buf[] (0:invalid) */
2015-04-26 17:54:51 +02:00
# if !_FS_READONLY
DWORD dir_sect ; /* Sector number containing the directory entry */
BYTE * dir_ptr ; /* Pointer to the directory entry in the win[] */
# endif
# if _USE_FASTSEEK
2017-04-06 17:03:53 +02:00
DWORD * cltbl ; /* Pointer to the cluster link map table (nulled on open, set by application) */
2015-04-26 17:54:51 +02:00
# endif
# if !_FS_TINY
BYTE buf [ _MAX_SS ] ; /* File private data read/write window */
# endif
} FIL ;
/* Directory object structure (DIR) */
typedef struct {
2017-04-06 17:03:53 +02:00
_FDID obj ; /* Object identifier */
DWORD dptr ; /* Current read/write offset */
2015-04-26 17:54:51 +02:00
DWORD clust ; /* Current cluster */
2017-04-06 17:03:53 +02:00
DWORD sect ; /* Current sector (0:Read operation has terminated) */
BYTE * dir ; /* Pointer to the directory item in the win[] */
BYTE fn [ 12 ] ; /* SFN (in/out) {body[8],ext[3],status[1]} */
# if _USE_LFN != 0
DWORD blk_ofs ; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
2015-04-26 17:54:51 +02:00
# endif
# if _USE_FIND
2017-04-06 17:03:53 +02:00
const TCHAR * pat ; /* Pointer to the name matching pattern */
2015-04-26 17:54:51 +02:00
# endif
} DIR ;
/* File information structure (FILINFO) */
typedef struct {
2017-04-06 17:03:53 +02:00
FSIZE_t fsize ; /* File size */
WORD fdate ; /* Modified date */
WORD ftime ; /* Modified time */
BYTE fattrib ; /* File attribute */
# if _USE_LFN != 0
TCHAR altname [ 13 ] ; /* Altenative file name */
TCHAR fname [ _MAX_LFN + 1 ] ; /* Primary file name */
# else
TCHAR fname [ 13 ] ; /* File name */
2015-04-26 17:54:51 +02:00
# endif
} FILINFO ;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0 , /* (0) Succeeded */
FR_DISK_ERR , /* (1) A hard error occurred in the low level disk I/O layer */
FR_INT_ERR , /* (2) Assertion failed */
FR_NOT_READY , /* (3) The physical drive cannot work */
FR_NO_FILE , /* (4) Could not find the file */
FR_NO_PATH , /* (5) Could not find the path */
FR_INVALID_NAME , /* (6) The path name format is invalid */
FR_DENIED , /* (7) Access denied due to prohibited access or directory full */
FR_EXIST , /* (8) Access denied due to prohibited access */
FR_INVALID_OBJECT , /* (9) The file/directory object is invalid */
FR_WRITE_PROTECTED , /* (10) The physical drive is write protected */
FR_INVALID_DRIVE , /* (11) The logical drive number is invalid */
FR_NOT_ENABLED , /* (12) The volume has no work area */
FR_NO_FILESYSTEM , /* (13) There is no valid FAT volume */
2017-04-06 17:03:53 +02:00
FR_MKFS_ABORTED , /* (14) The f_mkfs() aborted due to any problem */
2015-04-26 17:54:51 +02:00
FR_TIMEOUT , /* (15) Could not get a grant to access the volume within defined period */
FR_LOCKED , /* (16) The operation is rejected according to the file sharing policy */
FR_NOT_ENOUGH_CORE , /* (17) LFN working buffer could not be allocated */
2017-04-06 17:03:53 +02:00
FR_TOO_MANY_OPEN_FILES , /* (18) Number of open files > _FS_LOCK */
2015-04-26 17:54:51 +02:00
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
} FRESULT ;
/*--------------------------------------------------------------*/
/* FatFs module application interface */
FRESULT f_open ( FIL * fp , const TCHAR * path , BYTE mode ) ; /* Open or create a file */
FRESULT f_close ( FIL * fp ) ; /* Close an open file object */
2017-04-06 17:03:53 +02:00
FRESULT f_read ( FIL * fp , void * buff , UINT btr , UINT * br ) ; /* Read data from the file */
FRESULT f_write ( FIL * fp , const void * buff , UINT btw , UINT * bw ) ; /* Write data to the file */
FRESULT f_lseek ( FIL * fp , FSIZE_t ofs ) ; /* Move file pointer of the file object */
FRESULT f_truncate ( FIL * fp ) ; /* Truncate the file */
FRESULT f_sync ( FIL * fp ) ; /* Flush cached data of the writing file */
2015-04-26 17:54:51 +02:00
FRESULT f_opendir ( DIR * dp , const TCHAR * path ) ; /* Open a directory */
FRESULT f_closedir ( DIR * dp ) ; /* Close an open directory */
FRESULT f_readdir ( DIR * dp , FILINFO * fno ) ; /* Read a directory item */
FRESULT f_findfirst ( DIR * dp , FILINFO * fno , const TCHAR * path , const TCHAR * pattern ) ; /* Find first file */
FRESULT f_findnext ( DIR * dp , FILINFO * fno ) ; /* Find next file */
FRESULT f_mkdir ( const TCHAR * path ) ; /* Create a sub directory */
FRESULT f_unlink ( const TCHAR * path ) ; /* Delete an existing file or directory */
FRESULT f_rename ( const TCHAR * path_old , const TCHAR * path_new ) ; /* Rename/Move a file or directory */
FRESULT f_stat ( const TCHAR * path , FILINFO * fno ) ; /* Get file status */
2017-04-06 17:03:53 +02:00
FRESULT f_chmod ( const TCHAR * path , BYTE attr , BYTE mask ) ; /* Change attribute of a file/dir */
FRESULT f_utime ( const TCHAR * path , const FILINFO * fno ) ; /* Change timestamp of a file/dir */
2015-04-26 17:54:51 +02:00
FRESULT f_chdir ( const TCHAR * path ) ; /* Change current directory */
FRESULT f_chdrive ( const TCHAR * path ) ; /* Change current drive */
FRESULT f_getcwd ( TCHAR * buff , UINT len ) ; /* Get current directory */
FRESULT f_getfree ( const TCHAR * path , DWORD * nclst , FATFS * * fatfs ) ; /* Get number of free clusters on the drive */
FRESULT f_getlabel ( const TCHAR * path , TCHAR * label , DWORD * vsn ) ; /* Get volume label */
FRESULT f_setlabel ( const TCHAR * label ) ; /* Set volume label */
2017-04-06 17:03:53 +02:00
FRESULT f_forward ( FIL * fp , UINT ( * func ) ( const BYTE * , UINT ) , UINT btf , UINT * bf ) ; /* Forward data to the stream */
FRESULT f_expand ( FIL * fp , FSIZE_t szf , BYTE opt ) ; /* Allocate a contiguous block to the file */
2015-04-26 17:54:51 +02:00
FRESULT f_mount ( FATFS * fs , const TCHAR * path , BYTE opt ) ; /* Mount/Unmount a logical drive */
2017-04-06 17:03:53 +02:00
FRESULT f_mkfs ( const TCHAR * path , BYTE opt , DWORD au , void * work , UINT len ) ; /* Create a FAT volume */
FRESULT f_fdisk ( BYTE pdrv , const DWORD * szt , void * work ) ; /* Divide a physical drive into some partitions */
2015-04-26 17:54:51 +02:00
int f_putc ( TCHAR c , FIL * fp ) ; /* Put a character to the file */
int f_puts ( const TCHAR * str , FIL * cp ) ; /* Put a string to the file */
int f_printf ( FIL * fp , const TCHAR * str , . . . ) ; /* Put a formatted string to the file */
TCHAR * f_gets ( TCHAR * buff , int len , FIL * fp ) ; /* Get a string from the file */
2017-04-06 17:03:53 +02:00
# define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
2015-04-26 17:54:51 +02:00
# define f_error(fp) ((fp)->err)
# define f_tell(fp) ((fp)->fptr)
2017-04-06 17:03:53 +02:00
# define f_size(fp) ((fp)->obj.objsize)
2015-04-26 17:54:51 +02:00
# define f_rewind(fp) f_lseek((fp), 0)
# define f_rewinddir(dp) f_readdir((dp), 0)
2017-04-06 17:03:53 +02:00
# define f_rmdir(path) f_unlink(path)
2015-04-26 17:54:51 +02:00
# ifndef EOF
# define EOF (-1)
# endif
/*--------------------------------------------------------------*/
/* Additional user defined functions */
/* RTC function */
# if !_FS_READONLY && !_FS_NORTC
DWORD get_fattime ( void ) ;
# endif
/* Unicode support functions */
2017-04-06 17:03:53 +02:00
# if _USE_LFN != 0 /* Unicode - OEM code conversion */
2015-04-26 17:54:51 +02:00
WCHAR ff_convert ( WCHAR chr , UINT dir ) ; /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper ( WCHAR chr ) ; /* Unicode upper-case conversion */
# if _USE_LFN == 3 /* Memory functions */
void * ff_memalloc ( UINT msize ) ; /* Allocate memory block */
void ff_memfree ( void * mblock ) ; /* Free memory block */
# endif
# endif
/* Sync functions */
# if _FS_REENTRANT
int ff_cre_syncobj ( BYTE vol , _SYNC_t * sobj ) ; /* Create a sync object */
int ff_req_grant ( _SYNC_t sobj ) ; /* Lock sync object */
void ff_rel_grant ( _SYNC_t sobj ) ; /* Unlock sync object */
int ff_del_syncobj ( _SYNC_t sobj ) ; /* Delete a sync object */
# endif
/*--------------------------------------------------------------*/
/* Flags and offset address */
2017-04-06 17:03:53 +02:00
/* File access mode and open method flags (3rd argument of f_open) */
2015-04-26 17:54:51 +02:00
# define FA_READ 0x01
# define FA_WRITE 0x02
2017-04-06 17:03:53 +02:00
# define FA_OPEN_EXISTING 0x00
2015-04-26 17:54:51 +02:00
# define FA_CREATE_NEW 0x04
# define FA_CREATE_ALWAYS 0x08
# define FA_OPEN_ALWAYS 0x10
2017-04-06 17:03:53 +02:00
# define FA_OPEN_APPEND 0x30
2015-04-26 17:54:51 +02:00
2017-04-06 17:03:53 +02:00
/* Fast seek controls (2nd argument of f_lseek) */
# define CREATE_LINKMAP ((FSIZE_t)0 - 1)
2015-04-26 17:54:51 +02:00
2017-04-06 17:03:53 +02:00
/* Format options (2nd argument of f_mkfs) */
# define FM_FAT 0x01
# define FM_FAT32 0x02
# define FM_EXFAT 0x04
# define FM_ANY 0x07
# define FM_SFD 0x08
2015-04-26 17:54:51 +02:00
2017-04-06 17:03:53 +02:00
/* Filesystem type (FATFS.fs_type) */
2015-04-26 17:54:51 +02:00
# define FS_FAT12 1
# define FS_FAT16 2
# define FS_FAT32 3
2017-04-06 17:03:53 +02:00
# define FS_EXFAT 4
2015-04-26 17:54:51 +02:00
2017-04-06 17:03:53 +02:00
/* File attribute bits for directory entry (FILINFO.fattrib) */
2015-04-26 17:54:51 +02:00
# define AM_RDO 0x01 /* Read only */
# define AM_HID 0x02 /* Hidden */
# define AM_SYS 0x04 /* System */
# define AM_DIR 0x10 /* Directory */
# define AM_ARC 0x20 /* Archive */
# ifdef __cplusplus
}
# endif
# endif /* _FATFS */