1 /**
2  * @file lv_fs.h
3  *
4  */
5 
6 #ifndef LV_FS_H
7 #define LV_FS_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../lv_conf_internal.h"
17 
18 #include <stdint.h>
19 #include <stdbool.h>
20 
21 /*********************
22  *      DEFINES
23  *********************/
24 #define LV_FS_MAX_FN_LENGTH 64
25 #define LV_FS_MAX_PATH_LENGTH 256
26 
27 /**********************
28  *      TYPEDEFS
29  **********************/
30 
31 /**
32  * Errors in the file system module.
33  */
34 enum {
35     LV_FS_RES_OK = 0,
36     LV_FS_RES_HW_ERR,     /*Low level hardware error*/
37     LV_FS_RES_FS_ERR,     /*Error in the file system structure*/
38     LV_FS_RES_NOT_EX,     /*Driver, file or directory is not exists*/
39     LV_FS_RES_FULL,       /*Disk full*/
40     LV_FS_RES_LOCKED,     /*The file is already opened*/
41     LV_FS_RES_DENIED,     /*Access denied. Check 'fs_open' modes and write protect*/
42     LV_FS_RES_BUSY,       /*The file system now can't handle it, try later*/
43     LV_FS_RES_TOUT,       /*Process time outed*/
44     LV_FS_RES_NOT_IMP,    /*Requested function is not implemented*/
45     LV_FS_RES_OUT_OF_MEM, /*Not enough memory for an internal operation*/
46     LV_FS_RES_INV_PARAM,  /*Invalid parameter among arguments*/
47     LV_FS_RES_UNKNOWN,    /*Other unknown error*/
48 };
49 typedef uint8_t lv_fs_res_t;
50 
51 /**
52  * File open mode.
53  */
54 enum {
55     LV_FS_MODE_WR = 0x01,
56     LV_FS_MODE_RD = 0x02,
57 };
58 typedef uint8_t lv_fs_mode_t;
59 
60 /**
61  * Seek modes.
62  */
63 typedef enum {
64     LV_FS_SEEK_SET = 0x00,      /**< Set the position from absolutely (from the start of file)*/
65     LV_FS_SEEK_CUR = 0x01,      /**< Set the position from the current position*/
66     LV_FS_SEEK_END = 0x02,      /**< Set the position from the end of the file*/
67 } lv_fs_whence_t;
68 
69 typedef struct _lv_fs_drv_t {
70     char letter;
71     uint16_t cache_size;
72     bool (*ready_cb)(struct _lv_fs_drv_t * drv);
73 
74     void * (*open_cb)(struct _lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
75     lv_fs_res_t (*close_cb)(struct _lv_fs_drv_t * drv, void * file_p);
76     lv_fs_res_t (*read_cb)(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
77     lv_fs_res_t (*write_cb)(struct _lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
78     lv_fs_res_t (*seek_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
79     lv_fs_res_t (*tell_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
80 
81     void * (*dir_open_cb)(struct _lv_fs_drv_t * drv, const char * path);
82     lv_fs_res_t (*dir_read_cb)(struct _lv_fs_drv_t * drv, void * rddir_p, char * fn);
83     lv_fs_res_t (*dir_close_cb)(struct _lv_fs_drv_t * drv, void * rddir_p);
84 
85 #if LV_USE_USER_DATA
86     void * user_data; /**< Custom file user data*/
87 #endif
88 } lv_fs_drv_t;
89 
90 typedef struct {
91     uint32_t start;
92     uint32_t end;
93     uint32_t file_position;
94     void * buffer;
95 } lv_fs_file_cache_t;
96 
97 typedef struct {
98     void * file_d;
99     lv_fs_drv_t * drv;
100     lv_fs_file_cache_t * cache;
101 } lv_fs_file_t;
102 
103 typedef struct {
104     void * dir_d;
105     lv_fs_drv_t * drv;
106 } lv_fs_dir_t;
107 
108 /**********************
109  * GLOBAL PROTOTYPES
110  **********************/
111 
112 /**
113  * Initialize the File system interface
114  */
115 void _lv_fs_init(void);
116 
117 /**
118  * Initialize a file system driver with default values.
119  * It is used to surly have known values in the fields ant not memory junk.
120  * After it you can set the fields.
121  * @param drv     pointer to driver variable to initialize
122  */
123 void lv_fs_drv_init(lv_fs_drv_t * drv);
124 
125 /**
126  * Add a new drive
127  * @param drv       pointer to an lv_fs_drv_t structure which is inited with the
128  *                  corresponding function pointers. Only pointer is saved, so the
129  *                  driver should be static or dynamically allocated.
130  */
131 void lv_fs_drv_register(lv_fs_drv_t * drv);
132 
133 /**
134  * Give a pointer to a driver from its letter
135  * @param letter    the driver letter
136  * @return          pointer to a driver or NULL if not found
137  */
138 lv_fs_drv_t * lv_fs_get_drv(char letter);
139 
140 /**
141  * Test if a drive is ready or not. If the `ready` function was not initialized `true` will be
142  * returned.
143  * @param letter    letter of the drive
144  * @return          true: drive is ready; false: drive is not ready
145  */
146 bool lv_fs_is_ready(char letter);
147 
148 /**
149  * Open a file
150  * @param file_p    pointer to a lv_fs_file_t variable
151  * @param path      path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
152  * @param mode      read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
153  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
154  */
155 lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode);
156 
157 /**
158  * Close an already opened file
159  * @param file_p    pointer to a lv_fs_file_t variable
160  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
161  */
162 lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p);
163 
164 /**
165  * Read from a file
166  * @param file_p    pointer to a lv_fs_file_t variable
167  * @param buf       pointer to a buffer where the read bytes are stored
168  * @param btr       Bytes To Read
169  * @param br        the number of real read bytes (Bytes Read). NULL if unused.
170  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
171  */
172 lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
173 
174 /**
175  * Write into a file
176  * @param file_p    pointer to a lv_fs_file_t variable
177  * @param buf       pointer to a buffer with the bytes to write
178  * @param btw       Bytes To Write
179  * @param bw        the number of real written bytes (Bytes Written). NULL if unused.
180  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
181  */
182 lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
183 
184 /**
185  * Set the position of the 'cursor' (read write pointer) in a file
186  * @param file_p    pointer to a lv_fs_file_t variable
187  * @param pos       the new position expressed in bytes index (0: start of file)
188  * @param whence    tells from where set the position. See @lv_fs_whence_t
189  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
190  */
191 lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence);
192 
193 /**
194  * Give the position of the read write pointer
195  * @param file_p    pointer to a lv_fs_file_t variable
196  * @param pos_p     pointer to store the position of the read write pointer
197  * @return          LV_FS_RES_OK or any error from 'fs_res_t'
198  */
199 lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos);
200 
201 /**
202  * Initialize a 'fs_dir_t' variable for directory reading
203  * @param rddir_p   pointer to a 'lv_fs_dir_t' variable
204  * @param path      path to a directory
205  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
206  */
207 lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path);
208 
209 /**
210  * Read the next filename form a directory.
211  * The name of the directories will begin with '/'
212  * @param rddir_p   pointer to an initialized 'fs_dir_t' variable
213  * @param fn        pointer to a buffer to store the filename
214  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
215  */
216 lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn);
217 
218 /**
219  * Close the directory reading
220  * @param rddir_p   pointer to an initialized 'fs_dir_t' variable
221  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
222  */
223 lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p);
224 
225 /**
226  * Fill a buffer with the letters of existing drivers
227  * @param buf       buffer to store the letters ('\0' added after the last letter)
228  * @return          the buffer
229  */
230 char * lv_fs_get_letters(char * buf);
231 
232 /**
233  * Return with the extension of the filename
234  * @param fn        string with a filename
235  * @return          pointer to the beginning extension or empty string if no extension
236  */
237 const char * lv_fs_get_ext(const char * fn);
238 
239 /**
240  * Step up one level
241  * @param path      pointer to a file name
242  * @return          the truncated file name
243  */
244 char * lv_fs_up(char * path);
245 
246 /**
247  * Get the last element of a path (e.g. U:/folder/file -> file)
248  * @param path      pointer to a file name
249  * @return          pointer to the beginning of the last element in the path
250  */
251 const char * lv_fs_get_last(const char * path);
252 
253 /**********************
254  *      MACROS
255  **********************/
256 
257 #ifdef __cplusplus
258 } /*extern "C"*/
259 #endif
260 
261 #endif /*LV_FS_H*/
262