comparison sd.c @ 50:d7207a9d3c3b

Add write support. LFN still broken though. Make sure we wait for the card to be done after a read or write (didn't seem to break reading but hosed writes).
author Daniel O'Connor <darius@dons.net.au>
date Fri, 05 Apr 2013 00:08:31 +1030
parents ace431a0d0f5
children 79c7892d07b3
comparison
equal deleted inserted replaced
49:ace431a0d0f5 50:d7207a9d3c3b
46 #define FAT_SEC(t) (((t) & 0x001f) << 1) 46 #define FAT_SEC(t) (((t) & 0x001f) << 1)
47 47
48 static FATFS fsh; 48 static FATFS fsh;
49 49
50 static void sd_domount(void); 50 static void sd_domount(void);
51 char *sderr2str(SD_Error err);
52 void dump_buf(uint8_t *buf, uint32_t size);
51 53
52 void 54 void
53 sd_init(void) { 55 sd_init(void) {
54 sd_domount(); 56 sd_domount();
55 } 57 }
58 sd_domount(void) { 60 sd_domount(void) {
59 SD_Error err; 61 SD_Error err;
60 FRESULT fserr; 62 FRESULT fserr;
61 63
62 if ((err = SD_Init()) != SD_OK) { 64 if ((err = SD_Init()) != SD_OK) {
63 printf("Failed init: %d\n", err); 65 printf("Failed init: %s\n", sderr2str(err));
64 return; 66 return;
65 } 67 }
66 68
67 if ((fserr = f_mount(0, &fsh)) != FR_OK) { 69 if ((fserr = f_mount(0, &fsh)) != FR_OK) {
68 printf("Unable to mount FS\n"); 70 printf("Unable to mount FS\n");
80 } 82 }
81 83
82 if (!strcmp(argv[0], "info")) { 84 if (!strcmp(argv[0], "info")) {
83 SD_CardInfo cardinfo; 85 SD_CardInfo cardinfo;
84 if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) { 86 if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) {
85 printf("Get card info failed: %d\r\b", err); 87 printf("Get card info failed: %s\r\b", sderr2str(err));
86 } else { 88 } else {
87 printf("Mfg ID %" PRIu8 ", OEM %" PRIu16 ", Prod1 %" PRIu32 ", Prod2 %" PRIu8 ", Rev %" PRIu8 ", SN %" PRIu32 ", Mfg %" PRIu16 "\n", 89 printf("Mfg ID %" PRIu8 ", OEM %" PRIu16 ", Prod1 %" PRIu32 ", Prod2 %" PRIu8 ", Rev %" PRIu8 ", SN %" PRIu32 ", Mfg %" PRIu16 "\n",
88 cardinfo.SD_cid.ManufacturerID, cardinfo.SD_cid.OEM_AppliID, 90 cardinfo.SD_cid.ManufacturerID, cardinfo.SD_cid.OEM_AppliID,
89 cardinfo.SD_cid.ProdName1, cardinfo.SD_cid.ProdName2, 91 cardinfo.SD_cid.ProdName1, cardinfo.SD_cid.ProdName2,
90 cardinfo.SD_cid.ProdRev, cardinfo.SD_cid.ProdSN, 92 cardinfo.SD_cid.ProdRev, cardinfo.SD_cid.ProdSN,
91 cardinfo.SD_cid.ManufactDate); 93 cardinfo.SD_cid.ManufactDate);
92 printf("Capacity %" PRIu32 ", blocksize %" PRIu32 "\n", cardinfo.CardCapacity, cardinfo.CardBlockSize); 94 printf("Capacity %" PRIu32 ", blocksize %" PRIu32 "\n", cardinfo.CardCapacity, cardinfo.CardBlockSize);
93 } 95 }
94 } else if (!strcmp(argv[0], "mount")) { 96 } else if (!strcmp(argv[0], "mount")) {
95 sd_domount(); 97 sd_domount();
96 } else if (!strcmp(argv[0], "read")) { 98 } else if (!strcmp(argv[0], "rdb")) {
97 uint32_t addr; 99 uint32_t addr;
98 uint8_t *buf; 100 uint8_t *buf;
99 uint32_t i; 101 uint32_t i;
100 102
101 if (argc != 2) { 103 if (argc != 2) {
109 return; 111 return;
110 } 112 }
111 113
112 /* If passed values not modulo 512 it hangs */ 114 /* If passed values not modulo 512 it hangs */
113 if ((err = SD_ReadBlock(buf, addr * SD_BLOCK_SIZE, SD_BLOCK_SIZE)) != SD_OK) { 115 if ((err = SD_ReadBlock(buf, addr * SD_BLOCK_SIZE, SD_BLOCK_SIZE)) != SD_OK) {
114 printf("Read block returned %d\n", err); 116 printf("Read block returned %s\n", sderr2str(err));
115 goto read_exit; 117 goto read_exit;
116 } 118 }
117 119
118 #ifdef SD_DMA_MODE 120 #ifdef SD_DMA_MODE
119 if ((err = SD_WaitReadOperation()) != SD_OK) { 121 if ((err = SD_WaitReadOperation()) != SD_OK) {
120 printf("Wait returned %d\n", err); 122 printf("Wait returned %s\n", sderr2str(err));
121 goto read_exit; 123 goto read_exit;
122 } 124 }
123 #endif 125 #endif
124 while(SD_GetStatus() != SD_TRANSFER_OK) 126 while(SD_GetStatus() != SD_TRANSFER_OK)
125 ; 127 ;
126 128
127 for (i = 0; i < SD_BLOCK_SIZE; i += 16) { 129 dump_buf(buf, SD_BLOCK_SIZE);
128 printf("0x%04lx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
129 buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7],
130 buf[i + 8], buf[i + 9], buf[i + 10], buf[i + 11], buf[i + 12], buf[i + 13], buf[i + 14], buf[i + 15]);
131 }
132 130
133 read_exit: 131 read_exit:
132 free(buf);
133 } else if (!strcmp(argv[0], "wrb")) {
134 uint32_t addr;
135 uint8_t *buf;
136 uint32_t i;
137
138 if (argc < 3) {
139 printf("Block to read and/or fill value(s) not specified\n");
140 return;
141 }
142 addr = atoi(argv[1]);
143
144 if ((buf = malloc(SD_BLOCK_SIZE)) == NULL) {
145 printf("Unable to allocate buffer\n");
146 return;
147 }
148
149 for (i = 0; i < SD_BLOCK_SIZE; i++) {
150 //buf[i] = atoi(argv[(i % (argc - 2)) + 2]);
151 if (i < argc - 2)
152 buf[i] = atoi(argv[i + 2]);
153 else
154 buf[i] = 0;
155 }
156
157 /* If passed values not modulo 512 it hangs */
158 if ((err = SD_WriteBlock(buf, addr * SD_BLOCK_SIZE, SD_BLOCK_SIZE)) != SD_OK) {
159 printf("Write block returned %s\n", sderr2str(err));
160 goto write_exit;
161 }
162
163 #ifdef SD_DMA_MODE
164 if ((err = SD_WaitWriteOperation()) != SD_OK) {
165 printf("Wait returned %s\n", sderr2str(err));
166 goto write_exit;
167 }
168 #endif
169 while(SD_GetStatus() != SD_TRANSFER_OK)
170 ;
171
172 write_exit:
134 free(buf); 173 free(buf);
135 } else if (!strcmp(argv[0], "erase")) { 174 } else if (!strcmp(argv[0], "erase")) {
136 uint32_t addr; 175 uint32_t addr;
137 176
138 if (argc != 2) { 177 if (argc != 2) {
140 return; 179 return;
141 } 180 }
142 addr = atoi(argv[1]); 181 addr = atoi(argv[1]);
143 182
144 if ((err = SD_Erase(addr * SD_BLOCK_SIZE, (addr + 1) * SD_BLOCK_SIZE)) != SD_OK) { 183 if ((err = SD_Erase(addr * SD_BLOCK_SIZE, (addr + 1) * SD_BLOCK_SIZE)) != SD_OK) {
145 printf("Erase block returned %d\n", err); 184 printf("Erase block returned %s\n", sderr2str(err));
146 goto read_exit; 185 goto read_exit;
147 } 186 }
148 187
149 #ifdef SD_DMA_MODE 188 #ifdef SD_DMA_MODE
150 if ((err = SD_WaitReadOperation()) != SD_OK) { 189 if ((err = SD_WaitReadOperation()) != SD_OK) {
151 printf("Wait returned %d\n", err); 190 printf("Wait returned %s\n", sderr2str(err));
152 goto read_exit; 191 goto read_exit;
153 } 192 }
154 #endif 193 #endif
155 while(SD_GetStatus() != SD_TRANSFER_OK) 194 while(SD_GetStatus() != SD_TRANSFER_OK)
156 ; 195 ;
157 printf("Erased OK\n"); 196 printf("Erased OK\n");
197 } else if (!strcmp(argv[0], "mkfs")) {
198 FRESULT fserr;
199 if ((fserr = f_mkfs(0, 0, 0)) != FR_OK) {
200 printf("Unable to mkfs: %d\n", fserr);
201 }
158 } else if (!strcmp(argv[0], "ls")) { 202 } else if (!strcmp(argv[0], "ls")) {
159 FRESULT fserr; 203 FRESULT fserr;
160 DIR d; 204 DIR d;
161 FILINFO fno; 205 FILINFO fno;
162 char *fn; 206 char *fn;
163 char label[12]; 207 char label[12];
164 DWORD sn; 208 DWORD sn;
165 209
166 if ((fserr = f_getlabel("", label, &sn)) != FR_OK) { 210 if ((fserr = f_getlabel("", label, &sn)) != FR_OK) {
167 printf("Unable to read label\n"); 211 printf("Unable to read label: %d\n", fserr);
168 } else { 212 } else {
169 printf("Label: %s Serial: %d\n", label, sn); 213 printf("Label: %s Serial: %d\n", label, sn);
170 } 214 }
171 215
172 if ((fserr = f_opendir(&d, argc == 1 ? "\\" : argv[1])) != FR_OK) { 216 if ((fserr = f_opendir(&d, argc == 1 ? "\\" : argv[1])) != FR_OK) {
210 } 254 }
211 255
212 while ((tmp = f_gets(buf, sizeof(buf), &f)) != NULL) { 256 while ((tmp = f_gets(buf, sizeof(buf), &f)) != NULL) {
213 puts(tmp); 257 puts(tmp);
214 } 258 }
259
260 f_close(&f);
261
262 } else if (!strcmp(argv[0], "wr")) {
263 FRESULT fserr;
264 FIL f;
265
266 if (argc != 3) {
267 printf("No file and/or text given\n");
268 return;
269 }
270
271 if ((fserr = f_open(&f, argv[1], FA_WRITE | FA_OPEN_ALWAYS)) != FR_OK) {
272 printf("Failed to open file: %d\n", fserr);
273 return;
274 }
275
276 if ((fserr = f_lseek(&f, f_size(&f))) != FR_OK) {
277 printf("Failed to seek to end of file: %d\n", fserr);
278 goto wr_out;
279 }
280
281 f_puts(argv[2], &f);
282 f_putc('\n', &f);
283 wr_out:
284 f_close(&f);
285 } else if (!strcmp(argv[0], "rm")) {
286 FRESULT fserr;
287
288 if (argc != 2) {
289 printf("No file given\n");
290 return;
291 }
292
293 if ((fserr = f_unlink(argv[1])) != FR_OK) {
294 printf("Failed to remove file: %d\n", fserr);
295 return;
296 }
215 } else { 297 } else {
216 printf("Unknown command\n"); 298 printf("Unknown command\n");
217 } 299 }
218 } 300 }
219 301
292 374
293 uint32_t SD_DMAEndOfTransferStatus(void) { 375 uint32_t SD_DMAEndOfTransferStatus(void) {
294 return (uint32_t)DMA_GetFlagStatus(DMA2_FLAG_TC4); 376 return (uint32_t)DMA_GetFlagStatus(DMA2_FLAG_TC4);
295 } 377 }
296 378
297 379 char *
298 380 sderr2str(SD_Error err) {
381 switch (err) {
382 case SD_CMD_CRC_FAIL:
383 return "CMD_CRC_FAIL";
384 case SD_DATA_CRC_FAIL:
385 return "DATA_CRC_FAIL";
386 case SD_CMD_RSP_TIMEOUT:
387 return "CMD_RSP_TIMEOUT";
388 case SD_DATA_TIMEOUT:
389 return "DATA_TIMEOUT";
390 case SD_TX_UNDERRUN:
391 return "TX_UNDERRUN";
392 case SD_RX_OVERRUN:
393 return "RX_OVERRUN";
394 case SD_START_BIT_ERR:
395 return "START_BIT_ERR";
396 case SD_CMD_OUT_OF_RANGE:
397 return "CMD_OUT_OF_RANGE";
398 case SD_ADDR_MISALIGNED:
399 return "ADDR_MISALIGNED";
400 case SD_BLOCK_LEN_ERR:
401 return "BLOCK_LEN_ERR";
402 case SD_ERASE_SEQ_ERR:
403 return "ERASE_SEQ_ERR";
404 case SD_BAD_ERASE_PARAM:
405 return "BAD_ERASE_PARAM";
406 case SD_WRITE_PROT_VIOLATION:
407 return "WRITE_PROT_VIOLATION";
408 case SD_LOCK_UNLOCK_FAILED:
409 return "LOCK_UNLOCK_FAILED";
410 case SD_COM_CRC_FAILED:
411 return "COM_CRC_FAILED";
412 case SD_ILLEGAL_CMD:
413 return "ILLEGAL_CMD";
414 case SD_CARD_ECC_FAILED:
415 return "CARD_ECC_FAILED";
416 case SD_CC_ERROR:
417 return "CC_ERROR";
418 case SD_GENERAL_UNKNOWN_ERROR:
419 return "GENERAL_UNKNOWN_ERROR";
420 case SD_STREAM_READ_UNDERRUN:
421 return "STREAM_READ_UNDERRUN";
422 case SD_STREAM_WRITE_OVERRUN:
423 return "STREAM_WRITE_OVERRUN";
424 case SD_CID_CSD_OVERWRITE:
425 return "OVERWRITE";
426 case SD_WP_ERASE_SKIP:
427 return "WP_ERASE_SKIP";
428 case SD_CARD_ECC_DISABLED:
429 return "CARD_ECC_DISABLED";
430 case SD_ERASE_RESET:
431 return "ERASE_RESET";
432 case SD_AKE_SEQ_ERROR:
433 return "AKE_SEQ_ERROR";
434 case SD_INVALID_VOLTRANGE:
435 return "INVALID_VOLTRANGE";
436 case SD_ADDR_OUT_OF_RANGE:
437 return "ADDR_OUT_OF_RANGE";
438 case SD_SWITCH_ERROR:
439 return "SWITCH_ERROR";
440 case SD_SDIO_DISABLED:
441 return "SDIO_DISABLED";
442 case SD_SDIO_FUNCTION_BUSY:
443 return "SDIO_FUNCTION_BUSY";
444 case SD_SDIO_FUNCTION_FAILED:
445 return "SDIO_FUNCTION_FAILED";
446 case SD_SDIO_UNKNOWN_FUNCTION:
447 return "SDIO_UNKNOWN_FUNCTION";
448 case SD_INTERNAL_ERROR:
449 return "INTERNAL_ERROR";
450 case SD_NOT_CONFIGURED:
451 return "NOT_CONFIGURED";
452 case SD_REQUEST_PENDING:
453 return "REQUEST_PENDING";
454 case SD_REQUEST_NOT_APPLICABLE:
455 return "REQUEST_NOT_APPLICABLE";
456 case SD_INVALID_PARAMETER:
457 return "INVALID_PARAMETER";
458 case SD_UNSUPPORTED_FEATURE:
459 return "UNSUPPORTED_FEATURE";
460 case SD_UNSUPPORTED_HW:
461 return "UNSUPPORTED_HW";
462 case SD_ERROR:
463 return "ERROR";
464 case SD_OK:
465 return "OK";
466 default:
467 return "Unknown";
468 }
469 }
470
471
472 void dump_buf(uint8_t *buf, uint32_t size) {
473 uint32_t i;
474
475 for (i = 0; i < size; i += 16) {
476 printf("0x%04lx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
477 buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7],
478 buf[i + 8], buf[i + 9], buf[i + 10], buf[i + 11], buf[i + 12], buf[i + 13], buf[i + 14], buf[i + 15]);
479 }
480 }