From b43c3cee2d92416919439b5ed485bee96ed834cb Mon Sep 17 00:00:00 2001 From: Robert Fancsik Date: Mon, 16 Apr 2018 11:22:38 +0200 Subject: [PATCH] Fix for sdio_write_sectors The issue was found by using f_mkdir("directory_name"). The function always returned FR_DISK_ERR due to an unhadled case in sdio_write_sectors(). According to this documentation: http://www.convict.lu/pdf/ProdManualSDCardv1.9.pdf#page=92 stop transmission command should be sent after writing multiple blocks. This patch fixes this bug also adds a test case for it. --- examples/fatfs/main.c | 14 ++++++++++++++ extras/sdio/sdio.c | 22 +++++++++------------- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/examples/fatfs/main.c b/examples/fatfs/main.c index cb0dda8..6bf2c44 100644 --- a/examples/fatfs/main.c +++ b/examples/fatfs/main.c @@ -12,6 +12,7 @@ #define CS_GPIO_PIN 2 #define TEST_FILENAME "/test_loooong_filename.txt" +#define TEST_DIRECTORYNAME "my_directory" #define TEST_CONTENTS "Hello! It's FatFs on esp8266 with ESP Open RTOS!" #define READBUF_SIZE 256 #define DELAY_MS 3000 @@ -69,6 +70,19 @@ void check_fatfs() if (failed(f_chdrive(vol))) return; + // Create a directory if it not exists + FILINFO info; + if (failed(f_stat(TEST_DIRECTORYNAME, &info)) && info.fattrib & AM_DIR) + { + printf("f_mkdir (\"%s\")\n", TEST_DIRECTORYNAME); + if (failed(f_mkdir(TEST_DIRECTORYNAME))) + return; + } + else + { + printf("\"%s\" directory already exists\n", TEST_DIRECTORYNAME); + } + FIL f; // Create test file printf("f_open(&f, \"%s\", FA_WRITE | FA_CREATE_ALWAYS)", TEST_FILENAME); diff --git a/extras/sdio/sdio.c b/extras/sdio/sdio.c index e601416..1f273fa 100644 --- a/extras/sdio/sdio.c +++ b/extras/sdio/sdio.c @@ -394,16 +394,10 @@ sdio_error_t sdio_write_sectors(sdio_card_t *card, uint32_t sector, uint8_t *src if (card->type != SDIO_TYPE_SDHC) sector <<= 9; - if (count == 1) - { - // single block - if (command(card, CMD24, sector)) - return set_error(card, SDIO_ERR_IO); - return set_error(card, write_data_block(card, TOKEN_SINGLE_TRAN, src)); - } + bool multi = count != 1; // send pre-erase count - if ((card->type == SDIO_TYPE_SD1 + if (multi && (card->type == SDIO_TYPE_SD1 || card->type == SDIO_TYPE_SD2 || card->type == SDIO_TYPE_SDHC) && app_command(card, ACMD23, count)) @@ -411,16 +405,19 @@ sdio_error_t sdio_write_sectors(sdio_card_t *card, uint32_t sector, uint8_t *src return set_error(card, SDIO_ERR_IO); } - if (command(card, CMD25, sector)) + if (command(card, multi ? CMD25 : CMD24, sector)) return set_error(card, SDIO_ERR_IO); while (count--) { - if (write_data_block(card, TOKEN_MULTI_TRAN, src) != SDIO_ERR_NONE) - return card->error; + if (write_data_block(card, multi ? TOKEN_MULTI_TRAN : TOKEN_SINGLE_TRAN, src) != SDIO_ERR_NONE){ + return card->error; + } src += SDIO_BLOCK_SIZE; } - spi_transfer_8(BUS, TOKEN_STOP_TRAN); + + if (multi && command(card, CMD12, 0)) + return set_error(card, SDIO_ERR_IO); return set_error(card, SDIO_ERR_NONE); } @@ -449,4 +446,3 @@ sdio_error_t sdio_erase_sectors(sdio_card_t *card, uint32_t first, uint32_t last return set_error(card, wait() ? SDIO_ERR_NONE : SDIO_ERR_TIMEOUT); } -