From 7ebfdd07f7b499051d979465e862d15af36d877f Mon Sep 17 00:00:00 2001 From: Segwon Date: Mon, 4 Dec 2017 15:56:09 +0900 Subject: [PATCH 01/16] test: fix to wrong number of i2c bus Change-Id: Ifcd09204d585070d303eff86e73738772fbf2ab2 Signed-off-by: Segwon --- test/src/test_peripheral_i2c.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/src/test_peripheral_i2c.c b/test/src/test_peripheral_i2c.c index bb1de7f..58f1ae0 100644 --- a/test/src/test_peripheral_i2c.c +++ b/test/src/test_peripheral_i2c.c @@ -19,7 +19,8 @@ #include #include "test_peripheral_i2c.h" -#define I2C_BUS 4 +#define I2C_BUS_RPI3 4 +#define I2C_BUS_ARTIK530 11 #define I2C_BUS_INVALID -99 #define I2C_ADDRESS 0x39 #define I2C_ADDRESS_INVALID -99 @@ -35,8 +36,10 @@ int test_peripheral_io_i2c_initialize(char *model, bool feature) { g_feature = feature; - if ((!strcmp(model, "rpi3")) || (!strcmp(model, "artik"))) - bus = I2C_BUS; + if (!strcmp(model, "rpi3")) + bus = I2C_BUS_RPI3; + else if (!strcmp(model, "artik")) + bus = I2C_BUS_ARTIK530; else return PERIPHERAL_ERROR_NO_DEVICE; -- 2.34.1 From 2fbe04726be903fc76e2d4ff68ccf47200058be5 Mon Sep 17 00:00:00 2001 From: Segwon Date: Fri, 8 Dec 2017 14:57:20 +0900 Subject: [PATCH 02/16] gdbus: communicate via gdbus when close Change-Id: Ieae106a611e8409c50996b68c08fcdbd3506d70b Signed-off-by: Segwon --- include/gdbus/peripheral_gdbus_gpio.h | 2 +- include/gdbus/peripheral_gdbus_i2c.h | 2 +- include/gdbus/peripheral_gdbus_pwm.h | 2 +- include/gdbus/peripheral_gdbus_spi.h | 2 +- include/gdbus/peripheral_gdbus_uart.h | 2 +- src/gdbus/peripheral_gdbus_gpio.c | 26 ++++++++++++++++++++------ src/gdbus/peripheral_gdbus_i2c.c | 26 ++++++++++++++++++++------ src/gdbus/peripheral_gdbus_pwm.c | 26 ++++++++++++++++++++------ src/gdbus/peripheral_gdbus_spi.c | 26 ++++++++++++++++++++------ src/gdbus/peripheral_gdbus_uart.c | 26 ++++++++++++++++++++------ src/gdbus/peripheral_io.xml | 20 ++++++++++++++++++++ src/peripheral_gpio.c | 2 +- src/peripheral_i2c.c | 2 +- src/peripheral_pwm.c | 2 +- src/peripheral_spi.c | 2 +- src/peripheral_uart.c | 2 +- 16 files changed, 130 insertions(+), 40 deletions(-) diff --git a/include/gdbus/peripheral_gdbus_gpio.h b/include/gdbus/peripheral_gdbus_gpio.h index edef2ea..7ccc4a3 100644 --- a/include/gdbus/peripheral_gdbus_gpio.h +++ b/include/gdbus/peripheral_gdbus_gpio.h @@ -20,6 +20,6 @@ #include "peripheral_gdbus_common.h" int peripheral_gdbus_gpio_open(peripheral_gpio_h gpio, int pin); -int peripheral_gdbus_gpio_close(void); +int peripheral_gdbus_gpio_close(peripheral_gpio_h gpio); #endif /* __PERIPHERAL_GDBUS_GPIO_H__ */ diff --git a/include/gdbus/peripheral_gdbus_i2c.h b/include/gdbus/peripheral_gdbus_i2c.h index 099da4e..e1b1722 100644 --- a/include/gdbus/peripheral_gdbus_i2c.h +++ b/include/gdbus/peripheral_gdbus_i2c.h @@ -20,6 +20,6 @@ #include "peripheral_gdbus_common.h" int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address); -int peripheral_gdbus_i2c_close(void); +int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c); #endif /* __PERIPHERAL_GDBUS_I2C_H__ */ diff --git a/include/gdbus/peripheral_gdbus_pwm.h b/include/gdbus/peripheral_gdbus_pwm.h index e5c26c8..70a4b02 100644 --- a/include/gdbus/peripheral_gdbus_pwm.h +++ b/include/gdbus/peripheral_gdbus_pwm.h @@ -20,6 +20,6 @@ #include "peripheral_gdbus_common.h" int peripheral_gdbus_pwm_open(peripheral_pwm_h pwm, int chip, int pin); -int peripheral_gdbus_pwm_close(void); +int peripheral_gdbus_pwm_close(peripheral_pwm_h pwm); #endif /* __PERIPHERAL_GDBUS_PWM_H__ */ diff --git a/include/gdbus/peripheral_gdbus_spi.h b/include/gdbus/peripheral_gdbus_spi.h index a828c10..94b2242 100644 --- a/include/gdbus/peripheral_gdbus_spi.h +++ b/include/gdbus/peripheral_gdbus_spi.h @@ -20,6 +20,6 @@ #include "peripheral_gdbus_common.h" int peripheral_gdbus_spi_open(peripheral_spi_h spi, int bus, int cs); -int peripheral_gdbus_spi_close(void); +int peripheral_gdbus_spi_close(peripheral_spi_h spi); #endif /* __PERIPHERAL_GDBUS_SPI_H_ */ diff --git a/include/gdbus/peripheral_gdbus_uart.h b/include/gdbus/peripheral_gdbus_uart.h index fc58ee8..bf7af68 100644 --- a/include/gdbus/peripheral_gdbus_uart.h +++ b/include/gdbus/peripheral_gdbus_uart.h @@ -20,6 +20,6 @@ #include "peripheral_gdbus_common.h" int peripheral_gdbus_uart_open(peripheral_uart_h uart, int port); -int peripheral_gdbus_uart_close(void); +int peripheral_gdbus_uart_close(peripheral_uart_h uart); #endif /* __PERIPHERAL_GDBUS_UART_H_ */ diff --git a/src/gdbus/peripheral_gdbus_gpio.c b/src/gdbus/peripheral_gdbus_gpio.c index 5400429..dcc9ff2 100644 --- a/src/gdbus/peripheral_gdbus_gpio.c +++ b/src/gdbus/peripheral_gdbus_gpio.c @@ -51,10 +51,7 @@ static int __gpio_proxy_init(void) static int __gpio_proxy_deinit(void) { - if (gpio_proxy == NULL) { - _E("Gpio proxy is NULL"); - return PERIPHERAL_ERROR_IO_ERROR; - } + RETVM_IF(gpio_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Gpio proxy is NULL"); g_object_unref(gpio_proxy); if (!G_IS_OBJECT(gpio_proxy)) @@ -117,8 +114,25 @@ int peripheral_gdbus_gpio_open(peripheral_gpio_h gpio, int pin) return ret; } -int peripheral_gdbus_gpio_close(void) +int peripheral_gdbus_gpio_close(peripheral_gpio_h gpio) { - int ret = __gpio_proxy_deinit(); + RETVM_IF(gpio_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Gpio proxy is NULL"); + + int ret; + GError *error = NULL; + + if (peripheral_io_gdbus_gpio_call_close_sync( + gpio_proxy, + gpio->handle, + &ret, + NULL, + &error) == FALSE) { + _E("Failed to request daemon to gpio close : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + __gpio_proxy_deinit(); + return ret; } \ No newline at end of file diff --git a/src/gdbus/peripheral_gdbus_i2c.c b/src/gdbus/peripheral_gdbus_i2c.c index e85f21b..c2fb06f 100644 --- a/src/gdbus/peripheral_gdbus_i2c.c +++ b/src/gdbus/peripheral_gdbus_i2c.c @@ -49,10 +49,7 @@ static int __i2c_proxy_init(void) static int __i2c_proxy_deinit(void) { - if (i2c_proxy == NULL) { - _E("I2c proxy is NULL"); - return PERIPHERAL_ERROR_IO_ERROR; - } + RETVM_IF(i2c_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "I2c proxy is NULL"); g_object_unref(i2c_proxy); if (!G_IS_OBJECT(i2c_proxy)) @@ -102,8 +99,25 @@ int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address) return ret; } -int peripheral_gdbus_i2c_close(void) +int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c) { - int ret = __i2c_proxy_deinit(); + RETVM_IF(i2c_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "I2c proxy is NULL"); + + int ret; + GError *error = NULL; + + if (peripheral_io_gdbus_i2c_call_close_sync( + i2c_proxy, + i2c->handle, + &ret, + NULL, + &error) == FALSE) { + _E("Failed to request daemon to i2c close : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + __i2c_proxy_deinit(); + return ret; } diff --git a/src/gdbus/peripheral_gdbus_pwm.c b/src/gdbus/peripheral_gdbus_pwm.c index 4b76866..71a7344 100644 --- a/src/gdbus/peripheral_gdbus_pwm.c +++ b/src/gdbus/peripheral_gdbus_pwm.c @@ -52,10 +52,7 @@ static int __pwm_proxy_init(void) static int __pwm_proxy_deinit(void) { - if (pwm_proxy == NULL) { - _E("Pwm proxy is NULL"); - return PERIPHERAL_ERROR_IO_ERROR; - } + RETVM_IF(pwm_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Pwm proxy is NULL"); g_object_unref(pwm_proxy); if (!G_IS_OBJECT(pwm_proxy)) @@ -126,8 +123,25 @@ int peripheral_gdbus_pwm_open(peripheral_pwm_h pwm, int chip, int pin) return ret; } -int peripheral_gdbus_pwm_close(void) +int peripheral_gdbus_pwm_close(peripheral_pwm_h pwm) { - int ret = __pwm_proxy_deinit(); + RETVM_IF(pwm_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Pwm proxy is NULL"); + + int ret; + GError *error = NULL; + + if (peripheral_io_gdbus_pwm_call_close_sync( + pwm_proxy, + pwm->handle, + &ret, + NULL, + &error) == FALSE) { + _E("Failed to request daemon to gpio pwm : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + __pwm_proxy_deinit(); + return ret; } diff --git a/src/gdbus/peripheral_gdbus_spi.c b/src/gdbus/peripheral_gdbus_spi.c index d518d85..2861d52 100644 --- a/src/gdbus/peripheral_gdbus_spi.c +++ b/src/gdbus/peripheral_gdbus_spi.c @@ -49,10 +49,7 @@ static int __spi_proxy_init(void) static int __spi_proxy_deinit(void) { - if (spi_proxy == NULL) { - _E("Spi proxy is NULL"); - return PERIPHERAL_ERROR_IO_ERROR; - } + RETVM_IF(spi_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Spi proxy is NULL"); g_object_unref(spi_proxy); if (!G_IS_OBJECT(spi_proxy)) @@ -102,8 +99,25 @@ int peripheral_gdbus_spi_open(peripheral_spi_h spi, int bus, int cs) return ret; } -int peripheral_gdbus_spi_close(void) +int peripheral_gdbus_spi_close(peripheral_spi_h spi) { - int ret = __spi_proxy_deinit(); + RETVM_IF(spi_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Spi proxy is NULL"); + + int ret; + GError *error = NULL; + + if (peripheral_io_gdbus_spi_call_close_sync( + spi_proxy, + spi->handle, + &ret, + NULL, + &error) == FALSE) { + _E("Failed to request daemon to gpio spi : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + __spi_proxy_deinit(); + return ret; } diff --git a/src/gdbus/peripheral_gdbus_uart.c b/src/gdbus/peripheral_gdbus_uart.c index 671f7da..3376dff 100644 --- a/src/gdbus/peripheral_gdbus_uart.c +++ b/src/gdbus/peripheral_gdbus_uart.c @@ -49,10 +49,7 @@ static int __uart_proxy_init(void) static int __uart_proxy_deinit(void) { - if (uart_proxy == NULL) { - _E("Uart proxy is NULL"); - return PERIPHERAL_ERROR_IO_ERROR; - } + RETVM_IF(uart_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Uart proxy is NULL"); g_object_unref(uart_proxy); if (!G_IS_OBJECT(uart_proxy)) @@ -101,8 +98,25 @@ int peripheral_gdbus_uart_open(peripheral_uart_h uart, int port) return ret; } -int peripheral_gdbus_uart_close(void) +int peripheral_gdbus_uart_close(peripheral_uart_h uart) { - int ret = __uart_proxy_deinit(); + RETVM_IF(uart_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Uart proxy is NULL"); + + int ret; + GError *error = NULL; + + if (peripheral_io_gdbus_uart_call_close_sync( + uart_proxy, + uart->handle, + &ret, + NULL, + &error) == FALSE) { + _E("Failed to request daemon to gpio uart : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + __uart_proxy_deinit(); + return ret; } diff --git a/src/gdbus/peripheral_io.xml b/src/gdbus/peripheral_io.xml index 6b987a3..00c49e7 100644 --- a/src/gdbus/peripheral_io.xml +++ b/src/gdbus/peripheral_io.xml @@ -7,6 +7,10 @@ + + + + @@ -16,6 +20,10 @@ + + + + @@ -25,6 +33,10 @@ + + + + @@ -33,6 +45,10 @@ + + + + @@ -42,5 +58,9 @@ + + + + diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index 229c831..4d0579b 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -88,7 +88,7 @@ int peripheral_gpio_close(peripheral_gpio_h gpio) RETVM_IF(gpio == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "gpio handle is NULL"); /* call gpio_close */ - ret = peripheral_gdbus_gpio_close(); + ret = peripheral_gdbus_gpio_close(gpio); if (ret != PERIPHERAL_ERROR_NONE) { _E("Failed to close the gpio pin, ret : %d", ret); return ret; diff --git a/src/peripheral_i2c.c b/src/peripheral_i2c.c index 3d9b908..c36d72f 100644 --- a/src/peripheral_i2c.c +++ b/src/peripheral_i2c.c @@ -90,7 +90,7 @@ int peripheral_i2c_close(peripheral_i2c_h i2c) RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "I2C feature is not supported"); RETVM_IF(i2c == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "i2c handle is NULL"); - ret = peripheral_gdbus_i2c_close(); + ret = peripheral_gdbus_i2c_close(i2c); if (ret != PERIPHERAL_ERROR_NONE) { _E("Failed to close i2c communcation, ret : %d", ret); return ret; diff --git a/src/peripheral_pwm.c b/src/peripheral_pwm.c index 51ad72b..ee0e829 100644 --- a/src/peripheral_pwm.c +++ b/src/peripheral_pwm.c @@ -82,7 +82,7 @@ int peripheral_pwm_close(peripheral_pwm_h pwm) RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "PWM feature is not supported"); RETVM_IF(pwm == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "pwm handle is NULL"); - ret = peripheral_gdbus_pwm_close(); + ret = peripheral_gdbus_pwm_close(pwm); if (ret != PERIPHERAL_ERROR_NONE) { _E("Failed to close PWM chip, continuing anyway, ret : %d", ret); return ret; diff --git a/src/peripheral_spi.c b/src/peripheral_spi.c index 0014893..10faddb 100644 --- a/src/peripheral_spi.c +++ b/src/peripheral_spi.c @@ -81,7 +81,7 @@ int peripheral_spi_close(peripheral_spi_h spi) RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "SPI feature is not supported"); RETVM_IF(spi == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "spi handle is NULL"); - ret = peripheral_gdbus_spi_close(); + ret = peripheral_gdbus_spi_close(spi); if (ret != PERIPHERAL_ERROR_NONE) { _E("Failed to close SPI device, continuing anyway, ret : %d", ret); return ret; diff --git a/src/peripheral_uart.c b/src/peripheral_uart.c index e66856c..2b48f85 100644 --- a/src/peripheral_uart.c +++ b/src/peripheral_uart.c @@ -86,7 +86,7 @@ int peripheral_uart_close(peripheral_uart_h uart) RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "UART feature is not supported"); RETVM_IF(uart == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "uart handle is NULL"); - ret = peripheral_gdbus_uart_close(); + ret = peripheral_gdbus_uart_close(uart); if (ret != PERIPHERAL_ERROR_NONE) { _E("Failed to close uart communication, continuing anyway, ret : %d", ret); return ret; -- 2.34.1 From f2b38db50344ce5a9c240b352435614f676bc6b1 Mon Sep 17 00:00:00 2001 From: Segwon Date: Thu, 14 Dec 2017 20:05:12 +0900 Subject: [PATCH 03/16] gpio: set initially edge_mode and direction in handle Change-Id: Ie9c50a3d680562c9f573ee006b816a3960096c46 Signed-off-by: Segwon --- include/interface/peripheral_interface_gpio.h | 5 ++ include/peripheral_handle.h | 2 + src/interface/peripheral_interface_gpio.c | 53 +++++++++++++++++++ src/peripheral_gpio.c | 16 +++++- 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/include/interface/peripheral_interface_gpio.h b/include/interface/peripheral_interface_gpio.h index 140edea..d4ca75d 100644 --- a/include/interface/peripheral_interface_gpio.h +++ b/include/interface/peripheral_interface_gpio.h @@ -22,8 +22,13 @@ #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); diff --git a/include/peripheral_handle.h b/include/peripheral_handle.h index 0fc1b25..b834d06 100644 --- a/include/peripheral_handle.h +++ b/include/peripheral_handle.h @@ -25,6 +25,8 @@ struct _peripheral_gpio_s { int fd_direction; int fd_edge; int fd_value; + peripheral_gpio_direction_e direction; + peripheral_gpio_edge_e edge; }; /** diff --git a/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c index 00b911b..4ca79e4 100644 --- a/src/interface/peripheral_interface_gpio.c +++ b/src/interface/peripheral_interface_gpio.c @@ -16,6 +16,30 @@ #include "peripheral_interface_gpio.h" +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; + return PERIPHERAL_ERROR_NONE; + } + } + + return PERIPHERAL_ERROR_IO_ERROR; +} + int peripheral_interface_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direction_e direction) { static predefined_type_s types[3] = { @@ -27,9 +51,36 @@ int peripheral_interface_gpio_set_direction(peripheral_gpio_h gpio, peripheral_g 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; +} + int peripheral_interface_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e edge) { static predefined_type_s types[4] = { @@ -42,6 +93,8 @@ int peripheral_interface_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_g 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; } diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index 4d0579b..4cd0290 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -71,9 +71,23 @@ int peripheral_gpio_open(int gpio_pin, peripheral_gpio_h *gpio) handle = NULL; } + ret = peripheral_interface_gpio_set_initial_direction_into_handle(handle); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("Failed to peripheral_interface_gpio_set_initial_direction_into_handle()"); + peripheral_gpio_close(handle); + return ret; + } + + ret = peripheral_interface_gpio_set_initial_edge_into_handle(handle); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("Failed to peripheral_interface_gpio_set_initial_edge_into_handle()"); + peripheral_gpio_close(handle); + return ret; + } + *gpio = handle; - return ret; + return PERIPHERAL_ERROR_NONE; } /** -- 2.34.1 From 4e217917479bccac3d79b1312c249cbf72ae9593 Mon Sep 17 00:00:00 2001 From: Segwon Date: Thu, 14 Dec 2017 20:13:04 +0900 Subject: [PATCH 04/16] gpio: enhance exception handling in interface function - GPIO set type functions require prerequisites 1) [edge_mode] [direction] none ----------------------> in, out (O) rising, falling, both -----> in (O) \ ---> out (X) 2) [direction] [edge_mode] in ------------------------> none, rising, falling, both (O) out -----------------------> none (O) \ ----------------> rising, falling, both (X) 3) [direction] [value] in ------------------------> read (O) \ ----------------> write (X) out -----------------------> read, write (O) Change-Id: I72f8557568916b01c1e2e9edef79ed79f5bb20e6 Signed-off-by: Segwon --- src/interface/peripheral_interface_gpio.c | 40 ++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c index 4ca79e4..119230d 100644 --- a/src/interface/peripheral_interface_gpio.c +++ b/src/interface/peripheral_interface_gpio.c @@ -40,8 +40,20 @@ int peripheral_interface_gpio_set_initial_direction_into_handle(peripheral_gpio_ 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}, @@ -81,8 +93,20 @@ int peripheral_interface_gpio_set_initial_edge_into_handle(peripheral_gpio_h gpi 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}, @@ -98,8 +122,16 @@ int peripheral_interface_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_g 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} @@ -111,6 +143,12 @@ int peripheral_interface_gpio_write(peripheral_gpio_h gpio, uint32_t value) 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; @@ -151,4 +189,4 @@ int peripheral_interface_gpio_close_isr(peripheral_gpio_h gpio) // TODO: unset interrupted callback function return PERIPHERAL_ERROR_NONE; -} \ No newline at end of file +} -- 2.34.1 From bc484e6c4e3e105d23079bf7f29a274214a60ca1 Mon Sep 17 00:00:00 2001 From: Segwon Date: Mon, 18 Dec 2017 11:42:48 +0900 Subject: [PATCH 05/16] gpio: add interrupted callback Change-Id: I6d8d2b3e6382e3ecc2ebbc7cee8747fc2290fae9 Signed-off-by: Segwon --- include/interface/peripheral_interface_gpio.h | 4 +- include/peripheral_handle.h | 11 +++ src/interface/peripheral_interface_gpio.c | 83 +++++++++++++++++-- src/peripheral_gpio.c | 4 +- 4 files changed, 93 insertions(+), 9 deletions(-) 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; } -- 2.34.1 From 24403e78dd985555bf2e35a04d9c9ed3e41eaa45 Mon Sep 17 00:00:00 2001 From: Segwon Date: Tue, 19 Dec 2017 15:31:25 +0900 Subject: [PATCH 06/16] spi: exclude the positive value in the ioctl error check, becasue of the ioctl return length Change-Id: If7d4d517c519f6d41c6bde7a7716edda4cd6a25a Signed-off-by: Segwon --- src/interface/peripheral_interface_spi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/interface/peripheral_interface_spi.c b/src/interface/peripheral_interface_spi.c index 15baf4b..b38436b 100644 --- a/src/interface/peripheral_interface_spi.c +++ b/src/interface/peripheral_interface_spi.c @@ -66,7 +66,7 @@ int peripheral_interface_spi_read(peripheral_spi_h spi, uint8_t *rxbuf, uint32_t xfer.len = length; ret = ioctl(spi->fd, SPI_IOC_MESSAGE(1), &xfer); - CHECK_ERROR(ret != 0); + CHECK_ERROR(ret < 0); return PERIPHERAL_ERROR_NONE; } @@ -81,7 +81,7 @@ int peripheral_interface_spi_write(peripheral_spi_h spi, uint8_t *txbuf, uint32_ xfer.len = length; ret = ioctl(spi->fd, SPI_IOC_MESSAGE(1), &xfer); - CHECK_ERROR(ret != 0); + CHECK_ERROR(ret < 0); return PERIPHERAL_ERROR_NONE; } @@ -99,7 +99,7 @@ int peripheral_interface_spi_transfer(peripheral_spi_h spi, uint8_t *txbuf, uint xfer.len = length; ret = ioctl(spi->fd, SPI_IOC_MESSAGE(1), &xfer); - CHECK_ERROR(ret != 0); + CHECK_ERROR(ret < 0); return PERIPHERAL_ERROR_NONE; } -- 2.34.1 From 68a6482231f0e0d827e071568a785054d6c74dd0 Mon Sep 17 00:00:00 2001 From: Segwon Date: Tue, 19 Dec 2017 15:38:30 +0900 Subject: [PATCH 07/16] interface: add return type EINVAL in CHECK_ERROR Change-Id: I7dfb65fb371c428a7ef2f030cb5711bfb9d221af Signed-off-by: Segwon --- include/interface/peripheral_interface_common.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/interface/peripheral_interface_common.h b/include/interface/peripheral_interface_common.h index f51a4c2..d6137ce 100644 --- a/include/interface/peripheral_interface_common.h +++ b/include/interface/peripheral_interface_common.h @@ -32,6 +32,8 @@ if (expr) { \ if (errno == EAGAIN) \ return PERIPHERAL_ERROR_TRY_AGAIN; \ + if (errno == EINVAL) \ + return PERIPHERAL_ERROR_INVALID_PARAMETER; \ char errmsg[MAX_ERR_LEN]; \ strerror_r(errno, errmsg, sizeof(errmsg)); \ _E("Failed the %s(%d) function. errmsg: %s", __FUNCTION__, __LINE__, errmsg); \ -- 2.34.1 From 65cfcb0c4618d9ef6f91669f8e28e5bcfb342ea8 Mon Sep 17 00:00:00 2001 From: Segwon Date: Wed, 27 Dec 2017 17:13:59 +0900 Subject: [PATCH 08/16] doxygen: give additional prerequisites information for set APIs Change-Id: If1a69bdfb93ef06f1f1c6734850dbafe75ff5c20 Signed-off-by: Segwon --- include/peripheral_io.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/peripheral_io.h b/include/peripheral_io.h index bb11f34..93e7e67 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -141,6 +141,7 @@ int peripheral_gpio_close(peripheral_gpio_h gpio); * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio + * @remarks To set the direction to PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH or PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW, the edge mode must be set to PERIPHERAL_GPIO_EDGE_NONE. * * @param[in] gpio The GPIO handle * @param[in] direction The direction of the GPIO pin @@ -155,6 +156,7 @@ int peripheral_gpio_close(peripheral_gpio_h gpio); * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error * * @see peripheral_gpio_direction_e + * @see peripheral_gpio_set_edge_mode() */ int peripheral_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direction_e direction); @@ -164,6 +166,7 @@ int peripheral_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direct * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio + * @remarks To set the edge mode to PERIPHERAL_GPIO_EDGE_RISING, PERIPHERAL_GPIO_EDGE_FALLING, PERIPHERAL_GPIO_EDGE_BOTH, the data direction must be set to the PERIPHERAL_GPIO_DIRECTION_IN. * * @param[in] gpio The GPIO handle * @param[in] edge The edge mode of the GPIO pin @@ -178,6 +181,7 @@ int peripheral_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direct * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error * * @see peripheral_gpio_edge_e + * @see peripheral_gpio_set_direction() */ int peripheral_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e edge); @@ -200,6 +204,7 @@ typedef void(*peripheral_gpio_interrupted_cb)(peripheral_gpio_h gpio, peripheral * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio + * @remarks The interrupted callback is unset when called peripheral_gpio_unset_interrupted_cb() or callback receives an error value other than PERIPHERAL_ERROR_NONE. * * @param[in] gpio The GPIO handle * @param[in] callback The GPIO interrupted callback function to set @@ -264,6 +269,7 @@ int peripheral_gpio_read(peripheral_gpio_h gpio, uint32_t *value); * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio + * @remarks To write binary data, the direction must be set to PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH or PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW. * * @param[in] gpio The GPIO handle * @param[in] value The value to set (must be 0 or 1) @@ -278,6 +284,7 @@ int peripheral_gpio_read(peripheral_gpio_h gpio, uint32_t *value); * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error * * @see peripheral_gpio_read() + * @see peripheral_gpio_set_direction() */ int peripheral_gpio_write(peripheral_gpio_h gpio, uint32_t value); @@ -1055,6 +1062,7 @@ int peripheral_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode); * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio + * @remarks ARTIK530 and Raspberry Pi 3 do not support LSB first bit order. * * @param[in] spi The SPI slave device handle * @param[in] bit_order The transfer bit order -- 2.34.1 From 76af428c6b7c3320670ec88347b332d4e8aa7412 Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Tue, 2 Jan 2018 17:16:54 +0900 Subject: [PATCH 09/16] pio: return error when open is failed - to prevent explicite null dereferenced, error should be returned when open is failed. Change-Id: I645dec3879d54d43edec1ba52ace84af6c86b180 Signed-off-by: kibak.yoon --- src/peripheral_gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index b51c577..e5a3d8c 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -69,6 +69,7 @@ int peripheral_gpio_open(int gpio_pin, peripheral_gpio_h *gpio) _E("Failed to open the gpio pin, ret : %d", ret); free(handle); handle = NULL; + return ret; } ret = peripheral_interface_gpio_set_initial_direction_into_handle(handle); -- 2.34.1 From 536ad7a2e101d3e3264565f0810cf27da990c5ae Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Tue, 2 Jan 2018 18:17:53 +0900 Subject: [PATCH 10/16] pio: free the memory allocated by system_info_get_platform_string() Change-Id: Ibccb1798db42ac207ecb5f9d95858919b40371c6 Signed-off-by: kibak.yoon --- test/peripheral-io-test.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index d8a103b..23b118d 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -16,6 +16,7 @@ */ #include +#include #include #include "peripheral_io.h" @@ -81,39 +82,41 @@ static int __test_peripheral_init() ret = __get_feature(KEY_FEATURE_PERIPHERAL_IO_GPIO, &feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = test_peripheral_io_gpio_initialize(model_name, feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = __get_feature(KEY_FEATURE_PERIPHERAL_IO_I2C, &feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = test_peripheral_io_i2c_initialize(model_name, feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = __get_feature(KEY_FEATURE_PERIPHERAL_IO_PWM, &feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = test_peripheral_io_pwm_initialize(model_name, feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = __get_feature(KEY_FEATURE_PERIPHERAL_IO_UART, &feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = test_peripheral_io_uart_initialize(model_name, feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = __get_feature(KEY_FEATURE_PERIPHERAL_IO_SPI, &feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; ret = test_peripheral_io_spi_initialize(model_name, feature); if (ret != PERIPHERAL_ERROR_NONE) - return ret; + goto ERR; +ERR: + free(model_name); return ret; } @@ -536,4 +539,4 @@ int main(int argc, char **argv) } return -1; -} \ No newline at end of file +} -- 2.34.1 From 9c754a6e87dc23a1958a84acac4f7beff82f43ca Mon Sep 17 00:00:00 2001 From: Segwon Date: Wed, 3 Jan 2018 12:00:19 +0900 Subject: [PATCH 11/16] gpio: do not join if the thread is null Change-Id: Ib1dafd777acaa7da520ac7aae050a05b1d607dca Signed-off-by: Segwon --- src/interface/peripheral_interface_gpio.c | 6 +++++- src/peripheral_gpio.c | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c index c8dd33b..2695a86 100644 --- a/src/interface/peripheral_interface_gpio.c +++ b/src/interface/peripheral_interface_gpio.c @@ -259,7 +259,11 @@ int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, periphe 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); + + if (gpio->cb_info.thread != NULL) { + g_thread_join(gpio->cb_info.thread); + gpio->cb_info.thread = NULL; + } return PERIPHERAL_ERROR_NONE; } \ No newline at end of file diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index e5a3d8c..0b4252c 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -86,6 +86,7 @@ int peripheral_gpio_open(int gpio_pin, peripheral_gpio_h *gpio) return ret; } + handle->cb_info.thread = NULL; *gpio = handle; return PERIPHERAL_ERROR_NONE; -- 2.34.1 From ccce883e3b46aa5a949751723bc7da9e211a7227 Mon Sep 17 00:00:00 2001 From: Segwon Date: Wed, 3 Jan 2018 12:10:20 +0900 Subject: [PATCH 12/16] gpio: enhance the interrupted callback thread safty Change-Id: Ib9374b0a62bdf7d8d71604365637d0dfacab69b6 Signed-off-by: Segwon --- include/peripheral_handle.h | 2 +- src/interface/peripheral_interface_gpio.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/peripheral_handle.h b/include/peripheral_handle.h index e07c4f1..18f260d 100644 --- a/include/peripheral_handle.h +++ b/include/peripheral_handle.h @@ -24,7 +24,7 @@ typedef struct _peripheral_gpio_interrupted_cb_info_s { peripheral_gpio_interrupted_cb cb; peripheral_error_e error; void *user_data; - int status; + gint status; } interrupted_cb_info_s; /** diff --git a/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c index 2695a86..90c2a21 100644 --- a/src/interface/peripheral_interface_gpio.c +++ b/src/interface/peripheral_interface_gpio.c @@ -204,7 +204,7 @@ static gpointer __peripheral_interface_gpio_poll(void *data) uint32_t value; - while (gpio->cb_info.status == GPIO_INTERRUPTED_CALLBACK_SET) { + while (g_atomic_int_get(&gpio->cb_info.status) == GPIO_INTERRUPTED_CALLBACK_SET) { poll_state = poll(&poll_fd, 1, 3000); @@ -250,7 +250,7 @@ int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, periphe gpio->cb_info.cb = callback; gpio->cb_info.user_data = user_data; - gpio->cb_info.status = GPIO_INTERRUPTED_CALLBACK_SET; + 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; @@ -258,7 +258,7 @@ int peripheral_interface_gpio_set_interrupted_cb(peripheral_gpio_h gpio, periphe int peripheral_interface_gpio_unset_interrupted_cb(peripheral_gpio_h gpio) { - gpio->cb_info.status = GPIO_INTERRUPTED_CALLBACK_UNSET; + 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); -- 2.34.1 From 516040688ce9ba95224091d75b826c38a7a890e8 Mon Sep 17 00:00:00 2001 From: Segwon Date: Wed, 3 Jan 2018 13:22:51 +0900 Subject: [PATCH 13/16] gpio: fix to free a handle when peripheral_gdbus_gpio_close() is failed Change-Id: Ibab4d38a57e91b11f2c5a6e1b21e94d2c6e40eed Signed-off-by: Segwon --- src/peripheral_gpio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index 0b4252c..eb2c999 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -105,10 +105,8 @@ int peripheral_gpio_close(peripheral_gpio_h gpio) /* call gpio_close */ ret = peripheral_gdbus_gpio_close(gpio); - if (ret != PERIPHERAL_ERROR_NONE) { + if (ret != PERIPHERAL_ERROR_NONE) _E("Failed to close the gpio pin, ret : %d", ret); - return ret; - } peripheral_interface_gpio_close(gpio); -- 2.34.1 From 9cff397cac3768d73a90cb768eb217431ec45b0e Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Mon, 19 Feb 2018 12:42:04 +0900 Subject: [PATCH 14/16] pio: deliver user data to gpio interrupted callback function Change-Id: Ib0048d8031a5799e0a495adafdbc4f824e117801 Signed-off-by: kibak.yoon --- src/interface/peripheral_interface_gpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interface/peripheral_interface_gpio.c b/src/interface/peripheral_interface_gpio.c index 90c2a21..ce9dbf4 100644 --- a/src/interface/peripheral_interface_gpio.c +++ b/src/interface/peripheral_interface_gpio.c @@ -187,7 +187,7 @@ void peripheral_interface_gpio_close(peripheral_gpio_h gpio) 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, NULL); + gpio->cb_info.cb(gpio, gpio->cb_info.error, gpio->cb_info.user_data); return FALSE; } @@ -266,4 +266,4 @@ int peripheral_interface_gpio_unset_interrupted_cb(peripheral_gpio_h gpio) } return PERIPHERAL_ERROR_NONE; -} \ No newline at end of file +} -- 2.34.1 From 145a47a47da2d3e2da2a59341f2810f70f21c249 Mon Sep 17 00:00:00 2001 From: Konrad Kuchciak Date: Mon, 13 Aug 2018 08:18:00 +0200 Subject: [PATCH 15/16] gpio: fix documentation errors * Added '#' before enums to automatically create links in the HTML documentation. * Added description of errors received in GPIO interrupted callback Change-Id: Idb818c52708b1e73de594f1b7ac77c09cda71534 Signed-off-by: Konrad Kuchciak --- include/peripheral_io.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/include/peripheral_io.h b/include/peripheral_io.h index 93e7e67..f652186 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -141,7 +141,7 @@ int peripheral_gpio_close(peripheral_gpio_h gpio); * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio - * @remarks To set the direction to PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH or PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW, the edge mode must be set to PERIPHERAL_GPIO_EDGE_NONE. + * @remarks To set the direction to #PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH or #PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW, the edge mode must be set to #PERIPHERAL_GPIO_EDGE_NONE. * * @param[in] gpio The GPIO handle * @param[in] direction The direction of the GPIO pin @@ -166,7 +166,7 @@ int peripheral_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direct * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio - * @remarks To set the edge mode to PERIPHERAL_GPIO_EDGE_RISING, PERIPHERAL_GPIO_EDGE_FALLING, PERIPHERAL_GPIO_EDGE_BOTH, the data direction must be set to the PERIPHERAL_GPIO_DIRECTION_IN. + * @remarks To set the edge mode to #PERIPHERAL_GPIO_EDGE_RISING, #PERIPHERAL_GPIO_EDGE_FALLING, #PERIPHERAL_GPIO_EDGE_BOTH, the data direction must be set to the #PERIPHERAL_GPIO_DIRECTION_IN. * * @param[in] gpio The GPIO handle * @param[in] edge The edge mode of the GPIO pin @@ -188,6 +188,17 @@ int peripheral_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e /** * @platform * @brief The GPIO interrupted callback called when the GPIO interrupt is triggered. + * @details The following errors can be received: \n + * #PERIPHERAL_ERROR_NONE Successful \n + * #PERIPHERAL_ERROR_IO_ERROR I/O operation failed \n + * #PERIPHERAL_ERROR_NO_DEVICE Device does not exist or is removed \n + * #PERIPHERAL_ERROR_TRY_AGAIN Try again \n + * #PERIPHERAL_ERROR_OUT_OF_MEMORY Memory allocation failed \n + * #PERIPHERAL_ERROR_PERMISSION_DENIED Permission denied \n + * #PERIPHERAL_ERROR_RESOURCE_BUSY Device is in use \n + * #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter \n + * #PERIPHERAL_ERROR_NOT_SUPPORTED Not supported \n + * #PERIPHERAL_ERROR_UNKNOWN Unknown internal error \n * @since_tizen 4.0 * * @param[in] gpio The GPIO handle @@ -204,7 +215,7 @@ typedef void(*peripheral_gpio_interrupted_cb)(peripheral_gpio_h gpio, peripheral * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio - * @remarks The interrupted callback is unset when called peripheral_gpio_unset_interrupted_cb() or callback receives an error value other than PERIPHERAL_ERROR_NONE. + * @remarks The interrupted callback is unset when called peripheral_gpio_unset_interrupted_cb() or callback receives an error value other than #PERIPHERAL_ERROR_NONE. * * @param[in] gpio The GPIO handle * @param[in] callback The GPIO interrupted callback function to set @@ -269,7 +280,7 @@ int peripheral_gpio_read(peripheral_gpio_h gpio, uint32_t *value); * @since_tizen 4.0 * @privlevel platform * @privilege http://tizen.org/privilege/peripheralio - * @remarks To write binary data, the direction must be set to PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH or PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW. + * @remarks To write binary data, the direction must be set to #PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH or #PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW. * * @param[in] gpio The GPIO handle * @param[in] value The value to set (must be 0 or 1) -- 2.34.1 From 4445b6522d29cae1970c7b79415801b289ba932f Mon Sep 17 00:00:00 2001 From: Konrad Kuchciak Date: Wed, 18 Jul 2018 11:56:23 +0200 Subject: [PATCH 16/16] Add API for the adc device This commit adds support for the adc device. For this to work, adc also has to be supported by peripheral-bus. Change-Id: I3277815fde9e6b82e5d165ccb5003b11f505f0e9 Signed-off-by: Konrad Kuchciak --- CMakeLists.txt | 3 + doc/peripheral_io_doc.h | 33 ++- include/gdbus/peripheral_gdbus_adc.h | 25 ++ include/gdbus/peripheral_gdbus_common.h | 3 +- include/interface/peripheral_interface_adc.h | 28 +++ include/peripheral_handle.h | 10 +- include/peripheral_io.h | 88 ++++++- src/gdbus/peripheral_gdbus_adc.c | 123 +++++++++ src/gdbus/peripheral_io.xml | 13 + src/interface/peripheral_interface_adc.c | 43 ++++ src/peripheral_adc.c | 113 +++++++++ test/include/test_peripheral_adc.h | 32 +++ test/peripheral-io-test.c | 53 +++- test/src/test_peripheral_adc.c | 251 +++++++++++++++++++ 14 files changed, 805 insertions(+), 13 deletions(-) create mode 100644 include/gdbus/peripheral_gdbus_adc.h create mode 100644 include/interface/peripheral_interface_adc.h create mode 100644 src/gdbus/peripheral_gdbus_adc.c create mode 100644 src/interface/peripheral_interface_adc.c create mode 100644 src/peripheral_adc.c create mode 100644 test/include/test_peripheral_adc.h create mode 100644 test/src/test_peripheral_adc.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 68a4f6a..b4da425 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,16 +50,19 @@ SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=%{_libdir}") SET(SOURCES src/peripheral_gpio.c src/peripheral_i2c.c src/peripheral_pwm.c + src/peripheral_adc.c src/peripheral_uart.c src/peripheral_spi.c src/interface/peripheral_interface_gpio.c src/interface/peripheral_interface_i2c.c src/interface/peripheral_interface_pwm.c + src/interface/peripheral_interface_adc.c src/interface/peripheral_interface_spi.c src/interface/peripheral_interface_uart.c src/gdbus/peripheral_gdbus_gpio.c src/gdbus/peripheral_gdbus_i2c.c src/gdbus/peripheral_gdbus_pwm.c + src/gdbus/peripheral_gdbus_adc.c src/gdbus/peripheral_gdbus_uart.c src/gdbus/peripheral_gdbus_spi.c src/gdbus/peripheral_io_gdbus.c) diff --git a/doc/peripheral_io_doc.h b/doc/peripheral_io_doc.h index 6741d54..6527e92 100644 --- a/doc/peripheral_io_doc.h +++ b/doc/peripheral_io_doc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2017-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. @@ -24,7 +24,7 @@ * * @section CAPI_SYSTEM_PERIPHERAL_IO_MODULE_OVERVIEW Overview * This @ref CAPI_SYSTEM_PERIPHERAL_IO_MODULE API provides access to the low level device providers, - * including GPIO, I2C, PWM, UART and SPI. + * including GPIO, I2C, PWM, ADC, UART and SPI. */ @@ -171,3 +171,32 @@ * * More details on featuring your application can be found from Feature Element. */ + + +/** + * @ingroup CAPI_SYSTEM_PERIPHERAL_IO_MODULE + * @defgroup CAPI_SYSTEM_PERIPHERAL_IO_ADC_MODULE ADC + * @brief The @ref CAPI_SYSTEM_PERIPHERAL_IO_ADC_MODULE API provides functions to control ADC peripherals connected to the IoT device. + * + * @section CAPI_SYSTEM_PERIPHERAL_IO_ADC_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_SYSTEM_PERIPHERAL_IO_ADC_MODULE_OVERVIEW Overview + * + * This @ref CAPI_SYSTEM_PERIPHERAL_IO_ADC_MODULE API provides functions to control ADC peripherals connected to the IoT device. + * + * @section CAPI_SYSTEM_PERIPHERAL_IO_ADC_MODULE_FEATURE Realted Features + * + * This API is related with the following feature:\n + * - http://tizen.org/feature/peripheral_io.adc\n + * + * It is recommended to use features in your application for reliability.\n + * + * You can check if a IoT device supports the related features for this API \n + * by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, and control your application's actions accordingly.\n + * + * To ensure your application is only running on the IoT device with specific features, \n + * please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + */ diff --git a/include/gdbus/peripheral_gdbus_adc.h b/include/gdbus/peripheral_gdbus_adc.h new file mode 100644 index 0000000..ffb1af7 --- /dev/null +++ b/include/gdbus/peripheral_gdbus_adc.h @@ -0,0 +1,25 @@ +/* + * 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. + */ + +#ifndef __PERIPHERAL_GDBUS_ADC_H__ +#define __PERIPHERAL_GDBUS_ADC_H__ + +#include "peripheral_gdbus_common.h" + +int peripheral_gdbus_adc_open(peripheral_adc_h adc, int device, int channel); +int peripheral_gdbus_adc_close(peripheral_adc_h adc); + +#endif /* __PERIPHERAL_GDBUS_ADC_H__ */ diff --git a/include/gdbus/peripheral_gdbus_common.h b/include/gdbus/peripheral_gdbus_common.h index 62b0717..803faf3 100644 --- a/include/gdbus/peripheral_gdbus_common.h +++ b/include/gdbus/peripheral_gdbus_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2017-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. @@ -30,6 +30,7 @@ #define PERIPHERAL_GDBUS_GPIO_PATH "/Org/Tizen/Peripheral_io/Gpio" #define PERIPHERAL_GDBUS_I2C_PATH "/Org/Tizen/Peripheral_io/I2c" #define PERIPHERAL_GDBUS_PWM_PATH "/Org/Tizen/Peripheral_io/Pwm" +#define PERIPHERAL_GDBUS_ADC_PATH "/Org/Tizen/Peripheral_io/Adc" #define PERIPHERAL_GDBUS_UART_PATH "/Org/Tizen/Peripheral_io/Uart" #define PERIPHERAL_GDBUS_SPI_PATH "/Org/Tizen/Peripheral_io/Spi" #define PERIPHERAL_GDBUS_NAME "org.tizen.peripheral_io" diff --git a/include/interface/peripheral_interface_adc.h b/include/interface/peripheral_interface_adc.h new file mode 100644 index 0000000..87d5383 --- /dev/null +++ b/include/interface/peripheral_interface_adc.h @@ -0,0 +1,28 @@ +/* + * 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. + */ + +#ifndef __PERIPHERAL_INTERFACE_ADC_H__ +#define __PERIPHERAL_INTERFACE_ADC_H__ + +#include "peripheral_interface_common.h" + +#define ADC_BUFFER_MAX 64 + +void peripheral_interface_adc_close(peripheral_adc_h adc); + +int peripheral_interface_adc_read(peripheral_adc_h adc, uint32_t *value); + +#endif/*__PERIPHERAL_INTERFACE_GPIO_H__*/ diff --git a/include/peripheral_handle.h b/include/peripheral_handle.h index 18f260d..9023b4e 100644 --- a/include/peripheral_handle.h +++ b/include/peripheral_handle.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2017-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. @@ -59,6 +59,14 @@ struct _peripheral_pwm_s { int fd_enable; }; +/** + * @brief Internal struct for adc context + */ +struct _peripheral_adc_s { + uint handle; + int fd; +}; + /** * @brief Internal struct for uart context */ diff --git a/include/peripheral_io.h b/include/peripheral_io.h index f652186..59187db 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2016-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. @@ -662,6 +662,92 @@ int peripheral_pwm_set_enabled(peripheral_pwm_h pwm, bool enabled); * @} */ +/** + * @addtogroup CAPI_SYSTEM_PERIPHERAL_IO_ADC_MODULE + * @{ + */ + +/** + * @brief The handle of the ADC peripherals. + * @since_tizen 5.0 + */ +typedef struct _peripheral_adc_s *peripheral_adc_h; + +/** + * @platform + * @brief Opens the ADC pin. + * @since_tizen 5.0 + * @privlevel platform + * @privilege http://tizen.org/privilege/peripheralio + * @remarks @a adc should be released with peripheral_adc_close() + * + * @param[in] device The ADC device number + * @param[in] channel The ADC channel number to control + * @param[out] adc The ADC handle is created on success + * + * @return 0 on success, otherwise a negative error value + * @retval #PERIPHERAL_ERROR_NONE Successful + * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device does not exist or is removed + * @retval #PERIPHERAL_ERROR_OUT_OF_MEMORY Memory allocation failed + * @retval #PERIPHERAL_ERROR_PERMISSION_DENIED Permission denied + * @retval #PERIPHERAL_ERROR_RESOURCE_BUSY Device is in use + * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_NOT_SUPPORTED Not supported + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * + * @post peripheral_adc_close() + */ +int peripheral_adc_open(int device, int channel, peripheral_adc_h *adc); + +/** + * @platform + * @brief Closes the ADC pin. + * @since_tizen 5.0 + * @privlevel platform + * @privilege http://tizen.org/privilege/peripheralio + * + * @param[in] adc The ADC handle + * + * @return 0 on success, otherwise a negative error value + * @retval #PERIPHERAL_ERROR_NONE Successful + * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device does not exist or is removed + * @retval #PERIPHERAL_ERROR_PERMISSION_DENIED Permission denied + * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_NOT_SUPPORTED Not supported + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * + * @pre peripheral_adc_open() + */ +int peripheral_adc_close(peripheral_adc_h adc); + +/** + * @platform + * @brief Gets the current value of the ADC pin. + * @since_tizen 5.0 + * @privlevel platform + * @privilege http://tizen.org/privilege/peripheralio + * + * @param[in] adc The ADC handle + * @param[out] value The value to get + * + * @return 0 on success, otherwise a negative error value + * @retval #PERIPHERAL_ERROR_NONE Successful + * @retval #PERIPHERAL_ERROR_IO_ERROR I/O operation failed + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device does not exist or is removed + * @retval #PERIPHERAL_ERROR_PERMISSION_DENIED Permission denied + * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_NOT_SUPPORTED Not supported + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * + */ +int peripheral_adc_read(peripheral_adc_h adc, uint32_t *value); + +/** +* @} +*/ + /** * @addtogroup CAPI_SYSTEM_PERIPHERAL_IO_UART_MODULE * @{ diff --git a/src/gdbus/peripheral_gdbus_adc.c b/src/gdbus/peripheral_gdbus_adc.c new file mode 100644 index 0000000..4ef8ed3 --- /dev/null +++ b/src/gdbus/peripheral_gdbus_adc.c @@ -0,0 +1,123 @@ +/* + * 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_gdbus_adc.h" + +#define ADC_FD_INDEX 0 + +static PeripheralIoGdbusAdc *adc_proxy = NULL; + +static int __adc_proxy_init(void) +{ + GError *error = NULL; + + if (adc_proxy != NULL) { + _E("Adc proxy is already created"); + g_object_ref(adc_proxy); + return PERIPHERAL_ERROR_NONE; + } + + adc_proxy = peripheral_io_gdbus_adc_proxy_new_for_bus_sync( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + PERIPHERAL_GDBUS_NAME, + PERIPHERAL_GDBUS_ADC_PATH, + NULL, + &error); + + if (adc_proxy == NULL) { + _E("Failed to create adc proxy : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + return PERIPHERAL_ERROR_NONE; +} + +static int __adc_proxy_deinit(void) +{ + RETVM_IF(adc_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Adc proxy is NULL"); + + g_object_unref(adc_proxy); + if (!G_IS_OBJECT(adc_proxy)) + adc_proxy = NULL; + + return PERIPHERAL_ERROR_NONE; +} + +int peripheral_gdbus_adc_open(peripheral_adc_h adc, int device, int channel) +{ + int ret; + GError *error = NULL; + GUnixFDList *fd_list = NULL; + + ret = __adc_proxy_init(); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + + if (peripheral_io_gdbus_adc_call_open_sync( + adc_proxy, + device, + channel, + NULL, + &adc->handle, + &ret, + &fd_list, + NULL, + &error) == FALSE) { + _E("Failed to request daemon to adc open : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + // TODO : If ret is not PERIPHERAL_ERROR_NONE, fd list it NULL from daemon. + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + + adc->fd = g_unix_fd_list_get(fd_list, ADC_FD_INDEX, &error); + if (adc->fd < 0) { + _E("Failed to get fd for adc : %s", error->message); + g_error_free(error); + ret = PERIPHERAL_ERROR_IO_ERROR; + } + + g_object_unref(fd_list); + + return ret; +} + +int peripheral_gdbus_adc_close(peripheral_adc_h adc) +{ + RETVM_IF(adc_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Adc proxy is NULL"); + + int ret; + GError *error = NULL; + + if (peripheral_io_gdbus_adc_call_close_sync( + adc_proxy, + adc->handle, + &ret, + NULL, + &error) == FALSE) { + _E("Failed to request daemon to adc close : %s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_IO_ERROR; + } + + __adc_proxy_deinit(); + + return ret; +} diff --git a/src/gdbus/peripheral_io.xml b/src/gdbus/peripheral_io.xml index 00c49e7..db72361 100644 --- a/src/gdbus/peripheral_io.xml +++ b/src/gdbus/peripheral_io.xml @@ -38,6 +38,19 @@ + + + + + + + + + + + + + diff --git a/src/interface/peripheral_interface_adc.c b/src/interface/peripheral_interface_adc.c new file mode 100644 index 0000000..9282858 --- /dev/null +++ b/src/interface/peripheral_interface_adc.c @@ -0,0 +1,43 @@ +/* + * 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_interface_adc.h" + +int peripheral_interface_adc_read(peripheral_adc_h adc, uint32_t *value) +{ + int ret; + uint32_t tmp_val; + char adc_buf[ADC_BUFFER_MAX] = {0, }; + + lseek(adc->fd, 0, SEEK_SET); + ret = read(adc->fd, &adc_buf, ADC_BUFFER_MAX); + CHECK_ERROR(ret <= 0); + + ret = sscanf(adc_buf, "%d", &tmp_val); + if (ret == 1) { + *value = tmp_val; + } else { + _E("Error: unable to read adc value \n"); + return PERIPHERAL_ERROR_IO_ERROR; + } + + return PERIPHERAL_ERROR_NONE; +} + +void peripheral_interface_adc_close(peripheral_adc_h adc) +{ + close(adc->fd); +} diff --git a/src/peripheral_adc.c b/src/peripheral_adc.c new file mode 100644 index 0000000..84baf24 --- /dev/null +++ b/src/peripheral_adc.c @@ -0,0 +1,113 @@ +/* + * 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 +#include + +#include "peripheral_io.h" +#include "peripheral_handle.h" +#include "peripheral_gdbus_adc.h" +#include "peripheral_interface_adc.h" +#include "peripheral_log.h" + +#define PERIPHERAL_IO_ADC_FEATURE "http://tizen.org/feature/peripheral_io.adc" + +#define ADC_FEATURE_UNKNOWN -1 +#define ADC_FEATURE_FALSE 0 +#define ADC_FEATURE_TRUE 1 + +static int adc_feature = ADC_FEATURE_UNKNOWN; + +static bool __is_feature_supported(void) +{ + int ret = SYSTEM_INFO_ERROR_NONE; + bool feature = false; + + if (adc_feature == ADC_FEATURE_UNKNOWN) { + ret = system_info_get_platform_bool(PERIPHERAL_IO_ADC_FEATURE, &feature); + RETVM_IF(ret != SYSTEM_INFO_ERROR_NONE, false, "Failed to get system info"); + + adc_feature = (feature ? ADC_FEATURE_TRUE : ADC_FEATURE_FALSE); + } + return (adc_feature == ADC_FEATURE_TRUE ? true : false); +} + +/** + * @brief Initializes adc pin and creates adc handle. + */ +int peripheral_adc_open(int device, int channel, peripheral_adc_h *adc) +{ + int ret = PERIPHERAL_ERROR_NONE; + peripheral_adc_h handle; + + RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "ADC feature is not supported"); + RETVM_IF(adc == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid adc handle"); + RETVM_IF(device < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid adc device number"); + RETVM_IF(channel < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid adc channel number"); + + handle = (peripheral_adc_h)calloc(1, sizeof(struct _peripheral_adc_s)); + if (handle == NULL) { + _E("Failed to allocate peripheral_adc_h"); + return PERIPHERAL_ERROR_OUT_OF_MEMORY; + } + + ret = peripheral_gdbus_adc_open(handle, device, channel); + if (ret != PERIPHERAL_ERROR_NONE) { + _E("Failed to open the adc pin, ret : %d", ret); + free(handle); + handle = NULL; + return ret; + } + + *adc = handle; + + return PERIPHERAL_ERROR_NONE; +} + +/** + * @brief Releases the adc handle. + */ +int peripheral_adc_close(peripheral_adc_h adc) +{ + int ret = PERIPHERAL_ERROR_NONE; + + RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "ADC feature is not supported"); + RETVM_IF(adc == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "adc handle is NULL"); + + /* call adc_close */ + ret = peripheral_gdbus_adc_close(adc); + if (ret != PERIPHERAL_ERROR_NONE) + _E("Failed to close the adc pin, ret : %d", ret); + + peripheral_interface_adc_close(adc); + + free(adc); + adc = NULL; + + return ret; +} + +/** + * @brief Reads value of the adc. + */ +int peripheral_adc_read(peripheral_adc_h adc, uint32_t *value) +{ + RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "ADC feature is not supported"); + RETVM_IF(adc == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "adc handle is NULL"); + RETVM_IF(value == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "adc read value is invalid"); + + return peripheral_interface_adc_read(adc, value); +} diff --git a/test/include/test_peripheral_adc.h b/test/include/test_peripheral_adc.h new file mode 100644 index 0000000..acc5b88 --- /dev/null +++ b/test/include/test_peripheral_adc.h @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#ifndef __TEST_PERIPHERAL_ADC_H__ +#define __TEST_PERIPHERAL_ADC_H__ + +int test_peripheral_io_adc_initialize(char *model, bool feature); + +int test_peripheral_io_adc_peripheral_adc_open_p(void); +int test_peripheral_io_adc_peripheral_adc_open_n1(void); +int test_peripheral_io_adc_peripheral_adc_open_n2(void); +int test_peripheral_io_adc_peripheral_adc_open_n3(void); +int test_peripheral_io_adc_peripheral_adc_close_p(void); +int test_peripheral_io_adc_peripheral_adc_close_n(void); +int test_peripheral_io_adc_peripheral_adc_read_p(void); +int test_peripheral_io_adc_peripheral_adc_read_n1(void); +int test_peripheral_io_adc_peripheral_adc_read_n2(void); + +#endif /* __TEST_PERIPHERAL_ADC_H__ */ diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index 23b118d..d152203 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2017-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. @@ -23,6 +23,7 @@ #include "test_peripheral_gpio.h" #include "test_peripheral_i2c.h" #include "test_peripheral_pwm.h" +#include "test_peripheral_adc.h" #include "test_peripheral_uart.h" #include "test_peripheral_spi.h" @@ -30,6 +31,7 @@ #define KEY_FEATURE_PERIPHERAL_IO_GPIO "http://tizen.org/feature/peripheral_io.gpio" #define KEY_FEATURE_PERIPHERAL_IO_I2C "http://tizen.org/feature/peripheral_io.i2c" #define KEY_FEATURE_PERIPHERAL_IO_PWM "http://tizen.org/feature/peripheral_io.pwm" +#define KEY_FEATURE_PERIPHERAL_IO_ADC "http://tizen.org/feature/peripheral_io.adc" #define KEY_FEATURE_PERIPHERAL_IO_UART "http://tizen.org/feature/peripheral_io.uart" #define KEY_FEATURE_PERIPHERAL_IO_SPI "http://tizen.org/feature/peripheral_io.spi" @@ -101,6 +103,13 @@ static int __test_peripheral_init() if (ret != PERIPHERAL_ERROR_NONE) goto ERR; + ret = __get_feature(KEY_FEATURE_PERIPHERAL_IO_ADC, &feature); + if (ret != PERIPHERAL_ERROR_NONE) + goto ERR; + ret = test_peripheral_io_adc_initialize(model_name, feature); + if (ret != PERIPHERAL_ERROR_NONE) + goto ERR; + ret = __get_feature(KEY_FEATURE_PERIPHERAL_IO_UART, &feature); if (ret != PERIPHERAL_ERROR_NONE) goto ERR; @@ -278,6 +287,30 @@ static void __test_peripheral_pwm_run() __error_check(ret, "test_peripheral_io_pwm_peripheral_pwm_set_enabled_n"); } +static void __test_peripheral_adc_run() +{ + int ret = PERIPHERAL_ERROR_NONE; + + ret = test_peripheral_io_adc_peripheral_adc_open_p(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_open_p"); + ret = test_peripheral_io_adc_peripheral_adc_open_n1(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_open_n1"); + ret = test_peripheral_io_adc_peripheral_adc_open_n2(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_open_n2"); + ret = test_peripheral_io_adc_peripheral_adc_open_n3(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_open_n3"); + ret = test_peripheral_io_adc_peripheral_adc_close_p(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_close_p"); + ret = test_peripheral_io_adc_peripheral_adc_close_n(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_close_n"); + ret = test_peripheral_io_adc_peripheral_adc_read_p(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_read_p"); + ret = test_peripheral_io_adc_peripheral_adc_read_n1(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_read_n1"); + ret = test_peripheral_io_adc_peripheral_adc_read_n2(); + __error_check(ret, "test_peripheral_io_adc_peripheral_adc_read_n2"); +} + static void __test_peripheral_uart_run() { int ret = PERIPHERAL_ERROR_NONE; @@ -484,11 +517,11 @@ int main(int argc, char **argv) while (1) { - printf("\n\n******************************************************************\n"); - printf("* *\n"); - printf("* MENU: 1.All 2.GPIO 3.I2C 4.PWM 5.UART 6.SPI 7.Exit *\n"); - printf("* *\n"); - printf("******************************************************************\n"); + printf("\n\n*************************************************************************\n"); + printf("* *\n"); + printf("* MENU: 1.All 2.GPIO 3.I2C 4.PWM 5.ADC 6.UART 7.SPI 8.Exit *\n"); + printf("* *\n"); + printf("*************************************************************************\n"); printf(" Input Menu : "); if (scanf("%d", &menu) < 0) return -1; @@ -509,6 +542,7 @@ int main(int argc, char **argv) __test_peripheral_gpio_run(); __test_peripheral_i2c_run(); __test_peripheral_pwm_run(); + __test_peripheral_adc_run(); __test_peripheral_uart_run(); break; case 2: @@ -521,12 +555,15 @@ int main(int argc, char **argv) __test_peripheral_pwm_run(); break; case 5: - __test_peripheral_uart_run(); + __test_peripheral_adc_run(); break; case 6: - __test_peripheral_spi_run(); + __test_peripheral_uart_run(); break; case 7: + __test_peripheral_spi_run(); + break; + case 8: printf("[Message] Close the Peripheral-IO API local Test...\n\n"); return 0; default: diff --git a/test/src/test_peripheral_adc.c b/test/src/test_peripheral_adc.c new file mode 100644 index 0000000..20595c0 --- /dev/null +++ b/test/src/test_peripheral_adc.c @@ -0,0 +1,251 @@ +/* + * 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 +#include +#include +#include "test_peripheral_adc.h" + +#define ADC_DEVICE_ARTIK530 0 +#define ADC_DEVICE_INVALID -99 +#define ADC_CHANNEL 3 +#define ADC_CHANNEL_INVALID -99 + +static bool g_feature = true; +static int device; +static int channel; + +int test_peripheral_io_adc_initialize(char *model, bool feature) +{ + g_feature = feature; + + if (!strcmp(model, "artik")) + device = ADC_DEVICE_ARTIK530; + else + return PERIPHERAL_ERROR_NO_DEVICE; + + channel = ADC_CHANNEL; + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_open_p(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + peripheral_adc_h adc_h = NULL; + + if (g_feature == false) { + ret = peripheral_adc_open(device, channel, &adc_h); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_open(device, channel, &adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + + ret = peripheral_adc_close(adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_open_n1(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (g_feature == false) { + ret = peripheral_adc_open(device, channel, NULL); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_open(device, channel, NULL); + if (ret != PERIPHERAL_ERROR_INVALID_PARAMETER) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_open_n2(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + peripheral_adc_h adc_h = NULL; + + if (g_feature == false) { + ret = peripheral_adc_open(ADC_DEVICE_INVALID, channel, &adc_h); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_open(ADC_DEVICE_INVALID, channel, &adc_h); + if (ret != PERIPHERAL_ERROR_INVALID_PARAMETER) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_open_n3(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + peripheral_adc_h adc_h = NULL; + + if (g_feature == false) { + ret = peripheral_adc_open(device, ADC_CHANNEL_INVALID, &adc_h); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_open(device, ADC_CHANNEL_INVALID, &adc_h); + if (ret != PERIPHERAL_ERROR_INVALID_PARAMETER) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_close_p(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + peripheral_adc_h adc_h = NULL; + + if (g_feature == false) { + ret = peripheral_adc_close(adc_h); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_open(device, channel, &adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + + ret = peripheral_adc_close(adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_close_n(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (g_feature == false) { + ret = peripheral_adc_close(NULL); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_close(NULL); + if (ret != PERIPHERAL_ERROR_INVALID_PARAMETER) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_read_p(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + peripheral_adc_h adc_h = NULL; + + uint32_t value; + + if (g_feature == false) { + ret = peripheral_adc_read(adc_h, &value); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_open(device, channel, &adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + + ret = peripheral_adc_read(adc_h, &value); + if (ret != PERIPHERAL_ERROR_NONE) { + peripheral_adc_close(adc_h); + return ret; + } + + ret = peripheral_adc_close(adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_read_n1(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + uint32_t value; + + if (g_feature == false) { + ret = peripheral_adc_read(NULL, &value); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_read(NULL, &value); + if (ret != PERIPHERAL_ERROR_INVALID_PARAMETER) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} + +int test_peripheral_io_adc_peripheral_adc_read_n2(void) +{ + int ret = PERIPHERAL_ERROR_NONE; + + peripheral_adc_h adc_h = NULL; + + uint32_t value; + + if (g_feature == false) { + ret = peripheral_adc_read(adc_h, &value); + if (ret != PERIPHERAL_ERROR_NOT_SUPPORTED) + return ret; + + } else { + ret = peripheral_adc_open(device, channel, &adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + + ret = peripheral_adc_read(adc_h, &value); + if (ret != PERIPHERAL_ERROR_INVALID_PARAMETER) { + peripheral_adc_close(adc_h); + return ret; + } + + ret = peripheral_adc_close(adc_h); + if (ret != PERIPHERAL_ERROR_NONE) + return ret; + } + + return PERIPHERAL_ERROR_NONE; +} -- 2.34.1