1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
/*
* Copyright (c) 2018 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <unistd.h>
#include <peripheral_io.h>
#include "log.h"
#define ARTIK_I2C_BUS 1
#define GY302_ADDR (0x23) /* Address of GY30 light sensor */
#define GY302_CONT_HIGH_RES_MODE 0x10 /* Start measurement at 11x resolution. Measurement time is approx 120mx */
#define GY302_CONSTANT_NUM (1.2) /* to convert sensor value to real lux value */
peripheral_i2c_h g_i2c_h = NULL;
int g_i2c_bus = ARTIK_I2C_BUS;
int g_i2c_address = GY302_ADDR;
static int _open_i2c_handle(void)
{
int ret;
// open i2c handle for I2C read/write
if ((ret = peripheral_i2c_open(g_i2c_bus, g_i2c_address, &g_i2c_h)) != 0 ) {
_E("peripheral_i2c_open() failed!![%d]", ret);
return ret;
}
return ret;
}
int resource_close_illuminance_sensor(void)
{
int ret = PERIPHERAL_ERROR_NONE;
if (g_i2c_h != NULL) {
// close i2c handle
if ((ret = peripheral_i2c_close(g_i2c_h)) != 0 ) {
_E("peripheral_i2c_close() failed!![%d]", ret);
return ret;
}
g_i2c_h = NULL;
}
return ret;
}
static void _reset_i2c_port(int reason)
{
int ret = PERIPHERAL_ERROR_NONE;
switch (reason) {
case PERIPHERAL_ERROR_RESOURCE_BUSY :
case PERIPHERAL_ERROR_IO_ERROR :
case PERIPHERAL_ERROR_TRY_AGAIN : {
uint8_t data[10] = { 0, };
// Reset 0000_0111 Reset Data register value.
data[0] = 0x07; // //Reset : 0000_0111
if ((ret = peripheral_i2c_write(g_i2c_h, data, 1)) != 0 ) {
_E("peripheral_i2c_write() failed!![%d]", ret);
return;
}
}
break;
default :
_E("unknown reason [%d]", reason);
break;
}
}
int resource_read_illuminance_sensor(uint16_t *out_value)
{
int ret = PERIPHERAL_ERROR_NONE;
static bool continuous_read = false;
unsigned char buf[10] = { 0, };
if (g_i2c_h == NULL) {
// open i2c handle for I2C read/write
if ((ret = _open_i2c_handle()) != PERIPHERAL_ERROR_NONE ) {
_E("peripheral_i2c_open() failed!![%d]", ret);
return ret;
}
}
// set data for mode register
if (continuous_read == false) {
// Continuously H-Resolution Mode 0001_0000 Start measurement at 1lx resolution.
buf[0] = GY302_CONT_HIGH_RES_MODE;
// write mode command to sensor
if ((ret = peripheral_i2c_write(g_i2c_h, buf, 1)) != PERIPHERAL_ERROR_NONE) {
_E("peripheral_i2c_write() failed!![%d]", ret);
return ret;
}
// Wait a few moments to wake up
// Measurement Time is typically 120ms.
usleep(120 * 1000); // wait 120 ms
continuous_read = true;
}
// Read two bytes from the sensor, which are low and high parts of the sensor
if ((ret = peripheral_i2c_read(g_i2c_h, buf, 2)) != PERIPHERAL_ERROR_NONE) {
_E("peripheral_i2c_read() failed!![%d]", ret);
_reset_i2c_port(ret);
return ret;
}
// Convert raw value to lux value
*out_value = (buf[0] << 8 | buf[1]) / GY302_CONSTANT_NUM; // Just Sum High 8bit and Low 8bit, divide by 1.2
return ret;
}
|