diff --git a/go.mod b/go.mod index f941d91..f817dab 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,8 @@ require ( github.com/eclipse/paho.mqtt.golang v1.3.5 github.com/golang/protobuf v1.5.2 github.com/sirupsen/logrus v1.8.1 - periph.io/x/periph v3.6.8+incompatible + periph.io/x/conn/v3 v3.6.8 + periph.io/x/host/v3 v3.7.0 ) require ( @@ -17,4 +18,5 @@ require ( golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect google.golang.org/protobuf v1.26.0 // indirect + periph.io/x/d2xx v0.0.1 // indirect ) diff --git a/go.sum b/go.sum index 173264e..028b875 100644 --- a/go.sum +++ b/go.sum @@ -124,5 +124,9 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v0.0.0-20181223230014-1083505acf35/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -periph.io/x/periph v3.6.8+incompatible h1:lki0ie6wHtvlilXhIkabdCUQMpb5QN4Fx33yNQdqnaA= -periph.io/x/periph v3.6.8+incompatible/go.mod h1:EWr+FCIU2dBWz5/wSWeiIUJTriYv9v2j2ENBmgYyy7Y= +periph.io/x/conn/v3 v3.6.8 h1:fnNSwSoKPzpoLOSxml70EInaP6YrrqcucP3KDfNxpmU= +periph.io/x/conn/v3 v3.6.8/go.mod h1:3OD27w9YVa5DS97VsUxsPGzD9Qrm5Ny7cF5b6xMMIWg= +periph.io/x/d2xx v0.0.1 h1:7iCO/aVK6k9GSZ45DcpMU8sOOcVLCqO/cheSm7nMUG0= +periph.io/x/d2xx v0.0.1/go.mod h1:38Euaaj+s6l0faIRHh32a+PrjXvxFTFkPBEQI0TKg34= +periph.io/x/host/v3 v3.7.0 h1:9CP/j0FcJmR+PRHlNzAmhV6Mt3GXoWnPmRhknJlQhnE= +periph.io/x/host/v3 v3.7.0/go.mod h1:okb5m0yUYLTM/dnMYWMBX47w4owTzyCPLpZUQb35nhs= diff --git a/led/led.go b/led/led.go index 6085127..2c65323 100644 --- a/led/led.go +++ b/led/led.go @@ -2,9 +2,9 @@ package led import ( log "github.com/sirupsen/logrus" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/host" - "periph.io/x/periph/host/bcm283x" + "periph.io/x/conn/v3/gpio" + "periph.io/x/host/v3" + "periph.io/x/host/v3/bcm283x" "sync" "time" ) diff --git a/led/led_test.go b/led/led_test.go index 994439a..80aaf4e 100644 --- a/led/led_test.go +++ b/led/led_test.go @@ -1,7 +1,7 @@ package led import ( - "periph.io/x/periph/conn/gpio" + "periph.io/x/conn/v3/gpio" "sync" "testing" "time" diff --git a/vendor/modules.txt b/vendor/modules.txt index b08c597..fb32fee 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -60,34 +60,41 @@ google.golang.org/protobuf/runtime/protoiface google.golang.org/protobuf/runtime/protoimpl google.golang.org/protobuf/types/descriptorpb google.golang.org/protobuf/types/known/timestamppb -# periph.io/x/periph v3.6.8+incompatible -## explicit -periph.io/x/periph -periph.io/x/periph/conn -periph.io/x/periph/conn/gpio -periph.io/x/periph/conn/gpio/gpioreg -periph.io/x/periph/conn/gpio/gpiostream -periph.io/x/periph/conn/i2c -periph.io/x/periph/conn/i2c/i2creg -periph.io/x/periph/conn/physic -periph.io/x/periph/conn/pin -periph.io/x/periph/conn/pin/pinreg -periph.io/x/periph/conn/spi -periph.io/x/periph/conn/spi/spireg -periph.io/x/periph/host -periph.io/x/periph/host/allwinner -periph.io/x/periph/host/am335x -periph.io/x/periph/host/bcm283x -periph.io/x/periph/host/beagle/black -periph.io/x/periph/host/beagle/bone -periph.io/x/periph/host/beagle/green -periph.io/x/periph/host/chip -periph.io/x/periph/host/cpu -periph.io/x/periph/host/distro -periph.io/x/periph/host/fs -periph.io/x/periph/host/odroidc1 -periph.io/x/periph/host/pine64 -periph.io/x/periph/host/pmem -periph.io/x/periph/host/rpi -periph.io/x/periph/host/sysfs -periph.io/x/periph/host/videocore +# periph.io/x/conn/v3 v3.6.8 +## explicit; go 1.13 +periph.io/x/conn/v3 +periph.io/x/conn/v3/driver +periph.io/x/conn/v3/driver/driverreg +periph.io/x/conn/v3/gpio +periph.io/x/conn/v3/gpio/gpioreg +periph.io/x/conn/v3/gpio/gpiostream +periph.io/x/conn/v3/i2c +periph.io/x/conn/v3/i2c/i2creg +periph.io/x/conn/v3/physic +periph.io/x/conn/v3/pin +periph.io/x/conn/v3/pin/pinreg +periph.io/x/conn/v3/spi +periph.io/x/conn/v3/spi/spireg +# periph.io/x/d2xx v0.0.1 +## explicit; go 1.13 +periph.io/x/d2xx +# periph.io/x/host/v3 v3.7.0 +## explicit; go 1.13 +periph.io/x/host/v3 +periph.io/x/host/v3/allwinner +periph.io/x/host/v3/am335x +periph.io/x/host/v3/bcm283x +periph.io/x/host/v3/beagle/black +periph.io/x/host/v3/beagle/bone +periph.io/x/host/v3/beagle/green +periph.io/x/host/v3/chip +periph.io/x/host/v3/cpu +periph.io/x/host/v3/distro +periph.io/x/host/v3/fs +periph.io/x/host/v3/ftdi +periph.io/x/host/v3/odroidc1 +periph.io/x/host/v3/pine64 +periph.io/x/host/v3/pmem +periph.io/x/host/v3/rpi +periph.io/x/host/v3/sysfs +periph.io/x/host/v3/videocore diff --git a/vendor/periph.io/x/conn/v3/.gohci.yml b/vendor/periph.io/x/conn/v3/.gohci.yml new file mode 100644 index 0000000..c27bade --- /dev/null +++ b/vendor/periph.io/x/conn/v3/.gohci.yml @@ -0,0 +1,513 @@ +# Copyright 2021 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. + +# See https://github.com/periph/gohci +version: 1 +workers: +# BeagleBone Green Wireles by SeedStudio. +# https://beagleboard.org/green-wireless +- name: beaglebone-1860 + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/host + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../host + - cmd: + - go + - test + - ./... + dir: ../host + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list + - cmd: + - periph-smoketest + - gpio + - -pin1 + - P8_45 + - -pin2 + - P8_46 + +# ODROID-C1+ by HardKernel +# https://www.hardkernel.com/shop/odroid-c1/ +- name: odroid-483d + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/host + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../host + - cmd: + - go + - test + - ./... + dir: ../host + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list + - cmd: + - periph-smoketest + - odroid-c1 + - cmd: + - periph-smoketest + - i2c-testboard + - cmd: + - periph-smoketest + - onewire-testboard + - cmd: + - periph-smoketest + - spi-testboard + - cmd: + - periph-smoketest + - sysfs-benchmark + - -p + - 97 + - -short + +# Raspberry Pi 3 +- name: raspberrypi-2f34 + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/host + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../host + - cmd: + - go + - test + - ./... + dir: ../host + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list + - cmd: + - periph-smoketest + - i2c-testboard + - cmd: + - periph-smoketest + - onewire-testboard + - -i2cbus + - 1 + - cmd: + - periph-smoketest + - spi-testboard + - cmd: + - periph-smoketest + - sysfs-benchmark + - -p + - 12 + - -short + - cmd: + - periph-smoketest + - bcm283x-benchmark + - -p + - 12 + - -short + - cmd: + - periph-smoketest + - gpio + - -pin1 + - P1_15 + - -pin2 + - P1_16 + - cmd: + - periph-smoketest + - bcm283x + - -quick + +# Old MacBook Pro on 10.9. +- name: mbp + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/host + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../host + - cmd: + - go + - test + - ./... + dir: ../host + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list + +# Laptop on Windows 10. +- name: win10 + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/host + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../host + - cmd: + - go + - test + - ./... + dir: ../host + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/conn/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list diff --git a/vendor/periph.io/x/periph/AUTHORS b/vendor/periph.io/x/conn/v3/AUTHORS similarity index 100% rename from vendor/periph.io/x/periph/AUTHORS rename to vendor/periph.io/x/conn/v3/AUTHORS diff --git a/vendor/periph.io/x/periph/CONTRIBUTING.md b/vendor/periph.io/x/conn/v3/CONTRIBUTING.md similarity index 100% rename from vendor/periph.io/x/periph/CONTRIBUTING.md rename to vendor/periph.io/x/conn/v3/CONTRIBUTING.md diff --git a/vendor/periph.io/x/periph/CONTRIBUTORS b/vendor/periph.io/x/conn/v3/CONTRIBUTORS similarity index 100% rename from vendor/periph.io/x/periph/CONTRIBUTORS rename to vendor/periph.io/x/conn/v3/CONTRIBUTORS diff --git a/vendor/periph.io/x/periph/LICENSE b/vendor/periph.io/x/conn/v3/LICENSE similarity index 100% rename from vendor/periph.io/x/periph/LICENSE rename to vendor/periph.io/x/conn/v3/LICENSE diff --git a/vendor/periph.io/x/conn/v3/README.md b/vendor/periph.io/x/conn/v3/README.md new file mode 100644 index 0000000..f677192 --- /dev/null +++ b/vendor/periph.io/x/conn/v3/README.md @@ -0,0 +1,57 @@ +# periph - Peripherals I/O in Go + +Documentation is at https://periph.io + +Join us for a chat on +[gophers.slack.com/messages/periph](https://gophers.slack.com/messages/periph), +get an [invite here](https://invite.slack.golangbridge.org/). + +[![mascot](https://raw.githubusercontent.com/periph/website/master/site/static/img/periph-mascot-280.png)](https://periph.io/) + +[![PkgGoDev](https://pkg.go.dev/badge/periph.io/x/conn/v3)](https://pkg.go.dev/periph.io/x/conn/v3) +[![Coverage +Status](https://codecov.io/gh/periph/conn/graph/badge.svg)](https://codecov.io/gh/periph/conn) + + +## Example + +Blink a LED: + +~~~go +package main + +import ( + "time" + "periph.io/x/conn/v3/gpio" + "periph.io/x/host" + "periph.io/x/host/rpi" +) + +func main() { + host.Init() + t := time.NewTicker(500 * time.Millisecond) + for l := gpio.Low; ; l = !l { + rpi.P1_33.Out(l) + <-t.C + } +} +~~~ + +Curious? Look at [supported devices](https://periph.io/device/) for more +examples! + + +## Authors + +`periph` was initiated with ❤️️ and passion by [Marc-Antoine +Ruel](https://github.com/maruel). The full list of contributors is in +[AUTHORS](https://github.com/periph/conn/blob/main/AUTHORS) and +[CONTRIBUTORS](https://github.com/periph/conn/blob/main/CONTRIBUTORS). + + +## Disclaimer + +This is not an official Google product (experimental or otherwise), it +is just code that happens to be owned by Google. + +This project is not affiliated with the Go project. diff --git a/vendor/periph.io/x/periph/codecov.yml b/vendor/periph.io/x/conn/v3/codecov.yml similarity index 100% rename from vendor/periph.io/x/periph/codecov.yml rename to vendor/periph.io/x/conn/v3/codecov.yml diff --git a/vendor/periph.io/x/periph/conn/conn.go b/vendor/periph.io/x/conn/v3/conn.go similarity index 100% rename from vendor/periph.io/x/periph/conn/conn.go rename to vendor/periph.io/x/conn/v3/conn.go diff --git a/vendor/periph.io/x/conn/v3/doc.go b/vendor/periph.io/x/conn/v3/doc.go new file mode 100644 index 0000000..2af0df5 --- /dev/null +++ b/vendor/periph.io/x/conn/v3/doc.go @@ -0,0 +1,63 @@ +// 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 conn defines core interfaces for protocols and connections. +// +// This package and its subpackages describe the base interfaces to connect the +// software with the real world. It doesn't contain any implementation but +// includes registries to enable the application to discover the available +// hardware. +// +// Concepts +// +// periph uses 3 layered concepts for interfacing: +// +// Bus → Port → Conn +// +// Not every subpackage expose all 3 concepts. In fact, most packages don't. +// For example, SPI doesn't expose Bus as the OSes generally only expose the +// Port, that is, a Chip Select (CS) line must be selected right upfront to get +// an handle. For I²C, there's no Port to configure, so selecting a "slave" +// address is sufficient to jump directly from a Bus to a Conn. +// +// periph doesn't have yet a concept of star-like communication network, like +// an IP network. +// +// Bus +// +// A Bus is a multi-point communication channel where one "master" and multiple +// "slaves" communicate together. In the case of periph, the Bus handle is +// assumed to be the "master". The "master" generally initiates communications +// and selects the "slave" to talk to. +// +// As the "master" selects a "slave" over a bus, a virtual Port is +// automatically created. +// +// Examples include SPI, I²C and 1-wire. In each case, selecting a +// communication line (Chip Select (CS) line for SPI, address for I²C or +// 1-wire) converts the Bus into a Port. +// +// Port +// +// A port is a point-to-point communication channel that is yet to be +// initialized. It cannot be used for communication until it is connected and +// transformed into a Conn. Configuring a Port converts it into a Conn. Not all +// Port need configuration. +// +// Conn +// +// A Conn is a fully configured half or full duplex communication channel that +// is point-to-point, only between two devices. It is ready to use like any +// readable and/or writable pipe. +// +// Subpackages +// +// Most connection-type specific subpackages include subpackages: +// +// → XXXreg: registry as that is populated by the host drivers and that can be +// leveraged by applications. +// +// → XXXtest: fake implementation that can be leveraged when writing device +// driver unit test. +package conn diff --git a/vendor/periph.io/x/conn/v3/driver/driver.go b/vendor/periph.io/x/conn/v3/driver/driver.go new file mode 100644 index 0000000..5b2b73c --- /dev/null +++ b/vendor/periph.io/x/conn/v3/driver/driver.go @@ -0,0 +1,45 @@ +// 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 driver devices a host peripheral driver to register when +// initializing. +// +// Drivers that can be automatically discovered should be registered in +// driverreg so discovery is done automatically. +package driver + +// Impl is a host peripheral driver implementation. +type Impl interface { + // String returns the name of the driver, as to be presented to the user. + // + // It must be unique in the list of registered drivers. + String() string + // Prerequisites returns a list of drivers that must be successfully loaded + // first before attempting to load this driver. + // + // A driver listing a prerequisite not registered is a fatal failure at + // initialization time. + Prerequisites() []string + // After returns a list of drivers that must be loaded first before + // attempting to load this driver. + // + // Unlike Prerequisites(), this driver will still be attempted even if the + // listed driver is missing or failed to load. + // + // This permits serialization without hard requirement. + After() []string + // Init initializes the driver. + // + // A driver may enter one of the three following state: loaded successfully, + // was skipped as irrelevant on this host, failed to load. + // + // On success, it must return true, nil. + // + // When irrelevant (skipped), it must return false, errors.New(). + // + // On failure, it must return true, errors.New(). The failure must + // state why it failed, for example an expected OS provided driver couldn't + // be opened, e.g. /dev/gpiomem on Raspbian. + Init() (bool, error) +} diff --git a/vendor/periph.io/x/periph/periph.go b/vendor/periph.io/x/conn/v3/driver/driverreg/driverreg.go similarity index 72% rename from vendor/periph.io/x/periph/periph.go rename to vendor/periph.io/x/conn/v3/driver/driverreg/driverreg.go index 9f47fe8..197cdcf 100644 --- a/vendor/periph.io/x/periph/periph.go +++ b/vendor/periph.io/x/conn/v3/driver/driverreg/driverreg.go @@ -2,61 +2,23 @@ // Use of this source code is governed under the Apache License, Version 2.0 // that can be found in the LICENSE file. -// Package periph is a peripheral I/O library. -// -// Is it now superseded by https://periph.io/x/conn/v3 (or later), -// https://periph.io/x/host/v3 (or later), https://periph.io/x/devices/v3 (or -// later) and https://periph.io/x/cmd. -// -// See https://periph.io/news/2020/a_new_start/ for more details. -package periph // import "periph.io/x/periph" +// Package driverreg is a registry for all host driver implementation that can +// be automatically discovered. +package driverreg import ( "errors" "strconv" "strings" "sync" -) -// Driver is an implementation for a protocol. -type Driver interface { - // String returns the name of the driver, as to be presented to the user. - // - // It must be unique in the list of registered drivers. - String() string - // Prerequisites returns a list of drivers that must be successfully loaded - // first before attempting to load this driver. - // - // A driver listing a prerequisite not registered is a fatal failure at - // initialization time. - Prerequisites() []string - // After returns a list of drivers that must be loaded first before - // attempting to load this driver. - // - // Unlike Prerequisites(), this driver will still be attempted even if the - // listed driver is missing or failed to load. - // - // This permits serialization without hard requirement. - After() []string - // Init initializes the driver. - // - // A driver may enter one of the three following state: loaded successfully, - // was skipped as irrelevant on this host, failed to load. - // - // On success, it must return true, nil. - // - // When irrelevant (skipped), it must return false, errors.New(). - // - // On failure, it must return true, errors.New(). The failure must - // state why it failed, for example an expected OS provided driver couldn't - // be opened, e.g. /dev/gpiomem on Raspbian. - Init() (bool, error) -} + "periph.io/x/conn/v3/driver" +) // DriverFailure is a driver that wasn't loaded, either because it was skipped // or because it failed to load. type DriverFailure struct { - D Driver + D driver.Impl Err error } @@ -74,7 +36,7 @@ func (d DriverFailure) String() string { // // Each list is sorted by the driver name. type State struct { - Loaded []Driver + Loaded []driver.Impl Skipped []DriverFailure Failed []DriverFailure } @@ -102,7 +64,7 @@ func Init() (*State, error) { // The d.String() value must be unique across all registered drivers. // // It is an error to call Register() after Init() was called. -func Register(d Driver) error { +func Register(d driver.Impl) error { mu.Lock() defer mu.Unlock() if state != nil { @@ -120,7 +82,7 @@ func Register(d Driver) error { // MustRegister calls Register() and panics if registration fails. // // This is the function to call in a driver's package init() function. -func MustRegister(d Driver) { +func MustRegister(d driver.Impl) { if err := Register(d); err != nil { panic(err) } @@ -136,14 +98,14 @@ var ( // Once Init() is called, Register() refuses registering more drivers, thus // byName is immutable once Init() started. mu sync.Mutex - byName = map[string]Driver{} + byName = map[string]driver.Impl{} state *State ) // stage is a set of drivers that can be loaded in parallel. type stage struct { // Subset of byName drivers, for the ones in this stage. - drvs map[string]Driver + drvs map[string]driver.Impl } // explodeStages creates one or multiple stages by processing byName. @@ -178,7 +140,7 @@ func explodeStages() ([]*stage, error) { // Create stages. var stages []*stage for len(dag) != 0 { - s := &stage{drvs: map[string]Driver{}} + s := &stage{drvs: map[string]driver.Impl{}} for name, deps := range dag { // This driver has no dependency, add it to the current stage. if len(deps) == 0 { @@ -211,7 +173,7 @@ func explodeStages() ([]*stage, error) { return stages, nil } -func insertDriver(l []Driver, d Driver) []Driver { +func insertDriver(l []driver.Impl, d driver.Impl) []driver.Impl { n := d.String() i := search(len(l), func(i int) bool { return l[i].String() > n }) l = append(l, nil) diff --git a/vendor/periph.io/x/periph/periph_parallel.go b/vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_parallel.go similarity index 92% rename from vendor/periph.io/x/periph/periph_parallel.go rename to vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_parallel.go index 656e3f0..5f7195f 100644 --- a/vendor/periph.io/x/periph/periph_parallel.go +++ b/vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_parallel.go @@ -7,18 +7,20 @@ // +build !tinygo -package periph +package driverreg import ( "errors" "strconv" "sync" + + "periph.io/x/conn/v3/driver" ) func initImpl() (*State, error) { state = &State{} // At this point, byName is guaranteed to be immutable. - cD := make(chan Driver) + cD := make(chan driver.Impl) cS := make(chan DriverFailure) cE := make(chan DriverFailure) var wg sync.WaitGroup @@ -62,7 +64,7 @@ func initImpl() (*State, error) { // loadParallel loads all the drivers for this stage in parallel. // // Updates loaded in a safe way. -func (s *stage) loadParallel(loaded map[string]struct{}, cD chan<- Driver, cS, cE chan<- DriverFailure) { +func (s *stage) loadParallel(loaded map[string]struct{}, cD chan<- driver.Impl, cS, cE chan<- DriverFailure) { success := make(chan string) go func() { defer close(success) @@ -79,7 +81,7 @@ func (s *stage) loadParallel(loaded map[string]struct{}, cD chan<- Driver, cS, c // Not skipped driver, attempt loading in a goroutine. wg.Add(1) - go func(n string, d Driver) { + go func(n string, d driver.Impl) { defer wg.Done() if ok, err := d.Init(); ok { if err == nil { diff --git a/vendor/periph.io/x/periph/periph_serial.go b/vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_serial.go similarity index 98% rename from vendor/periph.io/x/periph/periph_serial.go rename to vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_serial.go index 3fa70c2..6ad587f 100644 --- a/vendor/periph.io/x/periph/periph_serial.go +++ b/vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_serial.go @@ -7,7 +7,7 @@ // +build tinygo -package periph +package driverreg import ( "errors" diff --git a/vendor/periph.io/x/periph/conn/gpio/func.go b/vendor/periph.io/x/conn/v3/gpio/func.go similarity index 95% rename from vendor/periph.io/x/periph/conn/gpio/func.go rename to vendor/periph.io/x/conn/v3/gpio/func.go index c5bb8e5..6ed41eb 100644 --- a/vendor/periph.io/x/periph/conn/gpio/func.go +++ b/vendor/periph.io/x/conn/v3/gpio/func.go @@ -4,7 +4,7 @@ package gpio -import "periph.io/x/periph/conn/pin" +import "periph.io/x/conn/v3/pin" // Well known pin functionality. const ( diff --git a/vendor/periph.io/x/periph/conn/gpio/gpio.go b/vendor/periph.io/x/conn/v3/gpio/gpio.go similarity index 99% rename from vendor/periph.io/x/periph/conn/gpio/gpio.go rename to vendor/periph.io/x/conn/v3/gpio/gpio.go index 2f6112f..6b6f587 100644 --- a/vendor/periph.io/x/periph/conn/gpio/gpio.go +++ b/vendor/periph.io/x/conn/v3/gpio/gpio.go @@ -14,8 +14,8 @@ import ( "strings" "time" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/pin" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" ) // Interfaces diff --git a/vendor/periph.io/x/periph/conn/gpio/gpioreg/gpioreg.go b/vendor/periph.io/x/conn/v3/gpio/gpioreg/gpioreg.go similarity index 99% rename from vendor/periph.io/x/periph/conn/gpio/gpioreg/gpioreg.go rename to vendor/periph.io/x/conn/v3/gpio/gpioreg/gpioreg.go index 65f2de5..f4c3d01 100644 --- a/vendor/periph.io/x/periph/conn/gpio/gpioreg/gpioreg.go +++ b/vendor/periph.io/x/conn/v3/gpio/gpioreg/gpioreg.go @@ -10,7 +10,7 @@ import ( "strconv" "sync" - "periph.io/x/periph/conn/gpio" + "periph.io/x/conn/v3/gpio" ) // ByName returns a GPIO pin from its name, gpio number or one of its aliases. diff --git a/vendor/periph.io/x/periph/conn/gpio/gpioreg/natsort.go b/vendor/periph.io/x/conn/v3/gpio/gpioreg/natsort.go similarity index 100% rename from vendor/periph.io/x/periph/conn/gpio/gpioreg/natsort.go rename to vendor/periph.io/x/conn/v3/gpio/gpioreg/natsort.go diff --git a/vendor/periph.io/x/periph/conn/gpio/gpiostream/gpiostream.go b/vendor/periph.io/x/conn/v3/gpio/gpiostream/gpiostream.go similarity index 98% rename from vendor/periph.io/x/periph/conn/gpio/gpiostream/gpiostream.go rename to vendor/periph.io/x/conn/v3/gpio/gpiostream/gpiostream.go index 849418a..18e77f9 100644 --- a/vendor/periph.io/x/periph/conn/gpio/gpiostream/gpiostream.go +++ b/vendor/periph.io/x/conn/v3/gpio/gpiostream/gpiostream.go @@ -13,9 +13,9 @@ import ( "fmt" "time" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/pin" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" ) // Stream is the interface to define a generic stream. diff --git a/vendor/periph.io/x/periph/conn/i2c/func.go b/vendor/periph.io/x/conn/v3/i2c/func.go similarity index 89% rename from vendor/periph.io/x/periph/conn/i2c/func.go rename to vendor/periph.io/x/conn/v3/i2c/func.go index f40308e..654edf0 100644 --- a/vendor/periph.io/x/periph/conn/i2c/func.go +++ b/vendor/periph.io/x/conn/v3/i2c/func.go @@ -4,7 +4,7 @@ package i2c -import "periph.io/x/periph/conn/pin" +import "periph.io/x/conn/v3/pin" // Well known pin functionality. const ( diff --git a/vendor/periph.io/x/periph/conn/i2c/i2c.go b/vendor/periph.io/x/conn/v3/i2c/i2c.go similarity index 95% rename from vendor/periph.io/x/periph/conn/i2c/i2c.go rename to vendor/periph.io/x/conn/v3/i2c/i2c.go index 279b25b..6d5f7f3 100644 --- a/vendor/periph.io/x/periph/conn/i2c/i2c.go +++ b/vendor/periph.io/x/conn/v3/i2c/i2c.go @@ -5,7 +5,7 @@ // 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 +// As described in https://periph.io/x/conn/v3#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 @@ -23,9 +23,9 @@ import ( "io" "strconv" - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/physic" + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/physic" ) // Bus defines the interface a concrete I²C driver must implement. diff --git a/vendor/periph.io/x/periph/conn/i2c/i2creg/i2creg.go b/vendor/periph.io/x/conn/v3/i2c/i2creg/i2creg.go similarity index 99% rename from vendor/periph.io/x/periph/conn/i2c/i2creg/i2creg.go rename to vendor/periph.io/x/conn/v3/i2c/i2creg/i2creg.go index 69c828b..98dbc72 100644 --- a/vendor/periph.io/x/periph/conn/i2c/i2creg/i2creg.go +++ b/vendor/periph.io/x/conn/v3/i2c/i2creg/i2creg.go @@ -11,7 +11,7 @@ import ( "strings" "sync" - "periph.io/x/periph/conn/i2c" + "periph.io/x/conn/v3/i2c" ) // Opener opens an handle to a bus. diff --git a/vendor/periph.io/x/periph/conn/physic/doc.go b/vendor/periph.io/x/conn/v3/physic/doc.go similarity index 100% rename from vendor/periph.io/x/periph/conn/physic/doc.go rename to vendor/periph.io/x/conn/v3/physic/doc.go diff --git a/vendor/periph.io/x/periph/conn/physic/physic.go b/vendor/periph.io/x/conn/v3/physic/physic.go similarity index 98% rename from vendor/periph.io/x/periph/conn/physic/physic.go rename to vendor/periph.io/x/conn/v3/physic/physic.go index 550855f..fb1d804 100644 --- a/vendor/periph.io/x/periph/conn/physic/physic.go +++ b/vendor/periph.io/x/conn/v3/physic/physic.go @@ -7,7 +7,7 @@ package physic import ( "time" - "periph.io/x/periph/conn" + "periph.io/x/conn/v3" ) // Env represents measurements from an environmental sensor. diff --git a/vendor/periph.io/x/periph/conn/physic/units.go b/vendor/periph.io/x/conn/v3/physic/units.go similarity index 100% rename from vendor/periph.io/x/periph/conn/physic/units.go rename to vendor/periph.io/x/conn/v3/physic/units.go diff --git a/vendor/periph.io/x/periph/conn/pin/func.go b/vendor/periph.io/x/conn/v3/pin/func.go similarity index 100% rename from vendor/periph.io/x/periph/conn/pin/func.go rename to vendor/periph.io/x/conn/v3/pin/func.go diff --git a/vendor/periph.io/x/periph/conn/pin/pin.go b/vendor/periph.io/x/conn/v3/pin/pin.go similarity index 99% rename from vendor/periph.io/x/periph/conn/pin/pin.go rename to vendor/periph.io/x/conn/v3/pin/pin.go index 9cf60bd..8ac9c8b 100644 --- a/vendor/periph.io/x/periph/conn/pin/pin.go +++ b/vendor/periph.io/x/conn/v3/pin/pin.go @@ -12,7 +12,7 @@ package pin import ( "errors" - "periph.io/x/periph/conn" + "periph.io/x/conn/v3" ) // These are well known pins. diff --git a/vendor/periph.io/x/periph/conn/pin/pinreg/doc.go b/vendor/periph.io/x/conn/v3/pin/pinreg/doc.go similarity index 100% rename from vendor/periph.io/x/periph/conn/pin/pinreg/doc.go rename to vendor/periph.io/x/conn/v3/pin/pinreg/doc.go diff --git a/vendor/periph.io/x/periph/conn/pin/pinreg/pinreg.go b/vendor/periph.io/x/conn/v3/pin/pinreg/pinreg.go similarity index 97% rename from vendor/periph.io/x/periph/conn/pin/pinreg/pinreg.go rename to vendor/periph.io/x/conn/v3/pin/pinreg/pinreg.go index b31ba33..4af303b 100644 --- a/vendor/periph.io/x/periph/conn/pin/pinreg/pinreg.go +++ b/vendor/periph.io/x/conn/v3/pin/pinreg/pinreg.go @@ -9,9 +9,9 @@ import ( "strconv" "sync" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/pin" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/pin" ) // All contains all the on-board headers on a micro computer. diff --git a/vendor/periph.io/x/periph/conn/spi/func.go b/vendor/periph.io/x/conn/v3/spi/func.go similarity index 91% rename from vendor/periph.io/x/periph/conn/spi/func.go rename to vendor/periph.io/x/conn/v3/spi/func.go index 6b9a2ea..97420e3 100644 --- a/vendor/periph.io/x/periph/conn/spi/func.go +++ b/vendor/periph.io/x/conn/v3/spi/func.go @@ -4,7 +4,7 @@ package spi -import "periph.io/x/periph/conn/pin" +import "periph.io/x/conn/v3/pin" // Well known pin functionality. const ( diff --git a/vendor/periph.io/x/periph/conn/spi/spi.go b/vendor/periph.io/x/conn/v3/spi/spi.go similarity index 97% rename from vendor/periph.io/x/periph/conn/spi/spi.go rename to vendor/periph.io/x/conn/v3/spi/spi.go index b1a2159..724da06 100644 --- a/vendor/periph.io/x/periph/conn/spi/spi.go +++ b/vendor/periph.io/x/conn/v3/spi/spi.go @@ -5,7 +5,7 @@ // Package spi defines the API to communicate with devices over the SPI // protocol. // -// As described in https://periph.io/x/periph/conn#hdr-Concepts, periph.io uses +// 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 @@ -25,9 +25,9 @@ import ( "io" "strconv" - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/physic" + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/physic" ) // Mode determines how communication is done. diff --git a/vendor/periph.io/x/periph/conn/spi/spireg/spireg.go b/vendor/periph.io/x/conn/v3/spi/spireg/spireg.go similarity index 99% rename from vendor/periph.io/x/periph/conn/spi/spireg/spireg.go rename to vendor/periph.io/x/conn/v3/spi/spireg/spireg.go index dbc74f7..dc7bc33 100644 --- a/vendor/periph.io/x/periph/conn/spi/spireg/spireg.go +++ b/vendor/periph.io/x/conn/v3/spi/spireg/spireg.go @@ -14,7 +14,7 @@ import ( "strings" "sync" - "periph.io/x/periph/conn/spi" + "periph.io/x/conn/v3/spi" ) // Opener opens an handle to a port. diff --git a/vendor/periph.io/x/d2xx/.gohci.yml b/vendor/periph.io/x/d2xx/.gohci.yml new file mode 100644 index 0000000..32d9ca2 --- /dev/null +++ b/vendor/periph.io/x/d2xx/.gohci.yml @@ -0,0 +1,48 @@ +# Copyright 2021 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. + +# See https://github.com/periph/gohci +version: 1 +workers: +- checks: + - cmd: + - go + - test + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/host + dir: .. + - cmd: + - go + - get + - periph.io/x/d2xx@${GIT_SHA} + dir: ../host + - cmd: + - go + - test + - ./... + dir: ../host + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/d2xx@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd diff --git a/vendor/periph.io/x/d2xx/LICENSE b/vendor/periph.io/x/d2xx/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/vendor/periph.io/x/d2xx/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/periph.io/x/d2xx/README.md b/vendor/periph.io/x/d2xx/README.md new file mode 100644 index 0000000..7a3f660 --- /dev/null +++ b/vendor/periph.io/x/d2xx/README.md @@ -0,0 +1,16 @@ +# d2xx + +Package d2xx is a thin Go wrapper for the Future Technology "D2XX" driver at +https://ftdichip.com/drivers/d2xx-drivers/. + +See https://periph.io/device/ftdi/ for more details, and how to configure +the host to be able to use this driver. + +This package is not Go idiomatic. You will want to use +https://periph.io/x/host/v3/ftdi (or later) instead. + +But if you really want, here it goes: +[![PkgGoDev](https://pkg.go.dev/badge/periph.io/x/d2xx)](https://pkg.go.dev/periph.io/x/d2xx) + +This Go package includes third party software. See +[third_party/README.md](third_party/README.md). diff --git a/vendor/periph.io/x/d2xx/d2xx.go b/vendor/periph.io/x/d2xx/d2xx.go new file mode 100644 index 0000000..79890c3 --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx.go @@ -0,0 +1,132 @@ +// Copyright 2021 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 d2xx + +import ( + "strconv" +) + +// Err is the error type returned by d2xx functions. +type Err int + +// These are additional synthetic error codes. +const ( + // NoCGO is returned when the package was compiled without cgo, thus the d2xx + // library is unavailable. + // + // This is never returned on Windows. + NoCGO Err = -2 + // Missing is returned when the dynamic library is not available. + Missing Err = -1 +) + +// String converts a error integer to a string representation of the error. +func (e Err) String() string { + switch e { + case Missing: + // when the library d2xx couldn't be loaded at runtime. + return "couldn't load driver; visit https://periph.io/device/ftdi/ for help" + case NoCGO: + return "can't be used without cgo" + case 0: // FT_OK + return "" + case 1: // FT_INVALID_HANDLE + return "invalid handle" + case 2: // FT_DEVICE_NOT_FOUND + return "device not found; see https://periph.io/device/ftdi/ for help" + case 3: // FT_DEVICE_NOT_OPENED + return "device busy; see https://periph.io/device/ftdi/ for help" + case 4: // FT_IO_ERROR + return "I/O error" + case 5: // FT_INSUFFICIENT_RESOURCES + return "insufficient resources" + case 6: // FT_INVALID_PARAMETER + return "invalid parameter" + case 7: // FT_INVALID_BAUD_RATE + return "invalid baud rate" + case 8: // FT_DEVICE_NOT_OPENED_FOR_ERASE + return "device not opened for erase" + case 9: // FT_DEVICE_NOT_OPENED_FOR_WRITE + return "device not opened for write" + case 10: // FT_FAILED_TO_WRITE_DEVICE + return "failed to write device" + case 11: // FT_EEPROM_READ_FAILED + return "eeprom read failed" + case 12: // FT_EEPROM_WRITE_FAILED + return "eeprom write failed" + case 13: // FT_EEPROM_ERASE_FAILED + return "eeprom erase failed" + case 14: // FT_EEPROM_NOT_PRESENT + return "eeprom not present" + case 15: // FT_EEPROM_NOT_PROGRAMMED + return "eeprom not programmed" + case 16: // FT_INVALID_ARGS + return "invalid argument" + case 17: // FT_NOT_SUPPORTED + return "not supported" + case 18: // FT_OTHER_ERROR + return "other error" + case 19: // FT_DEVICE_LIST_NOT_READY + return "device list not ready" + default: + return "unknown status " + strconv.Itoa(int(e)) + } +} + +// unknown is a forward declaration of ftdi.DevType. +const unknown = 3 + +// handle is a d2xx handle. +// +// This is the base type which each OS specific implementation adds methods to. +type handle uintptr + +// Handle is d2xx device handle. +type Handle interface { + Close() Err + // ResetDevice takes >1.2ms + ResetDevice() Err + GetDeviceInfo() (uint32, uint16, uint16, Err) + EEPROMRead(devType uint32, e *EEPROM) Err + EEPROMProgram(e *EEPROM) Err + EraseEE() Err + WriteEE(offset uint8, value uint16) Err + EEUASize() (int, Err) + EEUARead(ua []byte) Err + EEUAWrite(ua []byte) Err + SetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) Err + SetUSBParameters(in, out int) Err + SetFlowControl() Err + SetTimeouts(readMS, writeMS int) Err + SetLatencyTimer(delayMS uint8) Err + SetBaudRate(hz uint32) Err + // GetQueueStatus takes >60µs + GetQueueStatus() (uint32, Err) + // Read takes <5µs if GetQueueStatus was called just before, + // 300µs~800µs otherwise (!) + Read(b []byte) (int, Err) + // Write takes >0.1ms + Write(b []byte) (int, Err) + GetBitMode() (byte, Err) + // SetBitMode takes >0.1ms + SetBitMode(mask, mode byte) Err +} + +var _ Handle = handle(0) + +// Version returns the library's version. +func Version() (uint8, uint8, uint8) { + return version() +} + +// CreateDeviceInfoList discovers the currently found devices. +func CreateDeviceInfoList() (int, Err) { + return createDeviceInfoList() +} + +// Open opens the ith device discovered. +func Open(i int) (Handle, Err) { + return open(i) +} diff --git a/vendor/periph.io/x/d2xx/d2xx_darwin_amd64.go b/vendor/periph.io/x/d2xx/d2xx_darwin_amd64.go new file mode 100644 index 0000000..3fa84a9 --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx_darwin_amd64.go @@ -0,0 +1,12 @@ +// 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. + +// +build cgo + +package d2xx + +/* +#cgo LDFLAGS: -framework CoreFoundation -framework IOKit ${SRCDIR}/third_party/libftd2xx_darwin_amd64_v1.4.4.a +*/ +import "C" diff --git a/vendor/periph.io/x/d2xx/d2xx_linux_amd64.go b/vendor/periph.io/x/d2xx/d2xx_linux_amd64.go new file mode 100644 index 0000000..cb3b46d --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx_linux_amd64.go @@ -0,0 +1,12 @@ +// 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. + +// +build cgo + +package d2xx + +/* +#cgo LDFLAGS: ${SRCDIR}/third_party/libftd2xx_linux_amd64_v1.4.6.a +*/ +import "C" diff --git a/vendor/periph.io/x/d2xx/d2xx_linux_arm.go b/vendor/periph.io/x/d2xx/d2xx_linux_arm.go new file mode 100644 index 0000000..014592c --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx_linux_arm.go @@ -0,0 +1,15 @@ +// 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. + +// +build cgo + +package d2xx + +// TODO(maruel): https://github.com/golang/go/issues/7211 would help target the +// optimal ARM architecture. + +/* +#cgo LDFLAGS: ${SRCDIR}/third_party/libftd2xx_linux_arm6hf_v1.4.6.a +*/ +import "C" diff --git a/vendor/periph.io/x/d2xx/d2xx_posix.go b/vendor/periph.io/x/d2xx/d2xx_posix.go new file mode 100644 index 0000000..5cc3d52 --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx_posix.go @@ -0,0 +1,217 @@ +// 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. + +// +build !windows + +package d2xx + +/* +#include "third_party/ftd2xx.h" +#include +*/ +import "C" +import ( + "unsafe" +) + +// Available is true if the library is available on this system. +const Available = true + +// Library functions. + +func version() (uint8, uint8, uint8) { + var v C.DWORD + C.FT_GetLibraryVersion(&v) + return uint8(v >> 16), uint8(v >> 8), uint8(v) +} + +func createDeviceInfoList() (int, Err) { + var num C.DWORD + e := C.FT_CreateDeviceInfoList(&num) + return int(num), Err(e) +} + +func open(i int) (Handle, Err) { + var h C.FT_HANDLE + e := C.FT_Open(C.int(i), &h) + if uintptr(h) == 0 && e == 0 { + // 18 means FT_OTHER_ERROR. Kind of a hack but better than panic. + e = 18 + } + return handle(h), Err(e) +} + +func (h handle) Close() Err { + return Err(C.FT_Close(h.toH())) +} + +func (h handle) ResetDevice() Err { + return Err(C.FT_ResetDevice(h.toH())) +} + +func (h handle) GetDeviceInfo() (uint32, uint16, uint16, Err) { + var dev C.FT_DEVICE + var id C.DWORD + if e := C.FT_GetDeviceInfo(h.toH(), &dev, &id, nil, nil, nil); e != 0 { + return unknown, 0, 0, Err(e) + } + return uint32(dev), uint16(id >> 16), uint16(id), 0 +} + +func (h handle) EEPROMRead(devType uint32, ee *EEPROM) Err { + var manufacturer [64]C.char + var manufacturerID [64]C.char + var desc [64]C.char + var serial [64]C.char + eepromVoid := unsafe.Pointer(&ee.Raw[0]) + hdr := ee.asHeader() + + // There something odd going on here. + // + // On a ft232h, we observed that hdr.DeviceType MUST NOT be set, but on a + // ft232r, it MUST be set. Since we can't know in advance what we must use, + // just try both. ¯\_(ツ)_/¯ + hdr.DeviceType = devType + if e := C.FT_EEPROM_Read(h.toH(), eepromVoid, C.DWORD(len(ee.Raw)), &manufacturer[0], &manufacturerID[0], &desc[0], &serial[0]); e != 0 { + // FT_INVALID_PARAMETER + if e == 6 { + hdr.DeviceType = 0 + e = C.FT_EEPROM_Read(h.toH(), eepromVoid, C.DWORD(len(ee.Raw)), &manufacturer[0], &manufacturerID[0], &desc[0], &serial[0]) + } + if e != 0 { + return Err(e) + } + } + + ee.Manufacturer = C.GoString(&manufacturer[0]) + ee.ManufacturerID = C.GoString(&manufacturerID[0]) + ee.Desc = C.GoString(&desc[0]) + ee.Serial = C.GoString(&serial[0]) + return 0 +} + +func (h handle) EEPROMProgram(ee *EEPROM) Err { + // len(manufacturer) + len(desc) <= 40. + /* + var cmanu [64]byte + copy(cmanu[:], ee.manufacturer) + var cmanuID [64]byte + copy(cmanuID[:], ee.manufacturerID) + var cdesc [64]byte + copy(cdesc[:], ee.desc) + var cserial [64]byte + copy(cserial[:], ee.serial) + */ + cmanu := C.CString(ee.Manufacturer) + defer C.free(unsafe.Pointer(cmanu)) + cmanuID := C.CString(ee.ManufacturerID) + defer C.free(unsafe.Pointer(cmanuID)) + cdesc := C.CString(ee.Desc) + defer C.free(unsafe.Pointer(cdesc)) + cserial := C.CString(ee.Serial) + defer C.free(unsafe.Pointer(cserial)) + + if len(ee.Raw) == 0 { + return Err(C.FT_EEPROM_Program(h.toH(), unsafe.Pointer(uintptr(0)), 0, cmanu, cmanuID, cdesc, cserial)) + } + return Err(C.FT_EEPROM_Program(h.toH(), unsafe.Pointer(&ee.Raw[0]), C.DWORD(len(ee.Raw)), cmanu, cmanuID, cdesc, cserial)) +} + +func (h handle) EraseEE() Err { + return Err(C.FT_EraseEE(h.toH())) +} + +func (h handle) WriteEE(offset uint8, value uint16) Err { + return Err(C.FT_WriteEE(h.toH(), C.DWORD(offset), C.WORD(value))) +} + +func (h handle) EEUASize() (int, Err) { + var size C.DWORD + if e := C.FT_EE_UASize(h.toH(), &size); e != 0 { + return 0, Err(e) + } + return int(size), 0 +} + +func (h handle) EEUARead(ua []byte) Err { + var size C.DWORD + if e := C.FT_EE_UARead(h.toH(), (*C.UCHAR)(unsafe.Pointer(&ua[0])), C.DWORD(len(ua)), &size); e != 0 { + return Err(e) + } + if int(size) != len(ua) { + return 6 // FT_INVALID_PARAMETER + } + return 0 +} + +func (h handle) EEUAWrite(ua []byte) Err { + if e := C.FT_EE_UAWrite(h.toH(), (*C.UCHAR)(&ua[0]), C.DWORD(len(ua))); e != 0 { + return Err(e) + } + return 0 +} + +func (h handle) SetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) Err { + v := C.UCHAR(0) + if eventEn { + v = 1 + } + w := C.UCHAR(0) + if errorEn { + w = 1 + } + return Err(C.FT_SetChars(h.toH(), C.UCHAR(eventChar), v, C.UCHAR(errorChar), w)) +} + +func (h handle) SetUSBParameters(in, out int) Err { + return Err(C.FT_SetUSBParameters(h.toH(), C.DWORD(in), C.DWORD(out))) +} + +func (h handle) SetFlowControl() Err { + return Err(C.FT_SetFlowControl(h.toH(), C.FT_FLOW_RTS_CTS, 0, 0)) +} + +func (h handle) SetTimeouts(readMS, writeMS int) Err { + return Err(C.FT_SetTimeouts(h.toH(), C.DWORD(readMS), C.DWORD(writeMS))) +} + +func (h handle) SetLatencyTimer(delayMS uint8) Err { + return Err(C.FT_SetLatencyTimer(h.toH(), C.UCHAR(delayMS))) +} + +func (h handle) SetBaudRate(hz uint32) Err { + return Err(C.FT_SetBaudRate(h.toH(), C.DWORD(hz))) +} + +func (h handle) GetQueueStatus() (uint32, Err) { + var v C.DWORD + e := C.FT_GetQueueStatus(h.toH(), &v) + return uint32(v), Err(e) +} + +func (h handle) Read(b []byte) (int, Err) { + var bytesRead C.DWORD + e := C.FT_Read(h.toH(), C.LPVOID(unsafe.Pointer(&b[0])), C.DWORD(len(b)), &bytesRead) + return int(bytesRead), Err(e) +} + +func (h handle) Write(b []byte) (int, Err) { + var bytesSent C.DWORD + e := C.FT_Write(h.toH(), C.LPVOID(unsafe.Pointer(&b[0])), C.DWORD(len(b)), &bytesSent) + return int(bytesSent), Err(e) +} + +func (h handle) GetBitMode() (byte, Err) { + var s C.UCHAR + e := C.FT_GetBitMode(h.toH(), &s) + return uint8(s), Err(e) +} + +func (h handle) SetBitMode(mask, mode byte) Err { + return Err(C.FT_SetBitMode(h.toH(), C.UCHAR(mask), C.UCHAR(mode))) +} + +func (h handle) toH() C.FT_HANDLE { + return C.FT_HANDLE(h) +} diff --git a/vendor/periph.io/x/d2xx/d2xx_posix_no_cgo.go b/vendor/periph.io/x/d2xx/d2xx_posix_no_cgo.go new file mode 100644 index 0000000..cc2382f --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx_posix_no_cgo.go @@ -0,0 +1,109 @@ +// 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. + +// +build !cgo +// +build !windows + +package d2xx + +// Available is true if the library is available on this system. +const Available = false + +// Library functions. + +func version() (uint8, uint8, uint8) { + return 0, 0, 0 +} + +func createDeviceInfoList() (int, Err) { + return 0, NoCGO +} + +func open(i int) (Handle, Err) { + return handle(0), NoCGO +} + +func (h handle) Close() Err { + return NoCGO +} + +func (h handle) ResetDevice() Err { + return NoCGO +} + +func (h handle) GetDeviceInfo() (uint32, uint16, uint16, Err) { + return unknown, 0, 0, NoCGO +} + +func (h handle) EEPROMRead(devType uint32, ee *EEPROM) Err { + return NoCGO +} + +func (h handle) EEPROMProgram(e *EEPROM) Err { + return NoCGO +} + +func (h handle) EraseEE() Err { + return NoCGO +} + +func (h handle) WriteEE(offset uint8, value uint16) Err { + return NoCGO +} + +func (h handle) EEUASize() (int, Err) { + return 0, NoCGO +} + +func (h handle) EEUARead(ua []byte) Err { + return NoCGO +} + +func (h handle) EEUAWrite(ua []byte) Err { + return NoCGO +} + +func (h handle) SetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) Err { + return NoCGO +} + +func (h handle) SetUSBParameters(in, out int) Err { + return NoCGO +} + +func (h handle) SetFlowControl() Err { + return NoCGO +} + +func (h handle) SetTimeouts(readMS, writeMS int) Err { + return NoCGO +} + +func (h handle) SetLatencyTimer(delayMS uint8) Err { + return NoCGO +} + +func (h handle) SetBaudRate(hz uint32) Err { + return NoCGO +} + +func (h handle) GetQueueStatus() (uint32, Err) { + return 0, NoCGO +} + +func (h handle) Read(b []byte) (int, Err) { + return 0, NoCGO +} + +func (h handle) Write(b []byte) (int, Err) { + return 0, NoCGO +} + +func (h handle) GetBitMode() (byte, Err) { + return 0, NoCGO +} + +func (h handle) SetBitMode(mask, mode byte) Err { + return NoCGO +} diff --git a/vendor/periph.io/x/d2xx/d2xx_posix_other.go b/vendor/periph.io/x/d2xx/d2xx_posix_other.go new file mode 100644 index 0000000..09a0538 --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx_posix_other.go @@ -0,0 +1,16 @@ +// 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. + +// +build cgo +// +build !darwin,!amd64 +// +build !linux,!amd64 +// +build !linux,!arm +// +build !windows + +package d2xx + +/* +#cgo LDFLAGS: -lftd2xx +*/ +import "C" diff --git a/vendor/periph.io/x/d2xx/d2xx_windows.go b/vendor/periph.io/x/d2xx/d2xx_windows.go new file mode 100644 index 0000000..2c840ce --- /dev/null +++ b/vendor/periph.io/x/d2xx/d2xx_windows.go @@ -0,0 +1,273 @@ +// 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 d2xx + +import ( + "bytes" + "syscall" + "unsafe" +) + +// Available is true if the library is available on this system. +var Available = false + +func version() (uint8, uint8, uint8) { + var v uint32 + if pGetLibraryVersion != nil { + _, _, _ = pGetLibraryVersion.Call(uintptr(unsafe.Pointer(&v))) + } + return uint8(v >> 16), uint8(v >> 8), uint8(v) +} + +func createDeviceInfoList() (int, Err) { + var num uint32 + r1, _, _ := pCreateDeviceInfoList.Call(uintptr(unsafe.Pointer(&num))) + return int(num), Err(r1) +} + +func open(i int) (Handle, Err) { + var h handle + r1, _, _ := pOpen.Call(uintptr(i), uintptr(unsafe.Pointer(&h))) + return h, Err(r1) +} + +func (h handle) Close() Err { + r1, _, _ := pClose.Call(h.toH()) + return Err(r1) +} + +func (h handle) ResetDevice() Err { + r1, _, _ := pResetDevice.Call(h.toH()) + return Err(r1) +} + +func (h handle) GetDeviceInfo() (uint32, uint16, uint16, Err) { + var d uint32 + var id uint32 + if r1, _, _ := pGetDeviceInfo.Call(h.toH(), uintptr(unsafe.Pointer(&d)), uintptr(unsafe.Pointer(&id)), 0, 0, 0); r1 != 0 { + return unknown, 0, 0, Err(r1) + } + return d, uint16(id >> 16), uint16(id), 0 +} + +func (h handle) EEPROMRead(devType uint32, ee *EEPROM) Err { + var manufacturer [64]byte + var manufacturerID [64]byte + var desc [64]byte + var serial [64]byte + // Shortcuts. + m := uintptr(unsafe.Pointer(&manufacturer[0])) + mi := uintptr(unsafe.Pointer(&manufacturerID[0])) + de := uintptr(unsafe.Pointer(&desc[0])) + s := uintptr(unsafe.Pointer(&serial[0])) + + eepromVoid := unsafe.Pointer(&ee.Raw[0]) + hdr := ee.asHeader() + // It MUST be set here. This is not always the case on posix. + hdr.DeviceType = devType + if r1, _, _ := pEEPROMRead.Call(h.toH(), uintptr(eepromVoid), uintptr(len(ee.Raw)), m, mi, de, s); r1 != 0 { + return Err(r1) + } + + ee.Manufacturer = toStr(manufacturer[:]) + ee.ManufacturerID = toStr(manufacturerID[:]) + ee.Desc = toStr(desc[:]) + ee.Serial = toStr(serial[:]) + return 0 +} + +func (h handle) EEPROMProgram(ee *EEPROM) Err { + var cmanu [64]byte + copy(cmanu[:], ee.Manufacturer) + var cmanuID [64]byte + copy(cmanuID[:], ee.ManufacturerID) + var cdesc [64]byte + copy(cdesc[:], ee.Desc) + var cserial [64]byte + copy(cserial[:], ee.Serial) + r1, _, _ := pEEPROMProgram.Call(h.toH(), uintptr(unsafe.Pointer(&ee.Raw[0])), uintptr(len(ee.Raw)), uintptr(unsafe.Pointer(&cmanu[0])), uintptr(unsafe.Pointer(&cmanuID[0])), uintptr(unsafe.Pointer(&cdesc[0])), uintptr(unsafe.Pointer(&cserial[0]))) + return Err(r1) +} + +func (h handle) EraseEE() Err { + r1, _, _ := pEraseEE.Call(h.toH()) + return Err(r1) +} + +func (h handle) WriteEE(offset uint8, value uint16) Err { + r1, _, _ := pWriteEE.Call(h.toH(), uintptr(offset), uintptr(value)) + return Err(r1) +} + +func (h handle) EEUASize() (int, Err) { + var size uint32 + if r1, _, _ := pEEUASize.Call(h.toH(), uintptr(unsafe.Pointer(&size))); r1 != 0 { + return 0, Err(r1) + } + return int(size), 0 +} + +func (h handle) EEUARead(ua []byte) Err { + var size uint32 + if r1, _, _ := pEEUARead.Call(h.toH(), uintptr(unsafe.Pointer(&ua[0])), uintptr(len(ua)), uintptr(unsafe.Pointer(&size))); r1 != 0 { + return Err(r1) + } + if int(size) != len(ua) { + return 6 // FT_INVALID_PARAMETER + } + return 0 +} + +func (h handle) EEUAWrite(ua []byte) Err { + r1, _, _ := pEEUAWrite.Call(h.toH(), uintptr(unsafe.Pointer(&ua[0])), uintptr(len(ua))) + return Err(r1) +} + +func (h handle) SetChars(eventChar byte, eventEn bool, errorChar byte, errorEn bool) Err { + v := uintptr(0) + if eventEn { + v = 1 + } + w := uintptr(0) + if errorEn { + w = 1 + } + r1, _, _ := pSetChars.Call(h.toH(), uintptr(eventChar), v, uintptr(errorChar), w) + return Err(r1) +} + +func (h handle) SetUSBParameters(in, out int) Err { + r1, _, _ := pSetUSBParameters.Call(h.toH(), uintptr(in), uintptr(out)) + return Err(r1) +} + +func (h handle) SetFlowControl() Err { + // FT_FLOW_RTS_CTS + r1, _, _ := pSetFlowControl.Call(h.toH(), 0x0100, 0, 0) + return Err(r1) +} + +func (h handle) SetTimeouts(readMS, writeMS int) Err { + r1, _, _ := pSetTimeouts.Call(h.toH(), uintptr(readMS), uintptr(writeMS)) + return Err(r1) +} + +func (h handle) SetLatencyTimer(delayMS uint8) Err { + r1, _, _ := pSetLatencyTimer.Call(h.toH(), uintptr(delayMS)) + return Err(r1) +} + +func (h handle) SetBaudRate(hz uint32) Err { + r1, _, _ := pSetBaudRate.Call(h.toH(), uintptr(hz)) + return Err(r1) +} + +func (h handle) GetQueueStatus() (uint32, Err) { + var v uint32 + r1, _, _ := pGetQueueStatus.Call(h.toH(), uintptr(unsafe.Pointer(&v))) + return v, Err(r1) +} + +func (h handle) Read(b []byte) (int, Err) { + var bytesRead uint32 + r1, _, _ := pRead.Call(h.toH(), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), uintptr(unsafe.Pointer(&bytesRead))) + return int(bytesRead), Err(r1) +} + +func (h handle) Write(b []byte) (int, Err) { + var bytesSent uint32 + r1, _, _ := pWrite.Call(h.toH(), uintptr(unsafe.Pointer(&b[0])), uintptr(len(b)), uintptr(unsafe.Pointer(&bytesSent))) + return int(bytesSent), Err(r1) +} + +func (h handle) GetBitMode() (byte, Err) { + var s uint8 + r1, _, _ := pGetBitMode.Call(h.toH(), uintptr(unsafe.Pointer(&s))) + return s, Err(r1) +} + +func (h handle) SetBitMode(mask, mode byte) Err { + r1, _, _ := pSetBitMode.Call(h.toH(), uintptr(mask), uintptr(mode)) + return Err(r1) +} + +func (h handle) toH() uintptr { + return uintptr(h) +} + +// + +var ( + pClose *syscall.Proc + pCreateDeviceInfoList *syscall.Proc + pEEPROMRead *syscall.Proc + pEEPROMProgram *syscall.Proc + pEraseEE *syscall.Proc + pWriteEE *syscall.Proc + pEEUASize *syscall.Proc + pEEUARead *syscall.Proc + pEEUAWrite *syscall.Proc + pGetBitMode *syscall.Proc + pGetDeviceInfo *syscall.Proc + pGetLibraryVersion *syscall.Proc + pGetQueueStatus *syscall.Proc + pOpen *syscall.Proc + pRead *syscall.Proc + pResetDevice *syscall.Proc + pSetBaudRate *syscall.Proc + pSetBitMode *syscall.Proc + pSetChars *syscall.Proc + pSetFlowControl *syscall.Proc + pSetLatencyTimer *syscall.Proc + pSetTimeouts *syscall.Proc + pSetUSBParameters *syscall.Proc + pWrite *syscall.Proc +) + +func init() { + if dll, _ := syscall.LoadDLL("ftd2xx.dll"); dll != nil { + // If any function is not found, disable the support. + Available = true + find := func(n string) *syscall.Proc { + s, _ := dll.FindProc(n) + if s == nil { + Available = false + } + return s + } + pClose = find("FT_Close") + pCreateDeviceInfoList = find("FT_CreateDeviceInfoList") + pEEPROMRead = find("FT_EEPROM_Read") + pEEPROMProgram = find("FT_EEPROM_Program") + pEraseEE = find("FT_EraseEE") + pWriteEE = find("FT_WriteEE") + pEEUASize = find("FT_EE_UASize") + pEEUARead = find("FT_EE_UARead") + pEEUAWrite = find("FT_EE_UAWrite") + pGetBitMode = find("FT_GetBitMode") + pGetDeviceInfo = find("FT_GetDeviceInfo") + pGetLibraryVersion = find("FT_GetLibraryVersion") + pGetQueueStatus = find("FT_GetQueueStatus") + pOpen = find("FT_Open") + pRead = find("FT_Read") + pResetDevice = find("FT_ResetDevice") + pSetBaudRate = find("FT_SetBaudRate") + pSetBitMode = find("FT_SetBitMode") + pSetChars = find("FT_SetChars") + pSetFlowControl = find("FT_SetFlowControl") + pSetLatencyTimer = find("FT_SetLatencyTimer") + pSetTimeouts = find("FT_SetTimeouts") + pSetUSBParameters = find("FT_SetUSBParameters") + pWrite = find("FT_Write") + } +} + +func toStr(c []byte) string { + i := bytes.IndexByte(c, 0) + if i != -1 { + return string(c[:i]) + } + return string(c) +} diff --git a/vendor/periph.io/x/d2xx/doc.go b/vendor/periph.io/x/d2xx/doc.go new file mode 100644 index 0000000..12e0c59 --- /dev/null +++ b/vendor/periph.io/x/d2xx/doc.go @@ -0,0 +1,21 @@ +// 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 d2xx is a thin Go wrapper for the Future Technology "D2XX" driver. +// +// This package is not Go idiomatic. You want to use +// https://periph.io/x/host/v3/ftdi instead. +// +// A binary copy of the d2xx driver is included for linux and macOS. They are +// from https://ftdichip.com/drivers/d2xx-drivers/. See third_party/README.md +// for more details. +// +// Configuration +// +// See https://periph.io/device/ftdi/ for more details, and how to configure +// the host to be able to use this driver. +// +// Windows 10 automatically fetches the driver from Windows Update upon +// connecting a FTDI device on the firt time, so no need to download a driver. +package d2xx diff --git a/vendor/periph.io/x/d2xx/eeprom.go b/vendor/periph.io/x/d2xx/eeprom.go new file mode 100644 index 0000000..52a38cc --- /dev/null +++ b/vendor/periph.io/x/d2xx/eeprom.go @@ -0,0 +1,39 @@ +// 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 d2xx + +import ( + "unsafe" +) + +// EEPROM is the unprocessed EEPROM content. +// +// The EEPROM is in 3 parts: the defined struct, the 4 strings and the rest +// which is used as an 'user area'. The size of the user area depends on the +// length of the strings. The user area content is not included in this struct. +type EEPROM struct { + // Raw is the raw EEPROM content. It excludes the strings. + Raw []byte + + // The following condition must be true: len(Manufacturer) + len(Desc) <= 40. + Manufacturer string + ManufacturerID string + Desc string + Serial string +} + +func (e *EEPROM) asHeader() *eepromHeader { + // sizeof(EEPROMHeader) + if len(e.Raw) < 16 { + return nil + } + return (*eepromHeader)(unsafe.Pointer(&e.Raw[0])) +} + +// eepromHeader is the common 16 bytes header. +type eepromHeader struct { + DeviceType uint32 + // The rest is not necessary here so it is skipped. +} diff --git a/vendor/periph.io/x/d2xx/test.sh b/vendor/periph.io/x/d2xx/test.sh new file mode 100644 index 0000000..a491258 --- /dev/null +++ b/vendor/periph.io/x/d2xx/test.sh @@ -0,0 +1,25 @@ +#!/bin/bash +# 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. + +# Builds the package on multiple OSes to confirm it builds fine. +# +# It is recommended to use the -i flag so subsequent runs are much faster. + +set -eu + +cd `dirname $0` + +OPT=$* + +function build { + echo "Testing on $1/$2" + GOOS=$1 GOARCH=$2 go build $OPT +} + +build darwin amd64 +build linux amd64 +build linux arm +build linux 386 +build windows amd64 diff --git a/vendor/periph.io/x/host/v3/.gohci.yml b/vendor/periph.io/x/host/v3/.gohci.yml new file mode 100644 index 0000000..2767055 --- /dev/null +++ b/vendor/periph.io/x/host/v3/.gohci.yml @@ -0,0 +1,433 @@ +# Copyright 2021 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. + +# See https://github.com/periph/gohci +version: 1 +workers: +# BeagleBone Green Wireles by SeedStudio. +# https://beagleboard.org/green-wireless +- name: beaglebone-1860 + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list + - cmd: + - periph-smoketest + - gpio + - -pin1 + - P8_45 + - -pin2 + - P8_46 + +# ODROID-C1+ by HardKernel +# https://www.hardkernel.com/shop/odroid-c1/ +- name: odroid-483d + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list + - cmd: + - periph-smoketest + - odroid-c1 + - cmd: + - periph-smoketest + - i2c-testboard + - cmd: + - periph-smoketest + - onewire-testboard + - cmd: + - periph-smoketest + - spi-testboard + - cmd: + - periph-smoketest + - sysfs-benchmark + - -p + - 97 + - -short + +# Raspberry Pi 3 +- name: raspberrypi-2f34 + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list + - cmd: + - periph-smoketest + - i2c-testboard + - cmd: + - periph-smoketest + - onewire-testboard + - -i2cbus + - 1 + - cmd: + - periph-smoketest + - spi-testboard + - cmd: + - periph-smoketest + - sysfs-benchmark + - -p + - 12 + - -short + - cmd: + - periph-smoketest + - bcm283x-benchmark + - -p + - 12 + - -short + - cmd: + - periph-smoketest + - gpio + - -pin1 + - P1_15 + - -pin2 + - P1_16 + - cmd: + - periph-smoketest + - bcm283x + - -quick + +# Old MacBook Pro on 10.9. +- name: mbp + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list +# - cmd: +# - periph-smoketest +# - ftdi +# - -type +# - ft232r + +# Laptop on Windows 10. +- name: win10 + checks: + - cmd: + - go + - test + - -cover + - -bench=. + - -benchtime=1000ms + - -benchmem + - ./... + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/devices + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../devices + - cmd: + - go + - test + - ./... + dir: ../devices + # Test in advance. + - cmd: + - git + - clone + - --depth + - 1 + - https://github.com/periph/cmd + dir: .. + - cmd: + - go + - get + - periph.io/x/host/v3@${GIT_SHA} + dir: ../cmd + - cmd: + - go + - test + - ./... + dir: ../cmd + # Test commands. + - cmd: + - go + - install + - -v + - ./gpio-list + - ./headers-list + - ./i2c-list + - ./periph-info + - ./periph-smoketest + - ./spi-list + dir: ../cmd + - cmd: + - periph-info + - cmd: + - gpio-list + - -f + - cmd: + - headers-list + - -f + - cmd: + - i2c-list + - cmd: + - spi-list +# - cmd: +# - periph-smoketest +# - ftdi +# - -type +# - ft232h diff --git a/vendor/periph.io/x/host/v3/AUTHORS b/vendor/periph.io/x/host/v3/AUTHORS new file mode 100644 index 0000000..e8ff861 --- /dev/null +++ b/vendor/periph.io/x/host/v3/AUTHORS @@ -0,0 +1,15 @@ +# This is the list of The Periph Authors for copyright purposes. +# +# This does not necessarily list everyone who has contributed code, since in +# some cases, their employer may be the copyright holder. To see the full list +# of contributors, see the revision history in source control. +Cássio Botaro +Fractal Industries, Inc +Google Inc. +Josh Gardiner +Matt Aimonetti +Max Ekman +Rifiniti, Inc +Stephan Sperber +Thorsten von Eicken + diff --git a/vendor/periph.io/x/host/v3/CONTRIBUTING.md b/vendor/periph.io/x/host/v3/CONTRIBUTING.md new file mode 100644 index 0000000..56a90a0 --- /dev/null +++ b/vendor/periph.io/x/host/v3/CONTRIBUTING.md @@ -0,0 +1,4 @@ +# Contributing + +Thanks for contributing to the project! Please look at [the periph contribution +guidelines](https://periph.io/project/contributing/) first. diff --git a/vendor/periph.io/x/host/v3/CONTRIBUTORS b/vendor/periph.io/x/host/v3/CONTRIBUTORS new file mode 100644 index 0000000..2e86a9b --- /dev/null +++ b/vendor/periph.io/x/host/v3/CONTRIBUTORS @@ -0,0 +1,41 @@ +# This is the official list of people who can contribute +# (and typically have contributed) code to the periph repository. +# The AUTHORS file lists the copyright holders; this file +# lists people. For example, Google employees are listed here +# but not in AUTHORS, because Google holds the copyright. +# +# Names should be added to this file only after verifying that +# the individual or the individual's organization has agreed to +# the appropriate Contributor License Agreement, found here: +# +# https://cla.developers.google.com/ +# +# When adding J Random Contributor's name to this file, +# either J's name or J's organization's name should be +# added to the AUTHORS file, depending on whether the +# individual or corporate CLA was used. + +# Names should be added to this file like so: +# Individual's name +# Individual's name +# +# An entry with multiple email addresses specifies that the +# first address should be used in the submit logs and +# that the other addresses should be recognized as the +# same person when interacting with Gerrit. + +# Please keep the list sorted. + +Cássio Botaro +Eugene Dzhurynsky +Hidetoshi Shimokawa +John Maguire +Josh Gardiner +Marc-Antoine Ruel +Matt Aimonetti +Max Ekman +Matias Insaurralde +Seán C McCord +Stephan Sperber +Thorsten von Eicken + diff --git a/vendor/periph.io/x/host/v3/LICENSE b/vendor/periph.io/x/host/v3/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/vendor/periph.io/x/host/v3/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/periph.io/x/host/v3/README.md b/vendor/periph.io/x/host/v3/README.md new file mode 100644 index 0000000..7e2fafe --- /dev/null +++ b/vendor/periph.io/x/host/v3/README.md @@ -0,0 +1,57 @@ +# periph - Peripherals I/O in Go + +Documentation is at https://periph.io + +Join us for a chat on +[gophers.slack.com/messages/periph](https://gophers.slack.com/messages/periph), +get an [invite here](https://invite.slack.golangbridge.org/). + +[![mascot](https://raw.githubusercontent.com/periph/website/master/site/static/img/periph-mascot-280.png)](https://periph.io/) + +[![PkgGoDev](https://pkg.go.dev/badge/periph.io/x/host/v3)](https://pkg.go.dev/periph.io/x/host/v3) +[![Coverage +Status](https://codecov.io/gh/periph/host/graph/badge.svg)](https://codecov.io/gh/periph/host) + + +## Example + +Blink a LED: + +~~~go +package main + +import ( + "time" + "periph.io/x/conn/v3/gpio" + "periph.io/x/host/v3" + "periph.io/x/host/v3/rpi" +) + +func main() { + host.Init() + t := time.NewTicker(500 * time.Millisecond) + for l := gpio.Low; ; l = !l { + rpi.P1_33.Out(l) + <-t.C + } +} +~~~ + +Curious? Look at [supported devices](https://periph.io/device/) for more +examples! + + +## Authors + +`periph` was initiated with ❤️️ and passion by [Marc-Antoine +Ruel](https://github.com/maruel). The full list of contributors is in +[AUTHORS](https://github.com/periph/host/blob/main/AUTHORS) and +[CONTRIBUTORS](https://github.com/periph/host/blob/main/CONTRIBUTORS). + + +## Disclaimer + +This is not an official Google product (experimental or otherwise), it +is just code that happens to be owned by Google. + +This project is not affiliated with the Go project. diff --git a/vendor/periph.io/x/periph/host/allwinner/a20.go b/vendor/periph.io/x/host/v3/allwinner/a20.go similarity index 99% rename from vendor/periph.io/x/periph/host/allwinner/a20.go rename to vendor/periph.io/x/host/v3/allwinner/a20.go index fab6595..8380f7c 100644 --- a/vendor/periph.io/x/periph/host/allwinner/a20.go +++ b/vendor/periph.io/x/host/v3/allwinner/a20.go @@ -10,8 +10,8 @@ package allwinner import ( "strings" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/sysfs" ) // mappingA20 describes the mapping of the A20 processor gpios to their diff --git a/vendor/periph.io/x/periph/host/allwinner/a64.go b/vendor/periph.io/x/host/v3/allwinner/a64.go similarity index 99% rename from vendor/periph.io/x/periph/host/allwinner/a64.go rename to vendor/periph.io/x/host/v3/allwinner/a64.go index 82a97f8..d871332 100644 --- a/vendor/periph.io/x/periph/host/allwinner/a64.go +++ b/vendor/periph.io/x/host/v3/allwinner/a64.go @@ -10,8 +10,8 @@ package allwinner import ( "strings" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/sysfs" ) // A64 specific pins. diff --git a/vendor/periph.io/x/periph/host/allwinner/allwinner_arm.go b/vendor/periph.io/x/host/v3/allwinner/allwinner_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/allwinner/allwinner_arm.go rename to vendor/periph.io/x/host/v3/allwinner/allwinner_arm.go diff --git a/vendor/periph.io/x/periph/host/allwinner/allwinner_arm64.go b/vendor/periph.io/x/host/v3/allwinner/allwinner_arm64.go similarity index 100% rename from vendor/periph.io/x/periph/host/allwinner/allwinner_arm64.go rename to vendor/periph.io/x/host/v3/allwinner/allwinner_arm64.go diff --git a/vendor/periph.io/x/periph/host/allwinner/allwinner_other.go b/vendor/periph.io/x/host/v3/allwinner/allwinner_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/allwinner/allwinner_other.go rename to vendor/periph.io/x/host/v3/allwinner/allwinner_other.go diff --git a/vendor/periph.io/x/periph/host/allwinner/clock.go b/vendor/periph.io/x/host/v3/allwinner/clock.go similarity index 100% rename from vendor/periph.io/x/periph/host/allwinner/clock.go rename to vendor/periph.io/x/host/v3/allwinner/clock.go diff --git a/vendor/periph.io/x/periph/host/allwinner/detect.go b/vendor/periph.io/x/host/v3/allwinner/detect.go similarity index 98% rename from vendor/periph.io/x/periph/host/allwinner/detect.go rename to vendor/periph.io/x/host/v3/allwinner/detect.go index 6235ee0..75f7510 100644 --- a/vendor/periph.io/x/periph/host/allwinner/detect.go +++ b/vendor/periph.io/x/host/v3/allwinner/detect.go @@ -8,7 +8,7 @@ import ( "strings" "sync" - "periph.io/x/periph/host/distro" + "periph.io/x/host/v3/distro" ) // Present detects whether the host CPU is an Allwinner CPU. diff --git a/vendor/periph.io/x/periph/host/allwinner/dma.go b/vendor/periph.io/x/host/v3/allwinner/dma.go similarity index 99% rename from vendor/periph.io/x/periph/host/allwinner/dma.go rename to vendor/periph.io/x/host/v3/allwinner/dma.go index 6a608b8..32751b4 100644 --- a/vendor/periph.io/x/periph/host/allwinner/dma.go +++ b/vendor/periph.io/x/host/v3/allwinner/dma.go @@ -21,8 +21,8 @@ import ( "log" "os" - "periph.io/x/periph" - "periph.io/x/periph/host/pmem" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/host/v3/pmem" ) // dmaMap represents the DMA memory mapped CPU registers. @@ -467,7 +467,7 @@ func (d *driverDMA) Close() error { func init() { if false && isArm { // TODO(maruel): This is intense, wait to be sure it works. - periph.MustRegister(&drvDMA) + driverreg.MustRegister(&drvDMA) } } diff --git a/vendor/periph.io/x/periph/host/allwinner/doc.go b/vendor/periph.io/x/host/v3/allwinner/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/allwinner/doc.go rename to vendor/periph.io/x/host/v3/allwinner/doc.go diff --git a/vendor/periph.io/x/periph/host/allwinner/gpio.go b/vendor/periph.io/x/host/v3/allwinner/gpio.go similarity index 99% rename from vendor/periph.io/x/periph/host/allwinner/gpio.go rename to vendor/periph.io/x/host/v3/allwinner/gpio.go index 19fc898..e01a3a9 100644 --- a/vendor/periph.io/x/periph/host/allwinner/gpio.go +++ b/vendor/periph.io/x/host/v3/allwinner/gpio.go @@ -16,13 +16,13 @@ import ( "strings" "time" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/pmem" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/pmem" + "periph.io/x/host/v3/sysfs" ) // List of all known pins. These global variables can be used directly. @@ -1030,7 +1030,7 @@ func (d *driverGPIO) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drvGPIO) + driverreg.MustRegister(&drvGPIO) } } diff --git a/vendor/periph.io/x/periph/host/allwinner/gpio_pl.go b/vendor/periph.io/x/host/v3/allwinner/gpio_pl.go similarity index 98% rename from vendor/periph.io/x/periph/host/allwinner/gpio_pl.go rename to vendor/periph.io/x/host/v3/allwinner/gpio_pl.go index b53e41b..154555d 100644 --- a/vendor/periph.io/x/periph/host/allwinner/gpio_pl.go +++ b/vendor/periph.io/x/host/v3/allwinner/gpio_pl.go @@ -13,13 +13,13 @@ import ( "strings" "time" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/pmem" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/pmem" + "periph.io/x/host/v3/sysfs" ) // All the pins in the PL group. @@ -551,7 +551,7 @@ func (d *driverGPIOPL) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drvGPIOPL) + driverreg.MustRegister(&drvGPIOPL) } } diff --git a/vendor/periph.io/x/periph/host/allwinner/pwm.go b/vendor/periph.io/x/host/v3/allwinner/pwm.go similarity index 100% rename from vendor/periph.io/x/periph/host/allwinner/pwm.go rename to vendor/periph.io/x/host/v3/allwinner/pwm.go diff --git a/vendor/periph.io/x/periph/host/allwinner/r8.go b/vendor/periph.io/x/host/v3/allwinner/r8.go similarity index 98% rename from vendor/periph.io/x/periph/host/allwinner/r8.go rename to vendor/periph.io/x/host/v3/allwinner/r8.go index 7790763..6d1a9f3 100644 --- a/vendor/periph.io/x/periph/host/allwinner/r8.go +++ b/vendor/periph.io/x/host/v3/allwinner/r8.go @@ -10,8 +10,8 @@ package allwinner import ( "strings" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/sysfs" ) // R8 specific pins. diff --git a/vendor/periph.io/x/periph/host/allwinner/spi.go b/vendor/periph.io/x/host/v3/allwinner/spi.go similarity index 100% rename from vendor/periph.io/x/periph/host/allwinner/spi.go rename to vendor/periph.io/x/host/v3/allwinner/spi.go diff --git a/vendor/periph.io/x/periph/host/allwinner/timer.go b/vendor/periph.io/x/host/v3/allwinner/timer.go similarity index 99% rename from vendor/periph.io/x/periph/host/allwinner/timer.go rename to vendor/periph.io/x/host/v3/allwinner/timer.go index f11f805..22f50a0 100644 --- a/vendor/periph.io/x/periph/host/allwinner/timer.go +++ b/vendor/periph.io/x/host/v3/allwinner/timer.go @@ -7,7 +7,7 @@ package allwinner import ( "time" - "periph.io/x/periph/host/cpu" + "periph.io/x/host/v3/cpu" ) // ReadTime returns the time on a monotonic timer. diff --git a/vendor/periph.io/x/periph/host/am335x/am335x.go b/vendor/periph.io/x/host/v3/am335x/am335x.go similarity index 88% rename from vendor/periph.io/x/periph/host/am335x/am335x.go rename to vendor/periph.io/x/host/v3/am335x/am335x.go index 686ce25..f5a3fa1 100644 --- a/vendor/periph.io/x/periph/host/am335x/am335x.go +++ b/vendor/periph.io/x/host/v3/am335x/am335x.go @@ -8,8 +8,8 @@ import ( "errors" "strings" - "periph.io/x/periph" - "periph.io/x/periph/host/distro" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/host/v3/distro" ) // Present returns true if a TM AM335x processor is detected. @@ -45,7 +45,7 @@ func (d *driver) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drv) + driverreg.MustRegister(&drv) } } diff --git a/vendor/periph.io/x/periph/host/am335x/am335x_arm.go b/vendor/periph.io/x/host/v3/am335x/am335x_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/am335x/am335x_arm.go rename to vendor/periph.io/x/host/v3/am335x/am335x_arm.go diff --git a/vendor/periph.io/x/periph/host/am335x/am335x_other.go b/vendor/periph.io/x/host/v3/am335x/am335x_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/am335x/am335x_other.go rename to vendor/periph.io/x/host/v3/am335x/am335x_other.go diff --git a/vendor/periph.io/x/periph/host/am335x/doc.go b/vendor/periph.io/x/host/v3/am335x/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/am335x/doc.go rename to vendor/periph.io/x/host/v3/am335x/doc.go diff --git a/vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm.go b/vendor/periph.io/x/host/v3/bcm283x/bcm283x_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm.go rename to vendor/periph.io/x/host/v3/bcm283x/bcm283x_arm.go diff --git a/vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm64.go b/vendor/periph.io/x/host/v3/bcm283x/bcm283x_arm64.go similarity index 100% rename from vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm64.go rename to vendor/periph.io/x/host/v3/bcm283x/bcm283x_arm64.go diff --git a/vendor/periph.io/x/periph/host/bcm283x/bcm283x_other.go b/vendor/periph.io/x/host/v3/bcm283x/bcm283x_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/bcm283x/bcm283x_other.go rename to vendor/periph.io/x/host/v3/bcm283x/bcm283x_other.go diff --git a/vendor/periph.io/x/periph/host/bcm283x/clock.go b/vendor/periph.io/x/host/v3/bcm283x/clock.go similarity index 99% rename from vendor/periph.io/x/periph/host/bcm283x/clock.go rename to vendor/periph.io/x/host/v3/bcm283x/clock.go index f1f084c..f9fd546 100644 --- a/vendor/periph.io/x/periph/host/bcm283x/clock.go +++ b/vendor/periph.io/x/host/v3/bcm283x/clock.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "periph.io/x/periph/conn/physic" + "periph.io/x/conn/v3/physic" ) // errClockRegister is returned in a situation where the clock memory is not diff --git a/vendor/periph.io/x/periph/host/bcm283x/dma.go b/vendor/periph.io/x/host/v3/bcm283x/dma.go similarity index 97% rename from vendor/periph.io/x/periph/host/bcm283x/dma.go rename to vendor/periph.io/x/host/v3/bcm283x/dma.go index 5a31b85..980bbcf 100644 --- a/vendor/periph.io/x/periph/host/bcm283x/dma.go +++ b/vendor/periph.io/x/host/v3/bcm283x/dma.go @@ -70,11 +70,11 @@ import ( "strings" "time" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio/gpiostream" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/host/pmem" - "periph.io/x/periph/host/videocore" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio/gpiostream" + "periph.io/x/conn/v3/physic" + "periph.io/x/host/v3/pmem" + "periph.io/x/host/v3/videocore" ) const ( @@ -711,7 +711,7 @@ func dmaWriteStreamPCM(p *Pin, w gpiostream.Stream) error { return err } defer buf.Close() - if err := copyStreamToDMABuf(w, buf.Uint32()); err != nil { + if err = copyStreamToDMABuf(w, buf.Uint32()); err != nil { return err } @@ -845,7 +845,7 @@ func dmaReadStream(p *Pin, b *gpiostream.BitStream) error { if err != nil { return err } - if _, err := setPWMClockSource(); err != nil { + if _, err = setPWMClockSource(); err != nil { return err } @@ -867,7 +867,7 @@ func dmaReadStream(p *Pin, b *gpiostream.BitStream) error { defer pCB.Close() reg := drvGPIO.gpioBaseAddr + 0x34 + uint32Size*uint32(p.number/32) // GPIO Pin Level 0 - if err := cb[0].initBlock(reg, uint32(buf.PhysAddr()), uint32(l), true, false, false, true, dmaPWM); err != nil { + if err = cb[0].initBlock(reg, uint32(buf.PhysAddr()), uint32(l), true, false, false, true, dmaPWM); err != nil { return err } err = runIO(pCB, l <= maxLite) @@ -953,7 +953,7 @@ func dmaWriteStreamEdges(p *Pin, w gpiostream.Stream) error { stride = uint32(skip) for i := 1; i < l; i++ { if v := getBit(bits[i/8], i%8, msb); v != last || stride == maxLite { - if err := cb[index].initBlock(physBit, dest[last], stride*uint32Size, false, true, false, false, dmaPWM); err != nil { + if err = cb[index].initBlock(physBit, dest[last], stride*uint32Size, false, true, false, false, dmaPWM); err != nil { return err } // It is not necessary to use physToUncachedPhys() here. @@ -964,13 +964,12 @@ func dmaWriteStreamEdges(p *Pin, w gpiostream.Stream) error { } stride += uint32(skip) } - if err := cb[index].initBlock(physBit, dest[last], stride*uint32Size, false, true, false, false, dmaPWM); err != nil { + if err = cb[index].initBlock(physBit, dest[last], stride*uint32Size, false, true, false, false, dmaPWM); err != nil { return err } // Start clock before DMA - _, err = setPWMClockSource() - if err != nil { + if _, err = setPWMClockSource(); err != nil { return err } return runIO(buf, true) @@ -1010,13 +1009,12 @@ func dmaWriteStreamDualChannel(p *Pin, w gpiostream.Stream) error { // Needs 64x the memory since each write is 2 full uint32. On the other // hand one could write 32 contiguous pins simultaneously at no cost. mask := uint32(1) << uint(p.number&31) - if err := raster32(w, skip, bufClear.Uint32(), bufSet.Uint32(), mask); err != nil { + if err = raster32(w, skip, bufClear.Uint32(), bufSet.Uint32(), mask); err != nil { return err } // Start clock before DMA start - _, err = setPWMClockSource() - if err != nil { + if _, err = setPWMClockSource(); err != nil { return err } @@ -1253,7 +1251,7 @@ func resetDMA(ch int) error { func init() { if isArm { - periph.MustRegister(&drvDMA) + driverreg.MustRegister(&drvDMA) } } diff --git a/vendor/periph.io/x/periph/host/bcm283x/doc.go b/vendor/periph.io/x/host/v3/bcm283x/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/bcm283x/doc.go rename to vendor/periph.io/x/host/v3/bcm283x/doc.go diff --git a/vendor/periph.io/x/periph/host/bcm283x/gpio.go b/vendor/periph.io/x/host/v3/bcm283x/gpio.go similarity index 99% rename from vendor/periph.io/x/periph/host/bcm283x/gpio.go rename to vendor/periph.io/x/host/v3/bcm283x/gpio.go index 6ee2f17..5919ad0 100644 --- a/vendor/periph.io/x/periph/host/bcm283x/gpio.go +++ b/vendor/periph.io/x/host/v3/bcm283x/gpio.go @@ -12,16 +12,16 @@ import ( "strings" "time" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/gpio/gpiostream" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/distro" - "periph.io/x/periph/host/pmem" - "periph.io/x/periph/host/sysfs" - "periph.io/x/periph/host/videocore" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/gpio/gpiostream" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/distro" + "periph.io/x/host/v3/pmem" + "periph.io/x/host/v3/sysfs" + "periph.io/x/host/v3/videocore" ) // All the pins supported by the CPU. @@ -1429,7 +1429,7 @@ func setSpeed(f physic.Frequency) error { func init() { if isArm { - periph.MustRegister(&drvGPIO) + driverreg.MustRegister(&drvGPIO) } } diff --git a/vendor/periph.io/x/periph/host/bcm283x/pcm.go b/vendor/periph.io/x/host/v3/bcm283x/pcm.go similarity index 99% rename from vendor/periph.io/x/periph/host/bcm283x/pcm.go rename to vendor/periph.io/x/host/v3/bcm283x/pcm.go index 7078de1..8181a1f 100644 --- a/vendor/periph.io/x/periph/host/bcm283x/pcm.go +++ b/vendor/periph.io/x/host/v3/bcm283x/pcm.go @@ -11,7 +11,7 @@ import ( "fmt" "time" - "periph.io/x/periph/conn/physic" + "periph.io/x/conn/v3/physic" ) type pcmCS uint32 diff --git a/vendor/periph.io/x/periph/host/bcm283x/pwm.go b/vendor/periph.io/x/host/v3/bcm283x/pwm.go similarity index 99% rename from vendor/periph.io/x/periph/host/bcm283x/pwm.go rename to vendor/periph.io/x/host/v3/bcm283x/pwm.go index 8426b67..e872128 100644 --- a/vendor/periph.io/x/periph/host/bcm283x/pwm.go +++ b/vendor/periph.io/x/host/v3/bcm283x/pwm.go @@ -9,7 +9,7 @@ import ( "fmt" "time" - "periph.io/x/periph/conn/physic" + "periph.io/x/conn/v3/physic" ) // PWENi is used to enable/disable the corresponding channel. Setting this bit diff --git a/vendor/periph.io/x/periph/host/bcm283x/streams.go b/vendor/periph.io/x/host/v3/bcm283x/streams.go similarity index 98% rename from vendor/periph.io/x/periph/host/bcm283x/streams.go rename to vendor/periph.io/x/host/v3/bcm283x/streams.go index 72807f1..35ae1e9 100644 --- a/vendor/periph.io/x/periph/host/bcm283x/streams.go +++ b/vendor/periph.io/x/host/v3/bcm283x/streams.go @@ -9,7 +9,7 @@ import ( "errors" "fmt" - "periph.io/x/periph/conn/gpio/gpiostream" + "periph.io/x/conn/v3/gpio/gpiostream" ) // uint32ToBitLSBF packs a bit offset found on slice `d` (that is actually diff --git a/vendor/periph.io/x/periph/host/bcm283x/timer.go b/vendor/periph.io/x/host/v3/bcm283x/timer.go similarity index 97% rename from vendor/periph.io/x/periph/host/bcm283x/timer.go rename to vendor/periph.io/x/host/v3/bcm283x/timer.go index 4c6247e..13a4022 100644 --- a/vendor/periph.io/x/periph/host/bcm283x/timer.go +++ b/vendor/periph.io/x/host/v3/bcm283x/timer.go @@ -7,7 +7,7 @@ package bcm283x import ( "time" - "periph.io/x/periph/host/cpu" + "periph.io/x/host/v3/cpu" ) // ReadTime returns the time on a monotonic 1Mhz clock (1µs resolution). diff --git a/vendor/periph.io/x/periph/host/beagle/black/black.go b/vendor/periph.io/x/host/v3/beagle/black/black.go similarity index 95% rename from vendor/periph.io/x/periph/host/beagle/black/black.go rename to vendor/periph.io/x/host/v3/beagle/black/black.go index 1ff0317..8df1858 100644 --- a/vendor/periph.io/x/periph/host/beagle/black/black.go +++ b/vendor/periph.io/x/host/v3/beagle/black/black.go @@ -21,7 +21,7 @@ package black import ( "strings" - "periph.io/x/periph/host/distro" + "periph.io/x/host/v3/distro" ) // Present returns true if the host is a BeagleBone Black or BeagleBone Black diff --git a/vendor/periph.io/x/periph/host/beagle/black/black_arm.go b/vendor/periph.io/x/host/v3/beagle/black/black_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/beagle/black/black_arm.go rename to vendor/periph.io/x/host/v3/beagle/black/black_arm.go diff --git a/vendor/periph.io/x/periph/host/beagle/black/black_other.go b/vendor/periph.io/x/host/v3/beagle/black/black_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/beagle/black/black_other.go rename to vendor/periph.io/x/host/v3/beagle/black/black_other.go diff --git a/vendor/periph.io/x/periph/host/beagle/bone/bone.go b/vendor/periph.io/x/host/v3/beagle/bone/bone.go similarity index 97% rename from vendor/periph.io/x/periph/host/beagle/bone/bone.go rename to vendor/periph.io/x/host/v3/beagle/bone/bone.go index 80410ab..c8929bb 100644 --- a/vendor/periph.io/x/periph/host/beagle/bone/bone.go +++ b/vendor/periph.io/x/host/v3/beagle/bone/bone.go @@ -16,13 +16,13 @@ package bone import ( "errors" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/conn/pin/pinreg" - "periph.io/x/periph/host/beagle/black" - "periph.io/x/periph/host/beagle/green" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/pin" + "periph.io/x/conn/v3/pin/pinreg" + "periph.io/x/host/v3/beagle/black" + "periph.io/x/host/v3/beagle/green" + "periph.io/x/host/v3/sysfs" ) // TODO(maruel): Use specialized am335x or pru implementation once available. @@ -311,7 +311,7 @@ func (d *driver) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drv) + driverreg.MustRegister(&drv) } } diff --git a/vendor/periph.io/x/periph/host/beagle/bone/bone_arm.go b/vendor/periph.io/x/host/v3/beagle/bone/bone_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/beagle/bone/bone_arm.go rename to vendor/periph.io/x/host/v3/beagle/bone/bone_arm.go diff --git a/vendor/periph.io/x/periph/host/beagle/bone/bone_other.go b/vendor/periph.io/x/host/v3/beagle/bone/bone_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/beagle/bone/bone_other.go rename to vendor/periph.io/x/host/v3/beagle/bone/bone_other.go diff --git a/vendor/periph.io/x/periph/host/beagle/green/green.go b/vendor/periph.io/x/host/v3/beagle/green/green.go similarity index 90% rename from vendor/periph.io/x/periph/host/beagle/green/green.go rename to vendor/periph.io/x/host/v3/beagle/green/green.go index bdb6f96..79d18c9 100644 --- a/vendor/periph.io/x/periph/host/beagle/green/green.go +++ b/vendor/periph.io/x/host/v3/beagle/green/green.go @@ -20,12 +20,12 @@ import ( "errors" "strings" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/conn/pin/pinreg" - "periph.io/x/periph/host/distro" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/pin" + "periph.io/x/conn/v3/pin/pinreg" + "periph.io/x/host/v3/distro" + "periph.io/x/host/v3/sysfs" ) // Headers found on BeagleBone Green. @@ -88,7 +88,7 @@ func (d *driver) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drv) + driverreg.MustRegister(&drv) } } diff --git a/vendor/periph.io/x/periph/host/beagle/green/green_arm.go b/vendor/periph.io/x/host/v3/beagle/green/green_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/beagle/green/green_arm.go rename to vendor/periph.io/x/host/v3/beagle/green/green_arm.go diff --git a/vendor/periph.io/x/periph/host/beagle/green/green_other.go b/vendor/periph.io/x/host/v3/beagle/green/green_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/beagle/green/green_other.go rename to vendor/periph.io/x/host/v3/beagle/green/green_other.go diff --git a/vendor/periph.io/x/periph/host/chip/chip.go b/vendor/periph.io/x/host/v3/chip/chip.go similarity index 97% rename from vendor/periph.io/x/periph/host/chip/chip.go rename to vendor/periph.io/x/host/v3/chip/chip.go index 19cd016..62bfbbb 100644 --- a/vendor/periph.io/x/periph/host/chip/chip.go +++ b/vendor/periph.io/x/host/v3/chip/chip.go @@ -13,14 +13,14 @@ import ( "strconv" "strings" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/conn/pin/pinreg" - "periph.io/x/periph/host/allwinner" - "periph.io/x/periph/host/distro" - "periph.io/x/periph/host/fs" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/pin" + "periph.io/x/conn/v3/pin/pinreg" + "periph.io/x/host/v3/allwinner" + "periph.io/x/host/v3/distro" + "periph.io/x/host/v3/fs" ) // C.H.I.P. hardware pins. @@ -351,7 +351,7 @@ func (d *driver) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drv) + driverreg.MustRegister(&drv) } } diff --git a/vendor/periph.io/x/periph/host/chip/chip_arm.go b/vendor/periph.io/x/host/v3/chip/chip_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/chip/chip_arm.go rename to vendor/periph.io/x/host/v3/chip/chip_arm.go diff --git a/vendor/periph.io/x/periph/host/chip/chip_other.go b/vendor/periph.io/x/host/v3/chip/chip_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/chip/chip_other.go rename to vendor/periph.io/x/host/v3/chip/chip_other.go diff --git a/vendor/periph.io/x/periph/host/chip/doc.go b/vendor/periph.io/x/host/v3/chip/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/chip/doc.go rename to vendor/periph.io/x/host/v3/chip/doc.go diff --git a/vendor/periph.io/x/host/v3/codecov.yml b/vendor/periph.io/x/host/v3/codecov.yml new file mode 100644 index 0000000..e1bd436 --- /dev/null +++ b/vendor/periph.io/x/host/v3/codecov.yml @@ -0,0 +1,20 @@ +# Copyright 2020 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. + +# https://docs.codecov.io/docs/codecovyml-reference +# and +# https://docs.codecov.io/docs/coverage-configuration +coverage: + precision: 1 + range: "40...80" + round: nearest + status: + patch: + default: + target: 60% + threshold: 10% + project: + default: + target: 60% + threshold: 10% diff --git a/vendor/periph.io/x/periph/host/cpu/cpu.go b/vendor/periph.io/x/host/v3/cpu/cpu.go similarity index 98% rename from vendor/periph.io/x/periph/host/cpu/cpu.go rename to vendor/periph.io/x/host/v3/cpu/cpu.go index c4e1ffd..6170c0f 100644 --- a/vendor/periph.io/x/periph/host/cpu/cpu.go +++ b/vendor/periph.io/x/host/v3/cpu/cpu.go @@ -13,7 +13,7 @@ import ( "sync" "time" - "periph.io/x/periph/host/fs" + "periph.io/x/host/v3/fs" ) // MaxSpeed returns the processor maximum speed in Hz. diff --git a/vendor/periph.io/x/periph/host/cpu/cpu_linux.go b/vendor/periph.io/x/host/v3/cpu/cpu_linux.go similarity index 100% rename from vendor/periph.io/x/periph/host/cpu/cpu_linux.go rename to vendor/periph.io/x/host/v3/cpu/cpu_linux.go diff --git a/vendor/periph.io/x/periph/host/cpu/cpu_other.go b/vendor/periph.io/x/host/v3/cpu/cpu_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/cpu/cpu_other.go rename to vendor/periph.io/x/host/v3/cpu/cpu_other.go diff --git a/vendor/periph.io/x/periph/host/cpu/doc.go b/vendor/periph.io/x/host/v3/cpu/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/cpu/doc.go rename to vendor/periph.io/x/host/v3/cpu/doc.go diff --git a/vendor/periph.io/x/periph/host/distro/devtree.go b/vendor/periph.io/x/host/v3/distro/devtree.go similarity index 100% rename from vendor/periph.io/x/periph/host/distro/devtree.go rename to vendor/periph.io/x/host/v3/distro/devtree.go diff --git a/vendor/periph.io/x/periph/host/distro/distro.go b/vendor/periph.io/x/host/v3/distro/distro.go similarity index 100% rename from vendor/periph.io/x/periph/host/distro/distro.go rename to vendor/periph.io/x/host/v3/distro/distro.go diff --git a/vendor/periph.io/x/periph/host/distro/distro_arm.go b/vendor/periph.io/x/host/v3/distro/distro_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/distro/distro_arm.go rename to vendor/periph.io/x/host/v3/distro/distro_arm.go diff --git a/vendor/periph.io/x/periph/host/distro/distro_arm64.go b/vendor/periph.io/x/host/v3/distro/distro_arm64.go similarity index 100% rename from vendor/periph.io/x/periph/host/distro/distro_arm64.go rename to vendor/periph.io/x/host/v3/distro/distro_arm64.go diff --git a/vendor/periph.io/x/periph/host/distro/distro_linux.go b/vendor/periph.io/x/host/v3/distro/distro_linux.go similarity index 100% rename from vendor/periph.io/x/periph/host/distro/distro_linux.go rename to vendor/periph.io/x/host/v3/distro/distro_linux.go diff --git a/vendor/periph.io/x/periph/host/distro/distro_nonarm.go b/vendor/periph.io/x/host/v3/distro/distro_nonarm.go similarity index 100% rename from vendor/periph.io/x/periph/host/distro/distro_nonarm.go rename to vendor/periph.io/x/host/v3/distro/distro_nonarm.go diff --git a/vendor/periph.io/x/periph/host/distro/distro_nonlinux.go b/vendor/periph.io/x/host/v3/distro/distro_nonlinux.go similarity index 100% rename from vendor/periph.io/x/periph/host/distro/distro_nonlinux.go rename to vendor/periph.io/x/host/v3/distro/distro_nonlinux.go diff --git a/vendor/periph.io/x/periph/host/doc.go b/vendor/periph.io/x/host/v3/doc.go similarity index 64% rename from vendor/periph.io/x/periph/host/doc.go rename to vendor/periph.io/x/host/v3/doc.go index 500ad4b..ee1b9af 100644 --- a/vendor/periph.io/x/periph/host/doc.go +++ b/vendor/periph.io/x/host/v3/doc.go @@ -4,7 +4,7 @@ // Package host defines the host itself. // -// Is it now superseded by https://periph.io/x/host/v3 (or later). +// The host is the machine where this code is running. // -// See https://periph.io/news/2020/a_new_start/ for more details. +// Subpackages contain the drivers that are loaded automatically. package host diff --git a/vendor/periph.io/x/periph/host/fs/fs.go b/vendor/periph.io/x/host/v3/fs/fs.go similarity index 100% rename from vendor/periph.io/x/periph/host/fs/fs.go rename to vendor/periph.io/x/host/v3/fs/fs.go diff --git a/vendor/periph.io/x/periph/host/fs/fs_linux.go b/vendor/periph.io/x/host/v3/fs/fs_linux.go similarity index 100% rename from vendor/periph.io/x/periph/host/fs/fs_linux.go rename to vendor/periph.io/x/host/v3/fs/fs_linux.go diff --git a/vendor/periph.io/x/periph/host/fs/fs_other.go b/vendor/periph.io/x/host/v3/fs/fs_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/fs/fs_other.go rename to vendor/periph.io/x/host/v3/fs/fs_other.go diff --git a/vendor/periph.io/x/periph/host/fs/ioctl.go b/vendor/periph.io/x/host/v3/fs/ioctl.go similarity index 100% rename from vendor/periph.io/x/periph/host/fs/ioctl.go rename to vendor/periph.io/x/host/v3/fs/ioctl.go diff --git a/vendor/periph.io/x/periph/host/fs/ioctl_mips_like.go b/vendor/periph.io/x/host/v3/fs/ioctl_mips_like.go similarity index 100% rename from vendor/periph.io/x/periph/host/fs/ioctl_mips_like.go rename to vendor/periph.io/x/host/v3/fs/ioctl_mips_like.go diff --git a/vendor/periph.io/x/periph/host/fs/ioctl_other.go b/vendor/periph.io/x/host/v3/fs/ioctl_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/fs/ioctl_other.go rename to vendor/periph.io/x/host/v3/fs/ioctl_other.go diff --git a/vendor/periph.io/x/host/v3/ftdi/dev.go b/vendor/periph.io/x/host/v3/ftdi/dev.go new file mode 100644 index 0000000..88e1d70 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/dev.go @@ -0,0 +1,878 @@ +// 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 ftdi + +import ( + "context" + "errors" + "strconv" + "sync" + + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/i2c" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/spi" +) + +// Info is the information gathered about the connected FTDI device. +// +// The data is gathered from the USB descriptor. +type Info struct { + // Opened is true if the device was successfully opened. + Opened bool + // Type is the FTDI device type. + // + // The value can be "FT232H", "FT232R", etc. + // + // An empty string means the type is unknown. + Type string + // VenID is the vendor ID from the USB descriptor information. It is expected + // to be 0x0403 (FTDI). + VenID uint16 + // DevID is the product ID from the USB descriptor information. It is + // expected to be one of 0x6001, 0x6006, 0x6010, 0x6014. + DevID uint16 +} + +// Dev represents one FTDI device. +// +// There can be multiple FTDI devices connected to a host. +// +// The device may also export one or multiple of I²C, SPI buses. You need to +// either cast into the right hardware, but more simply use the i2creg / spireg +// bus/port registries. +type Dev interface { + // conn.Resource + String() string + Halt() error + + // Info returns information about an opened device. + Info(i *Info) + + // Header returns the GPIO pins exposed on the chip. + Header() []gpio.PinIO + + // SetSpeed sets the base clock for all I/O transactions. + // + // The device defaults to its fastest speed. + SetSpeed(f physic.Frequency) error + + // EEPROM returns the EEPROM content. + EEPROM(ee *EEPROM) error + // WriteEEPROM updates the EEPROM. Must be used carefully. + WriteEEPROM(ee *EEPROM) error + // EraseEEPROM erases the EEPROM. Must be used carefully. + EraseEEPROM() error + // UserArea reads and return the EEPROM part that can be used to stored user + // defined values. + UserArea() ([]byte, error) + // WriteUserArea updates the user area in the EEPROM. + // + // If the length of ua is less than the available space, is it zero extended. + WriteUserArea(ua []byte) error +} + +// broken represents a device that couldn't be opened correctly. +// +// It returns an error message to help the user diagnose issues. +type broken struct { + index int + err error + name string +} + +func (b *broken) String() string { + return b.name +} + +func (b *broken) Halt() error { + return nil +} + +func (b *broken) Info(i *Info) { + i.Opened = false +} + +func (b *broken) Header() []gpio.PinIO { + return nil +} + +func (b *broken) SetSpeed(f physic.Frequency) error { + return b.err +} + +func (b *broken) EEPROM(ee *EEPROM) error { + return b.err +} + +func (b *broken) WriteEEPROM(ee *EEPROM) error { + return b.err +} + +func (b *broken) EraseEEPROM() error { + return b.err +} + +func (b *broken) UserArea() ([]byte, error) { + return nil, b.err +} + +func (b *broken) WriteUserArea(ua []byte) error { + return b.err +} + +// generic represents a generic FTDI device. +// +// It is used for the models that this package doesn't fully support yet. +type generic struct { + // Immutable after initialization. + index int + h *handle + name string +} + +func (f *generic) String() string { + return f.name +} + +// Halt implements conn.Resource. +// +// This halts all operations going through this device. +func (f *generic) Halt() error { + return f.h.Reset() +} + +// Info returns information about an opened device. +func (f *generic) Info(i *Info) { + i.Opened = true + i.Type = f.h.t.String() + i.VenID = f.h.venID + i.DevID = f.h.devID +} + +// Header returns the GPIO pins exposed on the chip. +func (f *generic) Header() []gpio.PinIO { + return nil +} + +func (f *generic) SetSpeed(freq physic.Frequency) error { + // TODO(maruel): Doc says the actual speed is 16x, confirm. + return f.h.SetBaudRate(freq) +} + +func (f *generic) EEPROM(ee *EEPROM) error { + return f.h.ReadEEPROM(ee) + /* + if f.ee.Raw == nil { + if err := f.h.readEEPROM(&f.ee); err != nil { + return nil + } + if f.ee.Raw == nil { + // It's a fresh new device. Devices bought via Adafruit already have + // their EEPROM programmed with Adafruit branding but devices sold by + // CJMCU are not. Since d2xxGetDeviceInfo() above succeeded, we know the + // device type via the USB descriptor, which is sufficient to load the + // driver, which permits to program the EEPROM to "bootstrap" it. + f.ee.Raw = []byte{} + } + } + *ee = f.ee + return nil + */ +} + +func (f *generic) WriteEEPROM(ee *EEPROM) error { + // TODO(maruel): Compare with the cached EEPROM, and only update the + // different values if needed so reduce the EEPROM wear. + // f.h.h.d2xxWriteEE() + return f.h.WriteEEPROM(ee) +} + +func (f *generic) EraseEEPROM() error { + return f.h.EraseEEPROM() +} + +func (f *generic) UserArea() ([]byte, error) { + return f.h.ReadUA() +} + +func (f *generic) WriteUserArea(ua []byte) error { + return f.h.WriteUA(ua) +} + +// + +func newFT232H(g generic) (*FT232H, error) { + f := &FT232H{ + generic: g, + cbus: gpiosMPSSE{h: g.h, cbus: true}, + dbus: gpiosMPSSE{h: g.h}, + c8: invalidPin{num: 16, n: g.name + ".C8"}, // , dp: gpio.PullUp + c9: invalidPin{num: 17, n: g.name + ".C9"}, // , dp: gpio.PullUp + } + f.cbus.init(f.name) + f.dbus.init(f.name) + + for i := range f.dbus.pins { + f.hdr[i] = &f.dbus.pins[i] + } + for i := range f.cbus.pins { + f.hdr[i+8] = &f.cbus.pins[i] + } + // TODO(maruel): C8 and C9 can be used when their mux in the EEPROM is set to + // ft232hCBusIOMode. + f.hdr[16] = &f.c8 + f.hdr[17] = &f.c9 + f.D0 = f.hdr[0] + f.D1 = f.hdr[1] + f.D2 = f.hdr[2] + f.D3 = f.hdr[3] + f.D4 = f.hdr[4] + f.D5 = f.hdr[5] + f.D6 = f.hdr[6] + f.D7 = f.hdr[7] + f.C0 = f.hdr[8] + f.C1 = f.hdr[9] + f.C2 = f.hdr[10] + f.C3 = f.hdr[11] + f.C4 = f.hdr[12] + f.C5 = f.hdr[13] + f.C6 = f.hdr[14] + f.C7 = f.hdr[15] + f.C8 = f.hdr[16] + f.C9 = f.hdr[17] + + // This function forces all pins as inputs. + if err := f.h.InitMPSSE(); err != nil { + return nil, err + } + f.s.c.f = f + f.i.f = f + return f, nil +} + +// FT232H represents a FT232H device. +// +// It implements Dev. +// +// The FT232H has 1024 bytes output buffer and 1024 bytes input buffer. It +// supports 512 bytes USB packets. +// +// The device can be used in a few different modes, two modes are supported: +// +// - D0~D3 as a serial protocol (MPSEE), supporting I²C and SPI (and eventually +// UART), In this mode, D4~D7 and C0~C7 can be used as synchronized GPIO. +// +// - D0~D7 as a synchronous 8 bits bit-bang port. In this mode, only a few pins +// on CBus are usable in slow mode. +// +// Each group of pins D0~D7 and C0~C7 can be changed at once in one pass via +// DBus() or CBus(). +// +// This enables usage as an 8 bit parallel port. +// +// Pins C8 and C9 can only be used in 'slow' mode via EEPROM and are currently +// not implemented. +// +// Datasheet +// +// http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf +type FT232H struct { + generic + + D0 gpio.PinIO // Clock output + D1 gpio.PinIO // Data out + D2 gpio.PinIO // Data in + D3 gpio.PinIO // Chip select + D4 gpio.PinIO + D5 gpio.PinIO + D6 gpio.PinIO + D7 gpio.PinIO + C0 gpio.PinIO + C1 gpio.PinIO + C2 gpio.PinIO + C3 gpio.PinIO + C4 gpio.PinIO + C5 gpio.PinIO + C6 gpio.PinIO + C7 gpio.PinIO + C8 gpio.PinIO // Not implemented + C9 gpio.PinIO // Not implemented + + hdr [18]gpio.PinIO + cbus gpiosMPSSE + dbus gpiosMPSSE + c8 invalidPin // gpio.PullUp + c9 invalidPin // gpio.PullUp + + mu sync.Mutex + usingI2C bool + usingSPI bool + i i2cBus + s spiMPSEEPort + // TODO(maruel): Technically speaking, a SPI port could be hacked up too in + // sync bit-bang but there's less point when MPSEE is available. +} + +// Header returns the GPIO pins exposed on the chip. +func (f *FT232H) Header() []gpio.PinIO { + out := make([]gpio.PinIO, len(f.hdr)) + copy(out, f.hdr[:]) + return out +} + +func (f *FT232H) SetSpeed(freq physic.Frequency) error { + // TODO(maruel): When using MPSEE, use the MPSEE command. If using sync + // bit-bang, use SetBaudRate(). + + // TODO(maruel): Doc says the actual speed is 16x, confirm. + return f.h.SetBaudRate(freq) +} + +// CBus sets the values of C0 to C7 in the specified direction and value. +// +// 0 direction means input, 1 means output. +func (f *FT232H) CBus(direction, value byte) error { + return f.h.MPSSECBus(direction, value) +} + +// DBus sets the values of D0 to d7 in the specified direction and value. +// +// 0 direction means input, 1 means output. +// +// This function must be used to set Clock idle level. +func (f *FT232H) DBus(direction, value byte) error { + return f.h.MPSSEDBus(direction, value) +} + +// CBusRead reads the values of C0 to C7. +func (f *FT232H) CBusRead() (byte, error) { + return f.h.MPSSECBusRead() +} + +// DBusRead reads the values of D0 to D7. +func (f *FT232H) DBusRead() (byte, error) { + return f.h.MPSSEDBusRead() +} + +// I2C returns an I²C bus over the AD bus. +// +// pull can be either gpio.PullUp or gpio.Float. The recommended pull up +// resistors are 10kΩ for 100kHz and 2kΩ for 400kHz when using Float. The +// GPIO's pull up is 75kΩ, which may require using a lower speed for signal +// reliability. Optimal pull up resistor calculation depends on the capacitance. +// +// It uses D0, D1 and D2. +// +// D0 is SCL. It must to be pulled up externally. +// +// D1 and D2 are used for SDA. D1 is the output using open drain, D2 is the +// input. D1 and D2 must be wired together and must be pulled up externally. +// +// It is recommended to set the mode to ‘245 FIFO’ in the EEPROM of the FT232H. +// +// The FIFO mode is recommended because it allows the ADbus lines to start as +// tristate. If the chip starts in the default UART mode, then the ADbus lines +// will be in the default UART idle states until the application opens the port +// and configures it as MPSSE. Care should also be taken that the RD# input on +// ACBUS is not asserted in this initial state as this can cause the FIFO lines +// to drive out. +func (f *FT232H) I2C(pull gpio.Pull) (i2c.BusCloser, error) { + if pull != gpio.PullUp && pull != gpio.Float { + return nil, errors.New("d2xx: I²C pull can only be PullUp or Float") + } + f.mu.Lock() + defer f.mu.Unlock() + if f.usingI2C { + return nil, errors.New("d2xx: already using I²C") + } + if f.usingSPI { + return nil, errors.New("d2xx: already using SPI") + } + if err := f.i.setupI2C(pull == gpio.PullUp); err != nil { + _ = f.i.stopI2C() + return nil, err + } + return &f.i, nil +} + +// SPI returns a SPI port over the AD bus. +// +// It uses D0, D1, D2 and D3. D0 is the clock, D1 the output (MOSI), D2 is the +// input (MISO) and D3 is CS line. +func (f *FT232H) SPI() (spi.PortCloser, error) { + f.mu.Lock() + defer f.mu.Unlock() + if f.usingI2C { + return nil, errors.New("d2xx: already using I²C") + } + if f.usingSPI { + return nil, errors.New("d2xx: already using SPI") + } + // Don't mark it as being used yet. It only become used once Connect() is + // called. + return &f.s, nil +} + +// + +func newFT232R(g generic) (*FT232R, error) { + f := &FT232R{ + generic: g, + dbus: [...]dbusPinSync{{num: 0}, {num: 1}, {num: 2}, {num: 3}, {num: 4}, {num: 5}, {num: 6}, {num: 7}}, + cbus: [...]cbusPin{{num: 8, p: gpio.PullUp}, {num: 9, p: gpio.PullUp}, {num: 10, p: gpio.PullUp}, {num: 11, p: gpio.Float}}, + } + // Use the UART names, as this is how all FT232R boards are marked. + dnames := [...]string{"TX", "RX", "RTS", "CTS", "DTR", "DSR", "DCD", "RI"} + for i := range f.dbus { + f.dbus[i].n = f.name + "." + dnames[i] + f.dbus[i].bus = f + f.hdr[i] = &f.dbus[i] + } + for i := range f.cbus { + f.cbus[i].n = f.name + ".C" + strconv.Itoa(i) + f.cbus[i].bus = f + f.hdr[i+8] = &f.cbus[i] + } + f.D0 = f.hdr[0] + f.D1 = f.hdr[1] + f.D2 = f.hdr[2] + f.D3 = f.hdr[3] + f.D4 = f.hdr[4] + f.D5 = f.hdr[5] + f.D6 = f.hdr[6] + f.D7 = f.hdr[7] + f.TX = f.hdr[0] + f.RX = f.hdr[1] + f.RTS = f.hdr[2] + f.CTS = f.hdr[3] + f.DTR = f.hdr[4] + f.DSR = f.hdr[5] + f.DCD = f.hdr[6] + f.RI = f.hdr[7] + f.C0 = f.hdr[8] + f.C1 = f.hdr[9] + f.C2 = f.hdr[10] + f.C3 = f.hdr[11] + + // Default to 3MHz. + if err := f.h.SetBaudRate(3 * physic.MegaHertz); err != nil { + return nil, err + } + + // Set all CBus pins as input. + if err := f.h.SetBitMode(0, bitModeCbusBitbang); err != nil { + return nil, err + } + // And read their value. + // TODO(maruel): Sadly this is impossible to know which pin is input or + // output, but we could try to guess, as the call above may generate noise on + // the line which could interfere with the device connected. + var err error + if f.cbusnibble, err = f.h.GetBitMode(); err != nil { + return nil, err + } + // Set all DBus as asynchronous bitbang, everything as input. + if err := f.h.SetBitMode(0, bitModeAsyncBitbang); err != nil { + return nil, err + } + // And read their value. + var b [1]byte + if _, err := f.h.ReadAll(context.Background(), b[:]); err != nil { + return nil, err + } + f.dvalue = b[0] + f.s.c.f = f + return f, nil +} + +// FT232R represents a FT232RL/FT232RQ device. +// +// It implements Dev. +// +// Not all pins may be physically connected on the header! +// +// Adafruit's version only has the following pins connected: RX, TX, RTS and +// CTS. +// +// SparkFun's version exports all pins *except* (inexplicably) the CBus ones. +// +// The FT232R has 128 bytes output buffer and 256 bytes input buffer. +// +// Pin C4 can only be used in 'slow' mode via EEPROM and is currently not +// implemented. +// +// Datasheet +// +// http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf +type FT232R struct { + generic + + // Pin and their alias to the Dn pins for user convenience. Each pair points + // to the exact same pin. + D0, TX gpio.PinIO // Transmit; SPI_MOSI + D1, RX gpio.PinIO // Receive; SPI_MISO + D2, RTS gpio.PinIO // Request To Send Control Output / Handshake signal; SPI_CLK + D3, CTS gpio.PinIO // Clear to Send Control input / Handshake signal; SPI_CS + D4, DTR gpio.PinIO // Data Terminal Ready Control Output / Handshake signal + D5, DSR gpio.PinIO // Data Set Ready Control Input / Handshake signal + D6, DCD gpio.PinIO // Data Carrier Detect Control input + D7, RI gpio.PinIO // Ring Indicator Control Input. When remote wake up is enabled in the internal EEPROM taking RI# low can be used to resume the PC USB host controller from suspend. + + // The CBus pins are slower to use, but can drive an high load, like a LED. + C0 gpio.PinIO + C1 gpio.PinIO + C2 gpio.PinIO + C3 gpio.PinIO + + dbus [8]dbusPinSync + cbus [4]cbusPin + hdr [12]gpio.PinIO + + // Mutable. + mu sync.Mutex + usingSPI bool + usingCBus bool + s spiSyncPort + dmask uint8 // 0 input, 1 output + dvalue uint8 + cbusnibble uint8 // upper nibble is I/O control, lower nibble is values. +} + +// Header returns the GPIO pins exposed on the chip. +func (f *FT232R) Header() []gpio.PinIO { + out := make([]gpio.PinIO, len(f.hdr)) + copy(out, f.hdr[:]) + return out +} + +// SetDBusMask sets all D0~D7 input or output mode at once. +// +// mask is the input/output pins to use. A bit value of 0 sets the +// corresponding pin to an input, a bit value of 1 sets the corresponding pin +// to an output. +// +// It should be called before calling Tx(). +func (f *FT232R) SetDBusMask(mask uint8) error { + f.mu.Lock() + defer f.mu.Unlock() + if f.usingSPI { + return errors.New("d2xx: already using SPI") + } + return f.setDBusMaskLocked(mask) +} + +// Tx does synchronized read-then-write on all the D0~D7 GPIOs. +// +// SetSpeed() determines the pace at which the I/O is done. +// +// SetDBusMask() determines which bits are interpreted in the w and r byte +// slice. w has its significant value masked by 'mask' and r has its +// significant value masked by '^mask'. +// +// Input sample is done *before* updating outputs. So r[0] is sampled before +// w[0] is used. The last w byte should be duplicated if an addition read is +// desired. +// +// On the Adafruit cable, only the first 4 bits D0(TX), D1(RX), D2(RTS) and +// D3(CTS) are connected. This is just enough to create a full duplex SPI bus! +func (f *FT232R) Tx(w, r []byte) error { + if len(w) != 0 { + if len(r) != 0 && len(w) != len(r) { + return errors.New("d2xx: length of buffer w and r must match") + } + } else if len(r) == 0 { + return errors.New("d2xx: at least one of w or r must be passed") + } + f.mu.Lock() + defer f.mu.Unlock() + if f.usingSPI { + return errors.New("d2xx: already using SPI") + } + return f.txLocked(w, r) +} + +// SPI returns a SPI port over the first 4 pins. +// +// It uses D0(TX), D1(RX), D2(RTS) and D3(CTS). D2(RTS) is the clock, D0(TX) +// the output (MOSI), D1(RX) is the input (MISO) and D3(CTS) is CS line. +func (f *FT232R) SPI() (spi.PortCloser, error) { + f.mu.Lock() + defer f.mu.Unlock() + if f.usingSPI { + return nil, errors.New("d2xx: already using SPI") + } + // Don't mark it as being used yet. It only become used once Connect() is + // called. + return &f.s, nil +} + +// setDBusMaskLocked is the locked version of SetDBusMask. +func (f *FT232R) setDBusMaskLocked(mask uint8) error { + if mask != f.dmask { + if err := f.h.SetBitMode(mask, bitModeAsyncBitbang); err != nil { + return err + } + f.dmask = mask + } + return nil +} + +func (f *FT232R) txLocked(w, r []byte) error { + // Investigate FT232R clock issue: + // http://developer.intra2net.com/mailarchive/html/libftdi/2010/msg00240.html + + // The FT232R has 128 bytes TX buffer and 256 bytes RX buffer. Chunk into 64 + // bytes chunks. That's half the buffer size of the TX buffer and permits + // pipelining and removes the risk of buffer overrun. This is important + // otherwise there's huge gaps due to the USB transmit overhead. + // TODO(maruel): Determine what's optimal via experimentation. + chunk := 64 + var scratch [128]byte + if len(w) == 0 { + // Read only. + for i := range scratch { + scratch[i] = f.dvalue + } + for len(r) != 0 { + // TODO(maruel): Optimize. + c := len(r) + if c > chunk { + c = chunk + } + if _, err := f.h.Write(scratch[:c]); err != nil { + return err + } + if _, err := f.h.ReadAll(context.Background(), r[:c]); err != nil { + return err + } + r = r[c:] + } + } else if len(r) == 0 { + // Write only. + // The first write is 128 bytes to fill the buffer. + chunk = 128 + for len(w) != 0 { + c := len(w) + if c > chunk { + c = chunk + } + if _, err := f.h.Write(w[:c]); err != nil { + return err + } + w = w[c:] + chunk = 64 + } + /* + // Let the USB drive pace it. + if _, err := f.h.Write(w); err != nil { + return err + } + */ + } else { + // R/W. + // Always write one 'w' ahead. + // The first write is 128 bytes to fill the buffer. + chunk = 128 + cw := len(w) + if cw > chunk { + cw = chunk + } + if _, err := f.h.Write(w[:cw]); err != nil { + return err + } + w = w[cw:] + chunk = 64 + for len(r) != 0 { + // Read then write. + cr := len(r) + if cr > chunk { + cr = chunk + } + if _, err := f.h.ReadAll(context.Background(), r[:cr]); err != nil { + return err + } + r = r[cr:] + + cw = len(w) + if cw > chunk { + cw = chunk + } + if cw != 0 { + if _, err := f.h.Write(w[:cw]); err != nil { + return err + } + w = w[cw:] + } + } + } + return nil +} + +// dbusSyncGPIOFunc implements dbusSync. It returns the function of a GPIO +// pin. +func (f *FT232R) dbusSyncGPIOFunc(n int) string { + f.mu.Lock() + defer f.mu.Unlock() + if f.usingSPI { + switch n { + case 0: + return "SPI_MOSI" // TX + case 1: + return "SPI_MISO" // RX + case 2: + return "SPI_CLK" // RTS + case 3: + return "SPI_CS" // CTS + } + } + mask := uint8(1 << uint(n)) + if f.dmask&mask != 0 { + return "Out/" + gpio.Level(f.dvalue&mask != 0).String() + } + return "In/" + f.dbusSyncReadLocked(n).String() +} + +// dbusSyncGPIOIn implements dbusSync. +func (f *FT232R) dbusSyncGPIOIn(n int) error { + f.mu.Lock() + defer f.mu.Unlock() + // TODO(maruel): if f.usingSPI && n < 4. + mask := uint8(1 << uint(n)) + if f.dmask&mask == 0 { + // Already input. + return nil + } + v := f.dmask &^ mask + if err := f.h.SetBitMode(v, bitModeAsyncBitbang); err != nil { + return err + } + f.dmask = v + return nil +} + +// dbusSyncGPIORead implements dbusSync. +func (f *FT232R) dbusSyncGPIORead(n int) gpio.Level { + f.mu.Lock() + defer f.mu.Unlock() + return f.dbusSyncReadLocked(n) +} + +func (f *FT232R) dbusSyncReadLocked(n int) gpio.Level { + // In synchronous mode, to read we must write first to for a sample. + b := [1]byte{f.dvalue} + if _, err := f.h.Write(b[:]); err != nil { + return gpio.Low + } + mask := uint8(1 << uint(n)) + if _, err := f.h.ReadAll(context.Background(), b[:]); err != nil { + return gpio.Low + } + f.dvalue = b[0] + return f.dvalue&mask != 0 +} + +// dbusSyncGPIOOut implements dbusSync. +func (f *FT232R) dbusSyncGPIOOut(n int, l gpio.Level) error { + f.mu.Lock() + defer f.mu.Unlock() + mask := uint8(1 << uint(n)) + if f.dmask&mask != 1 { + // Was input. + v := f.dmask | mask + if err := f.h.SetBitMode(v, bitModeAsyncBitbang); err != nil { + return err + } + f.dmask = v + } + return f.dbusSyncGPIOOutLocked(n, l) +} + +func (f *FT232R) dbusSyncGPIOOutLocked(n int, l gpio.Level) error { + b := [1]byte{f.dvalue} + if _, err := f.h.Write(b[:]); err != nil { + return err + } + f.dvalue = b[0] + // In synchronous mode, we must read after writing to flush the buffer. + if _, err := f.h.Write(b[:]); err != nil { + return err + } + return nil +} + +// cBusGPIOFunc implements cBusGPIO. +func (f *FT232R) cBusGPIOFunc(n int) string { + f.mu.Lock() + defer f.mu.Unlock() + fmask := uint8(0x10 << uint(n)) + vmask := uint8(1 << uint(n)) + if f.cbusnibble&fmask != 0 { + return "Out/" + gpio.Level(f.cbusnibble&vmask != 0).String() + } + return "In/" + f.cBusReadLocked(n).String() +} + +// cBusGPIOIn implements cBusGPIO. +func (f *FT232R) cBusGPIOIn(n int) error { + f.mu.Lock() + defer f.mu.Unlock() + fmask := uint8(0x10 << uint(n)) + if f.cbusnibble&fmask == 0 { + // Already input. + return nil + } + v := f.cbusnibble &^ fmask + if err := f.h.SetBitMode(v, bitModeCbusBitbang); err != nil { + return err + } + f.cbusnibble = v + return nil +} + +// cBusGPIORead implements cBusGPIO. +func (f *FT232R) cBusGPIORead(n int) gpio.Level { + f.mu.Lock() + defer f.mu.Unlock() + return f.cBusReadLocked(n) +} + +func (f *FT232R) cBusReadLocked(n int) gpio.Level { + v, err := f.h.GetBitMode() + if err != nil { + return gpio.Low + } + f.cbusnibble = v + vmask := uint8(1 << uint(n)) + return f.cbusnibble&vmask != 0 +} + +// cBusGPIOOut implements cBusGPIO. +func (f *FT232R) cBusGPIOOut(n int, l gpio.Level) error { + f.mu.Lock() + defer f.mu.Unlock() + fmask := uint8(0x10 << uint(n)) + vmask := uint8(1 << uint(n)) + v := f.cbusnibble | fmask + if l { + v |= vmask + } else { + v &^= vmask + } + if f.cbusnibble == v { + // Was already in the right mode. + return nil + } + if err := f.h.SetBitMode(v, bitModeCbusBitbang); err != nil { + return err + } + f.cbusnibble = v + return nil +} + +// + +var _ conn.Resource = Dev(nil) diff --git a/vendor/periph.io/x/host/v3/ftdi/doc.go b/vendor/periph.io/x/host/v3/ftdi/doc.go new file mode 100644 index 0000000..631f266 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/doc.go @@ -0,0 +1,20 @@ +// 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 ftdi implements support for popular FTDI devices. +// +// The supported devices (FT232h/FT232r) implement support for various +// protocols like the GPIO, I²C, SPI, UART, JTAG. +// +// More details +// +// See https://periph.io/device/ftdi/ for more details, and how to configure +// the host to be able to use this driver. +// +// Datasheets +// +// http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf +// +// http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf +package ftdi diff --git a/vendor/periph.io/x/host/v3/ftdi/driver.go b/vendor/periph.io/x/host/v3/ftdi/driver.go new file mode 100644 index 0000000..d7ca3b0 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/driver.go @@ -0,0 +1,213 @@ +// 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 ftdi + +import ( + "strconv" + "sync" + + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/i2c" + "periph.io/x/conn/v3/i2c/i2creg" + "periph.io/x/conn/v3/pin" + "periph.io/x/conn/v3/pin/pinreg" + "periph.io/x/conn/v3/spi/spireg" + "periph.io/x/d2xx" +) + +// All enumerates all the connected FTDI devices. +func All() []Dev { + drv.mu.Lock() + defer drv.mu.Unlock() + out := make([]Dev, len(drv.all)) + copy(out, drv.all) + return out +} + +// + +// open opens a FTDI device. +// +// Must be called with mu held. +func open(opener func(i int) (d2xx.Handle, d2xx.Err), i int) (Dev, error) { + h, err := openHandle(opener, i) + if err != nil { + return nil, err + } + if err := h.Init(); err != nil { + // setupCommon() takes the device in its previous state. It could be in an + // unexpected state, so try resetting it first. + if err := h.Reset(); err != nil { + _ = h.Close() + return nil, err + } + if err := h.Init(); err != nil { + _ = h.Close() + return nil, err + } + // The second attempt worked. + } + // Makes a copy of the handle. + g := generic{index: i, h: h, name: h.t.String()} + if i > 0 { + // When more than one device is present, add "(index)" suffix. + // TODO(maruel): Using the serial number would be nicer than a number. + g.name += "(" + strconv.Itoa(i) + ")" + } + // Makes a copy of the generic instance. + switch g.h.t { + case DevTypeFT232H: + f, err := newFT232H(g) + if err != nil { + _ = h.Close() + return nil, err + } + return f, nil + case DevTypeFT2232H: + f, err := newFT232H(g) + if err != nil { + _ = h.Close() + return nil, err + } + return f, nil + case DevTypeFT232R: + f, err := newFT232R(g) + if err != nil { + _ = h.Close() + return nil, err + } + return f, nil + default: + return &g, nil + } +} + +// registerDev registers the header and supported buses and ports in the +// relevant registries. +func registerDev(d Dev, multi bool) error { + name := d.String() + hdr := d.Header() + + // Register the GPIOs. + for _, p := range hdr { + if err := gpioreg.Register(p); err != nil { + return err + } + } + if !multi { + // Register shorthands. + // The "." used here vs the "_" used in pinreg is unfortunate. Investigate + // a better way. + prefix := len(name) + 1 + for _, p := range hdr { + n := p.Name() + if err := gpioreg.RegisterAlias(n[prefix:], n); err != nil { + return err + } + } + } + + // Register the header. + raw := make([][]pin.Pin, len(hdr)) + for i := range hdr { + raw[i] = []pin.Pin{hdr[i]} + } + if err := pinreg.Register(name, raw); err != nil { + return err + } + switch t := d.(type) { + case *FT232H: + // Register I²C without pull up. + if err := i2creg.Register(name, nil, -1, func() (i2c.BusCloser, error) { return t.I2C(gpio.Float) }); err != nil { + return err + } + if err := spireg.Register(name, nil, -1, t.SPI); err != nil { + return err + } + // TODO(maruel): UART + case *FT232R: + // TODO(maruel): SPI, UART + } + return nil +} + +// driver implements driver.Impl. +type driver struct { + mu sync.Mutex + all []Dev + d2xxOpen func(i int) (d2xx.Handle, d2xx.Err) + numDevices func() (int, error) +} + +func (d *driver) String() string { + return "ftdi" +} + +func (d *driver) Prerequisites() []string { + return nil +} + +func (d *driver) After() []string { + return nil +} + +func (d *driver) Init() (bool, error) { + num, err := d.numDevices() + if err != nil { + return true, err + } + multi := num > 1 + for i := 0; i < num; i++ { + // TODO(maruel): Close the device one day. :) + if dev, err1 := open(d.d2xxOpen, i); err1 == nil { + d.all = append(d.all, dev) + if err = registerDev(dev, multi); err != nil { + return true, err + } + } else { + // Create a shallow broken handle, so the user can learn how to fix the + // problem. + // + // TODO(maruel): On macOS with a FT232R, calling two processes in a row + // often results in a broken device on the second process. Figure out why + // and make it more resilient. + err = err1 + // The serial number is not available so what can be listed is limited. + // TODO(maruel): Add VID/PID? + name := "broken#" + strconv.Itoa(i) + ": " + err.Error() + d.all = append(d.all, &broken{index: i, err: err, name: name}) + } + } + return true, err +} + +func (d *driver) reset() { + d.mu.Lock() + defer d.mu.Unlock() + d.all = nil + // open is mocked in tests. + d.d2xxOpen = d2xx.Open + // numDevices is mocked in tests. + d.numDevices = numDevices + + // The d2xx can hang for up to the timeout under certain circumstances and the + // Go profiler is not very useful to find the source, so use manual logging + // to see where time it spent. + //d.d2xxOpen = func(i int) (d2xx.Handle, int) { + // h, e := d2xxOpen(i) + // return &d2xxLoggingHandle{h}, e + //} +} + +func init() { + if d2xx.Available { + drv.reset() + driverreg.MustRegister(&drv) + } +} + +var drv driver diff --git a/vendor/periph.io/x/host/v3/ftdi/eeprom.go b/vendor/periph.io/x/host/v3/ftdi/eeprom.go new file mode 100644 index 0000000..6b11649 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/eeprom.go @@ -0,0 +1,368 @@ +// 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 ftdi + +import ( + "errors" + "fmt" + "unsafe" +) + +// EEPROM is the unprocessed EEPROM content. +// +// The EEPROM is in 3 parts: the defined struct, the 4 strings and the rest +// which is used as an 'user area'. The size of the user area depends on the +// length of the strings. The user area content is not included in this struct. +type EEPROM struct { + // Raw is the raw EEPROM content. It excludes the strings. + Raw []byte + + // The following condition must be true: len(Manufacturer) + len(Desc) <= 40. + Manufacturer string + ManufacturerID string + Desc string + Serial string +} + +// Validate checks that the data is good. +func (e *EEPROM) Validate() error { + // Verify that the values are set correctly. + if len(e.Manufacturer) > 40 { + return errors.New("ftdi: Manufacturer is too long") + } + if len(e.ManufacturerID) > 40 { + return errors.New("ftdi: ManufacturerID is too long") + } + if len(e.Desc) > 40 { + return errors.New("ftdi: Desc is too long") + } + if len(e.Serial) > 40 { + return errors.New("ftdi: Serial is too long") + } + if len(e.Manufacturer)+len(e.Desc) > 40 { + return errors.New("ftdi: length of Manufacturer plus Desc is too long") + } + return nil +} + +func (e *EEPROM) AsHeader() *EEPROMHeader { + // sizeof(EEPROMHeader) + if len(e.Raw) < 16 { + return nil + } + return (*EEPROMHeader)(unsafe.Pointer(&e.Raw[0])) +} + +// AsFT232H returns the Raw data aliased as EEPROMFT232H. +func (e *EEPROM) AsFT232H() *EEPROMFT232H { + // sizeof(EEPROMFT232H) + if len(e.Raw) < 44 { + return nil + } + return (*EEPROMFT232H)(unsafe.Pointer(&e.Raw[0])) +} + +// AsFT2232H returns the Raw data aliased as EEPROMFT2232H. +func (e *EEPROM) AsFT2232H() *EEPROMFT2232H { + // sizeof(EEPROMFT2232H) + if len(e.Raw) < 40 { + return nil + } + return (*EEPROMFT2232H)(unsafe.Pointer(&e.Raw[0])) +} + +// AsFT232R returns the Raw data aliased as EEPROMFT232R. +func (e *EEPROM) AsFT232R() *EEPROMFT232R { + // sizeof(EEPROMFT232R) + if len(e.Raw) < 32 { + return nil + } + return (*EEPROMFT232R)(unsafe.Pointer(&e.Raw[0])) +} + +// FT232hCBusMux is stored in the FT232H EEPROM to control each CBus pin. +type FT232hCBusMux uint8 + +const ( + // TriSt-PU; Sets in Tristate (pull up) (C0~C6, C8, C9) on 75kΩ. + FT232hCBusTristatePullUp FT232hCBusMux = 0x00 + // TXLED#; Pulses low when transmitting data (C0~C6, C8, C9). + FT232hCBusTxLED FT232hCBusMux = 0x01 + // RXLED#; Pulses low when receiving data (C0~C6, C8, C9). + FT232hCBusRxLED FT232hCBusMux = 0x02 + // TX&RXLED#; Pulses low when either receiving or transmitting data (C0~C6, + // C8, C9). + FT232hCBusTxRxLED FT232hCBusMux = 0x03 + // PWREN#; Output is low after the device has been configured by USB, then + // high during USB suspend mode (C0~C6, C8, C9). + // + // Must be used with an external 10kΩ pull up. + FT232hCBusPwrEnable FT232hCBusMux = 0x04 + // SLEEP#; Goes low during USB suspend mode (C0~C6, C8, C9). + FT232hCBusSleep FT232hCBusMux = 0x05 + // DRIVE1; Drives pin to logic 0 (C0~C6, C8, C9). + FT232hCBusDrive0 FT232hCBusMux = 0x06 + // DRIVE1; Drives pin to logic 1 (C0, C5, C6, C8, C9). + FT232hCBusDrive1 FT232hCBusMux = 0x07 + // I/O Mode; CBus bit-bang mode option (C5, C6, C8, C9). + FT232hCBusIOMode FT232hCBusMux = 0x08 + // TXDEN; Tx Data Enable. Used with RS485 level converters to enable the line + // driver during data transmit. It is active one bit time before the start + // bit up to until the end of the stop bit (C0~C6, C8, C9). + FT232hCBusTxdEnable FT232hCBusMux = 0x09 + // CLK30 30MHz clock output (C0, C5, C6, C8, C9). + FT232hCBusClk30 FT232hCBusMux = 0x0A + // CLK15 15MHz clock output (C0, C5, C6, C8, C9). + FT232hCBusClk15 FT232hCBusMux = 0x0B + // CLK7.5 7.5MHz clock output (C0, C5, C6, C8, C9). + FT232hCBusClk7_5 FT232hCBusMux = 0x0C +) + +const ft232hCBusMuxName = "FT232hCBusTristatePullUpFT232hCBusTxLEDFT232hCBusRxLEDFT232hCBusTxRxLEDFT232hCBusPwrEnableFT232hCBusSleepFT232hCBusDrive0FT232hCBusDrive1FT232hCBusIOModeFT232hCBusTxdEnableFT232hCBusClk30FT232hCBusClk15FT232hCBusClk7_5" + +var fr232hCBusMuxIndex = [...]uint8{0, 24, 39, 54, 71, 90, 105, 121, 137, 153, 172, 187, 202, 218} + +func (f FT232hCBusMux) String() string { + if f >= FT232hCBusMux(len(fr232hCBusMuxIndex)-1) { + return fmt.Sprintf("FT232hCBusMux(%d)", f) + } + return ft232hCBusMuxName[fr232hCBusMuxIndex[f]:fr232hCBusMuxIndex[f+1]] +} + +// FT232rCBusMux is stored in the FT232R EEPROM to control each CBus pin. +type FT232rCBusMux uint8 + +const ( + // TXDEN; Tx Data Enable. Used with RS485 level converters to enable the line + // driver during data transmit. It is active one bit time before the start + // bit up to until the end of the stop bit (C0~C4). + FT232rCBusTxdEnable FT232rCBusMux = 0x00 + // PWREN#; Output is low after the device has been configured by USB, then + // high during USB suspend mode (C0~C4). + // + // Must be used with an external 10kΩ pull up. + FT232rCBusPwrEnable FT232rCBusMux = 0x01 + // RXLED#; Pulses low when receiving data (C0~C4). + FT232rCBusRxLED FT232rCBusMux = 0x02 + // TXLED#; Pulses low when transmitting data (C0~C4). + FT232rCBusTxLED FT232rCBusMux = 0x03 + // TX&RXLED#; Pulses low when either receiving or transmitting data (C0~C4). + FT232rCBusTxRxLED FT232rCBusMux = 0x04 + // SLEEP# Goes low during USB suspend mode (C0~C4). + FT232rCBusSleep FT232rCBusMux = 0x05 + // CLK48 48Mhz +/-0.7% clock output (C0~C4). + FT232rCBusClk48 FT232rCBusMux = 0x06 + // CLK24 24Mhz clock output (C0~C4). + FT232rCBusClk24 FT232rCBusMux = 0x07 + // CLK12 12Mhz clock output (C0~C4). + FT232rCBusClk12 FT232rCBusMux = 0x08 + // CLK6 6Mhz +/-0.7% clock output (C0~C4). + FT232rCBusClk6 FT232rCBusMux = 0x09 + // CBitBangI/O; CBus bit-bang mode option (C0~C3). + FT232rCBusIOMode FT232rCBusMux = 0x0A + // BitBangWRn; CBus WR# strobe output (C0~C3). + FT232rCBusBitBangWR FT232rCBusMux = 0x0B + // BitBangRDn; CBus RD# strobe output (C0~C3). + FT232rCBusBitBangRD FT232rCBusMux = 0x0C +) + +const ft232rCBusMuxName = "FT232rCBusTxdEnableFT232rCBusPwrEnableFT232rCBusRxLEDFT232rCBusTxLEDFT232rCBusTxRxLEDFT232rCBusSleepFT232rCBusClk48FT232rCBusClk24FT232rCBusClk12FT232rCBusClk6FT232rCBusIOModeFT232rCBusBitBangWRFT232rCBusBitBangRD" + +var ft232rCBusMuxIndex = [...]uint8{0, 19, 38, 53, 68, 85, 100, 115, 130, 145, 159, 175, 194, 213} + +func (f FT232rCBusMux) String() string { + if f >= FT232rCBusMux(len(ft232rCBusMuxIndex)-1) { + return fmt.Sprintf("FT232rCBusMux(%d)", f) + } + return ft232rCBusMuxName[ft232rCBusMuxIndex[f]:ft232rCBusMuxIndex[f+1]] +} + +// EEPROMHeader is the common header found on FTDI devices. +// +// It is 16 bytes long. +type EEPROMHeader struct { + DeviceType DevType // 0x00 FTxxxx device type to be programmed + VendorID uint16 // 0x04 Defaults to 0x0403; can be changed + ProductID uint16 // 0x06 Defaults to 0x6001 for FT232R, 0x6014 for FT232H, relevant value + SerNumEnable uint8 // 0x07 bool Non-zero if serial number to be used + Unused0 uint8 // 0x08 For alignment. + MaxPower uint16 // 0x0A 0mA < MaxPower <= 500mA + SelfPowered uint8 // 0x0C bool 0 = bus powered, 1 = self powered + RemoteWakeup uint8 // 0x0D bool 0 = not capable, 1 = capable; RI# low will wake host in 20ms. + PullDownEnable uint8 // 0x0E bool Non zero if pull down in suspend enabled + Unused1 uint8 // 0x0F For alignment. +} + +// EEPROMFT232H is the EEPROM layout of a FT232H device. +// +// It is 44 bytes long. +type EEPROMFT232H struct { + EEPROMHeader + + // FT232H specific. + ACSlowSlew uint8 // 0x10 bool Non-zero if AC bus pins have slow slew + ACSchmittInput uint8 // 0x11 bool Non-zero if AC bus pins are Schmitt input + ACDriveCurrent uint8 // 0x12 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units + ADSlowSlew uint8 // 0x13 bool Non-zero if AD bus pins have slow slew + ADSchmittInput uint8 // 0x14 bool Non-zero if AD bus pins are Schmitt input + ADDriveCurrent uint8 // 0x15 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units + Cbus0 FT232hCBusMux // 0x16 + Cbus1 FT232hCBusMux // 0x17 + Cbus2 FT232hCBusMux // 0x18 + Cbus3 FT232hCBusMux // 0x19 + Cbus4 FT232hCBusMux // 0x1A + Cbus5 FT232hCBusMux // 0x1B + Cbus6 FT232hCBusMux // 0x1C + Cbus7 FT232hCBusMux // 0x1D C7 is limited a sit can only do 'suspend on C7 low'. Defaults pull down. + Cbus8 FT232hCBusMux // 0x1E + Cbus9 FT232hCBusMux // 0x1F + FT1248Cpol uint8 // 0x20 bool FT1248 clock polarity - clock idle high (true) or clock idle low (false) + FT1248Lsb uint8 // 0x21 bool FT1248 data is LSB (true), or MSB (false) + FT1248FlowControl uint8 // 0x22 bool FT1248 flow control enable + IsFifo uint8 // 0x23 bool Non-zero if Interface is 245 FIFO + IsFifoTar uint8 // 0x24 bool Non-zero if Interface is 245 FIFO CPU target + IsFastSer uint8 // 0x25 bool Non-zero if Interface is Fast serial + IsFT1248 uint8 // 0x26 bool Non-zero if Interface is FT1248 + PowerSaveEnable uint8 // 0x27 bool Suspect on ACBus7 low. + DriverType uint8 // 0x28 bool 0 is D2XX, 1 is VCP + Unused2 uint8 // 0x29 + Unused3 uint16 // 0x30 +} + +func (e *EEPROMFT232H) Defaults() { + // As found on Adafruit device. + e.ACDriveCurrent = 4 + e.ADDriveCurrent = 4 + e.Cbus0 = FT232hCBusTristatePullUp + e.Cbus1 = FT232hCBusTristatePullUp + e.Cbus2 = FT232hCBusTristatePullUp + e.Cbus3 = FT232hCBusTristatePullUp + e.Cbus4 = FT232hCBusTristatePullUp + e.Cbus5 = FT232hCBusTristatePullUp + e.Cbus6 = FT232hCBusTristatePullUp + e.Cbus7 = FT232hCBusTristatePullUp + e.Cbus8 = FT232hCBusDrive1 + e.Cbus9 = FT232hCBusDrive0 +} + +// EEPROMFT2232H is the EEPROM layout of a FT2232H device. +// +// It is 40 bytes long. +type EEPROMFT2232H struct { + EEPROMHeader + + // FT232H specific. + ALSlowSlew uint8 // 0x10 bool non-zero if AL pins have slow slew + ALSchmittInput uint8 // 0x11 bool non-zero if AL pins are Schmitt input + ALDriveCurrent uint8 // 0x12 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units + AHSlowSlew uint8 // 0x13 bool non-zero if AH pins have slow slew + AHSchmittInput uint8 // 0x14 bool non-zero if AH pins are Schmitt input + AHDriveCurrent uint8 // 0x15 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units + BLSlowSlew uint8 // 0x16 bool non-zero if BL pins have slow slew + BLSchmittInput uint8 // 0x17 bool non-zero if BL pins are Schmitt input + BLDriveCurrent uint8 // 0x18 Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units + BHSlowSlew uint8 // 0x19 bool non-zero if BH pins have slow slew + BHSchmittInput uint8 // 0x1A bool non-zero if BH pins are Schmitt input + BHDriveCurrent uint8 // 0x1B Valid values are 4mA, 8mA, 12mA, 16mA in 2mA units + AIsFifo uint8 // 0x1C bool non-zero if interface is 245 FIFO + AIsFifoTar uint8 // 0x1D bool non-zero if interface is 245 FIFO CPU target + AIsFastSer uint8 // 0x1E bool non-zero if interface is Fast serial + BIsFifo uint8 // 0x1F bool non-zero if interface is 245 FIFO + BIsFifoTar uint8 // 0x20 bool non-zero if interface is 245 FIFO CPU target + BIsFastSer uint8 // 0x21 bool non-zero if interface is Fast serial + PowerSaveEnable uint8 // 0x22 bool non-zero if using BCBUS7 to save power for self-powered designs + ADriverType uint8 // 0x23 bool + BDriverType uint8 // 0x24 bool + Unused2 uint8 // 0x25 + Unused3 uint16 // 0x26 +} + +// EEPROMFT232R is the EEPROM layout of a FT232R device. +// +// It is 32 bytes long. +type EEPROMFT232R struct { + EEPROMHeader + + // FT232R specific. + IsHighCurrent uint8 // 0x10 bool High Drive I/Os; 3mA instead of 1mA (@3.3V) + UseExtOsc uint8 // 0x11 bool Use external oscillator + InvertTXD uint8 // 0x12 bool + InvertRXD uint8 // 0x13 bool + InvertRTS uint8 // 0x14 bool + InvertCTS uint8 // 0x15 bool + InvertDTR uint8 // 0x16 bool + InvertDSR uint8 // 0x17 bool + InvertDCD uint8 // 0x18 bool + InvertRI uint8 // 0x19 bool + Cbus0 FT232rCBusMux // 0x1A Default ft232rCBusTxLED + Cbus1 FT232rCBusMux // 0x1B Default ft232rCBusRxLED + Cbus2 FT232rCBusMux // 0x1C Default ft232rCBusTxdEnable + Cbus3 FT232rCBusMux // 0x1D Default ft232rCBusPwrEnable + Cbus4 FT232rCBusMux // 0x1E Default ft232rCBusSleep + DriverType uint8 // 0x1F bool 0 is D2XX, 1 is VCP +} + +func (e *EEPROMFT232R) Defaults() { + // As found on Adafruit device. + e.Cbus0 = FT232rCBusTxLED + e.Cbus1 = FT232rCBusRxLED + e.Cbus2 = FT232rCBusTxdEnable + e.Cbus3 = FT232rCBusPwrEnable + e.Cbus4 = FT232rCBusSleep + e.DriverType = 1 +} + +// + +// DevType is the FTDI device type. +type DevType uint32 + +const ( + DevTypeFTBM DevType = iota // 0 + DevTypeFTAM + DevTypeFT100AX + DevTypeUnknown // 3 + DevTypeFT2232C + DevTypeFT232R // 5 + DevTypeFT2232H + DevTypeFT4232H + DevTypeFT232H // 8 + DevTypeFTXSeries + DevTypeFT4222H0 + DevTypeFT4222H1_2 + DevTypeFT4222H3 + DevTypeFT4222Prog + DevTypeFT900 + DevTypeFT930 + DevTypeFTUMFTPD3A +) + +// EEPROMSize returns the size of the EEPROM for this device. +func (d DevType) EEPROMSize() int { + switch d { + case DevTypeFT232H: + // sizeof(EEPROMFT232H) + return 44 + case DevTypeFT2232H: + // sizeof(EEPROMFT2232H) + return 40 + case DevTypeFT232R: + // sizeof(EEPROMFT232R) + return 32 + default: + return 256 + } +} + +const devTypeName = "FTBMFTAMFT100AXUnknownFT2232CFT232RFT2232HFT4232HFT232HFTXSeriesFT4222H0FT4222H1/2FT4222H3FT4222ProgFT900FT930FTUMFTPD3A" + +var devTypeIndex = [...]uint8{0, 4, 8, 15, 22, 29, 35, 42, 49, 55, 64, 72, 82, 90, 100, 105, 110, 120} + +func (d DevType) String() string { + if d >= DevType(len(devTypeIndex)-1) { + d = DevTypeUnknown + } + return devTypeName[devTypeIndex[d]:devTypeIndex[d+1]] +} diff --git a/vendor/periph.io/x/host/v3/ftdi/ftdi.go b/vendor/periph.io/x/host/v3/ftdi/ftdi.go new file mode 100644 index 0000000..07f0a83 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/ftdi.go @@ -0,0 +1,5 @@ +// Copyright 2021 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 ftdi diff --git a/vendor/periph.io/x/host/v3/ftdi/gpio.go b/vendor/periph.io/x/host/v3/ftdi/gpio.go new file mode 100644 index 0000000..b8afc46 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/gpio.go @@ -0,0 +1,241 @@ +// 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. + +// Emulate independent GPIOs. + +package ftdi + +import ( + "errors" + "time" + + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/physic" +) + +// dbusSync is the handler of a synchronous bitbang on DBus. +// +// More details at: +// http://www.ftdichip.com/Support/Documents/AppNotes/AN_232R-01_Bit_Bang_Mode_Available_For_FT232R_and_Ft245R.pdf +type dbusSync interface { + dbusSyncGPIOFunc(n int) string + dbusSyncGPIOIn(n int) error + dbusSyncGPIORead(n int) gpio.Level + dbusSyncGPIOOut(n int, l gpio.Level) error +} + +// dbusPinSync represents a GPIO on a synchronous bitbang DBus. +// +// It is immutable and stateless. +type dbusPinSync struct { + n string + num int + bus dbusSync +} + +// String implements conn.Resource. +func (s *dbusPinSync) String() string { + return s.n +} + +// Halt implements conn.Resource. +func (s *dbusPinSync) Halt() error { + return nil +} + +// Name implements pin.Pin. +func (s *dbusPinSync) Name() string { + return s.n +} + +// Number implements pin.Pin. +func (s *dbusPinSync) Number() int { + return s.num +} + +// Function implements pin.Pin. +func (s *dbusPinSync) Function() string { + return s.bus.dbusSyncGPIOFunc(s.num) +} + +// In implements gpio.PinIn. +func (s *dbusPinSync) In(pull gpio.Pull, e gpio.Edge) error { + if e != gpio.NoEdge { + // We could support it on D5. + return errors.New("d2xx: edge triggering is not supported") + } + if pull != gpio.PullUp && pull != gpio.PullNoChange { + // EEPROM has a PullDownEnable flag. + return errors.New("d2xx: pull is not supported") + } + return s.bus.dbusSyncGPIOIn(s.num) +} + +// Read implements gpio.PinIn. +func (s *dbusPinSync) Read() gpio.Level { + return s.bus.dbusSyncGPIORead(s.num) +} + +// WaitForEdge implements gpio.PinIn. +func (s *dbusPinSync) WaitForEdge(t time.Duration) bool { + return false +} + +// DefaultPull implements gpio.PinIn. +func (s *dbusPinSync) DefaultPull() gpio.Pull { + // 200kΩ + // http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf + // p. 24 + return gpio.PullUp +} + +// Pull implements gpio.PinIn. +func (s *dbusPinSync) Pull() gpio.Pull { + return gpio.PullUp +} + +// Out implements gpio.PinOut. +func (s *dbusPinSync) Out(l gpio.Level) error { + return s.bus.dbusSyncGPIOOut(s.num, l) +} + +// PWM implements gpio.PinOut. +func (s *dbusPinSync) PWM(d gpio.Duty, f physic.Frequency) error { + return errors.New("d2xx: not implemented") +} + +/* +func (s *dbusPinSync) Drive() physic.ElectricCurrent { + // optionally 3 + //return s.bus.ee.DDriveCurrent * physic.MilliAmpere + return physic.MilliAmpere +} + +func (s *dbusPinSync) SlewLimit() bool { + //return s.bus.ee.DSlowSlew + return false +} + +func (s *dbusPinSync) Hysteresis() bool { + //return s.bus.ee.DSchmittInput + return true +} +*/ + +// + +// cBusGPIO is the handler of a CBus bitbang bus. +// +// This is an asynchronous mode. +// +// More details at: +// http://www.ftdichip.com/Support/Knowledgebase/index.html?cbusbitbangmode.htm +type cBusGPIO interface { + cBusGPIOFunc(n int) string + cBusGPIOIn(n int) error + cBusGPIORead(n int) gpio.Level + cBusGPIOOut(n int, l gpio.Level) error +} + +// cbusPin represents a GPIO on a CBus bitbang bus. +// +// It is immutable and stateless. +type cbusPin struct { + n string + num int + p gpio.Pull + bus cBusGPIO +} + +// String implements conn.Resource. +func (c *cbusPin) String() string { + return c.n +} + +// Halt implements conn.Resource. +func (c *cbusPin) Halt() error { + return nil +} + +// Name implements pin.Pin. +func (c *cbusPin) Name() string { + return c.n +} + +// Number implements pin.Pin. +func (c *cbusPin) Number() int { + return c.num +} + +// Function implements pin.Pin. +func (c *cbusPin) Function() string { + return c.bus.cBusGPIOFunc(c.num) +} + +// In implements gpio.PinIn. +func (c *cbusPin) In(pull gpio.Pull, e gpio.Edge) error { + if e != gpio.NoEdge { + // We could support it on D5. + return errors.New("d2xx: edge triggering is not supported") + } + if pull != c.p && pull != gpio.PullNoChange { + // EEPROM has a PullDownEnable flag. + return errors.New("d2xx: pull is not supported") + } + return c.bus.cBusGPIOIn(c.num) +} + +// Read implements gpio.PinIn. +func (c *cbusPin) Read() gpio.Level { + return c.bus.cBusGPIORead(c.num) +} + +// WaitForEdge implements gpio.PinIn. +func (c *cbusPin) WaitForEdge(t time.Duration) bool { + return false +} + +// DefaultPull implements gpio.PinIn. +func (c *cbusPin) DefaultPull() gpio.Pull { + // 200kΩ + // http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232R.pdf + // p. 24 + return c.p +} + +// Pull implements gpio.PinIn. +func (c *cbusPin) Pull() gpio.Pull { + return c.p +} + +// Out implements gpio.PinOut. +func (c *cbusPin) Out(l gpio.Level) error { + return c.bus.cBusGPIOOut(c.num, l) +} + +// PWM implements gpio.PinOut. +func (c *cbusPin) PWM(d gpio.Duty, f physic.Frequency) error { + return errors.New("d2xx: not implemented") +} + +/* +func (c *cbusPin) Drive() physic.ElectricCurrent { + // optionally 3 + //return c.bus.ee.CDriveCurrent * physic.MilliAmpere + return physic.MilliAmpere +} + +func (c *cbusPin) SlewLimit() bool { + //return c.bus.ee.CSlowSlew + return false +} + +func (c *cbusPin) Hysteresis() bool { + //return c.bus.ee.CSchmittInput + return true +} +*/ + +var _ gpio.PinIO = &dbusPinSync{} +var _ gpio.PinIO = &cbusPin{} diff --git a/vendor/periph.io/x/host/v3/ftdi/handle.go b/vendor/periph.io/x/host/v3/ftdi/handle.go new file mode 100644 index 0000000..cc9264f --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/handle.go @@ -0,0 +1,382 @@ +// Copyright 2021 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 ftdi + +import ( + "context" + "errors" + "fmt" + "io" + + "periph.io/x/conn/v3/physic" + "periph.io/x/d2xx" +) + +// + +// bitMode is used by SetBitMode to change the chip behavior. +type bitMode uint8 + +const ( + // Resets all Pins to their default value + bitModeReset bitMode = 0x00 + // Sets the DBus to asynchronous bit-bang. + bitModeAsyncBitbang bitMode = 0x01 + // Switch to MPSSE mode (FT2232, FT2232H, FT4232H and FT232H). + bitModeMpsse bitMode = 0x02 + // Sets the DBus to synchronous bit-bang (FT232R, FT245R, FT2232, FT2232H, + // FT4232H and FT232H). + bitModeSyncBitbang bitMode = 0x04 + // Switch to MCU host bus emulation (FT2232, FT2232H, FT4232H and FT232H). + bitModeMcuHost bitMode = 0x08 + // Switch to fast opto-isolated serial mode (FT2232, FT2232H, FT4232H and + // FT232H). + bitModeFastSerial bitMode = 0x10 + // Sets the CBus in 4 bits bit-bang mode (FT232R and FT232H) + // In this case, upper nibble controls which pin is output/input, lower + // controls which of outputs are high and low. + bitModeCbusBitbang bitMode = 0x20 + // Single Channel Synchronous 245 FIFO mode (FT2232H and FT232H). + bitModeSyncFifo bitMode = 0x40 +) + +// numDevices returns the number of detected devices. +func numDevices() (int, error) { + num, e := d2xx.CreateDeviceInfoList() + if e != 0 { + return 0, toErr("GetNumDevices initialization failed", e) + } + return num, nil +} + +func openHandle(opener func(i int) (d2xx.Handle, d2xx.Err), i int) (*handle, error) { + h, e := opener(i) + if e != 0 { + return nil, toErr("Open", e) + } + d := &handle{h: h} + t, vid, did, e := h.GetDeviceInfo() + if e != 0 { + _ = d.Close() + return nil, toErr("GetDeviceInfo", e) + } + d.t = DevType(t) + d.venID = vid + d.devID = did + return d, nil +} + +// handle is a thin wrapper around the low level d2xx device handle to make it +// more go-idiomatic. +// +// It also implements many utility functions to help with initialization and +// device management. +type handle struct { + // It is just above 'handle' which directly maps to D2XX function calls. + // + // Dev converts the int error type into Go native error and handles higher + // level functionality like reading and writing to the USB connection. + // + // The content of the struct is immutable after initialization. + h d2xx.Handle + t DevType + venID uint16 + devID uint16 +} + +func (h *handle) Close() error { + // Not yet called. + return toErr("Close", h.h.Close()) +} + +// Init is the general setup for common devices. +// +// It tries first the 'happy path' which doesn't reset the device. By doing so, +// the goal is to reduce the amount of glitches on the GPIO pins, on a best +// effort basis. On all devices, the GPIOs are still reset as inputs, since +// there is no way to determine if each GPIO is an input or output. +func (h *handle) Init() error { + // Driver: maximum packet size. Note that this clears any data in the buffer, + // so it is good to do it immediately after a reset. The 'out' parameter is + // ignored. + // TODO(maruel): The FT232H doc claims a 512 byte packets support in hi-speed + // mode, which means that this would likely be better to use this value. + if e := h.h.SetUSBParameters(65536, 0); e != 0 { + return toErr("SetUSBParameters", e) + } + // Driver: Set I/O timeouts to 15 sec. The reason is that we want the + // timeouts to be very visible, at least as the driver is being developed. + if e := h.h.SetTimeouts(15000, 15000); e != 0 { + return toErr("SetTimeouts", e) + } + // Not sure: Disable event/error characters. + if e := h.h.SetChars(0, false, 0, false); e != 0 { + return toErr("SetChars", e) + } + // Not sure: Latency timer at 1ms. + if e := h.h.SetLatencyTimer(1); e != 0 { + return toErr("SetLatencyTimer", e) + } + // Not sure: Turn on flow control to synchronize IN requests. + if e := h.h.SetFlowControl(); e != 0 { + return toErr("SetFlowControl", e) + } + // Just in case. It's a very small cost. + return h.Flush() +} + +// Reset resets the device. +func (h *handle) Reset() error { + if e := h.h.ResetDevice(); e != 0 { + return toErr("Reset", e) + } + if err := h.SetBitMode(0, bitModeReset); err != nil { + return err + } + // USB/driver: Flush any pending read buffer that had been sent by the device + // before it reset. Do not return any error there, as the device may spew a + // read error right after being initialized. + _ = h.Flush() + return nil +} + +// GetBitMode returns the current bit mode. +// +// This is device-dependent. +func (h *handle) GetBitMode() (byte, error) { + l, e := h.h.GetBitMode() + if e != 0 { + return 0, toErr("GetBitMode", e) + } + return l, nil +} + +// SetBitMode change the mode of operation of the device. +// +// mask sets which pins are inputs and outputs for bitModeCbusBitbang. +func (h *handle) SetBitMode(mask byte, mode bitMode) error { + return toErr("SetBitMode", h.h.SetBitMode(mask, byte(mode))) +} + +// Flush flushes any data left in the read buffer. +func (h *handle) Flush() error { + var buf [128]byte + for { + p, err := h.Read(buf[:]) + if err != nil { + return err + } + if p == 0 { + return nil + } + } +} + +// Read returns as much as available in the read buffer without blocking. +func (h *handle) Read(b []byte) (int, error) { + // GetQueueStatus() 60µs is relatively slow compared to Read() 4µs, + // but surprisingly if GetQueueStatus() is *not* called, Read() + // becomes largely slower (800µs). + // + // TODO(maruel): This asks for more perf testing before settling on the best + // solution. + // TODO(maruel): Investigate FT_GetStatus(). + p, e := h.h.GetQueueStatus() + if p == 0 || e != 0 { + return int(p), toErr("Read/GetQueueStatus", e) + } + v := int(p) + if v > len(b) { + v = len(b) + } + n, e := h.h.Read(b[:v]) + return n, toErr("Read", e) +} + +// ReadAll blocks to return all the data. +// +// Similar to ioutil.ReadAll() except that it will stop if the context is +// canceled. +func (h *handle) ReadAll(ctx context.Context, b []byte) (int, error) { + // TODO(maruel): Use FT_SetEventNotification() instead of looping when + // waiting for bytes. + for offset := 0; offset != len(b); { + if ctx.Err() != nil { + return offset, io.EOF + } + chunk := len(b) - offset + if chunk > 4096 { + chunk = 4096 + } + n, err := h.Read(b[offset : offset+chunk]) + if offset += n; err != nil { + return offset, err + } + } + return len(b), nil +} + +// WriteFast writes to the USB device. +// +// In practice this takes at least 0.1ms, which limits the effective rate. +// +// There's no guarantee that the data is all written, so it is important to +// check the return value. +func (h *handle) WriteFast(b []byte) (int, error) { + n, e := h.h.Write(b) + return n, toErr("Write", e) +} + +// Write blocks until all data is written. +func (h *handle) Write(b []byte) (int, error) { + for offset := 0; offset != len(b); { + chunk := len(b) - offset + if chunk > 4096 { + chunk = 4096 + } + p, err := h.WriteFast(b[offset : offset+chunk]) + if err != nil { + return offset + p, err + } + if p != 0 { + offset += p + } + } + return len(b), nil +} + +// ReadEEPROM reads the EEPROM. +func (h *handle) ReadEEPROM(ee *EEPROM) error { + // The raw data size must be exactly what the device contains. + eepromSize := h.t.EEPROMSize() + if len(ee.Raw) < eepromSize { + ee.Raw = make([]byte, eepromSize) + } else if len(ee.Raw) > eepromSize { + ee.Raw = ee.Raw[:eepromSize] + } + ee2 := d2xx.EEPROM{Raw: ee.Raw} + e := h.h.EEPROMRead(uint32(h.t), &ee2) + ee.Manufacturer = ee2.Manufacturer + ee.ManufacturerID = ee2.ManufacturerID + ee.Desc = ee2.Desc + ee.Serial = ee2.Serial + if e != 0 { + // 15 == FT_EEPROM_NOT_PROGRAMMED + if e != 15 { + return toErr("EEPROMRead", e) + } + // It's a fresh new device. Devices bought via Adafruit already have + // their EEPROM programmed with Adafruit branding but fake devices sold by + // CJMCU are not. Since GetDeviceInfo() above succeeded, we know the + // device type via the USB descriptor, which is sufficient to load the + // driver, which permits to program the EEPROM to "bootstrap" it. + // + // Fill it with an empty yet valid EEPROM content. We don't want to set + // VenID or DevID to 0! Nobody would do that, right? + ee.Raw = make([]byte, h.t.EEPROMSize()) + hdr := ee.AsHeader() + hdr.DeviceType = h.t + hdr.VendorID = h.venID + hdr.ProductID = h.devID + } + return nil +} + +// WriteEEPROM programs the EEPROM. +func (h *handle) WriteEEPROM(ee *EEPROM) error { + if err := ee.Validate(); err != nil { + return err + } + if len(ee.Raw) != 0 { + hdr := ee.AsHeader() + if hdr == nil { + return errors.New("ftdi: unexpected EEPROM header size") + } + if hdr.DeviceType != h.t { + return errors.New("ftdi: unexpected device type set while programming EEPROM") + } + if hdr.VendorID != h.venID { + return errors.New("ftdi: unexpected VenID set while programming EEPROM") + } + if hdr.ProductID != h.devID { + return errors.New("ftdi: unexpected DevID set while programming EEPROM") + } + } + ee2 := d2xx.EEPROM{ + Raw: ee.Raw, + Manufacturer: ee.Manufacturer, + ManufacturerID: ee.ManufacturerID, + Desc: ee.Desc, + Serial: ee.Serial, + } + return toErr("EEPROMWrite", h.h.EEPROMProgram(&ee2)) +} + +// EraseEEPROM erases all the EEPROM. +// +// Will fail on FT232R and FT245R. +func (h *handle) EraseEEPROM() error { + return toErr("EraseEE", h.h.EraseEE()) +} + +// ReadUA reads the EEPROM user area. +// +// May return nil when there's nothing programmed yet. +func (h *handle) ReadUA() ([]byte, error) { + size, e := h.h.EEUASize() + if e != 0 { + return nil, toErr("EEUASize", e) + } + if size == 0 { + // Happens on uninitialized EEPROM. + return nil, nil + } + b := make([]byte, size) + if e := h.h.EEUARead(b); e != 0 { + return nil, toErr("EEUARead", e) + } + return b, nil +} + +// WriteUA writes to the EEPROM user area. +func (h *handle) WriteUA(ua []byte) error { + size, e := h.h.EEUASize() + if e != 0 { + return toErr("EEUASize", e) + } + if size == 0 { + return errors.New("ftdi: please program EEPROM first") + } + if size < len(ua) { + return fmt.Errorf("ftdi: maximum user area size is %d bytes", size) + } + if size != len(ua) { + b := make([]byte, size) + copy(b, ua) + ua = b + } + if e := h.h.EEUAWrite(ua); e != 0 { + return toErr("EEUAWrite", e) + } + return nil +} + +// SetBaudRate sets the baud rate. +func (h *handle) SetBaudRate(f physic.Frequency) error { + if f >= physic.GigaHertz { + return errors.New("ftdi: baud rate too high") + } + v := uint32(f / physic.Hertz) + return toErr("SetBaudRate", h.h.SetBaudRate(v)) +} + +// + +func toErr(s string, e d2xx.Err) error { + if e == 0 { + return nil + } + return errors.New("ftdi: " + s + ": " + e.String()) +} diff --git a/vendor/periph.io/x/host/v3/ftdi/i2c.go b/vendor/periph.io/x/host/v3/ftdi/i2c.go new file mode 100644 index 0000000..c7169f2 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/i2c.go @@ -0,0 +1,295 @@ +// 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. + +// This functionality requires MPSSE. +// +// Interfacing I²C: +// http://www.ftdichip.com/Support/Documents/AppNotes/AN_113_FTDI_Hi_Speed_USB_To_I2C_Example.pdf +// +// Implementation based on +// http://www.ftdichip.com/Support/Documents/AppNotes/AN_255_USB%20to%20I2C%20Example%20using%20the%20FT232H%20and%20FT201X%20devices.pdf +// +// Page 18: MPSSE does not automatically support clock stretching for I²C. + +package ftdi + +import ( + "context" + "errors" + "fmt" + + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/i2c" + "periph.io/x/conn/v3/physic" +) + +const i2cSCL = 1 // D0 +const i2cSDAOut = 2 // D1 +const i2cSDAIn = 4 // D2 + +type i2cBus struct { + f *FT232H + pullUp bool +} + +// Close stops I²C mode, returns to high speed mode, disable tri-state. +func (d *i2cBus) Close() error { + d.f.mu.Lock() + err := d.stopI2C() + d.f.mu.Unlock() + return err +} + +// Duplex implements conn.Conn. +func (d *i2cBus) Duplex() conn.Duplex { + return conn.Half +} + +func (d *i2cBus) String() string { + return d.f.String() +} + +// SetSpeed implements i2c.Bus. +func (d *i2cBus) SetSpeed(f physic.Frequency) error { + if f > 10*physic.MegaHertz { + return fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 10MHz", f) + } + if f < 100*physic.Hertz { + return fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.KiloHertz?", f) + } + d.f.mu.Lock() + defer d.f.mu.Unlock() + _, err := d.f.h.MPSSEClock(f * 2 / 3) + return err +} + +// Tx implements i2c.Bus. +func (d *i2cBus) Tx(addr uint16, w, r []byte) error { + d.f.mu.Lock() + defer d.f.mu.Unlock() + if err := d.setI2CStart(); err != nil { + return err + } + a := [1]byte{byte(addr)} + if err := d.writeBytes(a[:]); err != nil { + return err + } + if len(w) != 0 { + if err := d.writeBytes(w); err != nil { + return err + } + } + if len(r) != 0 { + if err := d.readBytes(r); err != nil { + return err + } + } + if err := d.setI2CStop(); err != nil { + return err + } + return d.setI2CLinesIdle() +} + +// SCL implements i2c.Pins. +func (d *i2cBus) SCL() gpio.PinIO { + return d.f.D0 +} + +// SDA implements i2c.Pins. +func (d *i2cBus) SDA() gpio.PinIO { + return d.f.D1 +} + +// setupI2C initializes the MPSSE to the state to run an I²C transaction. +// +// Defaults to 400kHz. +// +// When pullUp is true; output alternates between Out(Low) and In(PullUp). +// +// when pullUp is false; pins are set in Tristate so Out(High) becomes float +// instead of drive High. Low still drives low. That's called open collector. +func (d *i2cBus) setupI2C(pullUp bool) error { + if pullUp { + return errors.New("d2xx: PullUp will soon be implemented") + } + // TODO(maruel): We could set these only *during* the I²C operation, which + // would make more sense. + f := 400 * physic.KiloHertz + clk := ((30 * physic.MegaHertz / f) - 1) * 2 / 3 + + buf := [4 + 3]byte{ + clock3Phase, + clock30MHz, byte(clk), byte(clk >> 8), + } + cmd := buf[:4] + if !d.pullUp { + // TODO(maruel): Do not mess with other GPIOs tristate. + cmd = append(cmd, dataTristate, 7, 0) + } + if _, err := d.f.h.Write(cmd); err != nil { + return err + } + d.f.usingI2C = true + d.pullUp = pullUp + return d.setI2CLinesIdle() +} + +// stopI2C resets the MPSSE to a more "normal" state. +func (d *i2cBus) stopI2C() error { + // Resets to 30MHz. + buf := [4 + 3]byte{ + clock2Phase, + clock30MHz, 0, 0, + } + cmd := buf[:4] + if !d.pullUp { + // TODO(maruel): Do not mess with other GPIOs tristate. + cmd = append(cmd, dataTristate, 0, 0) + } + _, err := d.f.h.Write(cmd) + d.f.usingI2C = false + return err +} + +// setI2CLinesIdle sets all D0 and D1 lines high. +// +// Does not touch D3~D7. +func (d *i2cBus) setI2CLinesIdle() error { + const mask = 0xFF &^ (i2cSCL | i2cSDAOut | i2cSDAIn) + // TODO(maruel): d.pullUp + d.f.dbus.direction = d.f.dbus.direction&mask | i2cSCL | i2cSDAOut + d.f.dbus.value = d.f.dbus.value & mask + cmd := [...]byte{gpioSetD, d.f.dbus.value | i2cSCL | i2cSDAOut, d.f.dbus.direction} + _, err := d.f.h.Write(cmd[:]) + return err +} + +// setI2CStart starts an I²C transaction. +// +// Does not touch D3~D7. +func (d *i2cBus) setI2CStart() error { + // TODO(maruel): d.pullUp + dir := d.f.dbus.direction + v := d.f.dbus.value + // Assumes last setup was d.setI2CLinesIdle(), e.g. D0 and D1 are high, so + // skip this. + // + // Runs the command 4 times as a way to delay execution. + cmd := [...]byte{ + // SCL high, SDA low for 600ns + gpioSetD, v | i2cSCL, dir, + gpioSetD, v | i2cSCL, dir, + gpioSetD, v | i2cSCL, dir, + gpioSetD, v | i2cSCL, dir, + // SCL low, SDA low + gpioSetD, v, dir, + gpioSetD, v, dir, + gpioSetD, v, dir, + } + _, err := d.f.h.Write(cmd[:]) + return err +} + +// setI2CStop completes an I²C transaction. +// +// Does not touch D3~D7. +func (d *i2cBus) setI2CStop() error { + // TODO(maruel): d.pullUp + dir := d.f.dbus.direction + v := d.f.dbus.value + // Runs the command 4 times as a way to delay execution. + cmd := [...]byte{ + // SCL low, SDA low + gpioSetD, v, dir, + gpioSetD, v, dir, + gpioSetD, v, dir, + gpioSetD, v, dir, + // SCL high, SDA low + gpioSetD, v | i2cSCL, dir, + gpioSetD, v | i2cSCL, dir, + gpioSetD, v | i2cSCL, dir, + gpioSetD, v | i2cSCL, dir, + // SCL high, SDA high + gpioSetD, v | i2cSCL | i2cSDAOut, dir, + gpioSetD, v | i2cSCL | i2cSDAOut, dir, + gpioSetD, v | i2cSCL | i2cSDAOut, dir, + gpioSetD, v | i2cSCL | i2cSDAOut, dir, + } + _, err := d.f.h.Write(cmd[:]) + return err +} + +// writeBytes writes multiple bytes within an I²C transaction. +// +// Does not touch D3~D7. +func (d *i2cBus) writeBytes(w []byte) error { + // TODO(maruel): d.pullUp + dir := d.f.dbus.direction + v := d.f.dbus.value + // TODO(maruel): WAT? + if err := d.f.h.Flush(); err != nil { + return err + } + // TODO(maruel): Implement both with and without NAK check. + var r [1]byte + cmd := [...]byte{ + // Data out, the 0 will be replaced with the byte. + dataOut | dataOutFall, 0, 0, 0, + // Set back to idle. + gpioSetD, v | i2cSCL | i2cSDAOut, dir, + // Read ACK/NAK. + dataIn | dataBit, 0, + flush, + } + for _, c := range w { + cmd[3] = c + if _, err := d.f.h.Write(cmd[:]); err != nil { + return err + } + if _, err := d.f.h.ReadAll(context.Background(), r[:]); err != nil { + return err + } + if r[0]&1 == 0 { + return errors.New("got NAK") + } + } + return nil +} + +// readBytes reads multiple bytes within an I²C transaction. +// +// Does not touch D3~D7. +func (d *i2cBus) readBytes(r []byte) error { + // TODO(maruel): d.pullUp + dir := d.f.dbus.direction + v := d.f.dbus.value + + cmd := [...]byte{ + // Read 8 bits. + dataIn | dataBit, 7, + // Send ACK/NAK. + dataOut | dataOutFall | dataBit, 0, 0, + // Set back to idle. + gpioSetD, v | i2cSCL | i2cSDAOut, dir, + // Force read buffer flush. This is only necessary if NAK are not ignored. + flush, + } + for i := range r { + if i == len(r)-1 { + // NAK. + cmd[4] = 0x80 + } + if _, err := d.f.h.Write(cmd[:]); err != nil { + return err + } + if _, err := d.f.h.ReadAll(context.Background(), r[i:1]); err != nil { + return err + } + } + return nil +} + +var _ i2c.BusCloser = &i2cBus{} +var _ i2c.Pins = &i2cBus{} diff --git a/vendor/periph.io/x/host/v3/ftdi/mpsse.go b/vendor/periph.io/x/host/v3/ftdi/mpsse.go new file mode 100644 index 0000000..ed462d6 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/mpsse.go @@ -0,0 +1,452 @@ +// 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. + +// MPSSE is Multi-Protocol Synchronous Serial Engine +// +// MPSSE basics: +// http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf +// +// MPSSE and MCU emulation modes: +// http://www.ftdichip.com/Support/Documents/AppNotes/AN_108_Command_Processor_for_MPSSE_and_MCU_Host_Bus_Emulation_Modes.pdf + +package ftdi + +import ( + "context" + "errors" + "fmt" + "time" + + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/physic" +) + +const ( + // TDI/TDO serial operation synchronised on clock edges. + // + // Long streams (default): + // - [1, 65536] bytes (length is sent minus one, requires 8 bits multiple) + // , , , , ..., + // + // Short streams (dataBit is specified): + // - [1, 8] bits + // , , + // + // When both dataOut and dataIn are specified, one of dataOutFall or + // dataInFall should be specified, at least for most sane protocols. + // + // Flags: + dataOut byte = 0x10 // Enable output, default on +VE (Rise) + dataIn byte = 0x20 // Enable input, default on +VE (Rise) + dataOutFall byte = 0x01 // instead of Rise + dataInFall byte = 0x04 // instead of Rise + dataLSBF byte = 0x08 // instead of MSBF + dataBit byte = 0x02 // instead of Byte + + // Data line drives low when the data is 0 and tristates on data 1. This is + // used with I²C. + // , , + dataTristate byte = 0x9E + + // TSM operation (for JTAG). + // + // - Send bits 6 to 0 to the TMS pin using LSB or MSB. + // - Bit 7 is passed to TDI/DO before the first clock of TMS and is held + // static for the duration of TMS clocking. + // + // , , + tmsOutLSBFRise byte = 0x4A + tmsOutLSBFFall byte = 0x4B + tmsIOLSBInRise byte = 0x6A + tmsIOLSBInFall byte = 0x6B + // Unclear: 0x6E and 0x6F + + // GPIO operation. + // + // - Operates on 8 GPIOs at a time, e.g. C0~C7 or D0~D7. + // - Direction 1 means output, 0 means input. + // + // , , + gpioSetD byte = 0x80 + gpioSetC byte = 0x82 + // , returns + gpioReadD byte = 0x81 + gpioReadC byte = 0x83 + + // Internal loopback. + // + // Connects TDI and TDO together. + internalLoopbackEnable byte = 0x84 + internalLoopbackDisable byte = 0x85 + + // Clock. + // + // The TCK/SK has a 50% duty cycle. + // + // The inactive clock state can be set via the gpioSetD command and control + // bit 0. + // + // By default, the base clock is 6MHz via a 5x divisor. On + // FT232H/FT2232H/FT4232H, the 5x divisor can be disabled. + clock30MHz byte = 0x8A + clock6MHz byte = 0x8B + // Sets clock divisor. + // + // The effective value depends if clock30MHz was sent or not. + // + // - 0(1) 6MHz / 30MHz + // - 1(2) 3MHz / 15MHz + // - 2(3) 2MHz / 10MHz + // - 3(4) 1.5MHz / 7.5MHz + // - 4(5) 1.25MHz / 6MHz + // - ... + // - 0xFFFF(65536) 91.553Hz / 457.763Hz + // + // , , + clockSetDivisor byte = 0x86 + // Uses 3 phases data clocking: data is valid on both clock edges. Needed + // for I²C. + clock3Phase byte = 0x8C + // Uses normal 2 phases data clocking. + clock2Phase byte = 0x8D + // Enables clock even while not doing any operation. Used with JTAG. + // Enables the clock between [1, 8] pulses. + // , + clockOnShort byte = 0x8E + // Enables the clock between [8, 524288] pulses in 8 multiples. + // , , + clockOnLong byte = 0x8F + // Enables clock until D5 is high or low. Used with JTAG. + clockUntilHigh byte = 0x94 + clockUntilLow byte = 0x95 + // , , in 8 multiples. + clockUntilHighLong byte = 0x9C + clockUntilLowLong byte = 0x9D + // Enables adaptive clocking. Used with JTAG. + // + // This causes the controller to wait for D7 signal state as an ACK. + clockAdaptive byte = 0x96 + // Disables adaptive clocking. + clockNormal byte = 0x97 + + // CPU mode. + // + // Access the device registers like a memory mapped device. + // + // , + cpuReadShort byte = 0x90 + // , , + cpuReadFar byte = 0x91 + // , , + cpuWriteShort byte = 0x92 + // , , , + cpuWriteFar byte = 0x91 + + // Buffer operations. + // + // Flush the buffer back to the host. + flush byte = 0x87 + // Wait until D5 (JTAG) or I/O1 (CPU) is high. Once it is detected as + // high, the MPSSE engine moves on to process the next instruction. + waitHigh byte = 0x88 + waitLow byte = 0x89 +) + +// InitMPSSE sets the device into MPSSE mode. +// +// This requires a f232h, ft2232, ft2232h or a ft4232h. +// +// Use only one of Init or InitMPSSE. +func (h *handle) InitMPSSE() error { + // http://www.ftdichip.com/Support/Documents/AppNotes/AN_255_USB%20to%20I2C%20Example%20using%20the%20FT232H%20and%20FT201X%20devices.pdf + // Pre-state: + // - Write EEPROM i.IsFifo = true so the device DBus is started in tristate. + + // Try to verify the MPSSE controller without initializing it first. This is + // the 'happy path', which enables reusing the device is its current state + // without affecting current GPIO state. + if h.mpsseVerify() != nil { + // Do a full reset. Just trying to set the MPSSE controller will + // likely not work. That's a layering violation (since the retry with reset + // is done in driver.go) but we've survived worse things... + // + // TODO(maruel): This is not helping in practice, this need to be fine + // tuned. + if err := h.Reset(); err != nil { + return err + } + if err := h.Init(); err != nil { + return err + } + if err := h.SetBitMode(0, bitModeMpsse); err != nil { + return err + } + if err := h.mpsseVerify(); err != nil { + return err + } + } + + // Initialize MPSSE to a known state. + // Reset the clock since it is impossible to read back the current clock rate. + // Reset all the GPIOs are inputs since it is impossible to read back the + // state of each GPIO (if they are input or output). + cmd := []byte{ + clock30MHz, clockNormal, clock2Phase, internalLoopbackDisable, + gpioSetC, 0x00, 0x00, + gpioSetD, 0x00, 0x00, + } + if _, err := h.Write(cmd); err != nil { + return err + } + // Success!! + return nil +} + +// mpsseVerify sends an invalid MPSSE command and verifies the returned value +// is incorrect. +// +// In practice this takes around 2ms. +func (h *handle) mpsseVerify() error { + var b [16]byte + for _, v := range []byte{0xAA, 0xAB} { + // Write a bad command and ensure it returned correctly. + // Unlike what the application note proposes, include a flush op right + // after. Without the flush, the device will only flush after the delay + // specified to SetLatencyTimer. The flush removes this unneeded wait, + // which enables increasing the delay specified to SetLatencyTimer. + b[0] = v + b[1] = flush + if _, err := h.Write(b[:2]); err != nil { + return fmt.Errorf("d2xx: mpsseVerify: %v", err) + } + // Sometimes, especially right after a reset, the device spews a few bytes. + // Discard them. This significantly increases the odds of a successful + // initialization. + p, e := h.h.GetQueueStatus() + if e != 0 { + return toErr("Read/GetQueueStatus", e) + } + for p > 2 { + l := int(p) - 2 + if l > len(b) { + l = len(b) + } + // Discard the overflow bytes. + ctx, cancel := context200ms() + defer cancel() + if _, err := h.ReadAll(ctx, b[:l]); err != nil { + return fmt.Errorf("d2xx: mpsseVerify: %v", err) + } + p -= uint32(l) + } + // Custom implementation, as we want to flush any stray byte. + ctx, cancel := context200ms() + defer cancel() + if _, err := h.ReadAll(ctx, b[:2]); err != nil { + return fmt.Errorf("d2xx: mpsseVerify: %v", err) + } + // 0xFA means invalid command, 0xAA is the command echoed back. + if b[0] != 0xFA || b[1] != v { + return fmt.Errorf("d2xx: mpsseVerify: failed test for byte %#x: %#x", v, b) + } + } + return nil +} + +// + +// MPSSERegRead reads the memory mapped registers from the device. +func (h *handle) MPSSERegRead(addr uint16) (byte, error) { + // Unlike most other operations, the uint16 byte order is , . + b := [...]byte{cpuReadFar, byte(addr >> 8), byte(addr), flush} + if _, err := h.Write(b[:]); err != nil { + return 0, err + } + ctx, cancel := context200ms() + defer cancel() + _, err := h.ReadAll(ctx, b[:1]) + return b[0], err +} + +// MPSSEClock sets the clock at the closest value and returns it. +func (h *handle) MPSSEClock(f physic.Frequency) (physic.Frequency, error) { + // TODO(maruel): Memory clock and skip if the same value. + clk := clock30MHz + base := 30 * physic.MegaHertz + div := base / f + if div >= 65536 { + clk = clock6MHz + base /= 5 + div = base / f + if div >= 65536 { + return 0, errors.New("d2xx: clock frequency is too low") + } + } + b := [...]byte{clk, clockSetDivisor, byte(div - 1), byte((div - 1) >> 8)} + _, err := h.Write(b[:]) + return base / div, err +} + +// mpsseTxOp returns the right MPSSE command byte for the stream. +func mpsseTxOp(w, r bool, ew, er gpio.Edge, lsbf bool) byte { + op := byte(0) + if lsbf { + op |= dataLSBF + } + if w { + op |= dataOut + if ew == gpio.FallingEdge { + op |= dataOutFall + } + } + if r { + op |= dataIn + if er == gpio.FallingEdge { + op |= dataInFall + } + } + return op +} + +// MPSSETx runs a transaction on the clock on pins D0, D1 and D2. +// +// It can only do it on a multiple of 8 bits. +func (h *handle) MPSSETx(w, r []byte, ew, er gpio.Edge, lsbf bool) error { + l := len(w) + if len(w) != 0 { + // TODO(maruel): This is easy to fix by daisy chaining operations. + if len(w) > 65536 { + return errors.New("d2xx: write buffer too long; max 65536") + } + } + if len(r) != 0 { + if len(r) > 65536 { + return errors.New("d2xx: read buffer too long; max 65536") + } + if l != 0 && len(r) != l { + return errors.New("d2xx: mismatched buffer lengths") + } + l = len(r) + } + // The FT232H has 1Kb Tx and Rx buffers. So partial writes should be done. + // TODO(maruel): Test. + + // Flush can be useful if rbits != 0. + op := mpsseTxOp(len(w) != 0, len(r) != 0, ew, er, lsbf) + cmd := []byte{op, byte(l - 1), byte((l - 1) >> 8)} + cmd = append(cmd, w...) + if len(r) != 0 { + cmd = append(cmd, flush) + } + if _, err := h.Write(cmd); err != nil { + return err + } + if len(r) != 0 { + ctx, cancel := context200ms() + defer cancel() + _, err := h.ReadAll(ctx, r) + return err + } + return nil +} + +// MPSSETxShort runs a transaction on the clock pins D0, D1 and D2 for a byte +// or less: between 1 and 8 bits. +func (h *handle) MPSSETxShort(w byte, wbits, rbits int, ew, er gpio.Edge, lsbf bool) (byte, error) { + op := byte(dataBit) + if lsbf { + op |= dataLSBF + } + l := wbits + if wbits != 0 { + if wbits > 8 { + return 0, errors.New("d2xx: write buffer too long; max 8") + } + op |= dataOut + if ew == gpio.FallingEdge { + op |= dataOutFall + } + } + if rbits != 0 { + if rbits > 8 { + return 0, errors.New("d2xx: read buffer too long; max 8") + } + op |= dataIn + if er == gpio.FallingEdge { + op |= dataInFall + } + if l != 0 && rbits != l { + return 0, errors.New("d2xx: mismatched buffer lengths") + } + l = rbits + } + b := [3]byte{op, byte(l - 1)} + cmd := b[:2] + if wbits != 0 { + cmd = append(cmd, w) + } + if rbits != 0 { + cmd = append(cmd, flush) + } + if _, err := h.Write(cmd); err != nil { + return 0, err + } + if rbits != 0 { + ctx, cancel := context200ms() + defer cancel() + _, err := h.ReadAll(ctx, b[:1]) + return b[0], err + } + return 0, nil +} + +// MPSSECBus operates on 8 GPIOs at a time C0~C7. +// +// Direction 1 means output, 0 means input. +func (h *handle) MPSSECBus(mask, value byte) error { + b := [...]byte{gpioSetC, value, mask} + _, err := h.Write(b[:]) + return err +} + +// MPSSEDBus operates on 8 GPIOs at a time D0~D7. +// +// Direction 1 means output, 0 means input. +func (h *handle) MPSSEDBus(mask, value byte) error { + b := [...]byte{gpioSetD, value, mask} + _, err := h.Write(b[:]) + return err +} + +// MPSSECBusRead reads all the CBus pins C0~C7. +func (h *handle) MPSSECBusRead() (byte, error) { + b := [...]byte{gpioReadC, flush} + if _, err := h.Write(b[:]); err != nil { + return 0, err + } + ctx, cancel := context200ms() + defer cancel() + if _, err := h.ReadAll(ctx, b[:1]); err != nil { + return 0, err + } + return b[0], nil +} + +// MPSSEDBusRead reads all the DBus pins D0~D7. +func (h *handle) MPSSEDBusRead() (byte, error) { + b := [...]byte{gpioReadD, flush} + if _, err := h.Write(b[:]); err != nil { + return 0, err + } + ctx, cancel := context200ms() + defer cancel() + if _, err := h.ReadAll(ctx, b[:1]); err != nil { + return 0, err + } + return b[0], nil +} + +func context200ms() (context.Context, func()) { + return context.WithTimeout(context.Background(), 200*time.Millisecond) +} diff --git a/vendor/periph.io/x/host/v3/ftdi/mpsse_gpio.go b/vendor/periph.io/x/host/v3/ftdi/mpsse_gpio.go new file mode 100644 index 0000000..ebbb425 --- /dev/null +++ b/vendor/periph.io/x/host/v3/ftdi/mpsse_gpio.go @@ -0,0 +1,205 @@ +// 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 ftdi + +import ( + "errors" + "fmt" + "strconv" + "time" + + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/physic" +) + +// gpiosMPSSE is a slice of 8 GPIO pins driven via MPSSE. +// +// This permits keeping a cache. +type gpiosMPSSE struct { + // Immutable. + h *handle + cbus bool // false if D bus + pins [8]gpioMPSSE + + // Cache of values + direction byte + value byte +} + +func (g *gpiosMPSSE) init(name string) { + s := "D" + if g.cbus { + s = "C" + } + // Configure pulls; pull ups are 75kΩ. + // http://www.ftdichip.com/Support/Documents/AppNotes/AN_184%20FTDI%20Device%20Input%20Output%20Pin%20States.pdf + // has a good table. + // D0, D2 and D4 go in high impedance before going into pull up. + // TODO(maruel): The pull on CBus depends on EEPROM! + for i := range g.pins { + g.pins[i].a = g + g.pins[i].n = name + "." + s + strconv.Itoa(i) + g.pins[i].num = i + g.pins[i].dp = gpio.PullUp + } + if g.cbus { + // That's just the default EEPROM value. + g.pins[7].dp = gpio.PullDown + } +} + +func (g *gpiosMPSSE) in(n int) error { + if g.h == nil { + return errors.New("d2xx: device not open") + } + g.direction = g.direction & ^(1 << uint(n)) + if g.cbus { + return g.h.MPSSECBus(g.direction, g.value) + } + return g.h.MPSSEDBus(g.direction, g.value) +} + +func (g *gpiosMPSSE) read() (byte, error) { + if g.h == nil { + return 0, errors.New("d2xx: device not open") + } + var err error + if g.cbus { + g.value, err = g.h.MPSSECBusRead() + } else { + g.value, err = g.h.MPSSEDBusRead() + } + return g.value, err +} + +func (g *gpiosMPSSE) out(n int, l gpio.Level) error { + if g.h == nil { + return errors.New("d2xx: device not open") + } + g.direction = g.direction | (1 << uint(n)) + if l { + g.value |= 1 << uint(n) + } else { + g.value &^= 1 << uint(n) + } + if g.cbus { + return g.h.MPSSECBus(g.direction, g.value) + } + return g.h.MPSSEDBus(g.direction, g.value) +} + +// + +// gpioMPSSE is a GPIO pin on a FTDI device driven via MPSSE. +// +// gpioMPSSE implements gpio.PinIO. +// +// It is immutable and stateless. +type gpioMPSSE struct { + a *gpiosMPSSE + n string + num int + dp gpio.Pull +} + +// String implements pin.Pin. +func (g *gpioMPSSE) String() string { + return g.n +} + +// Name implements pin.Pin. +func (g *gpioMPSSE) Name() string { + return g.n +} + +// Number implements pin.Pin. +func (g *gpioMPSSE) Number() int { + return g.num +} + +// Function implements pin.Pin. +func (g *gpioMPSSE) Function() string { + s := "Out/" + m := byte(1 << uint(g.num)) + if g.a.direction&m == 0 { + s = "In/" + _, _ = g.a.read() + } + return s + gpio.Level(g.a.value&m != 0).String() +} + +// Halt implements gpio.PinIO. +func (g *gpioMPSSE) Halt() error { + return nil +} + +// In implements gpio.PinIn. +func (g *gpioMPSSE) In(pull gpio.Pull, e gpio.Edge) error { + if e != gpio.NoEdge { + // We could support it on D5. + return errors.New("d2xx: edge triggering is not supported") + } + if pull != g.dp && pull != gpio.PullNoChange { + // TODO(maruel): This needs to be redone: + // - EEPROM values FT232hCBusTristatePullUp and FT232hCBusPwrEnable can be + // used to control individual CBus pins. + // - dataTristate enables gpio.Float when set to output High, but I don't + // know if it will enable reading the value (?). This needs to be + // confirmed. + return fmt.Errorf("d2xx: pull %s is not supported; try %s", pull, g.dp) + } + return g.a.in(g.num) +} + +// Read implements gpio.PinIn. +func (g *gpioMPSSE) Read() gpio.Level { + v, _ := g.a.read() + return gpio.Level(v&(1< physic.GigaHertz { + return nil, fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 30MHz", f) + } + if f > 30*physic.MegaHertz { + // TODO(maruel): Figure out a way to communicate that the speed was lowered. + // https://github.com/google/periph/issues/255 + f = 30 * physic.MegaHertz + } + if f < 100*physic.Hertz { + return nil, fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?", f) + } + if bits&7 != 0 { + return nil, errors.New("d2xx: bits must be multiple of 8") + } + if bits != 8 { + return nil, errors.New("d2xx: implement bits per word above 8") + } + + s.c.f.mu.Lock() + defer s.c.f.mu.Unlock() + s.c.noCS = m&spi.NoCS != 0 + s.c.halfDuplex = m&spi.HalfDuplex != 0 + s.c.lsbFirst = m&spi.LSBFirst != 0 + m &^= spi.NoCS | spi.HalfDuplex | spi.LSBFirst + if s.c.halfDuplex { + return nil, errors.New("d2xx: spi.HalfDuplex is not yet supported (implementing wouldn't be too hard, please submit a PR") + } + if m < 0 || m > 3 { + return nil, errors.New("d2xx: unknown spi mode") + } + s.c.edgeInvert = m&1 != 0 + s.c.clkActiveLow = m&2 != 0 + if s.maxFreq == 0 || f < s.maxFreq { + // TODO(maruel): We could set these only *during* the SPI operation, which + // would make more sense. + if _, err := s.c.f.h.MPSSEClock(f); err != nil { + return nil, err + } + s.maxFreq = f + } + s.c.resetIdle() + if err := s.c.f.h.MPSSEDBus(s.c.f.dbus.direction, s.c.f.dbus.value); err != nil { + return nil, err + } + s.c.f.usingSPI = true + return &s.c, nil +} + +// LimitSpeed implements spi.Port. +func (s *spiMPSEEPort) LimitSpeed(f physic.Frequency) error { + if f > physic.GigaHertz { + return fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 30MHz", f) + } + if f > 30*physic.MegaHertz { + f = 30 * physic.MegaHertz + } + if f < 100*physic.Hertz { + return errors.New("d2xx: minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?") + } + s.c.f.mu.Lock() + defer s.c.f.mu.Unlock() + if s.maxFreq != 0 && s.maxFreq <= f { + return nil + } + s.maxFreq = f + // TODO(maruel): We could set these only *during* the SPI operation, which + // would make more sense. + _, err := s.c.f.h.MPSSEClock(s.maxFreq) + return err +} + +// CLK returns the SCK (clock) pin. +func (s *spiMPSEEPort) CLK() gpio.PinOut { + return s.c.CLK() +} + +// MOSI returns the SDO (master out, slave in) pin. +func (s *spiMPSEEPort) MOSI() gpio.PinOut { + return s.c.MOSI() +} + +// MISO returns the SDI (master in, slave out) pin. +func (s *spiMPSEEPort) MISO() gpio.PinIn { + return s.c.MISO() +} + +// CS returns the CSN (chip select) pin. +func (s *spiMPSEEPort) CS() gpio.PinOut { + return s.c.CS() +} + +type spiMPSEEConn struct { + // Immutable. + f *FT232H + + // Initialized at Connect(). + edgeInvert bool // CPHA=1 + clkActiveLow bool // CPOL=1 + noCS bool // CS line is not changed + lsbFirst bool // Default is MSB first + halfDuplex bool // 3 wire mode +} + +func (s *spiMPSEEConn) String() string { + return s.f.String() +} + +func (s *spiMPSEEConn) Tx(w, r []byte) error { + var p = [1]spi.Packet{{W: w, R: r}} + return s.TxPackets(p[:]) +} + +func (s *spiMPSEEConn) Duplex() conn.Duplex { + // TODO(maruel): Support half if there's a need. + return conn.Full +} + +func (s *spiMPSEEConn) TxPackets(pkts []spi.Packet) error { + // Verification. + for _, p := range pkts { + if p.KeepCS { + return errors.New("d2xx: implement spi.Packet.KeepCS") + } + if p.BitsPerWord&7 != 0 { + return errors.New("d2xx: bits must be a multiple of 8") + } + if p.BitsPerWord != 0 && p.BitsPerWord != 8 { + return errors.New("d2xx: implement spi.Packet.BitsPerWord") + } + if err := verifyBuffers(p.W, p.R); err != nil { + return err + } + } + s.f.mu.Lock() + defer s.f.mu.Unlock() + const clk = byte(1) << 0 + const mosi = byte(1) << 1 + const miso = byte(1) << 2 + const cs = byte(1) << 3 + s.resetIdle() + idle := s.f.dbus.value + start1 := idle + if !s.noCS { + start1 &^= cs + } + // In mode 0 and 2, start2 is not needed. + start2 := start1 + stop := idle + if s.edgeInvert { + // This is needed to 'prime' the clock. + start2 ^= clk + // With mode 1 and 3, keep the clock steady while CS is being deasserted to + // not create a spurious clock. + stop ^= clk + } + ew := gpio.FallingEdge + er := gpio.RisingEdge + if s.edgeInvert { + ew, er = er, ew + } + if s.clkActiveLow { + // TODO(maruel): Not sure. + ew, er = er, ew + } + + // FT232H claims 512 USB packet support, so to reduce the chatter over USB, + // try to make all I/O be aligned on this amount. This also removes the need + // for heap usage. The idea is to always trail reads by one buffer. This is + // fine as the device has 1024 byte read buffer. Operations look like this: + // W, W, R, W, R, W, R, R + // This enables reducing the I/O gaps between USB packets as the device is + // always busy with operations. + var buf [512]byte + cmd := buf[:0] + keptCS := false + + // Loop, without increasing the index. + for _, p := range pkts { + if len(p.W) == 0 && len(p.R) == 0 { + continue + } + // TODO(maruel): s.halfDuplex. + + if !keptCS { + for i := 0; i < 5; i++ { + cmd = append(cmd, gpioSetD, idle, s.f.dbus.direction) + } + for i := 0; i < 5; i++ { + cmd = append(cmd, gpioSetD, start1, s.f.dbus.direction) + } + } + if s.edgeInvert { + // This is needed to 'prime' the clock. + for i := 0; i < 5; i++ { + cmd = append(cmd, gpioSetD, start2, s.f.dbus.direction) + } + } + op := mpsseTxOp(len(p.W) != 0, len(p.R) != 0, ew, er, s.lsbFirst) + + // Do an I/O loop. We can mutate p here because it is a copy. + // TODO(maruel): Have the pipeline cross the packet boundary. + if len(p.W) == 0 { + // Have the write buffer point to the read one. This saves from + // allocating memory. The side effect is that it will write whatever + // happened to be in the read buffer. + p.W = p.R[:] + } + pendingRead := 0 + for len(p.W) != 0 { + // op, sizelo, sizehi. + chunk := len(buf) - 3 - len(cmd) + if l := len(p.W); chunk > l { + chunk = l + } + cmd = append(cmd, op, byte(chunk-1), byte((chunk-1)>>8)) + cmd = append(cmd, p.W[:chunk]...) + p.W = p.W[chunk:] + if _, err := s.f.h.WriteFast(cmd); err != nil { + return err + } + cmd = buf[:0] + + // TODO(maruel): Read 62 bytes at a time? + // Delay reading by 512 bytes. + if pendingRead >= 512 { + if len(p.R) != 0 { + // Align reads on 512 bytes exactly, aligned on USB packet size. + if _, err := s.f.h.ReadAll(context.Background(), p.R[:512]); err != nil { + return err + } + p.R = p.R[512:] + pendingRead -= 512 + } + } + pendingRead += chunk + } + // Do not forget to read whatever is pending. + // TODO(maruel): Investigate if a flush helps. + if len(p.R) != 0 { + // Send a flush to not wait for data. + cmd = append(cmd, flush) + if _, err := s.f.h.WriteFast(cmd); err != nil { + return err + } + cmd = buf[:0] + if _, err := s.f.h.ReadAll(context.Background(), p.R); err != nil { + return err + } + } + // TODO(maruel): Inject this in the write if it fits (it will generally + // do). That will save one USB I/O, which is not insignificant. + keptCS = p.KeepCS + if !keptCS { + cmd = append(cmd, flush) + for i := 0; i < 5; i++ { + cmd = append(cmd, gpioSetD, stop, s.f.dbus.direction) + } + for i := 0; i < 5; i++ { + cmd = append(cmd, gpioSetD, idle, s.f.dbus.direction) + } + if _, err := s.f.h.WriteFast(cmd); err != nil { + return err + } + cmd = buf[:0] + } + } + return nil +} + +// CLK returns the SCK (clock) pin. +func (s *spiMPSEEConn) CLK() gpio.PinOut { + return s.f.D0 +} + +// MOSI returns the SDO (master out, slave in) pin. +func (s *spiMPSEEConn) MOSI() gpio.PinOut { + return s.f.D1 +} + +// MISO returns the SDI (master in, slave out) pin. +func (s *spiMPSEEConn) MISO() gpio.PinIn { + return s.f.D2 +} + +// CS returns the CSN (chip select) pin. +func (s *spiMPSEEConn) CS() gpio.PinOut { + return s.f.D3 +} + +// resetIdle sets D0~D3. D0, D1 and D3 are output but only touch D3 is CS is +// used. +func (s *spiMPSEEConn) resetIdle() { + const clk = byte(1) << 0 + const mosi = byte(1) << 1 + const miso = byte(1) << 2 + const cs = byte(1) << 3 + if !s.noCS { + s.f.dbus.direction &= 0xF0 + s.f.dbus.direction |= cs + s.f.dbus.value &= 0xF0 + s.f.dbus.value |= cs + } else { + s.f.dbus.value &= 0xF8 + s.f.dbus.direction &= 0xF8 + } + s.f.dbus.direction |= mosi | clk + if s.clkActiveLow { + // Clock idles high. + s.f.dbus.value |= clk + } +} + +// + +// spiSyncPort is an SPI port over a FTDI device in synchronous bit-bang mode. +type spiSyncPort struct { + c spiSyncConn + + // Mutable. + maxFreq physic.Frequency +} + +func (s *spiSyncPort) Close() error { + s.c.f.mu.Lock() + s.c.f.usingSPI = false + s.maxFreq = 0 + s.c.edgeInvert = false + s.c.clkActiveLow = false + s.c.noCS = false + s.c.lsbFirst = false + s.c.halfDuplex = false + s.c.f.mu.Unlock() + return nil +} + +func (s *spiSyncPort) String() string { + return s.c.f.String() +} + +const ft232rMaxSpeed = 3 * physic.MegaHertz + +// Connect implements spi.Port. +func (s *spiSyncPort) Connect(f physic.Frequency, m spi.Mode, bits int) (spi.Conn, error) { + if f > physic.GigaHertz { + return nil, fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 1.5MHz", f) + } + if f > ft232rMaxSpeed/2 { + // TODO(maruel): Figure out a way to communicate that the speed was lowered. + // https://github.com/google/periph/issues/255 + f = ft232rMaxSpeed / 2 + } + if f < 100*physic.Hertz { + return nil, fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?", f) + } + if bits&7 != 0 { + return nil, errors.New("d2xx: bits must be multiple of 8") + } + if bits != 8 { + return nil, errors.New("d2xx: implement bits per word above 8") + } + + s.c.f.mu.Lock() + defer s.c.f.mu.Unlock() + s.c.noCS = m&spi.NoCS != 0 + s.c.halfDuplex = m&spi.HalfDuplex != 0 + s.c.lsbFirst = m&spi.LSBFirst != 0 + m &^= spi.NoCS | spi.HalfDuplex | spi.LSBFirst + if s.c.halfDuplex { + return nil, errors.New("d2xx: spi.HalfDuplex is not yet supported (implementing wouldn't be too hard, please submit a PR") + } + if m < 0 || m > 3 { + return nil, errors.New("d2xx: unknown spi mode") + } + s.c.edgeInvert = m&1 != 0 + s.c.clkActiveLow = m&2 != 0 + if s.maxFreq == 0 || f < s.maxFreq { + if err := s.c.f.SetSpeed(f * 2); err != nil { + return nil, err + } + s.maxFreq = f + } + // D0, D2 and D3 are output. D4~D7 are kept as-is. + const mosi = byte(1) << 0 // TX + const miso = byte(1) << 1 // RX + const clk = byte(1) << 2 // RTS + const cs = byte(1) << 3 // CTS + mask := mosi | clk | cs | (s.c.f.dmask & 0xF0) + if err := s.c.f.setDBusMaskLocked(mask); err != nil { + return nil, err + } + // TODO(maruel): Combine both following calls if possible. We'd shave off a + // few ms. + if !s.c.noCS { + // CTS/SPI_CS is active low. + if err := s.c.f.dbusSyncGPIOOutLocked(3, gpio.High); err != nil { + return nil, err + } + } + if s.c.clkActiveLow { + // RTS/SPI_CLK is active low. + if err := s.c.f.dbusSyncGPIOOutLocked(2, gpio.High); err != nil { + return nil, err + } + } + s.c.f.usingSPI = true + return &s.c, nil +} + +// LimitSpeed implements spi.Port. +func (s *spiSyncPort) LimitSpeed(f physic.Frequency) error { + if f > physic.GigaHertz { + return fmt.Errorf("d2xx: invalid speed %s; maximum supported clock is 1.5MHz", f) + } + if f < 100*physic.Hertz { + return fmt.Errorf("d2xx: invalid speed %s; minimum supported clock is 100Hz; did you forget to multiply by physic.MegaHertz?", f) + } + s.c.f.mu.Lock() + defer s.c.f.mu.Unlock() + if s.maxFreq != 0 && s.maxFreq <= f { + return nil + } + if err := s.c.f.SetSpeed(f * 2); err == nil { + s.maxFreq = f + } + return nil +} + +// CLK returns the SCK (clock) pin. +func (s *spiSyncPort) CLK() gpio.PinOut { + return s.c.CLK() +} + +// MOSI returns the SDO (master out, slave in) pin. +func (s *spiSyncPort) MOSI() gpio.PinOut { + return s.c.MOSI() +} + +// MISO returns the SDI (master in, slave out) pin. +func (s *spiSyncPort) MISO() gpio.PinIn { + return s.c.MISO() +} + +// CS returns the CSN (chip select) pin. +func (s *spiSyncPort) CS() gpio.PinOut { + return s.c.CS() +} + +type spiSyncConn struct { + // Immutable. + f *FT232R + + // Initialized at Connect(). + edgeInvert bool // CPHA=1 + clkActiveLow bool // CPOL=1 + noCS bool // CS line is not changed + lsbFirst bool // Default is MSB first + halfDuplex bool // 3 wire mode +} + +func (s *spiSyncConn) String() string { + return s.f.String() +} + +func (s *spiSyncConn) Tx(w, r []byte) error { + var p = [1]spi.Packet{{W: w, R: r}} + return s.TxPackets(p[:]) +} + +func (s *spiSyncConn) Duplex() conn.Duplex { + // TODO(maruel): Support half if there's a need. + return conn.Full +} + +func (s *spiSyncConn) TxPackets(pkts []spi.Packet) error { + // We need to 'expand' each bit 2 times * 8 bits, which leads + // to a 16x memory usage increase. Adds 5 samples before and after. + totalW := 0 + totalR := 0 + for _, p := range pkts { + if p.KeepCS { + return errors.New("d2xx: implement spi.Packet.KeepCS") + } + if p.BitsPerWord&7 != 0 { + return errors.New("d2xx: bits must be a multiple of 8") + } + if p.BitsPerWord != 0 && p.BitsPerWord != 8 { + return errors.New("d2xx: implement spi.Packet.BitsPerWord") + } + if err := verifyBuffers(p.W, p.R); err != nil { + return err + } + // TODO(maruel): Correctly calculate offsets. + if len(p.W) != 0 { + totalW += 2 * 8 * len(p.W) + } + if len(p.R) != 0 { + totalR += 2 * 8 * len(p.R) + } + } + + // Create a large, single chunk. + var we, re []byte + if totalW != 0 { + totalW += 10 + we = make([]byte, 0, totalW) + } + if totalR != 0 { + totalR += 10 + re = make([]byte, totalR) + } + const mosi = byte(1) << 0 // TX + const miso = byte(1) << 1 // RX + const clk = byte(1) << 2 // RTS + const cs = byte(1) << 3 // CTS + + s.f.mu.Lock() + defer s.f.mu.Unlock() + + // https://en.wikipedia.org/wiki/Serial_Peripheral_Interface#Data_transmission + + csActive := s.f.dvalue & s.f.dmask & 0xF0 + csIdle := csActive + if !s.noCS { + csIdle = csActive | cs + } + clkIdle := csActive + clkActive := clkIdle | clk + if s.clkActiveLow { + clkActive, clkIdle = clkIdle, clkActive + csIdle |= clk + } + // Start of tx; assert CS if needed. + we = append(we, csIdle, clkIdle, clkIdle, clkIdle, clkIdle) + for _, p := range pkts { + if len(p.W) == 0 && len(p.R) == 0 { + continue + } + // TODO(maruel): s.halfDuplex. + for _, b := range p.W { + for j := uint(0); j < 8; j++ { + // For each bit, handle clock phase and data phase. + bit := byte(0) + if !s.lsbFirst { + // MSBF + if b&(0x80>>j) != 0 { + bit = mosi + } + } else { + // LSBF + if b&(1<> uint(j) + } else { + // LSBF + b |= 1 << uint(j) + } + } + } + p.R[i] = b + } + } + return nil +} + +// CLK returns the SCK (clock) pin. +func (s *spiSyncConn) CLK() gpio.PinOut { + return s.f.D2 // RTS +} + +// MOSI returns the SDO (master out, slave in) pin. +func (s *spiSyncConn) MOSI() gpio.PinOut { + return s.f.D0 // TX +} + +// MISO returns the SDI (master in, slave out) pin. +func (s *spiSyncConn) MISO() gpio.PinIn { + return s.f.D1 // RX +} + +// CS returns the CSN (chip select) pin. +func (s *spiSyncConn) CS() gpio.PinOut { + return s.f.D3 // CTS +} + +// + +func verifyBuffers(w, r []byte) error { + if len(w) != 0 { + if len(r) != 0 { + if len(w) != len(r) { + return errors.New("d2xx: both buffers must have the same size") + } + } + // TODO(maruel): When the buffer is >64Kb, cut it in parts and do not + // request a flush. Still try to read though. + if len(w) > 65536 { + return errors.New("d2xx: maximum buffer size is 64Kb") + } + } else if len(r) != 0 { + // TODO(maruel): Remove, this is not a problem. + if len(r) > 65536 { + return errors.New("d2xx: maximum buffer size is 64Kb") + } + } + return nil +} + +var _ spi.PortCloser = &spiMPSEEPort{} +var _ spi.Conn = &spiMPSEEConn{} +var _ spi.PortCloser = &spiSyncPort{} +var _ spi.Conn = &spiSyncConn{} diff --git a/vendor/periph.io/x/host/v3/host.go b/vendor/periph.io/x/host/v3/host.go new file mode 100644 index 0000000..ba5892b --- /dev/null +++ b/vendor/periph.io/x/host/v3/host.go @@ -0,0 +1,19 @@ +// 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 host + +import ( + "periph.io/x/conn/v3/driver/driverreg" + _ "periph.io/x/host/v3/ftdi" +) + +// Init calls driverreg.Init() and returns it as-is. +// +// The only difference is that by calling host.Init(), you are guaranteed to +// have all the host drivers implemented in this library to be implicitly +// loaded. +func Init() (*driverreg.State, error) { + return driverreg.Init() +} diff --git a/vendor/periph.io/x/periph/host/host_arm.go b/vendor/periph.io/x/host/v3/host_arm.go similarity index 51% rename from vendor/periph.io/x/periph/host/host_arm.go rename to vendor/periph.io/x/host/v3/host_arm.go index 3227b9a..843c446 100644 --- a/vendor/periph.io/x/periph/host/host_arm.go +++ b/vendor/periph.io/x/host/v3/host_arm.go @@ -6,15 +6,16 @@ package host import ( // Make sure CPU and board drivers are registered. - _ "periph.io/x/periph/host/allwinner" - _ "periph.io/x/periph/host/am335x" - _ "periph.io/x/periph/host/bcm283x" - _ "periph.io/x/periph/host/beagle/bone" - _ "periph.io/x/periph/host/beagle/green" - _ "periph.io/x/periph/host/chip" - _ "periph.io/x/periph/host/odroidc1" + _ "periph.io/x/host/v3/allwinner" + _ "periph.io/x/host/v3/am335x" + _ "periph.io/x/host/v3/bcm283x" + _ "periph.io/x/host/v3/beagle/bone" + _ "periph.io/x/host/v3/beagle/green" + _ "periph.io/x/host/v3/chip" + _ "periph.io/x/host/v3/odroidc1" + // While this board is ARM64, it may run ARM 32 bits binaries so load it on // 32 bits builds too. - _ "periph.io/x/periph/host/pine64" - _ "periph.io/x/periph/host/rpi" + _ "periph.io/x/host/v3/pine64" + _ "periph.io/x/host/v3/rpi" ) diff --git a/vendor/periph.io/x/periph/host/host_arm64.go b/vendor/periph.io/x/host/v3/host_arm64.go similarity index 63% rename from vendor/periph.io/x/periph/host/host_arm64.go rename to vendor/periph.io/x/host/v3/host_arm64.go index fdeb96f..a4caebf 100644 --- a/vendor/periph.io/x/periph/host/host_arm64.go +++ b/vendor/periph.io/x/host/v3/host_arm64.go @@ -6,8 +6,8 @@ package host import ( // Make sure CPU and board drivers are registered. - _ "periph.io/x/periph/host/allwinner" - _ "periph.io/x/periph/host/bcm283x" - _ "periph.io/x/periph/host/pine64" - _ "periph.io/x/periph/host/rpi" + _ "periph.io/x/host/v3/allwinner" + _ "periph.io/x/host/v3/bcm283x" + _ "periph.io/x/host/v3/pine64" + _ "periph.io/x/host/v3/rpi" ) diff --git a/vendor/periph.io/x/periph/host/host_linux.go b/vendor/periph.io/x/host/v3/host_linux.go similarity index 87% rename from vendor/periph.io/x/periph/host/host_linux.go rename to vendor/periph.io/x/host/v3/host_linux.go index 72f93a7..9a569c1 100644 --- a/vendor/periph.io/x/periph/host/host_linux.go +++ b/vendor/periph.io/x/host/v3/host_linux.go @@ -6,5 +6,5 @@ package host import ( // Make sure sysfs drivers are registered. - _ "periph.io/x/periph/host/sysfs" + _ "periph.io/x/host/v3/sysfs" ) diff --git a/vendor/periph.io/x/periph/host/odroidc1/doc.go b/vendor/periph.io/x/host/v3/odroidc1/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/odroidc1/doc.go rename to vendor/periph.io/x/host/v3/odroidc1/doc.go diff --git a/vendor/periph.io/x/periph/host/odroidc1/odroidc1.go b/vendor/periph.io/x/host/v3/odroidc1/odroidc1.go similarity index 95% rename from vendor/periph.io/x/periph/host/odroidc1/odroidc1.go rename to vendor/periph.io/x/host/v3/odroidc1/odroidc1.go index fee4667..6ea9509 100644 --- a/vendor/periph.io/x/periph/host/odroidc1/odroidc1.go +++ b/vendor/periph.io/x/host/v3/odroidc1/odroidc1.go @@ -9,13 +9,13 @@ import ( "strconv" "strings" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/conn/pin/pinreg" - "periph.io/x/periph/host/distro" - "periph.io/x/periph/host/sysfs" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/pin" + "periph.io/x/conn/v3/pin/pinreg" + "periph.io/x/host/v3/distro" + "periph.io/x/host/v3/sysfs" ) // The J2 header is rPi compatible, except for the two analog pins and the 1.8V @@ -188,7 +188,7 @@ func (d *driver) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drv) + driverreg.MustRegister(&drv) } } diff --git a/vendor/periph.io/x/periph/host/odroidc1/odroidc1_arm.go b/vendor/periph.io/x/host/v3/odroidc1/odroidc1_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/odroidc1/odroidc1_arm.go rename to vendor/periph.io/x/host/v3/odroidc1/odroidc1_arm.go diff --git a/vendor/periph.io/x/periph/host/odroidc1/odroidc1_other.go b/vendor/periph.io/x/host/v3/odroidc1/odroidc1_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/odroidc1/odroidc1_other.go rename to vendor/periph.io/x/host/v3/odroidc1/odroidc1_other.go diff --git a/vendor/periph.io/x/periph/host/pine64/doc.go b/vendor/periph.io/x/host/v3/pine64/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/pine64/doc.go rename to vendor/periph.io/x/host/v3/pine64/doc.go diff --git a/vendor/periph.io/x/periph/host/pine64/pine64.go b/vendor/periph.io/x/host/v3/pine64/pine64.go similarity index 97% rename from vendor/periph.io/x/periph/host/pine64/pine64.go rename to vendor/periph.io/x/host/v3/pine64/pine64.go index 81864a4..bfa05ce 100644 --- a/vendor/periph.io/x/periph/host/pine64/pine64.go +++ b/vendor/periph.io/x/host/v3/pine64/pine64.go @@ -8,11 +8,11 @@ import ( "errors" "strings" - "periph.io/x/periph" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/conn/pin/pinreg" - "periph.io/x/periph/host/allwinner" - "periph.io/x/periph/host/distro" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/pin" + "periph.io/x/conn/v3/pin/pinreg" + "periph.io/x/host/v3/allwinner" + "periph.io/x/host/v3/distro" ) // Present returns true if running on a Pine64 board. @@ -264,7 +264,7 @@ func (d *driver) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drv) + driverreg.MustRegister(&drv) } } diff --git a/vendor/periph.io/x/periph/host/pine64/pine64_arm.go b/vendor/periph.io/x/host/v3/pine64/pine64_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/pine64/pine64_arm.go rename to vendor/periph.io/x/host/v3/pine64/pine64_arm.go diff --git a/vendor/periph.io/x/periph/host/pine64/pine64_arm64.go b/vendor/periph.io/x/host/v3/pine64/pine64_arm64.go similarity index 100% rename from vendor/periph.io/x/periph/host/pine64/pine64_arm64.go rename to vendor/periph.io/x/host/v3/pine64/pine64_arm64.go diff --git a/vendor/periph.io/x/periph/host/pine64/pine64_other.go b/vendor/periph.io/x/host/v3/pine64/pine64_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/pine64/pine64_other.go rename to vendor/periph.io/x/host/v3/pine64/pine64_other.go diff --git a/vendor/periph.io/x/periph/host/pmem/alloc.go b/vendor/periph.io/x/host/v3/pmem/alloc.go similarity index 97% rename from vendor/periph.io/x/periph/host/pmem/alloc.go rename to vendor/periph.io/x/host/v3/pmem/alloc.go index 78ebfb0..5cdde3c 100644 --- a/vendor/periph.io/x/periph/host/pmem/alloc.go +++ b/vendor/periph.io/x/host/v3/pmem/alloc.go @@ -102,7 +102,7 @@ func uallocMemLocked(size int) ([]byte, error) { for i := range b { b[i] = 0 } - if err := mlock(b); err != nil { + if err = mlock(b); err != nil { // Ignore the unmap error. _ = munmap(b) return nil, wrapf("locking %d bytes failed: %v", size, err) @@ -165,8 +165,8 @@ func virtToPhys(virt uintptr) (uint64, error) { } func toRaw(b []byte) uintptr { - header := *(*reflect.SliceHeader)(unsafe.Pointer(&b)) - return header.Data + h := (*reflect.SliceHeader)(unsafe.Pointer(&b)) + return h.Data } // isWSL returns true if running under Windows Subsystem for Linux. diff --git a/vendor/periph.io/x/periph/host/pmem/doc.go b/vendor/periph.io/x/host/v3/pmem/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/pmem/doc.go rename to vendor/periph.io/x/host/v3/pmem/doc.go diff --git a/vendor/periph.io/x/periph/host/pmem/mem_linux.go b/vendor/periph.io/x/host/v3/pmem/mem_linux.go similarity index 100% rename from vendor/periph.io/x/periph/host/pmem/mem_linux.go rename to vendor/periph.io/x/host/v3/pmem/mem_linux.go diff --git a/vendor/periph.io/x/periph/host/pmem/mem_other.go b/vendor/periph.io/x/host/v3/pmem/mem_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/pmem/mem_other.go rename to vendor/periph.io/x/host/v3/pmem/mem_other.go diff --git a/vendor/periph.io/x/periph/host/pmem/pagemap.go b/vendor/periph.io/x/host/v3/pmem/pagemap.go similarity index 100% rename from vendor/periph.io/x/periph/host/pmem/pagemap.go rename to vendor/periph.io/x/host/v3/pmem/pagemap.go diff --git a/vendor/periph.io/x/periph/host/pmem/smoketest.go b/vendor/periph.io/x/host/v3/pmem/smoketest.go similarity index 100% rename from vendor/periph.io/x/periph/host/pmem/smoketest.go rename to vendor/periph.io/x/host/v3/pmem/smoketest.go diff --git a/vendor/periph.io/x/periph/host/pmem/view.go b/vendor/periph.io/x/host/v3/pmem/view.go similarity index 93% rename from vendor/periph.io/x/periph/host/pmem/view.go rename to vendor/periph.io/x/host/v3/pmem/view.go index 6d207ed..6728f8b 100644 --- a/vendor/periph.io/x/periph/host/pmem/view.go +++ b/vendor/periph.io/x/host/v3/pmem/view.go @@ -12,7 +12,7 @@ import ( "sync" "unsafe" - "periph.io/x/periph/host/fs" + "periph.io/x/host/v3/fs" ) // Slice can be transparently viewed as []byte, []uint32 or a struct. @@ -20,10 +20,12 @@ type Slice []byte // Uint32 returns a view of the byte slice as a []uint32. func (s *Slice) Uint32() []uint32 { - header := *(*reflect.SliceHeader)(unsafe.Pointer(s)) - header.Len /= 4 - header.Cap /= 4 - return *(*[]uint32)(unsafe.Pointer(&header)) + // It's important to make a copy here. + h := new(reflect.SliceHeader) + h.Data = (*reflect.SliceHeader)(unsafe.Pointer(s)).Data + h.Len = (*reflect.SliceHeader)(unsafe.Pointer(s)).Len / 4 + h.Cap = (*reflect.SliceHeader)(unsafe.Pointer(s)).Cap / 4 + return *(*[]uint32)(unsafe.Pointer(h)) } // Bytes implements Mem. @@ -178,13 +180,13 @@ func mapGPIOLinux() (*View, error) { if gpioMemView == nil && gpioMemErr == nil { if f, err := openFile("/dev/gpiomem", os.O_RDWR|os.O_SYNC); err == nil { defer f.Close() - if i, err := mmap(f.Fd(), 0, pageSize); err == nil { + if i, err2 := mmap(f.Fd(), 0, pageSize); err2 == nil { gpioMemView = &View{Slice: i, orig: i, phys: 0} } else { - gpioMemErr = wrapf("failed to memory map in user space GPIO memory: %v", err) + gpioMemErr = wrapf("failed to memory map in user space GPIO memory: %w", err2) } } else { - gpioMemErr = wrapf("failed to open GPIO memory: %v", err) + gpioMemErr = wrapf("failed to open GPIO memory: %w", err) } } return gpioMemView, gpioMemErr @@ -200,7 +202,7 @@ func mapLinux(base uint64, size int) (*View, error) { offset := int(base & 0xFFF) i, err := mmap(f.Fd(), int64(base&^0xFFF), (size+offset+0xFFF)&^0xFFF) if err != nil { - return nil, wrapf("mapping at 0x%x failed: %v", base, err) + return nil, wrapf("mapping at 0x%x failed: %w", base, err) } return &View{Slice: i[offset : offset+size], orig: i, phys: base + uint64(offset)}, nil } diff --git a/vendor/periph.io/x/periph/host/rpi/doc.go b/vendor/periph.io/x/host/v3/rpi/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/rpi/doc.go rename to vendor/periph.io/x/host/v3/rpi/doc.go diff --git a/vendor/periph.io/x/periph/host/rpi/rpi.go b/vendor/periph.io/x/host/v3/rpi/rpi.go similarity index 99% rename from vendor/periph.io/x/periph/host/rpi/rpi.go rename to vendor/periph.io/x/host/v3/rpi/rpi.go index 6e2bd26..238ec48 100644 --- a/vendor/periph.io/x/periph/host/rpi/rpi.go +++ b/vendor/periph.io/x/host/v3/rpi/rpi.go @@ -11,12 +11,12 @@ import ( "fmt" "os" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/conn/pin/pinreg" - "periph.io/x/periph/host/bcm283x" - "periph.io/x/periph/host/distro" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/pin" + "periph.io/x/conn/v3/pin/pinreg" + "periph.io/x/host/v3/bcm283x" + "periph.io/x/host/v3/distro" ) // Present returns true if running on a Raspberry Pi board. @@ -806,7 +806,7 @@ func (d *driver) Init() (bool, error) { func init() { if isArm { - periph.MustRegister(&drv) + driverreg.MustRegister(&drv) } } diff --git a/vendor/periph.io/x/periph/host/rpi/rpi_arm.go b/vendor/periph.io/x/host/v3/rpi/rpi_arm.go similarity index 100% rename from vendor/periph.io/x/periph/host/rpi/rpi_arm.go rename to vendor/periph.io/x/host/v3/rpi/rpi_arm.go diff --git a/vendor/periph.io/x/periph/host/rpi/rpi_arm64.go b/vendor/periph.io/x/host/v3/rpi/rpi_arm64.go similarity index 100% rename from vendor/periph.io/x/periph/host/rpi/rpi_arm64.go rename to vendor/periph.io/x/host/v3/rpi/rpi_arm64.go diff --git a/vendor/periph.io/x/periph/host/rpi/rpi_other.go b/vendor/periph.io/x/host/v3/rpi/rpi_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/rpi/rpi_other.go rename to vendor/periph.io/x/host/v3/rpi/rpi_other.go diff --git a/vendor/periph.io/x/periph/host/sysfs/doc.go b/vendor/periph.io/x/host/v3/sysfs/doc.go similarity index 100% rename from vendor/periph.io/x/periph/host/sysfs/doc.go rename to vendor/periph.io/x/host/v3/sysfs/doc.go diff --git a/vendor/periph.io/x/periph/host/sysfs/fs_linux.go b/vendor/periph.io/x/host/v3/sysfs/fs_linux.go similarity index 96% rename from vendor/periph.io/x/periph/host/sysfs/fs_linux.go rename to vendor/periph.io/x/host/v3/sysfs/fs_linux.go index e0da590..2416a7d 100644 --- a/vendor/periph.io/x/periph/host/sysfs/fs_linux.go +++ b/vendor/periph.io/x/host/v3/sysfs/fs_linux.go @@ -111,32 +111,13 @@ func (e *eventsListener) init() error { e.mu.Unlock() return nil } - var err error - e.epollFd, err = syscall.EpollCreate(1) - switch { - case err == nil: - break - case err.Error() == "function not implemented": - // Some arch (arm64) do not implement EpollCreate(). - if e.epollFd, err = syscall.EpollCreate1(0); err != nil { - e.mu.Unlock() - return err - } - default: - e.mu.Unlock() - return err - } - e.r, e.w, err = os.Pipe() + err := e.initLocked() + atomic.StoreInt32(&e.initialized, 1) if err != nil { e.mu.Unlock() return err } - // Only need epollIN. epollPRI has no effect on pipes. - if err = e.addFdInner(e.r.Fd(), epollET|epollIN); err != nil { - // This object will not be reusable at this point. - e.mu.Unlock() - return err - } + wakeUp := make(chan time.Time) e.wakeUp = wakeUp e.fds = map[int32]chan<- time.Time{} @@ -146,11 +127,31 @@ func (e *eventsListener) init() error { // // This forces loop() to be started before addFd() can be called by users. go e.loop() - // Initialization is now good to go. - atomic.StoreInt32(&e.initialized, 1) return nil } +func (e *eventsListener) initLocked() error { + var err error + e.epollFd, err = syscall.EpollCreate(1) + switch { + case err == nil: + break + case err.Error() == "function not implemented": + // Some arch (arm64) do not implement EpollCreate(). + if e.epollFd, err = syscall.EpollCreate1(0); err != nil { + return err + } + default: + return err + } + e.r, e.w, err = os.Pipe() + if err != nil { + return err + } + // Only need epollIN. epollPRI has no effect on pipes. + return e.addFdInner(e.r.Fd(), epollET|epollIN) +} + // loop is the main event loop. func (e *eventsListener) loop() { var events []syscall.EpollEvent @@ -288,9 +289,6 @@ func (e *eventsListener) removeFd(fd uintptr) error { // // Must not be called with the lock held. func (e *eventsListener) wakeUpLoop(c <-chan time.Time) time.Time { - if atomic.LoadInt32(&e.initialized) == 0 { - return time.Time{} - } // TODO(maruel): Figure out a way to wake up that doesn't require emptying. var b [1]byte _, _ = e.w.Write(b[:]) diff --git a/vendor/periph.io/x/periph/host/sysfs/fs_other.go b/vendor/periph.io/x/host/v3/sysfs/fs_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/sysfs/fs_other.go rename to vendor/periph.io/x/host/v3/sysfs/fs_other.go diff --git a/vendor/periph.io/x/periph/host/sysfs/gpio.go b/vendor/periph.io/x/host/v3/sysfs/gpio.go similarity index 97% rename from vendor/periph.io/x/periph/host/sysfs/gpio.go rename to vendor/periph.io/x/host/v3/sysfs/gpio.go index c751bad..7e947ad 100644 --- a/vendor/periph.io/x/periph/host/sysfs/gpio.go +++ b/vendor/periph.io/x/host/v3/sysfs/gpio.go @@ -14,13 +14,13 @@ import ( "sync" "time" - "periph.io/x/periph" - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/fs" + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/fs" ) // Pins is all the pins exported by GPIO sysfs. @@ -461,7 +461,7 @@ func (d *driverGPIO) Init() (bool, error) { // of an array. Pins = map[int]*Pin{} for _, item := range items { - if err := d.parseGPIOChip(item + "/"); err != nil { + if err = d.parseGPIOChip(item + "/"); err != nil { return true, err } } @@ -507,7 +507,7 @@ func (d *driverGPIO) parseGPIOChip(path string) error { func init() { if isLinux { - periph.MustRegister(&drvGPIO) + driverreg.MustRegister(&drvGPIO) } } diff --git a/vendor/periph.io/x/periph/host/sysfs/i2c.go b/vendor/periph.io/x/host/v3/sysfs/i2c.go similarity index 96% rename from vendor/periph.io/x/periph/host/sysfs/i2c.go rename to vendor/periph.io/x/host/v3/sysfs/i2c.go index 2112793..dfc4ff4 100644 --- a/vendor/periph.io/x/periph/host/sysfs/i2c.go +++ b/vendor/periph.io/x/host/v3/sysfs/i2c.go @@ -15,12 +15,12 @@ import ( "sync" "unsafe" - "periph.io/x/periph" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/i2c" - "periph.io/x/periph/conn/i2c/i2creg" - "periph.io/x/periph/conn/physic" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/i2c" + "periph.io/x/conn/v3/i2c/i2creg" + "periph.io/x/conn/v3/physic" ) // I2CSetSpeedHook can be set by a driver to enable changing the I²C buses @@ -47,11 +47,11 @@ func I2CSetSpeedHook(h func(f physic.Frequency) error) error { // The resulting object is safe for concurent use. // // Do not use sysfs.NewI2C() directly as the package sysfs is providing a -// https://periph.io/x/periph/conn/i2c Linux-specific implementation. +// https://periph.io/x/conn/v3/i2c Linux-specific implementation. // // periph.io works on many OSes! // -// Instead, use https://periph.io/x/periph/conn/i2c/i2creg#Open. This permits +// Instead, use https://periph.io/x/conn/v3/i2c/i2creg#Open. This permits // it to work on all operating systems, or devices like I²C over USB. func NewI2C(busNumber int) (*I2C, error) { if isLinux { @@ -378,7 +378,7 @@ func (o openerI2C) Open() (i2c.BusCloser, error) { func init() { if isLinux { - periph.MustRegister(&drvI2C) + driverreg.MustRegister(&drvI2C) } } diff --git a/vendor/periph.io/x/periph/host/sysfs/led.go b/vendor/periph.io/x/host/v3/sysfs/led.go similarity index 96% rename from vendor/periph.io/x/periph/host/sysfs/led.go rename to vendor/periph.io/x/host/v3/sysfs/led.go index f9e22cb..f934a6e 100644 --- a/vendor/periph.io/x/periph/host/sysfs/led.go +++ b/vendor/periph.io/x/host/v3/sysfs/led.go @@ -14,12 +14,12 @@ import ( "sync" "time" - "periph.io/x/periph" - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/pin" - "periph.io/x/periph/host/fs" + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/pin" + "periph.io/x/host/v3/fs" ) // LEDs is all the leds discovered on this host via sysfs. @@ -244,7 +244,7 @@ func (d *driverLED) Init() (bool, error) { func init() { if isLinux { - periph.MustRegister(&drvLED) + driverreg.MustRegister(&drvLED) } } diff --git a/vendor/periph.io/x/periph/host/sysfs/spi.go b/vendor/periph.io/x/host/v3/sysfs/spi.go similarity index 97% rename from vendor/periph.io/x/periph/host/sysfs/spi.go rename to vendor/periph.io/x/host/v3/sysfs/spi.go index 9eb89cb..b45681a 100644 --- a/vendor/periph.io/x/periph/host/sysfs/spi.go +++ b/vendor/periph.io/x/host/v3/sysfs/spi.go @@ -17,14 +17,14 @@ import ( "sync" "unsafe" - "periph.io/x/periph" - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/gpio" - "periph.io/x/periph/conn/gpio/gpioreg" - "periph.io/x/periph/conn/physic" - "periph.io/x/periph/conn/spi" - "periph.io/x/periph/conn/spi/spireg" - "periph.io/x/periph/host/fs" + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/gpio" + "periph.io/x/conn/v3/gpio/gpioreg" + "periph.io/x/conn/v3/physic" + "periph.io/x/conn/v3/spi" + "periph.io/x/conn/v3/spi/spireg" + "periph.io/x/host/v3/fs" ) // NewSPI opens a SPI port via its devfs interface as described at @@ -36,7 +36,7 @@ import ( // busNumber is the bus number as exported by devfs. For example if the path is // /dev/spidev0.1, busNumber should be 0 and chipSelect should be 1. // -// It is recommended to use https://periph.io/x/periph/conn/spi/spireg#Open +// It is recommended to use https://periph.io/x/conn/v3/spi/spireg#Open // instead of using NewSPI() directly as the package sysfs is providing a // Linux-specific implementation. periph.io works on many OSes! This permits // it to work on all operating systems, or devices like SPI over USB. @@ -548,9 +548,9 @@ func (d *driverSPI) Init() (bool, error) { // Do not use "/sys/bus/spi/devices/spi" as Raspbian's provided udev rules // only modify the ACL of /dev/spidev* but not the ones in /sys/bus/... prefix := "/dev/spidev" - items, err := filepath.Glob(prefix + "*") - if err != nil { - return true, err + items, err2 := filepath.Glob(prefix + "*") + if err2 != nil { + return true, err2 } if len(items) == 0 { return false, errors.New("no SPI port found") @@ -604,7 +604,7 @@ func (o *openerSPI) Open() (spi.PortCloser, error) { func init() { if isLinux { - periph.MustRegister(&drvSPI) + driverreg.MustRegister(&drvSPI) } } diff --git a/vendor/periph.io/x/periph/host/sysfs/sysfs.go b/vendor/periph.io/x/host/v3/sysfs/sysfs.go similarity index 97% rename from vendor/periph.io/x/periph/host/sysfs/sysfs.go rename to vendor/periph.io/x/host/v3/sysfs/sysfs.go index 3cfaf49..dd37af9 100644 --- a/vendor/periph.io/x/periph/host/sysfs/sysfs.go +++ b/vendor/periph.io/x/host/v3/sysfs/sysfs.go @@ -7,7 +7,7 @@ package sysfs import ( "io" - "periph.io/x/periph/host/fs" + "periph.io/x/host/v3/fs" ) var ioctlOpen = ioctlOpenDefault diff --git a/vendor/periph.io/x/periph/host/sysfs/sysfs_linux.go b/vendor/periph.io/x/host/v3/sysfs/sysfs_linux.go similarity index 100% rename from vendor/periph.io/x/periph/host/sysfs/sysfs_linux.go rename to vendor/periph.io/x/host/v3/sysfs/sysfs_linux.go diff --git a/vendor/periph.io/x/periph/host/sysfs/sysfs_other.go b/vendor/periph.io/x/host/v3/sysfs/sysfs_other.go similarity index 100% rename from vendor/periph.io/x/periph/host/sysfs/sysfs_other.go rename to vendor/periph.io/x/host/v3/sysfs/sysfs_other.go diff --git a/vendor/periph.io/x/periph/host/sysfs/thermal_sensor.go b/vendor/periph.io/x/host/v3/sysfs/thermal_sensor.go similarity index 97% rename from vendor/periph.io/x/periph/host/sysfs/thermal_sensor.go rename to vendor/periph.io/x/host/v3/sysfs/thermal_sensor.go index c3d7d0b..d5c6ac9 100644 --- a/vendor/periph.io/x/periph/host/sysfs/thermal_sensor.go +++ b/vendor/periph.io/x/host/v3/sysfs/thermal_sensor.go @@ -14,9 +14,9 @@ import ( "sync" "time" - "periph.io/x/periph" - "periph.io/x/periph/conn" - "periph.io/x/periph/conn/physic" + "periph.io/x/conn/v3" + "periph.io/x/conn/v3/driver/driverreg" + "periph.io/x/conn/v3/physic" ) // ThermalSensors is all the sensors discovered on this host via sysfs. It @@ -251,7 +251,7 @@ func (d *driverThermalSensor) discoverDevices(glob, typeFilename string) error { func init() { if isLinux { - periph.MustRegister(&drvThermalSensor) + driverreg.MustRegister(&drvThermalSensor) } } diff --git a/vendor/periph.io/x/periph/host/videocore/videocore.go b/vendor/periph.io/x/host/v3/videocore/videocore.go similarity index 99% rename from vendor/periph.io/x/periph/host/videocore/videocore.go rename to vendor/periph.io/x/host/v3/videocore/videocore.go index 3dcea0d..d11eb0e 100644 --- a/vendor/periph.io/x/periph/host/videocore/videocore.go +++ b/vendor/periph.io/x/host/v3/videocore/videocore.go @@ -20,8 +20,8 @@ import ( "sync" "unsafe" - "periph.io/x/periph/host/fs" - "periph.io/x/periph/host/pmem" + "periph.io/x/host/v3/fs" + "periph.io/x/host/v3/pmem" ) // Mem represents contiguous physically locked memory that was allocated by diff --git a/vendor/periph.io/x/periph/.gitignore b/vendor/periph.io/x/periph/.gitignore deleted file mode 100644 index ba077a4..0000000 --- a/vendor/periph.io/x/periph/.gitignore +++ /dev/null @@ -1 +0,0 @@ -bin diff --git a/vendor/periph.io/x/periph/.gohci.yml b/vendor/periph.io/x/periph/.gohci.yml deleted file mode 100644 index 88c5595..0000000 --- a/vendor/periph.io/x/periph/.gohci.yml +++ /dev/null @@ -1,258 +0,0 @@ -# Copyright 2020 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. - -# See https://github.com/periph/gohci -version: 1 -workers: -# BeagleBone Green Wireles by SeedStudio. -# https://beagleboard.org/green-wireless -- name: beaglebone-4373 - checks: - - cmd: - - go - - install - - -v - - ./cmd/headers-list - - ./cmd/i2c-list - - ./cmd/periph-info - - ./cmd/periph-smoketest - - ./cmd/spi-list - - cmd: - - periph-info - - cmd: - - headers-list - - -f - - cmd: - - i2c-list - - cmd: - - spi-list - - cmd: - - periph-smoketest - - gpio - - -pin1 - - P8_45 - - -pin2 - - P8_46 -# C.H.I.P. by Next Thing Co. The company closed its doors. -- name: chip-a87d - checks: - - cmd: - - go - - install - - -v - - ./cmd/gpio-list - - ./cmd/headers-list - - ./cmd/i2c-list - - ./cmd/periph-info - - ./cmd/periph-smoketest - - ./cmd/spi-list - - cmd: - - periph-info - - cmd: - - gpio-list - - -f - - cmd: - - headers-list - - -f - - cmd: - - i2c-list - - cmd: - - spi-list - - cmd: - - periph-smoketest - - chip - - cmd: - - periph-smoketest - - i2c-testboard - - -bus - - 1 - - cmd: - - periph-smoketest - - onewire-testboard - - -i2cbus - - 1 - - cmd: - - periph-smoketest - - sysfs-benchmark - - -p - - 1013 - - -short - - cmd: - - periph-smoketest - - sysfs-benchmark - - -p - - 132 - - -short - - cmd: - - periph-smoketest - - allwinner-benchmark - - -p - - 132 - - -short - - cmd: - - periph-smoketest - - spi-testboard -# Old MacBook Pro on 10.9. -- name: mbp - checks: - - cmd: - - go - - test - - -race - - ./... - - cmd: - - go - - install - - -v - - ./cmd/gpio-list - - ./cmd/headers-list - - ./cmd/i2c-list - - ./cmd/periph-info - - ./cmd/spi-list - - cmd: - - periph-info - - cmd: - - gpio-list - - -f - - cmd: - - headers-list - - -f - - cmd: - - i2c-list - - cmd: - - spi-list -# ODROID-C1+ by HardKernel -# https://www.hardkernel.com/shop/odroid-c1/ -- name: odroid-483d - checks: - - cmd: - - go - - test - - -cover - - -bench=. - - -benchtime=1000ms - - -benchmem - - ./... - - ./... - - cmd: - - go - - install - - -v - - ./cmd/gpio-list - - ./cmd/headers-list - - ./cmd/i2c-list - - ./cmd/periph-info - - ./cmd/periph-smoketest - - ./cmd/spi-list - - cmd: - - periph-info - - cmd: - - gpio-list - - -f - - cmd: - - headers-list - - -f - - cmd: - - i2c-list - - cmd: - - spi-list - - cmd: - - periph-smoketest - - odroid-c1 - - cmd: - - periph-smoketest - - i2c-testboard - - cmd: - - periph-smoketest - - onewire-testboard - - cmd: - - periph-smoketest - - spi-testboard - - cmd: - - periph-smoketest - - sysfs-benchmark - - -p - - 97 - - -short -# Raspberry Pi 3 -- name: raspberrypi-2f34 - checks: - - cmd: - - go - - install - - -v - - ./cmd/gpio-list - - ./cmd/headers-list - - ./cmd/i2c-list - - ./cmd/periph-info - - ./cmd/periph-smoketest - - ./cmd/spi-list - - cmd: - - periph-info - - cmd: - - gpio-list - - -f - - cmd: - - headers-list - - -f - - cmd: - - i2c-list - - cmd: - - spi-list - - cmd: - - periph-smoketest - - i2c-testboard - - cmd: - - periph-smoketest - - onewire-testboard - - -i2cbus - - 1 - - cmd: - - periph-smoketest - - spi-testboard - - cmd: - - periph-smoketest - - sysfs-benchmark - - -p - - 12 - - -short - - cmd: - - periph-smoketest - - bcm283x-benchmark - - -p - - 12 - - -short - - cmd: - - periph-smoketest - - gpio - - -pin1 - - P1_15 - - -pin2 - - P1_16 - - cmd: - - periph-smoketest - - bcm283x - - -quick -# Laptop on Windows 10. -- name: win10 - checks: - - cmd: - - go - - test - - -cover - - -bench=. - - -benchtime=1000ms - - -benchmem - - ./... - - cmd: - - go - - test - - -race - - ./... - - cmd: - - go - - vet - - -all - - -unsafeptr=false - - ./... diff --git a/vendor/periph.io/x/periph/.travis.yml b/vendor/periph.io/x/periph/.travis.yml deleted file mode 100644 index e0af408..0000000 --- a/vendor/periph.io/x/periph/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2019 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. - -os: linux -dist: bionic -language: go -go_import_path: periph.io/x/periph - -jobs: - include: - - go: 1.14.x - cache: - directories: - - $GOPATH/pkg/mod - # Cache tools sources. - #- $GOPATH/src/golang\.org - before_script: - - echo $TRAVIS_GO_VERSION - - go get -t -v periph.io/x/periph/... - - > - go get -u -v - golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow - script: - - > - echo 'Looking for external dependencies:'; - go list -f '{{join .Imports "\n"}}' periph.io/x/periph/... | sort | uniq | grep -v ^periph.io/x/periph | xargs go list -f '{{if not .Standard}}- {{.ImportPath}}{{end}}' - - > - echo 'Erroring on external dependencies:'; - ! go list -f '{{join .Imports "\n"}}' periph.io/x/periph/... | sort | uniq | grep -v ^periph.io/x/periph | xargs go list -f '{{if not .Standard}}Remove {{.ImportPath}}{{end}}' | grep -q Remove - - > - echo 'Erroring on /host depending on /devices:'; - ! go list -f '{{.ImportPath}} depends on {{join .Imports ", "}}' periph.io/x/periph/host/... | sort | uniq | grep periph.io/x/periph/devices - - > - echo 'Erroring on /conn depending on /devices:'; - ! go list -f '{{.ImportPath}} depends on {{join .Imports ", "}}' periph.io/x/periph/conn/... | sort | uniq | grep periph.io/x/periph/devices - - > - echo 'Erroring on /conn depending on /host:'; - ! go list -f '{{.ImportPath}} depends on {{join .Imports ", "}}' periph.io/x/periph/conn/... | sort | uniq | grep periph.io/x/periph/host - - > - echo 'Erroring on shadowed variables:'; - ! go vet -vettool=$(which shadow) ./... |& grep -v '"err"' | grep -e '^[^#]' diff --git a/vendor/periph.io/x/periph/Makefile b/vendor/periph.io/x/periph/Makefile deleted file mode 100644 index 53b7fb4..0000000 --- a/vendor/periph.io/x/periph/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# 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. - -# This Makefile captures common tasks for the periph library. The hope is that this Makefile can remain -# simple and straightforward... - -# *** This Makefile is a work in progress, please help impove it! *** - -# not sure yet what all should do... -all: - @echo Available targets: test build - -.PHONY: all test clean depend - -# test runs the platform independent tests -# (gofmt|grep is used to obtain a non-zero exit status if the formatting is off) -test: - go test ./... - @if gofmt -l . | grep .go; then \ - echo "Repo contains improperly formatted go files; run gofmt on above files" && exit 1; \ - else echo "OK gofmt"; fi - -go vet -unsafeptr=false ./... - -# BUILD -# -# The build target cross compiles each program in cmd to a binary for each platform in the bin -# directory. It is assumed that each command has a main.go file in its directory. Trying to keep all -# this relatively simple and not descend into makefile hell... - -# Get a list of all main.go in cmd subdirs -# MAINS becomes: cmd/gpio-list/main.go cmd/periph-info/main.go ... -MAINS := $(wildcard cmd/*/main.go) -# Get a list of all the commands, i.e. names of dirs that contain a main.go -# CMDS becomes: gpio-list periph-info ... -CMDS := $(patsubst cmd/%/main.go,%,$(MAINS)) -# Get a list of binaries to build -# BINS becomes: bin/gpio-list-arm bin/periph-info-arm ... bin/gpio-list-arm64 bin/periph-info-arm64 ... -ARCHS := arm arm64 amd64 win64.exe -BINS=$(foreach arch,$(ARCHS),$(foreach cmd,$(CMDS),bin/$(cmd)-$(arch))) - -build: depend bin $(BINS) -bin: - mkdir bin - -# Rules to build binaries for a command in cmd. The prereqs could be improved... -bin/%-arm: cmd/%/*.go - GOARCH=arm GOOS=linux go build -o $@ ./cmd/$* -bin/%-arm64: cmd/%/*.go - GOARCH=arm64 GOOS=linux go build -o $@ ./cmd/$* -bin/%-amd64: cmd/%/*.go - GOARCH=amd64 GOOS=linux go build -o $@ ./cmd/$* -bin/%-win64.exe: cmd/%/*.go - GOARCH=amd64 GOOS=windows go build -o $@ ./cmd/$* - -# clean removes all compiled binaries -clean: - rm bin/*-* - rmdir bin diff --git a/vendor/periph.io/x/periph/README.md b/vendor/periph.io/x/periph/README.md deleted file mode 100644 index e561aa2..0000000 --- a/vendor/periph.io/x/periph/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# periph - Peripherals I/O in Go - -[![mascot](https://raw.githubusercontent.com/periph/website/master/site/static/img/periph-mascot-280.png)](https://periph.io/) - -Documentation is at https://periph.io - -Join us for a chat on -[gophers.slack.com/messages/periph](https://gophers.slack.com/messages/periph), -get an [invite here](https://invite.slack.golangbridge.org/). - - -## New home - -The source code is now hosted in multiple repositories at -[github.com/periph](https://github.com/periph). See -https://periph.io/news/2020/a_new_start/ for more details. - - -## Authors - -`periph` was initiated with ❤️️ and passion by [Marc-Antoine -Ruel](https://github.com/maruel). The full list of contributors is in -[AUTHORS](https://github.com/google/periph/blob/master/AUTHORS) and -[CONTRIBUTORS](https://github.com/google/periph/blob/master/CONTRIBUTORS). - - -## Disclaimer - -This is not an official Google product (experimental or otherwise), it -is just code that happens to be owned by Google. - -This project is not affiliated with the Go project. diff --git a/vendor/periph.io/x/periph/conn/doc.go b/vendor/periph.io/x/periph/conn/doc.go deleted file mode 100644 index 310ac6d..0000000 --- a/vendor/periph.io/x/periph/conn/doc.go +++ /dev/null @@ -1,10 +0,0 @@ -// 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 conn defines core interfaces for protocols and connections. -// -// Is it now superseded by https://periph.io/x/conn/v3 (or later). -// -// See https://periph.io/news/2020/a_new_start/ for more details. -package conn diff --git a/vendor/periph.io/x/periph/host/host.go b/vendor/periph.io/x/periph/host/host.go deleted file mode 100644 index 64ccef9..0000000 --- a/vendor/periph.io/x/periph/host/host.go +++ /dev/null @@ -1,15 +0,0 @@ -// 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 host - -import "periph.io/x/periph" - -// Init calls periph.Init() and returns it as-is. -// -// The only difference is that by calling host.Init(), you are guaranteed to -// have all the drivers implemented in this library to be implicitly loaded. -func Init() (*periph.State, error) { - return periph.Init() -}