add: humidity (WIP)
This commit is contained in:
		
							
								
								
									
										12
									
								
								vendor/periph.io/x/periph/conn/i2c/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								vendor/periph.io/x/periph/conn/i2c/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
// Copyright 2018 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package i2c
 | 
			
		||||
 | 
			
		||||
import "periph.io/x/periph/conn/pin"
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	SCL pin.Func = "I2C_SCL" // Clock
 | 
			
		||||
	SDA pin.Func = "I2C_SDA" // Data
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										114
									
								
								vendor/periph.io/x/periph/conn/i2c/i2c.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								vendor/periph.io/x/periph/conn/i2c/i2c.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package i2c defines the API to communicate with devices over the I²C
 | 
			
		||||
// protocol.
 | 
			
		||||
//
 | 
			
		||||
// As described in https://periph.io/x/periph/conn#hdr-Concepts, periph.io uses
 | 
			
		||||
// the concepts of Bus, Port and Conn.
 | 
			
		||||
//
 | 
			
		||||
// In the package i2c, 'Port' is not exposed, since once you know the I²C
 | 
			
		||||
// device address, there's no unconfigured Port to configure.
 | 
			
		||||
//
 | 
			
		||||
// Instead, the package includes the adapter 'Dev' to directly convert an I²C
 | 
			
		||||
// bus 'i2c.Bus' into a connection 'conn.Conn' by only specifying the device
 | 
			
		||||
// I²C address.
 | 
			
		||||
//
 | 
			
		||||
// See https://en.wikipedia.org/wiki/I%C2%B2C for more information.
 | 
			
		||||
package i2c
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/physic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Bus defines the interface a concrete I²C driver must implement.
 | 
			
		||||
//
 | 
			
		||||
// This interface is consummed by a device driver for a device sitting on a bus.
 | 
			
		||||
//
 | 
			
		||||
// This interface doesn't implement conn.Conn since a device address must be
 | 
			
		||||
// specified. Use i2cdev.Dev as an adapter to get a conn.Conn compatible
 | 
			
		||||
// object.
 | 
			
		||||
type Bus interface {
 | 
			
		||||
	String() string
 | 
			
		||||
	// Tx does a transaction at the specified device address.
 | 
			
		||||
	//
 | 
			
		||||
	// Write is done first, then read. One of 'w' or 'r' can be omitted for a
 | 
			
		||||
	// unidirectional operation.
 | 
			
		||||
	Tx(addr uint16, w, r []byte) error
 | 
			
		||||
	// SetSpeed changes the bus speed, if supported.
 | 
			
		||||
	//
 | 
			
		||||
	// On linux due to the way the I²C sysfs driver is exposed in userland,
 | 
			
		||||
	// calling this function will likely affect *all* I²C buses on the host.
 | 
			
		||||
	SetSpeed(f physic.Frequency) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BusCloser is an I²C bus that can be closed.
 | 
			
		||||
//
 | 
			
		||||
// This interface is meant to be handled by the application and not the device
 | 
			
		||||
// driver. A device driver doesn't "own" a bus, hence it must operate on a Bus,
 | 
			
		||||
// not a BusCloser.
 | 
			
		||||
type BusCloser interface {
 | 
			
		||||
	io.Closer
 | 
			
		||||
	Bus
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pins defines the pins that an I²C bus interconnect is using on the host.
 | 
			
		||||
//
 | 
			
		||||
// It is expected that a implementer of Bus also implement Pins but this is not
 | 
			
		||||
// a requirement.
 | 
			
		||||
type Pins interface {
 | 
			
		||||
	// SCL returns the CLK (clock) pin.
 | 
			
		||||
	SCL() gpio.PinIO
 | 
			
		||||
	// SDA returns the DATA pin.
 | 
			
		||||
	SDA() gpio.PinIO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Dev is a device on a I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// It implements conn.Conn.
 | 
			
		||||
//
 | 
			
		||||
// It saves from repeatedly specifying the device address.
 | 
			
		||||
type Dev struct {
 | 
			
		||||
	Bus  Bus
 | 
			
		||||
	Addr uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *Dev) String() string {
 | 
			
		||||
	s := "<nil>"
 | 
			
		||||
	if d.Bus != nil {
 | 
			
		||||
		s = d.Bus.String()
 | 
			
		||||
	}
 | 
			
		||||
	return s + "(" + strconv.Itoa(int(d.Addr)) + ")"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tx does a transaction by adding the device's address to each command.
 | 
			
		||||
//
 | 
			
		||||
// It's a wrapper for Bus.Tx().
 | 
			
		||||
func (d *Dev) Tx(w, r []byte) error {
 | 
			
		||||
	return d.Bus.Tx(d.Addr, w, r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write writes to the I²C bus without reading, implementing io.Writer.
 | 
			
		||||
//
 | 
			
		||||
// It's a wrapper for Tx()
 | 
			
		||||
func (d *Dev) Write(b []byte) (int, error) {
 | 
			
		||||
	if err := d.Tx(b, nil); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return len(b), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Duplex always return conn.Half for I²C.
 | 
			
		||||
func (d *Dev) Duplex() conn.Duplex {
 | 
			
		||||
	return conn.Half
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var _ conn.Conn = &Dev{}
 | 
			
		||||
							
								
								
									
										252
									
								
								vendor/periph.io/x/periph/conn/i2c/i2creg/i2creg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								vendor/periph.io/x/periph/conn/i2c/i2creg/i2creg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,252 @@
 | 
			
		||||
// Copyright 2017 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package i2creg defines I²C bus registry to list buses present on the host.
 | 
			
		||||
package i2creg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/i2c"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Opener opens an handle to a bus.
 | 
			
		||||
//
 | 
			
		||||
// It is provided by the actual bus driver.
 | 
			
		||||
type Opener func() (i2c.BusCloser, error)
 | 
			
		||||
 | 
			
		||||
// Ref references an I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// It is returned by All() to enumerate all registered buses.
 | 
			
		||||
type Ref struct {
 | 
			
		||||
	// Name of the bus.
 | 
			
		||||
	//
 | 
			
		||||
	// It must not be a sole number. It must be unique across the host.
 | 
			
		||||
	Name string
 | 
			
		||||
	// Aliases are the alternative names that can be used to reference this bus.
 | 
			
		||||
	Aliases []string
 | 
			
		||||
	// Number of the bus or -1 if the bus doesn't have any "native" number.
 | 
			
		||||
	//
 | 
			
		||||
	// Buses provided by the CPU normally have a 0 based number. Buses provided
 | 
			
		||||
	// via an addon (like over USB) generally are not numbered.
 | 
			
		||||
	Number int
 | 
			
		||||
	// Open is the factory to open an handle to this I²C bus.
 | 
			
		||||
	Open Opener
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Open opens an I²C bus by its name, an alias or its number and returns an
 | 
			
		||||
// handle to it.
 | 
			
		||||
//
 | 
			
		||||
// Specify the empty string "" to get the first available bus. This is the
 | 
			
		||||
// recommended default value unless an application knows the exact bus to use.
 | 
			
		||||
//
 | 
			
		||||
// Each bus can register multiple aliases, each leading to the same bus handle.
 | 
			
		||||
//
 | 
			
		||||
// "Bus number" is a generic concept that is highly dependent on the platform
 | 
			
		||||
// and OS. On some platform, the first bus may have the number 0, 1 or higher.
 | 
			
		||||
// Bus numbers are not necessarily continuous and may not start at 0. It was
 | 
			
		||||
// observed that the bus number as reported by the OS may change across OS
 | 
			
		||||
// revisions.
 | 
			
		||||
//
 | 
			
		||||
// When the I²C bus is provided by an off board plug and play bus like USB via
 | 
			
		||||
// a FT232H USB device, there can be no associated number.
 | 
			
		||||
func Open(name string) (i2c.BusCloser, error) {
 | 
			
		||||
	var r *Ref
 | 
			
		||||
	var err error
 | 
			
		||||
	func() {
 | 
			
		||||
		mu.Lock()
 | 
			
		||||
		defer mu.Unlock()
 | 
			
		||||
		if len(byName) == 0 {
 | 
			
		||||
			err = errors.New("i2creg: no bus found; did you forget to call Init()?")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if len(name) == 0 {
 | 
			
		||||
			r = getDefault()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// Try by name, by alias, by number.
 | 
			
		||||
		if r = byName[name]; r == nil {
 | 
			
		||||
			if r = byAlias[name]; r == nil {
 | 
			
		||||
				if i, err2 := strconv.Atoi(name); err2 == nil {
 | 
			
		||||
					r = byNumber[i]
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		return nil, errors.New("i2creg: can't open unknown bus: " + strconv.Quote(name))
 | 
			
		||||
	}
 | 
			
		||||
	return r.Open()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// All returns a copy of all the registered references to all know I²C buses
 | 
			
		||||
// available on this host.
 | 
			
		||||
//
 | 
			
		||||
// The list is sorted by the bus name.
 | 
			
		||||
func All() []*Ref {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	out := make([]*Ref, 0, len(byName))
 | 
			
		||||
	for _, v := range byName {
 | 
			
		||||
		r := &Ref{Name: v.Name, Aliases: make([]string, len(v.Aliases)), Number: v.Number, Open: v.Open}
 | 
			
		||||
		copy(r.Aliases, v.Aliases)
 | 
			
		||||
		out = insertRef(out, r)
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register registers an I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// Registering the same bus name twice is an error, e.g. o.Name(). o.Number()
 | 
			
		||||
// can be -1 to signify that the bus doesn't have an inherent "bus number". A
 | 
			
		||||
// good example is a bus provided over a FT232H device connected on an USB bus.
 | 
			
		||||
// In this case, the bus name should be created from the serial number of the
 | 
			
		||||
// device for unique identification.
 | 
			
		||||
func Register(name string, aliases []string, number int, o Opener) error {
 | 
			
		||||
	if len(name) == 0 {
 | 
			
		||||
		return errors.New("i2creg: can't register a bus with no name")
 | 
			
		||||
	}
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with nil Opener")
 | 
			
		||||
	}
 | 
			
		||||
	if number < -1 {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with invalid bus number " + strconv.Itoa(number))
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := strconv.Atoi(name); err == nil {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with name being only a number")
 | 
			
		||||
	}
 | 
			
		||||
	if strings.Contains(name, ":") {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with name containing ':'")
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		if len(alias) == 0 {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an empty alias")
 | 
			
		||||
		}
 | 
			
		||||
		if name == alias {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an alias the same as the bus name")
 | 
			
		||||
		}
 | 
			
		||||
		if _, err := strconv.Atoi(alias); err == nil {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an alias that is a number: " + strconv.Quote(alias))
 | 
			
		||||
		}
 | 
			
		||||
		if strings.Contains(alias, ":") {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an alias containing ':': " + strconv.Quote(alias))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if _, ok := byName[name]; ok {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice")
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := byAlias[name]; ok {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice; it is already an alias")
 | 
			
		||||
	}
 | 
			
		||||
	if number != -1 {
 | 
			
		||||
		if _, ok := byNumber[number]; ok {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + "; bus number " + strconv.Itoa(number) + " is already registered")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		if _, ok := byName[alias]; ok {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice; alias " + strconv.Quote(alias) + " is already a bus")
 | 
			
		||||
		}
 | 
			
		||||
		if _, ok := byAlias[alias]; ok {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice; alias " + strconv.Quote(alias) + " is already an alias")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r := &Ref{Name: name, Aliases: make([]string, len(aliases)), Number: number, Open: o}
 | 
			
		||||
	copy(r.Aliases, aliases)
 | 
			
		||||
	byName[name] = r
 | 
			
		||||
	if number != -1 {
 | 
			
		||||
		byNumber[number] = r
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		byAlias[alias] = r
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unregister removes a previously registered I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// This can happen when an I²C bus is exposed via an USB device and the device
 | 
			
		||||
// is unplugged.
 | 
			
		||||
func Unregister(name string) error {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	r := byName[name]
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		return errors.New("i2creg: can't unregister unknown bus name " + strconv.Quote(name))
 | 
			
		||||
	}
 | 
			
		||||
	delete(byName, name)
 | 
			
		||||
	delete(byNumber, r.Number)
 | 
			
		||||
	for _, alias := range r.Aliases {
 | 
			
		||||
		delete(byAlias, alias)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu     sync.Mutex
 | 
			
		||||
	byName = map[string]*Ref{}
 | 
			
		||||
	// Caches
 | 
			
		||||
	byNumber = map[int]*Ref{}
 | 
			
		||||
	byAlias  = map[string]*Ref{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getDefault returns the Ref that should be used as the default bus.
 | 
			
		||||
func getDefault() *Ref {
 | 
			
		||||
	var o *Ref
 | 
			
		||||
	if len(byNumber) == 0 {
 | 
			
		||||
		// Fallback to use byName using a lexical sort.
 | 
			
		||||
		name := ""
 | 
			
		||||
		for n, o2 := range byName {
 | 
			
		||||
			if len(name) == 0 || n < name {
 | 
			
		||||
				o = o2
 | 
			
		||||
				name = n
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return o
 | 
			
		||||
	}
 | 
			
		||||
	number := int((^uint(0)) >> 1)
 | 
			
		||||
	for n, o2 := range byNumber {
 | 
			
		||||
		if number > n {
 | 
			
		||||
			number = n
 | 
			
		||||
			o = o2
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func insertRef(l []*Ref, r *Ref) []*Ref {
 | 
			
		||||
	n := r.Name
 | 
			
		||||
	i := search(len(l), func(i int) bool { return l[i].Name > n })
 | 
			
		||||
	l = append(l, nil)
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = r
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// search implements the same algorithm as sort.Search().
 | 
			
		||||
//
 | 
			
		||||
// It was extracted to to not depend on sort, which depends on reflect.
 | 
			
		||||
func search(n int, f func(int) bool) int {
 | 
			
		||||
	lo := 0
 | 
			
		||||
	for hi := n; lo < hi; {
 | 
			
		||||
		if i := int(uint(lo+hi) >> 1); !f(i) {
 | 
			
		||||
			lo = i + 1
 | 
			
		||||
		} else {
 | 
			
		||||
			hi = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return lo
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user