
5 changed files with 407 additions and 0 deletions
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2015 Ludwig Ortmann |
||||
* |
||||
* 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 driver_isl29125 ISL29125 light sensor |
||||
* @ingroup drivers |
||||
* @brief Device driver for the ISL29125 RGB light sensor |
||||
* |
||||
* ## Description |
||||
* |
||||
* The device supports level conversion in 12, and 16 bit depth per |
||||
* channel. Selecting a higher precision results in a longer |
||||
* conversion time. |
||||
* |
||||
* The driver uses the @ref color_rgb_t color definition from @ref |
||||
* color.h for value representation. It does not depend on the color |
||||
* module however. |
||||
* |
||||
* ## Usage |
||||
* |
||||
* Examine `tests/driver_isr29125` for an exemplary application using |
||||
* this driver. |
||||
* |
||||
* ## Caveats |
||||
* |
||||
* A GPIO pin definition has been included in the interface for future |
||||
* compatibility only. |
||||
* - The driver does not support SYNC mode at the moment. |
||||
* - The driver supports polling only, i.e. interrupt mode is |
||||
* currently not supported. |
||||
* |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief Device driver interface for the ISL29125 RGB light sensor |
||||
* |
||||
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de |
||||
*/ |
||||
|
||||
#ifndef ISL29125_H |
||||
#define ISL29125_H |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include "periph/i2c.h" |
||||
#include "periph/gpio.h" |
||||
#include "color.h" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/**
|
||||
* @brief data type for storing lux RGB sensor readings |
||||
*/ |
||||
typedef struct { |
||||
float red; /**< red lux value */ |
||||
float green; /**< green lux value */ |
||||
float blue; /**< blue lux value */ |
||||
} isl29125_rgb_t; |
||||
|
||||
/**
|
||||
* @brief supported operation modes of the ISL29125 sensor's AD |
||||
* conversion |
||||
*/ |
||||
typedef enum { |
||||
ISL29125_MODE_DOWN = 0x00, /**< ADC powered down */ |
||||
ISL29125_MODE_STANDBY = 0x04, /**< AD conversion not performed */ |
||||
ISL29125_MODE_RGB = 0x05, /**< RGB conversion */ |
||||
ISL29125_MODE_R = 0x02, /**< red conversion only */ |
||||
ISL29125_MODE_G = 0x01, /**< green conversion only */ |
||||
ISL29125_MODE_B = 0x03, /**< blue conversion only */ |
||||
ISL29125_MODE_RG = 0x06, /**< red and green conversion only */ |
||||
ISL29125_MODE_GB = 0x07 /**< green and blue conversion only */ |
||||
} isl29125_mode_t; |
||||
|
||||
/**
|
||||
* @brief supported RGB sensing range values of the ISL29125 sensor |
||||
*/ |
||||
typedef enum { |
||||
ISL29125_RANGE_375 = 0x00, /**< range: 5.7m - 375 lux */ |
||||
ISL29125_RANGE_10K = 0x08 /**< range: 0.152 - 10,000 lux */ |
||||
} isl29125_range_t; |
||||
|
||||
/**
|
||||
* @brief supported color resolutions of the ISL29125 sensor's AD |
||||
* conversion |
||||
*/ |
||||
typedef enum { |
||||
ISL29125_RESOLUTION_12 = 0x10, /**< resolution: 12 bit */ |
||||
ISL29125_RESOLUTION_16 = 0x00 /**< resolution: 16 bit */ |
||||
} isl29125_resolution_t; |
||||
|
||||
/**
|
||||
* @brief Device descriptor for ISL29125 sensors |
||||
*/ |
||||
typedef struct { |
||||
i2c_t i2c; /**< I2C device the sensor is connected to */ |
||||
gpio_t gpio; /**< GPIO pin for interrupt/sync mode */ |
||||
isl29125_range_t range; /**< sensor range */ |
||||
isl29125_resolution_t res; /**< sensor resolution */ |
||||
} isl29125_t; |
||||
|
||||
/**
|
||||
* @brief initialize a new ISL29125 device |
||||
* |
||||
* @param[in] dev device descriptor of an ISL29125 device |
||||
* @param[in] i2c I2C device the sensor is connected to |
||||
* @param[in] gpio GPIO pin for interrupt/sync mode (currently unused) |
||||
* @param[in] mode operation mode |
||||
* @param[in] range measurement range |
||||
* @param[in] resolution AD conversion resolution |
||||
* |
||||
* @return 0 on success |
||||
* @return -1 on error |
||||
*/ |
||||
int isl29125_init(isl29125_t *dev, i2c_t i2c, gpio_t gpio, |
||||
isl29125_mode_t mode, isl29125_range_t range, |
||||
isl29125_resolution_t resolution); |
||||
|
||||
/**
|
||||
* @brief read RGB values from device |
||||
* |
||||
* @param[in] dev device descriptor of an ISL29125 device |
||||
* @param[in] dest pointer to lux RGB color object data is written to |
||||
*/ |
||||
void isl29125_read_rgb_lux(isl29125_t *dev, isl29125_rgb_t *dest); |
||||
|
||||
/**
|
||||
* @brief read color values from device |
||||
* |
||||
* @param[in] dev device descriptor of an ISL29125 device |
||||
* @param[in] dest pointer to RGB color object data is written to |
||||
*/ |
||||
void isl29125_read_rgb_color(isl29125_t *dev, color_rgb_t *dest); |
||||
|
||||
/**
|
||||
* @brief set the device's operation mode |
||||
* |
||||
* @param[in] dev device descriptor of an ISL29125 device |
||||
* @param[in] mode operation mode |
||||
*/ |
||||
void isl29125_set_mode(isl29125_t *dev, isl29125_mode_t mode); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* ISL29125_H */ |
||||
/** @} */ |
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2015 Ludwig Ortmann |
||||
* |
||||
* 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 driver_isl29125 |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief Definitions for the ISL29125 RGB light sensor |
||||
* |
||||
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de> |
||||
*/ |
||||
|
||||
#ifndef ISL29125_INTERNAL_H |
||||
#define ISL29125_INTERNAL_H |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/**
|
||||
* @brief The sensors hard coded I2C address |
||||
*/ |
||||
#define ISL29125_I2C_ADDRESS 0x44 |
||||
|
||||
/**
|
||||
* @name ISL29125 constants |
||||
* @{ |
||||
*/ |
||||
#define ISL29125_ID 0x7D |
||||
/** @} */ |
||||
|
||||
/**
|
||||
* @name ISL29125 register map |
||||
* @{ |
||||
*/ |
||||
/* main register */ |
||||
#define ISL29125_REG_ID 0x00 |
||||
#define ISL29125_REG_RESET 0x00 |
||||
/* configuration registers */ |
||||
#define ISL29125_REG_CONF1 0x01 |
||||
#define ISL29125_REG_CONF2 0x02 |
||||
#define ISL29125_REG_CONF3 0x03 |
||||
/* interrupt mode threshold registers */ |
||||
#define ISL29125_REG_LTHLB 0x04 |
||||
#define ISL29125_REG_LTHHB 0x05 |
||||
#define ISL29125_REG_HTHLB 0x06 |
||||
#define ISL29125_REG_HTHHB 0x07 |
||||
/* status register */ |
||||
#define ISL29125_REG_STATUS 0x08 |
||||
/* sensor readout registers (double buffered) */ |
||||
#define ISL29125_REG_GDLB 0x09 |
||||
#define ISL29125_REG_GDHB 0x0A |
||||
#define ISL29125_REG_RDLB 0x0B |
||||
#define ISL29125_REG_RDHB 0x0C |
||||
#define ISL29125_REG_BDLB 0x0D |
||||
#define ISL29125_REG_BDHB 0x0E |
||||
/** @} */ |
||||
|
||||
/**
|
||||
* @name ISL29125 commands |
||||
* @{ |
||||
*/ |
||||
#define ISL29125_CMD_RESET 0x46 |
||||
/** @} */ |
||||
|
||||
/**
|
||||
* @name ISL29125 configuration masks and bits |
||||
* @{ |
||||
*/ |
||||
/* ISL29125_REG_CONF1 B2:B0 */ |
||||
#define ISL29125_CON1_MASK_MODE 0x07 |
||||
/* ISL29125_REG_CONF1 B3 */ |
||||
#define ISL29125_CON1_MASK_RANGE 0x08 |
||||
/* ISL29125_REG_CONF1 B4 */ |
||||
#define ISL29125_CON1_MASK_RES 0x10 |
||||
/* ISL29125_REG_CONF1 B5 */ |
||||
#define ISL29125_CON1_MASK_SYNC 0x20 |
||||
#define ISL29125_CON1_SYNCOFF 0x00 |
||||
#define ISL29125_CON1_SYNCON 0x20 |
||||
/** @} */ |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* ISL29125_INTERNAL_H */ |
||||
/** @} */ |
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2015 Ludwig Ortmann |
||||
* |
||||
* 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 driver_isl29125 |
||||
* @{ |
||||
* |
||||
* @file |
||||
* @brief Device driver implementation for the ISL29125 RGB light sensor |
||||
* |
||||
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de> |
||||
* |
||||
* @} |
||||
*/ |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include "isl29125.h" |
||||
#include "isl29125-internal.h" |
||||
#include "periph/i2c.h" |
||||
#include "periph/gpio.h" |
||||
#include "color.h" |
||||
|
||||
#define ENABLE_DEBUG (0) |
||||
#include "debug.h" |
||||
|
||||
/***********************************************************************
|
||||
* public API implementation |
||||
**********************************************************************/ |
||||
|
||||
int isl29125_init(isl29125_t *dev, i2c_t i2c, gpio_t gpio, |
||||
isl29125_mode_t mode, isl29125_range_t range, |
||||
isl29125_resolution_t resolution) |
||||
{ |
||||
DEBUG("isl29125_init\n"); |
||||
|
||||
/* initialize device descriptor */ |
||||
dev->i2c = i2c; |
||||
dev->res = resolution; |
||||
dev->range = range; |
||||
dev->gpio = gpio; |
||||
|
||||
/* configuration 1: operation mode, range, resolution */ |
||||
char conf1 = 0x00; |
||||
conf1 |= mode; |
||||
conf1 |= range; |
||||
conf1 |= resolution; |
||||
conf1 |= ISL29125_CON1_SYNCOFF; /* TODO: implement SYNC mode configuration */ |
||||
|
||||
/* TODO: implement configuration 2: infrared compensation configuration */ |
||||
|
||||
/* TODO: implement configuration 3: interrupt mode configuration */ |
||||
|
||||
/* acquire exclusive access to the bus */ |
||||
DEBUG("isl29125_init: i2c_acquire\n"); |
||||
(void) i2c_acquire(dev->i2c); |
||||
|
||||
/* initialize the I2C bus */ |
||||
DEBUG("isl29125_init: i2c_init_master\n"); |
||||
(void) i2c_init_master(i2c, I2C_SPEED_NORMAL); |
||||
|
||||
/* verify the device ID */ |
||||
DEBUG("isl29125_init: i2c_read_reg\n"); |
||||
char reg_id; |
||||
int ret = i2c_read_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_ID, ®_id); |
||||
if ((reg_id == ISL29125_ID) && (ret == 1)) { |
||||
DEBUG("isl29125_init: ID successfully verified\n"); |
||||
} |
||||
else { |
||||
DEBUG("isl29125_init: ID could not be verified, ret: %i\n", ret); |
||||
(void) i2c_release(dev->i2c); |
||||
return -1; |
||||
} |
||||
|
||||
/* configure and enable the sensor */ |
||||
DEBUG("isl29125_init: i2c_write_reg(ISL29125_REG_RESET)\n"); |
||||
(void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_RESET, ISL29125_CMD_RESET); |
||||
|
||||
DEBUG("isl29125_init: i2c_write_reg(ISL29125_REG_CONF1)\n"); |
||||
(void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_CONF1, conf1); |
||||
|
||||
/* release the I2C bus */ |
||||
DEBUG("isl29125_init: i2c_release\n"); |
||||
(void) i2c_release(dev->i2c); |
||||
|
||||
DEBUG("isl29125_init: success\n"); |
||||
return 0; |
||||
} |
||||
|
||||
void isl29125_read_rgb_lux(isl29125_t *dev, isl29125_rgb_t *dest) |
||||
{ |
||||
/* acquire exclusive access to the bus */ |
||||
(void) i2c_acquire(dev->i2c); |
||||
|
||||
/* read values */ |
||||
char bytes[6]; |
||||
(void) i2c_read_regs(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_GDLB, bytes, 6); |
||||
|
||||
/* release the I2C bus */ |
||||
(void) i2c_release(dev->i2c); |
||||
|
||||
/* possibly shift by 4 to normalize 12 to 16 bit */ |
||||
int resfactor = (dev->res == ISL29125_RESOLUTION_12) ? 4 : 0; |
||||
/* parse and normalize readings */ |
||||
uint16_t green = (bytes[0] | (bytes[1] << 8)) << resfactor; |
||||
uint16_t red = (bytes[2] | (bytes[3] << 8)) << resfactor; |
||||
uint16_t blue = (bytes[4] | (bytes[5] << 8)) << resfactor; |
||||
|
||||
DEBUG("isl29125_read_rgb: adjusted, unconverted readings: (%5i / %5i / %5i) \n", red, green, blue); |
||||
|
||||
/* convert readings to lux */ |
||||
float luxfactor = (dev->range == ISL29125_RANGE_10K) ? 10000.0 / 65535.0 : 375.0 / 65535.0; |
||||
dest->red = red * luxfactor; |
||||
dest->green = green * luxfactor; |
||||
dest->blue = blue * luxfactor; |
||||
} |
||||
|
||||
void isl29125_read_rgb_color(isl29125_t *dev, color_rgb_t *dest) |
||||
{ |
||||
/* acquire exclusive access to the bus */ |
||||
(void) i2c_acquire(dev->i2c); |
||||
|
||||
/* read values */ |
||||
char bytes[6]; |
||||
(void) i2c_read_regs(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_GDLB, bytes, 6); |
||||
|
||||
/* release the I2C bus */ |
||||
(void) i2c_release(dev->i2c); |
||||
|
||||
/* factor normalize 12 or 16 bit to 8 bit */ |
||||
int normfactor = (dev->res == ISL29125_RESOLUTION_12) ? 4 : 8; |
||||
/* parse and normalize readings */ |
||||
dest->g = (bytes[0] | (bytes[1] << 8)) >> normfactor; |
||||
dest->r = (bytes[2] | (bytes[3] << 8)) >> normfactor; |
||||
dest->b = (bytes[4] | (bytes[5] << 8)) >> normfactor; |
||||
} |
||||
|
||||
void isl29125_set_mode(isl29125_t *dev, isl29125_mode_t mode) |
||||
{ |
||||
char conf1; |
||||
|
||||
(void) i2c_acquire(dev->i2c); |
||||
|
||||
(void) i2c_read_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_CONF1, &conf1); |
||||
conf1 &= ~ISL29125_CON1_MASK_MODE; |
||||
conf1 |= mode; |
||||
(void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_CONF1, conf1); |
||||
|
||||
(void) i2c_release(dev->i2c); |
||||
} |
Loading…
Reference in new issue