0
\$\begingroup\$

I'm using SPI to interface with a micro SD card 2GB and get error respond in CMD16 response and also CMD17 response. Because of that, I can't also read bytes from SD card. Here is my code:

SD card Initialize function:

uint8_t SDCard_Initialize(void) {
 uint8_t i;
 //Send 80 pulses to active SD card
 for(i = 0; i < 10; i++) 
 SPI_ByteTransfer(0xFF); //Each byte send = 8 pulses
 GPIO_SPI->BRR = GPIO_CS; //Enable SD card CS pin
 SDCard_SendCommand(CMD0, 0, 0x4A); //SD card go to Idle state
 if(!SDCard_CheckRespond(0x01))
 return 1; //Error code 1
 for(i = 0; i < 10; i++) { 
 SDCard_SendCommand(CMD1, 0, 0xFF); //SD card active operations
 if(SDCard_CheckRespond(0x00)) 
 break; 
 } 
 if(i == 10)
 return 2; //Error code 2
 SDCard_SendCommand(CMD16, 512, 0xFF); //SD card active operations
 if(!SDCard_CheckRespond(0x00))
 return 3;
 GPIO_SPI->BSRR = GPIO_CS; //Disable SD card CS pin
 return 0;
}

SD Card send command function:

void SDCard_SendCommand(uint8_t cmd, uint32_t arg, uint8_t crc) {
 uint8_t temp;
 int8_t i;
 SPI_ByteTransfer(cmd | 0x40); //Transmit 6bit command, transmission and start bit first 
 for(i = 3; i >= 0; i--) { //Transmit 32bit argument 
 temp = (arg >> (8 * i)) & 0x000000FF;
 SPI_ByteTransfer(temp);
 }
 SPI_ByteTransfer((crc << 1) | 0x01); //Transmit 7bit CRC and stop bit
}

SD Card check respond function:

uint8_t SDCard_CheckRespond(uint8_t res) { 
 timeout = 0;
 Timer_Initialize(3600, 1999); //Set timer trigger at 100milisecond 
 while(SPI_ByteTransfer(0xFF) != res) { //Loop until get correct respond or timeout
 if(timeout) { 
 TIM_DeInit(TIM2);
 return 0; //Return error if timeout
 }
 }
 TIM_DeInit(TIM2);
 SPI_ByteTransfer(0xFF); //Add 8 clock after receive respond
 return 1;
}

The response from CMD16 that I got instead of 0x00 really strange: It can't be 0xC0 because the response's MSB in manual must be 0.

FF C0 7F FF FF FF FF FF FF FF
asked May 20, 2018 at 9:01
\$\endgroup\$
4
  • \$\begingroup\$ Your CMD0 looks wrong, the correct checksum should be 0x95. Also, most 2GB cards follow the SD 2.0 standard, which uses different commands in initialization - closer to SDHC cards: CDM0, CMD8, ACMD41. \$\endgroup\$ Commented May 20, 2018 at 10:10
  • \$\begingroup\$ My checksum is 0x4A and in the function, I shift left 1 bit and add 1 in LSB, then it will become 0x95. Btw, I'll test for SDHC case, thanks \$\endgroup\$ Commented May 20, 2018 at 10:59
  • \$\begingroup\$ Just a comment, don't think has nothing to do but I noticed that you put CS low and then call a function which I presume sends an SPI command. There is minimum time between CS going low and the first clock edge. Make sure you respect that as now that delay is governed by the time the function takes to execute which is not an ideal practice. \$\endgroup\$ Commented May 20, 2018 at 13:24
  • \$\begingroup\$ Thanks Andrés, I've checked and add 0xFF through SPI to create delay time beetween CS and first clock edge \$\endgroup\$ Commented May 20, 2018 at 14:44

1 Answer 1

0
\$\begingroup\$

I've add 8 clock by sending 0xFF through SPI after receiving respond and now I get the correct respond. Don't add it with read block command, it could flush additional 1 byte from offset.

uint8_t SDCard_Initialize(void) {
 uint8_t i;
 //Send 80 pulses to active SD card
 for(i = 0; i < 10; i++) 
 SPI_ByteTransfer(0xFF); //Each byte send = 8 pulses
 GPIO_SPI->BRR = GPIO_CS; //Enable SD card CS pin
 SDCard_SendCommand(CMD0, 0, 0x4A); //SD card go to Idle state
 if(!SDCard_CheckRespond(0x01))
 return 1; //Error code 1
 /* ADD 8 CLOCK AFTER RECEIVE RESPONSE */
 **SPI_ByteTransfer(0xFF);**
 for(i = 0; i < 10; i++) { 
 SDCard_SendCommand(CMD1, 0, 0xFF); //SD card active operations
 if(SDCard_CheckRespond(0x00)) 
 break; 
 } 
 if(i == 10)
 return 2; //Error code 2
 /* ADD 8 CLOCK AFTER RECEIVE RESPONSE */
 **SPI_ByteTransfer(0xFF);**
 SDCard_SendCommand(CMD16, 512, 0xFF); //SD card active operations
 if(!SDCard_CheckRespond(0x00))
 return 3;
 /* ADD 8 CLOCK AFTER RECEIVE RESPONSE */
 **SPI_ByteTransfer(0xFF);**
 GPIO_SPI->BSRR = GPIO_CS; //Disable SD card CS pin
 return 0;
}
answered May 20, 2018 at 17:14
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.