diff --git a/boards/mcb2388/Makefile.dep b/boards/mcb2388/Makefile.dep index 0688b61ce6..ea9b31270f 100644 --- a/boards/mcb2388/Makefile.dep +++ b/boards/mcb2388/Makefile.dep @@ -2,3 +2,10 @@ ifneq (,$(filter saul_default,$(USEMODULE))) USEMODULE += saul_adc USEMODULE += saul_gpio endif + +# default to mtd_mci if no other MTD backend is selected +ifneq (,$(filter mtd,$(USEMODULE))) + ifeq (,$(filter mtd_%,$(USEMODULE))) + USEMODULE += mtd_mci + endif +endif diff --git a/boards/mcb2388/board_init.c b/boards/mcb2388/board_init.c index 7ea374ff4e..77b1a0ca14 100644 --- a/boards/mcb2388/board_init.c +++ b/boards/mcb2388/board_init.c @@ -22,9 +22,16 @@ #include "board.h" #include "cpu.h" +#include "mtd.h" #include "periph/init.h" #include "stdio_base.h" +#ifdef MODULE_MTD_MCI +extern const mtd_desc_t mtd_mci_driver; +static mtd_dev_t _mtd_mci = { .driver = &mtd_mci_driver }; +mtd_dev_t *mtd0 = &_mtd_mci; +#endif + void board_init(void) { /* LEDS */ diff --git a/boards/mcb2388/include/board.h b/boards/mcb2388/include/board.h index 6546c0ab6d..96baa5c618 100644 --- a/boards/mcb2388/include/board.h +++ b/boards/mcb2388/include/board.h @@ -20,6 +20,7 @@ #define BOARD_H #include "lpc23xx.h" +#include "mtd.h" #ifdef __cplusplus extern "C" { @@ -104,6 +105,16 @@ extern "C" { GPIO_UNDEF, GPIO_UNDEF } /** @} */ +/** + * @name MTD configuration + * @{ + */ +#ifdef MODULE_MTD_MCI +extern mtd_dev_t *mtd0; +#define MTD_0 mtd0 +#endif +/** @} */ + #ifdef __cplusplus } #endif diff --git a/boards/msba2/Makefile.dep b/boards/msba2/Makefile.dep index ad07c250df..7b08d62e5e 100644 --- a/boards/msba2/Makefile.dep +++ b/boards/msba2/Makefile.dep @@ -6,3 +6,10 @@ ifneq (,$(filter saul_default,$(USEMODULE))) USEMODULE += ltc4150 USEMODULE += sht11 endif + +# default to mtd_mci if no other MTD backend is selected +ifneq (,$(filter mtd,$(USEMODULE))) + ifeq (,$(filter mtd_%,$(USEMODULE))) + USEMODULE += mtd_mci + endif +endif diff --git a/boards/msba2/board_init.c b/boards/msba2/board_init.c index ee03815863..bffbfee3a4 100644 --- a/boards/msba2/board_init.c +++ b/boards/msba2/board_init.c @@ -26,9 +26,16 @@ #include "board.h" #include "cpu.h" +#include "mtd.h" #include "periph/init.h" #include "stdio_base.h" +#ifdef MODULE_MTD_MCI +extern const mtd_desc_t mtd_mci_driver; +static mtd_dev_t _mtd_mci = { .driver = &mtd_mci_driver }; +mtd_dev_t *mtd0 = &_mtd_mci; +#endif + void board_init(void) { /* LEDS */ diff --git a/boards/msba2/include/board.h b/boards/msba2/include/board.h index f23d98f98e..68a5353caa 100644 --- a/boards/msba2/include/board.h +++ b/boards/msba2/include/board.h @@ -20,6 +20,7 @@ #define BOARD_H #include "lpc23xx.h" +#include "mtd.h" #include "bitarithm.h" #ifdef __cplusplus @@ -45,6 +46,16 @@ extern "C" { #define LED1_TOGGLE (FIO3PIN ^= LED1_MASK) /** @} */ +/** + * @name MTD configuration + * @{ + */ +#ifdef MODULE_MTD_MCI +extern mtd_dev_t *mtd0; +#define MTD_0 mtd0 +#endif +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/lpc23xx/Makefile.dep b/cpu/lpc23xx/Makefile.dep index 0e6317d81d..2751e15f57 100644 --- a/cpu/lpc23xx/Makefile.dep +++ b/cpu/lpc23xx/Makefile.dep @@ -3,4 +3,8 @@ USEMODULE += bitfield USEMODULE += periph USEMODULE += pm_layered +ifneq (,$(filter mci,$(USEMODULE))) + USEMODULE += xtimer +endif + include $(RIOTCPU)/arm7_common/Makefile.dep 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, +}; diff --git a/tests/pkg_fatfs_vfs/main.c b/tests/pkg_fatfs_vfs/main.c index b90b5f3636..907031236f 100644 --- a/tests/pkg_fatfs_vfs/main.c +++ b/tests/pkg_fatfs_vfs/main.c @@ -25,6 +25,7 @@ #include "fs/fatfs.h" #include "vfs.h" #include "mtd.h" +#include "board.h" #include "kernel_defines.h" @@ -403,7 +404,7 @@ int main(void) } #endif -#ifdef MODULE_MTD_NATIVE +#if defined(MODULE_MTD_NATIVE) || defined(MODULE_MTD_MCI) fatfs_mtd_devs[fatfs.vol_idx] = mtd0; #else fatfs_mtd_devs[fatfs.vol_idx] = mtd1;