diff 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
line wrap: on
line diff
--- a/sd.c	Wed Apr 03 23:34:20 2013 +1030
+++ b/sd.c	Fri Apr 05 00:08:31 2013 +1030
@@ -48,6 +48,8 @@
 static FATFS fsh;
 
 static void sd_domount(void);
+char *sderr2str(SD_Error err);
+void dump_buf(uint8_t *buf, uint32_t size);
 
 void
 sd_init(void) {
@@ -60,7 +62,7 @@
     FRESULT fserr;
 
     if ((err = SD_Init()) != SD_OK) {
-	printf("Failed init: %d\n", err);
+	printf("Failed init: %s\n", sderr2str(err));
 	return;
     }
     
@@ -82,7 +84,7 @@
     if (!strcmp(argv[0], "info")) {
 	SD_CardInfo cardinfo;
 	if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) {
-	    printf("Get card info failed: %d\r\b", err);
+	    printf("Get card info failed: %s\r\b", sderr2str(err));
 	} else {
 	    printf("Mfg ID %" PRIu8 ", OEM %" PRIu16 ", Prod1 %" PRIu32 ", Prod2 %" PRIu8 ", Rev %" PRIu8 ", SN %" PRIu32 ", Mfg %" PRIu16 "\n",
 		   cardinfo.SD_cid.ManufacturerID, cardinfo.SD_cid.OEM_AppliID,
@@ -93,7 +95,7 @@
 	}
     } else if (!strcmp(argv[0], "mount")) {
 	sd_domount();
-    } else if (!strcmp(argv[0], "read")) {
+    } else if (!strcmp(argv[0], "rdb")) {
 	uint32_t addr;
 	uint8_t *buf;
 	uint32_t i;
@@ -111,26 +113,63 @@
 	
 	/* If passed values not modulo 512 it hangs */
 	if ((err = SD_ReadBlock(buf, addr * SD_BLOCK_SIZE, SD_BLOCK_SIZE)) != SD_OK) {
-	    printf("Read block returned %d\n", err);
+	    printf("Read block returned %s\n", sderr2str(err));
 	    goto read_exit;
 	}
 	
 #ifdef SD_DMA_MODE
 	if ((err = SD_WaitReadOperation()) != SD_OK) {
-	    printf("Wait returned %d\n", err);
+	    printf("Wait returned %s\n", sderr2str(err));
 	    goto read_exit;
 	}
 #endif
 	while(SD_GetStatus() != SD_TRANSFER_OK)
 	    ;
 
-	for (i = 0; i < SD_BLOCK_SIZE; i += 16) {
-	    printf("0x%04lx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
-		   buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7],
-		   buf[i + 8], buf[i + 9], buf[i + 10], buf[i + 11], buf[i + 12], buf[i + 13], buf[i + 14], buf[i + 15]);
+	dump_buf(buf, SD_BLOCK_SIZE);
+	
+      read_exit:
+	free(buf);
+    } else if (!strcmp(argv[0], "wrb")) {
+	uint32_t addr;
+	uint8_t *buf;
+	uint32_t i;
+	
+	if (argc < 3) {
+	    printf("Block to read and/or fill value(s) not specified\n");
+	    return;
+	}
+	addr = atoi(argv[1]);
+
+	if ((buf = malloc(SD_BLOCK_SIZE)) == NULL) {
+	    printf("Unable to allocate buffer\n");
+	    return;
 	}
 	
-      read_exit:
+	for (i = 0; i < SD_BLOCK_SIZE; i++) {
+	    //buf[i] = atoi(argv[(i % (argc - 2)) + 2]);
+	    if (i < argc - 2)
+		buf[i] = atoi(argv[i + 2]);
+	    else
+		buf[i] = 0;
+	}
+
+	/* If passed values not modulo 512 it hangs */
+	if ((err = SD_WriteBlock(buf, addr * SD_BLOCK_SIZE, SD_BLOCK_SIZE)) != SD_OK) {
+	    printf("Write block returned %s\n", sderr2str(err));
+	    goto write_exit;
+	}
+	
+#ifdef SD_DMA_MODE
+	if ((err = SD_WaitWriteOperation()) != SD_OK) {
+	    printf("Wait returned %s\n", sderr2str(err));
+	    goto write_exit;
+	}
+#endif
+	while(SD_GetStatus() != SD_TRANSFER_OK)
+	    ;
+
+      write_exit:
 	free(buf);
     } else if (!strcmp(argv[0], "erase")) {
 	uint32_t addr;
@@ -142,19 +181,24 @@
 	addr = atoi(argv[1]);
 	
 	if ((err = SD_Erase(addr * SD_BLOCK_SIZE, (addr + 1) * SD_BLOCK_SIZE)) != SD_OK) {
-	    printf("Erase block returned %d\n", err);
+	    printf("Erase block returned %s\n", sderr2str(err));
 	    goto read_exit;
 	}
 	
 #ifdef SD_DMA_MODE
 	if ((err = SD_WaitReadOperation()) != SD_OK) {
-	    printf("Wait returned %d\n", err);
+	    printf("Wait returned %s\n", sderr2str(err));
 	    goto read_exit;
 	}
 #endif
 	while(SD_GetStatus() != SD_TRANSFER_OK)
 	    ;
 	printf("Erased OK\n");
+    } else if (!strcmp(argv[0], "mkfs")) {
+	FRESULT fserr;
+	if ((fserr = f_mkfs(0, 0, 0)) != FR_OK) {
+	    printf("Unable to mkfs: %d\n", fserr);
+	}
     } else if (!strcmp(argv[0], "ls")) {
 	FRESULT fserr;
 	DIR d;
@@ -164,7 +208,7 @@
 	DWORD sn;
 	
 	if ((fserr = f_getlabel("", label, &sn)) != FR_OK) {
-	    printf("Unable to read label\n");
+	    printf("Unable to read label: %d\n", fserr);
 	} else {
 	    printf("Label: %s Serial: %d\n", label, sn);
 	}
@@ -212,6 +256,44 @@
 	while ((tmp = f_gets(buf, sizeof(buf), &f)) != NULL) {
 	    puts(tmp);
 	}
+
+	f_close(&f);
+	
+    } else if (!strcmp(argv[0], "wr")) {
+	FRESULT fserr;
+	FIL f;
+	
+	if (argc != 3) {
+	    printf("No file and/or text given\n");
+	    return;
+	}
+	
+	if ((fserr = f_open(&f, argv[1], FA_WRITE | FA_OPEN_ALWAYS)) != FR_OK) {
+	    printf("Failed to open file: %d\n", fserr);
+	    return;
+	}
+
+	if ((fserr = f_lseek(&f, f_size(&f))) != FR_OK) {
+	    printf("Failed to seek to end of file: %d\n", fserr);
+	    goto wr_out;
+	}
+	
+	f_puts(argv[2], &f);
+	f_putc('\n', &f);
+      wr_out:
+	f_close(&f);
+    } else if (!strcmp(argv[0], "rm")) {
+	FRESULT fserr;
+	
+	if (argc != 2) {
+	    printf("No file given\n");
+	    return;
+	}
+	
+	if ((fserr = f_unlink(argv[1])) != FR_OK) {
+	    printf("Failed to remove file: %d\n", fserr);
+	    return;
+	}
     } else {
 	printf("Unknown command\n");
     }
@@ -294,5 +376,105 @@
   return (uint32_t)DMA_GetFlagStatus(DMA2_FLAG_TC4);
 }
 
+char *
+sderr2str(SD_Error err) {
+    switch (err) {
+	case SD_CMD_CRC_FAIL:
+	    return "CMD_CRC_FAIL";
+	case SD_DATA_CRC_FAIL:
+	    return "DATA_CRC_FAIL";
+	case SD_CMD_RSP_TIMEOUT:
+	    return "CMD_RSP_TIMEOUT";
+	case SD_DATA_TIMEOUT:
+	    return "DATA_TIMEOUT";
+	case SD_TX_UNDERRUN:
+	    return "TX_UNDERRUN";
+	case SD_RX_OVERRUN:
+	    return "RX_OVERRUN";
+	case SD_START_BIT_ERR:
+	    return "START_BIT_ERR";
+	case SD_CMD_OUT_OF_RANGE:
+	    return "CMD_OUT_OF_RANGE";
+	case SD_ADDR_MISALIGNED:
+	    return "ADDR_MISALIGNED";
+	case SD_BLOCK_LEN_ERR:
+	    return "BLOCK_LEN_ERR";
+	case SD_ERASE_SEQ_ERR:
+	    return "ERASE_SEQ_ERR";
+	case SD_BAD_ERASE_PARAM:
+	    return "BAD_ERASE_PARAM";
+	case SD_WRITE_PROT_VIOLATION:
+	    return "WRITE_PROT_VIOLATION";
+	case SD_LOCK_UNLOCK_FAILED:
+	    return "LOCK_UNLOCK_FAILED";
+	case SD_COM_CRC_FAILED:
+	    return "COM_CRC_FAILED";
+	case SD_ILLEGAL_CMD:
+	    return "ILLEGAL_CMD";
+	case SD_CARD_ECC_FAILED:
+	    return "CARD_ECC_FAILED";
+	case SD_CC_ERROR:
+	    return "CC_ERROR";
+	case SD_GENERAL_UNKNOWN_ERROR:
+	    return "GENERAL_UNKNOWN_ERROR";
+	case SD_STREAM_READ_UNDERRUN:
+	    return "STREAM_READ_UNDERRUN";
+	case SD_STREAM_WRITE_OVERRUN:
+	    return "STREAM_WRITE_OVERRUN";
+	case SD_CID_CSD_OVERWRITE:
+	    return "OVERWRITE";
+	case SD_WP_ERASE_SKIP:
+	    return "WP_ERASE_SKIP";
+	case SD_CARD_ECC_DISABLED:
+	    return "CARD_ECC_DISABLED";
+	case SD_ERASE_RESET:
+	    return "ERASE_RESET";
+	case SD_AKE_SEQ_ERROR:
+	    return "AKE_SEQ_ERROR";
+	case SD_INVALID_VOLTRANGE:
+	    return "INVALID_VOLTRANGE";
+	case SD_ADDR_OUT_OF_RANGE:
+	    return "ADDR_OUT_OF_RANGE";
+	case SD_SWITCH_ERROR:
+	    return "SWITCH_ERROR";
+	case SD_SDIO_DISABLED:
+	    return "SDIO_DISABLED";
+	case SD_SDIO_FUNCTION_BUSY:
+	    return "SDIO_FUNCTION_BUSY";
+	case SD_SDIO_FUNCTION_FAILED:
+	    return "SDIO_FUNCTION_FAILED";
+	case SD_SDIO_UNKNOWN_FUNCTION:
+	    return "SDIO_UNKNOWN_FUNCTION";
+	case SD_INTERNAL_ERROR:
+	    return "INTERNAL_ERROR";
+	case SD_NOT_CONFIGURED:
+	    return "NOT_CONFIGURED";
+	case SD_REQUEST_PENDING:
+	    return "REQUEST_PENDING";
+	case SD_REQUEST_NOT_APPLICABLE:
+	    return "REQUEST_NOT_APPLICABLE";
+	case SD_INVALID_PARAMETER:
+	    return "INVALID_PARAMETER";
+	case SD_UNSUPPORTED_FEATURE:
+	    return "UNSUPPORTED_FEATURE";
+	case SD_UNSUPPORTED_HW:
+	    return "UNSUPPORTED_HW";
+	case SD_ERROR:
+	    return "ERROR";
+	case SD_OK:
+	    return "OK";
+	default:
+	    return "Unknown";
+    }
+}
 
-
+	
+void dump_buf(uint8_t *buf, uint32_t size) {
+    uint32_t i;
+    
+    for (i = 0; i < size; i += 16) {
+	printf("0x%04lx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
+	       buf[i + 0], buf[i + 1], buf[i + 2], buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7],
+	       buf[i + 8], buf[i + 9], buf[i + 10], buf[i + 11], buf[i + 12], buf[i + 13], buf[i + 14], buf[i + 15]);
+    }
+}