SD/fat32 implementations

in Propeller 2
Has anyone developed a framework/object to access files on a fat32 filesystem of an SD card?
I know that TaqOz does this, but I didn't know if there was something outside of TaqOz.
Thanks,
Terry
I know that TaqOz does this, but I didn't know if there was something outside of TaqOz.
Thanks,
Terry
Comments
For an example, see the Fun with the P2 ROM thread.
cs_pin=60 clk_pin=61 miso_pin=58 mosi_pin=59
Any thoughts about this?
Use the built-in TAQOZ to do a sanity check for you. Just reset and type the three keys [>] [space] [esc] and from TAQOZ type MOUNT. From there you can do a DIR.
If it doesn't work there then it won't work elsewhere.
Cold start ---------------------------------------------------------------- Parallax P2 .:.:--TAQOZ--:.:. V1.0--142 180530-0135 ---------------------------------------------------------------- TAQOZ# MOUNT .SDSL08G 5E5F_7F14 TAQOZ 32k 7,576M ok TAQOZ# DIR .SDSL08G 5E5F_7F14 TAQOZ 32k 7,576M TAQOZ $0000_3F80 2018.05.21.10.33 0 CODE $0000_4080 2017.07.20.07.56 0 HELP $0000_42C0 2017.12.04.12.34 0 MUSIC $0000_4680 2016.06.25.02.37 0 VIDEOS $0004_06C0 2016.08.05.02.50 0 3X5 .TXT $0007_A540 2017.11.23.15.06 3,968 ASCIIART.TXT $0007_A580 2017.11.23.15.05 55,148 CALCDEMO.FTH $0007_A600 2017.10.11.06.28 1,848 EASYFILE.FTH $0007_A640 2017.10.24.13.53 46,173 EASYNET .FTH $0007_A6C0 2017.10.24.01.57 42,985 EXTEND .FTH $0007_A740 2017.10.24.12.14 60,355 FISH2 .VT $0007_A7C0 2017.11.23.15.08 211,945 HOME .HTM $0007_A980 2014.06.15.15.45 68,513 HTTP001 .HTM $0007_AA40 2013.12.02.16.25 388 HTTP404 .HTM $0007_AA80 2013.12.02.23.58 564 ILIAD .TXT $0007_AAC0 2017.11.23.12.55 1,201,891 KJV .TXT $0007_B400 2017.08.28.12.28 5,504,282 LEXICON .TXT $0007_DE00 2017.11.23.13.48 988,130 LIFE .FTH $0007_E5C0 2017.10.15.05.40 7,308 LOGON .HTM $0007_E600 2013.12.02.16.25 388 LOVE .WAV $0007_E640 2015.02.16.08.06 14,630,692 MIDENG .TXT $0008_5600 2017.11.23.14.11 1,248,077 P8X32A .PDF $0008_5FC0 2012.02.22.12.57 1,442,886 PARALLAX.PNG $0008_6B00 2013.12.12.01.41 6,109 POPCORN .WAV $0008_6B40 2012.11.07.13.26 3,242,394 PRIDE .TXT $0008_8400 2017.11.23.12.54 726,223 ROUGES .TXT $0008_89C0 2017.11.23.13.51 219,885 SEE .FTH $0008_8B80 2017.07.06.01.30 2,187 SPLAT-V4.FTH $0008_8BC0 2017.03.09.12.30 18,944 VULGAR .TXT $0008_8C00 2017.11.23.13.56 511,916 WARPEACE.TXT $0008_9000 2015.08.30.07.27 3,226,652 WARWORLD.TXT $0008_A8C0 2017.11.23.13.42 365,413 WEBSTERS.TXT $0008_ABC0 2017.11.23.12.59 28,956,348 _BOOT_P2.BIN $0009_8940 2018.12.27.06.48 131,072 BEACH .BMP $0009_8C40 2018.12.03.06.50 308,314 P2 .ROM $0009_BF40 2019.02.18.07.09 65,536 _BOOT_P2.BIB $0009_8B40 2018.12.27.06.48 131,072 BOOT_P2.BIX $0009_C0C0 2019.02.15.08.21 65,536 BEACH2 .BMP $0009_8EC0 2018.12.06.14.20 308,274 BIRD .BMP $0009_9140 2018.12.03.06.54 308,346 BUZZ .BMP $0009_93C0 2018.11.11.01.53 308,346 DRAGON .BMP $0009_9640 2018.10.23.01.21 308,346 EYEGOD .BMP $0009_98C0 2018.10.28.04.17 308,346 FACE .BMP $0009_9B40 2018.10.28.04.03 308,346 FIRE .BMP $0009_9DC0 2018.11.02.23.51 308,346 LMMS .BMP $0009_A040 2018.10.23.01.01 308,280 MARIO .BMP $0009_A2C0 2018.12.03.06.55 308,266 MARIO .PNG $0009_A540 2018.10.19.14.37 16,813 MCQUEEN .BMP $0009_A580 2018.10.28.04.19 308,346 P2D2 .BMP $0009_A800 2018.12.06.14.26 308,346 SPIDEY .BMP $0009_AA80 2018.10.28.04.24 308,346 SPIDEY .GIF $0009_AD00 2018.10.29.01.28 145,609 SPIDEY .PNG $0009_AE40 2018.10.29.13.16 124,697 SUNSET .BMP $0009_AF40 2018.10.28.04.13 308,346 TIGER .BMP $0009_B1C0 2018.12.06.14.23 308,346 TIGER .GIF $0009_B440 2018.10.25.01.16 248,692 TIGER .JPG $0009_B640 2018.10.25.01.10 133,590 TIGER .PNG $0009_B780 2018.10.25.01.07 693,848 TIGER1 .BMP $0009_BD00 2018.12.03.06.58 77,946 TAQOZ1V1.FTH $0009_BDC0 2018.12.30.14.06 25,371 W5500A .FTH $0009_BE00 2018.12.30.00.56 12,367 C2PROG .FTH $0009_BE40 2018.12.12.13.58 12,180 _BOOT_P2.BY $0009_BE80 2019.01.28.06.53 84,736 _BOOT_P2.BIZ $0009_8A40 2018.12.27.06.48 131,072 _BOOT_P2.BAD $0009_C0C0 2019.02.15.08.21 65,536 A_ _ B O. O $0C80_3F80 1980.02.02.00.01 5,767,241 __BOOT~1.BIX $0009_C140 2019.02.19.12.40 32 ok TAQOZ#
Looking in sdspi.spin2, I think this may be the problem.
I don't think the pins are laid out the same.
You can also test your pin arrangement other than the default with TAQOZ by changing the sdpin constant with this expression:
&60.58.59.61 ' sdpins 2+ !
It's a bit more awkward than it usually is with the cramped ROM space because we are writing directly to the sdpins constant whereas normally we have a word to take care of it easily.But the syntax is & for a decimal bytes notation (as in IP notation where every group of decimal digits represent a byte) in the sequence CS.MISO,MOSI.CLK and then the tick ' then a space and the name of the constant (sdpins) then 2+ to modify that address to point to the parameter field and then ! to store the new value into the sdpins constant. Just in case you want to double check your original setup.
BTW, the extended TAQOZ implementation of FAT32 includes all the FOPEN type commands, handling a file as virtual memory etc as well as the disk utilities and FORMAT.
pri read | r ' ' Read eight bits from the card. ' r := 0 repeat 8 outa[clk] := 0 outa[clk] := 1 r += r + ina[do] return r
becomes
pri read | r ' ' Read eight bits from the card. ' r := 0 repeat 8 outB[clk] := 0 outB[clk] := 1 r += r + inB[do] return r
Which won't work with pin numbers >31!!Pretty sure he already fixed the Start_Explicit… at least I have it in mine if you need.
The thread I've got for what I was working on is here;
https://forums.parallax.com/discussion/169786/working-on-fsrw/p1
Right now I'm trying to learn how to start a cog the right way and pass everything, basic asm engine stuff. Once I have a handle on that I plan on using the smart pins. This is my SDSPI using inline asm. It should just replace fsrw2.6 sdspi, although I made some small tweaks to the fsrw file to make things return gracefully. When all the abort code was changed to return there were some edge cases that didn't seem quite right.
{{ SDSPI driver for P2-ES FastSpin/InlineASM RC2 Cheezus Slice (Joe Heinz) - Feb - 2019 Thanks to cluso, ersmith, David Betz, Rayman, Dave Hein and all the other greats out there in fourm land! Original spin version by Radical Eye Software Copyright 2008 }} con sectorsize = 512 sectorshift = 9 var long di, do, clk, cs, starttime, sdhc, di_mask, do_mask, clk_mask, do_pin pri send(outv) | c, i ' Send eight bits, then raise di. i := di c := clk asm rol outv, #24 rep #.end_send, #8 rol outv, #1 wc drvl c drvc i drvh c .end_send drvh i endasm pri read : r | c, o ' Read eight bits from the card. c := clk o := do asm mov r, #0 rep #.end_read, #8 drvl c waitx #14 '' !! 13 safe for up to 160 mhz, 14 for 320mhz testp o wc drvh c rcl r, #1 .end_read endasm pri readresp | r '' made return timeout to caller CHZ 2-2019 ' Read eight bits, and loop until we ' get something other than $ff. ' repeat if (r := read) <> $ff return r if checktime == -41 return -41 pri busy | r ' Wait until card stops returning busy '' made return timeout to caller CHZ 2-2019 ' repeat if (r := read) return r if checktime == -41 return -41 pri checktime ' Did we go over our time limit yet? { if cnt - starttime > clkfreq return -41'abort -41 ' Timeout during read } pri cmd(op, parm) ' ' Send a full command sequence, and get and ' return the response. We make sure cs is low, ' send the required eight clocks, then the ' command and parameter, and then the CRC for ' the only command that needs one (the first one). ' Finally we spin until we get a result. DRVL_(cs) read send($40+op) send(parm >> 24) send(parm >> 16) send(parm >> 8) send(parm << 0) if (op == 0) send($95) else send($87) return readresp pri endcmd ' Deselect the card to terminate a command. drvh_(cs) ' Deselect the card to terminate a command. PUB stop ' RJA adding in some things PUB release pub start_explicit(iDO, iCLK, iDI, iCS)| t 'RJA adding in some things to make work do := iDO clk := iCLK di := iDI cs := iCS t := clk outh_(cs) outh_(clk) outh_(di) dirh_(cs) dirh_(clk) dirh_(di) asm rep #.initclksout, #4800 drvnot t .initclksout getct t endasm starttime := t cmd(0, 0) drvh_(cs) ' Deselect the card to terminate a command. cmd(8, $1aa) read read read read drvh_(cs) ' Deselect the card to terminate a command. repeat cmd(55, 0) t := cmd(41, $4000_0000) drvh_(cs) ' Deselect the card to terminate a command. if t <> 1 quit if t return -40'abort -40 ' could not initialize card cmd(58, 0) sdhc := (read >> 6) & 1 read read read drvh_(cs) ' Deselect the card to terminate a command. return sdhc +1 ' return card type pub start(basepin) result := start_explicit(basepin, basepin+1, basepin+2, basepin+3) PUB doSDHC(n) if sdhc == 0 return n <<= 9 else return n pub readblock(n, b) ' ' Read a single block. The "n" passed in is the ' block number (blocks are 512 bytes); the b passed ' in is the address of 512 blocks to fill with the ' data. ' starttime := cnt cmd(17, doSDHC(n)) readresp repeat sectorsize byte[b++] := read read read return endcmd { pub getCSD(b) ' ' Read the CSD register. Passed in is a 16-byte ' buffer. ' starttime := cnt cmd(9, 0) readresp repeat 16 byte[b++] := read read read return endcmd } pub writeblock(n, b) ' ' Write a single block. Mirrors the read above. ' starttime := cnt cmd(24, doSDHC(n)) send($fe) repeat sectorsize send(byte[b++]) read read if ((readresp & $1f) <> 5) return -42'abort -42 busy return endcmd {{ ' Permission is hereby granted, free of charge, to any person obtaining ' a copy of this software and associated documentation files ' (the "Software"), to deal in the Software without restriction, ' including without limitation the rights to use, copy, modify, merge, ' publish, distribute, sublicense, and/or sell copies of the Software, ' and to permit persons to whom the Software is furnished to do so, ' subject to the following conditions: ' ' The above copyright notice and this permission notice shall be included ' in all copies or substantial portions of the Software. ' ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ' IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ' CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ' TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ' SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. }}
So, I replaced dira and outa with DIR and OUT. I am going to look through simple serial and see how that works. I have pin 62 assigned.
Mounting. Mounted. Dir: That's the dir Wrote file.urned - That's, all, folks! 3 Returned from start
I think the idea is to set smartpin mode %00101 = transition output for the clock. Then use Sync serial tx and rx to push data around. It should end up with some really optimized code, as well as nice mhz.
Now that you have the dir and out macro, you'll still need to change the pin numbers by 32 right?
I didn't try this on Eval board's uSD, used one on my own board...
I imagine those switches have to be in the right position for uSD access...
I'll look into this and see about fixing it.
I thought this stuff at the beginning would make it work, but maybe not
#ifdef __P2__ #define OUT OUTB #define DIR DIRB #else #define OUT OUTA #define DIR DIRA #endif
Maybe changing OUTA to OUTB and DIRA to DIRB in sdspi.spin2 would fix it?
PUB High(pin) drvh_(pin) PUB Low(pin) drvl_(pin) PUB Toggle(pin) drvnot_(pin) PUB In(pin) : state #ifdef __P2__ asm testp pin wc muxc state, #1 endasm #else dira[pin] := 0 waitx_(clkfreq / 10000) state := ina[pin] #endif
fastspin provides P1 definitions for drvh_, drvl_, drvnot_, and waitx_. I should create a testp_ builtin as well, I think.
The RIGHT way to do it would be to use the DRVx instructions (and TESTP), since they can span all 64 pins. The one place to watch seems to be the READ mov ina. I have a rather large delay to make sure things work at 320mhz and that's using the TESTP instruction...
pri read : r | c, o ' Read eight bits from the card. c := clk o := do asm mov r, #0 rep #.end_read, #8 drvl c waitx #14 '' !! 13 safe for up to 160 mhz, 14 for 320mhz testp o wc drvh c rcl r, #1 .end_read endasm
I'm pretty sure using the smart pins will make that delay go away. Cluso's way is to toggle the clock early and end up with an extra clock. I was going for the more brute force method, at least until I understand the chip better.
@Rayman, could you share your working version with all three .spin2 files in a zip? The one above only has sdspi2.spin2, but not the other spin2 files. I am sure I am doing something wrong and would like to compare with one that works.
Weird. Not sure what to do next. Maybe I should do a logic capture and compare with TAQOZ.
I think the pins just need to be initialized properly.
non-working mount with fsrw
Working mount in TAQOZ.
It might only work with FastSpin...
Ok, never mind PNut doesn't do Spin, dumb question...
I'm puzzled as to why it works for me and not you on the same hardware...
I lack a logic analyzer/scope, so I'm a bit stuck. Maybe start loking into ozpropdev's or cluso's prop2 based LA working.
I was unable to get your version of FSRW working as well. I'm wondering how much of this has to do with PortB. I'm thinking once I attach a card to PortA pins things should work but I'll let you know when I figure it out.
BTW, I've been idling the clock high without an issue.
If so, I'll upload my working binary. Can't imagine what's going on here...
You are running this as the top level file, right?:
sdrw_test_eval.spin2