' sdspi: SPI interface to a Secure Digital card. ' ' Copyright 2008 Radical Eye Software ' Modified 2009 by Michael Park: added pointer to rendezvous variables. ' ' See end of file for terms of use. ' ' You probably never want to call this; you want to use fsrw ' instead (which calls this); this is only the lowest layer. ' ' Assumes SD card is interfaced using four consecutive Propeller ' pins, as follows (assuming the base pin is pin 0): ' 3.3v ' | | | | | | ' R R R R R R 20k ' p0 --------*-+-+-+-+-+------ do ' p1 ----------*-+-+-+-+------ clk ' p2 ------------*-+-+-+------ di ' p3 --------------*-+-+------ cs (dat3) ' 150 +-+------ irq (dat1) ' +------ p9 (dat2) ' ' The 20k resistors ' are pullups, and should be there on all six lines (even ' the ones we don't drive). ' ' This code is not general-purpose SPI code; it's very specific ' to reading SD cards, although it can be used as an example. ' ' The code does not use CRC at the moment (this is the default). ' With some additional effort we can probe the card to see if it ' supports CRC, and if so, turn it on. ' ' All operations are guarded by a watchdog timer, just in case ' no card is plugged in or something else is wrong. If an ' operation does not complete in one second it is aborted. ' con sectorsize = 512 sectorshift = 9 var long cog long pCommand, pParam, pBlockno ' rendezvous between spin and assembly pub stop if cog cogstop(cog~ - 1) pub start(basepin, pRendezvous) ' ' Initialize the card! Send a whole bunch of ' clocks (in case the previous program crashed ' in the middle of a read command or something), ' then a reset command, and then wait until the ' card goes idle. ' do := basepin++ clk := basepin++ di := basepin++ cs := basepin stop pCommand := pRendezvous pParam := pRendezvous + 4 pBlockno := pRendezvous + 8 long[pCommand] := "I" cog := 1 + cognew(@entry, pRendezvous) repeat while long[pCommand] if long[pParam] abort long[pParam] return 0 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. ' long[pParam] := b long[pBlockno] := n long[pCommand] := "R" repeat while long[pCommand] if long[pParam] abort long[pParam] return 0 pub writeblock(n, b) ' ' Write a single block. Mirrors the read above. ' long[pParam] := b long[pBlockno] := n long[pCommand] := "W" repeat while long[pCommand] if long[pParam] abort long[pParam] return 0 dat org entry mov comptr,par mov parptr,par add parptr,#4 mov parptr2,parptr add parptr2,#4 ' set up mov acca,#1 shl acca,di or dira,acca mov acca,#1 shl acca,clk or dira,acca mov acca,#1 shl acca,do mov domask,acca mov acca,#1 shl acca,cs or dira,acca mov csmask,acca neg phsb,#1 mov frqb,#0 mov acca,nco add acca,clk mov ctra,acca mov acca,nco add acca,di mov ctrb,acca mov ctr2,onek oneloop call #sendiohi djnz ctr2,#oneloop mov starttime,cnt mov cmdo,#0 mov cmdp,#0 call #cmd or outa,csmask call #sendiohi initloop mov cmdo,#55 call #cmd mov cmdo,#41 call #cmd or outa,csmask cmp accb,#1 wz if_z jmp #initloop wrlong accb,parptr ' reset frqa and the clock finished mov frqa,#0 wrlong frqa,comptr or outa,csmask neg phsb,#1 call #sendiohi pause mov acca,#511 add acca,cnt waitcnt acca,#0 waitloop mov starttime,cnt rdlong acca,comptr wz cmp acca,#"B" wz if_z jmp #byteio mov ctr2,sector cmp acca,#"R" wz if_z jmp #rblock cmp acca,#"W" wz if_nz jmp #pause wblock mov starttime,cnt mov cmdo,#24 rdlong cmdp,parptr2 call #cmd mov phsb,#$fe call #sendio rdlong accb,parptr neg frqa,#1 wbyte rdbyte phsb,accb shl phsb,#23 add accb,#1 mov ctr,#8 wbit mov phsa,#8 shl phsb,#1 djnz ctr,#wbit djnz ctr2,#wbyte neg phsb,#1 call #sendiohi call #sendiohi call #readresp and accb,#$1f sub accb,#5 wrlong accb,parptr call #busy jmp #finished rblock mov starttime,cnt mov cmdo,#17 rdlong cmdp,parptr2 call #cmd call #readresp rdlong accb,parptr sub accb,#1 rbyte mov phsa,hifreq mov frqa,freq add accb,#1 test domask,ina wc addx acca,acca test domask,ina wc addx acca,acca test domask,ina wc addx acca,acca test domask,ina wc addx acca,acca test domask,ina wc addx acca,acca test domask,ina wc addx acca,acca test domask,ina wc addx acca,acca mov frqa,#0 test domask,ina wc addx acca,acca wrbyte acca,accb djnz ctr2,#rbyte mov frqa,#0 neg phsb,#1 call #sendiohi call #sendiohi or outa,csmask wrlong ctr2,parptr jmp #finished byteio rdlong phsb,parptr call #sendio wrlong accb,parptr jmp #finished sendio rol phsb,#24 sendiohi mov ctr,#8 neg frqa,#1 mov accb,#0 bit mov phsa,#8 test domask,ina wc addx accb,accb rol phsb,#1 djnz ctr,#bit sendio_ret sendiohi_ret ret checktime mov duration,cnt sub duration,starttime cmp duration,clockfreq wc checktime_ret if_c ret neg duration,#13 wrlong duration,parptr jmp #finished cmd andn outa,csmask neg phsb,#1 call #sendiohi mov phsb,cmdo add phsb,#$40 call #sendio mov phsb,cmdp shl phsb,#9 call #sendiohi call #sendiohi call #sendiohi call #sendiohi mov phsb,#$95 call #sendio readresp neg phsb,#1 call #sendiohi call #checktime cmp accb,#$ff wz if_z jmp #readresp cmd_ret readresp_ret ret busy neg phsb,#1 call #sendiohi call #checktime cmp accb,#$0 wz if_z jmp #busy busy_ret ret di long 0 do long 0 clk long 0 cs long 0 nco long $1000_0000 hifreq long $e0_00_00_00 freq long $20_00_00_00 clockfreq long 80_000_000 onek long 1000 sector long 512 domask res 1 csmask res 1 acca res 1 accb res 1 cmdo res 1 cmdp res 1 comptr res 1 parptr res 1 parptr2 res 1 ctr res 1 ctr2 res 1 starttime res 1 duration res 1 {{ ' 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. }}