1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/tsl4531x: Add driver for TSL45315 illuiminance sensor.

Missing run modes and power saving configurations, but otherwise
functional.
This commit is contained in:
Juan Carrano 2018-09-10 14:13:52 +02:00 committed by danpetry
parent 13312ef11e
commit 63dcc18c55
5 changed files with 248 additions and 0 deletions

View File

@ -475,3 +475,7 @@ ifneq (,$(filter xbee,$(USEMODULE)))
USEMODULE += xtimer
USEMODULE += netif
endif
ifneq (,$(filter tsl4531x,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
endif

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* 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_tsl4531x TSL4531x Illuminance sensor
* @ingroup drivers_sensors
* @brief Device driver for the AMS TSL4531 sensor
* @{
*
* @file
* @brief Device driver for the AMS TSL4531 sensor
*
* @author Juan I Carrano <j.carrano@fu-berlin.de>
*/
#ifndef TSL4531x_H
#define TSL4531x_H
#include <stdint.h>
#include "periph/i2c.h"
static const uint16_t TSL4531x_INTEGRATE_400ms = 0; /* 0b00 */
static const uint16_t TSL4531x_INTEGRATE_200ms = 1; /* 0b01 */
static const uint16_t TSL4531x_INTEGRATE_100ms = 2; /* 0b10 */
/**
* @brief Represents a single TSL4531x device.
*/
typedef struct tsl4531x {
i2c_t i2c_dev;
uint8_t integration_time;
} tsl4531x_t;
/**
* Initialize TSL4513 device.
*
* @param dev Device object.
* @param i2c_dev I2C interface to use.
* @param integration_time one of TSL4531x_INTEGRATE_400ms,
* TSL4531x_INTEGRATE_200ms, TSL4531x_INTEGRATE_100ms.
*
* @return Zero on success, negative on error.
*/
int tsl4531x_init(tsl4531x_t *dev, i2c_t i2c_dev, uint8_t integration_time);
/**
* Get the last measurements of illuminance, in lux.
*
* @return 0 on sucess, negative on error. If there is an error, the value of
* `*result_lux` is undefined.
*/
int tsl4531x_read(const tsl4531x_t *dev, uint16_t *result_lux);
#endif /* TSL4531x_H */

View File

@ -0,0 +1,3 @@
MODULE = tsl4531x
include $(RIOTBASE)/Makefile.base

140
drivers/tsl4531x/tsl4531x.c Normal file
View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* 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_tsl4531x
* @{
*
* @file
* @brief Device driver for the TSL4531 Luminosity sensor.
*
* @author Juan I Carrano <j.carrano@fu-berlin.de>
*
* This driver was derived from the one for TSL2561.
*
* @todo The i2c address is hardcoded
* @todo The only operating mode is "Normal Operation"
* @todo PowerSave is not supported
*
* @}
*/
#include <errno.h>
#include "log.h"
#include "tsl4531x.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
static const uint16_t TSL4531_Addr = 0x29;
static const uint16_t TSL4531_PARTNO = 0xA; /* 0b1010 */
static const uint16_t Control_Reg = 0x0;
static const uint16_t Configuration_Reg = 0x01;
static const uint16_t ALSData1_Reg = 0x04; /* contains DATALOW */
static const uint16_t ALSData2_Reg = 0x05; /* contains DATAHIGH */
static const uint16_t ID_Reg = 0x0A;
static const uint16_t TSL4531x_MODE_Normal = 0x03; /* 0b11 */
/* Assemble the Command register */
#define TSL4531_COMMAND(addr) ((1<<7)|(addr))
/* Assemble the Configuration register */
#define TSL4531_CONFIG(psaveskip, tcntrl) (((!!(psaveskip)) << 3) | (tcntrl))
/* Assemble the Control register */
#define TSL4531_CONTROL(mode) (mode)
#define TSL4531_GET_PARTNO(id_reg) ((id_reg) >> 4)
/* Apply the multiplier corresponding to the active integration time */
/* From the manual:
* MULTIPLIER = 1 for TCNTRL = 00 (Tint = 400 ms),
* MULTIPLIER = 2 for TCNTRL = 01 (Tint = 200 ms), and
* MULTIPLIER = 4 for TCNTRL = 10 (Tint = 100 ms), and
*/
#define MULTIPLY_DATA(data_raw, integration_time) ((data_raw) << (integration_time))
int tsl4531x_init(tsl4531x_t *dev, i2c_t i2c_dev, uint8_t integration_time)
{
int r;
uint8_t id;
dev->i2c_dev = i2c_dev;
dev->integration_time = integration_time;
if ((r = i2c_acquire(dev->i2c_dev)) < 0) {
DEBUG("[Error] Cannot acquire device: %d\n", r);
goto acquire_error;
}
/* Verify sensor ID */
if ((r = i2c_read_reg(dev->i2c_dev, TSL4531_Addr, TSL4531_COMMAND(ID_Reg),
&id, 0)) < 0) {
DEBUG("[Error] Cannot read ID register: %d\n", r);
goto init_error;
}
DEBUG("[Info] ID ? %d\n", id);
if (TSL4531_GET_PARTNO(id) != TSL4531_PARTNO) {
DEBUG("[Error] not a TSL4531 sensor\n");
r = -ENOTSUP;
goto init_error;
}
/* configure device */
if (((r = i2c_write_reg(dev->i2c_dev , TSL4531_Addr, TSL4531_COMMAND(Control_Reg),
TSL4531_CONTROL(TSL4531x_MODE_Normal), 0)) < 0)
||
((r = i2c_write_reg(dev->i2c_dev , TSL4531_Addr, TSL4531_COMMAND(Configuration_Reg),
TSL4531_CONFIG(1, integration_time), 0)) < 0)) {
DEBUG("[Error] Cannot configure device %d\n", r);
goto init_error;
}
init_error:
/* ignore errors on device release */
i2c_release(dev->i2c_dev);
acquire_error:
return r;
}
#define _DATALOW 0
#define _DATAHIGH 1
int tsl4531x_read(const tsl4531x_t *dev, uint16_t *result_lux)
{
int r;
uint8_t als_data[2]; /* = {[DATALOW], [DATAHIGH]} */
if ((r = i2c_acquire(dev->i2c_dev)) < 0) {
DEBUG("[Error] Cannot acquire device: %d\n", r);
goto read_acquire_error;
}
if ((r = i2c_read_regs(dev->i2c_dev, TSL4531_Addr, TSL4531_COMMAND(ALSData1_Reg),
als_data, 2, 0)) < 0) {
(void)ALSData2_Reg; /* suppress warning */
DEBUG("[Error] Cannot read device: %d\n", r);
goto read_error;
}
*result_lux = MULTIPLY_DATA((((uint16_t)als_data[_DATAHIGH]) << 8)
+ als_data[_DATALOW], dev->integration_time);
read_error:
/* ignore errors on device release */
i2c_release(dev->i2c_dev);
read_acquire_error:
return r;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2018 Freie Universität Berlin
*
* 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_tsl4531x
* @{
*
* @file
* @brief SAUL interface for TSL4531 Luminosity sensor.
*
* @author Juan I Carrano <j.carrano@fu-berlin.de>
*
* @}
*/
#include "saul.h"
#include "tsl4531x.h"
static int _read(const void *dev, phydat_t *res)
{
int nvals;
uint16_t lux;
nvals = (tsl4531x_read(dev, &lux) >= 0)? 1 : 0;
res->val[0] = lux;
res->unit = UNIT_LUX;
res->scale = 0;
return nvals;
}
const saul_driver_t tsl2561_illuminance_saul_driver = {
.read = _read,
.write = saul_notsup,
.type = SAUL_SENSE_LIGHT
};