COSA
An Object-Oriented Platform for Arduino Programming
SD.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_SD_HH
22 #define COSA_SD_HH
23 
24 #include "Cosa/Types.h"
25 #include "Cosa/SPI.hh"
26 
35 class SD : private SPI::Driver {
36 public:
38  static const size_t BLOCK_MAX = 512;
39 
41  enum CARD {
43  TYPE_SD1 = 1,
44  TYPE_SD2 = 2,
46  } __attribute__((packed));
47 
49  struct cid_t {
50  uint8_t mid;
51  char oid[2];
52  char pnm[5];
53  uint8_t prv;
54  uint32_t psn;
55  uint16_t mdt;
56  uint8_t crc;
57  };
58 
60  struct csd_v1_t {
61  uint8_t reserved1:6;
62  uint8_t csd_ver:2;
63  uint8_t taac;
64  uint8_t nsac;
65  uint8_t tran_speed;
66  uint8_t ccc_high;
67  uint8_t read_bl_len:4;
68  uint8_t ccc_low:4;
69  uint8_t c_size_high:2;
70  uint8_t reserved2:2;
71  uint8_t dsr_imp:1;
72  uint8_t read_blk_misalign:1;
73  uint8_t write_blk_misalign:1;
74  uint8_t read_bl_partial:1;
75  uint8_t c_size_mid;
76  uint8_t vdd_r_curr_max:3;
77  uint8_t vdd_r_curr_min:3;
78  uint8_t c_size_low :2;
79  uint8_t c_size_mult_high:2;
80  uint8_t vdd_w_cur_max:3;
81  uint8_t vdd_w_curr_min:3;
82  uint8_t sector_size_high:6;
83  uint8_t erase_blk_en:1;
84  uint8_t c_size_mult_low:1;
85  uint8_t wp_grp_size:7;
86  uint8_t sector_size_low:1;
87  uint8_t write_bl_len_high:2;
88  uint8_t r2w_factor:3;
89  uint8_t reserved3:2;
90  uint8_t wp_grp_enable:1;
91  uint8_t reserved4:5;
92  uint8_t write_partial:1;
93  uint8_t write_bl_len_low:2;
94  uint8_t reserved5:2;
95  uint8_t file_format:2;
96  uint8_t tmp_write_protect:1;
97  uint8_t perm_write_protect:1;
98  uint8_t copy:1;
99  uint8_t file_format_grp:1;
100  uint8_t crc;
101  };
102 
104  struct csd_v2_t {
105  uint8_t reserved1:6;
106  uint8_t csd_ver:2;
107  uint8_t taac;
108  uint8_t nsac;
109  uint8_t tran_speed;
110  uint8_t ccc_high;
111  uint8_t read_bl_len:4;
112  uint8_t ccc_low:4;
113  uint8_t reserved2:4;
114  uint8_t dsr_imp:1;
115  uint8_t read_blk_misalign:1;
116  uint8_t write_blk_misalign:1;
117  uint8_t read_bl_partial:1;
118  uint8_t c_size_high:6;
119  uint8_t reserved3:2;
120  uint8_t c_size_mid;
121  uint8_t c_size_low;
122  uint8_t sector_size_high:6;
123  uint8_t erase_blk_en:1;
124  uint8_t reserved4:1;
125  uint8_t wp_grp_size:7;
126  uint8_t sector_size_low:1;
127  uint8_t write_bl_len_high:2;
128  uint8_t r2w_factor:3;
129  uint8_t reserved5:2;
130  uint8_t wp_grp_enable:1;
131  uint8_t reserved6:5;
132  uint8_t write_partial:1;
133  uint8_t write_bl_len_low:2;
134  uint8_t reserved7:2;
135  uint8_t file_format:2;
136  uint8_t tmp_write_protect:1;
137  uint8_t perm_write_protect:1;
138  uint8_t copy:1;
139  uint8_t file_format_grp:1;
140  uint8_t crc;
141  };
142 
144  union csd_t {
147  };
148 
149 protected:
151  enum CMD {
155  SET_DSR = 4,
159  SEND_CSD = 9,
160  SEND_CID = 10,
163  SEND_STATUS = 13,
171  WRITE_BLOCK = 24,
173  PROGRAM_CSD = 27,
179  ERASE = 38,
180  LOCK_UNLOCK = 40,
181  APP_CMD = 55,
182  GEN_CMD = 56,
183  READ_OCR = 58,
185  } __attribute__((packed));
186 
188  enum ACMD {
190  SD_STATUS = 13,
195  SEND_SCR = 51
196  } __attribute__((packed));
197 
199  enum STATE {
209  } __attribute__((packed));;
210 
212  union R1 {
213  uint8_t as_uint8;
214  struct {
215  uint8_t in_idle_state:1;
216  uint8_t erase_reset:1;
217  uint8_t illegal_command:1;
218  uint8_t com_crc_error:1;
219  uint8_t erase_sequence_error:1;
220  uint8_t address_error:1;
221  uint8_t parameter_error:1;
222  uint8_t reserved:1;
223  };
224  R1(uint8_t value = 0) { as_uint8 = value; }
225  bool is_error() const { return ((as_uint8 & 0x7e) != 0); }
226  bool is_ready() const { return (as_uint8 == 0); }
227  };
228 
230  union R2 {
231  uint8_t as_uint8;
232  struct {
233  uint8_t card_is_locked:1;
234  uint8_t wp_erased:1;
235  uint8_t error:1;
236  uint8_t cc_error:1;
237  uint8_t card_ecc_failed:1;
238  uint8_t wp_violation:1;
239  uint8_t erase_param:1;
240  uint8_t out_of_range:1;
241  };
242  R2(uint8_t value = 0) { as_uint8 = value; }
243  };
244 
246  struct R3 {
247  uint32_t vdd_voltage_window:24;
248  uint8_t switch_to_1V8_accepted:1;
249  uint8_t reserved:4;
250  uint8_t uhs_ii_card:1;
251  uint8_t card_capacity:1;
252  uint8_t card_power_up:1;
253  };
254 
256  union R6 {
257  uint32_t as_uint32;
258  struct {
259  uint16_t rca;
260  uint16_t status;
261  };
262  R6(uint32_t value = 0L) { as_uint32 = value; }
263  };
264 
266  union R7 {
267  uint32_t as_uint32;
268  struct {
269  uint8_t check_pattern;
270  uint8_t voltage_accepted:4;
271  uint32_t reserved:16;
272  uint8_t command_version:4;
273  };
274  R7(uint32_t value = 0L) { as_uint32 = value; }
275  };
276 
278  static const uint8_t CHECK_PATTERN = 0xAA;
279 
280  enum TOKEN {
288  } __attribute__((packed));
289 
291  struct request_t {
292  uint8_t command;
293  uint32_t arg;
294  uint8_t crc;
295  };
296 
298  static const uint16_t INIT_TIMEOUT = 2000;
299  static const uint16_t ERASE_TIMEOUT = 10000;
300  static const uint16_t READ_TIMEOUT = 300;
301  static const uint16_t WRITE_TIMEOUT = 600;
302 
304  static const uint8_t INIT_PULSES = 10;
305 
307  static const uint8_t INIT_RETRY = 200;
308  static const uint8_t RESPONSE_RETRY = 100;
309 
311  uint8_t m_response;
312 
315 
322  uint8_t send(CMD command, uint32_t arg = 0L);
323 
332  bool send(uint16_t ms, CMD command, uint32_t arg = 0L);
333 
341  uint8_t send(ACMD command, uint32_t arg = 0L);
342 
352  bool send(uint16_t ms, ACMD command, uint32_t arg = 0L);
353 
362  bool await(uint16_t ms = 0, uint8_t token = 0);
363 
368  uint32_t receive();
369 
380  bool read(CMD command, uint32_t arg, void* buf, size_t count);
381 
382 public:
388 #if defined(BOARD_ATTINYX5)
390  SPI::Driver(csn, SPI::ACTIVE_LOW, SPI::DIV128_CLOCK, 0, SPI::MSB_ORDER, NULL),
391  m_type(TYPE_UNKNOWN)
392  {}
393 #elif defined(WICKEDDEVICE_WILDFIRE)
395  SPI::Driver(csn, SPI::ACTIVE_LOW, SPI::DIV128_CLOCK, 0, SPI::MSB_ORDER, NULL),
396  m_type(TYPE_UNKNOWN)
397  {}
398 #else
400  SPI::Driver(csn, SPI::ACTIVE_LOW, SPI::DIV128_CLOCK, 0, SPI::MSB_ORDER, NULL),
401  m_type(TYPE_UNKNOWN)
402  {}
403 #endif
404 
408  CARD type() const
409  {
410  return (m_type);
411  }
412 
419  bool begin(SPI::Clock rate = SPI::DIV128_CLOCK);
420 
427  bool end();
428 
436  bool erase(uint32_t start, uint32_t end);
437 
446  bool read(uint32_t block, uint8_t* dst)
447  __attribute__((always_inline))
448  {
449  if (m_type != TYPE_SDHC) block <<= 9;
450  return (read(READ_SINGLE_BLOCK, block, dst, BLOCK_MAX));
451  }
452 
460  bool read(cid_t* cid)
461  __attribute__((always_inline))
462  {
463  return (read(SEND_CID, 0, cid, sizeof(cid_t)));
464  }
465 
472  bool read(csd_t* csd)
473  __attribute__((always_inline))
474  {
475  return (read(SEND_CSD, 0, csd, sizeof(csd_t)));
476  }
477 
485  bool write(uint32_t block, const uint8_t* src);
486 };
487 
488 #endif
Asks the selected card to send CSD.
Definition: SD.hh:159
uint8_t tran_speed
Definition: SD.hh:109
uint8_t c_size_mid
Definition: SD.hh:75
char oid[2]
OEM/Application ID.
Definition: SD.hh:51
R2(uint8_t value=0)
Definition: SD.hh:242
Set/reset password or unlock/lock card.
Definition: SD.hh:180
Sends host capacity support information.
Definition: SD.hh:153
uint8_t crc
Definition: SD.hh:294
Clock
Definition: SPI.hh:60
bool read(csd_t *csd)
Definition: SD.hh:472
Definition: SD.hh:230
uint32_t psn
Product serial number.
Definition: SD.hh:54
bool is_error() const
Definition: SD.hh:225
Checks switchable function.
Definition: SD.hh:154
bool erase(uint32_t start, uint32_t end)
Definition: SD.cpp:289
static const uint16_t ERASE_TIMEOUT
Definition: SD.hh:299
static const uint16_t WRITE_TIMEOUT
Definition: SD.hh:301
Definition: SD.hh:266
Turns the CRC on/off.
Definition: SD.hh:184
static const size_t BLOCK_MAX
Definition: SD.hh:38
Enable pull-up resistor on CD/DAT3 (pin 1).
Definition: SD.hh:194
Definition: SPI.hh:57
csd_v2_t v2
Definition: SD.hh:146
static const uint8_t INIT_RETRY
Definition: SD.hh:307
CARD m_type
Definition: SD.hh:314
Number of write blocks.
Definition: SD.hh:191
Reads the Configuration Register.
Definition: SD.hh:195
#define NULL
Definition: Types.h:101
uint8_t ccc_high
Definition: SD.hh:110
CARD type() const
Definition: SD.hh:408
static const uint8_t INIT_PULSES
Definition: SD.hh:304
Write block length bytes.
Definition: SD.hh:171
R6(uint32_t value=0L)
Definition: SD.hh:262
Number of pre-erased write blocks.
Definition: SD.hh:192
Next command is application specific command.
Definition: SD.hh:181
bool write(uint32_t block, const uint8_t *src)
Definition: SD.cpp:314
Divide system clock by 128.
Definition: SPI.hh:67
uint8_t ccc_high
Definition: SD.hh:66
Definition: SD.hh:212
Reset the SD Memory Card.
Definition: SD.hh:152
Set programmable bits in CSD.
Definition: SD.hh:173
Asks the selected card to send CID.
Definition: SD.hh:160
uint8_t c_size_mid
Definition: SD.hh:120
Read blocks until STOP_TRANSMISSION.
Definition: SD.hh:167
Check speed class.
Definition: SD.hh:169
char pnm[5]
Product name.
Definition: SD.hh:52
Send 64 byte tuning pattern to card.
Definition: SD.hh:168
uint8_t as_uint8
Definition: SD.hh:231
uint16_t mdt
Manufacturing date.
Definition: SD.hh:55
Sends SD Memory Card interface condition.
Definition: SD.hh:158
uint8_t nsac
Definition: SD.hh:64
CARD
Definition: SD.hh:41
uint8_t tran_speed
Definition: SD.hh:65
static const uint8_t CHECK_PATTERN
Definition: SD.hh:278
csd_v1_t v1
Definition: SD.hh:145
Read block length bytes.
Definition: SD.hh:166
static const uint16_t INIT_TIMEOUT
Definition: SD.hh:298
Card status.
Definition: SD.hh:190
uint8_t mid
Manufacturer ID.
Definition: SD.hh:50
TOKEN
Definition: SD.hh:280
Definition: SD.hh:35
uint32_t arg
Definition: SD.hh:293
uint8_t check_pattern
Definition: SD.hh:269
STATE
Definition: SD.hh:199
Toggles card state (stdby/prog and disc).
Definition: SD.hh:157
Set first write block to be erased.
Definition: SD.hh:177
Definition: SD.hh:144
uint16_t rca
Definition: SD.hh:259
uint8_t crc
Definition: SD.hh:140
Asks the selected card status register.
Definition: SD.hh:163
Definition: SD.hh:256
ACMD
Definition: SD.hh:188
Definition: SD.hh:49
Defines the data bus width.
Definition: SD.hh:189
CMD
Definition: SD.hh:151
SD(Board::DigitalPin csn=Board::D8)
Definition: SD.hh:399
bool read(uint32_t block, uint8_t *dst)
Definition: SD.hh:446
R7(uint32_t value=0L)
Definition: SD.hh:274
Switch to 1V8 bus signaling level.
Definition: SD.hh:161
Set block length (in bytes).
Definition: SD.hh:165
bool await(uint16_t ms=0, uint8_t token=0)
Definition: SD.cpp:150
R1(uint8_t value=0)
Definition: SD.hh:224
uint8_t m_response
Definition: SD.hh:311
uint8_t as_uint8
Definition: SD.hh:213
bool read(CMD command, uint32_t arg, void *buf, size_t count)
Definition: SD.cpp:183
uint8_t prv
Product revision.
Definition: SD.hh:53
uint8_t taac
Definition: SD.hh:107
static const uint16_t READ_TIMEOUT
Definition: SD.hh:300
bool begin(SPI::Clock rate=SPI::DIV128_CLOCK)
Definition: SD.cpp:226
Programs the DSR of all cards.
Definition: SD.hh:155
static const uint8_t RESPONSE_RETRY
Definition: SD.hh:308
Set write protect bit.
Definition: SD.hh:174
Set last write block to be erased.
Definition: SD.hh:178
uint8_t taac
Definition: SD.hh:63
uint8_t nsac
Definition: SD.hh:108
Host capacity support information.
Definition: SD.hh:193
Clears write protect bit.
Definition: SD.hh:175
Addressed card into inactive state.
Definition: SD.hh:164
uint32_t as_uint32
Definition: SD.hh:257
Read OCR register of a card.
Definition: SD.hh:183
Write block until STOP_TRANSMISSION.
Definition: SD.hh:172
Checks switchable function.
Definition: SD.hh:156
uint16_t status
Definition: SD.hh:260
bool end()
Definition: SD.cpp:283
bool read(cid_t *cid)
Definition: SD.hh:460
uint8_t send(CMD command, uint32_t arg=0L)
Definition: SD.cpp:96
Stop Multiple Block Read.
Definition: SD.hh:162
uint8_t command
Definition: SD.hh:292
Specify block count for multiple block.
Definition: SD.hh:170
Erases selected write blocks.
Definition: SD.hh:179
bool is_ready() const
Definition: SD.hh:226
uint32_t receive()
Definition: SD.cpp:164
uint8_t crc
CRC7 checksum.
Definition: SD.hh:56
Driver(Board::DigitalPin cs, Pulse pulse=DEFAULT_PULSE, Clock rate=DEFAULT_CLOCK, uint8_t mode=0, Order order=MSB_ORDER, Interrupt::Handler *irq=NULL)
Definition: SOFT_SPI.cpp:25
Data block for application specific command.
Definition: SD.hh:182
uint8_t crc
Definition: SD.hh:100
uint32_t as_uint32
Definition: SD.hh:267
Read write protect bit.
Definition: SD.hh:176
uint8_t c_size_low
Definition: SD.hh:121
Definition: SD.hh:246