Browse Source

si114x: Initial implementation

This module implements support for the Adafruit UV sensor:
https://www.adafruit.com/products/1777

Signed-off-by: Jon Trulson <jtrulson@ics.com>
Signed-off-by: Zion Orent <zorent@ics.com>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
Jon Trulson 10 years ago
parent
commit
4759d70541

+ 3
- 0
examples/c++/CMakeLists.txt View File

@@ -115,6 +115,7 @@ add_executable (uln200xa-example uln200xa.cxx)
115 115
 add_executable (grovewfs-example grovewfs.cxx)
116 116
 add_executable (isd1820-example isd1820.cxx)
117 117
 add_executable (sx6119-example sx6119.cxx)
118
+add_executable (si114x-example si114x.cxx)
118 119
 
119 120
 include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
120 121
 include_directories (${PROJECT_SOURCE_DIR}/src/grove)
@@ -208,6 +209,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/uln200xa)
208 209
 include_directories (${PROJECT_SOURCE_DIR}/src/grovewfs)
209 210
 include_directories (${PROJECT_SOURCE_DIR}/src/isd1820)
210 211
 include_directories (${PROJECT_SOURCE_DIR}/src/sx6119)
212
+include_directories (${PROJECT_SOURCE_DIR}/src/si114x)
211 213
 
212 214
 target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
213 215
 target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
@@ -324,3 +326,4 @@ target_link_libraries (uln200xa-example uln200xa ${CMAKE_THREAD_LIBS_INIT})
324 326
 target_link_libraries (grovewfs-example grovewfs ${CMAKE_THREAD_LIBS_INIT})
325 327
 target_link_libraries (isd1820-example isd1820 ${CMAKE_THREAD_LIBS_INIT})
326 328
 target_link_libraries (sx6119-example sx6119 ${CMAKE_THREAD_LIBS_INIT})
329
+target_link_libraries (si114x-example si114x ${CMAKE_THREAD_LIBS_INIT})

+ 78
- 0
examples/c++/si114x.cxx View File

@@ -0,0 +1,78 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining
6
+ * a copy of this software and associated documentation files (the
7
+ * "Software"), to deal in the Software without restriction, including
8
+ * without limitation the rights to use, copy, modify, merge, publish,
9
+ * distribute, sublicense, and/or sell copies of the Software, and to
10
+ * permit persons to whom the Software is furnished to do so, subject to
11
+ * the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+#include <unistd.h>
26
+#include <iostream>
27
+#include <signal.h>
28
+#include "si114x.h"
29
+
30
+using namespace std;
31
+
32
+int shouldRun = true;
33
+
34
+void sig_handler(int signo)
35
+{
36
+  if (signo == SIGINT)
37
+    shouldRun = false;
38
+}
39
+
40
+
41
+int main ()
42
+{
43
+  signal(SIGINT, sig_handler);
44
+
45
+//! [Interesting]
46
+  // Instantiate a SI114x UV Sensor on I2C bus 0
47
+  upm::SI114X* uvi = new upm::SI114X(0);
48
+  
49
+  // First initialize it
50
+  uvi->initialize();
51
+
52
+  cout << "UV Index Scale:" << endl;
53
+  cout << "---------------" << endl;
54
+  cout << "11+        Extreme" << endl;
55
+  cout << "8-10       Very High" << endl;
56
+  cout << "6-7        High" << endl;
57
+  cout << "3-5        Moderate" << endl;
58
+  cout << "0-2        Low" << endl;
59
+  cout << endl;
60
+
61
+  // update every second and print the currently measured UV Index
62
+  while (shouldRun)
63
+    {
64
+      // update current value(s)
65
+      uvi->update();
66
+
67
+      // print detected value
68
+      cout << "UV Index: " << uvi->getUVIndex() << endl;
69
+
70
+      sleep(1);
71
+    }
72
+//! [Interesting]
73
+
74
+  cout << "Exiting..." << endl;
75
+
76
+  delete uvi;
77
+  return 0;
78
+}

+ 66
- 0
examples/javascript/si114x.js View File

@@ -0,0 +1,66 @@
1
+/*jslint node:true, vars:true, bitwise:true, unparam:true */
2
+/*jshint unused:true */
3
+
4
+/*
5
+* Author: Zion Orent <zorent@ics.com>
6
+* Copyright (c) 2015 Intel Corporation.
7
+*
8
+* Permission is hereby granted, free of charge, to any person obtaining
9
+* a copy of this software and associated documentation files (the
10
+* "Software"), to deal in the Software without restriction, including
11
+* without limitation the rights to use, copy, modify, merge, publish,
12
+* distribute, sublicense, and/or sell copies of the Software, and to
13
+* permit persons to whom the Software is furnished to do so, subject to
14
+* the following conditions:
15
+*
16
+* The above copyright notice and this permission notice shall be
17
+* included in all copies or substantial portions of the Software.
18
+*
19
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+*/
27
+
28
+var UV_lib = require('jsupm_si114x');
29
+
30
+// Instantiate a SI114x UV Sensor on I2C bus 0
31
+var myUVSensor = new UV_lib.SI114X(0);
32
+
33
+for (var x in myUVSensor)
34
+	console.log(x);
35
+// First initialize it
36
+myUVSensor.initialize();
37
+
38
+console.log("UV Index Scale:");
39
+console.log("---------------");
40
+console.log("11+        Extreme");
41
+console.log("8-10       Very High");
42
+console.log("6-7        High");
43
+console.log("3-5        Moderate");
44
+console.log("0-2        Low\n");
45
+
46
+// update every second and print the currently measured UV Index
47
+var myInterval = setInterval(function()
48
+{
49
+	// update current value(s)
50
+	myUVSensor.update();
51
+
52
+	// print detected value
53
+	console.log("UV Index: " + myUVSensor.getUVIndex());
54
+}, 1000);
55
+
56
+
57
+// When exiting: clear interval and print message
58
+process.on('SIGINT', function()
59
+{
60
+	clearInterval(myInterval);
61
+	myUVSensor = null
62
+	UV_lib.cleanUp();
63
+	UV_lib = null;
64
+	console.log("Exiting");
65
+	process.exit(0);
66
+});

+ 66
- 0
examples/python/si114x.py View File

@@ -0,0 +1,66 @@
1
+#!/usr/bin/python
2
+# Author: Zion Orent <zorent@ics.com>
3
+# Copyright (c) 2015 Intel Corporation.
4
+#
5
+# Permission is hereby granted, free of charge, to any person obtaining
6
+# a copy of this software and associated documentation files (the
7
+# "Software"), to deal in the Software without restriction, including
8
+# without limitation the rights to use, copy, modify, merge, publish,
9
+# distribute, sublicense, and/or sell copies of the Software, and to
10
+# permit persons to whom the Software is furnished to do so, subject to
11
+# the following conditions:
12
+#
13
+# The above copyright notice and this permission notice shall be
14
+# included in all copies or substantial portions of the Software.
15
+#
16
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+import time, sys, signal, atexit
25
+import pyupm_si114x as upmSi114x
26
+
27
+# Instantiate a SI114x UV Sensor on I2C bus 0
28
+myUVSensor = upmSi114x.SI114X(0)
29
+
30
+
31
+## Exit handlers ##
32
+# This stops python from printing a stacktrace when you hit control-C
33
+def SIGINTHandler(signum, frame):
34
+	raise SystemExit
35
+
36
+# This function lets you run code on exit,
37
+# including functions from myUVSensor
38
+def exitHandler():
39
+	print "Exiting"
40
+	sys.exit(0)
41
+
42
+# Register exit handlers
43
+atexit.register(exitHandler)
44
+signal.signal(signal.SIGINT, SIGINTHandler)
45
+
46
+
47
+# First initialize it
48
+myUVSensor.initialize()
49
+
50
+print "UV Index Scale:"
51
+print "---------------"
52
+print "11+        Extreme"
53
+print "8-10       Very High"
54
+print "6-7        High"
55
+print "3-5        Moderate"
56
+print "0-2        Low\n"
57
+
58
+# update every second and print the currently measured UV Index
59
+while (1):
60
+	# update current value(s)
61
+	myUVSensor.update()
62
+
63
+	# print detected value
64
+	print "UV Index:", myUVSensor.getUVIndex()
65
+
66
+	time.sleep(1)

+ 5
- 0
src/si114x/CMakeLists.txt View File

@@ -0,0 +1,5 @@
1
+set (libname "si114x")
2
+set (libdescription "upm si114x UV/IR/Visible light sensor")
3
+set (module_src ${libname}.cxx)
4
+set (module_h ${libname}.h)
5
+upm_module_init()

+ 9
- 0
src/si114x/jsupm_si114x.i View File

@@ -0,0 +1,9 @@
1
+%module jsupm_si114x
2
+%include "../upm.i"
3
+%include "cpointer.i"
4
+
5
+%{
6
+    #include "si114x.h"
7
+%}
8
+
9
+%include "si114x.h"

+ 13
- 0
src/si114x/pyupm_si114x.i View File

@@ -0,0 +1,13 @@
1
+%module pyupm_si114x
2
+%include "../upm.i"
3
+
4
+%feature("autodoc", "3");
5
+
6
+#ifdef DOXYGEN
7
+%include "si114x_doc.i"
8
+#endif
9
+
10
+%include "si114x.h"
11
+%{
12
+    #include "si114x.h"
13
+%}

+ 190
- 0
src/si114x/si114x.cxx View File

@@ -0,0 +1,190 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Thanks to Adafruit for some important clues
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining
8
+ * a copy of this software and associated documentation files (the
9
+ * "Software"), to deal in the Software without restriction, including
10
+ * without limitation the rights to use, copy, modify, merge, publish,
11
+ * distribute, sublicense, and/or sell copies of the Software, and to
12
+ * permit persons to whom the Software is furnished to do so, subject to
13
+ * the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ */
26
+
27
+#include <unistd.h>
28
+#include <math.h>
29
+#include <iostream>
30
+#include <string>
31
+
32
+#include "si114x.h"
33
+
34
+using namespace upm;
35
+using namespace std;
36
+
37
+
38
+SI114X::SI114X(int bus, uint8_t address)
39
+{
40
+  m_addr = address;
41
+  m_uvIndex = 0;
42
+
43
+  // setup our i2c link
44
+  if ( !(m_i2c = mraa_i2c_init(bus)) )
45
+    {
46
+      cerr << "SI114X: mraa_i2c_init() failed." << endl;
47
+      return;
48
+    }
49
+      
50
+  mraa_result_t rv;
51
+  
52
+  if ( (rv = mraa_i2c_address(m_i2c, m_addr)) != MRAA_SUCCESS)
53
+    {
54
+      cerr << "SI114X: Could not initialize i2c bus. " << endl;
55
+      mraa_result_print(rv);
56
+      return;
57
+    }
58
+
59
+  // The data sheet recommends setting the UV calibration values to
60
+  // 0x7b, 0x6b, 0x01, and 0x00, however the adafruit code uses a
61
+  // different set of values, presumably calibrated to their specific
62
+  // implementation.  We will use those defaults here, as this was
63
+  // developed on an adafruit device.  
64
+
65
+  // Use setUVCalibration() to set a different set of values before
66
+  // calling init() if you need different values.
67
+
68
+  setUVCalibration(0x29, 0x89, 0x02, 0x00);
69
+}
70
+
71
+SI114X::~SI114X()
72
+{
73
+  mraa_i2c_stop(m_i2c);
74
+}
75
+
76
+bool SI114X::writeByte(uint8_t reg, uint8_t byte)
77
+{
78
+  mraa_result_t rv = mraa_i2c_write_byte_data(m_i2c, byte, reg);
79
+
80
+  if (rv != MRAA_SUCCESS)
81
+    {
82
+      cerr << __FUNCTION__ << ": mraa_i2c_write_byte() failed." << endl;
83
+      mraa_result_print(rv);
84
+      return false;
85
+    }
86
+
87
+  return true;
88
+}
89
+
90
+uint8_t SI114X::readByte(uint8_t reg)
91
+{
92
+  return mraa_i2c_read_byte_data(m_i2c, reg);
93
+}
94
+
95
+uint16_t SI114X::readWord(uint8_t reg)
96
+{
97
+  return mraa_i2c_read_word_data(m_i2c, reg);
98
+}
99
+
100
+void SI114X::setUVCalibration(uint8_t uvcoeff0, uint8_t uvcoeff1, 
101
+                              uint8_t uvcoeff2, uint8_t uvcoeff3)
102
+{
103
+  m_uv_cal[0] = uvcoeff0;
104
+  m_uv_cal[1] = uvcoeff1;
105
+  m_uv_cal[2] = uvcoeff2;
106
+  m_uv_cal[3] = uvcoeff3; 
107
+};
108
+
109
+
110
+void SI114X::writeParam(SI114X_PARAM_T param, uint8_t value)
111
+{
112
+  // write a parameter to the RAM parameter area
113
+
114
+  // We write the value to the PARAM_WR register, then execute a
115
+  // PARAM_WRITE command
116
+
117
+  writeByte(REG_PARAM_WR, value);
118
+
119
+  // now write it to parameter memory
120
+  writeByte(REG_COMMAND, CMD_PARAM_SET | param);
121
+}
122
+
123
+uint8_t SI114X::readParam(SI114X_PARAM_T param)
124
+{
125
+  // get the parameter into register REG_PARAM_READ, then read and return it.
126
+
127
+  writeByte(REG_COMMAND, CMD_PARAM_QUERY | param);
128
+  return readByte(REG_PARAM_READ);
129
+}
130
+
131
+void SI114X::reset()
132
+{
133
+  // reset the device 
134
+
135
+  // zero out measuring rate
136
+  writeByte(REG_MEAS_RATE0, 0);
137
+  writeByte(REG_MEAS_RATE1, 0);
138
+
139
+  // disable IRQ MODES
140
+  // these are undocumented in the datasheet, but mentioned in Adafruit's code
141
+  writeByte(REG_IRQ_MODE1, 0);
142
+  writeByte(REG_IRQ_MODE2, 0);
143
+  
144
+  // turn off interrupts
145
+  writeByte(REG_INT_CFG, 0);
146
+  writeByte(REG_IRQ_STATUS, 0xff);
147
+
148
+  // send a reset
149
+  writeByte(REG_COMMAND, CMD_RESET);
150
+  usleep(100);
151
+
152
+  // set the hardware key
153
+  writeByte(REG_HW_KEY, SI114X_HW_KEY);
154
+  usleep(100);
155
+}
156
+
157
+void SI114X::initialize()
158
+{
159
+  // initialize the device
160
+
161
+  // first, reset it
162
+  reset();
163
+
164
+  // UV coefficients
165
+  writeByte(REG_UCOEF0, m_uv_cal[0]);
166
+  writeByte(REG_UCOEF1, m_uv_cal[1]);
167
+  writeByte(REG_UCOEF2, m_uv_cal[2]);
168
+  writeByte(REG_UCOEF3, m_uv_cal[3]);
169
+  
170
+  // enable UV sensor only for now
171
+  writeParam(PARAM_CHLIST, CHLIST_EN_UV);
172
+
173
+  // auto-measure speed - slowest - (rate * 31.25us)
174
+  writeByte(REG_MEAS_RATE0, 0xff); // 7.9ms
175
+
176
+  // set autorun
177
+  writeByte(REG_COMMAND, CMD_ALS_AUTO);
178
+}
179
+
180
+void SI114X::update()
181
+{
182
+  // for now, just update the UV Index member variable
183
+  uint16_t uvi = readWord(REG_AUX_UVINDEX0);
184
+
185
+  m_uvIndex = float(uvi) / 100.0;
186
+
187
+  // Add any further data gets() here
188
+
189
+  return;
190
+}

+ 322
- 0
src/si114x/si114x.h View File

@@ -0,0 +1,322 @@
1
+/*
2
+ * Author: Jon Trulson <jtrulson@ics.com>
3
+ * Copyright (c) 2015 Intel Corporation.
4
+ *
5
+ * Thanks to Adafruit for some important clues
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining
8
+ * a copy of this software and associated documentation files (the
9
+ * "Software"), to deal in the Software without restriction, including
10
+ * without limitation the rights to use, copy, modify, merge, publish,
11
+ * distribute, sublicense, and/or sell copies of the Software, and to
12
+ * permit persons to whom the Software is furnished to do so, subject to
13
+ * the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ */
26
+#pragma once
27
+
28
+#include <string>
29
+#include <mraa/i2c.h>
30
+#include <mraa/gpio.h>
31
+
32
+#define SI114X_I2C_BUS 0
33
+#define SI114X_DEFAULT_I2C_ADDR 0x60
34
+#define SI114X_HW_KEY 0x17
35
+
36
+
37
+namespace upm {
38
+  
39
+  /**
40
+   * @brief SI1145 UV light sensor
41
+   * @defgroup si114x libupm-si114x
42
+   * @ingroup adafruit i2c light
43
+   */
44
+
45
+  /**
46
+   * @library si114x
47
+   * @sensor si114x
48
+   * @comname SI1145 UV light sensor
49
+   * @altname SI1146, SI1147
50
+   * @type light
51
+   * @man adafruit
52
+   * @web https://www.adafruit.com/products/1777
53
+   * @con i2c
54
+   *
55
+   * @brief C++ API for the SI1145 UV light sensor
56
+   *
57
+   * This module was tested with the Adafruit UV Sensor
58
+   *
59
+   * This device is also capable of measuring IR and visible ambient
60
+   * light as well.  It also supports the ability to use externally
61
+   * attached LED's to perform proximity detection on 3 separate
62
+   * channels.
63
+   *
64
+   * This class currently only supports the retriving of the
65
+   * calculated UV index measured by the device, but enough
66
+   * infrastructure is provided to make it easy to enhance this driver
67
+   * in the future to support additional capabilities, including
68
+   * interrupt support.
69
+   *
70
+   * @snippet si114x.cxx Interesting
71
+   */
72
+  class SI114X {
73
+  public:
74
+
75
+    /**
76
+     * SI114X registers
77
+     */
78
+    typedef enum { REG_PART_ID       = 0x00,
79
+                   REG_REV_ID        = 0x01,
80
+                   REG_SEQ_ID        = 0x02,
81
+                   REG_INT_CFG       = 0x03,
82
+                   REG_IRQ_ENABLE    = 0x04,
83
+
84
+                   // these two are not documented in the datasheet,
85
+                   // but are mentioned there, as well as in the
86
+                   // Adafruit example
87
+                   REG_IRQ_MODE1     = 0x05,
88
+                   REG_IRQ_MODE2     = 0x06,
89
+
90
+                   REG_HW_KEY        = 0x07,
91
+                   REG_MEAS_RATE0    = 0x08,
92
+                   REG_MEAS_RATE1    = 0x09,
93
+
94
+                   REG_PS_LED21      = 0x0f,
95
+                   REG_PS_LED3       = 0x10,
96
+
97
+                   REG_UCOEF0        = 0x13,
98
+                   REG_UCOEF1        = 0x14,
99
+                   REG_UCOEF2        = 0x15,
100
+                   REG_UCOEF3        = 0x16,
101
+                   REG_PARAM_WR      = 0x17,
102
+                   REG_COMMAND       = 0x18,
103
+
104
+                   REG_RESPONSE      = 0x20,
105
+                   REG_IRQ_STATUS    = 0x21,
106
+                   REG_ALS_VIS_DATA0 = 0x22,
107
+                   REG_ALS_VIS_DATA1 = 0x23,
108
+                   REG_ALS_IR_DATA0  = 0x24,
109
+                   REG_ALS_IR_DATA1  = 0x25,
110
+                   REG_PS1_DATA0     = 0x26,
111
+                   REG_PS1_DATA1     = 0x27,
112
+                   REG_PS2_DATA0     = 0x28,
113
+                   REG_PS2_DATA1     = 0x29,
114
+                   REG_PS3_DATA0     = 0x2a,
115
+                   REG_PS3_DATA1     = 0x2b,
116
+                   REG_AUX_UVINDEX0  = 0x2c,
117
+                   REG_AUX_UVINDEX1  = 0x2d,
118
+                   REG_PARAM_READ    = 0x2e,
119
+
120
+                   REG_CHIP_STAT     = 0x30,
121
+
122
+                   REG_ANA_IN_KEY0   = 0x3b,
123
+                   REG_ANA_IN_KEY1   = 0x3c,
124
+                   REG_ANA_IN_KEY2   = 0x3d,
125
+                   REG_ANA_IN_KEY3   = 0x3e
126
+    } SI114X_REG_T;
127
+    
128
+    /**
129
+     * Parameter memory (PARAM)
130
+     */
131
+    typedef enum { PARAM_I2C_ADDDR         = 0x00,
132
+                   PARAM_CHLIST            = 0x01,
133
+                   PARAM_PSLED12_SEL       = 0x02,
134
+                   PARAM_PSLED3_SEL        = 0x03,
135
+
136
+                   PARAM_PS_ENCODING       = 0x05,
137
+                   PARAM_ALS_ENCODING      = 0x06,
138
+                   PARAM_PS1_ADCMUX        = 0x07,
139
+                   PARAM_PS2_ADCMUX        = 0x08,
140
+                   PARAM_PS3_ADCMUX        = 0x09,
141
+                   PARAM_PS_ADC_COUNT      = 0x0a,
142
+                   PARAM_PS_ADC_GAIN       = 0x0b,
143
+                   PARAM_PS_ADC_MISC       = 0x0c,
144
+
145
+                   PARAM_ALS_IR_ADCMUX     = 0x0e,
146
+                   PARAM_AUX_ADCMUX        = 0x0f,
147
+                   PARAM_ALS_VIS_ADC_COUNT = 0x10,
148
+                   PARAM_ALS_VIS_ADC_GAIN  = 0x11,
149
+                   PARAM_ALS_VIS_ADC_MISC  = 0x12,
150
+
151
+                   PARAM_LED_REC           = 0x1c,
152
+                   PARAM_ALS_IR_ADC_COUNT  = 0x1d,
153
+                   PARAM_ALS_IR_ADX_GAIN   = 0x1e,
154
+                   PARAM_ALS_IR_ADC_MISC   = 0x1f
155
+    } SI114X_PARAM_T;
156
+    
157
+    /**
158
+     * Commands (written to the REG_COMMAND register)
159
+     */
160
+    typedef enum { CMD_NOOP          = 0x00, // clear RESPONSE reg
161
+                   CMD_RESET         = 0x01,
162
+                   CMD_BUSADDR       = 0x02,
163
+
164
+                   CMD_PS_FORCE      = 0x05,
165
+                   CMD_GET_CAL       = 0x12,
166
+                   CMD_ALS_FORCE     = 0x06,
167
+                   CMD_PSALS_FORCE   = 0x07,
168
+
169
+                   CMD_PS_PAUSE      = 0x09,
170
+                   CMD_ALS_PAUSE     = 0x0a,
171
+                   CMD_PSALS_PAUSE   = 0x0b,
172
+
173
+                   CMD_PS_AUTO       = 0x0d,
174
+                   CMD_ALS_AUTO      = 0x0e,
175
+                   CMD_PSALS_AUTO    = 0x0f,
176
+
177
+                   CMD_PARAM_QUERY   = 0x80, // or'd with PARAM_T value
178
+                   CMD_PARAM_SET     = 0xa0  // or'd with PARAM_T value
179
+    } SI114X_CMD_T;
180
+
181
+
182
+    /**
183
+     * Channel List enable bits
184
+     */
185
+    typedef enum { CHLIST_EN_PS1     = 0x01, // proximity sense 1-3
186
+                   CHLIST_EN_PS2     = 0x02,
187
+                   CHLIST_EN_PS3     = 0x04,
188
+
189
+                   CHLIST_EN_ALS_VIS = 0x10, // ambient light sense
190
+                   CHLIST_EN_ALS_IR  = 0x20,
191
+                   CHLIST_EN_AUX     = 0x40, // AUX sense
192
+                   CHLIST_EN_UV      = 0x80  // UV sense
193
+    } SI114X_CHLIST_BITS_T;
194
+
195
+    /**
196
+     * Error codes from the RESPONSE register
197
+     */
198
+    typedef enum { ERR_NONE          = 0x00, // no error if high nibble is 0
199
+                                             // lower nibble is a counter
200
+                   ERR_INVALID_SET   = 0x80, // invalid setting
201
+                   ERR_PS1_ADC_OVER  = 0x88, // overflows
202
+                   ERR_PS2_ADC_OVER  = 0x89,
203
+                   ERR_PS3_ADC_OVER  = 0x8a,
204
+                   ERR_ALS_VIS_ADC_OVER  = 0x8c,
205
+                   ERR_ALS_IR_ADC_OVER   = 0x8d,
206
+                   ERR_AUX_ADC_OVER  = 0x8e
207
+    } SI114X_ERR_T;
208
+    
209
+
210
+    /**
211
+     * Interrupt enable bits
212
+     */
213
+    typedef enum { IRQEN_ALS_IE      = 0x01,
214
+                   IRQEN_PS1_IE      = 0x04,
215
+                   IRQEN_PS2_IE      = 0x08,
216
+                   IRQEN_PS3_IE      = 0x10
217
+    } SI114X_IRQEN_BITS_T;
218
+
219
+    /**
220
+     * si114x constructor
221
+     *
222
+     * @param bus i2c bus to use
223
+     * @param address the address for this device
224
+     */
225
+    SI114X(int bus, uint8_t address = SI114X_DEFAULT_I2C_ADDR);
226
+
227
+    /**
228
+     * SI114X Destructor
229
+     */
230
+    ~SI114X();
231
+
232
+    /**
233
+     * Write byte value into register
234
+     *
235
+     * @param reg register location to write into
236
+     * @param byte byte to write
237
+     * @return true if successful
238
+     */
239
+    bool writeByte(uint8_t reg, uint8_t byte);
240
+
241
+    /**
242
+     * Read byte value from register
243
+     *
244
+     * @param reg register location to read from
245
+     * @return value at specified register
246
+     */
247
+    uint8_t readByte(uint8_t reg);
248
+
249
+    /**
250
+     * Read word value from register.
251
+     *
252
+     * @param reg register location to read from
253
+     * @return value at specified register
254
+     */
255
+    uint16_t readWord(uint8_t reg);
256
+
257
+    /**
258
+     * disable interrupts and auto measuring, issue a device reset,
259
+     * and then set the hardware key.
260
+     */
261
+    void reset();
262
+
263
+    /**
264
+     * set the UV calibration values.  The constructor sets default
265
+     * values for you, so you only need this function if you need
266
+     * different values for your device and situation.  If you set new
267
+     * values here, be sure to do so before calling initialize().
268
+     *
269
+     * @param uvcoeff0 coefficient for REG_UCOEF0
270
+     * @param uvcoeff1 coefficient for REG_UCOEF1
271
+     * @param uvcoeff2 coefficient for REG_UCOEF2
272
+     * @param uvcoeff3 coefficient for REG_UCOEF3
273
+     *
274
+     */
275
+    void setUVCalibration(uint8_t uvcoeff0, uint8_t uvcoeff1, uint8_t uvcoeff2,
276
+                          uint8_t uvcoeff3);
277
+
278
+    /**
279
+     * write a value to parameter memory.
280
+     *
281
+     * @param param the SI114X_PARAM_T register to write
282
+     * @param value the value to write
283
+     */
284
+    void writeParam(SI114X_PARAM_T param, uint8_t value);
285
+    
286
+    /**
287
+     * read a value from parameter memory
288
+     *
289
+     * @param param the SI114X_PARAM_T register to read
290
+     * @return the value
291
+     */
292
+    uint8_t readParam(SI114X_PARAM_T param);
293
+
294
+    /**
295
+     * Reset and initialize device, start auto sampling
296
+     */
297
+    void initialize();
298
+
299
+    /**
300
+     * update stored values.  You should call this before calling
301
+     * getUVIndex()
302
+     */
303
+    void update();
304
+
305
+    /**
306
+     * Read the currently measured UV Index value
307
+     *
308
+     * @return UV Index value
309
+     */
310
+    float getUVIndex() { return m_uvIndex; };
311
+
312
+  private:
313
+    mraa_i2c_context m_i2c;
314
+    uint8_t m_addr;
315
+    // UV calibration values
316
+    uint8_t m_uv_cal[4];
317
+    // updated by update()
318
+    float m_uvIndex;
319
+  };
320
+}
321
+
322
+