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