From fb6bdd41d41fe6711f7d1ad1bf0d85af2f61dafa Mon Sep 17 00:00:00 2001 From: George Sexton Date: Sat, 18 Jan 2025 17:13:19 -0700 Subject: [PATCH 1/4] Change lineset to implement gpio.Group() --- gpioioctl/example_test.go | 6 ++-- gpioioctl/lineset.go | 58 +++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/gpioioctl/example_test.go b/gpioioctl/example_test.go index a9b126f..e790cb4 100644 --- a/gpioioctl/example_test.go +++ b/gpioioctl/example_test.go @@ -47,8 +47,8 @@ func testRotary(chip *gpioioctl.GPIOChip, stateLine, dataLine, buttonLine string log.Fatal(err) } defer ls.Close() - statePinNumber := uint32(ls.ByOffset(0).Number()) - buttonPinNumber := uint32(ls.ByOffset(2).Number()) + statePinNumber := ls.ByOffset(0).Number() + buttonPinNumber := ls.ByOffset(2).Number() var tLast = time.Now().Add(-1 * time.Second) var halting bool @@ -68,7 +68,7 @@ func testRotary(chip *gpioioctl.GPIOChip, stateLine, dataLine, buttonLine string } tLast = tNow if lineNumber == statePinNumber { - var bits uint64 + var bits gpio.GPIOValue tDeadline := tNow.UnixNano() + 20_000_000 var consecutive uint64 for time.Now().UnixNano() < tDeadline { diff --git a/gpioioctl/lineset.go b/gpioioctl/lineset.go index 24de22d..4cf5554 100644 --- a/gpioioctl/lineset.go +++ b/gpioioctl/lineset.go @@ -11,11 +11,11 @@ import ( "fmt" "log" "os" - "sync" - "time" - "periph.io/x/conn/v3/gpio" "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" + "sync" + "time" ) // LineConfigOverride is an override for a LineSet configuration. @@ -147,6 +147,15 @@ func (ls *LineSet) Lines() []*LineSetLine { return ls.lines } +func (ls *LineSet) Pins() []*pin.Pin { + pins := make([]*pin.Pin, len(ls.lines)) + for ix, l := range ls.lines { + var p pin.Pin = l + pins[ix] = &p + } + return pins +} + // Interrupt any calls to WaitForEdge(). func (ls *LineSet) Halt() error { if ls.fEdge != nil { @@ -163,33 +172,33 @@ func (ls *LineSet) Halt() error { // bits is the values for each line in the bit set. // // mask is a bitmask indicating which bits should be applied. -func (ls *LineSet) Out(bits, mask uint64) error { +func (ls *LineSet) Out(bits, mask gpio.GPIOValue) error { ls.mu.Lock() defer ls.mu.Unlock() var data gpio_v2_line_values - data.bits = bits + data.bits = uint64(bits) if mask == 0 { mask = (1 << ls.LineCount()) - 1 } - data.mask = mask + data.mask = uint64(mask) return ioctl_set_gpio_v2_line_values(uintptr(ls.fd), &data) } // Read the pins in this LineSet. This is done as one syscall to the // operating system and will be very fast. mask is a bitmask of set pins // to read. If 0, then all pins are read. -func (ls *LineSet) Read(mask uint64) (uint64, error) { +func (ls *LineSet) Read(mask gpio.GPIOValue) (gpio.GPIOValue, error) { ls.mu.Lock() defer ls.mu.Unlock() if mask == 0 { mask = (1 << ls.LineCount()) - 1 } var lvalues gpio_v2_line_values - lvalues.mask = mask + lvalues.mask = uint64(mask) if err := ioctl_get_gpio_v2_line_values(uintptr(ls.fd), &lvalues); err != nil { return 0, err } - return lvalues.bits, nil + return gpio.GPIOValue(lvalues.bits), nil } func (ls *LineSet) MarshalJSON() ([]byte, error) { @@ -216,7 +225,7 @@ func (ls *LineSet) String() string { // then the edge returned will be gpio.NoEdge // // err - Error value if any. -func (ls *LineSet) WaitForEdge(timeout time.Duration) (number uint32, edge gpio.Edge, err error) { +func (ls *LineSet) WaitForEdge(timeout time.Duration) (number int, edge gpio.Edge, err error) { number = 0 edge = gpio.NoEdge if ls.fEdge == nil { @@ -248,21 +257,28 @@ func (ls *LineSet) WaitForEdge(timeout time.Duration) (number uint32, edge gpio. } else if event.Id == _GPIO_V2_LINE_EVENT_FALLING_EDGE { edge = gpio.FallingEdge } - number = uint32(event.Offset) + number = int(event.Offset) return } -// ByOffset returns a line by it's offset in the LineSet. -func (ls *LineSet) ByOffset(offset int) *LineSetLine { +// ByOffset returns a line by it's offset in the LineSet. See ByName() for an +// example that casts the return value to a LineSetLine +func (ls *LineSet) ByOffset(offset int) pin.Pin { if offset < 0 || offset >= len(ls.lines) { return nil } return ls.lines[offset] } -// ByName returns a Line by name from the LineSet. -func (ls *LineSet) ByName(name string) *LineSetLine { - +// ByName returns a Line by name from the LineSet. To cast the returned value +// to a LineSet line, use: +// +// var lsl *gpioioctl.LineSetLine +// lsl, ok := ls.ByNumber(line0.Number()).(*gpioioctl.LineSetLine) +// if !ok { +// log.Fatal("error converting to LineSetLine") +// } +func (ls *LineSet) ByName(name string) pin.Pin { for _, line := range ls.lines { if line.Name() == name { return line @@ -272,8 +288,9 @@ func (ls *LineSet) ByName(name string) *LineSetLine { } // LineNumber Return a line from the LineSet via it's GPIO line -// number. -func (ls *LineSet) ByNumber(number int) *LineSetLine { +// number. See ByName() for an example that casts the return value to a +// LineSetLine +func (ls *LineSet) ByNumber(number int) pin.Pin { for _, line := range ls.lines { if line.Number() == number { return line @@ -325,7 +342,7 @@ func (lsl *LineSetLine) Edge() gpio.Edge { // Out writes to this specific GPIO line. func (lsl *LineSetLine) Out(l gpio.Level) error { - var mask, bits uint64 + var mask, bits gpio.GPIOValue mask = 1 << lsl.offset if l { bits |= mask @@ -353,7 +370,7 @@ func (lsl *LineSetLine) In(pull gpio.Pull, edge gpio.Edge) error { // Read returns the value of this specific line. func (lsl *LineSetLine) Read() gpio.Level { - var mask uint64 = 1 << lsl.offset + var mask gpio.GPIOValue = 1 << lsl.offset bits, err := lsl.parent.Read(mask) if err != nil { log.Printf("LineSetLine.Read() Error reading line %d. Error: %s\n", lsl.number, err) @@ -411,6 +428,7 @@ func (lsl *LineSetLine) Offset() uint32 { } // Ensure that Interfaces for these types are implemented fully. +var _ gpio.Group = &LineSet{} var _ gpio.PinIO = &LineSetLine{} var _ gpio.PinIn = &LineSetLine{} var _ gpio.PinOut = &LineSetLine{} From 54a9d374f307a51ad8c645d73b734edad041f64c Mon Sep 17 00:00:00 2001 From: George Sexton Date: Sat, 8 Mar 2025 12:34:23 -0700 Subject: [PATCH 2/4] Convert for group --- gpioioctl/lineset.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gpioioctl/lineset.go b/gpioioctl/lineset.go index 4cf5554..7910d6f 100644 --- a/gpioioctl/lineset.go +++ b/gpioioctl/lineset.go @@ -147,11 +147,10 @@ func (ls *LineSet) Lines() []*LineSetLine { return ls.lines } -func (ls *LineSet) Pins() []*pin.Pin { - pins := make([]*pin.Pin, len(ls.lines)) +func (ls *LineSet) Pins() []pin.Pin { + pins := make([]pin.Pin, len(ls.lines)) for ix, l := range ls.lines { - var p pin.Pin = l - pins[ix] = &p + pins[ix] = l } return pins } From bfd9100fa6efde91bd431b2566e8f11e02978f62 Mon Sep 17 00:00:00 2001 From: George Sexton Date: Sun, 9 Mar 2025 13:02:25 -0600 Subject: [PATCH 3/4] Update go.mod, move to current conn version --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 144f9ff..dfea089 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,6 @@ module periph.io/x/host/v3 go 1.22.6 require ( - periph.io/x/conn/v3 v3.7.1 + periph.io/x/conn/v3 v3.7.2 periph.io/x/d2xx v0.1.1 ) From 6be3152c703522f574bb937da3d1bc60b74b96bb Mon Sep 17 00:00:00 2001 From: George Sexton Date: Sun, 9 Mar 2025 13:04:19 -0600 Subject: [PATCH 4/4] Fix go.sum --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index c0d2828..e78040c 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -periph.io/x/conn/v3 v3.7.1 h1:tMjNv3WO8jEz/ePuXl7y++2zYi8LsQ5otbmqGKy3Myg= -periph.io/x/conn/v3 v3.7.1/go.mod h1:c+HCVjkzbf09XzcqZu/t+U8Ss/2QuJj0jgRF6Nye838= +periph.io/x/conn/v3 v3.7.2 h1:qt9dE6XGP5ljbFnCKRJ9OOCoiOyBGlw7JZgoi72zZ1s= +periph.io/x/conn/v3 v3.7.2/go.mod h1:Ao0b4sFRo4QOx6c1tROJU1fLJN1hUIYggjOrkIVnpGg= periph.io/x/d2xx v0.1.1 h1:LHp+u+qAWLB5THrTT/AzyjdvfUhllvDF5wBJP7uvn+U= periph.io/x/d2xx v0.1.1/go.mod h1:rLM321G11Fc14Pp088khBkmXb70Pxx/kCPaIK7uRUBc=