Skip to content
Snippets Groups Projects
Unverified Commit 7fde6fc2 authored by Gunar Schorcht's avatar Gunar Schorcht Committed by GitHub
Browse files

Merge pull request #6712 from aabadie/driver_vcnl4010

drivers/vcnl4010: initial implementation
parents 3849c4b3 456e0a3a
No related branches found
No related tags found
No related merge requests found
Showing
with 788 additions and 0 deletions
......@@ -452,6 +452,11 @@ ifneq (,$(filter uart_half_duplex,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter vcnl40%0,$(USEMODULE)))
USEMODULE += vcnl40x0
FEATURES_REQUIRED += periph_i2c
endif
ifneq (,$(filter veml6070,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
endif
......
......@@ -246,6 +246,10 @@ ifneq (,$(filter uart_half_duplex,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/uart_half_duplex/include
endif
ifneq (,$(filter vcnl40x0,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/vcnl40x0/include
endif
ifneq (,$(filter veml6070,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/veml6070/include
endif
......
......@@ -97,6 +97,7 @@ enum {
SAUL_SENSE_CO2 = 0x8f, /**< sensor: CO2 Gas */
SAUL_SENSE_TVOC = 0x90, /**< sensor: TVOC Gas */
SAUL_SENSE_OCCUP = 0x91, /**< sensor: occupancy */
SAUL_SENSE_PROXIMITY= 0x92, /**< sensor: proximity */
SAUL_CLASS_ANY = 0xff /**< any device - wildcard */
/* extend this list as needed... */
};
......
/*
* 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_vcnl40x0 VCNL4010/VCNL4020/VCNL4040 Proximity and Ambient Light Sensors
* @ingroup drivers_sensors
* @brief Device driver interface for the VCNL40X0 Proximity and Ambient Light Sensors.
* @{
*
* @file
* @brief Device driver interface for the VCNL40X0 sensors family.
*
* @note VCNL4010, VCNL4020 and VCNL4040 are supported.
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*/
#ifndef VCNL40X0_H
#define VCNL40X0_H
#include "saul.h"
#include "periph/i2c.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Proximity measure rate
*/
enum {
VCNL40X0_PROXIMITY_RATE_2 = 0, /**< 1.95 measurements/s (default) */
VCNL40X0_PROXIMITY_RATE_4, /**< 3.90625 measurements/s */
VCNL40X0_PROXIMITY_RATE_8, /**< 7.8125 measurements/s */
VCNL40X0_PROXIMITY_RATE_16, /**< 16.625 measurements/s */
VCNL40X0_PROXIMITY_RATE_31, /**< 31.25 measurements/s */
VCNL40X0_PROXIMITY_RATE_62, /**< 62.5 measurements/s */
VCNL40X0_PROXIMITY_RATE_125, /**< 125 measurements/s */
VCNL40X0_PROXIMITY_RATE_250, /**< 250 measurements/s */
};
/**
* @brief Ambient light measurement rate
*/
enum {
VCNL40X0_AMBIENT_RATE_1 = 0, /**< 1 sample/s */
VCNL40X0_AMBIENT_RATE_2, /**< 2 sample/s (default) */
VCNL40X0_AMBIENT_RATE_3, /**< 3 sample/s */
VCNL40X0_AMBIENT_RATE_4, /**< 4 sample/s */
VCNL40X0_AMBIENT_RATE_5, /**< 5 sample/s */
VCNL40X0_AMBIENT_RATE_6, /**< 6 sample/s */
VCNL40X0_AMBIENT_RATE_8, /**< 8 sample/s */
VCNL40X0_AMBIENT_RATE_10, /**< 10 sample/s */
};
/**
* @brief Ambient light number of conversions during one measurement cycle
*
* Number of conversions = 2^decimal value
*/
enum {
VCNL40X0_AMBIENT_AVERAGE_1 = 0, /**< Decimal value 1 */
VCNL40X0_AMBIENT_AVERAGE_2, /**< Decimal value 2 */
VCNL40X0_AMBIENT_AVERAGE_4, /**< Decimal value 4 */
VCNL40X0_AMBIENT_AVERAGE_8, /**< Decimal value 8 */
VCNL40X0_AMBIENT_AVERAGE_16, /**< Decimal value 16 */
VCNL40X0_AMBIENT_AVERAGE_32, /**< Decimal value 32 (default) */
VCNL40X0_AMBIENT_AVERAGE_64, /**< Decimal value 64 */
VCNL40X0_AMBIENT_AVERAGE_128, /**< Decimal value 128 */
};
/**
* @brief Status and error return codes
*/
enum {
VCNL40X0_OK = 0, /**< Everything was fine */
VCNL40X0_ERR_I2C, /**< Error initializing the I2C bus */
VCNL40X0_ERR_NODEV /**< Error wrong device */
};
/**
* @brief Device initialization parameters
*/
typedef struct {
i2c_t i2c_dev; /**< I2C device which is used */
uint8_t i2c_addr; /**< Address on I2C bus */
uint8_t led_current; /**< LED current */
uint8_t proximity_rate; /**< Proximity rate */
uint8_t ambient_rate; /**< Ambient light rate */
uint8_t ambient_avg; /**< Ambient light conversion average */
} vcnl40x0_params_t;
/**
* @brief Device descriptor for the VCNL40X0 sensor
*/
typedef struct {
vcnl40x0_params_t params; /**< Device parameters */
} vcnl40x0_t;
/**
* @brief Initialize the given VCNL40X0 device
*
* @param[out] dev Initialized device descriptor of VCNL40X0 device
* @param[in] params The parameters for the VCNL40X0 device
*
* @return VCNL40X0_OK on success
* @return -VCNL40X0_ERR_I2C if given I2C is not enabled in board config
* @return -VCNL40X0_ERR_NODEV if not a vcnl40X0 device
*/
int vcnl40x0_init(vcnl40x0_t *dev, const vcnl40x0_params_t *params);
/**
* @brief Read proximity value from the vcnl40X0 device
*
* @param[in] dev Device descriptor of VCNL40X0 device to read from
*
* @return Proximity in counts
*/
uint16_t vcnl40x0_read_proximity(const vcnl40x0_t *dev);
/**
* @brief Read ambient light value from the vcnl40X0 device
*
* @param[in] dev Device descriptor of VCNL40X0 device to read from
*
* @return Ambient light in counts
*/
uint16_t vcnl40x0_read_ambient_light(const vcnl40x0_t *dev);
/**
* @brief Read illuminance value from the vcnl40X0 device
*
* @param[in] dev Device descriptor of VCNL40X0 device to read from
*
* @return Illuminance in lux
*/
uint16_t vcnl40x0_read_illuminance(const vcnl40x0_t *dev);
#ifdef __cplusplus
}
#endif
#endif /* VCNL40X0_H */
/** @} */
......@@ -53,6 +53,7 @@ const char *saul_class_to_str(const uint8_t class_id)
case SAUL_SENSE_DISTANCE: return "SENSE_DISTANCE";
case SAUL_SENSE_CO2: return "SENSE_CO2";
case SAUL_SENSE_TVOC: return "SENSE_TVOC";
case SAUL_SENSE_PROXIMITY: return "SENSE_PROXIMITY";
case SAUL_CLASS_ANY: return "CLASS_ANY";
case SAUL_SENSE_OCCUP: return "SENSE_OCCUP";
default: return "CLASS_UNKNOWN";
......
include $(RIOTBASE)/Makefile.base
/*
* 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_vcnl40x0
* @{
*
* @file
* @brief Internal addresses, registers, constants for the VCNL40X0 devices.
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
* @}
*/
#ifndef VCNL40X0_INTERNALS_H
#define VCNL40X0_INTERNALS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief VCNL40X0 I2C address
*/
#define VCNL40X0_ADDR (0x13)
/**
* @brief VCNL40X0 product ID
*/
#define VCNL40X0_PRODUCT_ID (0x20)
/**
* @name VCNL40X0 registers
* @{
*/
#define VCNL40X0_REG_COMMAND (0x80)
#define VCNL40X0_REG_PRODUCT_ID (0x81)
#define VCNL40X0_REG_PROXIMITY_RATE (0x82)
#define VCNL40X0_REG_PROXIMITY_CURRENT (0x83)
#define VCNL40X0_REG_AMBIENT_PARAMETER (0x84)
#define VCNL40X0_REG_AMBIENT_VALUE (0x85)
#define VCNL40X0_REG_PROXIMITY_VALUE (0x87)
#define VCNL40X0_REG_INTERRUPT_CONTROL (0x89)
#define VCNL40X0_REG_INTERRUPT_LOW_THRES (0x8a)
#define VCNL40X0_REG_HIGH_THRES (0x8c)
#define VCNL40X0_REG_INTERRUPT_STATUS (0x8e)
#define VCNL40X0_REG_PROX_TIMING (0xf9)
#define VCNL40X0_REG_AMBIENT_IR_LIGHT_LEVEL (0x90) /* should not be used */
/** @} */
/**
* @name VCNL40X0 command register constants
* @{
*/
#define VCNL40X0_COMMAND_ALL_DISABLE (0x00)
#define VCNL40X0_COMMAND_SELFTIMED_MODE_ENABLE (0x01)
#define VCNL40X0_COMMAND_PROX_ENABLE (0x02)
#define VCNL40X0_COMMAND_AMBI_ENABLE (0x04)
#define VCNL40X0_COMMAND_PROX_ON_DEMAND (0x08)
#define VCNL40X0_COMMAND_AMBI_ON_DEMAND (0x10)
#define VCNL40X0_COMMAND_MASK_PROX_DATA_READY (0x20)
#define VCNL40X0_COMMAND_MASK_AMBI_DATA_READY (0x40)
#define VCNL40X0_COMMAND_MASK_LOCK (0x80)
/** @} */
/**
* @name VCNL40X0 product ID register constants
* @{
*/
#define VCNL40X0_PRODUCT_MASK_REVISION_ID (0x0f)
#define VCNL40X0_PRODUCT_MASK_PRODUCT_ID (0xf0)
/** @} */
/**
* @name VCNL40X0 proximity rate register constants
* @{
*/
#define VCNL40X0_PROXIMITY_MASK_MEASUREMENT_RATE (0x07)
#define VCNL40X0_PROXIMITY_MASK_LED_CURRENT (0x3f)
#define VCNL40X0_PROXIMITY_MASK_FUSE_PROG_ID (0xc0)
/** @} */
/**
* @name VCNL40X0 ambient light parameter register constants
* @{
*/
#define VCNL40X0_AMBIENT_MASK_PARA_AVERAGE (0x07)
#define VCNL40X0_AMBIENT_PARA_AUTO_OFFSET_ENABLE (0x08)
#define VCNL40X0_AMBIENT_MASK_PARA_AUTO_OFFSET (0x08)
#define VCNL40X0_AMBIENT_MASK_PARA_MEAS_RATE (0x70)
#define VCNL40X0_AMBIENT_PARA_CONT_CONV_ENABLE (0x80)
#define VCNL40X0_AMBIENT_MASK_PARA_CONT_CONV (0x80)
/** @} */
/**
* @name VCNL40X0 interrupt control register constants
* @{
*/
#define VCNL40X0_INTERRUPT_THRES_SEL_PROX (0x00)
#define VCNL40X0_INTERRUPT_THRES_SEL_ALS (0x01)
#define VCNL40X0_INTERRUPT_THRES_ENABLE (0x02)
#define VCNL40X0_INTERRUPT_ALS_READY_ENABLE (0x04)
#define VCNL40X0_INTERRUPT_PROX_READY_ENABLE (0x08)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_1 (0x00)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_2 (0x20)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_4 (0x40)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_8 (0x60)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_16 (0x80)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_32 (0xa0)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_64 (0xc0)
#define VCNL40X0_INTERRUPT_COUNT_EXCEED_128 (0xe0)
#define VCNL40X0_INTERRUPT_MASK_COUNT_EXCEED (0xe0)
/** @} */
/**
* @name VCNL40X0 interrupt status register constants
* @{
*/
#define VCNL40X0_INTERRUPT_STATUS_THRES_HI (0x01)
#define VCNL40X0_INTERRUPT_STATUS_THRES_LO (0x02)
#define VCNL40X0_INTERRUPT_STATUS_ALS_READY (0x04)
#define VCNL40X0_INTERRUPT_STATUS_PROX_READY (0x08)
#define VCNL40X0_INTERRUPT_MASK_STATUS_THRES_HI (0x01)
#define VCNL40X0_INTERRUPT_MASK_THRES_LO (0x02)
#define VCNL40X0_INTERRUPT_MASK_ALS_READY (0x04)
#define VCNL40X0_INTERRUPT_MASK_PROX_READY (0x08)
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* VCNL40X0_INTERNALS_H */
/** @} */
/*
* 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_vcnl40x0
*
* @{
* @file
* @brief Default configuration for VCNL40X0 devices
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*/
#ifndef VCNL40X0_PARAMS_H
#define VCNL40X0_PARAMS_H
#include "board.h"
#include "vcnl40x0.h"
#include "vcnl40x0_internals.h"
#include "saul_reg.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Default configuration parameters for the VCNL40X0
* @{
*/
#ifndef VCNL40X0_PARAM_I2C_DEV
#define VCNL40X0_PARAM_I2C_DEV I2C_DEV(0)
#endif
#ifndef VCNL40X0_PARAM_I2C_ADDR
#define VCNL40X0_PARAM_I2C_ADDR (VCNL40X0_ADDR)
#endif
#ifndef VCNL40X0_PARAM_LED_CURRENT
#define VCNL40X0_PARAM_LED_CURRENT (2U)
#endif
#ifndef VCNL40X0_PARAM_PROXIMITY_RATE
#define VCNL40X0_PARAM_PROXIMITY_RATE (VCNL40X0_PROXIMITY_RATE_2)
#endif
#ifndef VCNL40X0_PARAM_AMBIENT_AVG
#define VCNL40X0_PARAM_AMBIENT_AVG (VCNL40X0_AMBIENT_AVERAGE_32)
#endif
#ifndef VCNL40X0_PARAM_AMBIENT_RATE
#define VCNL40X0_PARAM_AMBIENT_RATE (VCNL40X0_AMBIENT_RATE_2)
#endif
#define VCNL40X0_PARAMS { .i2c_dev = VCNL40X0_PARAM_I2C_DEV, \
.i2c_addr = VCNL40X0_PARAM_I2C_ADDR, \
.led_current = VCNL40X0_PARAM_LED_CURRENT, \
.proximity_rate = VCNL40X0_PARAM_PROXIMITY_RATE, \
.ambient_avg = VCNL40X0_PARAM_AMBIENT_AVG, \
.ambient_rate = VCNL40X0_PARAM_AMBIENT_RATE }
/**@}*/
/**
* @brief Configure VCNL40X0
*/
static const vcnl40x0_params_t vcnl40x0_params[] =
{
VCNL40X0_PARAMS,
};
/**
* @brief Configure SAUL registry entries
*/
static const saul_reg_info_t vcnl40x0_saul_reg_info[] =
{
{ .name = "vcnl40x0" }
};
#ifdef __cplusplus
}
#endif
#endif /* VCNL40X0_PARAMS_H */
/** @} */
/*
* 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_vcnl40x0
* @{
*
* @file
* @brief Device driver implementation for VCNL40X0 Proximity and Ambient Light devices.
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*
* @}
*/
#include "vcnl40x0.h"
#include "vcnl40x0_internals.h"
#include "vcnl40x0_params.h"
#include "periph/i2c.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define DEV_I2C (dev->params.i2c_dev)
#define DEV_ADDR (dev->params.i2c_addr)
/* Internal functions */
static int _set_command_reg(const vcnl40x0_t *dev, uint8_t reg)
{
if (i2c_write_reg(DEV_I2C, DEV_ADDR, VCNL40X0_REG_COMMAND, reg, 0) != 0) {
return -1;
}
return 0;
}
static int _get_command_reg(const vcnl40x0_t *dev, uint8_t *reg)
{
if (i2c_read_reg(DEV_I2C, DEV_ADDR, VCNL40X0_REG_COMMAND, reg, 0) != 0) {
return -1;
}
return 0;
}
/*---------------------------------------------------------------------------*
* VCNL40X0 Core API *
*---------------------------------------------------------------------------*/
int vcnl40x0_init(vcnl40x0_t *dev, const vcnl40x0_params_t *params)
{
dev->params = *params;
/* Acquire exclusive access */
i2c_acquire(DEV_I2C);
/* Check sensor ID */
uint8_t checkid;
i2c_read_reg(DEV_I2C, DEV_ADDR, VCNL40X0_REG_PRODUCT_ID,
&checkid, 0);
if ((checkid & VCNL40X0_PRODUCT_MASK_PRODUCT_ID) != VCNL40X0_PRODUCT_ID) {
DEBUG("[vcnl40x0] Error: wrong device ID '0x%02x', expected '0x%02x'\n",
checkid, VCNL40X0_PRODUCT_ID);
i2c_release(DEV_I2C);
return -VCNL40X0_ERR_NODEV;
}
/* LED current cannot be above 20 */
if (dev->params.led_current > 20) {
dev->params.led_current = 20;
}
if (i2c_write_reg(DEV_I2C, DEV_ADDR, VCNL40X0_REG_PROXIMITY_CURRENT,
dev->params.led_current, 0) != 0) {
DEBUG("[vcnl40x0] Error: failed to set proximity current\n");
i2c_release(DEV_I2C);
return -VCNL40X0_ERR_I2C;
}
if (_set_command_reg(dev, VCNL40X0_COMMAND_ALL_DISABLE) < 0) {
DEBUG("[vcnl40x0] Error: failed to set disable all commands\n");
i2c_release(DEV_I2C);
return -VCNL40X0_ERR_I2C;
}
if (i2c_write_reg(DEV_I2C, DEV_ADDR, VCNL40X0_REG_PROXIMITY_RATE,
dev->params.proximity_rate, 0) != 0) {
DEBUG("[vcnl40x0] Error: failed to set proximity rate\n");
i2c_release(DEV_I2C);
return -VCNL40X0_ERR_I2C;
}
if (i2c_write_reg(DEV_I2C, DEV_ADDR, VCNL40X0_REG_AMBIENT_PARAMETER,
dev->params.ambient_rate |
VCNL40X0_AMBIENT_PARA_AUTO_OFFSET_ENABLE |
dev->params.ambient_avg, 0) != 0) {
DEBUG("[vcnl40x0] Error: failed to set ambient light rate\n");
i2c_release(DEV_I2C);
return -VCNL40X0_ERR_I2C;
}
/* Release I2C device */
i2c_release(DEV_I2C);
DEBUG("[vcnl40x0] info: vcnl40x0 sensor initialized with success\n");
return VCNL40X0_OK;
}
uint16_t vcnl40x0_read_proximity(const vcnl40x0_t *dev)
{
i2c_acquire(DEV_I2C);
_set_command_reg(dev,
VCNL40X0_COMMAND_PROX_ENABLE |
VCNL40X0_COMMAND_PROX_ON_DEMAND);
uint16_t cnt = 0xffff;
while (cnt--) {
uint8_t reg;
_get_command_reg(dev, &reg);
if (reg & VCNL40X0_COMMAND_MASK_PROX_DATA_READY) {
uint8_t prox_buf[2];
i2c_read_regs(DEV_I2C, DEV_ADDR, VCNL40X0_REG_PROXIMITY_VALUE,
&prox_buf, 2, 0);
uint16_t res = (uint16_t)((prox_buf[0] << 8) | prox_buf[1]);
DEBUG("[vcnl40x0] Proximity read: %i\n", res);
i2c_release(DEV_I2C);
return res;
}
}
i2c_release(DEV_I2C);
return 0;
}
uint16_t vcnl40x0_read_ambient_light(const vcnl40x0_t *dev)
{
i2c_acquire(DEV_I2C);
_set_command_reg(dev,
VCNL40X0_COMMAND_AMBI_ENABLE |
VCNL40X0_COMMAND_AMBI_ON_DEMAND);
uint16_t cnt = 0xffff;
while (cnt--) {
uint8_t reg;
_get_command_reg(dev, &reg);
if (reg & VCNL40X0_COMMAND_MASK_AMBI_DATA_READY) {
uint8_t ambient_buf[2];
i2c_read_regs(DEV_I2C, DEV_ADDR, VCNL40X0_REG_AMBIENT_VALUE,
&ambient_buf, 2, 0);
uint16_t res = (uint16_t)((ambient_buf[0] << 8) | ambient_buf[1]);
DEBUG("[vcnl40x0] Ambient light read: %i\n", res);
i2c_release(DEV_I2C);
return res;
}
}
i2c_release(DEV_I2C);
return 0;
}
uint16_t vcnl40x0_read_illuminance(const vcnl40x0_t *dev)
{
return vcnl40x0_read_ambient_light(dev) >> 2;
}
/*
* 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_vcnl40x0
* @{
*
* @file
* @brief SAUL adaption for VCNL40X0 devices
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*
* @}
*/
#include <string.h>
#include "saul.h"
#include "vcnl40x0.h"
#include "vcnl40x0_params.h"
#include "xtimer.h"
static int read_proximity(const void *dev, phydat_t *res)
{
const vcnl40x0_t *d = (vcnl40x0_t *)dev;
res->val[0] = (int16_t)vcnl40x0_read_proximity(d);
res->unit = UNIT_CTS;
res->scale = 0;
return 1;
}
static int read_illuminance(const void *dev, phydat_t *res)
{
const vcnl40x0_t *d = (vcnl40x0_t *)dev;
res->val[0] = (int16_t)vcnl40x0_read_illuminance(d);
res->unit = UNIT_LUX;
res->scale = 0;
return 1;
}
const saul_driver_t vcnl40x0_proximity_saul_driver = {
.read = read_proximity,
.write = saul_notsup,
.type = SAUL_SENSE_PROXIMITY
};
const saul_driver_t vcnl40x0_illuminance_saul_driver = {
.read = read_illuminance,
.write = saul_notsup,
.type = SAUL_SENSE_LIGHT
};
......@@ -116,6 +116,11 @@ PSEUDOMODULES += si7021
PSEUDOMODULES += rn2483
PSEUDOMODULES += rn2903
# include variants of VCNL40x0 drivers as pseudo modules
PSEUDOMODULES += vcnl4010
PSEUDOMODULES += vcnl4020
PSEUDOMODULES += vcnl4040
# add all pseudo random number generator variants as pseudomodules
PSEUDOMODULES += prng_%
......
......@@ -433,6 +433,10 @@ void auto_init(void)
extern void auto_init_tsl2561(void);
auto_init_tsl2561();
#endif
#ifdef MODULE_VCNL40X0
extern void auto_init_vcnl40x0(void);
auto_init_vcnl40x0();
#endif
#ifdef MODULE_VEML6070
extern void auto_init_veml6070(void);
auto_init_veml6070();
......
/*
* 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 VCNL40X0 driver.
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*
* @}
*/
#ifdef MODULE_VCNL40X0
#include "log.h"
#include "saul_reg.h"
#include "vcnl40x0_params.h"
#define ENABLE_DEBUG (0)
/**
* @brief Define the number of configured sensors
*/
#define VCNL40X0_NUMOF (sizeof(vcnl40x0_params) / sizeof(vcnl40x0_params[0]))
/**
* @brief Allocation of memory for device descriptors
*/
static vcnl40x0_t vcnl40x0_devs[VCNL40X0_NUMOF];
/**
* @brief Memory for the SAUL registry entries
*/
static saul_reg_t saul_entries[VCNL40X0_NUMOF * 2];
/**
* @brief Reference the driver structs.
* @{
*/
extern const saul_driver_t vcnl40x0_proximity_saul_driver;
extern const saul_driver_t vcnl40x0_illuminance_saul_driver;
/** @} */
void auto_init_vcnl40x0(void)
{
for (unsigned i = 0; i < VCNL40X0_NUMOF; i++) {
LOG_DEBUG("[auto_init_saul] initializing vcnl40x0 #%u\n", i);
if (vcnl40x0_init(&vcnl40x0_devs[i],
&vcnl40x0_params[i]) != VCNL40X0_OK) {
LOG_ERROR("[auto_init_saul] error initializing vcnl40x0 #%u\n", i);
return;
}
/* proximity */
saul_entries[(i * 2)].dev = &(vcnl40x0_devs[i]);
saul_entries[(i * 2)].name = vcnl40x0_saul_reg_info[i].name;
saul_entries[(i * 2)].driver = &vcnl40x0_proximity_saul_driver;
/* illuminance */
saul_entries[(i * 2) + 1].dev = &(vcnl40x0_devs[i]);
saul_entries[(i * 2) + 1].name = vcnl40x0_saul_reg_info[i].name;
saul_entries[(i * 2) + 1].driver = &vcnl40x0_illuminance_saul_driver;
/* register to saul */
saul_reg_add(&(saul_entries[(i * 2)]));
saul_reg_add(&(saul_entries[(i * 2) + 1]));
}
}
#else
typedef int dont_be_pedantic;
#endif /* MODULE_VCNL40X0 */
......@@ -101,6 +101,7 @@ enum {
UNIT_CD, /**< Candela */
/* logical */
UNIT_BOOL, /**< boolean value [0|1] */
UNIT_CTS, /**< counts */
UNIT_PERCENT, /**< out of 100 */
UNIT_PERMILL, /**< out of 1000 */
UNIT_PPM, /**< part per million */
......
......@@ -98,6 +98,7 @@ const char *phydat_unit_to_str(uint8_t unit)
case UNIT_PPB: return "ppb";
case UNIT_CD: return "cd";
case UNIT_PERCENT: return "%";
case UNIT_CTS: return "cts";
default: return "";
}
}
......
APPLICATION = driver_vcnl40x0
include ../Makefile.tests_common
USEMODULE += vcnl4010
USEMODULE += xtimer
include $(RIOTBASE)/Makefile.include
## About
This is a test application for the VCNL40X0 proximity and ambient light sensor.
## Usage
After initialization, every 2 seconds, the application:
* reads the proximity (cts);
* reads the ambient light (cts);
* reads the illuminance (computed from ambient light by dividing it by 4);
* those values are printed to STDOUT.
/*
* 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 VNCL40X0 proximity and ambient light sensor.
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*
* @}
*/
#include <stdio.h>
#include <inttypes.h>
#include "vcnl40x0.h"
#include "vcnl40x0_params.h"
#include "xtimer.h"
#include "board.h"
#define SLEEP_2S (2U) /* 2 seconds delay between printf */
int main(void)
{
vcnl40x0_t dev;
int result;
puts("VCNL40X0 test application\n");
printf("+------------Initializing------------+\n");
result = vcnl40x0_init(&dev, &vcnl40x0_params[0]);
if (result == -VCNL40X0_ERR_I2C) {
puts("[Error] The given i2c is not enabled");
return 1;
}
else if (result == -VCNL40X0_ERR_NODEV) {
puts("[Error] The sensor did not answer correctly on the given address");
return 1;
}
else {
printf("Initialization successful\n\n");
}
printf("\n+--------Starting Measurements--------+\n");
while (1) {
printf("Proximity [cts]: %d\n"
"Ambient light [cts]: %d\n"
"Illuminance [lx]: %d\n"
"\n+-------------------------------------+\n",
vcnl40x0_read_proximity(&dev),
vcnl40x0_read_ambient_light(&dev),
vcnl40x0_read_illuminance(&dev));
xtimer_sleep(SLEEP_2S);
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment