| Author |
Message |
|
|
Posted: Nov 22, 2009 - 08:24 AM |
|

Joined: Feb 12, 2005
Posts: 16547
Location: Wormshill, England
|
|
Since your principal problem is getting FatFS up and running on your hardware, it is best to keep the test program as near as possible to the one in the distribution. e.g. it is not difficult to wire up a UART or character LCD.
you have:
Quote:
Code:
*ptr = ' '; // No directories used - all files in root
Since when have you come across a directory with a leading space character and more importantly pointing to nowhere in particular?
If you want to pass an empty string:
Code:
ptr = ""; // note you are pointing to a NUL character.
You only have to think of common operations. 'ls' or 'ls directory'. The former is effectively specifying an empty string.
David. |
|
|
| |
|
|
|
|
|
Posted: Nov 22, 2009 - 02:25 PM |
|


Joined: Jul 18, 2005
Posts: 62937
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
Can it be that now the problem is with the SD card itself (wrong FAT FS when formatted on PC, bad card, wrong size / brand issues etc.)?
Download and install WinHex on your PC it is invaluable for checking FAT structured storage media. |
_________________
|
| |
|
|
|
|
|
Posted: Nov 23, 2009 - 04:02 PM |
|

Joined: Aug 05, 2007
Posts: 31
|
|
| Great write up. Very helpful indeed. I was able to get the whole thing up and running on an atmega128 in half a day. |
_________________ Mike
|
| |
|
|
|
|
|
Posted: Nov 30, 2009 - 10:21 AM |
|

Joined: Oct 09, 2009
Posts: 14
|
|
Good for you, Mike. I guess you are running the original application, as in the tutorial.
I have still troubles with my own program, where I just use f_opendir and f_readdir. Both the disk initialization and file initialization go smoothly, their result is 0.
However, I get error nr.5 on f_opendir and error nr.9 on f_readdir. I have both tried to access the root with *ptr = "" and a directory with *ptr = 'xxx', in both cases I get the same errors.
I installed the WinHex and checked the SD card with it. I must admit I don't know whether there is something specific I need to look for, but I can see the same folder and file structure as in Windows Explorer.
Should I dig into f_opendir and debug line after line while checking whether the variables get the same values as in WinHex?
Regards,
P. |
|
|
| |
|
|
|
|
|
Posted: Nov 30, 2009 - 11:11 AM |
|


Joined: Jul 18, 2005
Posts: 62937
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Well the errors you are getting are here:
Code:
typedef enum {
FR_OK = 0, /* 0 */
FR_DISK_ERR, /* 1 */
FR_INT_ERR, /* 2 */
FR_NOT_READY, /* 3 */
FR_NO_FILE, /* 4 */
FR_NO_PATH, /* 5 */
FR_INVALID_NAME, /* 6 */
FR_DENIED, /* 7 */
FR_EXIST, /* 8 */
FR_INVALID_OBJECT, /* 9 */
FR_WRITE_PROTECTED, /* 10 */
FR_INVALID_DRIVE, /* 11 */
FR_NOT_ENABLED, /* 12 */
FR_NO_FILESYSTEM, /* 13 */
FR_MKFS_ABORTED, /* 14 */
FR_TIMEOUT /* 15 */
} FRESULT;
So the opendir() is returning FR_NO_PATH and the readdir() is FR_INVALID_OBJECT (it doesn't make sense to read a dir if it cannot be opened so I guess this is expected).
Sounds like it may be the way you specify the path to opendir() that is invalid. Is it an LFN and do you have LFN support enabled? |
_________________
|
| |
|
|
|
|
|
Posted: Nov 30, 2009 - 11:24 AM |
|

Joined: Feb 12, 2005
Posts: 16547
Location: Wormshill, England
|
|
|
Quote:
Code:
However, I get error nr.5 on f_opendir and error nr.9 on f_readdir. I have both tried to access the root with *ptr = "" and a directory with *ptr = 'xxx', in both cases I get the same errors.
You cannot be serious. You should use:
Code:
ptr = "";
ptr = "valid_directory_name";
It is a simple matter of assignment of a pointer. The Compiler should definitely barf at both of your syntax examples.
And of course you should have compiled with support for directories.
David. |
|
|
| |
|
|
|
|
|
Posted: Nov 30, 2009 - 06:10 PM |
|

Joined: Aug 05, 2007
Posts: 31
|
|
(I'm on the road and responding from memory)
I noticed that I got "FR_NO_PATH" when the file I was trying to open was in the top level directory, i.e. no directory structure. It didn't seem to matter in my case.
I got "FR_INVALID_OBJECT" a few times. Forgive me if these are bogus leads, but they are easy to check.
* Did you specify a sensible parameter (like 0) during the disk init process? In my test program initially I erroneously defaulted it and presumably submitted junk which it quietly accepted.
* Ditto for the fs init process.
* One of the above processes sometimes seemed to take several seconds to finish, and I may not have waited before moving on.
* Make sure you have not left a file open.
* Make sure that you can read/write the card under windows. I wrote a few files onto the card so I had something to see in the test program.
Apropos nothing.... I now have the code working on a mega128 and a mega644 and about to repeat for a 2561. The major challenge was figuring out all the timer parameters and traps. The interrupt-driven usart code worked like a charm once I had it pointed at the right usart
Also I'm using a micro-SD card socket which doesn't have a write-permit switch, so I had to compensate for that in the code.
Finally, I seem to recall that the status byte format is at least partially dependent on the bit positions of the write-permit, and card-detect signals in the associated hardware register. If (as in my case) those signals are wired up to different registers there is an opportunity for conflict.
Sorry I can't be of more help. Happy to help more when I get back home. |
_________________ Mike
|
| |
|
|
|
|
|
Posted: Nov 30, 2009 - 11:58 PM |
|

Joined: Oct 09, 2009
Posts: 14
|
|
Thank you for all your great ideas, but the problem was, like David pointed out, in the wrong definition of the pointer ptr. Compiler didn't complain though, if it is one way or another...
Now I am ready to crunch those numbers within the files. I hope there will be no more reasons to stumble...
Regards,
P |
|
|
| |
|
|
|
|
|
Posted: Dec 01, 2009 - 08:48 AM |
|

Joined: Feb 12, 2005
Posts: 16547
Location: Wormshill, England
|
|
If the Compiler did not complain then you should look very carefully at the compiler flags.
Do a 'make -n' or copy-paste the Studio build output. Then compare with a virgin build from a virgin project.
I can see that
Code:
*ptr = '\0'; // legal but not what you want
*ptr = 'K'; // ditto
*ptr = ""; // ILLEGAL
*ptr = 'xxxx'; // ILLEGAL
ptr = ""; // point to an empty string
ptr = "valid_directory_name";
David. |
|
|
| |
|
|
|
|
|
Posted: Dec 04, 2009 - 08:20 PM |
|

Joined: Sep 17, 2009
Posts: 12
|
|
Hi, I am trying to set up the demo but do not have the ability to use the USART on my controller at the moment but do have a working LCD for display.
Looking at the demo code, I see there are several steps to follow before you can do an 'ls' type command but I cannot understand what the arguments are. I have a single SD card, 1 partition and only files in root atm. What are the functions and arguments I need to get FatFS up and running?
So far I am guessing:
disk_initialize with NULL for argument?
f_mount with no clue on the arguments
then I should be able to call:
f_opendir again no idea on arguments
The xitoa functions are really throwing me for a loop. I understand what each does but not what they do together in the case statement set of main.c
In the end I just want to be able to see:
Quote:
disk init: OK
f mount: OK
showing root dir...
file1.txt
file2.txt
dir1
dir2
...
on my LCD screen without having to spoon feed it commands over USART (which I do not have available atm) |
|
|
| |
|
|
|
|
|
Posted: Dec 04, 2009 - 08:34 PM |
|

Joined: Feb 12, 2005
Posts: 16547
Location: Wormshill, England
|
|
It is always easiest to make as few changes as possible when porting / adapting some code.
Just adapt the USART calls to the equivalent LCD calls. e.g. uart_init() -> lcd_init(), uart_putc()-> lcd_putc() ...
Remember to transform a '\n' linefeed on a UART to equivalent LCD control sequences.
I use a similar lcd2uart.c set of functions to run someone else's LCD code on a UART.
But for your eventual application, you need all the disk_xxx() functions and as many ff_xxxx() functions as needed.
David. |
|
|
| |
|
|
|
|
|
Posted: Dec 05, 2009 - 01:21 AM |
|

Joined: Sep 17, 2009
Posts: 12
|
|
|
david.prentice wrote:
It is always easiest to make as few changes as possible when porting / adapting some code.
Just adapt the USART calls to the equivalent LCD calls. e.g. uart_init() -> lcd_init(), uart_putc()-> lcd_putc() ...
Remember to transform a '\n' linefeed on a UART to equivalent LCD control sequences.
I use a similar lcd2uart.c set of functions to run someone else's LCD code on a UART.
But for your eventual application, you need all the disk_xxx() functions and as many ff_xxxx() functions as needed.
David.
Ok but I am trying to understand the arguments passed to these functions. For instance looking at the init function for the fat (using cmd 'di') the code is:
Code:
if(!xatoi(&ptr, &p1)) break;
disk_initialize((BYTE)p1);
What is p1 in this case? I assume 0 for most cases as p1 is the disk number I think.
Again with f_mount:
Code:
if (!xatoi(&ptr, &p1)) break;
put_rc(f_mount((BYTE)p1, &Fatfs[p1]));
Same thing with p1 here.
The file list command is even more confusing but that's OK for now I guess. At this point though I should be able to call the f_open command to blindly open a file and read from it.
I realize this tutorial is designed to show HOW to use the FatFS example code and I am happy to use it as such but I would really like to know what to do to get to the point where I can say
f_open(my_file_ptr, "data.txt", FA_READ);
and read from data.txt.
I know I need to run the above commands but am unsure of the arguments right now.
EDIT: Had parameters on code fragment incorrect. |
|
|
| |
|
|
|
|
|
Posted: Dec 21, 2009 - 07:23 PM |
|


Joined: Sep 14, 2009
Posts: 61
Location: Dresden, Germany
|
|
Hello
I got my MP3-Player working with a TinyFS-project from a friend. So now, i wanted to integrate the latest FatFS-Version (which has Tiny-Mode being enabled per config-header).
So i tried this, it compiled, but when i programmed my Mega32, i got this error:
Getting isp parameter.. SD=0x01 .. OKOK
Reading FLASH input file.. OK
Entering programming mode.. OK!
Erasing device.. OK!
Programming FLASH .. OK!
Reading FLASH .. OK!
WARNING: FLASH byte address 0x0D5A is 0x00 (should be 0x80).. FAILED!
Leaving programming mode.. OK!
And the address value is changes with every programming.
If i use the old .hex-file, there's no problem.
Very strange... |
|
|
| |
|
|
|
|
|
Posted: Dec 21, 2009 - 08:21 PM |
|


Joined: Jul 18, 2005
Posts: 62937
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
| Has the code burst 32K? |
_________________
|
| |
|
|
|
|
|
Posted: Dec 21, 2009 - 08:56 PM |
|


Joined: Sep 14, 2009
Posts: 61
Location: Dresden, Germany
|
|
you mean, that it got above 32K?
No i don't think so, because AVR-Studio tells me:
Device: atmega32
Program: 10270 bytes (31.3% Full)
(.text + .data + .bootloader)
Data: 1836 bytes (89.6% Full)
(.data + .bss + .noinit) |
|
|
| |
|
|
|
|
|
Posted: Dec 22, 2009 - 09:29 AM |
|


Joined: Sep 14, 2009
Posts: 61
Location: Dresden, Germany
|
|
Ha! I could solve the problem. I forgot to copy the Makefile_mmc in my new project.
Now, everything works fine. |
|
|
| |
|
|
|
|
|
Posted: Dec 22, 2009 - 04:05 PM |
|


Joined: Sep 14, 2009
Posts: 61
Location: Dresden, Germany
|
|
No *!
I still had the old working project opened.
So with the new FatFs and the Makefile added it still doesn't work. Damn!
Any Ideas? |
|
|
| |
|
|
|
|
|
Posted: Jan 19, 2010 - 01:06 PM |
|

Joined: Mar 06, 2009
Posts: 1
|
|
My compiler gives a warning "../main.c:64: warning: implicit declaration of function 'disk_timerproc'
" when I am trying to call this function in my timer interrupt. What is this? |
|
|
| |
|
|
|
|
|
Posted: Jan 19, 2010 - 01:17 PM |
|


Joined: Jul 18, 2005
Posts: 62937
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
My main.c has:
Code:
void disk_timerproc (void); // in mmc.c
and
Code:
/*---------------------------------------------------------*/
/* 100Hz timer interrupt generated by OC2 */
/*---------------------------------------------------------*/
ISR(TIMER2_COMP_vect)
{
Timer++; /* Performance counter for this module */
disk_timerproc(); /* Drive timer procedure of low level disk I/O module */
}
then mmc.c has:
Code:
/*-----------------------------------------------------------------------*/
/* Device Timer Interrupt Procedure (Platform dependent) */
/*-----------------------------------------------------------------------*/
/* This function must be called in period of 10ms */
void disk_timerproc (void)
{
static BYTE pv;
BYTE n, s;
n = Timer1; /* 100Hz decrement timer */
if (n) Timer1 = --n;
n = Timer2;
if (n) Timer2 = --n;
etc. etc.
Does your code not have these?
(at the very least it sounds like your main.c doesn't have the declaration) |
_________________
|
| |
|
|
|
|
|
Posted: Feb 05, 2010 - 05:20 AM |
|

Joined: Oct 29, 2009
Posts: 13
|
|
|
MasterBate wrote:
No *!
I still had the old working project opened.
So with the new FatFs and the Makefile added it still doesn't work. Damn!
Any Ideas?
Try disconnecting your SD card while programming. I was getting the same error using an STK500 with the card connected.
On a different note, I've been troubleshooting this code on an ATMega32 and so far no luck. It seems like disk init and mounting are successful - both 'di 0' and 'fi 0' return rc=0. 'ds' returns
Sector size: 512
Card type: 2
OCR:
00000000 01 FE 00 03 ....
However, when I try other commands, e.g. fs or fl, I get rc=1 FR_DISK_ERR. I managed to track this down to disk_read() in mmc.c. When the CMD17 command is sent to read a single block of data, the card seems to acknowledge it correctly. But when rcvr_datablock is invoked to actually read the data, it returns an error due to an incorrect token sent by the card - correct token is 0xFE, but I see 0x01. Thus, I cannot receive any data from the card (which is a 2gb kingston). Anyone had similar problems? Help greatly appreciated. |
|
|
| |
|
|
|
|
|