diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/controller.c | 122 | ||||
-rwxr-xr-x | src/resource/resource_infrared_motion.c | 195 | ||||
-rwxr-xr-x | src/resource/resource_led.c | 101 |
3 files changed, 418 insertions, 0 deletions
diff --git a/src/controller.c b/src/controller.c new file mode 100755 index 0000000..6595ea2 --- /dev/null +++ b/src/controller.c @@ -0,0 +1,122 @@ +/* + * 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 <tizen.h> +#include <service_app.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <Ecore.h> + +#include "log.h" +#include "resource/resource_infrared_motion.h" +#include "resource/resource_led.h" + +// Timer duration +#define TIMER_GATHER_INTERVAL (2.0f) + +// Motion sensor information +#define SENSOR_MOTION_GPIO_NUMBER (18) + +// LED sensor information +#define SENSOR_LED_GPIO_NUMBER (24) + +Ecore_Timer *getter_timer = NULL; + +static int _change_led_state(int state) { + int ret = 0; + + // Write state to LED light + ret = resource_write_led(SENSOR_LED_GPIO_NUMBER, state); + if (ret != 0) { + _E("cannot write led data"); + return -1; + } + + _I("LED State : %s", state ? "ON":"OFF"); + + return 0; +} + +static Eina_Bool _get_motion_set_led(void *user_data) +{ + int ret = 0; + uint32_t value = 0; + + // Get value from motion sensor + ret = resource_read_infrared_motion(SENSOR_MOTION_GPIO_NUMBER, &value); + if (ret != 0) { + _E("cannot read data from the infrared motion sensor"); + return ECORE_CALLBACK_CANCEL; + } + + _I("Detected motion value : %u", value); + + // Set LED light with value + _change_led_state(value); + + return ECORE_CALLBACK_RENEW; +} + +static bool service_app_create(void *user_data) +{ + return true; +} + +static void service_app_control(app_control_h app_control, void *user_data) +{ + // Delete old timer if there is one + if (getter_timer) { + ecore_timer_del(getter_timer); + getter_timer = NULL; + } + + // Create a timer to call the given function in given period of time + getter_timer = ecore_timer_add(TIMER_GATHER_INTERVAL, _get_motion_set_led, user_data); + if (!getter_timer) { + _E("Failed to add getter timer"); + return; + } +} + +static void service_app_terminate(void *user_data) +{ + // Delete timer + if (getter_timer) { + ecore_timer_del(getter_timer); + getter_timer = NULL; + } + + // Turn off LED light with __set_led() + _change_led_state(0); + + // Close Motion and LED resources + resource_close_infrared_motion(); + resource_close_led(); + + FN_END; +} + +int main(int argc, char *argv[]) +{ + service_app_lifecycle_callback_s event_callback; + + event_callback.create = service_app_create; + event_callback.terminate = service_app_terminate; + event_callback.app_control = service_app_control; + + return service_app_main(argc, argv, &event_callback, NULL); +} diff --git a/src/resource/resource_infrared_motion.c b/src/resource/resource_infrared_motion.c new file mode 100755 index 0000000..9263143 --- /dev/null +++ b/src/resource/resource_infrared_motion.c @@ -0,0 +1,195 @@ +/* + * 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 <peripheral_io.h> +#include "resource/resource_infrared_motion.h" +#include "log.h" + +enum { + MOTION_HANDLE_ERROR_NONE = 0, /**< Successful */ + MOTION_HANDLE_ERROR_NOT_OPEN, + MOTION_HANDLE_ERROR_INVALID_PIN +} motion_handle_error_e; + +struct resource_im_interrupted_data { + resource_infrared_motion_interrupted_cb interrupted_cb; + void *interrupted_cb_user_data; + uint32_t motion_value; +}; + +static peripheral_gpio_h g_sensor_h = NULL; +static int g_pin_num = -1; +static struct resource_im_interrupted_data g_interrupted_data; + +static int _resource_validate_infrared_motion(int pin_num) +{ + int ret = MOTION_HANDLE_ERROR_NONE; + + if (!g_sensor_h) + { + ret = MOTION_HANDLE_ERROR_NOT_OPEN; + } else if (g_pin_num != pin_num) { + ret = MOTION_HANDLE_ERROR_INVALID_PIN; + } + + return ret; +} + +static int resource_open_infrared_motion(int pin_num) +{ + int ret = PERIPHERAL_ERROR_NONE; + peripheral_gpio_h temp = NULL; + + ret = peripheral_gpio_open(pin_num, &temp); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("peripheral_gpio_open failed."); + return -1; + } + + // It should be removed after peripheral-io is patched. + peripheral_gpio_set_direction(temp, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW); + if (ret) { + peripheral_gpio_close(temp); + _E("peripheral_gpio_set_direction failed."); + return -1; + } + + ret = peripheral_gpio_set_direction(temp, PERIPHERAL_GPIO_DIRECTION_IN); + if (ret != PERIPHERAL_ERROR_NONE) { + peripheral_gpio_close(temp); + _E("peripheral_gpio_set_direction failed."); + return -1; + } + + g_sensor_h = temp; + g_pin_num = pin_num; + + return 0; +} + +int resource_read_infrared_motion(int pin_num, uint32_t *out_value) +{ + int ret = PERIPHERAL_ERROR_NONE; + int ret_valid = MOTION_HANDLE_ERROR_NONE; + + ret_valid = _resource_validate_infrared_motion(pin_num); + if (ret_valid != MOTION_HANDLE_ERROR_NONE) { + if (ret_valid == MOTION_HANDLE_ERROR_NOT_OPEN) { + ret = resource_open_infrared_motion(pin_num); + retv_if(ret != PERIPHERAL_ERROR_NONE, -1); + } else if (ret_valid == MOTION_HANDLE_ERROR_INVALID_PIN) { + _E("Invalid pin number."); + return -1; + } + } + + ret = peripheral_gpio_read(g_sensor_h, out_value); + retv_if(ret != PERIPHERAL_ERROR_NONE, -1); + + return 0; +} + +void resource_close_infrared_motion(void) +{ + if (!g_sensor_h) return; + + _I("Infrared Motion Sensor is finishing..."); + + if (g_interrupted_data.interrupted_cb) { + peripheral_gpio_unset_interrupted_cb(g_sensor_h); + g_interrupted_data.interrupted_cb = NULL; + g_interrupted_data.interrupted_cb_user_data = NULL; + g_interrupted_data.motion_value = 0; + } + + peripheral_gpio_close(g_sensor_h); + + g_sensor_h = NULL; + g_pin_num = -1; +} + +void _resoucre_motion_interrupted_cb (peripheral_gpio_h gpio, peripheral_error_e error, void *user_data) +{ + if (!g_sensor_h) return; + + g_interrupted_data.motion_value = !g_interrupted_data.motion_value; + + g_interrupted_data.interrupted_cb(g_interrupted_data.motion_value, g_interrupted_data.interrupted_cb_user_data); +} + +int resource_set_interrupted_cb_infrared_motion(int pin_num, resource_infrared_motion_interrupted_cb interrupted_cb, void *user_data) +{ + int ret = PERIPHERAL_ERROR_NONE; + int ret_valid = MOTION_HANDLE_ERROR_NONE; + + retv_if(!interrupted_cb, -1); + + ret_valid = _resource_validate_infrared_motion(pin_num); + if (ret_valid == MOTION_HANDLE_ERROR_NOT_OPEN) { + ret = resource_open_infrared_motion(pin_num); + retv_if(ret != PERIPHERAL_ERROR_NONE, -1); + } else if (ret_valid == MOTION_HANDLE_ERROR_INVALID_PIN) { + _E("Invalid pin number."); + return -1; + } + + ret = peripheral_gpio_set_edge_mode(g_sensor_h, PERIPHERAL_GPIO_EDGE_BOTH); + retv_if(ret != PERIPHERAL_ERROR_NONE, -1); + + g_interrupted_data.motion_value = 0; + ret = peripheral_gpio_read(g_sensor_h, &g_interrupted_data.motion_value); + retv_if(ret != PERIPHERAL_ERROR_NONE, -1); + + ret = peripheral_gpio_set_interrupted_cb(g_sensor_h, _resoucre_motion_interrupted_cb, &g_interrupted_data); + goto_if(ret != PERIPHERAL_ERROR_NONE, ERROR); + + g_interrupted_data.interrupted_cb = interrupted_cb; + g_interrupted_data.interrupted_cb_user_data = user_data; + + return 0; + +ERROR: + _E("failed to read gpio"); + peripheral_gpio_unset_interrupted_cb(g_sensor_h); + g_interrupted_data.interrupted_cb = NULL; + g_interrupted_data.interrupted_cb_user_data = NULL; + g_interrupted_data.motion_value = 0; + return -1; +} + +int resource_unset_interrupted_cb_infrared_motion(int pin_num) +{ + int ret = PERIPHERAL_ERROR_NONE; + int ret_valid = MOTION_HANDLE_ERROR_NONE; + + ret_valid = _resource_validate_infrared_motion(pin_num); + if (ret_valid == MOTION_HANDLE_ERROR_NOT_OPEN) { + _E("No open handle."); + return -1; + } else if (ret_valid == MOTION_HANDLE_ERROR_INVALID_PIN) { + _E("Invalid pin number."); + return -1; + } + + ret = peripheral_gpio_unset_interrupted_cb(g_sensor_h); + retv_if(ret != PERIPHERAL_ERROR_NONE, -1); + + g_interrupted_data.interrupted_cb = NULL; + g_interrupted_data.interrupted_cb_user_data = NULL; + g_interrupted_data.motion_value = 0; + + return 0; +} diff --git a/src/resource/resource_led.c b/src/resource/resource_led.c new file mode 100755 index 0000000..a6edd7c --- /dev/null +++ b/src/resource/resource_led.c @@ -0,0 +1,101 @@ +/* + * 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 <peripheral_io.h> +#include "resource/resource_led.h" +#include "log.h" + +typedef enum { + LED_HANDLE_ERROR_NONE = 0, /**< Successful */ + LED_HANDLE_ERROR_NOT_OPEN, + LED_HANDLE_ERROR_INVALID_PIN +} led_handle_error_e; + +static peripheral_gpio_h g_sensor_h = NULL; +static int g_pin_num = -1; + +int _resource_validate_led(int pin_num) +{ + int ret = LED_HANDLE_ERROR_NONE; + + if (!g_sensor_h) + { + ret = LED_HANDLE_ERROR_NOT_OPEN; + } else if (g_pin_num != pin_num) { + ret = LED_HANDLE_ERROR_INVALID_PIN; + } + + return ret; +} + +int resource_open_led(int pin_num) +{ + int ret = PERIPHERAL_ERROR_NONE; + peripheral_gpio_h temp = NULL; + + ret = peripheral_gpio_open(pin_num, &temp); + if (ret != PERIPHERAL_ERROR_NONE) { + peripheral_gpio_close(temp); + _E("peripheral_gpio_open failed."); + return -1; + } + + ret = peripheral_gpio_set_direction(temp, PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW); + if (ret != PERIPHERAL_ERROR_NONE) { + peripheral_gpio_close(temp); + _E("peripheral_gpio_set_direction failed."); + return -1; + } + + g_sensor_h = temp; + g_pin_num = pin_num; + + return 0; +} + +void resource_close_led(void) +{ + if (!g_sensor_h) return; + + _I("LED is finishing..."); + + peripheral_gpio_close(g_sensor_h); + + g_sensor_h = NULL; + g_pin_num = -1; +} + +int resource_write_led(int pin_num, int write_value) +{ + int ret = PERIPHERAL_ERROR_NONE; + int ret_valid = LED_HANDLE_ERROR_NONE; + + ret_valid = _resource_validate_led(pin_num); + if (ret_valid != LED_HANDLE_ERROR_NONE) { + if (ret_valid == LED_HANDLE_ERROR_NOT_OPEN) { + ret = resource_open_led(pin_num); + retv_if(ret != PERIPHERAL_ERROR_NONE, -1); + } else if (ret_valid == LED_HANDLE_ERROR_INVALID_PIN) { + _E("Invalid pin number."); + return -1; + } + } + + ret = peripheral_gpio_write(g_sensor_h, write_value); + retv_if(ret < 0, -1); + + return 0; +} |