2
\$\begingroup\$

EDIT 1 : I made changes to the code as @Anonymous suggested in the answer. It seems to have improved but now I seems to be getting incorrect response OR SD CARD putting response at the wrong time.

The logic data file after making changes as Anonymous suggested in the answer


I am trying to bitbang SPI interface for the sd card. I was at first confused regarding the mode to be used. so I asked regarding the SPI Mode over here.

I am initializing my CLK as Output with internal pull up and driving low. Same goes for the MOSI. while MISO is Input , Pull up and nothing driving that.

Here is my SPI Send and Recieve.

int spi_bb_send(spi_bb_config_t *spi_conf,unsigned char data)
{
  int i;
  uint8_t data_in = 0;

  // send bits 7..0
  for (i = 0; i < 8; i++)
  {
      spi_pin_clear(&(spi_conf->clk));

      // consider leftmost bit
      // set line high if bit is 1, low if bit is 0
      if (data & (1<<7))
          spi_pin_set(&(spi_conf->mosi));
      else
          spi_pin_clear(&(spi_conf->mosi));

       data_in <<= 1;
      data_in |= gpio_read(&(spi_conf->miso));

      Delay(SPI_TIME_IN_US(SPI_FREQ_KHZ));

      // pulse clock to indicate that bit value should be read
      spi_pin_set(&(spi_conf->clk));
      Delay(SPI_TIME_IN_US(SPI_FREQ_KHZ));

      //read the miso
      //data_in |= gpio_read(&(spi_conf->miso));

      // shift byte left so next bit will be leftmost
      data <<= 1;       
  }

  Delay(SPI_TIME_IN_US(SPI_FREQ_KHZ));
  spi_pin_clear(&(spi_conf->clk));

  return data_in;
}

int spi_bb_recieve(spi_bb_config_t *spi_conf)
{
    return(spi_bb_send(spi_conf,0xFF));
}

The initialization command have been tried as per Physical Layer document provided by SD ORD i.e following this initialization flow. initialization flow

As well as the initialization flow I found from this Answer regarding initialization flow.

The issue I am facing is I am getting the command and response for the 1st two commands correctly that is CMD0 and CMD8 and I am not facing any issue no matter how many times I try. When I send the third command i.e :

1) CMD58 as per the SD Org document , I dont get any response back. 2) CMD55 as per the person's answer on this SE, I seem to get correct response but the reponse I read get's an 0xF before the reponse so I believe that SD Card starts reponding from halfway of the clock generated. So I hooked up logic analyzer to it and here are the results.

Command 55 : Command 55

No Response on the first clock : No Response

Response : Response

There is some insights given on the link to answer pasted above that say :

Note that responses that have the MSB set but ain't 0xFF usually suggest that your SPI got a shift in clocking (as a result of e.g. Vcc drop, which happens routinely when you're doing SD hotplugs). To fix it, you can try to completely reset the device (power on/off, deassert/assert S̲S̲ etc.); it usually works.

But I am not doing any hotplug and neither resetting / power cycling works, So can anyone help? Please?

\$\endgroup\$
1
\$\begingroup\$

Your diagrams show chip select as always active. I do not say that it would not work this way, but deactivating CS, in most of the cases, signals card that host is finished with the command.

The I have the following suggestion for you - change the way you access the card:

  1. when powered on, you must clock CLK for some time (70 times or something like this) to enable card to initialize and synchronize;
  2. when you want to access the card, you have CS as high (inactive), and perform 8 spare clock cycles to the card. MOSI stays high;
  3. then you get CS low, and perform another 8 spare clock pulses with MOSI being high;
  4. starting next clock cycle you shift command into the sd-card. After command is shifted in, you wait for response as instructed in the documentation;
  5. after you have got required response, you do NOT deactivate CS, and perform 8 spare clocks with MOSI high;
  6. then you deactivate CS, and perform another 8 spare clocks with CS high and MOSI high.
  7. and then you are ready for next access.
\$\endgroup\$
  • \$\begingroup\$ Point 1 with CS deasserted? I assert CS , then delay of 50 us, deassert CS and then I generate 80 Clocks. Is that fine? \$\endgroup\$ – MaNyYaCk Oct 12 '18 at 9:04
  • \$\begingroup\$ I adapted the code as per the points you made, Solved the issue for that command. But now I am getting 3F for CMD0. I am attaching the logicdata file in the question. \$\endgroup\$ – MaNyYaCk Oct 12 '18 at 9:15
  • \$\begingroup\$ I noticed that for all the commands MISO stays high when receiving the command and then goes low. But for the first command it stays low only. Could the issue be there? \$\endgroup\$ – MaNyYaCk Oct 12 '18 at 9:33
  • \$\begingroup\$ In my implementation after power on or card insertion I set CS low and clock it low speed with MOSI high for about 600 ms (if I am reading my code properly :). It is a lot of time, but there were no reports on any card initialization issues. \$\endgroup\$ – Anonymous Oct 12 '18 at 10:01
  • 1
    \$\begingroup\$ Thanks for the help, that was the noise on the line that looked like clock pulse to sd card . \$\endgroup\$ – MaNyYaCk Oct 24 '18 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.