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