PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Committer:
spinal
Date:
Sun Nov 18 15:47:54 2018 +0000
Revision:
64:6e6c6c2b664e
Parent:
52:c04087025cab
added fix for directrectangle()

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pokitto 52:c04087025cab 1 /*----------------------------------------------------------------------------/
Pokitto 52:c04087025cab 2 / Petit FatFs - FAT file system module R0.02 (C)ChaN, 2009
Pokitto 52:c04087025cab 3 /-----------------------------------------------------------------------------/
Pokitto 52:c04087025cab 4 / Petit FatFs module is an open source software to implement FAT file system to
Pokitto 52:c04087025cab 5 / small embedded systems. This is a free software and is opened for education,
Pokitto 52:c04087025cab 6 / research and commercial developments under license policy of following trems.
Pokitto 52:c04087025cab 7 /
Pokitto 52:c04087025cab 8 / Copyright (C) 2009, ChaN, all right reserved.
Pokitto 52:c04087025cab 9 /
Pokitto 52:c04087025cab 10 / * The Petit FatFs module is a free software and there is NO WARRANTY.
Pokitto 52:c04087025cab 11 / * No restriction on use. You can use, modify and redistribute it for
Pokitto 52:c04087025cab 12 / personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
Pokitto 52:c04087025cab 13 / * Redistributions of source code must retain the above copyright notice.
Pokitto 52:c04087025cab 14 /
Pokitto 52:c04087025cab 15 /-----------------------------------------------------------------------------/
Pokitto 52:c04087025cab 16 / Jun 15,'09 R0.01a First release. (Branched from FatFs R0.07b.)
Pokitto 52:c04087025cab 17 /
Pokitto 52:c04087025cab 18 / Dec 14,'09 R0.02 Added multiple code page support.
Pokitto 52:c04087025cab 19 / Added write funciton.
Pokitto 52:c04087025cab 20 / Changed stream read mode interface.
Pokitto 52:c04087025cab 21 /----------------------------------------------------------------------------*/
Pokitto 52:c04087025cab 22
Pokitto 52:c04087025cab 23
Pokitto 52:c04087025cab 24 #include "pff.h" /* Petit FatFs configurations and declarations */
Pokitto 52:c04087025cab 25 #include "diskio.h" /* Declarations of low level disk I/O functions */
Pokitto 52:c04087025cab 26
Pokitto 52:c04087025cab 27 namespace PFFS {
Pokitto 52:c04087025cab 28
Pokitto 52:c04087025cab 29 /*--------------------------------------------------------------------------
Pokitto 52:c04087025cab 30
Pokitto 52:c04087025cab 31 Private Functions
Pokitto 52:c04087025cab 32
Pokitto 52:c04087025cab 33 ---------------------------------------------------------------------------*/
Pokitto 52:c04087025cab 34
Pokitto 52:c04087025cab 35 static
Pokitto 52:c04087025cab 36 FATFS *FatFs; /* Pointer to the file system object (logical drive) */
Pokitto 52:c04087025cab 37
Pokitto 52:c04087025cab 38
Pokitto 52:c04087025cab 39
Pokitto 52:c04087025cab 40 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 41 /* String functions */
Pokitto 52:c04087025cab 42 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 43
Pokitto 52:c04087025cab 44 /* Fill memory */
Pokitto 52:c04087025cab 45 static
Pokitto 52:c04087025cab 46 void mem_set (void* dst, int val, int cnt) {
Pokitto 52:c04087025cab 47 char *d = (char*)dst;
Pokitto 52:c04087025cab 48 while (cnt--) *d++ = (char)val;
Pokitto 52:c04087025cab 49 }
Pokitto 52:c04087025cab 50
Pokitto 52:c04087025cab 51 /* Compare memory to memory */
Pokitto 52:c04087025cab 52 static
Pokitto 52:c04087025cab 53 int mem_cmp (const void* dst, const void* src, int cnt) {
Pokitto 52:c04087025cab 54 const char *d = (const char *)dst, *s = (const char *)src;
Pokitto 52:c04087025cab 55 int r = 0;
Pokitto 52:c04087025cab 56 while (cnt-- && (r = *d++ - *s++) == 0) ;
Pokitto 52:c04087025cab 57 return r;
Pokitto 52:c04087025cab 58 }
Pokitto 52:c04087025cab 59
Pokitto 52:c04087025cab 60
Pokitto 52:c04087025cab 61
Pokitto 52:c04087025cab 62 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 63 /* FAT access - Read value of a FAT entry */
Pokitto 52:c04087025cab 64 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 65
Pokitto 52:c04087025cab 66 static
Pokitto 52:c04087025cab 67 CLUST get_fat ( /* 1:IO error, Else:Cluster status */
Pokitto 52:c04087025cab 68 CLUST clst /* Cluster# to get the link information */
Pokitto 52:c04087025cab 69 ) {
Pokitto 52:c04087025cab 70 WORD wc, bc, ofs;
Pokitto 52:c04087025cab 71 BYTE buf[4];
Pokitto 52:c04087025cab 72 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 73
Pokitto 52:c04087025cab 74
Pokitto 52:c04087025cab 75 if (clst < 2 || clst >= fs->max_clust) /* Range check */
Pokitto 52:c04087025cab 76 return 1;
Pokitto 52:c04087025cab 77
Pokitto 52:c04087025cab 78 switch (fs->fs_type) {
Pokitto 52:c04087025cab 79 case FS_FAT12 :
Pokitto 52:c04087025cab 80 bc = (WORD)clst;
Pokitto 52:c04087025cab 81 bc += bc / 2;
Pokitto 52:c04087025cab 82 ofs = bc % 512;
Pokitto 52:c04087025cab 83 bc /= 512;
Pokitto 52:c04087025cab 84 if (ofs != 511) {
Pokitto 52:c04087025cab 85 if (disk_readp(buf, fs->fatbase + bc, ofs, 2)) break;
Pokitto 52:c04087025cab 86 } else {
Pokitto 52:c04087025cab 87 if (disk_readp(buf, fs->fatbase + bc, 511, 1)) break;
Pokitto 52:c04087025cab 88 if (disk_readp(buf+1, fs->fatbase + bc + 1, 0, 1)) break;
Pokitto 52:c04087025cab 89 }
Pokitto 52:c04087025cab 90 wc = LD_WORD(buf);
Pokitto 52:c04087025cab 91 return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
Pokitto 52:c04087025cab 92
Pokitto 52:c04087025cab 93 case FS_FAT16 :
Pokitto 52:c04087025cab 94 if (disk_readp(buf, fs->fatbase + clst / 256, (WORD)(((WORD)clst % 256) * 2), 2)) break;
Pokitto 52:c04087025cab 95 return LD_WORD(buf);
Pokitto 52:c04087025cab 96 #if _FS_FAT32
Pokitto 52:c04087025cab 97 case FS_FAT32 :
Pokitto 52:c04087025cab 98 if (disk_readp(buf, fs->fatbase + clst / 128, (WORD)(((WORD)clst % 128) * 4), 4)) break;
Pokitto 52:c04087025cab 99 return ((WORD)(((WORD)*(BYTE*)((buf)+1)<<8)|(WORD)*(BYTE*)(buf))) & 0x0FFFFFFF; //return LD_DWORD(buf) & 0x0FFFFFFF; //get rid of out of bounds warning in online IDE
Pokitto 52:c04087025cab 100 #endif
Pokitto 52:c04087025cab 101 }
Pokitto 52:c04087025cab 102
Pokitto 52:c04087025cab 103 return 1; /* An error occured at the disk I/O layer */
Pokitto 52:c04087025cab 104 }
Pokitto 52:c04087025cab 105
Pokitto 52:c04087025cab 106
Pokitto 52:c04087025cab 107
Pokitto 52:c04087025cab 108
Pokitto 52:c04087025cab 109 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 110 /* Get sector# from cluster# */
Pokitto 52:c04087025cab 111 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 112
Pokitto 52:c04087025cab 113 static
Pokitto 52:c04087025cab 114 DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
Pokitto 52:c04087025cab 115 CLUST clst /* Cluster# to be converted */
Pokitto 52:c04087025cab 116 ) {
Pokitto 52:c04087025cab 117 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 118
Pokitto 52:c04087025cab 119
Pokitto 52:c04087025cab 120 clst -= 2;
Pokitto 52:c04087025cab 121 if (clst >= (fs->max_clust - 2)) return 0; /* Invalid cluster# */
Pokitto 52:c04087025cab 122 return (DWORD)clst * fs->csize + fs->database;
Pokitto 52:c04087025cab 123 }
Pokitto 52:c04087025cab 124
Pokitto 52:c04087025cab 125
Pokitto 52:c04087025cab 126
Pokitto 52:c04087025cab 127
Pokitto 52:c04087025cab 128 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 129 /* Directory handling - Rewind directory index */
Pokitto 52:c04087025cab 130 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 131
Pokitto 52:c04087025cab 132 static
Pokitto 52:c04087025cab 133 FRESULT dir_rewind (
Pokitto 52:c04087025cab 134 FATDIR *dj /* Pointer to directory object */
Pokitto 52:c04087025cab 135 ) {
Pokitto 52:c04087025cab 136 CLUST clst;
Pokitto 52:c04087025cab 137 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 138
Pokitto 52:c04087025cab 139
Pokitto 52:c04087025cab 140 dj->index = 0;
Pokitto 52:c04087025cab 141 clst = dj->sclust;
Pokitto 52:c04087025cab 142 if (clst == 1 || clst >= fs->max_clust) /* Check start cluster range */
Pokitto 52:c04087025cab 143 return FR_DISK_ERR;
Pokitto 52:c04087025cab 144 #if _FS_FAT32
Pokitto 52:c04087025cab 145 if (!clst && fs->fs_type == FS_FAT32) /* Replace cluster# 0 with root cluster# if in FAT32 */
Pokitto 52:c04087025cab 146 clst = fs->dirbase;
Pokitto 52:c04087025cab 147 #endif
Pokitto 52:c04087025cab 148 dj->clust = clst; /* Current cluster */
Pokitto 52:c04087025cab 149 dj->sect = clst ? clust2sect(clst) : fs->dirbase; /* Current sector */
Pokitto 52:c04087025cab 150
Pokitto 52:c04087025cab 151 return FR_OK; /* Seek succeeded */
Pokitto 52:c04087025cab 152 }
Pokitto 52:c04087025cab 153
Pokitto 52:c04087025cab 154
Pokitto 52:c04087025cab 155
Pokitto 52:c04087025cab 156
Pokitto 52:c04087025cab 157 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 158 /* Directory handling - Move directory index next */
Pokitto 52:c04087025cab 159 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 160
Pokitto 52:c04087025cab 161 static
Pokitto 52:c04087025cab 162 FRESULT dir_next ( /* FR_OK:Succeeded, FR_NO_FILE:End of table */
Pokitto 52:c04087025cab 163 FATDIR *dj /* Pointer to directory object */
Pokitto 52:c04087025cab 164 ) {
Pokitto 52:c04087025cab 165 CLUST clst;
Pokitto 52:c04087025cab 166 WORD i;
Pokitto 52:c04087025cab 167 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 168
Pokitto 52:c04087025cab 169
Pokitto 52:c04087025cab 170 i = dj->index + 1;
Pokitto 52:c04087025cab 171 if (!i || !dj->sect) /* Report EOT when index has reached 65535 */
Pokitto 52:c04087025cab 172 return FR_NO_FILE;
Pokitto 52:c04087025cab 173
Pokitto 52:c04087025cab 174 if (!(i & (16-1))) { /* Sector changed? */
Pokitto 52:c04087025cab 175 dj->sect++; /* Next sector */
Pokitto 52:c04087025cab 176
Pokitto 52:c04087025cab 177 if (dj->clust == 0) { /* Static table */
Pokitto 52:c04087025cab 178 if (i >= fs->n_rootdir) /* Report EOT when end of table */
Pokitto 52:c04087025cab 179 return FR_NO_FILE;
Pokitto 52:c04087025cab 180 } else { /* Dynamic table */
Pokitto 52:c04087025cab 181 if (((i / 16) & (fs->csize-1)) == 0) { /* Cluster changed? */
Pokitto 52:c04087025cab 182 clst = get_fat(dj->clust); /* Get next cluster */
Pokitto 52:c04087025cab 183 if (clst <= 1) return FR_DISK_ERR;
Pokitto 52:c04087025cab 184 if (clst >= fs->max_clust) /* When it reached end of dynamic table */
Pokitto 52:c04087025cab 185 return FR_NO_FILE; /* Report EOT */
Pokitto 52:c04087025cab 186 dj->clust = clst; /* Initialize data for new cluster */
Pokitto 52:c04087025cab 187 dj->sect = clust2sect(clst);
Pokitto 52:c04087025cab 188 }
Pokitto 52:c04087025cab 189 }
Pokitto 52:c04087025cab 190 }
Pokitto 52:c04087025cab 191
Pokitto 52:c04087025cab 192 dj->index = i;
Pokitto 52:c04087025cab 193
Pokitto 52:c04087025cab 194 return FR_OK;
Pokitto 52:c04087025cab 195 }
Pokitto 52:c04087025cab 196
Pokitto 52:c04087025cab 197
Pokitto 52:c04087025cab 198
Pokitto 52:c04087025cab 199
Pokitto 52:c04087025cab 200 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 201 /* Directory handling - Find an object in the directory */
Pokitto 52:c04087025cab 202 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 203
Pokitto 52:c04087025cab 204 static
Pokitto 52:c04087025cab 205 FRESULT dir_find (
Pokitto 52:c04087025cab 206 FATDIR *dj /* Pointer to the directory object linked to the file name */
Pokitto 52:c04087025cab 207 ) {
Pokitto 52:c04087025cab 208 FRESULT res;
Pokitto 52:c04087025cab 209 BYTE c, *dir;
Pokitto 52:c04087025cab 210
Pokitto 52:c04087025cab 211
Pokitto 52:c04087025cab 212 res = dir_rewind(dj); /* Rewind directory object */
Pokitto 52:c04087025cab 213 if (res != FR_OK) return res;
Pokitto 52:c04087025cab 214
Pokitto 52:c04087025cab 215 dir = FatFs->buf;
Pokitto 52:c04087025cab 216 do {
Pokitto 52:c04087025cab 217 res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
Pokitto 52:c04087025cab 218 ? FR_DISK_ERR : FR_OK;
Pokitto 52:c04087025cab 219 if (res != FR_OK) break;
Pokitto 52:c04087025cab 220 c = dir[DIR_Name]; /* First character */
Pokitto 52:c04087025cab 221 if (c == 0) {
Pokitto 52:c04087025cab 222 res = FR_NO_FILE; /* Reached to end of table */
Pokitto 52:c04087025cab 223 break;
Pokitto 52:c04087025cab 224 }
Pokitto 52:c04087025cab 225 if (!(dir[DIR_Attr] & AM_VOL) && !mem_cmp(dir, dj->fn, 11)) /* Is it a valid entry? */
Pokitto 52:c04087025cab 226 break;
Pokitto 52:c04087025cab 227 res = dir_next(dj); /* Next entry */
Pokitto 52:c04087025cab 228 } while (res == FR_OK);
Pokitto 52:c04087025cab 229
Pokitto 52:c04087025cab 230 return res;
Pokitto 52:c04087025cab 231 }
Pokitto 52:c04087025cab 232
Pokitto 52:c04087025cab 233
Pokitto 52:c04087025cab 234
Pokitto 52:c04087025cab 235
Pokitto 52:c04087025cab 236 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 237 /* Read an object from the directory */
Pokitto 52:c04087025cab 238 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 239 #if _USE_DIR
Pokitto 52:c04087025cab 240 static
Pokitto 52:c04087025cab 241 FRESULT dir_read (
Pokitto 52:c04087025cab 242 FATDIR *dj /* Pointer to the directory object to store read object name */
Pokitto 52:c04087025cab 243 ) {
Pokitto 52:c04087025cab 244 FRESULT res;
Pokitto 52:c04087025cab 245 BYTE a, c, *dir;
Pokitto 52:c04087025cab 246
Pokitto 52:c04087025cab 247
Pokitto 52:c04087025cab 248 res = FR_NO_FILE;
Pokitto 52:c04087025cab 249 dir = FatFs->buf;
Pokitto 52:c04087025cab 250 while (dj->sect) {
Pokitto 52:c04087025cab 251 res = disk_readp(dir, dj->sect, (WORD)((dj->index % 16) * 32), 32) /* Read an entry */
Pokitto 52:c04087025cab 252 ? FR_DISK_ERR : FR_OK;
Pokitto 52:c04087025cab 253 if (res != FR_OK) break;
Pokitto 52:c04087025cab 254 c = dir[DIR_Name];
Pokitto 52:c04087025cab 255 if (c == 0) {
Pokitto 52:c04087025cab 256 res = FR_NO_FILE; /* Reached to end of table */
Pokitto 52:c04087025cab 257 break;
Pokitto 52:c04087025cab 258 }
Pokitto 52:c04087025cab 259 a = dir[DIR_Attr] & AM_MASK;
Pokitto 52:c04087025cab 260 if (c != 0xE5 && c != '.' && !(a & AM_VOL)) /* Is it a valid entry? */
Pokitto 52:c04087025cab 261 break;
Pokitto 52:c04087025cab 262 res = dir_next(dj); /* Next entry */
Pokitto 52:c04087025cab 263 if (res != FR_OK) break;
Pokitto 52:c04087025cab 264 }
Pokitto 52:c04087025cab 265
Pokitto 52:c04087025cab 266 if (res != FR_OK) dj->sect = 0;
Pokitto 52:c04087025cab 267
Pokitto 52:c04087025cab 268 return res;
Pokitto 52:c04087025cab 269 }
Pokitto 52:c04087025cab 270 #endif
Pokitto 52:c04087025cab 271
Pokitto 52:c04087025cab 272
Pokitto 52:c04087025cab 273
Pokitto 52:c04087025cab 274 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 275 /* Pick a segment and create the object name in directory form */
Pokitto 52:c04087025cab 276 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 277
Pokitto 52:c04087025cab 278 #ifdef _EXCVT
Pokitto 52:c04087025cab 279 static const BYTE cvt[] = _EXCVT;
Pokitto 52:c04087025cab 280 #endif
Pokitto 52:c04087025cab 281
Pokitto 52:c04087025cab 282 static
Pokitto 52:c04087025cab 283 FRESULT create_name (
Pokitto 52:c04087025cab 284 FATDIR *dj, /* Pointer to the directory object */
Pokitto 52:c04087025cab 285 const char **path /* Pointer to pointer to the segment in the path string */
Pokitto 52:c04087025cab 286 ) {
Pokitto 52:c04087025cab 287 BYTE c, d, ni, si, i, *sfn;
Pokitto 52:c04087025cab 288 const char *p;
Pokitto 52:c04087025cab 289
Pokitto 52:c04087025cab 290 /* Create file name in directory form */
Pokitto 52:c04087025cab 291 sfn = dj->fn;
Pokitto 52:c04087025cab 292 mem_set(sfn, ' ', 11);
Pokitto 52:c04087025cab 293 si = i = 0;
Pokitto 52:c04087025cab 294 ni = 8;
Pokitto 52:c04087025cab 295 p = *path;
Pokitto 52:c04087025cab 296 for (;;) {
Pokitto 52:c04087025cab 297 c = p[si++];
Pokitto 52:c04087025cab 298 if (c <= ' ' || c == '/') break; /* Break on end of segment */
Pokitto 52:c04087025cab 299 if (c == '.' || i >= ni) {
Pokitto 52:c04087025cab 300 if (ni != 8 || c != '.') break;
Pokitto 52:c04087025cab 301 i = 8;
Pokitto 52:c04087025cab 302 ni = 11;
Pokitto 52:c04087025cab 303 continue;
Pokitto 52:c04087025cab 304 }
Pokitto 52:c04087025cab 305 #ifdef _EXCVT
Pokitto 52:c04087025cab 306 if (c >= 0x80) /* To upper extended char (SBCS) */
Pokitto 52:c04087025cab 307 c = cvt[c - 0x80];
Pokitto 52:c04087025cab 308 #endif
Pokitto 52:c04087025cab 309 if (IsDBCS1(c) && i >= ni - 1) { /* DBC 1st byte? */
Pokitto 52:c04087025cab 310 d = p[si++]; /* Get 2nd byte */
Pokitto 52:c04087025cab 311 sfn[i++] = c;
Pokitto 52:c04087025cab 312 sfn[i++] = d;
Pokitto 52:c04087025cab 313 } else { /* Single byte code */
Pokitto 52:c04087025cab 314 if (IsLower(c)) c -= 0x20; /* toupper */
Pokitto 52:c04087025cab 315 sfn[i++] = c;
Pokitto 52:c04087025cab 316 }
Pokitto 52:c04087025cab 317 }
Pokitto 52:c04087025cab 318 *path = &p[si]; /* Rerurn pointer to the next segment */
Pokitto 52:c04087025cab 319
Pokitto 52:c04087025cab 320 sfn[11] = (c <= ' ') ? 1 : 0; /* Set last segment flag if end of path */
Pokitto 52:c04087025cab 321
Pokitto 52:c04087025cab 322 return FR_OK;
Pokitto 52:c04087025cab 323 }
Pokitto 52:c04087025cab 324
Pokitto 52:c04087025cab 325
Pokitto 52:c04087025cab 326
Pokitto 52:c04087025cab 327
Pokitto 52:c04087025cab 328 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 329 /* Get file information from directory entry */
Pokitto 52:c04087025cab 330 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 331 #if _USE_DIR
Pokitto 52:c04087025cab 332 static
Pokitto 52:c04087025cab 333 void get_fileinfo ( /* No return code */
Pokitto 52:c04087025cab 334 FATDIR *dj, /* Pointer to the directory object */
Pokitto 52:c04087025cab 335 FILINFO *fno /* Pointer to store the file information */
Pokitto 52:c04087025cab 336 ) {
Pokitto 52:c04087025cab 337 BYTE i, c, *dir;
Pokitto 52:c04087025cab 338 char *p;
Pokitto 52:c04087025cab 339
Pokitto 52:c04087025cab 340
Pokitto 52:c04087025cab 341 p = fno->fname;
Pokitto 52:c04087025cab 342 if (dj->sect) {
Pokitto 52:c04087025cab 343 dir = FatFs->buf;
Pokitto 52:c04087025cab 344 for (i = 0; i < 8; i++) { /* Copy file name body */
Pokitto 52:c04087025cab 345 c = dir[i];
Pokitto 52:c04087025cab 346 if (c == ' ') break;
Pokitto 52:c04087025cab 347 if (c == 0x05) c = 0xE5;
Pokitto 52:c04087025cab 348 *p++ = c;
Pokitto 52:c04087025cab 349 }
Pokitto 52:c04087025cab 350 if (dir[8] != ' ') { /* Copy file name extension */
Pokitto 52:c04087025cab 351 *p++ = '.';
Pokitto 52:c04087025cab 352 for (i = 8; i < 11; i++) {
Pokitto 52:c04087025cab 353 c = dir[i];
Pokitto 52:c04087025cab 354 if (c == ' ') break;
Pokitto 52:c04087025cab 355 *p++ = c;
Pokitto 52:c04087025cab 356 }
Pokitto 52:c04087025cab 357 }
Pokitto 52:c04087025cab 358 fno->fattrib = dir[DIR_Attr]; /* Attribute */
Pokitto 52:c04087025cab 359 fno->fsize = LD_DWORD(dir+DIR_FileSize); /* Size */
Pokitto 52:c04087025cab 360 fno->fdate = LD_WORD(dir+DIR_WrtDate); /* Date */
Pokitto 52:c04087025cab 361 fno->ftime = LD_WORD(dir+DIR_WrtTime); /* Time */
Pokitto 52:c04087025cab 362 }
Pokitto 52:c04087025cab 363 *p = 0;
Pokitto 52:c04087025cab 364 }
Pokitto 52:c04087025cab 365 #endif /* _USE_DIR */
Pokitto 52:c04087025cab 366
Pokitto 52:c04087025cab 367
Pokitto 52:c04087025cab 368
Pokitto 52:c04087025cab 369 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 370 /* Follow a file path */
Pokitto 52:c04087025cab 371 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 372
Pokitto 52:c04087025cab 373 static
Pokitto 52:c04087025cab 374 FRESULT follow_path ( /* FR_OK(0): successful, !=0: error code */
Pokitto 52:c04087025cab 375 FATDIR *dj, /* Directory object to return last directory and found object */
Pokitto 52:c04087025cab 376 const char *path /* Full-path string to find a file or directory */
Pokitto 52:c04087025cab 377 ) {
Pokitto 52:c04087025cab 378 FRESULT res;
Pokitto 52:c04087025cab 379 BYTE *dir;
Pokitto 52:c04087025cab 380
Pokitto 52:c04087025cab 381
Pokitto 52:c04087025cab 382 while (*path == ' ') path++; /* Skip leading spaces */
Pokitto 52:c04087025cab 383 if (*path == '/') path++; /* Strip heading separator */
Pokitto 52:c04087025cab 384 dj->sclust = 0; /* Set start directory (always root dir) */
Pokitto 52:c04087025cab 385
Pokitto 52:c04087025cab 386 if ((BYTE)*path <= ' ') { /* Null path means the root directory */
Pokitto 52:c04087025cab 387 res = dir_rewind(dj);
Pokitto 52:c04087025cab 388 FatFs->buf[0] = 0;
Pokitto 52:c04087025cab 389
Pokitto 52:c04087025cab 390 } else { /* Follow path */
Pokitto 52:c04087025cab 391 for (;;) {
Pokitto 52:c04087025cab 392 res = create_name(dj, &path); /* Get a segment */
Pokitto 52:c04087025cab 393 if (res != FR_OK) break;
Pokitto 52:c04087025cab 394 res = dir_find(dj); /* Find it */
Pokitto 52:c04087025cab 395 if (res != FR_OK) { /* Could not find the object */
Pokitto 52:c04087025cab 396 if (res == FR_NO_FILE && !*(dj->fn+11))
Pokitto 52:c04087025cab 397 res = FR_NO_PATH;
Pokitto 52:c04087025cab 398 break;
Pokitto 52:c04087025cab 399 }
Pokitto 52:c04087025cab 400 if (*(dj->fn+11)) break; /* Last segment match. Function completed. */
Pokitto 52:c04087025cab 401 dir = FatFs->buf; /* There is next segment. Follow the sub directory */
Pokitto 52:c04087025cab 402 if (!(dir[DIR_Attr] & AM_DIR)) { /* Cannot follow because it is a file */
Pokitto 52:c04087025cab 403 res = FR_NO_PATH;
Pokitto 52:c04087025cab 404 break;
Pokitto 52:c04087025cab 405 }
Pokitto 52:c04087025cab 406 dj->sclust =
Pokitto 52:c04087025cab 407 #if _FS_FAT32
Pokitto 52:c04087025cab 408 ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) |
Pokitto 52:c04087025cab 409 #endif
Pokitto 52:c04087025cab 410 LD_WORD(dir+DIR_FstClusLO);
Pokitto 52:c04087025cab 411 }
Pokitto 52:c04087025cab 412 }
Pokitto 52:c04087025cab 413
Pokitto 52:c04087025cab 414 return res;
Pokitto 52:c04087025cab 415 }
Pokitto 52:c04087025cab 416
Pokitto 52:c04087025cab 417
Pokitto 52:c04087025cab 418
Pokitto 52:c04087025cab 419
Pokitto 52:c04087025cab 420 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 421 /* Check a sector if it is an FAT boot record */
Pokitto 52:c04087025cab 422 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 423
Pokitto 52:c04087025cab 424 static
Pokitto 52:c04087025cab 425 __attribute__((section(".SD_Code"))) BYTE check_fs ( /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record, 3:Error */
Pokitto 52:c04087025cab 426 BYTE *buf, /* Working buffer */
Pokitto 52:c04087025cab 427 DWORD sect /* Sector# (lba) to check if it is an FAT boot record or not */
Pokitto 52:c04087025cab 428 ) {
Pokitto 52:c04087025cab 429 if (disk_readp(buf, sect, 510, 2)) /* Read the boot sector */
Pokitto 52:c04087025cab 430 return 3;
Pokitto 52:c04087025cab 431 if (LD_WORD(buf) != 0xAA55) /* Check record signature */
Pokitto 52:c04087025cab 432 return 2;
Pokitto 52:c04087025cab 433
Pokitto 52:c04087025cab 434 if (!disk_readp(buf, sect, BS_FilSysType, 2) && LD_WORD(buf) == 0x4146) /* Check FAT12/16 */
Pokitto 52:c04087025cab 435 return 0;
Pokitto 52:c04087025cab 436 #if _FS_FAT32
Pokitto 52:c04087025cab 437 if (!disk_readp(buf, sect, BS_FilSysType32, 2) && LD_WORD(buf) == 0x4146) /* Check FAT32 */
Pokitto 52:c04087025cab 438 return 0;
Pokitto 52:c04087025cab 439 #endif
Pokitto 52:c04087025cab 440 return 1;
Pokitto 52:c04087025cab 441 }
Pokitto 52:c04087025cab 442
Pokitto 52:c04087025cab 443
Pokitto 52:c04087025cab 444
Pokitto 52:c04087025cab 445
Pokitto 52:c04087025cab 446 /*--------------------------------------------------------------------------
Pokitto 52:c04087025cab 447
Pokitto 52:c04087025cab 448 Public Functions
Pokitto 52:c04087025cab 449
Pokitto 52:c04087025cab 450 --------------------------------------------------------------------------*/
Pokitto 52:c04087025cab 451
Pokitto 52:c04087025cab 452
Pokitto 52:c04087025cab 453
Pokitto 52:c04087025cab 454 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 455 /* Mount/Unmount a Locical Drive */
Pokitto 52:c04087025cab 456 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 457
Pokitto 52:c04087025cab 458 __attribute__((section(".SD_Code"))) FRESULT pf_mount (
Pokitto 52:c04087025cab 459 FATFS *fs /* Pointer to new file system object (NULL: Unmount) */
Pokitto 52:c04087025cab 460 ) {
Pokitto 52:c04087025cab 461 BYTE fmt, buf[36];
Pokitto 52:c04087025cab 462 DWORD bsect, fsize, tsect, mclst;
Pokitto 52:c04087025cab 463
Pokitto 52:c04087025cab 464
Pokitto 52:c04087025cab 465 FatFs = 0;
Pokitto 52:c04087025cab 466 if (!fs) return FR_OK; /* Unregister fs object */
Pokitto 52:c04087025cab 467
Pokitto 52:c04087025cab 468 if (disk_initialize() & STA_NOINIT) /* Check if the drive is ready or not */
Pokitto 52:c04087025cab 469 return FR_NOT_READY;
Pokitto 52:c04087025cab 470
Pokitto 52:c04087025cab 471 /* Search FAT partition on the drive */
Pokitto 52:c04087025cab 472 bsect = 0;
Pokitto 52:c04087025cab 473 fmt = check_fs(buf, bsect); /* Check sector 0 as an SFD format */
Pokitto 52:c04087025cab 474 if (fmt == 1) { /* Not an FAT boot record, it may be FDISK format */
Pokitto 52:c04087025cab 475 /* Check a partition listed in top of the partition table */
Pokitto 52:c04087025cab 476 if (disk_readp(buf, bsect, MBR_Table, 16)) { /* 1st partition entry */
Pokitto 52:c04087025cab 477 fmt = 3;
Pokitto 52:c04087025cab 478 } else {
Pokitto 52:c04087025cab 479 if (buf[4]) { /* Is the partition existing? */
Pokitto 52:c04087025cab 480 bsect = LD_DWORD(&buf[8]); /* Partition offset in LBA */
Pokitto 52:c04087025cab 481 fmt = check_fs(buf, bsect); /* Check the partition */
Pokitto 52:c04087025cab 482 }
Pokitto 52:c04087025cab 483 }
Pokitto 52:c04087025cab 484 }
Pokitto 52:c04087025cab 485 if (fmt == 3) return FR_DISK_ERR;
Pokitto 52:c04087025cab 486 if (fmt) return FR_NO_FILESYSTEM; /* No valid FAT patition is found */
Pokitto 52:c04087025cab 487
Pokitto 52:c04087025cab 488 /* Initialize the file system object */
Pokitto 52:c04087025cab 489 if (disk_readp(buf, bsect, 13, sizeof(buf))) return FR_DISK_ERR;
Pokitto 52:c04087025cab 490
Pokitto 52:c04087025cab 491 fsize = LD_WORD(buf+BPB_FATSz16-13); /* Number of sectors per FAT */
Pokitto 52:c04087025cab 492 if (!fsize) fsize = LD_DWORD(buf+BPB_FATSz32-13);
Pokitto 52:c04087025cab 493
Pokitto 52:c04087025cab 494 fsize *= buf[BPB_NumFATs-13]; /* Number of sectors in FAT area */
Pokitto 52:c04087025cab 495 fs->fatbase = bsect + LD_WORD(buf+BPB_RsvdSecCnt-13); /* FAT start sector (lba) */
Pokitto 52:c04087025cab 496 fs->csize = buf[BPB_SecPerClus-13]; /* Number of sectors per cluster */
Pokitto 52:c04087025cab 497 fs->n_rootdir = LD_WORD(buf+BPB_RootEntCnt-13); /* Nmuber of root directory entries */
Pokitto 52:c04087025cab 498 tsect = LD_WORD(buf+BPB_TotSec16-13); /* Number of sectors on the file system */
Pokitto 52:c04087025cab 499 if (!tsect) tsect = LD_DWORD(buf+BPB_TotSec32-13);
Pokitto 52:c04087025cab 500 mclst = (tsect /* Last cluster# + 1 */
Pokitto 52:c04087025cab 501 - LD_WORD(buf+BPB_RsvdSecCnt-13) - fsize - fs->n_rootdir / 16
Pokitto 52:c04087025cab 502 ) / fs->csize + 2;
Pokitto 52:c04087025cab 503 fs->max_clust = (CLUST)mclst;
Pokitto 52:c04087025cab 504
Pokitto 52:c04087025cab 505 fmt = FS_FAT12; /* Determine the FAT sub type */
Pokitto 52:c04087025cab 506 if (mclst >= 0xFF7) fmt = FS_FAT16; /* Number of clusters >= 0xFF5 */
Pokitto 52:c04087025cab 507 if (mclst >= 0xFFF7) /* Number of clusters >= 0xFFF5 */
Pokitto 52:c04087025cab 508 #if _FS_FAT32
Pokitto 52:c04087025cab 509 fmt = FS_FAT32;
Pokitto 52:c04087025cab 510 #else
Pokitto 52:c04087025cab 511 return FR_NO_FILESYSTEM;
Pokitto 52:c04087025cab 512 #endif
Pokitto 52:c04087025cab 513
Pokitto 52:c04087025cab 514 fs->fs_type = fmt; /* FAT sub-type */
Pokitto 52:c04087025cab 515 #if _FS_FAT32
Pokitto 52:c04087025cab 516 if (fmt == FS_FAT32)
Pokitto 52:c04087025cab 517 fs->dirbase = LD_DWORD(buf+(BPB_RootClus-13)); /* Root directory start cluster */
Pokitto 52:c04087025cab 518 else
Pokitto 52:c04087025cab 519 #endif
Pokitto 52:c04087025cab 520 fs->dirbase = fs->fatbase + fsize; /* Root directory start sector (lba) */
Pokitto 52:c04087025cab 521 fs->database = fs->fatbase + fsize + fs->n_rootdir / 16; /* Data start sector (lba) */
Pokitto 52:c04087025cab 522
Pokitto 52:c04087025cab 523 fs->flag = 0;
Pokitto 52:c04087025cab 524 FatFs = fs;
Pokitto 52:c04087025cab 525
Pokitto 52:c04087025cab 526 return FR_OK;
Pokitto 52:c04087025cab 527 }
Pokitto 52:c04087025cab 528
Pokitto 52:c04087025cab 529
Pokitto 52:c04087025cab 530
Pokitto 52:c04087025cab 531
Pokitto 52:c04087025cab 532 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 533 /* Open or Create a File */
Pokitto 52:c04087025cab 534 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 535
Pokitto 52:c04087025cab 536 FRESULT pf_open (
Pokitto 52:c04087025cab 537 const char *path /* Pointer to the file name */
Pokitto 52:c04087025cab 538 ) {
Pokitto 52:c04087025cab 539 FRESULT res;
Pokitto 52:c04087025cab 540 FATDIR dj;
Pokitto 52:c04087025cab 541 BYTE sp[12], dir[32];
Pokitto 52:c04087025cab 542 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 543
Pokitto 52:c04087025cab 544
Pokitto 52:c04087025cab 545 if (!fs) /* Check file system */
Pokitto 52:c04087025cab 546 return FR_NOT_ENABLED;
Pokitto 52:c04087025cab 547
Pokitto 52:c04087025cab 548 fs->flag = 0;
Pokitto 52:c04087025cab 549 fs->buf = dir;
Pokitto 52:c04087025cab 550 dj.fn = sp;
Pokitto 52:c04087025cab 551 res = follow_path(&dj, path); /* Follow the file path */
Pokitto 52:c04087025cab 552 if (res != FR_OK) return res; /* Follow failed */
Pokitto 52:c04087025cab 553 if (!dir[0] || (dir[DIR_Attr] & AM_DIR)) /* It is a directory */
Pokitto 52:c04087025cab 554 return FR_NO_FILE;
Pokitto 52:c04087025cab 555
Pokitto 52:c04087025cab 556 fs->org_clust = /* File start cluster */
Pokitto 52:c04087025cab 557 #if _FS_FAT32
Pokitto 52:c04087025cab 558 ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) |
Pokitto 52:c04087025cab 559 #endif
Pokitto 52:c04087025cab 560 LD_WORD(dir+DIR_FstClusLO);
Pokitto 52:c04087025cab 561 fs->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
Pokitto 52:c04087025cab 562 fs->fptr = 0; /* File pointer */
Pokitto 52:c04087025cab 563 fs->flag = FA_OPENED;
Pokitto 52:c04087025cab 564
Pokitto 52:c04087025cab 565 return FR_OK;
Pokitto 52:c04087025cab 566 }
Pokitto 52:c04087025cab 567
Pokitto 52:c04087025cab 568
Pokitto 52:c04087025cab 569
Pokitto 52:c04087025cab 570
Pokitto 52:c04087025cab 571 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 572 /* Read File */
Pokitto 52:c04087025cab 573 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 574 #if _USE_READ
Pokitto 52:c04087025cab 575
Pokitto 52:c04087025cab 576 FRESULT pf_read (
Pokitto 52:c04087025cab 577 void* buff, /* Pointer to the read buffer (NULL:Forward data to the stream)*/
Pokitto 52:c04087025cab 578 WORD btr, /* Number of bytes to read */
Pokitto 52:c04087025cab 579 WORD* br /* Pointer to number of bytes read */
Pokitto 52:c04087025cab 580 ) {
Pokitto 52:c04087025cab 581 DRESULT dr;
Pokitto 52:c04087025cab 582 CLUST clst;
Pokitto 52:c04087025cab 583 DWORD sect, remain;
Pokitto 52:c04087025cab 584 BYTE *rbuff = (BYTE *)buff;
Pokitto 52:c04087025cab 585 WORD rcnt;
Pokitto 52:c04087025cab 586 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 587
Pokitto 52:c04087025cab 588
Pokitto 52:c04087025cab 589 *br = 0;
Pokitto 52:c04087025cab 590 if (!fs) return FR_NOT_ENABLED; /* Check file system */
Pokitto 52:c04087025cab 591 if (!(fs->flag & FA_OPENED)) /* Check if opened */
Pokitto 52:c04087025cab 592 return FR_NOT_OPENED;
Pokitto 52:c04087025cab 593
Pokitto 52:c04087025cab 594 remain = fs->fsize - fs->fptr;
Pokitto 52:c04087025cab 595 if (btr > remain) btr = (WORD)remain; /* Truncate btr by remaining bytes */
Pokitto 52:c04087025cab 596
Pokitto 52:c04087025cab 597 while (btr) { /* Repeat until all data transferred */
Pokitto 52:c04087025cab 598 if ((fs->fptr % 512) == 0) { /* On the sector boundary? */
Pokitto 52:c04087025cab 599 if ((fs->fptr / 512 % fs->csize) == 0) { /* On the cluster boundary? */
Pokitto 52:c04087025cab 600 clst = (fs->fptr == 0) ? /* On the top of the file? */
Pokitto 52:c04087025cab 601 fs->org_clust : get_fat(fs->curr_clust);
Pokitto 52:c04087025cab 602 if (clst <= 1) goto fr_abort;
Pokitto 52:c04087025cab 603 fs->curr_clust = clst; /* Update current cluster */
Pokitto 52:c04087025cab 604 fs->csect = 0; /* Reset sector offset in the cluster */
Pokitto 52:c04087025cab 605 }
Pokitto 52:c04087025cab 606 sect = clust2sect(fs->curr_clust); /* Get current sector */
Pokitto 52:c04087025cab 607 if (!sect) goto fr_abort;
Pokitto 52:c04087025cab 608 fs->dsect = sect + fs->csect++;
Pokitto 52:c04087025cab 609 }
Pokitto 52:c04087025cab 610 rcnt = 512 - ((WORD)fs->fptr % 512); /* Get partial sector data from sector buffer */
Pokitto 52:c04087025cab 611 if (rcnt > btr) rcnt = btr;
Pokitto 52:c04087025cab 612 dr = disk_readp(!buff ? 0 : rbuff, fs->dsect, (WORD)(fs->fptr % 512), rcnt);
Pokitto 52:c04087025cab 613 if (dr) goto fr_abort;
Pokitto 52:c04087025cab 614 fs->fptr += rcnt;
Pokitto 52:c04087025cab 615 rbuff += rcnt; /* Update pointers and counters */
Pokitto 52:c04087025cab 616 btr -= rcnt;
Pokitto 52:c04087025cab 617 *br += rcnt;
Pokitto 52:c04087025cab 618 }
Pokitto 52:c04087025cab 619
Pokitto 52:c04087025cab 620 return FR_OK;
Pokitto 52:c04087025cab 621
Pokitto 52:c04087025cab 622 fr_abort:
Pokitto 52:c04087025cab 623 fs->flag = 0;
Pokitto 52:c04087025cab 624 return FR_DISK_ERR;
Pokitto 52:c04087025cab 625 }
Pokitto 52:c04087025cab 626 #endif
Pokitto 52:c04087025cab 627
Pokitto 52:c04087025cab 628
Pokitto 52:c04087025cab 629
Pokitto 52:c04087025cab 630 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 631 /* Write File */
Pokitto 52:c04087025cab 632 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 633 #if _USE_WRITE
Pokitto 52:c04087025cab 634
Pokitto 52:c04087025cab 635 FRESULT pf_write (
Pokitto 52:c04087025cab 636 const void* buff, /* Pointer to the data to be written */
Pokitto 52:c04087025cab 637 WORD btw, /* Number of bytes to write (0:Finalize the current write operation) */
Pokitto 52:c04087025cab 638 WORD* bw /* Pointer to number of bytes written */
Pokitto 52:c04087025cab 639 ) {
Pokitto 52:c04087025cab 640 CLUST clst;
Pokitto 52:c04087025cab 641 DWORD sect, remain;
Pokitto 52:c04087025cab 642 const BYTE *p = (const BYTE *)buff;
Pokitto 52:c04087025cab 643 WORD wcnt;
Pokitto 52:c04087025cab 644 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 645
Pokitto 52:c04087025cab 646
Pokitto 52:c04087025cab 647 *bw = 0;
Pokitto 52:c04087025cab 648 if (!fs) return FR_NOT_ENABLED; /* Check file system */
Pokitto 52:c04087025cab 649 if (!(fs->flag & FA_OPENED)) /* Check if opened */
Pokitto 52:c04087025cab 650 return FR_NOT_OPENED;
Pokitto 52:c04087025cab 651
Pokitto 52:c04087025cab 652 if (!btw) { /* Finalize request */
Pokitto 52:c04087025cab 653 if ((fs->flag & FA__WIP) && disk_writep(0, 0)) goto fw_abort;
Pokitto 52:c04087025cab 654 fs->flag &= ~FA__WIP;
Pokitto 52:c04087025cab 655 return FR_OK;
Pokitto 52:c04087025cab 656 } else { /* Write data request */
Pokitto 52:c04087025cab 657 if (!(fs->flag & FA__WIP)) /* Round down fptr to the sector boundary */
Pokitto 52:c04087025cab 658 fs->fptr &= 0xFFFFFE00;
Pokitto 52:c04087025cab 659 }
Pokitto 52:c04087025cab 660 remain = fs->fsize - fs->fptr;
Pokitto 52:c04087025cab 661 if (btw > remain) btw = (WORD)remain; /* Truncate btw by remaining bytes */
Pokitto 52:c04087025cab 662
Pokitto 52:c04087025cab 663 while (btw) { /* Repeat until all data transferred */
Pokitto 52:c04087025cab 664 if (((WORD)fs->fptr % 512) == 0) { /* On the sector boundary? */
Pokitto 52:c04087025cab 665 if ((fs->fptr / 512 % fs->csize) == 0) { /* On the cluster boundary? */
Pokitto 52:c04087025cab 666 clst = (fs->fptr == 0) ? /* On the top of the file? */
Pokitto 52:c04087025cab 667 fs->org_clust : get_fat(fs->curr_clust);
Pokitto 52:c04087025cab 668 if (clst <= 1) goto fw_abort;
Pokitto 52:c04087025cab 669 fs->curr_clust = clst; /* Update current cluster */
Pokitto 52:c04087025cab 670 fs->csect = 0; /* Reset sector offset in the cluster */
Pokitto 52:c04087025cab 671 }
Pokitto 52:c04087025cab 672 sect = clust2sect(fs->curr_clust); /* Get current sector */
Pokitto 52:c04087025cab 673 if (!sect) goto fw_abort;
Pokitto 52:c04087025cab 674 fs->dsect = sect + fs->csect++;
Pokitto 52:c04087025cab 675 if (disk_writep(0, fs->dsect)) goto fw_abort; /* Initiate a sector write operation */
Pokitto 52:c04087025cab 676 fs->flag |= FA__WIP;
Pokitto 52:c04087025cab 677 }
Pokitto 52:c04087025cab 678 wcnt = 512 - ((WORD)fs->fptr % 512); /* Number of bytes to write to the sector */
Pokitto 52:c04087025cab 679 if (wcnt > btw) wcnt = btw;
Pokitto 52:c04087025cab 680 if (disk_writep(p, wcnt)) goto fw_abort; /* Send data to the sector */
Pokitto 52:c04087025cab 681 fs->fptr += wcnt;
Pokitto 52:c04087025cab 682 p += wcnt; /* Update pointers and counters */
Pokitto 52:c04087025cab 683 btw -= wcnt;
Pokitto 52:c04087025cab 684 *bw += wcnt;
Pokitto 52:c04087025cab 685 if (((WORD)fs->fptr % 512) == 0) {
Pokitto 52:c04087025cab 686 if (disk_writep(0, 0)) goto fw_abort; /* Finalize the currtent secter write operation */
Pokitto 52:c04087025cab 687 fs->flag &= ~FA__WIP;
Pokitto 52:c04087025cab 688 }
Pokitto 52:c04087025cab 689 }
Pokitto 52:c04087025cab 690
Pokitto 52:c04087025cab 691 return FR_OK;
Pokitto 52:c04087025cab 692
Pokitto 52:c04087025cab 693 fw_abort:
Pokitto 52:c04087025cab 694 fs->flag = 0;
Pokitto 52:c04087025cab 695 return FR_DISK_ERR;
Pokitto 52:c04087025cab 696 }
Pokitto 52:c04087025cab 697 #endif
Pokitto 52:c04087025cab 698
Pokitto 52:c04087025cab 699
Pokitto 52:c04087025cab 700
Pokitto 52:c04087025cab 701 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 702 /* Seek File R/W Pointer */
Pokitto 52:c04087025cab 703 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 704 #if _USE_LSEEK
Pokitto 52:c04087025cab 705
Pokitto 52:c04087025cab 706 FRESULT pf_lseek (
Pokitto 52:c04087025cab 707 DWORD ofs /* File pointer from top of file */
Pokitto 52:c04087025cab 708 ) {
Pokitto 52:c04087025cab 709 CLUST clst;
Pokitto 52:c04087025cab 710 DWORD bcs, sect, ifptr;
Pokitto 52:c04087025cab 711 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 712
Pokitto 52:c04087025cab 713
Pokitto 52:c04087025cab 714 if (!fs) return FR_NOT_ENABLED; /* Check file system */
Pokitto 52:c04087025cab 715 if (!(fs->flag & FA_OPENED)) /* Check if opened */
Pokitto 52:c04087025cab 716 return FR_NOT_OPENED;
Pokitto 52:c04087025cab 717
Pokitto 52:c04087025cab 718 if (ofs > fs->fsize) ofs = fs->fsize; /* Clip offset with the file size */
Pokitto 52:c04087025cab 719 ifptr = fs->fptr;
Pokitto 52:c04087025cab 720 fs->fptr = 0;
Pokitto 52:c04087025cab 721 if (ofs > 0) {
Pokitto 52:c04087025cab 722 bcs = (DWORD)fs->csize * 512; /* Cluster size (byte) */
Pokitto 52:c04087025cab 723 if (ifptr > 0 &&
Pokitto 52:c04087025cab 724 (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
Pokitto 52:c04087025cab 725 fs->fptr = (ifptr - 1) & ~(bcs - 1); /* start from the current cluster */
Pokitto 52:c04087025cab 726 ofs -= fs->fptr;
Pokitto 52:c04087025cab 727 clst = fs->curr_clust;
Pokitto 52:c04087025cab 728 } else { /* When seek to back cluster, */
Pokitto 52:c04087025cab 729 clst = fs->org_clust; /* start from the first cluster */
Pokitto 52:c04087025cab 730 fs->curr_clust = clst;
Pokitto 52:c04087025cab 731 }
Pokitto 52:c04087025cab 732 while (ofs > bcs) { /* Cluster following loop */
Pokitto 52:c04087025cab 733 clst = get_fat(clst); /* Follow cluster chain */
Pokitto 52:c04087025cab 734 if (clst <= 1 || clst >= fs->max_clust) goto fe_abort;
Pokitto 52:c04087025cab 735 fs->curr_clust = clst;
Pokitto 52:c04087025cab 736 fs->fptr += bcs;
Pokitto 52:c04087025cab 737 ofs -= bcs;
Pokitto 52:c04087025cab 738 }
Pokitto 52:c04087025cab 739 fs->fptr += ofs;
Pokitto 52:c04087025cab 740 sect = clust2sect(clst); /* Current sector */
Pokitto 52:c04087025cab 741 if (!sect) goto fe_abort;
Pokitto 52:c04087025cab 742 fs->csect = (BYTE)(ofs / 512); /* Sector offset in the cluster */
Pokitto 52:c04087025cab 743 if (ofs % 512)
Pokitto 52:c04087025cab 744 fs->dsect = sect + fs->csect++;
Pokitto 52:c04087025cab 745 }
Pokitto 52:c04087025cab 746
Pokitto 52:c04087025cab 747 return FR_OK;
Pokitto 52:c04087025cab 748
Pokitto 52:c04087025cab 749 fe_abort:
Pokitto 52:c04087025cab 750 fs->flag = 0;
Pokitto 52:c04087025cab 751 return FR_DISK_ERR;
Pokitto 52:c04087025cab 752 }
Pokitto 52:c04087025cab 753 #endif
Pokitto 52:c04087025cab 754
Pokitto 52:c04087025cab 755
Pokitto 52:c04087025cab 756
Pokitto 52:c04087025cab 757 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 758 /* Create a Directroy Object */
Pokitto 52:c04087025cab 759 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 760 #if _USE_DIR
Pokitto 52:c04087025cab 761
Pokitto 52:c04087025cab 762 FRESULT pf_opendir (
Pokitto 52:c04087025cab 763 FATDIR *dj, /* Pointer to directory object to create */
Pokitto 52:c04087025cab 764 const char *path /* Pointer to the directory path */
Pokitto 52:c04087025cab 765 ) {
Pokitto 52:c04087025cab 766 FRESULT res;
Pokitto 52:c04087025cab 767 BYTE sp[12], dir[32];
Pokitto 52:c04087025cab 768 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 769
Pokitto 52:c04087025cab 770
Pokitto 52:c04087025cab 771 if (!fs) { /* Check file system */
Pokitto 52:c04087025cab 772 res = FR_NOT_ENABLED;
Pokitto 52:c04087025cab 773 } else {
Pokitto 52:c04087025cab 774 fs->buf = dir;
Pokitto 52:c04087025cab 775 dj->fn = sp;
Pokitto 52:c04087025cab 776 res = follow_path(dj, path); /* Follow the path to the directory */
Pokitto 52:c04087025cab 777 if (res == FR_OK) { /* Follow completed */
Pokitto 52:c04087025cab 778 if (dir[0]) { /* It is not the root dir */
Pokitto 52:c04087025cab 779 if (dir[DIR_Attr] & AM_DIR) { /* The object is a directory */
Pokitto 52:c04087025cab 780 dj->sclust =
Pokitto 52:c04087025cab 781 #if _FS_FAT32
Pokitto 52:c04087025cab 782 ((DWORD)LD_WORD(dir+DIR_FstClusHI) << 16) |
Pokitto 52:c04087025cab 783 #endif
Pokitto 52:c04087025cab 784 LD_WORD(dir+DIR_FstClusLO);
Pokitto 52:c04087025cab 785 } else { /* The object is not a directory */
Pokitto 52:c04087025cab 786 res = FR_NO_PATH;
Pokitto 52:c04087025cab 787 }
Pokitto 52:c04087025cab 788 }
Pokitto 52:c04087025cab 789 if (res == FR_OK)
Pokitto 52:c04087025cab 790 res = dir_rewind(dj); /* Rewind dir */
Pokitto 52:c04087025cab 791 }
Pokitto 52:c04087025cab 792 if (res == FR_NO_FILE) res = FR_NO_PATH;
Pokitto 52:c04087025cab 793 }
Pokitto 52:c04087025cab 794
Pokitto 52:c04087025cab 795 return res;
Pokitto 52:c04087025cab 796 }
Pokitto 52:c04087025cab 797
Pokitto 52:c04087025cab 798
Pokitto 52:c04087025cab 799
Pokitto 52:c04087025cab 800
Pokitto 52:c04087025cab 801 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 802 /* Read Directory Entry in Sequense */
Pokitto 52:c04087025cab 803 /*-----------------------------------------------------------------------*/
Pokitto 52:c04087025cab 804
Pokitto 52:c04087025cab 805 FRESULT pf_readdir (
Pokitto 52:c04087025cab 806 FATDIR *dj, /* Pointer to the open directory object */
Pokitto 52:c04087025cab 807 FILINFO *fno /* Pointer to file information to return */
Pokitto 52:c04087025cab 808 ) {
Pokitto 52:c04087025cab 809 FRESULT res;
Pokitto 52:c04087025cab 810 BYTE sp[12], dir[32];
Pokitto 52:c04087025cab 811 FATFS *fs = FatFs;
Pokitto 52:c04087025cab 812
Pokitto 52:c04087025cab 813
Pokitto 52:c04087025cab 814 if (!fs) { /* Check file system */
Pokitto 52:c04087025cab 815 res = FR_NOT_ENABLED;
Pokitto 52:c04087025cab 816 } else {
Pokitto 52:c04087025cab 817 fs->buf = dir;
Pokitto 52:c04087025cab 818 dj->fn = sp;
Pokitto 52:c04087025cab 819 if (!fno) {
Pokitto 52:c04087025cab 820 res = dir_rewind(dj);
Pokitto 52:c04087025cab 821 } else {
Pokitto 52:c04087025cab 822 res = dir_read(dj);
Pokitto 52:c04087025cab 823 if (res == FR_NO_FILE) {
Pokitto 52:c04087025cab 824 dj->sect = 0;
Pokitto 52:c04087025cab 825 res = FR_OK;
Pokitto 52:c04087025cab 826 }
Pokitto 52:c04087025cab 827 if (res == FR_OK) { /* A valid entry is found */
Pokitto 52:c04087025cab 828 get_fileinfo(dj, fno); /* Get the object information */
Pokitto 52:c04087025cab 829 res = dir_next(dj); /* Increment index for next */
Pokitto 52:c04087025cab 830 if (res == FR_NO_FILE) {
Pokitto 52:c04087025cab 831 dj->sect = 0;
Pokitto 52:c04087025cab 832 res = FR_OK;
Pokitto 52:c04087025cab 833 }
Pokitto 52:c04087025cab 834 }
Pokitto 52:c04087025cab 835 }
Pokitto 52:c04087025cab 836 }
Pokitto 52:c04087025cab 837
Pokitto 52:c04087025cab 838 return res;
Pokitto 52:c04087025cab 839 }
Pokitto 52:c04087025cab 840
Pokitto 52:c04087025cab 841 #endif /* _USE_DIR */
Pokitto 52:c04087025cab 842
Pokitto 52:c04087025cab 843 } // namespace PFFS
Pokitto 52:c04087025cab 844
Pokitto 52:c04087025cab 845