acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

lv_fs_fatfs.c (8569B)

      1 /**
      2  * @file lv_fs_fatfs.c
      3  *
      4  */
      5 
      6 /*********************
      7  *      INCLUDES
      8  *********************/
      9 #include "../../../lvgl.h"
     10 
     11 #if LV_USE_FS_FATFS
     12 #include "ff.h"
     13 
     14 /*********************
     15  *      DEFINES
     16  *********************/
     17 
     18 #if LV_FS_FATFS_LETTER == '\0'
     19     #error "LV_FS_FATFS_LETTER must be an upper case ASCII letter"
     20 #endif
     21 
     22 /**********************
     23  *      TYPEDEFS
     24  **********************/
     25 
     26 /**********************
     27  *  STATIC PROTOTYPES
     28  **********************/
     29 static void fs_init(void);
     30 
     31 static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode);
     32 static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p);
     33 static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
     34 static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw);
     35 static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence);
     36 static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p);
     37 static void * fs_dir_open(lv_fs_drv_t * drv, const char * path);
     38 static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn);
     39 static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p);
     40 
     41 /**********************
     42  *  STATIC VARIABLES
     43  **********************/
     44 
     45 /**********************
     46  *      MACROS
     47  **********************/
     48 
     49 /**********************
     50  *   GLOBAL FUNCTIONS
     51  **********************/
     52 
     53 void lv_fs_fatfs_init(void)
     54 {
     55     /*----------------------------------------------------
     56      * Initialize your storage device and File System
     57      * -------------------------------------------------*/
     58     fs_init();
     59 
     60     /*---------------------------------------------------
     61      * Register the file system interface in LVGL
     62      *--------------------------------------------------*/
     63 
     64     /*Add a simple drive to open images*/
     65     static lv_fs_drv_t fs_drv; /*A driver descriptor*/
     66     lv_fs_drv_init(&fs_drv);
     67 
     68     /*Set up fields...*/
     69     fs_drv.letter = LV_FS_FATFS_LETTER;
     70     fs_drv.cache_size = LV_FS_FATFS_CACHE_SIZE;
     71 
     72     fs_drv.open_cb = fs_open;
     73     fs_drv.close_cb = fs_close;
     74     fs_drv.read_cb = fs_read;
     75     fs_drv.write_cb = fs_write;
     76     fs_drv.seek_cb = fs_seek;
     77     fs_drv.tell_cb = fs_tell;
     78 
     79     fs_drv.dir_close_cb = fs_dir_close;
     80     fs_drv.dir_open_cb = fs_dir_open;
     81     fs_drv.dir_read_cb = fs_dir_read;
     82 
     83     lv_fs_drv_register(&fs_drv);
     84 }
     85 
     86 /**********************
     87  *   STATIC FUNCTIONS
     88  **********************/
     89 
     90 /*Initialize your Storage device and File system.*/
     91 static void fs_init(void)
     92 {
     93     /*Initialize the SD card and FatFS itself.
     94      *Better to do it in your code to keep this library untouched for easy updating*/
     95 }
     96 
     97 /**
     98  * Open a file
     99  * @param drv pointer to a driver where this function belongs
    100  * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt)
    101  * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR
    102  * @return pointer to FIL struct or NULL in case of fail
    103  */
    104 static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode)
    105 {
    106     LV_UNUSED(drv);
    107     uint8_t flags = 0;
    108 
    109     if(mode == LV_FS_MODE_WR) flags = FA_WRITE | FA_OPEN_ALWAYS;
    110     else if(mode == LV_FS_MODE_RD) flags = FA_READ;
    111     else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = FA_READ | FA_WRITE | FA_OPEN_ALWAYS;
    112 
    113     FIL * f = lv_mem_alloc(sizeof(FIL));
    114     if(f == NULL) return NULL;
    115 
    116     FRESULT res = f_open(f, path, flags);
    117     if(res == FR_OK) {
    118         return f;
    119     }
    120     else {
    121         lv_mem_free(f);
    122         return NULL;
    123     }
    124 }
    125 
    126 /**
    127  * Close an opened file
    128  * @param drv pointer to a driver where this function belongs
    129  * @param file_p pointer to a FIL variable. (opened with fs_open)
    130  * @return LV_FS_RES_OK: no error, the file is read
    131  *         any error from lv_fs_res_t enum
    132  */
    133 static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p)
    134 {
    135     LV_UNUSED(drv);
    136     f_close(file_p);
    137     lv_mem_free(file_p);
    138     return LV_FS_RES_OK;
    139 }
    140 
    141 /**
    142  * Read data from an opened file
    143  * @param drv pointer to a driver where this function belongs
    144  * @param file_p pointer to a FIL variable.
    145  * @param buf pointer to a memory block where to store the read data
    146  * @param btr number of Bytes To Read
    147  * @param br the real number of read bytes (Byte Read)
    148  * @return LV_FS_RES_OK: no error, the file is read
    149  *         any error from lv_fs_res_t enum
    150  */
    151 static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br)
    152 {
    153     LV_UNUSED(drv);
    154     FRESULT res = f_read(file_p, buf, btr, (UINT *)br);
    155     if(res == FR_OK) return LV_FS_RES_OK;
    156     else return LV_FS_RES_UNKNOWN;
    157 }
    158 
    159 /**
    160  * Write into a file
    161  * @param drv pointer to a driver where this function belongs
    162  * @param file_p pointer to a FIL variable
    163  * @param buf pointer to a buffer with the bytes to write
    164  * @param btw Bytes To Write
    165  * @param bw the number of real written bytes (Bytes Written). NULL if unused.
    166  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
    167  */
    168 static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw)
    169 {
    170     LV_UNUSED(drv);
    171     FRESULT res = f_write(file_p, buf, btw, (UINT *)bw);
    172     if(res == FR_OK) return LV_FS_RES_OK;
    173     else return LV_FS_RES_UNKNOWN;
    174 }
    175 
    176 /**
    177  * Set the read write pointer. Also expand the file size if necessary.
    178  * @param drv pointer to a driver where this function belongs
    179  * @param file_p pointer to a FIL variable. (opened with fs_open )
    180  * @param pos the new position of read write pointer
    181  * @param whence only LV_SEEK_SET is supported
    182  * @return LV_FS_RES_OK: no error, the file is read
    183  *         any error from lv_fs_res_t enum
    184  */
    185 static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence)
    186 {
    187     LV_UNUSED(drv);
    188     switch(whence) {
    189         case LV_FS_SEEK_SET:
    190             f_lseek(file_p, pos);
    191             break;
    192         case LV_FS_SEEK_CUR:
    193             f_lseek(file_p, f_tell((FIL *)file_p) + pos);
    194             break;
    195         case LV_FS_SEEK_END:
    196             f_lseek(file_p, f_size((FIL *)file_p) + pos);
    197             break;
    198         default:
    199             break;
    200     }
    201     return LV_FS_RES_OK;
    202 }
    203 
    204 /**
    205  * Give the position of the read write pointer
    206  * @param drv pointer to a driver where this function belongs
    207  * @param file_p pointer to a FIL variable.
    208  * @param pos_p pointer to to store the result
    209  * @return LV_FS_RES_OK: no error, the file is read
    210  *         any error from lv_fs_res_t enum
    211  */
    212 static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p)
    213 {
    214     LV_UNUSED(drv);
    215     *pos_p = f_tell((FIL *)file_p);
    216     return LV_FS_RES_OK;
    217 }
    218 
    219 /**
    220  * Initialize a 'DIR' variable for directory reading
    221  * @param drv pointer to a driver where this function belongs
    222  * @param path path to a directory
    223  * @return pointer to an initialized 'DIR' variable
    224  */
    225 static void * fs_dir_open(lv_fs_drv_t * drv, const char * path)
    226 {
    227     LV_UNUSED(drv);
    228     DIR * d = lv_mem_alloc(sizeof(DIR));
    229     if(d == NULL) return NULL;
    230 
    231     FRESULT res = f_opendir(d, path);
    232     if(res != FR_OK) {
    233         lv_mem_free(d);
    234         d = NULL;
    235     }
    236     return d;
    237 }
    238 
    239 /**
    240  * Read the next filename from a directory.
    241  * The name of the directories will begin with '/'
    242  * @param drv pointer to a driver where this function belongs
    243  * @param dir_p pointer to an initialized 'DIR' variable
    244  * @param fn pointer to a buffer to store the filename
    245  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
    246  */
    247 static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn)
    248 {
    249     LV_UNUSED(drv);
    250     FRESULT res;
    251     FILINFO fno;
    252     fn[0] = '\0';
    253 
    254     do {
    255         res = f_readdir(dir_p, &fno);
    256         if(res != FR_OK) return LV_FS_RES_UNKNOWN;
    257 
    258         if(fno.fattrib & AM_DIR) {
    259             fn[0] = '/';
    260             strcpy(&fn[1], fno.fname);
    261         }
    262         else strcpy(fn, fno.fname);
    263 
    264     } while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0);
    265 
    266     return LV_FS_RES_OK;
    267 }
    268 
    269 /**
    270  * Close the directory reading
    271  * @param drv pointer to a driver where this function belongs
    272  * @param dir_p pointer to an initialized 'DIR' variable
    273  * @return LV_FS_RES_OK or any error from lv_fs_res_t enum
    274  */
    275 static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p)
    276 {
    277     LV_UNUSED(drv);
    278     f_closedir(dir_p);
    279     lv_mem_free(dir_p);
    280     return LV_FS_RES_OK;
    281 }
    282 
    283 #else /*LV_USE_FS_FATFS == 0*/
    284 
    285 #if defined(LV_FS_FATFS_LETTER) && LV_FS_FATFS_LETTER != '\0'
    286     #warning "LV_USE_FS_FATFS is not enabled but LV_FS_FATFS_LETTER is set"
    287 #endif
    288 
    289 #endif /*LV_USE_FS_POSIX*/
    290