1 /*
2 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3 * Copyright (c) 2014 Intel Corporation.
4 *
5 * Credits to Seeed Studeo.
6 * Based on Seeed Studeo code example,
7 * http://www.seeedstudio.com/wiki/index.php?title=Twig_-_I2C_Color_Sensor_v0.9b.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining
10 * a copy of this software and associated documentation files (the
11 * "Software"), to deal in the Software without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29 #include <iostream>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <stdexcept>
33
34 #include "tcs3414cs.h"
35
36 using namespace upm;
37
TCS3414CS()38 TCS3414CS::TCS3414CS () : m_i2Ctx(0) {
39 m_name = "TCS3414CS";
40
41 mraa::Result ret = m_i2Ctx.address(ADDR);
42 if (ret != mraa::SUCCESS) {
43 throw std::invalid_argument(std::string(__FUNCTION__) +
44 ": m_i2Ctx.address() failed");
45 }
46
47 // Set timing register
48 i2cWriteReg (REG_TIMING, INTEG_MODE_FREE);
49 usleep (100000);
50
51 // Set interrupt source register
52 i2cWriteReg (REG_INT_SOURCE, INT_SOURCE_GREEN);
53 usleep (100000);
54
55 // Set interrupt control register
56 i2cWriteReg (REG_INT, INTR_LEVEL | INTR_PERSIST_EVERY);
57 usleep (100000);
58
59 // Set gain
60 i2cWriteReg (REG_GAIN, GAIN_1 | PRESCALER_4);
61 usleep (100000);
62
63 // Enable ADC
64 i2cWriteReg (REG_CTL, CTL_DAT_INIITIATE);
65 usleep (100000);
66 }
67
68 void
readRGB(tcs3414sc_rgb_t * rgb)69 TCS3414CS::readRGB (tcs3414sc_rgb_t * rgb) {
70 uint8_t buffer[8];
71
72 // We need 7 bytes of data.
73 if (i2cReadReg_N (REG_BLOCK_READ, 8, buffer) > 7) {
74 rgb->g = buffer[1] * 256 + buffer[0];
75 rgb->r = buffer[3] * 256 + buffer[2];
76 rgb->b = buffer[5] * 256 + buffer[4];
77 rgb->clr = buffer[7] * 256 + buffer[6];
78 }
79 }
80
81 void
clearInterrupt()82 TCS3414CS::clearInterrupt () {
83 mraa::Result error = mraa::SUCCESS;
84
85 error = m_i2Ctx.address (ADDR);
86 error = m_i2Ctx.writeByte (CLR_INT);
87
88 if (error != mraa::SUCCESS) {
89 throw std::runtime_error(std::string(__FUNCTION__) +
90 ": Couldn't clear interrupt");
91 }
92 }
93
94 /*
95 * **************
96 * private area
97 * **************
98 */
99 uint16_t
i2cReadReg_N(int reg,unsigned int len,uint8_t * buffer)100 TCS3414CS::i2cReadReg_N (int reg, unsigned int len, uint8_t * buffer) {
101 int readByte = 0;
102
103 m_i2Ctx.address(ADDR);
104 m_i2Ctx.writeByte(reg);
105
106 m_i2Ctx.address(ADDR);
107 readByte = m_i2Ctx.read(buffer, len);
108 return readByte;
109 }
110
111 mraa::Result
i2cWriteReg_N(uint8_t reg,unsigned int len,uint8_t * buffer)112 TCS3414CS::i2cWriteReg_N (uint8_t reg, unsigned int len, uint8_t * buffer) {
113 mraa::Result error = mraa::SUCCESS;
114
115 error = m_i2Ctx.address (ADDR);
116 error = m_i2Ctx.writeByte (reg);
117 error = m_i2Ctx.write (buffer, len);
118
119 return error;
120 }
121
122 mraa::Result
i2cWriteReg(uint8_t reg,uint8_t data)123 TCS3414CS::i2cWriteReg (uint8_t reg, uint8_t data) {
124 mraa::Result error = mraa::SUCCESS;
125
126 error = m_i2Ctx.address (ADDR);
127 error = m_i2Ctx.writeByte (reg);
128 error = m_i2Ctx.writeByte (data);
129
130 return error;
131 }
132