File: toggle_multiple_line_values_glib.c

package info (click to toggle)
libgpiod 2.2.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,108 kB
  • sloc: ansic: 26,612; sh: 7,554; cpp: 4,944; python: 2,426; makefile: 811; xml: 49
file content (132 lines) | stat: -rw-r--r-- 3,624 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2023-2024 Bartosz Golaszewski <bartosz.golaszewski@linaro.org>

/* Minimal example of periodically toggling multiple lines. */

#include <glib.h>
#include <gpiod-glib.h>
#include <stdlib.h>

typedef struct {
	GpiodglibLineRequest *request;
	GArray *offsets;
	GArray *values;
} ToggleData;

static void toggle_values(GArray *values)
{
	GpiodglibLineValue *value;
	guint i;

	for (i = 0; i < values->len; i++) {
		value = &g_array_index(values, GpiodglibLineValue, i);
		*value = *value == GPIODGLIB_LINE_VALUE_ACTIVE ?
					GPIODGLIB_LINE_VALUE_INACTIVE :
					GPIODGLIB_LINE_VALUE_ACTIVE;
	}
}

static gboolean toggle_lines(gpointer user_data)
{
	ToggleData *data = user_data;
	g_autoptr(GError) err = NULL;
	gboolean ret;
	guint i;

	toggle_values(data->values);

	ret = gpiodglib_line_request_set_values_subset(data->request,
						       data->offsets,
						       data->values, &err);
	if (!ret) {
		g_printerr("failed to set line values: %s\n", err->message);
		exit(EXIT_FAILURE);
	}

	for (i = 0; i < data->offsets->len; i++)
		g_print("%u=%s ",
			g_array_index(data->offsets, guint, i),
			g_array_index(data->values,
				      GpiodglibLineValue,
				      i) == GPIODGLIB_LINE_VALUE_ACTIVE ?
						"active" : "inactive");
	g_print("\n");

	return G_SOURCE_CONTINUE;
}

int main(void)
{
	/* Example configuration - customize to suit your situation. */
	static const gchar *const chip_path = "/dev/gpiochip1";
	static const guint line_offsets[] = { 5, 3, 7 };
	static const GpiodglibLineValue line_values[] = {
		GPIODGLIB_LINE_VALUE_ACTIVE,
		GPIODGLIB_LINE_VALUE_ACTIVE,
		GPIODGLIB_LINE_VALUE_INACTIVE
	};
	static const gsize num_lines = 3;

	g_autoptr(GpiodglibRequestConfig) req_cfg = NULL;
	g_autoptr(GpiodglibLineSettings) settings = NULL;
	g_autoptr(GpiodglibLineRequest) request = NULL;
	g_autoptr(GpiodglibLineConfig) line_cfg = NULL;
	g_autoptr(GpiodglibChip) chip = NULL;
	g_autoptr(GArray) offsets = NULL;
	g_autoptr(GMainLoop) loop = NULL;
	g_autoptr(GArray) values = NULL;
	g_autoptr(GError) err = NULL;
	ToggleData data;
	gboolean ret;

	offsets = g_array_new(FALSE, TRUE, sizeof(guint));
	g_array_append_vals(offsets, line_offsets, num_lines);

	values = g_array_new(FALSE, TRUE, sizeof(GpiodglibLineValue));
	g_array_append_vals(values, line_values, num_lines);

	chip = gpiodglib_chip_new(chip_path, &err);
	if (!chip) {
		g_printerr("unable to open %s: %s\n", chip_path, err->message);
		return EXIT_FAILURE;
	}

	settings = gpiodglib_line_settings_new("direction",
					       GPIODGLIB_LINE_DIRECTION_OUTPUT,
					       NULL);
	line_cfg = gpiodglib_line_config_new();
	ret = gpiodglib_line_config_add_line_settings(line_cfg, offsets,
						      settings, &err);
	if (!ret) {
		g_printerr("failed to add line settings to line config: %s\n",
			   err->message);
		return EXIT_FAILURE;
	}

	ret = gpiodglib_line_config_set_output_values(line_cfg, values, &err);
	if (!ret) {
		g_printerr("failed to set output values: %s\n", err->message);
		return EXIT_FAILURE;
	}

	req_cfg = gpiodglib_request_config_new("consumer", "toggle-line-value",
					       NULL);

	request = gpiodglib_chip_request_lines(chip, req_cfg, line_cfg, &err);
	if (!request) {
		g_printerr("failed to request lines: %s\n", err->message);
		return EXIT_FAILURE;
	}

	data.request = request;
	data.offsets = offsets;
	data.values = values;

	loop = g_main_loop_new(NULL, FALSE);
	/* Do the GLib way: add a callback to be invoked from the main loop. */
	g_timeout_add_seconds(1, toggle_lines, &data);

	g_main_loop_run(loop);

	return EXIT_SUCCESS;
}