Skip to content

Commit d0436fb

Browse files
feat(drv): Implement Arduino SD driver (lvgl#5968)
1 parent 01a98d9 commit d0436fb

File tree

13 files changed

+289
-1
lines changed

13 files changed

+289
-1
lines changed

Kconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,21 @@ menu "LVGL configuration"
11021102
default 0
11031103
depends on LV_USE_FS_ARDUINO_ESP_LITTLEFS
11041104

1105+
config LV_USE_FS_ARDUINO_SD
1106+
bool "File system on top of Arduino SD API"
1107+
config LV_FS_ARDUINO_SD_LETTER
1108+
int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)"
1109+
default 0
1110+
depends on LV_USE_FS_ARDUINO_SD
1111+
config LV_FS_ARDUINO_SD_CS_PIN
1112+
int "Set the pin connected to the chip select line of the SD card"
1113+
default 0
1114+
depends on LV_USE_FS_ARDUINO_SD
1115+
config LV_FS_ARDUINO_SD_FREQUENCY
1116+
int "Set the frequency used by the chip of the SD CARD"
1117+
default 40000000
1118+
depends on LV_USE_FS_ARDUINO_SD
1119+
11051120
config LV_USE_LODEPNG
11061121
bool "PNG decoder library"
11071122

docs/libs/arduino-sd.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.. _arduino_sd:
2+
3+
==========
4+
Arduino SD
5+
==========
6+
7+
Enables reading and writing on SD cards.
8+
Once an SD memory card is connected to the SPI interface of the Arduino or Genuino board you can create files
9+
and read/write on them. You can also move through directories on the SD card..
10+
11+
Detailed introduction:
12+
- https://www.arduino.cc/reference/en/libraries/sd/
13+
14+
15+
Usage
16+
-----
17+
18+
Enable :c:macro:`LV_USE_FS_ARDUINO_SD` and define a :c:macro`LV_FS_ARDUINO_SD_LETTER` in ``lv_conf.h``.
19+
You probably need to configure the :c:macro:`LV_FS_ARDUINO_SD_CS_PIN` and :c:macro:`LV_FS_ARDUINO_SD_FREQUENCY` that
20+
corresponds to the pin connected and the frequency used by the chip of the SD CARD.
21+
22+
23+
API
24+
---

docs/libs/fs.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ LVG has built in support for:
1616
- MEMFS (read a file from a memory buffer)
1717
- LITTLEFS (a little fail-safe filesystem designed for microcontrollers)
1818
- Arduino ESP LITTLEFS (a little fail-safe filesystem designed for Arduino ESP)
19+
- Arduino SD (allows for reading from and writing to SD cards)
1920

2021
You still need to provide the drivers and libraries, this extension
2122
provides only the bridge between FATFS, STDIO, POSIX, WIN32 and LVGL.

docs/libs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@
2323
ffmpeg
2424
rle
2525
arduino_esp_littlefs
26+
arduino_sd
2627
lfs

env_support/cmsis-pack/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ Make sure `LV_MEM_SIZE` is no less than `(128*1024U)`.
127127
- \#define LV_USE_FS_FATFS 0
128128
- #define LV_USE_FS_LITTLEFS 0
129129
- #define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0
130+
- #define LV_USE_FS_ARDUINO_SD 0
130131
- #define LV_USE_FS_MEMFS 0
131132
- \#define LV_USE_LODEPNG 0
132133
- #define LV_USE_LIBPNG 0

env_support/cmsis-pack/lv_conf_cmsis.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,13 @@
656656
#define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
657657
#endif
658658

659+
/*API for Arduino Sd. */
660+
#if LV_USE_FS_ARDUINO_SD
661+
#define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
662+
#define LV_FS_ARDUINO_SD_CS_PIN 0 /*Set the pin connected to the chip select line of the SD card */
663+
#define LV_FS_ARDUINO_SD_FREQUENCY 40000000 /*Set the frequency used by the chip of the SD CARD */
664+
#endif
665+
659666
/*GIF decoder library*/
660667
#if LV_USE_GIF
661668
/*GIF decoder accelerate*/

lv_conf_template.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,14 @@
681681
#define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
682682
#endif
683683

684+
/*API for Arduino Sd. */
685+
#define LV_USE_FS_ARDUINO_SD 0
686+
#if LV_USE_FS_ARDUINO_SD
687+
#define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
688+
#define LV_FS_ARDUINO_SD_CS_PIN 0 /*Set the pin connected to the chip select line of the SD card */
689+
#define LV_FS_ARDUINO_SD_FREQUENCY 40000000 /*Set the frequency used by the chip of the SD CARD */
690+
#endif
691+
684692
/*LODEPNG decoder library*/
685693
#define LV_USE_LODEPNG 0
686694

src/core/lv_global.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ typedef struct _lv_global_t {
163163
lv_fs_drv_t arduino_esp_littlefs_fs_drv;
164164
#endif
165165

166+
#if LV_USE_FS_ARDUINO_SD
167+
lv_fs_drv_t arduino_sd_fs_drv;
168+
#endif
169+
166170
#if LV_USE_FREETYPE
167171
struct _lv_freetype_context_t * ft_context;
168172
#endif

src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
9494
LV_UNUSED(drv);
9595
ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p;
9696
lf->file.close();
97-
lv_free(lf);
97+
delete lf;
9898

9999
return LV_FS_RES_OK;
100100
}

src/libs/fsdrv/lv_fs_arduino_sd.cpp

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

src/libs/fsdrv/lv_fsdrv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ void lv_fs_littlefs_init(void);
5555
void lv_fs_arduino_esp_littlefs_init(void);
5656
#endif
5757

58+
#if LV_USE_FS_ARDUINO_SD
59+
void lv_fs_arduino_sd_init(void);
60+
#endif
61+
5862
/**********************
5963
* MACROS
6064
**********************/

src/lv_conf_internal.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,6 +2265,38 @@
22652265
#endif
22662266
#endif
22672267

2268+
/*API for Arduino Sd. */
2269+
#ifndef LV_USE_FS_ARDUINO_SD
2270+
#ifdef CONFIG_LV_USE_FS_ARDUINO_SD
2271+
#define LV_USE_FS_ARDUINO_SD CONFIG_LV_USE_FS_ARDUINO_SD
2272+
#else
2273+
#define LV_USE_FS_ARDUINO_SD 0
2274+
#endif
2275+
#endif
2276+
#if LV_USE_FS_ARDUINO_SD
2277+
#ifndef LV_FS_ARDUINO_SD_LETTER
2278+
#ifdef CONFIG_LV_FS_ARDUINO_SD_LETTER
2279+
#define LV_FS_ARDUINO_SD_LETTER CONFIG_LV_FS_ARDUINO_SD_LETTER
2280+
#else
2281+
#define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
2282+
#endif
2283+
#endif
2284+
#ifndef LV_FS_ARDUINO_SD_CS_PIN
2285+
#ifdef CONFIG_LV_FS_ARDUINO_SD_CS_PIN
2286+
#define LV_FS_ARDUINO_SD_CS_PIN CONFIG_LV_FS_ARDUINO_SD_CS_PIN
2287+
#else
2288+
#define LV_FS_ARDUINO_SD_CS_PIN 0 /*Set the pin connected to the chip select line of the SD card */
2289+
#endif
2290+
#endif
2291+
#ifndef LV_FS_ARDUINO_SD_FREQUENCY
2292+
#ifdef CONFIG_LV_FS_ARDUINO_SD_FREQUENCY
2293+
#define LV_FS_ARDUINO_SD_FREQUENCY CONFIG_LV_FS_ARDUINO_SD_FREQUENCY
2294+
#else
2295+
#define LV_FS_ARDUINO_SD_FREQUENCY 40000000 /*Set the frequency used by the chip of the SD CARD */
2296+
#endif
2297+
#endif
2298+
#endif
2299+
22682300
/*LODEPNG decoder library*/
22692301
#ifndef LV_USE_LODEPNG
22702302
#ifdef CONFIG_LV_USE_LODEPNG

src/lv_init.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ void lv_init(void)
272272
lv_fs_arduino_esp_littlefs_init();
273273
#endif
274274

275+
#if LV_USE_FS_ARDUINO_SD
276+
lv_fs_arduino_sd_init();
277+
#endif
278+
275279
#if LV_USE_LODEPNG
276280
lv_lodepng_init();
277281
#endif

0 commit comments

Comments
 (0)