-1

I have an SD card (or SDHC card) connected to a microcontroller via SPI mode. I am using Chan’s FAT library. In this I used CodevisionAVR v2.05.3 example code from help. By using this I read a text document and opened the file using open existing.

However, when I created a new file or tried to write, I couldn't open the file (do f_open). Giving error ERROR: FR_INVALID_OBJECT.

How can I clear this issue?

And my code is:

/* ATmega128 I/O register definitions */
#include <io.h>
#if defined(_CHIP_ATMEGA32_)
#warning using ATMEGA32
#define TIMSK1   TIMSK
#define UCSR0A   UCSRA
#define UCSR0B   UCSRB
//#define UCSR0C   UCSRC    //this is commented out
#define UBRR0H   UBRRH
#define UBRR0L   UBRRL
#define TXEN0    TXEN
#endif

/* FAT on MMC/SD/SD HC card support */
#include <ff.h>


/* printf */
#include <stdio.h>


/* String functions */
#include <string.h>
#include <delay.h>


/* Timer1 overflow interrupt frequency [Hz] */
#define T1_OVF_FREQ 100

/* Timer1 clock prescaler value */
#define T1_PRESC 1024L

/* Timer1 initialization value after overflow */
#define T1_INIT (0x10000L-(_MCU_CLOCK_FREQUENCY_/(T1_PRESC*T1_OVF_FREQ)))


/* USART Baud rate */
#define BAUD_RATE 9600
#define BAUD_INIT (_MCU_CLOCK_FREQUENCY_/(BAUD_RATE*16L)-1)

/* Root directory path */
char path[] = "0:/fil.txt";

/* Text to be written to the file */
char text[]="I like CodeVisionAVR!";


/* 100 Hz timer interrupt generated by ATmega128 Timer1 overflow */
interrupt [TIM1_OVF] void timer_comp_isr(void)
{
    /* Re-initialize Timer1 */
    TCNT1H = T1_INIT >> 8;
    TCNT1L = T1_INIT & 0xFF;

    /* MMC/SD/SD HC card access low level timing function */
    disk_timerproc();
}


/* Error message list */
flash char *flash error_msg[] = {
    "",                         /* Not used */
    "FR_DISK_ERR",
    "FR_INT_ERR",
    "FR_INT_ERR",
    "FR_NOT_READY",
    "FR_NO_FILE",
    "FR_NO_PATH",
    "FR_INVALID_NAME",
    "FR_DENIED",
    "FR_EXIST",
    "FR_INVALID_OBJECT",
    "FR_WRITE_PROTECTED",
    "FR_INVALID_DRIVE",
    "FR_NOT_ENABLED",
    "FR_NO_FILESYSTEM",
    "FR_MKFS_ABORTED",
    "FR_TIMEOUT"
};


/* Display error message and stop */
void error(FRESULT res)
{
    if ((res >= FR_DISK_ERR) && (res <= FR_TIMEOUT))
        printf("ERROR: %p\r\n", error_msg[res]);

    /* Stop here */
    while (1);
}


void main(void)
{
    /* FAT function result */
    FRESULT res;

    /* Will hold the information for logical drive 0: */
    FATFS drive;

    /* Will hold the file information */
    FIL file;

    /* Number of bytes written/read to the file */
    unsigned int nbytes;

    /* File read buffer */
    char buffer[256];


    /* Initialize Timer1 overflow interrupts in Mode 0 (Normal) */
    TCCR1A = 0x00;

    /* clkio/1024 */
    TCCR1B = (1<<CS12)|(1<<CS10);

    /* Timer overflow interrupts will occur with 100Hz frequency */
    TCNT1H = T1_INIT >> 8;
    TCNT1L = T1_INIT & 0xFF;

    /* Enable Timer1 overflow interrupt */
    TIMSK1 = 1 << TOIE1;


    /* Initialize the USART0 TX, 8N1, Baud rate: 19200 */
    UCSR0A = 0;
    UCSR0B = 1 << TXEN0;
    //UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
    UBRR0H = BAUD_INIT >> 8;
    UBRR0L = BAUD_INIT & 0xFF;


    /* Globally enable interrupts */
    #asm("sei")

    PORTB.4 = 0;
    delay_ms(1000);

    printf("\n\nDirectory listing for root of logical drive 0:\r\n");


    /* Mount logical drive 0: */
    if ((res = f_mount(0, &drive)) == FR_OK)
        printf("Logical drive 0: mounted OK\r\n");
    else
        /* An error occurred, display it and stop */
        error(res);


    printf("%s \r\n", path);

    /* Open the file in read mode */
    if ((res = f_open(&file, path, FA_READ)) == FR_OK)
        printf("1_File %s opened OK\r\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);


    /* Read and display the file's content.
       make sure to leave space for a NULL terminator
       in the buffer, so maximum sizeof(buffer)-1 bytes can be read */
    if ((res=f_read(&file,buffer,sizeof(buffer)-1,&nbytes))==FR_OK)
    {
        printf("%u bytes read\r\n", nbytes);

        /* NULL terminate the char string in the buffer */
        buffer[nbytes+1]=NULL;

        /* Display the buffer contents */
        printf("Read text: \"%s\"\r\n", buffer);
    }
    else
        /* An error occurred, display it and stop */
        error(res);


    /* Close the file */
    if ((res = f_close(&file)) == FR_OK)
        printf("1_File %s closed OK\r\n\n\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);


    /* Create a new file in the root of drive 0:
       and set write access mode */
    if ((res = f_open(&file,path, FA_OPEN_EXISTING)) == FR_OK)
        printf("File %s opened OK\r\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);

    /* Close the file */
    if ((res = f_close(&file)) == FR_OK)
        printf("2_File %s closed OK\r\n\n\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);

    if ((res = f_open(&file,path, FA_WRITE | FA_CREATE_ALWAYS)) == FR_OK)
        printf("File %s created OK\r\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);

    /* Write some text to the file,
       without the NULL string terminator sizeof(data)-1 */
    if ((res = f_write(&file, text, sizeof(text)-1,&nbytes)) == FR_OK)
        printf("%u bytes written of %u\r\n", nbytes, sizeof(text)-1);

    else
        /* An error occurred, display it and stop */
        error(res);


    /* Close the file */
    if ((res = f_close(&file)) == FR_OK)
        printf("3_File %s closed OK\r\n\n\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);


    /* Open the file in read mode */
    if ((res = f_open(&file,path,FA_READ)) == FR_OK)
        printf("1_File %s opened OK\r\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);


    /* Read and display the file's content.
       make sure to leave space for a NULL terminator
       in the buffer, so maximum sizeof(buffer)-1 bytes can be read */
    if ((res = f_read(&file, buffer, sizeof(buffer)-1, &nbytes)) == FR_OK)
    {
        printf("%u bytes read\r\n", nbytes);

        /* NULL terminate the char string in the buffer */
        buffer[nbytes+1] = NULL;

        /* Display the buffer contents */
        printf("Read text: \"%s\"\r\n", buffer);
    }
    else
        /* An error occurred, display it and stop */
        error(res);


    /* Close the file */
    if ((res = f_close(&file)) == FR_OK)
        printf("4_File %s closed OK\r\n", path);
    else
        /* An error occurred, display it and stop */
        error(res);

    printf("done\r\n");

    PORTB.4 = 1;

    /* Stop here */
    while (1);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sasi
  • 1
  • 1
  • 3
  • 1
    First, did the FS mount OK? – Martin James Nov 29 '14 at 12:52
  • if ((res = f_mount(0, &drive)) == FR_OK) printf("Logical drive 0: mounted OK\r\n"); else error(res); if ((res=f_open(&file,path,FA_READ))==FR_OK) printf("1_File %s opened OK\r\n",path); else error(res); if ((res=f_read(&file,buffer,sizeof(buffer)-1,&nbytes))==FR_OK) { printf("%u bytes read\r\n",nbytes); buffer[nbytes+1]=NULL; printf("Read text: \"%s\"\r\n",buffer); } else error(res); if ((res=f_close(&file))==FR_OK) printf("1_File %s closed OK\r\n\n\n",path); else error(res); – sasi Dec 01 '14 at 10:19
  • Clifford i added my code in OP – sasi Dec 01 '14 at 10:25
  • OK, so it mounts OK and opens/reads, but will not create/write. When you stepped through the FATfs, and driver, source with your debugger, what operation failed? It sounds like writes are not happening, doesn't it? – Martin James Dec 01 '14 at 11:00
  • I mean, you have posted a gob of code and an error return, but not actually indicated which line fails. I'm guessing it's 'if ((res=f_open(&file,path, FA_WRITE | FA_CREATE_ALWAYS))==FR_OK)', but why do you expect us to guess at this stuff? Why does getting debugging info from posters always seem like pulling teeth? Is the stuff you've found out some sort of secret? You have the hardware and debugger, why can you not make more progress with debugging? – Martin James Dec 01 '14 at 11:07
  • 'if ((res=f_open(&file,path, FA_WRITE | FA_CREATE_ALWAYS))==FR_OK)' this gives error FR_INVALID_OBJECT. and SD card or PC is not a write protected or read-only access. – sasi Dec 02 '14 at 05:02
  • @sasi : At that point then you need to *step-into* f_open() and determine why it is failing. If you have a hardware debugger, you are in a better position to debug this that we are by guessing! – Clifford Dec 02 '14 at 19:14
  • okay clifford. i will debug it. Thanks you clifford. – sasi Dec 04 '14 at 07:53

1 Answers1

0

From the documentation:

FR_INVALID_OBJECT

The file/directory object structure is invalid or a null pointer is given. All open objects of the logical drive are invalidated by the volume mount process.

Your file pointer is perhaps null?

Also to consider is that you have configured the library to actually support write operations. In ffconf.h you should have:

#define _FS_READONLY    0
Clifford
  • 88,407
  • 13
  • 85
  • 165
  • but the same file is working for read and open existing operations. – sasi Dec 01 '14 at 08:51
  • It is possible to configure ELM FatFs for read-only (to reduce size if write is not needed) - have you configured it for write? – Clifford Dec 01 '14 at 11:33
  • yes i configured for write. and hardware setup working Dharmanitech atmel studio code. and the link is http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html – sasi Dec 02 '14 at 05:06