#include #include #include "crc7.h" #include "decode.h" static const unsigned int tran_exp[] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; static const unsigned char tran_mant[] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, }; static const unsigned int tacc_exp[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, }; static const unsigned int tacc_mant[] = { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80, }; static const unsigned int min_cur[] = { 5, 10, 50, 100, 250, 350, 600, 1000, }; static const unsigned int max_cur[] = { 10, 50, 100, 250, 350, 450, 800, 2000, }; int main(int argc, char** argv) { int i, j; int temp, e, m; char ch; unsigned long resp[4]; if (argc != 2) return -1; if (strlen(argv[1]) != 8 * 4) return -1; for (i = 0;i < 4;i++) { resp[i] = 0; for (j = 0;j < 8;j++) { resp[i] <<= 4; ch = tolower(argv[1][i * 8 + j]); if (isdigit(ch)) resp[i] |= ch - '0'; else if (isxdigit(ch)) resp[i] |= ch - 'a' + 0xA; else return -1; } } printf("CSD Version: "); temp = UNSTUFF_BITS(resp, 126, 2); switch (temp) { case 0: printf("v1.0"); break; case 1: printf("v1.1"); break; case 2: printf("v1.2"); break; default: printf("Unknown [%d]", temp); } printf("\n"); printf("MMCA Version: "); temp = UNSTUFF_BITS(resp, 122, 4); switch (temp) { case 0: printf("v1.0 to v1.2"); break; case 1: printf("v1.4"); break; case 2: printf("v2.0 to v2.2"); break; case 3: printf("v3.1 to v3.3"); break; default: printf("Unknown [%d]", temp); } printf("\n"); m = UNSTUFF_BITS(resp, 115, 4); e = UNSTUFF_BITS(resp, 112, 3); printf("TACC: %d ns\n", (tacc_exp[e] * tacc_mant[m] + 9) / 10); printf("NSAC: %d clks\n", UNSTUFF_BITS(resp, 104, 8) * 100); m = UNSTUFF_BITS(resp, 99, 4); e = UNSTUFF_BITS(resp, 96, 3); printf("Max rate: %d kHz\n", tran_exp[e] * tran_mant[m] / 1000); printf("Command classes: "); temp = UNSTUFF_BITS(resp, 84, 12); for (i = 0;i < 12;i++) { if (temp & (1 << i)) { switch (i) { case 0: printf("basic, "); break; case 1: printf("stream read, "); break; case 2: printf("block read, "); break; case 3: printf("stream write, "); break; case 4: printf("block write, "); break; case 5: printf("erase, "); break; case 6: printf("write prot., "); break; case 7: printf("lock, "); break; case 8: printf("app. specific, "); break; case 9: printf("I/O mode, "); break; default: printf("class %d, ", i); } } } printf("\n"); temp = 1 << UNSTUFF_BITS(resp, 80, 4); printf("Read block size: %d bytes\n", temp); temp = 1 << UNSTUFF_BITS(resp, 22, 4); printf("Write block size: %d bytes\n", temp); printf("Partial read: "); if (UNSTUFF_BITS(resp, 79, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("Partial write: "); if (UNSTUFF_BITS(resp, 21, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("Read misalign: "); if (UNSTUFF_BITS(resp, 77, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("Write misalign: "); if (UNSTUFF_BITS(resp, 78, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("DSR: "); if (UNSTUFF_BITS(resp, 76, 1)) printf("Yes"); else printf("No"); printf("\n"); e = UNSTUFF_BITS(resp, 47, 3); m = UNSTUFF_BITS(resp, 62, 12); printf("Capacity: %d blocks %d %d\n", ((1 + m) << (e + 2)), m, e); printf("Min read current: %0.1f mA\n", (float)min_cur[UNSTUFF_BITS(resp, 59, 3)]/10); printf("Max read current: %0.1f mA\n", (float)max_cur[UNSTUFF_BITS(resp, 56, 3)]/10); printf("Min write current: %0.1f mA\n", (float)min_cur[UNSTUFF_BITS(resp, 53, 3)]/10); printf("Max write current: %0.1f mA\n", (float)max_cur[UNSTUFF_BITS(resp, 50, 3)]/10); m = UNSTUFF_BITS(resp, 42, 5); e = UNSTUFF_BITS(resp, 37, 5); printf("Erase group size: %d blocks\n", (m+1) * (e+1)); printf("WP group size: %d erase group(s)\n", UNSTUFF_BITS(resp, 32, 5)); printf("WP enable: "); if (UNSTUFF_BITS(resp, 31, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("R2W factor: %d\n", UNSTUFF_BITS(resp, 26, 3)); printf("Content protect: "); if (UNSTUFF_BITS(resp, 16, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("File format: "); if (UNSTUFF_BITS(resp, 15, 1)) printf("Reserved"); else { switch (UNSTUFF_BITS(resp, 10, 2)) { case 0: printf("Hard disk"); break; case 1: printf("Floppy"); break; case 2: printf("Universal"); break; case 3: printf("Unknown"); break; } } printf("\n"); printf("Copy: "); if (UNSTUFF_BITS(resp, 14, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("Perm write protect: "); if (UNSTUFF_BITS(resp, 13, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("Tmp write protect: "); if (UNSTUFF_BITS(resp, 12, 1)) printf("Yes"); else printf("No"); printf("\n"); printf("ECC: "); switch (UNSTUFF_BITS(resp, 8, 2)) { case 0: printf("none"); break; case 1: printf("BCH(512,512)"); break; default: printf("Reserved"); } printf("\n"); gen_crc7_syndrome_table(); printf("CRC: "); if (UNSTUFF_BITS(resp, 1, 7) == calc_crc7(resp)) printf("OK"); else printf("Fail"); printf("\n"); return 0; }