diff --git a/drivers/include/isl29125.h b/drivers/include/isl29125.h index 9221828100..3ddd32744e 100644 --- a/drivers/include/isl29125.h +++ b/drivers/include/isl29125.h @@ -1,5 +1,6 @@ /* * Copyright 2015 Ludwig Knüpfer + * Copyright 2017 HAW Hamburg * * 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 @@ -40,6 +41,8 @@ * @brief Device driver interface for the ISL29125 RGB light sensor * * @author Ludwig Knüpfer + * @author Cenk Gündoğan */ #ifndef ISL29125_H @@ -106,6 +109,34 @@ typedef struct { isl29125_resolution_t res; /**< sensor resolution */ } isl29125_t; +/** + * @brief Configuration-3 Register 0x03 B1:0 + */ +typedef enum { + ISL29125_INTERRUPT_STATUS_NONE = 0x00, /**< No interrupt */ + ISL29125_INTERRUPT_STATUS_GREEN = 0x01, /**< GREEN interrupt */ + ISL29125_INTERRUPT_STATUS_RED = 0x02, /**< RED interrupt */ + ISL29125_INTERRUPT_STATUS_BLUE = 0x03 /**< BLUE interrupt */ +} isl29125_interrupt_status_t; + +/** + * @brief Configuration-3 Register 0x03 B3:2 + */ +typedef enum { + ISL29125_INTERRUPT_PERSIST_1 = (0x00 << 2), /**< Int. Persist: Number of integration cycle 1 */ + ISL29125_INTERRUPT_PERSIST_2 = (0x01 << 2), /**< Int. Persist: Number of integration cycle 2 */ + ISL29125_INTERRUPT_PERSIST_4 = (0x02 << 2), /**< Int. Persist: Number of integration cycle 4 */ + ISL29125_INTERRUPT_PERSIST_8 = (0x03 << 2) /**< Int. Persist: Number of integration cycle 8 */ +} isl29125_interrupt_persist_t; + +/** + * @brief Configuration-3 Register 0x03 B4 + */ +typedef enum { + ISL29125_INTERRUPT_CONV_DIS = (0x0 << 4), /**< RGB Conversion done to ~INT Control disable */ + ISL29125_INTERRUPT_CONV_EN = (0x1 << 4), /**< RGB Conversion done to ~INT Control enable */ +} isl29125_interrupt_conven_t; + /** * @brief initialize a new ISL29125 device * @@ -123,6 +154,27 @@ 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 initialize interrupts + * + * @param[in] dev device descriptor of an ISL29125 device + * @param[in] interrupt_status Interrupt status + * @param[in] interrupt_persist Interrupt persistency + * @param[in] interrupt_conven RGB conversion done to interrupt control, enable + * @param[in] lower_threshold Lower interrupt threshold + * @param[in] higher_threshold Higher interrupt threshold + * @param[in] cb Callback function on interrupts + * @param[in] arg Argument passed to the callback function + * + * @return 0 on success + * @return -1 on error + */ +int isl29125_init_int(isl29125_t *dev, isl29125_interrupt_status_t interrupt_status, + isl29125_interrupt_persist_t interrupt_persist, + isl29125_interrupt_conven_t interrupt_conven, + uint16_t lower_threshold, uint16_t higher_threshold, + gpio_cb_t cb, void *arg); + /** * @brief read RGB values from device * @@ -147,6 +199,15 @@ void isl29125_read_rgb_color(isl29125_t *dev, color_rgb_t *dest); */ void isl29125_set_mode(isl29125_t *dev, isl29125_mode_t mode); +/** + * @brief read isl29125 interrupt status + * + * @param[in] dev device descriptor of an ISL29125 device + * + * @return interrupt status + */ +int isl29125_read_irq_status(isl29125_t *dev); + #ifdef __cplusplus } #endif diff --git a/drivers/isl29125/isl29125.c b/drivers/isl29125/isl29125.c index afd02f32db..b891bc61d8 100644 --- a/drivers/isl29125/isl29125.c +++ b/drivers/isl29125/isl29125.c @@ -1,5 +1,6 @@ /* * Copyright 2015 Ludwig Knüpfer + * Copyright 2017 HAW Hamburg * * 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 @@ -14,6 +15,8 @@ * @brief Device driver implementation for the ISL29125 RGB light sensor * * @author Ludwig Knüpfer + * @author Martin Heusmann + * @author Cenk Gündoğan * * @} */ @@ -54,8 +57,6 @@ int isl29125_init(isl29125_t *dev, i2c_t i2c, gpio_t gpio, /* 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); @@ -92,6 +93,61 @@ int isl29125_init(isl29125_t *dev, i2c_t i2c, gpio_t gpio, return 0; } +int isl29125_init_int(isl29125_t *dev, isl29125_interrupt_status_t interrupt_status, + isl29125_interrupt_persist_t interrupt_persist, + isl29125_interrupt_conven_t interrupt_conven, + uint16_t lower_threshold, uint16_t higher_threshold, + gpio_cb_t cb, void *arg) +{ + /* configuration 3: interrupt mode configuration */ + uint8_t conf3 = 0x00; + conf3 |= interrupt_status; + conf3 |= interrupt_persist; + conf3 |= interrupt_conven; + + /* Lower and higher interrupt threshold registers. */ + uint8_t lthlb = 0x00; + uint8_t lthhb = 0x00; + uint8_t hthlb = 0x00; + uint8_t hthhb = 0x00; + uint16_t max_range = 10000; + + if (dev->range == 0x00) { + max_range = 375; + } + + if ((higher_threshold <= max_range) && (lower_threshold < higher_threshold)) { + lower_threshold *= (uint16_t) (65535 / max_range); + lthlb = (uint8_t)(lower_threshold & 0xff); + lthhb = (uint8_t)(lower_threshold >> 8); + higher_threshold *= (uint16_t) (65535 / max_range); + hthlb = (uint8_t)(higher_threshold & 0xff); + hthhb = (uint8_t)(higher_threshold >> 8); + } + + DEBUG("isl29125_init: i2c_write_reg(ISL29125_REG_CONF3)\n"); + (void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_CONF3, conf3); + + DEBUG("isl29125_init: i2c_write_reg(ISL29125_REG_LTHLB)\n"); + (void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_LTHLB, lthlb); + + DEBUG("isl29125_init: i2c_write_reg(ISL29125_REG_LTHHB)\n"); + (void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_LTHHB, lthhb); + + DEBUG("isl29125_init: i2c_write_reg(ISL29125_REG_HTHLB)\n"); + (void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_HTHLB, hthlb); + + DEBUG("isl29125_init: i2c_write_reg(ISL29125_REG_HTHHB)\n"); + (void) i2c_write_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_HTHHB, hthhb); + + if (gpio_init_int(dev->gpio, GPIO_IN, GPIO_FALLING, cb, arg) < 0) { + DEBUG("error: gpio_init_int failed\n"); + return -1; + } + + return 0; +} + void isl29125_read_rgb_lux(isl29125_t *dev, isl29125_rgb_t *dest) { /* acquire exclusive access to the bus */ @@ -153,3 +209,19 @@ void isl29125_set_mode(isl29125_t *dev, isl29125_mode_t mode) (void) i2c_release(dev->i2c); } + +int isl29125_read_irq_status(isl29125_t *dev) +{ + /* acquire exclusive access to the bus */ + (void) i2c_acquire(dev->i2c); + + /* read status register */ + uint8_t irq_status; + (void) i2c_read_reg(dev->i2c, ISL29125_I2C_ADDRESS, ISL29125_REG_STATUS, &irq_status); + + /* release the I2C bus */ + (void) i2c_release(dev->i2c); + + /* return bit 0 (RGBTHF)*/ + return (irq_status & 0x01); +}