# HG changeset patch # User Daniel O'Connor # Date 1365082711 -37800 # Node ID d7207a9d3c3b6624e9948dfff54b998c2b58fafd # Parent ace431a0d0f55df19e386cfd2a4fdbfc67135965 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). diff -r ace431a0d0f5 -r d7207a9d3c3b BSDmakefile --- a/BSDmakefile Wed Apr 03 23:34:20 2013 +1030 +++ b/BSDmakefile Fri Apr 05 00:08:31 2013 +1030 @@ -21,6 +21,8 @@ tempctrl.c \ touch.c +#SRCS+= ccsbcs.c + STM32LIBS= usart gpio rcc rtc pwr bkp fsmc spi tim i2c crc sdio dma .for f in ${STM32LIBS} diff -r ace431a0d0f5 -r d7207a9d3c3b fatfs/ffconf.h --- a/fatfs/ffconf.h Wed Apr 03 23:34:20 2013 +1030 +++ b/fatfs/ffconf.h Fri Apr 05 00:08:31 2013 +1030 @@ -20,7 +20,7 @@ / data transfer. This reduces memory consumption 512 bytes each file object. */ -#define _FS_READONLY 01/* 0:Read/Write or 1:Read only */ +#define _FS_READONLY 0/* 0:Read/Write or 1:Read only */ /* Setting _FS_READONLY to 1 defines read only configuration. This removes / writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, / f_truncate and useless f_getfree. */ diff -r ace431a0d0f5 -r d7207a9d3c3b fatfs_sd.c --- 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 #include #include +#include +#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 * diff -r ace431a0d0f5 -r d7207a9d3c3b sd.c --- 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]); + } +} diff -r ace431a0d0f5 -r d7207a9d3c3b stm32_eval.h --- a/stm32_eval.h Wed Apr 03 23:34:20 2013 +1030 +++ b/stm32_eval.h Fri Apr 05 00:08:31 2013 +1030 @@ -20,3 +20,4 @@ void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize); void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize); +