1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
|
/*--------------------------------------------------------------------------/
/ Tiny-FatFs - FAT file system module include file R0.06 (C)ChaN, 2008
/---------------------------------------------------------------------------/
/ FatFs module is an experimenal project to implement FAT file system to
/ cheap microcontrollers. This is a free software and is opened for education,
/ research and development under license policy of following trems.
/
/ Copyright (C) 2008, ChaN, all right reserved.
/
/ * The FatFs module is a free software and there is no warranty.
/ * You can use, modify and/or redistribute it for personal, non-profit or
/ commercial use without any restriction under your responsibility.
/ * Redistributions of source code must retain the above copyright notice.
/
/---------------------------------------------------------------------------*/
#include <fatfs_config.h>
#if _FATFS_TINY == 1
#ifndef _FATFS
#include "integer.h"
/* Type definition for cluster number */
#if _FAT32
typedef DWORD CLUST;
#else
typedef WORD CLUST;
#undef _USE_FSINFO
#define _USE_FSINFO 0
#endif
/* File system object structure */
typedef struct _FATFS {
WORD id; /* File system mount ID */
WORD n_rootdir; /* Number of root directory entries */
DWORD winsect; /* Current sector appearing in the win[] */
DWORD fatbase; /* FAT start sector */
DWORD dirbase; /* Root directory start sector */
DWORD database; /* Data start sector */
CLUST sects_fat; /* Sectors per fat */
CLUST max_clust; /* Maximum cluster# + 1 */
#if !_FS_READONLY
CLUST last_clust; /* Last allocated cluster */
CLUST free_clust; /* Number of free clusters */
#if _USE_FSINFO
DWORD fsi_sector; /* fsinfo sector */
BYTE fsi_flag; /* fsinfo dirty flag (1:must be written back) */
BYTE pad1;
#endif
#endif
BYTE fs_type; /* FAT sub type */
BYTE csize; /* Number of sectors per cluster */
BYTE n_fats; /* Number of FAT copies */
BYTE winflag; /* win[] dirty flag (1:must be written back) */
BYTE win[512]; /* Disk access window for Directory/FAT/File */
} FATFS;
/* Directory object structure */
typedef struct _DIR {
WORD id; /* Owner file system mount ID */
WORD index; /* Current index */
FATFS* fs; /* Pointer to the owner file system object */
CLUST sclust; /* Start cluster */
CLUST clust; /* Current cluster */
DWORD sect; /* Current sector */
} DIR;
/* File object structure */
typedef struct _FIL {
WORD id; /* Owner file system mount ID */
BYTE flag; /* File status flags */
BYTE csect; /* Sector address in the cluster */
FATFS* fs; /* Pointer to owner file system */
DWORD fptr; /* File R/W pointer */
DWORD fsize; /* File size */
CLUST org_clust; /* File start cluster */
CLUST curr_clust; /* Current cluster */
DWORD curr_sect; /* Current sector */
#if !_FS_READONLY
DWORD dir_sect; /* Sector containing the directory entry */
BYTE* dir_ptr; /* Ponter to the directory entry in the window */
#endif
} FIL;
/* File status structure */
typedef struct _FILINFO {
DWORD fsize; /* Size */
WORD fdate; /* Date */
WORD ftime; /* Time */
BYTE fattrib; /* Attribute */
char fname[8+1+3+1]; /* Name (8.3 format) */
} FILINFO;
/* File function return code (FRESULT) */
typedef enum {
FR_OK = 0, /* 0 */
FR_NOT_READY, /* 1 */
FR_NO_FILE, /* 2 */
FR_NO_PATH, /* 3 */
FR_INVALID_NAME, /* 4 */
FR_INVALID_DRIVE, /* 5 */
FR_DENIED, /* 6 */
FR_EXIST, /* 7 */
FR_RW_ERROR, /* 8 */
FR_WRITE_PROTECTED, /* 9 */
FR_NOT_ENABLED, /* 10 */
FR_NO_FILESYSTEM, /* 11 */
FR_INVALID_OBJECT, /* 12 */
FR_MKFS_ABORTED /* 13 (not used) */
} FRESULT;
/*-----------------------------------------------------*/
/* Tiny-FatFs module application interface */
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
FRESULT f_open (FIL*, const char*, BYTE); /* Open or create a file */
FRESULT f_read (FIL*, void*, UINT, UINT*); /* Read data from a file */
FRESULT f_write (FIL*, const void*, UINT, UINT*); /* Write data to a file */
FRESULT f_lseek (FIL*, DWORD); /* Move file pointer of a file object */
FRESULT f_close (FIL*); /* Close an open file object */
FRESULT f_opendir (DIR*, const char*); /* Open an existing directory */
FRESULT f_readdir (DIR*, FILINFO*); /* Read a directory item */
FRESULT f_stat (const char*, FILINFO*); /* Get file status */
FRESULT f_getfree (const char*, DWORD*, FATFS**); /* Get number of free clusters on the drive */
FRESULT f_truncate (FIL*); /* Truncate file */
FRESULT f_sync (FIL*); /* Flush cached data of a writing file */
FRESULT f_unlink (const char*); /* Delete an existing file or directory */
FRESULT f_mkdir (const char*); /* Create a new directory */
FRESULT f_chmod (const char*, BYTE, BYTE); /* Change file/dir attriburte */
FRESULT f_utime (const char*, const FILINFO*); /* Change file/dir timestamp */
FRESULT f_rename (const char*, const char*); /* Rename/Move a file or directory */
FRESULT f_forward (FIL*, UINT(*)(const BYTE*,UINT), UINT, UINT*); /* Forward data to the stream */
#if _USE_STRFUNC
#define feof(fp) ((fp)->fptr == (fp)->fsize)
#define EOF -1
int fputc (int, FIL*); /* Put a character to the file */
int fputs (const char*, FIL*); /* Put a string to the file */
int fprintf (FIL*, const char*, ...); /* Put a formatted string to the file */
char* fgets (char*, int, FIL*); /* Get a string from the file */
#endif
/* User defined function to give a current time to fatfs module */
DWORD get_fattime (void); /* 31-25: Year(0-127 +1980), 24-21: Month(1-12), 20-16: Day(1-31) */
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */
/* File access control and file status flags (FIL.flag) */
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#if !_FS_READONLY
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA__WRITTEN 0x20
#endif
#define FA__ERROR 0x80
/* FAT sub type (FATFS.fs_type) */
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
/* File attribute bits for directory entry */
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_VOL 0x08 /* Volume label */
#define AM_LFN 0x0F /* LFN entry */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
/* Offset of FAT structure members */
#define BS_jmpBoot 0
#define BS_OEMName 3
#define BPB_BytsPerSec 11
#define BPB_SecPerClus 13
#define BPB_RsvdSecCnt 14
#define BPB_NumFATs 16
#define BPB_RootEntCnt 17
#define BPB_TotSec16 19
#define BPB_Media 21
#define BPB_FATSz16 22
#define BPB_SecPerTrk 24
#define BPB_NumHeads 26
#define BPB_HiddSec 28
#define BPB_TotSec32 32
#define BS_55AA 510
#define BS_DrvNum 36
#define BS_BootSig 38
#define BS_VolID 39
#define BS_VolLab 43
#define BS_FilSysType 54
#define BPB_FATSz32 36
#define BPB_ExtFlags 40
#define BPB_FSVer 42
#define BPB_RootClus 44
#define BPB_FSInfo 48
#define BPB_BkBootSec 50
#define BS_DrvNum32 64
#define BS_BootSig32 66
#define BS_VolID32 67
#define BS_VolLab32 71
#define BS_FilSysType32 82
#define FSI_LeadSig 0
#define FSI_StrucSig 484
#define FSI_Free_Count 488
#define FSI_Nxt_Free 492
#define MBR_Table 446
#define DIR_Name 0
#define DIR_Attr 11
#define DIR_NTres 12
#define DIR_CrtTime 14
#define DIR_CrtDate 16
#define DIR_FstClusHI 20
#define DIR_WrtTime 22
#define DIR_WrtDate 24
#define DIR_FstClusLO 26
#define DIR_FileSize 28
/* Multi-byte word access macros */
#if _MCU_ENDIAN == 1 /* Use word access */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(WORD*)(BYTE*)(ptr)=(WORD)(val)
#define ST_DWORD(ptr,val) *(DWORD*)(BYTE*)(ptr)=(DWORD)(val)
#elif _MCU_ENDIAN == 2 /* Use byte-by-byte access */
#define LD_WORD(ptr) (WORD)(((WORD)*(volatile BYTE*)((ptr)+1)<<8)|(WORD)*(volatile BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(((DWORD)*(volatile BYTE*)((ptr)+3)<<24)|((DWORD)*(volatile BYTE*)((ptr)+2)<<16)|((WORD)*(volatile BYTE*)((ptr)+1)<<8)|*(volatile BYTE*)(ptr))
#define ST_WORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(volatile BYTE*)(ptr)=(BYTE)(val); *(volatile BYTE*)((ptr)+1)=(BYTE)((WORD)(val)>>8); *(volatile BYTE*)((ptr)+2)=(BYTE)((DWORD)(val)>>16); *(volatile BYTE*)((ptr)+3)=(BYTE)((DWORD)(val)>>24)
#else
#error Do not forget to set _MCU_ENDIAN properly!
#endif
#define _FATFS
#endif /* _FATFS */
#endif /* _FATFS_TINY */
|