build: upgrade periph.io dependencies
This commit is contained in:
15
vendor/periph.io/x/conn/v3/spi/func.go
generated
vendored
Normal file
15
vendor/periph.io/x/conn/v3/spi/func.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// 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 spi
|
||||
|
||||
import "periph.io/x/conn/v3/pin"
|
||||
|
||||
// Well known pin functionality.
|
||||
const (
|
||||
CLK pin.Func = "SPI_CLK" // Clock
|
||||
CS pin.Func = "SPI_CS" // Chip select
|
||||
MISO pin.Func = "SPI_MISO" // Master in
|
||||
MOSI pin.Func = "SPI_MOSI" // Master out
|
||||
)
|
187
vendor/periph.io/x/conn/v3/spi/spi.go
generated
vendored
Normal file
187
vendor/periph.io/x/conn/v3/spi/spi.go
generated
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
// 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 spi defines the API to communicate with devices over the SPI
|
||||
// protocol.
|
||||
//
|
||||
// As described in https://periph.io/x/conn/v3#hdr-Concepts, periph.io uses
|
||||
// the concepts of Bus, Port and Conn.
|
||||
//
|
||||
// In the package spi, 'Bus' is not exposed, as it would be SPI bus number
|
||||
// without a CS line, for example on linux asking for "/dev/spi0" without the
|
||||
// ".0" suffix.
|
||||
//
|
||||
// The OS doesn't allow that so it is counter productive to express this at the
|
||||
// API layer, so 'Port' is exposed directly instead.
|
||||
//
|
||||
// Use Port.Connect() converts the uninitialized Port into a Conn.
|
||||
//
|
||||
// See https://en.wikipedia.org/wiki/Serial_Peripheral_Interface for more
|
||||
// information.
|
||||
package spi
|
||||
|
||||
import (
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
"periph.io/x/conn/v3"
|
||||
"periph.io/x/conn/v3/gpio"
|
||||
"periph.io/x/conn/v3/physic"
|
||||
)
|
||||
|
||||
// Mode determines how communication is done.
|
||||
//
|
||||
// The bits can be OR'ed to change the parameters used for
|
||||
// communication.
|
||||
//
|
||||
type Mode int
|
||||
|
||||
// Mode determines the SPI communication parameters.
|
||||
//
|
||||
// CPOL means the clock polarity. Idle is High when set.
|
||||
//
|
||||
// CPHA is the clock phase, sample on trailing edge when set.
|
||||
const (
|
||||
Mode0 Mode = 0x0 // CPOL=0, CPHA=0
|
||||
Mode1 Mode = 0x1 // CPOL=0, CPHA=1
|
||||
Mode2 Mode = 0x2 // CPOL=1, CPHA=0
|
||||
Mode3 Mode = 0x3 // CPOL=1, CPHA=1
|
||||
|
||||
// HalfDuplex specifies that MOSI and MISO use the same wire, and that only
|
||||
// one duplex is used at a time.
|
||||
HalfDuplex Mode = 0x4
|
||||
// NoCS request the driver to not use the CS line.
|
||||
NoCS Mode = 0x8
|
||||
// LSBFirst requests the words to be encoded in little endian instead of the
|
||||
// default big endian.
|
||||
LSBFirst = 0x10
|
||||
)
|
||||
|
||||
func (m Mode) String() string {
|
||||
s := ""
|
||||
switch m & Mode3 {
|
||||
case Mode0:
|
||||
s = "Mode0"
|
||||
case Mode1:
|
||||
s = "Mode1"
|
||||
case Mode2:
|
||||
s = "Mode2"
|
||||
case Mode3:
|
||||
s = "Mode3"
|
||||
}
|
||||
m &^= Mode3
|
||||
if m&HalfDuplex != 0 {
|
||||
s += "|HalfDuplex"
|
||||
}
|
||||
m &^= HalfDuplex
|
||||
if m&NoCS != 0 {
|
||||
s += "|NoCS"
|
||||
}
|
||||
m &^= NoCS
|
||||
if m&LSBFirst != 0 {
|
||||
s += "|LSBFirst"
|
||||
}
|
||||
m &^= LSBFirst
|
||||
if m != 0 {
|
||||
s += "|0x"
|
||||
s += strconv.FormatUint(uint64(m), 16)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Packet represents one packet when sending multiple packets as a transaction.
|
||||
type Packet struct {
|
||||
// W and R are the output and input data. When HalfDuplex is specified to
|
||||
// Connect, only one of the two can be set.
|
||||
W, R []byte
|
||||
// BitsPerWord overrides the default bits per word value set in Connect.
|
||||
BitsPerWord uint8
|
||||
// KeepCS tells the driver to keep CS asserted after this packet is
|
||||
// completed. This can be leveraged to create long transaction as multiple
|
||||
// packets like to use 9 bits commands then 8 bits data.
|
||||
//
|
||||
// Normally during a spi.Conn.TxPackets() call, KeepCS should be set to true
|
||||
// for all packets except the last one. If the last one is set to true, the
|
||||
// CS line stays asserted, leaving the transaction hanging on the bus.
|
||||
//
|
||||
// KeepCS is ignored when NoCS was specified to Connect.
|
||||
KeepCS bool
|
||||
}
|
||||
|
||||
// Conn defines the interface a concrete SPI driver must implement.
|
||||
//
|
||||
// Implementers can optionally implement io.Writer and io.Reader for
|
||||
// unidirectional operation.
|
||||
type Conn interface {
|
||||
conn.Conn
|
||||
// TxPackets does multiple operations over the SPI connection.
|
||||
//
|
||||
// The maximum number of bytes can be limited depending on the driver. Query
|
||||
// conn.Limits.MaxTxSize() can be used to determine the limit.
|
||||
//
|
||||
// If the last packet has KeepCS:true, the CS line stays asserted. This
|
||||
// enables doing SPI transaction over multiple calls.
|
||||
//
|
||||
// Conversely, if any packet beside the last one has KeepCS:false, the CS
|
||||
// line will blip for a short amount of time to force a new transaction.
|
||||
//
|
||||
// It was observed on RPi3 hardware to have a one clock delay between each
|
||||
// packet.
|
||||
TxPackets(p []Packet) error
|
||||
}
|
||||
|
||||
// Port is the interface to be provided to device drivers.
|
||||
//
|
||||
// The device driver, that is the driver for the peripheral connected over
|
||||
// this port, calls Connect() to retrieve a configured connection as Conn.
|
||||
type Port interface {
|
||||
String() string
|
||||
// Connect sets the communication parameters of the connection for use by a
|
||||
// device.
|
||||
//
|
||||
// The device driver must call this function exactly once.
|
||||
//
|
||||
// f must specify the maximum rated speed by the device's spec. The lowest
|
||||
// speed between the port speed and the device speed is selected. Use 0 for f
|
||||
// if there is no known maximum value for this device.
|
||||
//
|
||||
// mode specifies the clock and signal polarities, if the port is using half
|
||||
// duplex (shared MISO and MOSI) or if CS is not needed.
|
||||
//
|
||||
// bits is the number of bits per word. Generally you should use 8.
|
||||
Connect(f physic.Frequency, mode Mode, bits int) (Conn, error)
|
||||
}
|
||||
|
||||
// PortCloser is a SPI port that can be closed.
|
||||
//
|
||||
// This interface is meant to be handled by the application.
|
||||
type PortCloser interface {
|
||||
io.Closer
|
||||
Port
|
||||
// LimitSpeed sets the maximum port speed.
|
||||
//
|
||||
// It lets an application use a device at a lower speed than the maximum
|
||||
// speed as rated by the device driver. This is useful for example when the
|
||||
// wires are long or the connection is of poor quality.
|
||||
//
|
||||
// This function can be called multiple times and resets the previous value.
|
||||
// 0 is not a valid value for f. The lowest speed between the port speed and
|
||||
// the device speed is selected.
|
||||
LimitSpeed(f physic.Frequency) error
|
||||
}
|
||||
|
||||
// Pins defines the pins that a SPI port interconnect is using on the host.
|
||||
//
|
||||
// It is expected that a implementer of ConnCloser or Conn also implement Pins
|
||||
// but this is not a requirement.
|
||||
type Pins interface {
|
||||
// CLK returns the SCK (clock) pin.
|
||||
CLK() gpio.PinOut
|
||||
// MOSI returns the SDO (master out, slave in) pin.
|
||||
MOSI() gpio.PinOut
|
||||
// MISO returns the SDI (master in, slave out) pin.
|
||||
MISO() gpio.PinIn
|
||||
// CS returns the CSN (chip select) pin.
|
||||
CS() gpio.PinOut
|
||||
}
|
262
vendor/periph.io/x/conn/v3/spi/spireg/spireg.go
generated
vendored
Normal file
262
vendor/periph.io/x/conn/v3/spi/spireg/spireg.go
generated
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
// 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 spireg defines the SPI registry for SPI ports discovered on the host.
|
||||
//
|
||||
// SPI ports discovered on the host are automatically registered in the SPI
|
||||
// registry by host.Init().
|
||||
package spireg
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"periph.io/x/conn/v3/spi"
|
||||
)
|
||||
|
||||
// Opener opens an handle to a port.
|
||||
//
|
||||
// It is provided by the actual port driver.
|
||||
type Opener func() (spi.PortCloser, error)
|
||||
|
||||
// Ref references a SPI port.
|
||||
//
|
||||
// It is returned by All() to enumerate all registered ports.
|
||||
type Ref struct {
|
||||
// Name of the port.
|
||||
//
|
||||
// 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 port.
|
||||
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.
|
||||
//
|
||||
// The port is a bus number plus a CS line.
|
||||
Number int
|
||||
// Open is the factory to open an handle to this SPI port.
|
||||
Open Opener
|
||||
}
|
||||
|
||||
// Open opens a SPI port by its name, an alias or its number and returns an
|
||||
// handle to it.
|
||||
//
|
||||
// Specify the empty string "" to get the first available port. This is the
|
||||
// recommended default value unless an application knows the exact port to use.
|
||||
//
|
||||
// Each port can register multiple aliases, each leading to the same port
|
||||
// handle.
|
||||
//
|
||||
// "Bus number" is a generic concept that is highly dependent on the platform
|
||||
// and OS. On some platform, the first port may have the number 0, 1 or as high
|
||||
// as 32766. 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.
|
||||
//
|
||||
// A SPI port is constructed of the bus number and the chip select (CS) number.
|
||||
//
|
||||
// When the SPI port 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) (spi.PortCloser, error) {
|
||||
var r *Ref
|
||||
var err error
|
||||
func() {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if len(byName) == 0 {
|
||||
err = errors.New("spireg: no port 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("spireg: can't open unknown port: " + strconv.Quote(name))
|
||||
}
|
||||
return r.Open()
|
||||
}
|
||||
|
||||
// All returns a copy of all the registered references to all know SPI ports
|
||||
// available on this host.
|
||||
//
|
||||
// The list is sorted by the port 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 a SPI port.
|
||||
//
|
||||
// Registering the same port name twice is an error, e.g. o.Name(). o.Number()
|
||||
// can be -1 to signify that the port doesn't have an inherent "bus number". A
|
||||
// good example is a port provided over a FT232H device connected on an USB bus.
|
||||
// In this case, the port name should be created from the serial number of the
|
||||
// device for unique identification.
|
||||
//
|
||||
// Only ports with the CS #0 are registered with their number.
|
||||
func Register(name string, aliases []string, number int, o Opener) error {
|
||||
if len(name) == 0 {
|
||||
return errors.New("spireg: can't register a port with no name")
|
||||
}
|
||||
if o == nil {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with nil Opener")
|
||||
}
|
||||
if number < -1 {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with invalid port number " + strconv.Itoa(number))
|
||||
}
|
||||
if _, err := strconv.Atoi(name); err == nil {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with name being only a number")
|
||||
}
|
||||
if strings.Contains(name, ":") {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with name containing ':'")
|
||||
}
|
||||
for _, alias := range aliases {
|
||||
if len(alias) == 0 {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an empty alias")
|
||||
}
|
||||
if name == alias {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an alias the same as the port name")
|
||||
}
|
||||
if _, err := strconv.Atoi(alias); err == nil {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an alias that is a number: " + strconv.Quote(alias))
|
||||
}
|
||||
if strings.Contains(alias, ":") {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an alias containing ':': " + strconv.Quote(alias))
|
||||
}
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if _, ok := byName[name]; ok {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " twice")
|
||||
}
|
||||
if _, ok := byAlias[name]; ok {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " twice; it is already an alias")
|
||||
}
|
||||
if number != -1 {
|
||||
if _, ok := byNumber[number]; ok {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + "; port number " + strconv.Itoa(number) + " is already registered")
|
||||
}
|
||||
}
|
||||
for _, alias := range aliases {
|
||||
if _, ok := byName[alias]; ok {
|
||||
return errors.New("spireg: can't register port " + strconv.Quote(name) + " twice; alias " + strconv.Quote(alias) + " is already a port")
|
||||
}
|
||||
if _, ok := byAlias[alias]; ok {
|
||||
return errors.New("spireg: can't register port " + 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 SPI port.
|
||||
//
|
||||
// This can happen when a SPI port 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("spireg: can't unregister unknown port 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 port.
|
||||
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