From 4468ad548522217e14c694900be0f60c5f26b5a7 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Tue, 22 Jun 2021 16:28:06 +0200 Subject: [PATCH] gpio: flatten structure - remove 'interface' Merge src/peripheral_gpio.c with src/interface/peripheral_interface_gpio.c, with additions from include/interface/peripheral_interface_gpio.h. Change-Id: I45f9eda5cf4ab47995db43bf934ab7176670b867 --- CMakeLists.txt | 1 - include/interface/peripheral_interface_gpio.h | 38 --- src/interface/peripheral_interface_gpio.c | 291 ------------------ src/peripheral_gpio.c | 256 ++++++++++++++- 4 files changed, 243 insertions(+), 343 deletions(-) delete mode 100644 include/interface/peripheral_interface_gpio.h delete mode 100644 src/interface/peripheral_interface_gpio.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 742b7b4..fbd65b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,7 +60,6 @@ SET(SOURCES src/peripheral_gpio.c src/peripheral_adc.c src/peripheral_uart.c src/peripheral_spi.c - src/interface/peripheral_interface_gpio.c src/interface/peripheral_interface_pwm.c src/gdbus/peripheral_gdbus_pwm.c src/gdbus/peripheral_io_gdbus.c) diff --git a/include/interface/peripheral_interface_gpio.h b/include/interface/peripheral_interface_gpio.h deleted file mode 100644 index bfc7b09..0000000 --- a/include/interface/peripheral_interface_gpio.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2016-2017 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. - */ - -#ifndef __PERIPHERAL_INTERFACE_GPIO_H__ -#define __PERIPHERAL_INTERFACE_GPIO_H__ - -#include "peripheral_interface_common.h" - -#define GPIO_BUFFER_MAX 64 - -void peripheral_interface_gpio_close(peripheral_gpio_h gpio); - -int peripheral_interface_gpio_set_initial_edge_into_handle(peripheral_gpio_h gpio); -int peripheral_interface_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e edge); - -int peripheral_interface_gpio_set_initial_direction_into_handle(peripheral_gpio_h gpio); -int peripheral_interface_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direction_e direction); - -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_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/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c deleted file mode 100644 index f4765f7..0000000 --- a/src/interface/peripheral_interface_gpio.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2016-2017 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 -#include -#include "peripheral_handle.h" -#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] = { - {"in", 2}, - {"out", 3}, - }; - - int index; - char gpio_buf[GPIO_BUFFER_MAX] = {0, }; - - int ret = read(gpio->fd_direction, &gpio_buf, GPIO_BUFFER_MAX); - CHECK_ERROR(ret <= 0); - - for (index = 0; index < 2; index++) { - if (!strncmp(gpio_buf, types[index].type, types[index].len)) { - // PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH and PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW : out type - gpio->direction = (peripheral_gpio_direction_e)index; - - /* - * Also write to direction for the very first time after boot - * to ensure that the pin is fully initialized. - * Without this, writing to 'edge' is not possible. - */ - ret = write(gpio->fd_direction, types[index].type, types[index].len); - CHECK_ERROR(ret != types[index].len); - - return PERIPHERAL_ERROR_NONE; - } - } - - return PERIPHERAL_ERROR_IO_ERROR; -} - -/* - * [edge_mode] [direction] - * - * none -----------------> in, out (O) - * - * rising, falling, both ---------> in (O) - * \ - * -----> out (X) - */ -int peripheral_interface_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direction_e direction) -{ - RETV_IF(gpio->direction == direction, PERIPHERAL_ERROR_NONE); - RETV_IF(gpio->edge != PERIPHERAL_GPIO_EDGE_NONE, PERIPHERAL_ERROR_IO_ERROR); - - static predefined_type_s types[3] = { - {"in", 2}, - {"high", 4}, - {"low", 3} - }; - - int ret = write(gpio->fd_direction, types[direction].type, types[direction].len); - CHECK_ERROR(ret != types[direction].len); - - gpio->direction = direction; - - return PERIPHERAL_ERROR_NONE; -} - -int peripheral_interface_gpio_set_initial_edge_into_handle(peripheral_gpio_h gpio) -{ - static predefined_type_s types[4] = { - {"none", 4}, - {"rising", 6}, - {"falling", 7}, - {"both", 4} - }; - - int index; - char gpio_buf[GPIO_BUFFER_MAX] = {0, }; - - int ret = read(gpio->fd_edge, &gpio_buf, GPIO_BUFFER_MAX); - CHECK_ERROR(ret <= 0); - - for (index = 0; index < 4; index++) { - if (!strncmp(gpio_buf, types[index].type, types[index].len)) { - gpio->edge = (peripheral_gpio_edge_e)index; - return PERIPHERAL_ERROR_NONE; - } - } - - return PERIPHERAL_ERROR_IO_ERROR; -} - -/* - * [direction] [edge_mode] - * - * in ---------> none, rising, falling, both (O) - * - * out --------> none (O) - * \ - * -----> rising, falling, both (X) - */ -int peripheral_interface_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e edge) -{ - RETV_IF(gpio->edge == edge, PERIPHERAL_ERROR_NONE); - RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR); - - static predefined_type_s types[4] = { - {"none", 4}, - {"rising", 6}, - {"falling", 7}, - {"both", 4} - }; - - int ret = write(gpio->fd_edge, types[edge].type, types[edge].len); - CHECK_ERROR(ret != types[edge].len); - - gpio->edge = edge; - - return PERIPHERAL_ERROR_NONE; -} - -/* - * [direction] [value] - * - * in ---------> write (X) - * out --------> write (O) - */ -int peripheral_interface_gpio_write(peripheral_gpio_h gpio, uint32_t value) -{ - RETV_IF(gpio->direction == PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR); - - static predefined_type_s types[2] = { - {"0", 1}, - {"1", 1} - }; - - int ret = write(gpio->fd_value, types[value].type, types[value].len); - CHECK_ERROR(ret != types[value].len); - - return PERIPHERAL_ERROR_NONE; -} - -/* - * [direction] [value] - * - * in ---------> read (O) - * out --------> read (O) - */ -int peripheral_interface_gpio_read(peripheral_gpio_h gpio, uint32_t *value) -{ - int ret; - int length = 1; - char gpio_buf[GPIO_BUFFER_MAX] = {0, }; - - ret = pread(gpio->fd_value, &gpio_buf, length, 0); - CHECK_ERROR(ret != length); - - if (gpio_buf[0] == '0') { - *value = 0; - } else if (gpio_buf[0] == '1') { - *value = 1; - } else { - _E("Error: gpio value is error \n"); - return PERIPHERAL_ERROR_IO_ERROR; - } - - return PERIPHERAL_ERROR_NONE; -} - -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); -} - -static gboolean __peripheral_interface_gpio_interrupted_cb_invoke(gpointer data) -{ - peripheral_gpio_h gpio = (peripheral_gpio_h)data; - gpio->cb_info.cb(gpio, gpio->cb_info.error, gpio->cb_info.user_data); - free(gpio); - gpio = NULL; - return FALSE; -} - -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 (g_atomic_int_get(&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; - gpio->cb_info.value = value; - - // copy structure for callback to prevent race condition - // otherwise e.g. gpio pin value could be changed during callback call - peripheral_gpio_h gpio_copy = (peripheral_gpio_h)calloc(1, sizeof(struct _peripheral_gpio_s)); - if (gpio_copy == NULL) { - _E("memory allocation for callback failed."); - continue; - } - memcpy(gpio_copy, gpio, sizeof(struct _peripheral_gpio_s)); - g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_interface_gpio_interrupted_cb_invoke, gpio_copy, NULL); - } - - return NULL; -} - -int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_interrupted_cb callback, void *user_data) -{ - 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; - g_atomic_int_set(&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) -{ - g_atomic_int_set(&gpio->cb_info.status, GPIO_INTERRUPTED_CALLBACK_UNSET); - - if (gpio->cb_info.thread != NULL) { - g_thread_join(gpio->cb_info.thread); - gpio->cb_info.thread = NULL; - } - - return PERIPHERAL_ERROR_NONE; -} diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index fe6fc9d..86da489 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -21,8 +21,7 @@ #include #include "peripheral_io.h" -#include "peripheral_handle.h" -#include "peripheral_interface_gpio.h" +#include "peripheral_interface_common.h" #include "peripheral_log.h" #define PERIPHERAL_IO_GPIO_FEATURE "http://tizen.org/feature/peripheral_io.gpio" @@ -33,6 +32,11 @@ #define GPIO_STRUCTURE_VERMAGIC 13712 #define GPIO_CALLBACK_STRUCTURE_VERMAGIC 14469 +#define GPIO_INTERRUPTED_CALLBACK_UNSET 0 +#define GPIO_INTERRUPTED_CALLBACK_SET 1 + +#define GPIO_BUFFER_MAX 64 + static int gpio_feature = GPIO_FEATURE_UNKNOWN; static bool __is_feature_supported(void) @@ -257,6 +261,64 @@ static inline void cleanup_handlep(peripheral_gpio_h *handle) { cleanup_handle(*handle); } +static int peripheral_gpio_set_initial_direction_into_handle(peripheral_gpio_h gpio) +{ + static predefined_type_s types[2] = { + {"in", 2}, + {"out", 3}, + }; + + int index; + char gpio_buf[GPIO_BUFFER_MAX] = {0, }; + + int ret = read(gpio->fd_direction, &gpio_buf, GPIO_BUFFER_MAX); + CHECK_ERROR(ret <= 0); + + for (index = 0; index < 2; index++) { + if (!strncmp(gpio_buf, types[index].type, types[index].len)) { + // PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH and PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW : out type + gpio->direction = (peripheral_gpio_direction_e)index; + + /* + * Also write to direction for the very first time after boot + * to ensure that the pin is fully initialized. + * Without this, writing to 'edge' is not possible. + */ + ret = write(gpio->fd_direction, types[index].type, types[index].len); + CHECK_ERROR(ret != types[index].len); + + return PERIPHERAL_ERROR_NONE; + } + } + + return PERIPHERAL_ERROR_IO_ERROR; +} + +static int peripheral_gpio_set_initial_edge_into_handle(peripheral_gpio_h gpio) +{ + static predefined_type_s types[4] = { + {"none", 4}, + {"rising", 6}, + {"falling", 7}, + {"both", 4} + }; + + int index; + char gpio_buf[GPIO_BUFFER_MAX] = {0, }; + + int ret = read(gpio->fd_edge, &gpio_buf, GPIO_BUFFER_MAX); + CHECK_ERROR(ret <= 0); + + for (index = 0; index < 4; index++) { + if (!strncmp(gpio_buf, types[index].type, types[index].len)) { + gpio->edge = (peripheral_gpio_edge_e)index; + return PERIPHERAL_ERROR_NONE; + } + } + + return PERIPHERAL_ERROR_IO_ERROR; +} + /** * @brief Initializes(export) gpio pin and creates gpio handle. */ @@ -323,15 +385,15 @@ int peripheral_gpio_open(int gpio_pin, peripheral_gpio_h *gpio) lock = peripheral_gpio_unlock_export(lock); - ret = peripheral_interface_gpio_set_initial_direction_into_handle(handle); + ret = peripheral_gpio_set_initial_direction_into_handle(handle); if (ret != PERIPHERAL_ERROR_NONE) { - _E("Failed to peripheral_interface_gpio_set_initial_direction_into_handle()"); + _E("Failed to peripheral_gpio_set_initial_direction_into_handle()"); return ret; } - ret = peripheral_interface_gpio_set_initial_edge_into_handle(handle); + ret = peripheral_gpio_set_initial_edge_into_handle(handle); if (ret != PERIPHERAL_ERROR_NONE) { - _E("Failed to peripheral_interface_gpio_set_initial_edge_into_handle()"); + _E("Failed to peripheral_gpio_set_initial_edge_into_handle()"); return ret; } @@ -351,7 +413,7 @@ int peripheral_gpio_close(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"); - peripheral_interface_gpio_unset_interrupted_cb(gpio); + peripheral_gpio_unset_interrupted_cb(gpio); cleanup_handlep(&gpio); @@ -367,7 +429,30 @@ int peripheral_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direct RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL"); RETVM_IF((direction < PERIPHERAL_GPIO_DIRECTION_IN) || (direction > PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW), PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid direction input"); - return peripheral_interface_gpio_set_direction(gpio, direction); + /* + * [edge_mode] [direction] + * + * none -----------------> in, out (O) + * + * rising, falling, both ---------> in (O) + * \ + * -----> out (X) + */ + RETV_IF(gpio->direction == direction, PERIPHERAL_ERROR_NONE); + RETV_IF(gpio->edge != PERIPHERAL_GPIO_EDGE_NONE, PERIPHERAL_ERROR_IO_ERROR); + + static predefined_type_s types[3] = { + {"in", 2}, + {"high", 4}, + {"low", 3} + }; + + int ret = write(gpio->fd_direction, types[direction].type, types[direction].len); + CHECK_ERROR(ret != types[direction].len); + + gpio->direction = direction; + + return PERIPHERAL_ERROR_NONE; } /** @@ -379,7 +464,101 @@ int peripheral_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL"); RETVM_IF((edge < PERIPHERAL_GPIO_EDGE_NONE) || (edge > PERIPHERAL_GPIO_EDGE_BOTH), PERIPHERAL_ERROR_INVALID_PARAMETER, "edge input is invalid"); - return peripheral_interface_gpio_set_edge_mode(gpio, edge); + /* + * [direction] [edge_mode] + * + * in ---------> none, rising, falling, both (O) + * + * out --------> none (O) + * \ + * -----> rising, falling, both (X) + */ + RETV_IF(gpio->edge == edge, PERIPHERAL_ERROR_NONE); + RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR); + + static predefined_type_s types[4] = { + {"none", 4}, + {"rising", 6}, + {"falling", 7}, + {"both", 4} + }; + + int ret = write(gpio->fd_edge, types[edge].type, types[edge].len); + CHECK_ERROR(ret != types[edge].len); + + gpio->edge = edge; + + return PERIPHERAL_ERROR_NONE; +} + +static gboolean __peripheral_gpio_interrupted_cb_invoke(gpointer data) +{ + peripheral_gpio_h gpio = (peripheral_gpio_h)data; + gpio->cb_info.cb(gpio, gpio->cb_info.error, gpio->cb_info.user_data); + free(gpio); + gpio = NULL; + return FALSE; +} + +static gpointer __peripheral_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 (g_atomic_int_get(&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_gpio_interrupted_cb_invoke, gpio, NULL); + break; + } + + if (poll_fd.revents & POLLPRI) { + ret = peripheral_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; + gpio->cb_info.value = value; + + // copy structure for callback to prevent race condition + // otherwise e.g. gpio pin value could be changed during callback call + peripheral_gpio_h gpio_copy = (peripheral_gpio_h)calloc(1, sizeof(struct _peripheral_gpio_s)); + if (gpio_copy == NULL) { + _E("memory allocation for callback failed."); + continue; + } + memcpy(gpio_copy, gpio, sizeof(struct _peripheral_gpio_s)); + g_idle_add_full(G_PRIORITY_HIGH_IDLE, __peripheral_gpio_interrupted_cb_invoke, gpio_copy, NULL); + } + + return NULL; } /** @@ -390,8 +569,16 @@ int peripheral_gpio_set_interrupted_cb(peripheral_gpio_h gpio, peripheral_gpio_i 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"); RETVM_IF(callback == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio interrupted callback is NULL"); + RETV_IF(gpio->direction != PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR); - return peripheral_interface_gpio_set_interrupted_cb(gpio, callback, user_data); + peripheral_gpio_unset_interrupted_cb(gpio); + + gpio->cb_info.cb = callback; + gpio->cb_info.user_data = user_data; + g_atomic_int_set(&gpio->cb_info.status, GPIO_INTERRUPTED_CALLBACK_SET); + gpio->cb_info.thread = g_thread_new(NULL, __peripheral_gpio_poll, gpio); + + return PERIPHERAL_ERROR_NONE; } /** @@ -402,7 +589,14 @@ 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"); - return peripheral_interface_gpio_unset_interrupted_cb(gpio); + g_atomic_int_set(&gpio->cb_info.status, GPIO_INTERRUPTED_CALLBACK_UNSET); + + if (gpio->cb_info.thread != NULL) { + g_thread_join(gpio->cb_info.thread); + gpio->cb_info.thread = NULL; + } + + return PERIPHERAL_ERROR_NONE; } /** @@ -413,8 +607,29 @@ int peripheral_gpio_read(peripheral_gpio_h gpio, uint32_t *value) 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"); RETVM_IF(value == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio read value is invalid"); + /* + * [direction] [value] + * + * in ---------> read (O) + * out --------> read (O) + */ + int ret; + int length = 1; + char gpio_buf[GPIO_BUFFER_MAX] = {0, }; + + ret = pread(gpio->fd_value, &gpio_buf, length, 0); + CHECK_ERROR(ret != length); - return peripheral_interface_gpio_read(gpio, value); + if (gpio_buf[0] == '0') { + *value = 0; + } else if (gpio_buf[0] == '1') { + *value = 1; + } else { + _E("Error: gpio value is error \n"); + return PERIPHERAL_ERROR_IO_ERROR; + } + + return PERIPHERAL_ERROR_NONE; } /** @@ -425,6 +640,21 @@ int peripheral_gpio_write(peripheral_gpio_h gpio, uint32_t value) 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"); RETVM_IF((value != 0) && (value != 1), PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio value is invalid"); + /* + * [direction] [value] + * + * in ---------> write (X) + * out --------> write (O) + */ + RETV_IF(gpio->direction == PERIPHERAL_GPIO_DIRECTION_IN, PERIPHERAL_ERROR_IO_ERROR); + + static predefined_type_s types[2] = { + {"0", 1}, + {"1", 1} + }; - return peripheral_interface_gpio_write(gpio, value); + int ret = write(gpio->fd_value, types[value].type, types[value].len); + CHECK_ERROR(ret != types[value].len); + + return PERIPHERAL_ERROR_NONE; } -- 2.34.1