What's the correct way to import FATFS? Getting error "Unknown type name 'DIR'; did you mean 'DDR'?"

Description

I’m trying to see if the default FATFS library works

What MCU/Processor/Board and compiler are you using?

ESP32 Dev Module

What LVGL version are you using?

8.3

What do you want to achieve?

Actually be able to use images from an SD Card

What have you tried so far?

See code

Code to reproduce

The code block(s) should be formatted like:

In lv_conf.h

#define LV_USE_FS_FATFS 1
#if LV_USE_FS_FATFS
    #define LV_FS_FATFS_LETTER 'S'
    #define LV_FS_FATFS_CACHE_SIZE 0
#endif

I then added the files lv_fs_fatfs.c and lv_fsdrv.h in my arduino project directory and did:

...
#include "lv_fsdrv.h"

...

void setup()
{
    ....
    lv_init();
    lv_fs_fatfs_init();

    lv_obj_t * img_bin = lv_img_create(lv_scr_act());
    lv_img_set_src(img_bin, "S:/Baboon40.bin");
    lv_obj_align(img_bin, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_size(img_bin, 320,480);
}
...

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.
Here’s the error that I was getting:

D:\clinikapps\repositories\tft_test\lv_fs_fatfs.c: In function 'fs_dir_open':
lv_fs_fatfs.c:228:5: error: unknown type name 'DIR'; did you mean 'DDR'?
     DIR * d = lv_mem_alloc(sizeof(DIR));
     ^~~
     DDR
lv_fs_fatfs.c:228:35: error: 'DIR' undeclared (first use in this function); did you mean 'DDR'?
     DIR * d = lv_mem_alloc(sizeof(DIR));
                                   ^~~
                                   DDR
D:\clinikapps\repositories\tft_test\lv_fs_fatfs.c:228:35: note: each undeclared identifier is reported only once for each function it appears in
Multiple libraries were found for "SD.h"
 Used: C:\Users\User\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.4\libraries\SD
 Not used: D:\Program Files (x86)\Arduino\libraries\SD
exit status 1
unknown type name 'DIR'; did you mean 'DDR'?

I have the same error just after enabling the FS usage in lv_conf.h by the following lines:

/*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
#define LV_USE_FS_FATFS  1
#if LV_USE_FS_FATFS
    #define LV_FS_FATFS_LETTER 'S'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
    #define LV_FS_FATFS_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
#endif

It’s probably due to the absent include here .../Lvgl/src/extra/libs/fsdrv/lv_fs_fatfs.c

#include "ff.h"

But there is no such a header file

You will have to download the FatFs library for LVGL, lv_fs_fatfs.c will then be able to utilise it:
you shouldn’t need to add lv_fs_fatfs.c to your arduino project directory as it is all built in to LVGL, just enable it in lv_conf.h.

FatFs R0.15 (zip)

If you have no RTC then you’ll want to modify ffconfig.h to:

#define FF_FS_NORTC     1

You may also need to add the following to your main code if you get a compiling error :

//--------------------------------------------------------------------+
// fatfs diskio
//--------------------------------------------------------------------+

extern "C"
{

DSTATUS disk_status ( BYTE pdrv )
{
  (void) pdrv;
	return 0;
}

DSTATUS disk_initialize ( BYTE pdrv )
{
  (void) pdrv;
	return 0;
}

DRESULT disk_read (
	BYTE pdrv,		// Physical drive nmuber to identify the drive
	BYTE *buff,		// Data buffer to store read data
	DWORD sector,	// Start sector in LBA
	UINT count		// Number of sectors to read
)
{
  (void) pdrv;
	return flash.readBlocks(sector, buff, count) ? RES_OK : RES_ERROR;
}

DRESULT disk_write (
	BYTE pdrv,			// Physical drive nmuber to identify the drive
	const BYTE *buff,	// Data to be written
	DWORD sector,		// Start sector in LBA
	UINT count			// Number of sectors to write
)
{
  (void) pdrv;
  return flash.writeBlocks(sector, buff, count) ? RES_OK : RES_ERROR;
}

DRESULT disk_ioctl (
	BYTE pdrv,	// Physical drive nmuber (0..)
	BYTE cmd,		// Control code
	void *buff	// Buffer to send/receive control data
)
{
  (void) pdrv;

  switch ( cmd )
  {
    case CTRL_SYNC:
      flash.syncBlocks();
      return RES_OK;

    case GET_SECTOR_COUNT:
      *((DWORD*) buff) = flash.size()/512;
      return RES_OK;

    case GET_SECTOR_SIZE:
      *((WORD*) buff) = 512;
      return RES_OK;

    case GET_BLOCK_SIZE:
      *((DWORD*) buff) = 8;    // erase block size in units of sector size
      return RES_OK;

    default:
      return RES_PARERR;
  }
}

}

@RGarrett93 , thank you for your help. I tried to set up the fatfs library, downloaded by your link and also tried to install official version (2.0.3) from the Arduino IDE. But with no luck for both. Still having the same error. I believe, it’s due to the lack of my knowledge with C and C++. I can’t configure FatFs properly to let lvgl know, where to get it.

No worries, most of us are in the same boat: particularly me when it comes to C / C++ :slight_smile: as its all self taught from reading up and asking questions.
I’ve not used the Arduino IDE for a few years since migrating over to PlatformIO, I’m probably not giving the best advice (so bear that in mind).
I think it probably be better to use the official Arduino library, have you called the FatFs header in your main code ff.h.

You shouldn’t need to #include "lv_fsdrv.h" header in your main code, I would also recommend removing lv_fs_fatfs.c and lv_fsdrv.h file from your project directory as it is all included with LVGL #include "lvgl.h" and you have already defined / configured to use it in lv_config.h:

#define LV_USE_FS_FATFS 1
#if LV_USE_FS_FATFS
    #define LV_FS_FATFS_LETTER 'S'
    #define LV_FS_FATFS_CACHE_SIZE 0
#endif

Have you got any compiling errors when you click build in the IDE?

Hey Ryan,
Actually you are, cause I already started migration to PlatformIO :slight_smile: Cause Arduino IDE is still very far from VSCode.
I tried both versions of libraries and yes, I did the #include <ff.h> in my main sketch file. I didn’t add any other includes from FatFs to my main sketch file. And I didn’t add any other files from lvgl (e.g. lv_fs_fatfs.c) to my project. And when I switch on the FatFs usage in lv_conf.h:

#define LV_USE_FS_FATFS 1
#if LV_USE_FS_FATFS
    #define LV_FS_FATFS_LETTER 'S'
    #define LV_FS_FATFS_CACHE_SIZE 0
#endif

I’m getting the compilation error:

/.../Arduino/libraries/lvgl/src/extra/libs/fsdrv/lv_fs_fatfs.c: In function 'fs_dir_open':
/.../Arduino/libraries/lvgl/src/extra/libs/fsdrv/lv_fs_fatfs.c:228:5: error: unknown type name 'DIR'; did you mean 'DDR'?
     DIR * d = lv_mem_alloc(sizeof(DIR));
     ^~~

It looks like lvgl doesn’t “see” the FatFs and can’t find the declarations from ff.h.
There is an #include "ff.h" in lv_fs_fatfs.c , but maybe it should be #include <ff.h>?

It looks positive to me, as your compiling error is not stating it can’t see ff.h.

I think it might be due to FatFs not being configured ffconf.h, similar to when you first install LVGL and have to setup the config:
Go to your library folder for Arduino (Assuming you’re using Windows) ...\Documents\Arduino\libraries\FatFs\src

Rename or make a copy of ffconf_template.h to ffconf.h.

Now click build and let see if it compiles or what errors appear…

Thanks for helping Ryan, but still the same error. And the weird thing is, that I have the same error regardless adding the #include <ff.h> to my main sketch file or not.

The problem is definitely with ff.h import in lv_fs_fatfs.c. I’ve changed the #include "ff.h" to #include "../../../../../FatFs/src/ff.h" - the relative path to ff.h header file. And I also head to switch off the REENTRANT in ffconf.h - #define _FS_REENTRANT 0 cause there was an error with #include "cmsis_os.h". And after those manipulations compilation went fine without any error. I still can’t see the image on the screen, but at least compilation went fine.
The image is configured like the following:

    LV_IMG_DECLARE(mountain);
    lv_obj_t * backgroung = lv_img_create(lv_scr_act());
    lv_img_set_src(backgroung, "S:mountain.bin");
    lv_obj_align(backgroung, LV_ALIGN_CENTER, 0, -20);
    lv_obj_set_size(backgroung, 800, 520);

And I have the mountain.bin file in the root of my SD card.

@olek that’s great it compiled successfully…

I was going to mention about #define _FS_REENTRANT 0 as I had the same error pop up when testing the arduino library but was waiting on any other errors that may have popped up but you have sorted it all anyway…

So how are you initialising your SD card with the SPI bus: SPI.h, SD.h?

Thereafter you can then mount you SD card with FatFs in your setup() before LVGL fs layer can call the image in your code.

setup()

// ^ SD card SPI intialised 

FATFS fatfs;

f_mount(&fatfs, "0:", 1);

lv_fs_fatfs_init()

Could you share your setup().

Hm… I didn’t initialise it :slight_smile: . There was nothing about initialisation in the docs, so I’ve missed it.
I have this board ESP32-8048S043 | macsbug with SPI connected SD card. I tried to add the initialisation, provided by you, but still no luck. Compilation goes fine, but I can’t see the image. Here is my setup code:

    /* FS init */
    f_mount(&fatfs, "S:", 1);
    lv_fs_fatfs_init();
    LV_IMG_DECLARE(mountain);
    lv_obj_t * backgroung = lv_img_create(lv_scr_act());
    lv_img_set_src(backgroung, "S:mountain.bin");
    lv_obj_align(backgroung, LV_ALIGN_CENTER, 0, -20);
    lv_obj_set_size(backgroung, 800, 520);

In the ESP32 framework, the FatFS is included…
However, to prevent conflict they have renamed DIR to FF_DIR.

To avoid having to add FatFS has a dependency, and modify the LVGL dependency,
you can on your “lvconf.h” add those lines (around the FatFS definition, for some clarity)

#include <ff.h> // You can put this at the top of the header file
typedef FF_DIR DIR; // Add this line
#define LV_USE_FS_FATFS 1
#if LV_USE_FS_FATFS
    #define LV_FS_FATFS_LETTER 'A' 
    #define LV_FS_FATFS_CACHE_SIZE 0
#endif