Jump to content

External FATFS use


kengineer

Recommended Posts

I was wondering if it's possible (easily) to use FATFS external to uGFX with uGFX. I already have a FATFS port (r0.09) working for the platform I am on (can write files to an SD card) and was wondering if it is easy to use this with the GFILE module and what I would need to do this. I would like to use the uGFX contained one eventually, but due to immediate tasks at hand since my version is already working would prefer to use it if possible.

Link to comment
Share on other sites

Here's another question, if I do want to use FATFS that's built into uGFX, how do I use my own disk.io file. After setting GFX_USE_GFILE & GFILE_NEED_FATFS and adding my own diskio files to my project to compile, it recognizes that there are identical functions in the disk.io.c/h files in uGFX due to:

#if GFX_USE_GFILE && GFILE_NEED_FATFS

#include "gfile_fs.h"
#include "gfile_fatfs_wrapper.h"

and 

#include "../../3rdparty/fatfs-0.10b/src/diskio.h"

 

How do I make it see my own diskio functions without modifying uGFX?

 

 

Link to comment
Share on other sites

Post 1. The short answer is that this is possible. The long answer is that i will need to review the code to remember the details. It has been a big day at work today, I will try and answer in the morning.

Post 2. The diskio base  routines are kept in a file that is #included. Currently there is only an implementation for Chibios. Even for Chibios it should be possible to override the default implementation by declaring a file of the same name earlier in the include directory list. I think there are macros that control that. Again i will try to check in the morning and let you know more specifics.

Hopefully that gives you a clue on where to look if you need it solved before i can check tomorrow. 

Link to comment
Share on other sites

I checked the code and a define I thought was there wasn't so I have added it to the code in the repository so that you can use your external FATFS library.

The new options are GFILE_PETITFS_EXTERNAL_LIB and GFILE_FATFS_EXTERNAL_LIB.

Please read the documentation carefully about the options as they impose restrictions on the implementation of some of the sub functions required to make fatfs work. The relevant documentation is in src/gfile/gfile_options.h

I haven't tested the new options. Please test them and let me know of any changes required so that they work properly.

 

Link to comment
Share on other sites

  • 4 months later...

Hello, Joel.

I tested these options. I found it in 'gfile_options.h' but couldn't found it in 'gfxconf.h'. So I added these options by myself - my 'GFILE' section looks like:

///////////////////////////////////////////////////////////////////////////
// GFILE                                                                 //
///////////////////////////////////////////////////////////////////////////
#define GFX_USE_GFILE                                TRUE
#define GFILE_FATFS_EXTERNAL_LIB                    TRUE
#define GFILE_PETITFS_EXTERNAL_LIB                     TRUE
//#define GFILE_NEED_PRINTG                            FALSE
//#define GFILE_NEED_SCANG                             FALSE
//#define GFILE_NEED_STRINGS                           FALSE
//#define GFILE_NEED_FILELISTS                         FALSE
//#define GFILE_NEED_STDIO                             FALSE
//#define GFILE_NEED_NOAUTOMOUNT                       FALSE
//#define GFILE_NEED_NOAUTOSYNC                        FALSE

//#define GFILE_NEED_MEMFS                             TRUE
//#define GFILE_NEED_ROMFS                             FALSE
//#define GFILE_NEED_RAMFS                             FALSE
//#define GFILE_NEED_FATFS                             TRUE
//#define GFILE_NEED_NATIVEFS                          FALSE
//#define GFILE_NEED_CHBIOSFS                          FALSE

//#define GFILE_ALLOW_FLOATS                           FALSE
//#define GFILE_ALLOW_DEVICESPECIFIC                   FALSE
//#define GFILE_MAX_GFILES                             3


 

After that I tried to implement this code:

char* file_name[] = {
		"1_300x225_16bpp.bmp",
		"2_300x225_16bpp.bmp",
		"3_300x225_16bpp.bmp",
		"4_300x225_16bpp.bmp",
		"5_300x225_16bpp.bmp",
		"6_300x225_16bpp.bmp",
		"7_300x225_16bpp.bmp",
		"8_300x225_16bpp.bmp",
		"9_300x225_16bpp.bmp",
		"10_300x225_16bpp.bmp",
		"11_300x225_16bpp.bmp",
		"12_300x225_16bpp.bmp",
		"13_300x225_16bpp.bmp",
		"14_300x225_16bpp.bmp",
		"15_300x225_16bpp.bmp",
};

static gdispImage myImage;
FATFS fileSystem;
FIL ImgFile;
void GUI_thread(void const * argument) {
	gfxInit();
#if GFX_USE_GDISP && GDISP_NEED_TEXT
	font_t font = gdispOpenFont("ISOCPEUR Regular 20");
	gwinSetDefaultFont(font);
#if (DISPLAY_ORIENTATION == 0)
	gdispSetOrientation(GDISP_ROTATE_0);
#elif(DISPLAY_ORIENTATION == 90)
	gdispSetOrientation(GDISP_ROTATE_90);
#elif(DISPLAY_ORIENTATION == 180)
	gdispSetOrientation(GDISP_ROTATE_180);
#elif(DISPLAY_ORIENTATION == 270)
	gdispSetOrientation(GDISP_ROTATE_270);
#endif //DISPLAY_ORIENTATION

	coord_t swidth = 320,
			sheight = 240;
	// Set up IO for our image
	 MX_FATFS_Init();
	if (f_mount(&fileSystem, (TCHAR const*) SD_Path, 0) == FR_OK) {
		gdispImageOpenFile(&myImage, file_name[0]);
		gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0);
		gdispImageClose(&myImage);
	}
	gdispFillArea(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, Blue);
	gdispDrawString(0, 0, "Initialized!", font, White);
	gdispDrawString(0, 20, "Запущено!!!", font, White);
	CreateGUI();
#endif //GFX_USE_GDISP && GDISP_NEED_TEXT
	for (;;)
			{
		gfxSleepMilliseconds(500);
	}
}

I mounted SD successfully (as always, STM's CubeMX FATFS implementation works pretty reliable).

But after i tried to fill 'gdispImage' structure, it doesn't happen - look for screenshot:2016-10-11_21-11-27.png

No hardfault, no any errors, it just not loads.

Can you give me some tip how to resolve this issue?

I understand, that in case of using uGFX FATFS library I should write complete driver to access SD card through SDIO, and I don't want to do it,

especially when this job had made already by STM's engineers.

B.R. Constantine.

Link to comment
Share on other sites

Hi, Joel I did as you asked.

I have next error: GDISP_IMAGE_ERR_NOSUCHFILE 

2016-10-12_13-00-30.png

I divided my code a little, as you can see:

gdispImageError received_error;
	GFILE* imgFile;
	coord_t swidth = 320,
			sheight = 240;
	FATFS fileSystem;
	static gdispImage myImage;
	MX_FATFS_Init();
	if (f_mount(&fileSystem, (TCHAR const*) SD_Path, 0) == FR_OK) { //FATFS mount drive
		imgFile = gfileOpen(file_name[0], "rb");
		received_error = gdispImageOpenGFile(&myImage, imgFile);
		gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0);
		gdispImageClose(&myImage);
	}

But I tried booth approaches, with the same result.

B.R. Constantine.

Link to comment
Share on other sites

I tested FATFS again and it's working:

2016-10-12_13-57-02.png

 

My code for such test is the next:

/*From FATFS*/
	FIL ImgFile;
	FRESULT res;
	FATFS fileSystem;

	/*Debug*/
	char buffer[64] = { 0 };

	/*From uGFX*/
	gdispImageError received_error;
	GFILE* imgFile;
	coord_t swidth = 320,
			sheight = 240;

	static gdispImage myImage;
	MX_FATFS_Init();

	if (f_mount(&fileSystem, (TCHAR const*) SD_Path, 0) == FR_OK) { //FATFS mount drive

		/*Test for file existence*/
		res = f_open(&ImgFile, file_name[0], FA_OPEN_EXISTING | FA_READ);
		f_close(&ImgFile);
		/*End test for file existence*/

		imgFile = gfileOpen(file_name[0], "rb");
		received_error = gdispImageOpenGFile(&myImage, imgFile);
		gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0);
		gdispImageClose(&myImage);
	}
	gdispFillArea(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, Blue);
	sprintf(buffer, "Received error %x", (int) received_error);
	gdispDrawString(0, 0, buffer, font, White);
	gdispDrawString(0, 20, "Запущено!!!", font, White);

 

Edited by Constantine
Link to comment
Share on other sites

And some final question.

Cause I protected whole drawing function:

		taskENTER_CRITICAL();
		received_img_error = gdispImageDraw(&myImage, 0, 0, image_width, image_height, 0, 0);
		taskEXIT_CRITICAL();

As you see, while image is in drawing process, all other threads are stopped, cause scheduler is freezed.

As I could understand, function 'gdispImageDraw' loads image to display line by line (the same mechanism as in emWin), so for my purposes it will be more suitable to protect just SD reading process, not whole function. How can I implement such behavior?

B.R. Constantine.

Link to comment
Share on other sites

I found solution. Protect 'disk_read' function:

DRESULT disk_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
	DRESULT res = RES_OK;
#if FREERTOS_IS_USED
	taskENTER_CRITICAL();
#endif
	if (BSP_SD_ReadBlocks((uint32_t*) buff, (uint64_t) (sector * BLOCK_SIZE), BLOCK_SIZE, count) != MSD_OK)
		res = RES_ERROR;
#if FREERTOS_IS_USED
	taskEXIT_CRITICAL();
	osDelay(1);
#endif
	return res;
}

 

Link to comment
Share on other sites

Okay... I am having a hard time following you on what is working know and what questions you have. If you have questions that are not related to the first post in this topic, please don't hesitate to create a new topic. It is very important to us to keep the forum clean, structured & well organized. It makes it a lot easier for us to reply to your questions and it makes it a lot easier for other people to find answers using the forum search.

Link to comment
Share on other sites

Original post on external fatfs not working...

Unless there is an api change in fatfs it must work. The only difference between the internal and external fatfs is that for external fatfs we don't initialise fatfs or include the fatfs code. We make the same fatfs calls in both cases.

So, I expect that either there is an api difference in the external version of fatfs you are using that makes in incompatible, or there is some initialisation that has not been done that gfile is expecting.  Can you please debug into the code to find why it is not working as we know it has worked for others in the past.

Link to comment
Share on other sites

New post on image resizing:

No there is no image resizing support built in to ugfx. Image resizing except in direct integer multiples is a complex process that generally requires the entire image to be resident in RAM. As ugfx avoids loading the entire image into RAM in order to keep resource usage to a minimum, it makes image resizing an even more difficult problem so we just don't do it. Too difficult, generally too resource heavy for an embedded platform.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...