Mercurial > ~darius > hgwebdir.cgi > stm32temp
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 *