-
Notifications
You must be signed in to change notification settings - Fork 2
/
sd.h
343 lines (311 loc) · 8.91 KB
/
sd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#ifndef SD_H_
#define SD_H_
#include "libsdio.h"
#include "libc/types.h"
#if CONFIG_USR_LIB_SD_DEBUG
# define log_printf(...) printf(__VA_ARGS__)
#else
# define log_printf(...)
#endif
struct sdio_cmd {
union {
struct {
uint8_t index:7;
uint8_t is_acmd:1;
} cmd;
uint8_t cmd_value;
};
uint32_t arg;
enum sdio_resp_type response;
/* For data commands */
uint32_t *buf;
uint32_t buf_len;
};
uint32_t sd_init(void);
/**
* sd_get_capacity - return the capacity of the SD card
*
* Return: This function returns the size in bytes of the SD card. The return
* value is undefined is the SD card is not ready (see @sd_is_ready)
*/
uint32_t sd_get_capacity(void);
/**
* sd_get_block_size - return the block size of the SD card
*
* Return: This function returns the block size in bytes of the SD card. The
* return value is undefined is the SD card is not ready (see @sd_is_ready)
*/
uint32_t sd_get_block_size(void);
/**
* sd_is_ready - return true if the SD card is ready
*
* Return: This function return 0 if the SD card is not ready (it is still in
* identification mode) or a value different than 0 is the SD card is ready:
* the SD card is in transfer mode (i.e. the identification is done) but an
* operation can be in progress.
*/
uint8_t sd_is_ready(void);
uint32_t sd_card_csd_structure(void);
/**
* sd_flush_commands - Send commands in SD queue
*/
void sd_flush_commands(void);
#define CMD_TIMEOUT 0xffffff
#define SD_CMD_QUEUE_SIZE 32
#define SD_ERROR_MAX_RETRIES 255
/* Normal commands */
#define SD_GO_TO_IDLE_STATE 0
#define SD_ALL_SEND_CID 2
#define SD_SEND_RELATIVE_ADDR 3
#define SD_SELECT_DESELECT_CARD 7
#define SD_SEND_IF_COND 8
# define SD_SEND_IF_COND_CHECK_PATTERN 0xaa
# define SD_SEND_IF_COND_27V_36V (1 << 8)
#define SD_SEND_CSD 9
#define SD_STOP_TRANSMISSION 12
#define SD_SEND_STATUS 13
#define SD_SET_BLOCKLEN 16
#define SD_READ_SINGLE_BLOCK 17
#define SD_READ_MULTIPLE_BLOCK 18
#define SD_WRITE_BLOCK 24
#define SD_WRITE_MULTIPLE_BLOCK 25
#define SD_APP_CMD 55
/* Application commands */
#define ACMD(cmd) (0x80000000 | (cmd))
#define SD_SET_BUS_WIDTH_idx 6
//# define SD_SET_BUS_WIDTH ACMD(SD_SET_BUS_WIDTH_idx)
#define SD_SET_BUS_WIDTH SD_SET_BUS_WIDTH_idx
#define SD_SEND_OP_COND_idx 41
//# define SD_SEND_OP_COND ACMD(SD_SEND_OP_COND_idx)
#define SD_SEND_OP_COND SD_SEND_OP_COND_idx
#define R2_OR_R3 ((1 << 6) - 1) /* ACMD41 => R3, See spec section 4.9.4 */
/* Card status in response R1 */
#define CARD_STATUS_OUT_OF_RANGE ((uint32_t)1 << 31)
#define CARD_STATUS_ADDRESS_ERROR (1 << 30)
#define CARD_STATUS_BLOCK_LEN_ERROR (1 << 29)
#define CARD_STATUS_ERASE_SEQ_ERROR (1 << 28)
#define CARD_STATUS_ERASE_PARAM (1 << 27)
#define CARD_STATUS_WP_VIOLATION (1 << 26)
#define CARD_STATUS_CARD_IS_LOCKED (1 << 25)
#define CARD_STATUS_LOCK_UNLOCK_FAILED (1 << 24)
#define CARD_STATUS_COM_CRC_ERROR (1 << 23)
#define CARD_STATUS_R6_COM_CRC_ERROR (1 << 15)
#define CARD_STATUS_ILLEGAL_COMMAND (1 << 22)
#define CARD_STATUS_R6_ILLEGAL_COMMAND (1 << 14)
#define CARD_STATUS_CARD_ECC_FAILED (1 << 21)
#define CARD_STATUS_CC_ERROR (1 << 20)
#define CARD_STATUS_ERROR (1 << 19)
#define CARD_STATUS_R6_ERROR (1 << 13)
#define CARD_STATUS_CSD_OVERWRITE (1 << 16)
#define CARD_STATUS_WP_ERASE_SKIP (1 << 15)
#define CARD_STATUS_CARD_ECC_DISABLED (1 << 14)
#define CARD_STATUS_ERASE_RESET (1 << 13)
#define CARD_STATUS_CURRENT_STATE (0xf << 9)
#define CARD_STATUS_READY_FOR_DATA (1 << 8)
#define CARD_STATUS_APP_CMD (1 << 5)
#define CARD_STATUS_AKE_SEQ_ERROR (1 << 3)
#define CARD_STATUS_R6_AKE_SEQ_ERROR (1 << 3)
#define CARD_STATUS_ERROR_MASK (CARD_STATUS_OUT_OF_RANGE|CARD_STATUS_ADDRESS_ERROR\
|CARD_STATUS_BLOCK_LEN_ERROR |CARD_STATUS_ERASE_SEQ_ERROR\
|CARD_STATUS_ERASE_PARAM |CARD_STATUS_WP_VIOLATION\
|CARD_STATUS_CARD_IS_LOCKED |CARD_STATUS_LOCK_UNLOCK_FAILED\
|CARD_STATUS_COM_CRC_ERROR |CARD_STATUS_ILLEGAL_COMMAND \
|CARD_STATUS_CARD_ECC_FAILED |CARD_STATUS_CC_ERROR \
|CARD_STATUS_ERROR |CARD_STATUS_CSD_OVERWRITE \
|CARD_STATUS_AKE_SEQ_ERROR)
typedef struct __packed sd_csd_v1 {
uint8_t reserved0:1;
uint8_t crc:7;
uint8_t reserved8:2;
uint8_t file_format:2;
uint8_t tmp_write_protect:1;
uint8_t perm_write_protect:1;
uint8_t copy:1;
uint8_t file_format_grp:1;
uint16_t reserved16:5;
uint16_t write_bl_partial:1;
uint16_t write_bl_len:4;
uint16_t r2w_factor:3;
uint16_t reserved29:2;
uint16_t wp_grp_enable:1;
uint32_t wp_grp_size:7;
uint32_t sector_size:7;
uint32_t erase_blk_en:1;
uint32_t c_size_mult:3;
uint32_t vdd_w_curr_max:3;
uint32_t vdd_w_curr_min:3;
uint32_t vdd_r_curr_max:3;
uint32_t vdd_r_curr_min:3;
uint32_t c_size_high:2;
uint16_t c_size_low:10;
uint16_t reserved74:2;
uint16_t dsr_imp:1;
uint16_t read_blk_misalign:1;
uint16_t write_blk_misalign:1;
uint16_t read_bl_partial:1;
uint16_t read_bl_len:4;
uint16_t ccc:12;
uint8_t tran_speed;
uint8_t nsac;
uint8_t taac;
uint8_t reserved120:6;
uint8_t csd_structure:2;
} sd_csd_v1_t;
typedef struct __packed {
uint8_t reserved0:1;
uint8_t crc:7;
uint8_t reserved8:2;
uint8_t file_format:2;
uint8_t tmp_write_protect:1;
uint8_t perm_write_protect:1;
uint8_t copy:1;
uint8_t file_format_grp:1;
uint16_t reserved16:5;
uint16_t write_bl_partial:1;
uint16_t write_bl_len:4;
uint16_t r2w_factor:3;
uint16_t reserved29:2;
uint16_t wp_grp_enable:1;
uint16_t wp_grp_size:7;
uint16_t sector_size:7;
uint16_t erase_blk_en:1;
uint16_t reserved47:1;
uint32_t c_size:22;
uint32_t reserved70:6;
uint32_t dsr_imp:1;
uint32_t read_blk_misalign:1;
uint32_t write_blk_misalign:1;
uint32_t read_bl_partial:1;
uint16_t read_bl_len:4;
uint16_t ccc:12;
uint8_t tran_speed;
uint8_t nsac;
uint8_t taac;
uint8_t reserved120:6;
uint8_t csd_structure:2;
} sd_csd_v2_t;
typedef struct __packed sd_cid {
uint8_t reserved0:1;
uint8_t crc:7;
uint16_t mdt:12;
uint16_t reserved20:4;
uint32_t psn;
uint8_t prv;
uint64_t pnm:40;
uint64_t oid:16;
uint64_t mid:8;
} sd_cid_t;
enum sd_state {
SD_IDLE = 0,
SD_READY,
SD_IDENT,
SD_STBY,
SD_TRAN,
SD_DATA,
SD_RCV,
SD_PRG,
SD_DIS,
/* NON STANDARD USED FOR IMPLEMENTING INIT MACHINE */
SD_ACMD41,
SD_CMD11,
SD_CMD2,
SD_CMD3,
SD_CMD8
};
static volatile struct {
uint16_t rca;
uint8_t version:1;
uint8_t s18r:1;
uint8_t s18a:1;
uint8_t hcs:1;
uint8_t ccs:1;
uint8_t send_if:1;
uint8_t ack_voltage:1;
uint8_t ACMD:1;
uint8_t sd_or_mmc:1;
volatile enum sd_state state;
struct sd_csd_v1 csd;
uint8_t bus_width;
uint8_t timeout;
uint8_t error;
struct sdio_cmd last_cmd;
uint32_t status_reg;
struct sd_cid cid;
} g_sd_card;
enum card_status_bit_type {
ERROR_BIT,
STATUS_BIT
};
struct card_status_bit {
uint32_t mask;
enum card_status_bit_type type;
};
struct card_status_bit card_status[] = {
{CARD_STATUS_OUT_OF_RANGE, ERROR_BIT},
{CARD_STATUS_ADDRESS_ERROR, ERROR_BIT},
{CARD_STATUS_BLOCK_LEN_ERROR, ERROR_BIT},
{CARD_STATUS_ERASE_SEQ_ERROR, ERROR_BIT},
{CARD_STATUS_ERASE_PARAM, ERROR_BIT},
{CARD_STATUS_WP_VIOLATION, ERROR_BIT},
{CARD_STATUS_CARD_IS_LOCKED, STATUS_BIT},
{CARD_STATUS_LOCK_UNLOCK_FAILED, ERROR_BIT},
{CARD_STATUS_COM_CRC_ERROR, ERROR_BIT},
{CARD_STATUS_ILLEGAL_COMMAND, ERROR_BIT},
{CARD_STATUS_CARD_ECC_FAILED, ERROR_BIT},
{CARD_STATUS_CC_ERROR, ERROR_BIT},
{CARD_STATUS_ERROR, ERROR_BIT},
{CARD_STATUS_CSD_OVERWRITE, ERROR_BIT},
{CARD_STATUS_WP_ERASE_SKIP, ERROR_BIT},
{CARD_STATUS_CARD_ECC_DISABLED, STATUS_BIT},
{CARD_STATUS_ERASE_RESET, STATUS_BIT},
{CARD_STATUS_CURRENT_STATE, STATUS_BIT},
{CARD_STATUS_READY_FOR_DATA, STATUS_BIT},
{CARD_STATUS_APP_CMD, STATUS_BIT},
{CARD_STATUS_AKE_SEQ_ERROR, ERROR_BIT}
};
struct card_status_bit card_status_r6[] = {
{CARD_STATUS_R6_COM_CRC_ERROR, ERROR_BIT},
{CARD_STATUS_R6_ILLEGAL_COMMAND, ERROR_BIT},
{CARD_STATUS_R6_ERROR, ERROR_BIT},
{CARD_STATUS_CURRENT_STATE, STATUS_BIT},
{CARD_STATUS_READY_FOR_DATA, STATUS_BIT},
{CARD_STATUS_APP_CMD, STATUS_BIT},
{CARD_STATUS_AKE_SEQ_ERROR, ERROR_BIT}
};
#if DEBUG_LVL >= 1
char error_strings[][20] = {
"",
"",
"",
"AKE_SEQ_ERROR",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"WP_ERASE_SKIP",
"CSD_OVERWRITE",
"",
"",
"ERROR",
"CC_ERROR",
"CARD_ECC_FAILED",
"ILLEGAL_COMMAND",
"COM_CRC_ERROR",
"LOCK_UNLOCK_FAILED",
"",
"WP_VIOLATION",
"ERASE_PARAM",
"ERASE_SEQ_ERROR",
"BLOCK_LEN_ERROR",
"ADDRESS_ERROR",
"OUT_OF_RANGE",
};
#endif
#endif