From 9d199d5d095a9866ba917c43fbcebad5a94885d2 Mon Sep 17 00:00:00 2001 From: martinheusmann Date: Mon, 14 Nov 2016 13:39:21 +0100 Subject: [PATCH 1/2] isl29125: added interrupt configuration register --- drivers/include/isl29125.h | 61 +++++++++++++++++++++++++++++ drivers/isl29125/isl29125.c | 76 ++++++++++++++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/drivers/include/isl29125.h b/drivers/include/isl29125.h index 922182810..3ddd32744 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 afd02f32d..b891bc61d 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); +} From c2458dbd6dd9f2da87bf314a34df9500453b28e8 Mon Sep 17 00:00:00 2001 From: martinheusmann Date: Mon, 14 Nov 2016 13:40:59 +0100 Subject: [PATCH 2/2] tests/driver_isl29125: extended test for interrupt use --- tests/driver_isl29125/Makefile | 4 ++++ tests/driver_isl29125/main.c | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/tests/driver_isl29125/Makefile b/tests/driver_isl29125/Makefile index 07923fb5e..da728a523 100644 --- a/tests/driver_isl29125/Makefile +++ b/tests/driver_isl29125/Makefile @@ -1,4 +1,8 @@ APPLICATION = driver_isl29125 + +# If no BOARD is found in the environment, use this default: +BOARD ?= samr21-xpro + include ../Makefile.tests_common FEATURES_REQUIRED = periph_i2c diff --git a/tests/driver_isl29125/main.c b/tests/driver_isl29125/main.c index 4b839e336..d00a637e6 100644 --- a/tests/driver_isl29125/main.c +++ b/tests/driver_isl29125/main.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 Test application for the ISL29125 RGB light sensor * * @author Ludwig Knüpfer + * @author Martin Heusmann + * @author Cenk Gündoğan * * @} */ @@ -34,6 +37,12 @@ #define SLEEP (250 * 1000U) +void cb(void *arg) +{ + (void) arg; + printf("INT: external interrupt\n"); +} + int main(void) { isl29125_t dev; @@ -41,6 +50,10 @@ int main(void) color_rgb_t data8bit; memset(&data, 0x00, sizeof(data)); + /* Parameters for testing, change if needed. */ + uint16_t lower_threshold = 0; + uint16_t higher_threshold = 8000; + puts("ISL29125 light sensor test application\n"); printf("Initializing ISL29125 sensor at I2C_%i... ", TEST_ISL29125_I2C); if (isl29125_init(&dev, TEST_ISL29125_I2C, TEST_ISL29125_IRQ_PIN, @@ -53,6 +66,15 @@ int main(void) return 1; } + puts("Initializing interrupt"); + + if (isl29125_init_int(&dev, ISL29125_INTERRUPT_STATUS_RED, + ISL29125_INTERRUPT_PERSIST_1, ISL29125_INTERRUPT_CONV_DIS, + lower_threshold, higher_threshold, cb, NULL) != 0) { + puts("[Failed]"); + return 1; + } + /* try out some modes */ static const isl29125_mode_t modes[] = { ISL29125_MODE_DOWN, ISL29125_MODE_STANDBY, ISL29125_MODE_RGB, @@ -80,6 +102,7 @@ int main(void) printf("RGB value: (%5i / %5i / %5i) lux\n", (int)data.red, (int)data.green, (int)data.blue); xtimer_usleep(SLEEP); + printf("IRQ-Status: %i \n", isl29125_read_irq_status(&dev)); } return 0;