From d3ace2e821c310f5940dbea898fb84abeadaecfe Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 19 Nov 2019 17:14:57 +0100 Subject: [PATCH] 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 82833da0b3..a1a45531e7 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 685078b89b..43cb202e0c 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 0000000000..48422e909a --- /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 0000000000..d23e8e03d4 --- /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 0000000000..64f6822da1 --- /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 0000000000..b77b172de0 --- /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 */ +/** @} */