SD card objects, fsrw etc...
R Pankau
Posts: 127
I'm trying my best to get the object fsrw to write to an SD card.
First thing I did was run test.spin and the results were good.
Here's the output:
Clock: 80000000 ClusterSize: 32768 ClusterCount: 60023
Raw write 3968 kB in 2197 ms at 1805 kB/s
Raw read 1920 kB in 2185 ms at 878 kB/s
fsrw pwrite 2016 kB in 2006 ms at 1005 kB/s
fsrw pread 2016 kB in 2299 ms at 876 kB/s
FSRW pputc 63 kB in 2111 ms at 29 kB/s
FSRW pgetc 63 kB in 1840 ms at 34 kB/s
All done!
So, when I try a little bit of this my results differ. Maybe I'm not calling the routines in the correct order to init the card?
Here is a snippet of my code. sd is fsrw.spin
the values that return in success_mount, success_popen, and success_write are -41, -2, 0
The -41 is quite confusing since it is not one of the abort values at all. the other two don't surprise me since the mount failed.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
First thing I did was run test.spin and the results were good.
Here's the output:
Clock: 80000000 ClusterSize: 32768 ClusterCount: 60023
Raw write 3968 kB in 2197 ms at 1805 kB/s
Raw read 1920 kB in 2185 ms at 878 kB/s
fsrw pwrite 2016 kB in 2006 ms at 1005 kB/s
fsrw pread 2016 kB in 2299 ms at 876 kB/s
FSRW pputc 63 kB in 2111 ms at 29 kB/s
FSRW pgetc 63 kB in 1840 ms at 34 kB/s
All done!
So, when I try a little bit of this my results differ. Maybe I'm not calling the routines in the correct order to init the card?
Here is a snippet of my code. sd is fsrw.spin
BYTEFILL(@strng_buf, "b", 39) strng_buf[noparse][[/noparse]39] := 0 success_mount := \sd.mount(0) success_popen := \sd.popen(@FileName, "w" ) success_write := \sd.SDStr(@strng_buf) \sd.pflush \sd.pclose
the values that return in success_mount, success_popen, and success_write are -41, -2, 0
The -41 is quite confusing since it is not one of the abort values at all. the other two don't surprise me since the mount failed.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Comments
What version of FSRW do you use?
Yes, in general your code-snipped does not look to bad. First you have to mount, then you open the file and then you can use the file.
not much else going on.·· receiving signals from GPS, although it is disconnected for this test.··
Thought maybe fsrw was only capable of 512 bytes per cluster.· my card is 2Gig so it is 32768 per cluster.· the paradox for me is that the test worked. so in theory (not too big of a stretch) it should work.··
the Test, however, did use another object "safe_spi.spin" which could hold some clues.·· I'm not using that one, not sure if it is needed.· it appears more robust maybe, but also not as user firendly.··
The version is 2.6 I'm almost sure.·· have to double check.·
Can anyone give me a quick answer to why there are so many flavors of this object?· Do I need just one?· the right one?·
Actually another test that I performed was the code straight out of the book,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Do you have a capacitor in place close to the SD card? If writing is the problem the SD card might draw to much peak currency which can't be delivered by the power supply fast enough.
I had such kind of problems with version 2.4. In the fastes driverthe timing is very tough and depending on capacities in the wiring , buffer capacitors used and even the signal length from COG to IO-pin it may work or not. I simply replaced the COGNEW (which takes the next free COG) with a COGINIT to start the SPI-driver in COG where it works.
If this does not work, you should test the different SPI-drivers in the test.spin and take the fastes one which works.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The parameter in the mount is the pin, do you really use pins 0-4?
If you are not willing to post your code there will be nothing more than guessing.
I am using 0,1,2,3 for DO, SCLK, DI, and CS
the hardware was the same during test.spin that came with the fsrw object (from object exchange)as it is now and it worked well with the test code. (no visible errors from fsrw or safe_spi) Also the test code declared both objects fsrw as well as safe_spi and it appears that both were called at will. no abort messages have ever appeared from running the test code. Looking at the SD card after running the test I found two files filled with "!" so there is no doubt in my mind that it was capable of dealing with 32k clusters. I have a feeling that my code however is tied down to 512 bytes per cluster by using fsrw exclusively. my SD card will not format at 512 since it is 2Gig.
I'm reluctant to go chasing hardware issues if it has proven to work with other code. Seems like it must be my software that is the issue here.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
You see what happens: It's like a ping pong game and you get valuable tips much later
For example - in your first post you only gave the snippet:
As such this snippet is fine! The important thing - from my experience is:
It's already mentioned in one of my guessing posts: What you do is, you start two other COGs before doing the mount. Which means the SD driver most likely will run in COG 3 (COG 0 = Spin interpreter, COG 1 = gps, COG 2 = serial). This means you could have the same problems than me. So, simply try it again after moving the mount to the beginning of your main.
You did not answer the question about the capacitor?! This is one of the advices I was given when I searched my problem.
What are your requirements for the read/write speed? If you can live with ~800kB/sec reads, the slow driver is fine. And that's the reason why it's in the FSRW package - when the fast drivers fail (f.e. because of bad SD cards or bad PCB design ....) the slow driver still gives you a chance to use the SD interface.
Post Edited (MagIO2) : 3/17/2010 7:57:48 AM GMT
Speed requirements are not fast.·· 40 bytes every 20 seconds or so.·
So you think the mount is too soon in time before the other functions, popen for example?
Does that answer this question though:· Why after running test.spin does mine work?· Could it be that my mount is not really working still but it does not matter because the card thinks the previous mount is in effect?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
If the speed requirements are so low, use safe_spi. Why is it less user friendly? You should always call FSRW functions.
No, I don't think the mount is to soon ... once again ... This means, that the fast version of SPI driver works when it is loaded into COG 1 and it does not work if it's loaded into COG 3 in your case. The COGs sit on different places of the propeller chips die, having different signal paths to the I/O ports. Shifting the mount to the beginning means that COG 1 is used for SPI, COG 2 for GPS and COG 3 for serial interface.
No, this is news ... you never mentioned it before. Did you maybe switch to safe_spi?
If a mount fails, the code should not try to open a file.
If a file open fails, the code should not try to write to the file.
Once the first failure is detected, further results will be suspect, no matter what their values.
What to do in case of failure can be a hard choice, and depends on what failed as well as what the overall project needs to do, whether to retry the same operation, or to continue other work, or to display an error message, or to completely halt.
But in general, failure codes should be believed and listened to and acted upon.
Anyway this is a good point.·· my code in general fails, returns -1 on the mount I believe.· until...· I load test.spin.·· This always works.· it never shows any errors and I get the messages that I posted in my original thread.·
then If I load my code without removing the SD card or cycling power it works as well, returns 0 for mount, open and writes, and the data is there to see on the SD card when I look with the pc.··
When the card goes back into the prop board it will not work with my code again until test.spin is run first.·(going back to default mode not-spi I'm guessing)
Looking through test.spin I did see that the first access to the SD card was accomplished not with fsrw but with safe_spi directly I believe using start instead of mount (it's not in front of me now)·· then later in the test it gets to mount with the fsrw object.· I have tried accessing through start and safe_spi as well but it returns an error.
obviously something about test.spin is different enough to allow it to always work. But it's just the top level so I must be·missing something or my·timing·is off.·
One other hint is that the return code from the mount abort was "SD card not reset" that might have been -1 but I'm not sure.··· Evidently test.spin was successful in resetting the card but this is the point at which my code gets stuck.·
So as far as the caps and lead lengths, all of the real bit-banging and critical timing is still being accomplished by the same code regardless of what top level code is calling the shots, mine or test.spin.···· We're not talking about Gbits per second here are we?···the test results showed more like kbits per second.· ·I'll take a peek at the data lines tonight with a scope to see what the bit widths are.··
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
as small as possible) I can try it here. Otherwise, we're just guessing.
Note that "resetting" the SD card can be a bit tricky. Have you tried downloading your code
to EEPROM, presumably seeing it fail, and then power cycling the board (ideally with the board
*not* attached via USB)? A power cycle is guaranteed to reset an SD card (although a power
cycle with USB attached might not).
But *usually* things like this come down to something else; some other object writing over
fsrw's vars, or somewhere someone using buf instead of @buf, or something like that.
That's why we want to see the code.
I'll have to work on the minimal code a little later.
I have tried writing to EEProm and letting it come up after power on but the Prop Plug was still attached.· That's also how I debug so I guess I'd have to pull the card and look at the results on a pc.··· When the mount aborts and returns -1 indicating card not reset my assumption was that the card was not put into SPI mode.·· I'm wondering what reset really means in this context.··
First thing I will remove all of·the gps code.· that will put the fsrw in cog1, that will test MAGIO2's·theory.···in that respect it·will match test.spin.·
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
some good advice thanks. I moved the mount prior to the 1 second wait before calling any other methods from fsrw. tried it without gps then added gps back in then switched the order around, Looks like it does not matter where the fsrw resides (cogwise) that's what I would expect.
What did surprise me however is that it was not exactly consistent with being successful on the mount portion. so I added the loop so it would continue to try if the mount failed. Am I correct in believing that an object is not loaded into a cog until coginit or the like is invoked usually with start or in this case mount? I guess my point is that if I added a waitcnt before the mount method it should not matter because nothing is going on prior to the call in either case. It would be nice to know why the mount does not always take. By all accounts the writing and opening always works though. Log01.txt appears to have contiguous rows.
To make things more robust I could watch for abort and return values from popen etc. like David B suggested and if anything fails then calling mount again should clean things up.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔