P2 SD PASM Driver Demo using SPIN2 (also uses Serial Monitor) v.209
Cluso99
Posts: 18,069
SD Driver (pasm)
Here is my latest SD PASM Driver and demo in SPIN2
It utilises my Serial Monitor (pasm) too
2929-05-08: Update v.209
Added spin call routines to the SD driver (and Serial Monitor) to simplify calling from spin.
Now returns $0 on success, -1=$FFFF_FFFF on failure.
2020-05-06: Update v.208
Code support for old bytemode SD cards removed
Fixed a bug where the initialisation clocks were failing due to 5us calculated at 20MHz with pullup on P59. Now works to 360MHz.
Returns status and checked in spin
- pnut v34r works only with P59 pullup
- fastspin 4.1.8 reports failure due to bug - will be fixed in next fastspin release
General tidy code tidyup.
Both SDDriver_208.spin2 and SDDriver_Equ.spin2 must be used as a pair.
Option to write sector commented out.
2020-05-06: Update: v.207c
New spin routines initialiseSD, readCSDCID, readSector, writeSector.
SD Driver now returns status for the preceeding calls but not checked in spin.
WARNING / NOTES:
* Always use the matching pair SDDriver_Code_207c.spin2 with SDDriver_Equ.spin2
* Option commented out to read, modify, write, read, fix, write, read sector $0000_0001 - It will temporarily overwrite sector $0000_0001 on your SD Card !!!
* Error detection working in the SD Driver but does not work in spin!!!
* Debug code displays the working registers and sector data to the serial port
Compiles with fastspin v4.1.8 (cannot load using pnut v34r)
C:\P2\Propeller_II_Latest\SDDriver_207>type f2.bat
f418 %1.spin2 -2 -l
l418 %1.binary -b115200 -t -SINGLE
C:\P2\Propeller_II_Latest\SDDriver_207>f2 sddriver_demo2
Here is an output on windows command prompt using fastspin...
Here is my latest SD PASM Driver and demo in SPIN2
It utilises my Serial Monitor (pasm) too
2929-05-08: Update v.209
Added spin call routines to the SD driver (and Serial Monitor) to simplify calling from spin.
Now returns $0 on success, -1=$FFFF_FFFF on failure.
2020-05-06: Update v.208
Code support for old bytemode SD cards removed
Fixed a bug where the initialisation clocks were failing due to 5us calculated at 20MHz with pullup on P59. Now works to 360MHz.
Returns status and checked in spin
- pnut v34r works only with P59 pullup
- fastspin 4.1.8 reports failure due to bug - will be fixed in next fastspin release
General tidy code tidyup.
Both SDDriver_208.spin2 and SDDriver_Equ.spin2 must be used as a pair.
Option to write sector commented out.
2020-05-06: Update: v.207c
New spin routines initialiseSD, readCSDCID, readSector, writeSector.
SD Driver now returns status for the preceeding calls but not checked in spin.
WARNING / NOTES:
* Always use the matching pair SDDriver_Code_207c.spin2 with SDDriver_Equ.spin2
* Option commented out to read, modify, write, read, fix, write, read sector $0000_0001 - It will temporarily overwrite sector $0000_0001 on your SD Card !!!
* Error detection working in the SD Driver but does not work in spin!!!
* Debug code displays the working registers and sector data to the serial port
Compiles with fastspin v4.1.8 (cannot load using pnut v34r)
C:\P2\Propeller_II_Latest\SDDriver_207>type f2.bat
f418 %1.spin2 -2 -l
l418 %1.binary -b115200 -t -SINGLE
C:\P2\Propeller_II_Latest\SDDriver_207>f2 sddriver_demo2
Here is an output on windows command prompt using fastspin...
..... C:\P2\Propeller_II_Latest\SDDriver_209>l418 sddriver_demo209.binary -b115200 -t -SINGLE ( Entering terminal mode. Press Ctrl-] to exit. ) P2-Monitor V1.51 P2-SDDriver x209 pass 100: 00 00 00 00 01 46 04 F6 25 00 C0 FD 4F 08 63 6E '.....F..%...O.cn' 104: 50 00 00 00 00 02 00 00 87 00 00 00 00 00 00 00 'P...............' 108: FF 00 00 00 00 00 00 00 FF FF FF FF 02 46 04 F6 '.............F..' 10C: 00 00 00 00 65 D8 00 F6 66 DA 00 F6 6C 44 02 F6 '....e...f...lD..' pass 100: 00 00 00 00 01 46 04 F6 00 C1 0F 00 DD CD 07 72 '.....F.........r' 104: 4A 00 00 00 00 00 00 00 87 00 00 00 01 00 00 00 'J...............' 108: FF 00 00 00 FE 00 00 00 FF FF FF FF 00 00 00 00 '................' 10C: 00 00 00 00 65 D8 00 F6 66 DA 00 F6 6C 44 02 F6 '....e...f...lD..' FC100: 03 53 44 53 4C 31 36 47 80 14 F3 4A 67 01 15 69 '.SDSL16G...Jg..i' FC110: EC 02 90 FD 1A C8 06 F6 F6 01 88 FC 64 05 D8 FC '............d...' pass 100: 00 00 00 00 00 00 00 00 00 C1 0F 00 13 64 C8 72 '.............d.r' 104: 51 00 00 00 00 00 00 00 87 00 00 00 01 00 00 00 'Q...............' 108: FF 00 00 00 FE 00 00 00 FF FF FF FF 00 00 00 00 '................' 10C: 00 00 00 00 65 D8 00 F6 66 DA 00 F6 6C 44 02 F6 '....e...f...lD..' FC100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC1A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC1B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC1C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC1D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC1E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC1F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC2A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC2B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 82 '................' FC2C0: 03 00 0C FE FF FF 00 20 00 00 00 AC DA 01 00 00 '....... ........' FC2D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC2E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' FC2F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA '..............U.' *
zip
19K
Comments
Can you just run the SD part without the extra monitor components or are there dependencies?
They can each be called from pasm or spin.
There are No dependencies between the monitor and the sd
I haven't done any timing tests and it will be slower than if it were in cog.
Maybe later I will copy the send/recv routine to cog to execute faster. It will fit in less than 16 longs. The routine does both send and receive combined. Due to required delays in the silicon the receive and transmit combined are without penalty.
This is the loop which could then be a cog rep
I have had extreme difficulty in getting this to run due to all sorts of compiler issues with errant addressing. It's only with Eric's latest v4.1.8 that I can compile this and then it ran first time! Same driver pasm as I've been trying to get running for the last 6+ months. Been extremely frustrating
BTW I've stripped the FAT32 file LOAD and RUN from the code. It now only uses 16 cog registers and not all of them are necessary as I'm going to strip all old SD Card support for sector byte addressing. So only SDHC+ using addressing in sectors.
So from what I see here at 21 clocks per loop iteration (EDIT: if you use REP instead of DJNZ) it seems the best speed in a COG running this loop would be about 8.6Mbps or just a little over 1 MB/s at 180MHz raw SPI transfer rate, and in practice this will be lowered with loop setup overheads/latency of course. Maybe a REP loop would be good to use instead of the DJNZ in Hub-exec mode (assuming interrupts can be delayed by the 8 bits) so that the 8 instructions in the loop fit entirely in the single HUB transfer with the FIFO refill and the branch penalty is then eliminated?
Also if we wish to go faster, I imagine a Smartpin approach can be taken hopefully getting us closer to 25Mbps, though it would then become a different implementation to this and it might be able to make use of the streamer at some point too. There may be other SPI implementations that already do that...haven't gone hunting around myself.
Uses the files in the first post excluding SDDriver_Demo.spin2
Postedit: Should always test those quickies There's a bug in the compiler so it always fails
There is a new update to my SD Driver, Equates and Demo files in the top post. Please replace all SDDriver files. Monitor files have not changed but are included.
There is plenty of debug info output to the serial terminal which can be disabled if required.
Best next step is streamer for SPI data and smartpin for SPI clock. This then allows easy going to dualSPI mode.
Do you mean that the SD is not looking for the serial while trying to boot the SD? If so, then yes it doesn't look. We were lucky to get SD booting!
BTW You can put a pullup on P59 to prevent the SD booting. This is required to use pnut as otherwise pnut doesn't find the P2. Fastspin/LoadP2 works fine.
However, there is another way...
The SD boot file could then listen on the serial port and do whatever it is supposed to be doing at the same time.
We were very limited to what Chip would let us (Peter and I) do in the ROM as Chip was understandably not willing to let us do anything that might cause his boot code to not work. Chip's code tests for the pullups and then jumps to my SD code, or in the case of the autobaud strings, Chip jumps to my SD or Peter's TAQOZ. It was only at the last minute that the SD code was changed to return to Chip's code on failure. Originally it was supposed to stop.
SDinit initialises the SD Card.
This routine must be called before any other routine (readCSDCID, readSector, writeSector) is called.
This routine currently requires bufad to be preset with an address for the hub sector buffer. I need to check if bufads is actually used by the routine as I think it no longer needs to be set.
readCSDCID
This routine requires bufad to be preset with an address for the hub sector buffer. The CSD (16 bytes) followed by CID (16 bytes) will be placed into hub at the address specified by bufad.
readSector
This routine requires sector to be preset with the (raw) sector address and bufad to be preset with an address for the hub sector buffer. The sector (512 bytes) will be placed into hub at the address specified by bufad.
writeSector
This routine requires sector to be preset with the (raw) sector address and bufad to be preset with an address for the hub sector buffer. The sector (512 bytes) will read from hub at the address specified by bufad and written to the sector on the card.
Status
All the above routines (SDInit, readCSDCID, readSector, writeSector) return status in the status cog register. It's value can be checked by comparing the value in status with the predefined constant success. Currently success will be signaled by status returning $A5 and an error will be signaled by status returning $FFFF_FFFF.
Further status information can be obtained by examining the cmdout cog register which contains the last command sent to the card. Note the command sent to the card is "OR"ed with $40.
SD Card Pins used are currently hardcoded to the P2 boot standard of P60=#CS, P61=CLK, P59=DI(MOSI in to card), P58=DO(MISO out from card).
Cog Register Usage is currently $100-$10C but may be changed and recompiled. See/change _regs equate in the SDDriver_EQU.spin2 file.
Hub Code Space is currently $FC560-~$FC880+ but may be changed and recompiled. See/change _hub equate in the SDDriver_EQU.spin2 file.
Hub sector buffer can be set to use $FC100[512] if desired as this is in the ROM booter space which can be reused (at least for now). The Serial Monitor uses $FC000[80] so don't use this space please.
Disable Boot from SD Card
This can be done by enabling a 10K pullup on P59 (a switch on P2EVAL pcbs) which forces the booter to go to the serial download routine.
History and Gotchas
My P2 SD Driver is based on the code I wrote for the P2 ROM plus a couple of tweeks and then some tidyup and removal of the support for really old cards using byte based addressing (2GB and less), and the file load and run sections which are probably better done with fsrw or FATEngine (Kye's) in spin. I spent some serious time back then finding out why many SD Cards do not release (float) DO after the whole transaction and I implemented this in the RevB silicon ROM. We were on a time schedule and I continued after the ROM code was frozen and found one obscure way where the DO may not be released although I think that path is unlikely.
This new code should now, under all circumstances, release DO after a transaction/routine (ie Initialise, readCSDCID, readSector, writeSector), and all SD Card pins are also floated too. This means sharing the pins with the Flash (or others) should work properly provided the pins are also released (floated) by other software.
In the last few days I've been finally been able to get my serial debug code (BTW is it a serial driver also) working and found that SD Card initialisation was sometimes failing. This was because I had coded the initialisation clocks used a hardcoded 5us which was calculated based on RC mode ~20MHz and 100Hz clocks. I've updated this to 5us 360MHz which should work up to 400MHz which would be over the max P2 clock range. Note this routine does not know the actual clock/frequency used - in the ROM at boot time this was known to be around ~22MHz.
Note there is also a Serial Monitor demo too.