diff fatfs_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 590886732da9
line wrap: on
line diff
--- a/fatfs_sd.c	Wed Apr 03 23:34:20 2013 +1030
+++ b/fatfs_sd.c	Fri Apr 05 00:08:31 2013 +1030
@@ -32,21 +32,40 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 
+#include "delay.h"
 #include "stm32f10x.h"
 #include "stm32_eval_sdio_sd.h"
 #include "diskio.h"
 
+#if 0
+#define DEBUG(fmt, ...) printf("%s: " fmt, __FUNCTION__, ## __VA_ARGS__)
+#else
+#define DEBUG(...)
+#endif
+
+char *sderr2str(SD_Error err);
+void dump_buf(uint8_t *buf, uint32_t size);
+
+static SD_CardInfo cardinfo;
+
 DSTATUS
 disk_initialize(BYTE pdrv) {
     SD_Error err;
     
+    DEBUG("disk_initialize(%d)\n", pdrv);
+    
     /* Only have 1 disk */
     if (pdrv != 0)
 	return STA_NOINIT;
     
     if ((err = SD_Init()) != SD_OK) {
-	printf("Failed init: %d\r\n", err);
+	printf("Failed init: %s\n", sderr2str(err));
+	return STA_NOINIT;
+    }
+    if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) {
+	printf("Get card info failed: %s\n", sderr2str(err));
 	return STA_NOINIT;
     }
 
@@ -55,6 +74,8 @@
 
 DSTATUS
 disk_status(BYTE pdrv) {
+    DEBUG("disk_status(%d)\n", pdrv);
+    
     if (pdrv != 0)
 	return STA_NOINIT;
 
@@ -65,6 +86,8 @@
 disk_read(BYTE pdrv, BYTE *buff, DWORD sector, BYTE count) {
     SD_Error err;
     
+    DEBUG("disk_read(%d, 0x%08x, %d, %d)\n", pdrv, buff, sector, count);
+
     if (pdrv != 0)
 	return STA_NOINIT;
 
@@ -73,29 +96,61 @@
     else
 	err = SD_ReadMultiBlocks(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE, count);
     
+#ifdef SD_DMA_MODE
+    if ((err = SD_WaitReadOperation()) != SD_OK) {
+	printf("Wait returned %s\n", sderr2str(err));
+	goto read_exit;
+    }
+#endif
     if (err != SD_OK) {
-	printf("Read failed: %d\r\n", err);
+	printf("Read failed: %s\n", sderr2str(err));
 	return STA_NOINIT;
     }
     
+    while(SD_GetStatus() != SD_TRANSFER_OK)
+	;
+
     return RES_OK;
 }
 
 DRESULT
 disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, BYTE count) {
+    SD_Error err;
+    
+    DEBUG("disk_write(%d, 0x%08x, %d, %d)\n", pdrv, buff, sector, count);
     if (pdrv != 0)
-	return STA_NOINIT;
+	return RES_NOTRDY;
+
+    if (count == 1)
+	err = SD_WriteBlock(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE);
+    else
+	err = SD_WriteMultiBlocks(buff, sector * SD_BLOCK_SIZE, SD_BLOCK_SIZE, count);
 
-    return RES_WRPRT;
+#ifdef SD_DMA_MODE
+    if ((err = SD_WaitReadOperation()) != SD_OK) {
+	printf("Wait returned %s\n", sderr2str(err));
+	goto read_exit;
+    }
+#endif
+    if (err != SD_OK) {
+	printf("Write failed: %s\n", sderr2str(err));
+	return RES_ERROR;
+    }
+    
+    while(SD_GetStatus() != SD_TRANSFER_OK)
+	;
+    
+    return RES_OK;
 }
 
 DRESULT
 disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) {
     WORD *wd;
     DWORD *dwd;
-    SD_CardInfo cardinfo;
     SD_Error err;
     
+    DEBUG("disk_ioctl(%d, %d, ...)\n", pdrv, cmd);
+    
     wd = buff;
     dwd = buff;
     
@@ -103,38 +158,27 @@
 	return STA_NOINIT;
     switch (cmd) {
 	case CTRL_SYNC:
-	    printf("Sync\r\n");
+	    DEBUG("Sync\n");
 	    break;
 
 	case GET_SECTOR_SIZE:
-	    printf("Get sector size\r\n");
 	    *wd = SD_BLOCK_SIZE;
+	    DEBUG("Get sector size (%d)\n", *wd);
 	    break;
 	    
 	case GET_SECTOR_COUNT:
-	    printf("Get sector count\r\n");
-
-	    if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) {
-		printf("Get card info failed: %d\r\b", err);
-		return RES_ERROR;
-	    }
 	    *dwd = cardinfo.CardCapacity / SD_BLOCK_SIZE;
+	    DEBUG("Get sector count (%d)\n", *dwd);
 	    break;
 	    
 	case GET_BLOCK_SIZE:
-	    printf("Get block size\r\n");
-
-	    if ((err = SD_GetCardInfo(&cardinfo)) != SD_OK) {
-		printf("Get card info failed: %d\r\b", err);
-		return RES_ERROR;
-	    }
-	    
 	    /* FatFS wants log2(blocksize) */
 	    *dwd = 0;
 	    while (cardinfo.CardBlockSize > 0) {
-		*dwd++;
+		*dwd = *dwd + 1;
 		cardinfo.CardBlockSize >>= 1;
 	    }
+	    DEBUG("Get block size (%d)\n", *dwd);
 	    break;
 
 	case CTRL_ERASE_SECTOR:
@@ -155,7 +199,20 @@
 */
 DWORD
 get_fattime(void) {
-    return 0;
+    struct tm now;
+    time_t t;
+    DWORD res;
+
+    t = time(NULL);
+    localtime_r(&t, &now);
+    res = ((now.tm_year - 80) << 25 |
+	   ((now.tm_mon + 1) << 21) |
+	   (now.tm_mday << 16) |
+	   (now.tm_hour << 11) |
+	   (now.tm_min << 5) |
+	   (now.tm_sec >> 1));
+
+    return res;
 }
 
 void *