diff options
Diffstat (limited to '')
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() +} |