From 7d291b570710351962830b9101cfb7ca234f05d3 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 6 May 2020 23:49:29 +0200 Subject: [PATCH] drivers/mtd_sdard: implement page-wise read() and write() SD cards are usually larger than 4 GiB, so using 32 bit addressing will break once they are filled to a certain extend. Implement read_page() and write_page() which at a page size of 512 should work for SD cards of up to 2 TiB. The read() and write() functions will ignore any offset that is not aligned with the page boundary, so do the same for the new functions, but at least report an error. --- drivers/mtd_sdcard/mtd_sdcard.c | 70 +++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/drivers/mtd_sdcard/mtd_sdcard.c b/drivers/mtd_sdcard/mtd_sdcard.c index a55258974d..1fa1e4eb32 100644 --- a/drivers/mtd_sdcard/mtd_sdcard.c +++ b/drivers/mtd_sdcard/mtd_sdcard.c @@ -29,22 +29,6 @@ #include #include -static int mtd_sdcard_init(mtd_dev_t *mtd); -static int mtd_sdcard_read(mtd_dev_t *mtd, void *dest, uint32_t addr, - uint32_t size); -static int mtd_sdcard_write(mtd_dev_t *mtd, const void *src, uint32_t addr, - uint32_t size); -static int mtd_sdcard_erase(mtd_dev_t *mtd, uint32_t addr, uint32_t size); -static int mtd_sdcard_power(mtd_dev_t *mtd, enum mtd_power_state power); - -const mtd_desc_t mtd_sdcard_driver = { - .init = mtd_sdcard_init, - .read = mtd_sdcard_read, - .write = mtd_sdcard_write, - .erase = mtd_sdcard_erase, - .power = mtd_sdcard_power, -}; - static int mtd_sdcard_init(mtd_dev_t *dev) { DEBUG("mtd_sdcard_init\n"); @@ -79,6 +63,28 @@ static int mtd_sdcard_read(mtd_dev_t *dev, void *buff, uint32_t addr, return -EIO; } +static int mtd_sdcard_read_page(mtd_dev_t *dev, void *buff, uint32_t page, + uint32_t offset, uint32_t size) +{ + DEBUG("mtd_sdcard_read_page: page:%" PRIu32 " offset:%" PRIu32 " size:%" PRIu32 "\n", + page, offset, size); + + if (offset) { + return -ENOTSUP; + } + + mtd_sdcard_t *mtd_sd = (mtd_sdcard_t*)dev; + sd_rw_response_t err; + int res = sdcard_spi_read_blocks(mtd_sd->sd_card, page, + buff, SD_HC_BLOCK_SIZE, + size / SD_HC_BLOCK_SIZE, &err); + + if (err != SD_RW_OK) { + return -EIO; + } + return res * SD_HC_BLOCK_SIZE; +} + static int mtd_sdcard_write(mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size) { @@ -95,6 +101,28 @@ static int mtd_sdcard_write(mtd_dev_t *dev, const void *buff, uint32_t addr, return -EIO; } +static int mtd_sdcard_write_page(mtd_dev_t *dev, const void *buff, uint32_t page, + uint32_t offset, uint32_t size) +{ + DEBUG("mtd_sdcard_write_page: page:%" PRIu32 " offset:%" PRIu32 " size:%" PRIu32 "\n", + page, offset, size); + + if (offset) { + return -ENOTSUP; + } + + mtd_sdcard_t *mtd_sd = (mtd_sdcard_t*)dev; + sd_rw_response_t err; + int res = sdcard_spi_write_blocks(mtd_sd->sd_card, page, + buff, SD_HC_BLOCK_SIZE, + size / SD_HC_BLOCK_SIZE, &err); + + if (err != SD_RW_OK) { + return -EIO; + } + return res * SD_HC_BLOCK_SIZE; +} + static int mtd_sdcard_erase(mtd_dev_t *dev, uint32_t addr, uint32_t size) @@ -121,3 +149,13 @@ static int mtd_sdcard_power(mtd_dev_t *dev, enum mtd_power_state power) (make use of sdcard_spi_params_t.power pin) */ return -ENOTSUP; /* currently not supported */ } + +const mtd_desc_t mtd_sdcard_driver = { + .init = mtd_sdcard_init, + .read = mtd_sdcard_read, + .read_page = mtd_sdcard_read_page, + .write = mtd_sdcard_write, + .write_page = mtd_sdcard_write_page, + .erase = mtd_sdcard_erase, + .power = mtd_sdcard_power, +};