PDA

View Full Version : PropBasic: SD Card



Maxwin
05-21-2010, 03:40 AM
OK, So here it is "SDplay.pbas" !

I have moved the core code into sd.lib

Functions currently included are:

SD_OPEN
SD_READID
SD_READSIZE
SD_READ <sectoraddr>
SD_WRITE <sectoraddr>
SD_CLOSE

BB_PUT <index> - Helper routine to pack 512 bytes into 128 longs; needed as COG limit is 496 longs without LMM!
BB_GET <index>

Assumes you have a serial terminal connected at 57600 on pin 30, and the SD card reader attached according to the pins in SDplay.pbas

Run the program ( a 2500ms delay at the start is to allow me time to click Enable on the PST after upload! )

Then the PST will blank and prompt you to insert card.

A screenshot of what to expect is attached, along with the all files you need. I am attaching 2 files by JonnyMac (delays.lib, serial.lib) without his permission, so hopefully I will not get beaten!

Note, I had the lib files in a subfolder "Library". You might need to check the LOAD statements in SDplayXX.pbas if you store your libs elsewhere!

As said before, the concept here is to provide mass storage (ala EEprom). It is not a FAT based library. This lib will be ideal for dataloggers who would have a dedicated PC program to read back the data and stick into a spreadsheet or database for analysis. (I could write the necessary program if someone needs it). -- OR just use it as cheap mass storage on your Propeller project and never move the SD card to your PC!

Finally, this is still a work in progress. I have more methods to add and no doubt stuff to improve.

If you use this, please do send feedback good or bad (especially bad!). I really would like to fix any bugs, and the more cards that can be tested the better!

__________________________________________________ _________________________________________________

Release History:

2010.Sep.24 - sd.lib updated to fix misreading of the card multiplier (thanks to MAX72)

2010.Sep.14 - Modified blocksize to always be 512 bytes/sector and calculate totalsectors correctly (as we always read/write in 512byte blocks, regardless of the card block size)

2010.Sep.09. - 1st Version

Rsadeika
05-21-2010, 05:43 AM
Looks good Maxwin! I have not run the code just yet, I am still looking at the code. In your pin assignments, what does SD_CARDINPIN do? I have a uController.com SD adapter, and it does not have a pin for that, it has the other pins. If it just tells you that a card is inserted, then I can get around that because the adapter has an LED that visually shows that a card is inserted. But, if you are relying on that for some other purpose, then maybe a detailed explanation maybe in order. More after I run the program.

Ray

Maxwin
05-21-2010, 12:54 PM
Ray, the SD_CARDINPIN is connected to the switch that detects the card. (As you correctly suspected!).

If you are sure the card is inserted before running the code, the card detection could be removed. Or maybe better, just connect an external switch? If you have the PPDB you could use one of the switches available onboard?

Rsadeika
05-21-2010, 09:19 PM
@Maxwin, I had a chance to run the program, and I get a line of 'FF'. I have to make the assumption that it is displaying the contents, which happens to be empty. Now that Bean created the LOAD function to read in files as if they were libs, I will have to think about your program, in terms of being a lib file. Now we are all waiting for the heavy duty stuff like create, delete ...

Ray

Maxwin
05-21-2010, 09:39 PM
rsadeika: The line of FF's might be an error. Do you get to the end of the Main program? It should count up through each section.. 1,2,3,4,End.
If not, where are you getting stuck?

ps. At my desk now working on putting together the "heavy duty" stuff! Kids allowing, I might even post an update tonight.

Maxwin
05-21-2010, 09:48 PM
... here is a screenshot of what the SDplay5 output should look like on PST.

I have tested with a 265mb sandisk, and a 2gb kingston.

I suspect the line of FF's means you are getting stuck somewhere.... Perhaps try again or with a different card - or triple check the connections !

Maxwin
09-09-2010, 09:47 AM
Just a little update...

I started back on the SDplay in the last few days. All is working... now I am quickly learning how to put a library together and also just finished some helper routines for put/get of the 512 byte blocks in a single cog (rather than using bytes in hub).

As a little taster, below is the write routine!

I will post the full library over the weekend.



FUNC SD_WRITE

' __param1 is the sector address to write to (0 is reserved, 1 onwards only!)
' __param2 is reference to the array holding 512 bytes to write


sd_write_status VAR LONG = 1
sd_write_tmp VAR LONG
sd_write_tries VAR LONG


' Wait until card is idle
sd_write_tmp = WAITFORNZ


' Send write command (CMD24 = CMD_WRITE_SINGLE_BLOCK)
sd_write_tmp = SHOUTCMD 24, __param1 ' <param = sector addr>


IF sd_write_tmp = 0 THEN ' Card ready for write

LOW SD_CSPIN

SHOUT $FF ' Send byte before start token
SHOUT $FE ' Start block token

' Actual write - replace with buffered 512 bytes after demo
SHOUT $35, 512 ' Sends lots of 5's!

' We should send a 16byte CRC after the data.
' It is ignored by the device, so can be any value.
SHOUT $95, 2

sd_write_tmp = SHIN ' Should be write result

sd_write_tmp = sd_write_tmp & 14
sd_write_tmp = sd_write_tmp >> 1

IF sd_write_tmp <> 2 THEN sd_write_return ' Failed!

SHOUT $FF, 10 ' Send 10 clocks after write ?

' Wait until card is idle
sd_write_tmp = WAITFORNZ


HIGH SD_CSPIN

sd_write_status = 0 ' All OK !

ENDIF

sd_write_return:
RETURN sd_write_status

ENDFUNC

Bean
09-09-2010, 12:16 PM
Maxwin,
I'm a little concerned about this line in your code:

sd_write_tmp = SHOUTCMD 24, __param1 ' <param = sector addr>

I don't think it will work right, because __param1 will get set to 24, then __param2 will get set to __param1 (which was already assigned the value of 24).

You should see something like this in the PASM code:

mov __param1,#24
mov __param2,__param1

The easiest way to avoid this would be to use sd_write_tmp to hold the value in __param1.

sd_write_tmp = __param1
sd_write_tmp = SHOUTCMD 24, sd_write_tmp

Keep up the good work.

Bean

Maxwin
09-09-2010, 01:29 PM
Thanks for the check. I think some "wires crossed", as SHOUTCMD is a SUB which is called and I pass in 2 args (in this case 24 and the value of __param1)

This is the PASM around that point of the code:



mov __param1,#24 ' sd_write_tmp = SHOUTCMD 24, __param1 ' <param = sector addr>
mov __param2,__param1
mov __paramcnt,#2
jmp #_LMM_CALL
long @SHOUTCMD_ret - @__Init
long @SHOUTCMD - @__Init
mov sd_write_tmp,__param1




.. anyhow it works ok so I won't fiddle with it just yet !!

Cheers!

Bean
09-09-2010, 04:08 PM
Well if it's working, it is just by "happy accident".

The first instruction put the value 24 into __param1, then the value in __param1 is loaded into __param2. So __param2 will ALWAYS be 24 instead of what was originally in __param1.

Bean

Maxwin
09-09-2010, 04:57 PM
...ah, the penny just dropped..

It was working when called from COG code, but at the moment I am moving everything to a lib and SUB code, with nice little methods like "SD_OPEN" and "SD_READID"... and of course it means I am now calling a sub from a sub, so the __params would be common.

Thank you for spotting this! I suspect that might have kept me up late!

Maxwin
09-09-2010, 09:21 PM
Latest version of sd.lib moved to first post in this thread.

$WMc%
09-10-2010, 12:49 AM
Maxwin:
'
Excellent work Dude!!!
'
PropBasic is getting better and better!!!
'

Baggers
09-10-2010, 09:35 AM
Excellent work Maxwin, I was going to look at it, but have been too busy again lately, so you beat me to it, nice work, as PropBasic was needing an SD lib, so Kudos to you :)

Maxwin
09-10-2010, 03:15 PM
Thanks guys!

Have anyone tried and had success running the code ? Would be good to hear which cards are working (or maybe not!)

So far I tested:

1. "Old" 256mb sandisk sd card
2. 2GB kingston microsd card

Do not have anything bigger than 2GB, so not sure what would happen there.

max72
09-10-2010, 10:27 PM
I had not time to test it yet, but I'll try is ASAP
Is the driver requiring pull up resistors?
Massimo

Maxwin
09-11-2010, 08:41 AM
max72:

I used the circuit shown here (schematic on last page), which does include pull-ups:

http://www.parallax.com/Portals/0/Downloads/docs/prod/comm/32313-SDCardAdapter-v1.0.pdf

max72
09-11-2010, 04:09 PM
Ok,
my SD card with pull ups is on the Garda lake for the Centomiglia (witout me!!!), so I only have hand soldered veroboard versions with no pullups around.
I'll give it a try as soon as I can nonetheless.

Massimo

max72
09-13-2010, 12:45 PM
I tested the routine with ucontroller's board.
I had to change the code because I have not the "inserted" pin, so I disabled the test routines in the main file and in the lib.

This is the output:

Insert card : Card inserted.
Card name=SD256 ,Serial number=1615369124
Blocksize=512 ,Totalsectors=988160 ,Totalcapacity=505937920
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.

How can I create a test file and fill it with some text?

I'll try to test it with other cards, and with a no pull-up SD reader.

Massimo

Maxwin
09-13-2010, 01:02 PM
Hi Massimo!

Thanks for posting the output. I will need to check over the routine, as your Totalcapacity reading would imply around 500MB card, whereas your card name suggests 256MB. I suspect your card name is correct, as that is an ASCII field.. I will go over my maths...

Apart from that, you do not "create a test file". You simply read/write from sectors in 512 byte blocks. It is up to your program how you do it, but it is very simple. Just populate the bytebuffer with 512 bytes, then use SD_WRITE <sector number>, from 0 to 988160 (according to your card output).

Then to read back, call SD_READ <sector number>, and then you will find the contents (512 bytes) in the bytebuffer.

Will post back later on once I check the Totalcapacity calculation...

Maxwin
09-14-2010, 09:59 AM
Massimo: OK, I checked again, and I always get the correct readings on the few cards I have available to me!

May I ask:

1. What type/brand of card you are using ?

2. If you read the card into the PC (use freeware HxD for example. There is an "Extras" menu to open the disk. Then at top right it will report the total sectors in your card. Also, as you scroll down the card data you can clearly see the per-sector byte size)

Does it match what my lib reports? Your reading of 988160 total sectors seems high, unless you have a card which uses 256byte sectors perhaps...

3. Could you try a different card ?

Thanks !

max72
09-14-2010, 11:13 AM
Hi,
it is a Sandisk 256Mb card.
At the moment I have not other SD cards available (or free for testing).
From HxD the sectors count is 494080 and not the 988160 shown at the terminal.

I retested the card and reformatted it, but with not success.

I'll test other SD cards as soon as possible.

Massimo

Maxwin
09-14-2010, 11:35 AM
In the HxD, if you scroll down and check the left hand column (offset), where does your last offset for Sector0 end... 1F0 ?

-- Also, if you use my lib to write a block of ZERO into the first sector (SD_WRITE 0), does that fix it ?

max72
09-14-2010, 03:48 PM
In the HxD, if you scroll down and check the left hand column (offset), where does your last offset for Sector0 end... 1F0 ?

-- Also, if you use my lib to write a block of ZERO into the first sector (SD_WRITE 0), does that fix it ?

The Sector 0 ends at 1F0.

I wrote 0 to the first sector. result is the same, while from the PC I wasn't able to access the card, I had to reformat it.

I have a couple of old small card (the ones include in digital cameras). They are a sitecom 128Mb and a Canon 16 Mb:

? - SDplay -
Insert card : Card inserted.
Card name=128MB ,Serial number=269180828
Blocksize=512 ,Totalsectors=488960 ,Totalcapacity=250347520
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.



? - SDplay -
Insert card : Card inserted.
Card name=S016B ,Serial number=997232359
Blocksize=512 ,Totalsectors=232960 ,Totalcapacity=119275520
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.

Massimo

Maxwin
09-14-2010, 04:10 PM
So, your sectors are identified as 512 bytes long by HxD. Good so far... :)

Writing 0's to the first sector would wipe out the FAT indexes, so your PC would no longer recognise the format of the card (of course a re-format puts it back). I was just curious if that made a difference in your case (OK, we can ignore that red herring!)

I can see your output above on the 2 different cards has the same symptoms. I am beginning to wonder if there was a gremlin in the first published version, or perhaps something you changed might have impacted something... Could I ask you to try re-downloading the sd.lib and re-try ?

I have just uploaded the latest version to post #1 in this thread.

Thanks for your efforts!

max72
09-14-2010, 04:55 PM
I redownloaded the Sd.lib file.
Only changes I made are changing pin constants, and commenting out the check of the SD pin, both in the main file and in the lib file.
Here we have the new dump (16, 128 and 256 Mb cards):

? - SDplay - _
Insert card : Card inserted.
Card name=S016B ,Serial number=997232359
Blocksize=512 ,Totalsectors=232960 ,Totalcapacity=119275520
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.?

- SDplay -
Insert card : Card inserted.
Card name=128MB ,Serial number=269180828
Blocksize=512 ,Totalsectors=488960 ,Totalcapacity=250347520
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.?

- SDplay -
Insert card : Card inserted.
Card name=SD256 ,Serial number=1615369124
Blocksize=512 ,Totalsectors=988160 ,Totalcapacity=505937920
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.

Massimo

Maxwin
09-14-2010, 05:57 PM
OK, so this is rather wierd!

I am attaching a debugging version of sd.lib and SDplay.... could you run them on one of your cards and post the results?

The extra data will show me the "raw" config coming from your cards, so that should help solve it.

Thanks for sticking with this.

In the meantime, I will go hunting the house for some more cards to try...

max72
09-14-2010, 09:49 PM
I'm away, but I'll test it tomorrow.

Massimo

whiteoxe
09-15-2010, 02:52 PM
hI, CAN AN sd CARD be put into other thigs or circuis and retrieve the data.

Could anSD card data be accesses by a keypad with an lcd ?

Harley
09-15-2010, 06:56 PM
Where does one find PropBASIC? I looked at OBEX and only find snippets and for OLED.

I would like to have some OS with SD card which I can adapt to use with a 4.3" LCD (Rayman's color touchscreen LCD) and a keyboard. What I've found so far only uses FDS thus requires some sort of other device to display results. The LCD allows display right with the Prop; keyboard usually is a separate though cabled item. I wouldn't want a touchscreen type of 'keyboard', though it probably could be implemented if sufficient RAM allows that code.

Sapieha
09-15-2010, 07:08 PM
hi Harley
LOOK on this thread.

Download PropBASIC here... 00.01.02 July 20, 2010
(http://forums.parallax.com/showthread.php?t=118611)

Where does one find PropBASIC? I looked at OBEX and only find snippets and for OLED.

I would like to have some OS with SD card which I can adapt to use with a 4.3" LCD (Rayman's color touchscreen LCD) and a keyboard. What I've found so far only uses FDS thus requires some sort of other device to display results. The LCD allows display right with the Prop; keyboard usually is a separate though cabled item. I wouldn't want a touchscreen type of 'keyboard', though it probably could be implemented if sufficient RAM allows that code.

Harley
09-15-2010, 07:53 PM
Sapieha,

Thank you, I downloaded the two files (OSX version for me), but found the IDE Preferences under 'bst' not Tools' menu.

Now to read the documentation to know what to do to begin.

Sapieha
09-15-2010, 08:01 PM
Hi Harley

You need start BSTC and link PropBasic to IDE before it can recognize it.

Look on attachment




Sapieha,

Thank you, I downloaded the two files (OSX version for me), but found the IDE Preferences under 'bst' not Tools' menu.

Now to read the documentation to know what to do to begin.

Harley
09-15-2010, 09:33 PM
Sapieha, I don't see a screen anything like what you are showing. Mine is like this attachment; a .tiff format. Lower-case 'bst' for the application on the window title, and this next window.

I don't have anything called BSTC, and if I did how does one link PropBasic to IDE. I don't have anything called PropBASICIDE. I'm wondering if I got something wrong somewhere.

Sapieha
09-15-2010, 09:41 PM
Hi Harley.

Sorry I dont know mych on OSX

BUT in BST You need find Top Menu Like on my BST.
And in it Tools --> IDE Preferences.

I think that menu opens with one of round buttons Top Left on BST window



Sapieha, I don't see a screen anything like what you are showing. Mine is like this attachment; a .tiff format. Lower-case 'bst' for the application on the window title, and this next window.

I don't have anything called BSTC, and if I did how does one link PropBasic to IDE. I don't have anything called PropBASICIDE. I'm wondering if I got something wrong somewhere.

max72
09-16-2010, 11:04 AM
New test run, still the same set of SD cards. i hope to be able to test also a bigger one...

debug results:

? - SDplay -
Insert card : Card inserted.
Card name=S016B ,Serial number=997232359

0 93 1 50 19 89 128 227 118 217 207 255 22 64 0 79
909 6 9
Blocksize=512 ,Totalsectors=232960 ,Totalcapacity=119275520
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.

? - SDplay -
Insert card : Card inserted.
Card name=128MB ,Serial number=269180828

0 54 0 50 23 89 129 221 118 218 255 129 150 64 0 233
1909 6 9
Blocksize=512 ,Totalsectors=488960 ,Totalcapacity=250347520
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.

? - SDplay -
Insert card : Card inserted.
Card name=SD256 ,Serial number=1615369124

0 38 0 50 31 89 131 196 254 250 207 255 146 64 64 193
3859 6 9
Blocksize=512 ,Totalsectors=988160 ,Totalcapacity=505937920
-- Data Written OK! --
-- Data Read OK! --
20 bytes of data back from card:
ABCDEFGHIJKLMNOPQRST
End.

Thanks for your effort.
Massimo

Maxwin
09-16-2010, 11:21 AM
Well, the quick fix is in sd.lib, around line 291...

change

INC SD_sectormult, 2
to

INC SD_sectormult, 1


BUT, this does not solve the matter. The SD card spec clearly states to add 2 to the mult value. It might be your cards are a different version/standard to mine??

1. I will look through the other "standards" to see if there is a case where adding 1 is desired!

2. I kindly ask if any other forum members could try this routine to establish the results from a different source?

Hope we can solve this soon...

max72
09-16-2010, 12:19 PM
Could it be related to the card size? Up to now I have been able to test it with small cards. Are yours bigger?

Massimo

PS: I solved the code modify issue putting a propeller pin to ground and using it as detect pin.

Maxwin
09-16-2010, 02:27 PM
Massimo,

Comparing your debugging data to mine I could find the problem! I was reading the wrong bits for the sd_mult, which by luck were correct on my cards !

Here is the updated sd.lib with debug code still included. If you can report back that its ok, I will update the non-debug version at the top of this thread :)

Thank you so much for your help.
Max.

max72
09-16-2010, 09:57 PM
I'll be way from my cards for a couple of days. I'll test it ASAP.
Thanks again.

Massimo

Maxwin
09-24-2010, 04:23 PM
I have updated the sd.lib to fix the "mult" problem identifed by MAX72 (thank you Massimo!)

The latest version is now available in the first post.

:)