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 /**
62  * Seek modes.
63  */
64 typedef enum {
65     LV_FS_SEEK_SET = 0x00,      /**< Set the position from absolutely (from the start of file)*/
66     LV_FS_SEEK_CUR = 0x01,      /**< Set the position from the current position*/
67     LV_FS_SEEK_END = 0x02,      /**< Set the position from the end of the file*/
68 } lv_fs_whence_t;
69 
70 typedef struct _lv_fs_drv_t {
71     char letter;
72     uint16_t cache_size;
73     bool (*ready_cb)(struct _lv_fs_drv_t * drv);
74 
75     void * (*open_cb)(struct _lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
76     lv_fs_res_t (*close_cb)(struct _lv_fs_drv_t * drv, void * file_p);
77     lv_fs_res_t (*read_cb)(struct _lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
78     lv_fs_res_t (*write_cb)(struct _lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
79     lv_fs_res_t (*seek_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
80     lv_fs_res_t (*tell_cb)(struct _lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
81 
82     void * (*dir_open_cb)(struct _lv_fs_drv_t * drv, const char * path);
83     lv_fs_res_t (*dir_read_cb)(struct _lv_fs_drv_t * drv, void * rddir_p, char * fn);
84     lv_fs_res_t (*dir_close_cb)(struct _lv_fs_drv_t * drv, void * rddir_p);
85 
86 #if LV_USE_USER_DATA
87     void * user_data; /**< Custom file user data*/
88 #endif
89 } lv_fs_drv_t;
90 
91 typedef struct {
92     uint32_t start;
93     uint32_t end;
94     uint32_t file_position;
95     void * buffer;
96 } lv_fs_file_cache_t;
97 
98 typedef struct {
99     void * file_d;
100     lv_fs_drv_t * drv;
101     lv_fs_file_cache_t * cache;
102 } lv_fs_file_t;
103 
104 typedef struct {
105     void * dir_d;
106     lv_fs_drv_t * drv;
107 } lv_fs_dir_t;
108 
109 /**********************
110  * GLOBAL PROTOTYPES
111  **********************/
112 
113 /**
114  * Initialize the File system interface
115  */
116 void _lv_fs_init(void);
117 
118 /**
119  * Initialize a file system driver with default values.
120  * It is used to surly have known values in the fields ant not memory junk.
121  * After it you can set the fields.
122  * @param drv     pointer to driver variable to initialize
123  */
124 void lv_fs_drv_init(lv_fs_drv_t * drv);
125 
126 /**
127  * Add a new drive
128  * @param drv       pointer to an lv_fs_drv_t structure which is inited with the
129  *                  corresponding function pointers. Only pointer is saved, so the
130  *                  driver should be static or dynamically allocated.
131  */
132 void lv_fs_drv_register(lv_fs_drv_t * drv);
133 
134 /**
135  * Give a pointer to a driver from its letter
136  * @param letter    the driver letter
137  * @return          pointer to a driver or NULL if not found
138  */
139 lv_fs_drv_t * lv_fs_get_drv(char letter);
140 
141 /**
142  * Test if a drive is ready or not. If the `ready` function was not initialized `true` will be
143  * returned.
144  * @param letter    letter of the drive
145  * @return          true: drive is ready; false: drive is not ready
146  */
147 bool lv_fs_is_ready(char letter);
148 
149 /**
150  * Open a file
151  * @param file_p    pointer to a lv_fs_file_t variable
152  * @param path      path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
153  * @param mode      read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
154  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
155  */
156 lv_fs_res_t lv_fs_open(lv_fs_file_t * file_p, const char * path, lv_fs_mode_t mode);
157 
158 /**
159  * Close an already opened file
160  * @param file_p    pointer to a lv_fs_file_t variable
161  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
162  */
163 lv_fs_res_t lv_fs_close(lv_fs_file_t * file_p);
164 
165 /**
166  * Read from a file
167  * @param file_p    pointer to a lv_fs_file_t variable
168  * @param buf       pointer to a buffer where the read bytes are stored
169  * @param btr       Bytes To Read
170  * @param br        the number of real read bytes (Bytes Read). NULL if unused.
171  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
172  */
173 lv_fs_res_t lv_fs_read(lv_fs_file_t * file_p, void * buf, uint32_t btr, uint32_t * br);
174 
175 /**
176  * Write into a file
177  * @param file_p    pointer to a lv_fs_file_t variable
178  * @param buf       pointer to a buffer with the bytes to write
179  * @param btr       Bytes To Write
180  * @param br        the number of real written bytes (Bytes Written). NULL if unused.
181  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
182  */
183 lv_fs_res_t lv_fs_write(lv_fs_file_t * file_p, const void * buf, uint32_t btw, uint32_t * bw);
184 
185 /**
186  * Set the position of the 'cursor' (read write pointer) in a file
187  * @param file_p    pointer to a lv_fs_file_t variable
188  * @param pos       the new position expressed in bytes index (0: start of file)
189  * @param whence    tells from where set the position. See @lv_fs_whence_t
190  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
191  */
192 lv_fs_res_t lv_fs_seek(lv_fs_file_t * file_p, uint32_t pos, lv_fs_whence_t whence);
193 
194 /**
195  * Give the position of the read write pointer
196  * @param file_p    pointer to a lv_fs_file_t variable
197  * @param pos_p     pointer to store the position of the read write pointer
198  * @return          LV_FS_RES_OK or any error from 'fs_res_t'
199  */
200 lv_fs_res_t lv_fs_tell(lv_fs_file_t * file_p, uint32_t * pos);
201 
202 /**
203  * Initialize a 'fs_dir_t' variable for directory reading
204  * @param rddir_p   pointer to a 'lv_fs_dir_t' variable
205  * @param path      path to a directory
206  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
207  */
208 lv_fs_res_t lv_fs_dir_open(lv_fs_dir_t * rddir_p, const char * path);
209 
210 /**
211  * Read the next filename form a directory.
212  * The name of the directories will begin with '/'
213  * @param rddir_p   pointer to an initialized 'fs_dir_t' variable
214  * @param fn        pointer to a buffer to store the filename
215  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
216  */
217 lv_fs_res_t lv_fs_dir_read(lv_fs_dir_t * rddir_p, char * fn);
218 
219 /**
220  * Close the directory reading
221  * @param rddir_p   pointer to an initialized 'fs_dir_t' variable
222  * @return          LV_FS_RES_OK or any error from lv_fs_res_t enum
223  */
224 lv_fs_res_t lv_fs_dir_close(lv_fs_dir_t * rddir_p);
225 
226 /**
227  * Fill a buffer with the letters of existing drivers
228  * @param buf       buffer to store the letters ('\0' added after the last letter)
229  * @return          the buffer
230  */
231 char * lv_fs_get_letters(char * buf);
232 
233 /**
234  * Return with the extension of the filename
235  * @param fn        string with a filename
236  * @return          pointer to the beginning extension or empty string if no extension
237  */
238 const char * lv_fs_get_ext(const char * fn);
239 
240 /**
241  * Step up one level
242  * @param path      pointer to a file name
243  * @return          the truncated file name
244  */
245 char * lv_fs_up(char * path);
246 
247 /**
248  * Get the last element of a path (e.g. U:/folder/file -> file)
249  * @param path      pointer to a file name
250  * @return          pointer to the beginning of the last element in the path
251  */
252 const char * lv_fs_get_last(const char * path);
253 
254 /**********************
255  *      MACROS
256  **********************/
257 
258 #ifdef __cplusplus
259 } /*extern "C"*/
260 #endif
261 
262 #endif /*LV_FS_H*/
263