From 4759d705411078015fb6c355d8d5708a5f8c4171 Mon Sep 17 00:00:00 2001 From: Jon Trulson Date: Thu, 16 Apr 2015 18:39:03 -0600 Subject: [PATCH] si114x: Initial implementation This module implements support for the Adafruit UV sensor: https://www.adafruit.com/products/1777 Signed-off-by: Jon Trulson Signed-off-by: Zion Orent Signed-off-by: Mihai Tudor Panu --- examples/c++/CMakeLists.txt | 3 + examples/c++/si114x.cxx | 78 ++++++++ examples/javascript/si114x.js | 66 +++++++ examples/python/si114x.py | 66 +++++++ src/si114x/CMakeLists.txt | 5 + src/si114x/jsupm_si114x.i | 9 + src/si114x/pyupm_si114x.i | 13 ++ src/si114x/si114x.cxx | 190 ++++++++++++++++++++ src/si114x/si114x.h | 322 ++++++++++++++++++++++++++++++++++ 9 files changed, 752 insertions(+) create mode 100644 examples/c++/si114x.cxx create mode 100644 examples/javascript/si114x.js create mode 100644 examples/python/si114x.py create mode 100644 src/si114x/CMakeLists.txt create mode 100644 src/si114x/jsupm_si114x.i create mode 100644 src/si114x/pyupm_si114x.i create mode 100644 src/si114x/si114x.cxx create mode 100644 src/si114x/si114x.h diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index bd0b14a2..e8ce8ebc 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -115,6 +115,7 @@ add_executable (uln200xa-example uln200xa.cxx) add_executable (grovewfs-example grovewfs.cxx) add_executable (isd1820-example isd1820.cxx) add_executable (sx6119-example sx6119.cxx) +add_executable (si114x-example si114x.cxx) include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l) include_directories (${PROJECT_SOURCE_DIR}/src/grove) @@ -208,6 +209,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/uln200xa) include_directories (${PROJECT_SOURCE_DIR}/src/grovewfs) include_directories (${PROJECT_SOURCE_DIR}/src/isd1820) include_directories (${PROJECT_SOURCE_DIR}/src/sx6119) +include_directories (${PROJECT_SOURCE_DIR}/src/si114x) target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT}) @@ -324,3 +326,4 @@ target_link_libraries (uln200xa-example uln200xa ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (grovewfs-example grovewfs ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (isd1820-example isd1820 ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (sx6119-example sx6119 ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries (si114x-example si114x ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/c++/si114x.cxx b/examples/c++/si114x.cxx new file mode 100644 index 00000000..4c069c9f --- /dev/null +++ b/examples/c++/si114x.cxx @@ -0,0 +1,78 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include "si114x.h" + +using namespace std; + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + + +int main () +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + // Instantiate a SI114x UV Sensor on I2C bus 0 + upm::SI114X* uvi = new upm::SI114X(0); + + // First initialize it + uvi->initialize(); + + cout << "UV Index Scale:" << endl; + cout << "---------------" << endl; + cout << "11+ Extreme" << endl; + cout << "8-10 Very High" << endl; + cout << "6-7 High" << endl; + cout << "3-5 Moderate" << endl; + cout << "0-2 Low" << endl; + cout << endl; + + // update every second and print the currently measured UV Index + while (shouldRun) + { + // update current value(s) + uvi->update(); + + // print detected value + cout << "UV Index: " << uvi->getUVIndex() << endl; + + sleep(1); + } +//! [Interesting] + + cout << "Exiting..." << endl; + + delete uvi; + return 0; +} diff --git a/examples/javascript/si114x.js b/examples/javascript/si114x.js new file mode 100644 index 00000000..94d438ab --- /dev/null +++ b/examples/javascript/si114x.js @@ -0,0 +1,66 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ + +/* +* Author: Zion Orent +* Copyright (c) 2015 Intel Corporation. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +var UV_lib = require('jsupm_si114x'); + +// Instantiate a SI114x UV Sensor on I2C bus 0 +var myUVSensor = new UV_lib.SI114X(0); + +for (var x in myUVSensor) + console.log(x); +// First initialize it +myUVSensor.initialize(); + +console.log("UV Index Scale:"); +console.log("---------------"); +console.log("11+ Extreme"); +console.log("8-10 Very High"); +console.log("6-7 High"); +console.log("3-5 Moderate"); +console.log("0-2 Low\n"); + +// update every second and print the currently measured UV Index +var myInterval = setInterval(function() +{ + // update current value(s) + myUVSensor.update(); + + // print detected value + console.log("UV Index: " + myUVSensor.getUVIndex()); +}, 1000); + + +// When exiting: clear interval and print message +process.on('SIGINT', function() +{ + clearInterval(myInterval); + myUVSensor = null + UV_lib.cleanUp(); + UV_lib = null; + console.log("Exiting"); + process.exit(0); +}); diff --git a/examples/python/si114x.py b/examples/python/si114x.py new file mode 100644 index 00000000..4264620b --- /dev/null +++ b/examples/python/si114x.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# Author: Zion Orent +# Copyright (c) 2015 Intel Corporation. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import time, sys, signal, atexit +import pyupm_si114x as upmSi114x + +# Instantiate a SI114x UV Sensor on I2C bus 0 +myUVSensor = upmSi114x.SI114X(0) + + +## Exit handlers ## +# This stops python from printing a stacktrace when you hit control-C +def SIGINTHandler(signum, frame): + raise SystemExit + +# This function lets you run code on exit, +# including functions from myUVSensor +def exitHandler(): + print "Exiting" + sys.exit(0) + +# Register exit handlers +atexit.register(exitHandler) +signal.signal(signal.SIGINT, SIGINTHandler) + + +# First initialize it +myUVSensor.initialize() + +print "UV Index Scale:" +print "---------------" +print "11+ Extreme" +print "8-10 Very High" +print "6-7 High" +print "3-5 Moderate" +print "0-2 Low\n" + +# update every second and print the currently measured UV Index +while (1): + # update current value(s) + myUVSensor.update() + + # print detected value + print "UV Index:", myUVSensor.getUVIndex() + + time.sleep(1) diff --git a/src/si114x/CMakeLists.txt b/src/si114x/CMakeLists.txt new file mode 100644 index 00000000..e2d8f2ef --- /dev/null +++ b/src/si114x/CMakeLists.txt @@ -0,0 +1,5 @@ +set (libname "si114x") +set (libdescription "upm si114x UV/IR/Visible light sensor") +set (module_src ${libname}.cxx) +set (module_h ${libname}.h) +upm_module_init() diff --git a/src/si114x/jsupm_si114x.i b/src/si114x/jsupm_si114x.i new file mode 100644 index 00000000..9ee70e0f --- /dev/null +++ b/src/si114x/jsupm_si114x.i @@ -0,0 +1,9 @@ +%module jsupm_si114x +%include "../upm.i" +%include "cpointer.i" + +%{ + #include "si114x.h" +%} + +%include "si114x.h" diff --git a/src/si114x/pyupm_si114x.i b/src/si114x/pyupm_si114x.i new file mode 100644 index 00000000..6f061c70 --- /dev/null +++ b/src/si114x/pyupm_si114x.i @@ -0,0 +1,13 @@ +%module pyupm_si114x +%include "../upm.i" + +%feature("autodoc", "3"); + +#ifdef DOXYGEN +%include "si114x_doc.i" +#endif + +%include "si114x.h" +%{ + #include "si114x.h" +%} diff --git a/src/si114x/si114x.cxx b/src/si114x/si114x.cxx new file mode 100644 index 00000000..535f0642 --- /dev/null +++ b/src/si114x/si114x.cxx @@ -0,0 +1,190 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Thanks to Adafruit for some important clues + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "si114x.h" + +using namespace upm; +using namespace std; + + +SI114X::SI114X(int bus, uint8_t address) +{ + m_addr = address; + m_uvIndex = 0; + + // setup our i2c link + if ( !(m_i2c = mraa_i2c_init(bus)) ) + { + cerr << "SI114X: mraa_i2c_init() failed." << endl; + return; + } + + mraa_result_t rv; + + if ( (rv = mraa_i2c_address(m_i2c, m_addr)) != MRAA_SUCCESS) + { + cerr << "SI114X: Could not initialize i2c bus. " << endl; + mraa_result_print(rv); + return; + } + + // The data sheet recommends setting the UV calibration values to + // 0x7b, 0x6b, 0x01, and 0x00, however the adafruit code uses a + // different set of values, presumably calibrated to their specific + // implementation. We will use those defaults here, as this was + // developed on an adafruit device. + + // Use setUVCalibration() to set a different set of values before + // calling init() if you need different values. + + setUVCalibration(0x29, 0x89, 0x02, 0x00); +} + +SI114X::~SI114X() +{ + mraa_i2c_stop(m_i2c); +} + +bool SI114X::writeByte(uint8_t reg, uint8_t byte) +{ + mraa_result_t rv = mraa_i2c_write_byte_data(m_i2c, byte, reg); + + if (rv != MRAA_SUCCESS) + { + cerr << __FUNCTION__ << ": mraa_i2c_write_byte() failed." << endl; + mraa_result_print(rv); + return false; + } + + return true; +} + +uint8_t SI114X::readByte(uint8_t reg) +{ + return mraa_i2c_read_byte_data(m_i2c, reg); +} + +uint16_t SI114X::readWord(uint8_t reg) +{ + return mraa_i2c_read_word_data(m_i2c, reg); +} + +void SI114X::setUVCalibration(uint8_t uvcoeff0, uint8_t uvcoeff1, + uint8_t uvcoeff2, uint8_t uvcoeff3) +{ + m_uv_cal[0] = uvcoeff0; + m_uv_cal[1] = uvcoeff1; + m_uv_cal[2] = uvcoeff2; + m_uv_cal[3] = uvcoeff3; +}; + + +void SI114X::writeParam(SI114X_PARAM_T param, uint8_t value) +{ + // write a parameter to the RAM parameter area + + // We write the value to the PARAM_WR register, then execute a + // PARAM_WRITE command + + writeByte(REG_PARAM_WR, value); + + // now write it to parameter memory + writeByte(REG_COMMAND, CMD_PARAM_SET | param); +} + +uint8_t SI114X::readParam(SI114X_PARAM_T param) +{ + // get the parameter into register REG_PARAM_READ, then read and return it. + + writeByte(REG_COMMAND, CMD_PARAM_QUERY | param); + return readByte(REG_PARAM_READ); +} + +void SI114X::reset() +{ + // reset the device + + // zero out measuring rate + writeByte(REG_MEAS_RATE0, 0); + writeByte(REG_MEAS_RATE1, 0); + + // disable IRQ MODES + // these are undocumented in the datasheet, but mentioned in Adafruit's code + writeByte(REG_IRQ_MODE1, 0); + writeByte(REG_IRQ_MODE2, 0); + + // turn off interrupts + writeByte(REG_INT_CFG, 0); + writeByte(REG_IRQ_STATUS, 0xff); + + // send a reset + writeByte(REG_COMMAND, CMD_RESET); + usleep(100); + + // set the hardware key + writeByte(REG_HW_KEY, SI114X_HW_KEY); + usleep(100); +} + +void SI114X::initialize() +{ + // initialize the device + + // first, reset it + reset(); + + // UV coefficients + writeByte(REG_UCOEF0, m_uv_cal[0]); + writeByte(REG_UCOEF1, m_uv_cal[1]); + writeByte(REG_UCOEF2, m_uv_cal[2]); + writeByte(REG_UCOEF3, m_uv_cal[3]); + + // enable UV sensor only for now + writeParam(PARAM_CHLIST, CHLIST_EN_UV); + + // auto-measure speed - slowest - (rate * 31.25us) + writeByte(REG_MEAS_RATE0, 0xff); // 7.9ms + + // set autorun + writeByte(REG_COMMAND, CMD_ALS_AUTO); +} + +void SI114X::update() +{ + // for now, just update the UV Index member variable + uint16_t uvi = readWord(REG_AUX_UVINDEX0); + + m_uvIndex = float(uvi) / 100.0; + + // Add any further data gets() here + + return; +} diff --git a/src/si114x/si114x.h b/src/si114x/si114x.h new file mode 100644 index 00000000..a6cab92f --- /dev/null +++ b/src/si114x/si114x.h @@ -0,0 +1,322 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 Intel Corporation. + * + * Thanks to Adafruit for some important clues + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include +#include +#include + +#define SI114X_I2C_BUS 0 +#define SI114X_DEFAULT_I2C_ADDR 0x60 +#define SI114X_HW_KEY 0x17 + + +namespace upm { + + /** + * @brief SI1145 UV light sensor + * @defgroup si114x libupm-si114x + * @ingroup adafruit i2c light + */ + + /** + * @library si114x + * @sensor si114x + * @comname SI1145 UV light sensor + * @altname SI1146, SI1147 + * @type light + * @man adafruit + * @web https://www.adafruit.com/products/1777 + * @con i2c + * + * @brief C++ API for the SI1145 UV light sensor + * + * This module was tested with the Adafruit UV Sensor + * + * This device is also capable of measuring IR and visible ambient + * light as well. It also supports the ability to use externally + * attached LED's to perform proximity detection on 3 separate + * channels. + * + * This class currently only supports the retriving of the + * calculated UV index measured by the device, but enough + * infrastructure is provided to make it easy to enhance this driver + * in the future to support additional capabilities, including + * interrupt support. + * + * @snippet si114x.cxx Interesting + */ + class SI114X { + public: + + /** + * SI114X registers + */ + typedef enum { REG_PART_ID = 0x00, + REG_REV_ID = 0x01, + REG_SEQ_ID = 0x02, + REG_INT_CFG = 0x03, + REG_IRQ_ENABLE = 0x04, + + // these two are not documented in the datasheet, + // but are mentioned there, as well as in the + // Adafruit example + REG_IRQ_MODE1 = 0x05, + REG_IRQ_MODE2 = 0x06, + + REG_HW_KEY = 0x07, + REG_MEAS_RATE0 = 0x08, + REG_MEAS_RATE1 = 0x09, + + REG_PS_LED21 = 0x0f, + REG_PS_LED3 = 0x10, + + REG_UCOEF0 = 0x13, + REG_UCOEF1 = 0x14, + REG_UCOEF2 = 0x15, + REG_UCOEF3 = 0x16, + REG_PARAM_WR = 0x17, + REG_COMMAND = 0x18, + + REG_RESPONSE = 0x20, + REG_IRQ_STATUS = 0x21, + REG_ALS_VIS_DATA0 = 0x22, + REG_ALS_VIS_DATA1 = 0x23, + REG_ALS_IR_DATA0 = 0x24, + REG_ALS_IR_DATA1 = 0x25, + REG_PS1_DATA0 = 0x26, + REG_PS1_DATA1 = 0x27, + REG_PS2_DATA0 = 0x28, + REG_PS2_DATA1 = 0x29, + REG_PS3_DATA0 = 0x2a, + REG_PS3_DATA1 = 0x2b, + REG_AUX_UVINDEX0 = 0x2c, + REG_AUX_UVINDEX1 = 0x2d, + REG_PARAM_READ = 0x2e, + + REG_CHIP_STAT = 0x30, + + REG_ANA_IN_KEY0 = 0x3b, + REG_ANA_IN_KEY1 = 0x3c, + REG_ANA_IN_KEY2 = 0x3d, + REG_ANA_IN_KEY3 = 0x3e + } SI114X_REG_T; + + /** + * Parameter memory (PARAM) + */ + typedef enum { PARAM_I2C_ADDDR = 0x00, + PARAM_CHLIST = 0x01, + PARAM_PSLED12_SEL = 0x02, + PARAM_PSLED3_SEL = 0x03, + + PARAM_PS_ENCODING = 0x05, + PARAM_ALS_ENCODING = 0x06, + PARAM_PS1_ADCMUX = 0x07, + PARAM_PS2_ADCMUX = 0x08, + PARAM_PS3_ADCMUX = 0x09, + PARAM_PS_ADC_COUNT = 0x0a, + PARAM_PS_ADC_GAIN = 0x0b, + PARAM_PS_ADC_MISC = 0x0c, + + PARAM_ALS_IR_ADCMUX = 0x0e, + PARAM_AUX_ADCMUX = 0x0f, + PARAM_ALS_VIS_ADC_COUNT = 0x10, + PARAM_ALS_VIS_ADC_GAIN = 0x11, + PARAM_ALS_VIS_ADC_MISC = 0x12, + + PARAM_LED_REC = 0x1c, + PARAM_ALS_IR_ADC_COUNT = 0x1d, + PARAM_ALS_IR_ADX_GAIN = 0x1e, + PARAM_ALS_IR_ADC_MISC = 0x1f + } SI114X_PARAM_T; + + /** + * Commands (written to the REG_COMMAND register) + */ + typedef enum { CMD_NOOP = 0x00, // clear RESPONSE reg + CMD_RESET = 0x01, + CMD_BUSADDR = 0x02, + + CMD_PS_FORCE = 0x05, + CMD_GET_CAL = 0x12, + CMD_ALS_FORCE = 0x06, + CMD_PSALS_FORCE = 0x07, + + CMD_PS_PAUSE = 0x09, + CMD_ALS_PAUSE = 0x0a, + CMD_PSALS_PAUSE = 0x0b, + + CMD_PS_AUTO = 0x0d, + CMD_ALS_AUTO = 0x0e, + CMD_PSALS_AUTO = 0x0f, + + CMD_PARAM_QUERY = 0x80, // or'd with PARAM_T value + CMD_PARAM_SET = 0xa0 // or'd with PARAM_T value + } SI114X_CMD_T; + + + /** + * Channel List enable bits + */ + typedef enum { CHLIST_EN_PS1 = 0x01, // proximity sense 1-3 + CHLIST_EN_PS2 = 0x02, + CHLIST_EN_PS3 = 0x04, + + CHLIST_EN_ALS_VIS = 0x10, // ambient light sense + CHLIST_EN_ALS_IR = 0x20, + CHLIST_EN_AUX = 0x40, // AUX sense + CHLIST_EN_UV = 0x80 // UV sense + } SI114X_CHLIST_BITS_T; + + /** + * Error codes from the RESPONSE register + */ + typedef enum { ERR_NONE = 0x00, // no error if high nibble is 0 + // lower nibble is a counter + ERR_INVALID_SET = 0x80, // invalid setting + ERR_PS1_ADC_OVER = 0x88, // overflows + ERR_PS2_ADC_OVER = 0x89, + ERR_PS3_ADC_OVER = 0x8a, + ERR_ALS_VIS_ADC_OVER = 0x8c, + ERR_ALS_IR_ADC_OVER = 0x8d, + ERR_AUX_ADC_OVER = 0x8e + } SI114X_ERR_T; + + + /** + * Interrupt enable bits + */ + typedef enum { IRQEN_ALS_IE = 0x01, + IRQEN_PS1_IE = 0x04, + IRQEN_PS2_IE = 0x08, + IRQEN_PS3_IE = 0x10 + } SI114X_IRQEN_BITS_T; + + /** + * si114x constructor + * + * @param bus i2c bus to use + * @param address the address for this device + */ + SI114X(int bus, uint8_t address = SI114X_DEFAULT_I2C_ADDR); + + /** + * SI114X Destructor + */ + ~SI114X(); + + /** + * Write byte value into register + * + * @param reg register location to write into + * @param byte byte to write + * @return true if successful + */ + bool writeByte(uint8_t reg, uint8_t byte); + + /** + * Read byte value from register + * + * @param reg register location to read from + * @return value at specified register + */ + uint8_t readByte(uint8_t reg); + + /** + * Read word value from register. + * + * @param reg register location to read from + * @return value at specified register + */ + uint16_t readWord(uint8_t reg); + + /** + * disable interrupts and auto measuring, issue a device reset, + * and then set the hardware key. + */ + void reset(); + + /** + * set the UV calibration values. The constructor sets default + * values for you, so you only need this function if you need + * different values for your device and situation. If you set new + * values here, be sure to do so before calling initialize(). + * + * @param uvcoeff0 coefficient for REG_UCOEF0 + * @param uvcoeff1 coefficient for REG_UCOEF1 + * @param uvcoeff2 coefficient for REG_UCOEF2 + * @param uvcoeff3 coefficient for REG_UCOEF3 + * + */ + void setUVCalibration(uint8_t uvcoeff0, uint8_t uvcoeff1, uint8_t uvcoeff2, + uint8_t uvcoeff3); + + /** + * write a value to parameter memory. + * + * @param param the SI114X_PARAM_T register to write + * @param value the value to write + */ + void writeParam(SI114X_PARAM_T param, uint8_t value); + + /** + * read a value from parameter memory + * + * @param param the SI114X_PARAM_T register to read + * @return the value + */ + uint8_t readParam(SI114X_PARAM_T param); + + /** + * Reset and initialize device, start auto sampling + */ + void initialize(); + + /** + * update stored values. You should call this before calling + * getUVIndex() + */ + void update(); + + /** + * Read the currently measured UV Index value + * + * @return UV Index value + */ + float getUVIndex() { return m_uvIndex; }; + + private: + mraa_i2c_context m_i2c; + uint8_t m_addr; + // UV calibration values + uint8_t m_uv_cal[4]; + // updated by update() + float m_uvIndex; + }; +} + +