diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 531a6b7c6aa73973eb8158b924ac4cb5921766b2..558ff0e35a6d6ceaeca5e4c5cae2a778daa4bc80 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -184,6 +184,10 @@ ifneq (,$(filter srf08,$(USEMODULE))) USEMODULE += xtimer endif +ifneq (,$(filter veml6070,$(USEMODULE))) + FEATURES_REQUIRED += periph_i2c +endif + ifneq (,$(filter w5100,$(USEMODULE))) USEMODULE += netdev2_eth USEMODULE += luid diff --git a/drivers/Makefile.include b/drivers/Makefile.include index 9af613263ef5fc2c50d8a1ed16d582bf6fd49ec3..07eaa78bd89727bbe8229407cd1b04823592067d 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -100,3 +100,6 @@ endif ifneq (,$(filter sdcard_spi,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/sdcard_spi/include endif +ifneq (,$(filter veml6070,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/veml6070/include +endif diff --git a/drivers/include/veml6070.h b/drivers/include/veml6070.h new file mode 100644 index 0000000000000000000000000000000000000000..26f802ecc2651931b9d9ed988bf7194a6ab55113 --- /dev/null +++ b/drivers/include/veml6070.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2017 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_veml6070 VEML6070 + * @ingroup drivers_sensors + * @brief Device driver interface for the VEML6070 UV sensor + * @{ + * + * @file + * @brief Device driver interface for the VEML6070 UV sensor. + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + */ + +#ifndef VEML6070_H +#define VEML6070_H + +#include "saul.h" +#include "periph/i2c.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Integration times + */ +typedef enum veml6070_integrationtime { + VEML6070_HALF_T = 0, /**< 1/2 T integration time */ + VEML6070_1_T, /**< 1 T integration time */ + VEML6070_2_T, /**< 2 T integration time */ + VEML6070_4_T, /**< 4 T integration time */ +} veml6070_itime_t; + +/** + * @brief Status and error return codes + */ +enum { + VEML6070_OK = 0, /**< Everything was fine */ + VEML6070_ERR_I2C /**< Error initializing the I2C bus */ +}; + +/** + * @brief Device initialization parameters + */ +typedef struct { + i2c_t i2c_dev; /**< I2C device which is used */ + veml6070_itime_t itime; /**< Integration time */ +} veml6070_params_t; + +/** + * @brief Device descriptor for the VEML6070 sensor + */ +typedef struct { + veml6070_params_t params; /**< Device parameters */ +} veml6070_t; + +/** + * @brief Initialize the given VEML6070 device + * + * @param[out] dev Initialized device descriptor of VEML6070 device + * @param[in] params The parameters for the VEML6070 device (integration time) + * + * @return VEML6070_OK on success + * @return VEML6070_ERR_I2C if given I2C is not enabled in board config + */ +int veml6070_init(veml6070_t *dev, const veml6070_params_t * params); + +/** + * @brief Read UV indice from the given VEML6070 device + * + * @param[in] dev Device descriptor of VEML6070 device to read from + * + * @return UV indice + */ +uint16_t veml6070_read_uv(veml6070_t *dev); + +#ifdef __cplusplus +} +#endif + +#endif /* VEML6070_H */ +/** @} */ diff --git a/drivers/veml6070/Makefile b/drivers/veml6070/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2 --- /dev/null +++ b/drivers/veml6070/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/veml6070/include/veml6070_params.h b/drivers/veml6070/include/veml6070_params.h new file mode 100644 index 0000000000000000000000000000000000000000..ef96b6d1b421315528202e4b49d97aae9abd5d87 --- /dev/null +++ b/drivers/veml6070/include/veml6070_params.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 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_veml6070 + * + * @{ + * @file + * @brief Default configuration for VEML6070 + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + */ + +#ifndef VEML6070_PARAMS_H +#define VEML6070_PARAMS_H + +#include "board.h" +#include "veml6070.h" +#include "saul_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set default configuration parameters for the VEML6070 + * @{ + */ +#ifndef VEML6070_PARAM_I2C_DEV +#define VEML6070_PARAM_I2C_DEV I2C_DEV(0) +#endif +#ifndef VEML6070_PARAM_ITIME +#define VEML6070_PARAM_ITIME VEML6070_1_T +#endif + +#define VEML6070_PARAMS_DEFAULT { .i2c_dev = VEML6070_PARAM_I2C_DEV, \ + .itime = VEML6070_PARAM_ITIME } +/**@}*/ + +/** + * @brief Configure VEML6070 + */ +static const veml6070_params_t veml6070_params[] = +{ +#ifdef VEML6070_PARAMS_BOARD + VEML6070_PARAMS_BOARD, +#else + VEML6070_PARAMS_DEFAULT, +#endif +}; + +/** + * @brief Configure SAUL registry entries + */ +static const saul_reg_info_t veml6070_saul_reg_info[] = +{ + { + .name = "veml6070-uv" + } +}; + +#ifdef __cplusplus +} +#endif + +#endif /* VEML6070_PARAMS_H */ +/** @} */ diff --git a/drivers/veml6070/veml6070.c b/drivers/veml6070/veml6070.c new file mode 100644 index 0000000000000000000000000000000000000000..32fa79dd282da3ac497466e4864a88bbba458cd1 --- /dev/null +++ b/drivers/veml6070/veml6070.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2017 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_veml6070 + * @{ + * + * @file + * @brief Device driver implementation for the VEML6070 UV sensor. + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include <math.h> + +#include "log.h" +#include "veml6070.h" +#include "veml6070_params.h" +#include "periph/i2c.h" +#include "xtimer.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define VEML6070_ADDRH (0x39) +#define VEML6070_ADDRL (0x38) + +/*---------------------------------------------------------------------------* + * VEML6070 Core API * + *---------------------------------------------------------------------------*/ + +int veml6070_init(veml6070_t *dev, const veml6070_params_t * params) +{ + dev->params = *params; + + /* Initialize I2C interface */ + if (i2c_init_master(dev->params.i2c_dev, I2C_SPEED_NORMAL)) { + DEBUG("[Error] I2C device not enabled\n"); + return -VEML6070_ERR_I2C; + } + + /* Acquire exclusive access */ + i2c_acquire(dev->params.i2c_dev); + + i2c_write_byte(dev->params.i2c_dev, VEML6070_ADDRL, + (uint8_t)(dev->params.itime << 2) | 0x02); + + /* Release I2C device */ + i2c_release(dev->params.i2c_dev); + + return VEML6070_OK; +} + +uint16_t veml6070_read_uv(veml6070_t *dev) +{ + /* Acquire exclusive access */ + i2c_acquire(dev->params.i2c_dev); + + uint8_t buffer[2]; + i2c_read_byte(dev->params.i2c_dev, VEML6070_ADDRL, &buffer[0]); + i2c_read_byte(dev->params.i2c_dev, VEML6070_ADDRH, &buffer[1]); + + uint16_t uv = (uint16_t)(buffer[1] << 8) | buffer[0]; + + /* Release I2C device */ + i2c_release(dev->params.i2c_dev); + + return uv; +} diff --git a/drivers/veml6070/veml6070_saul.c b/drivers/veml6070/veml6070_saul.c new file mode 100644 index 0000000000000000000000000000000000000000..7ba6dd2fcdd791dcb2bf3ab2bb6563173cdba169 --- /dev/null +++ b/drivers/veml6070/veml6070_saul.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 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_veml6070 + * @{ + * + * @file + * @brief SAUL adaption for VEML6070 UV sensor + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include <string.h> + +#include "saul.h" +#include "veml6070.h" +#include "xtimer.h" + +static int read_uv(void *dev, phydat_t *res) +{ + veml6070_t *d = (veml6070_t *)dev; + + res->val[0] = veml6070_read_uv(d); + res->unit = UNIT_NONE; + res->scale = -1; + return 1; +} + +const saul_driver_t veml6070_uv_saul_driver = { + .read = read_uv, + .write = saul_notsup, + .type = SAUL_SENSE_ANY +}; diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 36b9350ddc3d7423e6a3e2a7828bdee470ce6645..c7813baf1ead038bbe7c9fa3b262975d77433fd9 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -310,6 +310,10 @@ void auto_init(void) extern void auto_init_tcs37727(void); auto_init_tcs37727(); #endif +#ifdef MODULE_VEML6070 + extern void auto_init_veml6070(void); + auto_init_veml6070(); +#endif #endif /* MODULE_AUTO_INIT_SAUL */ diff --git a/sys/auto_init/saul/auto_init_veml6070.c b/sys/auto_init/saul/auto_init_veml6070.c new file mode 100644 index 0000000000000000000000000000000000000000..46ebd2705d41cb5a329ca3f3967cea35214b861a --- /dev/null +++ b/sys/auto_init/saul/auto_init_veml6070.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2017 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 auto_init_saul + * @{ + * + * @file + * @brief Auto initialization of VEML6070 driver. + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#ifdef MODULE_VEML6070 + +#include "log.h" +#include "saul_reg.h" + +#include "veml6070_params.h" + +/** + * @brief Define the number of configured sensors + */ +#define VEML6070_NUMOF (sizeof(veml6070_params) / sizeof(veml6070_params[0])) + +/** + * @brief Allocation of memory for device descriptors + */ +static veml6070_t veml6070_devs[VEML6070_NUMOF]; + +/** + * @brief Memory for the SAUL registry entries + */ +static saul_reg_t saul_entries[VEML6070_NUMOF]; + +/** + * @brief Reference the driver structs. + * @{ + */ +extern const saul_driver_t veml6070_uv_saul_driver; +/** @} */ + +void auto_init_veml6070(void) +{ + for (unsigned i = 0; i < VEML6070_NUMOF; i++) { + LOG_DEBUG("[auto_init_saul] initializing veml6070 #%u\n", i); + + if (veml6070_init(&veml6070_devs[i], + &veml6070_params[i]) != VEML6070_OK) { + LOG_ERROR("[auto_init_saul] error initializing veml6070 #%u\n", i); + return; + } + + saul_entries[(i)].dev = &(veml6070_devs[i]); + saul_entries[(i)].name = veml6070_saul_reg_info[i].name; + saul_entries[(i)].driver = &veml6070_uv_saul_driver; + + /* register to saul */ + saul_reg_add(&(saul_entries[(i)])); + } +} +#else +typedef int dont_be_pedantic; +#endif /* MODULE_VEML6070 */ diff --git a/tests/driver_veml6070/Makefile b/tests/driver_veml6070/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..6f4b9d30e871da7ee2754b8c9d341b7cf76e9cea --- /dev/null +++ b/tests/driver_veml6070/Makefile @@ -0,0 +1,7 @@ +APPLICATION = driver_veml6070 +include ../Makefile.tests_common + +USEMODULE += veml6070 +USEMODULE += xtimer + +include $(RIOTBASE)/Makefile.include diff --git a/tests/driver_veml6070/Readme.md b/tests/driver_veml6070/Readme.md new file mode 100644 index 0000000000000000000000000000000000000000..a60517f11628f9b03ff2f096dcaf48c48e15cfed --- /dev/null +++ b/tests/driver_veml6070/Readme.md @@ -0,0 +1,6 @@ +## About +This is a test application for the VEML6070 UV sensor. + +## Usage +The application initializes the VEML6070 sensor and displays the UV indice +measure every 2 seconds. diff --git a/tests/driver_veml6070/main.c b/tests/driver_veml6070/main.c new file mode 100644 index 0000000000000000000000000000000000000000..0c81fbf01a38dad06efe9da37aef184969355b3b --- /dev/null +++ b/tests/driver_veml6070/main.c @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2017 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 VEML6070 UV sensor + * + * @author Alexandre Abadie <alexandre.abadie@inria.fr> + * + * @} + */ + +#include <stdio.h> +#include <inttypes.h> + +#include "veml6070.h" +#include "veml6070_params.h" +#include "xtimer.h" +#include "board.h" + +#define SLEEP_2S (2 * 1000 * 1000u) /* 2 seconds delay between printf */ + +int main(void) +{ + veml6070_t dev; + int result; + + puts("VEML6070 test application\n"); + + printf("+------------Initializing------------+\n"); + result = veml6070_init(&dev, &veml6070_params[0]); + if (result == VEML6070_ERR_I2C) { + puts("[Error] The given i2c is not enabled"); + return 1; + } else { + printf("Initialization successful\n\n"); + } + + printf("\n+--------Starting Measurements--------+\n"); + while (1) { + printf("UV indive: %d" + "\n+-------------------------------------+\n", + veml6070_read_uv(&dev)); + + xtimer_usleep(SLEEP_2S); + } + + return 0; +}