• AVR Freaks

SD Card SPI Operation

Author
Tech644
New Member
  • Total Posts : 11
  • Reward points : 0
  • Joined: 2008/11/16 15:39:38
  • Location: 0
  • Status: offline
2009/06/14 15:32:29 (permalink)
0

SD Card SPI Operation


I am attempting to interface a Sandisk SD memory card to a PIC16LF819 via the SPI interface. I am running at 3.3V with a clock frequency of 125 Khz. I am programming in assembly language since I do not require a high level language for this relatively simple application. Nor do I require storing data using the FAT format. I have searched this forum and also the PIC18F and PIC24F forums for information and have downloaded the Simplified Physical Layer SD specification and the Sandisk Product Manual. I have also followed all the links provided from forum postings. I have not been able to identify the clock polarity or edge setting so I have set the initialization of the MCU as follows: SPI master mode, SMP = 1, CKE=1, CKP=1. (I have also tried every other combination of these bits). I then programmed the following sequence:

1. Set CS high.
2. Send 80 clock pulses to card.
3. Send the following command to card. 0x40, 0x00, 0x00, 0x00, 0x00, 0x95.
4. Send the following initialization command. 0x41, 0x00, 0x00, 0x00, 0x00, 0x01.
5. Send 0xFF until response from card is read.
6. Loop until response indicates initialization is complete, (D0=0).

I am monitoring the card SO pin on an oscilloscope. Unfortunately, it never comes out of idle. D0 is always 1. I have tried two different cards in case one was defective.



Where have I gone wrong?
#1

10 Replies Related Threads

    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11251
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    RE: SD Card SPI Operation 2009/06/14 16:12:39 (permalink)
    0
    Are you asserting CS before step 3? Are you waiting for an R1 idle response after step 3?
    #2
    eddygo
    Super Member
    • Total Posts : 691
    • Reward points : 0
    • Joined: 2004/03/04 15:45:37
    • Location: Bucharest, ROMANIA
    • Status: offline
    RE: SD Card SPI Operation 2009/06/14 16:57:21 (permalink)
    0
    Please use search feature of this forum, there are dozens of questions like yours.
    Few notes:
     
    1. Use several manuals for understanding SD, there are specs ver. 1.9, 2.0, 2.2 covering latest SDHC, SDIO etc. Also check other manufacturers specs like Toshiba, Samsung, etc.
     
    2. SPI bus working "modes" doesn't represent exact CKE, CKP bit status, don't be confused. Aka. mode 00 means CKP=0 and CKE=1. It's just a convention. I use mode 00 and works fine.
     
    3. SCL can be up to 500KHz in init mode. I use 625KHz for all my SD/SDHC and works perfect. Aka. you don't need extra timer for MSSP module when MCU speed is up to ~40MHz.
     
    4. You must follow exact init sequence required by your card type (MMC/SD/SDHC/SDIO etc) and there are quite differences. Seems you use SD, so for init may work old CMD1 like you tried but more adequate is recommended ACMD41.
     
    5. Every command requires some extra SCL pulses before/after (padding) called NCR, NWR (check datasheets). I always use one 0xFF before and one after.
     
    I am monitoring the card SO pin on an oscilloscope. Unfortunately, it never comes out of idle. D0 is always 1. I have tried two different cards in case one was defective.

     
    This means assuming your hw is ok, that card remain in standby. Check with scope if mcu is actually outputting. Send minimum 80 SCL with CS=HI (I use 20 x 0xFF so 160 pulses) then from now on, every time you want to communicate with card you must select’ it so make:
     
    - CS->hi
    - send 80...100 SCL pulses
    - CS->lo // select the card
    - send NCR
    - send CMD0 with correct CRC // that's yours step 3
    - send NCR // can be included in send_cmd routine so will be transparent to you
    - expect reply from your SD. It's important to expect that certain reply from card, because it's not mandatory to appears immediately after your last NCR. For CMD0 for eg. reply should be 0x01 (card idle) but memory can reply after few 0xFF. It's a very good idea when sending some CMD to card, watch on USART next 10...100 bytes requested, even they are more than expected. You'll understand then card reply, timeouts, NCR implied, etc.
    - finally, deselect your card CS->hi
     
    Edi,  

    ENEA, OSECK
    http://www.enea.com
    #3
    P Lameijn
    Super Member
    • Total Posts : 1967
    • Reward points : 0
    • Joined: 2004/01/22 18:30:23
    • Location: The Netherlands
    • Status: offline
    RE: SD Card SPI Operation 2009/06/14 17:05:13 (permalink)
    0
    Make sure it's a SD card, and not a SDHC card, because those are different in addressing.

    Regards,
    Peter
    #4
    demonicpicguy
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2007/07/29 06:03:11
    • Location: 0
    • Status: offline
    RE: SD Card SPI Operation 2009/06/14 17:08:03 (permalink)
    0
     
     
    the sequence i use is this
     
    1, make cs high
    2, send 10 bytes of (11111111)
    3, make cs low
    4, issue command 40h,0h,0h,0h,0h,95h
    -make sure your sipout pin is high and stays that way whenever you read a byteout
    5,read 1 bummy byte
    6, read your r1  response byte if your  r1 response byte is not 1 then reissue command
    7, when you have the r1 response 1
    8, read another dummy byte
    9, make cs high
    10, delay up to 10ms again
    make cs low
    11, issue the command 41
    12, the response should be 0 don't forget there is a 1 byte spacing between the last byte of the command and the r1 response, if you don't get the rs response 0 re issue the command after reading out another dummy byte
    when you get the response 0 make cs high again and you should be good to read and write
     
     
     
     
     
     
     
    #5
    saipan59
    Super Member
    • Total Posts : 191
    • Reward points : 0
    • Joined: 2006/06/19 11:27:36
    • Location: 0
    • Status: offline
    RE: SD Card SPI Operation 2009/06/15 07:40:03 (permalink)
    0
    I am programming in assembly language since I do not require a high level language for this relatively simple application.

    I would suggest to simplify your life and use a C compiler, such as the free version of PICC. Unless you are Very Good at assembly on the PIC16 platform, you may be introducing problems that you don't know about.
     
    Instead of saying "do not require a high level language", I would say "do not require the extreme low-level control of assembly". The latter statement applies to nearly every single real-world application that we can imagine.
     
    Pete
     
    #6
    Tech644
    New Member
    • Total Posts : 11
    • Reward points : 0
    • Joined: 2008/11/16 15:39:38
    • Location: 0
    • Status: offline
    RE: SD Card SPI Operation 2009/06/16 14:47:49 (permalink)
    0
    Thanks to all for your responses. I have read them all very carefully and have incorporated some of your suggestions. First of all, let me clarify what I originally posted.
     
    1) I did in fact set CS low before step three and received the r1 response after. The response came after two bytes of 0xFF were sent.
    2) I am using an SD card, not an SDHC.
    3) I increased the number of clock pulses in step 2 from 80 to 160. 
    4) I have experimented with various settings for SMP, CKE, and CKP. I settled on SMP=1, CKE=0, CKP=0. This was based on the SD card spec timing diagram. IF I set CKE=1 the card output was in the three state mode and would return nothing.
     
    As I indicated, I have read everything I could find in the forum postings and have followed the links suggested. One of the links provided a logic analyzer screen shot of the timing signals.These compare well to what I am seeing on my oscilloscope, (I don't have a logic analyzer), except my card response always indicates idle state.
     
    Question for demonicpicguy: In your step 11 you send command 41. I am assuming you are preceding this with command 55, correct? According to the card spec an SD card should respond to either a command 1 or command 41 for initialization. I tried both command 1 and the command 55/command 41 sequence but it still won't come out of idle. Another question: According to one of the links I followed, once CS is set low, it can be kept there for all subsequent commands yet other sources say to set it high at the end of each command and low again before the next command. What is your experience? I tried it both ways and saw no difference.
     
    At this point I have still not achieved success but haven't given up yet.
    #7
    eddygo
    Super Member
    • Total Posts : 691
    • Reward points : 0
    • Joined: 2004/03/04 15:45:37
    • Location: Bucharest, ROMANIA
    • Status: offline
    RE: SD Card SPI Operation 2009/06/16 15:21:53 (permalink)
    0
    Tech644

    I think you don't understand init process quite well, maybe you have other problems in your sw/hw. Check attached flowchart by Toshiba. If you see that 0x01 on CMD0 then you are on the right way. I use asm too and my drivers works ok. Remark: after each command I deselect card (CS-> HI) + 100uS minimum delay in unselected state and re-select (CS->LOW) when need.
     
    So now you should give init cmd which is ACMD41, a combo command CMD55 followed by CMD41. You must use a large loop especially for unbranded cards like this
     
    MAIN_INIT_LOOP
     
    - CS -> LO
    - send NCR 0xFF
    - send CMD55 with arg=0 and no CRC(0xFF) which is (55dec+64dec=119dec or 0x77) :
    0x77 0x00 0x00 0x00 0x00 0xFF
    - send NCR 0xFF
    - card should reply with 0x01 (idle) or 0x00 (ready) but you must expect those results after 0...x of 0xFF
      - if other reply here you should return with fail
      - if 0x00 return with success, card is ready
      - if 0x01 card is idle continue
     
    - CS -> HI
    - small delay, max. 100uS
    - CS -> LO
    - send NCR 0xFF
    - send CMD41 with arg 0 and no CRC (0xFF) to complete ACMD41 which is
    0x69 0x00 0x00 0x00 0x00 0xFF
    - send NCR 0xFF
    - card should reply with 0x01 (idle) or 0x00 (ready), again, expect those responses
        - if other reply here you should return with fail
        - if 0x00 return with success, card is already ready
        - if 0x01 card is idle
    - CS -> HI
    - small delay, max. 100uS
     
    goto MAIN_INIT_LOOP
     
    Of course, make a finite loop (I use 65536 times) and then declare fail.
    CMD8 is required only by SDHC.
     
    Hope helps,
    Edi
     
     

    Attached Image(s)


    ENEA, OSECK
    http://www.enea.com
    #8
    demonicpicguy
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2007/07/29 06:03:11
    • Location: 0
    • Status: offline
    RE: SD Card SPI Operation 2009/06/16 16:16:34 (permalink)
    0
    all i use if command0 then command41 , and i find it goes into spi very reliably, generally it's better to select and deselect the card for each comand you issue, you'll find some cards won't like the cs line being held low constantly, be prepared for it some cards even though they are supposed to will not go into spi mode no matter what you do, you're best just using standard size sd cards, ie stay away from mini sd and micro sd, they don't all nessarily support the spi mode either,

    the other thing everyone is assueming is that the circuit you have a working ok as well,
    the best circuit i've found for dealing with these sd cards is running the pic at 3.3v and wiring straight to the card
    via a connector for it, also you MUST have a pullup resistor on the DO pin on the card otherwise you'll just get unreliable output from it, i've found even though it's recommended in some schematics pullup resistors don't seem to make a difference to any of the other input lines on the card, i do recomment however a small capacitor close to the card between the 3.3v and gnd as in some cases this can make the world of difference as far as performance goes

    i also don't use the hardware spi side of things either, the code i use that handles the data in and out is bit banged and also consistantly sends the datin line on the card high when reading out bytes
    post edited by demonicpicguy - 2009/06/16 16:26:13
    #9
    pradeepshetty
    New Member
    • Total Posts : 2
    • Reward points : 0
    • Joined: 2013/08/26 09:07:30
    • Location: 0
    • Status: offline
    Re: RE: SD Card SPI Operation 2013/08/26 09:46:13 (permalink)
    0
    Dear Friends,
     
    I am testing MDD filesystem for PIC24EP series which was given by microchip. I am able to write the raw data properly in to SD card using SPI protocol and it is in blocking mode. I am re-writing the SD-SPI interface in non-blocking using OS. I am doing the following steps for writing single sector as shown below.
    1) Send command as shown below
       SD_CS = 0;
       buffer[0] = 0x58
       buffer[1] = 0x00;
       buffer[2] = 0x00;
       buffer[3] = 0x20;
       buffer[4] = 0x00;
       buffer[5] = 0xFF;
      SPI_WriteStart(PORT1, buffer, 6);
    2) Wait for SPI_SUCCESS_SIG, where SPI_SUCCESS_SIG will be posted from Interrupt handler
    3) read r1 response from the media as shown below
      SPI_ReadStart(PORT1, r1.response, 1);
    4) Wait for SPI_SUCCESS_SIG and check for r1.response
        - if(r1.response == 0x00) then issue 8 clock cycles as shown below
              val = 0xff;
              SPI_WriteStart(PORT1, &val, 1);
        - else repeat step 4 for 20 times    
    Note: most of the time I will get r1.response = 0x00;
    5) Write raw data as shown below
         buffer[512] ;
         SPI_WriteStart(PORT1, buffer, 512);
    6) Wait for SPI_SUCCESS_SIG and send CRC as shown below
         buffer[2]={0xff, 0xff};
         SPI_WriteStart(PORT1, buffer, 2);
    7) Wait for SPI_SUCCESS_SIG and read the media as shown below
        char mediaStat;
        SPI_ReadStart(PORT1, &mediaStat, 1);
     
    At the last step i.e step 7 I am always getting either 0x00 or 0xFF. It looks like timing issue. I tried my best to resolve the issue.
     
    Kindly help me to resolve the issue.
     
    Regards
    Ashok
    #10
    Paul Wolstenholme
    Super Member
    • Total Posts : 54
    • Reward points : 0
    • Joined: 2013/05/09 15:50:26
    • Location: New Zealand
    • Status: offline
    Re: SD Card SPI Operation 2013/08/26 16:40:30 (permalink)
    +2 (1)
    1. CS is active LOW.  (I would never name a pin with the wrong sense, but that is how it is.)
    2. CLK transfers data (in and out) on the rising edge.  Data must be stable for a time prior and held stable for a time after the rising edge.
     
    Others have published code for this (and others have published where they went wrong).  You don't need to start from specifications.
    #11
    Jump to:
    © 2019 APG vNext Commercial Version 4.5