/** @brief Initialize a disk. @param bVolNum The volume number of the volume whose block device is being initialized. @param mode The open mode, indicating the type of access required. @return A negated ::REDSTATUS code indicating the operation result. @retval 0 Operation was successful. @retval -RED_EIO A disk I/O error occurred. @retval -RED_EROFS The device is read-only media and write access was requested. */ static REDSTATUS DiskOpen( uint8_t bVolNum, BDEVOPENMODE mode) { REDSTATUS ret = 0; uint32_t ulTries; Ctrl_status cs; /* Note: Assuming the volume number is the same as the SD card slot. The ASF SD/MMC driver supports two SD slots. This implementation will need to be modified if multiple volumes share a single SD card. */ /* The first time the disk is opened, the SD card can take a while to get ready, in which time sd_mmc_test_unit_ready() returns either CTRL_BUSY or CTRL_NO_PRESENT. Try numerous times, waiting half a second after each failure. Empirically, this has been observed to succeed on the second try, so trying 10x more than that provides a margin of error. */ for(ulTries = 0U; ulTries < 20U; ulTries++) { cs = sd_mmc_test_unit_ready(bVolNum); if((cs != CTRL_NO_PRESENT) && (cs != CTRL_BUSY)) { break; } vTaskDelay(500U / portTICK_PERIOD_MS); } if(cs == CTRL_GOOD) { #if REDCONF_READ_ONLY == 0 if(mode != BDEV_O_RDONLY) { if(sd_mmc_wr_protect(bVolNum)) { ret = -RED_EROFS; } } if(ret == 0) #endif { uint32_t ulSectorLast; (void)sd_mmc_read_capacity(bVolNum, &ulSectorLast); /* The ASF SD/MMC driver only supports 512-byte sectors. */ if( (gaRedVolConf[bVolNum].ulSectorSize != 512U) || (((uint64_t)ulSectorLast + 1U) < gaRedVolConf[bVolNum].ullSectorCount)) { ret = -RED_EINVAL; } } } else { ret = -RED_EIO; } return ret; }
Ctrl_status sd_mmc_read_capacity_1(uint32_t *nb_sector) { return sd_mmc_read_capacity(1, nb_sector); }