mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/vcnl40x0: initial implementation
This commit is contained in:
parent
83be0314be
commit
1ca44cf072
@ -452,6 +452,11 @@ ifneq (,$(filter uart_half_duplex,$(USEMODULE)))
|
|||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter vcnl40%0,$(USEMODULE)))
|
||||||
|
USEMODULE += vcnl40x0
|
||||||
|
FEATURES_REQUIRED += periph_i2c
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter veml6070,$(USEMODULE)))
|
ifneq (,$(filter veml6070,$(USEMODULE)))
|
||||||
FEATURES_REQUIRED += periph_i2c
|
FEATURES_REQUIRED += periph_i2c
|
||||||
endif
|
endif
|
||||||
|
@ -246,6 +246,10 @@ ifneq (,$(filter uart_half_duplex,$(USEMODULE)))
|
|||||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/uart_half_duplex/include
|
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/uart_half_duplex/include
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter vcnl40x0,$(USEMODULE)))
|
||||||
|
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/vcnl40x0/include
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter veml6070,$(USEMODULE)))
|
ifneq (,$(filter veml6070,$(USEMODULE)))
|
||||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/veml6070/include
|
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/veml6070/include
|
||||||
endif
|
endif
|
||||||
|
@ -97,6 +97,7 @@ enum {
|
|||||||
SAUL_SENSE_CO2 = 0x8f, /**< sensor: CO2 Gas */
|
SAUL_SENSE_CO2 = 0x8f, /**< sensor: CO2 Gas */
|
||||||
SAUL_SENSE_TVOC = 0x90, /**< sensor: TVOC Gas */
|
SAUL_SENSE_TVOC = 0x90, /**< sensor: TVOC Gas */
|
||||||
SAUL_SENSE_OCCUP = 0x91, /**< sensor: occupancy */
|
SAUL_SENSE_OCCUP = 0x91, /**< sensor: occupancy */
|
||||||
|
SAUL_SENSE_PROXIMITY= 0x92, /**< sensor: proximity */
|
||||||
SAUL_CLASS_ANY = 0xff /**< any device - wildcard */
|
SAUL_CLASS_ANY = 0xff /**< any device - wildcard */
|
||||||
/* extend this list as needed... */
|
/* extend this list as needed... */
|
||||||
};
|
};
|
||||||
|
149
drivers/include/vcnl40x0.h
Normal file
149
drivers/include/vcnl40x0.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
||||||
|
/** @} */
|
1
drivers/vcnl40x0/Makefile
Normal file
1
drivers/vcnl40x0/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
include $(RIOTBASE)/Makefile.base
|
139
drivers/vcnl40x0/include/vcnl40x0_internals.h
Normal file
139
drivers/vcnl40x0/include/vcnl40x0_internals.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
||||||
|
/** @} */
|
83
drivers/vcnl40x0/include/vcnl40x0_params.h
Normal file
83
drivers/vcnl40x0/include/vcnl40x0_params.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
||||||
|
/** @} */
|
172
drivers/vcnl40x0/vcnl40x0.c
Normal file
172
drivers/vcnl40x0/vcnl40x0.c
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* 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, ®);
|
||||||
|
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, ®);
|
||||||
|
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;
|
||||||
|
}
|
59
drivers/vcnl40x0/vcnl40x0_saul.c
Normal file
59
drivers/vcnl40x0/vcnl40x0_saul.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user