pf_open() returning FR_NO_FILE inspite of an existing file on microSD card
Started by 8 years ago●14 replies●latest reply 8 years ago●1473 viewsI am trying to connect microSD card (transcend 2GB) to MSP430F67791 controller via SPI interface (USCI_B1).
I am using petit Fatfs library (latest R0.03) for this. (http://elm-chan.org/fsw/ff/00index_p.html)
In main(), I am calling the petit-FatFs functions in this order:
fileStatus = pf_mount(&fs); // FRESULT fileStatus; fileStatus = pf_open(fileName); // const char fileName[15] = "test.txt"; // I even tried pf_open("test.txt") //In pffconf.h : #define _USE_LCC 1 /* Allow lower case characters for path name */ fileStatus = pf_write("Hello world!\r\n", 14, &bytesWritten); fileStatus = pf_write(0, 0, &bytesWritten);
pf_mount() returns FR_OK but pf_open() is returning FR_NO_FILE, and this is the problem I'm facing. I made sure that the file exists and it exists in the root directory. From my computer, I formatted the card as FAT32 and created test.txt on it. I even tried writing a character in it from my computer so that the file size is non-zero.
The FR_NO_FILE status is returned by dir_find():
pf_open() -> follow_path() -> dir_find()
I had to write only 4 low-level SPI functions for the petit FatFs library to work on my MSP430.
void init_spi (void) { P4DIR |= BIT5 | BIT6; // MOSI, CLK as o/p P4DIR &= ~BIT4; // MISO as i/p P4SEL0 |= BIT4 | BIT5 |BIT6; // SPI UCB1CTLW0 |= UCSWRST; // reset state UCB1CTLW0 |= UCMST | UCSYNC | UCCKPL | UCMSB; // 3-pin, 8-bit SPI master // Clock polarity high, MSB UCB1CTLW0 |= UCSSEL_2; // SMCLK UCB1BRW = 84; // SMCLK/84 = 200kHz UCB1CTLW0 &= ~UCSWRST; // SPI on } void xmit_spi (BYTE d) { while (!(UCB1IFG & UCTXIFG)) ; // USCI_B1 TX buffer ready? UCB1TXBUF = d; // Transmit character } BYTE rcv_spi (void) { char recd_byte; rcv_spi_count++; xmit_spi(0xFF); while (!(UCB1IFG & UCRXIFG)); //USCI_B1 RX buffer filled ? recd_byte = UCB1RXBUF; return recd_byte; } void dly_100us (void) { // MCLK= 16 MHz, 1 NOP = 0.06us, if microSec=1 then delay= (0.06*16) * 1 = 0.96us (approx 1 us) unsigned int microSec= 100; unsigned long int i; for ( i= 16*microSec ; i > 0 ; i--) { _NOP(); } } #define SELECT() P4OUT &= ~BIT3 // CS = L. P4.3 is configured as o/p #define DESELECT() P4OUT |= BIT3 // CS = H
Can anyone help to let me know if I'm missing something or if the microSD card & SPI specs that I'm working with are ok ? Thanks
On the Petit FAT File System page (http://elm-chan.org/fsw/ff/pf/appnote.html) I see: "_FS_FAT16 is 1. _FS_FAT12, _FS_FAT32 and _USE_LCC are 0." Since you're using FAT32, did you set _FS_FAT16 to 0 and _FS_FAT32 to 1?
yes, the flags are set correctly
As you can see, copying a question from stack overflow doesn't yield good results with the editor. May I ask you to edit your post and fix this? I can do it for you if you are unsure as to how to proceed.
Unless you've enabled long file names, you need to use "old DOS" names: meaning an 8.3 format where the characters used are limited to capital letters, numbers, and a few things like underscores (you'll have to look up for any more). So:
THIS.TXT is OK
my-cool-file.txt is not
BOB_009.000 is OK
BOB_009.0000 is not.
Dunno what else to suggest -- I've scratched the surface of that code, but it's for a hobby project, and so I've been stalled at the verge of putting it on the debugger and seeing if it works with real hardware.
Thank you
If FatFs worked and petit FatFs didn't, that may point to a bug of some sort in petit FatFs. Can you use FatFs instead? It has a small footprint as well, if space is an issue.
yes,I am using FatFs for my application but as described above, I'm struggling with f_sync() returning FR_DISK_ERR but f_close() working ok.
I'm looking at the FatFs source code and f_close calls f_sync prior to actually closing the file. So I can't see why it isn't working. Could you post a code snippet?
My main() looks like this:
f_mount_timeout=10; do { fMountStatus = f_mount (&myFs, "0:", 1); } while(f_mount_timeout-- && fMountStatus); f_open_timeout=10; do { fOpenStatus = f_open(&fileObject, fileName, FA_OPEN_APPEND | FA_WRITE | FA_READ); } while(f_open_timeout-- && fOpenStatus); f_write_timeout = 10; do { fWriteStatus = f_write(&fileObject, content, (stringSize-1), &bytesWritten); } while(f_write_timeout-- && fWriteStatus); f_sync_timeout=20; do { fsyncStatus = f_sync(&fileObject); } while(f_sync_timeout-- && fSyncStatus);
All file functions except f_sync() return OK. f_sync() returns DISK_ERR. If I use f_close() instead of f_sync(), then f_close() returns OK after 2 attempts. I think using f_sync() for my data logger application is better than f_close() because after every f_close() I have to mount & open.
I've looked over your code as well as the FatFs source code and I can't find anything that stands out. So most likely there's a bug somewhere in the code you wrote that implements diskio.c, since DISK_ERR (or FR_DISK_ERR) comes from there. My guess is that it's in the disk_write function.
Hi, i found that f_sync was not working because of a different problem and f_close was working ok because I tested my firmware under different SD card conditions. The real problem is that my file size is getting restricted to the Allocation Unit Size that is set during formatting of SD card as FAT32. The max Allocation Unit Size that can be set to an 8GB SDHC card is 64KB. I am not able to write into the file after it grows to 64KB. Is there something to be done once the file size reaches Allocation Unit Size of the SD card ?
My file function calls are same as above, except that now I'm calling f_write() 100 times before f_sync() and f_close(). So my code is as follows in a continuous loop :
f_mount_timeout=10; do { fMountStatus = f_mount (&myFs, "0:", 1); } while(f_mount_timeout-- && fMountStatus); f_open_timeout=10; do { fOpenStatus = f_open(&fileObject, fileName, FA_OPEN_APPEND | FA_WRITE | FA_READ); } while(f_open_timeout-- && fOpenStatus); while(f_write_count < 100) // f_write_count initialized to 0 { f_write_timeout = 10; do { fWriteStatus = f_write(&fileObject, content, (stringSize-1), &bytesWritten); } while(f_write_timeout-- && fWriteStatus); f_write_count++; } f_sync_timeout=20; do { fsyncStatus = f_sync(&fileObject); } while(f_sync_timeout-- && fSyncStatus); f_close_timeout=20; do { fcloseStatus = f_close(&fileObject); } while(f_close_timeout-- && fcloseStatus);
I was hoping that after the file size reaches 64KB, f_close() & then f_mount() would take care of increasing the file size because I observed that after a reset to the system, it could write beyond 64KB. But I do not wish to reset my system for that. Is there any straight forward way to handle this situation ?
My file is a .csv file that I create on SD card before connecting it to MSP430 controller.
I thought creating a new thread for this new problem would be better. So it is posted here: https://www.embeddedrelated.com/thread/1257/