From 3aa1ffb5fb43450cf2c17735faab768d98210715 Mon Sep 17 00:00:00 2001 From: Alexandre Abadie Date: Fri, 2 Sep 2016 09:13:51 +0200 Subject: [PATCH] drivers/io1_xplained: initial implementation including temperature/LED/GPIO and auto init --- drivers/Makefile.dep | 6 + drivers/Makefile.include | 3 + drivers/include/io1_xplained.h | 109 ++++++++++++++++ drivers/io1_xplained/Makefile | 3 + .../include/io1_xplained_internals.h | 60 +++++++++ .../include/io1_xplained_params.h | 110 ++++++++++++++++ drivers/io1_xplained/io1_xplained.c | 122 ++++++++++++++++++ drivers/io1_xplained/io1_xplained_saul.c | 43 ++++++ sys/auto_init/auto_init.c | 8 ++ tests/driver_io1_xplained/Makefile | 14 ++ tests/driver_io1_xplained/README.md | 5 + tests/driver_io1_xplained/main.c | 79 ++++++++++++ 12 files changed, 562 insertions(+) create mode 100644 drivers/include/io1_xplained.h create mode 100644 drivers/io1_xplained/Makefile create mode 100644 drivers/io1_xplained/include/io1_xplained_internals.h create mode 100644 drivers/io1_xplained/include/io1_xplained_params.h create mode 100644 drivers/io1_xplained/io1_xplained.c create mode 100644 drivers/io1_xplained/io1_xplained_saul.c create mode 100644 tests/driver_io1_xplained/Makefile create mode 100644 tests/driver_io1_xplained/README.md create mode 100644 tests/driver_io1_xplained/main.c diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index c85dcffbc..bdd5b6da1 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -2,6 +2,7 @@ ifneq (,$(filter at30tse75x,$(USEMODULE))) USEMODULE += xtimer + FEATURES_REQUIRED += periph_i2c endif ifneq (,$(filter at86rf2%,$(USEMODULE))) @@ -76,6 +77,11 @@ ifneq (,$(filter hih6130,$(USEMODULE))) USEMODULE += xtimer endif +ifneq (,$(filter io1_xplained,$(USEMODULE))) + FEATURES_REQUIRED += periph_gpio + USEMODULE += at30tse75x +endif + ifneq (,$(filter kw2xrf,$(USEMODULE))) USEMODULE += ieee802154 USEMODULE += netif diff --git a/drivers/Makefile.include b/drivers/Makefile.include index 2328776d0..330ed55bb 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -10,6 +10,9 @@ endif ifneq (,$(filter kw2xrf,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/kw2xrf/include endif +ifneq (,$(filter io1_xplained,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/io1_xplained/include +endif ifneq (,$(filter isl29020,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/isl29020/include endif diff --git a/drivers/include/io1_xplained.h b/drivers/include/io1_xplained.h new file mode 100644 index 000000000..16b51b8f6 --- /dev/null +++ b/drivers/include/io1_xplained.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 Inria + * + * 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_io1_xplained IO1_XPLAINED + * @ingroup drivers_sensors + * @brief Device driver interface for the IO1 Xplained extension. + * @{ + * + * @file + * @brief Device driver interface for the IO1 Xplained extention. + * + * @author Alexandre Abadie + */ + +#ifndef IO1_XPLAINED_H_ +#define IO1_XPLAINED_H_ + +#include "saul.h" +#include "at30tse75x.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Device descriptor for the IO1 Xplained extension. + */ +typedef struct { + at30tse75x_t temp /**< On-board temperature sensor */; +} io1_xplained_t; + + +/** + * @brief Device initialization parameters + */ +typedef struct { + uint8_t addr; /**< extension custom address */ +} io1_xplained_params_t; + +/** + * @brief export SAUL endpoints + * @{ + */ +extern const saul_driver_t io1_xplained_temperature_saul_driver; +/** @} */ + +/** + * @brief auto-initialize all configured IO1 Xplained extensions + */ +void io1_xplained_auto_init(void); + +/** + * @brief Initialize the given IO1 Xplained extension + * + * @param[out] dev Initialized device descriptor of IO1 Xplained extension + * @param[in] addr Custom address of the extension board + * + * @return 0 on success + * @return -1 if given I2C is not enabled in board config + */ +int io1_xplained_init(io1_xplained_t *dev, uint8_t addr); + +/** + * @brief Read temperature value from the given IO1 Xplained extension, returned in °C + * + * @param[in] dev Device descriptor of IO1 Xplained to read from + * @param[out] temperature Temperature in °C + * + * @return 0 on success + * @return -1 if device's I2C is not enabled in board config + */ +int io1_xplained_read_temperature(io1_xplained_t *dev, float *temperature); + +/** + * @brief Set the on-board led of the IO1 Xplained extension + * + * @return 0 on success + * @return -1 if extension GPIO is not enabled in board config + */ +int io1_xplained_set_led(void); + +/** + * @brief Clear the on-board led of the IO1 Xplained extension + * + * @return 0 on success + * @return -1 if extension GPIO is not enabled in board config + */ +int io1_xplained_clear_led(void); + +/** + * @brief Toggle the on-board led of the IO1 Xplained extension + * + * @return 0 on success + * @return -1 if extension GPIO is not enabled in board config + */ +int io1_xplained_toggle_led(void); + +#ifdef __cplusplus +} +#endif + +#endif /* IO1_XPLAINED_H_ */ +/** @} */ diff --git a/drivers/io1_xplained/Makefile b/drivers/io1_xplained/Makefile new file mode 100644 index 000000000..075a3c4ea --- /dev/null +++ b/drivers/io1_xplained/Makefile @@ -0,0 +1,3 @@ +MODULE = io1_xplained + +include $(RIOTBASE)/Makefile.base diff --git a/drivers/io1_xplained/include/io1_xplained_internals.h b/drivers/io1_xplained/include/io1_xplained_internals.h new file mode 100644 index 000000000..e3c929c3b --- /dev/null +++ b/drivers/io1_xplained/include/io1_xplained_internals.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 Inria + * + * 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_io1_xplained IO1_XPLAINED + * @ingroup drivers_sensors + * @brief Internal addresses, constants for the IO1 Xplained extension. + * @{ + * + * @file + * @brief Internal addresses, constants for the IO1 Xplained extension. + * + * @author Alexandre Abadie + */ + +#ifndef IO1_XPLAINED_INTERNALS_H_ +#define IO1_XPLAINED_INTERNALS_H_ + +#include "cpu.h" +#include "periph_cpu.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name IO1 Xplained I2C addresses + * @{ + */ +#define TEMPERATURE_BASE_ADDR (0x48) +#define TEMPERATURE_DEFAULT_ADDR (0x07) +/** @} */ + +/** + * @name IO1 Xplained LED pin + * @{ + */ +#define IO1_LED_PIN GPIO_PIN(0,18) +/** @} */ + +/** + * @name IO1 Xplained gpio pins + * @{ + */ +#define IO1_GPIO1_PIN GPIO_PIN(0,13) +#define IO1_GPIO2_PIN GPIO_PIN(0,28) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* IO1_XPLAINED_INTERNALS_H_ */ +/** @} */ diff --git a/drivers/io1_xplained/include/io1_xplained_params.h b/drivers/io1_xplained/include/io1_xplained_params.h new file mode 100644 index 000000000..5bd1ea7f0 --- /dev/null +++ b/drivers/io1_xplained/include/io1_xplained_params.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2016 Inria + * + * 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_io1_xplained + * + * @{ + * @file + * @brief Default configuration for IO1 Xplained + * + * @author Alexandre Abadie + */ + +#ifndef IO1_XPLAINED_PARAMS_H +#define IO1_XPLAINED_PARAMS_H + +#include "board.h" +#include "io1_xplained.h" +#include "saul.h" +#include "saul_reg.h" +#include "saul/periph.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set default configuration parameters for the IO1 Xplained extension + * @{ + */ +#ifndef IO1_XPLAINED_PARAM_ADDR +#define IO1_XPLAINED_PARAM_ADDR (0x07) +#endif + +#define IO1_XPLAINED_PARAMS_DEFAULT { .addr = IO1_XPLAINED_PARAM_ADDR } +/**@}*/ + +/** + * @brief Configure IO1 Xplained extension + */ +static const io1_xplained_params_t io1_xplained_params[] = +{ +#ifdef IO1_XPLAINED_PARAMS_BOARD + IO1_XPLAINED_PARAMS_BOARD, +#else + IO1_XPLAINED_PARAMS_DEFAULT, +#endif +}; + +/** + * @brief Get the number of configured IO1 Xplained extension + */ +#define IO1_XPLAINED_NUMOF (sizeof(io1_xplained_params) / sizeof(io1_xplained_params[0])) + +/** + * @brief Reference the gpio driver struct + */ +extern saul_driver_t gpio_saul_driver; + +#ifdef MODULE_SAUL_REG +/** + * @brief Allocate and configure entries to the SAUL registry + */ +saul_reg_t io1_xplained_saul_reg[][4] = +{ + { + { + .name = "Temperature (IO1 Xplained)", + .driver = &io1_xplained_temperature_saul_driver + }, + { + .name = "LED (IO1 Xplained)", + .driver = &gpio_saul_driver + }, + { + .name = "GPIO1 (IO1 Xplained)", + .driver = &gpio_saul_driver + }, + { + .name = "GPIO2 (IO1 Xplained)", + .driver = &gpio_saul_driver + }, + } +}; +#endif + +#ifdef MODULE_SAUL_GPIO +/** + * @brief Allocate and configure the extension LED gpios + */ +static gpio_t io1_xplained_saul_gpios[3] = +{ + IO1_LED_PIN, + IO1_GPIO1_PIN, + IO1_GPIO2_PIN, +}; +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* IO1_XPLAINED_PARAMS_H */ +/** @} */ diff --git a/drivers/io1_xplained/io1_xplained.c b/drivers/io1_xplained/io1_xplained.c new file mode 100644 index 000000000..33d1a66db --- /dev/null +++ b/drivers/io1_xplained/io1_xplained.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2016 Inria + * + * 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_io1_xplained + * @{ + * + * @file + * @brief Device driver implementation for the Atmel IO1 Xplained extension + * + * @author Alexandre Abadie + * + * @} + */ + +#include + +#include "log.h" +#include "io1_xplained.h" +#include "io1_xplained_internals.h" +#include "io1_xplained_params.h" +#include "at30tse75x.h" +#include "periph/i2c.h" +#include "periph/gpio.h" +#include "xtimer.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +/** + * @brief Allocation of memory for device descriptors + */ +io1_xplained_t io1_xplained_devs[IO1_XPLAINED_NUMOF]; + +/*---------------------------------------------------------------------------* + * IO1 Xplained Core API * + *---------------------------------------------------------------------------*/ + +int io1_xplained_init(io1_xplained_t *dev, uint8_t addr) +{ + /* Initialize I2C interface */ + if (at30tse75x_init(&dev->temp, + I2C_DEV(0), + I2C_SPEED_NORMAL, (TEMPERATURE_BASE_ADDR | addr)) < 0) { + DEBUG("[Error] Cannot initialize temperature sensor.\n"); + return -1; + } + + /* Use maximum resolution */ + at30tse75x_set_resolution(&dev->temp, AT30TSE75X_RESOLUTION_12BIT); + + if (gpio_init(IO1_LED_PIN, GPIO_OUT) < 0) { + DEBUG("[Error] GPIO LED not enabled\n"); + return -1; + } + + if (gpio_init(IO1_GPIO1_PIN, GPIO_OUT) < 0) { + DEBUG("[Error] GPIO1 not enabled\n"); + return -1; + } + + if (gpio_init(IO1_GPIO2_PIN, GPIO_OUT) < 0) { + DEBUG("[Error] GPIO2 not enabled\n"); + return -1; + } + + DEBUG("[Info] IO1 Xplained extension initialized!\n"); + + return 0; +} + +void io1_xplained_auto_init(void) +{ + for (unsigned i = 0; i < IO1_XPLAINED_NUMOF; i++) { + if (io1_xplained_init(&io1_xplained_devs[i], + io1_xplained_params[i].addr) < 0) { + LOG_ERROR("Unable to initialize IO1 Xplained #%i\n", i); + } +#ifdef MODULE_SAUL_REG + io1_xplained_saul_reg[i][0].dev = &io1_xplained_devs[i]; + saul_reg_add(&io1_xplained_saul_reg[i][0]); +#endif +#ifdef MODULE_SAUL_GPIO + for (unsigned j = 1; j < 4; j++) { + io1_xplained_saul_reg[i][j].dev = &(io1_xplained_saul_gpios[j-1]); + saul_reg_add(&(io1_xplained_saul_reg[i][j])); + } +#endif + } +} + +int io1_xplained_read_temperature(io1_xplained_t *dev, float *temperature) +{ + if (at30tse75x_get_temperature(&dev->temp, temperature) < 0) { + DEBUG("[Error] Cannot read IO1 Xplained temperatuse sensor.\n"); + return -1; + } + return 0; +} + +int io1_xplained_set_led(void) +{ + gpio_set(IO1_LED_PIN); + return 0; +} + +int io1_xplained_clear_led(void) +{ + gpio_clear(IO1_LED_PIN); + return 0; +} + +int io1_xplained_toggle_led(void) +{ + gpio_toggle(IO1_LED_PIN); + return 0; +} diff --git a/drivers/io1_xplained/io1_xplained_saul.c b/drivers/io1_xplained/io1_xplained_saul.c new file mode 100644 index 000000000..0d5c23b79 --- /dev/null +++ b/drivers/io1_xplained/io1_xplained_saul.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2016 Inria + * + * 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_io1_xplained + * @{ + * + * @file + * @brief SAUL adaption for IO1 Xplained extension + * + * @author Alexandre Abadie + * + * @} + */ + +#include + +#include "saul.h" +#include "io1_xplained.h" +#include "xtimer.h" + +static float temperature; + +static int read_temperature(void *dev, phydat_t *res) +{ + io1_xplained_t *d = (io1_xplained_t *)dev; + io1_xplained_read_temperature(d, &temperature); + res->val[0] = (int)(temperature * 100.0); + res->unit = UNIT_TEMP_C; + res->scale = -2; + return 1; +} + +const saul_driver_t io1_xplained_temperature_saul_driver = { + .read = read_temperature, + .write = saul_notsup, + .type = SAUL_SENSE_TEMP +}; diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 2074f330a..2597f45aa 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -24,6 +24,10 @@ #include "bmp180.h" #endif +#ifdef MODULE_IO1_XPLAINED +#include "io1_xplained.h" +#endif + #ifdef MODULE_SHT11 #include "sht11.h" #endif @@ -108,6 +112,10 @@ void auto_init(void) DEBUG("Auto init BMP180 module.\n"); bmp180_auto_init(); #endif +#ifdef MODULE_IO1_XPLAINED + DEBUG("Auto init IO1 Xplained extension module.\n"); + io1_xplained_auto_init(); +#endif #ifdef MODULE_SHT11 DEBUG("Auto init SHT11 module.\n"); sht11_init(); diff --git a/tests/driver_io1_xplained/Makefile b/tests/driver_io1_xplained/Makefile new file mode 100644 index 000000000..5794cb2e9 --- /dev/null +++ b/tests/driver_io1_xplained/Makefile @@ -0,0 +1,14 @@ +APPLICATION = driver_io1_xplained +include ../Makefile.tests_common + +USEMODULE += io1_xplained +USEMODULE += xtimer +USEMODULE += printf_float + +# set default device parameters in case they are undefined +TEST_ADDR ?= 0x07 + +# export parameters +CFLAGS += -DTEST_ADDR=$(TEST_ADDR) + +include $(RIOTBASE)/Makefile.include diff --git a/tests/driver_io1_xplained/README.md b/tests/driver_io1_xplained/README.md new file mode 100644 index 000000000..fe53d0d56 --- /dev/null +++ b/tests/driver_io1_xplained/README.md @@ -0,0 +1,5 @@ +### Test application for the IO1 Xplained extension + +The Atmel IO1 Xplained is an extension board to the Atmel Xplained Pro +evaluation platform. +More information in the [user mannual](http://www.atmel.com/images/atmel-42078-io1-xplained-pro_user-guide.pdf). diff --git a/tests/driver_io1_xplained/main.c b/tests/driver_io1_xplained/main.c new file mode 100644 index 000000000..39ca98edc --- /dev/null +++ b/tests/driver_io1_xplained/main.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2016 Inria + * + * 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 Atmel IO1 Xplained extension + * + * @author Alexandre Abadie + * + * @} + */ + +#ifndef TEST_ADDR +#error "TEST_ADDR not defined" +#endif + +#include +#include + +#include "io1_xplained.h" +#include "xtimer.h" +#include "board.h" + +#define SLEEP_1S (1 * 1000 * 1000u) /* 1 seconds delay between each test */ + +int main(void) +{ + io1_xplained_t dev; + float temperature; + int result; + + puts("IO1 Xplained extention test application\n"); + + printf("+------------Initializing------------+\n"); + result = io1_xplained_init(&dev, TEST_ADDR); + if (result == -1) { + puts("[Error] Cannot initialize the IO1 Xplained extension\n"); + return 1; + } + else { + printf("Initialization successful\n\n"); + } + + printf("\n+--------Starting tests --------+\n"); + while (1) { + /* Get temperature in degrees celsius */ + io1_xplained_read_temperature(&dev, &temperature); + printf("Temperature [°C]: %.2f\n" + "\n+-------------------------------------+\n", + temperature); + xtimer_usleep(SLEEP_1S); + + /* set led */ + io1_xplained_set_led(); + xtimer_usleep(SLEEP_1S); + + /* clear led */ + io1_xplained_clear_led(); + xtimer_usleep(SLEEP_1S); + + /* toggle led */ + io1_xplained_toggle_led(); + xtimer_usleep(SLEEP_1S); + + /* toggle led again */ + io1_xplained_toggle_led(); + xtimer_usleep(SLEEP_1S); + } + + return 0; +}