int init_sdmmc_device() { int result; // Set clock to 200k_hz (50Mhz system clock) set_clock_divisor(125); // After power on, send a bunch of clocks to initialize the chip set_cs(1); for (int i = 0; i < 10; i++) spi_transfer(0xff); set_cs(0); // Reset the card result = send_sd_command(SD_CMD_RESET, 0); if (result != 1) return -1; // Poll until it is ready while (1) { result = send_sd_command(SD_CMD_INIT, 0); if (result == 0) break; if (result != 1) return -1; } // Configure the block size result = send_sd_command(SD_CMD_SET_BLOCK_LEN, BLOCK_SIZE); if (result != 0) return -1; // Increase clock rate to 5 Mhz set_clock_divisor(5); return 0; }
int read_sdmmc_device(unsigned int block_address, void *ptr) { int result; result = send_sd_command(SD_CMD_READ_BLOCK, block_address); if (result != 0) return -1; for (int i = 0; i < BLOCK_SIZE; i++) ((char*) ptr)[i] = spi_transfer(0xff); // checksum (ignored) spi_transfer(0xff); spi_transfer(0xff); return BLOCK_SIZE; }
int read_sdmmc_device(unsigned int block_address, void *ptr) { int result; int old_flags; old_flags = disable_interrupts(); acquire_spinlock(&sd_lock); result = send_sd_command(SD_CMD_READ_BLOCK, block_address); if (result != 0) return -1; for (int i = 0; i < BLOCK_SIZE; i++) ((char*) ptr)[i] = spi_transfer(0xff); // checksum (ignored) spi_transfer(0xff); spi_transfer(0xff); release_spinlock(&sd_lock); restore_interrupts(old_flags); return BLOCK_SIZE; }