Atmega2560 and FatFs(avr foolproof)

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

Hi, i am going to use FatFs in mega2560 and since space is no more an issue i was wondering if i can use AVRfoolproof version of the library? its inside the Samples

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

Interesting. I last pulled a copy of ffsample.zip on Jun22nd and that wasn't there. Now you mention it I see ffsample.zip was updated on July 28th. So this was something new added since then. In the readme file the log shows:

  Jul 28, 2013  Added a foolproof project for ATMEL AVR.

It also says:

        ATMEL AVR complex (ATmega64)
      ATMEL AVR foolproof (>=16K devices)

but there doesn't seem to be much else to explain the difference/merits of one versus the other.

The only differences I can see when comparing the common files in both directories are:

E:\ffsample-jun28>diff avr\diskio.h avrfp\diskio.h
12,14d11
< #define _USE_WRITE    1       /* 1: Enable disk_write function */
< #define _USE_IOCTL    1       /* 1: Enable disk_ioctl fucntion */
<
38d34
< #if   _USE_WRITE
40,41d35
< #endif
< #if   _USE_IOCTL
43,44d36
< #endif
< void disk_timerproc (void);
E:\ffsample-jun28>diff avr\ffconf.h avrfp\ffconf.h
29c29
< #define _FS_MINIMIZE  0       /* 0 to 3 */
---
> #define _FS_MINIMIZE  3       /* 0 to 3 */
43c43
< #define       _USE_MKFS               1       /* 0:Disable or 1:Enable */
---
> #define       _USE_MKFS               0       /* 0:Disable or 1:Enable */
51c51
< #define _USE_LABEL            1       /* 0:Disable or 1:Enable */
---
> #define _USE_LABEL            0       /* 0:Disable or 1:Enable */
63c63
< #define _CODE_PAGE    932
---
> #define _CODE_PAGE    437
116c116
< #define _FS_RPATH             2       /* 0 to 2 */
---
> #define _FS_RPATH             0       /* 0 to 2 */
130c130
< #define _VOLUMES      2
---
> #define _VOLUMES      1

and then a HUGE difference between their main.c files. The one in the avr\ directory has the usual huge test program that you usually end up throwing away. The one in avrfp is "bared to the bone".

So in effect it seems the only real difference in "avrfp" is that he's thrown away all the stuff you usually don't use and left main.c as the bare bones for an implementation:

E:\ffsample-jun28>type avrfp\main.c
/*----------------------------------------------------------------------*/
/* Foolproof FatFs sample project for AVR              (C)ChaN, 2013    */
/*----------------------------------------------------------------------*/

#include 
#include "ff.h"

FATFS FatFs;    /* FatFs work area */
FIL Fil;                /* File object */


int main (void)
{
        UINT bw;


        f_mount(0, &FatFs);             /* Give a work area to the FatFs module */

        if (f_open(&Fil, "newfile.txt", FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) {        /* Create a file */

                f_write(&Fil, "It works!\r\n", 11, &bw);        /* Write data to the file */

                f_close(&Fil);                                                          /* Close the file */

                if (bw == 11) {         /* Lights green LED if data written well */
                        DDRB |= 0x10; PORTB |= 0x10;    /* Set PB4 high */
                }
        }

        for (;;) ;
}



/*---------------------------------------------------------*/
/* User Provided RTC Function called by FatFs module       */

DWORD get_fattime (void)
{
        /* Returns current time packed into a DWORD variable */
        return    ((DWORD)(2013 - 1980) << 25)  /* Year 2013 */
                        | ((DWORD)7 << 21)                              /* Month 7 */
                        | ((DWORD)28 << 16)                             /* Mday 28 */
                        | ((DWORD)0 << 11)                              /* Hour 0 */
                        | ((DWORD)0 << 5)                               /* Min 0 */
                        | ((DWORD)0 >> 1);                              /* Sec 0 */
}

So, yes, there seems to be no reason to not use the avrfp version as it's a little closer to what you would have done anyway. By throwing away the huge test program it acts as a seeing the wood from the trees exercise so you can concentrate on the bits you really need.

I'm not sure why he's implemented a whole new avrfp\ directory though? Why not just two main.c files or even one with a #ifdef protection around the unneeded stuff?

EDIT: actually there's a serious fault there - he's cut TOO MUCH from the cut-down main. There's supposed to be a 100ms timer that increments the timeout variables. That seems to have gone completely. So I don't see how the avrfp version would actually work?!?!

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

Well you took quite some time studying it :) i guess ill have to try it to see if it works. But am afraid being a beginner it wont be easy to get something new running so i will perhaps stick with the older code.

btw in the sdmmc.c file, he has implemented a delay routine and it is used in this file. May be that is why he removed the timer for creating delay

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

My post in the FatFs tutorial thread that worked through the Jun 22nd code:

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

Should still be valid. Maybe compare the main() I ended up with there to this "foolproof" one. The main difference you will see is that I started a timer with an interrupt that then made calls to disk_timerproc(). The avrfp code seems to be missing that.

The interrupt driven timers ARE necessary because mmc.c contains code such as this:

		for (Timer1 = 20; Timer1; );	/* Wait for 20ms */

If there wasn't something ticking away, decrementing Timer1 while non-zero then that loop would never end. Similarly:

		Timer1 = 100;						/* Initialization timeout of 1000 msec */
		if (send_cmd(CMD8, 0x1AA) == 1) {	/* SDv2? */
			for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);		/* Get trailing return value of R7 resp */
			if (ocr[2] == 0x01 && ocr[3] == 0xAA) {				/* The card can work at vdd range of 2.7-3.6V */
				while (Timer1 && send_cmd(ACMD41, 1UL << 30));	/* Wait for leaving idle state (ACMD41 with HCS bit) */
				if (Timer1 && send_cmd(CMD58, 0) == 0) {		/* Check CCS bit in the OCR */
					for (n = 0; n < 4; n++) ocr[n] = xchg_spi(0xFF);
					ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;	/* SDv2 */
				}
			}
		} else {							/* SDv1 or MMCv3 */

These timeouts would never break out of the look if "Timer1" was not ticking down.