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.
pull/1/head
M-A 8 years ago committed by GitHub
parent e1decce7e5
commit 10ef55d6b0

@ -17,6 +17,7 @@ import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"log" "log"
"strconv"
"time" "time"
"periph.io/x/periph/conn" "periph.io/x/periph/conn"
@ -47,7 +48,7 @@ var touchStatusIndex = [...]uint8{0, 9, 22, 32, 46}
func (i TouchStatus) String() string { func (i TouchStatus) String() string {
if i < 0 || i >= TouchStatus(len(touchStatusIndex)-1) { 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]] return touchStatusName[touchStatusIndex[i]:touchStatusIndex[i+1]]
} }
@ -57,7 +58,7 @@ func (i TouchStatus) String() string {
// Use default options if nil is used. // Use default options if nil is used.
func NewI2C(b i2c.Bus, opts *Opts) (*Dev, error) { func NewI2C(b i2c.Bus, opts *Opts) (*Dev, error) {
if opts == nil { if opts == nil {
opts = DefaultOpts() opts = &DefaultOpts
} }
addr, err := opts.i2cAddr() addr, err := opts.i2cAddr()
if err != nil { if err != nil {
@ -100,13 +101,17 @@ func (d *Dev) Halt() error {
return nil return nil
} }
// InputStatus reads and returns the status of the 8 inputs. // InputStatus reads and returns the status of the inputs.
func (d *Dev) InputStatus() ([8]TouchStatus, error) { //
// 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) d.resetSinceAtLeast(200 * time.Millisecond)
// Read inputs. // Read inputs.
status, err := d.c.ReadUint8(0x3) status, err := d.c.ReadUint8(0x3)
if err != nil { 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). // 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 d.inputStatuses[i] = OffStatus
} }
} }
copy(t, d.inputStatuses[:])
return d.inputStatuses, nil return nil
} }
// LinkLEDs links the behavior of the LEDs to the touch sensors. // LinkLEDs links the behavior of the LEDs to the touch sensors.

@ -13,7 +13,6 @@ import (
// SamplingTime determines the time to make a single sample. // SamplingTime determines the time to make a single sample.
type SamplingTime uint8 type SamplingTime uint8
// Possible sampling time values. (written as 2 bits)
const ( const (
S320us SamplingTime = 0 S320us SamplingTime = 0
S640us SamplingTime = 1 S640us SamplingTime = 1
@ -25,7 +24,6 @@ const (
// AvgSampling set the number of samples per measurement that get averaged. // AvgSampling set the number of samples per measurement that get averaged.
type AvgSampling uint8 type AvgSampling uint8
// Possible average sampling values. (written as 3 bits)
const ( const (
// Avg1 means that 1 sample is taken per measurement // Avg1 means that 1 sample is taken per measurement
Avg1 AvgSampling = iota // 0 Avg1 AvgSampling = iota // 0
@ -142,9 +140,8 @@ func (o *Opts) i2cAddr() (uint16, error) {
} }
} }
// DefaultOpts returns a pointer to a new Opts with the default option values. // DefaultOpts contains default options to use.
func DefaultOpts() *Opts { var DefaultOpts = Opts{
return &Opts{
LinkedLEDs: true, LinkedLEDs: true,
MaxTouchDuration: MaxDur5600ms, MaxTouchDuration: MaxDur5600ms,
RetriggerOnHold: false, RetriggerOnHold: false,
@ -154,4 +151,3 @@ func DefaultOpts() *Opts {
SamplingTime: S1_28ms, SamplingTime: S1_28ms,
CycleTime: C35ms, CycleTime: C35ms,
} }
}

@ -141,12 +141,12 @@ func TestDev_InputStatus(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
d, err := NewI2C(tt.bus, DefaultOpts()) d, err := NewI2C(tt.bus, &DefaultOpts)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
got, err := d.InputStatus() var got [8]TouchStatus
if err != nil { if err := d.InputStatus(got[:]); err != nil {
t.Fatalf("Dev.InputStatus() error = %v", err) t.Fatalf("Dev.InputStatus() error = %v", err)
} }
if !reflect.DeepEqual(got, tt.want) { 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. // Set the recorded response to have the retrigger option on.
bus.Ops[10] = i2ctest.IO{Addr: 40, W: []byte{0x28, 0xff}, R: nil} 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. // Following option needs to be true so we can get the held status.
opts.RetriggerOnHold = true opts.RetriggerOnHold = true
d, err := NewI2C(bus, opts) d, err := NewI2C(bus, &opts)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// first check // first check
got, err := d.InputStatus() var got [8]TouchStatus
if err != nil { if err := d.InputStatus(got[:]); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !reflect.DeepEqual(got, [8]TouchStatus{PressedStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus}) { 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) t.Fatalf("expected to have the first sensor touched but instead got %v", got)
} }
// 2nd check // 2nd check
got, err = d.InputStatus() if err = d.InputStatus(got[:]); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !reflect.DeepEqual(got, [8]TouchStatus{HeldStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus}) { if !reflect.DeepEqual(got, [8]TouchStatus{HeldStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus, OffStatus}) {

@ -42,12 +42,12 @@ func Example() {
// We will configure the cap1188 by setting some options, we can start by the // We will configure the cap1188 by setting some options, we can start by the
// defaults. // defaults.
opts := cap1188.DefaultOpts() opts := cap1188.DefaultOpts
opts.AlertPin = alertPin opts.AlertPin = alertPin
opts.ResetPin = resetPin opts.ResetPin = resetPin
// Open the device so we can detect touch events. // Open the device so we can detect touch events.
dev, err := cap1188.NewI2C(i2cBus, opts) dev, err := cap1188.NewI2C(i2cBus, &opts)
if err != nil { if err != nil {
log.Fatalf("couldn't open cap1188: %v", err) log.Fatalf("couldn't open cap1188: %v", err)
} }
@ -57,8 +57,8 @@ func Example() {
for maxTouches > 0 { for maxTouches > 0 {
if alertPin.WaitForEdge(-1) { if alertPin.WaitForEdge(-1) {
maxTouches-- maxTouches--
statuses, err := dev.InputStatus() var statuses [8]cap1188.TouchStatus
if err != nil { if err := dev.InputStatus(statuses[:]); err != nil {
fmt.Printf("Error reading inputs: %v\n", err) fmt.Printf("Error reading inputs: %v\n", err)
continue continue
} }
Loading…
Cancel
Save