00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "fat.h"
00043 #include <core/heap.h>
00044 #include <core/device.h>
00045 #include <drivers/sd/sd.h>
00046 #include <common/mem.h>
00047 #include <common/string.h>
00048 #include <core/dbgterm.h>
00049 #include <core/rtc.h>
00050
00051 #if __CONFIG_COMPILE_FAT
00052
00070 __PFAT_VOLUME __fatVolumes;
00081 __PFAT_VOLUME __fatGetVolumeFromFatFS(__PFAT_FATFS fs)
00082 {
00083 __PFAT_VOLUME vol = __fatVolumes;
00084 while (vol)
00085 {
00086 if (vol->fat == fs) return vol;
00087 vol = vol->next;
00088 }
00089
00090 return __NULL;
00091 }
00092
00102 __STATIC __PDEVICE __fatGetDevice(u8 drv)
00103 {
00104 __PFAT_VOLUME vol = __fatVolumes;
00105 while (vol)
00106 {
00107 if (vol->num == drv) return vol->dv;
00108 vol = vol->next;
00109 }
00110
00111 return __NULL;
00112 }
00113
00129 __STATIC __PFAT_VOLUME __fatCreateVolume(u8 num, __PFAT_FATFS fat, __PDEVICE dv)
00130 {
00131 __PFAT_VOLUME ptr = __fatVolumes;
00132 __PFAT_VOLUME last = ptr;
00133
00134 __systemStop();
00135
00136
00137 while (ptr)
00138 {
00139 last = ptr;
00140 ptr = ptr->next;
00141 }
00142
00143 ptr = (__PFAT_VOLUME) __heapAllocZero(sizeof(__FAT_VOLUME));
00144 if (!ptr) return __NULL;
00145
00146 ptr->num = num;
00147 ptr->fat = fat;
00148 ptr->dv = dv;
00149 ptr->next = __NULL;
00150
00151 if (!last)
00152 {
00153 __fatVolumes = ptr;
00154 } else
00155 {
00156 last->next = ptr;
00157 }
00158
00159 __systemStart();
00160
00161 return ptr;
00162 }
00163
00176 __STATIC __VOID __fatFreeVolume(__PFAT_VOLUME vol)
00177 {
00178 __PFAT_VOLUME ptr = __fatVolumes;
00179 __PFAT_VOLUME last = ptr;
00180
00181 __systemStop();
00182
00183
00184 while (ptr) {
00185 if (ptr == vol)
00186 {
00187 if (vol == __fatVolumes)
00188 {
00189 __fatVolumes = __fatVolumes->next;
00190 } else
00191 {
00192 last->next = ptr->next;
00193 }
00194
00195 __heapFree(vol);
00196 }
00197 last = ptr;
00198 ptr = ptr->next;
00199 }
00200 }
00201
00222 __PFAT_VOLUME __fatMount(u8 num, __PDEVICE dv)
00223 {
00224 __PFAT_VOLUME ptr = __fatVolumes;
00225 __PFAT_FATFS fat;
00226
00227
00228 while (ptr)
00229 {
00230 if (ptr->num == num) return ptr;
00231 ptr = ptr->next;
00232 }
00233
00234
00235
00236
00237 fat = (__PFAT_FATFS) __heapAllocZero(sizeof(__FAT_FATFS));
00238 if (!fat) return __NULL;
00239
00240
00241 if (f_mount(num, fat) != FR_OK)
00242 {
00243 __heapFree(fat);
00244 return __NULL;
00245 }
00246
00247
00248 ptr = __fatCreateVolume(num, fat, dv);
00249
00250
00251 return ptr;
00252 }
00253
00261 __VOID __fatDismount(__PFAT_VOLUME vol)
00262 {
00263
00264 __PFAT_FATFS fat = vol->fat;
00265
00266
00267 f_mount(vol->num, __NULL);
00268
00269 __fatFreeVolume(vol);
00270 __heapFree(fat);
00271 }
00272
00273
00274 u32 __fatGetFreeClusters(__CONST __PSTRING part, __PFAT_VOLUME* vol);
00275
00304 __FILE_RES __dirCreate(__CONST __PSTRING name)
00305 {
00306 return f_mkdir(name);
00307 }
00308
00333 __FILE_RES __dirOpen(__PDIR dir, __CONST __PSTRING name)
00334 {
00335 return f_opendir(dir, name);
00336 }
00337
00368 __FILE_RES __dirRead(__PDIR dir, __PFILEINFO fi)
00369 {
00370 return f_readdir(dir, fi);
00371 }
00372
00382 #if __CONFIG_COMPILE_DBGTERM
00383
00392 __VOID __fatDirCmd(__PTERMINAL term)
00393 {
00394 __DIR dir;
00395 __FILEINFO fi;
00396 __PSTRING str;
00397 u32 count = 0;
00398 u32 bytes = 0;
00399
00400
00401 str = __heapAllocZero(64);
00402 if (!str) return;
00403
00404
00405 __memSet(&dir, 0, sizeof(dir));
00406 __memSet(&fi, 0, sizeof(fi));
00407
00408
00409 if (__dirOpen(&dir, "") == FR_OK)
00410 {
00411 __terminalWriteLine(term, "\r\nFiles in FAT:\r\n");
00412 __terminalWriteLine(term, "Name Size");
00413 __terminalWriteLine(term, "-------------------------");
00414
00415
00416 __dirRead(&dir, __NULL);
00417
00418
00419 while (__dirRead(&dir, &fi) == FR_OK && dir.sect > 0)
00420 {
00421 count++;
00422 bytes += fi.fsize;
00423 __strFmt(str, "%12s %lu bytes", fi.fname, (u32) fi.fsize);
00424 __terminalWriteLine(term, str);
00425 }
00426
00427 __terminalWriteLine(term, "\r\n%lu file(s) %lu bytes\r\n", count, bytes);
00428 } else
00429 {
00430 __terminalWriteLine(term, "Error calling __dirOpen()");
00431 }
00432
00433 __heapFree(str);
00434 }
00435
00436 #endif
00437
00470 __PFILE __fileOpen(__CONST __PSTRING file, u8 mode)
00471 {
00472 __PFILE ptr;
00473
00474 ptr = (__PFILE) __heapAllocZero(sizeof(__FILE));
00475 if (!ptr) return __NULL;
00476
00477 if (f_open(ptr, file, mode) != FR_OK)
00478 {
00479 __heapFree(ptr);
00480 return __NULL;
00481 }
00482
00483 return ptr;
00484 }
00485
00496 u32 __fileRead(__PFILE file, __PVOID buf, u32 qty)
00497 {
00498 UINT ret = 0;
00499
00500 f_read(file, buf, qty, &ret);
00501 return ret;
00502 }
00503
00538 __FILE_RES __fileSeek(__PFILE file, u32 offs)
00539 {
00540 return f_lseek(file, offs);
00541 }
00542
00560 __FILE_RES __fileClose(__PFILE file)
00561 {
00562 __FILE_RES ret;
00563 ret = f_close(file);
00564 if (ret == FR_OK) {
00565 __heapFree(file);
00566 }
00567
00568 return ret;
00569 }
00570
00595 __FILE_RES __fileGetStatus(__CONST __PSTRING file, __PFILEINFO fi)
00596 {
00597 return f_stat(file, fi);
00598 }
00599
00616 u32 __fileWrite(__PFILE file, __PVOID buf, u32 qty)
00617 {
00618 UINT ret;
00619 f_write(file, buf, qty, &ret);
00620 return ret;
00621 }
00622
00644 __FILE_RES __fileFlush(__PFILE file)
00645 {
00646 return f_sync(file);
00647 }
00648
00666 __FILE_RES __fileTruncate(__PFILE file)
00667 {
00668 return f_truncate(file);
00669 }
00670
00697 __FILE_RES __fileDelete(__CONST __PSTRING file)
00698 {
00699 return f_unlink(file);
00700 }
00701
00728 __FILE_RES __fileChmod(__CONST __PSTRING file, u8 value, u8 mask)
00729 {
00730 return f_chmod(file, value, mask);
00731 }
00732
00754 __FILE_RES __fileChangeTime(__CONST __PSTRING file, __CONST __PFILEINFO fi)
00755 {
00756 return f_utime(file, fi);
00757 }
00758
00783 __FILE_RES __fileRename(__CONST __PSTRING name1, __CONST __PSTRING name2);
00784
00809 __FATFS_STATUS disk_initialize (u8 drv)
00810 {
00811
00812 __PDEVICE dv = __fatGetDevice(drv);
00813 if (!dv) return RES_NOTRDY;
00814
00815
00816
00817
00818 if (__deviceOpen(dv, 0) == 0) return RES_OK;
00819 return RES_ERROR;
00820 }
00821
00842 __FATFS_STATUS disk_status (BYTE drv)
00843 {
00844 __FATFS_STATUS ret = 0;
00845 __PDEVICE dv;
00846
00847
00848 dv = __fatGetDevice(drv);
00849 if (!dv) return ret;
00850
00851 switch (dv->dv_type)
00852 {
00853
00854 case __DEV_CFSD:
00855 if (__deviceIOCtl(dv, __IOCTL_WRITE_PROTECTED, 0, __NULL, 0))
00856 {
00857 ret |= STA_PROTECT;
00858 }
00859
00860 if (!__deviceIOCtl(dv, __IOCTL_MEDIA_AVAILABLE, 0, __NULL, 0))
00861 {
00862 ret |= STA_NODISK;
00863 }
00864 break;
00865 default:
00866
00867 ret = STA_NOINIT;
00868 break;
00869 }
00870
00871 if (!dv->dv_initd || !dv->dv_opcnt)
00872 {
00873 ret |= STA_NOINIT;
00874 }
00875 return ret;
00876 }
00877
00907 __FATFS_RES disk_ioctl (u8 drv, u8 ctrl, __PVOID buff)
00908 {
00909 __FATFS_RES res = RES_ERROR;
00910 u8* ptr = (u8*) buff;
00911 __PDEVICE dv;
00912
00913
00914 dv = __fatGetDevice(drv);
00915 if (!dv) return res;
00916
00917
00918 if (dv->dv_type == __DEV_CFSD)
00919 {
00920
00921 if (ctrl == CTRL_POWER)
00922 {
00923 switch (*ptr) {
00924
00925 case 0:
00926 if (__deviceIOCtl(dv, __IOCTL_GET_POWER_STATUS, 0, __NULL, 0)) {
00927 __deviceIOCtl(dv, __IOCTL_SET_POWER_STATUS, 0, __NULL, 0);
00928 }
00929 res = RES_OK;
00930 break;
00931
00932
00933 case 1:
00934 __deviceIOCtl(dv, __IOCTL_SET_POWER_STATUS, 1, __NULL, 0);
00935 res = RES_OK;
00936 break;
00937
00938
00939 case 2:
00940 *(ptr+1) = (u8) __deviceIOCtl(dv, __IOCTL_GET_POWER_STATUS, 0, __NULL, 0);
00941 res = RES_OK;
00942 break;
00943
00944 default:
00945 res = RES_PARERR;
00946 break;
00947 }
00948 } else
00949 {
00950
00951 if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
00952
00953 switch (ctrl)
00954 {
00955
00956
00957
00958
00959 case CTRL_SYNC:
00960
00961 res = RES_OK;
00962 break;
00963
00964
00965
00966
00967
00968 case GET_SECTOR_COUNT:
00969 *(u32*) buff = __deviceIOCtl(dv, __IOCTL_GET_SECTOR_COUNT, 0, __NULL, 0);
00970 res = RES_OK;
00971 break;
00972
00973
00974
00975
00976 case GET_SECTOR_SIZE:
00977 *(u16*) buff = 512;
00978 res = RES_OK;
00979 break;
00980
00981
00982
00983
00984
00985
00986
00987 case GET_BLOCK_SIZE:
00988 *(u32*) buff = __deviceIOCtl(dv, __IOCTL_GET_BLOCK_SIZE, 0, __NULL, 0);
00989 res = RES_OK;
00990 break;
00991
00992
00993 case MMC_GET_TYPE:
00994 *ptr = (u8) __deviceIOCtl(dv, __IOCTL_GET_CARD_TYPE, 0, __NULL, 0);
00995 res = RES_OK;
00996 break;
00997
00998 case MMC_GET_CSD:
00999 __deviceIOCtl(dv, __IOCTL_GET_CSD, 0, __NULL, 0);
01000 res = RES_OK;
01001 break;
01002
01003 case MMC_GET_CID:
01004 __deviceIOCtl(dv, __IOCTL_GET_CID, 0, __NULL, 0);
01005 res = RES_OK;
01006 break;
01007
01008 case MMC_GET_OCR:
01009 __deviceIOCtl(dv, __IOCTL_GET_OCR, 0, __NULL, 0);
01010 res = RES_OK;
01011 break;
01012
01013 case MMC_GET_SDSTAT:
01014 __deviceIOCtl(dv, __IOCTL_GET_SDSTAT, 0, __NULL, 0);
01015 res = RES_OK;
01016 break;
01017
01018 default:
01019 res = RES_PARERR;
01020 break;
01021 }
01022 }
01023 }
01024
01025 return res;
01026 }
01027
01052 __FATFS_RES disk_read (u8 drv, u8 *buff, u32 sector, u8 count)
01053 {
01054 __PDEVICE dv;
01055
01056
01057 dv = __fatGetDevice(drv);
01058 if (!dv) return RES_PARERR;
01059
01060
01061 if (dv->dv_type == __DEV_CFSD) __deviceIOCtl(dv, __IOCTL_SET_SECTOR, sector, __NULL, 0);
01062 if (__deviceRead(dv, buff, count) == 0) return RES_OK;
01063
01064 return RES_ERROR;
01065 }
01066
01093 __FATFS_RES disk_write (BYTE drv, __CONST u8 *buff, u32 sector, u8 count)
01094 {
01095 __PDEVICE dv;
01096
01097
01098 dv = __fatGetDevice(drv);
01099 if (!dv) return RES_PARERR;
01100
01101 if (dv->dv_type == __DEV_CFSD)
01102 {
01103 if (__deviceIOCtl(dv, __IOCTL_WRITE_PROTECTED, 0, __NULL, 0))
01104 {
01105 return RES_WRPRT;
01106 }
01107 }
01108
01109
01110 if (dv->dv_type == __DEV_CFSD)
01111 {
01112 __deviceIOCtl(dv, __IOCTL_SET_SECTOR, sector, __NULL, 0);
01113 }
01114
01115
01116 if (__deviceWrite(dv, buff, count) == 0) return RES_OK;
01117
01118 return RES_ERROR;
01119 }
01120
01143 u32 get_fattime (__VOID)
01144 {
01145
01146 #if __CONFIG_COMPILE_RTC
01147 __DATETIME dt;
01148
01149 __rtcGetDateTime(&dt);
01150
01151 return ((dt.year - 1980) << 25 |
01152 dt.month << 21 |
01153 dt.day << 16 |
01154 dt.hour << 11 |
01155 dt.min << 5 |
01156 dt.sec);
01157
01158 #else
01159
01160
01161 return (30 << 25 | 12 << 21 | 30 << 16 | 19 << 11 | 2 << 5 | 50);
01162
01163 #endif
01164
01165 }
01166
01167 #if _FS_REENTRANT
01168
01181 __BOOL ff_cre_syncobj (u8 vol, _SYNC_t *sobj)
01182 {
01183 __BOOL ret = __FALSE;
01184
01185 *sobj = __lockCreate();
01186 ret = (*sobj != __NULL) ? __TRUE : __FALSE;
01187
01188 return ret;
01189 }
01190
01191
01204 BOOL ff_del_syncobj (_SYNC_t sobj) {
01205 __lockDestroy(sobj);
01206 return __TRUE;
01207 }
01208
01221 BOOL ff_req_grant(_SYNC_t sobj) {
01222 __BOOL ret;
01223
01224 ret = __lockOwn(sobj, _FS_TIMEOUT);
01225 return ret;
01226 }
01227
01239 __VOID ff_rel_grant (_SYNC_t sobj)
01240 {
01241 __lockRelease(sobj);
01242 }
01243
01244 #endif
01245
01246
01247 #if _USE_LFN == 3
01248
01260 __PVOID ff_memalloc (UINT size)
01261 {
01262 return __heapAlloc(size);
01263 }
01264
01274 __VOID ff_memfree(__PVOID mblock)
01275 {
01276 __heapFree(mblock);
01277 }
01278
01279 #endif // _USE_LFN
01280
01297 #endif // __CONFIG_COMPILE_FAT