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
kubark42
PostPosted: Jul 24, 2008 - 04:30 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


NOTE: This thread is an evolving work. E L Chan continues to develop FatFs and this first post is based on his version back in 2008. It has changed a lot over the years. So yes, read just this first post and understand some of the things you need to do to adapt FatFs for yourown use but you MUST red all pages (currently 15 as I write this) to understand later changes that have happened in the FatFs code. After reading to the end of the thread you are then ready to start work. You will probably end up using one of the worked examples in the later pages of this thread - not necessarily just this first post. Moderator, August 2013

FatFS is a great library for getting FAT12/FAT16/FAT32 running on pretty much any C platform http://elm-chan.org/fsw/ff/00index_e.html. The developer even took the time to provide example code for pretty much any application you could want. The problem that I ran into, however, is that the code isn't very easy to adapt, unless you spend a lot of timing pouring over it and troubleshooting.

This tutorial is primarily aimed at people who have little idea about how to program AVRs and want to spend more time developing their ideas and less time trouble-shooting the back-end. I hope that this tutorial helps you cut to the chase and have a working MMC/SD card interface in just a few minutes.

First off, let me point out that this code is running on an ATmega644p, developed on an STK500. I'm using a Kingston microSD card that I can plug into a miniSD adapter (that I soldered to wires so that I could plug them directly into the SPI pins) or into a normal adapter (that I can plug into a computer SD card reader).

My pinout looks like this:

DAT1-------NC
DO---------MISO (PB6)
Vss2-------GND
CLK--------SCK (PB7)
Vcc--------3.3V (PC0)
Vss1-------GND
DI---------MOSI (PB5)
CS---------SS (PC1)
DAT2-------NC

with no extra components. (In retrospect, it's probably not a bad idea to put a capacitor at the 3.3V input to the SD card, in order to make sure voltage doesn't sag.)

For this tutorial, you will need a uC with at least 32K of flash memory and 4K of internal SRAM. (Of course, by disabling many of the functions and using Tiny-FatFS, it can be made far smaller, but that is outside the scope of this tutorial.)

The code is very comprehensive, but there are a few things that are overengineered, and were causing serious problems with my ATmega644p.

For instance, the UART code is very dense, and makes use of interrupts, which somewhat complicates things (the code is no longer linear, as the interrupts can, well, interrupt) and makes it harder to understand for beginners. It also uses a FIFO buffer, which is again overkill for a program that patiently waits until the user inputs a two letter combination.

Anyhoo... Don't get me wrong, it's a GREAT library! I just think that for a first time user it's a little harder than it should be.

CAVEAT!!!:
Quote:
You MUST use 3.5V or less on both the SD card, and the SPI lines. If your chip is already running at <3.5V, great, otherwise you NEED level converters. Don't be mad at me if you blow up your SD card because you gave it too much juice. (They like 3.3V, but will tolerate 3.5V.)

Now on to the good stuff. Start by downloading the ffsample.zip package from http://elm-chan.org/fsw/ff/00index_e.html. Unzip the avr directory-- it's the only one you will need.

This next step is optional; it's only to help clean the directory. Delete/move the following files (They're unnecessary for SD card support, although they don't hurt anything if you leave them there.):
    ata.c
    cfc.c
    cfmm.c
    Makefile_ata
    Makefile_ata2
    Makefile_cfc
    Makefile_cfc2
    Makefile_cfmm

makefile

Next, modify "MCU_TARGET = atmega64" (line 3 or so) in both Makefile_mmc and Makefile_mmc2 to match your uC. I'm using a ATmega644p so I replaced "atmega64" with "atmega644p".

Next, make a copy of Makefile_mmc and rename it Makefile. (Makefile_mmc2 is for Tiny-FatFS, which we'll get to later. The modifications to one apply to the other, with the exception of a couple bugs that needed fixing.)

Right now, if you were to compile it, there's a good chance it wouldn't even compile because of different register names between uC. This is certainly the case between the atmega64 and the atmega644p. So let's fix that.


main.c

If you read the warnings, you'll probably see that most of the errors are in main.c where the ATmega64 has a LOT more ports than your standard avr chip. So fire up your favorite text editor (I use Smultron), and take a look at the IoInit() function.

First, find the function ISR(TIMER2_COMP_vect). You need to check that this is the correct vector name. It wasn't for me. Looking on the Interrupt Vector table in the ATmega644p's documentation, I saw I had to change it to:
Code:
TIMER2_COMPA_vect
(Remember, "_vect" must be put at the end of the vector name in the table)

Comment ALL the lines out from PORTA = ... to PORTG=...
(See further down for how this looks). You'll eventually need to feed the SD card 3.3V, so later on you might reactivate ONE (1) pin, but you certainly don't need all of them.

Next, a little bit further down in the same function (line 196 or so) you might need to change the Timer2 variables. Be careful here, as it's not as simple as just renaming the variables. The registers might have changed, too. By looking on the ATmega64 datasheet, you can see on page 160 that OCR2 is the Output Compare Register for Timer2, an 8-bit timer. Cross-referencing to the ATmega644p datasheet, you see that there are TWO (2) Output Compare Registers. I chose to replace OCR2 with OCR2A, but I expect it would have worked just fine with OCR2B, also.

You'll also probably need to change TCRR2 and TIMSK, but be careful, as you might need to change the value written to the register, too. In my case, again comparing datasheets, on page 157 I found that originally, TCCR2 bits WGM21, CS22, and CS20 are written high. On the ATmega644p, page 153-156, I found that the TCCR2 register has been split into two parts, and so in order to enable all the original bits, I had to write to both TCCR2A and TCCR2B. Likewise for TIMSK, where on page 160 you see that only OCIE2 is high. On the ATmega644p, I had to set TIMSK2 (I don't know why there is a two here and not on the ATmega64) for OCIE2A.

Lastly, two lines later comment out sei();. The final function now looks like this:
Code:
//   PORTA = 0b11111111;   // Port A

//   PORTB = 0b10110000; // Port B
//   DDRB  = 0b11000000;

//   PORTC = 0b11111111;   // Port C

//   PORTD = 0b11111111; // Port D

//   PORTE = 0b11110010; // Port E
//   DDRE  = 0b10000010;

//   PORTF = 0b11111111;   // Port F

//   PORTG = 0b11111;    // Port G
   OCR2A = 90-1;      // Timer2: 100Hz interval (OC2)
   TCCR2A = 0b00000010;
   TCCR2B = 0b00000101;

   TIMSK2 = 0b00000010;   // Enable TC2.oc interrupt

   rtc_init();         // Initialize RTC

//   sei();


mmc.c

Now it still won't compile for most of us, but we're almost there. We need to fix some things in mmc.c. We will make a lot of modifications, so you might want to back it up, too.

Again, on my chip I don't have a PORTE, so of course this fails. Moreover, the pins for the SPI port on the ATmega64 and ATmega644p are different.

Start by adding the following lines right after the #include section.
Code:
/*SPI configuration*/
#define DD_MOSI   DDB5
#define DD_SCK   DDB7
#define DDR_SPI   DDRB
#define DD_SS   4

/* Defines for SD card SPI access */
#define SD_CS_PIN   1
#define SD_CS_PORT   PORTC
#define SD_PWR_PIN   0
#define SD_PWR_PORT   PORTC

These defines will all have to be modified to your particular ATmega and setup. The DD_* #defines can be found in the I/O Ports-->Alternate Port Functions section.

The SD_* #defines are up to you. I chose to conenct the SD card's power supply to PIN0 (you did make sure you're not outputting more than 3.5V, right???) chip select to PIN1 of PORTC, but you could chose another if it were more convenient. Just avoid using one of the four pins associated with the SPI port. You can even comment out the SD_PWR_* if you have an alternate power supply (in this case, you have a 3.3V level converter on the SPI I/O pins, right???)

Continuing on, modify the #define SELECT() and #define DESELECT() as so:
Code:
#define SELECT()      SD_CS_PORT &= ~(1<<SD_CS_PIN)      /* MMC CS = L */
#define DESELECT()   SD_CS_PORT |=  (1<<SD_CS_PIN)      /* MMC CS = H */

Then delete these three lines:

Code:
#define SOCKPORT   PINB         /* Socket contact port */
#define SOCKWP      0x20         /* Write protect switch (PB5) */
#define SOCKINS      0x10         /* Card detect switch (PB4) */

Next, go to the power_on(void) function and replace it with
Code:
static
void power_on (void)
{
#if (defined SD_PWR_PIN | defined SD_PWR_PORT)
   DDRC|=(1<<SD_PWR_PIN);          // Turns on PWR pin as output
   SD_PWR_PORT|=(1<<SD_PWR_PIN);   // Drives PWR pin high
#endif

   DDRC|=(1<<SD_CS_PIN);          // Turns on CS pin as output
   DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)| (1<<DD_SS);
   SPCR = (1<<SPE)|(1<<MSTR); /* Initialize SPI port (Mode 0) */
}

Change power_off(void) to:
Code:
static
void power_off (void)
{
   SELECT();            /* Wait for card ready */
   wait_ready();
   release_spi();
   Stat |= STA_NOINIT;      /* Set STA_NOINIT */
}

and change chk_power(void) to
Code:
static
int chk_power(void)      /* Socket power state: 0=off, 1=on */
{
   return 1;
}

Finally, at the very end, replace the function disk_timerproc(void) with:
Code:
void disk_timerproc (void)
{
   BYTE n;

   n=Timer1;                  /* 100Hz decrement timer */
   if(n)
      Timer1 = --n;
   n=Timer2;
   if(n)
      Timer2 = --n;
}

The code will probably now compile, but it almost certainly won't work. There are still some more modifications to make.


uart.c

First, let's get rid of the original uarts code and replace it with something a little easier to understand. Simply rename the existing uart.c, for example to uart.c.old, and save this code as a new uarts.c:
Code:
/*------------------------------------------------*/
/* UART functions                                 */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "uart.h"

#define   BAUD      9600

void USART_Transmit( unsigned char txData )
{
   /* Wait for empty transmit buffer */
   while ( !( UCSR0A & (1<<UDRE0)) );
   /* Put data into buffer, sends the data */
   UDR0 = txData;
}

void USART_set_baud_rate(double baudrate)
{
   // calculate division factor for requested baud rate, and set it
   int bauddiv = ((F_CPU+(baudrate*8L))/(baudrate*16L)-1);
   UBRR0L= bauddiv;
#ifdef UBRR0H
   UBRR0H= (bauddiv>>8);
#endif
}

/* Initialize UART */

void uart_init()
{
   UCSR0B = (1<<RXEN0)|(1<<TXEN0);      // Turn on U(S)ART port
   UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);   // Set frame format: 8 data bits, 1 stop bit, no parity
   USART_set_baud_rate(BAUD); //Set baud rate
}


/* Get a received character */
uint8_t uart_get ()
{
   unsigned char d;
   while ((UCSR0A & (1 << RXC0)) == 0) {}; // Do nothing until data have been recieved and is ready to be read from UDR
   d=UDR0;
   return d;
}

/* Transmit a character */
void uart_put(uint8_t d)
{
   
   USART_Transmit( d );
}

/* Transmit a string */
void uart_puts(const char *s)
{
   while (*s)
      USART_Transmit( *s++ );
}


uart.h

You'll also need to backup uart.h (uart.h.old, perhaps), and replace it with:
Code:
void uart_init(void);         /* Initialize UART */
uint8_t uart_get (void);      /* Get a byte from UART Rx */
uint8_t uart_test(void);      /* Check number of data in UART Rx FIFO */
void uart_put(unsigned char);   /* Transmit a byte*/
void uart_puts(const char *s);   /* Transmit a string of bytes*/

If you have trouble understand what this does, check out abcminiuser's excellent tutorial on USART.

Next, let's look at the rtc clock. While what was done in the example was very comprehensive, this is far too much for a simple data logging operation. Let's just trim this down to the bare minimum. I'll leave the function structure there because it could come in handy later on, especially if you want to run a clock off the internal oscillator-- even if it's inaccurate, it will still be accurate enough to let you know approximately when a file was made.

Again, backup rtc.c-- to for instance rtc.c.old-- and save this code to a new rtc.c
Code:
/*--------------------------------------------------------------------------*/
/*  RTC controls                                                            */

#include <avr/io.h>
#include <string.h>
#include "rtc.h"

BOOL rtc_gettime (RTC *rtc)
{

//   BYTE buf[8];

//   rtc_read() //This is where you would read the clock.
   
//   rtc->sec = (buf[0] & 0x0F) + ((buf[0] >> 4) & 7) * 10;
//   rtc->min = (buf[1] & 0x0F) + (buf[1] >> 4) * 10;
//   rtc->hour = (buf[2] & 0x0F) + ((buf[2] >> 4) & 3) * 10;
//   rtc->mday = (buf[4] & 0x0F) + ((buf[4] >> 4) & 3) * 10;
//   rtc->month = (buf[5] & 0x0F) + ((buf[5] >> 4) & 1) * 10;
//   rtc->year = 2000 + (buf[6] & 0x0F) + (buf[6] >> 4) * 10;


   //This code is just to provide some kind of a valid response.
   rtc->sec = 1;
   rtc->min = 2;
   rtc->hour = 3;
   rtc->mday = 4;
   rtc->month = 5;
   rtc->year = 2006;


   return TRUE;
}

BOOL rtc_settime (const RTC *rtc)
{
   BYTE buf[8];

   buf[0] = rtc->sec / 10 * 16 + rtc->sec % 10;
   buf[1] = rtc->min / 10 * 16 + rtc->min % 10;
   buf[2] = rtc->hour / 10 * 16 + rtc->hour % 10;
   buf[3] = 0;
   buf[4] = rtc->mday / 10 * 16 + rtc->mday % 10;
   buf[5] = rtc->month / 10 * 16 + rtc->month % 10;
   buf[6] = (rtc->year - 2000) / 10 * 16 + (rtc->year - 2000) % 10;

/*This is where you would set the new time to the clock*/

   return TRUE;
}

BOOL rtc_init (void)
{
   BYTE buf[8];   /* RTC R/W buffer */
//   UINT n;

   /* Read RTC */
//   rtc_read() //This is where you would read the clock the first time.

   if (/*SOMETHING_IS_WRONG*/0) {   /* When RTC data has been broken, set default time */
      /* Reset time to Jan 1, '08 */
      memset(buf, 0, 8);
      buf[4] = 1; buf[5] = 1; buf[6] = 8;
//      rtc_write(buf);
      /* Clear data memory */
      memset(buf, 0, 8);
//      for (n = 8; n < 64; n += 8)
//         rtc_write(buf);
      return FALSE;
   }
   return TRUE;
}


There you go, all done! Now just type make in the directory root and you should have a hex file ready to be uploaded to your uC.

CAVEAT!!!:
Quote:
On many uC, the SPI port is the same as the ISP port, so you may have problems uploading the program if the uC is connected to the memory card. I do, so I have to remove it every time I want to upload, otherwise I get an error.


Once you upload the hex file, you need to interface with the program through a serial terminal. It's a very simple interface, although it's not well documented. Commands are given in two-letter combinations, followed by a parameter, if one is needed. If the command was correctly formatted, there is ALWAYS a response of the form:
Code:
rc=
To get started, you need to initialize the disk. Type:
Code:
di 0
This is a Disk Initialize for disk #0. Afterward, assuming the sd card is already formatted, type:
Code:
fi 0
which means File-system Initialize for disk #0. Now you can access the disk structure by typing
Code:
fl

which means File-system List.

If you get this far and it seems to respond, then everything is just fine. (If not, post here and hopefully someone will help you.) There are many more commands, but you can discover them for yourself by looking in the for(;;) loop in main.c

Enjoy!

--Kenn



P.S. If you want to try Tiny-FatFS, just apply the same modifications to main2.c as above, copy Makefile_mmc2 to Makefile, and recompile with
Code:
make clean
make


Edit: Fixed typos, added suggestion for capacitor on 3.3V input.


Last edited by kubark42 on Dec 07, 2009 - 09:28 AM; edited 6 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 24, 2008 - 05:49 PM
10k+ Postman


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

Wow - thanks for this - I just bought one of these:

http://www.futurlec.com/Mini_SC.shtml

and was about to start "playing" !

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Jul 25, 2008 - 12:48 AM
Resident


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

Yes, thanks a lot for writing this up. Currently, I am looking at interfacing a SD card to my ATmega32 and this TUT will be a great help.

davef
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Jul 25, 2008 - 10:26 AM
Resident


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

Thought I'd just try compiling it for the ATmega64, before making changes and the error file doesn't look too good. BTW, it generates the hex file.

What compiler are you using? With WinAVR 20071221 I get the following:
(I think I have seen this "signedness" issue moving from older versions of WinAVR)

Quote:

> "make" all
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=atmega64 -c -o main.o main.c
main.c: In function 'main':
main.c:235: warning: pointer targets in passing argument 1 of 'get_line' differ in signedness
main.c:236: warning: pointer targets in assignment differ in signedness
main.c:243: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:244: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:249: warning: pointer targets in assignment differ in signedness
main.c:250: warning: pointer targets in passing argument 1 of 'put_dump' differ in signedness
main.c:254: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:259: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:289: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:290: warning: pointer targets in assignment differ in signedness
main.c:291: warning: pointer targets in passing argument 1 of 'put_dump' differ in signedness
main.c:295: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:296: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:299: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:304: warning: pointer targets in passing argument 1 of 'get_line' differ in signedness
main.c:305: warning: pointer targets in assignment differ in signedness
main.c:308: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:316: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:317: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:318: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:323: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:324: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:325: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:330: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:341: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:393: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:402: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:410: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:426: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:440: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:440: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:478: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:478: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:483: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:483: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:483: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:485: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:485: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:485: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:524: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:524: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:524: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:534: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:536: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:537: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:538: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:539: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
main.c:540: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
C:\DOCUME~1\Sander\LOCALS~1\Temp/ccJ6Gurb.s: Assembler messages:
C:\DOCUME~1\Sander\LOCALS~1\Temp/ccJ6Gurb.s:1503: Warning: expression dangerous with linker stubs
C:\DOCUME~1\Sander\LOCALS~1\Temp/ccJ6Gurb.s:1504: Warning: expression dangerous with linker stubs
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=atmega64 -c -o uart.o uart.c
avr-gcc -c -mmcu=atmega64 -I. -x assembler-with-cpp -Wa,-adhlns=xitoa.lst,-gstabs xitoa.S -o xitoa.o
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=atmega64 -c -o ff.o ff.c
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=atmega64 -c -o mmc.o mmc.c
C:\DOCUME~1\Sander\LOCALS~1\Temp/cc7GywOR.s: Assembler messages:
C:\DOCUME~1\Sander\LOCALS~1\Temp/cc7GywOR.s:1291: Warning: expression dangerous with linker stubs
C:\DOCUME~1\Sander\LOCALS~1\Temp/cc7GywOR.s:1292: Warning: expression dangerous with linker stubs
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=atmega64 -c -o rtc.o rtc.c
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=atmega64 -Wl,-Map,avr_mmc.map -o avr_mmc.elf main.o uart.o xitoa.o ff.o mmc.o rtc.o
avr-objdump -h -S avr_mmc.elf > avr_mmc.lst
avr-objcopy -j .text -j .data -O ihex avr_mmc.elf avr_mmc.hex
avr-size -C --mcu=atmega64 avr_mmc.elf
AVR Memory Usage
----------------
Device: atmega64

Program: 23910 bytes (36.5% Full)
(.text + .data + .bootloader)

Data: 2494 bytes (60.9% Full)
(.data + .bss + .noinit)



> Process Exit Code: 0
> Time Taken: 00:11


A minor typo in the last line (of the tutorial), I think you mean Makefile_mmc2. BTW, excellent job of writing it up.

Any suggestions to clean up the errors?

Thanks,
davef
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jul 25, 2008 - 10:36 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Hmm... strange. I didn't get that kind of error for xitoa.o, but if you're using an older WinAVR, why not upgrade? I just learned that a new version (20080610) came out last month, so maybe this will work right out of the box. In any case, once I get to work I'll check and see what WinAVR I'm using. It's possible there's a mistake in the [TUT], but I don't know what that is because I didn't touch xitoa.S.

P.S. Fixed the typo. Thanks!

P.P.S. It seems you fixed the error, as the output now compiles. What was it?
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Jul 25, 2008 - 11:32 AM
Resident


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

Initially, when I deleted the files that weren't needed I must have deleted xitoa.S
When I put it in the project the .hex file was generated, but with all the above warnings.

I am using WinAvr-20071221. The signedness issues I mentioned happened when I upgraded from a 2006 or 2005 version. I have WinAVR-20080610, I'll give that a try in the next few days.

I found that Tiny-FatFS, as in the source, is not really much smaller. As suggested I would need to eliminate functions to try and get it into an ATmega32. A friend is just in the process of developing a board with the ATmega128 on it. Perhaps good timing!

davef
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 25, 2008 - 11:38 AM
10k+ Postman


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

Quote:
I found that Tiny-FatFS, as in the source, is not really much smaller.

I thought it was "tiny" in the sense of reduced RAM usage, not necessarily reduced code space usage.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Jul 25, 2008 - 12:03 PM
Resident


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

Quote:
AVR Memory Usage
----------------
Device: atmega64

Program: 20470 bytes (31.2% Full)
(.text + .data + .bootloader)

Data: 2914 bytes (71.1% Full)
(.data + .bss + .noinit)


I thought Data was RAM Embarassed How can you tell how much RAM it is going to use?


Last edited by davef on Jul 25, 2008 - 12:07 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 25, 2008 - 12:05 PM
10k+ Postman


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

Data in that context IS RAM

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jul 25, 2008 - 12:32 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


clawson wrote:
Quote:
I found that Tiny-FatFS, as in the source, is not really much smaller.

I thought it was "tiny" in the sense of reduced RAM usage, not necessarily reduced code space usage.


I think that you have to configure it for read only, minimize, etc... (all in the header file (t)ff.h) in order to really reduce the code base. I'll have to do a couple tests once I get everything going to see what kind of difference it makes. Maybe not enough to shoehorn it into a 16K one, but perhaps enough to run some reasonably big code alongside FatFS on a 32K. Since I'm using a 64K module for some simple data logging, it doesn't really make any difference to me.

==========================================
UPDATE:
==========================================

I just ran a couple experiments with my current code. I don't use have any of the functions that are removed, so this is just the difference in program size for the exact same program. ~4K is quite a big difference, especially if it's the difference between a 32K chip and a 64K one!

_FS_MINIMIZE=0
Code:
AVR Memory Usage
----------------
Device: atmega644p

Program: 23726 bytes (36.2% Full)
(.text + .data + .bootloader)

Data: 1687 bytes (41.2% Full)
(.data + .bss + .noinit)


_FS_MINIMIZE=1
Code:
AVR Memory Usage
----------------
Device: atmega644p

Program: 21116 bytes (32.2% Full)
(.text + .data + .bootloader)

Data: 1687 bytes (41.2% Full)
(.data + .bss + .noinit)


_FS_MINIMIZE=2
Code:
AVR Memory Usage
----------------
Device: atmega644p

Program: 20414 bytes (31.1% Full)
(.text + .data + .bootloader)

Data: 1687 bytes (41.2% Full)
(.data + .bss + .noinit)


_FS_MINIMIZE=3
Code:
AVR Memory Usage
----------------
Device: atmega644p

Program: 19682 bytes (30.0% Full)
(.text + .data + .bootloader)

Data: 1687 bytes (41.2% Full)
(.data + .bss + .noinit)
 
 View user's profile Send private message  
Reply with quote Back to top
divgup
PostPosted: Sep 01, 2008 - 07:29 PM
Rookie


Joined: Sep 01, 2008
Posts: 28
Location: India,Delhi

hi from where can i get he code to build this amazing project..
this link i not functional http://elm-chan.org/fsw/ff/ffsample.zip

please forward me the file
divyansh@ymail.com
thanx in advance..
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
divgup
PostPosted: Sep 01, 2008 - 07:30 PM
Rookie


Joined: Sep 01, 2008
Posts: 28
Location: India,Delhi

hi from where can i get he code to build this amazing project..
this link i not functional http://elm-chan.org/fsw/ff/ffsample.zip

please forward me the file
divyansh@ymail.com
thanx in advance..
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
clawson
PostPosted: Sep 01, 2008 - 07:32 PM
10k+ Postman


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

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

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
clarke61
PostPosted: Sep 03, 2008 - 07:25 AM
Newbie


Joined: Jul 09, 2006
Posts: 7


Pointer to where I can learn about the xitoa function?
I can't find any definition about xitoa on the net. Seems odd, but this SD/MMC FATFS seems to be about the only piece of code that uses xitoa. It's not in the WINAVR library.
Especially this piece of code: !xatoi(&ptr, &p1) what is this doing?

Thanks
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Sep 03, 2008 - 08:16 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


As near as I can figure, xitoa seems to be Chen's implementation of an eXtended print-to-console API. I quite like it, and I now use it in a lot of other programs. For the most part, you would use it as you would use the normal functions in a C program running in the terminal. There are a couple ones which change functionality somewhat, notably xitoa(), which allows you to print directly to the serial port, instead of first printing to a string buffer and then writing the buffer to the port.

Quote:
Especially this piece of code: !xatoi(&ptr, &p1) what is this doing?


I have no idea what that does. There's some funky pointer-fu that I don't really understand in Chen's work. Of course, maybe with a bit more context it might be easier to grok.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Sep 03, 2008 - 11:55 AM
10k+ Postman


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

Quote:
Especially this piece of code: !xatoi(&ptr, &p1) what is this doing?

Well ptr is going to be a pointer to a string of digits such as "0x1F2C" or "0b101010" or whatever and p1 is a pointer to a 'long' variable that will take the result. The code then does a pretty standard atoi() style conversion but if it finds an "illegal" character (such as "01F2C" being passed without the 'x') it returns 0 rather than 1. So all the uses tend to be "if (!xatoi(&ptr, &p1)) break;" so that it doesn't use an illegally converted result.

You can see all this in the asm code in xitoa.S

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
H. Carl Ott
PostPosted: Oct 09, 2008 - 07:38 PM
Hangaround


Joined: Oct 03, 2001
Posts: 285
Location: NYC, USA

Hi Folks,
I just started playing around with the FAT FS code.
Seems to compile, but I'm also getting that signedness warning (about 50 times).

Using winavr 20080610
Quote:
main.c:235: warning: pointer targets in passing argument 1 of 'get_line' differ in signedness


Pretty much a noob with c. I sort of get the issue of unsigned versus signed char pointers, but with elm chans extended print routines being in assembler I'm lost. Was there an easy fix found for this error (other then going back to an earlier version of winavr)?

BTW, the -funsigned-char flag has no effect. But I don't know if that would affect pointers.

Thanks,

-carl
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Oct 10, 2008 - 09:39 AM
10k+ Postman


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

That's a benign warning - ignore it.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
H. Carl Ott
PostPosted: Oct 12, 2008 - 04:42 PM
Hangaround


Joined: Oct 03, 2001
Posts: 285
Location: NYC, USA

clawson,
Thanks, as long as it's benign I guess I can ignore it.

In general, I like to get rid of these warnings, especially when there are 40-50 of them. When an additional non-benign warning pops up (as I learn and develop new code) it tends to get lost in the field of all these other ignorable warnings.

I'll check to see if I can suppress this particular warning msg. Additionally, if this is becoming a more general gcc question, I'll take it over to the avr gcc forum.

-carl
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Oct 12, 2008 - 05:07 PM
10k+ Postman


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

It was one of the recent GCC releases where that over-aggressive warning started to appear. As it doesn't help much and causes a lot of people concern I think moves are afoot to revert the behaviour in future.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
divgup
PostPosted: Oct 24, 2008 - 06:00 PM
Rookie


Joined: Sep 01, 2008
Posts: 28
Location: India,Delhi

successfully compiled elmchan code..
I am able to read the MBR but not able find files..
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
kubark42
PostPosted: Oct 24, 2008 - 06:22 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


divgup wrote:
successfully compiled elmchan code..
I am able to read the MBR but not able find files..


That could be a million things. Would it have hurt you to have given a bit more information? You are looking for help, after all.

However, if you're able to read the MBR, at least your SD settings work properly, so there's still hope.

What size is the card? Over 2GB and it could have problems. I've heard about some of these new SD-HD cards not following the specs.

Check the filesystem, too. If it's not working with FAT16, try FAT32 and vice-versa.
 
 View user's profile Send private message  
Reply with quote Back to top
divgup
PostPosted: Oct 24, 2008 - 06:42 PM
Rookie


Joined: Sep 01, 2008
Posts: 28
Location: India,Delhi

I am sorry but i dont know what is the problem..
I am using 256 MB card of kingston.

I have written two codes in the first one which i learnt after reading this post.Following problem is coming.
If i make two files in the SD-card.Both of them are read upto the end.When i give command to read the file which is located first in the MBR(which i get to know by seeing the SD viewer).

In the second code i was able to
create file.
See a list of files present.
But the code hangs in between.I am not able to find the problem.
I can mail you the .zip file.
I know i am asking for too much but can you please help me in this.
I assure you that there will only be a slight problem in the code.
thanx and regards
divyansh@ymail.com
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
kubark42
PostPosted: Oct 24, 2008 - 07:10 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Sorry, I'm not really clear on what your problem is. Maybe someone else can read between the lines?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 25, 2008 - 02:44 PM
10k+ Postman


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

divgup,

Can you use a utility such as WinHex (http://www.x-ways.net/winhex/) to capture the MBR? Then look at the four byte field at offset 0x1C6 (which is LBA of the start of the first partition) and also take a dump of that sector.

Both these sectors end 55,AA - if they don't you are looking in the wrong place.

Once we can see a copy of the boot/BPB sector it'll be possible to determine where the FATs and root directory are and check those.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Hammer111
PostPosted: Dec 27, 2008 - 12:33 PM
Hangaround


Joined: Aug 09, 2007
Posts: 137


Is there any code that can be used with ATmega8? 32K is too much

I just need to write and read from sd card
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Dec 28, 2008 - 02:42 AM
Resident


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

There was a thread recently (last 1-2 months) describing a method of writing a (dummy?) file to the card then writing and reading from it without using a file system.
 
 View user's profile Send private message  
Reply with quote Back to top
kingFisher
PostPosted: Jan 01, 2009 - 08:22 PM
Newbie


Joined: Aug 01, 2007
Posts: 1


Hammer111 wrote:
Is there any code that can be used with ATmega8? 32K is too much

I just need to write and read from sd card



If you can read german, the following site is something for you.
http://www.holger-klabunde.de/avr/avrboard.htm
Download the file: FATSingleOpt WinAVR 4.1.1
This can run in an ATMega8.
I successfully used it to build a GPS logger

Success,

Paul
 
 View user's profile Send private message  
Reply with quote Back to top
krazatchu
PostPosted: Jan 03, 2009 - 02:35 PM
Resident


Joined: Dec 29, 2007
Posts: 558
Location: Ontario, Canada

Hey...

I've been banging my head off the wall trying to get this working...
But no luck.... Using Tiny FS on an ATmega8 @ 8Mhz...

I'm a little confused about this part....
Quote:
Code:
/*SPI configuration*/
#define DD_MOSI DDB5
#define DD_SCK DDB7
#define DDR_SPI DDRB
#define DD_SS 4

/* Defines for SD card SPI access */
#define SD_CS_PIN 1
#define SD_CS_PORT PORTC
#define SD_PWR_PIN 0
#define SD_PWR_PORT PORTC

These defines will all have to be modified to your particular ATmega and setup. The DD_* #defines can be found in the I/O Ports-->Alternate Port Functions section.

The SD_* #defines are up to you. I chose to conenct the SD card's power supply to PIN0 (you did make sure you're not outputting more than 3.5V, right???) chip select to PIN1 of PORTC, but you could chose another if it were more convenient. Just avoid using one of the four pins associated with the SPI port. You can even comment out the SD_PWR_* if you have an alternate power supply (in this case, you have a 3.3V level converter on the SPI I/O pins, right???)


Where and what is chip select... ?
On the card holder, there is a CS pin... I've got it wired to SS on the mega32...
But where does this go?

Thanks!

_________________
Michael
--
http://krazatchu.ca/
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jan 05, 2009 - 09:17 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


krazatchu wrote:

Where and what is chip select... ?
On the card holder, there is a CS pin... I've got it wired to SS on the mega32...
But where does this go?


Ready for a magic trick? CS is... Chip Select! Ta-da. Thank you, thank you, I'll be here all week.

Explained better, "slave select" can be another name for "chip select". Since all devices on the SPI bus share the same communication lines, there has to be a way to differentiate between them when the master is talking. The master does this by activating the chip/slave select pin on the device it wants to talk to. Any devices who are not being addressed simply ignore the data they see on the bus until such time as their chip select pin is pulled appropriately.
 
 View user's profile Send private message  
Reply with quote Back to top
krazatchu
PostPosted: Jan 05, 2009 - 09:35 AM
Resident


Joined: Dec 29, 2007
Posts: 558
Location: Ontario, Canada

lol...

I should be more specific...
It was this part in particular:
Quote:
chip select to PIN1 of PORTC, but you could chose another if it were more convenient. Just avoid using one of the four pins associated with the SPI port.


I think you mean 3 pins, right? SCK, MOSI, MISO...
There would be no need to avoid using SS on the AVR as CS on the MMC...

I was having much trouble on the weekend getting it to work ...
Part of the problem seemed to be one of the SD cards, A SanDisk Ultra II 2GB...
They seem to have a slightly different initialization sequence...

I did manage to get it working with a SanDisk 256mb card...
But then I think I damaged the MBR, so it will still initialize but it won't access or reformat...

Still trying to get the 2GB card working if anyone has suggestions...
I found this thread and experimented a bit, but no luck yet...

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50889&postdays=0&postorder=asc

Thanks and great tutorial...
Michael

_________________
Michael
--
http://krazatchu.ca/
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jan 05, 2009 - 12:01 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


krazatchu wrote:
lol...

I should be more specific...
It was this part in particular:
Quote:
chip select to PIN1 of PORTC, but you could chose another if it were more convenient. Just avoid using one of the four pins associated with the SPI port.


I think you mean 3 pins, right? SCK, MOSI, MISO...
There would be no need to avoid using SS on the AVR as CS on the MMC...


You are absolutely correct, but when using SPI I tend to stay away from the SS pin, as if you configure it incorrectly, and then use it, you'll get some really annoying headache bugs that won't make sense. (Basically, it can knock the uC out of master mode and into slave mode, causing communications to fail for no apparent reason.) So it's safer for those of us to lazy or befuddled to make bug-free code on the first try just to leave it alone.

Quote:

I was having much trouble on the weekend getting it to work ...
Part of the problem seemed to be one of the SD cards, A SanDisk Ultra II 2GB...
They seem to have a slightly different initialization sequence...

I did manage to get it working with a SanDisk 256mb card...
But then I think I damaged the MBR, so it will still initialize but it won't access or reformat...

Still trying to get the 2GB card working if anyone has suggestions...
I found this thread and experimented a bit, but no luck yet...

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=50889&postdays=0&postorder=asc

Thanks and great tutorial...
Michael


Yeah, some cards can be a little odd, I understand. Even if you damage the MBR, that shouldn't change a thing for you reformatting. That being said, I now have two SD cards that simply don't work anymore with the AVR, but can and do work with a normal card reader. Don't know what could be happening, but obviously it's something in the way the card is being handled. Maybe the voltage supply isn't as clean as I'd like...

Glad you found the tutorial useful. If you look around, you'll find another one I just wrote on using the SD card for a bootloader. That goes pretty well with this one.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jan 05, 2009 - 12:09 PM
10k+ Postman


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

kubark42 wrote:
but when using SPI I tend to stay away from the SS pin, as if you configure it incorrectly, and then use it, you'll get some really annoying headache bugs that won't make sense. (Basically, it can knock the uC out of master mode and into slave mode, causing communications to fail for no apparent reason.) So it's safer for those of us to lazy or befuddled to make bug-free code on the first try just to leave it alone.

That's not a great idea. The whole point of SS (apart from ensuring that only one slave is enabled at a time) is as a resynchronisation mechanism. SPI works by having 8 pulses on the SCK and data lines but if a spurious clock pulse enters the system or one is not detected then the master and slave can get out of syncronisation. The way to get them back is for the master to de-assert SS (take it high) to the active slave andthen assert it (take it low) before a sequence of byte transfers. At this moment the slave can resynchronise its counter back to the start of an 8 bit frame.

The only "gotcha" to do with SPI on AVRs is that if an AVR is configured as a master and the designated SS pin (which would only be used if it were a slave) happens to get pulled low then the AVR will switch to slave mode operation unexpectedly. The usual solution is either to leave that pin as an input but enable it's pull-up or actually make use of it as the driving line for controlling the distant slave anyway.

I'd recommend anyone using SPI *do* make use of _SS unless they simply cannot afford the pins or tracking space. Avoiding the unexpected Master->Slave transition is easy once you are aware that it can occur and what may cause it.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jan 05, 2009 - 12:15 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


clawson wrote:

The only "gotcha" to do with SPI on AVRs is that if an AVR is configured as a master and the designated SS pin (which would only be used if it were a slave) happens to get pulled low then the AVR will switch to slave mode operation unexpectedly. The usual solution is either to leave that pin as an input but enable it's pull-up or actually make use of it as the driving line for controlling the distant slave anyway.

I'd recommend anyone using SPI *do* make use of _SS unless they simply cannot afford the pins or tracking space. Avoiding the unexpected Master->Slave transition is easy once you are aware that it can occur and what may cause it.

Cliff


Alright, sounds like good advice. In reality, I use the SS pin for controlling the slave (as you say, it's there so might as well use it) but I've seen others advise against it so I thought I'd follow their lead.

Quote:

That's not a great idea. The whole point of SS (apart from ensuring that only one slave is enabled at a time) is as a resynchronisation mechanism. SPI works by having 8 pulses on the SCK and data lines but if a spurious clock pulse enters the system or one is not detected then the master and slave can get out of syncronisation. The way to get them back is for the master to de-assert SS (take it high) to the active slave andthen assert it (take it low) before a sequence of byte transfers. At this moment the slave can resynchronise its counter back to the start of an 8 bit frame.


I didn't know about that. Is this something that happens asynchronously from the uC, or do you have to program that yourself?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jan 05, 2009 - 12:19 PM
10k+ Postman


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

It's asynchronous within the operation of the SPI logic I believe. When it sees a high->low transition on _SS it resets its internal bit counter.

EDIT: yup, just found this in the mega16 datasheet where it's describing its own use as a slave:
Quote:
The SS pin is useful for packet/byte synchronization to keep the Slave Bit Counter synchronous with the Master Clock generator. When the SS pin is driven high, the SPI Slave will immediately reset the send and receive logic, and drop any partially received data in the Shift Register.

_________________


Last edited by clawson on Jan 05, 2009 - 12:22 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
krazatchu
PostPosted: Jan 05, 2009 - 12:22 PM
Resident


Joined: Dec 29, 2007
Posts: 558
Location: Ontario, Canada

While searching for a fix for my 256mb SanDisk, I found a couple of utilities that are supposed to reformat the SD card according to the SD Spec...

I read that a windows format won't return the drive to the proper SD Specs...

For SD/MMC cards...
http://panasonic.jp/support/global/cs/sd/download/sd_formatter.html

For USB disks...
http://files.extremeoverclocking.com/file.php?f=197

Neither of them worked for me as my 256mb card won't even detect by windows...

I'm going to try the MMC Unlocker project here: http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=798&item_type=project But if that doesn't work, I guess this card is dead...

Ciao!

_________________
Michael
--
http://krazatchu.ca/
 
 View user's profile Send private message  
Reply with quote Back to top
bonzoq
PostPosted: Jan 07, 2009 - 04:48 PM
Newbie


Joined: Dec 09, 2006
Posts: 7


Thank you kubark42 for this comprehensive tutorial. I've now successfully implemented FatFS on an Atmega128. I'm able to communicate with my 2 gb Sandisk SD card. I've one question though. How do I read a file? According to the code in main.c I type
Code:
fr <len>
. What is len then? I guess it's not the name of the file, since that doesn't work.
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jan 07, 2009 - 05:00 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


`len` is the number of bytes you want to read. Usually, you'll want to read/write all a sector at once, so it'll be 512.

Glad to hear it's worked for you! Hope it was clear enough and there weren't too many gotchas. Let me know if you think there's anything that could be improved.

Kenn
 
 View user's profile Send private message  
Reply with quote Back to top
bonzoq
PostPosted: Jan 07, 2009 - 07:30 PM
Newbie


Joined: Dec 09, 2006
Posts: 7


Thanks for the quick reply. Your tutorial seems to me totally flawless, it's very hard for me to find anything that could be improved. Keep up the good work:).

Marcin
 
 View user's profile Send private message  
Reply with quote Back to top
krazatchu
PostPosted: Jan 08, 2009 - 02:13 PM
Resident


Joined: Dec 29, 2007
Posts: 558
Location: Ontario, Canada

Another question ...

I'm trying to create a single file which I append every time I want to add data...

I believe I should be using f_stat to get the file size...
Then f_lseek to set the write position to the end of the file...

However, I'm a bit confused on the implementation...
Here is my broken code ...
Code:

FILINFO FileInfo;

........

// Register a work area for logical drive 0
error_code ( f_mount(0, &fs)) ;   
   
// create destination file
error_code ( f_open (&fdst, file_name_id , FA_CREATE_ALWAYS | FA_WRITE) );

f_sync(&fdst); // flushes cached information

// get file info including freespace...
error_code ( f_stat ( file_name_id , FileInfo.fsize   ) );

// goto end of file, append
error_code ( f_lseek (file_name_id,  FileInfo.fsize) );

//write file, 32 is buffer size    
res_write = ( f_write(&fdst, write_file_buffer, 32, &bw) );


I'm sure I'm handling the union structure wrong, and perhaps the declaration...
Please don't laugh at me :< ... it's late....

Thanks!!
Michael

_________________
Michael
--
http://krazatchu.ca/
 
 View user's profile Send private message  
Reply with quote Back to top
ifor
PostPosted: Jan 08, 2009 - 11:01 PM
Rookie


Joined: May 27, 2008
Posts: 41


No need for the f_stat the following is working for me.

Code:


FIL   log_file;             // system logfile stdout gets piped here.

...

            res = f_open(&log_file, "log.txt", FA_OPEN_ALWAYS | FA_WRITE);
            if (!res)
            {
                res = f_lseek(&log_file, log_file.fsize);
                if (res)
                {
                    D(1) fprintf_P(stderr, PSTR("sd_putchar f_lseek failed res 0x%x\n"),res);
                }
            }
            else
            {
                D(1) fprintf_P(stderr, PSTR("sd_putchar f_open failed res 0x%x\n"),res);
            }
 
 View user's profile Send private message  
Reply with quote Back to top
krazatchu
PostPosted: Jan 09, 2009 - 01:22 AM
Resident


Joined: Dec 29, 2007
Posts: 558
Location: Ontario, Canada

Oh silly me...

I thought it was looking for the file name on disk... lol

Thanks!

_________________
Michael
--
http://krazatchu.ca/
 
 View user's profile Send private message  
Reply with quote Back to top
bonzoq
PostPosted: Jan 11, 2009 - 07:58 PM
Newbie


Joined: Dec 09, 2006
Posts: 7


kingFisher wrote:


If you can read german, the following site is something for you.
http://www.holger-klabunde.de/avr/avrboard.htm
Download the file: FATSingleOpt WinAVR 4.1.1
This can run in an ATMega8.
I successfully used it to build a GPS logger

Success,

Paul


Paul, I downloaded this library and compiled it, but after compilation the hex file is still some 21 kb. I disabled most of the functions but still can't get it smaller than that. Is there any chance you could share your code, I'm trying to get it running on an atmega168.

Thanks in advance

Marcin
 
 View user's profile Send private message  
Reply with quote Back to top
bonzoq
PostPosted: Jan 12, 2009 - 02:52 PM
Newbie


Joined: Dec 09, 2006
Posts: 7


I've managed to overcome this problem. Been doing a silly mistake. Admin could remove this and my last post.
 
 View user's profile Send private message  
Reply with quote Back to top
leoren_tm
PostPosted: Jan 13, 2009 - 09:29 AM
Rookie


Joined: Nov 11, 2006
Posts: 49


hi bonzoq. i just successfully implemented the tutorial thank to kubark42. bonzoq may i ask what parameter you change when using 128? cause i have 128, and not a 644p.

and hi kubark42, may i ask further tutorial? i a m newbie(VERY,MUCH) on AVR, after compiling it completely...how can i generate the hex file? i did generate it, but by some trails, and now i cant generate it again. I base it on the modified time.
I use: winavr,GCC,programmers notepad
im really new, thanks alot.
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jan 13, 2009 - 09:45 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


To generate a hex file? Programmers Notepad can do it for you in one of the menus. I believe it's "Make all" or something to that effect. However, you should be able to open a command window, go to the local directory, and type "make".

FYI, "make clean" erases all the compiled files so you can recompile with a blank slate. This is sometimes necessary for various reasons. If things don't seem to work, but should, you might try a "make clean" first.
 
 View user's profile Send private message  
Reply with quote Back to top
bonzoq
PostPosted: Jan 13, 2009 - 01:14 PM
Newbie


Joined: Dec 09, 2006
Posts: 7


leoren_tm wrote:
hi bonzoq. i just successfully implemented the tutorial thank to kubark42. bonzoq may i ask what parameter you change when using 128? cause i have 128, and not a 644p.


Hi leoren_tm. you just need to follow kubark's tutorial and change the names of the registers he mentions according to the atmega128's documentation. Don't forget to set the correct MCU_TARGET in the makefile too. I could send you my code, but no sooner than on Thursday CET. Just send my a private message with your e-mail address if you want to.
 
 View user's profile Send private message  
Reply with quote Back to top
leoren_tm
PostPosted: Jan 14, 2009 - 02:38 AM
Rookie


Joined: Nov 11, 2006
Posts: 49


ohhh NICE..i have the code running. thanks a lot. anyway do i have to set those fuse setting, bootloader(just read those)..
 
 View user's profile Send private message  
Reply with quote Back to top
JussiS
PostPosted: Feb 03, 2009 - 04:05 AM
Newbie


Joined: Mar 09, 2008
Posts: 8


As the Atmega128 and Atmega64 are identical in pins and feature set, do I have to change anything in the example?

I'm having little trouble getting this to work. I bet its my proto board giving me the hard time, but we'll see as I get a new SD-socket today..
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Feb 03, 2009 - 07:13 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Careful. I programmed this for the ATMega644p, NOT the ATMega64. As far as I'm aware, they're not the same processor at all.
 
 View user's profile Send private message  
Reply with quote Back to top
JussiS
PostPosted: Feb 03, 2009 - 07:54 AM
Newbie


Joined: Mar 09, 2008
Posts: 8


kubark42 wrote:
Careful. I programmed this for the ATMega644p, NOT the ATMega64. As far as I'm aware, they're not the same processor at all.


Nononono.. Very Happy

You got me all wrong. The original ELM example is written for the ATMega64 and I was referring to that.

But.. I guess I'll just have to find out for myself.
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Feb 03, 2009 - 08:42 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Ah, sorry, of course. I was the one who was confused. Well, as for the proto board, mine was spread out over several centimeters of free-hanging wire, with no attempt whatsoever to shield. I didn't have any problems running SPI at the maximum transmission speed of the processor, which I guess was around 2MHz.

Some SD card libraries start off by communicating with the SD card at the lowest speed possible, and then incrementally ratchet up the speed until the maximum stable speed is found. Have you thought about something similar?
 
 View user's profile Send private message  
Reply with quote Back to top
krifos
PostPosted: Feb 03, 2009 - 01:20 PM
Newbie


Joined: Mar 06, 2008
Posts: 6
Location: Norway

Hi gang,

been scratching my head for a couple of days now, trying to get communications up and running with a SD Card using this tutorial.

What I've done so far is adapting the FatFS AVR example to a AtMega128 chip (Mainly - 128 use different pins on PORTB for SPI communications than the 64.) The code compiled successfully.

I've also connected the SD Card via a SD Card holder soldered to the correct pins on the AtMega128 (using a STK 600 btw). I've triple and quadroupled checked the pins - they are exactly like the start of this tutorial.

Now, firing up the 128, I get the welcome message via the RS 232 interface - I type di 0, and get a RC = 1 response. This seems to indicate that the card is initialized, correct? Then I run fi 0 and get a RC=0 FR_OK. So, the file system is initialized, if I understand the code correctly?

However, running fl, fi, any file read, directory read and other such commands yields me a rc = 1 FR_NOT_READY or rc=11 FR_NO_FILESYSTEM error. I've tried the format command fm, and this will be running for several minutes, until it quits with a FR_NOT_READY or similar error somehwere in the middle of the formatting process( I assume).

I've tested two different cars (1GB and 2 GB from Kingston), and they both work flawlessly when read from a computer - I've even tried the Panasonic SD-Card Format program to ensure that the cards are properly formatted.

Any suggestions/hints would be most welcome.

Thanks in advance.
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Feb 03, 2009 - 02:02 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


I'm not sure, as I don't really remember how the original code is written and don't have it before me, but you can the only 0 means success. So if you're getting a RC = 1 for the disk initialize, then things aren't quite right on the disk.

I can confirm from personal experience that FatFS will return a "file system initialized" when the disk fails to initialize. So not quite sure what your problem here is, but if my experience is any indication, it's the SPI bus that's not configured correctly.
 
 View user's profile Send private message  
Reply with quote Back to top
krifos
PostPosted: Feb 03, 2009 - 03:03 PM
Newbie


Joined: Mar 06, 2008
Posts: 6
Location: Norway

Thanks for the response - I'm going to have a gander at the SPI codes, make sure everything is right. What clock speed are you using for your project, I've adapted the code to run a F_clk of 8MHz - but I might running your original speed to see if I've done a error somewehere.
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Feb 03, 2009 - 06:34 PM
Resident


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

Sounds familiar. I could only get disk_initialize() to work by slowing down the SPI, still can't run at full speed.

You might have to add
Code:
#include <avr/pgmspace.h>
#include "xitoa.h"


Code:
DSTATUS disk_initialize(BYTE drv) // Physical drive nmuber (0)
{
   BYTE n = 0;
   BYTE cmd = 0;
   BYTE ty = 0;
   BYTE ocr[4] = {0};


   if(drv)
   {
      return STA_NOINIT; /* supports only single drive */
   }
   
   if(Stat & STA_NODISK)
   {
      return Stat; /* no card in the socket */
   }
   
   power_on();   /* force socket power on */

// set SPI speed lower until it works, F_CPU/32 = 115kHz with a 3.6864MHz xtal
   SPSR |= (1<<SPI2X);
   SPCR |= (1<<SPR1);

   for(n = 10; n; n--)
   {
      rcvr_spi();   /* 80 dummy clocks */
   }
   
   ty = 0;
   
   if(send_cmd(CMD0, 0) == 1) // enter Idle state
   {    
      Timer1 = 100; // initialisation timeout of 1000 msec
      
      if(send_cmd(CMD8, 0x1AA) == 1) // SDHC
      {   
         for(n = 0; n < 4; n++)
         {
            ocr[n] = rcvr_spi(); // get trailing return value of R7 resp
         }

         if(ocr[2] == 0x01 && ocr[3] == 0xAA) // 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] = rcvr_spi();
               }
   
               ty = (ocr[0] & 0x40) ? 12 : 4;
            }
         }
      }
      else // SDSC or MMC
      {                     
         if(send_cmd(ACMD41, 0) <= 1)
         {
            ty = 2;
            cmd = ACMD41; // SDSC
         }
         else
         {
            ty = 1;
            cmd = CMD1; // MMC
         }

         while (Timer1 && send_cmd(cmd, 0)) // wait for leaving idle state
            {;}
           
         if(!Timer1 || send_cmd(CMD16, 512) != 0)   // set R/W block length to 512
         {
            ty = 0;
         }   
      }
   }
   else
   {
      xputs(PSTR("\nYou failed to talk to the disc\n"));
   }
 
// set SPI speed back to F_CPU/4 = 912.6KHz with a 3.6864MHz xtal
//   SPSR &= ~(1<<SPI2X);
//   SPCR &= ~(1<<SPR1);
 
   CardType = ty;
   release_spi();

   if(ty) // initialisation succeded
   {
      Stat &= ~STA_NOINIT;      /* Clear STA_NOINIT */
   }
   else // initialisation failed
   {         
      xputs(PSTR("\nYou failed to initialise the disc\n"));
     
      power_off();
   }

   return Stat;
}
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Feb 03, 2009 - 09:21 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


krifos wrote:
Thanks for the response - I'm going to have a gander at the SPI codes, make sure everything is right. What clock speed are you using for your project, I've adapted the code to run a F_clk of 8MHz - but I might running your original speed to see if I've done a error somewehere.


I'm running with the internal oscillator at 8Mhz, just as I guess you are. My thoughts are to try the code that davef posted and see if it works.
 
 View user's profile Send private message  
Reply with quote Back to top
krifos
PostPosted: Feb 04, 2009 - 03:27 PM
Newbie


Joined: Mar 06, 2008
Posts: 6
Location: Norway

Thanks for the responses. The code davef provided did indeed help - I've now been able to properly initialize the card, and even read the disk status. Altough I have more work to do on tweaking the SPI timings, as initialiation is still flaky, I usually have to try a couple of times before it will work - and I still cant get the fl or fs commands to return anything but various errors.
 
 View user's profile Send private message  
Reply with quote Back to top
JussiS
PostPosted: Feb 05, 2009 - 01:14 AM
Newbie


Joined: Mar 09, 2008
Posts: 8


And you do have the voltage divider resistors or something like that between the SD card and the MCU?

Or are you running the MCU on 3.3V?

So.. Has anyone got the ATMega128 working with this at full speed (XTAL 20MHz)?
 
 View user's profile Send private message  
Reply with quote Back to top
JussiS
PostPosted: Feb 05, 2009 - 10:26 AM
Newbie


Joined: Mar 09, 2008
Posts: 8


I finally got the time to fully test this..

Works without any modifications on ATMega128, BUT I cannot make any sense of the UART when running at full speed. On 8MHz it works ok, though.

Well.. Good enough for me! Time to write a program! Very Happy
 
 View user's profile Send private message  
Reply with quote Back to top
krifos
PostPosted: Feb 05, 2009 - 12:11 PM
Newbie


Joined: Mar 06, 2008
Posts: 6
Location: Norway

JussiS wrote:
And you do have the voltage divider resistors or something like that between the SD card and the MCU?

Or are you running the MCU on 3.3V?


Running the MCU at 3.3V, yes.
 
 View user's profile Send private message  
Reply with quote Back to top
ajpinotti
PostPosted: Feb 09, 2009 - 06:49 PM
Newbie


Joined: Feb 09, 2009
Posts: 6


Hi, I was reading this post and I got the FatFS module working at a MC56F8013 CPU (freescale). I made a routine to write a txt for a datalogger, but it was taking some minutes to write a file. So I increased the SPI CLK frequency (that was at 250kHz, because initialization of the Card) and functions like f_open, f_write and f_read work, but f_sync always returns FR_RW_ERROR at this clock speed.
When I put CLK at 250kHz f_sync works perfectly.
Anyone got this module working and writing files and got this problem or can help me?

Thx a lot!
 
 View user's profile Send private message  
Reply with quote Back to top
JussiS
PostPosted: Feb 11, 2009 - 12:40 PM
Newbie


Joined: Mar 09, 2008
Posts: 8


ok.. I have another problem.

I have several 512MB cards and if I use them, the system either refuses to even open a file or then just reboots.

I do also have a 32MB card, with which the system runs OK.

I've tried several options here.. Reduced the written buffer size, tried different initialize options etc. nothing works! Only the 32MB card functions!
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Feb 11, 2009 - 01:15 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


I've had similar experiences with cards. My 2GB cards work fine, but a 512MB didn't. No idea why, nor how to fix it. I've tried multiple SD programs from different authors and a card has either worked with all of them, or none.

If anyone ever comes across the answer, I'd love to see it. In between time, since a 2GB card costs $2 at the local supermarket, for all practical purposes the problem can just be worked around.
 
 View user's profile Send private message  
Reply with quote Back to top
JussiS
PostPosted: Feb 11, 2009 - 03:52 PM
Newbie


Joined: Mar 09, 2008
Posts: 8


Well.. I'm glad to hear that at least someone has got bigger cards working. I was already looking for obsolete, below 128MB cards. Very Happy I'll give the local shop a call and try bigger ones.
 
 View user's profile Send private message  
Reply with quote Back to top
EsanAcc
PostPosted: Mar 02, 2009 - 03:27 AM
Newbie


Joined: Dec 25, 2008
Posts: 3


I have been trying to fix this for weeks now, I sure hope some one out thier may have the answer. The process is as follows:
Open file, write data to it, then close it.
When I open it again, it will not write to it, send_cmd fn return error code 0xff.
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Mar 02, 2009 - 06:41 AM
Resident


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

Can we assume if you leave the file open you can repetitively write to it?
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 02, 2009 - 07:18 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


I'm not sure what EsanAcc wants to say, but, yes, you can repetitively write to an open file. If you're going to do that, don't forget to do an f_sync() periodically, or otherwise the data won't be saved. In my logging application, I did an f_sync() after every write.
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Mar 02, 2009 - 09:42 AM
Resident


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

kubark42,

I was wondering if he was able do that! Maybe, it would be useful information for someone who understands FatFS better to suggest a solution for him.

Following someone's excellent example I am doing a f_sync after each write!

The reason I am interested in this issue is that it was suggested to me that I should close the file after each write and then open it before the next write. The recommendation was based on concerns about corrupting an open file while the uP was off doing other work. However, I haven't seen a problem for the last 2-3months leaving the file open for weeks at a time.

Thanks again for providing enough information for guys like me to get a SD card file system working on their favourite uP.
 
 View user's profile Send private message  
Reply with quote Back to top
ajpinotti
PostPosted: Mar 02, 2009 - 02:39 PM
Newbie


Joined: Feb 09, 2009
Posts: 6


Hi

Someone has already used f_lseek to do cluster pre-allocations like ELM Chan says in his page?
I am trying to do so, just like the code we can find at http://elm-chan.org/fsw/ff/en/lseek.html, but the file doesn't get any longer.

I am having problems on creating big files, it goes writing data, but suddenly it stops and f_write only gives me FR_RW_ERROR, and it is always on cluster change.

Someone could help me?

Tks
 
 View user's profile Send private message  
Reply with quote Back to top
ajpinotti
PostPosted: Mar 02, 2009 - 03:53 PM
Newbie


Joined: Feb 09, 2009
Posts: 6


PLUS:

I am creating a new file:
f_open(&file,FileName[0],FA_CREATE_NEW | FA_WRITE)
f_lseek(&file,12582912) //allocates 12MB

Im looking to the "file" variable (FIL type) that gives the fsize and fptr

When I do the f_lseek fptr don't go to those 12582912 bytes, it goes to around 520000, and fsize is still 0 bytes.

Hows can I fix this? If I need to use f_truncate, please tell me how. This can be some problems with SPI clock?

Tks
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 02, 2009 - 04:16 PM
10k+ Postman


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

You seem to misunderstand fundamental file access programming (maybe try writing some file programs using the POSIX routines in Windows or Linux first to get the hang of it?). An fopen() and an fseek() does nothing more than move the read pointer in an open file. Try following it with an fputc() to actually write a byte at the offset and then fclose().

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
ajpinotti
PostPosted: Mar 02, 2009 - 04:34 PM
Newbie


Joined: Feb 09, 2009
Posts: 6


Tks for the answer.

But I can write data in the card. I already created some files, and actualy saw the fsize rising, then checking at windows.

I'm having this trouble with the size of the file. I dont know why, but at some point the system broke and f_write only give me FR_RW_ERROR. I try to remount, re-open, sync, re-write, and nothing, just some bytes are sent. What I could find out is that this error happens near cluster changes and reading the FAT table I see that more the last cluster is already signed as "last of chain (0xFFFF).

So, as I am using Chan's library, Im trying to use the pre-allocation that he explain, and he uses f_lseek(). He says: "[...]When an offset above the file size is specified in write mode, the file size is extended to the offset and the data in the extended area is undefined[...]"

Need some more help.

Tks a lot.
 
 View user's profile Send private message  
Reply with quote Back to top
ajpinotti
PostPosted: Mar 02, 2009 - 08:06 PM
Newbie


Joined: Feb 09, 2009
Posts: 6


Guys!

Please, see if this info helps:

I started logging again and at some point it stopped, one f_write() returned FR_RW_ERROR. I used read_disk() to read 3 FAT TABLE sectors (8,9,10) and the first ROOT SECTOR(488)

What I found out

a) My file starts at cluster #257 (that's because there was another LOG file at the card)
b) This cluster is pointed at the 2nd sector of the FAT Table (sector 9).
c) The cluster chain goes perfectly (cluster 257 points to 258 (0x0102) etc ), until it reaches the end
of that sector
d) Still reading sector 9, I see that cluster #510 points to cluster #511, but #511 DOES NOT points to next cluster it signals END OF FILE (0xFFFF)
e) f_write() returns also the ByteWritten variable, verifying it I see that it could only write the bytes that completes the last sector (90).
f) I was sending 183 bytes, the file would have to go to 522,333 bytes. But due to the error it "wrote" 90 bytes, fsize was 522,150 (because it could not write) and fptr 522,240 which is the size of the allocation (and of cluster)
g) Looking the properties of the file at windows explorer, I see that: Size 522,150 and Size on disc is 522,240.

I dont know what else to do. Hope u could provide me some answers.

Tks a lot for everything!
 
 View user's profile Send private message  
Reply with quote Back to top
EsanAcc
PostPosted: Mar 03, 2009 - 02:47 AM
Newbie


Joined: Dec 25, 2008
Posts: 3


sorry for the confusion. The aplication would open a file and wirte data to at the user's desire. When done, the application should close the file,but it don't have to. Here are some notes about FatFs.
- f_sync is called from within f_close fn to insure data are not lost.
- I use a function called, fprintf that is wrap around function of f_puts that calls fputc that calls f_write fn.
- when calling f_write fn, it does not necessary means, it would be written to sd card. f_write function saves data to the open file buffer (512 bytes).
- To ensure data are written to sd card, f_sync must calles. f_sync calls disk_write that writes data to sd with two steps:
1- send write command via send_cmd(CMD24,sector) fn
2- send data to be written via xmit_datablock(buffer,0xfe) fn.
so here is what happens,
- I open the file,
f_open(&RFile,"/rec.xls,FA_WRITE | FA_OPEN_ALWAYS)
- I write data with fprintf as such
fprintf(&RFile,"%s",strcd);
--
--
up to 512 bytes

when done

- I call f_close as such: f_close(&RFile);
note f_close function calls for f_sync(fp)

now so far data are writen correctly to file and file closed successfully.

Now when this file is opened the second time and process is repeated, the process fails at disk_write function. In particular when send_cmd(CMD24,sector) is called, it returns 0xff. it should return 0. When 0xff is returned, the function abort writing to disk and flag that file as FA_ERROR.
One more note, I am using 1GB micro SD from Kingston.
I would like to thank davef and kubark42 for thier comments.
 
 View user's profile Send private message  
Reply with quote Back to top
ajpinotti
PostPosted: Mar 04, 2009 - 02:22 PM
Newbie


Joined: Feb 09, 2009
Posts: 6


Hello Everybody.

I was debuging my code again, but this time I set some breakpoints inside f_write() and move_window() functions to see what is happening.

The problem my f_write() returns FR_RW_ERROR happens when FatFS calls disk_read() inside move_window(sect) (that was called by f_write() fc).

Inside move_window() there is this code:
Code:

if (sector) {
   Stat=disk_read(0, fs->win, sector, 1);
   if (Stat != RES_OK)
      return FALSE_Value;
   fs->winsect = sector;
}


So move_window() returns FALSE_Value (0).

And in f_write()
Code:

if (!move_window(sect)) /* Move sector window */
  goto fw_error;
[...]
fw_error:/* Abort this file due to an unrecoverable error */
   fp->flag |= FA__ERROR;
   return FR_RW_ERROR;


We can assume that the problem is in the implementation of the disk_read() function??
Like the card isnt prepared yet to send data, is busy, something like that?

The f_sync() calls the move_window() as well and many times it returns FR_RW_ERROR, but the program continues to write bytes on my file.

I would appreciate a lot if u could provide me some answers.

Thanks!
 
 View user's profile Send private message  
Reply with quote Back to top
LeslieTroyer
PostPosted: Mar 04, 2009 - 03:23 PM
Rookie


Joined: Jan 21, 2009
Posts: 38
Location: Sammamish

JussiS wrote:
ok.. I have another problem.

I have several 512MB cards and if I use them, the system either refuses to even open a file or then just reboots.

I do also have a 32MB card, with which the system runs OK.

I've tried several options here.. Reduced the written buffer size, tried different initialize options etc. nothing works! Only the 32MB card functions!


You might try reformatting the cards (on your PC) that don't work to fat32 or fat16 --- lots and lots of cards are formatted with ntfs -- which is not a fat based file system so won't be recognized.

LEs
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 04, 2009 - 10:24 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


ajpinotti wrote:
We can assume that the problem is in the implementation of the disk_read() function??
Like the card isnt prepared yet to send data, is busy, something like that?

The f_sync() calls the move_window() as well and many times it returns FR_RW_ERROR, but the program continues to write bytes on my file.


I would love to help you, but, honestly, I'm as lost as you are. I had problems with FatFS keeping up with my write speeds (I write a full buffer 3-5 times per second), so I in a sense abandoned the full functionality in favor of some reduced, but more efficient code.

It is entirely possible that move_window is borked. I don't know exactly what it should do, nor how it should do it. Maybe you can set up debugging so when you get an error, you immediately repeat the write/read process in order to see if asking a second time helps? What's important is that you're getting data back from the SD card, even if it's not the data you want in the style you expect it. If you get data back, then you can fix the problem yourself by looking at the specs. That's how I did things for the SD Bootloader tutorial I wrote.

Another idea occurs to me (sort of like what we used to tell people at Lexmark: "If your printer doesn't work, reinstall the drivers.") is to suggest running at a slower speed.

Keep trying to debug it and report back here. You might even try contacting the original author, or, even better, going to the BBS channel, http://elm-chan.org/bbs/?lang=en. Not as elegant as avrfreaks, of course, but if it works? (And if you HATE the stupid white on black contrast the way I do, add this to your bookmark bar and load the "bookmark" when you're on those kind of websites:
Code:
javascript:(function(){var%20newSS,%20styles='*%20{%20background:%20white%20
!%20important;%20color:%20black%20!important%20}%20:
link,%20:link%20*%20{%20color:%20#0000EE%20!important
%20}%20:visited,%20:visited%20*%20{%20color:%20#551A8B%20
!important%20}';%20if(document.createStyleSheet)%20
{%20document.createStyleSheet(%22javascript:'%22+
styles+%22'%22);%20}%20else%20{%20newSS=
document.createElement('link');%20newSS.rel='stylesheet'
;%20newSS.href='data:text/css,'+escape(styles);
%20document.getElementsByTagName(%22head%22)[0].appendChild(newSS);%20}%20})();
NOTE: this should all be on one line, but it really wreaks havoc with phpBB's formatting [makes the webpage monde characters wide], so I put some newlines in.)


Cheers,
Kenn


Last edited by kubark42 on Mar 04, 2009 - 10:44 PM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 04, 2009 - 10:37 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


EsanAcc wrote:
Now when this file is opened the second time and process is repeated, the process fails at disk_write function. In particular when send_cmd(CMD24,sector) is called, it returns 0xff. it should return 0. When 0xff is returned, the function abort writing to disk and flag that file as FA_ERROR.
One more note, I am using 1GB micro SD from Kingston.
I would like to thank davef and kubark42 for thier comments.


I saw you got an answer on ELM's BB. Did it work?
 
 View user's profile Send private message  
Reply with quote Back to top
EsanAcc
PostPosted: Mar 05, 2009 - 02:40 AM
Newbie


Joined: Dec 25, 2008
Posts: 3


Kubark42 thanks for asking. I have deleted the following line from f_sync function:
dir[DIR_Attr] |=AM_ARC; //set archive bit
also made sure, the file is not archived by Windows
(right click the file, select properties, unchecked archive)
Though this may not make sense, but it did help. I may have to deal with this issue again....

its has been extremly hard to debug this FatFs firmware. The main issue here when the code encounter a problem with the file setup, it exit the function and aband the process, it does not deal with the issue, in other word their is no error handler. I am learning about this code every day;
Regards
Crying or Very sad
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 05, 2009 - 07:28 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


EsanAcc wrote:
its has been extremly hard to debug this FatFs firmware. The main issue here when the code encounter a problem with the file setup, it exit the function and aband the process, it does not deal with the issue, in other word their is no error handler. I am learning about this code every day;


Yes, that is pretty common of FatFS. I guess error handling is all about how much space you have to spare for it. FatFS already takes up a monstrous amount of space compared to what is available in the Atmel DIP packages. Error, checking, however, would come in handy. Hve you considered making a fork?
 
 View user's profile Send private message  
Reply with quote Back to top
LyingNoise
PostPosted: Mar 08, 2009 - 02:09 PM
Newbie


Joined: Mar 08, 2009
Posts: 1


This
Code:
static
BYTE rcvr_spi (void)
{
  SPDR = 0xFF;
  loop_until_bit_is_set(SPSR, SPIF);
  return SPDR;
}
(mmc.c)
is not working if I don't write
Code:
PORTB |= (1<<DDB6); // <- power_on

or, if you prefer,
Code:
#define DD_MISO DDB6
PORTB |= (1<<DD_MISO); // <- power_on
Am I right?
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 08, 2009 - 05:43 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Wouldn't that just be taking the port to HI, instead of turning it into an output? Or is that not what you meant?

In any case, I'm not sure that having it as an output is necessary. I don't quite remember right now, but I can check Monday when I'm back in front of the code.
 
 View user's profile Send private message  
Reply with quote Back to top
frto_nr1
PostPosted: Mar 16, 2009 - 07:11 PM
Newbie


Joined: Oct 18, 2008
Posts: 16


I'm trying the same FatFS driver, but i will only read files and put them to glcd. I'm running AtMega64 @16MHz what changes are required? my schematic is in attachment
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 16, 2009 - 07:17 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


I'm not sure we can help you with that kind of question. It's quite vague, and doesn't even pose a problem to be solved. Furthermore, your schematic doesn't show an ATMega at all, so I wonder if you've posted the right.

I suggest you rethink your questions and schematic, and be very clear. I'd love to help you, but I'm not a mind reader.
 
 View user's profile Send private message  
Reply with quote Back to top
frto_nr1
PostPosted: Mar 17, 2009 - 06:53 AM
Newbie


Joined: Oct 18, 2008
Posts: 16


kubark42 wrote:
I'm not sure we can help you with that kind of question. It's quite vague, and doesn't even pose a problem to be solved. Furthermore, your schematic doesn't show an ATMega at all, so I wonder if you've posted the right.

I suggest you rethink your questions and schematic, and be very clear. I'd love to help you, but I'm not a mind reader.


Oh sorry i did a mistake i posteted only connection of the SD card socket. here is the mcu schematic with the lines. PortA and PortC is reserved for display, PortD is reserved for buttons and some diodes. and the problem which changes in the code are requied to comunicate with the SD card when i'm using 16MHz crystal and i will do some read options with keys connected to atmega, write it to my display and disuse uart (nothing goes via uart)
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 17, 2009 - 09:03 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


I don't think any changes should be required when communicating at 16MHz. You _might_ have a speed problem, as you're approaching 25MHz, which I've heard is the maximum speed for the SPI connection to the SD card. Even if you do, though, the solution is simple: slow down the SPI bus by writing the right bit to the register. I suggest you do some read/write tests and see if everything is okay. If it's not, slow it down, and if it is... perfect!
 
 View user's profile Send private message  
Reply with quote Back to top
mien_noodles
PostPosted: Mar 17, 2009 - 01:44 PM
Rookie


Joined: Feb 17, 2009
Posts: 33


Hi kubark42 I am a newbie to AVR and C so sorry if my question sounds unreasonable! First of all thanks for the tutorial that you've written. I have modified the code according to my AVR162 but I don't really know which PORT/PINs are used for uSD function (I will need other pins for other functions). I tried reading the code from ffsample.zip but I couldn't understand the port assignments. I understand that 1 is output and 0 is input but can you please list down the pins that is used, for example:

MOSI, MISO, SCK, OC0 etc. Or a schemnatic of your circuit will do. MANY THANKS!
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 17, 2009 - 02:50 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Well, there's really no schematic to be made. In fact, there's no choice of pins to be made. You don't have a choice. You must hook up the ATMega's MISO (Master In/Slave Out) pin to the SD's data out, the MOSI (Master Out/Slave In) to the SD's data in, the SCLK (system clock) to the SD's system clock, and then (take a deep breath) designate another pin, ANY other pin, as the CS (chip select) pin. The other SD pins are all unnecessary, with the obvious exception of the power and ground pins.

The exact pins used by SPI, i.e MOSI, MISO, and SCLK, are detailed in the documentation of whatever chip you're using. Best of luck.
 
 View user's profile Send private message  
Reply with quote Back to top
mien_noodles
PostPosted: Mar 17, 2009 - 03:15 PM
Rookie


Joined: Feb 17, 2009
Posts: 33


Thanks for the reply Smile
Just wondering, you stated that your pinout is CS --SS (PC1) in the fist tutorial. I had a look at the pin configuration of your uC and I am slightly confused. Did you mean !SS pin on AVR or ANY other pin (eg. PC1) as you just said?
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 17, 2009 - 04:36 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Well, I meant not to use SS, but if you read through the thread, you'll see that others have a diametrically opposed opinion. You just have to be more careful if you use SS not to make a stupid coding mistake that will cost you hours of frustration tracking down two months into the project. Ask me how I know. Wink That being said, SS is actually sort of foreseen for exactly that purpose, so it's up to you. In any case, the chip select is nothing more nor less than a pin that controls if the peripheral is listening. If the peripheral has a HI at its chip select, it ignores everything. If it has a LO, it listens and responds (if appropriate). So you can use any pin in the entire world that you like.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 17, 2009 - 04:43 PM
10k+ Postman


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

But the key thing about SS when SPI is being used is that even if you don't use it the pin should either be tied high or set as an output and driven. If left as a (floating) input then if it gets pulled low the master switches to become a slave and disaster ensues.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 17, 2009 - 04:48 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Thank you, Cliff, that's a good point.
 
 View user's profile Send private message  
Reply with quote Back to top
mien_noodles
PostPosted: Mar 18, 2009 - 12:50 AM
Rookie


Joined: Feb 17, 2009
Posts: 33


Alright thank you guys! I will opt for normal pin and tie !SS high. Cheers! Smile
 
 View user's profile Send private message  
Reply with quote Back to top
lnlh21
PostPosted: Mar 18, 2009 - 05:46 AM
Newbie


Joined: Sep 26, 2008
Posts: 1


thanks
first login the abroad websit!
the avrfreaks is good!
 
 View user's profile Send private message  
Reply with quote Back to top
doctek
PostPosted: Mar 24, 2009 - 10:47 PM
Wannabe


Joined: Jun 10, 2007
Posts: 53


Ken - Thanks for a GREAT tutorial!

I have loaded this into a Mega644 just like yours and am successfully reading my 4Meg SDHC Card. So that much works. BTW, I have used the /SS pin (PB4) as part of my SPI protocol. Works fine.

Now a couple of questions.

First, regarding the changes in Main.c. Why do you comment out the sei() instruction? That appears to leave the interrupts off and the timer will never run. If I try running the program without a card in the socket, it just hangs! If I put sei() back in, then I get a time out like I'd expect. Am I missing something?

Nother question: While I'm reading my 4M SDHC just fine, I can't access my 2M SD card. (It reads just fine on my PC.) Could this be because it has 1024 byte block length?? Is there a utility to force a smaller block size on the 2M card? Is there a way to postively determine the block size?

Thanks!
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Mar 25, 2009 - 07:39 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


doctek wrote:
First, regarding the changes in Main.c. Why do you comment out the sei() instruction? That appears to leave the interrupts off and the timer will never run. If I try running the program without a card in the socket, it just hangs! If I put sei() back in, then I get a time out like I'd expect. Am I missing something?


Well, disabling the sei() instruction certainly has the downside that the program doesn't behave the way it should with regard to the timeout, but that's the trade-off I made for simplicity's sake. In the tutorial, it's important that you level the playing field as much as possible. With sei() turned off, when someone asks a question I know that it's never because of some random interrupt that's causing a problem.

That being said, my loggigg program has interrupts, and lots of them. It works just fine, but that's clearly because the interrupts are neither long enough, nor often enough to perturb the read/write process. Your mileage may vary.

Quote:
Nother question: While I'm reading my 4M SDHC just fine, I can't access my 2M SD card. (It reads just fine on my PC.) Could this be because it has 1024 byte block length?? Is there a utility to force a smaller block size on the 2M card? Is there a way to postively determine the block size?


It seems logical to me that 1024 byte blocks cause problems, as most of the time you're reading/writing in 512 byte blocks, but without looking through the code I can't swear by it. However, one thing is for certain and that's that if the read/write buffers are limited to 512 bytes, there ain't no way in hay-yell that 1024 byte block operations will work successfully.

As for forcing smaller block sizes, I have no idea. I think I'll have to pass the buck on this one to some of our more knowledgeable members.

Glad you enjoyed the tutorial and it worked out for you. Cheers!


Last edited by kubark42 on Mar 25, 2009 - 11:13 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 25, 2009 - 10:39 AM
10k+ Postman


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

Quote:

Could this be because it has 1024 byte block length??

Are you sure - can you dump the boot/BPB sector? - it's very unusual if it hasn't got 512 byte blocks.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
doctek
PostPosted: Mar 25, 2009 - 05:54 PM
Wannabe


Joined: Jun 10, 2007
Posts: 53


Thanks to kubark42 (Ken) and clawson for your responses. I am completely lost about why my 2G SD card won't work, so thanks for any insights.

Here's the source of my confusion about the block size > 512 bytes.
http://en.wikipedia.org/wiki/Secure_Digital_card
have a look at the sections titled Compatibility issues with 2 GB and larger cards and SD (non-SDHC) cards with greater than 1 GB capacity. Are Block size and Sector size the same thing? I'll be glad to post the Master Blocks (Sector 0? is that right?), if I can manage to add the figures. I've used Winhex to read them.

Again, thanks for the help. Since several others seem to have had problems with certain SD cards, I'd like to get to the bottom of this.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Mar 25, 2009 - 06:49 PM
10k+ Postman


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

The BPB data is in the first of those two pictures. The key field is the int16 at offset 0x0B/0x0C which has the value 0x200 - this is "bytes per sector" and is the fairly standard value of 512.

The next byte (offset 0x0D) is the sectors per cluster - this is set to 0x40 - 64. So there are 32K clusters on the disk

Offset 0x0E/0x0F is interesting as this is the "reserved sectors" and is set to 0x186c so there's a LOT (6,252) of wasted sectors between the BPB and the first FAT

Offset 0x10 shows there are two FATs (as expected)

At 0x20 we're told that there are 0x795400 (7,951,360) sectors on the device. As the sectors are 0.5KiB this means there's 3,975,680KiB of storage available. That is 3,882.5MiB or ~3.79GB

Offset 0x24 tells us there are 0xF800 (63,488) sectors per FAT

0x2C says the root starts at cluster 2 (as usual)

So I'd have said this entire boot/BPB was "normal" with nothing unusual in it.

Cliff

PS As that's Winhex I guess you know you can use the template manager to cast a boot/BPB template onto that sector which makes this kind of decode totally automatic?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
doctek
PostPosted: Mar 26, 2009 - 03:15 AM
Wannabe


Joined: Jun 10, 2007
Posts: 53


The first picture is for the 4G SDHC card - the one that works. The second is for the 2G SC card that doesn't work.

Thanks to pointing me to the Templates in Winhex. Using the one for the 2G card implies that all is well - 512 bytes per sector. The rest of the parameters look OK also. So the problem remains: Why doesn't this card (and lots of others) work? All I can think is that the responses to the queries the program sends don't come back as expected. I'm going to try to chase this a bit with some "printf" statements.

If anyone has any suggestions or insights, I'll be very interested.

Thanks.
 
 View user's profile Send private message  
Reply with quote Back to top
jofre
PostPosted: Apr 18, 2009 - 08:58 PM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

Hi,

After following the tutorial literally as I used an ATMEGA644V, the compiling went flowlessly just the about 48 warnings mentioned in earlier postings.

But when I connected the terminal an attempted any command for example di the replies are always two weird characters ( extended characters as they are a big hexa number). I've tried different baud rates etc , always garbage. On the other side everything looks dead, not SCK activity just noisy ugly waveforms when sending any command.

So, here my first question; What clock frequency is this project using ? ( I could not find anyone mentioning this). I am using 8 MHZ internal( unset the DIV8 fuse).

I hope this could be the reason. On the other side I was using an STK500 and it is a pain to change the serial port for every try plus I must power cycle the USB adapter. I am now making a breadboard so I can use the ISP programmer and keep the same serial communication connected all the time.

I am having bad luck with SD card projects last month I've attemted the one from Roland Riegel and exactly the same poor waveforms on the SPI pins and all seems to be dead. So I disregarded on the spot as most feedback in the internet points to Elm.

The only code one it worked so far is the one on the Captain for raw access, waveforms are OK and very nice. FYI, it was EXACTLY the same hardware using ATMEGA168 than with the Roland's, so I know the problem is 100% software.

I believe my problem could also rely on the interrupts. I've never worked with interrupts ( I am scared of them)not sure whether do I need to set fuses?? Perhaps it is time to learn and get used with them.

Thanks in advance for any help anyone can throw, I will post again after retesting with the breadboard.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 19, 2009 - 11:01 AM
10k+ Postman


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

The code bases the value it puts into UBRR on the current setting of F_CPU so you'd just need to ensure that you have F_CPU defined to 8000000UL somewhere in the project then just keep your fingers crossed that the RC inaccuracy is not sufficient to blow the baud rate out of the water.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
jofre
PostPosted: Apr 29, 2009 - 03:39 PM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

Ok, I finally got it working. It is easier on a dedicated board than using the STK500. I am using a 2 GB Sandisk microSD.

As I mentioned, I am using same MCU as in the tutorial ATMEGA644 ( but not "p", the standard 644 which it is functionally the same). However, the original posting needs some little addittions as follows:

The F_CPU is not defined so ( Thanks Clawson) I defined it on uart.c adding:
Code:
 #define F_CPU 8000000


Above definition is using the internal RC oscillator and unprogramming the divide by 8 fuse.

I've also tried first to define F_CPU in the Makefile as
Code:

......................
PRG            = avr_mmc
OBJ            = prjELM.o uart.o xitoa.o ff.o mmc.o rtc.o
MCU_TARGET     = atmega644
F_CPU         = 8000000
OPTIMIZE       = -Os -mcall-prologues
...........................


But it did not work, perhaps bad syntax , I am not very familiar with the makefiles.

At this point, I was not able to get the card initialized ; always got rc=1 after sending di 0 , so I overwrote the disk_initialize function as per davef post on February 3rd, but still same problem.

Then I kept reading the postings and found LyingNoise posting on March 8th that ( surprisingly) nobody else but the author replied .I realized that MISO was not defined anywhere


From the original tutorial text:
Quote:
Code:

*SPI configuration*/
#define DD_MOSI   DDB5
#define DD_SCK   DDB7
#define DDR_SPI   DDRB
#define DD_SS   4

/* Defines for SD card SPI access */
#define SD_CS_PIN   1
#define SD_CS_PORT   PORTC
#define SD_PWR_PIN   0
#define SD_PWR_PORT   PORTC


shows that the DD_MISO is not defined. Then I tried again and after adding:
Code:
#define DD_MISO DDB6
PORTB |= (1<<DD_MISO);

.... and , Yahoo!!!, the code is running OK and I can see directories etc. So, LyingNoise you DID were right!

What I need to retest is to go back to the original disk_initialize function to see whether the davef code is making a difference on this case or not.

kubark42 THANK YOU very much for sharing this , I know it is a lot of effort to put all this together also thanks a lot to all people posting if it were not from your postings, getting this project running would be much more difficult. I will keep testing and playing and will post if I find something useful to share.
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Apr 29, 2009 - 08:45 PM
Resident


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

Hold on a moment . . . MISO is an input and should be set up as so from reset. Where you setting the MISO to something else before running kubark42's code?
 
 View user's profile Send private message  
Reply with quote Back to top
jofre
PostPosted: Apr 30, 2009 - 04:21 AM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

Davef,

Negative, MISO is not anywhere in the original posting. So , the code above is the only reference to it. Perhaps it needs the internal pull up ?
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Apr 30, 2009 - 06:33 AM
Resident


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

Yes, there has been recent postings on not forgetting to enable the pull up on this pin or the SPI can be confused about whether it is a master or slave (from memory).

I did:
Code:
// PORTB, PB0 output high, all others input pull-up enabled
// PB4, PB5 and PB7 get configured as outputs later on (SS, MOSI and SCK)
   DDRB = 0x01;  // 0000 0001
   PORTB = 0xFF; // 1111 1111
on my ATmega 32 and there is probably even an external pull-up to be darn sure.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 30, 2009 - 10:02 AM
10k+ Postman


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

Quote:

not forgetting to enable the pull up on this pin or the SPI can be confused about whether it is a master or slave

That's _SS not MISO

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Apr 30, 2009 - 11:24 AM
Resident


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

oops! Should have re-read those posts!
 
 View user's profile Send private message  
Reply with quote Back to top
jofre
PostPosted: Apr 30, 2009 - 04:05 PM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

Thanks, yes, I think the problem is the pull up . In the faq questions of similar project from Roland Riegel it is mentioned to put a 50k Omhs to 3.3 volts on the DO pin of the card as one of the tips to fix initialization problems.

The only problem I am realizing now is that I am using 5 V for the AVR and activating the internal pull up may be not good in spite so far it is working fine.

I will put a 50K resistor to to 3.3V, comment out the code and try again.
 
 View user's profile Send private message  
Reply with quote Back to top
ganzziani
PostPosted: Jun 10, 2009 - 02:59 PM
Resident


Joined: Jun 16, 2006
Posts: 657
Location: Sarasota, FL

Thanks for the tutorial, it was helpful when porting to my XMultiKit XMEGA project. You can check my implementation here:
http://www.gabotronics.com/development-boards/xmega-xmultikit.htm

And thanks to ChaN for his great FatFs library!

_________________
www.gabotronics.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
meslomp
PostPosted: Aug 05, 2009 - 07:45 PM
Raving lunatic


Joined: May 02, 2007
Posts: 3990
Location: Nieuwegein, Netherlands

After a couple of evenings spitting through this tutorial and all its follow-up threads.....
I have this working on an ATMega128 running at 16MHz.

I have done
di 0
fl 0
fi
and got a responce in the form of the'good old dir command in DOS. So I assume that communication is up and running.

So first a big thanks to kubark42 and ofcoarse everybody who helped him in refining this.

I have used Rev0.07c from the FatFS system and notice that my ROM and RAm nubers aer significantly off from what is posted in earlier threads.
I now have
Code:

AVR Memory Usage
----------------
Device: atmega128

Program:   44974 bytes (34.3% Full)
(.text + .data + .bootloader)

Data:       2544 bytes (62.1% Full)
(.data + .bss + .noinit)



I have already changed the following FatFS parameter settings to try to reduce the code:

Code:

#define   _USE_MKFS   0  // not needed as I use preformatted card

#define _FS_RPATH   0 // not needed because I can write all files in the root and thus dont need directory structure



I now wonder if I can chaneg other settings in order to reduce the consumed space.
It would be nice to get the code space down a little, although I use a 128 and will have enough.
More important is the RAM space occupied. This is 2,5K out of 4K.
I have a graphical display that I can only write to, no read back, so for conveniance I have used 1K ram space to give me display RAM that I can manipulate before actually updating the display itself.
I Have an event que that I now have set to 50 events thus 100 bytes.
I want to receive GPS stuff so guestimate is 700 bytes for that
and then ofcoarse a stack.....
and then I ran out of RAM space. so that is why I would like to get the SRAM usage down

All I basically need is to be able to open a file (new and existing) and being able to write data to that file.

My guess is that if it can be run on a mega8 it should be possible to get the numbers down for me to, but I have no clue as to where to start.

just becaues of the simple fact that I'm also a relative newby in the playing feeld of embeded software

I hope someone can help me out here.

thanks

_________________
1)Datasheet and application notes checked?
2)tutorial forum
3)Newbie start here
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Aug 05, 2009 - 09:12 PM
Resident


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

Would TinyFat with appropriate functions disabled be any smaller?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 05, 2009 - 09:31 PM
10k+ Postman


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

meslomp,

As I said in a PM, the FatFs demo program defines a [1024] byte array for "general use". There'd be no need for that in a "normal" app. Maybe [512] to hold a sector but not more. So that should drop 2.5K to 2K for starters.

I've just started doing something with FatFs on 128 too - I'll report my numbers when I have them. But the static allocation so far is nothing like 2.5K

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
meslomp
PostPosted: Aug 06, 2009 - 06:20 AM
Raving lunatic


Joined: May 02, 2007
Posts: 3990
Location: Nieuwegein, Netherlands

Ok,

when I have time this evening I will go and give it a try. and ofcoarse wait for your numbers. I have litterally followed this tutorial(as a relative newby). I can not imagine that you are going to do the same Smile
do you also use the latest version of FatFS? or an earlier version.

thanks

_________________
1)Datasheet and application notes checked?
2)tutorial forum
3)Newbie start here
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 06, 2009 - 01:53 PM
10k+ Postman


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

meslomp,

I pulled ffsampl.zip in the last few days so I'm using the very latest software (the one that merges ff.c and tff.c with the _FS_TINY switch in ff.h).

I notice that you:
Code:
di 0
fl 0
fi

where you are using a single drive (drive = 0) and yet the example code has:
Code:
FATFS Fatfs[2];            /* File system object for each logical drive */

to cater for two drives (0 and 1). Within the definition of the FATFS structure there is:
Code:
...
   DWORD   database;   /* Data start sector */
   DWORD   winsect;   /* Current sector appearing in the win[] */
   BYTE   win[_MAX_SS];/* Disk access window for Directory/FAT */
} FATFS;

where _MAX_SS is almost certainly defined as 512 in your ff.h

So you are reserving about 560 bytes to support a second drive you are almost bound to never use. That's be a good place to start saving memory. Simply make that [2] a [1] instead.

Also the file has:
Code:
BYTE Buff[1024];         /* Working buffer */

But Buff[] is only used in the commands

dd (dump sector - 512 bytes used)
ds (disk status - only 64 bytes used)
bd (buffer dump - just 512 bytes)
be (buffer edit - variable length usage)
br (buffer read - 512 * number of sectors)
bw (buffer write - 512 * number of sectors)
bf (buffer fill - sizeof(Buff[]))
fr (file read - limited to sizeof(Buff[]))
fd (file dump - depends on given 'len')
fd (file write - depends on given 'len')
fx (file copy - done in chunks sizeof(Buff[]))

Soo, there's room there to reduce the size of Buff[], maybe reducing it from 1024 to 512 would be the first step. Beyond that you'd need to re-work the implementation of some of those commands or prevent their use all together.

With those two changes alone you should be able to knock 1,072 bytes off your RAM usage.

But the whole point of the "monitor" example is that it is just that - an example. It allows pretty much everything in the API to exercised . But in a "real" app you will probably use a subset of the functionality with a more limite RAM requirement. Though you are going to need one FatFs[] entry and almost certainly one 512 byte buffer. A bit over 1K.

You can see this in the Application note:

http://elm-chan.org/fsw/ff/en/appnote.html

Notice the D and F values. A minimal system could work with D=1 and F=1. So for _FS_TINY this would mean just 560+32 and for non-Tiny operation 560+544 - a bit over 1K

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
meslomp
PostPosted: Aug 07, 2009 - 06:39 AM
Raving lunatic


Joined: May 02, 2007
Posts: 3990
Location: Nieuwegein, Netherlands

Cliff,

thanks for this clear explenation. I'm sure that more people in the future will benefit from it. I will try it as soon as possible. I forgot to take the code with me this morning Sad so can not try it quickly on my work.

Regards

Marcel

_________________
1)Datasheet and application notes checked?
2)tutorial forum
3)Newbie start here
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 07, 2009 - 09:36 AM
10k+ Postman


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

Marcel,

Well I think you will expect to get something like:
Code:
AVR Memory Usage
----------------
Device: atmega128

Program:   29826 bytes (22.8% Full)
(.text + .data + .bootloader)

Data:       1790 bytes (43.7% Full)
(.data + .bss + .noinit)

Cliff

(my code is slightly larger than expected as I already have my own UART and LCD support added)

PS what that 1790 figure (and your own figures) don't show is:
Code:
int main (void)
{
...
   DIR dir;            /* Directory object */
   FIL file1, file2;      /* File object */

and each of those FIL structures (unless _FS_TINY is defined) will contain another 512 byte sector buffer. So there's more than 1K more of SRAM being used there too that is not shown at build time. Personally I think it is an argument for moving those FIL's out of main() and making them global so they "show up" at build time. By the way "file2" is ONLY used to support the fx (file copy) command. So if you can live without that remove "file2" and "#if 0" the case' 'x' where it's used.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 07, 2009 - 04:45 PM
10k+ Postman


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

How very annoying. I just spent a rather unhappy couple of hours adding printf()s and driving each control line in turn, checking wiring with a meter and so on to try and track down why I wasn't getting the 0x01 response to CMD0. All the control lines seemed to be connected and drivable/readable (including card inserted and write protect). The only I/O I didn't check was PE7 which I was using to switch Vcc to the card. As the SD socket from www.futurlec.com has a power LED I was pretty sure at least that bit was working.

Except it wasn't.

The Chan example code has:
Code:
   PORTE = 0b11110010; // Port E
   DDRE  = 0b10000010;

and mmc.c has:
Code:
static
void power_on (void)
{
   PORTE &= ~0x80;            /* Socket power ON */

and
Code:
static
void power_off (void)
{
...
   PORTE |=  0x80;         /* Socket power OFF */

It only took me about 2 hours to realise that all this is the "wrong way up" (because Chan's example circuit uses PE7 to switch a transistor off and thus inverts the sens of it). What was actually happening was that each time the card was accessed the power was momentarily being turned off, not on.

But finally I got to:
Code:
>FatFs R0.07b test monitor for AVR
>di 0
rc=0
>fi 0
rc=0 FR_OK
>fl
D---- 2007/06/01 18:44         0  DCIM
----A 2008/04/09 08:24       296  WMPINFO.XML  WMPInfo.xml
D---A 2009/01/18 17:38         0  20GREA~1  20 Greatest Hits
D---A 2009/01/28 10:44         0  CARPEN~1  Carpenters Gold
D---A 2009/01/18 17:48         0  CLASSI~1  Classic Experience (Disc 2)
D---A 2009/01/18 17:48         0  CLASSI~2  Classic Experience II (Disc 1)
D---A 2009/01/18 17:49         0  CLASSI~3  Classic Experience II (Disc 2)
D---A 2009/01/28 10:45         0  DARE!  Dare!
D---A 2009/01/18 17:55         0  HEARMY~1  Hear My Song (Best Of Josef Locke)
D---A 2009/01/28 10:45         0  JOSHUA~1  Joshua Tree
D---A 2009/01/18 18:09         0  ONEORI~1  One Original Step Beyond - The Story Of Ska
D---A 2009/01/18 18:10         0  PAINTI~1  Painting It Red [Expanded]
D---A 2009/01/28 10:47         0  PRINCE  Prince
D---A 2009/01/18 19:03         0  WAROFT~1  War of the Worlds
D---A 2009/01/18 19:02         0  VIVALD~1  Vivaldi_ The Four Seasons
D---A 2009/01/18 18:59         0  THISIS~1  This Is SKA - The Famous And Infamous
D---A 2009/01/18 19:00         0  TRUECO~1  True Confessions
D---A 2009/01/28 10:47         0  QUEENG~1  Queen Greatest Hits [UK CD]
----A 2007/11/08 21:07   2255368  TORAMO~1.WMA  To Ramona.wma
   2 File(s),   2255664 bytes total
  17 Dir(s),     324320K bytes free
>

So I'm now a happy bunny.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 09, 2009 - 06:12 PM
10k+ Postman


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

By the way, does anyone else have problems with some SD not responding to initialisation:

Sandisk 128MB - No
"integral" 1GB - Yes
Tesco 4GB - Yes
Kingston 16GB - No
no-name 1GB - Yes
Kingston 2GB (micro SD in carrier) - No

I've tried defining the FCLK_SLOW:
Code:
#define   FCLK_SLOW()      (SPCR |= ((1<<SPR0)|(1<<SPR1) ))

which for F_CPU=8MHz should select /128 to run the SPI at 62.5kHz - actually too slow but I get the same with /64

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
meslomp
PostPosted: Aug 10, 2009 - 09:20 AM
Raving lunatic


Joined: May 02, 2007
Posts: 3990
Location: Nieuwegein, Netherlands

Cliff,

I have had a few minutes to play with your described settigns.
The code space still was around 47K, but that was including the entire terminal application. The memory space I reduced to 1350Bytes. I decreased the _MAX_LFN parameter to a lower value. It is used for long filename support( want to use that) and as far as I could tell it is teh max number of characters a file name may be. As i intend to always use a format of date and time + extension I could reduce this number and save some more bytes.

btw nice music choice Smile

Thanks for telling about the additional memory usage. I will have to keep that in mind.

regards

_________________
1)Datasheet and application notes checked?
2)tutorial forum
3)Newbie start here
 
 View user's profile Send private message  
Reply with quote Back to top
djoshi
PostPosted: Aug 24, 2009 - 10:53 PM
Raving lunatic


Joined: Dec 04, 2007
Posts: 2639
Location: UK London

Hi All

I am trying there guide in geting the FatFs working, but i am getting some problems.

Mojority of the errors i get are repeated, so i presume all route to same area.

Quote:

E:\AVR_Project\CHIP\FAT\ffsample\avr\default/../main.c:584: undefined reference to `xatoi'
E:\AVR_Project\CHIP\FAT\ffsample\avr\default/../main.c:570: undefined reference to `xprintf'
E:\AVR_Project\CHIP\FAT\ffsample\avr\default/../main.c:243: undefined reference to `xfunc_out'
E:\AVR_Project\CHIP\FAT\ffsample\avr\default/../main.c:245: undefined reference to `xputs'
E:\AVR_Project\CHIP\FAT\ffsample\avr\default/../main.c:248: undefined reference to `xputc'



And warnings

Quote:

../main.c:322: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness
../main.c:318: warning: pointer targets in passing argument 1 of 'get_line' differ in signedness
../main.c:249: warning: pointer targets in passing argument 1 of 'get_line' differ in signedness



DJ
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 25, 2009 - 09:28 AM
10k+ Postman


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

The "x" functions are in xitoa.S - make sure this is added to the list of files to be built in your project

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
djoshi
PostPosted: Aug 25, 2009 - 09:33 AM
Raving lunatic


Joined: Dec 04, 2007
Posts: 2639
Location: UK London

Thanks i remember i have not included the file, so i will added it in the eveneing.

Thanks

_________________
Thanks

Regads

DJ
 
 View user's profile Send private message  
Reply with quote Back to top
djoshi
PostPosted: Aug 25, 2009 - 06:34 PM
Raving lunatic


Joined: Dec 04, 2007
Posts: 2639
Location: UK London

The errors have gone, but i am getting 50 of the warnigns as shown below

Quote:
../main.c:515: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness

Quote:
e:/program files/winavr20090313/lib/gcc/../../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for <util/delay.h>"


By the way why is there a UART, i though the code uses SPI and not the UART ports.


DJ
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 25, 2009 - 06:42 PM
10k+ Postman


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

Quote:

i am getting 50 of the warnigns as shown below

If you are worried about that it suggest you haven't read the whole of this thread.

I actually went to the trouble of fixing up all the warnings (by changing a lot of "char" to "BYTE") but it's benign

The UART in the demo program is for you to control the demo. It presents a command prompt and (again as documented in this thread) you type commands like "di 0", "fi 0", "fl" etc.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
djoshi
PostPosted: Aug 25, 2009 - 07:31 PM
Raving lunatic


Joined: Dec 04, 2007
Posts: 2639
Location: UK London

So i presume it still works with all the warnings

DJ

_________________
Thanks

Regads

DJ
 
 View user's profile Send private message  
Reply with quote Back to top
djoshi
PostPosted: Aug 25, 2009 - 07:34 PM
Raving lunatic


Joined: Dec 04, 2007
Posts: 2639
Location: UK London

With USART i presume i need the terminal on the PC, if i want to avoid all this a write test file, can this be done with the download recommened, as the guide does not show this.

DJ

_________________
Thanks

Regads

DJ
 
 View user's profile Send private message  
Reply with quote Back to top
djoshi
PostPosted: Aug 25, 2009 - 07:49 PM
Raving lunatic


Joined: Dec 04, 2007
Posts: 2639
Location: UK London

Is there a sample cod e that is known to work that creates a file and writes hello.

This way i can test that everything is ok in terms of connection etc.

DJ
 
 View user's profile Send private message  
Reply with quote Back to top
djoshi
PostPosted: Aug 26, 2009 - 07:21 PM
Raving lunatic


Joined: Dec 04, 2007
Posts: 2639
Location: UK London

Quote:

That's a benign warning - ignore it.

What does Benign mean?
Quote:
../main.c:544: warning: pointer targets in passing argument 2 of 'xatoi' differ in signedness

So code can work and i dont need to worry about all these warnings? Right?

_________________
Thanks

Regads

DJ
 
 View user's profile Send private message  
Reply with quote Back to top
SteveN
PostPosted: Aug 26, 2009 - 07:29 PM
Raving lunatic


Joined: Nov 14, 2001
Posts: 3438
Location: Charlottesville, VA USA

Quote:
What does Benign mean?


From the Merriam-Webster dictionary:

having no significant effect, harmless
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 27, 2009 - 11:34 AM
10k+ Postman


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

If you really want to know it all hinges around the fact that there are three types of char.

"char", "signed char" and "unsigned char".

"char" is neither signed nor unsigned. A constant string like "Hello, world" is of type char. If you pass this to a routine declared to use "signed char" or "unsigned char" you will get a warning about "differ in signedness".

On the whole this does not matter but if you worry about this then, like I say, you can add typecasts and change "char var"'s into "BYTE var"'s as I did (BYTE is "unsigned char")

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Aug 30, 2009 - 02:57 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


djoshi wrote:
Is there a sample cod e that is known to work that creates a file and writes hello.

This way i can test that everything is ok in terms of connection etc.

DJ


Not... per se. However, if you follow the tutorial precisely, it will lead you to an area where you can read and write, just by following the instructions in the example. In any case, this is something you need to do before going any further, as, as many have pointed out, some SD cards don't respond to the initialization. There's no sense in you wasting time pulling out your hair over a card that's borked.

I suggest that you follow the tutorial line by line. I did my best to write it as clearly as possible, and normally there is not one single thing that is left unsaid for getting it up and running on a bog-standard AVR and SD socket. (Of course, if there is anything unclear, just let me know and I'll do my best to fix it.). Again: follow it LINE BY LINE.

Hope it works for you!

Cheers,
Kenn
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Aug 30, 2009 - 02:58 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


clawson wrote:
How very annoying. I just spent a rather unhappy couple of hours adding printf()s and driving each control line in turn, checking wiring with a meter and so on to try and track down why I wasn't getting the 0x01 response to CMD0. All the control lines seemed to be connected and drivable/readable (including card inserted and write protect). The only I/O I didn't check was PE7 which I was using to switch Vcc to the card. As the SD socket from www.futurlec.com has a power LED I was pretty sure at least that bit was working.

Except it wasn't.

The Chan example code has:
Code:
   PORTE = 0b11110010; // Port E
   DDRE  = 0b10000010;

and mmc.c has:
Code:
static
void power_on (void)
{
   PORTE &= ~0x80;            /* Socket power ON */

and
Code:
static
void power_off (void)
{
...
   PORTE |=  0x80;         /* Socket power OFF */

It only took me about 2 hours to realise that all this is the "wrong way up" (because Chan's example circuit uses PE7 to switch a transistor off and thus inverts the sens of it). What was actually happening was that each time the card was accessed the power was momentarily being turned off, not on.


I hadn't realized there were a new version of FatFS. Not having looked into it yet, I can't say whether my tutorial needs updating or not. Cliff, do Chen's changes break my tutorial?

Kenn
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 30, 2009 - 04:41 PM
10k+ Postman


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

Kenn,

I *think* there are changes which might have a bearing. Somewhere in this thread someone said something about needing to add code in the initialization to slow things down. Yet the newer code seems to have a macro FCLK_SLOW() at the salient places. I imagine there may be other such improvements in 0.7c

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Chupa
PostPosted: Aug 31, 2009 - 01:25 AM
Wannabe


Joined: Sep 12, 2004
Posts: 99
Location: Clearwater, Florida, USA!

Good tut. I got it working on a mega644 of my own.

I'm attempting to read an mp3 off a SD card and feeding to a VS1002 mp3 decoder chip. IM a long ways away from that but I gota start somewhere. I'm trying to understand the process of making file data present on the Atmega from a terminal (for now).

I believe it goes something like this, Correct me if im wrong please:

Initialize disk - di 0
Mount the drive - fi 0
Open the file, mode 3 for read - fo 3 1.mp3
read the file - fr 512

I think that would make the first 512 bytes of the file present in Buff[] for me to do with what I want, which in this case would be to send it to the VS1002 for DAC. Is that process correct?
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Aug 31, 2009 - 08:53 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


clawson wrote:
By the way, does anyone else have problems with some SD not responding to initialisation:

Sandisk 128MB - No
"integral" 1GB - Yes
Tesco 4GB - Yes
Kingston 16GB - No
no-name 1GB - Yes
Kingston 2GB (micro SD in carrier) - No

I've tried defining the FCLK_SLOW:
Code:
#define   FCLK_SLOW()      (SPCR |= ((1<<SPR0)|(1<<SPR1) ))

which for F_CPU=8MHz should select /128 to run the SPI at 62.5kHz - actually too slow but I get the same with /64

Cliff


Could this be due to current requirements making the voltage sag? I realized that in my original tutorial, I recommend using the AVR output pin for voltage. In retrospect, this isn't at all what I do in practice, as I've connected the card straight up to the 3.3V rail. These SD cards tend to pull a lot of amps (relative to the rest of a uC circuit), and so these problems might be more due to insufficient current supply rather than inherent card incompatibility. If you still have those cards lying around, why not start adding some capacitance to the V_in at the SD card and see if anything improves?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Aug 31, 2009 - 11:17 AM
10k+ Postman


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

Quote:

If you still have those cards lying around, why not start adding some capacitance to the V_in at the SD card and see if anything improves?

Great idea - but for starters I'll just jst use a high current PSU direct as I think that is the issue. Another approach would be to use several IO pins to power the card to share the current load.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
unebonnevie
PostPosted: Oct 16, 2009 - 05:09 PM
Resident


Joined: Oct 30, 2008
Posts: 648


Quote:
CAVEAT!!!:
Quote:
You MUST use 3.5V or less on both the SD card, and the SPI lines. If your chip is already running at <3.5V, great, otherwise you NEED level converters. Don't be mad at me if you blow up your SD card because you gave it too much juice. (They like 3.3V, but will tolerate 3.5V.)


Folks, what's the best way to go from 5V to 3.3V per the above? Diodes/resistors/DC-2-DC stepdown IC? Appreciate for specific details.

Btw, FatFS is GPL?

Thx


Last edited by unebonnevie on Oct 16, 2009 - 05:52 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 16, 2009 - 05:12 PM
10k+ Postman


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

In their mini-board range Futurlec have:

http://www.futurlec.com/Mini_Logic.shtml
and
http://www.futurlec.com/Mini_SC.shtml

Or if you want to do it yourself then just borrow the design of that 74LC245 based board.

Or there is, of course, the option of running everything (including the AVR) at 3V3 in the first place. (except that the speed junkies may baulk at possibly having to run the AVR slower - God forbid!)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Oct 16, 2009 - 06:38 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


unebonnevie wrote:
Quote:
CAVEAT!!!:
Quote:
You MUST use 3.5V or less on both the SD card, and the SPI lines. If your chip is already running at <3.5V, great, otherwise you NEED level converters. Don't be mad at me if you blow up your SD card because you gave it too much juice. (They like 3.3V, but will tolerate 3.5V.)


Folks, what's the best way to go from 5V to 3.3V per the above? Diodes/resistors/DC-2-DC stepdown IC? Appreciate for specific details.

Btw, FatFS is GPL?

Thx


Definitely NOT a resistor. You'll apply 5V to the chip until the current starts moving. I'm not sure if you'll fry some things or not, but I wouldn't want to try it.

I just run my uC at 3.3V. That's a much easier way of doing things for me. Of course, you could make a transistor bank in order to level shift, or just get one of those MAX level shifters.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 16, 2009 - 06:41 PM
10k+ Postman


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

Quote:

Btw, FatFS is GPL?

ff.h just says:
Code:
/  Copyright (C) 2009, ChaN, all right reserved.
/
/ * The FatFs module is a free software and there is NO WARRANTY.
/ * No restriction on use. You can use, modify and redistribute it for
/   personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
/ * Redistributions of source code must retain the above copyright notice.

Which sounds more like a BSD licence to me though I don't think he actually names one of the well known licences as such.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
unebonnevie
PostPosted: Oct 16, 2009 - 08:46 PM
Resident


Joined: Oct 30, 2008
Posts: 648


Here is a schematic that shows how to get the SD card to 3.3V.

http://www.olimex.com/dev/images/sam7-p64-sch.gif

Urggg...Sorry, not really. Smile
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Oct 19, 2009 - 02:38 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


unebonnevie wrote:
Here is a schematic that shows how to get the SD card to 3.3V.


That schematic uses 3.3V for the microcontroller. While I'm certain that it will be useful for anyone hoping to hook up a 3.3V card, I think it confuses the question at hand, which is how to hook it up to 5V.
 
 View user's profile Send private message  
Reply with quote Back to top
MasterBate
PostPosted: Oct 23, 2009 - 12:51 PM
Wannabe


Joined: Sep 14, 2009
Posts: 61
Location: Dresden, Germany

Hello

Clawson gave me the hint to this tutorial and i have a quesition:

Code:
#define DD_MOSI   DDB5
#define DD_SCK   DDB7
#define DDR_SPI   DDRB
#define DD_SS   4


Where ist the pin-declaration for the MISO-line?
Is there a difference between for example DDB5 and PB5?
Do i need the SS for my ATmega(on my AVR it's NC)?

And what is with the FCLK-Settings?

Thank you
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 23, 2009 - 01:05 PM
10k+ Postman


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

He's only using those defines to set the bits in the DDR that are outputs (by default the rest are inputs) so by not specifically setting MISO it'll just be left as an input.

To be honest the point he's making is that this is not the cast in stone way it MUST be done but simply that what exists in power_on() must match the way the hardware has been wired up. As you'll see Chan simply did:
Code:
   PORTB = 0b10110101;         /* Enable drivers */
   DDRB  = 0b11000111;
   SPCR = 0b01010000;         /* Initialize SPI port (Mode 0) */
   SPSR = 0b00000001;

without any fancy naming of the individual bits. Though it's true that you have to sit down and study this in conjunction with that avr_mmc.png picture quite a bit to spot what he's actually doing.

avr_mms.png shows Chan using a 9.216MHz crystal but you aren't tied to that - the key point is that if you use a very fast F_CPU (like 16 or 20MHz) then you may need to implement the FCLK_SLOW() macro to slow down the SPI during the start of initialisation. Just for "belts and braces" I used:
Code:
#define   FCLK_SLOW()      (SPCR |= ((1<<SPR0)|(1<<SPR1) ))   /* Set slow clock (100k-400k) */
#define   FCLK_FAST()      (SPCR = 0b01010000)               /* Set fast clock (depends on the CSD) */

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
unebonnevie
PostPosted: Oct 28, 2009 - 07:21 AM
Resident


Joined: Oct 30, 2008
Posts: 648


Here is a schematic to show how to have 3.3V for the MMC/SD card.

http://www.mikroe.com/pdf/mmc-sd_board_schematic.pdf
 
 View user's profile Send private message  
Reply with quote Back to top
MasterBate
PostPosted: Oct 29, 2009 - 02:51 PM
Wannabe


Joined: Sep 14, 2009
Posts: 61
Location: Dresden, Germany

So some cards doesn't seem to work.
But how does a cardreader for the PC manage the cards? The procedure of initialization and so on is the same. Then where is the difference?
 
 View user's profile Send private message  
Reply with quote Back to top
ratep2001
PostPosted: Nov 19, 2009 - 10:56 PM
Newbie


Joined: Oct 09, 2009
Posts: 14


Does anybody made this work on Olimex AVR-TLCD-128CAN development board?

I am simply trying to get the file names up on the LCD screen, but it seems that the Finfo is empty although I put several files on the card using the PC and formatting the card to FAT. Where to start debugging?

I skipped completely the UART part since I am not using a console, might some definition their be the reason, although everything is compiling without errors?

Regards,
P.
 
 View user's profile Send private message  
Reply with quote Back to top
divgup
PostPosted: Nov 20, 2009 - 04:38 AM
Rookie


Joined: Sep 01, 2008
Posts: 28
Location: India,Delhi

ratep2001 wrote:
Does anybody made this work on Olimex AVR-TLCD-128CAN development board?


I am simply trying to get the file names up on the LCD screen, but it seems that the Finfo is empty although I put several files on the card using the PC and formatting the card to FAT. Where to start debugging?


1)Try formatting the CARD with Ms-Dos (Select the Cluster size according to the File System you have implemented).

2)If the connections are correct it will work.
3)To start Debugging ,Check if MBR loads successfully.
4)Have you selected the right Crystal and whether correct power supply is given its 3.3 V by default.
5)I have tried this code on a SD-CARD having memory upto 512 Mb.

6)If it still doesn't work i will suggest try it on SD-CARD of some other company.
This codes works fine with ScanDisk(64MB) and Nokia(128 Mb)

B'Regards
Dakudiv Twisted Evil
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
clawson
PostPosted: Nov 20, 2009 - 10:16 AM
10k+ Postman


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

Get a copy of WinHex on your PC and use it to explore the key sectors in the file structure (MBR, BPB, FAT entries, root DIR). Then add debug to the FatFs code to show the sector contents after each of these key sectors is reads and make sure it's seeing the same thing and interpreting it properly.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Nov 20, 2009 - 11:18 AM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
Location: Wormshill, England

Surely the first step is to run your AVR at 3.3V.
Connect all the relevant pins of your card reader.
Connect LEDs for Card-detect and Write-protect.

Use the basic disk commands to read sectors. Observe any error returns.

If necessary, put stubs in for lying about card-detect etc.

You can examine the sector contents and just see that they do not contain garbage.

If the disk-commands "di", "dd", "ds" etc work ok, then the FAT commands "fi", "fs", "fl" ... etc should work too. And unlike a lot of other SDCard code, FatFs works fine with FAT16 and FAT32.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
Magister
PostPosted: Nov 20, 2009 - 06:22 PM
Hangaround


Joined: Aug 06, 2008
Posts: 146
Location: Montréal, QC

I adapted it for a MEGA168, using a 10ms timer too, and it works pretty well!
I started from the original AVR sample and I kept the socket insertion and write protection functionnalities etc. I remapped pins to my pins, I commented out everything about RTC. I took the UART souce from the OP.

For timer2 I use this at 16MHz, it's not exact but for a test, it's ok:
Code:
   OCR2A = 156-1;      // Timer2: 100Hz interval (OC2)
   TCCR2A = _BV(WGM21);                // CTC mode (clear timer on compare match)
   TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20);     // clock/1024

   TIMSK2 = _BV(OCIE2A);   // Enable TC2.oc, interrupt


For SPI speed I used:
Code:
// 16MHz / 64 = 250K, in the slow clock range
#define   FCLK_SLOW()      (SPCR |=  _BV(SPR1))      /* Set slow clock (100k-400k) */
#define   FCLK_FAST()      (SPCR &= ~_BV(SPR1))      /* Set fast clock (depends on the CSD) */


My 168 is running at 5V, the SD at 3.3V, and to communicate with the card (a lexar 2GB) I use voltage divider on SCK, MOSI, SS. I can read/write SDHC/FAT32. (I changed the main to do some open/write/close then some open/read/close etc and output some debug on the serial port, because the "monitor" is too big for my 168)
 
 View user's profile Send private message  
Reply with quote Back to top
ratep2001
PostPosted: Nov 20, 2009 - 11:45 PM
Newbie


Joined: Oct 09, 2009
Posts: 14


Thank you for the great feedback.

What I can see is that the disk_initialize() routine returns error (1). Does this mean that something is wrong with the hardware (pin mapping, clock settings etc.) or it can also be a problem with the way the card is formatted on a PC (FAT or FAT32 FS, cluster size etc.)?

I have a code example that works without using FATFS, and I am using the same pin mapping, so I am not sure if I have a pure hardware problem...

Regards,
P
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Nov 21, 2009 - 08:48 AM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
Location: Wormshill, England

You are using a CAN128, so you should be very similar to the mega64/mega128 sample code.

Do you have an LED on the CD output. So you can verify the Card detect input when you insert/remove card.
Basically, if you have the SPI lines + CS + CD lines connected correctly then disk_initialise() should be ok.

I would suggest just making a fresh start with unzipping the project. If you can match the wiring exactly then the only change is 'mcu=at90can128' in the Makefile.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
Mike B
PostPosted: Nov 21, 2009 - 07:10 PM
Raving lunatic


Joined: Jun 22, 2004
Posts: 3849
Location: South West Utah, USA

david.prentice wrote:
If you can match the wiring exactly then the only change is 'mcu=at90can128' in the Makefile.
Not correct in this case. Read the migration document:

AVR096: Migrating from ATmega128 to AT90CAN128
http://www.atmel.com/dyn/resources/prod ... oc4313.pdf

migration document wrote:
The AT90CAN128 is functionally pin compatible with ATmega128. Certain pins have been upgraded with regard to their associated alternate functions, the change of the timers/counters index and the voluntary removal ATmega103 compatibility.


There are some important changes like the synchronous and aynchronous timer0 and timer2 register names are swapped. The pins are in the same place, its just program code gets messed up when switching between these chips.

The ATmega128 SFIOR register bits were split up and moved into AT90CAN128 GTCCR, ADCSRB and MCUCR registers. MCUCR and MCUCSR are changed and so on. Some bit locations have moved, so program code that used numeric constants to manipulate bits in these registers, rather than using the individual bit names is another problem. For example: the mega128 SM bit in MCUCR=0x20 would become 90CAN SMCR=0x01, while (1 << SM) would still be OK when changed to the correct register. At least cases where both the register changed and the bit position changed are rare.
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Nov 21, 2009 - 08:44 PM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
Location: Wormshill, England

From memory, there is one 100Hz timer IRQ and one SPI function.
Also from memory, the code uses the relevant bit names. So the code will compile correctly regardless of where the sfr's live in the AVR. MOSI, MISO, SCK use the same physical pins. The SS, Card-detect, LED-indicators are all just regular GPIO.

I do not have a CAN128. But I am sure that ratep2001 has already checked the availability of these SPI and GPIO pins on his particular board.

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
ratep2001
PostPosted: Nov 21, 2009 - 09:39 PM
Newbie


Joined: Oct 09, 2009
Posts: 14


I have just solved the problem with the disk_initialize() error - it was indeed a hardware problem.

Since my CS pin is on the PORTG, blindly replacing the code from the tutorial and believing the power_on() routine was platform independet (with CS on PORTC) gave me the problem in the power_on() routine. Maybe a good idea is to define new DDR_CS in the pin mapping section and use it in all other routines, like power_on, to avoid any platform dependent definitions further on.

Now I get error 9 - INVALID OBJECT as FRESULT from the function f_readdir. What can be wrong?

Since I place all my files in the root, I define *ptr=' ' in the f_opendir function. Maybe this gives me a wrong dir object? Can I completely skip f_openddir if I am working in the root? If Yes, what do I replace &dir from f_readdir() with?

Regards,
P
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Nov 21, 2009 - 10:16 PM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
Location: Wormshill, England

You should get good results for "di 0", "ds 0", "dd 0 123".
Try "fi 0", "fs", "fl".
Then "fg directory", "fl"

The default "ff.h" and "ff.c" should work out of the box. You have probably only altered "rtc.c" and "mmc.c"

Go through all the commands in "main.c" to exercise the filesystems. Try reading and writing files, making directories etc.

You should make no alterations to "ff.c" at all. If you want to see how to use f_opendir() then look at how it is exercised in "main.c".

David.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
ratep2001
PostPosted: Nov 21, 2009 - 11:28 PM
Newbie


Joined: Oct 09, 2009
Posts: 14


I am not using the uart console, so I cannot send the commands di, fi and fl. In the main.c, I put just a very short version of the original code:

// Initialize disk #0
di_res = disk_initialize((BYTE)0);

// File-system initialize - mount the drive #0
fi_res = f_mount((BYTE)0, &Fatfs[0]);

// Directory listing

*ptr = ' '; // No directories used - all files in root
/* MMC - SD card Directory listing */
// while (*ptr == ' ') ptr++;
res = f_opendir(&dir, ptr);


Why do I get error nr. 5 (FR_NO_PATH) as a result of f_opendir? How do I refer to the root in the f_opendir command to create the directory object?

I tried also to list the directory called "direct", by defining *ptr = "direct", and I got the same error.

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.)?

Regards,
P
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Nov 22, 2009 - 08:24 AM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
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.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
clawson
PostPosted: Nov 22, 2009 - 02:25 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
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.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
lamming
PostPosted: Nov 23, 2009 - 04:02 PM
Rookie


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
 
 View user's profile Send private message  
Reply with quote Back to top
ratep2001
PostPosted: Nov 30, 2009 - 10:21 AM
Newbie


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.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Nov 30, 2009 - 11:11 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
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?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Nov 30, 2009 - 11:24 AM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
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.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
lamming
PostPosted: Nov 30, 2009 - 06:10 PM
Rookie


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 Smile

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
 
 View user's profile Send private message  
Reply with quote Back to top
ratep2001
PostPosted: Nov 30, 2009 - 11:58 PM
Newbie


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
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Dec 01, 2009 - 08:48 AM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
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.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
IsThisNameTakenAlready
PostPosted: Dec 04, 2009 - 08:20 PM
Newbie


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)
 
 View user's profile Send private message  
Reply with quote Back to top
david.prentice
PostPosted: Dec 04, 2009 - 08:34 PM
10k+ Postman


Joined: Feb 12, 2005
Posts: 20707
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.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
IsThisNameTakenAlready
PostPosted: Dec 05, 2009 - 01:21 AM
Newbie


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.
 
 View user's profile Send private message  
Reply with quote Back to top
MasterBate
PostPosted: Dec 21, 2009 - 07:23 PM
Wannabe


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...
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Dec 21, 2009 - 08:21 PM
10k+ Postman


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

Has the code burst 32K?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
MasterBate
PostPosted: Dec 21, 2009 - 08:56 PM
Wannabe


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)
 
 View user's profile Send private message  
Reply with quote Back to top
MasterBate
PostPosted: Dec 22, 2009 - 09:29 AM
Wannabe


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.
 
 View user's profile Send private message  
Reply with quote Back to top
MasterBate
PostPosted: Dec 22, 2009 - 04:05 PM
Wannabe


Joined: Sep 14, 2009
Posts: 61
Location: Dresden, Germany

No [**censored**]!
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?
 
 View user's profile Send private message  
Reply with quote Back to top
kapu27
PostPosted: Jan 19, 2010 - 01:06 PM
Newbie


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?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jan 19, 2010 - 01:17 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71934
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)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Zora53
PostPosted: Feb 05, 2010 - 05:20 AM
Newbie


Joined: Oct 29, 2009
Posts: 13


MasterBate wrote:
No [**censored**]!
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.
 
 View user's profile Send private message  
Reply with quote Back to top
Zora53
PostPosted: Feb 10, 2010 - 12:12 AM
Newbie


Joined: Oct 29, 2009
Posts: 13


Tried a different card - Cannon 16Meg SD - same problem...
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Feb 10, 2010 - 08:34 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Zora53 wrote:
MasterBate wrote:
No [**censored**]!
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.
 
 View user's profile Send private message  
Reply with quote Back to top
Zora53
PostPosted: Feb 10, 2010 - 08:00 PM
Newbie


Joined: Oct 29, 2009
Posts: 13


I solved my problem, although I still can't explain why things weren't working in the first place. All I did was remove my SD card from the breadboard and connect it directly to the port header on the STK500, so now I just have 6 wires going from the STK to the card's breakout board. Everything else is exactly the same. Can anyone explain how the breadboard could have messed up SPI comms with the SD card?

Also I forgot to mention earlier that one of the symptoms I had when the card was malfunctioning was that instead of the 0xFE byte at the beginning of a data block in the card's response, I would always get 0xFC.
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Feb 10, 2010 - 08:02 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Maybe you were picking up noise on the longer lines? I don't know how the current Chen handles speed. It could be that the initial conversation is at a lower speed and then it tries to transfer data at a higher speed. At the higher speed, the noise from longer lines might have been enough to disrupt the communication.
 
 View user's profile Send private message  
Reply with quote Back to top
Zora53
PostPosted: Feb 10, 2010 - 09:27 PM
Newbie


Joined: Oct 29, 2009
Posts: 13


kubark42 wrote:
Maybe you were picking up noise on the longer lines? I don't know how the current Chen handles speed. It could be that the initial conversation is at a lower speed and then it tries to transfer data at a higher speed. At the higher speed, the noise from longer lines might have been enough to disrupt the communication.


I tried different SPI clock speeds, all the way down to 25kHz and it didn't make a difference. But yes, it seems like there had to be noise somewhere.
 
 View user's profile Send private message  
Reply with quote Back to top
hsieber
PostPosted: Apr 06, 2010 - 09:07 PM
Newbie


Joined: Jun 02, 2009
Posts: 15


I have implemented the console program from Chen and modified it for my test setup. I have benefited greatly from the many others who preceded me, and heeded the cautions & caveats. Things seem to be basically working- I can mount & initialize the SD card, and read files pre-written elsewhere. The question is, has anyone done a 'magic decoder ring' for the console program to make it easier to use? I can't find a user's manual, or function description manual anywhere. I'm looking for things like file mode arguments for the f_open() and f_write() functions. For instance, things seem to work if I use 0x01 (read only) as the mode argument for fo (file open), but I'm not sure if other flags & descriptors need to be or'ed in. This will be even more important for writing files. I'm willing to wade through the ff.c and ff.h files if I have to but of course I'd prefer the easy way.

I would like to get a solid grasp of the demo program, next step is to go right to the functions to open, write, append etc as required by the application. Sorry if this is in the wrong place- it's not really a reply to the previous post but it's not a new topic either. Feel free to advise as to proper etiquette- it's my first time (be gentle...).

Thanks,
Harry
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 06, 2010 - 09:59 PM
10k+ Postman


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

Quote:

This will be even more important for writing files. I'm willing to wade through the ff.c and ff.h files

You can't expect to use a lib without reading at least the .h file - that's what (should!) document the API. If you are lucky there'll maybe also be separate documentation (though often this is simply Doxygen extracted from the .h in human readable form)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Apr 07, 2010 - 10:05 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


clawson wrote:
Quote:

This will be even more important for writing files. I'm willing to wade through the ff.c and ff.h files

You can't expect to use a lib without reading at least the .h file - that's what (should!) document the API. If you are lucky there'll maybe also be separate documentation (though often this is simply Doxygen extracted from the .h in human readable form)


I disagree with that. While that might be standard practice, it is in fact more of a sign of laziness than good design. When I bake a cake, I don't mix in the ingredient list with the ingredients.

Doxygen is a bastard solution that doesn't really work except when you already are very clear in what you're doing. It messes up the code royally by adding lots of garbage to a file that should otherwise be clear.
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Apr 07, 2010 - 10:18 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


hsieber wrote:
I have implemented the console program from Chen and modified it for my test setup. I have benefited greatly from the many others who preceded me, and heeded the cautions & caveats. Things seem to be basically working- I can mount & initialize the SD card, and read files pre-written elsewhere. The question is, has anyone done a 'magic decoder ring' for the console program to make it easier to use?


No, it's not something I ever did. What I always did was take the snippets of code that I saw in Chen and modified them to suit my needs. This is really easy with a debugger, since you can follow the code through step by step and see what functions really do the work.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Apr 07, 2010 - 10:22 AM
10k+ Postman


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

Quote:

While that might be standard practice, it is in fact more of a sign of laziness than good design.

But it IS standard practice, so those of us who use libs have to get jiggy with it. You or I may not like it and prefer a proper .doc to describe the API but this is the real world.

I'd far sooner the programmer at least stop to put as much documentation as possible in the .h at least rather than leaving things unsaid!

The AVR-LibC is a good example (I think) that shows that the technique can work well. Almost the entire library reference at:

http://www.nongnu.org/avr-libc/user-manual/modules.html

is Doxygen extracted from the .h's and it reads very well. I'm more than happy with that HTML documenation.

The upshot of Doxygen annotation is that it's FAR more likely that the manual remains in step with the actual functionality offered. It's far to easy for .h/.c to be changed and the programmer to forget to update a separate .doc otherwise.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Apr 07, 2010 - 10:46 AM
Hangaround


Joined: Jun 04, 2008
Posts: 256


[quote="clawson"]
Quote:

The upshot of Doxygen annotation is that it's FAR more likely that the manual remains in step with the actual functionality offered. It's far to easy for .h/.c to be changed and the programmer to forget to update a separate .doc otherwise.


Yup, yup. Wasn't it Churchill who quipped "It has been said that democracy is the worst form of government except all the others that have been tried."?

Still, I'd rather pretty much anything than doxygen. But I do have to admit that the AVR-LibC manual looks pretty good, in fact spectacular, compared to all other doxygen outputs I've seen. I wonder what they do differently?
 
 View user's profile Send private message  
Reply with quote Back to top
hsieber
PostPosted: Apr 07, 2010 - 10:14 PM
Newbie


Joined: Jun 02, 2009
Posts: 15


Thanks for the responses. I didn't mean to imply that I wouldn't take the time to go through the code if necessary; in fact I had to delve through f_write() to create_chain() to get_fat() to move_window() to disk_write() to find the source of a pesky FR_DISK_ERR during writes, only to find that it was all because the SCLK was too fast (looked more like a sine wave than a square wave). And yes, I did read through all 10 pages of this thread and I did see where others had SPI clock speed issues. Thought I had implemented the FCLK_SLOW & _FAST macros but I hadn't. Oddly, this problem didn't seem to affect reads, just writes. Moral- start with the basics & work up, not vice versa.

Also I found Mr. Chan's very nice 'FAT File System Module' description online- everything one needs to know to use the functions.

Thanks again,
Harry
 
 View user's profile Send private message  
Reply with quote Back to top
ArnoldB
PostPosted: Apr 08, 2010 - 11:28 AM
Raving lunatic


Joined: Nov 29, 2007
Posts: 3219


kubark42 wrote:
Still, I'd rather pretty much anything than doxygen. But I do have to admit that the AVR-LibC manual looks pretty good, in fact spectacular, compared to all other doxygen outputs I've seen. I wonder what they do differently?
Isn't that obvious? People knowing how to use doxygen, and time invested in writing the doxygen documentation.

It is the old, simple thing: No tool in the world can convert sh*it into gold, garbage in, garbage out. So if you want non-garbage out, you have to put non-garbage in.
 
 View user's profile Send private message  
Reply with quote Back to top
tabshizzle
PostPosted: Jul 14, 2010 - 02:22 AM
Newbie


Joined: Jul 13, 2010
Posts: 10


First of all, I would like to thank everybody (and especially kubark42) for all their help. I have finally gotten this working on Atmega644P - the comments were especially invaluable.

A few discoveries:
1. I did require an internal pullup. I've experimented with taking out the pullup code, however, the disk I/O initialisation then consistently fails.
2. I was able to use the SS as chip select.

Hence, SPI code resembled as follows:
mmc.c (or diskio.c) initialisation
Code:
#define DD_SS   DDB4
#define DD_MOSI   DDB5
#define DD_MISO   DDB6
#define DD_SCK   DDB7
   
#define SELECT()   PORTB &= ~(1<<DD_SS)
#define   DESELECT()   PORTB |= (1<<DD_SS)

mmc.c (or diskio.c) power on
Code:
DDRB = (1<<DD_SS)|(1<<DD_MOSI)|(1<<DD_SCK);
PORTB = (1<<DD_SS)|(1<<DD_MISO);
SPCR = (1<<SPE)|(1<<MSTR);

I have one question regarding your tutorial, and it's specifically regarding how you set up the timer. You did:
Code:
OCR2A = 90-1;
TCCR2B = 0b00000101;

Now, if you're using the 8Mhz internal oscillator, then the values in TCCR2B result in the clock divided by 128 - resulting in essentially a 65.5Khz timer. You then count to 89 which further divides the 65.5Khz timer by 89 resulting in a 702Hz signal. But the requirement is for a 100Hz timer. Am I missing something?
My timer initilisation was as follows:
Code:
TCCR2B |= (1<<CS22)|(1<<CS21)|(1<<CS20);
OCR2A = 78;

I was thus dividing by the clock by 1024 and then further dividing by 78. 8Mhz/(1024*78) = ~100Hz.
I'm an AVR newbie, so any explanation for the above lines will be very helpful.

Thanks once again!
 
 View user's profile Send private message  
Reply with quote Back to top
meslomp
PostPosted: Jul 14, 2010 - 06:30 AM
Raving lunatic


Joined: May 02, 2007
Posts: 3990
Location: Nieuwegein, Netherlands

If you are running of the internal 8MHz oscillator.( also in anyother case)
what did you have set your clok/8 fuse to? if it is set then you have to divide by an additional factor of 8 giving you roughly 100Hz)

regards

_________________
1)Datasheet and application notes checked?
2)tutorial forum
3)Newbie start here
 
 View user's profile Send private message  
Reply with quote Back to top
tabshizzle
PostPosted: Jul 14, 2010 - 08:51 AM
Newbie


Joined: Jul 13, 2010
Posts: 10


Ah, that might explain it. My CLKDIV8 fuse is not set. Thanks for clearing that up meslomp.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 14, 2010 - 09:16 AM
10k+ Postman


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

Quote:

You then count to 89 which further divides the 65.5Khz timer by 89 resulting in a 702Hz signal.

Just to note that when a timer is run in CTC mode the OCR is always set to "desired count - 1" because the counting sequence includes 0. So a setting of 90-1 (or 89) is actually counting 90 ticks, not 89. So the calculation would be 694.4Hz, not 702Hz.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
steverino
PostPosted: Jul 18, 2010 - 09:31 PM
Rookie


Joined: Jun 30, 2010
Posts: 37


Maybe a helpful hint for those porting this to xmega...

In mmc..c you'll probably notice on your own that you need to change rcvr_spi() to check SPIC.STATUS bit 7 instead of SPIC>DATA bit 7.

At least for me, it was too easy to miss the equivalent change in the marcro, rcvr_spi_m.

Many, many thanks to kbark42, to ChaN, and to all those who have provided helpful input to this tutorial.

Steve
 
 View user's profile Send private message  
Reply with quote Back to top
abhishekbhardwaj007
PostPosted: Jul 23, 2010 - 07:41 PM
Wannabe


Joined: Jun 06, 2009
Posts: 66


has anyone tried this link?

http://www.dharmanitech.com/2009/01/sd- ... fat32.html

Does it work?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 23, 2010 - 07:49 PM
10k+ Postman


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

Quote:

has anyone tried this link?

It might well work but what confidence would you have in software that took until V2.0 to correct something as fundamental as using 8+3 rather than 7+3. Or how about that only in the latest (2.3) code was the following fault fixed:
Quote:
A bug which was causing the program flow to go into infinite loop if the character number 512 in a sector was a CR (Carriage Return, '\r'), in the writeFile function

The subject of this thread is FatFs and the reason the majority of people choose to use it is because it's well written, highly developed, extensively tested code and, because it's used by 1,000's of people, there is a LOT of support for it (such as this very thread). If you used the software in your link where could you hope to find support for it?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
mzeu
PostPosted: Oct 04, 2010 - 03:47 PM
Hangaround


Joined: Mar 27, 2006
Posts: 156


Hello, I'm also trying to integrate this into my Xmega project and I'm running into following problem when I try to compile I get this :

Code:
../FF/rtc.h:12: error: expected ')' before '*' token
../FF/rtc.h:12: error: expected ')' before numeric constant
../FF/rtc.h:18: error: expected declaration specifiers or '...' before '(' token
../FF/rtc.h:19: error: expected ')' before numeric constant


and I don't know why. Has anyone else seen this before or can explain when and why this kind of errors occur ?

the rtc.h looks like this :
Code:

#include "integer.h"

typedef struct {
   WORD   year;   // 2000..2099
   BYTE   month;   // 1..12
   BYTE   mday;   // 1.. 31
   BYTE   wday;   // 1..7
   BYTE   hour;   // 0..23
   BYTE   min;   // 0..59
   BYTE   sec;   // 0..59
line 12 }RTC;

//int iic_write (BYTE, UINT, UINT, const void*);   // Write to IIC device
//int iic_read (BYTE, UINT, UINT, void*);      // Read from IIC device

//int rtc_init (void);                  // Initialize RTC
line 18 int rtc_gettime (RTC*);               // Get time
line 19 int rtc_settime (const RTC*);            // Set time


and rtc.c like this :
Code:

#include <avr/io.h>
#include <string.h>
#include "rtc.h"


int rtc_gettime (RTC *rtc)
{
/*
   BYTE buf[8];


   if (!iic_read(0xD0, 0, 7, buf)) return 0;

   rtc->sec = (buf[0] & 0x0F) + ((buf[0] >> 4) & 7) * 10;
   rtc->min = (buf[1] & 0x0F) + (buf[1] >> 4) * 10;
   rtc->hour = (buf[2] & 0x0F) + ((buf[2] >> 4) & 3) * 10;
   rtc->wday = (buf[2] & 0x07);
   rtc->mday = (buf[4] & 0x0F) + ((buf[4] >> 4) & 3) * 10;
   rtc->month = (buf[5] & 0x0F) + ((buf[5] >> 4) & 1) * 10;
   rtc->year = 2000 + (buf[6] & 0x0F) + (buf[6] >> 4) * 10;
*/
    rtc->sec = 1;
   rtc->min = 2;
   rtc->hour = 3;
   rtc->wday = 4;
   rtc->mday = 5;
   rtc->month = 6;
   rtc->year = 2007;
   return 1;
}




int rtc_settime (const RTC *rtc)
{

   BYTE buf[8];


   buf[0] = rtc->sec / 10 * 16 + rtc->sec % 10;
   buf[1] = rtc->min / 10 * 16 + rtc->min % 10;
   buf[2] = rtc->hour / 10 * 16 + rtc->hour % 10;
   buf[3] = rtc->wday & 7;
   buf[4] = rtc->mday / 10 * 16 + rtc->mday % 10;
   buf[5] = rtc->month / 10 * 16 + rtc->month % 10;
   buf[6] = (rtc->year - 2000) / 10 * 16 + (rtc->year - 2000) % 10;

//   return iic_write(0xD0, 0, 7, buf);
   return TRUE;
}


Thank you very much.
Mat


Last edited by mzeu on Oct 05, 2010 - 08:00 AM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 04, 2010 - 04:02 PM
10k+ Postman


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

Surely this was discussed earlier in the thread? Anyway most AVRs don't have an RTC so there's no way to give accurate timestamps to the files that are created. The only function ff.c actually calls is get_fattime() so in your own main.c (or some appropriate .c file) just use:
Code:
typedef struct {
   WORD   year;   /* 2000..2099 */
   BYTE   month;   /* 1..12 */
   BYTE   mday;   /* 1.. 31 */
   BYTE   wday;   /* 1..7 */
   BYTE   hour;   /* 0..23 */
   BYTE   min;   /* 0..59 */
   BYTE   sec;   /* 0..59 */
} RTC;

...

/*---------------------------------------------------------*/
/* User Provided Timer Function for FatFs module           */
/*---------------------------------------------------------*/
/* This is a real time clock service to be called from     */
/* FatFs module. Any valid time must be returned even if   */
/* the system does not support a real time clock.          */
/* This is not required in read-only configuration.        */
/*---------------------------------------------------------*/
/* Dummy time function as no rtc.c                         */
/*---------------------------------------------------------*/
DWORD get_fattime ()
{
   RTC rtc;


   /* Get local time */
//   rtc_gettime(&rtc);

   rtc.year = 2009;
   rtc.month = 1;
   rtc.mday = 1;
   rtc.wday = 1;
   rtc.hour = 12;
   rtc.min = 0;
   rtc.sec = 0;

   /* Pack date and time into a DWORD variable */
   return     ((DWORD)(rtc.year - 1980) << 25)
         | ((DWORD)rtc.month << 21)
         | ((DWORD)rtc.mday << 16)
         | ((DWORD)rtc.hour << 11)
         | ((DWORD)rtc.min << 5)
         | ((DWORD)rtc.sec >> 1);
}

then remove any other references to "RTC". The above just arranges for all files to have a time stamp of "12:00:00 1/1/2009"

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
mzeu
PostPosted: Oct 04, 2010 - 04:08 PM
Hangaround


Joined: Mar 27, 2006
Posts: 156


that's what I did... or didn't I ?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 04, 2010 - 04:14 PM
10k+ Postman


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

Read again. The function I'm talking about is get_fattime() not rtc_gettime() or rtc_settime(). Just leave rtc.c out of the list of files to build in the makefile and the only "Undefined reference" you'll see is to get_fattime(). So now just provide that dummy function I showed in one of the .c files that IS still being built.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
mzeu
PostPosted: Oct 04, 2010 - 06:09 PM
Hangaround


Joined: Mar 27, 2006
Posts: 156


ah, yes, ok. Will do, thank you.
Taking the risk to annoy you, but let's assume I have an RTC and I just give dummy values here as a start so that the rtc function returns something, where does that error actually come from ?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 04, 2010 - 07:24 PM
10k+ Postman


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

Which line is line 12 in rtc.h ? The error messages say you have errors on lines 12, 18 and 19.

(note however that sometimes you get an error on line N because of a fault on a prior line)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
mzeu
PostPosted: Oct 05, 2010 - 08:02 AM
Hangaround


Joined: Mar 27, 2006
Posts: 156


I edited the respective line numbers above in the code
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 05, 2010 - 10:05 AM
10k+ Postman


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

Well that is VERY odd - line 12 does not have a '*' token as suggested in the error message? Could "RTC" have been defined as a macro prior to this somewhere?

(Oh, just a minute, you said Xmega - could their .h files have something called "RTC" by any chance?)

EDIT: just checked - guess what:
Code:
C:\WinAVR-20100110\avr\include\avr>grep "#define RTC " iox*
iox128a1.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox128a3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox128d3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox16a4.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox16d4.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox192a3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox192d3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox256a3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox256d3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox32a4.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox32d4.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox64a1.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox64a3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */
iox64d3.h:#define RTC    (*(RTC_t *) 0x0400)  /* Real-Time Counter */

So rename this typedef to FS_RTC rather than just RTC.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
mzeu
PostPosted: Oct 05, 2010 - 10:18 AM
Hangaround


Joined: Mar 27, 2006
Posts: 156


wow, great, that's it. Very good thinking, thank you very much once again !
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Oct 05, 2010 - 10:52 AM
10k+ Postman


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

But as a programmer you could have worked this out too. If line 12 was the point of the error (it was) then you have to ask yourself how was the C compiler seeing a "*" on that line. Using the -E option on the compiler is always a good idea to see what the code looks like with any macros expanded. But it was a fair bet that it was a macro. So then you ask yourself "have I defined a macro called RTC?", if not then it must have come from system header files. At which point you use your programmer's experience to guess where/why a macro called "RTC" might be defined.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
theseapalm
PostPosted: Nov 20, 2010 - 01:13 AM
Newbie


Joined: Nov 20, 2010
Posts: 1


I made an account just to thank you kubark42. I wasted one day trying to port the sample code from FATfs on my own. Then I got serious and wasted another half day before I found your TUT which fixed a lot of the other things I wasn't noticing. I was able to get it up and running in a few hours with your TUT. I originally had the card powered straight from my 3.3V but noticed your comment to connect it to an output on the AVR and this had me going in circles for a bit till I noticed another post said not to do that.

I am porting for ATMEGA1284p. WinAVR-20100110, FATfs sample code of October 14, 2010.

I wasn't able to use the mmc.c function for select() that you had because my version of the sample code required a return value. So I tried my best to merge your function with the original.

Code:

static
int select (void)   // 1:Successful, 0:Timeout //
{
   SD_CS_PORT &= ~(1<<SD_CS_PIN);      /* MMC CS = L */
   if (!wait_ready()) {
      DESELECT();
      return 0;
   }
   return 1;
}


Also, I believe chk_power(void) was renamed to power_status(void) in my version of the sample code. I left both in just in case, but the compiler let me know chk_power() was not used.

I also changed the rtc.c return data types to int instead of BOOL. Because the compiler was complaining.

Thanks again for your help and work!
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Nov 21, 2010 - 10:23 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


Glad to hear it! Sometime in the future, when I need to use SD cards again, I'll update the tutorial to reflect Chen's new code. I wouldn't count on that anytime soon, though.

Thanks for publishing your modifications here. I'm sure they'll be put to good use by others.
 
 View user's profile Send private message  
Reply with quote Back to top
netogodoy
PostPosted: Dec 23, 2010 - 07:46 PM
Newbie


Joined: Nov 09, 2008
Posts: 9
Location: Brazil

Hi, I'm trying to use this lib into my mega644 to build a simple data logger, but I'm stuck with all this libs, codes and functions.

I've read the tutorial and made all the changes that kubark42 said to be done, but the code still don't compile. Here is the log:

Code:


avr-gcc  -mmcu=atmega644 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
avr-gcc  -mmcu=atmega644 -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT rtc.o -MF dep/rtc.o.d  -c  ../rtc.c
../rtc.c:8: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rtc_gettime'
../rtc.c:35: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rtc_settime'
../rtc.c:52: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'rtc_init'


When double clicking the error, it points to these lines of the code:

Code:

.
.
BOOL rtc_gettime (RTC *rtc)
.
.
BOOL rtc_settime (const RTC *rtc)
.
.
BOOL rtc_init (void)
.
.


I can't figure out what problem is going on.

Another thing that i would like to ask:

- What are the .h and .c files needed to make a data logger ? There are many files like: mmc.c, diskio.h , ff.h, etc. Wich ones are the essentials to the FATFS lib run like the original one ?

Sorry for any mistake in my english.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Dec 23, 2010 - 07:59 PM
10k+ Postman


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

You can drop rtc.c all together. The only calls made to rtc.c are from the example program in main.c. It calls to rtc_init(), rtc_settime() and rtc_gettime(). It does that in:
Code:
static
void IoInit ()
{
   PORTA = 0b11111111;   // Port A

   PORTB = 0b10110000; // Port B
   DDRB  = 0b11000000;

   PORTC = 0b11111111;   // Port C

   PORTD = 0b11111111; // Port D

   PORTE = 0b11110010; // Port E
   DDRE  = 0b10000010;

   PORTF = 0b11111111;   // Port F

   PORTG = 0b11111;    // Port G

   uart_init();      // Initialize UART driver

/*
   OCR1A = 51;         // Timer1: LCD bias generator (OC1B)
   OCR1B = 51;
   TCCR1A = 0b00010000;
   TCCR1B = 0b00001010;
*/
   OCR2 = 90-1;      // Timer2: 100Hz interval (OC2)
   TCCR2 = 0b00001101;

   TIMSK = 0b10000000;   // Enable TC2.oc, interrupt

   rtc_init();         // Initialize RTC

Just remove this call.
Code:
      case 't' :   /* t [<year> <mon> <mday> <hour> <min> <sec>] */
         if (xatoi(&ptr, &p1)) {
            rtc.year = (WORD)p1;
            xatoi(&ptr, &p1); rtc.month = (BYTE)p1;
            xatoi(&ptr, &p1); rtc.mday = (BYTE)p1;
            xatoi(&ptr, &p1); rtc.hour = (BYTE)p1;
            xatoi(&ptr, &p1); rtc.min = (BYTE)p1;
            if (!xatoi(&ptr, &p1)) break;
            rtc.sec = (BYTE)p1;
            rtc_settime(&rtc);
         }
         rtc_gettime(&rtc);
         xprintf(PSTR("#u/#u/#u #02u:#02u:#02u\n"), rtc.year, rtc.month, rtc.mday, rtc.hour, rtc.min, rtc.sec);
         break;

Just remove this entire "case 't'". Finally:
Code:
/*---------------------------------------------------------*/
/* User Provided Timer Function for FatFs module           */
/*---------------------------------------------------------*/
/* This is a real time clock service to be called from     */
/* FatFs module. Any valid time must be returned even if   */
/* the system does not support a real time clock.          */
/* This is not required in read-only configuration.        */


DWORD get_fattime ()
{
   RTC rtc;


   /* Get local time */
   rtc_gettime(&rtc);

   /* Pack date and time into a DWORD variable */
   return     ((DWORD)(rtc.year - 1980) << 25)
         | ((DWORD)rtc.month << 21)
         | ((DWORD)rtc.mday << 16)
         | ((DWORD)rtc.hour << 11)
         | ((DWORD)rtc.min << 5)
         | ((DWORD)rtc.sec >> 1);
}

This is the only one of any importance. The value returned from this function is used to time stamp the files when they are created/written. What I've done is:
Code:
typedef struct {
   WORD   year;   /* 2000..2099 */
   BYTE   month;   /* 1..12 */
   BYTE   mday;   /* 1.. 31 */
   BYTE   wday;   /* 1..7 */
   BYTE   hour;   /* 0..23 */
   BYTE   min;   /* 0..59 */
   BYTE   sec;   /* 0..59 */
} RTC;

DWORD get_fattime ()
{
   RTC rtc;


   /* Get local time */
//   rtc_gettime(&rtc);

   rtc.year = 2009;
   rtc.month = 1;
   rtc.mday = 1;
   rtc.wday = 1;
   rtc.hour = 12;
   rtc.min = 0;
   rtc.sec = 0;

   /* Pack date and time into a DWORD variable */
   return     ((DWORD)(rtc.year - 1980) << 25)
         | ((DWORD)rtc.month << 21)
         | ((DWORD)rtc.mday << 16)
         | ((DWORD)rtc.hour << 11)
         | ((DWORD)rtc.min << 5)
         | ((DWORD)rtc.sec >> 1);
}

That just means all files are stamped "12:00 1-1-2009".

Either provide your own RTC functionality and arrange for the result to be given in response to get_fattime() or do what I've done and all files will have a fixed date/time.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Modeon
PostPosted: Dec 29, 2010 - 09:14 AM
Newbie


Joined: Nov 28, 2010
Posts: 7


Have someone edited this code for atmega8 ?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Dec 29, 2010 - 11:36 PM
10k+ Postman


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

You won't get FatFs to fit in a mega8 bit petitFs will - the smallest build is something like just 4K

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Modeon
PostPosted: Dec 30, 2010 - 01:04 AM
Newbie


Joined: Nov 28, 2010
Posts: 7


Damn, so i probably went for nothing through this tut ;/ Can petitFS create a file? I have read that it just can't ;/
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Dec 31, 2010 - 11:43 AM
10k+ Postman


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

Suggest you read:

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

Rather than believing every bit of tittle-tattle you read on the Internet.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
Modeon
PostPosted: Jan 02, 2011 - 11:07 PM
Newbie


Joined: Nov 28, 2010
Posts: 7


So to do this working at atmega8 from attiny85 i just need to change the makefile and those lines in main.c ?
Code:
   PORTB = 0b101011;   /* u z H L H u */
   DDRB =  0b001110;
 
 View user's profile Send private message  
Reply with quote Back to top
Modeon
PostPosted: Jan 02, 2011 - 11:28 PM
Newbie


Joined: Nov 28, 2010
Posts: 7


so even when i compile for attiny the sample of pfFS has errors:
Code:
../usi.S: Assembler messages:
../usi.S:19: Error: constant value required
../usi.S:19: Error: number must be positive and less than 64
../usi.S:64: Error: constant value required
../usi.S:64: Error: number must be positive and less than 64
../usi.S:71: Error: constant value required
../usi.S:71: Error: number must be positive and less than 64
make: *** [usi.o] Error 1
Build failed with 1 errors and 0 warnings...
 
 View user's profile Send private message  
Reply with quote Back to top
js
PostPosted: Jan 02, 2011 - 11:35 PM
10k+ Postman


Joined: Mar 28, 2001
Posts: 22850
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)

A few links that may help you.

http://www.avrfreaks.net/index.php?name ... 256#770256
http://www.avrfreaks.net/index.php?name ... 731#770731
http://www.avrfreaks.net/index.php?name ... 171#771171
http://www.avrfreaks.net/index.php?name ... 591#774591
http://www.avrfreaks.net/index.php?name ... 921#774921
http://www.avrfreaks.net/index.php?name ... 155#775155

_________________
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
Modeon
PostPosted: Jan 03, 2011 - 02:38 PM
Newbie


Joined: Nov 28, 2010
Posts: 7


Thank you a lot, that's what I needed
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jan 03, 2011 - 09:10 PM
10k+ Postman


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

As I think I told you via PM. John Samperi and I have modified the PetitFs code to work on Megas that don't have USI but that do have real UARTs and SPIs. Search out the threads and download the code.

BTW this is not an appropriate thread to continue the diagnose of your PetitFs porting problems - take it to "AVR Forum".

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
san_juan_dad
PostPosted: Jan 17, 2011 - 05:31 PM
Rookie


Joined: Mar 13, 2003
Posts: 36
Location: San Juan Capistrano, CA, USA

Many thanks to everyone that has contributed to this TUT.
I now have FatFS running on a 644p and can:
1) Initialize the disk
2) List directories
3) Open and close a file, with a valid time stamp
But, writing to a file seems to have me stumped. I assume the following process is about right, so correct me please:
a) Open a file for write
b) Write to the “buff” until you have 512, or more bytes
c) Write the first 512 to a sector, using “disk_write”
d) When done, flush the buffer
e) Close the file
My hang-up is that the disk_write function wants to know the “sector”. That’s where I’m stuck. Can anyone help me across this knowledge gap?

Tom
 
 View user's profile Send private message  
Reply with quote Back to top
kubark42
PostPosted: Jan 17, 2011 - 05:41 PM
Hangaround


Joined: Jun 04, 2008
Posts: 256


The sector it's asking for is the memory location of the 512-byte page that you want to write. I haven't used FatFS since I wrote the tutorial, and subsequently rewrote many of the functions to minimize the size and maximize write performance for a very specific task, so I no longer recall exactly how with FatFS you get the sector location after you open the file.

However, I'm certain it will be instantly obvious if you spend a couple minutes looking in the right places. Try backtracking using the example code to see where it gets the sector from.

In any case, this is important, as if you write to the beginning of the file, you're overwriting it, whereas if you're writing to the end you're appending to it. I'm certain you can appreciate the nuance!
 
 View user's profile Send private message  
Reply with quote Back to top
jofre
PostPosted: Jun 24, 2011 - 05:13 PM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

I successfully followed this tutorial in April 2009 using same ucontroller as the OP, I did have just some issues with pull ups, but not a big deal as I posted.

Now, based on that the code reported for other members seemed to be just below 32 K . I've attemped to get the FaTFs with an ATMEGA328.

I've downloaded the latest version from elm-chang R08b April 2011 and found out same name changes that clash with the tutorial posted at the beginning of the thread.

For example the chk_power() function in old version is now called power_status(). I am not sure if there are other things.

The problem is that after it compiled with zero errors this is the result:


Code:

AVR Memory Usage
----------------
Device: atmega328p

Program:   47490 bytes (144.9% Full)
(.text + .data + .bootloader)

Data:       2467 bytes (120.5% Full)
(.data + .bss + .noinit)


I've attempted to use the _FS_MINIMIZE parameter but it seems to be there is a bug on the automatization directives as plenty of errors shows up from the calling of the functions supposed to be suppressed in case of using 1,2 or 3, so it only compiles OK with this parameter set to ZERO. I attempted to remove the terminal functions related , but errors still come from other terminal functions not supposed to be suppressed...

So, my question is if anyone know whether this last version may have more functions or what I am doing wrong?

I have attached the complete project. It has the modified rtc.c , however it uses the original uart.c and uart.h from Chang.

Based on the answers if this is not possible to run on an ATMEGA328, then I will look around your modified Petit_FS
posted before as well as the Roland Riegel that is for an ATMEGA168.

Last but not least, the application I am aiming to is to play WAV files from SD card using the PWM. So I just need to read . However,as a side effect I wanted to see if I could fit the whole nine yards on the 328.

Thanks in advance for any advice.

Jose
 
 View user's profile Send private message  
Reply with quote Back to top
jofre
PostPosted: Jun 25, 2011 - 04:55 AM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

I've successfully run the Petit FS from Cliff / JS on the Atmega328

Code:


Device: atmega328p

Program:    8810 bytes (26.9% Full)
(.text + .data + .bootloader)

Data:        139 bytes (6.8% Full)
(.data + .bss + .noinit)


Biiiig difference. Not even a 328 is needed.

Please disregard previous crazy post. The only modifications done on the code posted was on the SPI pins as the TX RX on the m164 are the same as on m/168/328.

I like the UART implementation in asm. The only question I have for this post is about the comment from JS

Code:

//The comms is duplex,38.4kbps, but there is no echo and local
// echo needs to be enabled on the terminal.



What does this mean ? no echo as well as "local echo" ?

Thanks a million in advance,

Jose v.
 
 View user's profile Send private message  
Reply with quote Back to top
js
PostPosted: Jun 25, 2011 - 08:34 AM
10k+ Postman


Joined: Mar 28, 2001
Posts: 22850
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)

In the terminal mode you will not see what you are typing unless you enable echo mode in your terminal progam. If you are using Hyperterminal

_________________
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
jofre
PostPosted: Jun 25, 2011 - 07:00 PM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

Js,
Thanks, I used Bray's terminal and it has a separated tx rx input display.

But, forgive my ignorance on this, how a Hyperterminal feature is related to the USART firmware?

Does this means that the atmega built-in USART automatically echoes on TX what is coming on RX ?and that was no available in Chang's implementation ?

I was playing with single line USART some time ago and I disabled RX when transmitting to avoid self receiving , but I did not verified the opposite.

Thanks for any input. Regards,

Jose v.
 
 View user's profile Send private message  
Reply with quote Back to top
js
PostPosted: Jun 25, 2011 - 11:10 PM
10k+ Postman


Joined: Mar 28, 2001
Posts: 22850
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)

What happened when you typed the message above? Did you see what you were typing?

If you type a line into petitfs you would NOT see anything on a terminal that has a single screen instead of a split send and receive screen, well pretty much like the screen you are reading now. This is the reason for local echo.

Local echo will let you see what you type so that, if you make a mistake and you see it you can edit the line.

I don't remember ever having used a split display terminal program, I always use character echo in my programs that needs input ie the USART receives a char from the keyboard, puts it into a buffer and then sends it back to the terminal.

In rare cases where this doesn't happen in a program (not written by me) I use local echo.

Do you have the ability to have a single screen with Brays instead of 2? If so use it and you will see what I mean.

This is as conprehensive an explanation as I can provide. Smile

_________________
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
jofre
PostPosted: Jun 26, 2011 - 06:49 AM
Newbie


Joined: Jul 23, 2008
Posts: 18
Location: Houston, TX , USA

John,

Thanks a lot I have the correct picture now as I also write the USART routines like in Petit that do the same thing just plain send and plain receive but I always use Bray's terminal ( attached) because you can send and receive in Hexadecimal and you can make some macros that are convenient.
[url]
http://hw-server.com/software/termv19b.html
[/url]
This is why I've got in trouble most of the time with the Hyperterminal. Embarassed

Thanks again,

Jose v.]
 
 View user's profile Send private message  
Reply with quote Back to top
osaka
PostPosted: Jul 22, 2011 - 08:07 AM
Wannabe


Joined: Mar 15, 2007
Posts: 83
Location: Spain/Ermua

if someone can share with me any code that can be used with an atmega32 I will be very happy after losing already a week(24 hour a day) trying to have something working on a sd card.

I have read the tutorials, this thread also. I see how the people has succed but I am UNABLE. I started with an atmega16 and changed to atmega32 thinking that atmega16 was insufficient. now I see the code is still to big.

also it seems that the files that were used for this tutorial already changed.


I got this with the elmchan full module. how the... people is getting 10kb codes...

Code:
AVR Memory Usage
      ----------------
      Device: atmega32
      Program:   56266 bytes (171.7% Full)
      (.text + .data + .bootloader)
      Data:       2835 bytes (138.4% Full)
      (.data + .bss + .noinit)



thankyou.
 
 View user's profile Send private message  
Reply with quote Back to top
js
PostPosted: Jul 22, 2011 - 08:30 AM
10k+ Postman


Joined: Mar 28, 2001
Posts: 22850
Location: Sydney, Australia (Gum trees, Koalas and Kangaroos, No Edelweiss)

Quote:
how the... people is getting 10kb codes...
Most likely by using PetitFs (just over 8K) rather than the full FatFs (at least 48K)

_________________
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
osaka
PostPosted: Jul 22, 2011 - 10:22 AM
Wannabe


Joined: Mar 15, 2007
Posts: 83
Location: Spain/Ermua

I try to do with the petitfs code but there is always something missing that make me include files from the full module... and I end up will errors and more errors. may be the full version code is ready to run but this small one...I compile the file and I get thousand of errors. If someone has succed with a code smaller than 32kb please share it with me. I am suffering.Sad

what I am doing wrong??
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 22, 2011 - 10:33 AM
10k+ Postman


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

Quote:

but there is always something missing that make me include files from the full module..

Tell us more about "something missing"?!?

For me pfsample\avr builds right after download:
Code:
E:\pfsample\avr[i386_vc]>make
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=attiny85 -DF_CPU=8000000   -c -o main.o main.c
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=attiny85 -DF_CPU=8000000   -c -o pff.o pff.c
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=attiny85 -DF_CPU=8000000   -c -o mmc.o mmc.c
avr-gcc -c -mmcu=attiny85 -I. -x assembler-with-cpp -Wa,-adhlns=suart.lst,-gstabs -DF_CPU=8000000 suart.S -o suart.o
avr-gcc -c -mmcu=attiny85 -I. -x assembler-with-cpp -Wa,-adhlns=xitoa.lst,-gstabs -DF_CPU=8000000 xitoa.S -o xitoa.o
avr-gcc -c -mmcu=attiny85 -I. -x assembler-with-cpp -Wa,-adhlns=usi.lst,-gstabs -DF_CPU=8000000 usi.S -o usi.o
avr-gcc -gdwarf-2 -Wall -Os -mcall-prologues -mmcu=attiny85 -DF_CPU=8000000 -Wl,-Map,pfftest.map -o pfftest.elf main.o p
ff.o mmc.o suart.o xitoa.o usi.o
avr-objdump -h -S pfftest.elf > pfftest.lst
avr-objcopy -j .text -j .data -O ihex pfftest.elf pfftest.hex
avr-size -C --mcu=attiny85 pfftest.elf
AVR Memory Usage
----------------
Device: attiny85

Program:    8066 bytes (98.5% Full)
(.text + .data + .bootloader)

Data:        139 bytes (27.1% Full)
(.data + .bss + .noinit)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
davef
PostPosted: Jul 22, 2011 - 10:34 AM
Resident


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

Post the first error that you see.
 
 View user's profile Send private message  
Reply with quote Back to top
osaka
PostPosted: Jul 22, 2011 - 12:34 PM
Wannabe


Joined: Mar 15, 2007
Posts: 83
Location: Spain/Ermua

I downloaded the petit module examples file. I choise AVR folder and I try to compile it.I know I can get some error regarding with the pinout but...

134 errors

undefined reference to 'xmit'
'xfunc_out'
'xputs'
'crvr'
'xmit_spi'.....
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 22, 2011 - 01:33 PM
10k+ Postman


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

What were you compiling it with? I have WinAVR20100110 installed which is what runs when I typed "make" above.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
osaka
PostPosted: Jul 22, 2011 - 02:46 PM
Wannabe


Joined: Mar 15, 2007
Posts: 83
Location: Spain/Ermua

I am using avrstudio5. I have done all kind of small projects with this software. All successfull till this.
BTW, I am a bit confused with the make file. Do I need to handle son makefile? I didn't in the previous projects.
 
 View user's profile Send private message