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

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Tue Oct 23 16:21:01 2018 +0000
Revision:
63:7d1c08cdde5c
Parent:
52:c04087025cab
Graphics bug fixed

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