├── README.md ├── FatFs ├── library.properties ├── LICENSE.txt ├── src │ ├── diskio.h │ ├── diskio.c │ ├── FatFs.h │ ├── ffsystem.c │ ├── ffconf.h │ ├── FatFs.cpp │ └── ff.h └── examples │ └── FatFsDemo │ └── FatFsDemo.ino ├── .gitattributes └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # Arduino-FatFs 2 | ## Classes to wrap FatFs module developed by ChaN on Arduino platform 3 | 4 | - Use SD library for Esp8266 for the low level device control 5 | - Use low level rutines of SdFat library with boards with others chips 6 | -------------------------------------------------------------------------------- /FatFs/library.properties: -------------------------------------------------------------------------------- 1 | name=FatFs 2 | version=0.14 3 | author=Jean-Michel Gallego 4 | maintainer=Jean-Michel Gallego 5 | sentence=adaptation of FAT file system (R0.14) developped by ChaN 6 | paragraph=adaptation of FAT file system (R0.14) developped by ChaN 7 | category=Data Storage 8 | url=https://github.com/gallegojm/ 9 | architectures=* 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must end with two \r 29 | Icon 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | -------------------------------------------------------------------------------- /FatFs/LICENSE.txt: -------------------------------------------------------------------------------- 1 | FatFs License 2 | 3 | FatFs has being developped as a personal project of the author, ChaN. It is free from the code anyone else wrote at current release. Following code block shows a copy of the FatFs license document that heading the source files. 4 | 5 | /*----------------------------------------------------------------------------/ 6 | / FatFs - Generic FAT Filesystem Module Rx.xx / 7 | /-----------------------------------------------------------------------------/ 8 | / 9 | / Copyright (C) 20xx, ChaN, all right reserved. 10 | / 11 | / FatFs module is an open source software. Redistribution and use of FatFs in 12 | / source and binary forms, with or without modification, are permitted provided 13 | / that the following condition is met: 14 | / 15 | / 1. Redistributions of source code must retain the above copyright notice, 16 | / this condition and the following disclaimer. 17 | / 18 | / This software is provided by the copyright holder and contributors "AS IS" 19 | / and any warranties related to this software are DISCLAIMED. 20 | / The copyright owner or contributors be NOT LIABLE for any damages caused 21 | / by use of this software. 22 | /----------------------------------------------------------------------------*/ 23 | 24 | Therefore FatFs license is one of the BSD-style licenses but there is a significant feature. FatFs is mainly intended for embedded systems. In order to extend the usability for commercial products, the redistributions of FatFs in binary form, such as embedded code, binary library and any forms without source code, does not need to include about FatFs in the documentations. This is equivalent to the 1-clause BSD license. Of course FatFs is compatible with the most of open source software licenses including GNU GPL. When you redistribute the FatFs source code with any changes or create a fork, the license can also be changed to GNU GPL, BSD-style license or any open source software license that not conflict with FatFs license. 25 | -------------------------------------------------------------------------------- /FatFs/src/diskio.h: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------/ 2 | / Low level disk interface modlue include file (C)ChaN, 2019 / 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO_DEFINED 6 | #define _DISKIO_DEFINED 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | /* Status of Disk Functions */ 13 | typedef BYTE DSTATUS; 14 | 15 | /* Results of Disk Functions */ 16 | typedef enum { 17 | RES_OK = 0, /* 0: Successful */ 18 | RES_ERROR, /* 1: R/W Error */ 19 | RES_WRPRT, /* 2: Write Protected */ 20 | RES_NOTRDY, /* 3: Not Ready */ 21 | RES_PARERR /* 4: Invalid Parameter */ 22 | } DRESULT; 23 | 24 | 25 | /*---------------------------------------*/ 26 | /* Prototypes for disk control functions */ 27 | 28 | 29 | DSTATUS disk_initialize (BYTE pdrv); 30 | DSTATUS disk_status (BYTE pdrv); 31 | DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count); 32 | DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count); 33 | DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); 34 | 35 | 36 | /* Disk Status Bits (DSTATUS) */ 37 | 38 | #define STA_NOINIT 0x01 /* Drive not initialized */ 39 | #define STA_NODISK 0x02 /* No medium in the drive */ 40 | #define STA_PROTECT 0x04 /* Write protected */ 41 | 42 | 43 | /* Command code for disk_ioctrl fucntion */ 44 | 45 | /* Generic command (Used by FatFs) */ 46 | #define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */ 47 | #define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */ 48 | #define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */ 49 | #define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */ 50 | #define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */ 51 | 52 | /* Generic command (Not used by FatFs) */ 53 | #define CTRL_POWER 5 /* Get/Set power status */ 54 | #define CTRL_LOCK 6 /* Lock/Unlock media removal */ 55 | #define CTRL_EJECT 7 /* Eject media */ 56 | #define CTRL_FORMAT 8 /* Create physical format on the media */ 57 | 58 | /* MMC/SDC specific ioctl command */ 59 | #define MMC_GET_TYPE 10 /* Get card type */ 60 | #define MMC_GET_CSD 11 /* Get CSD */ 61 | #define MMC_GET_CID 12 /* Get CID */ 62 | #define MMC_GET_OCR 13 /* Get OCR */ 63 | #define MMC_GET_SDSTAT 14 /* Get SD status */ 64 | #define ISDIO_READ 55 /* Read data form SD iSDIO register */ 65 | #define ISDIO_WRITE 56 /* Write data to SD iSDIO register */ 66 | #define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */ 67 | 68 | /* ATA/CF specific ioctl command */ 69 | #define ATA_GET_REV 20 /* Get F/W revision */ 70 | #define ATA_GET_MODEL 21 /* Get model name */ 71 | #define ATA_GET_SN 22 /* Get serial number */ 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /FatFs/src/diskio.c: -------------------------------------------------------------------------------- 1 | /*-----------------------------------------------------------------------*/ 2 | /* Low level disk I/O module skeleton for FatFs (C)ChaN, 2019 */ 3 | /*-----------------------------------------------------------------------*/ 4 | /* If a working storage control module is available, it should be */ 5 | /* attached to the FatFs via a glue function rather than modifying it. */ 6 | /* This is an example of glue functions to attach various exsisting */ 7 | /* storage control modules to the FatFs module with a defined API. */ 8 | /*-----------------------------------------------------------------------*/ 9 | 10 | #include "ff.h" /* Obtains integer types */ 11 | #include "diskio.h" /* Declarations of disk functions */ 12 | 13 | /* Definitions of physical drive number for each drive */ 14 | // #define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ 15 | // #define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ 16 | // #define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ 17 | 18 | 19 | /*-----------------------------------------------------------------------*/ 20 | /* Get Drive Status */ 21 | /*-----------------------------------------------------------------------*/ 22 | 23 | DSTATUS disk_status( BYTE pdrv ) // Physical drive nmuber to identify the drive 24 | { 25 | return sd_status(); 26 | } 27 | 28 | /*-----------------------------------------------------------------------*/ 29 | /* Inidialize a Drive */ 30 | /*-----------------------------------------------------------------------*/ 31 | 32 | DSTATUS disk_initialize( BYTE pdrv ) // Physical drive nmuber to identify the drive 33 | { 34 | return sd_initialize(); 35 | } 36 | 37 | /*-----------------------------------------------------------------------*/ 38 | /* Read Sector(s) */ 39 | /*-----------------------------------------------------------------------*/ 40 | 41 | DRESULT disk_read( BYTE pdrv, // Physical drive nmuber to identify the drive 42 | BYTE *buff, // Data buffer to store read data 43 | LBA_t sector, // Sector address in LBA 44 | UINT count ) // Number of sectors to read 45 | { 46 | return sd_disk_read( buff, sector, count ); 47 | } 48 | 49 | /*-----------------------------------------------------------------------*/ 50 | /* Write Sector(s) */ 51 | /*-----------------------------------------------------------------------*/ 52 | 53 | #if FF_FS_READONLY == 0 54 | 55 | DRESULT disk_write( BYTE pdrv, // Physical drive nmuber to identify the drive 56 | const BYTE *buff, // Data to be written 57 | LBA_t sector, // Sector address in LBA 58 | UINT count ) // Number of sectors to write 59 | { 60 | return sd_disk_write( buff, sector, count ); 61 | } 62 | 63 | #endif 64 | 65 | 66 | /*-----------------------------------------------------------------------*/ 67 | /* Miscellaneous Functions */ 68 | /*-----------------------------------------------------------------------*/ 69 | 70 | DRESULT disk_ioctl( BYTE pdrv, // Physical drive nmuber (0..) 71 | BYTE cmd, // Control code 72 | void *buff ) // Buffer to send/receive control data 73 | { 74 | return sd_disk_ioctl( cmd ); 75 | } 76 | 77 | -------------------------------------------------------------------------------- /FatFs/src/FatFs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Classes to wrap FatFs library from ChaN 3 | * Copyright (c) 2018 by Jean-Michel Gallego 4 | * 5 | * Use version R0.12c of FatFs 6 | * 7 | * Use SD library for Esp8266 for the low level device control 8 | * Use low level rutines of SdFat library with boards with others chips 9 | * 10 | * This Library is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This Library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License, 21 | * If not, see . 22 | */ 23 | 24 | #ifndef FATFS_H 25 | #define FATFS_H 26 | 27 | #include 28 | #ifdef ESP8266 29 | #include 30 | #define SD_CS_PIN 15 // Chip Select for SD card reader on Esp8266 31 | #else 32 | #include 33 | #endif 34 | #include "ff.h" 35 | #include "diskio.h" 36 | 37 | class FatFsClass 38 | { 39 | public: 40 | FatFsClass() {}; 41 | 42 | #ifdef ESP8266 43 | bool begin( uint8_t csPin = SD_CS_PIN, uint32_t speed = SPI_FULL_SPEED ); 44 | #else 45 | bool begin( uint8_t csPin, SPISettings spiSettings ); 46 | #endif 47 | int32_t capacity(); 48 | int32_t free(); 49 | uint8_t error(); 50 | 51 | bool mkdir( const char * path ); 52 | bool rmdir( const char * path ); 53 | bool remove( const char * path ); 54 | bool rename( const char * oldName, const char * newName ); 55 | bool exists( const char * path ); 56 | bool isDir( const char * path ); 57 | bool timeStamp( const char * path, uint16_t year, uint8_t month, uint8_t day, 58 | uint8_t hour, uint8_t minute, uint8_t second ); 59 | bool getFileModTime( const char * path, uint16_t * pdate, uint16_t * ptime ); 60 | 61 | private: 62 | FATFS ffs; 63 | 64 | #ifndef ESP8266 65 | protected: 66 | SdFatSpiDriver m_spi; 67 | #endif 68 | }; 69 | 70 | extern FatFsClass FatFs; 71 | 72 | class DirFs 73 | { 74 | public: 75 | DirFs() {}; 76 | ~DirFs() { f_closedir( & dir ); }; 77 | 78 | bool open( char * dirPath ); 79 | bool close(); 80 | bool nextFile(); 81 | bool rewind(); 82 | bool isDir(); 83 | char * fileName(); 84 | uint32_t fileSize(); 85 | uint16_t fileModDate(); 86 | uint16_t fileModTime(); 87 | 88 | private: 89 | FILINFO finfo; 90 | DIR dir; 91 | }; 92 | 93 | class FileFs 94 | { 95 | public: 96 | FileFs() {}; 97 | 98 | bool open( char * fileName, uint8_t mode = FA_OPEN_EXISTING ); 99 | bool close(); 100 | 101 | uint32_t write( void * buf, uint32_t lbuf ); 102 | int writeString( char * str ); 103 | bool writeChar( char car ); 104 | 105 | uint32_t read( void * buf, uint32_t lbuf ); 106 | int16_t readString( char * buf, int len ); 107 | char readChar(); 108 | uint16_t readInt(); 109 | uint16_t readHex(); 110 | 111 | uint32_t curPosition(); 112 | bool seekSet( uint32_t cur ); 113 | 114 | uint32_t fileSize(); 115 | 116 | private: 117 | FIL ffile; 118 | }; 119 | 120 | // Return true if char c is allowed in a long file name 121 | 122 | inline bool legalChar( char c ) 123 | { 124 | if( c == '"' || c == '*' || c == '?' || c == ':' || 125 | c == '<' || c == '>' || c == '|' ) 126 | return false; 127 | return true; 128 | } 129 | 130 | #endif // FATFS_H 131 | -------------------------------------------------------------------------------- /FatFs/src/ffsystem.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------*/ 2 | /* Sample Code of OS Dependent Functions for FatFs */ 3 | /* (C)ChaN, 2018 */ 4 | /*------------------------------------------------------------------------*/ 5 | 6 | 7 | #include "ff.h" 8 | 9 | 10 | #if FF_USE_LFN == 3 /* Dynamic memory allocation */ 11 | 12 | /*------------------------------------------------------------------------*/ 13 | /* Allocate a memory block */ 14 | /*------------------------------------------------------------------------*/ 15 | 16 | void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */ 17 | UINT msize /* Number of bytes to allocate */ 18 | ) 19 | { 20 | return malloc(msize); /* Allocate a new memory block with POSIX API */ 21 | } 22 | 23 | 24 | /*------------------------------------------------------------------------*/ 25 | /* Free a memory block */ 26 | /*------------------------------------------------------------------------*/ 27 | 28 | void ff_memfree ( 29 | void* mblock /* Pointer to the memory block to free (nothing to do if null) */ 30 | ) 31 | { 32 | free(mblock); /* Free the memory block with POSIX API */ 33 | } 34 | 35 | #endif 36 | 37 | 38 | 39 | #if FF_FS_REENTRANT /* Mutal exclusion */ 40 | 41 | /*------------------------------------------------------------------------*/ 42 | /* Create a Synchronization Object */ 43 | /*------------------------------------------------------------------------*/ 44 | /* This function is called in f_mount() function to create a new 45 | / synchronization object for the volume, such as semaphore and mutex. 46 | / When a 0 is returned, the f_mount() function fails with FR_INT_ERR. 47 | */ 48 | 49 | //const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */ 50 | 51 | 52 | int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */ 53 | BYTE vol, /* Corresponding volume (logical drive number) */ 54 | FF_SYNC_t* sobj /* Pointer to return the created sync object */ 55 | ) 56 | { 57 | /* Win32 */ 58 | *sobj = CreateMutex(NULL, FALSE, NULL); 59 | return (int)(*sobj != INVALID_HANDLE_VALUE); 60 | 61 | /* uITRON */ 62 | // T_CSEM csem = {TA_TPRI,1,1}; 63 | // *sobj = acre_sem(&csem); 64 | // return (int)(*sobj > 0); 65 | 66 | /* uC/OS-II */ 67 | // OS_ERR err; 68 | // *sobj = OSMutexCreate(0, &err); 69 | // return (int)(err == OS_NO_ERR); 70 | 71 | /* FreeRTOS */ 72 | // *sobj = xSemaphoreCreateMutex(); 73 | // return (int)(*sobj != NULL); 74 | 75 | /* CMSIS-RTOS */ 76 | // *sobj = osMutexCreate(&Mutex[vol]); 77 | // return (int)(*sobj != NULL); 78 | } 79 | 80 | 81 | /*------------------------------------------------------------------------*/ 82 | /* Delete a Synchronization Object */ 83 | /*------------------------------------------------------------------------*/ 84 | /* This function is called in f_mount() function to delete a synchronization 85 | / object that created with ff_cre_syncobj() function. When a 0 is returned, 86 | / the f_mount() function fails with FR_INT_ERR. 87 | */ 88 | 89 | int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */ 90 | FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */ 91 | ) 92 | { 93 | /* Win32 */ 94 | return (int)CloseHandle(sobj); 95 | 96 | /* uITRON */ 97 | // return (int)(del_sem(sobj) == E_OK); 98 | 99 | /* uC/OS-II */ 100 | // OS_ERR err; 101 | // OSMutexDel(sobj, OS_DEL_ALWAYS, &err); 102 | // return (int)(err == OS_NO_ERR); 103 | 104 | /* FreeRTOS */ 105 | // vSemaphoreDelete(sobj); 106 | // return 1; 107 | 108 | /* CMSIS-RTOS */ 109 | // return (int)(osMutexDelete(sobj) == osOK); 110 | } 111 | 112 | 113 | /*------------------------------------------------------------------------*/ 114 | /* Request Grant to Access the Volume */ 115 | /*------------------------------------------------------------------------*/ 116 | /* This function is called on entering file functions to lock the volume. 117 | / When a 0 is returned, the file function fails with FR_TIMEOUT. 118 | */ 119 | 120 | int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */ 121 | FF_SYNC_t sobj /* Sync object to wait */ 122 | ) 123 | { 124 | /* Win32 */ 125 | return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0); 126 | 127 | /* uITRON */ 128 | // return (int)(wai_sem(sobj) == E_OK); 129 | 130 | /* uC/OS-II */ 131 | // OS_ERR err; 132 | // OSMutexPend(sobj, FF_FS_TIMEOUT, &err)); 133 | // return (int)(err == OS_NO_ERR); 134 | 135 | /* FreeRTOS */ 136 | // return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE); 137 | 138 | /* CMSIS-RTOS */ 139 | // return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK); 140 | } 141 | 142 | 143 | /*------------------------------------------------------------------------*/ 144 | /* Release Grant to Access the Volume */ 145 | /*------------------------------------------------------------------------*/ 146 | /* This function is called on leaving file functions to unlock the volume. 147 | */ 148 | 149 | void ff_rel_grant ( 150 | FF_SYNC_t sobj /* Sync object to be signaled */ 151 | ) 152 | { 153 | /* Win32 */ 154 | ReleaseMutex(sobj); 155 | 156 | /* uITRON */ 157 | // sig_sem(sobj); 158 | 159 | /* uC/OS-II */ 160 | // OSMutexPost(sobj); 161 | 162 | /* FreeRTOS */ 163 | // xSemaphoreGive(sobj); 164 | 165 | /* CMSIS-RTOS */ 166 | // osMutexRelease(sobj); 167 | } 168 | 169 | #endif 170 | 171 | -------------------------------------------------------------------------------- /FatFs/examples/FatFsDemo/FatFsDemo.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Test of a class to access the FatFs module 3 | on Arduino Due by Jean-Michel Gallego 4 | FatFs module is a generic FAT file system for 5 | small embedded systems developped by ChaN. 6 | 7 | Tested with Due, Mega2560 and Esp8266 8 | 9 | Wiring for Esp8266 and SD card reader: 10 | SD card Esp8266 11 | MISO #12 12 | MOSI #13 13 | SCK #14 14 | CS #15 (Can be modified specifying value for SD_CS_PIN) 15 | 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | // Modify according to your hardware 22 | // #define MY_SD_CS_PIN 4 // Chip Select for SD card reader with Ethernet shield 23 | #define MY_SD_CS_PIN 53 // Chip Select for SD card reader on Due 24 | // #define MY_SD_CS_PIN 15 // Default Chip Select for SD card reader on Esp8266 25 | 26 | void setup() 27 | { 28 | int res; 29 | 30 | // If other chips are connected to SPI bus, set to high the pin connected to their CS 31 | /* 32 | pinMode( 10, OUTPUT ); 33 | digitalWrite( 10, HIGH ); 34 | pinMode( 4, OUTPUT ); 35 | digitalWrite( 4, HIGH ); 36 | */ 37 | 38 | Serial.begin( 115200 ); 39 | Serial.println( "== Testing FatFs on Arduino ==" ); 40 | Serial.println( "Press a key to start\n" ); 41 | while( Serial.read() < 0 ) 42 | delay( 1 ); 43 | delay( 400 ); 44 | 45 | // Mount SD card 46 | #ifdef ESP8266 47 | res = FatFs.begin(); // Use default pin 15 for chip select 48 | #else 49 | res = FatFs.begin( MY_SD_CS_PIN, SD_SCK_MHZ(50)); 50 | // res = FatFs.begin( MY_SD_CS_PIN, SPI_HALF_SPEED ); 51 | #endif 52 | printError( res, "Unable to mount SD card" ); 53 | Serial.println( "SD card mounted" ); 54 | 55 | // Show capacity and free space of SD card 56 | Serial.print( "Capacity of card: " ); 57 | Serial.print( FatFs.capacity()); 58 | Serial.println( " kBytes" ); 59 | Serial.print( "Free space on card: " ); 60 | Serial.print( FatFs.free()); 61 | Serial.println( " kBytes" ); 62 | 63 | // List root directory 64 | Serial.println( "List of directories and files in root:" ); 65 | DirFs dir; 66 | if( dir.openDir( "/" )) 67 | while( dir.nextFile()) 68 | { 69 | Serial.print( dir.fileName()); 70 | Serial.print( "\t" ); 71 | if( dir.isDir() ) 72 | Serial.println( "(Directory)" ); 73 | else 74 | { 75 | Serial.print( dir.fileSize()); 76 | Serial.println( " Bytes" ); 77 | } 78 | } 79 | 80 | // Create directory 81 | char * dirName = "/Nouveau répertoire"; 82 | Serial.print( "\nCreate directory '" ); 83 | Serial.print( dirName ); 84 | Serial.println( "'" ); 85 | if( FatFs.exists( dirName )) 86 | { 87 | Serial.print( dirName ); 88 | Serial.println( " already exists!" ); 89 | } 90 | else 91 | { 92 | res = FatFs.mkdir( dirName ); 93 | printError( res, "Error creating directory" ); 94 | } 95 | Serial.print( dirName ); 96 | Serial.println( " created!" ); 97 | 98 | // Create a file in that directory 99 | FileFs file; 100 | char * fileName = "/Nouveau répertoire/Test d'écriture.txt"; 101 | Serial.print( "\nCreate file '" ); 102 | Serial.print( fileName ); 103 | Serial.println( "'" ); 104 | res = file.open( fileName, FA_WRITE | FA_READ | FA_CREATE_ALWAYS ); 105 | printError( res, "Error creating file" ); 106 | 107 | // Writing text to a file and closing it 108 | Serial.println( "Write to file" ); 109 | res = file.writeString( "Test d'écriture dans un fichier\r\n" ); 110 | if( res >= 0 ) 111 | res = file.writeString( "Testing writing to file\r\n" ); 112 | if( res >= 0 ) 113 | res = file.writeString( "Prueba de escritura en un archivo\r\n" ); 114 | // Write next line using writeBuffer() 115 | if( res >= 0 ) 116 | { 117 | char * ps1 = "Test di scrittura su file\r\n"; 118 | uint32_t nwrite = file.write( ps1, strlen( ps1 )); 119 | res = nwrite == strlen( ps1 ); 120 | } 121 | // Write last line byte per byte, using writeChar() 122 | if( res >= 0 ) 123 | { 124 | char * ps2 = "Testes de gravação em um arquivo\r\n"; 125 | uint8_t pc = 0 ; 126 | while( res >= 0 && ps2[ pc ] != 0 ) 127 | res = file.writeChar( ps2[ pc ++ ] ); 128 | } 129 | printError( ( res >= 0 ), "Error writing to file" ); 130 | 131 | // Read content of file 132 | Serial.print( "\nContent of '" ); 133 | Serial.print( fileName ); 134 | Serial.println( "' is:" ); 135 | file.seekSet( 0 ); // set cursor to beginning of file 136 | char line[ 64 ]; 137 | // Read lines with readString() and print length of lines 138 | int l; 139 | while( ( l = file.readString( line, sizeof( line ))) >= 0 ) 140 | { 141 | Serial.print( line ); 142 | Serial.print( " (Length is: " ); 143 | Serial.print( l ); 144 | Serial.println( ")" ); 145 | } 146 | 147 | // Size of the file 148 | Serial.print( "\nSize of file " ); 149 | Serial.print( fileName ); 150 | Serial.print( " : " ); 151 | Serial.println( file.fileSize()); 152 | 153 | // Close the file 154 | Serial.println( "\nClose the file" ); 155 | res = file.close(); 156 | printError( res, "Error closing file" ); 157 | 158 | // Rename and move the file to root 159 | char * newName = "/TEST.TXT"; 160 | Serial.print( "\nRename file '" ); 161 | Serial.print( fileName ); 162 | Serial.print( "' to '" ); 163 | Serial.print( newName ); 164 | Serial.println( "'" ); 165 | if( FatFs.exists( newName )) 166 | FatFs.remove( newName ); 167 | res = FatFs.rename( fileName, newName ); 168 | printError( res, "Error renaming file" ); 169 | 170 | // Show content of directories 171 | listDir( dirName ); 172 | listDir( "/" ); 173 | 174 | // Copy file 175 | char * copyName = "/Copy.txt"; 176 | Serial.print( "\nCopy '" ); 177 | Serial.print( newName ); 178 | Serial.print( "' to new file '" ); 179 | Serial.print( copyName ); 180 | Serial.println( "' :" ); 181 | file.open( newName, FA_OPEN_EXISTING | FA_READ ); 182 | FileFs copy; 183 | res = copy.open( copyName, FA_WRITE | FA_READ | FA_CREATE_ALWAYS ); 184 | printError( res, "Error creating file" ); 185 | uint8_t buf[ 64 ]; 186 | while(( l = file.read( buf, sizeof( buf ))) > 0 ) 187 | if( copy.write( buf, l ) != l ) 188 | printError( res, "Error copying file" ); 189 | copy.close(); 190 | 191 | // Open file for reading 192 | Serial.print( "\nOpen file '" ); 193 | Serial.print( copyName ); 194 | Serial.println( "' :" ); 195 | res = copy.open( copyName, FA_OPEN_EXISTING | FA_READ ); 196 | printError( res, "Error opening file" ); 197 | 198 | // Read content of file and close it 199 | Serial.print( "\nContent of '" ); 200 | Serial.print( copyName ); 201 | Serial.println( "' is:" ); 202 | // Read first line byte per byte, just to demostrate use of readChar() 203 | char c; 204 | do 205 | { 206 | c = copy.readChar(); 207 | Serial.print( c ); 208 | } 209 | while( c != '\n' && c != -1 ); 210 | // Read next lines with readString() 211 | while( copy.readString( line, sizeof( line )) > 0 ) 212 | Serial.println( line ); 213 | copy.close(); 214 | 215 | // Delete the files 216 | Serial.print( "\nDelete the files '" ); 217 | Serial.print( newName ); 218 | Serial.print( "' and '" ); 219 | Serial.print( copyName ); 220 | Serial.println( "'" ); 221 | res = FatFs.remove( newName ) || FatFs.remove( copyName ); 222 | printError( res, "Error deleting files" ); 223 | 224 | // Delete the directory 225 | Serial.print( "\nDelete directory '" ); 226 | Serial.print( dirName ); 227 | Serial.println( "'" ); 228 | res = FatFs.rmdir( dirName ); 229 | printError( res, "Error deleting directory" ); 230 | 231 | Serial.println( "\nTest ok!" ); 232 | } 233 | 234 | void loop() 235 | { 236 | } 237 | 238 | // LIST DIRECTORY 239 | 240 | void listDir( char * dirname ) 241 | { 242 | DirFs d; 243 | 244 | Serial.print( "\nContent of directory '" ); 245 | Serial.print( dirname ); 246 | Serial.println( "' :" ); 247 | if( d.openDir( dirname )) 248 | { 249 | uint8_t entrees = 0; 250 | while( d.nextFile()) 251 | { 252 | Serial.println( d.fileName()); 253 | entrees ++; 254 | } 255 | d.closeDir(); 256 | Serial.print( entrees ); 257 | Serial.print( " files or directories in " ); 258 | Serial.println( dirname ); 259 | } 260 | } 261 | 262 | // PRINT ERROR STRING & STOP EXECUTION 263 | 264 | // if ok is false, print the string msg and enter a while loop for ever 265 | 266 | void printError( int ok, char * msg ) 267 | { 268 | if( ok ) 269 | return; 270 | Serial.print( msg ); 271 | Serial.print( ": " ); 272 | Serial.println( FatFs.error()); 273 | while( true ) 274 | delay( 1 ); 275 | } 276 | -------------------------------------------------------------------------------- /FatFs/src/ffconf.h: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------------------------/ 2 | / FatFs Functional Configurations 3 | /---------------------------------------------------------------------------*/ 4 | 5 | #define FFCONF_DEF 86606 /* Revision ID */ 6 | 7 | /*---------------------------------------------------------------------------/ 8 | / Function Configurations 9 | /---------------------------------------------------------------------------*/ 10 | 11 | #define FF_FS_READONLY 0 12 | /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) 13 | / Read-only configuration removes writing API functions, f_write(), f_sync(), 14 | / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() 15 | / and optional writing functions as well. */ 16 | 17 | 18 | #define FF_FS_MINIMIZE 0 19 | /* This option defines minimization level to remove some basic API functions. 20 | / 21 | / 0: Basic functions are fully enabled. 22 | / 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename() 23 | / are removed. 24 | / 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1. 25 | / 3: f_lseek() function is removed in addition to 2. */ 26 | 27 | 28 | //#define FF_USE_STRFUNC 0 29 | #define FF_USE_STRFUNC 1 30 | /* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf(). 31 | / 32 | / 0: Disable string functions. 33 | / 1: Enable without LF-CRLF conversion. 34 | / 2: Enable with LF-CRLF conversion. */ 35 | 36 | 37 | #define FF_USE_FIND 0 38 | /* This option switches filtered directory read functions, f_findfirst() and 39 | / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ 40 | 41 | 42 | #define FF_USE_MKFS 0 43 | /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ 44 | 45 | 46 | #define FF_USE_FASTSEEK 0 47 | /* This option switches fast seek function. (0:Disable or 1:Enable) */ 48 | 49 | 50 | #define FF_USE_EXPAND 0 51 | /* This option switches f_expand function. (0:Disable or 1:Enable) */ 52 | 53 | 54 | //#define FF_USE_CHMOD 0 55 | #define FF_USE_CHMOD 1 56 | /* This option switches attribute manipulation functions, f_chmod() and f_utime(). 57 | / (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ 58 | 59 | 60 | #define FF_USE_LABEL 0 61 | /* This option switches volume label functions, f_getlabel() and f_setlabel(). 62 | / (0:Disable or 1:Enable) */ 63 | 64 | 65 | #define FF_USE_FORWARD 0 66 | /* This option switches f_forward() function. (0:Disable or 1:Enable) */ 67 | 68 | 69 | /*---------------------------------------------------------------------------/ 70 | / Locale and Namespace Configurations 71 | /---------------------------------------------------------------------------*/ 72 | 73 | //#define FF_CODE_PAGE 932 74 | #define FF_CODE_PAGE 437 75 | /* This option specifies the OEM code page to be used on the target system. 76 | / Incorrect code page setting can cause a file open failure. 77 | / 78 | / 437 - U.S. 79 | / 720 - Arabic 80 | / 737 - Greek 81 | / 771 - KBL 82 | / 775 - Baltic 83 | / 850 - Latin 1 84 | / 852 - Latin 2 85 | / 855 - Cyrillic 86 | / 857 - Turkish 87 | / 860 - Portuguese 88 | / 861 - Icelandic 89 | / 862 - Hebrew 90 | / 863 - Canadian French 91 | / 864 - Arabic 92 | / 865 - Nordic 93 | / 866 - Russian 94 | / 869 - Greek 2 95 | / 932 - Japanese (DBCS) 96 | / 936 - Simplified Chinese (DBCS) 97 | / 949 - Korean (DBCS) 98 | / 950 - Traditional Chinese (DBCS) 99 | / 0 - Include all code pages above and configured by f_setcp() 100 | */ 101 | 102 | 103 | //#define FF_USE_LFN 0 104 | #define FF_USE_LFN 1 105 | #define FF_MAX_LFN 255 106 | /* The FF_USE_LFN switches the support for LFN (long file name). 107 | / 108 | / 0: Disable LFN. FF_MAX_LFN has no effect. 109 | / 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe. 110 | / 2: Enable LFN with dynamic working buffer on the STACK. 111 | / 3: Enable LFN with dynamic working buffer on the HEAP. 112 | / 113 | / To enable the LFN, ffunicode.c needs to be added to the project. The LFN function 114 | / requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and 115 | / additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled. 116 | / The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can 117 | / be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN 118 | / specification. 119 | / When use stack for the working buffer, take care on stack overflow. When use heap 120 | / memory for the working buffer, memory management functions, ff_memalloc() and 121 | / ff_memfree() exemplified in ffsystem.c, need to be added to the project. */ 122 | 123 | 124 | #define FF_LFN_UNICODE 0 125 | /* This option switches the character encoding on the API when LFN is enabled. 126 | / 127 | / 0: ANSI/OEM in current CP (TCHAR = char) 128 | / 1: Unicode in UTF-16 (TCHAR = WCHAR) 129 | / 2: Unicode in UTF-8 (TCHAR = char) 130 | / 3: Unicode in UTF-32 (TCHAR = DWORD) 131 | / 132 | / Also behavior of string I/O functions will be affected by this option. 133 | / When LFN is not enabled, this option has no effect. */ 134 | 135 | 136 | #define FF_LFN_BUF 255 137 | #define FF_SFN_BUF 12 138 | /* This set of options defines size of file name members in the FILINFO structure 139 | / which is used to read out directory items. These values should be suffcient for 140 | / the file names to read. The maximum possible length of the read file name depends 141 | / on character encoding. When LFN is not enabled, these options have no effect. */ 142 | 143 | 144 | #define FF_STRF_ENCODE 3 145 | /* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(), 146 | / f_putc(), f_puts and f_printf() convert the character encoding in it. 147 | / This option selects assumption of character encoding ON THE FILE to be 148 | / read/written via those functions. 149 | / 150 | / 0: ANSI/OEM in current CP 151 | / 1: Unicode in UTF-16LE 152 | / 2: Unicode in UTF-16BE 153 | / 3: Unicode in UTF-8 154 | */ 155 | 156 | 157 | #define FF_FS_RPATH 0 158 | /* This option configures support for relative path. 159 | / 160 | / 0: Disable relative path and remove related functions. 161 | / 1: Enable relative path. f_chdir() and f_chdrive() are available. 162 | / 2: f_getcwd() function is available in addition to 1. 163 | */ 164 | 165 | 166 | /*---------------------------------------------------------------------------/ 167 | / Drive/Volume Configurations 168 | /---------------------------------------------------------------------------*/ 169 | 170 | #define FF_VOLUMES 1 171 | /* Number of volumes (logical drives) to be used. (1-10) */ 172 | 173 | 174 | #define FF_STR_VOLUME_ID 0 175 | #define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" 176 | /* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. 177 | / When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive 178 | / number in the path name. FF_VOLUME_STRS defines the volume ID strings for each 179 | / logical drives. Number of items must not be less than FF_VOLUMES. Valid 180 | / characters for the volume ID strings are A-Z, a-z and 0-9, however, they are 181 | / compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is 182 | / not defined, a user defined volume string table needs to be defined as: 183 | / 184 | / const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",... 185 | */ 186 | 187 | 188 | #define FF_MULTI_PARTITION 0 189 | /* This option switches support for multiple volumes on the physical drive. 190 | / By default (0), each logical drive number is bound to the same physical drive 191 | / number and only an FAT volume found on the physical drive will be mounted. 192 | / When this function is enabled (1), each logical drive number can be bound to 193 | / arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk() 194 | / funciton will be available. */ 195 | 196 | 197 | #define FF_MIN_SS 512 198 | #define FF_MAX_SS 512 199 | /* This set of options configures the range of sector size to be supported. (512, 200 | / 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and 201 | / harddisk. But a larger value may be required for on-board flash memory and some 202 | / type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured 203 | / for variable sector size mode and disk_ioctl() function needs to implement 204 | / GET_SECTOR_SIZE command. */ 205 | 206 | 207 | #define FF_LBA64 0 208 | /* This option switches support for 64-bit LBA. (0:Disable or 1:Enable) 209 | / To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */ 210 | 211 | 212 | #define FF_MIN_GPT 0x100000000 213 | /* Minimum number of sectors to switch GPT format to create partition in f_mkfs and 214 | / f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */ 215 | 216 | 217 | #define FF_USE_TRIM 0 218 | /* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) 219 | / To enable Trim function, also CTRL_TRIM command should be implemented to the 220 | / disk_ioctl() function. */ 221 | 222 | 223 | 224 | /*---------------------------------------------------------------------------/ 225 | / System Configurations 226 | /---------------------------------------------------------------------------*/ 227 | 228 | #define FF_FS_TINY 0 229 | /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) 230 | / At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. 231 | / Instead of private sector buffer eliminated from the file object, common sector 232 | / buffer in the filesystem object (FATFS) is used for the file data transfer. */ 233 | 234 | 235 | #define FF_FS_EXFAT 0 236 | /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) 237 | / To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) 238 | / Note that enabling exFAT discards ANSI C (C89) compatibility. */ 239 | 240 | 241 | #define FF_FS_NORTC 0 242 | #define FF_NORTC_MON 1 243 | #define FF_NORTC_MDAY 1 244 | #define FF_NORTC_YEAR 2019 245 | /* The option FF_FS_NORTC switches timestamp functiton. If the system does not have 246 | / any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable 247 | / the timestamp function. Every object modified by FatFs will have a fixed timestamp 248 | / defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time. 249 | / To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be 250 | / added to the project to read current time form real-time clock. FF_NORTC_MON, 251 | / FF_NORTC_MDAY and FF_NORTC_YEAR have no effect. 252 | / These options have no effect in read-only configuration (FF_FS_READONLY = 1). */ 253 | 254 | 255 | //#define FF_FS_NOFSINFO 0 256 | #define FF_FS_NOFSINFO 1 257 | /* If you need to know correct free space on the FAT32 volume, set bit 0 of this 258 | / option, and f_getfree() function at first time after volume mount will force 259 | / a full FAT scan. Bit 1 controls the use of last allocated cluster number. 260 | / 261 | / bit0=0: Use free cluster count in the FSINFO if available. 262 | / bit0=1: Do not trust free cluster count in the FSINFO. 263 | / bit1=0: Use last allocated cluster number in the FSINFO if available. 264 | / bit1=1: Do not trust last allocated cluster number in the FSINFO. 265 | */ 266 | 267 | 268 | #define FF_FS_LOCK 0 269 | /* The option FF_FS_LOCK switches file lock function to control duplicated file open 270 | / and illegal operation to open objects. This option must be 0 when FF_FS_READONLY 271 | / is 1. 272 | / 273 | / 0: Disable file lock function. To avoid volume corruption, application program 274 | / should avoid illegal open, remove and rename to the open objects. 275 | / >0: Enable file lock function. The value defines how many files/sub-directories 276 | / can be opened simultaneously under file lock control. Note that the file 277 | / lock control is independent of re-entrancy. */ 278 | 279 | 280 | /* #include // O/S definitions */ 281 | #define FF_FS_REENTRANT 0 282 | #define FF_FS_TIMEOUT 1000 283 | #define FF_SYNC_t HANDLE 284 | /* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs 285 | / module itself. Note that regardless of this option, file access to different 286 | / volume is always re-entrant and volume control functions, f_mount(), f_mkfs() 287 | / and f_fdisk() function, are always not re-entrant. Only file/directory access 288 | / to the same volume is under control of this function. 289 | / 290 | / 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect. 291 | / 1: Enable re-entrancy. Also user provided synchronization handlers, 292 | / ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj() 293 | / function, must be added to the project. Samples are available in 294 | / option/syscall.c. 295 | / 296 | / The FF_FS_TIMEOUT defines timeout period in unit of time tick. 297 | / The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*, 298 | / SemaphoreHandle_t and etc. A header file for O/S definitions needs to be 299 | / included somewhere in the scope of ff.h. */ 300 | 301 | 302 | 303 | /*--- End of configuration options ---*/ 304 | -------------------------------------------------------------------------------- /FatFs/src/FatFs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * A class to wrap FatFs library from ChaN 3 | * Copyright (c) 2018 by Jean-Michel Gallego 4 | * 5 | * Use version R0.14 of FatFs 6 | * 7 | * Use SD library for Esp8266 for the low level device control 8 | * Use low level rutines of SdFat library with boards with others chips 9 | * 10 | * This Library is free software: you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation, either version 3 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This Library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License, 21 | * If not, see . 22 | */ 23 | 24 | #include "FatFs.h" 25 | 26 | #ifdef ESP8266 27 | Sd2Card card; 28 | #else 29 | SdSpiCard card; 30 | #endif 31 | 32 | /* 33 | extern "C" void sd_print( uint8_t a, uint32_t b ) 34 | { 35 | // Serial.println(); 36 | Serial.print( "==> " ); 37 | Serial.print( a ); 38 | Serial.print( " " ); 39 | Serial.println( b ); 40 | } 41 | */ 42 | 43 | extern "C" int sd_status() 44 | { 45 | if( card.type() == 0 ) 46 | return STA_NOINIT; 47 | return 0; // card.errorData(); 48 | } 49 | 50 | // card.init return 1 if initialisation is successfull. 51 | // sd_initialize must return 0 when success 52 | 53 | extern "C" int sd_initialize() 54 | { 55 | return 0; 56 | } 57 | 58 | extern "C" int sd_disk_read( uint8_t * buff, uint32_t sector, uint32_t count ) 59 | { 60 | uint8_t * b = buff; 61 | 62 | for( uint32_t n = 0; n < count; n ++ ) 63 | { 64 | if( card.readBlock( sector + n, b ) == 0 ) 65 | return 1; 66 | } 67 | return 0; 68 | } 69 | 70 | extern "C" int sd_disk_write( uint8_t * buff, uint32_t sector, uint32_t count ) 71 | { 72 | uint8_t * b = buff; 73 | 74 | for( int n = 0; n < count; n ++ ) 75 | if( card.writeBlock( sector + n, b ) == 0 ) 76 | return 1; 77 | return 0; 78 | } 79 | 80 | extern "C" int sd_disk_ioctl( uint8_t cmd ) 81 | { 82 | DRESULT res = RES_ERROR; 83 | 84 | switch( cmd ) 85 | { 86 | case CTRL_SYNC : // Make sure that data has been written 87 | res = RES_OK; 88 | // res = spiRec() == 0XFF ? RES_OK : RES_NOTRDY ; 89 | // res = card.waitNotBusy( SD_WRITE_TIMEOUT ) ? RES_OK : RES_NOTRDY ; 90 | break; 91 | 92 | default: 93 | res = RES_PARERR; 94 | } 95 | } 96 | 97 | extern "C" DWORD get_fattime( void ) 98 | { 99 | return ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16); 100 | } 101 | 102 | extern "C" void* ff_memalloc (UINT msize) 103 | { 104 | return malloc( msize ); 105 | } 106 | 107 | extern "C" void ff_memfree (void* mblock) 108 | { 109 | free( mblock ); 110 | } 111 | 112 | /* =========================================================== 113 | 114 | FatFsClass functions 115 | 116 | =========================================================== */ 117 | 118 | uint8_t ffs_result; 119 | 120 | // Initialize SD card and file system 121 | // csPin : SD card chip select pin 122 | // speed : SPI speed = SPI_HALF_SPEED (default), SPI_FULL_SPEED 123 | // Return true if ok 124 | 125 | #ifdef ESP8266 126 | bool FatFsClass::begin( uint8_t csPin, uint32_t speed ) 127 | #else 128 | bool FatFsClass::begin( uint8_t csPin, SPISettings spiSettings ) 129 | #endif 130 | { 131 | ffs_result = 0; 132 | #ifdef ESP8266 133 | if( ! card.init( speed, csPin )) 134 | #else 135 | if( ! card.begin( &m_spi, csPin, spiSettings )) 136 | #endif 137 | return false; 138 | ffs_result = f_mount( & ffs, "", 1 ); 139 | return ffs_result == FR_OK; 140 | } 141 | 142 | // Return capacity of card in kBytes 143 | 144 | int32_t FatFsClass::capacity() 145 | { 146 | return ( ffs.n_fatent - 2 ) * ffs.csize >> 1; // >> 11; 147 | } 148 | 149 | // Return free space in kBytes 150 | 151 | int32_t FatFsClass::free() 152 | { 153 | uint32_t fre_clust; 154 | FATFS * fs; 155 | 156 | if( f_getfree( "0:", (DWORD*) & fre_clust, & fs ) != 0 ) 157 | return -1; 158 | return fre_clust * ffs.csize >> 1; // >> 11; 159 | } 160 | 161 | // Return last error value 162 | // See ff.h for a description of errors 163 | 164 | uint8_t FatFsClass::error() 165 | { 166 | return ffs_result; 167 | } 168 | 169 | // Make a directory 170 | // dirPath : absolute name of new directory 171 | // Return true if ok 172 | 173 | bool FatFsClass::mkdir( const char * path ) 174 | { 175 | ffs_result = f_mkdir( path ); 176 | return ffs_result == FR_OK; // || res == FR_EXIST; 177 | } 178 | 179 | // Remove a directory (must be empty) 180 | // path : absolute name of directory to remove 181 | // Return true if ok 182 | 183 | bool FatFsClass::rmdir( const char * path ) 184 | { 185 | return remove( path ); 186 | } 187 | 188 | // Remove a file 189 | // path : absolute name of file to remove 190 | // Return true if ok 191 | 192 | bool FatFsClass::remove( const char * path ) 193 | { 194 | ffs_result = f_unlink( path ); 195 | return ffs_result == FR_OK; 196 | } 197 | 198 | // Rename a file or directory 199 | // oldName : old absolute name of file/directory to rename 200 | // newName : new absolute name 201 | // Return true if ok 202 | 203 | bool FatFsClass::rename( const char * oldName, const char * newName ) 204 | { 205 | // f_rename modify the value pointed by parameters oldName0 and newName0 206 | const char * oldName0 = oldName; 207 | const char * newName0 = newName; 208 | ffs_result = f_rename( oldName0, newName0 ); 209 | return ffs_result == FR_OK; 210 | } 211 | 212 | // Return true if a file or directory exists 213 | // path : absolute name of file or directory 214 | 215 | bool FatFsClass::exists( const char * path ) 216 | { 217 | if( strcmp( path, "/" ) == 0 ) 218 | return true; 219 | return f_stat( path, NULL ) == FR_OK; 220 | } 221 | 222 | // Return true if a absolute name correspond to an existing directory 223 | 224 | bool FatFsClass::isDir( const char * path ) 225 | { 226 | if( strcmp( path, "/" ) == 0 ) 227 | return true; 228 | 229 | FILINFO finfo; 230 | return ( f_stat( path, & finfo ) == FR_OK ) && 231 | ( finfo.fattrib & AM_DIR ); 232 | } 233 | 234 | // Set time stamp of file or directory 235 | 236 | bool FatFsClass::timeStamp( const char * path, uint16_t year, uint8_t month, uint8_t day, 237 | uint8_t hour, uint8_t minute, uint8_t second ) 238 | { 239 | FILINFO finfo; 240 | 241 | finfo.fdate = ( year - 1980 ) << 9 | month << 5 | day; 242 | finfo.ftime = hour << 11 | minute << 5 | second >> 1; 243 | ffs_result = f_utime( path, & finfo ); 244 | return ffs_result == FR_OK; 245 | } 246 | 247 | // Return date and time of last modification 248 | 249 | bool FatFsClass::getFileModTime( const char * path, uint16_t * pdate, uint16_t * ptime ) 250 | { 251 | FILINFO finfo; 252 | 253 | if( f_stat( path, & finfo ) != FR_OK ) 254 | return false; 255 | * pdate = finfo.fdate; 256 | * ptime = finfo.ftime; 257 | return true; 258 | } 259 | 260 | /* =========================================================== 261 | 262 | DirFs functions 263 | 264 | =========================================================== */ 265 | 266 | // Open a directory 267 | // dirPath : absolute name of directory 268 | // Return true if ok 269 | 270 | bool DirFs::open( char * dirPath ) 271 | { 272 | ffs_result = f_opendir( & dir, dirPath ); 273 | return ffs_result == FR_OK; 274 | } 275 | 276 | // Close the open directory 277 | 278 | bool DirFs::close() 279 | { 280 | ffs_result = f_closedir( & dir ); 281 | return ffs_result == FR_OK; 282 | } 283 | 284 | // Read next directory entry 285 | // Return false if end of directory is reached or an error had occurred 286 | 287 | bool DirFs::nextFile() 288 | { 289 | ffs_result = f_readdir( & dir, & finfo ); 290 | return ffs_result == FR_OK && finfo.fname[0] != 0; 291 | } 292 | 293 | // Rewind the read index 294 | 295 | bool DirFs::rewind() 296 | { 297 | ffs_result = f_readdir ( & dir, NULL ); 298 | return ffs_result == FR_OK; 299 | } 300 | 301 | // Return true if the pointed entry is a directory 302 | 303 | bool DirFs::isDir() 304 | { 305 | return finfo.fattrib & AM_DIR; 306 | } 307 | 308 | // Return a pointer to a string containing the name of the pointed entry 309 | 310 | char * DirFs::fileName() 311 | { 312 | return finfo.fname; 313 | } 314 | 315 | // Return the size of the pointed entry 316 | 317 | uint32_t DirFs::fileSize() 318 | { 319 | return finfo.fsize; 320 | } 321 | 322 | // Return date of last modification 323 | 324 | uint16_t DirFs::fileModDate() 325 | { 326 | return finfo.fdate; 327 | } 328 | 329 | // Return time of last modification 330 | 331 | uint16_t DirFs::fileModTime() 332 | { 333 | return finfo.ftime; 334 | } 335 | 336 | /* =========================================================== 337 | 338 | FileFs functions 339 | 340 | =========================================================== */ 341 | 342 | // Open a file 343 | // fileName : absolute name of the file to open 344 | // mode : specifies the type of access and open method for the file 345 | // (see ff.h for a description of possible values) 346 | // Return true if ok 347 | 348 | bool FileFs::open( char * fileName, uint8_t mode ) 349 | { 350 | ffs_result = f_open( & ffile, fileName, mode ); 351 | return ffs_result == FR_OK; 352 | } 353 | 354 | // Close the file 355 | // Return true if ok 356 | 357 | bool FileFs::close() 358 | { 359 | ffs_result = f_close( & ffile ); 360 | return ffs_result == FR_OK; 361 | } 362 | 363 | // Writes data to the file 364 | // buf : pointer to the data to be written 365 | // lbuf : number of bytes to write 366 | // Return number of bytes written 367 | 368 | uint32_t FileFs::write( void * buf, uint32_t lbuf ) 369 | { 370 | uint32_t lb, nwrt0, nwrt = 0; 371 | 372 | ffs_result = FR_OK; 373 | while( nwrt < lbuf && ffs_result == FR_OK ) 374 | { 375 | nwrt0 = 0; 376 | lb = lbuf - nwrt; 377 | if( lb > FF_MIN_SS ) 378 | lb = FF_MIN_SS; 379 | ffs_result = f_write( & ffile, ( buf + nwrt ), lb, (UINT*) & nwrt0 ); 380 | nwrt += nwrt0; 381 | } 382 | return nwrt; 383 | } 384 | 385 | // Write a string to the file 386 | // str : string to write 387 | // Return number of characters written or -1 if an error occurs 388 | 389 | int FileFs::writeString( char * str ) 390 | { 391 | return f_puts( str, & ffile ); 392 | } 393 | 394 | // Write a character to the file 395 | // car : character to write 396 | // Return true if ok 397 | 398 | bool FileFs::writeChar( char car ) 399 | { 400 | return f_putc( car, & ffile ) == 1; 401 | } 402 | 403 | // Read data from the file 404 | // buf : pointer to buffer where to store read data 405 | // lbuf : number of bytes to read 406 | // Return number of read bytes 407 | 408 | uint32_t FileFs::read( void * buf, uint32_t lbuf ) 409 | { 410 | uint32_t lb, nrd0, nrd; 411 | 412 | nrd = 0; 413 | do 414 | { 415 | nrd0 = 0; 416 | lb = lbuf - nrd; 417 | if( lb > FF_MIN_SS ) 418 | lb = FF_MIN_SS; 419 | ffs_result = f_read( & ffile, ( buf + nrd ), lb, (UINT*) & nrd0 ); 420 | nrd += nrd0; 421 | } 422 | while( nrd0 > 0 && nrd < lbuf && ffs_result == FR_OK ); 423 | return nrd; 424 | } 425 | 426 | // Read a string from the file 427 | // str : read buffer 428 | // len : size of read buffer 429 | // Return number of characters read or -1 if an error occurs 430 | 431 | int16_t FileFs::readString( char * str, int len ) 432 | { 433 | str = f_gets( str, len, & ffile ); 434 | if( str == NULL ) 435 | return -1; 436 | uint16_t lstr = strlen( str ) - 1; 437 | while( lstr > 0 && ( str[ lstr ] == '\n' || str[ lstr ] == '\r' )) 438 | str[ lstr -- ] = 0; 439 | return lstr; 440 | } 441 | 442 | // Read a character from the file 443 | // Return read char or -1 if an error occurs 444 | // In case of -1 returned, must call FatFs.error() to know 445 | // if this is an error or null character 446 | 447 | char FileFs::readChar() 448 | { 449 | char car; 450 | uint32_t nrd; 451 | 452 | ffs_result = f_read( & ffile, & car, 1, (UINT*) & nrd ); 453 | return nrd == 1 ? car : -1; 454 | } 455 | 456 | // Read next literal integer from file 457 | // Return value of integer 458 | // You must call FatFs.error() to know if an error has occurred 459 | 460 | uint16_t FileFs::readInt() 461 | { 462 | uint16_t i = 0; 463 | char c; 464 | // skip characters they are not integer 465 | do 466 | c = readChar(); 467 | while( c != -1 && ! isdigit( c )); 468 | while( isdigit( c )) 469 | { 470 | i = 10 * i + c - '0'; 471 | c = readChar(); 472 | } 473 | return i; 474 | } 475 | 476 | // Read next literal hexadecinal integer from file 477 | // Return value of integer 478 | // You must call FatFs.error() to know if an error has occurred 479 | 480 | uint16_t FileFs::readHex() 481 | { 482 | uint16_t i = 0; 483 | char c; 484 | // skip characters they are not hexadecimal 485 | do 486 | c = readChar(); 487 | while( c != -1 && ! isxdigit( c )); 488 | while( isxdigit( c )) 489 | { 490 | i = 16 * i + c; 491 | if( isdigit( c )) 492 | i -= '0'; 493 | else 494 | { 495 | i += 10; 496 | if( c < 'F' ) 497 | i -= 'A'; 498 | else 499 | i -= 'a'; 500 | } 501 | c = readChar(); 502 | } 503 | return i; 504 | } 505 | 506 | // Return the current read/write pointer of a file 507 | 508 | uint32_t FileFs::curPosition() 509 | { 510 | return f_tell( & ffile ); 511 | } 512 | 513 | // Moves the file read/write pointer 514 | // cur : new file pointer value 515 | // Return if ok 516 | // In case cur is greater than file size and file is opened in write mode, 517 | // size of file is expanded 518 | 519 | bool FileFs::seekSet( uint32_t cur ) 520 | { 521 | ffs_result = f_lseek( & ffile, cur ); 522 | return ffs_result == FR_OK; 523 | } 524 | 525 | // Return size of file 526 | 527 | uint32_t FileFs::fileSize() 528 | { 529 | return f_size( & ffile ); 530 | } 531 | 532 | FatFsClass FatFs; 533 | -------------------------------------------------------------------------------- /FatFs/src/ff.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------/ 2 | / FatFs - Generic FAT Filesystem module R0.14 / 3 | /-----------------------------------------------------------------------------/ 4 | / 5 | / Copyright (C) 2019, ChaN, all right reserved. 6 | / 7 | / FatFs module is an open source software. Redistribution and use of FatFs in 8 | / source and binary forms, with or without modification, are permitted provided 9 | / that the following condition is met: 10 | 11 | / 1. Redistributions of source code must retain the above copyright notice, 12 | / this condition and the following disclaimer. 13 | / 14 | / This software is provided by the copyright holder and contributors "AS IS" 15 | / and any warranties related to this software are DISCLAIMED. 16 | / The copyright owner or contributors be NOT LIABLE for any damages caused 17 | / by use of this software. 18 | / 19 | /----------------------------------------------------------------------------*/ 20 | 21 | 22 | #ifndef FF_DEFINED 23 | #define FF_DEFINED 86606 /* Revision ID */ 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #include "ffconf.h" /* FatFs configuration options */ 30 | 31 | #if FF_DEFINED != FFCONF_DEF 32 | #error Wrong configuration file (ffconf.h). 33 | #endif 34 | 35 | 36 | /* Integer types used for FatFs API */ 37 | 38 | #if defined(_WIN32) /* Main development platform */ 39 | #define FF_INTDEF 2 40 | #include 41 | typedef unsigned __int64 QWORD; 42 | #elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */ 43 | #define FF_INTDEF 2 44 | #include 45 | typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ 46 | typedef unsigned char BYTE; /* char must be 8-bit */ 47 | typedef uint16_t WORD; /* 16-bit unsigned integer */ 48 | typedef uint32_t DWORD; /* 32-bit unsigned integer */ 49 | typedef uint64_t QWORD; /* 64-bit unsigned integer */ 50 | typedef WORD WCHAR; /* UTF-16 character type */ 51 | #else /* Earlier than C99 */ 52 | #define FF_INTDEF 1 53 | typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ 54 | typedef unsigned char BYTE; /* char must be 8-bit */ 55 | typedef unsigned short WORD; /* 16-bit unsigned integer */ 56 | typedef unsigned long DWORD; /* 32-bit unsigned integer */ 57 | typedef WORD WCHAR; /* UTF-16 character type */ 58 | #endif 59 | 60 | 61 | /* Definitions of volume management */ 62 | 63 | #if FF_MULTI_PARTITION /* Multiple partition configuration */ 64 | typedef struct { 65 | BYTE pd; /* Physical drive number */ 66 | BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */ 67 | } PARTITION; 68 | extern PARTITION VolToPart[]; /* Volume - Partition mapping table */ 69 | #endif 70 | 71 | #if FF_STR_VOLUME_ID 72 | #ifndef FF_VOLUME_STRS 73 | extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */ 74 | #endif 75 | #endif 76 | 77 | 78 | 79 | /* Type of path name strings on FatFs API */ 80 | 81 | #ifndef _INC_TCHAR 82 | #define _INC_TCHAR 83 | 84 | #if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */ 85 | typedef WCHAR TCHAR; 86 | #define _T(x) L ## x 87 | #define _TEXT(x) L ## x 88 | #elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */ 89 | typedef char TCHAR; 90 | #define _T(x) u8 ## x 91 | #define _TEXT(x) u8 ## x 92 | #elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */ 93 | typedef DWORD TCHAR; 94 | #define _T(x) U ## x 95 | #define _TEXT(x) U ## x 96 | #elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3) 97 | #error Wrong FF_LFN_UNICODE setting 98 | #else /* ANSI/OEM code in SBCS/DBCS */ 99 | typedef char TCHAR; 100 | #define _T(x) x 101 | #define _TEXT(x) x 102 | #endif 103 | 104 | #endif 105 | 106 | 107 | 108 | /* Type of file size and LBA variables */ 109 | 110 | #if FF_FS_EXFAT 111 | #if FF_INTDEF != 2 112 | #error exFAT feature wants C99 or later 113 | #endif 114 | typedef QWORD FSIZE_t; 115 | #if FF_LBA64 116 | typedef QWORD LBA_t; 117 | #else 118 | typedef DWORD LBA_t; 119 | #endif 120 | #else 121 | #if FF_LBA64 122 | #error exFAT needs to be enabled when enable 64-bit LBA 123 | #endif 124 | typedef DWORD FSIZE_t; 125 | typedef DWORD LBA_t; 126 | #endif 127 | 128 | 129 | 130 | /* Filesystem object structure (FATFS) */ 131 | 132 | typedef struct { 133 | BYTE fs_type; /* Filesystem type (0:not mounted) */ 134 | BYTE pdrv; /* Associated physical drive */ 135 | BYTE n_fats; /* Number of FATs (1 or 2) */ 136 | BYTE wflag; /* win[] flag (b0:dirty) */ 137 | BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */ 138 | WORD id; /* Volume mount ID */ 139 | WORD n_rootdir; /* Number of root directory entries (FAT12/16) */ 140 | WORD csize; /* Cluster size [sectors] */ 141 | #if FF_MAX_SS != FF_MIN_SS 142 | WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */ 143 | #endif 144 | #if FF_USE_LFN 145 | WCHAR* lfnbuf; /* LFN working buffer */ 146 | #endif 147 | #if FF_FS_EXFAT 148 | BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */ 149 | #endif 150 | #if FF_FS_REENTRANT 151 | FF_SYNC_t sobj; /* Identifier of sync object */ 152 | #endif 153 | #if !FF_FS_READONLY 154 | DWORD last_clst; /* Last allocated cluster */ 155 | DWORD free_clst; /* Number of free clusters */ 156 | #endif 157 | #if FF_FS_RPATH 158 | DWORD cdir; /* Current directory start cluster (0:root) */ 159 | #if FF_FS_EXFAT 160 | DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */ 161 | DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */ 162 | DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */ 163 | #endif 164 | #endif 165 | DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */ 166 | DWORD fsize; /* Size of an FAT [sectors] */ 167 | LBA_t volbase; /* Volume base sector */ 168 | LBA_t fatbase; /* FAT base sector */ 169 | LBA_t dirbase; /* Root directory base sector/cluster */ 170 | LBA_t database; /* Data base sector */ 171 | #if FF_FS_EXFAT 172 | LBA_t bitbase; /* Allocation bitmap base sector */ 173 | #endif 174 | LBA_t winsect; /* Current sector appearing in the win[] */ 175 | BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */ 176 | } FATFS; 177 | 178 | 179 | 180 | /* Object ID and allocation information (FFOBJID) */ 181 | 182 | typedef struct { 183 | FATFS* fs; /* Pointer to the hosting volume of this object */ 184 | WORD id; /* Hosting volume mount ID */ 185 | BYTE attr; /* Object attribute */ 186 | BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */ 187 | DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */ 188 | FSIZE_t objsize; /* Object size (valid when sclust != 0) */ 189 | #if FF_FS_EXFAT 190 | DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */ 191 | DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */ 192 | DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */ 193 | DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */ 194 | DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */ 195 | #endif 196 | #if FF_FS_LOCK 197 | UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */ 198 | #endif 199 | } FFOBJID; 200 | 201 | 202 | 203 | /* File object structure (FIL) */ 204 | 205 | typedef struct { 206 | FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */ 207 | BYTE flag; /* File status flags */ 208 | BYTE err; /* Abort flag (error code) */ 209 | FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */ 210 | DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */ 211 | LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */ 212 | #if !FF_FS_READONLY 213 | LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */ 214 | BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */ 215 | #endif 216 | #if FF_USE_FASTSEEK 217 | DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */ 218 | #endif 219 | #if !FF_FS_TINY 220 | BYTE buf[FF_MAX_SS]; /* File private data read/write window */ 221 | #endif 222 | } FIL; 223 | 224 | 225 | 226 | /* Directory object structure (DIR) */ 227 | 228 | typedef struct { 229 | FFOBJID obj; /* Object identifier */ 230 | DWORD dptr; /* Current read/write offset */ 231 | DWORD clust; /* Current cluster */ 232 | LBA_t sect; /* Current sector (0:Read operation has terminated) */ 233 | BYTE* dir; /* Pointer to the directory item in the win[] */ 234 | BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */ 235 | #if FF_USE_LFN 236 | DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */ 237 | #endif 238 | #if FF_USE_FIND 239 | const TCHAR* pat; /* Pointer to the name matching pattern */ 240 | #endif 241 | } DIR; 242 | 243 | 244 | 245 | /* File information structure (FILINFO) */ 246 | 247 | typedef struct { 248 | FSIZE_t fsize; /* File size */ 249 | WORD fdate; /* Modified date */ 250 | WORD ftime; /* Modified time */ 251 | BYTE fattrib; /* File attribute */ 252 | #if FF_USE_LFN 253 | TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */ 254 | TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */ 255 | #else 256 | TCHAR fname[12 + 1]; /* File name */ 257 | #endif 258 | } FILINFO; 259 | 260 | 261 | 262 | /* Format parameter structure (MKFS_PARM) */ 263 | 264 | typedef struct { 265 | BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */ 266 | BYTE n_fat; /* Number of FATs */ 267 | UINT align; /* Data area alignment (sector) */ 268 | UINT n_root; /* Number of root directory entries */ 269 | DWORD au_size; /* Cluster size (byte) */ 270 | } MKFS_PARM; 271 | 272 | 273 | 274 | /* File function return code (FRESULT) */ 275 | 276 | typedef enum { 277 | FR_OK = 0, /* (0) Succeeded */ 278 | FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */ 279 | FR_INT_ERR, /* (2) Assertion failed */ 280 | FR_NOT_READY, /* (3) The physical drive cannot work */ 281 | FR_NO_FILE, /* (4) Could not find the file */ 282 | FR_NO_PATH, /* (5) Could not find the path */ 283 | FR_INVALID_NAME, /* (6) The path name format is invalid */ 284 | FR_DENIED, /* (7) Access denied due to prohibited access or directory full */ 285 | FR_EXIST, /* (8) Access denied due to prohibited access */ 286 | FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */ 287 | FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */ 288 | FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */ 289 | FR_NOT_ENABLED, /* (12) The volume has no work area */ 290 | FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */ 291 | FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */ 292 | FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */ 293 | FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */ 294 | FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */ 295 | FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */ 296 | FR_INVALID_PARAMETER /* (19) Given parameter is invalid */ 297 | } FRESULT; 298 | 299 | 300 | 301 | /*--------------------------------------------------------------*/ 302 | /* FatFs module application interface */ 303 | 304 | FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */ 305 | FRESULT f_close (FIL* fp); /* Close an open file object */ 306 | FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */ 307 | FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */ 308 | FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */ 309 | FRESULT f_truncate (FIL* fp); /* Truncate the file */ 310 | FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */ 311 | FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */ 312 | FRESULT f_closedir (DIR* dp); /* Close an open directory */ 313 | FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */ 314 | FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */ 315 | FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */ 316 | FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */ 317 | FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */ 318 | FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */ 319 | FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */ 320 | FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */ 321 | FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */ 322 | FRESULT f_chdir (const TCHAR* path); /* Change current directory */ 323 | FRESULT f_chdrive (const TCHAR* path); /* Change current drive */ 324 | FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */ 325 | FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */ 326 | FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */ 327 | FRESULT f_setlabel (const TCHAR* label); /* Set volume label */ 328 | FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */ 329 | FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */ 330 | FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */ 331 | FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */ 332 | FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */ 333 | FRESULT f_setcp (WORD cp); /* Set current code page */ 334 | int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */ 335 | int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */ 336 | int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */ 337 | TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */ 338 | 339 | #define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize)) 340 | #define f_error(fp) ((fp)->err) 341 | #define f_tell(fp) ((fp)->fptr) 342 | #define f_size(fp) ((fp)->obj.objsize) 343 | #define f_rewind(fp) f_lseek((fp), 0) 344 | #define f_rewinddir(dp) f_readdir((dp), 0) 345 | #define f_rmdir(path) f_unlink(path) 346 | #define f_unmount(path) f_mount(0, path, 0) 347 | 348 | #ifndef EOF 349 | #define EOF (-1) 350 | #endif 351 | 352 | 353 | 354 | 355 | /*--------------------------------------------------------------*/ 356 | /* Additional user defined functions */ 357 | 358 | /* RTC function */ 359 | #if !FF_FS_READONLY && !FF_FS_NORTC 360 | DWORD get_fattime (void); 361 | #endif 362 | 363 | /* LFN support functions */ 364 | #if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */ 365 | WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */ 366 | WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */ 367 | DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */ 368 | #endif 369 | #if FF_USE_LFN == 3 /* Dynamic memory allocation */ 370 | void* ff_memalloc (UINT msize); /* Allocate memory block */ 371 | void ff_memfree (void* mblock); /* Free memory block */ 372 | #endif 373 | 374 | /* Sync functions */ 375 | #if FF_FS_REENTRANT 376 | int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */ 377 | int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */ 378 | void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */ 379 | int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */ 380 | #endif 381 | 382 | 383 | 384 | 385 | /*--------------------------------------------------------------*/ 386 | /* Flags and offset address */ 387 | 388 | 389 | /* File access mode and open method flags (3rd argument of f_open) */ 390 | #define FA_READ 0x01 391 | #define FA_WRITE 0x02 392 | #define FA_OPEN_EXISTING 0x00 393 | #define FA_CREATE_NEW 0x04 394 | #define FA_CREATE_ALWAYS 0x08 395 | #define FA_OPEN_ALWAYS 0x10 396 | #define FA_OPEN_APPEND 0x30 397 | 398 | /* Fast seek controls (2nd argument of f_lseek) */ 399 | #define CREATE_LINKMAP ((FSIZE_t)0 - 1) 400 | 401 | /* Format options (2nd argument of f_mkfs) */ 402 | #define FM_FAT 0x01 403 | #define FM_FAT32 0x02 404 | #define FM_EXFAT 0x04 405 | #define FM_ANY 0x07 406 | #define FM_SFD 0x08 407 | 408 | /* Filesystem type (FATFS.fs_type) */ 409 | #define FS_FAT12 1 410 | #define FS_FAT16 2 411 | #define FS_FAT32 3 412 | #define FS_EXFAT 4 413 | 414 | /* File attribute bits for directory entry (FILINFO.fattrib) */ 415 | #define AM_RDO 0x01 /* Read only */ 416 | #define AM_HID 0x02 /* Hidden */ 417 | #define AM_SYS 0x04 /* System */ 418 | #define AM_DIR 0x10 /* Directory */ 419 | #define AM_ARC 0x20 /* Archive */ 420 | 421 | 422 | #ifdef __cplusplus 423 | } 424 | #endif 425 | 426 | #endif /* FF_DEFINED */ 427 | --------------------------------------------------------------------------------