Skip to content

Commit d0eef64

Browse files
Merge pull request #48 from tiagocoutinho/gpio-set-many-one-value
Gpio set many one value
2 parents 5cbaae3 + 5c05881 commit d0eef64

File tree

6 files changed

+463
-41
lines changed

6 files changed

+463
-41
lines changed

docs/user_guide/gpio.md

+187-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,193 @@ Without further ado:
88
<span data-ty="input" data-ty-prompt="$">python</span>
99
<span data-ty="input" data-ty-prompt=">>>">from linuxpy.gpio import find</span>
1010
<span data-ty="input" data-ty-prompt=">>>">with find() as gpio:</span>
11-
<span data-ty="input" data-ty-prompt="..."> with gpio[1, 2, 5:8] as lines:</span>
11+
<span data-ty="input" data-ty-prompt="..."> with gpio.request([1, 2, 5:8]) as lines:</span>
1212
<span data-ty="input" data-ty-prompt=">>>"> print(lines[:])</span>
1313
<span data-ty>{1: 0, 2: 1, 5: 0, 6: 1, 7:0}</span>
1414
</div>
15+
16+
## Basics
17+
18+
The GPIO interface consists of a Device class representing a single gpiochip.
19+
20+
The Device works as a context manager but you can also manually handle open/close.
21+
22+
Example:
23+
24+
```python
25+
from linuxpy.gpio import Device
26+
27+
with Device.from_id(0) as gpio:
28+
info = gpio.get_info()
29+
print(info.name, info.label, len(info.lines))
30+
l0 = info.lines[0]
31+
print(f"L0: {l0.name!r} {l0.flags.name}")
32+
33+
# output should look somethig like:
34+
# gpiochip0 INT3450:00 32
35+
# L0: '' INPUT
36+
```
37+
38+
The example above also shows how to obtain information about the gpio device
39+
including up to date information about line usage.
40+
41+
linuxpy provides a `find` helper that makes it easier on single chip systems
42+
to work without knowing the chip number. So the example above can be written
43+
using `find`:
44+
45+
```python
46+
from linuxpy.gpio import find
47+
48+
with find() as gpio:
49+
info = gpio.get_info()
50+
print(info.name, info.label, len(info.lines))
51+
l0 = info.lines[0]
52+
print(f"L0: {l0.name!r} {l0.flags.name}")
53+
```
54+
55+
## Working with lines: Request
56+
57+
Lines need to be requested before working with them.
58+
A request for line(s) reserves it for exclusive access by the requestor.
59+
60+
The API uses a context manager and it looks like this:
61+
62+
```python
63+
with find() as gpio:
64+
with gpio.request([5, 12], "my sweet app", raw.LineFlag.OUTPUT) as lines:
65+
...
66+
```
67+
68+
The request is only sent at the entry of the context manager. This allows
69+
you to create the request object lazily and tweek it's parameters before
70+
actually reserving the lines.
71+
72+
Linuxpy transparently handles requests with more than 64 lines.
73+
74+
A helper is provided for 'dict like' access. So the example above can also be
75+
written as:
76+
77+
```python
78+
with find() as gpio:
79+
lines = gpio.request[5, 12]
80+
lines.name = "my sweet app"
81+
lines.flags = raw.LineFlag.OUTPUT
82+
with lines:
83+
...
84+
```
85+
86+
### Writting
87+
88+
To change OUTPUT line(s) value(s) simply invoke the `set_values` method on
89+
the request object:
90+
91+
```python
92+
with find() as gpio:
93+
with device.request([5, 12], "my sweet app", raw.LineFlag.OUTPUT) as lines:
94+
lines.set_values({5: 1})
95+
```
96+
97+
The example above reserves lines 5 and 7 for **output** by a client (aka
98+
consumer) called *my sweet app*. It then sets line 5 to 1.
99+
As you can see, it is possible to write only the lines you're interested.
100+
101+
A helper is provided for 'dict like' access. So the example above can also be
102+
written as:
103+
104+
```python
105+
with find() as gpio:
106+
with device.request([5, 12], "my sweet app", raw.LineFlag.OUTPUT) as lines:
107+
lines[5] = 1
108+
```
109+
110+
The dict like API also supports setting multiple lines. Here are some examples:
111+
112+
```python
113+
with find() as gpio:
114+
with device.request(tuple(range(16)), "16 lines reserved", raw.LineFlag.OUTPUT) as lines:
115+
# write line 5
116+
lines[5] = 1
117+
# set lines 7, 5, to 0 and 1 respectively
118+
lines[7, 5] = 0, 1
119+
# set all lines to 0
120+
lines[:] = 0
121+
# set lines 3, 10 to 0 and lines 12 to 1, 13 to 0 and 14 to 1
122+
lines[3, 10, 12:15] = (0, 0, 1, 0, 1)
123+
```
124+
125+
A current limitation is all lines in the request must share the same
126+
configuration. This is a linuxpy limitation as linux supports different line
127+
configurations in the same request.
128+
129+
### Reading
130+
131+
Reading line values is very similar to writting:
132+
133+
```python
134+
with find() as gpio:
135+
with device.request([5, 12], "my sweet app", raw.LineFlag.INPUT) as lines:
136+
values = lines.get_values([5, 12])
137+
138+
# values will be something like {5: 0, 12: 1}
139+
```
140+
141+
The "dict like" API is also supported for reading so the above example could be
142+
written as:
143+
144+
```python
145+
with find() as gpio:
146+
with device.request([5, 12], "my sweet app", raw.LineFlag.INPUT) as lines:
147+
values = lines[5, 12]
148+
149+
```
150+
151+
A more complex reads also works:
152+
153+
```python
154+
155+
with find() as gpio:
156+
with device.request(tuple(range(16)), "16 lines reserved", raw.LineFlag.INPUT) as lines:
157+
# read lines 7, 5
158+
values = lines[7, 5]
159+
# read all lines
160+
values = lines[:]
161+
# read lines 3, 6, 10, 12, 14
162+
values = lines[3, 6, 10:16:2]
163+
```
164+
165+
166+
## Edge detection events
167+
168+
The request object can be used as an infinite iterator to watch for line events:
169+
170+
```python
171+
172+
with find() as gpio:
173+
with device.request([1, 4], "a client", raw.LineFlag.INPUT) as lines:
174+
for event in lines:
175+
print(f"{event.type.name} #{event.sequence} detected for line {event.line}")
176+
```
177+
178+
Reading one event is easy:
179+
180+
```python
181+
182+
event = next(iter(lines))
183+
184+
```
185+
186+
Async API is also supported:
187+
188+
```python
189+
import asyncio
190+
191+
192+
async def main():
193+
with find() as gpio:
194+
with device.request([1, 4], "a client", raw.LineFlag.INPUT) as lines:
195+
async for event in lines:
196+
print(f"{event.type.name} #{event.sequence} detected for line {event.line}")
197+
198+
199+
asyncio.run(main())
200+
```

linuxpy/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
# Copyright (c) 2023 Tiago Coutinho
55
# Distributed under the GPLv3 license. See LICENSE for more info.
66

7-
__version__ = "0.16.0"
7+
__version__ = "0.18.0"

0 commit comments

Comments
 (0)