Implement infrared obstacle avoidance sensor
[apps/native/gear-racing-car.git] / src / resource / resource_infrared_obstacle_avoidance_sensor.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Contact: Jin Yoon <jinny.yoon@samsung.com>
5  *          Geunsun Lee <gs86.lee@samsung.com>
6  *          Eunyoung Lee <ey928.lee@samsung.com>
7  *          Junkyu Han <junkyu.han@samsung.com>
8  *
9  * Licensed under the Flora License, Version 1.1 (the License);
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://floralicense.org/license/
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an AS IS BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <peripheral_io.h>
25 #include <sys/time.h>
26
27 #include "log.h"
28 #include "resource_internal.h"
29
30 void resource_close_infrared_obstacle_avoidance_sensor(int pin_num)
31 {
32         if (!resource_get_info(pin_num)->opened) return;
33
34         _I("Infrared Obstacle Avoidance Sensor is finishing...");
35         if (resource_get_info(pin_num)->resource_changed_info) {
36                 free(resource_get_info(pin_num)->resource_changed_info);
37                 resource_get_info(pin_num)->resource_changed_info = NULL;
38         }
39         peripheral_gpio_unset_interrupted_cb(resource_get_info(pin_num)->sensor_h);
40         peripheral_gpio_close(resource_get_info(pin_num)->sensor_h);
41         resource_get_info(pin_num)->sensor_h = NULL;
42         resource_get_info(pin_num)->opened = 0;
43
44         return;
45 }
46
47 static int _init_pin(int pin_num)
48 {
49         int ret = PERIPHERAL_ERROR_NONE;
50
51         ret = peripheral_gpio_open(pin_num, &resource_get_info(pin_num)->sensor_h);
52         retv_if(ret != PERIPHERAL_ERROR_NONE, -1);
53
54         ret = peripheral_gpio_set_direction(resource_get_info(pin_num)->sensor_h, PERIPHERAL_GPIO_DIRECTION_IN);
55         if (ret != PERIPHERAL_ERROR_NONE) {
56                 peripheral_gpio_close(resource_get_info(pin_num)->sensor_h);
57                 resource_get_info(pin_num)->sensor_h = NULL;
58                 return -1;
59         }
60
61         resource_get_info(pin_num)->opened = 1;
62         resource_get_info(pin_num)->close = resource_close_infrared_obstacle_avoidance_sensor;
63
64         return 0;
65 }
66
67 int resource_read_infrared_obstacle_avoidance_sensor(int pin_num, uint32_t *out_value)
68 {
69         int ret = PERIPHERAL_ERROR_NONE;
70
71         if (!resource_get_info(pin_num)->opened) {
72                 ret = _init_pin(pin_num);
73                 retv_if(ret < 0, -1);
74         }
75
76         ret = peripheral_gpio_read(resource_get_info(pin_num)->sensor_h, out_value);
77         retv_if(ret != PERIPHERAL_ERROR_NONE, -1);
78
79         *out_value = !*out_value;
80
81         _I("Infrared Obstacle Avoidance Sensor Value : %d", *out_value);
82
83         return 0;
84 }
85
86
87 static void __ioa_sensor_interrupt_cb(peripheral_gpio_h gpio, peripheral_error_e error, void *user_data)
88 {
89         uint32_t value;
90         resource_changed_s *resource_changed_info = (resource_changed_s *)user_data;
91
92         /* Detected : 0, Non-detected : 1 */
93         peripheral_gpio_read(gpio, &value);
94         _D("interrupt value = %d", !value);
95
96         resource_changed_info->cb(!value, resource_changed_info->data);
97
98         return;
99 }
100
101 int resource_set_infrared_obstacle_avoidance_sensor_interrupted_cb(int pin_num, resource_changed_cb cb, void *data)
102 {
103         int ret = PERIPHERAL_ERROR_NONE;
104
105         if (resource_get_info(pin_num)->resource_changed_info == NULL) {
106                 resource_get_info(pin_num)->resource_changed_info = calloc(1, sizeof(resource_changed_s));
107                 retv_if(!resource_get_info(pin_num)->resource_changed_info, -1);
108         } else {
109                 if (resource_get_info(pin_num)->sensor_h) {
110                         peripheral_gpio_unset_interrupted_cb(resource_get_info(resource_get_info(pin_num)->resource_changed_info->pin_num)->sensor_h);
111                 }
112         }
113
114         resource_get_info(pin_num)->resource_changed_info->cb = cb;
115         resource_get_info(pin_num)->resource_changed_info->data = data;
116         resource_get_info(pin_num)->resource_changed_info->pin_num = pin_num;
117
118         if (!resource_get_info(pin_num)->opened) {
119                 ret = _init_pin(pin_num);
120                 goto_if(ret < 0, FREE_RESOURCE);
121         }
122
123         if (resource_get_info(pin_num)->sensor_h) {
124                 ret = peripheral_gpio_set_edge_mode(resource_get_info(pin_num)->sensor_h, PERIPHERAL_GPIO_EDGE_BOTH);
125                 goto_if(ret != PERIPHERAL_ERROR_NONE, FREE_RESOURCE);
126
127                 ret = peripheral_gpio_set_interrupted_cb(resource_get_info(pin_num)->sensor_h, __ioa_sensor_interrupt_cb, resource_get_info(pin_num)->resource_changed_info);
128                 goto_if(ret != PERIPHERAL_ERROR_NONE, FREE_RESOURCE);
129         }
130
131         return 0;
132
133 FREE_RESOURCE:
134         if (resource_get_info(pin_num)->resource_changed_info) {
135                 free(resource_get_info(pin_num)->resource_changed_info);
136                 resource_get_info(pin_num)->resource_changed_info = NULL;
137         }
138
139         if (resource_get_info(pin_num)->sensor_h) {
140                 peripheral_gpio_unset_interrupted_cb(resource_get_info(pin_num)->sensor_h);
141                 peripheral_gpio_close(resource_get_info(pin_num)->sensor_h);
142                 resource_get_info(pin_num)->sensor_h = NULL;
143                 resource_get_info(pin_num)->opened = 0;
144         }
145
146         return -1;
147 }