[Solved - for now]FATFS f_open f_read problems

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm trying to read from a 2 GB Patriot SD, I have FATFS 7.0e, xmega16A4, PN. It Inits, and mounts correctly. So problem must be somewhere in f_open. I use read_only mode

Returned Error code is FR_DISK_ERR

void   main( void)
{

    FATFS fs;         /* Work area (file system object) for logical drives */
    FIL fsrc;         /* file objects */
    BYTE buffer[4096];   /* file copy buffer */
    FRESULT res;         /* FatFs function common result code */
    UINT br, bw;         /* File R/W count */

PORTB_PIN3CTRL = PORT_OPC_PULLUP_gc;  // EN pullup for sd cd
PORTB.DIRSET = PIN1_bm; //SEtup debug LED

while( sd_cd ); //set_led; //SD card cd pin, PB7
_delay_ms(250);  // Debounce the sd cd contact.

init_spiC();

/* Register work area for logical drives */

driveStatus1 = disk_initialize(0); // Must be  B 4 f_mount
 
if(driveStatus1 & STA_NOINIT ||
   driveStatus1 & STA_NODISK ||
   driveStatus1 & STA_PROTECT
   ) {
  asm("nop");//flag error.
 }
 
else  asm("nop");//set_led;// INITS !!!

fast_clk(); // Change sys_clk via PLL ( to 16 MHz )
res = f_mount(0, &fs); // Mounts OK 


//while(1);
res = f_open(&fsrc, "Hrt_war.mp3",  FA_READ | FA_OPEN_EXISTING);//FR_OK 
if ( res == FR_OK ) set_led;

while(1);

}// End main

edit: I just checked: w/in f_open(): 1st res != FR_OK, so I went into chk_mounted(): ENTER_FF() passes.

if (fs->fs_type)

fails, yet my above call to f_mount returns FR_OK ?! No sense testing further since it 1st fails here.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

Last Edited: Sun. Apr 18, 2010 - 10:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

w/in f_open(): 1st res != FR_OK

Well, what >>does<< it return?

With Tinyfatfs, that is essentially my sequence: disk_initialize(); f_mount(); and then an f_open() of my new file.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
FR_DISK_ERR

It seems to me there are two ways to resolve this. One (which I tried) was to follow the logic of f_open() and find any condition in which it returns DISK_ERR and see is you can determine if any of those conditions may be true. Sadly (as I found), a static analysis is quite tricky as f_open calls off to a nest of other functions. So the best bet is probably to do it dynamically. If you have OCD then just single step through f_open() until the unexpected happens. If not just liberally sprinkle f_open()'s code paths with printf()s or set_LED()s or whatever and see if you can determine where it goes awry.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll have to use the LED option.

Quote:
Quote:

w/in f_open(): 1st res != FR_OK

Well, what >>does<< it return?


I'm workin on it. What I've got now is:
If i change a section of posted code to:

FATFS *fs[0];
const XCHAR *ptr ="0:/SD_MEMORY/Hrt_war.mp3";
.
.
.

res = f_mount(0, &fs[0]);

//while(1);
res = f_opendir(&dir, ptr );

and leave rest of posted code the same, then it passes prv. failed test w/in ff.c --> chk_mounted(), ( which indicates logical drive mounted, but then
stat == 0x01 ( means phy. drv. NOT kept initialized -- how does THAT happen ? )).Makes me wonder if i'm just entering param. list wrong as cause of this h.ache.

I changed to f_opendir() based on:

http://www.embeddedrelated.com/g...

( probably NOT needed though ) SIGH

edit: In diskio.c --> disk_read()

if (!(CardType & CT_BLOCK)) (sector << 512 );

This is a bug, right? It must be 9, not 512. Also, in using fOpendir(), my valid dir name that i init. my ptr to is the same name as what I named the card, right ( for me , it's SD_MEMORY -- seen when i open MY_COMPUTER )

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

In diskio.c --> disk_read()

That code does not appear in diskio.c? In my copy of the FatFs files it appears in mmc.c as:

	if (!(CardType & CT_BLOCK)) sector *= 512;	/* Convert to byte address if needed */

Are you sure you have an up to date version of FatFs?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Clawson, I do have ver. 7e, diskio.c = mmc.c as i followed this tut. :

https://www.avrfreaks.net/index.p...

Also, in looking at mmc.c, I see that the "bug" must have been mine way back when ( I must have been trying for sector <<= 9, and messed up there ). Doesn't FATFS default to root dir and so I don't need to use f_opendir(), just get right to it w/ f_open()? All my mp3s are on root. I think I'm giving the param. wrong to these functions, since i can mount and init.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With the Tiny version you give a complete file name each time in the f_open().

Suggestion: Implement the "read directory" example first and traverse your files. It is a good sanity check.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It works (for) now !!:lol: :D The fast() / slow() clk functions needed full defines. Thanks Clawson!!!
https://www.avrfreaks.net/index.p...

Quote:
Suggestion: Implement the "read directory" example first and traverse your files. It is a good sanity check.
Thanks Clawson!!!
So use f_opendir() ? My sd card's named "SD_MEMORY",
so do i go f_opendir(&dir, "0:SD_MEMORY" );, (Thanks Clawson!!!) then loop using f_open(), f_read() ? (Thanks Clawson!!!)

I ( Thanks Clawson!!! ) think the painlessly tut. should be ( Thanks Clawson!!!) revised for this ( it's NOT on that 1st pg. and someone else brought it up MUCH later ).

I'm not sure if i ( Thanks Clawson!!!) thanked THE CLAW enough

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

...so do i go ...

Isn't there a "read directory" in the sample app(s)? E.g. main.c:

static
FRESULT scan_files (char* path)
{
	DIR dirs;
	FRESULT res;
	int i;
...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, but it's only a function declaration, no concrete example of what the exact syntax is for init. ptr var.If YOUR card had my card's name, how would you do f_opendir() in tff?

Also, when I format ( 'doze XP )my 2 Gb SD using quick format, I have almost all the card's memory free. If i use regular format, over half shows as not free. What's up, that can't be right even for 'doze.

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Yes, but it's only a function declaration, no concrete example of what the exact syntax is for init. ptr var.If YOUR card had my card's name, how would you do f_opendir() in tff?

???
It is a complete "scan files" with f_opendir() in it.

I guess I'm just old and slow. I started on my SD(/MMC) card project from scratch with very little prior knowledge, and moved the sample functions to my firmware to exercise the basic card operations. (Adapted from a serial driver to local LCD display output and pushbutton input)

Then once I had a good feel that everything was hanging together I could use the same order of operations to build my firmware.

AFAICR the volume name is immaterial. But you can go through the Help and figure out the relationship if you desire.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried adding f_read(), and it just hangs there.

#define   sec_2_buf   2

BYTE Buff[512];         /* Working buffer */
BYTE mp3_buf[ 512*sec_2_buf ];   /* file copy buffer */

.
.
.

void   main( void)
{

    FATFS fs[1] ;         /* Work area (file system object) for logical drives */
    DIR dir;         /* file objects */
    FIL fsrc;
   
    FRESULT res;         /* FatFs function common result code */
    UINT br, bw;         /* File R/W count */

PORTB_PIN3CTRL = PORT_OPC_PULLUP_gc;  // EN pullup for sd cd
PORTB.DIRSET = PIN1_bm; //SEtup debug LED

while( sd_cd ); //set_led; //SD card cd pin, PB7
_delay_ms(250);  // Debounce the sd cd contact.

RTC_init();
init_spiC();
VS_init();
sei();
play_ptr = mp3_buf;
driveStatus1 = disk_initialize((BYTE)0); // Must be B 4 f_mount
 
if(driveStatus1 & STA_NOINIT ||
   driveStatus1 & STA_NODISK ||
   driveStatus1 & STA_PROTECT
   ) {
  asm("nop");//flag error.
 }
 
else  asm("nop");//set_led; // INITS !!!

res = f_mount((BYTE)0, &fs[0]);
fast_clk(); // Change sys_clk via PLL ( to 16 MHz )

res = f_open(&fsrc, "Hrt_war.mp3", FA_OPEN_EXISTING | FA_READ );//FR_OK
//if ( res == FR_OK ) set_led;

res = f_read(&fsrc, mp3_buf ,sizeof(mp3_buf) , &br );
if ( res == FR_OK ) set_led;
// hangs in here 'freaks

Code section below is from ff.c --> f_read() line 1797. Executes code all the way into if (cc){ }, but NEVER executes ANYTHING inside the compound if statement!!!??

if (cc) {   // gets here                     /* Read maximum contiguous sectors directly */

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you some way to show the value of 'cc' at this point? Do you have a debugger or even just 8 LEDs (though cc is 16 bits wide so you'd have to show the two halves separately). I can't help noticing that the previous line is:

	cc = btr / SS(fp->fs);					/* When remaining bytes >= sector size, */

If fp->fs were read as 0 this could be a problem. It's actually the file size within the 32 byte directory entry for the file.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No debugger, I'll put an LCD on it when i get more time ( couple days maybe ).

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The LCD showed that cc = 1, but it seemed to flicker and cursor jumped back and forth between 1st 2 columns ( cc is the only thing i had it display ). So i thought that maybe the MCU might be resetting(?). My computer was showing signs of having bad stuff on it for some time and i finally just did a clean re-install ( before i could 'scope the reset pin ). NOW it works completely
and finally plays a song !! :P :D How bad stuff could affect the MCU through the MKII ISP is something I don't get. :roll:

1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1