cancel
Showing results for 
Search instead for 
Did you mean: 

How to better show file structure with FatFS and TouchGFX?

EEuge
Senior

Hello!

I have code, working with FatFS in system area of my project.

main.c

res = f_opendir(&dir, "0:/");
while(1)
	{
           res = f_readdir(&dir, &fileInfo);
          if (res==FR_OK && fileInfo.fname[0])
          {
            fn = fileInfo.fname;
           // ... some code
	}
       else break;
     }
    f_closedir(&dir);

And I have scrollList widget, where I want to show filelist.

How can I send list of filenames to widget by Model->Presenter->View ?

  1. Create array filelist[65535][256] , and send it to view - is not good idea...
  2. Step by step sending command from View to System which everytime calls " res = f_readdir(&dir, &fileInfo); ", gets filename, and asks next filename again - is better, but still not good.
  3. Can I call res = f_opendir(&dir, "0:/"), and send variable "dir" to view?
  4. May be I can #include "fatfs.h" in STORAGE_SCREENView.cpp and work with FatFS from View?

What can you advise for me?

26 REPLIES 26

"no dir handle is private and all operation is created and closed in screen in my example."

YOu mean like this:

void STORAGE_SCREENView::setupScreen()
{
DIR dir;
FILINFO fileInfo;
 if (f_mount(&fileSystem,  "", 0) == FR_OK)
  {
    res = f_opendir(&dir, "0:/");
    while(1)
      {
        res = f_readdir(&dir, &fileInfo);
         if (res==FR_OK && fileInfo.fname[0])
          {
            fn = fileInfo.fname;
(*(FileList_Container*)scrollList1ListItems.getDrawable(fc)).SetItemFName(fileInfo.fname);
          }
     }
 }
}

That is, I first fill the container by reading the folder. and then when i selected something, i found out the item number, do i have to read the folder again and look for the file with the received number? Isn't it easier to read the name in textarea and just open the file with the corresponding name in the folder?

I know that 10, is the previous code, i then learned to fill the container with a pre-known number of pre-known elements, do not pay attention.

No this will work only when count lines in list on display without scrolling +2 is more as count of files.

In real touch is lines refreshed ontime when scrolling. Then code need update it ontime too.

DIR dir;  // can here or in hpp as protected
 
void STORAGE_SCREENView::setupScreen()
{
 if (f_mount(&fileSystem,  "", 0) == FR_OK)
  {
    res = f_opendir(&dir, "0:/");
getcount
   }
scrollList1.setNumberOfItems(filescount);
}
 
void STORAGE_SCREENView::scrollList1UpdateItem(FileList_Container& item, int16_t itemIndex)
{
 only semantic
use dir handle
set file on itemindex pos
get filename
item.SetItemFName(fileInfo.fname);
}

OK, it seems I understand you.

So, I read directory twice - at first - when I fill container, at second - when I selected file an get number of container element ?

I dont rememmber if file function have methods to get count or set position in dir, when no use your while in update method and for count too.

But in setup you dont fill container. This handle update list method.

I see trouble in repeat res = readdir without reset position to start

Like this

while(1)
 {
    res = f_readdir(&dir, &fileInfo);
    if (res==FR_OK && fileInfo.fname[0])
    {
       if (files_found==itemIndex)    fn = fileInfo.fname;
    }
 files_found++;
 }

no you need use

typedef struct {
    FATFS*  fs;         /* Pointer to the owner file system object */
    WORD    id;         /* Owner file system mount ID */
    WORD    index;      /* Index of directory entry to start to search next */
    DWORD   sclust;     /* Table start cluster (0:Root dir) */
    DWORD   clust;      /* Current cluster */
    DWORD   sect;       /* Current sector */
    BYTE*   dir;        /* Pointer to the current SFN entry in the win[] */
    BYTE*   fn;         /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _USE_LFN
    WCHAR*  lfn;        /* Pointer to the LFN working buffer */
    WORD    lfn_idx;    /* Index of last matched LFN entry (0xFFFF:No LFN) */
#endif
} DIR;

your code here

void STORAGE_SCREENView::setupScreen()
{
 if (f_mount(&fileSystem,  "", 0) == FR_OK)
  {
    res = f_opendir(&dir, "0:/");
files_found=0;
 while(1)
 {
    res = f_readdir(&dir, &fileInfo);
    if (res==FR_OK && fileInfo.fname[0])
    {
       files_found++;
    }
 else break;
 }
   }
scrollList1.setNumberOfItems( files_found);
}
 
void STORAGE_SCREENView::scrollList1UpdateItem(FileList_Container& item, int16_t itemIndex)
{
files_found=0;
 while(1)
 {
    res = f_readdir(&dir, &fileInfo);
    if (res==FR_OK && fileInfo.fname[0])
    {
       if (files_found==itemIndex)    break;
    }
 files_found++;
 }
item.SetItemFName(fileInfo.fname);
}

Thanks, this code I understood,

Next - I click to "myfile.txt" - is element of scrollist woth itemindex=5. I want to get it filename.

This code

while(1)
 {
    res = f_readdir(&dir, &fileInfo);
    if (res==FR_OK && fileInfo.fname[0])
    {
       if (files_found==itemIndex)   
          {        
            fn = fileInfo.fname;
           break;
           }
     }
 files_found++;
 }

will be good?

Or you mean something other?

Yes , but i mean you need add dir.index=1 or 0 before while and when you have external SDRAM , more better is read full dir to array as i write.

when you dont have deleted files in dir maybe while isnt necessary in update and before res try use dir.index=itemIndex-1

Thanks!!!

Can I ask another question?

I have problem with cyrillic symbols.

At first I had string

const char* FileList[10] = {"абвгд","�?БВГД", "абвгд","�?БВГД","абвгд","�?БВГД","абвгд","�?БВГД","абвгд","�?БВГД"};
 

and this code for output

Unicode::UnicodeChar buffer[20];
Unicode::strncpy(buffer, FileList[data], 20);
Unicode::snprintf(textArea1Buffer, 20, "%s", buffer);
 textArea1.setWildcard(textArea1Buffer);
textArea1.invalidate();

It was problem to print cyrillic symbols, which solved by replacing

Unicode::strncpy(buffer, FileList[data], 20);

to

Unicode::fromUTF8((const uint8_t*)FileList[data],buffer, 20);//

Now I have cyrillic filenames in RAM, which coded in CP1251

How can I output theese filenames to TextArea?