PropBasic: SD Card
VonSzarvas
Posts: 3,525
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
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
Comments
Ray
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?
Ray
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.
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 !
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.
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
This is the PASM around that point of the code:
.. anyhow it works ok so I won't fiddle with it just yet !!
Cheers!
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
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!
'
Excellent work Dude!!!
'
PropBasic is getting better and better!!!
'
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.
Is the driver requiring pull up resistors?
Massimo
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
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
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
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...
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 !
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
-- 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
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!
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
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...
Massimo
Could anSD card data be accesses by a keypad with an lcd ?
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.
LOOK on this thread.
Download PropBASIC here... 00.01.02 July 20, 2010