Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
jokkebk
PostPosted: Apr 01, 2012 - 11:37 PM
Rookie


Joined: Apr 07, 2011
Posts: 39


After coming across quite many SD tutorials that are based on Petit FS or FatFS and guide the user through modifying these libraries, I thought it would be interesting to make one that would really start from the fundamentals of reading FAT file systems, so you'd actually understand all of the code, not just the pins you connected to your MCU.

The first part of this effort is now available, I'm planning a similar 3-5 part layout as my previous V-USB tutorial I posted here a while ago:

http://codeandlife.com/2012/04/02/simpl ... al-part-1/

The second part covers reading longer files using the file allocation table, and converts everything into a compact and portable library:

http://codeandlife.com/2012/04/07/simpl ... al-part-2/

The third part introduces the hardware built around ATmega88 and communicating with the SD card using SPI.

http://codeandlife.com/2012/04/25/simpl ... al-part-3/

The last part combines the information in parts 2 and 3 to create a simple FAT16 library for reading any 1-2 GB card.

http://codeandlife.com/2012/04/27/simpl ... al-part-4/

I might also do additional parts covering FAT32, SDHC or file writing, depending on reader interest. All and any feedback is appreciated, if you have some specific things you'd like me to cover in the future, please let me know!

_________________
http://codeandlife.com


Last edited by jokkebk on Apr 27, 2012 - 08:14 PM; edited 3 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Apr 04, 2012 - 01:59 AM
Resident


Joined: Sep 03, 2005
Posts: 832
Location: Christchurch, NZ

Excellent communications skills and very well organised. Look forward to parts 2 and 3.
 
 View user's profile Send private message  
Reply with quote Back to top
jokkebk
PostPosted: Apr 11, 2012 - 10:12 PM
Rookie


Joined: Apr 07, 2011
Posts: 39


Thanks! I do like writing tutorials a lot, it's a great way to organize my own thoughts on a given subject.

The part 2 has been published, ending up with a FAT16 library that should be easily ported to AVR (doing that in part 3). I ended up with a memory footprint of 51 bytes instead of the 44 in Petit FatFS. On the other hand, I prefer my version for code readability. Smile

_________________
http://codeandlife.com
 
 View user's profile Send private message  
Reply with quote Back to top
meteor
PostPosted: Apr 12, 2012 - 04:20 AM
Hangaround


Joined: Dec 11, 2010
Posts: 211


jokkebk wrote:
The part 2 has been published, [...]
FYI, the updated project ZIP file that you reference in part 2 seems to be missing from your website.

Thank you for writing these tutorials. I haven't had a chance yet to thoroughly read them and put them to proper use with some hardware, but playing around with SD cards and the FAT filesystem is on my AVR MCU "to do" list. Your tutorials appear to be a great guide for when I do finally get around to trying that. Nice work!

Regards,
Bill
 
 View user's profile Send private message  
Reply with quote Back to top
jokkebk
PostPosted: Apr 13, 2012 - 09:12 AM
Rookie


Joined: Apr 07, 2011
Posts: 39


meteor wrote:
jokkebk wrote:
The part 2 has been published, [...]
FYI, the updated project ZIP file that you reference in part 2 seems to be missing from your website.


Whoops, fixed that. And thanks for the kind words!

I'll look in to the hardware part this weekend (I already succeeded in communicating with SD card using bus pirate and setting up ATtiny as a SPI slave so I'm halfway there), so the part 3 might even get finished this Sunday, or at least in the beginning of next week.

_________________
http://codeandlife.com
 
 View user's profile Send private message  
Reply with quote Back to top
jokkebk
PostPosted: Apr 24, 2012 - 11:41 PM
Rookie


Joined: Apr 07, 2011
Posts: 39


Part 3 is now available. I also suggested readers to post questions to this forum instead of just to my blog, that way there's more audience for both the questions and answers.

_________________
http://codeandlife.com
 
 View user's profile Send private message  
Reply with quote Back to top
battoesai
PostPosted: May 02, 2012 - 09:37 AM
Newbie


Joined: Aug 25, 2010
Posts: 4


just about all what I need..

thanks dude
very appreciate that...
 
 View user's profile Send private message  
Reply with quote Back to top
5cript
PostPosted: May 14, 2012 - 09:43 PM
Newbie


Joined: Jan 31, 2012
Posts: 10


Awesome tutorial!
Quote:
I might also do additional parts covering FAT32, SDHC or file writing, depending on reader interest
highly interested!
Currently I am wrapping it into a C++ singleton, but I still have to write the writing routines...

EDIT: I totally forgot to say that I was able to write too a long time ago with the help of this and the Bus Pirate tutorial.
 
 View user's profile Send private message  
Reply with quote Back to top
Tiberius
PostPosted: Jun 23, 2012 - 11:01 AM
Rookie


Joined: Oct 30, 2010
Posts: 49


This is a great tutorial ! I agree, most of the resources available for interfacing SD cards are just instructions to get the FatFS libraries working.
Thanks a lot for this!

(I also love the way the tut is presented)
 
 View user's profile Send private message  
Reply with quote Back to top
jamawg
PostPosted: Feb 07, 2013 - 07:02 AM
Wannabe


Joined: Jan 27, 2012
Posts: 76


There is now a fourth part at

http://codeandlife.com/2012/04/27/simpl ... al-part-4/

however it is still sector based.

Does anyone know of something a litle higher level?

Specifically, I want to

CheckFileExists
OpenFile
fgets() // read text lines, each lind ending with \n
CloseFil

I also want to be able to write text files a line at a time ....


all of the standard fopen(), fgetc() fgets(), fprintf(), fclose() stuff

If you can help, please reply to my thread at http://www.avrfreaks.net/index.php?name ... p;t=125733

menawhile, I will continue to google
 
 View user's profile Send private message  
Reply with quote Back to top
jokkebk
PostPosted: Feb 07, 2013 - 08:08 AM
Rookie


Joined: Apr 07, 2011
Posts: 39


jamawg wrote:
There is now a fourth part at

http://codeandlife.com/2012/04/27/simpl ... al-part-4/

however it is still sector based.

Does anyone know of something a litle higher level?

Specifically, I want to

CheckFileExists
OpenFile
fgets() // read text lines, each lind ending with \n
CloseFil


Short answer also here, in hopes that it will help other readers of the tutorial...

The reading part of your question should be trivial to implement. The fat16_open_file() returns error value if file is not found, so CheckFileExists is almost 1:1 covered (you can make a wrapper function if you don't mind calling the exact same function again after you've made sure that file exists). Of course it doesn't understand complete paths (say CheckFileExists("some_dir/subdir/somefile.txt"), but writing a recursive function to handle those is quite easy.

Separate fopen() and fclose() are not needed because your AVR has no concept of file handles unless you implement them yourself. Only reason to do that would be so that you can have multiple files open - in that case you're right and some refactoring of the code would be needed (make a file handle structure to store sector and offset of open file, and create reading function that uses the data in handle instead of global library variables).

fgets() is basically reading the file byte at a time, and stopping when you get to the end or encounter '\n':

Code:

char line[20];
int len = 0;

while(len<20 && fat16_state.file_left) {
  if(fat16_read_file(1)) {
    line[len++] = *fat16_buffer;
    if(*fat16_buffer == '\n')
      break;
  } else break; // EOF or some other error
}

if(len >= 20) // too long line
  deal_with_error();
else
  line[len] = NULL; // terminate string


Quite easy, right? Note that most AVRs don't have enough memory to read long lines of text at one go. Due to memory limitations, higher level file functions are usually not feasible.

I might write an additional tutorial on writing files this month. Smile

Joonas

_________________
http://codeandlife.com
 
 View user's profile Send private message  
Reply with quote Back to top
jamawg
PostPosted: Feb 07, 2013 - 11:40 AM
Wannabe


Joined: Jan 27, 2012
Posts: 76


Thank you *very* mcuh for such a quick response - and for the code sample.

Glad that FileExists() is so simple.

I am new to such smallprocessors, though I can appreciate what you are saying. Personally, I use a UC3 which is 32-bit so things might be easier for me. But I guess that I won't find an existign library to make things look just liek a larger processor and standard C system calls(?)

Just to show you my mindset, I was wanting to process an INI file. I can see that I might have to rethink that ...

I look forward to the next part of your tutorial.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Feb 07, 2013 - 03:43 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71119
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

But I guess that I won't find an existign library to make things look just liek a larger processor and standard C system calls(?)
Eh? Surely FatFs does exactly that?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
jamawg
PostPosted: Feb 08, 2013 - 02:44 AM
Wannabe


Joined: Jan 27, 2012
Posts: 76


clawson wrote:
Quote:

But I guess that I won't find an existing library to make things look just like a larger processor and standard C system calls(?)
Eh? Surely FatFs does exactly that?


Thanks very much for replying. Obviously, I am missing something.

Sorry to be such a n00b, but can you point me at the FatFs you speak of? With a URL?

All that I could find was http://asf.atmel.com/docs/latest/uc3a/h ... __fat.html

Is that the one? Can I use it open a file? To get a line with fgets() or even fscanf() & similar for writing? It doesn't seem so.

I am sure that this is do-able, but can't find where. This is my first Atmel project - I guess we all have to start somewhere.

Thanks again for any help.
 
 View user's profile Send private message  
Reply with quote Back to top
jmulchin
PostPosted: Feb 08, 2013 - 04:00 AM
Rookie


Joined: Aug 01, 2004
Posts: 46
Location: Orange County, California

The FatFS URL is

http://elm-chan.org/fsw/ff/00index_e.html

Jerry
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Feb 08, 2013 - 11:22 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71119
Location: (using avr-gcc in) Finchingfield, Essex, England

I only said "fatfs" because I know for a fact that if you type nothing but that one word into Google it's the top hit.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
ombedded
PostPosted: Sep 17, 2013 - 10:31 AM
Newbie


Joined: Sep 15, 2013
Posts: 6
Location: Auckland, New Zealand

I learnt a lot from the tutorial. I am quite new to embedded programming and trying to communicate with SD card using atmega32. I flashed the SPI.c provided on the http://codeandlife.com/2012/04/25/simpl ... al-part-3/ but I am getting response CMD 40 FF FF FF FF FF FF FF FF
CMD 41 FF FF FF FF FF FF FF FF

I am not sure where I am going wrong. I have connected my circuit like https://dlnmh9ip6v2uc.cloudfront.net/im ... g/ST-3.jpg
 
 View user's profile Send private message  
Reply with quote Back to top
bianchi77
PostPosted: Feb 07, 2014 - 12:25 AM
Resident


Joined: May 02, 2013
Posts: 887
Location: Perth,Western Australia

I didn't get any response from SPI, anyone has idea ?

Here's the code for ATMEGA128
Yes Usart is working, I tested on the first time program running, I used ATMEGA128
main :
Code:


#define SD_CS_ASSERT PORTB &= ~0x01
#define SD_CS_DEASSERT PORTB |= 0x01
#define CS (1<<PB0)
#define MOSI (1<<PB2)
#define MISO (1<<PB3)
#define SCK (1<<PB1)
#define CS_DDR DDRB
#define CS_ENABLE() (PORTB &= ~CS)
#define CS_DISABLE() (PORTB |= CS)

void port_init(void)
{
CS_DDR |= CS; // SD card circuit select as output
DDRB |= MOSI + SCK; // MOSI and SCK as outputs
PORTB |= MISO; // pullup in MISO, might not be needed

}

void spi_init(void)
{
SPCR = _BV(SPE)|_BV(MSTR)|_BV(SPR1)|_BV(SPR0);
SPSR &= ~_BV(SPI2X);
}

unsigned char SPI_transmit(unsigned char data)
{
// Start transmission
SPDR = data;

// Wait for transmission complete
while(!(SPSR & (1<<SPIF)));

return SPDR;
}
int main (void)
{
unsigned char option;
port_init();
spi_init();
usart_init(BAUD_PRESCALE);

usart_pstr("USART READY!");
while(1)
{
option = usart_receive();
switch(option)
{
case '1':
usart_pstr("1 command");
SD_command(0x40, 0x00000000, 0x95, 8);
break;
case '2':
SD_command(0x41, 0x00000000, 0xFF, 8);
usart_pstr("2 command");
break;
case '3':
SD_command(0x50, 0x00000200, 0xFF, 8);
usart_pstr("3 command");
break;
}

}
}
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits