Strange problem with SD card program [solved]
Patrick1ab
Posts: 136
Hi everyone!
I'm experiencing some problems with the SD card interface of my newest project.
(a multi format music player with LCD, IR remote control, playback from SD card and Internet Radio Streams)
I even reduced my program to a minimum to locate the error, but I'm still not able to find it.
This is what happens:
The text message "Checking for SD card" is displayed and afterwards the program crashes.
In the original program it won't even listen for IR commands anymore, so I wondered whether there could be an infinite loop.
The strange thing about it is, that it doesn't matter whether I insert the SD card or not.
This is the configuration I use:
- Propeller running at 80 MHz
- I/O pin 13, 14 used for a modified version of "parallel_lcd"; because I connected my display to a PCF8574 port expander
- I/O pin 16, 17, 18, 19 used for my sd card interface (with pull up resistors; same values I already used with my webserver)
- newest version of fsrw (2.6)
This is the reduced program I used for testing purposes:
Please tell me if you can find the mistake I made.
Post Edited (Patrick1ab) : 3/24/2010 12:45:51 AM GMT
I'm experiencing some problems with the SD card interface of my newest project.
(a multi format music player with LCD, IR remote control, playback from SD card and Internet Radio Streams)
I even reduced my program to a minimum to locate the error, but I'm still not able to find it.
This is what happens:
The text message "Checking for SD card" is displayed and afterwards the program crashes.
In the original program it won't even listen for IR commands anymore, so I wondered whether there could be an infinite loop.
The strange thing about it is, that it doesn't matter whether I insert the SD card or not.
This is the configuration I use:
- Propeller running at 80 MHz
- I/O pin 13, 14 used for a modified version of "parallel_lcd"; because I connected my display to a PCF8574 port expander
- I/O pin 16, 17, 18, 19 used for my sd card interface (with pull up resistors; same values I already used with my webserver)
- newest version of fsrw (2.6)
This is the reduced program I used for testing purposes:
CON _clkmode = xtal1+pll16x _xinfreq = 5_000_000 VAR long filelist[noparse][[/noparse]255] OBJ text : "parallel_lcd_pexp_mod" 'str : "util_strings" sdfat : "fsrw" PUB start text.start text.str(string("Checking for SDcard")) text.pos(0,3) text.dec(checkforSD) text.pos(0,4) text.str(string("Done!")) PRI checkforSD | NOofFiles, temp NOofFiles:=0 temp:=0 if sdfat.mount_explicit(16,17,18,19)==0 sdfat.opendir repeat until sdfat.nextfile(@temp)==-1 OR NOofFiles>255 filelist[noparse][[/noparse]NOofFiles]:=temp NOofFiles++ return 0 else return -1
Please tell me if you can find the mistake I made.
Post Edited (Patrick1ab) : 3/24/2010 12:45:51 AM GMT
Comments
just a question....
is
supposed to store the filename?
I might be wrong but I do not think it does that.
Have you tried to make the loop even simpler to check if this instruction is having any unexpected issue?
byte temp[noparse][[/noparse]sdfat#DIRSIZE]
because it needs to be big enough for a complete directory-entry. The first characters are the filename. To print the filename you can do temp[noparse][[/noparse]11]:=0 to replace whatever comes next with the stringend and then print @temp.
If you really want to copy all that strings, you need a bigger filelist too. Each filename needs 8+3 bytes (+stringend).
What you say sounds logical to me. I was a bit na
You could create a linked list growing down from $8000 (assuming you can use this area of RAM, which I'm not sure about). If you don't know how to do this, I may try to write a few lines of Spin code to show how to do it.
Okay, here's a try, but don't beat me if it's wrong. I haven't tried to compile it, just written from the top of my head. I hope you get the idea...
Hmm... the longer I think about it, you don't even need the pointers in byte 0+1, just the length. A length of 0 would indicate the end of the list.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Post Edited (pullmoll) : 3/23/2010 10:53:06 AM GMT
The directory-entry always has a fixed size, no matter how long the filename is. The rest will be extended by $20 (space) as far as I remember. The extension is also on a fixed place and there is no ".".
The problem with your code might be that you don't catch the abort properly. You need the \ in front of the mount to catch an abort condition. If you don't do it like that your main COG will be stopped.
Great! That's it. Thank you very much. Now the detection of the SD Card works and the program keeps running.
I'm doing this because I want to navigate through the files with the up and down buttons of the remote control.
I could also navigate down by calling the nextfile procedure each time the down button is pressed, but a previousfile procedure is missing, so navigating up is not possible at the moment.
Another thing is that navigating through the files should work without a big delay between press of the button and change of the display.
In the next step I will add a file extension filter, so that only mp3, m4a, wav, ogg and mid files are allowed.
Okay, a fixed size will make it easy to store the filenames, but in the nextfile procedure the dot is definitely included.
Have a look:
Good thing is that the filenames are already zero terminated, so I don't have to worry about separators in my list.
@pullmoll:
Thank you very much for your help. The code looks great and I can't wait to try it out
The get_list_entry function is exactly what I need.
Just one question: Why are you using different variables for filename and name? Is name another pointer?
filename is an array of bytes used as a string buffer. name is just a pointer to somewhere, e.g. a string on the heap. Be careful, I don't know if you can use the memory from $8000 downwards or if it is used by Spin. In that case you would have to find out where the free memory begins by inspecting some system variable.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
He died at the console of hunger and thirst.
Next day he was buried. Face down, nine edge first.
Other solution .. start from the beginning and do nextfile until you reached the previous file. FSRW can read some at least hundred kilobytes per second which will be enough for a lot of directory entries.
Oh ... reread your post ... ok ... here is some code I use to filter *.bmp-files:
Maybe you want to use what I call "virtual memory" as well? It's an addition to FSRW and you can find a version in this thread:
http://forums.parallax.com/showthread.php?p=856170
The idea with virtual memory is that you have a file on the SD card which is accessed by addresses. So, if you have a list of filenames with a fixed length you can simply address entry x by calculating x*size of entry. This way the access will be very fast.
In your case you can scan the directory on demand or when you detect changes and keep the filtered file-list in the virtual memory file.
Post Edited (MagIO2) : 3/23/2010 7:25:57 PM GMT
Sounds interesting Although I'm a bit scared of writing to an SD card with a microcontroller.
Last time I tried, I killed the FAT system on it
Luckily I made a backup of the files before, but I had to reformat the card afterwards.
Maybe I'll try to extend the existing memory by connecting an SPI SRAM and then store a temporary copy of the file list there.
I'll need a bigger memory anyway if I want to listen to streaming audio (for example: 48Kbyte for a three second buffer).