@@ -8,7 +8,193 @@ Without further ado:
8
8
<span data-ty =" input " data-ty-prompt =" $ " >python</span >
9
9
<span data-ty =" input " data-ty-prompt =" >>> " >from linuxpy.gpio import find</span >
10
10
<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 >
12
12
<span data-ty =" input " data-ty-prompt =" >>> " > print(lines[ :] )</span >
13
13
<span data-ty >{1: 0, 2: 1, 5: 0, 6: 1, 7:0}</span >
14
14
</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
+ ```
0 commit comments