From: Segwon Date: Mon, 18 Dec 2017 02:42:48 +0000 (+0900) Subject: gpio: add interrupted callback X-Git-Tag: submit/tizen_4.0/20171220.125806^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc484e6c4e3e105d23079bf7f29a274214a60ca1;p=platform%2Fcore%2Fapi%2Fperipheral-io.git gpio: add interrupted callback Change-Id: I6d8d2b3e6382e3ecc2ebbc7cee8747fc2290fae9 Signed-off-by: Segwon --- diff --git a/include/interface/peripheral_interface_gpio.h b/include/interface/peripheral_interface_gpio.h index d4ca75d..bfc7b09 100644 --- a/include/interface/peripheral_interface_gpio.h +++ b/include/interface/peripheral_interface_gpio.h @@ -32,7 +32,7 @@ int peripheral_interface_gpio_set_direction(peripheral_gpio_h gpio, peripheral_g int peripheral_interface_gpio_write(peripheral_gpio_h gpio, uint32_t value); int peripheral_interface_gpio_read(peripheral_gpio_h gpio, uint32_t *value); -int peripheral_interface_gpio_open_isr(peripheral_gpio_h gpio); -int peripheral_interface_gpio_close_isr(peripheral_gpio_h gpio); +int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_interrupted_cb callback, void *user_data); +int peripheral_interface_gpio_unset_interrupted_cb(peripheral_gpio_h gpio); #endif/*__PERIPHERAL_INTERFACE_GPIO_H__*/ \ No newline at end of file diff --git a/include/peripheral_handle.h b/include/peripheral_handle.h index b834d06..e07c4f1 100644 --- a/include/peripheral_handle.h +++ b/include/peripheral_handle.h @@ -17,6 +17,16 @@ #ifndef __PERIPHERAL_HANDLE_H__ #define __PERIPHERAL_HANDLE_H__ +#include + +typedef struct _peripheral_gpio_interrupted_cb_info_s { + GThread *thread; + peripheral_gpio_interrupted_cb cb; + peripheral_error_e error; + void *user_data; + int status; +} interrupted_cb_info_s; + /** * @brief Internal struct for gpio context */ @@ -27,6 +37,7 @@ struct _peripheral_gpio_s { int fd_value; peripheral_gpio_direction_e direction; peripheral_gpio_edge_e edge; + interrupted_cb_info_s cb_info; }; /** diff --git a/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c index 119230d..c8dd33b 100644 --- a/src/interface/peripheral_interface_gpio.c +++ b/src/interface/peripheral_interface_gpio.c @@ -14,8 +14,12 @@ * limitations under the License. */ +#include #include "peripheral_interface_gpio.h" +#define GPIO_INTERRUPTED_CALLBACK_UNSET 0 +#define GPIO_INTERRUPTED_CALLBACK_SET 1 + int peripheral_interface_gpio_set_initial_direction_into_handle(peripheral_gpio_h gpio) { static predefined_type_s types[2] = { @@ -155,6 +159,7 @@ int peripheral_interface_gpio_read(peripheral_gpio_h gpio, uint32_t *value) int length = 1; char gpio_buf[GPIO_BUFFER_MAX] = {0, }; + lseek(gpio->fd_value, 0, SEEK_SET); ret = read(gpio->fd_value, &gpio_buf, length); CHECK_ERROR(ret != length); @@ -172,21 +177,89 @@ int peripheral_interface_gpio_read(peripheral_gpio_h gpio, uint32_t *value) void peripheral_interface_gpio_close(peripheral_gpio_h gpio) { + peripheral_interface_gpio_unset_interrupted_cb(gpio); + close(gpio->fd_direction); close(gpio->fd_edge); close(gpio->fd_value); } -int peripheral_interface_gpio_open_isr(peripheral_gpio_h gpio) +static gboolean __peripheral_interface_gpio_interrupted_cb_invoke(gpointer data) { - // TODO: set interrupted callback function + peripheral_gpio_h gpio = (peripheral_gpio_h)data; + gpio->cb_info.cb(gpio, gpio->cb_info.error, NULL); + return FALSE; +} - return PERIPHERAL_ERROR_NONE; +static gpointer __peripheral_interface_gpio_poll(void *data) +{ + peripheral_gpio_h gpio = (peripheral_gpio_h)data; + + int ret; + int poll_state = 0; + struct pollfd poll_fd; + + poll_fd.fd = gpio->fd_value; + poll_fd.events = POLLPRI; + + uint32_t value; + + while (gpio->cb_info.status == GPIO_INTERRUPTED_CALLBACK_SET) { + + poll_state = poll(&poll_fd, 1, 3000); + + if (poll_state == 0) + continue; + + if (poll_state < 0) { + _E("poll failed!"); + gpio->cb_info.error = PERIPHERAL_ERROR_IO_ERROR; + g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_interface_gpio_interrupted_cb_invoke, gpio, NULL); + break; + } + + if (poll_fd.revents & POLLPRI) { + ret = peripheral_interface_gpio_read(gpio, &value); + if (ret != PERIPHERAL_ERROR_NONE) + continue; + } else { + continue; + } + + if (gpio->edge == PERIPHERAL_GPIO_EDGE_NONE) + continue; + + if (gpio->edge == PERIPHERAL_GPIO_EDGE_RISING && value == 0) + continue; + + if (gpio->edge == PERIPHERAL_GPIO_EDGE_FALLING && value == 1) + continue; + + gpio->cb_info.error = PERIPHERAL_ERROR_NONE; + g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_interface_gpio_interrupted_cb_invoke, gpio, NULL); + } + + return NULL; } -int peripheral_interface_gpio_close_isr(peripheral_gpio_h gpio) +int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_interrupted_cb callback, void *user_data) { - // TODO: unset interrupted callback function + RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR); + + peripheral_interface_gpio_unset_interrupted_cb(gpio); + + gpio->cb_info.cb = callback; + gpio->cb_info.user_data = user_data; + gpio->cb_info.status = GPIO_INTERRUPTED_CALLBACK_SET; + gpio->cb_info.thread = g_thread_new(NULL, __peripheral_interface_gpio_poll, gpio); return PERIPHERAL_ERROR_NONE; } + +int peripheral_interface_gpio_unset_interrupted_cb(peripheral_gpio_h gpio) +{ + gpio->cb_info.status = GPIO_INTERRUPTED_CALLBACK_UNSET; + g_thread_join(gpio->cb_info.thread); + + return PERIPHERAL_ERROR_NONE; +} \ No newline at end of file diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index 4cd0290..b51c577 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -151,7 +151,7 @@ int peripheral_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_i RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL"); RETVM_IF(callback == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio interrupted callback is NULL"); - // TODO : replace interface function + peripheral_interface_gpio_set_interrupted_cb(gpio, callback, user_data); return ret; } @@ -166,7 +166,7 @@ int peripheral_gpio_unset_interrupted_cb(peripheral_gpio_h gpio) RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "GPIO feature is not supported"); RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL"); - // TODO : replace interface function + peripheral_interface_gpio_unset_interrupted_cb(gpio); return ret; }