int peripheral_dbus_gpio_write(peripheral_gpio_h gpio, int value);
int peripheral_dbus_gpio_get_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e *edge);
int peripheral_dbus_gpio_set_edge_mode(peripheral_gpio_h gpio, peripheral_gpio_edge_e edge);
+int peripheral_dbus_gpio_register_cb(peripheral_gpio_h gpio, gpio_isr_cb callback, void *user_data);
+int peripheral_dbus_gpio_unregister_cb(peripheral_gpio_h gpio);
int peripheral_dbus_i2c_open(peripheral_i2c_h i2c, int bus, int address);
int peripheral_dbus_i2c_close(peripheral_i2c_h i2c);
#include "peripheral_internal.h"
#include "peripheral_io_gdbus.h"
+extern int peripheral_gpio_isr_callback(int pin);
+void handle_gpio_changed(PeripheralIoGdbusGpio *gpio, gint pin, gint state, gpointer user_data);
+
PeripheralIoGdbusGpio *gpio_proxy = NULL;
PeripheralIoGdbusI2c *i2c_proxy = NULL;
PeripheralIoGdbusPwm *pwm_proxy = NULL;
PERIPHERAL_DBUS_GPIO_PATH,
NULL,
&error);
+ if (gpio_proxy == NULL) {
+ _E("Can not create gpio proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ g_signal_connect(gpio_proxy,
+ "gpio-changed",
+ G_CALLBACK(handle_gpio_changed),
+ NULL);
}
void i2c_proxy_init(void)
}
}
+void handle_gpio_changed(
+ PeripheralIoGdbusGpio *gpio,
+ gint pin,
+ gint state,
+ gpointer user_data)
+{
+ if (!gpio)
+ return;
+
+ _D("gpio=%d state=%d",pin, state);
+
+ peripheral_gpio_isr_callback(pin);
+}
+
int peripheral_dbus_gpio_open(peripheral_gpio_h gpio)
{
GError *error = NULL;
return ret;
}
+int peripheral_dbus_gpio_register_cb(peripheral_gpio_h gpio, gpio_isr_cb callback, void *user_data)
+{
+ GError *error = NULL;
+ peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+ if (gpio_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+ if (peripheral_io_gdbus_gpio_call_register_irq_sync(
+ gpio_proxy,
+ gpio->pin,
+ &ret,
+ NULL,
+ &error) == FALSE) {
+ _E("Error in %s() : %s\n", __func__, error->message);
+ g_error_free(error);
+ return PERIPHERAL_ERROR_UNKNOWN;
+ }
+
+ return ret;
+}
+
+int peripheral_dbus_gpio_unregister_cb(peripheral_gpio_h gpio)
+{
+ GError *error = NULL;
+ peripheral_error_e ret = PERIPHERAL_ERROR_NONE;
+
+ if (gpio_proxy == NULL) return PERIPHERAL_ERROR_UNKNOWN;
+
+ if (peripheral_io_gdbus_gpio_call_unregister_irq_sync(
+ gpio_proxy,
+ gpio->pin,
+ &ret,
+ NULL,
+ &error) == FALSE) {
+ _E("Error in %s() : %s\n", __func__, error->message);
+ g_error_free(error);
+ return PERIPHERAL_ERROR_UNKNOWN;
+ }
+
+ return ret;
+}
+
int peripheral_dbus_i2c_open(peripheral_i2c_h i2c, int bus, int address)
{
GError *error = NULL;
#include "peripheral_internal.h"
#include "peripheral_io_gdbus.h"
+typedef struct {
+ int pin;
+ gpio_isr_cb callback;
+ void *user_data;
+} gpio_isr_data_s;
+
+static GList *gpio_isr_list = NULL;
+
+int peripheral_gpio_isr_callback(int pin)
+{
+ GList *link;
+ gpio_isr_data_s *isr_data;
+
+ link = gpio_isr_list;
+ while (link) {
+ isr_data = (gpio_isr_data_s*)link->data;
+
+ if (isr_data->pin == pin) {
+ if (isr_data->callback)
+ isr_data->callback(isr_data->user_data);
+ return PERIPHERAL_ERROR_NONE;
+ }
+ link = g_list_next(link);
+ }
+
+ return PERIPHERAL_ERROR_NONE;
+}
+
+int peripheral_gpio_isr_set(int pin, gpio_isr_cb callback, void *user_data)
+{
+ GList *link;
+ gpio_isr_data_s *isr_data = NULL;
+
+ link = gpio_isr_list;
+ while (link) {
+ gpio_isr_data_s *tmp;
+ tmp = (gpio_isr_data_s*)link->data;
+ if (tmp->pin == pin) {
+ isr_data = tmp;
+ break;
+ }
+ link = g_list_next(link);
+ }
+
+ if (isr_data == NULL) {
+ isr_data = (gpio_isr_data_s*)calloc(1, sizeof(gpio_isr_data_s));
+ if (isr_data == NULL) {
+ _E("failed to allocate gpio_isr_data_s");
+ return PERIPHERAL_ERROR_OUT_OF_MEMORY;
+ }
+
+ gpio_isr_list = g_list_append(gpio_isr_list, isr_data);
+ }
+
+ isr_data->pin = pin;
+ isr_data->callback = callback;
+ isr_data->user_data = user_data;
+
+ return PERIPHERAL_ERROR_NONE;
+}
+
+int peripheral_gpio_isr_unset(int pin)
+{
+ GList *link;
+ gpio_isr_data_s *isr_data;
+
+ link = gpio_isr_list;
+ while (link) {
+ isr_data = (gpio_isr_data_s*)link->data;
+
+ if (isr_data->pin == pin) {
+ gpio_isr_list = g_list_remove_link(gpio_isr_list, link);
+ free(link->data);
+ g_list_free(link);
+ break;
+ }
+ link = g_list_next(link);
+ }
+
+ return PERIPHERAL_ERROR_NONE;
+}
+
/**
* @brief Initializes(export) gpio pin and creates gpio handle.
*/
*/
int peripheral_gpio_register_cb(peripheral_gpio_h gpio, gpio_isr_cb callback, void *user_data)
{
+ int ret = PERIPHERAL_ERROR_NONE;
+
/* check validation of gpio context handle */
if (gpio == NULL)
return PERIPHERAL_ERROR_INVALID_PARAMETER;
- //TODO
- return PERIPHERAL_ERROR_INVALID_OPERATION;
+ ret = peripheral_dbus_gpio_register_cb(gpio, callback, user_data);
+ if (ret != PERIPHERAL_ERROR_NONE)
+ return ret;
+
+ /* set isr */
+ ret = peripheral_gpio_isr_set(gpio->pin, callback, user_data);
+
+ return ret;
}
/**
*/
int peripheral_gpio_unregister_cb(peripheral_gpio_h gpio)
{
+ int ret = PERIPHERAL_ERROR_NONE;
+
/* check validation of gpio context handle */
if (gpio == NULL)
return PERIPHERAL_ERROR_INVALID_PARAMETER;
- //TODO
- return PERIPHERAL_ERROR_INVALID_OPERATION;
+
+ ret = peripheral_dbus_gpio_unregister_cb(gpio);
+ if (ret != PERIPHERAL_ERROR_NONE)
+ return ret;
+
+ /* clean up isr */
+ ret = peripheral_gpio_isr_unset(gpio->pin);
+
+ return ret;
}
/**
<arg type="i" name="edge" direction="in"/>
<arg type="i" name="result" direction="out"/>
</method>
+ <method name="RegisterIrq">
+ <arg type="i" name="pin" direction="in"/>
+ <arg type="i" name="result" direction="out"/>
+ </method>
+ <method name="UnregisterIrq">
+ <arg type="i" name="pin" direction="in"/>
+ <arg type="i" name="result" direction="out"/>
+ </method>
+ <signal name='GpioChanged'>
+ <arg type='i' name='pin'/>
+ <arg type='i' name='state'/>
+ </signal>
</interface>
<interface name="org.tizen.peripheral_io.i2c">
<method name="Open">
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <gio/gio.h>
extern int gpio_test();
extern int i2c_test();
extern int adc_test();
+GMainLoop *loop;
+
int gpio_test(void)
{
int num;
return 0;
}
+void gpio_irq_test_isr(void *user_data)
+{
+ int pin;
+ peripheral_gpio_h gpio = user_data;
+
+ peripheral_gpio_get_pin(gpio, &pin);
+
+ printf("gpio_irq_test_isr: GPIO %d interrupt occurs.\n", pin);
+}
+
+void *gpio_irq_test_thread(void *data)
+{
+ 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;
+
+ printf("artik710 : 27 \n");
+ printf(">> PIN NUMBER : ");
+
+ if (scanf("%d", &num) < 0)
+ return 0;
+
+ if (peripheral_gpio_open(num, &gpio) != PERIPHERAL_ERROR_NONE) {
+ printf("test dev is null\n");
+ return 0;
+ }
+
+ if (peripheral_gpio_set_direction(gpio, PERIPHERAL_GPIO_DIRECTION_IN) != 0) {
+ printf("test set direction error!!!");
+ goto error;
+ }
+
+ printf(">> Select Edge Mode (0 = None, 1 = Falling, 2 = Rising, 3 = Both) : ");
+ if (scanf("%d", &num) < 0)
+ return 0;
+
+ if (num >= 0 && num <= 3)
+ edge = num;
+
+ peripheral_gpio_set_edge_mode( gpio, edge);
+ peripheral_gpio_register_cb(gpio, gpio_irq_test_isr, 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);
+
+ g_thread_join(test_thread);
+ if (loop != NULL)
+ g_main_loop_unref(loop);
+
+ return 0;
+
+error:
+ peripheral_gpio_close(gpio);
+ return 0;
+}
/* Address of GY30 light sensor */
#define GY30_ADDR 0x23
printf(" 3. pwm led test\n");
printf(" 4. pwm motor test\n");
- printf(" 11. H/W IF GPIO Test\n");
+ 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");
ret = pwm_test_motor();
break;
case 11:
- ret = gpio_test();
+ ret = gpio_irq_test();
break;
case 12:
ret = i2c_test();