From d3ace2e821c310f5940dbea898fb84abeadaecfe Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 19 Nov 2019 17:14:57 +0100 Subject: [PATCH 1/4] drivers: add at24mac driver The AT24MAC is an EEPROM that provides unique ID functionality. On one address it provides normal AT24xxx EEPROM operations, but on a seperate i2c address a read-only EUI-64 and a 128-bit ID are provided. This adds a simply driver for this chip. --- drivers/Makefile.dep | 4 + drivers/Makefile.include | 4 + drivers/at24mac/Makefile | 1 + drivers/at24mac/at24mac.c | 91 ++++++++++++++++++++ drivers/at24mac/include/at24mac_params.h | 63 ++++++++++++++ drivers/include/at24mac.h | 104 +++++++++++++++++++++++ 6 files changed, 267 insertions(+) create mode 100644 drivers/at24mac/Makefile create mode 100644 drivers/at24mac/at24mac.c create mode 100644 drivers/at24mac/include/at24mac_params.h create mode 100644 drivers/include/at24mac.h diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 82833da0b323..a1a45531e73a 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -36,6 +36,10 @@ ifneq (,$(filter at,$(USEMODULE))) USEMODULE += isrpipe_read_timeout endif +ifneq (,$(filter at24mac,$(USEMODULE))) + FEATURES_REQUIRED += periph_i2c +endif + ifneq (,$(filter at30tse75x,$(USEMODULE))) USEMODULE += xtimer FEATURES_REQUIRED += periph_i2c diff --git a/drivers/Makefile.include b/drivers/Makefile.include index 685078b89b6f..43cb202e0c0d 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -20,6 +20,10 @@ ifneq (,$(filter apa102,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/apa102/include endif +ifneq (,$(filter at24mac,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/at24mac/include +endif + ifneq (,$(filter at86rf2xx,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/at86rf2xx/include endif diff --git a/drivers/at24mac/Makefile b/drivers/at24mac/Makefile new file mode 100644 index 000000000000..48422e909a47 --- /dev/null +++ b/drivers/at24mac/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/at24mac/at24mac.c b/drivers/at24mac/at24mac.c new file mode 100644 index 000000000000..d23e8e03d45a --- /dev/null +++ b/drivers/at24mac/at24mac.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2019 Benjamin Valentin + * + * 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_at24mac + * + * @{ + * @file + * @brief Driver for AT24MAC unique ID chip. + * + * @author Benjamin Valentin + * + * @} + */ + +#include + +#include "at24mac.h" +#include "at24mac_params.h" + +#define CMD_READ_EUI48 (0x9A) +#define CMD_READ_EUI64 (0x98) +#define CMD_READ_ID128 (0x80) + +static bool _is_valid(at24mac_type_t type, uint8_t reg) +{ + if (type == AT24MAC4XX && reg == CMD_READ_EUI64) { + return false; + } + + if (type == AT24MAC6XX && reg == CMD_READ_EUI48) { + return false; + } + + return true; +} + +static int _read_reg(at24mac_t dev, uint8_t reg, void *dst, size_t size) +{ + if (dev >= ARRAY_SIZE(at24mac_params)) { + return -ERANGE; + } + + int res = 0; + const at24mac_params_t *params = &at24mac_params[dev]; + + if (!_is_valid(params->type, reg)) { + return -ENOTSUP; + } + + res = i2c_acquire(params->i2c_dev); + if (res) { + return res; + } + + res = i2c_read_regs(params->i2c_dev, params->i2c_addr, + reg, dst, size, 0); + + i2c_release(params->i2c_dev); + + return res; +} + +int at24mac_get_eui48(at24mac_t dev, eui48_t *dst) +{ + return _read_reg(dev, CMD_READ_EUI48, dst, sizeof(*dst)); +} + +int at24mac_get_eui64(at24mac_t dev, eui64_t *dst) +{ + return _read_reg(dev, CMD_READ_EUI64, dst, sizeof(*dst)); +} + +int at24mac_get_id128(at24mac_t dev, void *dst) +{ + return _read_reg(dev, CMD_READ_ID128, dst, AT24MAC_ID_LEN); +} + +at24mac_type_t at24mac_get_type(at24mac_t dev) +{ + if (dev >= ARRAY_SIZE(at24mac_params)) { + return -ERANGE; + } + + return at24mac_params[dev].type; +} diff --git a/drivers/at24mac/include/at24mac_params.h b/drivers/at24mac/include/at24mac_params.h new file mode 100644 index 000000000000..64f6822da1d0 --- /dev/null +++ b/drivers/at24mac/include/at24mac_params.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2019 Benjamin Valentin + * + * 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_at24mac + * + * @{ + * @file + * @brief Default configuration for the AT24MAC chip + * + * @author Benjamin Valentin + */ + +#ifndef AT24MAC_PARAMS_H +#define AT24MAC_PARAMS_H + +#include "board.h" +#include "at24mac.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Set default configuration parameters for AT24Mac driver + * @{ + */ +#ifndef AT24MAC_PARAM_I2C_DEV +#define AT24MAC_PARAM_I2C_DEV I2C_DEV(0) +#endif +#ifndef AT24MAC_PARAM_I2C_ADDR +#define AT24MAC_PARAM_I2C_ADDR (0x58) +#endif +#ifndef AT24MAC_PARAM_TYPE +#define AT24MAC_PARAM_TYPE (AT24MAC6XX) +#endif + +#ifndef AT24MAC_PARAMS +#define AT24MAC_PARAMS { .i2c_dev = AT24MAC_PARAM_I2C_DEV, \ + .i2c_addr = AT24MAC_PARAM_I2C_ADDR,\ + .type = AT24MAC_PARAM_TYPE } +#endif +/**@}*/ + +/** + * @brief Configuration for AT24MACs + */ +static const at24mac_params_t at24mac_params[] = +{ + AT24MAC_PARAMS +}; + +#ifdef __cplusplus +} +#endif + +#endif /* AT24MAC_PARAMS_H */ +/** @} */ diff --git a/drivers/include/at24mac.h b/drivers/include/at24mac.h new file mode 100644 index 000000000000..b77b172de0e4 --- /dev/null +++ b/drivers/include/at24mac.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2019 Benjamin Valentin + * + * 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_at24mac unique ID chip + * @brief Device driver interface for the AT24MAC I2C chip + * @{ + * + * @file + * + * @author Benjamin Valentin + */ + +#ifndef AT24MAC_H +#define AT24MAC_H + +#include +#include "net/eui48.h" +#include "net/eui64.h" +#include "periph/i2c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Device handle type for AT24Mac devices + */ +typedef uint_fast8_t at24mac_t; + +#define AT24MAC_ID_LEN (16) /**< Length of ID128 */ + +/** + * @brief Type of the AT24Mac device + */ +typedef enum { + AT24MAC4XX, /**< provides EUI-48 */ + AT24MAC6XX /**< provides EUI-64 */ +} at24mac_type_t; + +/** + * @brief struct holding all params needed for device communication + */ +typedef struct { + i2c_t i2c_dev; /**< I2C device */ + uint8_t i2c_addr; /**< I2C address */ + at24mac_type_t type; /**< Device type */ +} at24mac_params_t; + +/** + * @brief Get the unique EUI48 address from a AT24MAC4xx chip + * + * @param[in] dev Index of the AT24Mac chip in the at24mac_params + * array. + * @param[out] addr memory location to copy the address into. + * + * @return 0 on success, error otherwise. + */ +int at24mac_get_eui48(at24mac_t dev, eui48_t *addr); + +/** + * @brief Get the unique EUI64 address from a AT24MAC6xx chip + * + * @param[in] dev Index of the AT24Mac chip in the at24mac_params + * array. + * @param[out] addr memory location to copy the address into. + * + * @return 0 on success, error otherwise. + */ +int at24mac_get_eui64(at24mac_t dev, eui64_t *addr); + +/** + * @brief Get the unique ID from a AT24MACxxx chip + * + * @param[in] dev Index of the AT24MAC chip in the at24mac_params + * array. + * @param[out] dst memory location to copy the ID into. + * Must be able to hold at least @ref AT24MAC_ID_LEN bytes. + * + * @return 0 on success, error otherwise. + */ +int at24mac_get_id128(at24mac_t dev, void *dst); + +/** + * @brief Get the type of a AT24MACxxx chip + * + * @param[in] dev Index of the AT24MAC chip in the at24mac_params + * array. + * + * @return The type of the device (AT24MAC4XX or AT24MAC6XX) + */ +at24mac_type_t at24mac_get_type(at24mac_t dev); + +#ifdef __cplusplus +} +#endif + +#endif /* AT24MAC_H */ +/** @} */ From ecd084781a2dc079d57852be8015bf080fe766e3 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 19 Nov 2019 17:15:22 +0100 Subject: [PATCH 2/4] tests: add test for at24mac driver --- tests/driver_at24mac/Makefile | 5 ++ tests/driver_at24mac/main.c | 100 ++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 tests/driver_at24mac/Makefile create mode 100644 tests/driver_at24mac/main.c diff --git a/tests/driver_at24mac/Makefile b/tests/driver_at24mac/Makefile new file mode 100644 index 000000000000..37a6486dca06 --- /dev/null +++ b/tests/driver_at24mac/Makefile @@ -0,0 +1,5 @@ +include ../Makefile.tests_common + +USEMODULE += at24mac + +include $(RIOTBASE)/Makefile.include diff --git a/tests/driver_at24mac/main.c b/tests/driver_at24mac/main.c new file mode 100644 index 000000000000..71cf41a19f73 --- /dev/null +++ b/tests/driver_at24mac/main.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2019 Benjamin Valentin + * + * 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 tests + * @{ + * + * @file + * @brief Test application for the AT24MAC driver + * + * @author Benjamin Valentin + * + * @} + */ + +#include +#include "at24mac.h" + +static int test_get_eui48(void) +{ + if (at24mac_get_type(0) != AT24MAC4XX) { + return 0; + } + + eui48_t e48; + if (at24mac_get_eui48(0, &e48) != 0) { + puts("[FAILED]"); + return 1; + } + + printf("EUI-48:"); + for (unsigned i = 0; i < sizeof(e48.uint8); ++i) { + printf(" %02x", e48.uint8[i]); + } + puts(""); + + return 0; +} + +static int test_get_eui64(void) +{ + if (at24mac_get_type(0) != AT24MAC6XX) { + return 0; + } + + eui64_t e64; + if (at24mac_get_eui64(0, &e64) != 0) { + puts("[FAILED]"); + return 1; + } + + printf("EUI-64:"); + for (unsigned i = 0; i < sizeof(e64.uint8); ++i) { + printf(" %02x", e64.uint8[i]); + } + puts(""); + + return 0; +} + +static int test_get_id128(void) +{ + uint8_t id[AT24MAC_ID_LEN]; + if (at24mac_get_id128(0, &id) != 0) { + puts("[FAILED]"); + return 1; + } + + printf("ID-128:"); + for (unsigned i = 0; i < sizeof(id); ++i) { + printf(" %02x", id[i]); + } + puts(""); + + return 0; +} + +int main(void) +{ + if (test_get_eui48()) { + return -1; + } + + if (test_get_eui64()) { + return -1; + } + + if (test_get_id128()) { + return -1; + } + + puts("[SUCCESS]"); + + return 0; +} From 59ca6a9b373a83eef713cd36ab0a1e0ad8c81d1e Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 13 Feb 2020 14:25:19 +0100 Subject: [PATCH 3/4] boards/avr-rss2: add configuration for AT24MAC602 --- boards/avr-rss2/include/board.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/avr-rss2/include/board.h b/boards/avr-rss2/include/board.h index 2d3fd61da1d6..4f625eaeec2b 100644 --- a/boards/avr-rss2/include/board.h +++ b/boards/avr-rss2/include/board.h @@ -27,6 +27,13 @@ extern "C" { #endif +/** + * @name AT24MAC602 configuration + * @{ + */ +#define AT24MAC_PARAM_I2C_DEV I2C_DEV(0) +#define AT24MAC_PARAM_TYPE AT24MAC6XX +/** @} */ /** * @name LED pin definitions and handlers From 02e1c0a4ed110913eb1359c543e873cd15584682 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Thu, 13 Feb 2020 14:25:53 +0100 Subject: [PATCH 4/4] boards/same54-xpro: add configuration for AT24MAC402 --- boards/same54-xpro/include/board.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/boards/same54-xpro/include/board.h b/boards/same54-xpro/include/board.h index 04c59a4c7d13..cde35f1a69d0 100644 --- a/boards/same54-xpro/include/board.h +++ b/boards/same54-xpro/include/board.h @@ -26,6 +26,15 @@ extern "C" { #endif +/** + * @name AT24MAC402 configuration + * @{ + */ +#define AT24MAC_PARAM_I2C_DEV I2C_DEV(0) +#define AT24MAC_PARAM_I2C_ADDR (0x5E) +#define AT24MAC_PARAM_TYPE AT24MAC4XX +/** @} */ + /** * @name LED pin definitions and handlers * @{