Pradeep Kotipalli
/
raw_sd_card_write_raw
efe
Fork of raw_sd_card_disc_init by
Diff: main.cpp
- Revision:
- 2:aea18e9b89d8
- Parent:
- 1:1843a53b51a8
- Child:
- 3:d4bb1e13a897
--- a/main.cpp Sat Jun 06 09:58:13 2015 +0000 +++ b/main.cpp Sat Jun 06 11:07:06 2015 +0000 @@ -16,9 +16,16 @@ int initialise_card(); int initialise_card_v1(); int initialise_card_v2(); +int disk_initialize(); +uint64_t sd_sectors(); +uint64_t sectors; + int cmd(int, int); int cmd58(); +int cmdx(int, int); int cmd8(); +int read(uint8_t*, uint32_t ); +static uint32_t ext_bits(unsigned char *, int , int ); int cdv; @@ -39,7 +46,8 @@ while(1) { initialise_card(); int result= initialise_card(); - printf("%d\n",result); + printf("initialise card result=%d\n",result); + disk_initialize(); wait(5); } } @@ -64,11 +72,13 @@ // send CMD8 to determine whther it is ver 2.x int r = cmd8(); if (r == R1_IDLE_STATE) { + printf("Entering v2 bro\n"); return initialise_card_v2(); - printf("Entering v2 bro"); + } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) { + printf("Entering v1 bro\n"); return initialise_card_v1(); - printf("Entering v1 bro"); + } else { debug("Not in idle state after sending CMD8 (not an SD card?)\n"); return SDCARD_FAIL; @@ -195,4 +205,133 @@ cs = 1; spi.write(0xFF); return -1; // timeout -} \ No newline at end of file +} + +uint64_t sd_sectors() { + uint32_t c_size, c_size_mult, read_bl_len; + uint32_t block_len, mult, blocknr, capacity; + uint32_t hc_c_size; + uint64_t blocks; + + // CMD9, Response R2 (R1 byte + 16-byte block read) + if (cmdx(9, 0) != 0) { + debug("Didn't get a response from the disk\n"); + return 0; + } + + uint8_t csd[16]; + if (read(csd, 16) != 0) { + debug("Couldn't read csd response from disk\n"); + return 0; + } + + // csd_structure : csd[127:126] + // c_size : csd[73:62] + // c_size_mult : csd[49:47] + // read_bl_len : csd[83:80] - the *maximum* read block length + + int csd_structure = ext_bits(csd, 127, 126); + + switch (csd_structure) { + case 0: + cdv = 512; + c_size = ext_bits(csd, 73, 62); + c_size_mult = ext_bits(csd, 49, 47); + read_bl_len = ext_bits(csd, 83, 80); + + block_len = 1 << read_bl_len; + mult = 1 << (c_size_mult + 2); + blocknr = (c_size + 1) * mult; + capacity = blocknr * block_len; + blocks = capacity / 512; + debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks); + break; + + case 1: + cdv = 1; + hc_c_size = ext_bits(csd, 63, 48); + blocks = (hc_c_size+1)*1024; + debug_if(SD_DBG, "\n\rSDHC Card \n\rhc_c_size: %d\n\rcapacity: %lld \n\rsectors: %lld\n\r", hc_c_size, blocks*512, blocks); + break; + + default: + debug("CSD struct unsupported\r\n"); + return 0; + }; + return blocks; +} + +int cmdx(int cmd, int arg) { + cs = 0; + + // send a command + spi.write(0x40 | cmd); + spi.write(arg >> 24); + spi.write(arg >> 16); + spi.write(arg >> 8); + spi.write(arg >> 0); + spi.write(0x95); + + // wait for the repsonse (response[7] == 0) + for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) { + int response = spi.write(0xFF); + if (!(response & 0x80)) { + return response; + } + } + cs = 1; + spi.write(0xFF); + return -1; // timeout +} + + +int read(uint8_t *buffer, uint32_t length) { + cs = 0; + + // read until start byte (0xFF) + while (spi.write(0xFF) != 0xFE); + + // read data + for (int i = 0; i < length; i++) { + buffer[i] = spi.write(0xFF); + } + spi.write(0xFF); // checksum + spi.write(0xFF); + + cs = 1; + spi.write(0xFF); + return 0; +} + +static uint32_t ext_bits(unsigned char *data, int msb, int lsb) { + uint32_t bits = 0; + uint32_t size = 1 + msb - lsb; + for (int i = 0; i < size; i++) { + uint32_t position = lsb + i; + uint32_t byte = 15 - (position >> 3); + uint32_t bit = position & 0x7; + uint32_t value = (data[byte] >> bit) & 1; + bits |= value << i; + } + return bits; +} + +int disk_initialize() { + int i = initialise_card(); + debug_if(SD_DBG, "init card = %d\n", i); + sectors = sd_sectors(); + + // Set block length to 512 (CMD16) + if (cmd(16, 512) != 0) { + debug("Set 512-byte block timed out\n"); + return 1; + } + else + { + printf("Hey,block init succesful"); + } + + spi.frequency(1000000); // Set to 1MHz for data transfer + return 0; +} +