From 10ef55d6b0581b3b0cddba3005f61bfa9821a072 Mon Sep 17 00:00:00 2001 From: M-A Date: Sun, 17 Jun 2018 21:50:33 -0400 Subject: [PATCH] cap1188: tweaks in the device driver (#244) - Change DefaultOpts to be a struct instead of a function. This makes the godoc much more descriptive. - Change InputStatus() to accept a slice, so that the driver will be able to eventually support the flavors cap1155 and cap1166. --- experimental/devices/cap1188/cap1188.go | 19 +++++++++------ .../devices/cap1188/cap1188_options.go | 24 ++++++++----------- experimental/devices/cap1188/cap1188_test.go | 17 +++++++------ ...ap1188_example_test.go => example_test.go} | 8 +++---- 4 files changed, 34 insertions(+), 34 deletions(-) rename experimental/devices/cap1188/{cap1188_example_test.go => example_test.go} (92%) diff --git a/experimental/devices/cap1188/cap1188.go b/experimental/devices/cap1188/cap1188.go index f043d38..d291f32 100644 --- a/experimental/devices/cap1188/cap1188.go +++ b/experimental/devices/cap1188/cap1188.go @@ -17,6 +17,7 @@ import ( "encoding/binary" "fmt" "log" + "strconv" "time" "periph.io/x/periph/conn" @@ -47,7 +48,7 @@ var touchStatusIndex = [...]uint8{0, 9, 22, 32, 46} func (i TouchStatus) String() string { if i < 0 || i >= TouchStatus(len(touchStatusIndex)-1) { - return fmt.Sprintf("TouchStatus(%d)", i) + return "TouchStatus(" + strconv.Itoa(int(i)) + ")" } return touchStatusName[touchStatusIndex[i]:touchStatusIndex[i+1]] } @@ -57,7 +58,7 @@ func (i TouchStatus) String() string { // Use default options if nil is used. func NewI2C(b i2c.Bus, opts *Opts) (*Dev, error) { if opts == nil { - opts = DefaultOpts() + opts = &DefaultOpts } addr, err := opts.i2cAddr() if err != nil { @@ -100,13 +101,17 @@ func (d *Dev) Halt() error { return nil } -// InputStatus reads and returns the status of the 8 inputs. -func (d *Dev) InputStatus() ([8]TouchStatus, error) { +// InputStatus reads and returns the status of the inputs. +// +// The slice t will have the sensed inputs updated upon successful read. If the +// slice is too long, extraneous elements are ignored. If the slice is too +// short, only the provided subset is updated without error. +func (d *Dev) InputStatus(t []TouchStatus) error { d.resetSinceAtLeast(200 * time.Millisecond) // Read inputs. status, err := d.c.ReadUint8(0x3) if err != nil { - return d.inputStatuses, wrapf("failed to read the input values: %v", err) + return wrapf("failed to read the input values: %v", err) } // Read deltas (in two's complement, capped at -128 to 127). @@ -143,8 +148,8 @@ func (d *Dev) InputStatus() ([8]TouchStatus, error) { d.inputStatuses[i] = OffStatus } } - - return d.inputStatuses, nil + copy(t, d.inputStatuses[:]) + return nil } // LinkLEDs links the behavior of the LEDs to the touch sensors. diff --git a/experimental/devices/cap1188/cap1188_options.go b/experimental/devices/cap1188/cap1188_options.go index 84eaa49..5aeec9e 100644 --- a/experimental/devices/cap1188/cap1188_options.go +++ b/experimental/devices/cap1188/cap1188_options.go @@ -13,7 +13,6 @@ import ( // SamplingTime determines the time to make a single sample. type SamplingTime uint8 -// Possible sampling time values. (written as 2 bits) const ( S320us SamplingTime = 0 S640us SamplingTime = 1 @@ -25,7 +24,6 @@ const ( // AvgSampling set the number of samples per measurement that get averaged. type AvgSampling uint8 -// Possible average sampling values. (written as 3 bits) const ( // Avg1 means that 1 sample is taken per measurement Avg1 AvgSampling = iota // 0 @@ -142,16 +140,14 @@ func (o *Opts) i2cAddr() (uint16, error) { } } -// DefaultOpts returns a pointer to a new Opts with the default option values. -func DefaultOpts() *Opts { - return &Opts{ - LinkedLEDs: true, - MaxTouchDuration: MaxDur5600ms, - RetriggerOnHold: false, - EnableRecalibration: false, - InterruptOnRelease: false, - SamplesPerMeasurement: Avg1, - SamplingTime: S1_28ms, - CycleTime: C35ms, - } +// DefaultOpts contains default options to use. +var DefaultOpts = Opts{ + LinkedLEDs: true, + MaxTouchDuration: MaxDur5600ms, + RetriggerOnHold: false, + EnableRecalibration: false, + InterruptOnRelease: false, + SamplesPerMeasurement: Avg1, + SamplingTime: S1_28ms, + CycleTime: C35ms, } diff --git a/experimental/devices/cap1188/cap1188_test.go b/experimental/devices/cap1188/cap1188_test.go index 31038ca..89e38cd 100644 --- a/experimental/devices/cap1188/cap1188_test.go +++ b/experimental/devices/cap1188/cap1188_test.go @@ -141,12 +141,12 @@ func TestDev_InputStatus(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - d, err := NewI2C(tt.bus, DefaultOpts()) + d, err := NewI2C(tt.bus, &DefaultOpts) if err != nil { t.Fatal(err) } - got, err := d.InputStatus() - if err != nil { + var got [8]TouchStatus + if err := d.InputStatus(got[:]); err != nil { t.Fatalf("Dev.InputStatus() error = %v", err) } if !reflect.DeepEqual(got, tt.want) { @@ -173,24 +173,23 @@ func TestDev_InputStatus(t *testing.T) { } // Set the recorded response to have the retrigger option on. bus.Ops[10] = i2ctest.IO{Addr: 40, W: []byte{0x28, 0xff}, R: nil} - opts := DefaultOpts() + opts := DefaultOpts // Following option needs to be true so we can get the held status. opts.RetriggerOnHold = true - d, err := NewI2C(bus, opts) + d, err := NewI2C(bus, &opts) if err != nil { t.Fatal(err) } // first check - got, err := d.InputStatus() - if err != nil { + var got [8]TouchStatus + if err := d.InputStatus(got[:]); err != nil { t.Fatal(err) } if !reflect.DeepEqual(got, [8]TouchStatus{PressedStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus}) { t.Fatalf("expected to have the first sensor touched but instead got %v", got) } // 2nd check - got, err = d.InputStatus() - if err != nil { + if err = d.InputStatus(got[:]); err != nil { t.Fatal(err) } if !reflect.DeepEqual(got, [8]TouchStatus{HeldStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus}) { diff --git a/experimental/devices/cap1188/cap1188_example_test.go b/experimental/devices/cap1188/example_test.go similarity index 92% rename from experimental/devices/cap1188/cap1188_example_test.go rename to experimental/devices/cap1188/example_test.go index f6edc5d..0278f53 100644 --- a/experimental/devices/cap1188/cap1188_example_test.go +++ b/experimental/devices/cap1188/example_test.go @@ -42,12 +42,12 @@ func Example() { // We will configure the cap1188 by setting some options, we can start by the // defaults. - opts := cap1188.DefaultOpts() + opts := cap1188.DefaultOpts opts.AlertPin = alertPin opts.ResetPin = resetPin // Open the device so we can detect touch events. - dev, err := cap1188.NewI2C(i2cBus, opts) + dev, err := cap1188.NewI2C(i2cBus, &opts) if err != nil { log.Fatalf("couldn't open cap1188: %v", err) } @@ -57,8 +57,8 @@ func Example() { for maxTouches > 0 { if alertPin.WaitForEdge(-1) { maxTouches-- - statuses, err := dev.InputStatus() - if err != nil { + var statuses [8]cap1188.TouchStatus + if err := dev.InputStatus(statuses[:]); err != nil { fmt.Printf("Error reading inputs: %v\n", err) continue }