File: line-settings.c

package info (click to toggle)
libgpiod 2.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,172 kB
  • sloc: ansic: 26,661; sh: 8,090; cpp: 4,944; python: 2,426; makefile: 811; xml: 49
file content (126 lines) | stat: -rw-r--r-- 2,948 bytes parent folder | download | duplicates (3)
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
// SPDX-License-Identifier: LGPL-2.1-or-later
// SPDX-FileCopyrightText: 2022 Bartosz Golaszewski <brgl@bgdev.pl>

#include "internal.h"

typedef struct {
	PyObject_HEAD;
	struct gpiod_line_settings *settings;
} line_settings_object;

static int set_error(void)
{
	Py_gpiod_SetErrFromErrno();
	return -1;
}

static int
line_settings_init(line_settings_object *self, PyObject *args, PyObject *kwargs)
{
	static char *kwlist[] = {
		"direction",
		"edge_detection",
		"bias",
		"drive",
		"active_low",
		"debounce_period",
		"event_clock",
		"output_value",
		NULL
	};

	enum gpiod_line_clock event_clock;
	enum gpiod_line_direction direction;
	enum gpiod_line_value output_value;
	unsigned long debounce_period;
	enum gpiod_line_drive drive;
	enum gpiod_line_edge edge;
	enum gpiod_line_bias bias;
	int ret, active_low;

	ret = PyArg_ParseTupleAndKeywords(args, kwargs, "IIIIpkII", kwlist,
			&direction, &edge, &bias, &drive, &active_low,
			&debounce_period, &event_clock, &output_value);
	if (!ret)
		return -1;

	self->settings = gpiod_line_settings_new();
	if (!self->settings) {
		Py_gpiod_SetErrFromErrno();
		return -1;
	}

	ret = gpiod_line_settings_set_direction(self->settings, direction);
	if (ret)
		return set_error();

	ret = gpiod_line_settings_set_edge_detection(self->settings, edge);
	if (ret)
		return set_error();

	ret = gpiod_line_settings_set_bias(self->settings, bias);
	if (ret)
		return set_error();

	ret = gpiod_line_settings_set_drive(self->settings, drive);
	if (ret)
		return set_error();

	gpiod_line_settings_set_active_low(self->settings, active_low);
	gpiod_line_settings_set_debounce_period_us(self->settings,
						   debounce_period);

	ret = gpiod_line_settings_set_edge_detection(self->settings, edge);
	if (ret)
		return set_error();

	ret = gpiod_line_settings_set_output_value(self->settings,
						   output_value);
	if (ret)
		return set_error();

	ret = gpiod_line_settings_set_event_clock(self->settings, event_clock);
	if (ret)
		return set_error();

	return 0;
}

static void line_settings_finalize(line_settings_object *self)
{
	if (self->settings)
		gpiod_line_settings_free(self->settings);
}

PyTypeObject line_settings_type = {
	PyVarObject_HEAD_INIT(NULL, 0)
	.tp_name = "gpiod._ext.LineSettings",
	.tp_basicsize = sizeof(line_settings_object),
	.tp_flags = Py_TPFLAGS_DEFAULT,
	.tp_new = PyType_GenericNew,
	.tp_init = (initproc)line_settings_init,
	.tp_finalize = (destructor)line_settings_finalize,
	.tp_dealloc = (destructor)Py_gpiod_dealloc,
};

struct gpiod_line_settings *Py_gpiod_LineSettingsGetData(PyObject *obj)
{
	line_settings_object *settings;
	PyObject *type;

	type = PyObject_Type(obj);
	if (!type)
		return NULL;

	if ((PyTypeObject *)type != &line_settings_type) {
		PyErr_SetString(PyExc_TypeError,
				"not a gpiod._ext.LineSettings object");
		Py_DECREF(type);
		return NULL;
	}
	Py_DECREF(type);

	settings = (line_settings_object *)obj;

	return settings->settings;
}