cancel
Showing results for 
Search instead for 
Did you mean: 

STM32_adafriut_sd version detection problem

M N
Associate II

Hi .

Below code has two part :

1- when there is response to CMD8

2- when there is not

And by this response we can determine if it is V1 or V2 but , when it will go for Initializing V2 after sending first ACMD41 then there is an "if" clause ,which will check response to knows if response is "SD_R1_ILLEGAL_COMMAND" then if it is "SD_R1_ILLEGAL_COMMAND" it will send ACMD41 with no argument .

---------------------

So there is two question here for me ?

(Both questions are related to line 947 in attached C file which is :)

if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND)

1- Is second "if clause " for checking ( SDSC ) or ( SDHC and SDXC ) type card ? => what I've got is : It is for initializing V2 - SDSC type card so it will send ACMD41 with no argument (HCS = 0) .(Am I right ?) ( It is what I got from flowchart in "SPI Mode Initilization Flow" part of SD documents ).

2- I read "Physical_Layer_Simplified_Specification" more than ten times but ,I couldn't find description, when it will send "SD_R1_ILLEGAL_COMMAND" in response of ACMD41 (which used in "if clause " after first ACMD41 with argument HCS = 1 ,so by checking response second ACMD41 which is in this "if clause " will send with HCS = 0 because of this ), which page has described this part of ACMD41 in SPI mode ?

response = SD_SendCmd(SD_CMD_SEND_IF_COND, 0x1AA, 0x87, SD_ANSWER_R7_EXPECTED);
  SD_IO_CSState(1);
  SD_IO_WriteByte(SD_DUMMY_BYTE);
  if((response.r1  & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND)
  {
    /* initialise card V1 */
    do
    {
      /* initialise card V1 */
      /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */
      response = SD_SendCmd(SD_CMD_APP_CMD, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED);
      SD_IO_CSState(1);
      SD_IO_WriteByte(SD_DUMMY_BYTE);
 
      /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */
      response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED);
      SD_IO_CSState(1);
      SD_IO_WriteByte(SD_DUMMY_BYTE);
    }
    while(response.r1 == SD_R1_IN_IDLE_STATE);
    flag_SDHC = 0;
  }
  else if(response.r1 == SD_R1_IN_IDLE_STATE)
  {
      /* initialise card V2 */
    do {
 
      /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */
      response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED);
      SD_IO_CSState(1);
      SD_IO_WriteByte(SD_DUMMY_BYTE);
 
      /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */
      response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x40000000, 0xFF, SD_ANSWER_R1_EXPECTED);
      SD_IO_CSState(1);
      SD_IO_WriteByte(SD_DUMMY_BYTE);
    }
    while(response.r1 == SD_R1_IN_IDLE_STATE);
//********************************QA**********************************
// below line of code is where I could not find description for it in SD Documentation 
//********************************QA**********************************
    if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND)
    {
      do {
        /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */
        response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED);
        SD_IO_CSState(1);
        SD_IO_WriteByte(SD_DUMMY_BYTE);
        if(response.r1 != SD_R1_IN_IDLE_STATE)
        {
          return BSP_SD_ERROR;
        }
        /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */
        response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED);
        SD_IO_CSState(1);
        SD_IO_WriteByte(SD_DUMMY_BYTE);
      }
      while(response.r1 == SD_R1_IN_IDLE_STATE);
    }
 
    /* Send CMD58 (SD_CMD_READ_OCR) to initialize SDHC or SDXC cards: R3 response (0x00: no errors) */
    response = SD_SendCmd(SD_CMD_READ_OCR, 0x00000000, 0xFF, SD_ANSWER_R3_EXPECTED);
    SD_IO_CSState(1);
    SD_IO_WriteByte(SD_DUMMY_BYTE);
    if(response.r1 != SD_R1_NO_ERROR)
    {
      return BSP_SD_ERROR;
    }
    flag_SDHC = (response.r2 & 0x40) >> 6;
12 REPLIES 12

>But here is the problem it will multiply our EndAddress with 512 !

Compare it with the FatFs implementation at http://elm-chan.org/fsw/ff/ffsample.zip. You'll find it in stm32\mmc_stm32f1_spi.c.

@Amel NASRI​, could you escalate this please? The stm32_adafruit_sd.c of https://github.com/STMicroelectronics/STM32CubeF1/tree/master/Drivers/BSP/Adafruit_Shield and other repositories (F4, etc) have implemented erase incorrectly.

Ok . But I hate FatFs, It is like below picture :

0693W000004KJqgQAG.jpg0693W000004KJqRQAW.jpg:grimacing_face:

The software is layered

  1. app
  2. file-system
  3. SD driver
  4. SPI driver

FatFs is an example file-system.

stm32_adafruit_sd.c is an SD driver. Fixing stm32_adafruit_sd.c or switching to a different SD driver like the one in http://elm-chan.org/fsw/ff/ffsample.zip doesn't force you to use FatFs.