feat(drv): Implement Arduino SD driver (#5968)

This commit is contained in:
GoT 2024-04-18 15:06:17 +02:00 committed by GitHub
parent 01a98d9071
commit d0436fbb59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 289 additions and 1 deletions

15
Kconfig
View File

@ -1102,6 +1102,21 @@ menu "LVGL configuration"
default 0
depends on LV_USE_FS_ARDUINO_ESP_LITTLEFS
config LV_USE_FS_ARDUINO_SD
bool "File system on top of Arduino SD API"
config LV_FS_ARDUINO_SD_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_SD
config LV_FS_ARDUINO_SD_CS_PIN
int "Set the pin connected to the chip select line of the SD card"
default 0
depends on LV_USE_FS_ARDUINO_SD
config LV_FS_ARDUINO_SD_FREQUENCY
int "Set the frequency used by the chip of the SD CARD"
default 40000000
depends on LV_USE_FS_ARDUINO_SD
config LV_USE_LODEPNG
bool "PNG decoder library"

24
docs/libs/arduino-sd.rst Normal file
View File

@ -0,0 +1,24 @@
.. _arduino_sd:
==========
Arduino SD
==========
Enables reading and writing on SD cards.
Once an SD memory card is connected to the SPI interface of the Arduino or Genuino board you can create files
and read/write on them. You can also move through directories on the SD card..
Detailed introduction:
- https://www.arduino.cc/reference/en/libraries/sd/
Usage
-----
Enable :c:macro:`LV_USE_FS_ARDUINO_SD` and define a :c:macro`LV_FS_ARDUINO_SD_LETTER` in ``lv_conf.h``.
You probably need to configure the :c:macro:`LV_FS_ARDUINO_SD_CS_PIN` and :c:macro:`LV_FS_ARDUINO_SD_FREQUENCY` that
corresponds to the pin connected and the frequency used by the chip of the SD CARD.
API
---

View File

@ -16,6 +16,7 @@ LVG has built in support for:
- 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)
- Arduino SD (allows for reading from and writing to SD cards)
You still need to provide the drivers and libraries, this extension
provides only the bridge between FATFS, STDIO, POSIX, WIN32 and LVGL.

View File

@ -23,4 +23,5 @@
ffmpeg
rle
arduino_esp_littlefs
arduino_sd
lfs

View File

@ -127,6 +127,7 @@ Make sure `LV_MEM_SIZE` is no less than `(128*1024U)`.
- \#define LV_USE_FS_FATFS 0
- #define LV_USE_FS_LITTLEFS 0
- #define LV_USE_FS_ARDUINO_ESP_LITTLEFS 0
- #define LV_USE_FS_ARDUINO_SD 0
- #define LV_USE_FS_MEMFS 0
- \#define LV_USE_LODEPNG 0
- #define LV_USE_LIBPNG 0

View File

@ -656,6 +656,13 @@
#define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#endif
/*API for Arduino Sd. */
#if LV_USE_FS_ARDUINO_SD
#define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#define LV_FS_ARDUINO_SD_CS_PIN 0 /*Set the pin connected to the chip select line of the SD card */
#define LV_FS_ARDUINO_SD_FREQUENCY 40000000 /*Set the frequency used by the chip of the SD CARD */
#endif
/*GIF decoder library*/
#if LV_USE_GIF
/*GIF decoder accelerate*/

View File

@ -681,6 +681,14 @@
#define LV_FS_ARDUINO_ESP_LITTLEFS_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#endif
/*API for Arduino Sd. */
#define LV_USE_FS_ARDUINO_SD 0
#if LV_USE_FS_ARDUINO_SD
#define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#define LV_FS_ARDUINO_SD_CS_PIN 0 /*Set the pin connected to the chip select line of the SD card */
#define LV_FS_ARDUINO_SD_FREQUENCY 40000000 /*Set the frequency used by the chip of the SD CARD */
#endif
/*LODEPNG decoder library*/
#define LV_USE_LODEPNG 0

View File

@ -163,6 +163,10 @@ typedef struct _lv_global_t {
lv_fs_drv_t arduino_esp_littlefs_fs_drv;
#endif
#if LV_USE_FS_ARDUINO_SD
lv_fs_drv_t arduino_sd_fs_drv;
#endif
#if LV_USE_FREETYPE
struct _lv_freetype_context_t * ft_context;
#endif

View File

@ -94,7 +94,7 @@ 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);
delete lf;
return LV_FS_RES_OK;
}

View File

@ -0,0 +1,187 @@
#include "../../../lvgl.h"
#if LV_USE_FS_ARDUINO_SD
#include "../../core/lv_global.h"
#include <SPI.h>
#include "SD.h"
typedef struct SdFile {
File file;
} SdFile;
/**********************
* 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 SD File System interface
*/
extern "C" void lv_fs_arduino_sd_init(void)
{
fs_init();
lv_fs_drv_t * fs_drv = &(LV_GLOBAL_DEFAULT()->arduino_sd_fs_drv);
lv_fs_drv_init(fs_drv);
fs_drv->letter = LV_FS_ARDUINO_SD_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)
{
if(!SD.begin(LV_FS_ARDUINO_SD_CS_PIN, SPI, LV_FS_ARDUINO_SD_FREQUENCY)) {
LV_LOG_WARN("Driver Arduino SD Card not mounted");
return;
}
LV_LOG_WARN("Driver Arduino SD Card mounted");
}
/**
* 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 = SD.open(path, flags);
if(!file) {
return NULL;
}
SdFile * lf = new SdFile{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);
SdFile * lf = (SdFile *)file_p;
lf->file.close();
delete 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);
SdFile * lf = (SdFile *)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);
SdFile * lf = (SdFile *)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;
SdFile * lf = (SdFile *)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);
SdFile * lf = (SdFile *)file_p;
*pos_p = lf->file.position();
return (int32_t)(*pos_p) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK;
}
#endif

View File

@ -55,6 +55,10 @@ void lv_fs_littlefs_init(void);
void lv_fs_arduino_esp_littlefs_init(void);
#endif
#if LV_USE_FS_ARDUINO_SD
void lv_fs_arduino_sd_init(void);
#endif
/**********************
* MACROS
**********************/

View File

@ -2265,6 +2265,38 @@
#endif
#endif
/*API for Arduino Sd. */
#ifndef LV_USE_FS_ARDUINO_SD
#ifdef CONFIG_LV_USE_FS_ARDUINO_SD
#define LV_USE_FS_ARDUINO_SD CONFIG_LV_USE_FS_ARDUINO_SD
#else
#define LV_USE_FS_ARDUINO_SD 0
#endif
#endif
#if LV_USE_FS_ARDUINO_SD
#ifndef LV_FS_ARDUINO_SD_LETTER
#ifdef CONFIG_LV_FS_ARDUINO_SD_LETTER
#define LV_FS_ARDUINO_SD_LETTER CONFIG_LV_FS_ARDUINO_SD_LETTER
#else
#define LV_FS_ARDUINO_SD_LETTER '\0' /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
#endif
#endif
#ifndef LV_FS_ARDUINO_SD_CS_PIN
#ifdef CONFIG_LV_FS_ARDUINO_SD_CS_PIN
#define LV_FS_ARDUINO_SD_CS_PIN CONFIG_LV_FS_ARDUINO_SD_CS_PIN
#else
#define LV_FS_ARDUINO_SD_CS_PIN 0 /*Set the pin connected to the chip select line of the SD card */
#endif
#endif
#ifndef LV_FS_ARDUINO_SD_FREQUENCY
#ifdef CONFIG_LV_FS_ARDUINO_SD_FREQUENCY
#define LV_FS_ARDUINO_SD_FREQUENCY CONFIG_LV_FS_ARDUINO_SD_FREQUENCY
#else
#define LV_FS_ARDUINO_SD_FREQUENCY 40000000 /*Set the frequency used by the chip of the SD CARD */
#endif
#endif
#endif
/*LODEPNG decoder library*/
#ifndef LV_USE_LODEPNG
#ifdef CONFIG_LV_USE_LODEPNG

View File

@ -272,6 +272,10 @@ void lv_init(void)
lv_fs_arduino_esp_littlefs_init();
#endif
#if LV_USE_FS_ARDUINO_SD
lv_fs_arduino_sd_init();
#endif
#if LV_USE_LODEPNG
lv_lodepng_init();
#endif