build: upgrade periph.io dependencies
This commit is contained in:
		
							
								
								
									
										513
									
								
								vendor/periph.io/x/conn/v3/.gohci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								vendor/periph.io/x/conn/v3/.gohci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/periph.io/x/conn/v3/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/periph.io/x/conn/v3/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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 <cassiobotaro@gmail.com>
 | 
			
		||||
Fractal Industries, Inc
 | 
			
		||||
Google Inc.
 | 
			
		||||
Josh Gardiner
 | 
			
		||||
Matt Aimonetti <mattaimonetti@gmail.com>
 | 
			
		||||
Max Ekman <max@looplab.se>
 | 
			
		||||
Rifiniti, Inc
 | 
			
		||||
Stephan Sperber
 | 
			
		||||
Thorsten von Eicken <tve@voneicken.com>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/periph.io/x/conn/v3/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								vendor/periph.io/x/conn/v3/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
# Contributing
 | 
			
		||||
 | 
			
		||||
Thanks for contributing to the project! Please look at [the periph contribution
 | 
			
		||||
guidelines](https://periph.io/project/contributing/) first.
 | 
			
		||||
							
								
								
									
										41
									
								
								vendor/periph.io/x/conn/v3/CONTRIBUTORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/periph.io/x/conn/v3/CONTRIBUTORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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 <submission email address>
 | 
			
		||||
#     Individual's name <submission email address> <email2> <emailN>
 | 
			
		||||
#
 | 
			
		||||
# 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 <cassiobotaro@gmail.com>
 | 
			
		||||
Eugene Dzhurynsky <jdevelop@gmail.com>
 | 
			
		||||
Hidetoshi Shimokawa <smkwhdts@gmail.com>
 | 
			
		||||
John Maguire <john.maguire@gmail.com>
 | 
			
		||||
Josh Gardiner <josh@zool.com>
 | 
			
		||||
Marc-Antoine Ruel <maruel@chromium.org> <maruel@gmail.com>
 | 
			
		||||
Matt Aimonetti <mattaimonetti@gmail.com>
 | 
			
		||||
Max Ekman <max@looplab.se>
 | 
			
		||||
Matias Insaurralde <matias@insaurral.de>
 | 
			
		||||
Seán C McCord <ulexus@gmail.com> <scm@cycoresys.com>
 | 
			
		||||
Stephan Sperber <sperberstephan@googlemail.com>
 | 
			
		||||
Thorsten von Eicken <tve@voneicken.com>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										202
									
								
								vendor/periph.io/x/conn/v3/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/periph.io/x/conn/v3/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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.
 | 
			
		||||
							
								
								
									
										57
									
								
								vendor/periph.io/x/conn/v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								vendor/periph.io/x/conn/v3/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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/).
 | 
			
		||||
 | 
			
		||||
[](https://periph.io/)
 | 
			
		||||
 | 
			
		||||
[](https://pkg.go.dev/periph.io/x/conn/v3)
 | 
			
		||||
[](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.
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/periph.io/x/conn/v3/codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/periph.io/x/conn/v3/codecov.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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%
 | 
			
		||||
							
								
								
									
										103
									
								
								vendor/periph.io/x/conn/v3/conn.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								vendor/periph.io/x/conn/v3/conn.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
import "strconv"
 | 
			
		||||
 | 
			
		||||
// Resource is a basic resource (like a gpio pin) or a device.
 | 
			
		||||
type Resource interface {
 | 
			
		||||
	// String returns a human readable identifier representing this resource in a
 | 
			
		||||
	// descriptive way for the user. It is the same signature as fmt.Stringer.
 | 
			
		||||
	String() string
 | 
			
		||||
	// Halt stops the resource.
 | 
			
		||||
	//
 | 
			
		||||
	// Unlike a Conn, a Resource may not be closable, On the other hand, a
 | 
			
		||||
	// resource can be halted. What halting entails depends on the resource
 | 
			
		||||
	// device but it should stop motion, sensing loop, light emission or PWM
 | 
			
		||||
	// output and go back into an inert state.
 | 
			
		||||
	Halt() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Duplex declares whether communication can happen simultaneously both ways.
 | 
			
		||||
//
 | 
			
		||||
// Some protocol can be either depending on configuration settings, like UART.
 | 
			
		||||
type Duplex int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// DuplexUnknown is used when the duplex of a connection is yet to be known.
 | 
			
		||||
	//
 | 
			
		||||
	// Some protocol can be configured either as half-duplex or full-duplex and
 | 
			
		||||
	// the connection is not yet is a determinate state.
 | 
			
		||||
	DuplexUnknown Duplex = 0
 | 
			
		||||
	// Half means that communication can only occurs one way at a time.
 | 
			
		||||
	//
 | 
			
		||||
	// Examples include 1-wire and I²C.
 | 
			
		||||
	Half Duplex = 1
 | 
			
		||||
	// Full means that communication occurs simultaneously both ways in a
 | 
			
		||||
	// synchronized manner.
 | 
			
		||||
	//
 | 
			
		||||
	// Examples include SPI (except 3-wire variant).
 | 
			
		||||
	Full Duplex = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const duplexName = "DuplexUnknownHalfFull"
 | 
			
		||||
 | 
			
		||||
var duplexIndex = [...]uint8{0, 13, 17, 21}
 | 
			
		||||
 | 
			
		||||
func (i Duplex) String() string {
 | 
			
		||||
	if i < 0 || i >= Duplex(len(duplexIndex)-1) {
 | 
			
		||||
		return "Duplex(" + strconv.Itoa(int(i)) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return duplexName[duplexIndex[i]:duplexIndex[i+1]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Conn defines the interface for a connection on a point-to-point
 | 
			
		||||
// communication channel.
 | 
			
		||||
//
 | 
			
		||||
// The connection can either be unidirectional (read-only, write-only) or
 | 
			
		||||
// bidirectional (read-write). It can either be half-duplex or full duplex.
 | 
			
		||||
//
 | 
			
		||||
// This is the lowest common denominator for all point-to-point communication
 | 
			
		||||
// channels.
 | 
			
		||||
//
 | 
			
		||||
// Implementation are expected but not required to also implement the following
 | 
			
		||||
// interfaces:
 | 
			
		||||
//
 | 
			
		||||
// - fmt.Stringer which returns something meaningful to the user like "SPI0.1",
 | 
			
		||||
// "I2C1.76", "COM6", etc.
 | 
			
		||||
//
 | 
			
		||||
// - io.Reader and io.Writer as a way to use io.Copy() for half duplex
 | 
			
		||||
// operation.
 | 
			
		||||
//
 | 
			
		||||
// - io.Closer for the owner of the communication channel.
 | 
			
		||||
type Conn interface {
 | 
			
		||||
	String() string
 | 
			
		||||
	// Tx does a single transaction.
 | 
			
		||||
	//
 | 
			
		||||
	// For full duplex protocols (generally SPI, UART), the two buffers must have
 | 
			
		||||
	// the same length as both reading and writing happen simultaneously.
 | 
			
		||||
	//
 | 
			
		||||
	// For half duplex protocols (I²C), there is no restriction as reading
 | 
			
		||||
	// happens after writing, and r can be nil.
 | 
			
		||||
	//
 | 
			
		||||
	// Query Limits.MaxTxSize() to know if there is a limit on the buffer size
 | 
			
		||||
	// per Tx() call.
 | 
			
		||||
	Tx(w, r []byte) error
 | 
			
		||||
	// Duplex returns the current duplex setting for this point-to-point
 | 
			
		||||
	// connection.
 | 
			
		||||
	//
 | 
			
		||||
	// It is expected to be either Half or Full unless the connection itself is
 | 
			
		||||
	// in an unknown state.
 | 
			
		||||
	Duplex() Duplex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Limits returns information about the connection's limits.
 | 
			
		||||
type Limits interface {
 | 
			
		||||
	// MaxTxSize returns the maximum allowed data size to be sent as a single
 | 
			
		||||
	// I/O.
 | 
			
		||||
	//
 | 
			
		||||
	// Returns 0 if undefined.
 | 
			
		||||
	MaxTxSize() int
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								vendor/periph.io/x/conn/v3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/periph.io/x/conn/v3/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										45
									
								
								vendor/periph.io/x/conn/v3/driver/driver.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								vendor/periph.io/x/conn/v3/driver/driver.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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(<reason>).
 | 
			
		||||
	//
 | 
			
		||||
	// On failure, it must return true, errors.New(<reason>). 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										215
									
								
								vendor/periph.io/x/conn/v3/driver/driverreg/driverreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								vendor/periph.io/x/conn/v3/driver/driverreg/driverreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,215 @@
 | 
			
		||||
// 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 driverreg is a registry for all host driver implementation that can
 | 
			
		||||
// be automatically discovered.
 | 
			
		||||
package driverreg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"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.Impl
 | 
			
		||||
	Err error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d DriverFailure) String() string {
 | 
			
		||||
	out := d.D.String() + ": "
 | 
			
		||||
	if d.Err != nil {
 | 
			
		||||
		out += d.Err.Error()
 | 
			
		||||
	} else {
 | 
			
		||||
		out += "<nil>"
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// State is the state of loaded device drivers.
 | 
			
		||||
//
 | 
			
		||||
// Each list is sorted by the driver name.
 | 
			
		||||
type State struct {
 | 
			
		||||
	Loaded  []driver.Impl
 | 
			
		||||
	Skipped []DriverFailure
 | 
			
		||||
	Failed  []DriverFailure
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Init initialises all the relevant drivers.
 | 
			
		||||
//
 | 
			
		||||
// Drivers are started concurrently.
 | 
			
		||||
//
 | 
			
		||||
// It is safe to call this function multiple times, the previous state is
 | 
			
		||||
// returned on later calls.
 | 
			
		||||
//
 | 
			
		||||
// Users will want to use host.Init(), which guarantees a baseline of included
 | 
			
		||||
// host drivers.
 | 
			
		||||
func Init() (*State, error) {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if state != nil {
 | 
			
		||||
		return state, nil
 | 
			
		||||
	}
 | 
			
		||||
	return initImpl()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register registers a driver to be initialized automatically on Init().
 | 
			
		||||
//
 | 
			
		||||
// 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.Impl) error {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if state != nil {
 | 
			
		||||
		return errors.New("periph: can't call Register() after Init()")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n := d.String()
 | 
			
		||||
	if _, ok := byName[n]; ok {
 | 
			
		||||
		return errors.New("periph: driver with same name " + strconv.Quote(n) + " was already registered")
 | 
			
		||||
	}
 | 
			
		||||
	byName[n] = d
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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.Impl) {
 | 
			
		||||
	if err := Register(d); err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// mu guards byName and state.
 | 
			
		||||
	// - byName is only mutated by Register().
 | 
			
		||||
	// - state is only mutated by Init().
 | 
			
		||||
	//
 | 
			
		||||
	// Once Init() is called, Register() refuses registering more drivers, thus
 | 
			
		||||
	// byName is immutable once Init() started.
 | 
			
		||||
	mu     sync.Mutex
 | 
			
		||||
	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.Impl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// explodeStages creates one or multiple stages by processing byName.
 | 
			
		||||
//
 | 
			
		||||
// It searches if there's any driver than has dependency on another driver and
 | 
			
		||||
// create stages from this DAG.
 | 
			
		||||
//
 | 
			
		||||
// It also verifies that there is not cycle in the DAG.
 | 
			
		||||
//
 | 
			
		||||
// When this function starts, allDriver and byName are guaranteed to be
 | 
			
		||||
// immutable. state must not be touched by this function.
 | 
			
		||||
func explodeStages() ([]*stage, error) {
 | 
			
		||||
	// First, create the DAG.
 | 
			
		||||
	dag := map[string]map[string]struct{}{}
 | 
			
		||||
	for name, d := range byName {
 | 
			
		||||
		m := map[string]struct{}{}
 | 
			
		||||
		for _, p := range d.Prerequisites() {
 | 
			
		||||
			if _, ok := byName[p]; !ok {
 | 
			
		||||
				return nil, errors.New("periph: unsatisfied dependency " + strconv.Quote(name) + "->" + strconv.Quote(p) + "; it is missing; skipping")
 | 
			
		||||
			}
 | 
			
		||||
			m[p] = struct{}{}
 | 
			
		||||
		}
 | 
			
		||||
		for _, p := range d.After() {
 | 
			
		||||
			// Skip undefined drivers silently, unlike Prerequisites().
 | 
			
		||||
			if _, ok := byName[p]; ok {
 | 
			
		||||
				m[p] = struct{}{}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		dag[name] = m
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Create stages.
 | 
			
		||||
	var stages []*stage
 | 
			
		||||
	for len(dag) != 0 {
 | 
			
		||||
		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 {
 | 
			
		||||
				s.drvs[name] = byName[name]
 | 
			
		||||
				delete(dag, name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(s.drvs) == 0 {
 | 
			
		||||
			// Print out the remaining DAG so users can diagnose.
 | 
			
		||||
			// It'd probably be nicer if it were done in Register()?
 | 
			
		||||
			s := make([]string, 0, len(dag))
 | 
			
		||||
			for name, deps := range dag {
 | 
			
		||||
				x := make([]string, 0, len(deps))
 | 
			
		||||
				for d := range deps {
 | 
			
		||||
					x = insertString(x, d)
 | 
			
		||||
				}
 | 
			
		||||
				s = insertString(s, name+": "+strings.Join(x, ", "))
 | 
			
		||||
			}
 | 
			
		||||
			return nil, errors.New("periph: found cycle(s) in drivers dependencies:\n" + strings.Join(s, "\n"))
 | 
			
		||||
		}
 | 
			
		||||
		stages = append(stages, s)
 | 
			
		||||
 | 
			
		||||
		// Trim the dependencies for the items remaining in the dag.
 | 
			
		||||
		for passed := range s.drvs {
 | 
			
		||||
			for name := range dag {
 | 
			
		||||
				delete(dag[name], passed)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return stages, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = d
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func insertDriverFailure(l []DriverFailure, f DriverFailure) []DriverFailure {
 | 
			
		||||
	n := f.String()
 | 
			
		||||
	i := search(len(l), func(i int) bool { return l[i].String() > n })
 | 
			
		||||
	l = append(l, DriverFailure{})
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = f
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func insertString(l []string, s string) []string {
 | 
			
		||||
	i := search(len(l), func(i int) bool { return l[i] > s })
 | 
			
		||||
	l = append(l, "")
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = s
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// search implements the same algorithm as sort.Search().
 | 
			
		||||
//
 | 
			
		||||
// It was extracted to to not depend on sort, which depends on reflect.
 | 
			
		||||
func search(n int, f func(int) bool) int {
 | 
			
		||||
	lo := 0
 | 
			
		||||
	for hi := n; lo < hi; {
 | 
			
		||||
		if i := int(uint(lo+hi) >> 1); !f(i) {
 | 
			
		||||
			lo = i + 1
 | 
			
		||||
		} else {
 | 
			
		||||
			hi = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return lo
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_parallel.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_parallel.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// This file contains the parallelized driver loading logic. It is meant to be
 | 
			
		||||
// load the drivers as fast as possible by parallelising work.
 | 
			
		||||
 | 
			
		||||
// +build !tinygo
 | 
			
		||||
 | 
			
		||||
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.Impl)
 | 
			
		||||
	cS := make(chan DriverFailure)
 | 
			
		||||
	cE := make(chan DriverFailure)
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer wg.Done()
 | 
			
		||||
		for d := range cD {
 | 
			
		||||
			state.Loaded = insertDriver(state.Loaded, d)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer wg.Done()
 | 
			
		||||
		for f := range cS {
 | 
			
		||||
			state.Skipped = insertDriverFailure(state.Skipped, f)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	wg.Add(1)
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer wg.Done()
 | 
			
		||||
		for f := range cE {
 | 
			
		||||
			state.Failed = insertDriverFailure(state.Failed, f)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	stages, err := explodeStages()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return state, err
 | 
			
		||||
	}
 | 
			
		||||
	loaded := make(map[string]struct{}, len(byName))
 | 
			
		||||
	for _, s := range stages {
 | 
			
		||||
		s.loadParallel(loaded, cD, cS, cE)
 | 
			
		||||
	}
 | 
			
		||||
	close(cD)
 | 
			
		||||
	close(cS)
 | 
			
		||||
	close(cE)
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
	return state, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 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.Impl, cS, cE chan<- DriverFailure) {
 | 
			
		||||
	success := make(chan string)
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer close(success)
 | 
			
		||||
		wg := sync.WaitGroup{}
 | 
			
		||||
	loop:
 | 
			
		||||
		for name, drv := range s.drvs {
 | 
			
		||||
			// Intentionally do not look at After(), only Prerequisites().
 | 
			
		||||
			for _, dep := range drv.Prerequisites() {
 | 
			
		||||
				if _, ok := loaded[dep]; !ok {
 | 
			
		||||
					cS <- DriverFailure{drv, errors.New("dependency not loaded: " + strconv.Quote(dep))}
 | 
			
		||||
					continue loop
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Not skipped driver, attempt loading in a goroutine.
 | 
			
		||||
			wg.Add(1)
 | 
			
		||||
			go func(n string, d driver.Impl) {
 | 
			
		||||
				defer wg.Done()
 | 
			
		||||
				if ok, err := d.Init(); ok {
 | 
			
		||||
					if err == nil {
 | 
			
		||||
						cD <- d
 | 
			
		||||
						success <- n
 | 
			
		||||
						return
 | 
			
		||||
					}
 | 
			
		||||
					cE <- DriverFailure{d, err}
 | 
			
		||||
				} else {
 | 
			
		||||
					cS <- DriverFailure{d, err}
 | 
			
		||||
				}
 | 
			
		||||
			}(name, drv)
 | 
			
		||||
		}
 | 
			
		||||
		wg.Wait()
 | 
			
		||||
	}()
 | 
			
		||||
	for s := range success {
 | 
			
		||||
		loaded[s] = struct{}{}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_serial.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								vendor/periph.io/x/conn/v3/driver/driverreg/driverreg_serial.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// This file contains the single threaded driver loading code, to be used on
 | 
			
		||||
// low performance cores.
 | 
			
		||||
 | 
			
		||||
// +build tinygo
 | 
			
		||||
 | 
			
		||||
package driverreg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func initImpl() (*State, error) {
 | 
			
		||||
	state = &State{}
 | 
			
		||||
	// At this point, byName is guaranteed to be immutable.
 | 
			
		||||
	stages, err := explodeStages()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return state, err
 | 
			
		||||
	}
 | 
			
		||||
	loaded := make(map[string]struct{}, len(byName))
 | 
			
		||||
	for _, s := range stages {
 | 
			
		||||
		s.loadSerial(state, loaded)
 | 
			
		||||
	}
 | 
			
		||||
	return state, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// loadSerial loads all the drivers for this stage, one after the other.
 | 
			
		||||
func (s *stage) loadSerial(state *State, loaded map[string]struct{}) {
 | 
			
		||||
	for name, drv := range s.drvs {
 | 
			
		||||
		// Intentionally do not look at After(), only Prerequisites().
 | 
			
		||||
		for _, dep := range drv.Prerequisites() {
 | 
			
		||||
			if _, ok := loaded[dep]; !ok {
 | 
			
		||||
				state.Skipped = insertDriverFailure(state.Skipped, DriverFailure{drv, errors.New("dependency not loaded: " + strconv.Quote(dep))})
 | 
			
		||||
				goto loop
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Not skipped driver, attempt loading in a goroutine.
 | 
			
		||||
		if ok, err := drv.Init(); ok {
 | 
			
		||||
			if err == nil {
 | 
			
		||||
				state.Loaded = insertDriver(state.Loaded, drv)
 | 
			
		||||
				loaded[name] = struct{}{}
 | 
			
		||||
			} else {
 | 
			
		||||
				state.Failed = insertDriverFailure(state.Failed, DriverFailure{drv, err})
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			state.Skipped = insertDriverFailure(state.Skipped, DriverFailure{drv, err})
 | 
			
		||||
		}
 | 
			
		||||
	loop:
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/periph.io/x/conn/v3/gpio/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/periph.io/x/conn/v3/gpio/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// 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 gpio
 | 
			
		||||
 | 
			
		||||
import "periph.io/x/conn/v3/pin"
 | 
			
		||||
 | 
			
		||||
// Well known pin functionality.
 | 
			
		||||
const (
 | 
			
		||||
	// Inputs
 | 
			
		||||
	IN      pin.Func = "IN"      // Input
 | 
			
		||||
	IN_HIGH pin.Func = "In/High" // Read high
 | 
			
		||||
	IN_LOW  pin.Func = "In/Low"  // Read low
 | 
			
		||||
 | 
			
		||||
	// Outputs
 | 
			
		||||
	OUT      pin.Func = "OUT"      // Output, drive
 | 
			
		||||
	OUT_OC   pin.Func = "OUT_OPEN" // Output, open collector/drain
 | 
			
		||||
	OUT_HIGH pin.Func = "Out/High" // Drive high
 | 
			
		||||
	OUT_LOW  pin.Func = "Out/Low"  // Drive low; open collector low
 | 
			
		||||
 | 
			
		||||
	FLOAT pin.Func = "FLOAT" // Input float or Output open collector high
 | 
			
		||||
 | 
			
		||||
	CLK pin.Func = "CLK" // Clock is a subset of a PWM, with a 50% duty cycle
 | 
			
		||||
	PWM pin.Func = "PWM" // Pulse Width Modulation, which is a clock with variable duty cycle
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										329
									
								
								vendor/periph.io/x/conn/v3/gpio/gpio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								vendor/periph.io/x/conn/v3/gpio/gpio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,329 @@
 | 
			
		||||
// 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 gpio defines digital pins.
 | 
			
		||||
//
 | 
			
		||||
// All GPIO implementations are expected to implement PinIO but the device
 | 
			
		||||
// driver may accept a more specific one like PinIn or PinOut.
 | 
			
		||||
package gpio
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/conn/v3/physic"
 | 
			
		||||
	"periph.io/x/conn/v3/pin"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Interfaces
 | 
			
		||||
 | 
			
		||||
// Level is the level of the pin: Low or High.
 | 
			
		||||
type Level bool
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Low represents 0v.
 | 
			
		||||
	Low Level = false
 | 
			
		||||
	// High represents Vin, generally 3.3v or 5v.
 | 
			
		||||
	High Level = true
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (l Level) String() string {
 | 
			
		||||
	if l == Low {
 | 
			
		||||
		return "Low"
 | 
			
		||||
	}
 | 
			
		||||
	return "High"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pull specifies the internal pull-up or pull-down for a pin set as input.
 | 
			
		||||
type Pull uint8
 | 
			
		||||
 | 
			
		||||
// Acceptable pull values.
 | 
			
		||||
const (
 | 
			
		||||
	PullNoChange Pull = 0 // Do not change the previous pull resistor setting or an unknown value
 | 
			
		||||
	Float        Pull = 1 // Let the input float
 | 
			
		||||
	PullDown     Pull = 2 // Apply pull-down
 | 
			
		||||
	PullUp       Pull = 3 // Apply pull-up
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const pullName = "PullNoChangeFloatPullDownPullUp"
 | 
			
		||||
 | 
			
		||||
var pullIndex = [...]uint8{0, 12, 17, 25, 31}
 | 
			
		||||
 | 
			
		||||
func (i Pull) String() string {
 | 
			
		||||
	if i >= Pull(len(pullIndex)-1) {
 | 
			
		||||
		return "Pull(" + strconv.Itoa(int(i)) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return pullName[pullIndex[i]:pullIndex[i+1]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Edge specifies if an input pin should have edge detection enabled.
 | 
			
		||||
//
 | 
			
		||||
// Only enable it when needed, since this causes system interrupts.
 | 
			
		||||
type Edge int
 | 
			
		||||
 | 
			
		||||
// Acceptable edge detection values.
 | 
			
		||||
const (
 | 
			
		||||
	NoEdge      Edge = 0
 | 
			
		||||
	RisingEdge  Edge = 1
 | 
			
		||||
	FallingEdge Edge = 2
 | 
			
		||||
	BothEdges   Edge = 3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const edgeName = "NoEdgeRisingEdgeFallingEdgeBothEdges"
 | 
			
		||||
 | 
			
		||||
var edgeIndex = [...]uint8{0, 6, 16, 27, 36}
 | 
			
		||||
 | 
			
		||||
func (i Edge) String() string {
 | 
			
		||||
	if i >= Edge(len(edgeIndex)-1) {
 | 
			
		||||
		return "Edge(" + strconv.Itoa(int(i)) + ")"
 | 
			
		||||
	}
 | 
			
		||||
	return edgeName[edgeIndex[i]:edgeIndex[i+1]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// DutyMax is a duty cycle of 100%.
 | 
			
		||||
	DutyMax Duty = 1 << 24
 | 
			
		||||
	// DutyHalf is a 50% duty PWM, which boils down to a normal clock.
 | 
			
		||||
	DutyHalf Duty = DutyMax / 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Duty is the duty cycle for a PWM.
 | 
			
		||||
//
 | 
			
		||||
// Valid values are between 0 and DutyMax.
 | 
			
		||||
type Duty int32
 | 
			
		||||
 | 
			
		||||
func (d Duty) String() string {
 | 
			
		||||
	// TODO(maruel): Implement one fractional number.
 | 
			
		||||
	return strconv.Itoa(int((d+50)/(DutyMax/100))) + "%"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Valid returns true if the Duty cycle value is valid.
 | 
			
		||||
func (d Duty) Valid() bool {
 | 
			
		||||
	return d >= 0 && d <= DutyMax
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseDuty parses a string and converts it to a Duty value.
 | 
			
		||||
func ParseDuty(s string) (Duty, error) {
 | 
			
		||||
	percent := strings.HasSuffix(s, "%")
 | 
			
		||||
	if percent {
 | 
			
		||||
		s = s[:len(s)-1]
 | 
			
		||||
	}
 | 
			
		||||
	i64, err := strconv.ParseInt(s, 10, 32)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	i := Duty(i64)
 | 
			
		||||
	if percent {
 | 
			
		||||
		// TODO(maruel): Add support for fractional number.
 | 
			
		||||
		if i < 0 {
 | 
			
		||||
			return 0, errors.New("duty must be >= 0%")
 | 
			
		||||
		}
 | 
			
		||||
		if i > 100 {
 | 
			
		||||
			return 0, errors.New("duty must be <= 100%")
 | 
			
		||||
		}
 | 
			
		||||
		return ((i * DutyMax) + 49) / 100, nil
 | 
			
		||||
	}
 | 
			
		||||
	if i < 0 {
 | 
			
		||||
		return 0, errors.New("duty must be >= 0")
 | 
			
		||||
	}
 | 
			
		||||
	if i > DutyMax {
 | 
			
		||||
		return 0, errors.New("duty must be <= " + strconv.Itoa(int(DutyMax)))
 | 
			
		||||
	}
 | 
			
		||||
	return i, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PinIn is an input GPIO pin.
 | 
			
		||||
//
 | 
			
		||||
// It may optionally support internal pull resistor and edge based triggering.
 | 
			
		||||
//
 | 
			
		||||
// A button is semantically a PinIn. So if you are looking to read from a
 | 
			
		||||
// button, PinIn is the interface you are looking for.
 | 
			
		||||
type PinIn interface {
 | 
			
		||||
	pin.Pin
 | 
			
		||||
	// In setups a pin as an input.
 | 
			
		||||
	//
 | 
			
		||||
	// If WaitForEdge() is planned to be called, make sure to use one of the Edge
 | 
			
		||||
	// value. Otherwise, use NoEdge to not generated unneeded hardware interrupts.
 | 
			
		||||
	//
 | 
			
		||||
	// Calling In() will try to empty the accumulated edges but it cannot be 100%
 | 
			
		||||
	// reliable due to the OS (linux) and its driver. It is possible that on a
 | 
			
		||||
	// gpio that is as input, doing a quick Out(), In() may return an edge that
 | 
			
		||||
	// occurred before the Out() call.
 | 
			
		||||
	In(pull Pull, edge Edge) error
 | 
			
		||||
	// Read return the current pin level.
 | 
			
		||||
	//
 | 
			
		||||
	// Behavior is undefined if In() wasn't used before.
 | 
			
		||||
	//
 | 
			
		||||
	// In some rare case, it is possible that Read() fails silently. This happens
 | 
			
		||||
	// if another process on the host messes up with the pin after In() was
 | 
			
		||||
	// called. In this case, call In() again.
 | 
			
		||||
	Read() Level
 | 
			
		||||
	// WaitForEdge() waits for the next edge or immediately return if an edge
 | 
			
		||||
	// occurred since the last call.
 | 
			
		||||
	//
 | 
			
		||||
	// Only waits for the kind of edge as specified in a previous In() call.
 | 
			
		||||
	// Behavior is undefined if In() with a value other than NoEdge wasn't called
 | 
			
		||||
	// before.
 | 
			
		||||
	//
 | 
			
		||||
	// Returns true if an edge was detected during or before this call. Return
 | 
			
		||||
	// false if the timeout occurred or In() was called while waiting, causing the
 | 
			
		||||
	// function to exit.
 | 
			
		||||
	//
 | 
			
		||||
	// Multiple edges may or may not accumulate between two calls to
 | 
			
		||||
	// WaitForEdge(). The behavior in this case is undefined and is OS driver
 | 
			
		||||
	// specific.
 | 
			
		||||
	//
 | 
			
		||||
	// It is not required to call Read() to reset the edge detection.
 | 
			
		||||
	//
 | 
			
		||||
	// Specify -1 to effectively disable timeout.
 | 
			
		||||
	WaitForEdge(timeout time.Duration) bool
 | 
			
		||||
	// Pull returns the internal pull resistor if the pin is set as input pin.
 | 
			
		||||
	//
 | 
			
		||||
	// Returns PullNoChange if the value cannot be read.
 | 
			
		||||
	Pull() Pull
 | 
			
		||||
	// DefaultPull returns the pull that is initialized on CPU/device reset. This
 | 
			
		||||
	// is useful to determine if the pin is acceptable for operation with
 | 
			
		||||
	// certain devices.
 | 
			
		||||
	DefaultPull() Pull
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PinOut is an output GPIO pin.
 | 
			
		||||
//
 | 
			
		||||
// A LED, a buzzer, a servo, are semantically a PinOut. So if you are looking
 | 
			
		||||
// to control these, PinOut is the interface you are looking for.
 | 
			
		||||
type PinOut interface {
 | 
			
		||||
	pin.Pin
 | 
			
		||||
	// Out sets a pin as output if it wasn't already and sets the initial value.
 | 
			
		||||
	//
 | 
			
		||||
	// After the initial call to ensure that the pin has been set as output, it
 | 
			
		||||
	// is generally safe to ignore the error returned.
 | 
			
		||||
	//
 | 
			
		||||
	// Out() tries to empty the accumulated edges detected if the gpio was
 | 
			
		||||
	// previously set as input but this is not 100% guaranteed due to the OS.
 | 
			
		||||
	Out(l Level) error
 | 
			
		||||
	// PWM sets the PWM output on supported pins, if the pin has hardware PWM
 | 
			
		||||
	// support.
 | 
			
		||||
	//
 | 
			
		||||
	// To use as a general purpose clock, set duty to DutyHalf. Some pins may
 | 
			
		||||
	// only support DutyHalf and no other value.
 | 
			
		||||
	//
 | 
			
		||||
	// Using 0 as frequency will use the optimal value as supported/preferred by
 | 
			
		||||
	// the pin.
 | 
			
		||||
	//
 | 
			
		||||
	// To use as a servo, see https://en.wikipedia.org/wiki/Servo_control as an
 | 
			
		||||
	// explanation how to calculate duty.
 | 
			
		||||
	PWM(duty Duty, f physic.Frequency) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PinIO is a GPIO pin that supports both input and output. It matches both
 | 
			
		||||
// interfaces PinIn and PinOut.
 | 
			
		||||
//
 | 
			
		||||
// A GPIO pin implementing PinIO may fail at either input or output or both.
 | 
			
		||||
type PinIO interface {
 | 
			
		||||
	pin.Pin
 | 
			
		||||
	// PinIn
 | 
			
		||||
	In(pull Pull, edge Edge) error
 | 
			
		||||
	Read() Level
 | 
			
		||||
	WaitForEdge(timeout time.Duration) bool
 | 
			
		||||
	Pull() Pull
 | 
			
		||||
	DefaultPull() Pull
 | 
			
		||||
	// PinOut
 | 
			
		||||
	Out(l Level) error
 | 
			
		||||
	PWM(duty Duty, f physic.Frequency) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// INVALID implements PinIO and fails on all access.
 | 
			
		||||
var INVALID PinIO
 | 
			
		||||
 | 
			
		||||
// RealPin is implemented by aliased pin and allows the retrieval of the real
 | 
			
		||||
// pin underlying an alias.
 | 
			
		||||
//
 | 
			
		||||
// Aliases are created by RegisterAlias. Aliases permits presenting a user
 | 
			
		||||
// friendly GPIO pin name while representing the underlying real pin.
 | 
			
		||||
//
 | 
			
		||||
// The purpose of the RealPin is to be able to cleanly test whether an arbitrary
 | 
			
		||||
// gpio.PinIO returned by ByName is an alias for another pin, and resolve it.
 | 
			
		||||
type RealPin interface {
 | 
			
		||||
	Real() PinIO // Real returns the real pin behind an Alias
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// errInvalidPin is returned when trying to use INVALID.
 | 
			
		||||
var errInvalidPin = errors.New("gpio: invalid pin")
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	INVALID = invalidPin{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// invalidPin implements PinIO for compatibility but fails on all access.
 | 
			
		||||
type invalidPin struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) String() string {
 | 
			
		||||
	return "INVALID"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Halt() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Number() int {
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Name() string {
 | 
			
		||||
	return "INVALID"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Function() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Func() pin.Func {
 | 
			
		||||
	return pin.FuncNone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) SupportedFuncs() []pin.Func {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) SetFunc(f pin.Func) error {
 | 
			
		||||
	return errInvalidPin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) In(Pull, Edge) error {
 | 
			
		||||
	return errInvalidPin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Read() Level {
 | 
			
		||||
	return Low
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) WaitForEdge(timeout time.Duration) bool {
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Pull() Pull {
 | 
			
		||||
	return PullNoChange
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) DefaultPull() Pull {
 | 
			
		||||
	return PullNoChange
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) Out(Level) error {
 | 
			
		||||
	return errInvalidPin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (invalidPin) PWM(Duty, physic.Frequency) error {
 | 
			
		||||
	return errInvalidPin
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ PinIn = INVALID
 | 
			
		||||
var _ PinOut = INVALID
 | 
			
		||||
var _ PinIO = INVALID
 | 
			
		||||
var _ pin.PinFunc = &invalidPin{}
 | 
			
		||||
							
								
								
									
										213
									
								
								vendor/periph.io/x/conn/v3/gpio/gpioreg/gpioreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								vendor/periph.io/x/conn/v3/gpio/gpioreg/gpioreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,213 @@
 | 
			
		||||
// 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 gpioreg defines a registry for the known digital pins.
 | 
			
		||||
package gpioreg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/conn/v3/gpio"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ByName returns a GPIO pin from its name, gpio number or one of its aliases.
 | 
			
		||||
//
 | 
			
		||||
// For example on a Raspberry Pi, the following values will return the same
 | 
			
		||||
// GPIO: the gpio as a number "2", the chipset name "GPIO2", the board pin
 | 
			
		||||
// position "P1_3", it's function name "I2C1_SDA".
 | 
			
		||||
//
 | 
			
		||||
// Returns nil if the gpio pin is not present.
 | 
			
		||||
func ByName(name string) gpio.PinIO {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if p, ok := byName[name]; ok {
 | 
			
		||||
		return p
 | 
			
		||||
	}
 | 
			
		||||
	if dest, ok := byAlias[name]; ok {
 | 
			
		||||
		if p := getByNameDeep(dest); p != nil {
 | 
			
		||||
			// Wraps the destination in an alias, so the name makes sense to the user.
 | 
			
		||||
			// The main drawback is that casting into other gpio interfaces like
 | 
			
		||||
			// gpio.PinPWM requires going through gpio.RealPin first.
 | 
			
		||||
			return &pinAlias{p, name}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// All returns all the GPIO pins available on this host.
 | 
			
		||||
//
 | 
			
		||||
// The list is guaranteed to be in order of name using 'natural sorting'.
 | 
			
		||||
//
 | 
			
		||||
// This list excludes aliases.
 | 
			
		||||
//
 | 
			
		||||
// This list excludes non-GPIO pins like GROUND, V3_3, etc, since they are not
 | 
			
		||||
// GPIO.
 | 
			
		||||
func All() []gpio.PinIO {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	out := make([]gpio.PinIO, 0, len(byName))
 | 
			
		||||
	for _, p := range byName {
 | 
			
		||||
		out = insertPinByName(out, p)
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Aliases returns all pin aliases.
 | 
			
		||||
//
 | 
			
		||||
// The list is guaranteed to be in order of aliase name.
 | 
			
		||||
func Aliases() []gpio.PinIO {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	out := make([]gpio.PinIO, 0, len(byAlias))
 | 
			
		||||
	for name, dest := range byAlias {
 | 
			
		||||
		// Skip aliases that were not resolved.
 | 
			
		||||
		if p := getByNameDeep(dest); p != nil {
 | 
			
		||||
			out = insertPinByName(out, &pinAlias{p, name})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register registers a GPIO pin.
 | 
			
		||||
//
 | 
			
		||||
// Registering the same pin number or name twice is an error.
 | 
			
		||||
//
 | 
			
		||||
// The pin registered cannot implement the interface RealPin.
 | 
			
		||||
func Register(p gpio.PinIO) error {
 | 
			
		||||
	name := p.Name()
 | 
			
		||||
	if len(name) == 0 {
 | 
			
		||||
		return errors.New("gpioreg: can't register a pin with no name")
 | 
			
		||||
	}
 | 
			
		||||
	if r, ok := p.(gpio.RealPin); ok {
 | 
			
		||||
		return errors.New("gpioreg: can't register pin " + strconv.Quote(name) + ", it is already an alias to " + strconv.Quote(r.Real().String()))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if orig, ok := byName[name]; ok {
 | 
			
		||||
		return errors.New("gpioreg: can't register pin " + strconv.Quote(name) + " twice; already registered as " + strconv.Quote(orig.String()))
 | 
			
		||||
	}
 | 
			
		||||
	if dest, ok := byAlias[name]; ok {
 | 
			
		||||
		return errors.New("gpioreg: can't register pin " + strconv.Quote(name) + "; an alias already exist to: " + strconv.Quote(dest))
 | 
			
		||||
	}
 | 
			
		||||
	byName[name] = p
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RegisterAlias registers an alias for a GPIO pin.
 | 
			
		||||
//
 | 
			
		||||
// It is possible to register an alias for a pin that itself has not been
 | 
			
		||||
// registered yet. It is valid to register an alias to another alias. It is
 | 
			
		||||
// valid to register the same alias multiple times, overriding the previous
 | 
			
		||||
// alias.
 | 
			
		||||
func RegisterAlias(alias string, dest string) error {
 | 
			
		||||
	if len(alias) == 0 {
 | 
			
		||||
		return errors.New("gpioreg: can't register an alias with no name")
 | 
			
		||||
	}
 | 
			
		||||
	if len(dest) == 0 {
 | 
			
		||||
		return errors.New("gpioreg: can't register alias " + strconv.Quote(alias) + " with no dest")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if _, ok := byName[alias]; ok {
 | 
			
		||||
		return errors.New("gpioreg: can't register alias " + strconv.Quote(alias) + " for a pin that exists")
 | 
			
		||||
	}
 | 
			
		||||
	byAlias[alias] = dest
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unregister removes a previously registered GPIO pin or alias from the GPIO
 | 
			
		||||
// pin registry.
 | 
			
		||||
//
 | 
			
		||||
// This can happen when a GPIO pin is exposed via an USB device and the device
 | 
			
		||||
// is unplugged, or when a generic OS provided pin is superseded by a CPU
 | 
			
		||||
// specific implementation.
 | 
			
		||||
func Unregister(name string) error {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if _, ok := byName[name]; ok {
 | 
			
		||||
		delete(byName, name)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := byAlias[name]; ok {
 | 
			
		||||
		delete(byAlias, name)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return errors.New("gpioreg: can't unregister unknown pin name " + strconv.Quote(name))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu      sync.Mutex
 | 
			
		||||
	byName  = map[string]gpio.PinIO{}
 | 
			
		||||
	byAlias = map[string]string{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// pinAlias implements an alias for a PinIO.
 | 
			
		||||
//
 | 
			
		||||
// pinAlias implements the RealPin interface, which allows querying for the
 | 
			
		||||
// real pin under the alias.
 | 
			
		||||
type pinAlias struct {
 | 
			
		||||
	gpio.PinIO
 | 
			
		||||
	name string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns the alias name along the real pin's Name() in parenthesis, if
 | 
			
		||||
// known, else the real pin's number.
 | 
			
		||||
func (a *pinAlias) String() string {
 | 
			
		||||
	return a.name + "(" + a.PinIO.Name() + ")"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name returns the pinAlias's name.
 | 
			
		||||
func (a *pinAlias) Name() string {
 | 
			
		||||
	return a.name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Real returns the real pin behind the alias
 | 
			
		||||
func (a *pinAlias) Real() gpio.PinIO {
 | 
			
		||||
	return a.PinIO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getByNameDeep recursively resolves the aliases to get the pin.
 | 
			
		||||
func getByNameDeep(name string) gpio.PinIO {
 | 
			
		||||
	if p, ok := byName[name]; ok {
 | 
			
		||||
		return p
 | 
			
		||||
	}
 | 
			
		||||
	if dest, ok := byAlias[name]; ok {
 | 
			
		||||
		if p := getByNameDeep(dest); p != nil {
 | 
			
		||||
			// Return the deep pin directly, bypassing the aliases.
 | 
			
		||||
			return p
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// insertPinByName inserts pin p into list l while keeping l ordered by name.
 | 
			
		||||
func insertPinByName(l []gpio.PinIO, p gpio.PinIO) []gpio.PinIO {
 | 
			
		||||
	n := p.Name()
 | 
			
		||||
	i := search(len(l), func(i int) bool { return lessNatural(n, l[i].Name()) })
 | 
			
		||||
	l = append(l, nil)
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = p
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// search implements the same algorithm as sort.Search().
 | 
			
		||||
//
 | 
			
		||||
// It was extracted to to not depend on sort, which depends on reflect.
 | 
			
		||||
func search(n int, f func(int) bool) int {
 | 
			
		||||
	lo := 0
 | 
			
		||||
	for hi := n; lo < hi; {
 | 
			
		||||
		if i := int(uint(lo+hi) >> 1); !f(i) {
 | 
			
		||||
			lo = i + 1
 | 
			
		||||
		} else {
 | 
			
		||||
			hi = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return lo
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										76
									
								
								vendor/periph.io/x/conn/v3/gpio/gpioreg/natsort.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/periph.io/x/conn/v3/gpio/gpioreg/natsort.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
// 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 gpioreg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// lessNatural does a 'natural' comparison on the two strings.
 | 
			
		||||
//
 | 
			
		||||
// It is extracted from https://github.com/maruel/natural.
 | 
			
		||||
func lessNatural(a, b string) bool {
 | 
			
		||||
	for {
 | 
			
		||||
		if a == b {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		if p := commonPrefix(a, b); p != 0 {
 | 
			
		||||
			a = a[p:]
 | 
			
		||||
			b = b[p:]
 | 
			
		||||
		}
 | 
			
		||||
		if ia := digits(a); ia > 0 {
 | 
			
		||||
			if ib := digits(b); ib > 0 {
 | 
			
		||||
				// Both sides have digits.
 | 
			
		||||
				an, aerr := strconv.ParseUint(a[:ia], 10, 64)
 | 
			
		||||
				bn, berr := strconv.ParseUint(b[:ib], 10, 64)
 | 
			
		||||
				if aerr == nil && berr == nil {
 | 
			
		||||
					if an != bn {
 | 
			
		||||
						return an < bn
 | 
			
		||||
					}
 | 
			
		||||
					// Semantically the same digits, e.g. "00" == "0", "01" == "1". In
 | 
			
		||||
					// this case, only continue processing if there's trailing data on
 | 
			
		||||
					// both sides, otherwise do lexical comparison.
 | 
			
		||||
					if ia != len(a) && ib != len(b) {
 | 
			
		||||
						a = a[ia:]
 | 
			
		||||
						b = b[ib:]
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return a < b
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// commonPrefix returns the common prefix except for digits.
 | 
			
		||||
func commonPrefix(a, b string) int {
 | 
			
		||||
	m := len(a)
 | 
			
		||||
	if n := len(b); n < m {
 | 
			
		||||
		m = n
 | 
			
		||||
	}
 | 
			
		||||
	if m == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	_ = a[m-1]
 | 
			
		||||
	_ = b[m-1]
 | 
			
		||||
	for i := 0; i < m; i++ {
 | 
			
		||||
		ca := a[i]
 | 
			
		||||
		cb := b[i]
 | 
			
		||||
		if (ca >= '0' && ca <= '9') || (cb >= '0' && cb <= '9') || ca != cb {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func digits(s string) int {
 | 
			
		||||
	for i := 0; i < len(s); i++ {
 | 
			
		||||
		c := s[i]
 | 
			
		||||
		if c < '0' || c > '9' {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return len(s)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										220
									
								
								vendor/periph.io/x/conn/v3/gpio/gpiostream/gpiostream.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								vendor/periph.io/x/conn/v3/gpio/gpiostream/gpiostream.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
			
		||||
// 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 gpiostream defines digital streams.
 | 
			
		||||
//
 | 
			
		||||
// Warning
 | 
			
		||||
//
 | 
			
		||||
// This package is still in flux as development is on-going.
 | 
			
		||||
package gpiostream
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"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.
 | 
			
		||||
type Stream interface {
 | 
			
		||||
	// Frequency is the minimum data rate at which the binary stream is usable.
 | 
			
		||||
	//
 | 
			
		||||
	// For example, a bit stream may have a 10kHz data rate.
 | 
			
		||||
	Frequency() physic.Frequency
 | 
			
		||||
	// Duration of the binary stream. For infinitely looping streams, it is the
 | 
			
		||||
	// duration of the non-looping part.
 | 
			
		||||
	Duration() time.Duration
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BitStream is a stream of bits to be written or read.
 | 
			
		||||
type BitStream struct {
 | 
			
		||||
	// Bits is a densely packed bitstream.
 | 
			
		||||
	//
 | 
			
		||||
	// The stream is required to be a multiple of 8 samples.
 | 
			
		||||
	Bits []byte
 | 
			
		||||
	// Freq is the rate at each the bit (not byte) stream should be processed.
 | 
			
		||||
	Freq physic.Frequency
 | 
			
		||||
	// LSBF when true means than Bits is in LSB-first. When false, the data is
 | 
			
		||||
	// MSB-first.
 | 
			
		||||
	//
 | 
			
		||||
	// With MSBF, the first bit processed is the most significant one (0x80). For
 | 
			
		||||
	// example, I²C, I2S PCM and SPI use MSB-first at the word level. This
 | 
			
		||||
	// requires to pack words correctly.
 | 
			
		||||
	//
 | 
			
		||||
	// With LSBF, the first bit processed is the least significant one (0x01).
 | 
			
		||||
	// For example, Ethernet uses LSB-first at the byte level and MSB-first at
 | 
			
		||||
	// the word level.
 | 
			
		||||
	LSBF bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Frequency implements Stream.
 | 
			
		||||
func (b *BitStream) Frequency() physic.Frequency {
 | 
			
		||||
	return b.Freq
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Duration implements Stream.
 | 
			
		||||
func (b *BitStream) Duration() time.Duration {
 | 
			
		||||
	if b.Freq == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return b.Freq.Period() * time.Duration(len(b.Bits)*8)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GoString implements fmt.GoStringer.
 | 
			
		||||
func (b *BitStream) GoString() string {
 | 
			
		||||
	return fmt.Sprintf("&gpiostream.BitStream{Bits: %x, Freq:%s, LSBF:%t}", b.Bits, b.Freq, b.LSBF)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// EdgeStream is a stream of edges to be written.
 | 
			
		||||
//
 | 
			
		||||
// This struct is more efficient than BitStream for short repetitive pulses,
 | 
			
		||||
// like controlling a servo. A PWM can be created by specifying a slice of
 | 
			
		||||
// twice the same resolution and make it looping via a Program.
 | 
			
		||||
type EdgeStream struct {
 | 
			
		||||
	// Edges is the list of Level change. It is assumed that the signal starts
 | 
			
		||||
	// with gpio.High. Use a duration of 0 for Edges[0] to start with a Low
 | 
			
		||||
	// instead of the default High.
 | 
			
		||||
	//
 | 
			
		||||
	// The value is a multiple of Res. Use a 0 value to 'extend' a continuous
 | 
			
		||||
	// signal that lasts more than "2^16-1*Res" duration by skipping a pulse.
 | 
			
		||||
	Edges []uint16
 | 
			
		||||
	// Res is the minimum resolution at which the edges should be
 | 
			
		||||
	// rasterized.
 | 
			
		||||
	//
 | 
			
		||||
	// The lower the value, the more memory shall be used when rasterized.
 | 
			
		||||
	Freq physic.Frequency
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Frequency implements Stream.
 | 
			
		||||
func (e *EdgeStream) Frequency() physic.Frequency {
 | 
			
		||||
	return e.Freq
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Duration implements Stream.
 | 
			
		||||
func (e *EdgeStream) Duration() time.Duration {
 | 
			
		||||
	if e.Freq == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	t := 0
 | 
			
		||||
	for _, edge := range e.Edges {
 | 
			
		||||
		t += int(edge)
 | 
			
		||||
	}
 | 
			
		||||
	return e.Freq.Period() * time.Duration(t)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Program is a loop of streams.
 | 
			
		||||
//
 | 
			
		||||
// This is itself a stream, it can be used to reduce memory usage when repeated
 | 
			
		||||
// patterns are used.
 | 
			
		||||
type Program struct {
 | 
			
		||||
	Parts []Stream // Each part must be a BitStream, EdgeStream or Program
 | 
			
		||||
	Loops int      // Set to -1 to create an infinite loop
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Frequency implements Stream.
 | 
			
		||||
func (p *Program) Frequency() physic.Frequency {
 | 
			
		||||
	if p.Loops == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	var buf [16]physic.Frequency
 | 
			
		||||
	freqs := buf[:0]
 | 
			
		||||
	for _, part := range p.Parts {
 | 
			
		||||
		if f := part.Frequency(); f != 0 {
 | 
			
		||||
			freqs = insertFreq(freqs, f)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(freqs) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	f := freqs[0]
 | 
			
		||||
	for i := 1; i < len(freqs); i++ {
 | 
			
		||||
		if r := freqs[i]; r*2 < f {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		// Take in account Nyquist rate. https://wikipedia.org/wiki/Nyquist_rate
 | 
			
		||||
		f *= 2
 | 
			
		||||
	}
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Duration implements Stream.
 | 
			
		||||
func (p *Program) Duration() time.Duration {
 | 
			
		||||
	if p.Loops == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	var d time.Duration
 | 
			
		||||
	for _, s := range p.Parts {
 | 
			
		||||
		d += s.Duration()
 | 
			
		||||
	}
 | 
			
		||||
	if p.Loops > 1 {
 | 
			
		||||
		d *= time.Duration(p.Loops)
 | 
			
		||||
	}
 | 
			
		||||
	return d
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// PinIn allows to read a bit stream from a pin.
 | 
			
		||||
//
 | 
			
		||||
// Caveat
 | 
			
		||||
//
 | 
			
		||||
// This interface doesn't enable sampling multiple pins in a
 | 
			
		||||
// synchronized way or reading in a continuous uninterrupted way. As such, it
 | 
			
		||||
// should be considered experimental.
 | 
			
		||||
type PinIn interface {
 | 
			
		||||
	pin.Pin
 | 
			
		||||
	// StreamIn reads for the pin at the specified resolution to fill the
 | 
			
		||||
	// provided buffer.
 | 
			
		||||
	//
 | 
			
		||||
	// May only support a subset of the structs implementing Stream.
 | 
			
		||||
	StreamIn(p gpio.Pull, b Stream) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PinOut allows to stream to a pin.
 | 
			
		||||
//
 | 
			
		||||
// The Stream may be a Program, a BitStream or an EdgeStream. If it is a
 | 
			
		||||
// Program that is an infinite loop, a separate goroutine can be used to cancel
 | 
			
		||||
// the program. In this case StreamOut() returns without an error.
 | 
			
		||||
//
 | 
			
		||||
// Caveat
 | 
			
		||||
//
 | 
			
		||||
// This interface doesn't enable streaming to multiple pins in a
 | 
			
		||||
// synchronized way or reading in a continuous uninterrupted way. As such, it
 | 
			
		||||
// should be considered experimental.
 | 
			
		||||
type PinOut interface {
 | 
			
		||||
	pin.Pin
 | 
			
		||||
	StreamOut(s Stream) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// insertFreq inserts in reverse order, highest frequency first.
 | 
			
		||||
func insertFreq(l []physic.Frequency, f physic.Frequency) []physic.Frequency {
 | 
			
		||||
	i := search(len(l), func(i int) bool { return l[i] < f })
 | 
			
		||||
	l = append(l, 0)
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = f
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// search implements the same algorithm as sort.Search().
 | 
			
		||||
//
 | 
			
		||||
// It was extracted to to not depend on sort, which depends on reflect.
 | 
			
		||||
func search(n int, f func(int) bool) int {
 | 
			
		||||
	lo := 0
 | 
			
		||||
	for hi := n; lo < hi; {
 | 
			
		||||
		if i := int(uint(lo+hi) >> 1); !f(i) {
 | 
			
		||||
			lo = i + 1
 | 
			
		||||
		} else {
 | 
			
		||||
			hi = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return lo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ Stream = &BitStream{}
 | 
			
		||||
var _ Stream = &EdgeStream{}
 | 
			
		||||
var _ Stream = &Program{}
 | 
			
		||||
							
								
								
									
										13
									
								
								vendor/periph.io/x/conn/v3/i2c/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/periph.io/x/conn/v3/i2c/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
// Copyright 2018 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package i2c
 | 
			
		||||
 | 
			
		||||
import "periph.io/x/conn/v3/pin"
 | 
			
		||||
 | 
			
		||||
// Well known pin functionality.
 | 
			
		||||
const (
 | 
			
		||||
	SCL pin.Func = "I2C_SCL" // Clock
 | 
			
		||||
	SDA pin.Func = "I2C_SDA" // Data
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										135
									
								
								vendor/periph.io/x/conn/v3/i2c/i2c.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								vendor/periph.io/x/conn/v3/i2c/i2c.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package i2c defines the API to communicate with devices over the I²C
 | 
			
		||||
// protocol.
 | 
			
		||||
//
 | 
			
		||||
// As described in https://periph.io/x/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
 | 
			
		||||
// device address, there's no unconfigured Port to configure.
 | 
			
		||||
//
 | 
			
		||||
// Instead, the package includes the adapter 'Dev' to directly convert an I²C
 | 
			
		||||
// bus 'i2c.Bus' into a connection 'conn.Conn' by only specifying the device
 | 
			
		||||
// I²C address.
 | 
			
		||||
//
 | 
			
		||||
// See https://en.wikipedia.org/wiki/I%C2%B2C for more information.
 | 
			
		||||
package i2c
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"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.
 | 
			
		||||
//
 | 
			
		||||
// This interface is consummed by a device driver for a device sitting on a bus.
 | 
			
		||||
//
 | 
			
		||||
// This interface doesn't implement conn.Conn since a device address must be
 | 
			
		||||
// specified. Use i2cdev.Dev as an adapter to get a conn.Conn compatible
 | 
			
		||||
// object.
 | 
			
		||||
type Bus interface {
 | 
			
		||||
	String() string
 | 
			
		||||
	// Tx does a transaction at the specified device address.
 | 
			
		||||
	//
 | 
			
		||||
	// Write is done first, then read. One of 'w' or 'r' can be omitted for a
 | 
			
		||||
	// unidirectional operation.
 | 
			
		||||
	Tx(addr uint16, w, r []byte) error
 | 
			
		||||
	// SetSpeed changes the bus speed, if supported.
 | 
			
		||||
	//
 | 
			
		||||
	// On linux due to the way the I²C sysfs driver is exposed in userland,
 | 
			
		||||
	// calling this function will likely affect *all* I²C buses on the host.
 | 
			
		||||
	SetSpeed(f physic.Frequency) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BusCloser is an I²C bus that can be closed.
 | 
			
		||||
//
 | 
			
		||||
// This interface is meant to be handled by the application and not the device
 | 
			
		||||
// driver. A device driver doesn't "own" a bus, hence it must operate on a Bus,
 | 
			
		||||
// not a BusCloser.
 | 
			
		||||
type BusCloser interface {
 | 
			
		||||
	io.Closer
 | 
			
		||||
	Bus
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pins defines the pins that an I²C bus interconnect is using on the host.
 | 
			
		||||
//
 | 
			
		||||
// It is expected that a implementer of Bus also implement Pins but this is not
 | 
			
		||||
// a requirement.
 | 
			
		||||
type Pins interface {
 | 
			
		||||
	// SCL returns the CLK (clock) pin.
 | 
			
		||||
	SCL() gpio.PinIO
 | 
			
		||||
	// SDA returns the DATA pin.
 | 
			
		||||
	SDA() gpio.PinIO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Dev is a device on a I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// It implements conn.Conn.
 | 
			
		||||
//
 | 
			
		||||
// It saves from repeatedly specifying the device address.
 | 
			
		||||
type Dev struct {
 | 
			
		||||
	Bus  Bus
 | 
			
		||||
	Addr uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *Dev) String() string {
 | 
			
		||||
	s := "<nil>"
 | 
			
		||||
	if d.Bus != nil {
 | 
			
		||||
		s = d.Bus.String()
 | 
			
		||||
	}
 | 
			
		||||
	return s + "(" + strconv.Itoa(int(d.Addr)) + ")"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tx does a transaction by adding the device's address to each command.
 | 
			
		||||
//
 | 
			
		||||
// It's a wrapper for Bus.Tx().
 | 
			
		||||
func (d *Dev) Tx(w, r []byte) error {
 | 
			
		||||
	return d.Bus.Tx(d.Addr, w, r)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write writes to the I²C bus without reading, implementing io.Writer.
 | 
			
		||||
//
 | 
			
		||||
// It's a wrapper for Tx()
 | 
			
		||||
func (d *Dev) Write(b []byte) (int, error) {
 | 
			
		||||
	if err := d.Tx(b, nil); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return len(b), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Duplex always return conn.Half for I²C.
 | 
			
		||||
func (d *Dev) Duplex() conn.Duplex {
 | 
			
		||||
	return conn.Half
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Addr is an I²C slave address.
 | 
			
		||||
type Addr uint16
 | 
			
		||||
 | 
			
		||||
// Set sets the Addr to a value represented by the string s. Values maybe in
 | 
			
		||||
// decimal or hexadecimal form. Set implements the flag.Value interface.
 | 
			
		||||
func (a *Addr) Set(s string) error {
 | 
			
		||||
	// Allow for only maximum of 10 bits for i2c addresses.
 | 
			
		||||
	u, err := strconv.ParseUint(s, 0, 10)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return errI2CSetError
 | 
			
		||||
	}
 | 
			
		||||
	*a = Addr(u)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String returns an i2c.Addr as a string formated in hexadecimal.
 | 
			
		||||
func (a Addr) String() string {
 | 
			
		||||
	return "0x" + strconv.FormatInt(int64(a), 16)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var errI2CSetError = errors.New("invalid i2c address")
 | 
			
		||||
 | 
			
		||||
var _ conn.Conn = &Dev{}
 | 
			
		||||
							
								
								
									
										252
									
								
								vendor/periph.io/x/conn/v3/i2c/i2creg/i2creg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								vendor/periph.io/x/conn/v3/i2c/i2creg/i2creg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,252 @@
 | 
			
		||||
// Copyright 2017 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package i2creg defines I²C bus registry to list buses present on the host.
 | 
			
		||||
package i2creg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/conn/v3/i2c"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Opener opens an handle to a bus.
 | 
			
		||||
//
 | 
			
		||||
// It is provided by the actual bus driver.
 | 
			
		||||
type Opener func() (i2c.BusCloser, error)
 | 
			
		||||
 | 
			
		||||
// Ref references an I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// It is returned by All() to enumerate all registered buses.
 | 
			
		||||
type Ref struct {
 | 
			
		||||
	// Name of the bus.
 | 
			
		||||
	//
 | 
			
		||||
	// It must not be a sole number. It must be unique across the host.
 | 
			
		||||
	Name string
 | 
			
		||||
	// Aliases are the alternative names that can be used to reference this bus.
 | 
			
		||||
	Aliases []string
 | 
			
		||||
	// Number of the bus or -1 if the bus doesn't have any "native" number.
 | 
			
		||||
	//
 | 
			
		||||
	// Buses provided by the CPU normally have a 0 based number. Buses provided
 | 
			
		||||
	// via an addon (like over USB) generally are not numbered.
 | 
			
		||||
	Number int
 | 
			
		||||
	// Open is the factory to open an handle to this I²C bus.
 | 
			
		||||
	Open Opener
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Open opens an I²C bus by its name, an alias or its number and returns an
 | 
			
		||||
// handle to it.
 | 
			
		||||
//
 | 
			
		||||
// Specify the empty string "" to get the first available bus. This is the
 | 
			
		||||
// recommended default value unless an application knows the exact bus to use.
 | 
			
		||||
//
 | 
			
		||||
// Each bus can register multiple aliases, each leading to the same bus handle.
 | 
			
		||||
//
 | 
			
		||||
// "Bus number" is a generic concept that is highly dependent on the platform
 | 
			
		||||
// and OS. On some platform, the first bus may have the number 0, 1 or higher.
 | 
			
		||||
// Bus numbers are not necessarily continuous and may not start at 0. It was
 | 
			
		||||
// observed that the bus number as reported by the OS may change across OS
 | 
			
		||||
// revisions.
 | 
			
		||||
//
 | 
			
		||||
// When the I²C bus is provided by an off board plug and play bus like USB via
 | 
			
		||||
// a FT232H USB device, there can be no associated number.
 | 
			
		||||
func Open(name string) (i2c.BusCloser, error) {
 | 
			
		||||
	var r *Ref
 | 
			
		||||
	var err error
 | 
			
		||||
	func() {
 | 
			
		||||
		mu.Lock()
 | 
			
		||||
		defer mu.Unlock()
 | 
			
		||||
		if len(byName) == 0 {
 | 
			
		||||
			err = errors.New("i2creg: no bus found; did you forget to call Init()?")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if len(name) == 0 {
 | 
			
		||||
			r = getDefault()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// Try by name, by alias, by number.
 | 
			
		||||
		if r = byName[name]; r == nil {
 | 
			
		||||
			if r = byAlias[name]; r == nil {
 | 
			
		||||
				if i, err2 := strconv.Atoi(name); err2 == nil {
 | 
			
		||||
					r = byNumber[i]
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		return nil, errors.New("i2creg: can't open unknown bus: " + strconv.Quote(name))
 | 
			
		||||
	}
 | 
			
		||||
	return r.Open()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// All returns a copy of all the registered references to all know I²C buses
 | 
			
		||||
// available on this host.
 | 
			
		||||
//
 | 
			
		||||
// The list is sorted by the bus name.
 | 
			
		||||
func All() []*Ref {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	out := make([]*Ref, 0, len(byName))
 | 
			
		||||
	for _, v := range byName {
 | 
			
		||||
		r := &Ref{Name: v.Name, Aliases: make([]string, len(v.Aliases)), Number: v.Number, Open: v.Open}
 | 
			
		||||
		copy(r.Aliases, v.Aliases)
 | 
			
		||||
		out = insertRef(out, r)
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register registers an I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// Registering the same bus name twice is an error, e.g. o.Name(). o.Number()
 | 
			
		||||
// can be -1 to signify that the bus doesn't have an inherent "bus number". A
 | 
			
		||||
// good example is a bus provided over a FT232H device connected on an USB bus.
 | 
			
		||||
// In this case, the bus name should be created from the serial number of the
 | 
			
		||||
// device for unique identification.
 | 
			
		||||
func Register(name string, aliases []string, number int, o Opener) error {
 | 
			
		||||
	if len(name) == 0 {
 | 
			
		||||
		return errors.New("i2creg: can't register a bus with no name")
 | 
			
		||||
	}
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with nil Opener")
 | 
			
		||||
	}
 | 
			
		||||
	if number < -1 {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with invalid bus number " + strconv.Itoa(number))
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := strconv.Atoi(name); err == nil {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with name being only a number")
 | 
			
		||||
	}
 | 
			
		||||
	if strings.Contains(name, ":") {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with name containing ':'")
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		if len(alias) == 0 {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an empty alias")
 | 
			
		||||
		}
 | 
			
		||||
		if name == alias {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an alias the same as the bus name")
 | 
			
		||||
		}
 | 
			
		||||
		if _, err := strconv.Atoi(alias); err == nil {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an alias that is a number: " + strconv.Quote(alias))
 | 
			
		||||
		}
 | 
			
		||||
		if strings.Contains(alias, ":") {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " with an alias containing ':': " + strconv.Quote(alias))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if _, ok := byName[name]; ok {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice")
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := byAlias[name]; ok {
 | 
			
		||||
		return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice; it is already an alias")
 | 
			
		||||
	}
 | 
			
		||||
	if number != -1 {
 | 
			
		||||
		if _, ok := byNumber[number]; ok {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + "; bus number " + strconv.Itoa(number) + " is already registered")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		if _, ok := byName[alias]; ok {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice; alias " + strconv.Quote(alias) + " is already a bus")
 | 
			
		||||
		}
 | 
			
		||||
		if _, ok := byAlias[alias]; ok {
 | 
			
		||||
			return errors.New("i2creg: can't register bus " + strconv.Quote(name) + " twice; alias " + strconv.Quote(alias) + " is already an alias")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r := &Ref{Name: name, Aliases: make([]string, len(aliases)), Number: number, Open: o}
 | 
			
		||||
	copy(r.Aliases, aliases)
 | 
			
		||||
	byName[name] = r
 | 
			
		||||
	if number != -1 {
 | 
			
		||||
		byNumber[number] = r
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		byAlias[alias] = r
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unregister removes a previously registered I²C bus.
 | 
			
		||||
//
 | 
			
		||||
// This can happen when an I²C bus is exposed via an USB device and the device
 | 
			
		||||
// is unplugged.
 | 
			
		||||
func Unregister(name string) error {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	r := byName[name]
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		return errors.New("i2creg: can't unregister unknown bus name " + strconv.Quote(name))
 | 
			
		||||
	}
 | 
			
		||||
	delete(byName, name)
 | 
			
		||||
	delete(byNumber, r.Number)
 | 
			
		||||
	for _, alias := range r.Aliases {
 | 
			
		||||
		delete(byAlias, alias)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu     sync.Mutex
 | 
			
		||||
	byName = map[string]*Ref{}
 | 
			
		||||
	// Caches
 | 
			
		||||
	byNumber = map[int]*Ref{}
 | 
			
		||||
	byAlias  = map[string]*Ref{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getDefault returns the Ref that should be used as the default bus.
 | 
			
		||||
func getDefault() *Ref {
 | 
			
		||||
	var o *Ref
 | 
			
		||||
	if len(byNumber) == 0 {
 | 
			
		||||
		// Fallback to use byName using a lexical sort.
 | 
			
		||||
		name := ""
 | 
			
		||||
		for n, o2 := range byName {
 | 
			
		||||
			if len(name) == 0 || n < name {
 | 
			
		||||
				o = o2
 | 
			
		||||
				name = n
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return o
 | 
			
		||||
	}
 | 
			
		||||
	number := int((^uint(0)) >> 1)
 | 
			
		||||
	for n, o2 := range byNumber {
 | 
			
		||||
		if number > n {
 | 
			
		||||
			number = n
 | 
			
		||||
			o = o2
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func insertRef(l []*Ref, r *Ref) []*Ref {
 | 
			
		||||
	n := r.Name
 | 
			
		||||
	i := search(len(l), func(i int) bool { return l[i].Name > n })
 | 
			
		||||
	l = append(l, nil)
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = r
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// search implements the same algorithm as sort.Search().
 | 
			
		||||
//
 | 
			
		||||
// It was extracted to to not depend on sort, which depends on reflect.
 | 
			
		||||
func search(n int, f func(int) bool) int {
 | 
			
		||||
	lo := 0
 | 
			
		||||
	for hi := n; lo < hi; {
 | 
			
		||||
		if i := int(uint(lo+hi) >> 1); !f(i) {
 | 
			
		||||
			lo = i + 1
 | 
			
		||||
		} else {
 | 
			
		||||
			hi = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return lo
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										21
									
								
								vendor/periph.io/x/conn/v3/physic/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/periph.io/x/conn/v3/physic/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
// 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 physic declares types for physical input, outputs and measurement
 | 
			
		||||
// units.
 | 
			
		||||
//
 | 
			
		||||
// This includes temperature, humidity, pressure, tension, current, etc.
 | 
			
		||||
//
 | 
			
		||||
// SI units
 | 
			
		||||
//
 | 
			
		||||
// The supported S.I. units is a subset of the official ones.
 | 
			
		||||
//    T  	tera 	10¹²  	1000000000000
 | 
			
		||||
//    G  	giga 	10⁹   	1000000000
 | 
			
		||||
//    M  	mega 	10⁶   	1000000
 | 
			
		||||
//    k  	kilo 	10³   	1000
 | 
			
		||||
//    m  	milli	10⁻³  	0.001
 | 
			
		||||
//    µ,u	micro	10⁻⁶  	0.000001
 | 
			
		||||
//    n  	nano 	10⁻⁹  	0.000000001
 | 
			
		||||
//    p  	pico 	10⁻¹² 	0.000000000001
 | 
			
		||||
package physic
 | 
			
		||||
							
								
								
									
										42
									
								
								vendor/periph.io/x/conn/v3/physic/physic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/periph.io/x/conn/v3/physic/physic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// 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 physic
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/conn/v3"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Env represents measurements from an environmental sensor.
 | 
			
		||||
type Env struct {
 | 
			
		||||
	Temperature Temperature
 | 
			
		||||
	Pressure    Pressure
 | 
			
		||||
	Humidity    RelativeHumidity
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SenseEnv represents an environmental sensor.
 | 
			
		||||
type SenseEnv interface {
 | 
			
		||||
	conn.Resource
 | 
			
		||||
 | 
			
		||||
	// Sense returns the value read from the sensor. Unsupported metrics are not
 | 
			
		||||
	// modified.
 | 
			
		||||
	Sense(env *Env) error
 | 
			
		||||
	// SenseContinuous initiates a continuous sensing at the specified interval.
 | 
			
		||||
	//
 | 
			
		||||
	// It is important to call Halt() once done with the sensing, which will turn
 | 
			
		||||
	// the device off and will close the channel.
 | 
			
		||||
	SenseContinuous(interval time.Duration) (<-chan Env, error)
 | 
			
		||||
	// Precision returns this sensor's precision.
 | 
			
		||||
	//
 | 
			
		||||
	// The env values are set to the number of bits that are significant for each
 | 
			
		||||
	// items that this sensor can measure.
 | 
			
		||||
	//
 | 
			
		||||
	// Precision is not accuracy. The sensor may have absolute and relative
 | 
			
		||||
	// errors in its measurement, that are likely well above the reported
 | 
			
		||||
	// precision. Accuracy may be improved on some sensor by using oversampling,
 | 
			
		||||
	// or doing oversampling in software. Refer to its datasheet if available.
 | 
			
		||||
	Precision(env *Env)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2313
									
								
								vendor/periph.io/x/conn/v3/physic/units.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2313
									
								
								vendor/periph.io/x/conn/v3/physic/units.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										58
									
								
								vendor/periph.io/x/conn/v3/pin/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								vendor/periph.io/x/conn/v3/pin/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
// 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 pin
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Func is a pin function.
 | 
			
		||||
//
 | 
			
		||||
// The Func format must be "[A-Z]+", "[A-Z]+_[A-Z]+" or exceptionally
 | 
			
		||||
// "(In|Out)/(Low|High)".
 | 
			
		||||
type Func string
 | 
			
		||||
 | 
			
		||||
// FuncNone is returned by PinFunc.Func() for a Pin without an active
 | 
			
		||||
// functionality.
 | 
			
		||||
const FuncNone Func = ""
 | 
			
		||||
 | 
			
		||||
// Specialize converts a "BUS_LINE" function and appends the bug number and
 | 
			
		||||
// line number, to look like "BUS0_LINE1".
 | 
			
		||||
//
 | 
			
		||||
// Use -1 to not add a bus or line number.
 | 
			
		||||
func (f Func) Specialize(b, l int) Func {
 | 
			
		||||
	if f == FuncNone {
 | 
			
		||||
		return FuncNone
 | 
			
		||||
	}
 | 
			
		||||
	if b != -1 {
 | 
			
		||||
		parts := strings.SplitN(string(f), "_", 2)
 | 
			
		||||
		if len(parts) == 1 {
 | 
			
		||||
			return FuncNone
 | 
			
		||||
		}
 | 
			
		||||
		f = Func(parts[0] + strconv.Itoa(b) + "_" + parts[1])
 | 
			
		||||
	}
 | 
			
		||||
	if l != -1 {
 | 
			
		||||
		f += Func(strconv.Itoa(l))
 | 
			
		||||
	}
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Generalize is the reverse of Specialize().
 | 
			
		||||
func (f Func) Generalize() Func {
 | 
			
		||||
	parts := strings.SplitN(string(f), "_", 2)
 | 
			
		||||
	f = Func(strings.TrimRightFunc(parts[0], isNum))
 | 
			
		||||
	if len(parts) == 2 {
 | 
			
		||||
		f += "_"
 | 
			
		||||
		f += Func(strings.TrimRightFunc(parts[1], isNum))
 | 
			
		||||
	}
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
func isNum(r rune) bool {
 | 
			
		||||
	return r >= '0' && r <= '9'
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										139
									
								
								vendor/periph.io/x/conn/v3/pin/pin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vendor/periph.io/x/conn/v3/pin/pin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
// 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 pin declare well known pins.
 | 
			
		||||
//
 | 
			
		||||
// pin is about physical pins, not about their logical function.
 | 
			
		||||
//
 | 
			
		||||
// While not a protocol strictly speaking, these are "well known constants".
 | 
			
		||||
package pin
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/conn/v3"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// These are well known pins.
 | 
			
		||||
var (
 | 
			
		||||
	INVALID  *BasicPin // Either floating or invalid pin
 | 
			
		||||
	GROUND   *BasicPin // Ground
 | 
			
		||||
	V1_8     *BasicPin // 1.8V (filtered)
 | 
			
		||||
	V2_8     *BasicPin // 2.8V (filtered)
 | 
			
		||||
	V3_3     *BasicPin // 3.3V (filtered)
 | 
			
		||||
	V5       *BasicPin // 5V (filtered)
 | 
			
		||||
	DC_IN    *BasicPin // DC IN; this is normally the 5V input
 | 
			
		||||
	BAT_PLUS *BasicPin // LiPo Battery + connector
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Pin is the minimal common interface shared between gpio.PinIO and
 | 
			
		||||
// analog.PinIO.
 | 
			
		||||
type Pin interface {
 | 
			
		||||
	conn.Resource
 | 
			
		||||
	// Name returns the name of the pin.
 | 
			
		||||
	Name() string
 | 
			
		||||
	// Number returns the logical pin number or a negative number if the pin is
 | 
			
		||||
	// not a GPIO, e.g. GROUND, V3_3, etc.
 | 
			
		||||
	Number() int
 | 
			
		||||
	// Function returns a user readable string representation of what the pin is
 | 
			
		||||
	// configured to do. Common case is In and Out but it can be bus specific pin
 | 
			
		||||
	// name.
 | 
			
		||||
	//
 | 
			
		||||
	// Deprecated: Use PinFunc.Func. Will be removed in v4.
 | 
			
		||||
	Function() string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PinFunc is a supplementary interface that enables specifically querying for
 | 
			
		||||
// the pin function.
 | 
			
		||||
//
 | 
			
		||||
// TODO(maruel): It will be merged into interface Pin for v4.
 | 
			
		||||
type PinFunc interface {
 | 
			
		||||
	// Func returns the pin's current function.
 | 
			
		||||
	//
 | 
			
		||||
	// The returned value may be specialized or generalized, depending on the
 | 
			
		||||
	// actual port. For example it will likely be generalized for ports served
 | 
			
		||||
	// over USB (like a FT232H with D0 set as SPI_MOSI) but specialized for
 | 
			
		||||
	// ports on the base board (like a RPi3 with GPIO10 set as SPI0_MOSI).
 | 
			
		||||
	Func() Func
 | 
			
		||||
	// SupportedFuncs returns the possible functions this pin support.
 | 
			
		||||
	//
 | 
			
		||||
	// Do not mutate the returned slice.
 | 
			
		||||
	SupportedFuncs() []Func
 | 
			
		||||
	// SetFunc sets the pin function.
 | 
			
		||||
	//
 | 
			
		||||
	// Example use is to reallocate a RPi3's GPIO14 active function between
 | 
			
		||||
	// UART0_TX and UART1_TX.
 | 
			
		||||
	SetFunc(f Func) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// BasicPin implements Pin as a static pin.
 | 
			
		||||
//
 | 
			
		||||
// It doesn't have a usable functionality.
 | 
			
		||||
type BasicPin struct {
 | 
			
		||||
	N string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String implements conn.Resource.
 | 
			
		||||
func (b *BasicPin) String() string {
 | 
			
		||||
	return b.N
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Halt implements conn.Resource.
 | 
			
		||||
func (b *BasicPin) Halt() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name implements Pin.
 | 
			
		||||
func (b *BasicPin) Name() string {
 | 
			
		||||
	return b.N
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Number implements Pin.
 | 
			
		||||
//
 | 
			
		||||
// Returns -1 as pin number.
 | 
			
		||||
func (b *BasicPin) Number() int {
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Function implements Pin.
 | 
			
		||||
//
 | 
			
		||||
// Returns "" as pin function.
 | 
			
		||||
func (b *BasicPin) Function() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Func implements PinFunc.
 | 
			
		||||
//
 | 
			
		||||
// Returns FuncNone as pin function.
 | 
			
		||||
func (b *BasicPin) Func() Func {
 | 
			
		||||
	return FuncNone
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SupportedFuncs implements PinFunc.
 | 
			
		||||
//
 | 
			
		||||
// Returns nil.
 | 
			
		||||
func (b *BasicPin) SupportedFuncs() []Func {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetFunc implements PinFunc.
 | 
			
		||||
func (b *BasicPin) SetFunc(f Func) error {
 | 
			
		||||
	return errors.New("pin: can't change static pin function")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	INVALID = &BasicPin{N: "INVALID"}
 | 
			
		||||
	GROUND = &BasicPin{N: "GROUND"}
 | 
			
		||||
	V1_8 = &BasicPin{N: "1.8V"}
 | 
			
		||||
	V2_8 = &BasicPin{N: "2.8V"}
 | 
			
		||||
	V3_3 = &BasicPin{N: "3.3V"}
 | 
			
		||||
	V5 = &BasicPin{N: "5V"}
 | 
			
		||||
	DC_IN = &BasicPin{N: "DC_IN"}
 | 
			
		||||
	BAT_PLUS = &BasicPin{N: "BAT+"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ Pin = INVALID
 | 
			
		||||
var _ PinFunc = INVALID
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/conn/v3/pin/pinreg/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/conn/v3/pin/pinreg/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// 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 pinreg is a registry for the physical headers (made up of pins) on
 | 
			
		||||
// a host.
 | 
			
		||||
package pinreg
 | 
			
		||||
							
								
								
									
										148
									
								
								vendor/periph.io/x/conn/v3/pin/pinreg/pinreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								vendor/periph.io/x/conn/v3/pin/pinreg/pinreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
// 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 pinreg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"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.
 | 
			
		||||
//
 | 
			
		||||
// The map key is the header name, e.g. "P1" or "EULER" and the value is a
 | 
			
		||||
// slice of slice of pin.Pin. For a 2x20 header, it's going to be a slice of
 | 
			
		||||
// [20][2]pin.Pin.
 | 
			
		||||
func All() map[string][][]pin.Pin {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	out := make(map[string][][]pin.Pin, len(allHeaders))
 | 
			
		||||
	for k, v := range allHeaders {
 | 
			
		||||
		outV := make([][]pin.Pin, len(v))
 | 
			
		||||
		for i, w := range v {
 | 
			
		||||
			outW := make([]pin.Pin, len(w))
 | 
			
		||||
			copy(outW, w)
 | 
			
		||||
			outV[i] = outW
 | 
			
		||||
		}
 | 
			
		||||
		out[k] = outV
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Position returns the position on a pin if found.
 | 
			
		||||
//
 | 
			
		||||
// The header and the pin number. Pin numbers are 1-based.
 | 
			
		||||
//
 | 
			
		||||
// Returns "", 0 if not connected.
 | 
			
		||||
func Position(p pin.Pin) (string, int) {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	pos := byPin[realPin(p).Name()]
 | 
			
		||||
	return pos.name, pos.number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsConnected returns true if the pin is on a header.
 | 
			
		||||
func IsConnected(p pin.Pin) bool {
 | 
			
		||||
	_, i := Position(p)
 | 
			
		||||
	return i != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register registers a physical header.
 | 
			
		||||
//
 | 
			
		||||
// It automatically registers all gpio pins to gpioreg.
 | 
			
		||||
func Register(name string, allPins [][]pin.Pin) error {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if _, ok := allHeaders[name]; ok {
 | 
			
		||||
		return errors.New("pinreg: header " + strconv.Quote(name) + " was already registered")
 | 
			
		||||
	}
 | 
			
		||||
	for i, line := range allPins {
 | 
			
		||||
		for j, pin := range line {
 | 
			
		||||
			if pin == nil || len(pin.Name()) == 0 {
 | 
			
		||||
				return errors.New("pinreg: invalid pin on header " + name + "[" + strconv.Itoa(i+1) + "][" + strconv.Itoa(j+1) + "]")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	allHeaders[name] = allPins
 | 
			
		||||
	number := 1
 | 
			
		||||
	for _, line := range allPins {
 | 
			
		||||
		for _, p := range line {
 | 
			
		||||
			byPin[realPin(p).Name()] = position{name, number}
 | 
			
		||||
			number++
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	count := 0
 | 
			
		||||
	for _, row := range allPins {
 | 
			
		||||
		for _, p := range row {
 | 
			
		||||
			count++
 | 
			
		||||
			if _, ok := p.(gpio.PinIO); ok {
 | 
			
		||||
				if err := gpioreg.RegisterAlias(name+"_"+strconv.Itoa(count), p.Name()); err != nil {
 | 
			
		||||
					// Unregister as much as possible.
 | 
			
		||||
					_ = unregister(name)
 | 
			
		||||
					return errors.New("pinreg: " + err.Error())
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unregister removes a previously registered header.
 | 
			
		||||
//
 | 
			
		||||
// This can happen when an USB device, which exposed an header, is unplugged.
 | 
			
		||||
// This is also useful for unit testing.
 | 
			
		||||
func Unregister(name string) error {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	return unregister(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
type position struct {
 | 
			
		||||
	name   string // Header name
 | 
			
		||||
	number int    // Pin number
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu         sync.Mutex
 | 
			
		||||
	allHeaders = map[string][][]pin.Pin{} // every known headers as per internal lookup table
 | 
			
		||||
	byPin      = map[string]position{}    // GPIO pin name to position
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func unregister(name string) error {
 | 
			
		||||
	if hdr, ok := allHeaders[name]; ok {
 | 
			
		||||
		var err error
 | 
			
		||||
		delete(allHeaders, name)
 | 
			
		||||
		count := 0
 | 
			
		||||
		for _, row := range hdr {
 | 
			
		||||
			for _, p := range row {
 | 
			
		||||
				count++
 | 
			
		||||
				if _, ok := p.(gpio.PinIO); ok {
 | 
			
		||||
					if err1 := gpioreg.Unregister(name + "_" + strconv.Itoa(count)); err1 != nil && err == nil {
 | 
			
		||||
						// Continue unregistering as much as possible.
 | 
			
		||||
						err = errors.New("pinreg: " + err1.Error())
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return errors.New("pinreg: can't unregister unknown header name " + strconv.Quote(name))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// realPin returns the real pin from an alias.
 | 
			
		||||
func realPin(p pin.Pin) pin.Pin {
 | 
			
		||||
	if r, ok := p.(gpio.RealPin); ok {
 | 
			
		||||
		p = r.Real()
 | 
			
		||||
	}
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/periph.io/x/conn/v3/spi/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/periph.io/x/conn/v3/spi/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
// Copyright 2018 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package spi
 | 
			
		||||
 | 
			
		||||
import "periph.io/x/conn/v3/pin"
 | 
			
		||||
 | 
			
		||||
// Well known pin functionality.
 | 
			
		||||
const (
 | 
			
		||||
	CLK  pin.Func = "SPI_CLK"  // Clock
 | 
			
		||||
	CS   pin.Func = "SPI_CS"   // Chip select
 | 
			
		||||
	MISO pin.Func = "SPI_MISO" // Master in
 | 
			
		||||
	MOSI pin.Func = "SPI_MOSI" // Master out
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										187
									
								
								vendor/periph.io/x/conn/v3/spi/spi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								vendor/periph.io/x/conn/v3/spi/spi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,187 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package spi defines the API to communicate with devices over the SPI
 | 
			
		||||
// protocol.
 | 
			
		||||
//
 | 
			
		||||
// As described in https://periph.io/x/conn/v3#hdr-Concepts, periph.io uses
 | 
			
		||||
// the concepts of Bus, Port and Conn.
 | 
			
		||||
//
 | 
			
		||||
// In the package spi, 'Bus' is not exposed, as it would be SPI bus number
 | 
			
		||||
// without a CS line, for example on linux asking for "/dev/spi0" without the
 | 
			
		||||
// ".0" suffix.
 | 
			
		||||
//
 | 
			
		||||
// The OS doesn't allow that so it is counter productive to express this at the
 | 
			
		||||
// API layer, so 'Port' is exposed directly instead.
 | 
			
		||||
//
 | 
			
		||||
// Use Port.Connect() converts the uninitialized Port into a Conn.
 | 
			
		||||
//
 | 
			
		||||
// See https://en.wikipedia.org/wiki/Serial_Peripheral_Interface for more
 | 
			
		||||
// information.
 | 
			
		||||
package spi
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/conn/v3"
 | 
			
		||||
	"periph.io/x/conn/v3/gpio"
 | 
			
		||||
	"periph.io/x/conn/v3/physic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Mode determines how communication is done.
 | 
			
		||||
//
 | 
			
		||||
// The bits can be OR'ed to change the parameters used for
 | 
			
		||||
// communication.
 | 
			
		||||
//
 | 
			
		||||
type Mode int
 | 
			
		||||
 | 
			
		||||
// Mode determines the SPI communication parameters.
 | 
			
		||||
//
 | 
			
		||||
// CPOL means the clock polarity. Idle is High when set.
 | 
			
		||||
//
 | 
			
		||||
// CPHA is the clock phase, sample on trailing edge when set.
 | 
			
		||||
const (
 | 
			
		||||
	Mode0 Mode = 0x0 // CPOL=0, CPHA=0
 | 
			
		||||
	Mode1 Mode = 0x1 // CPOL=0, CPHA=1
 | 
			
		||||
	Mode2 Mode = 0x2 // CPOL=1, CPHA=0
 | 
			
		||||
	Mode3 Mode = 0x3 // CPOL=1, CPHA=1
 | 
			
		||||
 | 
			
		||||
	// HalfDuplex specifies that MOSI and MISO use the same wire, and that only
 | 
			
		||||
	// one duplex is used at a time.
 | 
			
		||||
	HalfDuplex Mode = 0x4
 | 
			
		||||
	// NoCS request the driver to not use the CS line.
 | 
			
		||||
	NoCS Mode = 0x8
 | 
			
		||||
	// LSBFirst requests the words to be encoded in little endian instead of the
 | 
			
		||||
	// default big endian.
 | 
			
		||||
	LSBFirst = 0x10
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (m Mode) String() string {
 | 
			
		||||
	s := ""
 | 
			
		||||
	switch m & Mode3 {
 | 
			
		||||
	case Mode0:
 | 
			
		||||
		s = "Mode0"
 | 
			
		||||
	case Mode1:
 | 
			
		||||
		s = "Mode1"
 | 
			
		||||
	case Mode2:
 | 
			
		||||
		s = "Mode2"
 | 
			
		||||
	case Mode3:
 | 
			
		||||
		s = "Mode3"
 | 
			
		||||
	}
 | 
			
		||||
	m &^= Mode3
 | 
			
		||||
	if m&HalfDuplex != 0 {
 | 
			
		||||
		s += "|HalfDuplex"
 | 
			
		||||
	}
 | 
			
		||||
	m &^= HalfDuplex
 | 
			
		||||
	if m&NoCS != 0 {
 | 
			
		||||
		s += "|NoCS"
 | 
			
		||||
	}
 | 
			
		||||
	m &^= NoCS
 | 
			
		||||
	if m&LSBFirst != 0 {
 | 
			
		||||
		s += "|LSBFirst"
 | 
			
		||||
	}
 | 
			
		||||
	m &^= LSBFirst
 | 
			
		||||
	if m != 0 {
 | 
			
		||||
		s += "|0x"
 | 
			
		||||
		s += strconv.FormatUint(uint64(m), 16)
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Packet represents one packet when sending multiple packets as a transaction.
 | 
			
		||||
type Packet struct {
 | 
			
		||||
	// W and R are the output and input data. When HalfDuplex is specified to
 | 
			
		||||
	// Connect, only one of the two can be set.
 | 
			
		||||
	W, R []byte
 | 
			
		||||
	// BitsPerWord overrides the default bits per word value set in Connect.
 | 
			
		||||
	BitsPerWord uint8
 | 
			
		||||
	// KeepCS tells the driver to keep CS asserted after this packet is
 | 
			
		||||
	// completed. This can be leveraged to create long transaction as multiple
 | 
			
		||||
	// packets like to use 9 bits commands then 8 bits data.
 | 
			
		||||
	//
 | 
			
		||||
	// Normally during a spi.Conn.TxPackets() call, KeepCS should be set to true
 | 
			
		||||
	// for all packets except the last one. If the last one is set to true, the
 | 
			
		||||
	// CS line stays asserted, leaving the transaction hanging on the bus.
 | 
			
		||||
	//
 | 
			
		||||
	// KeepCS is ignored when NoCS was specified to Connect.
 | 
			
		||||
	KeepCS bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Conn defines the interface a concrete SPI driver must implement.
 | 
			
		||||
//
 | 
			
		||||
// Implementers can optionally implement io.Writer and io.Reader for
 | 
			
		||||
// unidirectional operation.
 | 
			
		||||
type Conn interface {
 | 
			
		||||
	conn.Conn
 | 
			
		||||
	// TxPackets does multiple operations over the SPI connection.
 | 
			
		||||
	//
 | 
			
		||||
	// The maximum number of bytes can be limited depending on the driver. Query
 | 
			
		||||
	// conn.Limits.MaxTxSize() can be used to determine the limit.
 | 
			
		||||
	//
 | 
			
		||||
	// If the last packet has KeepCS:true, the CS line stays asserted. This
 | 
			
		||||
	// enables doing SPI transaction over multiple calls.
 | 
			
		||||
	//
 | 
			
		||||
	// Conversely, if any packet beside the last one has KeepCS:false, the CS
 | 
			
		||||
	// line will blip for a short amount of time to force a new transaction.
 | 
			
		||||
	//
 | 
			
		||||
	// It was observed on RPi3 hardware to have a one clock delay between each
 | 
			
		||||
	// packet.
 | 
			
		||||
	TxPackets(p []Packet) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Port is the interface to be provided to device drivers.
 | 
			
		||||
//
 | 
			
		||||
// The device driver, that is the driver for the peripheral connected over
 | 
			
		||||
// this port, calls Connect() to retrieve a configured connection as Conn.
 | 
			
		||||
type Port interface {
 | 
			
		||||
	String() string
 | 
			
		||||
	// Connect sets the communication parameters of the connection for use by a
 | 
			
		||||
	// device.
 | 
			
		||||
	//
 | 
			
		||||
	// The device driver must call this function exactly once.
 | 
			
		||||
	//
 | 
			
		||||
	// f must specify the maximum rated speed by the device's spec. The lowest
 | 
			
		||||
	// speed between the port speed and the device speed is selected. Use 0 for f
 | 
			
		||||
	// if there is no known maximum value for this device.
 | 
			
		||||
	//
 | 
			
		||||
	// mode specifies the clock and signal polarities, if the port is using half
 | 
			
		||||
	// duplex (shared MISO and MOSI) or if CS is not needed.
 | 
			
		||||
	//
 | 
			
		||||
	// bits is the number of bits per word. Generally you should use 8.
 | 
			
		||||
	Connect(f physic.Frequency, mode Mode, bits int) (Conn, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PortCloser is a SPI port that can be closed.
 | 
			
		||||
//
 | 
			
		||||
// This interface is meant to be handled by the application.
 | 
			
		||||
type PortCloser interface {
 | 
			
		||||
	io.Closer
 | 
			
		||||
	Port
 | 
			
		||||
	// LimitSpeed sets the maximum port speed.
 | 
			
		||||
	//
 | 
			
		||||
	// It lets an application use a device at a lower speed than the maximum
 | 
			
		||||
	// speed as rated by the device driver. This is useful for example when the
 | 
			
		||||
	// wires are long or the connection is of poor quality.
 | 
			
		||||
	//
 | 
			
		||||
	// This function can be called multiple times and resets the previous value.
 | 
			
		||||
	// 0 is not a valid value for f. The lowest speed between the port speed and
 | 
			
		||||
	// the device speed is selected.
 | 
			
		||||
	LimitSpeed(f physic.Frequency) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pins defines the pins that a SPI port interconnect is using on the host.
 | 
			
		||||
//
 | 
			
		||||
// It is expected that a implementer of ConnCloser or Conn also implement Pins
 | 
			
		||||
// but this is not a requirement.
 | 
			
		||||
type Pins interface {
 | 
			
		||||
	// CLK returns the SCK (clock) pin.
 | 
			
		||||
	CLK() gpio.PinOut
 | 
			
		||||
	// MOSI returns the SDO (master out, slave in) pin.
 | 
			
		||||
	MOSI() gpio.PinOut
 | 
			
		||||
	// MISO returns the SDI (master in, slave out) pin.
 | 
			
		||||
	MISO() gpio.PinIn
 | 
			
		||||
	// CS returns the CSN (chip select) pin.
 | 
			
		||||
	CS() gpio.PinOut
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										262
									
								
								vendor/periph.io/x/conn/v3/spi/spireg/spireg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								vendor/periph.io/x/conn/v3/spi/spireg/spireg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,262 @@
 | 
			
		||||
// Copyright 2017 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package spireg defines the SPI registry for SPI ports discovered on the host.
 | 
			
		||||
//
 | 
			
		||||
// SPI ports discovered on the host are automatically registered in the SPI
 | 
			
		||||
// registry by host.Init().
 | 
			
		||||
package spireg
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/conn/v3/spi"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Opener opens an handle to a port.
 | 
			
		||||
//
 | 
			
		||||
// It is provided by the actual port driver.
 | 
			
		||||
type Opener func() (spi.PortCloser, error)
 | 
			
		||||
 | 
			
		||||
// Ref references a SPI port.
 | 
			
		||||
//
 | 
			
		||||
// It is returned by All() to enumerate all registered ports.
 | 
			
		||||
type Ref struct {
 | 
			
		||||
	// Name of the port.
 | 
			
		||||
	//
 | 
			
		||||
	// It must not be a sole number. It must be unique across the host.
 | 
			
		||||
	Name string
 | 
			
		||||
	// Aliases are the alternative names that can be used to reference this port.
 | 
			
		||||
	Aliases []string
 | 
			
		||||
	// Number of the bus or -1 if the bus doesn't have any "native" number.
 | 
			
		||||
	//
 | 
			
		||||
	// Buses provided by the CPU normally have a 0 based number. Buses provided
 | 
			
		||||
	// via an addon (like over USB) generally are not numbered.
 | 
			
		||||
	//
 | 
			
		||||
	// The port is a bus number plus a CS line.
 | 
			
		||||
	Number int
 | 
			
		||||
	// Open is the factory to open an handle to this SPI port.
 | 
			
		||||
	Open Opener
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Open opens a SPI port by its name, an alias or its number and returns an
 | 
			
		||||
// handle to it.
 | 
			
		||||
//
 | 
			
		||||
// Specify the empty string "" to get the first available port. This is the
 | 
			
		||||
// recommended default value unless an application knows the exact port to use.
 | 
			
		||||
//
 | 
			
		||||
// Each port can register multiple aliases, each leading to the same port
 | 
			
		||||
// handle.
 | 
			
		||||
//
 | 
			
		||||
// "Bus number" is a generic concept that is highly dependent on the platform
 | 
			
		||||
// and OS. On some platform, the first port may have the number 0, 1 or as high
 | 
			
		||||
// as 32766. Bus numbers are not necessarily continuous and may not start at 0.
 | 
			
		||||
// It was observed that the bus number as reported by the OS may change across
 | 
			
		||||
// OS revisions.
 | 
			
		||||
//
 | 
			
		||||
// A SPI port is constructed of the bus number and the chip select (CS) number.
 | 
			
		||||
//
 | 
			
		||||
// When the SPI port is provided by an off board plug and play bus like USB via
 | 
			
		||||
// a FT232H USB device, there can be no associated number.
 | 
			
		||||
func Open(name string) (spi.PortCloser, error) {
 | 
			
		||||
	var r *Ref
 | 
			
		||||
	var err error
 | 
			
		||||
	func() {
 | 
			
		||||
		mu.Lock()
 | 
			
		||||
		defer mu.Unlock()
 | 
			
		||||
		if len(byName) == 0 {
 | 
			
		||||
			err = errors.New("spireg: no port found; did you forget to call Init()?")
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		if len(name) == 0 {
 | 
			
		||||
			r = getDefault()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		// Try by name, by alias, by number.
 | 
			
		||||
		if r = byName[name]; r == nil {
 | 
			
		||||
			if r = byAlias[name]; r == nil {
 | 
			
		||||
				if i, err2 := strconv.Atoi(name); err2 == nil {
 | 
			
		||||
					r = byNumber[i]
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		return nil, errors.New("spireg: can't open unknown port: " + strconv.Quote(name))
 | 
			
		||||
	}
 | 
			
		||||
	return r.Open()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// All returns a copy of all the registered references to all know SPI ports
 | 
			
		||||
// available on this host.
 | 
			
		||||
//
 | 
			
		||||
// The list is sorted by the port name.
 | 
			
		||||
func All() []*Ref {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	out := make([]*Ref, 0, len(byName))
 | 
			
		||||
	for _, v := range byName {
 | 
			
		||||
		r := &Ref{Name: v.Name, Aliases: make([]string, len(v.Aliases)), Number: v.Number, Open: v.Open}
 | 
			
		||||
		copy(r.Aliases, v.Aliases)
 | 
			
		||||
		out = insertRef(out, r)
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register registers a SPI port.
 | 
			
		||||
//
 | 
			
		||||
// Registering the same port name twice is an error, e.g. o.Name(). o.Number()
 | 
			
		||||
// can be -1 to signify that the port doesn't have an inherent "bus number". A
 | 
			
		||||
// good example is a port provided over a FT232H device connected on an USB bus.
 | 
			
		||||
// In this case, the port name should be created from the serial number of the
 | 
			
		||||
// device for unique identification.
 | 
			
		||||
//
 | 
			
		||||
// Only ports with the CS #0 are registered with their number.
 | 
			
		||||
func Register(name string, aliases []string, number int, o Opener) error {
 | 
			
		||||
	if len(name) == 0 {
 | 
			
		||||
		return errors.New("spireg: can't register a port with no name")
 | 
			
		||||
	}
 | 
			
		||||
	if o == nil {
 | 
			
		||||
		return errors.New("spireg: can't register port " + strconv.Quote(name) + " with nil Opener")
 | 
			
		||||
	}
 | 
			
		||||
	if number < -1 {
 | 
			
		||||
		return errors.New("spireg: can't register port " + strconv.Quote(name) + " with invalid port number " + strconv.Itoa(number))
 | 
			
		||||
	}
 | 
			
		||||
	if _, err := strconv.Atoi(name); err == nil {
 | 
			
		||||
		return errors.New("spireg: can't register port " + strconv.Quote(name) + " with name being only a number")
 | 
			
		||||
	}
 | 
			
		||||
	if strings.Contains(name, ":") {
 | 
			
		||||
		return errors.New("spireg: can't register port " + strconv.Quote(name) + " with name containing ':'")
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		if len(alias) == 0 {
 | 
			
		||||
			return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an empty alias")
 | 
			
		||||
		}
 | 
			
		||||
		if name == alias {
 | 
			
		||||
			return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an alias the same as the port name")
 | 
			
		||||
		}
 | 
			
		||||
		if _, err := strconv.Atoi(alias); err == nil {
 | 
			
		||||
			return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an alias that is a number: " + strconv.Quote(alias))
 | 
			
		||||
		}
 | 
			
		||||
		if strings.Contains(alias, ":") {
 | 
			
		||||
			return errors.New("spireg: can't register port " + strconv.Quote(name) + " with an alias containing ':': " + strconv.Quote(alias))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if _, ok := byName[name]; ok {
 | 
			
		||||
		return errors.New("spireg: can't register port " + strconv.Quote(name) + " twice")
 | 
			
		||||
	}
 | 
			
		||||
	if _, ok := byAlias[name]; ok {
 | 
			
		||||
		return errors.New("spireg: can't register port " + strconv.Quote(name) + " twice; it is already an alias")
 | 
			
		||||
	}
 | 
			
		||||
	if number != -1 {
 | 
			
		||||
		if _, ok := byNumber[number]; ok {
 | 
			
		||||
			return errors.New("spireg: can't register port " + strconv.Quote(name) + "; port number " + strconv.Itoa(number) + " is already registered")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		if _, ok := byName[alias]; ok {
 | 
			
		||||
			return errors.New("spireg: can't register port " + strconv.Quote(name) + " twice; alias " + strconv.Quote(alias) + " is already a port")
 | 
			
		||||
		}
 | 
			
		||||
		if _, ok := byAlias[alias]; ok {
 | 
			
		||||
			return errors.New("spireg: can't register port " + strconv.Quote(name) + " twice; alias " + strconv.Quote(alias) + " is already an alias")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r := &Ref{Name: name, Aliases: make([]string, len(aliases)), Number: number, Open: o}
 | 
			
		||||
	copy(r.Aliases, aliases)
 | 
			
		||||
	byName[name] = r
 | 
			
		||||
	if number != -1 {
 | 
			
		||||
		byNumber[number] = r
 | 
			
		||||
	}
 | 
			
		||||
	for _, alias := range aliases {
 | 
			
		||||
		byAlias[alias] = r
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unregister removes a previously registered SPI port.
 | 
			
		||||
//
 | 
			
		||||
// This can happen when a SPI port is exposed via an USB device and the device
 | 
			
		||||
// is unplugged.
 | 
			
		||||
func Unregister(name string) error {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	r := byName[name]
 | 
			
		||||
	if r == nil {
 | 
			
		||||
		return errors.New("spireg: can't unregister unknown port name " + strconv.Quote(name))
 | 
			
		||||
	}
 | 
			
		||||
	delete(byName, name)
 | 
			
		||||
	delete(byNumber, r.Number)
 | 
			
		||||
	for _, alias := range r.Aliases {
 | 
			
		||||
		delete(byAlias, alias)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu     sync.Mutex
 | 
			
		||||
	byName = map[string]*Ref{}
 | 
			
		||||
	// Caches
 | 
			
		||||
	byNumber = map[int]*Ref{}
 | 
			
		||||
	byAlias  = map[string]*Ref{}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// getDefault returns the Ref that should be used as the default port.
 | 
			
		||||
func getDefault() *Ref {
 | 
			
		||||
	var o *Ref
 | 
			
		||||
	if len(byNumber) == 0 {
 | 
			
		||||
		// Fallback to use byName using a lexical sort.
 | 
			
		||||
		name := ""
 | 
			
		||||
		for n, o2 := range byName {
 | 
			
		||||
			if len(name) == 0 || n < name {
 | 
			
		||||
				o = o2
 | 
			
		||||
				name = n
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return o
 | 
			
		||||
	}
 | 
			
		||||
	number := int((^uint(0)) >> 1)
 | 
			
		||||
	for n, o2 := range byNumber {
 | 
			
		||||
		if number > n {
 | 
			
		||||
			number = n
 | 
			
		||||
			o = o2
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func insertRef(l []*Ref, r *Ref) []*Ref {
 | 
			
		||||
	n := r.Name
 | 
			
		||||
	i := search(len(l), func(i int) bool { return l[i].Name > n })
 | 
			
		||||
	l = append(l, nil)
 | 
			
		||||
	copy(l[i+1:], l[i:])
 | 
			
		||||
	l[i] = r
 | 
			
		||||
	return l
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// search implements the same algorithm as sort.Search().
 | 
			
		||||
//
 | 
			
		||||
// It was extracted to to not depend on sort, which depends on reflect.
 | 
			
		||||
func search(n int, f func(int) bool) int {
 | 
			
		||||
	lo := 0
 | 
			
		||||
	for hi := n; lo < hi; {
 | 
			
		||||
		if i := int(uint(lo+hi) >> 1); !f(i) {
 | 
			
		||||
			lo = i + 1
 | 
			
		||||
		} else {
 | 
			
		||||
			hi = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return lo
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user