EmbeddedRelated.com
Forums

SPI / SD initialization sequence - my way

Started by Peter Jakacki October 16, 2005
I've had a few queries in regards to SD card initialization in SPI
mode. For anyone who is interested I have included a dump of the SPI
activity during an init. There are two examples, the first with a
SANDISK 512M Ultra, and the second with a generic 128M SD.

The SD & FAT code are written in a Forth that I have written for the
LPC2000s. Since this is not everyones cup of tea, I have included a
simple dump of the activity of the SD interface. Comments are as
normal and bytes that are read are prefixed with "r", those that are
writes are prefixed with "w". All bytes are in hex.

Although it is possible to issue a CMD1 following a CMD0, the SANDISK
SD CARD product manual states that ACMD41 should be used. This avoids
confusion with MMC cards but read what SANDISK have to say in section
5.8. Apparently ACMD1 is an illegal command for the thin cards in SPI
mode.

The dummy read at the start of the CMD is just to make sure that the
SD interface is synchronized etc. This is easier than putting dummy
reads at the end of transfers .

One thing that didn't show-up on the 128M cards but did on the 512M
was when I was accessing high memory around 300MBs up. I would find
that the data token response on a read block request was taking a lot
longer. I had to either introduce a delay of 1ms in each loop or
increase the retry counter from 8 to 4000!!! (I am running at 16Mhz
SPI rate).

Hope this is useful.

*Peter*

;*************************** SD CARD INITIALIZATION
************************ ; *** Initialize a Sandisk 512M SD CARD ***

VDD OFF
CS ON
5ms
VDD ON
1ms

; Dummy clocks
CS ON
rFF rFF rFF rFF rFF rFF rFF rFF rFF rFF
CS OFF
wFF wFF

; CS is asserted to ensure that all interfaces lines are at VSS (no
power whatsoever)
CS ON
rFF rFF
CS OFF
5ms

; CMD0
CS ON
rFF w40 w00 w00 w00 w00 w95 rFF r01

; ACMD41 until response = 0
CS ON
rFF w77 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w69 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w77 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w69 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w77 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w69 w00 w00 w00 w00 w95 rFF r00

; Read OCR
CS ON
rFF w7A w00 w00 w00 w00 w95 rFF r00
r80 rFF r80 r00

; Read CID
CS ON
rFF w4A w00 w00 w00 w00 w95 rFF rFF r00
rFE
r03 r53 r44 r53 r44 r35 r31 r32 r57 r50
r3D r11 r89 r00 r51 r5F rFD rA2 rFF

; Read CSD
CS ON
rFF w49 w00 w00 w00 w00 w95 rFF rFF r00
rFE
r00 r26 r00 r32 r1F r59 r83 rC7 rBE rFB
r4F rFF r92 r40 r40 r3F rF9 rAF rFF
CS OFF ; *** Initialize a generic 128M SD CARD ***

VDD OFF

CS ON
5ms
VDD ON
1ms
CS ON
rFF rFF rFF rFF rFF rFF rFF rFF rFF rFF
CS OFF
wFF wFF
CS ON
rFF rFF
CS OFF
5ms

; CMD0
CS ON
rFF w40 w00 w00 w00 w00 w95 rFF r01

; ACMD41
CS ON
rFF w77 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w69 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w77 w00 w00 w00 w00 w95 rFF r01
CS ON
rFF w69 w00 w00 w00 w00 w95 rFF r00

; Read OCR
CS ON
rFF w7A w00 w00 w00 w00 w95 rFF r00
r80 rFF r80 r00

; Read CID
CS ON
rFF w4A w00 w00 w00 w00 w95 rFF r00
rFF rFE
r04 r00 r00 r44 r30 r35 r30 r37 r00 r02
r02 r8E r69 r00 r48 rFB r6E r4B rFF

; Read CSD
CS ON
rFF w49 w00 w00 w00 w00 w95 rFF r00
rFF rFE
r00 r7F r00 r32 r1F r59 r83 rC9 rF6 rDA
r3F r9F r96 r60 r00 r2D r76 rB7 rFF
CS OFF ________
P.S. Resent this message as my SMTP server seems to have a problem.



An Engineer's Guide to the LPC2100 Series

Peter,

been away for a week, but now busy again :)
Your code looks good only I'm not that familiar with Forth.
Can you shortly explane what happens when you do a r.. or w.. ? I
understand that this are the read and write commands, but is it a
function ore something or does it just writes or reads bytes from the
SPDR (data register)?

thanks,

Wouter --- In lpc2000@lpc2..., "Peter Jakacki" <peterjak@t...> wrote:
>
> I've had a few queries in regards to SD card initialization in SPI
> mode. For anyone who is interested I have included a dump of the SPI
> activity during an init. There are two examples, the first with a
> SANDISK 512M Ultra, and the second with a generic 128M SD.
>
> The SD & FAT code are written in a Forth that I have written for the
> LPC2000s. Since this is not everyones cup of tea, I have included a
> simple dump of the activity of the SD interface. Comments are as
> normal and bytes that are read are prefixed with "r", those that are
> writes are prefixed with "w". All bytes are in hex.
>
> Although it is possible to issue a CMD1 following a CMD0, the SANDISK
> SD CARD product manual states that ACMD41 should be used. This avoids
> confusion with MMC cards but read what SANDISK have to say in section
> 5.8. Apparently ACMD1 is an illegal command for the thin cards in SPI
> mode.
>
> The dummy read at the start of the CMD is just to make sure that the
> SD interface is synchronized etc. This is easier than putting dummy
> reads at the end of transfers .
>
> One thing that didn't show-up on the 128M cards but did on the 512M
> was when I was accessing high memory around 300MBs up. I would find
> that the data token response on a read block request was taking a lot
> longer. I had to either introduce a delay of 1ms in each loop or
> increase the retry counter from 8 to 4000!!! (I am running at 16Mhz
> SPI rate).
>
> Hope this is useful.
>
> *Peter*
>
> ;*************************** SD CARD INITIALIZATION
> ************************ > ; *** Initialize a Sandisk 512M SD CARD ***
>
> VDD OFF
> CS ON
> 5ms
> VDD ON
> 1ms
>
> ; Dummy clocks
> CS ON
> rFF rFF rFF rFF rFF rFF rFF rFF rFF rFF
> CS OFF
> wFF wFF
>
> ; CS is asserted to ensure that all interfaces lines are at VSS (no
> power whatsoever)
> CS ON
> rFF rFF
> CS OFF
> 5ms
>
> ; CMD0
> CS ON
> rFF w40 w00 w00 w00 w00 w95 rFF r01
>
> ; ACMD41 until response = 0
> CS ON
> rFF w77 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w69 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w77 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w69 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w77 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w69 w00 w00 w00 w00 w95 rFF r00
>
> ; Read OCR
> CS ON
> rFF w7A w00 w00 w00 w00 w95 rFF r00
> r80 rFF r80 r00
>
> ; Read CID
> CS ON
> rFF w4A w00 w00 w00 w00 w95 rFF rFF r00
> rFE
> r03 r53 r44 r53 r44 r35 r31 r32 r57 r50
> r3D r11 r89 r00 r51 r5F rFD rA2 rFF
>
> ; Read CSD
> CS ON
> rFF w49 w00 w00 w00 w00 w95 rFF rFF r00
> rFE
> r00 r26 r00 r32 r1F r59 r83 rC7 rBE rFB
> r4F rFF r92 r40 r40 r3F rF9 rAF rFF
> CS OFF > ; *** Initialize a generic 128M SD CARD ***
>
> VDD OFF
>
> CS ON
> 5ms
> VDD ON
> 1ms
> CS ON
> rFF rFF rFF rFF rFF rFF rFF rFF rFF rFF
> CS OFF
> wFF wFF
> CS ON
> rFF rFF
> CS OFF
> 5ms
>
> ; CMD0
> CS ON
> rFF w40 w00 w00 w00 w00 w95 rFF r01
>
> ; ACMD41
> CS ON
> rFF w77 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w69 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w77 w00 w00 w00 w00 w95 rFF r01
> CS ON
> rFF w69 w00 w00 w00 w00 w95 rFF r00
>
> ; Read OCR
> CS ON
> rFF w7A w00 w00 w00 w00 w95 rFF r00
> r80 rFF r80 r00
>
> ; Read CID
> CS ON
> rFF w4A w00 w00 w00 w00 w95 rFF r00
> rFF rFE
> r04 r00 r00 r44 r30 r35 r30 r37 r00 r02
> r02 r8E r69 r00 r48 rFB r6E r4B rFF
>
> ; Read CSD
> CS ON
> rFF w49 w00 w00 w00 w00 w95 rFF r00
> rFF rFE
> r00 r7F r00 r32 r1F r59 r83 rC9 rF6 rDA
> r3F r9F r96 r60 r00 r2D r76 rB7 rFF
> CS OFF > ________
> P.S. Resent this message as my SMTP server seems to have a problem.
>



hi Wouter,

That listing is not Forth, just a formatted diagnostic I quickly wrote
so you can see the traffic. Of course bytes are bytes so it helps to
know if we are reading or writing them, that's all.

The actual code snippets are;

: CMD ( data cmd -- res )
ON SDCS \ assert SD CS (in case it
isn't yet asserted)
SD@ DROP \ dummy read - discard result
3Fh AND 40h OR SD! \ encode cmd and send (leaves
data to send on stack)
DUP 18h SHR SD! \ send msb of data
DUP 10h SHR SD! \ next byte
DUP 8 SHR SD! \ next byte
SD! \ send last byte (SD! only
uses byte)
95h SD! \ dummy checksum (to suit CMD0)
RES@ \ read the result onto the
data stack
;

: InitSdCard ( -- ocr | false ) \ Initialize SD CARD and return
with ocr or false
OFF SDPWR \ turn off SD CARD POWER
(including pulling I/O to VSS)
5 ms \ 5ms delay
ON SDPWR \ turn on power
5 ms \ 5ms delay
200 0 TIMER ! \ 200ms timeout for fault handling
BEGIN ?TIMEOUT 0 0 CMD 1 = UNTIL \ begin sending CMD0(0) until res=1
BEGIN ?TIMEOUT 0 41 ACMD 0= UNTIL \ begin sending ACMD41(0) until
res = 0
BEGIN 0 58 CMD 0= UNTIL \ card may be busy - keep
trying for CMD58(0)
SD4@ \ read 4 bytes of the ocr and
leave on data stack as 1 word
GETCID GETCSD \ read CID and CSD as well
(handled by these definitions)
OFF SDCS \ turn off chip select
; *Peter* armqamp wrote:

>Peter,
>
>been away for a week, but now busy again :)
>Your code looks good only I'm not that familiar with Forth.
>Can you shortly explane what happens when you do a r.. or w.. ? I
>understand that this are the read and write commands, but is it a
>function ore something or does it just writes or reads bytes from the
>SPDR (data register)?
>




&^%)(*$#%# wordwrapping ^&%##$(*!

hi Wouter,

That listing is not Forth, just a formatted diagnostic I quickly wrote
so you can see the traffic. Of course bytes are bytes so it helps to
know if we are reading or writing them, that's all.

The actual code snippets are; : CMD ( data cmd -- res )
ON SDCS \ assert SD CS (in case it isn't yet asserted)
SD@ DROP \ dummy read - discard result
3Fh AND 40h OR SD! \ encode cmd and send (cmd used from stack)
DUP 18h SHR SD! \ send msb of data
DUP 10h SHR SD! \ next byte
DUP 8 SHR SD! \ next byte
SD! \ send last byte (SD! only uses byte)
95h SD! \ dummy checksum (to suit CMD0)
RES@ \ read the result onto the data stack
;

\ Initialize SD CARD and return with ocr or false
\
: InitSdCard ( -- ocr | false )
OFF SDPWR \ turn off SD CARD POWER (I/O to VSS)
5 ms \ 5ms delay
ON SDPWR \ turn on power
5 ms \ 5ms delay
200 0 TIMER ! \ 200ms timeout for fault handling
\ begin sending CMD0(0) until res=1
BEGIN ?TIMEOUT 0 0 CMD 1 = UNTIL
\ begin sending ACMD41(0) until res = 0
BEGIN ?TIMEOUT 0 41 ACMD 0= UNTIL
\ card may be busy - keep trying for CMD58(0)
BEGIN 0 58 CMD 0= UNTIL
SD4@ \ read 4 bytes of the ocr onto data stack
GETCID GETCSD \ read CID and CSD as well
OFF SDCS \ turn off chip select
; *Peter* armqamp wrote:

>Peter,
>
>been away for a week, but now busy again :)
>Your code looks good only I'm not that familiar with Forth.
>Can you shortly explane what happens when you do a r.. or w.. ? I
>understand that this are the read and write commands, but is it a
>function ore something or does it just writes or reads bytes from the
>SPDR (data register)?
>