1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 #include <stddef.h>
17 #include "esp_err.h"
18 #include "driver/gpio.h"
19 #include "driver/sdmmc_types.h"
20 #include "driver/sdspi_host.h"
21 #include "ff.h"
22 #include "wear_levelling.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /**
29  * @brief Register FATFS with VFS component
30  *
31  * This function registers given FAT drive in VFS, at the specified base path.
32  * If only one drive is used, fat_drive argument can be an empty string.
33  * Refer to FATFS library documentation on how to specify FAT drive.
34  * This function also allocates FATFS structure which should be used for f_mount
35  * call.
36  *
37  * @note This function doesn't mount the drive into FATFS, it just connects
38  *       POSIX and C standard library IO function with FATFS. You need to mount
39  *       desired drive into FATFS separately.
40  *
41  * @param base_path  path prefix where FATFS should be registered
42  * @param fat_drive  FATFS drive specification; if only one drive is used, can be an empty string
43  * @param max_files  maximum number of files which can be open at the same time
44  * @param[out] out_fs  pointer to FATFS structure which can be used for FATFS f_mount call is returned via this argument.
45  * @return
46  *      - ESP_OK on success
47  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_register was already called
48  *      - ESP_ERR_NO_MEM if not enough memory or too many VFSes already registered
49  */
50 esp_err_t esp_vfs_fat_register(const char* base_path, const char* fat_drive,
51         size_t max_files, FATFS** out_fs);
52 
53 /**
54  * @brief Un-register FATFS from VFS
55  *
56  * @note FATFS structure returned by esp_vfs_fat_register is destroyed after
57  *       this call. Make sure to call f_mount function to unmount it before
58  *       calling esp_vfs_fat_unregister_ctx.
59  *       Difference between this function and the one above is that this one
60  *       will release the correct drive, while the one above will release
61  *       the last registered one
62  *
63  * @param base_path     path prefix where FATFS is registered. This is the same
64  *                      used when esp_vfs_fat_register was called
65  * @return
66  *      - ESP_OK on success
67  *      - ESP_ERR_INVALID_STATE if FATFS is not registered in VFS
68  */
69 esp_err_t esp_vfs_fat_unregister_path(const char* base_path);
70 
71 
72 /**
73  * @brief Configuration arguments for esp_vfs_fat_sdmmc_mount and esp_vfs_fat_spiflash_mount functions
74  */
75 typedef struct {
76     /**
77      * If FAT partition can not be mounted, and this parameter is true,
78      * create partition table and format the filesystem.
79      */
80     bool format_if_mount_failed;
81     int max_files;                  ///< Max number of open files
82     /**
83      * If format_if_mount_failed is set, and mount fails, format the card
84      * with given allocation unit size. Must be a power of 2, between sector
85      * size and 128 * sector size.
86      * For SD cards, sector size is always 512 bytes. For wear_levelling,
87      * sector size is determined by CONFIG_WL_SECTOR_SIZE option.
88      *
89      * Using larger allocation unit size will result in higher read/write
90      * performance and higher overhead when storing small files.
91      *
92      * Setting this field to 0 will result in allocation unit set to the
93      * sector size.
94      */
95     size_t allocation_unit_size;
96 } esp_vfs_fat_mount_config_t;
97 
98 // Compatibility definition
99 typedef esp_vfs_fat_mount_config_t esp_vfs_fat_sdmmc_mount_config_t;
100 
101 /**
102  * @brief Convenience function to get FAT filesystem on SD card registered in VFS
103  *
104  * This is an all-in-one function which does the following:
105  * - initializes SDMMC driver or SPI driver with configuration in host_config
106  * - initializes SD card with configuration in slot_config
107  * - mounts FAT partition on SD card using FATFS library, with configuration in mount_config
108  * - registers FATFS library with VFS, with prefix given by base_prefix variable
109  *
110  * This function is intended to make example code more compact.
111  * For real world applications, developers should implement the logic of
112  * probing SD card, locating and mounting partition, and registering FATFS in VFS,
113  * with proper error checking and handling of exceptional conditions.
114  *
115  * @note Use this API to mount a card through SDSPI is deprecated. Please call
116  *       `esp_vfs_fat_sdspi_mount()` instead for that case.
117  *
118  * @param base_path     path where partition should be registered (e.g. "/sdcard")
119  * @param host_config   Pointer to structure describing SDMMC host. When using
120  *                      SDMMC peripheral, this structure can be initialized using
121  *                      SDMMC_HOST_DEFAULT() macro. When using SPI peripheral,
122  *                      this structure can be initialized using SDSPI_HOST_DEFAULT()
123  *                      macro.
124  * @param slot_config   Pointer to structure with slot configuration.
125  *                      For SDMMC peripheral, pass a pointer to sdmmc_slot_config_t
126  *                      structure initialized using SDMMC_SLOT_CONFIG_DEFAULT.
127  *                      (Deprecated) For SPI peripheral, pass a pointer to sdspi_slot_config_t
128  *                      structure initialized using SDSPI_SLOT_CONFIG_DEFAULT().
129  * @param mount_config  pointer to structure with extra parameters for mounting FATFS
130  * @param[out] out_card  if not NULL, pointer to the card information structure will be returned via this argument
131  * @return
132  *      - ESP_OK on success
133  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called
134  *      - ESP_ERR_NO_MEM if memory can not be allocated
135  *      - ESP_FAIL if partition can not be mounted
136  *      - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers
137  */
138 esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
139     const sdmmc_host_t* host_config,
140     const void* slot_config,
141     const esp_vfs_fat_mount_config_t* mount_config,
142     sdmmc_card_t** out_card);
143 
144 /**
145  * @brief Convenience function to get FAT filesystem on SD card registered in VFS
146  *
147  * This is an all-in-one function which does the following:
148  * - initializes an SPI Master device based on the SPI Master driver with configuration in
149  *   slot_config, and attach it to an initialized SPI bus.
150  * - initializes SD card with configuration in host_config_input
151  * - mounts FAT partition on SD card using FATFS library, with configuration in mount_config
152  * - registers FATFS library with VFS, with prefix given by base_prefix variable
153  *
154  * This function is intended to make example code more compact.
155  * For real world applications, developers should implement the logic of
156  * probing SD card, locating and mounting partition, and registering FATFS in VFS,
157  * with proper error checking and handling of exceptional conditions.
158  *
159  * @note This function try to attach the new SD SPI device to the bus specified in host_config.
160  *       Make sure the SPI bus specified in `host_config->slot` have been initialized by
161  *       `spi_bus_initialize()` before.
162  *
163  * @param base_path     path where partition should be registered (e.g. "/sdcard")
164  * @param host_config_input Pointer to structure describing SDMMC host. This structure can be
165  *                          initialized using SDSPI_HOST_DEFAULT() macro.
166  * @param slot_config   Pointer to structure with slot configuration.
167  *                      For SPI peripheral, pass a pointer to sdspi_device_config_t
168  *                      structure initialized using SDSPI_DEVICE_CONFIG_DEFAULT().
169  * @param mount_config  pointer to structure with extra parameters for mounting FATFS
170  * @param[out] out_card If not NULL, pointer to the card information structure will be returned via
171  *                      this argument. It is suggested to hold this handle and use it to unmount the card later if
172  *                      needed. Otherwise it's not suggested to use more than one card at the same time and unmount one
173  *                      of them in your application.
174  * @return
175  *      - ESP_OK on success
176  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called
177  *      - ESP_ERR_NO_MEM if memory can not be allocated
178  *      - ESP_FAIL if partition can not be mounted
179  *      - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers
180  */
181 esp_err_t esp_vfs_fat_sdspi_mount(const char* base_path,
182                                   const sdmmc_host_t* host_config_input,
183                                   const sdspi_device_config_t* slot_config,
184                                   const esp_vfs_fat_mount_config_t* mount_config,
185                                   sdmmc_card_t** out_card);
186 
187 /**
188  * @brief Unmount FAT filesystem and release resources acquired using esp_vfs_fat_sdmmc_mount
189  *
190  * @deprecated Use `esp_vfs_fat_sdcard_unmount()` instead.
191  *
192  * @return
193  *      - ESP_OK on success
194  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount hasn't been called
195  */
196 esp_err_t esp_vfs_fat_sdmmc_unmount(void);
197 
198 /**
199  * @brief Unmount an SD card from the FAT filesystem and release resources acquired using
200  *        `esp_vfs_fat_sdmmc_mount()` or `esp_vfs_fat_sdspi_mount()`
201  *
202  * @return
203  *      - ESP_OK on success
204  *      - ESP_ERR_INVALID_ARG if the card argument is unregistered
205  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount hasn't been called
206  */
207 esp_err_t esp_vfs_fat_sdcard_unmount(const char *base_path, sdmmc_card_t *card);
208 
209 /**
210  * @brief Convenience function to initialize FAT filesystem in SPI flash and register it in VFS
211  *
212  * This is an all-in-one function which does the following:
213  *
214  * - finds the partition with defined partition_label. Partition label should be
215  *   configured in the partition table.
216  * - initializes flash wear levelling library on top of the given partition
217  * - mounts FAT partition using FATFS library on top of flash wear levelling
218  *   library
219  * - registers FATFS library with VFS, with prefix given by base_prefix variable
220  *
221  * This function is intended to make example code more compact.
222  *
223  * @param base_path        path where FATFS partition should be mounted (e.g. "/spiflash")
224  * @param partition_label  label of the partition which should be used
225  * @param mount_config     pointer to structure with extra parameters for mounting FATFS
226  * @param[out] wl_handle   wear levelling driver handle
227  * @return
228  *      - ESP_OK on success
229  *      - ESP_ERR_NOT_FOUND if the partition table does not contain FATFS partition with given label
230  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_spiflash_mount was already called
231  *      - ESP_ERR_NO_MEM if memory can not be allocated
232  *      - ESP_FAIL if partition can not be mounted
233  *      - other error codes from wear levelling library, SPI flash driver, or FATFS drivers
234  */
235 esp_err_t esp_vfs_fat_spiflash_mount(const char* base_path,
236     const char* partition_label,
237     const esp_vfs_fat_mount_config_t* mount_config,
238     wl_handle_t* wl_handle);
239 
240 /**
241  * @brief Unmount FAT filesystem and release resources acquired using esp_vfs_fat_spiflash_mount
242  *
243  * @param base_path  path where partition should be registered (e.g. "/spiflash")
244  * @param wl_handle  wear levelling driver handle returned by esp_vfs_fat_spiflash_mount
245  *
246  * @return
247  *      - ESP_OK on success
248  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_spiflash_mount hasn't been called
249  */
250  esp_err_t esp_vfs_fat_spiflash_unmount(const char* base_path, wl_handle_t wl_handle);
251 
252 
253 /**
254  * @brief Convenience function to initialize read-only FAT filesystem and register it in VFS
255  *
256  * This is an all-in-one function which does the following:
257  *
258  * - finds the partition with defined partition_label. Partition label should be
259  *   configured in the partition table.
260  * - mounts FAT partition using FATFS library
261  * - registers FATFS library with VFS, with prefix given by base_prefix variable
262  *
263  * @note Wear levelling is not used when FAT is mounted in read-only mode using this function.
264  *
265  * @param base_path        path where FATFS partition should be mounted (e.g. "/spiflash")
266  * @param partition_label  label of the partition which should be used
267  * @param mount_config     pointer to structure with extra parameters for mounting FATFS
268  * @return
269  *      - ESP_OK on success
270  *      - ESP_ERR_NOT_FOUND if the partition table does not contain FATFS partition with given label
271  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_rawflash_mount was already called for the same partition
272  *      - ESP_ERR_NO_MEM if memory can not be allocated
273  *      - ESP_FAIL if partition can not be mounted
274  *      - other error codes from SPI flash driver, or FATFS drivers
275  */
276 esp_err_t esp_vfs_fat_rawflash_mount(const char* base_path,
277     const char* partition_label,
278     const esp_vfs_fat_mount_config_t* mount_config);
279 
280 /**
281  * @brief Unmount FAT filesystem and release resources acquired using esp_vfs_fat_rawflash_mount
282  *
283  * @param base_path  path where partition should be registered (e.g. "/spiflash")
284  * @param partition_label label of partition to be unmounted
285  *
286  * @return
287  *      - ESP_OK on success
288  *      - ESP_ERR_INVALID_STATE if esp_vfs_fat_spiflash_mount hasn't been called
289  */
290  esp_err_t esp_vfs_fat_rawflash_unmount(const char* base_path, const char* partition_label);
291 
292 
293 #ifdef __cplusplus
294 }
295 #endif
296