Improve SD/MMC support driver, allowing use of newer uSD cards Tested on 8Gb SDHC...
authorNathael Pajani <nathael.pajani@ed3l.fr>
Thu, 19 Nov 2020 18:54:29 +0000 (19:54 +0100)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 16:03:05 +0000 (17:03 +0100)
extdrv/sdmmc.c
include/extdrv/sdmmc.h

index 1460e75..829f068 100644 (file)
@@ -164,6 +164,28 @@ static int sdmmc_send_app_command(const struct sdmmc_card* mmc, uint8_t index, u
        return sdmmc_send_command(mmc, index, arg, NULL, 0);
 }
 
+int sdmmc_reset(struct sdmmc_card* mmc)
+{
+       int r1 = 0, ret = 0;
+
+       config_gpio(&(mmc->chip_select), LPC_IO_MODE_PULL_UP, GPIO_DIR_OUT, 1);
+
+       /* Get SPI Bus */
+       spi_get_mutex(mmc->ssp_bus_num);
+       sdmmc_cs_activate(mmc);
+
+       /* Send CMD0 (RESET or GO_IDLE_STATE) */
+       r1 = sdmmc_send_command(mmc, MMC_GO_IDLE_STATE, 0, NULL, 0);
+       if (r1 > MMC_R1_IN_IDLE_STATE) {
+               ret = -EIO; /* This one should have succeded even without a card inserted ... */
+       }
+
+       sdmmc_cs_release(mmc);
+       spi_release_mutex(mmc->ssp_bus_num);
+
+       return ret;
+}
+
 
 int sdmmc_init(struct sdmmc_card* mmc)
 {
@@ -266,7 +288,16 @@ int sdmmc_init_end(struct sdmmc_card* mmc)
                mmc->card_type = (buf[0] & 0x40) ? MMC_CARDTYPE_SDV2_HC : MMC_CARDTYPE_SDV2_SC;
        }
 
-       /* Set block length */
+       /* SDHC and SDXC have fixed block length of 512 bytes */
+       if (mmc->card_type >= MMC_CARDTYPE_SDV2_SC) {
+               /* Fixed 512 bytes block length */
+               mmc->block_size = MMC_MAX_SECTOR_SIZE;
+               mmc->block_shift = (31 - clz(mmc->block_size));
+               goto end_init_release_bus;
+       }
+
+       /* Set block length for MMC, SDV1 and SDV2_HC cards */
+       /* Check that is is within boundaries */
        if (mmc->block_size > MMC_MAX_SECTOR_SIZE) {
                mmc->block_size = MMC_MAX_SECTOR_SIZE;
                mmc->block_shift = (31 - clz(mmc->block_size));
@@ -278,6 +309,7 @@ int sdmmc_init_end(struct sdmmc_card* mmc)
        r1 = sdmmc_send_command(mmc, MMC_SET_BLOCKLEN, mmc->block_size, NULL, 0);
        if (r1 > MMC_R1_IN_IDLE_STATE) {
                mmc->card_type = MMC_CARDTYPE_UNKNOWN;
+               ret = r1;
        }
 
 end_init_release_bus:
index b2d4183..1e113b7 100644 (file)
@@ -42,6 +42,8 @@ int sdmmc_init(struct sdmmc_card* mmc);
 int sdmmc_init_wait_card_ready(struct sdmmc_card* mmc);
 int sdmmc_init_end(struct sdmmc_card* mmc);
 
+int sdmmc_reset(struct sdmmc_card* mmc);
+
 /* Read one block of data.
  * Return -ENODEV on error, -EBUSY on timeout, -EIO on CRC error, or 0 on success
  */
@@ -71,17 +73,26 @@ int sdmmc_write_block(const struct sdmmc_card* mmc, uint32_t block_number, uint8
 /* Command definitions in SPI bus mode
  * Response type is R1 unless specified
  */
-#define MMC_GO_IDLE_STATE           0
+#define MMC_GO_IDLE_STATE           0  /* CMD0 */
 #define MMC_SEND_OP_COND            1
+#define MMC_ALL_SEND_CID            2  /* R2 */
+#define MMC_SEND_REL_ADDR           3  /* R6 */
+#define MMC_SET_DSR                 4
 #define MMC_SWITCH_FUNC             6
-#define MMC_SEND_IF_COND            8 /* R7 (R1 + 4 bytes) */
-#define MMC_SEND_CSD                9
-#define MMC_SEND_CID                10
+#define MMC_SELECT_CARD             7
+#define MMC_SEND_IF_COND            8  /* R7 (R1 + 4 bytes) */
+#define MMC_SEND_CSD                9  /* R2 */
+#define MMC_SEND_CID                10 /* R2 */
+#define MMC_VOLTAGE_SWITCH          11
 #define MMC_STOP_TRANSMISSION       12 /* R1b (busy) */
 #define MMC_SEND_STATUS             13 /* R2 (2 bytes) */
+#define MMC_GO_INACTIVE_STATE       15
 #define MMC_SET_BLOCKLEN            16
 #define MMC_READ_SINGLE_BLOCK       17
 #define MMC_READ_MULTIPLE_BLOCK     18
+#define MMC_SEND_TUNING_BLOCK       19
+#define MMC_SPEED_CLASS_CONTROL     20
+#define MMC_SET_BLOCK_COUNT         23
 #define MMC_WRITE_SINGLE_BLOCK      24
 #define MMC_WRITE_MULTIPLE_BLOCK    25
 #define MMC_PROGRAMM_CSD            27
@@ -101,8 +112,9 @@ int sdmmc_write_block(const struct sdmmc_card* mmc, uint32_t block_number, uint8
 /* Application specific commands supported by SD.
  * All these commands shall be preceded with APP_CMD (CMD55).
  */
+#define MMC_SD_SET_BUS_WIDTH        6
 #define MMC_SD_SEND_STATUS          13 /* R2 (2 bytes) */
-#define MMC_SD_SEND_NUM_WR_BLOCKS   22
+#define MMC_SD_SEND_NUM_WR_BLOCKS   22 /* Responds with 32bits + CRC. Unit is 512 bytes */
 #define MMC_SD_SET_WR_BLK_ERASE_COUNT  23
 #define MMC_SD_SEND_OP_COND         41
 #define MMC_SD_SET_CLR_CARD_DETECT  42