• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » Interfacing SD_CARD with MSP430G2231
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • Interfacing SD_CARD with MSP430G2231

    Interfacing SD_CARD with MSP430G2231

    This question is answered
    MaxE
    Posted by MaxE
    on Aug 09 2012 06:52 AM
    Intellectual385 points

    Hi,

    at the moment I am trying to interface a SD Card with the MSP430G2231.

    Therefore I´m using the MMC library functions provided by TI.

    Now the problem is after sending the Go_Idle command to the SD Card it always responses

    with a TIMEOUT_ERROR and I really can´t imagine why.

    Maybe a bit more precise explanation :

    First I raise Chip select and send some dummy bytes to the sd card for about 80 clock cycles.

    Then I pull CS low and send the Go_Idle command to the sd. Afterwards I try to read the response of the

    sd card and that´s where it answers with the timeout error.

    The voltage levels are perfectly correct ( I just measured it).

    But I don´t know if the MSP430 clocks properly (can´t measure it because I have no scope).

    So here´s my port initialization :

     WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer

              P1OUT =  0x10;                        // P1.4 set, else reset
              P1DIR = 0x01;                         // P1.0 output, else input
              P1DIR |= SD_CS;                           // Set P1.4 to output direction Chip Select
              P1DIR |= SPI_SCLK;                        // Set P1.5 to output direction Master Clock
              P1DIR |= SPI_SDO;                         // Set P1.6 to output direction Data Output
             

              USICTL0 |= USIPE7 +  USIPE6 + USIPE5 + USIMST + USIOE; // Port, SPI master
              USICKCTL = USIDIV_4 + USISSEL_2 + USICKPL;      // /16 SMCLK
              USICTL0 &= ~USISWRST;                 // USI released for operation
              USISRL = 0x00;


              for (i = 0xFFF; i > 0; i--);          // Time for slave to ready
              USICNT = 1;                           // init-load counter

    Hope somebody could help me.

    Regards, Max

    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Aug 09 2012 11:23 AM
      Guru140435 points

      MaxE
                for (i = 0xFFF; i > 0; i--);          // Time for slave to ready
                USICNT = 1;                           // init-load counter

      This sets the USI to send one bit with SMCLK/16. However, the loop itself is faster than 16 MCLK (and therefore most likely SMCLK too) cycles.

      So you program the USI for another bit before it has sent the first bit, probably resettign the baudrate divider and nothing is ever sent. Jsu ta guess.

      You should do

      for(i=10;i>0;i--){ // send 80 bits
       USICNT = 8; // clears USIIFG, as long as USIIFGCC is clear
       while(USICTL1& USIIFG); // wait for 8 bits sent
      }

      Also, it might be necessary to set USICKPL. IIRC I had to do it on the USCI module (MSP430F1611) for SD card access for correct clock polarity (clock is inactive high and active low)

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • MaxE
      Posted by MaxE
      on Aug 10 2012 04:38 AM
      Intellectual385 points

      Hi Jens,

      I tried to get it run with the for loop you suggested but it didn´t work anyway. So what should the USICKPL look like ??

      It is set in this line :

      USICKCTL = USISSEL_2 + USICKPL +USIDIV_4;   

      should I set it up like this :

      USICKPL.IIRC

      And in my main function there´s this while loop :

                while(status!=0){

                    status = SD_Init();
                    timeout++;
                    if(timeout==150){

                        break;
                     }

                }
      the SD_Init() returns the Init_Error all the time.

      It looks like this :

      // Initialize SD card
      unsigned short SD_Init(void)
      {
        //raise CS and MOSI for 80 clock cycles
        //SendByte(0xff) 10 times with CS high
        //RAISE CS
        int i;

        //initialization sequence on PowerUp
        CS_HIGH();
        for(i=0;i<=9;i++)
          spiSendByte(DUMMY_CHAR);

        return (SD_GoIdle());
      }

      So the SD_GoIdle returns the Timeout_Error.

      // set SD in Idle mode
      unsigned short SD_GoIdle()
      {
        unsigned short response=0x01;
        CS_LOW();

        //Send Command 0 to put SD in SPI mode
        SDSendCmd(SD_GOIDLE,0,0x95);
        //Now wait for READY RESPONSE
        if(SDGetResponse()!=0x01)
          return SD_INIT_ERROR;

        while(response==0x01)
        {
          CS_HIGH();
          spiSendByte(DUMMY_CHAR);
          CS_LOW();
          SDSendCmd(SD_SEND_OP_COND,0x00,0xff);
          response=SDGetResponse();
        }
        CS_HIGH();
        spiSendByte(DUMMY_CHAR);
        return (SD_SUCCESS);
      }

      It always happens after sending the SD_GOIDLE command. The following SDGetResponse

      returns the Timeout_Error.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Aug 10 2012 09:16 AM
      Guru140435 points

      MaxE
      USICKCTL = USISSEL_2 + USICKPL +USIDIV_4;   

      Should do. IIRC, the clock mus tbe low-active, so CKPL needs to be set.

      MaxE
      the SD_Init() returns the Init_Error all the time.

      Sure? How do you know? You don't check for status in this loop.

      What library do you use? I only know the MMC libary (slaa281b), which more or less also applies to CD cards.

      However, a general quesiton: what size is your SD card? Newer cards, usually SDHC/SDXC cards, Especially those which claim to be 'high speed' do not implement the serial/SPI protocol anymore.
      Cards above 4GB (or sometimes even 2GB types), require a larger blocksize than the original 512 bytes and have a completely different configuration structure. Along with changing the internal organization, most manufacturers have also dropped the serial support.

      That SD_GOIDLE returns a timeout may indicate that your card doesn't support serial mode at all.

      Of course there's still a chance of a hardware problem. Does the card support the MSPs supply voltage? If they have separate supplies, what about the logic levels?

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Mark Green
      Posted by Mark Green
      on Aug 10 2012 09:35 AM
      Intellectual640 points

      I'm not sure what the TI libraries do. But the following info might help.

      SPI mode in an SD card can only be engaged after a power cycle.

      Pin 1 (CS) must be held low as the power comes up or you will go into API mode.

      I had problems engaging a few SD cards and it turned out that although I thought I was power cycling SD card (SD Vcc On then Off) I was still driving some of the IO lines on the SD card so it didn't always see a true power cycle, and consequently stayed in API mode.

      I've got some SD-SPI code I could post but is written for a Freescale S08.....

      (cue boo's and hisses)  

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • MaxE
      Posted by MaxE
      on Aug 10 2012 09:53 AM
      Intellectual385 points

      When I´m debugging the code I can check the variable for the error code and it´s always the

      timeout error.

      Thw library I am using is the slaa281b.

      I´m using a Sandisk 1GB MicroSD card. So I think the 512 bytes blocksize is ok.

      It needs 2.7 V up to 3.6 V supply voltage and I´m driving it

      with the 3.6 V provided by the MSP430 Launch Pad.

      Is it possible that it doesn´t work with this card ??

      Does anybody know a card that surely works ??

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Mark Green
      Posted by Mark Green
      on Aug 10 2012 10:05 AM
      Intellectual640 points

      @Jens : SPI mode should be fine on SDHC and SDXC. RE block size it was fixed at 512 bytes in SDHC and SDXC. SDSC can also use 512 bytes, but optionally less if the mfg supported it.

      @MaxE: In my experience if anything is going to work a SANDISK will.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Aug 10 2012 10:18 AM
      Guru140435 points

      Mark Green
      Pin 1 (CS) must be held low as the power comes up or you will go into API mode.

      Sure about this? I just checked my code and no, when inserting the card, CS is high. And so it is if the card is inserted and power is applied to both, MSP and card (well, of course the signal is in high-impedance state at first, before the MSP port pin switches to high output).
      It still works perfectly, whether I insert the card while the MSP is powered and CS is high, or whether I switch the power on with the card inserted.

      My code works with MMC, SD (up to 2GB) and microSD cards (which behave a bit different than normal SD cards in that they don't accept CMD1 whereas normal MMC cards do accept CMD1 and ACMD41 and MMC cards of course won't accept ACMD41). So I don't think it is necessary to have CS low on power-up. Or I was just lucky getting only cards that didn't require it :)

      I just took a look into the SD card specs V1.01 and it reads:

      "The SD Memory Card wakes up in the SD mode. It will enter SPI mode if the CS signal is asserted (negative) during the reception of the reset command (CMD0) and the card is in idle_state"

      So it always enters SD mode (the parallel mode, which I think is what you call API mode) on power-up and the state of CS determines whether it goes into SPI mode or not.
      Independently of mode, commands are always transmitted serially, only data transfers are done parallel.
      Of course there might have been an update to the standard since I wrote my code a few years ago. (Well, there definitely was, for SDHC and SDXC), but I don't have the newer specs.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Aug 10 2012 10:40 AM
      Guru140435 points

      Mark Green
      SPI mode should be fine on SDHC and SDXC.

      I got a couple of SDHC cards that refused to run in SPI mode. But maybe this was because these cards will indeed require CS low on power-up (which tehy never got from my hardware).
      About the 512 bytes, well, it is impossible to express a card size >1GB with the original, MMC-card compatible CSD structure and 512 bytes block size.

      C_SIZE_MULT is 512 max, and C_SIZE is 4095 max, which gives a factor of 2097152*READ_BL_LEN. 1GB for 512 byte read block length. And since READ_BL_LEN is 2048 max, 4GB is the maximum size that can be expressed at all - with 2k block size then. Also, the data read command only has a 32 bit address (which isn't a block address but a byte address).

      For anything above, the CSD needed to be changed, which is then no longer compatible to SD cards with the older CSD or MMC cards. And I noticed that manufacturers seemed to drop SPI mode at all for those cards, as those cards didn't respond at all. So I turned them down. 1GB was more than enough for all projects so far.
      Maybe it's time to think about a code extension. :) Do you have a link for the newest specs?

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Mark Green
      Posted by Mark Green
      on Aug 10 2012 11:43 AM
      Intellectual640 points

      Jens-Michael Gross
      Sure about this?

      Obviously not... Just pulled up some of my old screen shots from the setup on this and your right, my CS is not held low from the get go. It goes low just before the first CMD. But the screen shot did remind me of what my original problem was. 

      The problem I had was the following:

      - I would plug an SD card in and sometimes it would enter SPI mode, sometimes it wouldn't.

      - Power cycle of the SD card rail would not cure the problem. (i.e. if it didn;t respond the first time, it wouldn't respond after a rail cycle.)

      - But if the whole board was powered down then brought back up again it might work.

      I think the problem was that if an SD card was plugged in while the socket was live then this would sometimes be interpreted as a false command by the SD card. Stopping entry into SPI mode (since this must be the first command after a power cycle). Subesequent rail cycles were not working because although the rail was dropped, the SPI lines were kept up (so keeping the SD card alive) .

      The cure was to drop all interface lines to 0V. Then the rail to 0V. Then bring the rail back up followed by the interface lines.

      It doesn't matter if CS is brought up at this point so long as it goes back down before the first command as Jens rightly points out.

      So to finish the sequence I found to be quite reliable was:

      - All lines low, and SD rail low

      - SD rail up

      - SPI on, (CS can go up as well)

      -  Send lots of 0xFF over the SPI (~80+clocks should do)

      - CS low

      - CMD0 (0x40) and off you go.....

        

      Apologies for the CS low on powerup curveball.... 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Mark Green
      Posted by Mark Green
      on Aug 10 2012 11:49 AM
      Intellectual640 points

      I should point out by off you go I mean carry on with the config, not your ready for data transfer.

      See p114 in the spec for more on the config command sequence:

      https://www.sdcard.org/downloads/pls/

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Mark Green
      Posted by Mark Green
      on Aug 10 2012 12:03 PM
      Intellectual640 points

      Jens-Michael Gross
      I got a couple of SDHC cards that refused to run in SPI mode. But maybe this was because these cards will indeed require CS low on power-up

      Nope not due to the CS that my false info.

       

      Jens-Michael Gross
      C_SIZE_MULT is 512 max, and C_SIZE is 4095 max, which
      .... 

      Page 125 of the spec explains this. But briefly:

      Block size is fixed at 512 bytes for SDHC and SDXC. i.e. CMD16 (SET_BLOCKLEN) no longer does anything.

      With blocks fixed at 512 bytes in HC/XC this gave them a bit of flexibility on the read commands (CMD17, CMD18). For these cards  the 32bit address field is no longer a byte address it is a block address. 512 bytes * 2^32 = 2048 GB (if my maths is correct...)

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • MaxE
      Posted by MaxE
      on Aug 11 2012 04:00 AM
      Intellectual385 points

      So to point this out very clearly.

      How should I do the init.

      This is my code :

                unsigned short status=1;
                unsigned int timeout=0;

                // SPI_Setup

                volatile unsigned int i;

                WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer

                P1OUT =  0x10;                        // P1.4 set, else reset
                P1DIR = 0x01;                         // P1.0 output, else input
                P1DIR |= SD_CS;                           // Set P1.4 to output direction Chip Select
                P1DIR |= SPI_SCLK;                        // Set P1.5 to output direction Master Clock
                P1DIR |= SPI_SDO;                         // Set P1.6 to output direction Data Output

                USICTL0 |= USIPE7 +  USIPE6 + USIPE5 + USIMST + USIOE + USISWRST; // Port, SPI master
                USICKCTL = USISSEL_2 + USICKPL +USIDIV_4;      // /16 SMCLK
                USICTL0 &= ~USISWRST;                 // USI released for operation

                USISRL = 0x00;
                USICNT = 1;

                for(i=10;i>0;i--){ // send 80 bits
                 USICNT = 8; // clears USIIFG, as long as USIIFGCC is clear
                 while(USICTL1& USIIFG); // wait for 8 bits sent
                }

                while(status!=0){

                    status = SD_Init();
                    timeout++;
                    if(timeout==150){

                        break;
                     }

                }

      You can read the SD_Init code  a few posts above.

      Could it work like this ??

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Mark Green
      Posted by Mark Green
      on Aug 12 2012 16:16 PM
      Intellectual640 points

      Hi Max,

      You are using CMD1 to initialise an SD card. Not all SD cards support the MMC method of initialisation, and it is not recommended even if they do. 

      If its an SD card you should be using CMD0 >> CMD8 >> ACMD41.

      I'll post a step through of the ACMD process on Monday.... If you can't wait download the physical spec (link above) then read section 7 SPI.

      @Jean: If you were doing the same, then this is why your SDHC cards were not responding. SPI mode for these cards will not proceed without going down the correct route.

      Mark.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Jens-Michael Gross
      Posted by Jens-Michael Gross
      on Aug 13 2012 05:29 AM
      Guru140435 points

      Mark Green
      If you were doing the same, then this is why your SDHC cards were not responding. SPI mode for these cards will not proceed without going down the correct route.

      No, my init sequence is

      - wait for CARD_DETECT signal
      - init SPI
      - 80 clock pulses
      - GO_IDLE_STATE
      - no response? go back to init SPI
      - MMC_APP_CMD
      - response == 4: try GO_IDLE_STATE/MMC_SEND_OP_COND istead (MMC)
      - response == 1: retry MMC_APP_CMD
      - response == 2: MMC_READ_CSD
      - check for valid (supported) card geometry.
      - done

      Well, the last step needs ot be expanded, as well as the address field in the data read/write functions.

      Mark Green
      Not all SD cards support the MMC method of initialisation, and it is not recommended even if they do. 

      MicroSD cards do not support MMC_SEND_OP_COND anymore. Mini and normal SD cards do, at least the pre-SDHC ones.
      This way you can (in theory, as it would require double-init) tell micro-SD from the others.

      _____________________________________
      Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.
      If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • MaxE
      Posted by MaxE
      on Aug 13 2012 05:53 AM
      Intellectual385 points

      The initialization seems to work now at least the card responds with a 0x00 which

      means success.

      I just modified the SDGetResponse() function a bit

      here`s the code :

      // SD Get Response
      unsigned short SDGetResponse(void)
      {
        //Response comes 1-8bytes after command
        //the first bit will be a 0
        //followed by an error code
        //data will be 0xff until response
        int i=0;

        unsigned short response;

        while(i<=64)
        {
          //response=spiSendByte(DUMMY_CHAR);

                response=SPIRXBUF;
          if(response==0x00)break;
          if(response==0x01)break;
          i++;
        }
        return response;
      }

      Sending the DUMMY_CHAR seems to cause trouble. Though when I write

      response=SPIRXBUF;

      it works (not every time but at least 90 % of the tries).

      But now there´s another problem which I will mention in another thread.

      It´s about malloc. The debugger says there´s no source for malloc.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    123
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use