Jonne Valola / PokittoLib Featured

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:
Wed Jun 27 13:14:54 2018 +0000
Revision:
50:ca94812a17b6
Parent:
6:72f87b7c7400
Lockup at startup due to missing EEPROM values fixed

Who changed what in which revision?

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