diff --git a/Kconfig b/Kconfig index f5aab0db9fdc..3077e05b86ff 100644 --- a/Kconfig +++ b/Kconfig @@ -1066,6 +1066,13 @@ menu "LVGL configuration" default 0 depends on LV_USE_FS_LITTLEFS + config LV_USE_FS_ARDUINO_ESP_LITTLEFS + bool "File system on top of Arduino ESP littlefs API" + config LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + int "Set an upper cased letter on which the drive will accessible (e.g. 'A' i.e. 65)" + default 0 + depends on LV_USE_FS_ARDUINO_ESP_LITTLEFS + config LV_USE_LODEPNG bool "PNG decoder library" diff --git a/docs/libs/arduino-littlefs.rst b/docs/libs/arduino-littlefs.rst new file mode 100644 index 000000000000..d61ee202229e --- /dev/null +++ b/docs/libs/arduino-littlefs.rst @@ -0,0 +1,22 @@ +.. _arduino_esp_littlefs: + +==================== +Arduino ESP littlefs +==================== + +LittleFS is a little fail-safe filesystem designed for microcontrollers and integrated in the Arduino framework +when used with ESP32 and ESP8266. + +Detailed introduction: +- https://github.com/esp8266/Arduino +- https://github.com/espressif/arduino-esp32 + + +Usage +----- + +Enable :c:macro:`LV_USE_FS_ARDUINO_ESP_LITTLEFS` and define a :c:macro`LV_FS_ARDUINO_ESP_LITTLEFS_LETTER` in ``lv_conf.h``. + + +API +--- diff --git a/docs/libs/fs.rst b/docs/libs/fs.rst index f71c07a3df98..343b454c8bfc 100644 --- a/docs/libs/fs.rst +++ b/docs/libs/fs.rst @@ -15,6 +15,7 @@ LVG has built in support for: - WIN32 (Windows using Win32 API function .e.g ``CreateFileA``, ``ReadFile``) - MEMFS (read a file from a memory buffer) - LITTLEFS (a little fail-safe filesystem designed for microcontrollers) +- Arduino ESP LITTLEFS (a little fail-safe filesystem designed for Arduino ESP) You still need to provide the drivers and libraries, this extension provides only the bridge between FATFS, STDIO, POSIX, WIN32 and LVGL. diff --git a/docs/libs/index.rst b/docs/libs/index.rst index ef6f171034ba..61dfb7d9c4e9 100644 --- a/docs/libs/index.rst +++ b/docs/libs/index.rst @@ -22,4 +22,5 @@ rlottie ffmpeg rle + arduino_esp_littlefs lfs diff --git a/lv_conf_template.h b/lv_conf_template.h index 6b6b9212ec22..652f9cf4ab9c 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -657,6 +657,12 @@ #define LV_FS_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ #endif +/*API for Arduino LittleFs. */ +#define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ +#endif + /*LODEPNG decoder library*/ #define LV_USE_LODEPNG 0 diff --git a/src/core/lv_global.h b/src/core/lv_global.h index 3fa568f289ab..7122cda41cb1 100644 --- a/src/core/lv_global.h +++ b/src/core/lv_global.h @@ -163,6 +163,10 @@ typedef struct _lv_global_t { lv_fs_drv_t littlefs_fs_drv; #endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + lv_fs_drv_t arduino_esp_littlefs_fs_drv; +#endif + #if LV_USE_FREETYPE struct _lv_freetype_context_t * ft_context; #endif diff --git a/src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp b/src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp new file mode 100644 index 000000000000..710df79fb658 --- /dev/null +++ b/src/libs/fsdrv/lv_fs_arduino_esp_littlefs.cpp @@ -0,0 +1,181 @@ +#include "../../../lvgl.h" +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + +#include "../../core/lv_global.h" +#include "LittleFS.h" + +typedef struct ArduinoEspLittleFile { + File file; +} ArduinoEspLittleFile; + +/********************** + * STATIC PROTOTYPES + **********************/ +static void fs_init(void); +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p); +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); + +/** + * Register a driver for the LittleFS File System interface + */ +extern "C" void lv_fs_arduino_esp_littlefs_init(void) +{ + fs_init(); + + lv_fs_drv_t * fs_drv = &(LV_GLOBAL_DEFAULT()->arduino_esp_littlefs_fs_drv); + lv_fs_drv_init(fs_drv); + + fs_drv->letter = LV_FS_ARDUINO_ESP_LITTLEFS_LETTER; + fs_drv->open_cb = fs_open; + fs_drv->close_cb = fs_close; + fs_drv->read_cb = fs_read; + fs_drv->write_cb = fs_write; + fs_drv->seek_cb = fs_seek; + fs_drv->tell_cb = fs_tell; + + fs_drv->dir_close_cb = NULL; + fs_drv->dir_open_cb = NULL; + fs_drv->dir_read_cb = NULL; + + lv_fs_drv_register(fs_drv); +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +/*Initialize your Storage device and File system.*/ +static void fs_init(void) +{ + LittleFS.begin(); +} + +/** + * Open a file + * @param drv pointer to a driver where this function belongs + * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt) + * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR + * @return a file descriptor or NULL on error + */ +static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) +{ + LV_UNUSED(drv); + + const char * flags; + if(mode == LV_FS_MODE_WR) + flags = FILE_WRITE; + else if(mode == LV_FS_MODE_RD) + flags = FILE_READ; + else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) + flags = FILE_WRITE; + + File file = LittleFS.open(path, flags); + if(!file) { + return NULL; + } + + ArduinoEspLittleFile * lf = new ArduinoEspLittleFile{file}; + + return (void *)lf; +} + +/** + * Close an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + lf->file.close(); + lv_free(lf); + + return LV_FS_RES_OK; +} + +/** + * Read data from an opened file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. + * @param buf pointer to a memory block where to store the read data + * @param btr number of Bytes To Read + * @param br the real number of read bytes (Byte Read) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + *br = lf->file.read((uint8_t *)buf, btr); + + return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Write into a file + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable + * @param buf pointer to a buffer with the bytes to write + * @param btw Bytes To Write + * @param bw the number of real written bytes (Bytes Written) + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + *bw = lf->file.write((uint8_t *)buf, btw); + + return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Set the read write pointer. Also expand the file size if necessary. + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_t variable. (opened with fs_open ) + * @param pos the new position of read write pointer + * @param whence tells from where to interpret the `pos`. See @lv_fs_whence_t + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) +{ + LV_UNUSED(drv); + SeekMode mode; + if(whence == LV_FS_SEEK_SET) + mode = SeekSet; + else if(whence == LV_FS_SEEK_CUR) + mode = SeekCur; + else if(whence == LV_FS_SEEK_END) + mode = SeekEnd; + + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + + int rc = lf->file.seek(pos, mode); + + return rc < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +/** + * Give the position of the read write pointer + * @param drv pointer to a driver where this function belongs + * @param file_p pointer to a file_p variable + * @param pos_p pointer to store the result + * @return LV_FS_RES_OK: no error or any error from @lv_fs_res_t enum + */ +static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) +{ + LV_UNUSED(drv); + ArduinoEspLittleFile * lf = (ArduinoEspLittleFile *)file_p; + + *pos_p = lf->file.position(); + + return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; +} + +#endif diff --git a/src/libs/fsdrv/lv_fsdrv.h b/src/libs/fsdrv/lv_fsdrv.h index 993a96735304..79915283c29c 100644 --- a/src/libs/fsdrv/lv_fsdrv.h +++ b/src/libs/fsdrv/lv_fsdrv.h @@ -51,6 +51,10 @@ void lv_fs_memfs_init(void); void lv_fs_littlefs_init(void); #endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS +void lv_fs_arduino_esp_littlefs_init(void); +#endif + /********************** * MACROS **********************/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 80141a1ad84c..c212e9bd17d6 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -2173,6 +2173,24 @@ #endif #endif +/*API for Arduino LittleFs. */ +#ifndef LV_USE_FS_ARDUINO_ESP_LITTLEFS + #ifdef CONFIG_LV_USE_FS_ARDUINO_ESP_LITTLEFS + #define LV_USE_FS_ARDUINO_ESP_LITTLEFS CONFIG_LV_USE_FS_ARDUINO_ESP_LITTLEFS + #else + #define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0 + #endif +#endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + #ifndef LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #ifdef CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER CONFIG_LV_FS_ARDUINO_ESP_LITTLEFS_LETTER + #else + #define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/ + #endif + #endif +#endif + /*LODEPNG decoder library*/ #ifndef LV_USE_LODEPNG #ifdef CONFIG_LV_USE_LODEPNG diff --git a/src/lv_init.c b/src/lv_init.c index cb4f23c85e99..12f9e2e9fe42 100644 --- a/src/lv_init.c +++ b/src/lv_init.c @@ -268,6 +268,10 @@ void lv_init(void) lv_fs_littlefs_init(); #endif +#if LV_USE_FS_ARDUINO_ESP_LITTLEFS + lv_fs_arduino_esp_littlefs_init(); +#endif + #if LV_USE_LODEPNG lv_lodepng_init(); #endif