4
\$\begingroup\$

I just want to clarify with everyone that I have exhausted all of my search options looking for an answer, and still cannot find the answer to my problem.

I am trying to interface a micro sd card slot with my pic32 project by bit banging an spi. I've had no problem initializing, and I can read the OCR and CSD register just fine, but when I send the read sector command, I get 512 Bytes of 0's no matter what.

I have tried with multiple cards with the same result with all. I am using SanDisk 2GB standard MicroSD cards. They are formatted as FAT(FAT16) by both Windows and using the SDFormatter provided by sdcard.org. I've used Disk Investigator to confirm that the MBR contains the correct data.

Here is the sequence I am using to initialize:

//Low speed
Send 10 Bytes of data to 'wake up' card w/ CS High
Send CMD0 to reset until response is idle (0x01)
Send CMD8 w/ arg 0x1AA and read correct response to verify SDC V2
Send ACMD41 w/ HCS flag to initialize until no longer idle (0x00)
//High speed
Send CMD58 to read OCR and check CCS flag in response
Send CMD16 to set block length to 512 Bytes
//At this point I should be able to read the MBR but get nothing
Send CMD17 /w arg 0x00 to read very first sector

When I send the read command, I do get a correct R1 response 0x00, then a few Byte transfers later, I get 0xFE indicating the start of data, but the data line just goes low for 512 Bytes, and nothing is read.

I've tried writing to a sector with dummy data, getting the 'data accepted' response, but when I tried to read it back, I got all zeros again. I'm wondering if I'm doing anything wrong with my initialization.

I'm sure it's not a problem with my program sending the wrong command, as I have everything hooked up to a scope, and everything seems to be correct. Here are the screenshots:

Here is the read sequence I am sending Here is the read command sequence I am sending

And immediately following, the response I get And immediately following, the response I get

Any insight into why this is not working would be appreciated. I've spent much more time on this than I'd like, and like may things, it's probably a simple problem I'm not seeing. I'm hoping extra sets of eyes will spot my problem. Thanks in advance, and I will update with any information needed to help solve this problem.

EDIT, more things I've tried:

  1. I've set the CS low for the entire read sequence, and no change in response.

  2. I've changed the fixed CRC to the actual CRC needed by the read sequence, no change in response.

Using Disk Investigator to read the card on the computer, I can see the expected result from reading the first sector as shown:

0000  EB 00 90 20 20 20 20 20   . . .          
0008  20 20 20 00 02 40 01 00         . . @ . .
0010  02 00 02 00 00 F8 EC 00   . . . . . . . .
0018  3F 00 40 00 87 00 00 00   ? . @ . . . . .
0020  79 EF 3A 00 80 00 29 10   y . : . . . ) .
0028  41 2E 17 4E 4F 20 4E 41   A . . N O   N A
0030  4D 45 20 20 20 20 46 41   M E         F A
0038  54 31 36 20 20 20 00 00   T 1 6       . .
0040  00 00 00 00 00 00 00 00   . . . . . . . .
----  All Zeros -------------   ---------------
01F0  00 00 00 00 00 00 00 00   . . . . . . . .
01F8  00 00 00 00 00 00 55 AA   . . . . . . U .

List of Miso and Mosi blocks during init (formatted as o-scope picture):

// wake up with 80 clk pulses w/ cs high not shown here
// First CMD0 send:
00 00 00 00 00 00 3F 01
40 00 00 00 00 95 FF FF

//Second CMD0 send:
FF FF FF FF FF FF FF C1 7F
40 00 00 00 00 95 FF FF FF

//Third CMD0 send:
FF FF FF FF FF FF FF 01 FF
40 00 00 00 00 95 FF FF FF

//CMD8 w/ 0x1AA arg
FF FF FF FF FF FF FF 01 00 00 01 AA FF
48 00 00 01 AA 87 FF FF FF FF FF FF FF

//ACMD41 w/ HCS flag          6 times before 00-vv
FF FF FF FF FF FF FF 01 FF FF FF FF FF FF FF FF 01 FF
77 00 00 00 00 95 FF FF FF 69 40 00 00 00 95 FF FF FF

//CMD58 read OCR
FF FF FF FF FF FF FF 00 80 FF 80 00 FF
7A 00 00 00 00 95 FF FF FF FF FF FF FF

//CMD16 to set block length
FF FF FF FF FF FF FF 00 FF
50 00 00 02 00 95 FF FF FF

After this is the read function shown above
\$\endgroup\$
  • 2
    \$\begingroup\$ Nice screenshots. What model scope is it? \$\endgroup\$ – tcrosley Apr 15 '14 at 18:25
  • 2
    \$\begingroup\$ Just tested a 2GB card lying around: There are a lot of zero bytes in the first sector. Check the last two for 0x55 0xAA. \$\endgroup\$ – Turbo J Apr 15 '14 at 19:22
  • 1
    \$\begingroup\$ The read exchange looks fine to me. Since it is reading all zeros (and you have checked it is actually incorrect), perhaps you should scratch the assumption that everything before it is correct, and post it as well. \$\endgroup\$ – apalopohapa Apr 15 '14 at 19:45
  • 1
    \$\begingroup\$ Can you post the relevant parts of the schematic? Are you powering the SD card with 2V7..3V6 ? \$\endgroup\$ – apalopohapa Apr 16 '14 at 1:09
  • 1
    \$\begingroup\$ The registers in the SD card can be more tolerant to voltage drops than actual memory access, so this could be a power issue, perhaps you can check with your scope that the voltage supply to the card stays within 2.7 to 3.6 V the whole time. \$\endgroup\$ – apalopohapa Apr 16 '14 at 1:17
4
\$\begingroup\$

Posting this answer as an excerpt of the comments, since the issue seems to have been resolved.

The registers in the SD card can be more tolerant to voltage drops than actual memory access, so this could be a power issue, perhaps you can check with your scope that the voltage supply to the card stays within 2.7 to 3.6 V the whole time. – apalopohapa

@apalopohapa Success, Looking at the input voltage, it was fine up until the ACMD41 init, then dropped down to 2. My boss pointed out a diode on a different page of the schematic that should have been tied low. Now I am reading everything correctly, and can continue. I'm just frustrated because time and time again I've had to tell myself to check power when having problems, and I can't just assume it's not an issue because it works half the time. I appreciate all your guys' help. – farraman

\$\endgroup\$
2
\$\begingroup\$

The blue "4" line looks like an "automatic" CS signal generated by the SPI peripherial. This will not work reliably with the SD card, as these require the CS line to be low (=selected) during the entire read command sequence.

But the automatic CS will turn high in case something like an interrupt delays the re-filling of the SPI output register with a new value - causing the card to abort the command.

Operating the CS line manually using a GPIO port avoids this problem.

Edit: Your "first sector" is the first sector of the first partition, not the first sector of the "disc" (or card in this case). Reading the first sector of the card (the partition table) will require admin privileges - and you cannot use the drive letter. You must use the pyhsical device name. Disk investigator does not seem to be capable of this.

\$\endgroup\$
  • 1
    \$\begingroup\$ As I just commented above, and in the content edit, this has proven no significance in the read command, but I have taken your advice and removed the spikes by asserting the CS manually. Will change the screenshots soon. \$\endgroup\$ – farraman Apr 15 '14 at 18:33

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.