diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 7a9773a980..dc39930244 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -342,14 +342,21 @@ ifneq (,$(filter mrf24j40,$(USEMODULE))) FEATURES_REQUIRED += periph_spi endif -ifneq (,$(filter mtd_sdcard,$(USEMODULE))) +ifneq (,$(filter mtd_%,$(USEMODULE))) USEMODULE += mtd - USEMODULE += sdcard_spi -endif -ifneq (,$(filter mtd_spi_nor,$(USEMODULE))) - USEMODULE += mtd - FEATURES_REQUIRED += periph_spi + ifneq (,$(filter mtd_sdcard,$(USEMODULE))) + USEMODULE += sdcard_spi + endif + + ifneq (,$(filter mtd_spi_nor,$(USEMODULE))) + FEATURES_REQUIRED += periph_spi + endif + + ifneq (,$(filter mtd_flashpage,$(USEMODULE))) + FEATURES_REQUIRED += periph_flashpage + FEATURES_REQUIRED += periph_flashpage_raw + endif endif ifneq (,$(filter my9221,$(USEMODULE))) diff --git a/drivers/include/mtd_flashpage.h b/drivers/include/mtd_flashpage.h new file mode 100644 index 0000000000..0c6d4ac8a4 --- /dev/null +++ b/drivers/include/mtd_flashpage.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2018 OTA keys S.A. + * + * 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. + */ + +/** + * @defgroup drivers_mtd_flashpage Flashpage MTD + * @ingroup drivers_storage + * @brief Driver for internal flash devices implementing flashpage interface + * + * @{ + * + * @file + * @brief Interface definition for the flashpage memory driver + * + * @author Vincent Dupont + */ + +#ifndef MTD_FLASHPAGE_H +#define MTD_FLASHPAGE_H + +#include "mtd.h" +#include "periph/flashpage.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Macro helper to initialize a mtd_t with flash-age driver + */ +#define MTD_FLASHPAGE_INIT_VAL(_pages_per_sector) { \ + .driver = &mtd_flashpage_driver, \ + .sector_count = FLASHPAGE_NUMOF, \ + .pages_per_sector = _pages_per_sector,\ + .page_size = FLASHPAGE_SIZE / _pages_per_sector,\ +} + +/** + * @brief Flashpage MTD device operations table + */ +extern const mtd_desc_t mtd_flashpage_driver; + +#ifdef __cplusplus +} +#endif + +#endif /* MTD_FLASHPAGE_H */ +/** @} */ diff --git a/drivers/mtd_flashpage/Makefile b/drivers/mtd_flashpage/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/drivers/mtd_flashpage/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/mtd_flashpage/mtd_flashpage.c b/drivers/mtd_flashpage/mtd_flashpage.c new file mode 100644 index 0000000000..4809542263 --- /dev/null +++ b/drivers/mtd_flashpage/mtd_flashpage.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2018 OTA keys S.A. + * + * 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_flashpage + * @brief Driver for internal flash devices implementing flashpage interface + * + * @{ + * + * @file + * @brief Implementation for the flashpage memory driver + * + * @author Vincent Dupont + * @} + */ + +#include +#include +#include + +#include "cpu_conf.h" +#include "mtd_flashpage.h" +#include "periph/flashpage.h" + +#define MTD_FLASHPAGE_END_ADDR CPU_FLASH_BASE + (FLASHPAGE_NUMOF * FLASHPAGE_SIZE) + +static int _init(mtd_dev_t *dev) +{ + (void)dev; + assert(dev->pages_per_sector * dev->page_size == FLASHPAGE_SIZE); + return 0; +} + +static int _read(mtd_dev_t *dev, void *buf, uint32_t addr, uint32_t size) +{ + assert(addr < MTD_FLASHPAGE_END_ADDR); + (void)dev; + + if (addr % FLASHPAGE_RAW_ALIGNMENT) { + return -EINVAL; + } + + memcpy(buf, (void*)addr, size); + + return size; +} + +static int _write(mtd_dev_t *dev, const void *buf, uint32_t addr, uint32_t size) +{ + (void)dev; + if (addr % FLASHPAGE_RAW_ALIGNMENT) { + return -EINVAL; + } + if ((uintptr_t)buf % FLASHPAGE_RAW_ALIGNMENT) { + return -EINVAL; + } + if (size % FLASHPAGE_RAW_BLOCKSIZE) { + return -EOVERFLOW; + } + if (addr + size > MTD_FLASHPAGE_END_ADDR) { + return -EOVERFLOW; + } + flashpage_write_raw((void *)addr, buf, size); + + return size; +} + +int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t size) +{ + size_t sector_size = dev->page_size * dev->pages_per_sector; + + if (size % sector_size) { + return -EOVERFLOW; + } + if (addr + size > MTD_FLASHPAGE_END_ADDR) { + return - EOVERFLOW; + } + if (addr % sector_size) { + return - EOVERFLOW; + } + for (size_t i = 0; i < size; i += sector_size) { + flashpage_write(flashpage_page((void *)addr), NULL); + } + + return 0; +} + + +const mtd_desc_t mtd_flashpage_driver = { + .init = _init, + .read = _read, + .write = _write, + .erase = _erase, +};