From f738ac66d325b63ed704f857708bd8e1516ed6fb Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 3 Sep 2020 23:38:43 +0200 Subject: [PATCH] drivers/mtd_mci: add MTD wrapper for MCI driver --- drivers/mtd_mci/Makefile | 1 + drivers/mtd_mci/Makefile.dep | 1 + drivers/mtd_mci/mtd_mci.c | 146 +++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 drivers/mtd_mci/Makefile create mode 100644 drivers/mtd_mci/Makefile.dep create mode 100644 drivers/mtd_mci/mtd_mci.c diff --git a/drivers/mtd_mci/Makefile b/drivers/mtd_mci/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/drivers/mtd_mci/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/mtd_mci/Makefile.dep b/drivers/mtd_mci/Makefile.dep new file mode 100644 index 0000000000..8acbf30ecd --- /dev/null +++ b/drivers/mtd_mci/Makefile.dep @@ -0,0 +1 @@ +USEMODULE += mci diff --git a/drivers/mtd_mci/mtd_mci.c b/drivers/mtd_mci/mtd_mci.c new file mode 100644 index 0000000000..3b285b1fc1 --- /dev/null +++ b/drivers/mtd_mci/mtd_mci.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2020 Beuth Hochschule für Technik Berlin + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + * + */ + +/** + * @ingroup drivers_mtd + * @{ + * + * @file + * @brief Driver for using lpc23xx-mci via mtd interface + * + * @author Benjamin Valentin + * + * @} + */ + +#include +#include + +#include "diskio.h" +#include "mtd.h" +#include "sdcard_spi.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define min(a, b) ((a) > (b) ? (b) : (a)) + +/* MCI driver only suports whole page reads / writes */ +static uint8_t _page_buffer[SD_HC_BLOCK_SIZE]; + +static int mtd_mci_init(mtd_dev_t *dev) +{ + if (mci_initialize()) { + return -EIO; + } + + if (ENABLE_DEBUG) { + uint32_t block_size; + mci_ioctl(GET_BLOCK_SIZE, &block_size); + DEBUG("block size: %lu\n", block_size); + } + + dev->pages_per_sector = 1; + dev->page_size = SD_HC_BLOCK_SIZE; + mci_ioctl(GET_SECTOR_COUNT, &dev->sector_count); + + DEBUG("sector size: %lu\n", dev->page_size); + DEBUG("sector count: %lu\n", dev->sector_count); + DEBUG("pages / sector: %lu\n", dev->pages_per_sector); + + return 0; +} + +static int mtd_mci_read_page(mtd_dev_t *dev, void *buff, uint32_t page, + uint32_t offset, uint32_t size) +{ + (void)dev; + uint8_t pages = size / SD_HC_BLOCK_SIZE; + + DEBUG("%s(%lu, %lu, %lu)\n", __func__, page, offset, size); + + /* emulate unaligned / sub-page read */ + if (pages == 0 || offset) { + size = min(SD_HC_BLOCK_SIZE - offset, size); + + if (mci_read(_page_buffer, page, 1)) { + return -EIO; + } + + memcpy(buff, _page_buffer + offset, size); + + return size; + } + + if (mci_read(buff, page, pages)) { + return -EIO; + } + + return pages * SD_HC_BLOCK_SIZE; +} + +static int mtd_mci_write_page(mtd_dev_t *dev, const void *buff, uint32_t page, + uint32_t offset, uint32_t size) +{ + (void)dev; + uint8_t pages = size / SD_HC_BLOCK_SIZE; + + DEBUG("%s(%lu, %lu, %lu)\n", __func__, page, offset, size); + + /* emulate unaligned / sub-page write */ + if (pages == 0 || offset) { + size = min(SD_HC_BLOCK_SIZE - offset, size); + + if (mci_read(_page_buffer, page, 1)) { + return -EIO; + } + + memcpy(_page_buffer + offset, buff, size); + + buff = _page_buffer; + pages = 1; + } + + if (mci_write(buff, page, pages)) { + return -EIO; + } + + return pages * SD_HC_BLOCK_SIZE; +} + +static int mtd_mci_erase_sector(mtd_dev_t *dev, uint32_t sector, uint32_t count) +{ + (void)dev; + + while (count--) { + mci_ioctl(CTRL_ERASE_SECTOR, §or); + ++sector; + } + return 0; +} + +static int mtd_mci_power(mtd_dev_t *dev, enum mtd_power_state power) +{ + (void)dev; + + unsigned char on = power == MTD_POWER_UP ? 1 : 0; + if (mci_ioctl(CTRL_POWER, &on)) { + return -EIO; + } + + return 0; +} + +const mtd_desc_t mtd_mci_driver = { + .init = mtd_mci_init, + .read_page = mtd_mci_read_page, + .write_page = mtd_mci_write_page, + .erase_sector = mtd_mci_erase_sector, + .power = mtd_mci_power, +};