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)
{
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));
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:
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
*/
/* 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
/* 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