CSD.h
Go to the documentation of this file.
1 /*
2  CSD register bit alignment is awkward, so borrowed the approach taken by linux
3  from https://github.com/torvalds/linux/blob/master/drivers/mmc/core/sd.c
4 */
5 
6 #pragma once
7 
8 #include <Print.h>
9 
10 /* CSD register field definitions as per specification */
11 
12 // Tag, Type, Start Bit, Size
13 #define SDCARD_CSD_MAP_A(XX) \
14  XX(structure, Structure, 126, 2) \
15  XX(taac, uint8_t, 112, 8) \
16  XX(nsac, uint8_t, 104, 8) \
17  XX(tran_speed, uint8_t, 96, 8) \
18  XX(ccc, uint16_t, 84, 12) \
19  XX(read_bl_len, uint8_t, 80, 4) \
20  XX(read_bl_partial, uint8_t, 79, 1) \
21  XX(write_blk_missalign, bool, 80, 1) \
22  XX(read_blk_misalign, bool, 78, 1) \
23  XX(dsr_imp, bool, 76, 1)
24 
25 // Version 1.0
26 #define SDCARD_CSD_MAP_B1(XX) \
27  XX(c_size, uint16_t, 62, 12) \
28  XX(vdd_r_curr_min, uint8_t, 59, 3) \
29  XX(vdd_r_curr_max, uint8_t, 56, 3) \
30  XX(vdd_w_curr_min, uint8_t, 53, 3) \
31  XX(vdd_w_curr_max, uint8_t, 50, 3) \
32  XX(c_size_mult, uint8_t, 47, 3)
33 
34 // Version 2.0
35 #define SDCARD_CSD_MAP_B2(XX) XX(c_size, uint32_t, 48, 22)
36 
37 // Version 3.0
38 #define SDCARD_CSD_MAP_B3(XX) XX(c_size, uint32_t, 48, 28)
39 
40 #define SDCARD_CSD_MAP_C(XX) \
41  XX(erase_blk_en, bool, 46, 1) \
42  XX(sector_size, uint8_t, 39, 7) \
43  XX(wp_grp_size, uint8_t, 32, 7) \
44  XX(wp_grp_enable, bool, 31, 1) \
45  XX(r2w_factor, uint8_t, 26, 3) \
46  XX(write_bl_len, uint8_t, 22, 4) \
47  XX(write_bl_partial, bool, 21, 1) \
48  XX(file_format_grp, bool, 15, 1) \
49  XX(copy, bool, 14, 1) \
50  XX(perm_write_protect, bool, 13, 1) \
51  XX(tmp_write_protect, bool, 12, 1) \
52  XX(file_format, uint8_t, 10, 2) \
53  XX(wp_upc, bool, 9, 1) \
54  XX(crc, uint8_t, 1, 7)
55 
56 namespace Storage::SD
57 {
58 #define XX(tag, Type, start, len, ...) \
59  Type tag() const \
60  { \
61  return Type(readBits(start, len)); \
62  }
63 
64 struct CSD1;
65 struct CSD2;
66 struct CSD3;
67 
68 struct CSD {
69  uint32_t raw_bits[4];
70 
71  enum class Structure {
77  v1 = 0,
78 
85  v2 = 1,
86 
92  v3 = 2,
93  };
94 
95  void bswap()
96  {
97  for(auto& w : raw_bits) {
98  w = __builtin_bswap32(w);
99  }
100  }
101 
102  SDCARD_CSD_MAP_A(XX)
103 
104  template <class C> const C& as() const
105  {
106  return *static_cast<const C*>(this);
107  }
108 
109  const CSD1& v1() const
110  {
111  return as<CSD1>();
112  }
113 
114  const CSD2& v2() const
115  {
116  return as<CSD2>();
117  }
118 
119  const CSD3& v3() const
120  {
121  return as<CSD3>();
122  }
123 
124  uint64_t getSize() const;
125 
126  SDCARD_CSD_MAP_C(XX)
127 
128  size_t printTo(Print& p) const;
129 
130 protected:
131  // This is our version of linux' `UNSTUFF_BITS` macro
132  uint32_t readBits(uint8_t start, uint8_t size) const
133  {
134  const uint32_t mask = (size < 32 ? 1U << size : 0) - 1U;
135  const unsigned off = 3 - (start / 32);
136  const unsigned shift = start & 31;
137  uint32_t res = raw_bits[off] >> shift;
138  if(size + shift > 32) {
139  res |= raw_bits[off - 1] << ((32 - shift) % 32);
140  }
141  return res & mask;
142  }
143 };
144 
145 struct CSD1 : public CSD {
147 
148  uint64_t size() const
149  {
150  return uint64_t(c_size() + 1) << (c_size_mult() + 2) << read_bl_len();
151  }
152 };
153 
154 struct CSD2 : public CSD {
156 
157  uint64_t size() const
158  {
159  return uint64_t(c_size() + 1) * 512 * 1024;
160  }
161 };
162 
163 struct CSD3 : public CSD {
165 
166  uint64_t size() const
167  {
168  return uint64_t(c_size() + 1) * 512 * 1024;
169  }
170 };
171 
172 #undef XX
173 
174 } // namespace Storage::SD
175 
uint64_t size() const
Definition: CSD.h:148
uint32_t readBits(uint8_t start, uint8_t size) const
Definition: CSD.h:132
const C & as() const
Definition: CSD.h:104
uint32_t raw_bits[4]
Definition: CSD.h:69
const CSD3 & v3() const
Definition: CSD.h:119
const CSD2 & v2() const
Definition: CSD.h:114
#define SDCARD_CSD_MAP_C(XX)
Definition: CSD.h:40
The String class.
Definition: WString.h:136
const CSD1 & v1() const
Definition: CSD.h:109
uint64_t getSize() const
size_t printTo(Print &p) const
String toString(Storage::SD::CSD::Structure structure)
#define XX(name, comment)
Definition: DirectoryTemplate.h:47
@ v1
SDC ver 1.XX or MMC.
#define SDCARD_CSD_MAP_B3(XX)
Definition: CSD.h:38
#define SDCARD_CSD_MAP_A(XX)
Definition: CSD.h:13
Definition: CSD.h:145
#define SDCARD_CSD_MAP_B2(XX)
Definition: CSD.h:35
uint64_t size() const
Definition: CSD.h:157
#define SDCARD_CSD_MAP_B1(XX)
Definition: CSD.h:26
Definition: Card.h:15
uint64_t size() const
Definition: CSD.h:166
Provides formatted output to stream.
Definition: Print.h:36
void bswap()
Definition: CSD.h:95
Definition: CSD.h:154
Definition: CSD.h:163
Structure
Definition: CSD.h:71
Definition: CSD.h:68