title: How to read_single_block from SD card using SPI mode (getting weird behavior as of yet)?
body: <p>When I issue cmd17 with address (0x00000000) to my card from PIC-18F4520 on SPI bus, I get a correct return R1 token from the command issue.  Then, after a few loops checking, I get a 0xFE marker returned from my issuing SPI_Put_Char(0xFF).  Data should then start so I read 512 bytes into my IO_Buffer array.  As I scan the returns, I got many 0x00 bytes.  Oddly, and repeatedly, at about pos 448 in sector 0, some data comes over - a few bytes here and there - then the the final 32 bytes (I can only view 32 at a time on my LCD screen) are all zeroes followed by the 0x55AA marker expected at the end of the boot sector.</p>
  
  <p>The odd thing, is that using disk investigator reveals the SD card has the proper sector zero information - MSDOS message, EB jump code, all sorts of stuff.  My read command gives all that back as zeroes.  I just don't get what's happening.</p>
  
  <p>Other information: I boot with the cmd0, cmd8, cmd58 and OCR reads fine.  Then acmd41 (looping cmd55 followed by APP_SEND_OP_COND).  All seem to respond and give expected marker.  Finally, I even use SEND_CID to get the card information.  that returns MID=3 OID=SD and a verion SD017 followed by other information - seems all to be correct.</p>
  
  <p>I have tried adding pull up and pull down resistors on DOUT from card but doesn't affect any results.</p>
  
  <p>I am desperate for ideas to try to get this card to read correctly.  I have (BTW) tried two other cards.  They give different specific results, but qualitatively the same - initialization, OCR, and CID read all work okay.  Data read gives mostly zeroes followed by some reproducible but sparse bytes, and a 0xAA55 marker!?!</p>
  
  <p>My SanDisk 1GB SD card is running at 3.296 volts which seems stable during card reading.</p>
  
  <p>Here's some code:</p>
  
  <pre><code>    bit MMC_Command(unsigned char cmd, unsigned short AdrH, unsigned short AdrL, unsigned char *response)
  {
      unsigned char response_length;
      unsigned char MMC_Counter_Byte = 255;
      unsigned char current_response;
  
      switch (cmd)
      {
          case MMC_SEND_IF_COND:
          case MMC_READ_OCR:
              response_length = 5;
              break;
          case MMC_SEND_STATUS:
              response_length = 2;
              break;
          default:
              response_length = 1;
      };
  
      DEV_xSELECT = DEV_MMC;
  
      SPI_Put_Char(cmd);
      SPI_Put_Char(AdrH &gt;&gt; 8);
      SPI_Put_Char(AdrH &amp; 0x00FFU);
      SPI_Put_Char(AdrL &gt;&gt; 8);
      SPI_Put_Char(AdrL &amp; 0x00FFU);
      SPI_Put_Char(0x95U); //CRC = 0x95 to get to SPI, then value not important, so always use this for convenience
  
      do
      {
          response[0] = SPI_Put_Char(0xFF);
      } while ((response[0] &amp; 0x80) &amp;&amp; --MMC_Counter_Byte);
      if (!MMC_Counter_Byte)
      {
          //SPI_Put_Char(0xFF); //some say is necessary
          DEV_xSELECT = DEV_NONE;
          return FALSE;
      };
  
      for (current_response = 1; current_response &lt; response_length; current_response++)
      {
          response[current_response] = SPI_Put_Char(0xFF);
      };
  
      SPI_Put_Char(0xFF); //some say is necessary
      DEV_xSELECT = DEV_NONE;
      return TRUE;
  };
  
      unsigned char MMC_Init_SD(void)
  {
      unsigned long MMC_Counter_Word;
      unsigned char response[5];
  
      DEV_xSELECT = DEV_MMC;
  
      for (MMC_Counter_Word = 0; MMC_Counter_Word &lt; 20; MMC_Counter_Word++)
      {
          SPI_Put_Char(0xFFU);
      };
  
      DEV_xSELECT = DEV_NONE;
  
      for (MMC_Counter_Word = 0; MMC_Counter_Word &lt; 10; MMC_Counter_Word++)
      {
          SPI_Put_Char(0xFFU);
      };
  
      MMC_Counter_Word = 255;
      do
      {
          MMC_Command(MMC_GO_IDLE_STATE, 0x0000, 0x0000, response); //cmd0
      } while (--MMC_Counter_Word &amp;&amp; (response[0] != 0x01));
      if (!MMC_Counter_Word) //if counter timed out, error
      {
          return FALSE;
      };
  
      MMC_Command(MMC_SEND_IF_COND, 0x0000, 0x01AA, response); //cmd8
      if (response[0] != 0x05)
      {
          return FALSE; //other card type
      };
  
      MMC_Command(MMC_READ_OCR, 0x0000, 0x0000, response); //cmd58
  
      MMC_Counter_Word = 0xFFFFU;
      do
      {
          if (MMC_Command(MMC_APP_CMD, 0x0000, 0x0000, response)) //cmd55
          {
              MMC_Command(MMC_APP_SEND_OP_COND, 0x4001, 0x0000, response); //acmd41
              SPI_Put_Char(0xFF);
          }
          else
          {
              return FALSE;
          };
      } while (--MMC_Counter_Word &amp;&amp; ((response[0] &amp; 1) == 1));
      if (!MMC_Counter_Word) 
      {
          return FALSE;
      };  
  
      if (MMC_Command(MMC_SEND_CID, 0x0000, 0x0000, response)) //cmd10
      {
          DEV_xSELECT = DEV_MMC;
  
          MMC_Counter_Word = 255;
          while (--MMC_Counter_Word &amp;&amp; (SPI_Put_Char(0xFF) != 0xFE));
          if (!MMC_Counter_Word)
          {
              DEV_xSELECT = DEV_NONE;
              return FALSE;
          };
  
                  //code for reading 16 byte OCR goes here
  
          SPI_Put_Char(0xFFU);
          SPI_Put_Char(0xFFU); //cycle through 16-bit CRC
          SPI_Put_Char(0xFFU); //1GB Sandisk SD seems to require another dummy
  
          DEV_xSELECT = DEV_NONE;
          Delay_Sec(2);
          LCD_CLS();
      }
      else
      {
          return FALSE;
      };
  
      return TRUE;
  };
  
      bit MMC_Fill_IO_Buffer(unsigned long sector)
  {
      unsigned short MMC_Fill_Index_Byte;
      unsigned char MMC_Counter_Byte = 255;
      unsigned char response[1];  
  
      if (MMC_Command(MMC_READ_SINGLE_BLOCK, 0x0000, 0x0000, response)) //cmd10
      {
          DEV_xSELECT = DEV_MMC;
  
          MMC_Counter_Byte = 255;
          while (--MMC_Counter_Byte &amp;&amp; (SPI_Put_Char(0xFF) != 0xFE));
          if (!MMC_Counter_Byte)
          {
              DEV_xSELECT = DEV_NONE;
              return FALSE;
          };
      }
      else
      {
          return FALSE;
      };
  
      for (MMC_Fill_Index_Byte = 0; MMC_Fill_Index_Byte &lt; 512 ; MMC_Fill_Index_Byte++)
      {
          IO_Buffer[MMC_Fill_Index_Byte] = SPI_Put_Char(0xFF);
      };
      SPI_Put_Char(0xFFU);
      SPI_Put_Char(0xFFU); //cycle through 16-bit CRC
      SPI_Put_Char(0xFFU); //1GB Sandisk SD seems to require another dummy
      DEV_xSELECT = DEV_NONE;
  
      //following is IO_Buffer displaying code.
      //LCD_CLS();
      //for (MMC_Counter_Byte = 0; MMC_Counter_Byte &lt; 42; MMC_Counter_Byte++)
      //{
      //  LCD_Draw_Byte_Hex(IO_Buffer[MMC_Counter_Byte + 448]);
      //};
      //while (1);
  
      return TRUE;
  };
  </code></pre>
  
  <p>Thanks ahead of time!</p>