sd card: what the card says it is, from its CID register

Type, size, and the identity register read by our SD driver (CMD10):
manufacturer, OEM, product name, revision, serial and date, decoded by a
host-tested parser. Needed for the upstream report of #21: nothing else
here could read the card's identity. This one is a Samsung 8 GB SDHC
from June 2013.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-05 23:15:29 +02:00
co-authored by Claude Opus 5.5
parent 3f2650c56e
commit 370f067fbf
7 changed files with 173 additions and 1 deletions
+53
View File
@@ -0,0 +1,53 @@
#include "sd_card_id.h"
#include <cstdio>
namespace roro {
namespace {
char printable(uint8_t b) { return b >= 0x20 && b < 0x7F ? static_cast<char>(b) : '?'; }
} // namespace
SdCardId parseSdCid(const uint8_t cid[16]) {
SdCardId id;
id.manufacturer = cid[0];
for (int i = 0; i < 2; ++i) id.oem[i] = printable(cid[1 + i]);
for (int i = 0; i < 5; ++i) id.product[i] = printable(cid[3 + i]);
id.revisionMajor = cid[8] >> 4;
id.revisionMinor = cid[8] & 0x0F;
id.serial = static_cast<uint32_t>(cid[9]) << 24 | cid[10] << 16 | cid[11] << 8 | cid[12];
// 4 reserved bits, 8 bits of year since 2000, 4 bits of month.
id.year = 2000 + (((cid[13] & 0x0F) << 4) | (cid[14] >> 4));
id.month = cid[14] & 0x0F;
return id;
}
const char* sdManufacturerName(uint8_t id) {
switch (id) {
case 0x01: return "Panasonic";
case 0x02: return "Toshiba/Kioxia";
case 0x03: return "SanDisk";
case 0x1B: return "Samsung";
case 0x1D: return "ADATA";
case 0x27: return "Phison";
case 0x28: return "Lexar";
case 0x31: return "Silicon Power";
case 0x41: return "Kingston";
case 0x74: return "Transcend";
case 0x76: return "Patriot";
case 0x82: return "Sony";
case 0x9C: return "Angelbird/Hoodman";
case 0xAD: return "Longsys/Lexar";
default: return "unknown";
}
}
std::string sdCardSummary(const SdCardId& id) {
char s[112];
std::snprintf(s, sizeof s, "%s (0x%02X) \"%s\" \"%s\" rev %u.%u, serial %08x, made %04d-%02d",
sdManufacturerName(id.manufacturer), id.manufacturer, id.oem, id.product, id.revisionMajor,
id.revisionMinor, static_cast<unsigned>(id.serial), id.year, id.month);
return s;
}
} // namespace roro