drivers/at25xxx: add MTD wrapper for AT25XXX EEPROMs
drivers/at25xxx: add mtd_wrapper as submodule tests: add mtd_at25xxx test module for mtd wrapper drivers/Makefile.dep: add at25xxx dep for mtd_at25xxx module
This commit is contained in:
parent
3e922f878a
commit
177a653bd1
@ -504,6 +504,10 @@ endif
|
||||
ifneq (,$(filter mtd_%,$(USEMODULE)))
|
||||
USEMODULE += mtd
|
||||
|
||||
ifneq (,$(filter mtd_at25xxx,$(USEMODULE)))
|
||||
USEMODULE += at25xxx
|
||||
endif
|
||||
|
||||
ifneq (,$(filter mtd_sdcard,$(USEMODULE)))
|
||||
USEMODULE += sdcard_spi
|
||||
endif
|
||||
|
||||
@ -1 +1,5 @@
|
||||
ifneq (,$(filter mtd_at25xxx,$(USEMODULE)))
|
||||
DIRS += mtd
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
10
drivers/at25xxx/mtd/Makefile
Normal file
10
drivers/at25xxx/mtd/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
MODULE := mtd_at25xxx
|
||||
BASE_MODULE := at25xxx
|
||||
|
||||
# at25xxx_mtd files
|
||||
SRC := mtd.c
|
||||
|
||||
# enable submodules
|
||||
SUBMODULES := 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
83
drivers/at25xxx/mtd/mtd.c
Normal file
83
drivers/at25xxx/mtd/mtd.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2020 ML!PA Consulting GmbH
|
||||
*
|
||||
* 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_at25xxx
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief MTD wrapper for AT25XXX based SPI EEPROMs (like AT25xxx, M95xxx, 25AAxxx, 25LCxxx,
|
||||
* CAT25xxx & BR25Sxxx)
|
||||
*
|
||||
* @author Johannes Koster <johannes.koster@ml-pa.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
#include "mtd.h"
|
||||
#include "at25xxx/mtd.h"
|
||||
#include "at25xxx.h"
|
||||
#include "at25xxx_params.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int mtd_at25xxx_init(mtd_dev_t *dev)
|
||||
{
|
||||
DEBUG("[mtd_at25xxx] initializing\n");
|
||||
mtd_at25xxx_t *mtd_at25xxx = (mtd_at25xxx_t*)dev;
|
||||
if (at25xxx_init(mtd_at25xxx->at25xxx_eeprom, mtd_at25xxx->params) == 0)
|
||||
{
|
||||
dev->pages_per_sector = 1;
|
||||
dev->page_size = mtd_at25xxx->params->page_size;
|
||||
dev->sector_count = mtd_at25xxx->params->size / mtd_at25xxx->params->page_size;
|
||||
return 0;
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static int mtd_at25xxx_read(mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size)
|
||||
{
|
||||
DEBUG("[mtd_at25xxx] read: addr:%" PRIu32 " size:%" PRIu32 "\n", addr, size);
|
||||
mtd_at25xxx_t *mtd_at25xxx_ = (mtd_at25xxx_t*)dev;
|
||||
return at25xxx_read(mtd_at25xxx_->at25xxx_eeprom, addr, buff, size);
|
||||
}
|
||||
|
||||
static int mtd_at25xxx_write(mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size)
|
||||
{
|
||||
DEBUG("[mtd_at25xxx] write: addr:%" PRIu32 " size:%" PRIu32 "\n", addr, size);
|
||||
mtd_at25xxx_t *mtd_at25xxx_ = (mtd_at25xxx_t*)dev;
|
||||
return at25xxx_write(mtd_at25xxx_->at25xxx_eeprom, addr, buff, size);
|
||||
}
|
||||
|
||||
static int mtd_at25xxx_erase(mtd_dev_t *dev, uint32_t addr, uint32_t size)
|
||||
{
|
||||
DEBUG("[mtd_at25xxx] mtd_at25xxx_erase: addr:%" PRIu32 " size:%" PRIu32 "\n", addr, size);
|
||||
mtd_at25xxx_t *mtd_at25xxx_ = (mtd_at25xxx_t*)dev;
|
||||
return at25xxx_clear(mtd_at25xxx_->at25xxx_eeprom, addr, size);
|
||||
}
|
||||
|
||||
static int mtd_at25xxx_power(mtd_dev_t *dev, enum mtd_power_state power)
|
||||
{
|
||||
(void)dev;
|
||||
(void)power;
|
||||
|
||||
/* TODO: implement power down/up of EEPROM (at25xxx driver?)
|
||||
*/
|
||||
return -ENOTSUP; /* currently not supported */
|
||||
}
|
||||
|
||||
const mtd_desc_t mtd_at25xxx_driver = {
|
||||
.init = mtd_at25xxx_init,
|
||||
.read = mtd_at25xxx_read,
|
||||
.write = mtd_at25xxx_write,
|
||||
.erase = mtd_at25xxx_erase,
|
||||
.power = mtd_at25xxx_power,
|
||||
};
|
||||
56
drivers/include/at25xxx/mtd.h
Normal file
56
drivers/include/at25xxx/mtd.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2020 ML!PA Consulting GmbH
|
||||
*
|
||||
* 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_at25xxx MTD wrapper for AT25xxx family of SPI-EEPROMs
|
||||
* @ingroup drivers_storage
|
||||
* @brief MTD wrapper for AT25XXX based SPI EEPROMs
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Interface definition for at25xxx MTD wrapper
|
||||
*
|
||||
* @author Johannes Koster <johannes.koster@ml-pa.com>
|
||||
*/
|
||||
|
||||
#ifndef AT25XXX_MTD_H
|
||||
#define AT25XXX_MTD_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "at25xxx.h"
|
||||
#include "mtd.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for mtd_at25xxx device
|
||||
*
|
||||
* This is an extension of the @c mtd_dev_t struct
|
||||
*/
|
||||
typedef struct {
|
||||
mtd_dev_t base; /**< inherit from mtd_dev_t object */
|
||||
at25xxx_t *at25xxx_eeprom; /**< at25xxx_eeprom dev descriptor */
|
||||
const at25xxx_params_t *params; /**< params for at25xxx_eeprom init */
|
||||
} mtd_at25xxx_t;
|
||||
|
||||
/**
|
||||
* @brief mtd_at25xxx_eeprom device operations table for mtd
|
||||
*/
|
||||
extern const mtd_desc_t mtd_at25xxx_driver;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AT25XXX_MTD_H */
|
||||
/** @} */
|
||||
6
tests/mtd_at25xxx/Makefile
Normal file
6
tests/mtd_at25xxx/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += mtd_at25xxx
|
||||
USEMODULE += embunit
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
125
tests/mtd_at25xxx/main.c
Normal file
125
tests/mtd_at25xxx/main.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2020 ML!PA Consulting GmbH
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "embUnit.h"
|
||||
|
||||
#include "mtd.h"
|
||||
#include "at25xxx.h"
|
||||
#include "at25xxx/mtd.h"
|
||||
#include "at25xxx_params.h"
|
||||
|
||||
#define TEST_ADDRESS (uint16_t)((dev->sector_count - 1) * dev->page_size)
|
||||
|
||||
static at25xxx_t at25xxx;
|
||||
|
||||
static mtd_at25xxx_t _dev = {
|
||||
.base = {
|
||||
.driver = &mtd_at25xxx_driver
|
||||
},
|
||||
.at25xxx_eeprom = &at25xxx,
|
||||
.params = &at25xxx_params[0],
|
||||
};
|
||||
|
||||
static mtd_dev_t *dev = (mtd_dev_t *)&_dev;
|
||||
|
||||
static void setup(void)
|
||||
{
|
||||
int ret = mtd_init(dev);
|
||||
TEST_ASSERT_EQUAL_INT(0, ret);
|
||||
mtd_erase(dev, TEST_ADDRESS, dev->pages_per_sector * dev->page_size);
|
||||
}
|
||||
|
||||
static void teardown(void)
|
||||
{
|
||||
mtd_erase(dev, TEST_ADDRESS, dev->pages_per_sector * dev->page_size);
|
||||
}
|
||||
|
||||
static void test_mtd_init(void)
|
||||
{
|
||||
int ret = mtd_init(dev);
|
||||
TEST_ASSERT_EQUAL_INT(0, ret);
|
||||
}
|
||||
|
||||
static void test_mtd_erase(void)
|
||||
{
|
||||
int ret = mtd_erase(dev, TEST_ADDRESS, dev->page_size);
|
||||
TEST_ASSERT_EQUAL_INT(0, ret);
|
||||
}
|
||||
|
||||
static void test_mtd_write_erase(void)
|
||||
{
|
||||
uint8_t buf_empty[] = {0, 0, 0};
|
||||
const char buf[] = "MTD_AT25XXX_TEST_WRITE_ERASE";
|
||||
|
||||
char buf_read[sizeof(buf) + sizeof(buf_empty)];
|
||||
memset(buf_read, 0, sizeof(buf_read));
|
||||
|
||||
int ret = mtd_write(dev, buf, TEST_ADDRESS, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(buf), ret);
|
||||
|
||||
ret = mtd_erase(dev, TEST_ADDRESS, dev->pages_per_sector * dev->page_size);
|
||||
TEST_ASSERT_EQUAL_INT(0, ret);
|
||||
|
||||
uint8_t expected[sizeof(buf_read)];
|
||||
memset(expected, 0, sizeof(expected));
|
||||
ret = mtd_read(dev, buf_read, TEST_ADDRESS, sizeof(buf_read));
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(buf_read), ret);
|
||||
TEST_ASSERT_EQUAL_INT(0, memcmp(expected, buf_read, sizeof(buf_read)));
|
||||
}
|
||||
|
||||
static void test_mtd_write_read(void)
|
||||
{
|
||||
uint8_t buf_empty[] = {0, 0, 0};
|
||||
const char buf[] = "MTD_AT25XXX_TEST_WRITE_ERASE";
|
||||
|
||||
char buf_read[sizeof(buf) + sizeof(buf_empty)];
|
||||
memset(buf_read, 0, sizeof(buf_read));
|
||||
|
||||
/* Basic write / read */
|
||||
int ret = mtd_write(dev, buf, TEST_ADDRESS, sizeof(buf));
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(buf), ret);
|
||||
|
||||
ret = mtd_read(dev, buf_read, TEST_ADDRESS, sizeof(buf_read));
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(buf_read), ret);
|
||||
TEST_ASSERT_EQUAL_INT(0, memcmp(buf, buf_read, sizeof(buf)));
|
||||
TEST_ASSERT_EQUAL_INT(0, memcmp(buf_empty, buf_read + sizeof(buf), sizeof(buf_empty)));
|
||||
|
||||
ret = mtd_erase(dev, TEST_ADDRESS, dev->pages_per_sector * dev->page_size);
|
||||
TEST_ASSERT_EQUAL_INT(0, ret);
|
||||
}
|
||||
|
||||
Test *tests_mtd_at25xxx_tests(void)
|
||||
{
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
new_TestFixture(test_mtd_init),
|
||||
new_TestFixture(test_mtd_erase),
|
||||
new_TestFixture(test_mtd_write_erase),
|
||||
new_TestFixture(test_mtd_write_read),
|
||||
};
|
||||
|
||||
EMB_UNIT_TESTCALLER(mtd_at25xxx_tests, setup, teardown, fixtures);
|
||||
|
||||
return (Test *)&mtd_at25xxx_tests;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
TESTS_START();
|
||||
TESTS_RUN(tests_mtd_at25xxx_tests());
|
||||
TESTS_END();
|
||||
return 0;
|
||||
}
|
||||
/** @} */
|
||||
Loading…
x
Reference in New Issue
Block a user