Skip to content

Commit 02c216f

Browse files
authored
gpioioctl: Correct gpioioctl to implement gpio.Group (#67)
* Change lineset to implement gpio.Group() * Update go.mod, move to current conn version
1 parent 28c0c75 commit 02c216f

File tree

4 files changed

+43
-26
lines changed

4 files changed

+43
-26
lines changed

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ module periph.io/x/host/v3
77
go 1.22.6
88

99
require (
10-
periph.io/x/conn/v3 v3.7.1
10+
periph.io/x/conn/v3 v3.7.2
1111
periph.io/x/d2xx v0.1.1
1212
)

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
22
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
3-
periph.io/x/conn/v3 v3.7.1 h1:tMjNv3WO8jEz/ePuXl7y++2zYi8LsQ5otbmqGKy3Myg=
4-
periph.io/x/conn/v3 v3.7.1/go.mod h1:c+HCVjkzbf09XzcqZu/t+U8Ss/2QuJj0jgRF6Nye838=
3+
periph.io/x/conn/v3 v3.7.2 h1:qt9dE6XGP5ljbFnCKRJ9OOCoiOyBGlw7JZgoi72zZ1s=
4+
periph.io/x/conn/v3 v3.7.2/go.mod h1:Ao0b4sFRo4QOx6c1tROJU1fLJN1hUIYggjOrkIVnpGg=
55
periph.io/x/d2xx v0.1.1 h1:LHp+u+qAWLB5THrTT/AzyjdvfUhllvDF5wBJP7uvn+U=
66
periph.io/x/d2xx v0.1.1/go.mod h1:rLM321G11Fc14Pp088khBkmXb70Pxx/kCPaIK7uRUBc=

gpioioctl/example_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ func testRotary(chip *gpioioctl.GPIOChip, stateLine, dataLine, buttonLine string
4747
log.Fatal(err)
4848
}
4949
defer ls.Close()
50-
statePinNumber := uint32(ls.ByOffset(0).Number())
51-
buttonPinNumber := uint32(ls.ByOffset(2).Number())
50+
statePinNumber := ls.ByOffset(0).Number()
51+
buttonPinNumber := ls.ByOffset(2).Number()
5252

5353
var tLast = time.Now().Add(-1 * time.Second)
5454
var halting bool
@@ -68,7 +68,7 @@ func testRotary(chip *gpioioctl.GPIOChip, stateLine, dataLine, buttonLine string
6868
}
6969
tLast = tNow
7070
if lineNumber == statePinNumber {
71-
var bits uint64
71+
var bits gpio.GPIOValue
7272
tDeadline := tNow.UnixNano() + 20_000_000
7373
var consecutive uint64
7474
for time.Now().UnixNano() < tDeadline {

gpioioctl/lineset.go

+37-20
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import (
1111
"fmt"
1212
"log"
1313
"os"
14-
"sync"
15-
"time"
16-
1714
"periph.io/x/conn/v3/gpio"
1815
"periph.io/x/conn/v3/physic"
16+
"periph.io/x/conn/v3/pin"
17+
"sync"
18+
"time"
1919
)
2020

2121
// LineConfigOverride is an override for a LineSet configuration.
@@ -147,6 +147,14 @@ func (ls *LineSet) Lines() []*LineSetLine {
147147
return ls.lines
148148
}
149149

150+
func (ls *LineSet) Pins() []pin.Pin {
151+
pins := make([]pin.Pin, len(ls.lines))
152+
for ix, l := range ls.lines {
153+
pins[ix] = l
154+
}
155+
return pins
156+
}
157+
150158
// Interrupt any calls to WaitForEdge().
151159
func (ls *LineSet) Halt() error {
152160
if ls.fEdge != nil {
@@ -163,33 +171,33 @@ func (ls *LineSet) Halt() error {
163171
// bits is the values for each line in the bit set.
164172
//
165173
// mask is a bitmask indicating which bits should be applied.
166-
func (ls *LineSet) Out(bits, mask uint64) error {
174+
func (ls *LineSet) Out(bits, mask gpio.GPIOValue) error {
167175
ls.mu.Lock()
168176
defer ls.mu.Unlock()
169177
var data gpio_v2_line_values
170-
data.bits = bits
178+
data.bits = uint64(bits)
171179
if mask == 0 {
172180
mask = (1 << ls.LineCount()) - 1
173181
}
174-
data.mask = mask
182+
data.mask = uint64(mask)
175183
return ioctl_set_gpio_v2_line_values(uintptr(ls.fd), &data)
176184
}
177185

178186
// Read the pins in this LineSet. This is done as one syscall to the
179187
// operating system and will be very fast. mask is a bitmask of set pins
180188
// to read. If 0, then all pins are read.
181-
func (ls *LineSet) Read(mask uint64) (uint64, error) {
189+
func (ls *LineSet) Read(mask gpio.GPIOValue) (gpio.GPIOValue, error) {
182190
ls.mu.Lock()
183191
defer ls.mu.Unlock()
184192
if mask == 0 {
185193
mask = (1 << ls.LineCount()) - 1
186194
}
187195
var lvalues gpio_v2_line_values
188-
lvalues.mask = mask
196+
lvalues.mask = uint64(mask)
189197
if err := ioctl_get_gpio_v2_line_values(uintptr(ls.fd), &lvalues); err != nil {
190198
return 0, err
191199
}
192-
return lvalues.bits, nil
200+
return gpio.GPIOValue(lvalues.bits), nil
193201
}
194202

195203
func (ls *LineSet) MarshalJSON() ([]byte, error) {
@@ -216,7 +224,7 @@ func (ls *LineSet) String() string {
216224
// then the edge returned will be gpio.NoEdge
217225
//
218226
// err - Error value if any.
219-
func (ls *LineSet) WaitForEdge(timeout time.Duration) (number uint32, edge gpio.Edge, err error) {
227+
func (ls *LineSet) WaitForEdge(timeout time.Duration) (number int, edge gpio.Edge, err error) {
220228
number = 0
221229
edge = gpio.NoEdge
222230
if ls.fEdge == nil {
@@ -248,21 +256,28 @@ func (ls *LineSet) WaitForEdge(timeout time.Duration) (number uint32, edge gpio.
248256
} else if event.Id == _GPIO_V2_LINE_EVENT_FALLING_EDGE {
249257
edge = gpio.FallingEdge
250258
}
251-
number = uint32(event.Offset)
259+
number = int(event.Offset)
252260
return
253261
}
254262

255-
// ByOffset returns a line by it's offset in the LineSet.
256-
func (ls *LineSet) ByOffset(offset int) *LineSetLine {
263+
// ByOffset returns a line by it's offset in the LineSet. See ByName() for an
264+
// example that casts the return value to a LineSetLine
265+
func (ls *LineSet) ByOffset(offset int) pin.Pin {
257266
if offset < 0 || offset >= len(ls.lines) {
258267
return nil
259268
}
260269
return ls.lines[offset]
261270
}
262271

263-
// ByName returns a Line by name from the LineSet.
264-
func (ls *LineSet) ByName(name string) *LineSetLine {
265-
272+
// ByName returns a Line by name from the LineSet. To cast the returned value
273+
// to a LineSet line, use:
274+
//
275+
// var lsl *gpioioctl.LineSetLine
276+
// lsl, ok := ls.ByNumber(line0.Number()).(*gpioioctl.LineSetLine)
277+
// if !ok {
278+
// log.Fatal("error converting to LineSetLine")
279+
// }
280+
func (ls *LineSet) ByName(name string) pin.Pin {
266281
for _, line := range ls.lines {
267282
if line.Name() == name {
268283
return line
@@ -272,8 +287,9 @@ func (ls *LineSet) ByName(name string) *LineSetLine {
272287
}
273288

274289
// LineNumber Return a line from the LineSet via it's GPIO line
275-
// number.
276-
func (ls *LineSet) ByNumber(number int) *LineSetLine {
290+
// number. See ByName() for an example that casts the return value to a
291+
// LineSetLine
292+
func (ls *LineSet) ByNumber(number int) pin.Pin {
277293
for _, line := range ls.lines {
278294
if line.Number() == number {
279295
return line
@@ -325,7 +341,7 @@ func (lsl *LineSetLine) Edge() gpio.Edge {
325341

326342
// Out writes to this specific GPIO line.
327343
func (lsl *LineSetLine) Out(l gpio.Level) error {
328-
var mask, bits uint64
344+
var mask, bits gpio.GPIOValue
329345
mask = 1 << lsl.offset
330346
if l {
331347
bits |= mask
@@ -353,7 +369,7 @@ func (lsl *LineSetLine) In(pull gpio.Pull, edge gpio.Edge) error {
353369

354370
// Read returns the value of this specific line.
355371
func (lsl *LineSetLine) Read() gpio.Level {
356-
var mask uint64 = 1 << lsl.offset
372+
var mask gpio.GPIOValue = 1 << lsl.offset
357373
bits, err := lsl.parent.Read(mask)
358374
if err != nil {
359375
log.Printf("LineSetLine.Read() Error reading line %d. Error: %s\n", lsl.number, err)
@@ -411,6 +427,7 @@ func (lsl *LineSetLine) Offset() uint32 {
411427
}
412428

413429
// Ensure that Interfaces for these types are implemented fully.
430+
var _ gpio.Group = &LineSet{}
414431
var _ gpio.PinIO = &LineSetLine{}
415432
var _ gpio.PinIn = &LineSetLine{}
416433
var _ gpio.PinOut = &LineSetLine{}

0 commit comments

Comments
 (0)