summaryrefslogtreecommitdiff
path: root/src/resource/resource_illuminance_sensor.c
blob: c6d4986ddd9c64a6b94864f0a9681e3c462f9a9b (plain)
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;
}