drivers/storage/spi_sdcard.c
/*
 * sd_spi_init - initialize a SPI sd card
 *
 * @spi - the SPI device that we will be using
 *
 *  This function initializes an SD card in SPI mode
 *  and reads the device geometry upon success.
 */
initialize a SPI sd card
@spi - the SPI device that we will be using

This function initializes an SD card in SPI mode
and reads the device geometry upon success.
initialize a SPI sd card @spi - the SPI device that we will be using This function initializes an SD card in SPI mode and reads the device geometry upon success .
int sd_spi_init(spi_master_dev_t *spi)
{
  uint8_t spi_rsp;
  int retry_counter = 0;
  g_sd_spi = spi;
  sd_generate_crc_table();
  sd_spi_set_cs(1);
  for (int i = 0; i < SPI_INIT_NUM_BYTES; i++)
    sd_spi_write(SPI_INIT_DUMMY_BYTE);
  LOG_INFO("Send CMD0 0x%x\n", SPI_RESET_CMD);
  sd_spi_send_cmd(SPI_RESET_CMD, 0);
  g_rsp_index = 6;
  if ((spi_rsp = sd_read_byte_ignore_char(0xFF)) != 1) {
    LOG_ERR("init bad response: 0x%x\n", spi_rsp);
    return -ENODEV;
  }
  LOG_INFO("Response: 0x%x", spi_rsp);
  LOG_INFO("Send CMD8 0x%x\n", SPI_SEND_IF_COND_CMD);
  sd_spi_send_cmd(SPI_SEND_IF_COND_CMD, 0x1AA);
  g_rsp_index = 6;
  spi_rsp = sd_read_byte_ignore_char(0xFF);
  if ((spi_rsp == 0xFF) || (spi_rsp == 0x05)) {
    sd_spi_set_cs(1);
  } else {
    sd_spi_set_cs(1);
    spi_rsp = sd_read_byte_ignore_char(0x00);
    if (spi_rsp != 0x01) {
      LOG_ERR("Voltage not accepted 0x%d\n", spi_rsp);
      return -EINVAL;
    }
    spi_rsp = sd_read_byte_ignore_char(0xFF);
    if (spi_rsp != 0xAA) {
      LOG_ERR("Wrong test patern 0x%x\n", spi_rsp);
      return -EINVAL;
    }
  }
  int counter = 0;
  uint8_t cmd = SPI_SD_SEND_OP_COND_CMD;
  LOG_INFO("Send CMD55");
  sd_spi_send_cmd(SPI_APP_CMD, 0);
  spi_rsp = sd_read_byte_ignore_char(0xFF);
  LOG_INFO("Response: 0x%x", spi_rsp);
  do {
    counter++;
    LOG_INFO("Send %s", cmd == SPI_SD_SEND_OP_COND_CMD ? "ACMD41" : "CMD 1");
    sd_spi_send_cmd(cmd, 0x40000000);
    spi_rsp = sd_read_byte_ignore_char(0xFF);
    LOG_INFO("Response: 0x%x", spi_rsp);
    if ((spi_rsp & 0xF) == 0x05) {
      cmd = SPI_SEND_OP_COND_CMD;
    } else {
      cmd = SPI_SD_SEND_OP_COND_CMD;
    }
  } while (spi_rsp != 0 && counter < SPI_MAX_RESET_RETRIES);
  if (counter == SPI_MAX_RESET_RETRIES) {
    LOG_ERR("cannot reset 0x%x\r\n", spi_rsp);
    return -EINVAL;
  }
  sd_spi_send_cmd(SPI_READ_OCR, 0);
  g_rsp_index = 6;
  spi_rsp = sd_read_byte_ignore_char(0xFF);
  if (spi_rsp != 0) {
    LOG_ERR("get capacity response 0x%x", spi_rsp);
    return -EINVAL;
  }
  spi_rsp = sd_read_byte_ignore_char(0xFF);
  if (((spi_rsp & 0x40) == 0x40) && (spi_rsp != 0xFF)) {
    LOG_INFO("SdCard block addressing 0x%x\n", spi_rsp);
    g_sd_card.type = SD_HIGH_CAPACITY_CARD;
  } else {
    LOG_ERR("byte addressing  0x%x\n", spi_rsp);
    g_sd_card.type = SD_LOW_CAPACITY_CARD;
    return -EINVAL;
  }
  LOG_INFO("Send CMD9\n");
  sd_spi_send_cmd(SPI_SEND_CSD, 0);
  spi_rsp = sd_read_byte_ignore_char(0xFF);
  if (spi_rsp != 0) {
    LOG_ERR("read CSD register failed 0x%x\n", spi_rsp);
    return -ENODEV;
  }
  uint8_t sd_capacity_info[SD_CSD_RESPONSE_LEN];
  sd_read_byte_ignore_char(0xFE);
  g_rsp_index++;
  int remaining_bytes = sizeof(g_sd_resp) - g_rsp_index;
#ifdef CONFIG_DEBUG_SD_CARD
  printf("\r\n Found 0xFE on %d pos\n", remaining_bytes);
#endif
  memcpy(sd_capacity_info, g_sd_resp + g_rsp_index, remaining_bytes);
  sd_spi_set_cs(0);
  sd_spi_read(sd_capacity_info + remaining_bytes,
              SD_CSD_RESPONSE_LEN - remaining_bytes);
  sd_spi_set_cs(1);
#ifdef CONFIG_DEBUG_SD_CARD
   for (int i = 0; i < SD_CSD_RESPONSE_LEN; i++) {
    printf("\r\n0x%x,", sd_capacity_info[i]);
  }
#endif
  if (g_sd_card.type == SD_HIGH_CAPACITY_CARD) {
    g_sd_card.num_blocks = sd_capacity_info[9] + 1;
    g_sd_card.num_blocks += (uint32_t)(sd_capacity_info[8] << 8);
    g_sd_card.num_blocks += (uint32_t)(sd_capacity_info[7] & 0x0F) << 12;
    g_sd_card.size = 524288 * g_sd_card.num_blocks;
  } else {
    g_sd_card.size = (((uint16_t)(sd_capacity_info[6] & 0x03) << 10) |
      ((uint16_t)(sd_capacity_info[7] << 2)) |
      ((uint16_t)(sd_capacity_info[8] & 0xC0) >> 6)) + 1;
    g_sd_card.size = g_sd_card.size << (((sd_capacity_info[9] & 0x03) << 1) |
      ((sd_capacity_info[10] & 0x80) >> 7) + 2);
    g_sd_card.size = g_sd_card.size << (sd_capacity_info[5] & 0x0F);
    g_sd_card.num_blocks = g_sd_card.size / 524288;
    sd_spi_set_cs(1);
  }
  LOG_INFO("card blocks: %d\n", g_sd_card.num_blocks);
#ifdef CONFIG_DEBUG_SD_CARD
  uint8_t buffer[64];
  memset(buffer, 0, 64);
  sd_spi_read_logical_block(spi, buffer, 0, 0, 64);
  for (int i = 0; i < sizeof(buffer); i += 8) {
    printf("%x %x %x %x %x %x %x %x\n",
           buffer[i],
           buffer[i + 1],
           buffer[i + 2],
           buffer[i + 3],
           buffer[i + 4],
           buffer[i + 5],
           buffer[i + 6],
           buffer[i + 7]);
  }
#endif
  return vfs_register_node(CONFIG_SD_SPI_NAME,
                           strlen(CONFIG_SD_SPI_NAME),
                           &g_sd_spi_ops,
                           VFS_TYPE_BLOCK_DEVICE,
                           spi);
}
int sd_spi_init ( spi_master_dev_t * spi ) { uint8_t spi_rsp ; int retry_counter = 0 ; g_sd_spi = spi ; sd_generate_crc_table ( ) ; sd_spi_set_cs ( 1 ) ; for ( int i = 0 ; i < SPI_INIT_NUM_BYTES ; i ++ ) sd_spi_write ( SPI_INIT_DUMMY_BYTE ) ; LOG_INFO ( " \n " , SPI_RESET_CMD ) ; sd_spi_send_cmd ( SPI_RESET_CMD , 0 ) ; g_rsp_index = 6 ; if ( ( spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ) != 1 ) { LOG_ERR ( " \n " , spi_rsp ) ; return - ENODEV ; } LOG_INFO ( " " , spi_rsp ) ; LOG_INFO ( " \n " , SPI_SEND_IF_COND_CMD ) ; sd_spi_send_cmd ( SPI_SEND_IF_COND_CMD , 0x1AA ) ; g_rsp_index = 6 ; spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ; if ( ( spi_rsp == 0xFF ) || ( spi_rsp == 0x05 ) ) { sd_spi_set_cs ( 1 ) ; } else { sd_spi_set_cs ( 1 ) ; spi_rsp = sd_read_byte_ignore_char ( 0x00 ) ; if ( spi_rsp != 0x01 ) { LOG_ERR ( " \n " , spi_rsp ) ; return - EINVAL ; } spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ; if ( spi_rsp != 0xAA ) { LOG_ERR ( " \n " , spi_rsp ) ; return - EINVAL ; } } int counter = 0 ; uint8_t cmd = SPI_SD_SEND_OP_COND_CMD ; LOG_INFO ( " " ) ; sd_spi_send_cmd ( SPI_APP_CMD , 0 ) ; spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ; LOG_INFO ( " " , spi_rsp ) ; do { counter ++ ; LOG_INFO ( " " , cmd == SPI_SD_SEND_OP_COND_CMD ? " " : " " ) ; sd_spi_send_cmd ( cmd , 0x40000000 ) ; spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ; LOG_INFO ( " " , spi_rsp ) ; if ( ( spi_rsp & 0xF ) == 0x05 ) { cmd = SPI_SEND_OP_COND_CMD ; } else { cmd = SPI_SD_SEND_OP_COND_CMD ; } } while ( spi_rsp != 0 && counter < SPI_MAX_RESET_RETRIES ) ; if ( counter == SPI_MAX_RESET_RETRIES ) { LOG_ERR ( " \r \n " , spi_rsp ) ; return - EINVAL ; } sd_spi_send_cmd ( SPI_READ_OCR , 0 ) ; g_rsp_index = 6 ; spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ; if ( spi_rsp != 0 ) { LOG_ERR ( " " , spi_rsp ) ; return - EINVAL ; } spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ; if ( ( ( spi_rsp & 0x40 ) == 0x40 ) && ( spi_rsp != 0xFF ) ) { LOG_INFO ( " \n " , spi_rsp ) ; g_sd_card . type = SD_HIGH_CAPACITY_CARD ; } else { LOG_ERR ( " \n " , spi_rsp ) ; g_sd_card . type = SD_LOW_CAPACITY_CARD ; return - EINVAL ; } LOG_INFO ( " \n " ) ; sd_spi_send_cmd ( SPI_SEND_CSD , 0 ) ; spi_rsp = sd_read_byte_ignore_char ( 0xFF ) ; if ( spi_rsp != 0 ) { LOG_ERR ( " \n " , spi_rsp ) ; return - ENODEV ; } uint8_t sd_capacity_info [ SD_CSD_RESPONSE_LEN ] ; sd_read_byte_ignore_char ( 0xFE ) ; g_rsp_index ++ ; int remaining_bytes = sizeof ( g_sd_resp ) - g_rsp_index ; #ifdef CONFIG_DEBUG_SD_CARD printf ( " \r \n \n " , remaining_bytes ) ; #endif memcpy ( sd_capacity_info , g_sd_resp + g_rsp_index , remaining_bytes ) ; sd_spi_set_cs ( 0 ) ; sd_spi_read ( sd_capacity_info + remaining_bytes , SD_CSD_RESPONSE_LEN - remaining_bytes ) ; sd_spi_set_cs ( 1 ) ; #ifdef CONFIG_DEBUG_SD_CARD for ( int i = 0 ; i < SD_CSD_RESPONSE_LEN ; i ++ ) { printf ( " \r \n " , sd_capacity_info [ i ] ) ; } #endif if ( g_sd_card . type == SD_HIGH_CAPACITY_CARD ) { g_sd_card . num_blocks = sd_capacity_info [ 9 ] + 1 ; g_sd_card . num_blocks += ( uint32_t ) ( sd_capacity_info [ 8 ] << 8 ) ; g_sd_card . num_blocks += ( uint32_t ) ( sd_capacity_info [ 7 ] & 0x0F ) << 12 ; g_sd_card . size = 524288 * g_sd_card . num_blocks ; } else { g_sd_card . size = ( ( ( uint16_t ) ( sd_capacity_info [ 6 ] & 0x03 ) << 10 ) | ( ( uint16_t ) ( sd_capacity_info [ 7 ] << 2 ) ) | ( ( uint16_t ) ( sd_capacity_info [ 8 ] & 0xC0 ) >> 6 ) ) + 1 ; g_sd_card . size = g_sd_card . size << ( ( ( sd_capacity_info [ 9 ] & 0x03 ) << 1 ) | ( ( sd_capacity_info [ 10 ] & 0x80 ) >> 7 ) + 2 ) ; g_sd_card . size = g_sd_card . size << ( sd_capacity_info [ 5 ] & 0x0F ) ; g_sd_card . num_blocks = g_sd_card . size / 524288 ; sd_spi_set_cs ( 1 ) ; } LOG_INFO ( " \n " , g_sd_card . num_blocks ) ; #ifdef CONFIG_DEBUG_SD_CARD uint8_t buffer [ 64 ] ; memset ( buffer , 0 , 64 ) ; sd_spi_read_logical_block ( spi , buffer , 0 , 0 , 64 ) ; for ( int i = 0 ; i < sizeof ( buffer ) ; i += 8 ) { printf ( " \n " , buffer [ i ] , buffer [ i + 1 ] , buffer [ i + 2 ] , buffer [ i + 3 ] , buffer [ i + 4 ] , buffer [ i + 5 ] , buffer [ i + 6 ] , buffer [ i + 7 ] ) ; } #endif return vfs_register_node ( CONFIG_SD_SPI_NAME , strlen ( CONFIG_SD_SPI_NAME ) , & g_sd_spi_ops , VFS_TYPE_BLOCK_DEVICE , spi ) ; }
sd_spi_init - initialize a SPI sd card
 @spi - the SPI device that we will be using
sd_spi_init - initialize a SPI sd card @spi - the SPI device that we will be using