summaryrefslogtreecommitdiffstats
path: root/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs.go177
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs_nonlinux.go40
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/driver/driver.go50
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/example_test.go38
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/spi.go107
5 files changed, 412 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs.go
new file mode 100644
index 0000000..a5f1bca
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs.go
@@ -0,0 +1,177 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+// +build linux
+
+package spi
+
+import (
+ "fmt"
+ "os"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/exp/io/spi/driver"
+)
+
+const (
+ devfs_MAGIC = 107
+
+ devfs_NRBITS = 8
+ devfs_TYPEBITS = 8
+ devfs_SIZEBITS = 13
+ devfs_DIRBITS = 3
+
+ devfs_NRSHIFT = 0
+ devfs_TYPESHIFT = devfs_NRSHIFT + devfs_NRBITS
+ devfs_SIZESHIFT = devfs_TYPESHIFT + devfs_TYPEBITS
+ devfs_DIRSHIFT = devfs_SIZESHIFT + devfs_SIZEBITS
+
+ devfs_READ = 2
+ devfs_WRITE = 4
+)
+
+type payload struct {
+ tx uint64
+ rx uint64
+ length uint32
+ speed uint32
+ delay uint16
+ bits uint8
+ csChange uint8
+ txNBits uint8
+ rxNBits uint8
+ pad uint16
+}
+
+// Devfs is an SPI driver that works against the devfs.
+// You need to have loaded the "spidev" Linux module to use this driver.
+type Devfs struct {
+ // Dev is the device to be opened.
+ // Device name is usually in the /dev/spidev<bus>.<chip> format.
+ // Required.
+ Dev string
+
+ // Mode is the SPI mode. SPI mode is a combination of polarity and phases.
+ // CPOL is the high order bit, CPHA is the low order. Pre-computed mode
+ // values are Mode0, Mode1, Mode2 and Mode3. The value of the mode argument
+ // can be overridden by the device's driver.
+ // Required.
+ Mode Mode
+
+ // MaxSpeed is the max clock speed (Hz) and can be overridden by the device's driver.
+ // Required.
+ MaxSpeed int64
+}
+
+// Open opens the provided device with the specified options
+// and returns a connection.
+func (d *Devfs) Open() (driver.Conn, error) {
+ f, err := os.OpenFile(d.Dev, os.O_RDWR, os.ModeDevice)
+ if err != nil {
+ return nil, err
+ }
+ conn := &devfsConn{f: f}
+ if err := conn.Configure(driver.Mode, int(d.Mode)); err != nil {
+ conn.Close()
+ return nil, err
+ }
+ if err := conn.Configure(driver.MaxSpeed, int(d.MaxSpeed)); err != nil {
+ conn.Close()
+ return nil, err
+ }
+ return conn, nil
+}
+
+type devfsConn struct {
+ f *os.File
+ mode uint8
+ speed uint32
+ bits uint8
+ delay uint16
+ csChange uint8
+}
+
+func (c *devfsConn) Configure(k, v int) error {
+ switch k {
+ case driver.Mode:
+ m := uint8(v)
+ if err := c.ioctl(requestCode(devfs_WRITE, devfs_MAGIC, 1, 1), uintptr(unsafe.Pointer(&m))); err != nil {
+ return fmt.Errorf("error setting mode to %v: %v", m, err)
+ }
+ c.mode = m
+ case driver.Bits:
+ b := uint8(v)
+ if err := c.ioctl(requestCode(devfs_WRITE, devfs_MAGIC, 3, 1), uintptr(unsafe.Pointer(&b))); err != nil {
+ return fmt.Errorf("error setting bits per word to %v: %v", b, err)
+ }
+ c.bits = b
+ case driver.MaxSpeed:
+ s := uint32(v)
+ if err := c.ioctl(requestCode(devfs_WRITE, devfs_MAGIC, 4, 4), uintptr(unsafe.Pointer(&s))); err != nil {
+ return fmt.Errorf("error setting speed to %v: %v", s, err)
+ }
+ c.speed = s
+ case driver.Order:
+ o := uint8(v)
+ if err := c.ioctl(requestCode(devfs_WRITE, devfs_MAGIC, 2, 1), uintptr(unsafe.Pointer(&o))); err != nil {
+ return fmt.Errorf("error setting bit order to %v: %v", o, err)
+ }
+ case driver.Delay:
+ c.delay = uint16(v)
+ case driver.CSChange:
+ c.csChange = uint8(v)
+ default:
+ return fmt.Errorf("unknown key: %v", k)
+ }
+ return nil
+}
+
+func (c *devfsConn) Tx(w, r []byte) error {
+ if r == nil {
+ r = make([]byte, len(w))
+ }
+ // TODO(jbd): len(w) == len(r)?
+ // TODO(jbd): Allow nil w.
+ p := payload{
+ tx: uint64(uintptr(unsafe.Pointer(&w[0]))),
+ rx: uint64(uintptr(unsafe.Pointer(&r[0]))),
+ length: uint32(len(w)),
+ speed: c.speed,
+ delay: c.delay,
+ bits: c.bits,
+ csChange: c.csChange,
+ }
+ // TODO(jbd): Read from the device and fill rx.
+ return c.ioctl(msgRequestCode(1), uintptr(unsafe.Pointer(&p)))
+}
+
+func (c *devfsConn) Close() error {
+ return c.f.Close()
+}
+
+// requestCode returns the device specific request code for the specified direction,
+// type, number and size to be used in the ioctl call.
+func requestCode(dir, typ, nr, size uintptr) uintptr {
+ return (dir << devfs_DIRSHIFT) | (typ << devfs_TYPESHIFT) | (nr << devfs_NRSHIFT) | (size << devfs_SIZESHIFT)
+}
+
+// msgRequestCode returns the device specific value for the SPI
+// message payload to be used in the ioctl call.
+// n represents the number of messages.
+func msgRequestCode(n uint32) uintptr {
+ return uintptr(0x40006B00 + (n * 0x200000))
+}
+
+// ioctl makes an IOCTL on the open device file descriptor.
+func (c *devfsConn) ioctl(a1, a2 uintptr) error {
+ _, _, errno := syscall.Syscall(
+ syscall.SYS_IOCTL, c.f.Fd(), a1, a2,
+ )
+ if errno != 0 {
+ return syscall.Errno(errno)
+ }
+ return nil
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs_nonlinux.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs_nonlinux.go
new file mode 100644
index 0000000..499d69d
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/devfs_nonlinux.go
@@ -0,0 +1,40 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux
+// +build !linux
+
+package spi
+
+import (
+ "errors"
+
+ "golang.org/x/exp/io/spi/driver"
+)
+
+// Devfs is a no-implementation of an SPI driver that works against the devfs.
+// You need to have loaded the Linux "spidev" module to use this driver.
+type Devfs struct {
+ // Dev is the device to be opened.
+ // Device name is usually in the /dev/spidev<bus>.<chip> format.
+ // Required.
+ Dev string
+
+ // Mode is the SPI mode. SPI mode is a combination of polarity and phases.
+ // CPOL is the high order bit, CPHA is the low order. Pre-computed mode
+ // values are Mode0, Mode1, Mode2 and Mode3. The value of the mode argument
+ // can be overridden by the device's driver.
+ // Required.
+ Mode Mode
+
+ // MaxSpeed is the max clock speed (Hz) and can be overridden by the device's driver.
+ // Required.
+ MaxSpeed int64
+}
+
+// Open opens the provided device with the speicifed options
+// and returns a connection.
+func (d *Devfs) Open() (driver.Conn, error) {
+ return nil, errors.New("not implemented on this platform")
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/driver/driver.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/driver/driver.go
new file mode 100644
index 0000000..7634440
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/driver/driver.go
@@ -0,0 +1,50 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package driver contains interfaces to be implemented by various SPI implementations.
+package driver // import "golang.org/x/exp/io/spi/driver"
+
+const (
+ Mode = iota
+ Bits
+ MaxSpeed
+ Order
+ Delay
+ CSChange
+)
+
+// Opener is an interface to be implemented by the SPI driver to open
+// a connection to an SPI device.
+type Opener interface {
+ Open() (Conn, error)
+}
+
+// Conn is a connection to an SPI device.
+// TODO(jbd): Extend the interface to query configuration values.
+type Conn interface {
+ // Configure configures the SPI device.
+ //
+ // Available configuration keys are:
+ // - Mode, the SPI mode (valid values are 0, 1, 2 and 3).
+ // - Bits, bits per word (default is 8-bit per word).
+ // - Speed, the max clock speed (in Hz).
+ // - Order, bit order to be used in transfers. Zero value represents
+ // the MSB-first, non-zero values represent LSB-first encoding.
+ // - Delay, the pause time between frames (in usecs).
+ // Some SPI devices require a minimum amount of wait time after
+ // each frame write. If set, Delay amount of usecs are inserted after
+ // each write.
+ // - CSChange, whether to leave the device's chipselect active after a Tx.
+ //
+ // SPI devices can override these values.
+ Configure(k, v int) error
+
+ // Tx performs a SPI transaction: w is written if not nil, the result is
+ // put into r if not nil. len(w) must be equal to len(r), otherwise the
+ // driver should return an error.
+ Tx(w, r []byte) error
+
+ // Close frees the underlying resources and closes the connection.
+ Close() error
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/example_test.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/example_test.go
new file mode 100644
index 0000000..e75ec37
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/example_test.go
@@ -0,0 +1,38 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package spi_test
+
+import "golang.org/x/exp/io/spi"
+
+// Example illustrates a program that drives an APA-102 LED strip.
+func Example() {
+ dev, err := spi.Open(&spi.Devfs{
+ Dev: "/dev/spidev0.1",
+ Mode: spi.Mode3,
+ MaxSpeed: 500000,
+ })
+ if err != nil {
+ panic(err)
+ }
+ defer dev.Close()
+
+ if err := dev.Tx([]byte{
+ 0, 0, 0, 0,
+ 0xff, 200, 0, 200,
+ 0xff, 200, 0, 200,
+ 0xe0, 200, 0, 200,
+ 0xff, 200, 0, 200,
+ 0xff, 8, 50, 0,
+ 0xff, 200, 0, 0,
+ 0xff, 0, 0, 0,
+ 0xff, 200, 0, 200,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ }, nil); err != nil {
+ panic(err)
+ }
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/spi.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/spi.go
new file mode 100644
index 0000000..a675bd1
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/io/spi/spi.go
@@ -0,0 +1,107 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package spi allows users to read from and write to an SPI device.
+//
+// # Deprecated
+//
+// This package is not maintained anymore. An actively supported cross-platform
+// alternative is https://periph.io/.
+package spi // import "golang.org/x/exp/io/spi"
+
+import (
+ "time"
+
+ "golang.org/x/exp/io/spi/driver"
+)
+
+// Mode represents the SPI mode number where clock parity (CPOL)
+// is the high order and clock edge (CPHA) is the low order bit.
+type Mode int
+
+const (
+ Mode0 = Mode(0)
+ Mode1 = Mode(1)
+ Mode2 = Mode(2)
+ Mode3 = Mode(3)
+)
+
+// Order is the bit justification to be used while transferring
+// words to the SPI device. MSB-first encoding is more popular
+// than LSB-first.
+type Order int
+
+const (
+ MSBFirst = Order(0)
+ LSBFirst = Order(1)
+)
+
+type Device struct {
+ conn driver.Conn
+}
+
+// SetMode sets the SPI mode. SPI mode is a combination of polarity and phases.
+// CPOL is the high order bit, CPHA is the low order. Pre-computed mode
+// values are Mode0, Mode1, Mode2 and Mode3.
+// The value can be changed by SPI device's driver.
+func (d *Device) SetMode(mode Mode) error {
+ return d.conn.Configure(driver.Mode, int(mode))
+}
+
+// SetMaxSpeed sets the maximum clock speed in Hz.
+// The value can be overridden by SPI device's driver.
+func (d *Device) SetMaxSpeed(speed int) error {
+ return d.conn.Configure(driver.MaxSpeed, speed)
+}
+
+// SetBitsPerWord sets how many bits it takes to represent a word, e.g. 8 represents 8-bit words.
+// The default is 8 bits per word.
+func (d *Device) SetBitsPerWord(bits int) error {
+ return d.conn.Configure(driver.Bits, bits)
+}
+
+// SetBitOrder sets the bit justification used to transfer SPI words.
+// Valid values are MSBFirst and LSBFirst.
+func (d *Device) SetBitOrder(o Order) error {
+ return d.conn.Configure(driver.Order, int(o))
+}
+
+// SetDelay sets the amount of pause will be added after each frame write.
+func (d *Device) SetDelay(t time.Duration) error {
+ return d.conn.Configure(driver.Delay, int(t.Nanoseconds()/1000))
+}
+
+// SetCSChange sets whether to leave the chipselect enabled after a Tx.
+func (d *Device) SetCSChange(leaveEnabled bool) error {
+ v := 0
+ if leaveEnabled {
+ v = 1
+ }
+ return d.conn.Configure(driver.CSChange, v)
+}
+
+// Tx performs a duplex transmission to write w to the SPI device
+// and read len(r) bytes to r.
+// User should not mutate the w and r until this call returns.
+func (d *Device) Tx(w, r []byte) error {
+ // TODO(jbd): Allow nil w.
+ return d.conn.Tx(w, r)
+}
+
+// Open opens a device with the specified bus and chip select
+// by using the given driver. If a nil driver is provided,
+// the default driver (devfs) is used.
+
+func Open(o driver.Opener) (*Device, error) {
+ conn, err := o.Open()
+ if err != nil {
+ return nil, err
+ }
+ return &Device{conn: conn}, nil
+}
+
+// Close closes the SPI device and releases the related resources.
+func (d *Device) Close() error {
+ return d.conn.Close()
+}