For days I work on this and I have no solution. My ACMD 41 constantly returns 0x01. Here's my code. Can someone help me with this, I really need someone who worked on this.
char micro_SD_Init()
{
//raise CS and MOSI for 80 clock cycles
//SendByte(0xff) 10 times with CS high
int i;
__delay_cycles(500);
// Init SPI Module
SPI_init();
/* Enable CS bit for using */
P3DIR |= BIT0;
//initialization sequence on PowerUp -> 80 clock cycles delay
CS_HIGH();
for(i = 0; i < 10; i++)
{
SPI_Send_Byte(DUMMY_CHAR);
}
CS_LOW();
SPI_Send_Byte(DUMMY_CHAR);
SPI_Send_Byte(DUMMY_CHAR);
//Send Command 0 to put microSD in SPI mode
micro_SD_SendCmd(MICROSD_GO_IDLE_STATE,0x00000000,0x95);
while (resp1 != 0x01) // resp1 != 0x01
{
SPI_Send_Byte(DUMMY_CHAR);
micro_SD_SendCmd(MICROSD_GO_IDLE_STATE,0x00000000,0x95); // CMD0
resp1 = micro_SD_GetResponse();
SPI_Send_Byte(DUMMY_CHAR);
}
SPI_Send_Byte(DUMMY_CHAR);
/* Send if cond */
while ((array_resp[0] != 0x01) && (array_resp[3] != 0x01) && (array_resp[4] != 0xAA))
{
micro_SD_SendCmd(MICROSD_SEND_IF_COND,0x000001AA,0x87); // CMD8
micro_SD_GetLongerResponse();
SPI_Send_Byte(DUMMY_CHAR);
}
/* prosla CMD8 */
CS_HIGH();
SPI_Send_Byte(DUMMY_CHAR);
CS_LOW();
/* Tell that the next command is aplication-specific command */
do
{
SPI_Send_Byte(DUMMY_CHAR);
micro_SD_SendCmd(MICROSD_NEXT_ACMD,0x00000000,0x65); // CMD 55
CS_HIGH();
__delay_cycles(50);
CS_LOW();
SPI_Send_Byte(DUMMY_CHAR);
//ACMD41
micro_SD_SendCmd(MICROSD_SEND_OP_COND,0x40000000,0x77);
resp1 = micro_SD_GetResponse();
if (resp1 == 0x00) break;
} while (resp1 != 0x00);
//SPI_speed_up();
//--------------------------------------------------
while (SPI_Send_Byte(DUMMY_CHAR) != 0xFF)
{
SPI_Send_Byte(DUMMY_CHAR);
}
// da provjerimo napon napajanja na kartici
SPI_Send_Byte(DUMMY_CHAR);
micro_SD_SendCmd(MICROSD_READ_OCR,0x00000000,0x75);
micro_SD_GetLongerResponse();
if ((array_resp[1] == 0xC0) || (array_resp[1] == 0x40))
printf ("SDHC kartica validna!");
else
micro_SD_SetBlockLength(512);
return (MICROSD_SUCCESS);
}
-
\$\begingroup\$ Why don't you simply use Arduino SD library, or use it as a reference to create your own code? \$\endgroup\$Dmitry Grigoryev– Dmitry Grigoryev2016年06月10日 09:21:09 +00:00Commented Jun 10, 2016 at 9:21
-
\$\begingroup\$ I'm using MSP430 microcontroller. This Send Command function just send 6 bytes of command, and this response function just sends 0xff about 10 times in a row. If a response is 0x01 or 0x00 I break the loop. \$\endgroup\$Bratic– Bratic2016年06月10日 09:23:55 +00:00Commented Jun 10, 2016 at 9:23
-
\$\begingroup\$ Also, I don't need file system, I want to send raw data. \$\endgroup\$Bratic– Bratic2016年06月10日 09:26:42 +00:00Commented Jun 10, 2016 at 9:26
-
\$\begingroup\$ My code (on Github) is implemented per the spec with minor workarounds for weird cards. Maybe it will help. \$\endgroup\$David– David2016年06月10日 20:41:20 +00:00Commented Jun 10, 2016 at 20:41
-
\$\begingroup\$ Your SPI speed is less than 400khz? \$\endgroup\$SoreDakeNoKoto– SoreDakeNoKoto2016年06月12日 01:52:46 +00:00Commented Jun 12, 2016 at 1:52
1 Answer 1
I fixed it fast forgot to answer here. It is important to be careful about timings between commands! Some of them need about ~100 ms. It is needed because of SD contorller's machine state. So if you are confused => increase time delay between commands.
100 ms is a huge waste of time.
It is not time between commands, it is number of spare clock cycles. You must supply several groups of 8 clock cycles after command completes, and before you are going to start new command. These clock cycles enable card to complete its internal stuff and get prepared for new command execution.
I supply 8 after command completes while CS is still active, then deactivate CS and supply another 8 cycles. Before starting new command, I supply 8 clock cycles before activating CS, and another 8 with CS active. Then start shifting command onto the card, and card detects it by start 01
bit sequence.