From 4f70ec201719542d860af4cd100774a05c6ad7c2 Mon Sep 17 00:00:00 2001 From: Sungguk Na Date: Thu, 25 May 2017 14:14:22 +0900 Subject: [PATCH 01/16] Additional fix to handle reference count of proxy Proxy object should be NULL after proxy deinit, but g_object_unref just make free the object and do not make it NULL Change-Id: I5ca2c14606527f5610181d6470d099fcf681c8cd Signed-off-by: Sungguk Na --- src/peripheral_gdbus_gpio.c | 2 ++ src/peripheral_gdbus_i2c.c | 2 ++ src/peripheral_gdbus_pwm.c | 2 ++ src/peripheral_gdbus_uart.c | 2 ++ 4 files changed, 8 insertions(+) diff --git a/src/peripheral_gdbus_gpio.c b/src/peripheral_gdbus_gpio.c index 1c0e90f..0bbe4f7 100644 --- a/src/peripheral_gdbus_gpio.c +++ b/src/peripheral_gdbus_gpio.c @@ -60,6 +60,8 @@ void gpio_proxy_deinit() { if (gpio_proxy) { g_object_unref(gpio_proxy); + if (!G_IS_OBJECT(gpio_proxy)) + gpio_proxy = NULL; } } diff --git a/src/peripheral_gdbus_i2c.c b/src/peripheral_gdbus_i2c.c index 2e176ef..c30399b 100644 --- a/src/peripheral_gdbus_i2c.c +++ b/src/peripheral_gdbus_i2c.c @@ -47,6 +47,8 @@ void i2c_proxy_deinit() { if (i2c_proxy) { g_object_unref(i2c_proxy); + if (!G_IS_OBJECT(i2c_proxy)) + i2c_proxy = NULL; } } diff --git a/src/peripheral_gdbus_pwm.c b/src/peripheral_gdbus_pwm.c index 31b2a78..a3b8b51 100644 --- a/src/peripheral_gdbus_pwm.c +++ b/src/peripheral_gdbus_pwm.c @@ -47,6 +47,8 @@ void pwm_proxy_deinit() { if (pwm_proxy) { g_object_unref(pwm_proxy); + if (!G_IS_OBJECT(pwm_proxy)) + pwm_proxy = NULL; } } diff --git a/src/peripheral_gdbus_uart.c b/src/peripheral_gdbus_uart.c index cf51b22..0a80e72 100644 --- a/src/peripheral_gdbus_uart.c +++ b/src/peripheral_gdbus_uart.c @@ -47,6 +47,8 @@ void uart_proxy_deinit() { if (uart_proxy) { g_object_unref(uart_proxy); + if (!G_IS_OBJECT(uart_proxy)) + uart_proxy = NULL; } } -- 2.7.4 From 46b2e09e69cce2257a90efdf5b67a5c3ce3c6f41 Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Wed, 24 May 2017 16:31:03 +0900 Subject: [PATCH 02/16] Add GPIO unit test This patch also implements menu for each tc module and utilizes glib IO channel to receive user input. Change-Id: Iedce7feab1887c822b172c30aba58b0f0eab959c Signed-off-by: Hyeongsik Min --- test/peripheral-io-test.c | 696 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 548 insertions(+), 148 deletions(-) diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index a787e10..163ffa5 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * Copyright (c) 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. @@ -14,28 +14,59 @@ * limitations under the License. */ -#include "peripheral_io.h" - #include #include #include +#include #include -extern int gpio_test(); -extern int i2c_test(); -extern int adc_test(); +#include "peripheral_io.h" + +#define BUFFER_LEN 32 -GMainLoop *loop; +typedef struct { + const char *tc_name; + int tc_code; + int (*tc_func)(void); +} tc_table_t; + +tc_table_t *tc_table; + +GMainLoop *main_loop; +GList *gpio_list; +GList *i2c_list; +GList *pwm_list; +GList *adc_list; +GList *uart_list; +GList *spi_list; + +int read_int_input(int *input) +{ + char buf[BUFFER_LEN]; + int rv; + + rv = read(0, buf, BUFFER_LEN); + + /* Ignore Enter without value */ + if (*buf == '\n' || *buf == '\r') { + printf("No input value\n"); + return -1; + } + + if (rv < 0) return -1; + *input = atoi(buf); + + return 0; +} -int gpio_test(void) +int gpio_led_test(void) { int num; int cnt = 0; peripheral_gpio_h handle = NULL; - printf("artik5 : 135 \n"); - printf("artik10 : 22 \n"); - printf(">> PIN NUMBER : "); + printf(" %s()\n", __func__); + printf("Enter GPIO pin number "); if (scanf("%d", &num) < 0) return 0; @@ -52,13 +83,13 @@ int gpio_test(void) } while (cnt++ < 5) { - printf("write~\n"); + printf("Writing..\n"); peripheral_gpio_write(handle, 1); sleep(1); peripheral_gpio_write(handle, 0); sleep(1); } - printf("write finish\n"); + printf("Write finish\n"); peripheral_gpio_close(handle); return 1; @@ -74,70 +105,66 @@ void gpio_irq_test_isr(void *user_data) peripheral_gpio_get_pin(gpio, &pin); - printf("gpio_irq_test_isr: GPIO %d interrupt occurs.\n", pin); + printf("%s: GPIO %d interrupt occurs.\n", __func__, pin); } -void *gpio_irq_test_thread(void *data) +int gpio_irq_register(void) { - peripheral_gpio_h gpio = data; - int num; - - printf(">> Press any key to exit GPIO IRQ Test : \n"); - if (scanf("%d", &num) < 0) - return 0; - - peripheral_gpio_unregister_cb(gpio); - peripheral_gpio_close(gpio); - - g_main_loop_quit(loop); - return 0; -} - -int gpio_irq_test(void) -{ - GThread *test_thread; - int num; peripheral_gpio_h gpio = NULL; - peripheral_gpio_edge_e edge = PERIPHERAL_GPIO_EDGE_NONE; + int pin, ret; - printf("artik710 : 27 \n"); - printf(">> PIN NUMBER : "); + printf(" %s()\n", __func__); + printf("Enter gpio pin number\n"); - if (scanf("%d", &num) < 0) - return 0; + if (read_int_input(&pin) < 0) + return -1; - if (peripheral_gpio_open(num, &gpio) != PERIPHERAL_ERROR_NONE) { - printf("test dev is null\n"); - return 0; + if ((ret = peripheral_gpio_open(pin, &gpio)) < 0) { + printf(">>>>> Failed to open GPIO pin, ret : %d\n", ret); + return -1; } + gpio_list = g_list_append(gpio_list, gpio); - if (peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_IN) != 0) { - printf("test set direction error!!!"); + if ((ret = peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_IN)) < 0) { + printf(">>>>> Failed to set direction, ret : %d\n", ret); goto error; } + peripheral_gpio_set_edge_mode(gpio, PERIPHERAL_GPIO_EDGE_BOTH); + peripheral_gpio_register_cb(gpio, gpio_irq_test_isr, gpio); - printf(">> Select Edge Mode (0 = None, 1 = Falling, 2 = Rising, 3 = Both) : "); - if (scanf("%d", &num) < 0) - return 0; + return 0; - if (num >= 0 && num <= 3) - edge = num; +error: + gpio_list = g_list_remove(gpio_list, gpio); + peripheral_gpio_close(gpio); + return -1; +} - peripheral_gpio_set_edge_mode( gpio, edge); - peripheral_gpio_register_cb(gpio, gpio_irq_test_isr, gpio); +int gpio_irq_unregister(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + int gpio_test_get_handle_by_pin(int pin, peripheral_gpio_h *gpio); - test_thread = g_thread_new("key input thread", &gpio_irq_test_thread, gpio); - loop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(loop); + printf(" %s()\n", __func__); + printf("Enter gpio pin number\n"); - g_thread_join(test_thread); - if (loop != NULL) - g_main_loop_unref(loop); + if (read_int_input(&pin) < 0) + return -1; - return 0; + if (gpio_test_get_handle_by_pin(pin, &gpio) < 0) { + printf(">>>>> cannot find handle. please open the gpio pin.\n"); + return -1; + } -error: + if ((ret = peripheral_gpio_unregister_cb(gpio)) < 0) { + printf(">>>>> failed to unregister callback function, ret : %d\n", ret); + return -1; + } + + gpio_list = g_list_remove(gpio_list, gpio); peripheral_gpio_close(gpio); + return 0; } @@ -149,66 +176,45 @@ error: #define GY30_READ_INTENSITY(buf) ((buf[0] << 8 | buf[1]) / 1.2) -int i2c_test(void) +int i2c_gy30_test(void) { int cnt = 0; - int bus_num; + int bus_num, ret; unsigned char buf[10]; peripheral_i2c_h i2c; - printf(">> I2C bus number : "); + printf(" %s()\n", __func__); + printf("Enter I2C bus number : "); if (scanf("%d", &bus_num) < 0) - return 0; + return -1; - if ((peripheral_i2c_open(bus_num, GY30_ADDR, &i2c)) != 0) { - printf("Failed to open I2C communication\n"); - return 0; + if ((ret = peripheral_i2c_open(bus_num, GY30_ADDR, &i2c)) < 0) { + printf("Failed to open I2C communication, ret : %d\n", ret); + return -1; } buf[0] = GY30_CONT_HIGH_RES_MODE; - if (peripheral_i2c_write(i2c, buf, 1) != 0) { - printf("Failed to write\n"); + if ((ret = peripheral_i2c_write(i2c, buf, 1)) < 0) { + printf("Failed to write, ret : %d\n", ret); goto error; } while (cnt++ < 15) { int result; sleep(1); - peripheral_i2c_read(i2c, buf, 2); + ret = peripheral_i2c_read(i2c, buf, 2); + if (ret < 0) + printf("Failed to read, ret : %d\n", ret); result = GY30_READ_INTENSITY(buf); - printf("Result [%d]\n", result); + printf("Light intensity : %d\n", result); } peripheral_i2c_close(i2c); - return 1; + return 0; error: peripheral_i2c_close(i2c); - return 0; -} - -int adc_test(void) -{ -#if 0 - int channel = 0; - int data = 0; - adc_context_h dev = NULL; - - printf(">>channel :"); - scanf("%d", &channel); - - dev = peripheral_adc_open(channel); - - if (!dev) { - printf("open error!\n"); - return 1; - } - - peripheral_adc_read(dev, &data); - - peripheral_adc_close(dev); -#endif - return 1; + return -1; } int pwm_test_led(void) @@ -222,7 +228,7 @@ int pwm_test_led(void) int get_period, get_duty_cycle; peripheral_pwm_h dev; - printf("<<< pwm_test >>>\n"); + printf(" %s()\n", __func__); peripheral_pwm_open(device, channel, &dev); peripheral_pwm_set_period(dev, period); /* period: nanosecond */ @@ -263,7 +269,7 @@ int pwm_test_motor(void) int degree[3] = {0, 45, 90}; peripheral_pwm_h dev; - printf("<<< pwm_test_motor >>>\n"); + printf(" %s()\n", __func__); peripheral_pwm_open(device, channel, &dev); for (cnt = 0; cnt < 5; cnt++) { @@ -305,25 +311,27 @@ int uart_test_accelerometer(void) int loop = 100; unsigned char buf[1024]; - printf("<<< uart_test_accelerometer >>>\n"); - printf("artik710 : 4 \n"); - printf(">> PORT NUMBER : "); + printf(" %s()\n", __func__); + printf("Enter port number"); if (scanf("%d", &port) < 0) - return 0; + return -1; ret = peripheral_uart_open(port, &uart); if (ret < 0) goto err_open; + ret = peripheral_uart_set_baudrate(uart, PERIPHERAL_UART_BAUDRATE_4800); if (ret < 0) goto out; + ret = peripheral_uart_set_mode(uart, PERIPHERAL_UART_BYTESIZE_8BIT, PERIPHERAL_UART_PARITY_NONE, PERIPHERAL_UART_STOPBITS_1BIT); if (ret < 0) goto out; + ret = peripheral_uart_set_flowcontrol(uart, true, false); if (ret < 0) goto out; @@ -347,65 +355,457 @@ int uart_test_accelerometer(void) usleep(100000); } + peripheral_uart_close(uart); + return 0; + out: peripheral_uart_close(uart); err_open: - printf(">> ret = %d\n", ret); + return -1; +} + +int gpio_test_get_handle_by_pin(int pin, peripheral_gpio_h *gpio) +{ + peripheral_gpio_h handle; + GList *cursor; + int cur_pin; + + cursor = gpio_list; + while (cursor) { + handle = (peripheral_gpio_h)cursor->data; + peripheral_gpio_get_pin(handle, &cur_pin); + if (pin == cur_pin) + break; + cursor = g_list_next(cursor); + } + if (!cursor) return -1; + + *gpio = handle; + + return 0; +} + +int print_gpio_handle(void) +{ + peripheral_gpio_h gpio; + GList *cursor; + peripheral_gpio_direction_e direction; + peripheral_gpio_edge_e edge; + int pin, value; + char *dir_str, *edge_str; + + printf("--- GPIO handle info. -------------------------------------------\n"); + printf(" No Pin Direction Value Edge mode\n"); + + cursor = gpio_list; + while (cursor) { + gpio = (peripheral_gpio_h)cursor->data; + + if (peripheral_gpio_get_pin(gpio, &pin) < 0) + continue; + if (peripheral_gpio_get_direction(gpio, &direction) < 0) + continue; + if (peripheral_gpio_get_edge_mode(gpio, &edge) < 0) + continue; + + if (direction == PERIPHERAL_GPIO_DIRECTION_IN) + dir_str = "IN"; + else if (direction == PERIPHERAL_GPIO_DIRECTION_OUT_LOW) + dir_str = "OUT_LOW"; + else if (direction == PERIPHERAL_GPIO_DIRECTION_OUT_HIGH) + dir_str = "OUT_HIGH"; + else + dir_str = "UNKNOWN"; + + if (edge == PERIPHERAL_GPIO_EDGE_NONE) + edge_str = "NONE"; + else if (edge == PERIPHERAL_GPIO_EDGE_RISING) + edge_str = "RISING"; + else if (edge == PERIPHERAL_GPIO_EDGE_FALLING) + edge_str = "FALLING"; + else if (edge == PERIPHERAL_GPIO_EDGE_BOTH) + edge_str = "BOTH"; + else + edge_str = "UNKNOWN"; + + if (direction == PERIPHERAL_GPIO_DIRECTION_IN) { + if (peripheral_gpio_read(gpio, &value) < 0) + continue; + printf("%8d%8d%12s%8d%12s\n", g_list_position(gpio_list, cursor), + pin, dir_str, value, edge_str); + } else + printf("%8d%8d%12s%20s\n", g_list_position(gpio_list, cursor), + pin, dir_str, edge_str); + + cursor = g_list_next(cursor); + } + printf("-----------------------------------------------------------------\n"); + + return 0; +} + +int gpio_test_open(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + + printf("%s\n", __func__); + printf("Enter GPIO pin number\n"); + + if (read_int_input(&pin) < 0) + return -1; + + if ((ret = peripheral_gpio_open(pin, &gpio)) < 0) { + printf(">>>>> GPIO open failed, ret : %d\n", ret); + return -1; + } + gpio_list = g_list_append(gpio_list, gpio); + print_gpio_handle(); + + return 0; +} + +int gpio_test_close(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + + printf("%s\n", __func__); + printf("Enter GPIO pin number\n"); + + if (read_int_input(&pin) < 0) + return -1; + + if (gpio_test_get_handle_by_pin(pin, &gpio) < 0) { + printf(">>>>> Cannot find handle. Please open the GPIO pin\n"); + return -1; + } + gpio_list = g_list_remove(gpio_list, gpio); + + if ((ret = peripheral_gpio_close(gpio)) < 0) { + printf(">>>>> GPIO close failed, ret : %d\n", ret); + return -1; + } + print_gpio_handle(); + + return 0; +} + +int gpio_test_set_direction(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + int direction; + + printf("%s\n", __func__); + printf("Enter gpio pin number\n"); + + if (read_int_input(&pin) < 0) + return -1; + + if (gpio_test_get_handle_by_pin(pin, &gpio) < 0) { + printf(">>>>> Cannot find handle. Please open the GPIO pin\n"); + return -1; + } + + printf("Enter direction (0:IN, 1:OUT_LOW, 2:OUT_HIGH)\n"); + if (read_int_input(&direction) < 0) + return -1; + + if (direction > PERIPHERAL_GPIO_DIRECTION_OUT_HIGH || + direction < PERIPHERAL_GPIO_DIRECTION_IN) { + printf(">>>>> Wrong input value\n"); + return -1; + } + + if ((ret = peripheral_gpio_set_direction(gpio, (peripheral_gpio_direction_e)direction)) < 0) { + printf(">>>>> Failed to set direction, ret : %d\n", ret); + return -1; + } + + return 0; +} + +int gpio_test_write(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + int value; + + printf("%s\n", __func__); + printf("Enter gpio pin number\n"); + + if (read_int_input(&pin) < 0) + return -1; + + if (gpio_test_get_handle_by_pin(pin, &gpio) < 0) { + printf(">>>>> Cannot find handle. Please open the GPIO pin\n"); + return -1; + } + + printf("Enter value (0:LOW, 1:HIGH)\n"); + if (read_int_input(&value) < 0) + return -1; + + if (value < 0 || value > 1) { + printf(">>>>> Wrong input value\n"); + return -1; + } + + if ((ret = peripheral_gpio_write(gpio, value)) < 0) { + printf(">>>>> Failed to write value, ret : %d\n", ret); + return -1; + } + + return 0; +} + +int gpio_test_set_edge_mode(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + int edge; + + printf("%s\n", __func__); + printf("Enter gpio pin number\n"); + + if (read_int_input(&pin) < 0) + return -1; + + if (gpio_test_get_handle_by_pin(pin, &gpio) < 0) { + printf(">>>>> Cannot find handle. Please open the GPIO pin\n"); + return -1; + } + + printf("Enter edge mode (0:NONE, 1:RISING, 2:FALLING, 3:BOTH)\n"); + if (read_int_input(&edge) < 0) + return -1; + + if (edge < PERIPHERAL_GPIO_EDGE_NONE || edge > PERIPHERAL_GPIO_EDGE_BOTH) { + printf(">>>>> Wrong input value\n"); + return -1; + } + + if ((ret = peripheral_gpio_set_edge_mode(gpio, (peripheral_gpio_edge_e)edge)) < 0) { + printf(">>>>> Failed to set edge mode, ret : %d\n", ret); + return -1; + } + + return 0; +} + +int gpio_test_set_register_cb(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + + printf("%s\n", __func__); + printf("Enter gpio pin number\n"); + + if (read_int_input(&pin) < 0) + return -1; + + if (gpio_test_get_handle_by_pin(pin, &gpio) < 0) { + printf(">>>>> Cannot find handle. Please open the GPIO pin\n"); + return -1; + } + + if ((ret = peripheral_gpio_register_cb(gpio, gpio_irq_test_isr, gpio)) < 0) { + printf(">>>>> Failed to register callback function, ret : %d\n", ret); + return -1; + } + return 0; +} + +int gpio_test_set_unregister_cb(void) +{ + peripheral_gpio_h gpio; + int pin, ret; + + printf("%s\n", __func__); + printf("Enter gpio pin number\n"); + + if (read_int_input(&pin) < 0) + return -1; + + if (gpio_test_get_handle_by_pin(pin, &gpio) < 0) { + printf(">>>>> Cannot find handle. Please open the GPIO pin\n"); + return -1; + } + + if ((ret = peripheral_gpio_unregister_cb(gpio)) < 0) { + printf(">>>>> failed to unregister callback function, ret : %d\n", ret); + return -1; + } + return 0; } +int enter_main(void); + +tc_table_t gpio_tc_table[] = { + {"Open GPIO pin", 1, gpio_test_open}, + {"Close GPIO pin", 2, gpio_test_close}, + {"Set direction GPIO pin", 3, gpio_test_set_direction}, + {"Write value to GPIO pin", 4, gpio_test_write}, + {"Set edge mode", 5, gpio_test_set_edge_mode}, + {"Register callback", 6, gpio_test_set_register_cb}, + {"Unregister callback", 7, gpio_test_set_unregister_cb}, + {"Print GPIO handle", 9, print_gpio_handle}, + {"Go back to main", 0, enter_main}, + {NULL, 0, NULL}, +}; + +int enter_gpio_test(void) +{ + tc_table = gpio_tc_table; + print_gpio_handle(); + + return 0; +} + +int enter_i2c_test(void) +{ + return 0; +} + +int enter_pwm_test(void) +{ + return 0; +} + +int enter_adc_test(void) +{ + return 0; +} + +int enter_uart_test(void) +{ + return 0; +} + +int enter_spi_test(void) +{ + return 0; +} + +int terminate_test(void) +{ + int ret = 0; + + printf("Terminate test\n"); + g_main_loop_quit(main_loop); + + exit(1); + + return ret; +} + +tc_table_t main_tc_table[] = { + {"GPIO Test Menu", 1, enter_gpio_test}, + {"I2C Test Menu", 2, enter_i2c_test}, + {"PWM Test Menu", 3, enter_pwm_test}, + {"ADC Test Menu", 4, enter_adc_test}, + {"UART Test Menu", 5, enter_uart_test}, + {"SPI Test Menu", 6, enter_spi_test}, + {"[Preset Test] GPIO LED", 11, gpio_led_test}, + {"[Preset Test] I2C GY30 Light sensor", 12, i2c_gy30_test}, + {"[Preset Test] PWM LED", 14, pwm_test_led}, + {"[Preset Test] PWM Motor", 15, pwm_test_motor}, + {"[Preset Test] Uart Accelerometer", 16, uart_test_accelerometer}, + {"[Preset Test] GPIO IRQ register", 17, gpio_irq_register}, + {"[Preset Test] GPIO IRQ unregister", 18, gpio_irq_unregister}, + {"Exit Test", 0, terminate_test}, + {NULL, 0, NULL}, +}; + +int enter_main(void) +{ + tc_table = main_tc_table; + + return 0; +} + +static int test_input_callback(void *data) +{ + long test_id = (long)data; + int ret = PERIPHERAL_ERROR_NONE; + int i = 0; + + while (tc_table[i].tc_name) { + if (tc_table[i].tc_code == test_id) { + ret = tc_table[i].tc_func(); + + if (ret != PERIPHERAL_ERROR_NONE) + printf(">>>>> Test Error Returned !!! : %d\n", ret); + + break; + } + i++; + } + if (!tc_table[i].tc_name) { + printf(">>>>> Wrong input value!\n"); + return -1; + } + + return 0; +} + +static void print_tc_usage(void) +{ + int i = 0; + + printf("===========================================\n"); + while (tc_table[i].tc_name) { + printf(" %2d : %s\n", tc_table[i].tc_code, tc_table[i].tc_name); + i++; + } + printf("===========================================\n"); + printf("Enter TC number\n"); +} + +static gboolean key_event_cb(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + char buf[BUFFER_LEN] = {0,}; + long test_id; + int rv = 0; + + memset(buf, 0, sizeof(buf)); + + rv = read(0, buf, BUFFER_LEN); + + if (*buf == '\n' || *buf == '\r') { + print_tc_usage(); + return TRUE; + } + + if (rv < 0) return FALSE; + + test_id = atoi(buf); + + test_input_callback((void *)test_id); + print_tc_usage(); + + return TRUE; +} + int main(int argc, char **argv) { - int num = 1; - int ret; + GIOChannel *key_io; - printf("===================\n"); - printf(" test Menu\n"); - printf("===================\n"); - printf(" 1. GPIO Test\n"); - printf(" 2. I2C Test\n"); - printf(" 3. pwm led test\n"); - printf(" 4. pwm motor test\n"); - printf(" 5. uart accelerometer test\n"); + main_loop = g_main_loop_new(NULL, FALSE); + key_io = g_io_channel_unix_new(0); - printf(" 11. GPIO Interrupt Test\n"); - printf(" 12. H/W IF I2C Test\n"); - printf(" 13. H/W IF PWM Test\n"); - printf(" 14. H/W IF SPI Test\n"); + tc_table = main_tc_table; - if (scanf("%d", &num) < 0) - return 0; + print_tc_usage(); + g_io_add_watch(key_io, (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL), key_event_cb, NULL); - switch (num) { - case 1: - ret = gpio_test(); - break; - case 2: - ret = i2c_test(); - break; - case 3: - ret = pwm_test_led(); - break; - case 4: - ret = pwm_test_motor(); - break; - case 5: - ret = uart_test_accelerometer(); - break; - case 11: - ret = gpio_irq_test(); - break; - case 12: - ret = i2c_test(); - break; - case 14: - ret = adc_test(); - break; - default: - printf("Not support \n"); - } - printf(" return : %d\n", ret); + g_main_loop_run(main_loop); - return 1; + g_io_channel_unref(key_io); + g_main_loop_unref(main_loop); + + return 0; } -- 2.7.4 From 26272320cf0cf2d34c7272d72f62e95c18907fa9 Mon Sep 17 00:00:00 2001 From: Sungguk Na Date: Thu, 25 May 2017 19:34:13 +0900 Subject: [PATCH 03/16] Change argument of gpio gdbus method - The gpio methods will pass handle instead of device informations. - Some arguments of gpio handle are removed. Change-Id: I6a0910cbd5e03878c17e5c6426850dbd2865ada4 Signed-off-by: Sungguk Na --- include/peripheral_internal.h | 3 +-- src/peripheral_gdbus_gpio.c | 25 ++++++++++--------------- src/peripheral_gpio.c | 8 -------- src/peripheral_io.xml | 21 ++++++++++----------- 4 files changed, 21 insertions(+), 36 deletions(-) diff --git a/include/peripheral_internal.h b/include/peripheral_internal.h index 85263aa..34f09b0 100644 --- a/include/peripheral_internal.h +++ b/include/peripheral_internal.h @@ -22,8 +22,7 @@ */ struct _peripheral_gpio_s { int pin; - peripheral_gpio_direction_e direction; - peripheral_gpio_edge_e edge; + uint handle; }; /** diff --git a/src/peripheral_gdbus_gpio.c b/src/peripheral_gdbus_gpio.c index 0bbe4f7..721b3d4 100644 --- a/src/peripheral_gdbus_gpio.c +++ b/src/peripheral_gdbus_gpio.c @@ -89,8 +89,7 @@ int peripheral_gdbus_gpio_open(peripheral_gpio_h gpio) if (peripheral_io_gdbus_gpio_call_open_sync( gpio_proxy, gpio->pin, - (gint*)&gpio->edge, - (gint*)&gpio->direction, + &gpio->handle, &ret, NULL, &error) == FALSE) { @@ -111,7 +110,7 @@ int peripheral_gdbus_gpio_close(peripheral_gpio_h gpio) if (peripheral_io_gdbus_gpio_call_close_sync( gpio_proxy, - gpio->pin, + gpio->handle, &ret, NULL, &error) == FALSE) { @@ -132,7 +131,7 @@ int peripheral_gdbus_gpio_get_direction(peripheral_gpio_h gpio, peripheral_gpio_ if (peripheral_io_gdbus_gpio_call_get_direction_sync( gpio_proxy, - gpio->pin, + gpio->handle, (gint*)direction, &ret, NULL, @@ -141,7 +140,6 @@ int peripheral_gdbus_gpio_get_direction(peripheral_gpio_h gpio, peripheral_gpio_ g_error_free(error); return PERIPHERAL_ERROR_UNKNOWN; } - gpio->direction = *direction; return ret; } @@ -155,7 +153,7 @@ int peripheral_gdbus_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_ if (peripheral_io_gdbus_gpio_call_set_direction_sync( gpio_proxy, - gpio->pin, + gpio->handle, direction, &ret, NULL, @@ -164,7 +162,6 @@ int peripheral_gdbus_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_ g_error_free(error); return PERIPHERAL_ERROR_UNKNOWN; } - gpio->direction = direction; return ret; } @@ -178,7 +175,7 @@ int peripheral_gdbus_gpio_read(peripheral_gpio_h gpio, int *value) if (peripheral_io_gdbus_gpio_call_read_sync( gpio_proxy, - gpio->pin, + gpio->handle, value, &ret, NULL, @@ -200,7 +197,7 @@ int peripheral_gdbus_gpio_write(peripheral_gpio_h gpio, int value) if (peripheral_io_gdbus_gpio_call_write_sync( gpio_proxy, - gpio->pin, + gpio->handle, value, &ret, NULL, @@ -222,7 +219,7 @@ int peripheral_gdbus_gpio_get_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_ if (peripheral_io_gdbus_gpio_call_get_edge_mode_sync( gpio_proxy, - gpio->pin, + gpio->handle, (int*)edge, &ret, NULL, @@ -231,7 +228,6 @@ int peripheral_gdbus_gpio_get_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_ g_error_free(error); return PERIPHERAL_ERROR_UNKNOWN; } - gpio->edge = *edge; return ret; } @@ -245,7 +241,7 @@ int peripheral_gdbus_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_ if (peripheral_io_gdbus_gpio_call_set_edge_mode_sync( gpio_proxy, - gpio->pin, + gpio->handle, edge, &ret, NULL, @@ -254,7 +250,6 @@ int peripheral_gdbus_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_ g_error_free(error); return PERIPHERAL_ERROR_UNKNOWN; } - gpio->edge = edge; return ret; } @@ -268,7 +263,7 @@ int peripheral_gdbus_gpio_register_cb(peripheral_gpio_h gpio, gpio_isr_cb callba if (peripheral_io_gdbus_gpio_call_register_irq_sync( gpio_proxy, - gpio->pin, + gpio->handle, &ret, NULL, &error) == FALSE) { @@ -289,7 +284,7 @@ int peripheral_gdbus_gpio_unregister_cb(peripheral_gpio_h gpio) if (peripheral_io_gdbus_gpio_call_unregister_irq_sync( gpio_proxy, - gpio->pin, + gpio->handle, &ret, NULL, &error) == FALSE) { diff --git a/src/peripheral_gpio.c b/src/peripheral_gpio.c index 2b3bd20..e49477c 100644 --- a/src/peripheral_gpio.c +++ b/src/peripheral_gpio.c @@ -176,8 +176,6 @@ int peripheral_gpio_get_direction(peripheral_gpio_h gpio, peripheral_gpio_direct return PERIPHERAL_ERROR_INVALID_PARAMETER; ret = peripheral_gdbus_gpio_get_direction(gpio, direction); - if (ret == PERIPHERAL_ERROR_NONE) - gpio->direction = (*direction); return ret; } @@ -199,8 +197,6 @@ int peripheral_gpio_set_direction(peripheral_gpio_h gpio, peripheral_gpio_direct /* call gpio_set_direction */ ret = peripheral_gdbus_gpio_set_direction(gpio, direction); - if (ret == PERIPHERAL_ERROR_NONE) - gpio->direction = direction; return ret; } @@ -251,8 +247,6 @@ int peripheral_gpio_get_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e return PERIPHERAL_ERROR_INVALID_PARAMETER; ret = peripheral_gdbus_gpio_get_edge_mode(gpio, edge); - if (ret == PERIPHERAL_ERROR_NONE) - gpio->edge = (*edge); return ret; } @@ -273,8 +267,6 @@ int peripheral_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e /* call gpio_set_edge_mode */ ret = peripheral_gdbus_gpio_set_edge_mode(gpio, edge); - if (ret == PERIPHERAL_ERROR_NONE) - gpio->edge = edge; return ret; } diff --git a/src/peripheral_io.xml b/src/peripheral_io.xml index abc3679..2480f92 100644 --- a/src/peripheral_io.xml +++ b/src/peripheral_io.xml @@ -3,50 +3,49 @@ - - + - + - + - + - + - + - + - + - + - + -- 2.7.4 From 1afae1b2e619a3cfca9697930daac0a16443efc1 Mon Sep 17 00:00:00 2001 From: "jino.cho" Date: Thu, 18 May 2017 19:25:15 +0900 Subject: [PATCH 04/16] Add description for pwm APIs This patch Adds description for pwm APIs. Change-Id: I1dc40bf40e4405616c5f719d905680bf31d783e0 Signed-off-by: jino.cho --- include/peripheral_io.h | 157 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) diff --git a/include/peripheral_io.h b/include/peripheral_io.h index 1000993..c68ff98 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -383,25 +383,180 @@ typedef enum { PERIPHERAL_PWM_POLARITY_INVERSED, } peripheral_pwm_polarity_e; +/** + * @brief Initializes(export) pwm device and creates pwm handle. + * @since_tizen 4.0 + * + * @param[in] device The pwm chip number + * @param[in] channel The pwm channel number to control + * @param[out] pwm The pwm 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_OUT_OF_MEMORY Memory allocation failed + * @retval #PERIPHERAL_ERROR_RESOURCE_BUSY Device is in use + * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + * + * @see peripheral_pwm_close() + */ int peripheral_pwm_open(int device, int channel, peripheral_pwm_h *pwm); +/** + * @brief Destory the pwm handle and finalize(unexport) the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + * + * @see peripheral_pwm_open() + */ int peripheral_pwm_close(peripheral_pwm_h pwm); - +/** + * @brief Sets Period of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[in] period The total period of the PWM signal (in nanoseconds) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_set_period(peripheral_pwm_h pwm, int period); +/** + * @brief Gets Period of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[out] period The total period of the PWM signal (in nanoseconds) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_get_period(peripheral_pwm_h pwm, int *period); +/** + * @brief Sets Duty Cycle of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[in] duty_cycle The active time of the pwm signal (in nanoseconds) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_set_duty_cycle(peripheral_pwm_h pwm, int duty_cycle); +/** + * @brief Gets Duty Cycle of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[out] duty_cycle The active time of the pwm signal (in nanoseconds) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_get_duty_cycle(peripheral_pwm_h pwm, int *duty_cycle); +/** + * @brief Sets Polarity of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[in] polarity The polarity of the pwm signal + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_set_polarity(peripheral_pwm_h pwm, peripheral_pwm_polarity_e polarity); +/** + * @brief Gets Polarity of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[out] polarity The polarity of the pwm signal + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_get_polarity(peripheral_pwm_h pwm, peripheral_pwm_polarity_e *polarity); +/** + * @brief Enable of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[in] enable Enable/disable the pwm signal + * true - enable + * false - disable + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_set_enable(peripheral_pwm_h pwm, bool enable); +/** + * @brief Gets Enable status of the pwm device. + * @since_tizen 4.0 + * + * @param[in] pwm The handle to the pwm device + * @param[out] enable Enable/disable the pwm signal + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_INVALID_OPERATION Invalid access + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ int peripheral_pwm_get_enable(peripheral_pwm_h pwm, bool *enable); /** -- 2.7.4 From df9f456867311136429eb4d41cddcf55d5f9feeb Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Thu, 25 May 2017 20:51:33 +0900 Subject: [PATCH 05/16] Add preset test for MMA7455 accel. sensor Change-Id: I51ed963015963f48d8b78db80a4ff6c4ac0bfc6f Signed-off-by: Hyeongsik Min --- test/peripheral-io-test.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index 163ffa5..fb90703 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -217,6 +217,76 @@ error: return -1; } +#define MMA_7455_ADDRESS 0x1D //I2C Address for the sensor +#define MMA_7455_MODE_CONTROL 0x16 //Call the sensors Mode Control + +#define MMA_7455_2G_MODE 0x04 //Set Sensitivity to 2g +#define MMA_7455_4G_MODE 0x08 //Set Sensitivity to 4g +#define MMA_7455_8G_MODE 0x00 //Set Sensitivity to 8g + +#define MMA_7455_STANDBY_MODE 0x0 +#define MMA_7455_MEASUREMENT_MODE 0x1 +#define MMA_7455_LEVEL_DETECTION_MODE 0x2 +#define MMA_7455_PULSE_DETECTION_MODE 0x3 + +#define X_OUT 0x06 //Register for reading the X-Axis +#define Y_OUT 0x07 //Register for reading the Y-Axis +#define Z_OUT 0x08 //Register for reading the Z-Axis + +int i2c_mma7455_test(void) +{ + int cnt = 0; + int bus_num, ret; + unsigned char buf[10]; + peripheral_i2c_h i2c; + + printf(" %s()\n", __func__); + printf("Enter I2C bus number"); + if (scanf("%d", &bus_num) < 0) + return -1; + + if ((ret = peripheral_i2c_open(bus_num, MMA_7455_ADDRESS, &i2c)) < 0) { + printf(">>>>> Failed to open I2C communication, ret : %d \n", ret); + return -1; + } + + buf[0] = MMA_7455_MODE_CONTROL; + buf[1] = MMA_7455_2G_MODE | MMA_7455_LEVEL_DETECTION_MODE; + if ((ret = peripheral_i2c_write(i2c, buf, 2)) != 0) { + printf(">>>>> Failed to write, ret : %d\n", ret); + goto error; + } + + while (cnt++ < 10) { + int x_pos, y_pos, z_pos; + sleep(1); + + buf[0] = X_OUT; + peripheral_i2c_write(i2c, buf, 1); + peripheral_i2c_read(i2c, buf, 1); + x_pos = (int)buf[0]; + + buf[0] = Y_OUT; + peripheral_i2c_write(i2c, buf, 1); + peripheral_i2c_read(i2c, buf, 1); + y_pos = (int)buf[0]; + + buf[0] = Z_OUT; + peripheral_i2c_write(i2c, buf, 1); + peripheral_i2c_read(i2c, buf, 1); + z_pos = (int)buf[0]; + + printf("Result X : %d, Y : %d, Z : %d\n", x_pos, y_pos, z_pos); + } + + peripheral_i2c_close(i2c); + return 0; + +error: + peripheral_i2c_close(i2c); + return -1; +} + int pwm_test_led(void) { int device = 0, channel = 0; @@ -711,6 +781,7 @@ tc_table_t main_tc_table[] = { {"SPI Test Menu", 6, enter_spi_test}, {"[Preset Test] GPIO LED", 11, gpio_led_test}, {"[Preset Test] I2C GY30 Light sensor", 12, i2c_gy30_test}, + {"[Preset Test] I2C MMA7455 Accel. sensor", 13, i2c_mma7455_test}, {"[Preset Test] PWM LED", 14, pwm_test_led}, {"[Preset Test] PWM Motor", 15, pwm_test_motor}, {"[Preset Test] Uart Accelerometer", 16, uart_test_accelerometer}, -- 2.7.4 From a494140fba1f58594a2d51f9a417b2a99bed43ef Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Mon, 29 May 2017 19:27:55 +0900 Subject: [PATCH 06/16] Add sub menu for preset test Change-Id: I5dd21166781377d15df3535be6fb2212f886203c Signed-off-by: Hyeongsik Min --- test/peripheral-io-test.c | 62 ++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index fb90703..fa7e18e 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -61,7 +61,7 @@ int read_int_input(int *input) int gpio_led_test(void) { - int num; + int num, ret; int cnt = 0; peripheral_gpio_h handle = NULL; @@ -69,16 +69,16 @@ int gpio_led_test(void) printf("Enter GPIO pin number "); if (scanf("%d", &num) < 0) - return 0; + return -1; printf("num %d\n", num); - if (peripheral_gpio_open(num, &handle) != PERIPHERAL_ERROR_NONE) { - printf("handle is null\n"); - return 0; + if ((ret = peripheral_gpio_open(num, &handle)) < PERIPHERAL_ERROR_NONE) { + printf("Failed to open\n"); + return ret; } - if (peripheral_gpio_set_direction(handle, PERIPHERAL_GPIO_DIRECTION_OUT) != PERIPHERAL_ERROR_NONE) { - printf("set direction error!!!"); + if ((ret = peripheral_gpio_set_direction(handle, PERIPHERAL_GPIO_DIRECTION_OUT)) < PERIPHERAL_ERROR_NONE) { + printf("Failed to set direction!!\n"); goto error; } @@ -90,12 +90,16 @@ int gpio_led_test(void) sleep(1); } printf("Write finish\n"); - peripheral_gpio_close(handle); - return 1; + if ((ret = peripheral_gpio_close(handle)) < PERIPHERAL_ERROR_NONE) { + printf("Failed to close the pin\n"); + return ret; + } + + return 0; error: peripheral_gpio_close(handle); - return 0; + return ret; } void gpio_irq_test_isr(void *user_data) @@ -760,6 +764,25 @@ int enter_spi_test(void) return 0; } +tc_table_t preset_tc_table[] = { + {"[Preset Test] GPIO LED", 1, gpio_led_test}, + {"[Preset Test] I2C GY30 Light sensor", 2, i2c_gy30_test}, + {"[Preset Test] I2C MMA7455 Accel. sensor", 3, i2c_mma7455_test}, + {"[Preset Test] PWM LED", 4, pwm_test_led}, + {"[Preset Test] PWM Motor", 5, pwm_test_motor}, + {"[Preset Test] Uart Accelerometer", 6, uart_test_accelerometer}, + {"[Preset Test] GPIO IRQ register", 7, gpio_irq_register}, + {"[Preset Test] GPIO IRQ unregister", 8, gpio_irq_unregister}, + {"Go back to main", 0, enter_main}, + {NULL, 0, NULL}, +}; + +int enter_preset_test(void) +{ + tc_table = preset_tc_table; + return 0; +} + int terminate_test(void) { int ret = 0; @@ -779,14 +802,7 @@ tc_table_t main_tc_table[] = { {"ADC Test Menu", 4, enter_adc_test}, {"UART Test Menu", 5, enter_uart_test}, {"SPI Test Menu", 6, enter_spi_test}, - {"[Preset Test] GPIO LED", 11, gpio_led_test}, - {"[Preset Test] I2C GY30 Light sensor", 12, i2c_gy30_test}, - {"[Preset Test] I2C MMA7455 Accel. sensor", 13, i2c_mma7455_test}, - {"[Preset Test] PWM LED", 14, pwm_test_led}, - {"[Preset Test] PWM Motor", 15, pwm_test_motor}, - {"[Preset Test] Uart Accelerometer", 16, uart_test_accelerometer}, - {"[Preset Test] GPIO IRQ register", 17, gpio_irq_register}, - {"[Preset Test] GPIO IRQ unregister", 18, gpio_irq_unregister}, + {"Preset Test", 10, enter_preset_test}, {"Exit Test", 0, terminate_test}, {NULL, 0, NULL}, }; @@ -800,14 +816,16 @@ int enter_main(void) static int test_input_callback(void *data) { + tc_table_t *tc; long test_id = (long)data; int ret = PERIPHERAL_ERROR_NONE; int i = 0; - while (tc_table[i].tc_name) { - if (tc_table[i].tc_code == test_id) { - ret = tc_table[i].tc_func(); + tc = tc_table; + while (tc[i].tc_name) { + if (tc[i].tc_code == test_id && tc[i].tc_func) { + ret = tc[i].tc_func(); if (ret != PERIPHERAL_ERROR_NONE) printf(">>>>> Test Error Returned !!! : %d\n", ret); @@ -815,7 +833,7 @@ static int test_input_callback(void *data) } i++; } - if (!tc_table[i].tc_name) { + if (!tc[i].tc_name) { printf(">>>>> Wrong input value!\n"); return -1; } -- 2.7.4 From 6402d036ce0b37a062d9d6506c75081f7d22cdaa Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Tue, 30 May 2017 11:25:18 +0900 Subject: [PATCH 07/16] Add i2c_write_byte, i2c_read_byte API In order to provide for single byte communication, this patch adds peripheral_i2c_write_byte() and peripheral_i2c_read_byte() APIs. Change-Id: I0b1404fc1571f6d21ab7bfa5ceb9a76cb8a3e936 Signed-off-by: Hyeongsik Min --- include/peripheral_io.h | 32 ++++++++++++++++++++++++++++++-- src/peripheral_i2c.c | 18 ++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/include/peripheral_io.h b/include/peripheral_io.h index c68ff98..7517d2a 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -332,7 +332,7 @@ int peripheral_i2c_close(peripheral_i2c_h i2c); * @since_tizen 4.0 * * @param[in] i2c The handle to the i2c device - * @param[in, out] data The address of read buffer + * @param[out] data The address of data buffer to read * @param[in] length The size of data buffer (in bytes) * * @return 0 on success, otherwise a negative error value @@ -348,7 +348,7 @@ int peripheral_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length); * @since_tizen 4.0 * * @param[in] i2c The handle to the i2c device - * @param[in, out] data The address of buffer to write + * @param[in] data The address of data buffer to write * @param[in] length The size of data buffer (in bytes) * * @return 0 on success, otherwise a negative error value @@ -359,6 +359,34 @@ int peripheral_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length); */ int peripheral_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length); +/** + * @brief Reads single byte data from the i2c device. + * @since_tizen 4.0 + * + * @param[in] i2c The handle to the i2c device + * @param[out] data The address of data buffer to read + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_i2c_read_byte(peripheral_i2c_h i2c, uint8_t *data); +/** + * @brief Write single byte data to the i2c device. + * @since_tizen 4.0 + * + * @param[in] i2c The handle to the i2c device + * @param[in] data The byte value to write + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_i2c_write_byte(peripheral_i2c_h i2c, uint8_t data); /** * @} diff --git a/src/peripheral_i2c.c b/src/peripheral_i2c.c index fee3a32..969e18b 100644 --- a/src/peripheral_i2c.c +++ b/src/peripheral_i2c.c @@ -89,3 +89,21 @@ int peripheral_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length) return peripheral_gdbus_i2c_write(i2c, data, length); } + +int peripheral_i2c_read_byte(peripheral_i2c_h i2c, uint8_t *data) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (i2c == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + ret = peripheral_gdbus_i2c_read(i2c, data, 0x1); + + return ret; +} + +int peripheral_i2c_write_byte(peripheral_i2c_h i2c, uint8_t data) +{ + if (i2c == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_i2c_write(i2c, &data, 0x1); +} -- 2.7.4 From b97f3396f26f6218964e10103197754f29aa482a Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Tue, 30 May 2017 19:13:16 +0900 Subject: [PATCH 08/16] Fix leak issue after reading byte array Calling g_variant_unref() was missing in the routine. Change-Id: Ie7cdfe86cab92c727397ddf31a062d8707cc65db Signed-off-by: Hyeongsik Min --- src/peripheral_gdbus_i2c.c | 1 + src/peripheral_gdbus_uart.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/peripheral_gdbus_i2c.c b/src/peripheral_gdbus_i2c.c index c30399b..1b296f1 100644 --- a/src/peripheral_gdbus_i2c.c +++ b/src/peripheral_gdbus_i2c.c @@ -126,6 +126,7 @@ int peripheral_gdbus_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length) if (i++ == length) break; } g_variant_iter_free(iter); + g_variant_unref(data_array); return ret; } diff --git a/src/peripheral_gdbus_uart.c b/src/peripheral_gdbus_uart.c index 0a80e72..a727f1a 100644 --- a/src/peripheral_gdbus_uart.c +++ b/src/peripheral_gdbus_uart.c @@ -215,6 +215,7 @@ int peripheral_gdbus_uart_read(peripheral_uart_h uart, uint8_t *data, int length if (i++ == length) break; } g_variant_iter_free(iter); + g_variant_unref(data_array); return ret; } -- 2.7.4 From fcd26a2f05f56ccba66a478b67381c9aa4884ca4 Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Tue, 30 May 2017 20:05:13 +0900 Subject: [PATCH 09/16] Improve MMA7455 Accelerometer test(I2C) If it receives gpio pin number for interrupt, the test will register isr function to react to sensor interrupt. Change-Id: I192db1ca642890672f5b216dbddb80cbb98f65d5 Signed-off-by: Hyeongsik Min --- test/peripheral-io-test.c | 166 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 123 insertions(+), 43 deletions(-) diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index fa7e18e..1ec14eb 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -188,8 +188,9 @@ int i2c_gy30_test(void) peripheral_i2c_h i2c; printf(" %s()\n", __func__); - printf("Enter I2C bus number : "); - if (scanf("%d", &bus_num) < 0) + printf("Enter I2C bus number\n"); + + if (read_int_input(&bus_num) < 0) return -1; if ((ret = peripheral_i2c_open(bus_num, GY30_ADDR, &i2c)) < 0) { @@ -197,8 +198,7 @@ int i2c_gy30_test(void) return -1; } - buf[0] = GY30_CONT_HIGH_RES_MODE; - if ((ret = peripheral_i2c_write(i2c, buf, 1)) < 0) { + if ((ret = peripheral_i2c_write_byte(i2c, GY30_CONT_HIGH_RES_MODE)) < 0) { printf("Failed to write, ret : %d\n", ret); goto error; } @@ -221,73 +221,153 @@ error: return -1; } -#define MMA_7455_ADDRESS 0x1D //I2C Address for the sensor -#define MMA_7455_MODE_CONTROL 0x16 //Call the sensors Mode Control +#define MMA7455_ADDRESS 0x1D //I2C Address for the sensor + +#define MMA7455_MCTL 0x16 // Mode Control + +#define MMA7455_MCTL_STANDBY_MODE 0x0 +#define MMA7455_MCTL_MEASUREMENT_MODE 0x01 +#define MMA7455_MCTL_LEVEL_DETECTION_MODE 0x02 +#define MMA7455_MCTL_PULSE_DETECTION_MODE 0x03 +#define MMA7455_MCTL_2G 0x04 //Set Sensitivity to 2g +#define MMA7455_MCTL_4G 0x08 //Set Sensitivity to 4g +#define MMA7455_MCTL_8G 0x00 //Set Sensitivity to 8g + +#define MMA7455_INTRST 0x17 + +#define MMA7455_CONTROL1 0x18 +#define MMA7455_CONTROL1_INTREG 0x06 +#define MMA7455_CONTROL1_DFBW 0x80 + +#define MMA7455_XOUT8 0x06 //Register for reading the X-Axis +#define MMA7455_YOUT8 0x07 //Register for reading the Y-Axis +#define MMA7455_ZOUT8 0x08 //Register for reading the Z-Axis + +static void i2c_mma7455_isr(void *user_data) +{ + peripheral_i2c_h i2c = user_data; + int x_pos, y_pos, z_pos; + uint8_t buf[4]; -#define MMA_7455_2G_MODE 0x04 //Set Sensitivity to 2g -#define MMA_7455_4G_MODE 0x08 //Set Sensitivity to 4g -#define MMA_7455_8G_MODE 0x00 //Set Sensitivity to 8g + peripheral_i2c_write_byte(i2c, MMA7455_XOUT8); + peripheral_i2c_read_byte(i2c, buf); + x_pos = (int)buf[0]; -#define MMA_7455_STANDBY_MODE 0x0 -#define MMA_7455_MEASUREMENT_MODE 0x1 -#define MMA_7455_LEVEL_DETECTION_MODE 0x2 -#define MMA_7455_PULSE_DETECTION_MODE 0x3 + peripheral_i2c_write_byte(i2c, MMA7455_YOUT8); + peripheral_i2c_read_byte(i2c, buf); + y_pos = (int)buf[0]; -#define X_OUT 0x06 //Register for reading the X-Axis -#define Y_OUT 0x07 //Register for reading the Y-Axis -#define Z_OUT 0x08 //Register for reading the Z-Axis + peripheral_i2c_write_byte(i2c, MMA7455_ZOUT8); + peripheral_i2c_read_byte(i2c, buf); + z_pos = (int)buf[0]; + + printf("Result X : %d, Y : %d, Z : %d\n", x_pos, y_pos, z_pos); + + /* Reset interrupt flags */ + buf[0] = MMA7455_INTRST; + buf[1] = 0x3; + peripheral_i2c_write(i2c, buf, 2); + buf[1] = 0x0; + peripheral_i2c_write(i2c, buf, 2); + + return; +} int i2c_mma7455_test(void) { + static peripheral_i2c_h i2c; + static peripheral_gpio_h isr_gpio; + unsigned char buf[4]; + int bus_num, gpio_num, ret; int cnt = 0; - int bus_num, ret; - unsigned char buf[10]; - peripheral_i2c_h i2c; printf(" %s()\n", __func__); - printf("Enter I2C bus number"); - if (scanf("%d", &bus_num) < 0) + if (i2c) { + printf("Disabling the test\n"); + + peripheral_i2c_close(i2c); + i2c = NULL; + printf("i2c(bus = %d address = %d) handle is closed\n", bus_num, MMA7455_ADDRESS); + + if (isr_gpio) { + peripheral_gpio_close(isr_gpio); + isr_gpio = NULL; + printf("isr_gpio handle is closed\n"); + } + + return 0; + } + + printf("Enter I2C bus number\n"); + + if (read_int_input(&bus_num) < 0) return -1; - if ((ret = peripheral_i2c_open(bus_num, MMA_7455_ADDRESS, &i2c)) < 0) { + if ((ret = peripheral_i2c_open(bus_num, MMA7455_ADDRESS, &i2c)) < 0) { printf(">>>>> Failed to open I2C communication, ret : %d \n", ret); return -1; } - buf[0] = MMA_7455_MODE_CONTROL; - buf[1] = MMA_7455_2G_MODE | MMA_7455_LEVEL_DETECTION_MODE; + buf[0] = MMA7455_MCTL; + buf[1] = MMA7455_MCTL_8G | MMA7455_MCTL_PULSE_DETECTION_MODE; if ((ret = peripheral_i2c_write(i2c, buf, 2)) != 0) { printf(">>>>> Failed to write, ret : %d\n", ret); goto error; } - while (cnt++ < 10) { - int x_pos, y_pos, z_pos; - sleep(1); + printf("Enter GPIO pin number for Interrupt\n"); + if (read_int_input(&gpio_num) < 0) + gpio_num = -1; - buf[0] = X_OUT; - peripheral_i2c_write(i2c, buf, 1); - peripheral_i2c_read(i2c, buf, 1); - x_pos = (int)buf[0]; - - buf[0] = Y_OUT; - peripheral_i2c_write(i2c, buf, 1); - peripheral_i2c_read(i2c, buf, 1); - y_pos = (int)buf[0]; + if ((gpio_num > 0) && (peripheral_gpio_open(gpio_num, &isr_gpio) == 0)) { + ret = peripheral_gpio_set_direction(isr_gpio, PERIPHERAL_GPIO_DIRECTION_IN); + if (ret < 0) + printf(">>>> Failed to set direction of isr_gpio\n"); - buf[0] = Z_OUT; - peripheral_i2c_write(i2c, buf, 1); - peripheral_i2c_read(i2c, buf, 1); - z_pos = (int)buf[0]; + ret = peripheral_gpio_set_edge_mode(isr_gpio, PERIPHERAL_GPIO_EDGE_RISING); + if (ret < 0) + printf(">>>> Failed to set edge mode of isr_gpio\n"); - printf("Result X : %d, Y : %d, Z : %d\n", x_pos, y_pos, z_pos); + ret = peripheral_gpio_register_cb(isr_gpio, i2c_mma7455_isr, (void*)i2c); + if (ret < 0) + printf(">>>> Failed to register gpio callback\n"); + + buf[0] = MMA7455_INTRST; + buf[1] = 0x03; + peripheral_i2c_write(i2c, buf, 2); + buf[1] = 0x0; + peripheral_i2c_write(i2c, buf, 2); + + printf("callback is registered on gpio pin %d\n", gpio_num); + printf("i2c(bus = %d address = %d) handle is open\n", bus_num, MMA7455_ADDRESS); + } else { + while (cnt++ < 10) { + int x_pos, y_pos, z_pos; + sleep(1); + + peripheral_i2c_write_byte(i2c, MMA7455_XOUT8); + peripheral_i2c_read_byte(i2c, buf); + x_pos = (int)buf[0]; + + peripheral_i2c_write_byte(i2c, MMA7455_YOUT8); + peripheral_i2c_read_byte(i2c, buf); + y_pos = (int)buf[0]; + + peripheral_i2c_write_byte(i2c, MMA7455_ZOUT8); + peripheral_i2c_read_byte(i2c, buf); + z_pos = (int)buf[0]; + + printf("Result X : %d, Y : %d, Z : %d\n", x_pos, y_pos, z_pos); + } + peripheral_i2c_close(i2c); + i2c = NULL; + printf("i2c(bus = %d address = %d) handle is closed\n", bus_num, MMA7455_ADDRESS); } - - peripheral_i2c_close(i2c); return 0; error: peripheral_i2c_close(i2c); + i2c = NULL; return -1; } -- 2.7.4 From f2e8133bf840f9e26822d563a4b0d48d7af1b326 Mon Sep 17 00:00:00 2001 From: "jino.cho" Date: Thu, 25 May 2017 19:50:58 +0900 Subject: [PATCH 10/16] Add APIs and functions for the spi device This patch support the spi device. And, it should work properly if the patch for peripheral-bus is applied together. Change-Id: Ia0094e516d5dff9fba1e2d40170dc7cce844d347 Signed-off-by: jino.cho --- CMakeLists.txt | 2 + include/peripheral_gdbus.h | 1 + include/peripheral_gdbus_spi.h | 36 ++++ include/peripheral_internal.h | 7 + include/peripheral_io.h | 234 ++++++++++++++++++++++-- src/peripheral_gdbus_spi.c | 406 +++++++++++++++++++++++++++++++++++++++++ src/peripheral_io.xml | 79 ++++++++ src/peripheral_spi.c | 121 +++++++++++- test/peripheral-io-test.c | 79 +++++++- 9 files changed, 935 insertions(+), 30 deletions(-) create mode 100644 include/peripheral_gdbus_spi.h create mode 100644 src/peripheral_gdbus_spi.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d051617..ebacf9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,10 +47,12 @@ SET(SOURCES src/peripheral_gpio.c src/peripheral_pwm.c src/peripheral_adc.c src/peripheral_uart.c + src/peripheral_spi.c src/peripheral_gdbus_gpio.c src/peripheral_gdbus_i2c.c src/peripheral_gdbus_pwm.c src/peripheral_gdbus_uart.c + src/peripheral_gdbus_spi.c src/peripheral_io_gdbus.c src/peripheral_spi.c) diff --git a/include/peripheral_gdbus.h b/include/peripheral_gdbus.h index aefe770..ff726de 100644 --- a/include/peripheral_gdbus.h +++ b/include/peripheral_gdbus.h @@ -23,6 +23,7 @@ #define PERIPHERAL_GDBUS_I2C_PATH "/Org/Tizen/Peripheral_io/I2c" #define PERIPHERAL_GDBUS_PWM_PATH "/Org/Tizen/Peripheral_io/Pwm" #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" #endif /* __PERIPHERAL_GDBUS_H__ */ diff --git a/include/peripheral_gdbus_spi.h b/include/peripheral_gdbus_spi.h new file mode 100644 index 0000000..78e7e97 --- /dev/null +++ b/include/peripheral_gdbus_spi.h @@ -0,0 +1,36 @@ +/* + * 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_GDBUS_SPI_H_ +#define __PERIPHERAL_GDBUS_SPI_H_ + +void spi_proxy_init(void); +void spi_proxy_deinit(); + +int peripheral_gdbus_spi_open(peripheral_spi_h spi, int bus, int cs); +int peripheral_gdbus_spi_close(peripheral_spi_h spi); +int peripheral_gdbus_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode); +int peripheral_gdbus_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode); +int peripheral_gdbus_spi_set_lsb_first(peripheral_spi_h spi, bool lsb); +int peripheral_gdbus_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb); +int peripheral_gdbus_spi_set_bits(peripheral_spi_h spi, unsigned char bits); +int peripheral_gdbus_spi_get_bits(peripheral_spi_h spi, unsigned char *bits); +int peripheral_gdbus_spi_set_frequency(peripheral_spi_h spi, unsigned int freq); +int peripheral_gdbus_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq); +int peripheral_gdbus_spi_read(peripheral_spi_h spi, unsigned char *data, int length); +int peripheral_gdbus_spi_write(peripheral_spi_h spi, unsigned char *data, int length); +int peripheral_gdbus_spi_read_write(peripheral_spi_h spi, unsigned char *tx_data, unsigned char *rx_data, int length); + +#endif /* __PERIPHERAL_GDBUS_SPI_H_ */ diff --git a/include/peripheral_internal.h b/include/peripheral_internal.h index 34f09b0..ae4f47e 100644 --- a/include/peripheral_internal.h +++ b/include/peripheral_internal.h @@ -46,4 +46,11 @@ struct _peripheral_uart_s { uint handle; }; +/** + * @brief Internal struct for spi context + */ +struct _peripheral_spi_s { + uint handle; +}; + #endif /* __PERIPHERAL_INTERNAL_H__ */ diff --git a/include/peripheral_io.h b/include/peripheral_io.h index 7517d2a..8e126c8 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -825,33 +825,231 @@ int peripheral_uart_write(peripheral_uart_h uart, uint8_t *data, int length); * @{ */ +/** + * @brief The handle to the spi device + * @since_tizen 4.0 + */ +typedef struct _peripheral_spi_s* peripheral_spi_h; + +/** + * @brief Enumeration for SPI mode. + */ typedef enum { - PERIPHERAL_SPI_MODE0 = 0, - PERIPHERAL_SPI_MODE1, - PERIPHERAL_SPI_MODE2, - PERIPHERAL_SPI_MODE3 + PERIPHERAL_SPI_MODE_0 = 0, + PERIPHERAL_SPI_MODE_1, + PERIPHERAL_SPI_MODE_2, + PERIPHERAL_SPI_MODE_3 } peripheral_spi_mode_e; -struct peripheral_spi_config_s { - int fd; - char bits_per_word; - int lsb; - unsigned int chip_select; - unsigned int frequency; - peripheral_spi_mode_e mode; -}; +/** + * @brief Initializes spi communication and creates spi handle. + * @since_tizen 4.0 + * + * @param[in] bus The spi bus number that the slave device is connected + * @param[in] cs The spi chip select number that the slave device is connected + * @param[out] spi The spi handle is created on success + * + * @return 0 on success, otherwise a negative error value + * @retval #PERIPHERAL_ERROR_NONE Successful + * + * @see peripheral_spi_close() + */ +int peripheral_spi_open(int bus, int cs, peripheral_spi_h *spi); + +/** + * @brief Destory the spi handle and release the communication. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * + * @return 0 on success, otherwise a negative error value + * @retval #PERIPHERAL_ERROR_NONE Successful + * @retval #PERIPHERAL_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * + * @see peripheral_spi_open() + */ +int peripheral_spi_close(peripheral_spi_h spi); + +/** + * @brief Sets mode of the spi device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[in] mode The mode of the spi device + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ +int peripheral_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode); + +/** + * @brief Gets mode of the spi device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[out] mode The mode of the spi device + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ +int peripheral_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode); + +/** + * @brief Sets bits justification of the spi device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[in] lsb The bit position to be transmitted first + * true - LSB first + * false - MSB first + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ +int peripheral_spi_set_lsb_first(peripheral_spi_h spi, bool lsb); + +/** + * @brief Gets bits justification of the spi device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[out] lsb The bit position to be transmitted first + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ +int peripheral_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb); + +/** + * @brief Sets the number of bits per word of the spi device + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[in] bits The number of bits per word (in bits) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ +int peripheral_spi_set_bits_per_word(peripheral_spi_h spi, unsigned char bits); -typedef struct peripheral_spi_config_s * peripheral_spi_context_h; +/** + * @brief Gets the number of bits per word of the spi device + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[out] bits The number of bits per word (in bits) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ +int peripheral_spi_get_bits_per_word(peripheral_spi_h spi, unsigned char *bits); -peripheral_spi_context_h peripheral_spi_open(unsigned int bus, peripheral_spi_context_h config); +/** + * @brief Sets default max speed of the spi device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[in] freq Max speed (in hz) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ +int peripheral_spi_set_frequency(peripheral_spi_h spi, unsigned int freq); -int peripheral_spi_write(peripheral_spi_context_h hnd, char *txbuf, int length); +/** + * @brief Gets default max speed of the spi device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[out] freq Max speed (in hz) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed + */ -int peripheral_spi_recv(peripheral_spi_context_h hnd, char *rxbuf, int length); +int peripheral_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq); -int peripheral_spi_transfer_buf(peripheral_spi_context_h hnd, char *txbuf, char *rxbuf, int length); +/** + * @brief Reads data from the slave device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[out] data The address of buffer to read + * @param[in] length The size of data buffer (in bytes) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_spi_read(peripheral_spi_h spi, unsigned char *data, int length); + +/** + * @brief Write data to the slave device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[in] data The address of buffer to write + * @param[in] length The size of data (in bytes) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_spi_write(peripheral_spi_h spi, unsigned char *data, int length); -int peripheral_spi_close(peripheral_spi_context_h hnd); +/** + * @brief Exchange data with the slave device. + * @since_tizen 4.0 + * + * @param[in] spi The handle to the spi device + * @param[in] txdata The address of buffer to write + * @param[out] rxdata The address of buffer to read + * @param[in] length The size of data (in bytes) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_spi_read_write(peripheral_spi_h spi, unsigned char *txdata, unsigned char *rxdata, int length); /** * @} diff --git a/src/peripheral_gdbus_spi.c b/src/peripheral_gdbus_spi.c new file mode 100644 index 0000000..b42e926 --- /dev/null +++ b/src/peripheral_gdbus_spi.c @@ -0,0 +1,406 @@ +/* + * 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_io.h" +#include "peripheral_gdbus.h" +#include "peripheral_common.h" +#include "peripheral_internal.h" +#include "peripheral_io_gdbus.h" + +PeripheralIoGdbusSpi *spi_proxy = NULL; + +void spi_proxy_init(void) +{ + GError *error = NULL; + + if (spi_proxy != NULL) { + g_object_ref(spi_proxy); + return; + } + + spi_proxy = peripheral_io_gdbus_spi_proxy_new_for_bus_sync( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + PERIPHERAL_GDBUS_NAME, + PERIPHERAL_GDBUS_SPI_PATH, + NULL, + &error); +} + +void spi_proxy_deinit() +{ + if (spi_proxy) { + g_object_unref(spi_proxy); + if (!G_IS_OBJECT(spi_proxy)) + spi_proxy = NULL; + } +} + +int peripheral_gdbus_spi_open(peripheral_spi_h spi, int bus, int cs) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_open_sync( + spi_proxy, + bus, + cs, + &spi->handle, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} + +int peripheral_gdbus_spi_close(peripheral_spi_h spi) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_close_sync( + spi_proxy, + spi->handle, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} + +int peripheral_gdbus_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_set_mode_sync( + spi_proxy, + spi->handle, + (guchar)mode, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} + +int peripheral_gdbus_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + guchar value; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_get_mode_sync( + spi_proxy, + spi->handle, + &value, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + if (value <= PERIPHERAL_SPI_MODE_3) + *mode = value; + else + _E("Invalid mode : %d", value); + + return ret; +} + +int peripheral_gdbus_spi_set_lsb_first(peripheral_spi_h spi, bool lsb) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_set_lsb_first_sync( + spi_proxy, + spi->handle, + lsb, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} + +int peripheral_gdbus_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gboolean value; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_get_lsb_first_sync( + spi_proxy, + spi->handle, + &value, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + *lsb = value ? true : false; + + return ret; +} + +int peripheral_gdbus_spi_set_bits(peripheral_spi_h spi, unsigned char bits) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_set_bits_sync( + spi_proxy, + spi->handle, + bits, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} + +int peripheral_gdbus_spi_get_bits(peripheral_spi_h spi, unsigned char *bits) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + guchar value; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_get_bits_sync( + spi_proxy, + spi->handle, + &value, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + *bits = (unsigned char)value; + + return ret; +} + +int peripheral_gdbus_spi_set_frequency(peripheral_spi_h spi, unsigned int freq) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_set_frequency_sync( + spi_proxy, + spi->handle, + freq, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} + +int peripheral_gdbus_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + guint value; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_get_frequency_sync( + spi_proxy, + spi->handle, + &value, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + *freq = (unsigned int)value; + + return ret; +} + +int peripheral_gdbus_spi_read(peripheral_spi_h spi, unsigned char *data, int length) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + GVariant *data_array; + GVariantIter *iter; + guint8 str; + int i = 0; + + if (spi_proxy == NULL || data == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_spi_call_read_sync( + spi_proxy, + spi->handle, + length, + &data_array, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + g_variant_get(data_array, "a(y)", &iter); + while (g_variant_iter_loop(iter, "(y)", &str)) { + data[i] = str; + if (i++ == length) break; + } + g_variant_iter_free(iter); + g_variant_unref(data_array); + + return ret; +} + +int peripheral_gdbus_spi_write(peripheral_spi_h spi, unsigned char *data, int length) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + GVariantBuilder *builder; + GVariant *data_array; + int i = 0; + + if (spi_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)")); + + for (i = 0; i < length; i++) + g_variant_builder_add(builder, "(y)", data[i]); + g_variant_builder_add(builder, "(y)", 0x00); + + data_array = g_variant_new("a(y)", builder); + g_variant_builder_unref(builder); + + if (peripheral_io_gdbus_spi_call_write_sync( + spi_proxy, + spi->handle, + length, + data_array, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} + +int peripheral_gdbus_spi_read_write(peripheral_spi_h spi, unsigned char *tx_data, unsigned char *rx_data, int length) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + GVariantBuilder *builder; + GVariant *rx_data_array; + GVariant *tx_data_array; + GVariantIter *iter; + guint8 str; + int i = 0; + + if (spi_proxy == NULL || !rx_data || !tx_data) return PERIPHERAL_ERROR_UNKNOWN; + + builder = g_variant_builder_new(G_VARIANT_TYPE("a(y)")); + + for (i = 0; i < length; i++) + g_variant_builder_add(builder, "(y)", tx_data[i]); + g_variant_builder_add(builder, "(y)", 0x00); + + tx_data_array = g_variant_new("a(y)", builder); + g_variant_builder_unref(builder); + + if (peripheral_io_gdbus_spi_call_read_write_sync( + spi_proxy, + spi->handle, + length, + tx_data_array, + &rx_data_array, + &ret, + NULL, + &error) == FALSE) { + _E("%s", error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + i = 0; + g_variant_get(rx_data_array, "a(y)", &iter); + while (g_variant_iter_loop(iter, "(y)", &str)) { + rx_data[i] = str; + if (i++ == length) break; + } + g_variant_iter_free(iter); + g_variant_unref(rx_data_array); + + return ret; +} diff --git a/src/peripheral_io.xml b/src/peripheral_io.xml index 2480f92..c6fff55 100644 --- a/src/peripheral_io.xml +++ b/src/peripheral_io.xml @@ -182,4 +182,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/peripheral_spi.c b/src/peripheral_spi.c index e2f8465..661b68a 100644 --- a/src/peripheral_spi.c +++ b/src/peripheral_spi.c @@ -20,27 +20,128 @@ #include #include -peripheral_spi_context_h peripheral_spi_open(unsigned int bus, peripheral_spi_context_h config) +#include "peripheral_io.h" +#include "peripheral_gdbus_spi.h" +#include "peripheral_common.h" +#include "peripheral_internal.h" + +int peripheral_spi_open(int bus, int cs, peripheral_spi_h *spi) +{ + peripheral_spi_h handle; + int ret = PERIPHERAL_ERROR_NONE; + + if (bus < 0 || cs < 0) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + /* Initialize */ + handle = (peripheral_spi_h)calloc(1, sizeof(struct _peripheral_spi_s)); + + if (handle == NULL) { + _E("Failed to allocate peripheral_spi_h"); + return PERIPHERAL_ERROR_OUT_OF_MEMORY; + } + + spi_proxy_init(); + + ret = peripheral_gdbus_spi_open(handle, bus, cs); + + if (ret != PERIPHERAL_ERROR_NONE) { + _E("SPI open error (%d, %d)", bus, cs); + free(handle); + handle = NULL; + } + *spi = handle; + + return ret; +} + +int peripheral_spi_close(peripheral_spi_h spi) +{ + int ret = PERIPHERAL_ERROR_NONE; + + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + if ((ret = peripheral_gdbus_spi_close(spi)) < 0) + _E("Failed to close SPI device, continuing anyway"); + + spi_proxy_deinit(); + free(spi); + + return ret; +} + +int peripheral_spi_set_mode(peripheral_spi_h spi, peripheral_spi_mode_e mode) +{ + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_set_mode(spi, mode); +} + +int peripheral_spi_get_mode(peripheral_spi_h spi, peripheral_spi_mode_e *mode) +{ + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_get_mode(spi, mode); +} + +int peripheral_spi_set_lsb_first(peripheral_spi_h spi, bool lsb) +{ + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_set_lsb_first(spi, lsb); +} + +int peripheral_spi_get_lsb_first(peripheral_spi_h spi, bool *lsb) +{ + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_get_lsb_first(spi, lsb); +} + +int peripheral_spi_set_bits_per_word(peripheral_spi_h spi, unsigned char bits) +{ + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_set_bits(spi, bits); +} + +int peripheral_spi_get_bits_per_word(peripheral_spi_h spi, unsigned char *bits) +{ + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_get_bits(spi, bits); +} + +int peripheral_spi_set_frequency(peripheral_spi_h spi, unsigned int freq) { - return NULL; + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_set_frequency(spi, freq); } -int peripheral_spi_write(peripheral_spi_context_h hnd, char *txbuf, int length) +int peripheral_spi_get_frequency(peripheral_spi_h spi, unsigned int *freq) { - return PERIPHERAL_ERROR_INVALID_OPERATION; + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_get_frequency(spi, freq); } -int peripheral_spi_recv(peripheral_spi_context_h hnd, char *rxbuf, int length) +int peripheral_spi_read(peripheral_spi_h spi, unsigned char *data, int length) { - return PERIPHERAL_ERROR_INVALID_OPERATION; + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_read(spi, data, length); } -int peripheral_spi_transfer_buf(peripheral_spi_context_h hnd, char *txbuf, char *rxbuf, int length) +int peripheral_spi_write(peripheral_spi_h spi, unsigned char *data, int length) { - return PERIPHERAL_ERROR_INVALID_OPERATION; + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_write(spi, data, length); } -int peripheral_spi_close(peripheral_spi_context_h hnd) +int peripheral_spi_read_write(peripheral_spi_h spi, unsigned char *txdata, unsigned char *rxdata, int length) { - return PERIPHERAL_ERROR_INVALID_OPERATION; + if (spi == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; + + return peripheral_gdbus_spi_read_write(spi, txdata, rxdata, length); } diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index 1ec14eb..d0aa4c6 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -519,6 +519,80 @@ err_open: return -1; } +#define MMA7455_MCTL_SPI3W 0x20 // SPI is 3 wire mode +#define MMA7455_MCTL_DRPD 0x40 // Data ready status is not output to INT1/DRDY PIN + +#define MMA7455_SPI_REGISTER_WRITE 0x40 + +int spi_mma7455_module_test(void) +{ + int cnt = 0; + int bus_num, cs_num, ret; + unsigned char tx_buf[10]; + unsigned char rx_buf[10]; + unsigned int num; + peripheral_spi_h spi; + + printf(" %s()\n", __func__); + printf("Enter SPI bus number : "); + if (scanf("%d", &bus_num) < 0) + return -1; + + printf("Enter SPI cs number : "); + if (scanf("%d", &cs_num) < 0) + return -1; + + if ((ret = peripheral_spi_open(bus_num, cs_num, &spi)) < 0) { + printf("Failed to open I2C communication, ret : %d\n", ret); + return -1; + } + peripheral_spi_set_mode(spi, PERIPHERAL_SPI_MODE_0); + peripheral_spi_set_lsb_first(spi, false); + peripheral_spi_set_bits_per_word(spi, 8); + peripheral_spi_set_frequency(spi, 100000); + + printf("bus : %d, cs : %d, ", bus_num, cs_num); + peripheral_spi_get_mode(spi, (peripheral_spi_mode_e*)&num); + printf("mode : %d, ", num); + peripheral_spi_get_lsb_first(spi, (bool*)&num); + printf("lsb first : %d, ", (bool)num); + peripheral_spi_get_bits_per_word(spi, (unsigned char*)&num); + printf("bits : %d, ", (unsigned char)num); + peripheral_spi_get_frequency(spi, &num); + printf("max frequency : %d\n", num); + + tx_buf[0] = (MMA7455_MCTL | MMA7455_SPI_REGISTER_WRITE) << 1; + tx_buf[1] = MMA7455_MCTL_DRPD | MMA7455_MCTL_SPI3W | MMA7455_MCTL_2G | MMA7455_MCTL_MEASUREMENT_MODE; + if ((ret = peripheral_spi_write(spi, tx_buf, 2)) < 0) { + printf("Failed to write, ret : %d\n", ret); + goto error; + } + + while (cnt++ < 15) { + int i; + unsigned char buf[5]; + + sleep(1); + for (i = 0; i < 3; i++) { + tx_buf[0] = (MMA7455_XOUT8 + i) << 1; + tx_buf[1] = 0; + ret = peripheral_spi_read_write(spi, tx_buf, rx_buf, 2); + if (ret < 0) + printf("Failed to read, ret : %d\n", ret); + buf[i] = rx_buf[1]; + } + + printf("X = 0x%02X, Y = 0x%02X, Z = 0x%02X\n", buf[0], buf[1], buf[2]); + } + + peripheral_spi_close(spi); + return 0; + +error: + peripheral_spi_close(spi); + return -1; +} + int gpio_test_get_handle_by_pin(int pin, peripheral_gpio_h *gpio) { peripheral_gpio_h handle; @@ -851,8 +925,9 @@ tc_table_t preset_tc_table[] = { {"[Preset Test] PWM LED", 4, pwm_test_led}, {"[Preset Test] PWM Motor", 5, pwm_test_motor}, {"[Preset Test] Uart Accelerometer", 6, uart_test_accelerometer}, - {"[Preset Test] GPIO IRQ register", 7, gpio_irq_register}, - {"[Preset Test] GPIO IRQ unregister", 8, gpio_irq_unregister}, + {"[Preset Test] SPI MMA7455 Accel. sensor", 7, spi_mma7455_module_test}, + {"[Preset Test] GPIO IRQ register", 8, gpio_irq_register}, + {"[Preset Test] GPIO IRQ unregister", 9, gpio_irq_unregister}, {"Go back to main", 0, enter_main}, {NULL, 0, NULL}, }; -- 2.7.4 From f60468fcf4509ed4452dd2cd930e501e14ee5f77 Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Thu, 1 Jun 2017 11:32:33 +0900 Subject: [PATCH 11/16] Add new APIs for I2C smbus transaction This patch adds below I2C APIs. - peripheral_i2c_read_register_byte() - peripheral_i2c_write_register_byte() - peripheral_i2c_read_register_word() - peripheral_i2c_write_register_word() igned-off-by: Hyeongsik Min Change-Id: Ic0e96b4225b6596556b670487c905e6c77c4039c --- include/peripheral_gdbus_i2c.h | 1 + include/peripheral_io.h | 73 ++++++++++++++++++++++++++++++++++-- src/peripheral_gdbus_i2c.c | 26 +++++++++++++ src/peripheral_i2c.c | 84 ++++++++++++++++++++++++++++++++++++++---- src/peripheral_io.xml | 9 +++++ 5 files changed, 182 insertions(+), 11 deletions(-) diff --git a/include/peripheral_gdbus_i2c.h b/include/peripheral_gdbus_i2c.h index c36cb04..7b2b899 100644 --- a/include/peripheral_gdbus_i2c.h +++ b/include/peripheral_gdbus_i2c.h @@ -24,5 +24,6 @@ int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address); int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c); int peripheral_gdbus_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length); int peripheral_gdbus_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length); +int peripheral_gdbus_i2c_smbus_ioctl(peripheral_i2c_h i2c, uint8_t read_write, uint8_t command, uint32_t size, uint16_t data_in, uint16_t *data_out); #endif /* __PERIPHERAL_GDBUS_I2C_H__ */ diff --git a/include/peripheral_io.h b/include/peripheral_io.h index 8e126c8..5629ae3 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -328,7 +328,7 @@ int peripheral_i2c_open(int bus, int address, peripheral_i2c_h *i2c); int peripheral_i2c_close(peripheral_i2c_h i2c); /** - * @brief Reads data from the i2c device. + * @brief Reads data from the i2c slave device. * @since_tizen 4.0 * * @param[in] i2c The handle to the i2c device @@ -344,7 +344,7 @@ int peripheral_i2c_close(peripheral_i2c_h i2c); int peripheral_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length); /** - * @brief Write data to the i2c device. + * @brief Write data to the i2c slave device. * @since_tizen 4.0 * * @param[in] i2c The handle to the i2c device @@ -360,7 +360,7 @@ int peripheral_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length); int peripheral_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length); /** - * @brief Reads single byte data from the i2c device. + * @brief Reads single byte data from the i2c slave device. * @since_tizen 4.0 * * @param[in] i2c The handle to the i2c device @@ -373,8 +373,9 @@ int peripheral_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length); * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error */ int peripheral_i2c_read_byte(peripheral_i2c_h i2c, uint8_t *data); + /** - * @brief Write single byte data to the i2c device. + * @brief Write single byte data to the i2c slave device. * @since_tizen 4.0 * * @param[in] i2c The handle to the i2c device @@ -389,6 +390,70 @@ int peripheral_i2c_read_byte(peripheral_i2c_h i2c, uint8_t *data); int peripheral_i2c_write_byte(peripheral_i2c_h i2c, uint8_t data); /** + * @brief Reads byte data from the register of i2c slave device. + * @since_tizen 4.0 + * + * @param[in] i2c The handle to the i2c device + * @param[in] address The register address of the i2c slave device to read + * @param[out] data The byte output of slave device(register value) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_i2c_read_register_byte(peripheral_i2c_h i2c, uint8_t address, uint8_t *data); + +/** + * @brief Write byte data to the register of i2c slave device. + * @since_tizen 4.0 + * + * @param[in] i2c The handle to the i2c device + * @param[in] address The register address of the i2c slave device to write + * @param[in] data The byte value to write + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_i2c_write_register_byte(peripheral_i2c_h i2c, uint8_t address, uint8_t data); + +/** + * @brief Reads word data from the register of i2c slave device. + * @since_tizen 4.0 + * + * @param[in] i2c The handle to the i2c device + * @param[in] address The register address of the i2c slave device to read + * @param[out] data The word output(2 bytes) of slave device(register value) + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_i2c_read_register_word(peripheral_i2c_h i2c, uint8_t address, uint16_t *data); + +/** + * @brief Write byte data to the register of i2c slave device. + * @since_tizen 4.0 + * + * @param[in] i2c The handle to the i2c device + * @param[in] address The register address of the i2c slave device to write + * @param[in] data The word(2 bytes) value to write + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + */ +int peripheral_i2c_write_register_word(peripheral_i2c_h i2c, uint8_t address, uint16_t data); + +/** * @} */ diff --git a/src/peripheral_gdbus_i2c.c b/src/peripheral_gdbus_i2c.c index 1b296f1..875df8c 100644 --- a/src/peripheral_gdbus_i2c.c +++ b/src/peripheral_gdbus_i2c.c @@ -165,3 +165,29 @@ int peripheral_gdbus_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length) return ret; } + +int peripheral_gdbus_i2c_smbus_ioctl(peripheral_i2c_h i2c, uint8_t read_write, uint8_t command, uint32_t size, uint16_t data_in, uint16_t *data_out) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + + if (i2c_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_i2c_call_smbus_ioctl_sync( + i2c_proxy, + i2c->handle, + read_write, + command, + size, + data_in, + data_out, + &ret, + NULL, + &error) == FALSE) { + _E("Error in %s() : %s\n", __func__, error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + return ret; +} diff --git a/src/peripheral_i2c.c b/src/peripheral_i2c.c index 969e18b..0af6dc8 100644 --- a/src/peripheral_i2c.c +++ b/src/peripheral_i2c.c @@ -24,6 +24,16 @@ #include "peripheral_common.h" #include "peripheral_internal.h" +/* i2c_smbus_xfer read or write markers */ +#define I2C_SMBUS_READ 1 +#define I2C_SMBUS_WRITE 0 + +/* SMBus transaction types */ +#define I2C_SMBUS_QUICK 0 +#define I2C_SMBUS_BYTE 1 +#define I2C_SMBUS_BYTE_DATA 2 +#define I2C_SMBUS_WORD_DATA 3 + int peripheral_i2c_open(int bus, int address, peripheral_i2c_h *i2c) { peripheral_i2c_h handle; @@ -75,11 +85,7 @@ int peripheral_i2c_read(peripheral_i2c_h i2c, uint8_t *data, int length) if (i2c == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; ret = peripheral_gdbus_i2c_read(i2c, data, length); - /* - _D("I2C read data : "); - for (int i = 0 ; i < length ; i++) - _D("[%02x]", data[i]); - */ + return ret; } @@ -93,17 +99,81 @@ int peripheral_i2c_write(peripheral_i2c_h i2c, uint8_t *data, int length) int peripheral_i2c_read_byte(peripheral_i2c_h i2c, uint8_t *data) { int ret = PERIPHERAL_ERROR_NONE; + uint16_t w_data, dummy = 0; if (i2c == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; - ret = peripheral_gdbus_i2c_read(i2c, data, 0x1); + ret = peripheral_gdbus_i2c_smbus_ioctl(i2c, I2C_SMBUS_READ, 0x0, I2C_SMBUS_BYTE, dummy, &w_data); + if (ret < PERIPHERAL_ERROR_NONE) + _E("Failed to read, ret : %d", ret); + + *data = (uint8_t)w_data; return ret; } int peripheral_i2c_write_byte(peripheral_i2c_h i2c, uint8_t data) { + int ret = PERIPHERAL_ERROR_NONE; + uint16_t dummy = 0; + if (i2c == NULL) return PERIPHERAL_ERROR_INVALID_PARAMETER; - return peripheral_gdbus_i2c_write(i2c, &data, 0x1); + ret = peripheral_gdbus_i2c_smbus_ioctl(i2c, I2C_SMBUS_WRITE, dummy, I2C_SMBUS_BYTE, (uint16_t)data, &dummy); + if (ret < PERIPHERAL_ERROR_NONE) + _E("Failed to read, ret : %d", ret); + + return ret; +} + +int peripheral_i2c_read_register_byte(peripheral_i2c_h i2c, uint8_t address, uint8_t *data) +{ + int ret; + uint16_t w_data, dummy = 0; + + ret = peripheral_gdbus_i2c_smbus_ioctl(i2c, I2C_SMBUS_READ, address, I2C_SMBUS_BYTE_DATA, dummy, &w_data); + if (ret < PERIPHERAL_ERROR_NONE) + _E("Smbus transaction failed, ret : %d", ret); + + *data = (uint8_t)w_data; + + return ret; +} + +int peripheral_i2c_write_register_byte(peripheral_i2c_h i2c, uint8_t address, uint8_t data) +{ + int ret; + uint16_t dummy = 0; + + ret = peripheral_gdbus_i2c_smbus_ioctl(i2c, I2C_SMBUS_WRITE, address, I2C_SMBUS_BYTE_DATA, (uint16_t)data, &dummy); + if (ret < PERIPHERAL_ERROR_NONE) + _E("Smbus transaction failed, ret : %d", ret); + + return ret; +} + +int peripheral_i2c_read_register_word(peripheral_i2c_h i2c, uint8_t address, uint16_t *data) +{ + int ret; + uint16_t dummy = 0, data_out; + + ret = peripheral_gdbus_i2c_smbus_ioctl(i2c, I2C_SMBUS_READ, address, I2C_SMBUS_WORD_DATA, dummy, &data_out); + if (ret < PERIPHERAL_ERROR_NONE) + _E("Smbus transaction failed, ret : %d", ret); + + *data = data_out; + + return ret; +} + +int peripheral_i2c_write_register_word(peripheral_i2c_h i2c, uint8_t address, uint16_t data) +{ + int ret; + uint16_t dummy = 0; + + ret = peripheral_gdbus_i2c_smbus_ioctl(i2c, I2C_SMBUS_WRITE, address, I2C_SMBUS_WORD_DATA, data, &dummy); + if (ret < PERIPHERAL_ERROR_NONE) + _E("Smbus transaction failed, ret : %d", ret); + + return ret; } diff --git a/src/peripheral_io.xml b/src/peripheral_io.xml index c6fff55..ea4b1f9 100644 --- a/src/peripheral_io.xml +++ b/src/peripheral_io.xml @@ -80,6 +80,15 @@ + + + + + + + + + -- 2.7.4 From a800f2e3a145901ee2791462cef3b735601438b2 Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Thu, 1 Jun 2017 13:05:45 +0900 Subject: [PATCH 12/16] Improve I2C test by using new APIs Change-Id: I06302e2c4c633a1746d58384554c7ba0e59e90b0 Signed-off-by: Hyeongsik Min --- test/peripheral-io-test.c | 91 +++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index d0aa4c6..00bb5f7 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "peripheral_io.h" @@ -183,9 +184,10 @@ int gpio_irq_unregister(void) int i2c_gy30_test(void) { int cnt = 0; - int bus_num, ret; unsigned char buf[10]; peripheral_i2c_h i2c; + struct timeval tv_1, tv_2; + int bus_num, ret, result, interval; printf(" %s()\n", __func__); printf("Enter I2C bus number\n"); @@ -203,15 +205,17 @@ int i2c_gy30_test(void) goto error; } - while (cnt++ < 15) { - int result; - sleep(1); - ret = peripheral_i2c_read(i2c, buf, 2); + gettimeofday(&tv_1, NULL); + while (cnt++ < 1000) { + ret = peripheral_i2c_read_byte(i2c, buf); if (ret < 0) printf("Failed to read, ret : %d\n", ret); result = GY30_READ_INTENSITY(buf); printf("Light intensity : %d\n", result); } + gettimeofday(&tv_2, NULL); + interval = (tv_2.tv_sec - tv_1.tv_sec) * 1000 + (int)(tv_2.tv_usec - tv_1.tv_usec)/1000; + printf("1000 i2c read calls took %d ms\n", interval); peripheral_i2c_close(i2c); return 0; @@ -234,6 +238,8 @@ error: #define MMA7455_MCTL_8G 0x00 //Set Sensitivity to 8g #define MMA7455_INTRST 0x17 +#define MMA7455_INTRST_CLRINT 0x03 +#define MMA7445_INTRST_DONOTCLR 0x00 #define MMA7455_CONTROL1 0x18 #define MMA7455_CONTROL1_INTREG 0x06 @@ -246,29 +252,17 @@ error: static void i2c_mma7455_isr(void *user_data) { peripheral_i2c_h i2c = user_data; - int x_pos, y_pos, z_pos; - uint8_t buf[4]; - - peripheral_i2c_write_byte(i2c, MMA7455_XOUT8); - peripheral_i2c_read_byte(i2c, buf); - x_pos = (int)buf[0]; + uint8_t x_pos, y_pos, z_pos; - peripheral_i2c_write_byte(i2c, MMA7455_YOUT8); - peripheral_i2c_read_byte(i2c, buf); - y_pos = (int)buf[0]; - - peripheral_i2c_write_byte(i2c, MMA7455_ZOUT8); - peripheral_i2c_read_byte(i2c, buf); - z_pos = (int)buf[0]; + peripheral_i2c_read_register_byte(i2c, MMA7455_XOUT8, &x_pos); + peripheral_i2c_read_register_byte(i2c, MMA7455_YOUT8, &y_pos); + peripheral_i2c_read_register_byte(i2c, MMA7455_ZOUT8, &z_pos); printf("Result X : %d, Y : %d, Z : %d\n", x_pos, y_pos, z_pos); /* Reset interrupt flags */ - buf[0] = MMA7455_INTRST; - buf[1] = 0x3; - peripheral_i2c_write(i2c, buf, 2); - buf[1] = 0x0; - peripheral_i2c_write(i2c, buf, 2); + peripheral_i2c_write_register_byte(i2c, MMA7455_INTRST, MMA7455_INTRST_CLRINT); + peripheral_i2c_write_register_byte(i2c, MMA7455_INTRST, MMA7445_INTRST_DONOTCLR); return; } @@ -277,7 +271,6 @@ int i2c_mma7455_test(void) { static peripheral_i2c_h i2c; static peripheral_gpio_h isr_gpio; - unsigned char buf[4]; int bus_num, gpio_num, ret; int cnt = 0; @@ -287,7 +280,7 @@ int i2c_mma7455_test(void) peripheral_i2c_close(i2c); i2c = NULL; - printf("i2c(bus = %d address = %d) handle is closed\n", bus_num, MMA7455_ADDRESS); + printf("i2c handle is closed\n"); if (isr_gpio) { peripheral_gpio_close(isr_gpio); @@ -308,9 +301,10 @@ int i2c_mma7455_test(void) return -1; } - buf[0] = MMA7455_MCTL; - buf[1] = MMA7455_MCTL_8G | MMA7455_MCTL_PULSE_DETECTION_MODE; - if ((ret = peripheral_i2c_write(i2c, buf, 2)) != 0) { + ret = peripheral_i2c_write_register_byte(i2c, + MMA7455_MCTL, + MMA7455_MCTL_8G | MMA7455_MCTL_PULSE_DETECTION_MODE); + if (ret < PERIPHERAL_ERROR_NONE) { printf(">>>>> Failed to write, ret : %d\n", ret); goto error; } @@ -332,32 +326,43 @@ int i2c_mma7455_test(void) if (ret < 0) printf(">>>> Failed to register gpio callback\n"); - buf[0] = MMA7455_INTRST; - buf[1] = 0x03; - peripheral_i2c_write(i2c, buf, 2); - buf[1] = 0x0; - peripheral_i2c_write(i2c, buf, 2); + /* Reset interrupt flags */ + peripheral_i2c_write_register_byte(i2c, MMA7455_INTRST, MMA7455_INTRST_CLRINT); + peripheral_i2c_write_register_byte(i2c, MMA7455_INTRST, MMA7445_INTRST_DONOTCLR); printf("callback is registered on gpio pin %d\n", gpio_num); printf("i2c(bus = %d address = %d) handle is open\n", bus_num, MMA7455_ADDRESS); } else { while (cnt++ < 10) { - int x_pos, y_pos, z_pos; + uint8_t x_pos, y_pos, z_pos; + unsigned char buf[4]; sleep(1); - peripheral_i2c_write_byte(i2c, MMA7455_XOUT8); - peripheral_i2c_read_byte(i2c, buf); - x_pos = (int)buf[0]; + /* Get measurement data with different APIs */ + buf[0] = MMA7455_XOUT8; + peripheral_i2c_write(i2c, buf, 0x1); + peripheral_i2c_read(i2c, &x_pos, 0x1); + buf[0] = MMA7455_YOUT8; + peripheral_i2c_write(i2c, buf, 0x1); + peripheral_i2c_read(i2c, &y_pos, 0x1); + buf[0] = MMA7455_ZOUT8; + peripheral_i2c_write(i2c, buf, 0x1); + peripheral_i2c_read(i2c, &z_pos, 0x1); + printf("Result X : %d, Y : %d, Z : %d (peripheral_i2c_read)\n", x_pos, y_pos, z_pos); + peripheral_i2c_write_byte(i2c, MMA7455_XOUT8); + peripheral_i2c_read_byte(i2c, &x_pos); peripheral_i2c_write_byte(i2c, MMA7455_YOUT8); - peripheral_i2c_read_byte(i2c, buf); - y_pos = (int)buf[0]; - + peripheral_i2c_read_byte(i2c, &y_pos); peripheral_i2c_write_byte(i2c, MMA7455_ZOUT8); - peripheral_i2c_read_byte(i2c, buf); - z_pos = (int)buf[0]; + peripheral_i2c_read_byte(i2c, &z_pos); + printf("Result X : %d, Y : %d, Z : %d (peripheral_i2c_read_byte)\n", x_pos, y_pos, z_pos); + + peripheral_i2c_read_register_byte(i2c, MMA7455_XOUT8, &x_pos); + peripheral_i2c_read_register_byte(i2c, MMA7455_YOUT8, &y_pos); + peripheral_i2c_read_register_byte(i2c, MMA7455_ZOUT8, &z_pos); + printf("Result X : %d, Y : %d, Z : %d (peripheral_i2c_read_register_byte)\n", x_pos, y_pos, z_pos); - printf("Result X : %d, Y : %d, Z : %d\n", x_pos, y_pos, z_pos); } peripheral_i2c_close(i2c); i2c = NULL; -- 2.7.4 From cad0071117298f730788051177f7a6374843cdc1 Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Thu, 1 Jun 2017 15:59:17 +0900 Subject: [PATCH 13/16] Update package version to 0.0.4 Change-Id: Id21d404d52630822966c60442266c5d7337f77a8 Signed-off-by: Hyeongsik Min --- packaging/capi-system-peripheral-io.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/capi-system-peripheral-io.spec b/packaging/capi-system-peripheral-io.spec index 91a3634..595430d 100644 --- a/packaging/capi-system-peripheral-io.spec +++ b/packaging/capi-system-peripheral-io.spec @@ -1,6 +1,6 @@ Name: capi-system-peripheral-io Summary: Tizen Peripheral Input & Output library -Version: 0.0.3 +Version: 0.0.4 Release: 0 Group: System & System Tools License: Apache-2.0 -- 2.7.4 From 84abf6350d82076f1abd27e893223224dcfe3353 Mon Sep 17 00:00:00 2001 From: "jino.cho" Date: Thu, 1 Jun 2017 16:18:28 +0900 Subject: [PATCH 14/16] Fix type mismatch issue The type size of bool and gboolean are different. Therefore, the pointer parameter should not be used directly as a argument of gdbus functions. Change-Id: I6ccccab228ca5fa57bee6db02e49bbe44a15eaef Signed-off-by: jino.cho --- src/peripheral_gdbus_gpio.c | 17 ++++++++++++++--- src/peripheral_gdbus_pwm.c | 26 ++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/peripheral_gdbus_gpio.c b/src/peripheral_gdbus_gpio.c index 721b3d4..6550360 100644 --- a/src/peripheral_gdbus_gpio.c +++ b/src/peripheral_gdbus_gpio.c @@ -126,21 +126,26 @@ int peripheral_gdbus_gpio_get_direction(peripheral_gpio_h gpio, peripheral_gpio_ { GError *error = NULL; peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gint value = 0; if (gpio_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; if (peripheral_io_gdbus_gpio_call_get_direction_sync( gpio_proxy, gpio->handle, - (gint*)direction, + &value, &ret, NULL, &error) == FALSE) { _E("Error in %s() : %s\n", __func__, error->message); g_error_free(error); - return PERIPHERAL_ERROR_UNKNOWN; } + if (value >= PERIPHERAL_GPIO_DIRECTION_IN && value <= PERIPHERAL_GPIO_DIRECTION_OUT_HIGH) + *direction = value; + else + return PERIPHERAL_ERROR_UNKNOWN; + return ret; } @@ -214,13 +219,14 @@ int peripheral_gdbus_gpio_get_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_ { GError *error = NULL; peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gint value = 0; if (gpio_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; if (peripheral_io_gdbus_gpio_call_get_edge_mode_sync( gpio_proxy, gpio->handle, - (int*)edge, + &value, &ret, NULL, &error) == FALSE) { @@ -229,6 +235,11 @@ int peripheral_gdbus_gpio_get_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_ return PERIPHERAL_ERROR_UNKNOWN; } + if (value >= PERIPHERAL_GPIO_EDGE_NONE && value <= PERIPHERAL_GPIO_EDGE_BOTH) + *edge = value; + else + return PERIPHERAL_ERROR_UNKNOWN; + return ret; } diff --git a/src/peripheral_gdbus_pwm.c b/src/peripheral_gdbus_pwm.c index a3b8b51..b32074e 100644 --- a/src/peripheral_gdbus_pwm.c +++ b/src/peripheral_gdbus_pwm.c @@ -122,13 +122,14 @@ int peripheral_gdbus_pwm_get_period(peripheral_pwm_h pwm, int *period) { GError *error = NULL; peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gint value = 0; if (pwm_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; if (peripheral_io_gdbus_pwm_call_get_period_sync( pwm_proxy, pwm->handle, - (gint*)period, + &value, &ret, NULL, &error) == FALSE) { @@ -137,6 +138,8 @@ int peripheral_gdbus_pwm_get_period(peripheral_pwm_h pwm, int *period) return PERIPHERAL_ERROR_UNKNOWN; } + *period = value; + return ret; } @@ -166,13 +169,14 @@ int peripheral_gdbus_pwm_get_duty_cycle(peripheral_pwm_h pwm, int *duty_cycle) { GError *error = NULL; peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gint value = 0; if (pwm_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; if (peripheral_io_gdbus_pwm_call_get_duty_cycle_sync( pwm_proxy, pwm->handle, - (gint*)duty_cycle, + &value, &ret, NULL, &error) == FALSE) { @@ -181,6 +185,8 @@ int peripheral_gdbus_pwm_get_duty_cycle(peripheral_pwm_h pwm, int *duty_cycle) return PERIPHERAL_ERROR_UNKNOWN; } + *duty_cycle = value; + return ret; } @@ -210,13 +216,14 @@ int peripheral_gdbus_pwm_get_polarity(peripheral_pwm_h pwm, peripheral_pwm_polar { GError *error = NULL; peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gint value = 0; if (pwm_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; if (peripheral_io_gdbus_pwm_call_get_polarity_sync( pwm_proxy, pwm->handle, - (gint*)polarity, + &value, &ret, NULL, &error) == FALSE) { @@ -225,6 +232,11 @@ int peripheral_gdbus_pwm_get_polarity(peripheral_pwm_h pwm, peripheral_pwm_polar return PERIPHERAL_ERROR_UNKNOWN; } + if (!value) + *polarity = PERIPHERAL_PWM_POLARITY_NORMAL; + else + *polarity = PERIPHERAL_PWM_POLARITY_INVERSED; + return ret; } @@ -254,13 +266,14 @@ int peripheral_gdbus_pwm_get_enable(peripheral_pwm_h pwm, bool *enable) { GError *error = NULL; peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gboolean value = 0; if (pwm_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; if (peripheral_io_gdbus_pwm_call_get_enable_sync( pwm_proxy, pwm->handle, - (gint*)enable, + &value, &ret, NULL, &error) == FALSE) { @@ -269,6 +282,11 @@ int peripheral_gdbus_pwm_get_enable(peripheral_pwm_h pwm, bool *enable) return PERIPHERAL_ERROR_UNKNOWN; } + if (!value) + *enable = false; + else + *enable = true; + return ret; } -- 2.7.4 From 6e53073c2bed4bf3b8af764cb46b093fd5a55464 Mon Sep 17 00:00:00 2001 From: Hyeongsik Min Date: Thu, 8 Jun 2017 16:38:07 +0900 Subject: [PATCH 15/16] Replace error code from ENODEV with ENXIO Change error code ENODEV to ENXIO for the case of no such device, because ENODEV is not defined in tizen_error.h and is also suitable for the case. Change-Id: I5e0f6d17bc9af720fd6d15862aaa2fd8da259ad1 Signed-off-by: Hyeongsik Min --- include/peripheral_io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/peripheral_io.h b/include/peripheral_io.h index 5629ae3..baa48e1 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -36,6 +36,7 @@ extern "C" { typedef enum { PERIPHERAL_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ PERIPHERAL_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< I/O error */ + PERIPHERAL_ERROR_NO_DEVICE = TIZEN_ERROR_NO_SUCH_DEVICE, /**< No such device */ PERIPHERAL_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ PERIPHERAL_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ PERIPHERAL_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY, /**< Device or resource busy */ @@ -45,7 +46,6 @@ typedef enum { PERIPHERAL_ERROR_TIMED_OUT = TIZEN_ERROR_TIMED_OUT, /**< Time out */ PERIPHERAL_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ PERIPHERAL_ERROR_UNKNOWN = TIZEN_ERROR_UNKNOWN, /**< Unknown error */ - PERIPHERAL_ERROR_NO_DEVICE = -ENODEV, /**< No such device */ } peripheral_error_e; /** -- 2.7.4 From 1eaf4739166f64d583d4f18bdf6f9694c8972bbf Mon Sep 17 00:00:00 2001 From: "jino.cho" Date: Thu, 1 Jun 2017 10:32:26 +0900 Subject: [PATCH 16/16] Add API for the adc device This patch support the adc device. And, it should work properly if the patch for peripheral-bus is applied together. Change-Id: Iac0b0d3421634443ef2de95268b748ab098d5170 Signed-off-by: jino.cho --- CMakeLists.txt | 3 +- include/peripheral_gdbus.h | 1 + include/peripheral_gdbus_adc.h | 25 ++++++++++++++ include/peripheral_io.h | 33 ++++++++---------- src/peripheral_adc.c | 32 +++++------------- src/peripheral_gdbus_adc.c | 76 ++++++++++++++++++++++++++++++++++++++++++ src/peripheral_io.xml | 8 +++++ test/peripheral-io-test.c | 32 ++++++++++++++++++ 8 files changed, 167 insertions(+), 43 deletions(-) create mode 100644 include/peripheral_gdbus_adc.h create mode 100644 src/peripheral_gdbus_adc.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ebacf9e..725fed5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ SET(SOURCES src/peripheral_gpio.c src/peripheral_gdbus_gpio.c src/peripheral_gdbus_i2c.c src/peripheral_gdbus_pwm.c + src/peripheral_gdbus_adc.c src/peripheral_gdbus_uart.c src/peripheral_gdbus_spi.c src/peripheral_io_gdbus.c @@ -85,4 +86,4 @@ CONFIGURE_FILE( ) INSTALL(FILES ${PROJECT_NAME}.pc DESTINATION ${libdir}/pkgconfig) -ADD_SUBDIRECTORY(test) \ No newline at end of file +ADD_SUBDIRECTORY(test) diff --git a/include/peripheral_gdbus.h b/include/peripheral_gdbus.h index ff726de..0e4f15a 100644 --- a/include/peripheral_gdbus.h +++ b/include/peripheral_gdbus.h @@ -22,6 +22,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/peripheral_gdbus_adc.h b/include/peripheral_gdbus_adc.h new file mode 100644 index 0000000..2f90ecf --- /dev/null +++ b/include/peripheral_gdbus_adc.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 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_GDBUS_ADC_H__ +#define __PERIPHERAL_GDBUS_ADC_H__ + +void adc_proxy_init(void); +void adc_proxy_deinit(void); + +int peripheral_gdbus_adc_read(unsigned int device, unsigned int channel, int *data); + +#endif /* __PERIPHERAL_GDBUS_ADC_H__ */ diff --git a/include/peripheral_io.h b/include/peripheral_io.h index baa48e1..bba13ca 100644 --- a/include/peripheral_io.h +++ b/include/peripheral_io.h @@ -662,26 +662,21 @@ int peripheral_pwm_get_enable(peripheral_pwm_h pwm, bool *enable); */ /** - * @brief Struct for peripheral_gpio_s - */ - -#define DEVICE_NAME_SIZE 20 - -struct _peripheral_adc_s { - char device_name[DEVICE_NAME_SIZE]; - int channel; -}; - -/** - * @brief Pointer definition to the internal struct peripheral_adc_s + * @brief Reads data from the adc device. + * @since_tizen 4.0 + * + * @param[in] device The device number of the adc device + * @param[in] channel The channel number to read + * @param[out] data The address of buffer to read + * + * @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_INVALID_PARAMETER Invalid parameter + * @retval #PERIPHERAL_ERROR_UNKNOWN Unknown internal error + * @retval #PERIPHERAL_ERROR_NO_DEVICE Device is not exist or removed */ -typedef struct _peripheral_adc_s* peripheral_adc_context_h; - -peripheral_adc_context_h peripheral_adc_open(int channel); - -int peripheral_adc_read(peripheral_adc_context_h dev, int *data); - -int peripheral_adc_close(peripheral_adc_context_h dev); +int peripheral_adc_read(unsigned int device, unsigned int channel, int *data); /** * @} diff --git a/src/peripheral_adc.c b/src/peripheral_adc.c index 1aa2973..8df1d75 100644 --- a/src/peripheral_adc.c +++ b/src/peripheral_adc.c @@ -15,32 +15,18 @@ */ #include "peripheral_io.h" +#include "peripheral_gdbus_adc.h" +#include "peripheral_common.h" -#include -#include -#include - -peripheral_adc_context_h peripheral_adc_open(int channel) -{ - return NULL; -} - -int peripheral_adc_read(peripheral_adc_context_h dev, int *data) +int peripheral_adc_read(unsigned int device, unsigned int channel, int *data) { - if (dev == NULL) - return PERIPHERAL_ERROR_INVALID_PARAMETER; - if (data == NULL) - return PERIPHERAL_ERROR_INVALID_PARAMETER; + int ret = PERIPHERAL_ERROR_NONE; - return PERIPHERAL_ERROR_INVALID_OPERATION; -} - -int peripheral_adc_close(peripheral_adc_context_h dev) -{ - if (dev != NULL) - free(dev); + adc_proxy_init(); - dev = NULL; + ret = peripheral_gdbus_adc_read(device, channel, data); + if (ret < PERIPHERAL_ERROR_NONE) + _E("Failed to read, ret : %d", ret); - return PERIPHERAL_ERROR_INVALID_OPERATION; + return ret; } diff --git a/src/peripheral_gdbus_adc.c b/src/peripheral_gdbus_adc.c new file mode 100644 index 0000000..e9a2513 --- /dev/null +++ b/src/peripheral_gdbus_adc.c @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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_io.h" +#include "peripheral_gdbus.h" +#include "peripheral_common.h" +#include "peripheral_io_gdbus.h" + +PeripheralIoGdbusAdc *adc_proxy = NULL; + +void adc_proxy_init(void) +{ + GError *error = NULL; + + if (adc_proxy != NULL) + return; + + 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); +} + +void adc_proxy_deinit() +{ + if (adc_proxy) { + g_object_unref(adc_proxy); + if (!G_IS_OBJECT(adc_proxy)) + adc_proxy = NULL; + } +} + +int peripheral_gdbus_adc_read(unsigned int device, unsigned int channel, int *data) +{ + GError *error = NULL; + peripheral_error_e ret = PERIPHERAL_ERROR_NONE; + gint value; + + if (adc_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN; + + if (peripheral_io_gdbus_adc_call_read_sync( + adc_proxy, + device, + channel, + &value, + &ret, + NULL, + &error) == FALSE) { + _E("Error in %s() : %s\n", __func__, error->message); + g_error_free(error); + return PERIPHERAL_ERROR_UNKNOWN; + } + + *data = value; + + return ret; +} diff --git a/src/peripheral_io.xml b/src/peripheral_io.xml index ea4b1f9..16b3cd2 100644 --- a/src/peripheral_io.xml +++ b/src/peripheral_io.xml @@ -142,6 +142,14 @@ + + + + + + + + diff --git a/test/peripheral-io-test.c b/test/peripheral-io-test.c index 00bb5f7..23a63ae 100644 --- a/test/peripheral-io-test.c +++ b/test/peripheral-io-test.c @@ -908,8 +908,40 @@ int enter_pwm_test(void) return 0; } +int adc_read_channel(void) +{ + int device, channel, ret; + int value; + + printf("%s\n", __func__); + + printf("Enter adc device number\n"); + if (read_int_input(&device) < 0) + return -1; + + printf("Enter adc channel number\n"); + if (read_int_input(&channel) < 0) + return -1; + + if ((ret = peripheral_adc_read(device, channel, &value)) < 0) { + printf(">>>>> Failed to read adc value, ret : %d\n", ret); + return -1; + } + printf("ADC(%d,%d) Value = %d\n", device, channel, value); + + return 0; +} + +tc_table_t adc_tc_table[] = { + {"Read ADC Channel", 1, adc_read_channel}, + {"Go back to main", 0, enter_main}, + {NULL, 0, NULL}, +}; + int enter_adc_test(void) { + tc_table = adc_tc_table; + return 0; } -- 2.7.4