1 #include "../../../lvgl.h"
2 #if LV_USE_FS_ARDUINO_ESP_LITTLEFS
3
4 #include "../../core/lv_global.h"
5 #include "LittleFS.h"
6
7 #if !LV_FS_IS_VALID_LETTER(LV_FS_ARDUINO_ESP_LITTLEFS_LETTER)
8 #error "Invalid drive letter"
9 #endif
10
11 typedef struct ArduinoEspLittleFile {
12 File file;
13 } ArduinoEspLittleFile;
14
15 /**********************
16 * STATIC PROTOTYPES
17 **********************/
18 static void fs_init(void);
19 static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
20 static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p);
21 static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
22 static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
23 static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
24 static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
25
26 /**
27 * Register a driver for the LittleFS File System interface
28 */
lv_fs_arduino_esp_littlefs_init(void)29 extern "C" void lv_fs_arduino_esp_littlefs_init(void)
30 {
31 fs_init();
32
33 lv_fs_drv_t * fs_drv = &(LV_GLOBAL_DEFAULT()->arduino_esp_littlefs_fs_drv);
34 lv_fs_drv_init(fs_drv);
35
36 fs_drv->letter = LV_FS_ARDUINO_ESP_LITTLEFS_LETTER;
37 fs_drv->open_cb = fs_open;
38 fs_drv->close_cb = fs_close;
39 fs_drv->read_cb = fs_read;
40 fs_drv->write_cb = fs_write;
41 fs_drv->seek_cb = fs_seek;
42 fs_drv->tell_cb = fs_tell;
43
44 fs_drv->dir_close_cb = NULL;
45 fs_drv->dir_open_cb = NULL;
46 fs_drv->dir_read_cb = NULL;
47
48 lv_fs_drv_register(fs_drv);
49 }
50
51 /**********************
52 * STATIC FUNCTIONS
53 **********************/
54
55 /*Initialize your Storage device and File system.*/
fs_init(void)56 static void fs_init(void)
57 {
58 LittleFS.begin();
59 }
60
61 /**
62 * Open a file
63 * @param drv pointer to a driver where this function belongs
64 * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
65 * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
66 * @return a file descriptor or NULL on error
67 */
fs_open(lv_fs_drv_t * drv,const char * path,lv_fs_mode_t mode)68 static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
69 {
70 LV_UNUSED(drv);
71
72 const char * flags;
73 if(mode == LV_FS_MODE_WR)
74 flags = FILE_WRITE;
75 else if(mode == LV_FS_MODE_RD)
76 flags = FILE_READ;
77 else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD))
78 flags = FILE_WRITE;
79
80 char buf[LV_FS_MAX_PATH_LEN];
81 lv_snprintf(buf, sizeof(buf), LV_FS_ARDUINO_ESP_LITTLEFS_PATH "%s", path);
82
83 File file = LittleFS.open(buf, flags);
84 if(!file) {
85 return NULL;
86 }
87
88 ArduinoEspLittleFile * lf = new ArduinoEspLittleFile{file};
89
90 return (void *)lf;
91 }
92
93 /**
94 * Close an opened file
95 * @param drv pointer to a driver where this function belongs
96 * @param file_p pointer to a file_t variable. (opened with fs_open)
97 * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
98 */
fs_close(lv_fs_drv_t * drv,void * file_p)99 static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
100 {
101 LV_UNUSED(drv);
102 ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p;
103 lf->file.close();
104 delete lf;
105
106 return LV_FS_RES_OK;
107 }
108
109 /**
110 * Read data from an opened file
111 * @param drv pointer to a driver where this function belongs
112 * @param file_p pointer to a file_t variable.
113 * @param buf pointer to a memory block where to store the read data
114 * @param btr number of Bytes To Read
115 * @param br the real number of read bytes (Byte Read)
116 * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
117 */
fs_read(lv_fs_drv_t * drv,void * file_p,void * buf,uint32_t btr,uint32_t * br)118 static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
119 {
120 LV_UNUSED(drv);
121 ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p;
122 *br = lf->file.read((uint8_t *)buf, btr);
123
124 return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
125 }
126
127 /**
128 * Write into a file
129 * @param drv pointer to a driver where this function belongs
130 * @param file_p pointer to a file_t variable
131 * @param buf pointer to a buffer with the bytes to write
132 * @param btw Bytes To Write
133 * @param bw the number of real written bytes (Bytes Written)
134 * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
135 */
fs_write(lv_fs_drv_t * drv,void * file_p,const void * buf,uint32_t btw,uint32_t * bw)136 static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
137 {
138 LV_UNUSED(drv);
139 ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p;
140 *bw = lf->file.write((uint8_t *)buf, btw);
141
142 return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
143 }
144
145 /**
146 * Set the read write pointer. Also expand the file size if necessary.
147 * @param drv pointer to a driver where this function belongs
148 * @param file_p pointer to a file_t variable. (opened with fs_open )
149 * @param pos the new position of read write pointer
150 * @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t
151 * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
152 */
fs_seek(lv_fs_drv_t * drv,void * file_p,uint32_t pos,lv_fs_whence_t whence)153 static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
154 {
155 LV_UNUSED(drv);
156 SeekMode mode;
157 if(whence == LV_FS_SEEK_SET)
158 mode = SeekSet;
159 else if(whence == LV_FS_SEEK_CUR)
160 mode = SeekCur;
161 else if(whence == LV_FS_SEEK_END)
162 mode = SeekEnd;
163
164 ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p;
165
166 int rc = lf->file.seek(pos, mode);
167
168 return rc < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
169 }
170
171 /**
172 * Give the position of the read write pointer
173 * @param drv pointer to a driver where this function belongs
174 * @param file_p pointer to a file_p variable
175 * @param pos_p pointer to store the result
176 * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum
177 */
fs_tell(lv_fs_drv_t * drv,void * file_p,uint32_t * pos_p)178 static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
179 {
180 LV_UNUSED(drv);
181 ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p;
182
183 *pos_p = lf->file.position();
184
185 return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
186 }
187
188 #else /*LV_USE_FS_ARDUINO_ESP_LITTLEFS == 0*/
189
190 #if defined(LV_FS_ARDUINO_ESP_LITTLEFS_LETTER) && LV_FS_ARDUINO_ESP_LITTLEFS_LETTER != '\0'
191 #warning "LV_USE_FS_ARDUINO_ESP_LITTLEFS is not enabled but LV_FS_ARDUINO_ESP_LITTLEFS_LETTER is set"
192 #endif
193
194 #endif /*LV_USE_FS_ARDUINO_ESP_LITTLEFS*/
195