Mercurial > ~darius > hgwebdir.cgi > stm32temp
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]); + } +}