First implementation
This commit is contained in:
		
							
								
								
									
										1
									
								
								vendor/periph.io/x/periph/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/periph.io/x/periph/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
bin
 | 
			
		||||
							
								
								
									
										254
									
								
								vendor/periph.io/x/periph/.gohci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								vendor/periph.io/x/periph/.gohci.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,254 @@
 | 
			
		||||
# See https://github.com/periph/gohci
 | 
			
		||||
version: 1
 | 
			
		||||
workers:
 | 
			
		||||
# BeagleBone Green Wireles by SeedStudio.
 | 
			
		||||
# https://beagleboard.org/green-wireless
 | 
			
		||||
- name: beaglebone-4373
 | 
			
		||||
  checks:
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - install
 | 
			
		||||
    - -v
 | 
			
		||||
    - ./cmd/headers-list
 | 
			
		||||
    - ./cmd/i2c-list
 | 
			
		||||
    - ./cmd/periph-info
 | 
			
		||||
    - ./cmd/periph-smoketest
 | 
			
		||||
    - ./cmd/spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-info
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - headers-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - i2c-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - gpio
 | 
			
		||||
    - -pin1
 | 
			
		||||
    - P8_45
 | 
			
		||||
    - -pin2
 | 
			
		||||
    - P8_46
 | 
			
		||||
# C.H.I.P. by Next Thing Co. The company closed its doors.
 | 
			
		||||
- name: chip-a87d
 | 
			
		||||
  checks:
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - install
 | 
			
		||||
    - -v
 | 
			
		||||
    - ./cmd/gpio-list
 | 
			
		||||
    - ./cmd/headers-list
 | 
			
		||||
    - ./cmd/i2c-list
 | 
			
		||||
    - ./cmd/periph-info
 | 
			
		||||
    - ./cmd/periph-smoketest
 | 
			
		||||
    - ./cmd/spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-info
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - gpio-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - headers-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - i2c-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - chip
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - i2c-testboard
 | 
			
		||||
    - -bus
 | 
			
		||||
    - 1
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - onewire-testboard
 | 
			
		||||
    - -i2cbus
 | 
			
		||||
    - 1
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - sysfs-benchmark
 | 
			
		||||
    - -p
 | 
			
		||||
    - 1013
 | 
			
		||||
    - -short
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - sysfs-benchmark
 | 
			
		||||
    - -p
 | 
			
		||||
    - 132
 | 
			
		||||
    - -short
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - allwinner-benchmark
 | 
			
		||||
    - -p
 | 
			
		||||
    - 132
 | 
			
		||||
    - -short
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - spi-testboard
 | 
			
		||||
# Old MacBook Pro on 10.9.
 | 
			
		||||
- name: mbp
 | 
			
		||||
  checks:
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - test
 | 
			
		||||
    - -race
 | 
			
		||||
    - ./...
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - install
 | 
			
		||||
    - -v
 | 
			
		||||
    - ./cmd/gpio-list
 | 
			
		||||
    - ./cmd/headers-list
 | 
			
		||||
    - ./cmd/i2c-list
 | 
			
		||||
    - ./cmd/periph-info
 | 
			
		||||
    - ./cmd/spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-info
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - gpio-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - headers-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - i2c-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - spi-list
 | 
			
		||||
# ODROID-C1+ by HardKernel
 | 
			
		||||
# https://www.hardkernel.com/shop/odroid-c1/
 | 
			
		||||
- name: odroid-483d
 | 
			
		||||
  checks:
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - test
 | 
			
		||||
    - -cover
 | 
			
		||||
    - -bench=.
 | 
			
		||||
    - -benchtime=1000ms
 | 
			
		||||
    - -benchmem
 | 
			
		||||
    - ./...
 | 
			
		||||
    - ./...
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - install
 | 
			
		||||
    - -v
 | 
			
		||||
    - ./cmd/gpio-list
 | 
			
		||||
    - ./cmd/headers-list
 | 
			
		||||
    - ./cmd/i2c-list
 | 
			
		||||
    - ./cmd/periph-info
 | 
			
		||||
    - ./cmd/periph-smoketest
 | 
			
		||||
    - ./cmd/spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-info
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - gpio-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - headers-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - i2c-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - odroid-c1
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - i2c-testboard
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - onewire-testboard
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - spi-testboard
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - sysfs-benchmark
 | 
			
		||||
    - -p
 | 
			
		||||
    - 97
 | 
			
		||||
    - -short
 | 
			
		||||
# Raspberry Pi 3
 | 
			
		||||
- name: raspberrypi-2f34
 | 
			
		||||
  checks:
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - install
 | 
			
		||||
    - -v
 | 
			
		||||
    - ./cmd/gpio-list
 | 
			
		||||
    - ./cmd/headers-list
 | 
			
		||||
    - ./cmd/i2c-list
 | 
			
		||||
    - ./cmd/periph-info
 | 
			
		||||
    - ./cmd/periph-smoketest
 | 
			
		||||
    - ./cmd/spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-info
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - gpio-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - headers-list
 | 
			
		||||
    - -f
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - i2c-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - spi-list
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - i2c-testboard
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - onewire-testboard
 | 
			
		||||
    - -i2cbus
 | 
			
		||||
    - 1
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - spi-testboard
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - sysfs-benchmark
 | 
			
		||||
    - -p
 | 
			
		||||
    - 12
 | 
			
		||||
    - -short
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - bcm283x-benchmark
 | 
			
		||||
    - -p
 | 
			
		||||
    - 12
 | 
			
		||||
    - -short
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - gpio
 | 
			
		||||
    - -pin1
 | 
			
		||||
    - P1_15
 | 
			
		||||
    - -pin2
 | 
			
		||||
    - P1_16
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - periph-smoketest
 | 
			
		||||
    - bcm283x
 | 
			
		||||
    - -quick
 | 
			
		||||
# Laptop on Windows 10.
 | 
			
		||||
- name: win10
 | 
			
		||||
  checks:
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - test
 | 
			
		||||
    - -cover
 | 
			
		||||
    - -bench=.
 | 
			
		||||
    - -benchtime=1000ms
 | 
			
		||||
    - -benchmem
 | 
			
		||||
    - ./...
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - test
 | 
			
		||||
    - -race
 | 
			
		||||
    - ./...
 | 
			
		||||
  - cmd:
 | 
			
		||||
    - go
 | 
			
		||||
    - vet
 | 
			
		||||
    - -all
 | 
			
		||||
    - -unsafeptr=false
 | 
			
		||||
    - ./...
 | 
			
		||||
							
								
								
									
										53
									
								
								vendor/periph.io/x/periph/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								vendor/periph.io/x/periph/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
# Copyright 2019 The Periph Authors. All rights reserved.
 | 
			
		||||
# Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
# that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
language: go
 | 
			
		||||
sudo: false
 | 
			
		||||
dist: xenial
 | 
			
		||||
go_import_path: periph.io/x/periph
 | 
			
		||||
 | 
			
		||||
matrix:
 | 
			
		||||
  include:
 | 
			
		||||
  - go: 1.12.x
 | 
			
		||||
    env: GO111MODULE=on
 | 
			
		||||
    cache:
 | 
			
		||||
      directories:
 | 
			
		||||
        # go1.10+ 'go test' cache on linux (macOS and Windows are # different).
 | 
			
		||||
        - $HOME/.cache/go-build
 | 
			
		||||
        # go1.11+ with GO111MODULE=on
 | 
			
		||||
        - $GOPATH/pkg/mod
 | 
			
		||||
        # Cache tools sources. Manually verified that both misspell and ineffassign
 | 
			
		||||
        # only depend on the stdlib.
 | 
			
		||||
        - $GOPATH/src/github\.com
 | 
			
		||||
        # For shadow.
 | 
			
		||||
        - $GOPATH/src/golang\.org
 | 
			
		||||
    # Dear future me: if you touch this line, don't forget to update the
 | 
			
		||||
    # conditions below!
 | 
			
		||||
  - go: 1.7.6
 | 
			
		||||
 | 
			
		||||
before_script:
 | 
			
		||||
  - echo $TRAVIS_GO_VERSION
 | 
			
		||||
  - go get -t -v periph.io/x/periph/...
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then go get -u -v github.com/client9/misspell/cmd/misspell github.com/gordonklaus/ineffassign golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow; fi
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  # Checks run on latest version.
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then echo 'Check Code is well formatted'; ! gofmt -s -d . | read; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then echo 'Looking for external dependencies:'; go list -f '{{join .Imports "\n"}}' periph.io/x/periph/... | sort | uniq | grep -v ^periph.io/x/periph | xargs go list -f '{{if not .Standard}}- {{.ImportPath}}{{end}}'; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then echo 'Erroring on external dependencies:'; ! go list -f '{{join .Imports "\n"}}' periph.io/x/periph/... | sort | uniq | grep -v ^periph.io/x/periph | xargs go list -f '{{if not .Standard}}Remove {{.ImportPath}}{{end}}' | grep -q Remove; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then echo 'Erroring on /host depending on /devices:'; ! go list -f '{{.ImportPath}} depends on {{join .Imports ", "}}' periph.io/x/periph/host/... | sort | uniq | grep periph.io/x/periph/devices; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then echo 'Erroring on /conn depending on /devices:'; ! go list -f '{{.ImportPath}} depends on {{join .Imports ", "}}' periph.io/x/periph/conn/... | sort | uniq | grep periph.io/x/periph/devices; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then echo 'Erroring on /conn depending on /host:'; ! go list -f '{{.ImportPath}} depends on {{join .Imports ", "}}' periph.io/x/periph/conn/... | sort | uniq | grep periph.io/x/periph/host; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then echo 'Erroring on misspelling'; ! misspell . | grep a; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then ineffassign .; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then ! go vet -vettool=$(which shadow) ./... |& grep -v '"err"' | grep -e '^[^#]'; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then bash -c 'set -e; echo "" > coverage.txt; for d in $(go list ./...); do go test -covermode=count -coverprofile=p.out $d; if [ -f p.out ]; then cat p.out >> coverage.txt; rm p.out; fi; done'; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then go test -race ./...; fi
 | 
			
		||||
 | 
			
		||||
  # Checks run on older version.
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION == 1.7.6 ]]; then go test ./...; fi
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION == 1.7.6 ]]; then if find . -path ./.git -prune -o -type f -executable -print | grep -e . ; then echo 'Do not commit executables'; false; fi; fi
 | 
			
		||||
 | 
			
		||||
after_success:
 | 
			
		||||
  - if [[ $TRAVIS_GO_VERSION != 1.7.6 ]]; then bash <(curl -s https://codecov.io/bash); fi
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/periph.io/x/periph/AUTHORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/periph.io/x/periph/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/periph/CONTRIBUTING.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								vendor/periph.io/x/periph/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/periph/CONTRIBUTORS
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								vendor/periph.io/x/periph/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/periph/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								vendor/periph.io/x/periph/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.
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/periph.io/x/periph/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/periph.io/x/periph/Makefile
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
# Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
# Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
# that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
# This Makefile captures common tasks for the periph library. The hope is that this Makefile can remain
 | 
			
		||||
# simple and straightforward...
 | 
			
		||||
 | 
			
		||||
# *** This Makefile is a work in progress, please help impove it! ***
 | 
			
		||||
 | 
			
		||||
# not sure yet what all should do...
 | 
			
		||||
all:
 | 
			
		||||
	@echo Available targets: test build
 | 
			
		||||
 | 
			
		||||
.PHONY: all test clean depend
 | 
			
		||||
 | 
			
		||||
# test runs the platform independent tests
 | 
			
		||||
# (gofmt|grep is used to obtain a non-zero exit status if the formatting is off)
 | 
			
		||||
test:
 | 
			
		||||
	go test ./...
 | 
			
		||||
	@if gofmt -l . | grep .go; then \
 | 
			
		||||
	  echo "Repo contains improperly formatted go files; run gofmt on above files" && exit 1; \
 | 
			
		||||
	else echo "OK gofmt"; fi
 | 
			
		||||
	-go vet -unsafeptr=false ./...
 | 
			
		||||
 | 
			
		||||
# BUILD
 | 
			
		||||
#
 | 
			
		||||
# The build target cross compiles each program in cmd to a binary for each platform in the bin
 | 
			
		||||
# directory. It is assumed that each command has a main.go file in its directory. Trying to keep all
 | 
			
		||||
# this relatively simple and not descend into makefile hell...
 | 
			
		||||
 | 
			
		||||
# Get a list of all main.go in cmd subdirs
 | 
			
		||||
# MAINS becomes: cmd/gpio-list/main.go cmd/periph-info/main.go ...
 | 
			
		||||
MAINS := $(wildcard cmd/*/main.go)
 | 
			
		||||
# Get a list of all the commands, i.e. names of dirs that contain a main.go
 | 
			
		||||
# CMDS becomes: gpio-list periph-info ...
 | 
			
		||||
CMDS  := $(patsubst cmd/%/main.go,%,$(MAINS))
 | 
			
		||||
# Get a list of binaries to build
 | 
			
		||||
# BINS becomes: bin/gpio-list-arm bin/periph-info-arm ... bin/gpio-list-arm64 bin/periph-info-arm64 ...
 | 
			
		||||
ARCHS := arm arm64 amd64 win64.exe
 | 
			
		||||
BINS=$(foreach arch,$(ARCHS),$(foreach cmd,$(CMDS),bin/$(cmd)-$(arch)))
 | 
			
		||||
 | 
			
		||||
build: depend bin $(BINS)
 | 
			
		||||
bin:
 | 
			
		||||
	mkdir bin
 | 
			
		||||
 | 
			
		||||
# Rules to build binaries for a command in cmd. The prereqs could be improved...
 | 
			
		||||
bin/%-arm: cmd/%/*.go
 | 
			
		||||
	GOARCH=arm GOOS=linux go build -o $@ ./cmd/$*
 | 
			
		||||
bin/%-arm64: cmd/%/*.go
 | 
			
		||||
	GOARCH=arm64 GOOS=linux go build -o $@ ./cmd/$*
 | 
			
		||||
bin/%-amd64: cmd/%/*.go
 | 
			
		||||
	GOARCH=amd64 GOOS=linux go build -o $@ ./cmd/$*
 | 
			
		||||
bin/%-win64.exe: cmd/%/*.go
 | 
			
		||||
	GOARCH=amd64 GOOS=windows go build -o $@ ./cmd/$*
 | 
			
		||||
	
 | 
			
		||||
# clean removes all compiled binaries
 | 
			
		||||
clean:
 | 
			
		||||
	rm bin/*-*
 | 
			
		||||
	rmdir bin
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/periph.io/x/periph/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/periph.io/x/periph/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
# periph - Peripherals I/O in Go
 | 
			
		||||
 | 
			
		||||
[](https://periph.io/)
 | 
			
		||||
 | 
			
		||||
Documentation is at https://periph.io
 | 
			
		||||
 | 
			
		||||
[](https://godoc.org/periph.io/x/periph)
 | 
			
		||||
[](https://goreportcard.com/report/periph.io/x/periph)
 | 
			
		||||
[](https://codecov.io/gh/google/periph)
 | 
			
		||||
[](https://travis-ci.org/google/periph)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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/).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
Blink a LED:
 | 
			
		||||
 | 
			
		||||
~~~go
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
    "time"
 | 
			
		||||
    "periph.io/x/periph/conn/gpio"
 | 
			
		||||
    "periph.io/x/periph/host"
 | 
			
		||||
    "periph.io/x/periph/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/google/periph/blob/master/AUTHORS) and
 | 
			
		||||
[CONTRIBUTORS](https://github.com/google/periph/blob/master/CONTRIBUTORS).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Disclaimer
 | 
			
		||||
 | 
			
		||||
This is not an official Google product (experimental or otherwise), it
 | 
			
		||||
is just code that happens to be owned by Google.
 | 
			
		||||
 | 
			
		||||
This project is not affiliated with the Go project.
 | 
			
		||||
							
								
								
									
										103
									
								
								vendor/periph.io/x/periph/conn/conn.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								vendor/periph.io/x/periph/conn/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
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/periph.io/x/periph/conn/duplex_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								vendor/periph.io/x/periph/conn/duplex_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
// Code generated by "stringer -type Duplex"; DO NOT EDIT
 | 
			
		||||
 | 
			
		||||
package conn
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/periph.io/x/periph/conn/gpio/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/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/periph/conn/gpio/gpio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										329
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/physic"
 | 
			
		||||
	"periph.io/x/periph/conn/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/periph/conn/gpio/gpioreg/gpioreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/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/periph/conn/gpio/gpioreg/natsort.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/gpio/gpiostream/gpiostream.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/physic"
 | 
			
		||||
	"periph.io/x/periph/conn/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/periph/conn/i2c/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/pin"
 | 
			
		||||
 | 
			
		||||
// Well known pin functionality.
 | 
			
		||||
const (
 | 
			
		||||
	SCL pin.Func = "I2C_SCL" // Clock
 | 
			
		||||
	SDA pin.Func = "I2C_SDA" // Data
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										135
									
								
								vendor/periph.io/x/periph/conn/i2c/i2c.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn#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/periph/conn"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/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/periph/conn/i2c/i2creg/i2creg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/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/periph/conn/physic/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/physic/physic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 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)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										2254
									
								
								vendor/periph.io/x/periph/conn/physic/units.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2254
									
								
								vendor/periph.io/x/periph/conn/physic/units.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										58
									
								
								vendor/periph.io/x/periph/conn/pin/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/pin/pin.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 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/periph/conn/pin/pinreg/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/pin/pinreg/pinreg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio/gpioreg"
 | 
			
		||||
	"periph.io/x/periph/conn/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/periph/conn/spi/func.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/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/periph/conn/spi/spi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn#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/periph/conn"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/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/periph/conn/spi/spireg/spireg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								vendor/periph.io/x/periph/conn/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/periph/conn/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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										220
									
								
								vendor/periph.io/x/periph/host/allwinner/a20.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								vendor/periph.io/x/periph/host/allwinner/a20.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
			
		||||
// 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 pin mapping information that is specific to the Allwinner
 | 
			
		||||
// A20 model.
 | 
			
		||||
 | 
			
		||||
package allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// mappingA20 describes the mapping of the A20 processor gpios to their
 | 
			
		||||
// alternate functions.
 | 
			
		||||
//
 | 
			
		||||
// It omits the in & out functions which are available on all gpio.
 | 
			
		||||
//
 | 
			
		||||
// The mapping comes from the datasheet page 241:
 | 
			
		||||
// http://dl.linux-sunxi.org/A20/A20%20User%20Manual%202013-03-22.pdf
 | 
			
		||||
var mappingA20 = map[string][5]pin.Func{
 | 
			
		||||
	"PA0":  {"ERXD3", "SPI1_CS0", "UART2_RTS", "GRXD3"},
 | 
			
		||||
	"PA1":  {"ERXD2", "SPI1_CLK", "UART2_CTS", "GRXD2"},
 | 
			
		||||
	"PA2":  {"ERXD1", "SPI1_MOSI", "UART2_TX", "GRXD1"},
 | 
			
		||||
	"PA3":  {"ERXD0", "SPI1_MISO", "UART2_RX", "GRXD0"},
 | 
			
		||||
	"PA4":  {"ETXD3", "SPI1_CS1", "", "GTXD3"},
 | 
			
		||||
	"PA5":  {"ETXD2", "SPI3_CS0", "", "GTXD2"},
 | 
			
		||||
	"PA6":  {"ETXD1", "SPI3_CLK", "", "GTXD1"},
 | 
			
		||||
	"PA7":  {"ETXD0", "SPI3_MOSI", "", "GTXD0"},
 | 
			
		||||
	"PA8":  {"ERXCK", "SPI3_MISO", "", "CRXCK"},
 | 
			
		||||
	"PA9":  {"ERXERR", "SPI3_CS1", "", "GNULL", "I2S1_MCLK"},
 | 
			
		||||
	"PA10": {"ERXDV", "", "UART1_TX", "GRXCTL"},
 | 
			
		||||
	"PA11": {"EMDC", "", "UART1_RX", "GMDC"},
 | 
			
		||||
	"PA12": {"EMDIO", "UART6_TX", "UART1_RTS", "GMDIO"},
 | 
			
		||||
	"PA13": {"ETXEN", "UART6_RX", "UART1_CTS", "GTXCTL"},
 | 
			
		||||
	"PA14": {"ETXCK", "UART7_TX", "UART1_DTR", "GNULL", "I2S1_SCK"},
 | 
			
		||||
	"PA15": {"ECRS", "UART7_RX", "UART1_DSR", "GTXCK", "I2S1_WS"},
 | 
			
		||||
	"PA16": {"ECOL", "CAN_TX", "UART1_DCD", "GCLKIN", "I2S1_DOUT"},
 | 
			
		||||
	"PA17": {"ETXERR", "CAN_RX", "UART1_RI", "GNULL", "I2S1_DIN"},
 | 
			
		||||
	"PB0":  {"I2C0_SCL"},
 | 
			
		||||
	"PB1":  {"I2C0_SDA"},
 | 
			
		||||
	"PB2":  {"PWM0"},
 | 
			
		||||
	"PB3":  {"IR0_TX", "", "SPDIF_MCLK", "", "STANBYWFI"},
 | 
			
		||||
	"PB4":  {"IR0_RX"},
 | 
			
		||||
	"PB5":  {"I2S0_MCLK", "AC97_MCLK"},
 | 
			
		||||
	"PB6":  {"I2S0_SCK", "AC97_SCK"},
 | 
			
		||||
	"PB7":  {"I2S0_WS", "AC97_SYNC"},
 | 
			
		||||
	"PB8":  {"I2S0_DOUT0", "AC97_DOUT"},
 | 
			
		||||
	"PB9":  {"I2S0_DOUT1"},
 | 
			
		||||
	"PB10": {"I2S0_DOUT2"},
 | 
			
		||||
	"PB11": {"I2S0_DOUT3"},
 | 
			
		||||
	"PB12": {"I2S0_DIN", "AC97_DI", "SPDIF_DI"},
 | 
			
		||||
	"PB13": {"SPI2_CS1", "", "SPDIF_DO"},
 | 
			
		||||
	"PB14": {"SPI2_CS0", "JTAG0_TMS"},
 | 
			
		||||
	"PB15": {"SPI2_CLK", "JTAG0_TCK"},
 | 
			
		||||
	"PB16": {"SPI2_MOSI", "JTAG0_TDO"},
 | 
			
		||||
	"PB17": {"SPI2_MISO", "JTAG0_TDI"},
 | 
			
		||||
	"PB18": {"I2C1_SCL"},
 | 
			
		||||
	"PB19": {"I2C1_SDA"},
 | 
			
		||||
	"PB20": {"I2C2_SCL"},
 | 
			
		||||
	"PB21": {"I2C2_SDA"},
 | 
			
		||||
	"PB22": {"UART0_TX", "IR1_TX"},
 | 
			
		||||
	"PB23": {"UART0_RX", "IR1_RX"},
 | 
			
		||||
	"PC0":  {"NWE#", "SPI0_MOSI"},
 | 
			
		||||
	"PC1":  {"NALE", "SPI0_MISO"},
 | 
			
		||||
	"PC2":  {"NCLE", "SPI0_CLK"},
 | 
			
		||||
	"PC3":  {"NCE1"},
 | 
			
		||||
	"PC4":  {"NCE0"},
 | 
			
		||||
	"PC5":  {"NRE#"},
 | 
			
		||||
	"PC6":  {"NRB0", "SDC2_CMD"},
 | 
			
		||||
	"PC7":  {"NRB1", "SDC2_CLK"},
 | 
			
		||||
	"PC8":  {"NDQ0", "SDC2_D0"},
 | 
			
		||||
	"PC9":  {"NDQ1", "SDC2_D1"},
 | 
			
		||||
	"PC10": {"NDQ2", "SDC2_D2"},
 | 
			
		||||
	"PC11": {"NDQ3", "SDC2_D3"},
 | 
			
		||||
	"PC12": {"NDQ4"},
 | 
			
		||||
	"PC13": {"NDQ5"},
 | 
			
		||||
	"PC14": {"NDQ6"},
 | 
			
		||||
	"PC15": {"NDQ7"},
 | 
			
		||||
	"PC16": {"NWP"},
 | 
			
		||||
	"PC17": {"NCE2"},
 | 
			
		||||
	"PC18": {"NCE3"},
 | 
			
		||||
	"PC19": {"NCE4", "SPI2_CS0", "", "", "PC_EINT12"},
 | 
			
		||||
	"PC20": {"NCE5", "SPI2_CLK", "", "", "PC_EINT13"},
 | 
			
		||||
	"PC21": {"NCE6", "SPI2_MOSI", "", "", "PC_EINT14"},
 | 
			
		||||
	"PC22": {"NCE7", "SPI2_MISO", "", "", "PC_EINT15"},
 | 
			
		||||
	"PC23": {"", "SPI2_CS0"},
 | 
			
		||||
	"PC24": {"NDQS"},
 | 
			
		||||
	"PD0":  {"LCD0_D0", "LVDS0_VP0"},
 | 
			
		||||
	"PD1":  {"LCD0_D1", "LVDS0_VN0"},
 | 
			
		||||
	"PD2":  {"LCD0_D2", "LVDS0_VP1"},
 | 
			
		||||
	"PD3":  {"LCD0_D3", "LVDS0_VN1"},
 | 
			
		||||
	"PD4":  {"LCD0_D4", "LVDS0_VP2"},
 | 
			
		||||
	"PD5":  {"LCD0_D5", "LVDS0_VN2"},
 | 
			
		||||
	"PD6":  {"LCD0_D6", "LVDS0_VPC"},
 | 
			
		||||
	"PD7":  {"LCD0_D7", "LVDS0_VNC"},
 | 
			
		||||
	"PD8":  {"LCD0_D8", "LVDS0_VP3"},
 | 
			
		||||
	"PD9":  {"LCD0_D9", "LVDS0_VN3"},
 | 
			
		||||
	"PD10": {"LCD0_D10", "LVDS1_VP0"},
 | 
			
		||||
	"PD11": {"LCD0_D11", "LVDS1_VN0"},
 | 
			
		||||
	"PD12": {"LCD0_D12", "LVDS1_VP1"},
 | 
			
		||||
	"PD13": {"LCD0_D13", "LVDS1_VN1"},
 | 
			
		||||
	"PD14": {"LCD0_D14", "LVDS1_VP2"},
 | 
			
		||||
	"PD15": {"LCD0_D15", "LVDS1_VN2"},
 | 
			
		||||
	"PD16": {"LCD0_D16", "LVDS1_VPC"},
 | 
			
		||||
	"PD17": {"LCD0_D17", "LVDS1_VNC"},
 | 
			
		||||
	"PD18": {"LCD0_D18", "LVDS1_VP3"},
 | 
			
		||||
	"PD19": {"LCD0_D19", "LVDS1_VN3"},
 | 
			
		||||
	"PD20": {"LCD0_D20", "CSI1_MCLK"},
 | 
			
		||||
	"PD21": {"LCD0_D21", "SMC_VPPEN"},
 | 
			
		||||
	"PD22": {"LCD0_D22", "SMC_VPPPP"},
 | 
			
		||||
	"PD23": {"LCD0_D23", "SMC_DET"},
 | 
			
		||||
	"PD24": {"LCD0_CLK", "SMC_VCCEN"},
 | 
			
		||||
	"PD25": {"LCD0_DE", "SMC_RST"},
 | 
			
		||||
	"PD26": {"LCD0_HSYNC", "SMC_SLK"},
 | 
			
		||||
	"PD27": {"LCD0_VSYNC", "SMC_SDA"},
 | 
			
		||||
	"PE0":  {"TS0_CLK", "CSI0_PCLK"},
 | 
			
		||||
	"PE1":  {"TS0_ERR", "CSI0_MCLK"},
 | 
			
		||||
	"PE2":  {"TS0_SYNC", "CSI0_HSYNC"},
 | 
			
		||||
	"PE3":  {"TS0_DLVD", "CSI0_VSYNC"},
 | 
			
		||||
	"PE4":  {"TS0_D0", "CSI0_D0"},
 | 
			
		||||
	"PE5":  {"TS0_D1", "CSI0_D1"},
 | 
			
		||||
	"PE6":  {"TS0_D2", "CSI0_D2"},
 | 
			
		||||
	"PE7":  {"TS0_D3", "CSI0_D3"},
 | 
			
		||||
	"PE8":  {"TS0_D4", "CSI0_D4"},
 | 
			
		||||
	"PE9":  {"TS0_D5", "CSI0_D5"},
 | 
			
		||||
	"PE10": {"TS0_D6", "CSI0_D6"},
 | 
			
		||||
	"PE11": {"TS0_D7", "CSI0_D7"},
 | 
			
		||||
	"PF0":  {"SDC0_D1", "", "JTAG1_TMS"},
 | 
			
		||||
	"PF1":  {"SDC0_D0", "", "JTAG1_TDI"},
 | 
			
		||||
	"PF2":  {"SDC0_CLK", "", "UART0_TX"},
 | 
			
		||||
	"PF3":  {"SDC0_CMD", "", "JTAG1_TDO"},
 | 
			
		||||
	"PF4":  {"SDC0_D3", "", "UART0_RX"},
 | 
			
		||||
	"PF5":  {"SDC0_D2", "", "JTAG1_TCK"},
 | 
			
		||||
	"PG0":  {"TS1_CLK", "CSI1_PCLK", "SDC1_CMD"},
 | 
			
		||||
	"PG1":  {"TS1_ERR", "CSI1_MCLK", "SDC1_CLK"},
 | 
			
		||||
	"PG2":  {"TS1_SYNC", "CSI1_HSYNC", "SDC1_D0"},
 | 
			
		||||
	"PG3":  {"TS1_DVLD", "CSI1_VSYNC", "SDC1_D1"},
 | 
			
		||||
	"PG4":  {"TS1_D0", "CSI1_D0", "SDC1_D2", "CSI0_D8"},
 | 
			
		||||
	"PG5":  {"TS1_D1", "CSI1_D1", "SDC1_D3", "CSI0_D9"},
 | 
			
		||||
	"PG6":  {"TS1_D2", "CSI1_D2", "UART3_TX", "CSI0_D10"},
 | 
			
		||||
	"PG7":  {"TS1_D3", "CSI1_D3", "UART3_RX", "CSI0_D11"},
 | 
			
		||||
	"PG8":  {"TS1_D4", "CSI1_D4", "UART3_RTS", "CSI0_D12"},
 | 
			
		||||
	"PG9":  {"TS1_D5", "CSI1_D4", "UART3_CTS", "CSI0_D13"},
 | 
			
		||||
	"PG10": {"TS1_D6", "CSI1_D6", "UART4_TX", "CSI0_D14"},
 | 
			
		||||
	"PG11": {"TS1_D7", "CSI1_D7", "UART4_RX", "CSI0_D15"},
 | 
			
		||||
	"PH0":  {"LCD1_D0", "", "UART3_TX", "", "PH_EINT0"},
 | 
			
		||||
	"PH1":  {"LCD1_D1", "", "UART3_RX", "", "PH_EINT1"},
 | 
			
		||||
	"PH2":  {"LCD1_D2", "", "UART3_RTS", "", "PH_EINT2"},
 | 
			
		||||
	"PH3":  {"LCD1_D3", "", "UART3_CTS", "", "PH_EINT3"},
 | 
			
		||||
	"PH4":  {"LCD1_D4", "", "UART4_TX", "", "PH_EINT4"},
 | 
			
		||||
	"PH5":  {"LCD1_D5", "", "UART4_RX", "", "PH_EINT5"},
 | 
			
		||||
	"PH6":  {"LCD1_D6", "", "UART5_TX", "MS_BS", "PH_EINT6"},
 | 
			
		||||
	"PH7":  {"LCD1_D7", "", "UART5_RX", "MS_CLK", "PH_EINT7"},
 | 
			
		||||
	"PH8":  {"LCD1_D8", "ERXD3", "KP_IN0", "MS_D0", "PH_EINT8"},
 | 
			
		||||
	"PH9":  {"LCD1_D9", "ERXD2", "KP_IN1", "MS_D1", "PH_EINT9"},
 | 
			
		||||
	"PH10": {"LCD1_D10", "ERXD1", "KP_IN2", "MS_D2", "PH_EINT10"},
 | 
			
		||||
	"PH11": {"LCD1_D11", "ERXD0", "KP_IN3", "MS_D3", "PH_EINT11"},
 | 
			
		||||
	"PH12": {"LCD1_D12", "", "PS2_SCK1", "", "PH_EINT12"},
 | 
			
		||||
	"PH13": {"LCD1_D13", "", "PS2_SDA1", "SMC_RST", "PH_EINT13"},
 | 
			
		||||
	"PH14": {"LCD1_D14", "ETXD3", "KP_IN4", "SMC_VPPEN", "PH_EINT14"},
 | 
			
		||||
	"PH15": {"LCD1_D15", "ETXD2", "KP_IN5", "SMC_VPPPP", "PH_EINT15"},
 | 
			
		||||
	"PH16": {"LCD1_D16", "ETXD1", "KP_IN6", "SMC_DET", "PH_EINT16"},
 | 
			
		||||
	"PH17": {"LCD1_D17", "ETXD0", "KP_IN7", "SMC_VCCEN", "PH_EINT17"},
 | 
			
		||||
	"PH18": {"LCD1_D18", "ERXCK", "KP_OUT0", "SMC_SLK", "PH_EINT18"},
 | 
			
		||||
	"PH19": {"LCD1_D19", "ERXERR", "KP_OUT1", "SMC_SDA", "PH_EINT19"},
 | 
			
		||||
	"PH20": {"LCD1_D20", "ERXDV", "CAN_TX", "", "PH_EINT20"},
 | 
			
		||||
	"PH21": {"LCD1_D21", "EMDC", "CAN_RX", "", "PH_EINT21"},
 | 
			
		||||
	"PH22": {"LCD1_D22", "EMDIO", "KP_OUT2", "SDC1_CMD", ""},
 | 
			
		||||
	"PH23": {"LCD1_D23", "ETXEN", "KP_OUT3", "SDC1_CLK", ""},
 | 
			
		||||
	"PH24": {"LCD1_CLK", "ETXCK", "KP_OUT4", "SDC1_D0", ""},
 | 
			
		||||
	"PH25": {"LCD1_DE", "ECRS", "KP_OUT5", "SDC1_D1", ""},
 | 
			
		||||
	"PH26": {"LCD1_HSYNC", "ECOL", "KP_OUT6", "SDC1_D2", ""},
 | 
			
		||||
	"PH27": {"LCD1_VSYNC", "ETXERR", "KP_OUT7", "SDC1_D3", ""},
 | 
			
		||||
	"PI0":  {"", "I2C3_SCL"},
 | 
			
		||||
	"PI1":  {"", "I2C3_SDA"},
 | 
			
		||||
	"PI2":  {"", "I2C4_SCL"},
 | 
			
		||||
	"PI3":  {"PWM1", "I2C4_SDA"},
 | 
			
		||||
	"PI4":  {"SDC3_CMD"},
 | 
			
		||||
	"PI5":  {"SDC3_CLK"},
 | 
			
		||||
	"PI6":  {"SDC3_D0"},
 | 
			
		||||
	"PI7":  {"SDC3_D1"},
 | 
			
		||||
	"PI8":  {"SDC3_D2"},
 | 
			
		||||
	"PI9":  {"SDC3_D3"},
 | 
			
		||||
	"PI10": {"SPI0_CS0", "UART5_TX", "", "PI_EINT22"},
 | 
			
		||||
	"PI11": {"SPI0_CLK", "UART5_RX", "", "PI_EINT23"},
 | 
			
		||||
	"PI12": {"SPI0_MOSI", "UART6_TX", "CLK_OUT_A", "PI_EINT24"},
 | 
			
		||||
	"PI13": {"SPI0_MISO", "UART6_RX", "CLK_OUT_B", "PI_EINT25"},
 | 
			
		||||
	"PI14": {"SPI0_CS0", "PS2_SCK1", "TCLKIN0", "PI_EINT26"},
 | 
			
		||||
	"PI15": {"SPI1_CS1", "PS2_SDA1", "TCLKIN1", "PI_EINT27"},
 | 
			
		||||
	"PI16": {"SPI1_CS0", "UART2_RTS", "", "PI_EINT28"},
 | 
			
		||||
	"PI17": {"SPI1_CLK", "UART2_CTS", "", "PI_EINT29"},
 | 
			
		||||
	"PI18": {"SPI1_MOSI", "UART2_TX", "", "PI_EINT30"},
 | 
			
		||||
	"PI19": {"SPI1_MISO", "UART2_RX", "", "PI_EINT31"},
 | 
			
		||||
	"PI20": {"PS2_SCK0", "UART7_TX", "HSCL"},
 | 
			
		||||
	"PI21": {"PS2_SDA0", "UART7_RX", "HSDA"},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mapA20Pins uses mappingA20 to actually set the altFunc fields of all gpio
 | 
			
		||||
// and mark them as available.
 | 
			
		||||
//
 | 
			
		||||
// It is called by the generic allwinner processor code if an A20 is detected.
 | 
			
		||||
func mapA20Pins() error {
 | 
			
		||||
	for name, altFuncs := range mappingA20 {
 | 
			
		||||
		pin := cpupins[name]
 | 
			
		||||
		pin.altFunc = altFuncs
 | 
			
		||||
		pin.available = true
 | 
			
		||||
		if strings.Contains(string(altFuncs[4]), "_EINT") ||
 | 
			
		||||
			strings.Contains(string(altFuncs[3]), "_EINT") {
 | 
			
		||||
			pin.supportEdge = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Initializes the sysfs corresponding pin right away.
 | 
			
		||||
		pin.sysfsPin = sysfs.Pins[pin.Number()]
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										174
									
								
								vendor/periph.io/x/periph/host/allwinner/a64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								vendor/periph.io/x/periph/host/allwinner/a64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,174 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// This file contains pin mapping information that is specific to the Allwinner
 | 
			
		||||
// A64 model.
 | 
			
		||||
 | 
			
		||||
package allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A64 specific pins.
 | 
			
		||||
var (
 | 
			
		||||
	X32KFOUT *pin.BasicPin // Clock output of 32Khz crystal
 | 
			
		||||
	KEY_ADC  *pin.BasicPin // 6 bits resolution ADC for key application; can work up to 250Hz conversion rate; reference voltage is 2.0V
 | 
			
		||||
	EAROUTP  *pin.BasicPin // Earpiece amplifier negative differential output
 | 
			
		||||
	EAROUTN  *pin.BasicPin // Earpiece amplifier positive differential output
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	X32KFOUT = &pin.BasicPin{N: "X32KFOUT"}
 | 
			
		||||
	// BUG(maruel): These need to be converted to an analog.PinIO implementation
 | 
			
		||||
	// once analog support is implemented.
 | 
			
		||||
	KEY_ADC = &pin.BasicPin{N: "KEY_ADC"}
 | 
			
		||||
	EAROUTP = &pin.BasicPin{N: "EAROUTP"}
 | 
			
		||||
	EAROUTN = &pin.BasicPin{N: "EAROUTN"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mappingA64 describes the mapping of the A64 processor gpios to their
 | 
			
		||||
// alternate functions.
 | 
			
		||||
//
 | 
			
		||||
// It omits the in & out functions which are available on all gpio.
 | 
			
		||||
//
 | 
			
		||||
// The mapping comes from the datasheet page 23:
 | 
			
		||||
// http://files.pine64.org/doc/datasheet/pine64/A64_Datasheet_V1.1.pdf
 | 
			
		||||
//
 | 
			
		||||
// - The datasheet uses TWI instead of I2C but it is renamed here for
 | 
			
		||||
//   consistency.
 | 
			
		||||
// - AIF is an audio interface, i.e. to connect to S/PDIF.
 | 
			
		||||
// - RGMII means Reduced gigabit media-independent interface.
 | 
			
		||||
// - SDC means SDCard?
 | 
			
		||||
// - NAND connects to a NAND flash controller.
 | 
			
		||||
// - CSI and CCI are for video capture.
 | 
			
		||||
var mappingA64 = map[string][5]pin.Func{
 | 
			
		||||
	"PB0":  {"UART2_TX", "", "JTAG0_TMS", "", "PB_EINT0"},
 | 
			
		||||
	"PB1":  {"UART2_RX", "", "JTAG0_TCK", "SIM_PWREN", "PB_EINT1"},
 | 
			
		||||
	"PB2":  {"UART2_RTS", "", "JTAG0_TDO", "SIM_VPPEN", "PB_EINT2"},
 | 
			
		||||
	"PB3":  {"UART2_CTS", "I2S0_MCLK", "JTAG0_TDI", "SIM_VPPPP", "PB_EINT3"},
 | 
			
		||||
	"PB4":  {"AIF2_SYNC", "I2S0_WS", "", "SIM_CLK", "PB_EINT4"},
 | 
			
		||||
	"PB5":  {"AIF2_BCLK", "I2S0_SCK", "", "SIM_DATA", "PB_EINT5"},
 | 
			
		||||
	"PB6":  {"AIF2_DOUT", "I2S0_DOUT", "", "SIM_RST", "PB_EINT6"},
 | 
			
		||||
	"PB7":  {"AIF2_DIN", "I2S0_DIN", "", "SIM_DET", "PB_EINT7"},
 | 
			
		||||
	"PB8":  {"", "", "UART0_TX", "", "PB_EINT8"},
 | 
			
		||||
	"PB9":  {"", "", "UART0_RX", "", "PB_EINT9"},
 | 
			
		||||
	"PC0":  {"NAND_WE", "", "SPI0_MOSI"},
 | 
			
		||||
	"PC1":  {"NAND_ALE", "SDC2_DS", "SPI0_MISO"},
 | 
			
		||||
	"PC2":  {"NAND_CLE", "", "SPI0_CLK"},
 | 
			
		||||
	"PC3":  {"NAND_CE1", "", "SPI0_CS0"},
 | 
			
		||||
	"PC4":  {"NAND_CE0"},
 | 
			
		||||
	"PC5":  {"NAND_RE", "SDC2_CLK"},
 | 
			
		||||
	"PC6":  {"NAND_RB0", "SDC2_CMD"},
 | 
			
		||||
	"PC7":  {"NAND_RB1"},
 | 
			
		||||
	"PC8":  {"NAND_DQ0", "SDC2_D0"},
 | 
			
		||||
	"PC9":  {"NAND_DQ1", "SDC2_D1"},
 | 
			
		||||
	"PC10": {"NAND_DQ2", "SDC2_D2"},
 | 
			
		||||
	"PC11": {"NAND_DQ3", "SDC2_D3"},
 | 
			
		||||
	"PC12": {"NAND_DQ4", "SDC2_D4"},
 | 
			
		||||
	"PC13": {"NAND_DQ5", "SDC2_D5"},
 | 
			
		||||
	"PC14": {"NAND_DQ6", "SDC2_D6"},
 | 
			
		||||
	"PC15": {"NAND_DQ7", "SDC2_D7"},
 | 
			
		||||
	"PC16": {"NAND_DQS", "SDC2_RST"},
 | 
			
		||||
	"PD0":  {"LCD_D2", "UART3_TX", "SPI1_CS0", "CCIR_CLK"},
 | 
			
		||||
	"PD1":  {"LCD_D3", "UART3_RX", "SPI1_CLK", "CCIR_DE"},
 | 
			
		||||
	"PD2":  {"LCD_D4", "UART4_TX", "SPI1_MOSI", "CCIR_HSYNC"},
 | 
			
		||||
	"PD3":  {"LCD_D5", "UART4_RX", "SPI1_MISO", "CCIR_VSYNC"},
 | 
			
		||||
	"PD4":  {"LCD_D6", "UART4_RTS", "", "CCIR_D0"},
 | 
			
		||||
	"PD5":  {"LCD_D7", "UART4_CTS", "", "CCIR_D1"},
 | 
			
		||||
	"PD6":  {"LCD_D10", "", "", "CCIR_D2"},
 | 
			
		||||
	"PD7":  {"LCD_D11", "", "", "CCIR_D3"},
 | 
			
		||||
	"PD8":  {"LCD_D12", "", "RGMII_RXD3", "CCIR_D4"},
 | 
			
		||||
	"PD9":  {"LCD_D13", "", "RGMII_RXD2", "CCIR_D5"},
 | 
			
		||||
	"PD10": {"LCD_D14", "", "RGMII_RXD1"},
 | 
			
		||||
	"PD11": {"LCD_D15", "", "RGMII_RXD0"},
 | 
			
		||||
	"PD12": {"LCD_D18", "LVDS_VP0", "RGMII_RXCK"},
 | 
			
		||||
	"PD13": {"LCD_D19", "LVDS_VN0", "RGMII_RXCT"},
 | 
			
		||||
	"PD14": {"LCD_D20", "LVDS_VP1", "RGMII_RXER"},
 | 
			
		||||
	"PD15": {"LCD_D21", "LVDS_VN1", "RGMII_TXD3", "CCIR_D6"},
 | 
			
		||||
	"PD16": {"LCD_D22", "LVDS_VP2", "RGMII_TXD2", "CCIR_D7"},
 | 
			
		||||
	"PD17": {"LCD_D23", "LVDS_VN2", "RGMII_TXD1"},
 | 
			
		||||
	"PD18": {"LCD_CLK", "LVDS_VPC", "RGMII_TXD0"},
 | 
			
		||||
	"PD19": {"LCD_DE", "LVDS_VNC", "RGMII_TXCK"},
 | 
			
		||||
	"PD20": {"LCD_HSYNC", "LVDS_VP3", "RGMII_TXCT"},
 | 
			
		||||
	"PD21": {"LCD_VSYNC", "LVDS_VN3", "RGMII_CLKI"},
 | 
			
		||||
	"PD22": {"PWM0", "", "MDC"},
 | 
			
		||||
	"PD23": {"", "", "MDIO"},
 | 
			
		||||
	"PD24": {""},
 | 
			
		||||
	"PE0":  {"CSI_PCLK", "", "TS_CLK"},
 | 
			
		||||
	"PE1":  {"CSI_MCLK", "", "TS_ERR"},
 | 
			
		||||
	"PE2":  {"CSI_HSYNC", "", "TS_SYNC"},
 | 
			
		||||
	"PE3":  {"CSI_VSYNC", "", "TS_DVLD"},
 | 
			
		||||
	"PE4":  {"CSI_D0", "", "TS_D0"},
 | 
			
		||||
	"PE5":  {"CSI_D1", "", "TS_D1"},
 | 
			
		||||
	"PE6":  {"CSI_D2", "", "TS_D2"},
 | 
			
		||||
	"PE7":  {"CSI_D3", "", "TS_D3"},
 | 
			
		||||
	"PE8":  {"CSI_D4", "", "TS_D4"},
 | 
			
		||||
	"PE9":  {"CSI_D5", "", "TS_D5"},
 | 
			
		||||
	"PE10": {"CSI_D6", "", "TS_D6"},
 | 
			
		||||
	"PE11": {"CSI_D7", "", "TS_D7"},
 | 
			
		||||
	"PE12": {"CSI_SCK"},
 | 
			
		||||
	"PE13": {"CSI_SDA"},
 | 
			
		||||
	"PE14": {"PLL_LOCK_DBG", "I2C2_SCL"},
 | 
			
		||||
	"PE15": {"", "I2C2_SDA"},
 | 
			
		||||
	"PE16": {""},
 | 
			
		||||
	"PE17": {""},
 | 
			
		||||
	"PF0":  {"SDC0_D1", "JTAG1_TMS"},
 | 
			
		||||
	"PF1":  {"SDC0_D0", "JTAG1_TDI"},
 | 
			
		||||
	"PF2":  {"SDC0_CLK", "UART0_TX"},
 | 
			
		||||
	"PF3":  {"SDC0_CMD", "JTAG1_TDO"},
 | 
			
		||||
	"PF4":  {"SDC0_D3", "UART0_RX"},
 | 
			
		||||
	"PF5":  {"SDC0_D2", "JTAG1_TCK"},
 | 
			
		||||
	"PF6":  {""},
 | 
			
		||||
	"PG0":  {"SDC1_CLK", "", "", "", "PG_EINT0"},
 | 
			
		||||
	"PG1":  {"SDC1_CMD", "", "", "", "PG_EINT1"},
 | 
			
		||||
	"PG2":  {"SDC1_D0", "", "", "", "PG_EINT2"},
 | 
			
		||||
	"PG3":  {"SDC1_D1", "", "", "", "PG_EINT3"},
 | 
			
		||||
	"PG4":  {"SDC1_D2", "", "", "", "PG_EINT4"},
 | 
			
		||||
	"PG5":  {"SDC1_D3", "", "", "", "PG_EINT5"},
 | 
			
		||||
	"PG6":  {"UART1_TX", "", "", "", "PG_EINT6"},
 | 
			
		||||
	"PG7":  {"UART1_RX", "", "", "", "PG_EINT7"},
 | 
			
		||||
	"PG8":  {"UART1_RTS", "", "", "", "PG_EINT8"},
 | 
			
		||||
	"PG9":  {"UART1_CTS", "", "", "", "PG_EINT9"},
 | 
			
		||||
	"PG10": {"AIF3_SYNC", "I2S1_WS", "", "", "PG_EINT10"},
 | 
			
		||||
	"PG11": {"AIF3_BCLK", "I2S1_SCK", "", "", "PG_EINT11"},
 | 
			
		||||
	"PG12": {"AIF3_DOUT", "I2S1_DOUT", "", "", "PG_EINT12"},
 | 
			
		||||
	"PG13": {"AIF3_DIN", "I2S1_DIN", "", "", "PG_EINT13"},
 | 
			
		||||
	"PH0":  {"I2C0_SCL", "", "", "", "PH_EINT0"},
 | 
			
		||||
	"PH1":  {"I2C0_SDA", "", "", "", "PH_EINT1"},
 | 
			
		||||
	"PH2":  {"I2C1_SCL", "", "", "", "PH_EINT2"},
 | 
			
		||||
	"PH3":  {"I2C1_SDA", "", "", "", "PH_EINT3"},
 | 
			
		||||
	"PH4":  {"UART3_TX", "", "", "", "PH_EINT4"},
 | 
			
		||||
	"PH5":  {"UART3_RX", "", "", "", "PH_EINT5"},
 | 
			
		||||
	"PH6":  {"UART3_RTS", "", "", "", "PH_EINT6"},
 | 
			
		||||
	"PH7":  {"UART3_CTS", "", "", "", "PH_EINT7"},
 | 
			
		||||
	"PH8":  {"OWA_OUT", "", "", "", "PH_EINT8"},
 | 
			
		||||
	"PH9":  {"", "", "", "", "PH_EINT9"},
 | 
			
		||||
	"PH10": {"MIC_CLK", "", "", "", "PH_EINT10"},
 | 
			
		||||
	"PH11": {"MIC_DATA", "", "", "", "PH_EINT11"},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mapA64Pins uses mappingA64 to actually set the altFunc fields of all gpio
 | 
			
		||||
// and mark them as available.
 | 
			
		||||
//
 | 
			
		||||
// It is called by the generic allwinner processor code if an A64 is detected.
 | 
			
		||||
func mapA64Pins() error {
 | 
			
		||||
	for name, altFuncs := range mappingA64 {
 | 
			
		||||
		pin := cpupins[name]
 | 
			
		||||
		pin.altFunc = altFuncs
 | 
			
		||||
		pin.available = true
 | 
			
		||||
		if strings.Contains(string(altFuncs[4]), "_EINT") {
 | 
			
		||||
			pin.supportEdge = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Initializes the sysfs corresponding pin right away.
 | 
			
		||||
		pin.sysfsPin = sysfs.Pins[pin.Number()]
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/allwinner/allwinner_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/allwinner/allwinner_arm.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 allwinner
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/allwinner/allwinner_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/allwinner/allwinner_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build arm64
 | 
			
		||||
 | 
			
		||||
package allwinner
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/allwinner/allwinner_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/allwinner/allwinner_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !arm,!arm64
 | 
			
		||||
 | 
			
		||||
package allwinner
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										281
									
								
								vendor/periph.io/x/periph/host/allwinner/clock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								vendor/periph.io/x/periph/host/allwinner/clock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,281 @@
 | 
			
		||||
// 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 allwinner
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	clockSPIEnable clockSPI = 1 << 31 // SCLK_GATING
 | 
			
		||||
	// 30:26 reserved
 | 
			
		||||
	clockSPIOSC24M clockSPI = 0 << 24 // CLK_SRC_SEL
 | 
			
		||||
	clockSPIPLL6   clockSPI = 1 << 24 // A64: PLL_PERIPH0(1X)
 | 
			
		||||
	clockSPIPLL5   clockSPI = 2 << 24 // A64: PLL_PERIPH1(1X)  R8: PLL5 = DDR
 | 
			
		||||
	// 23:18 reserved
 | 
			
		||||
	clockSPIDiv1a clockSPI = 0 << 16 // CLK_DIV_RATIO_N
 | 
			
		||||
	clockSPIDiv2a clockSPI = 1 << 16 //
 | 
			
		||||
	clockSPIDiv4a clockSPI = 2 << 16 //
 | 
			
		||||
	clockSPIDiv8a clockSPI = 3 << 16 //
 | 
			
		||||
	// 15:4 reserved
 | 
			
		||||
	clockSPIDiv1b  clockSPI = 0 << 0  // CLK_DIV_RATIO_M
 | 
			
		||||
	clockSPIDiv2b  clockSPI = 1 << 0  //
 | 
			
		||||
	clockSPIDiv3b  clockSPI = 2 << 0  //
 | 
			
		||||
	clockSPIDiv4b  clockSPI = 3 << 0  //
 | 
			
		||||
	clockSPIDiv5b  clockSPI = 4 << 0  //
 | 
			
		||||
	clockSPIDiv6b  clockSPI = 5 << 0  //
 | 
			
		||||
	clockSPIDiv7b  clockSPI = 6 << 0  //
 | 
			
		||||
	clockSPIDiv8b  clockSPI = 7 << 0  //
 | 
			
		||||
	clockSPIDiv9b  clockSPI = 8 << 0  //
 | 
			
		||||
	clockSPIDiv10b clockSPI = 9 << 0  //
 | 
			
		||||
	clockSPIDiv11b clockSPI = 10 << 0 //
 | 
			
		||||
	clockSPIDiv12b clockSPI = 11 << 0 //
 | 
			
		||||
	clockSPIDiv13b clockSPI = 12 << 0 //
 | 
			
		||||
	clockSPIDiv14b clockSPI = 13 << 0 //
 | 
			
		||||
	clockSPIDiv15b clockSPI = 14 << 0 //
 | 
			
		||||
	clockSPIDiv16b clockSPI = 15 << 0 //
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Also valid for IR.
 | 
			
		||||
//
 | 
			
		||||
// SPI0_SCLK_CFG_REG / SPI1_SCLK_CFG_REG / SPI2_SCLK_CFG_REG / IR_SCLK_CFG_REG
 | 
			
		||||
//
 | 
			
		||||
// A64: Page 110-111. (Also Page 554?)
 | 
			
		||||
// R8: Page 71.
 | 
			
		||||
type clockSPI uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	clockPLL6Enable     clockPLL6R8Ctl = 1 << 31 // PLL6_Enable
 | 
			
		||||
	clockPLL6Force24Mhz clockPLL6R8Ctl = 1 << 30 // PLL6_BYPASS_EN; force 24Mhz
 | 
			
		||||
	// 29:13 reserved
 | 
			
		||||
	clockPLL6FactorMulN0  clockPLL6R8Ctl = 0 << 8  // PLL6_FACTOR_N
 | 
			
		||||
	clockPLL6FactorMulN1  clockPLL6R8Ctl = 1 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN2  clockPLL6R8Ctl = 2 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN3  clockPLL6R8Ctl = 3 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN4  clockPLL6R8Ctl = 4 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN5  clockPLL6R8Ctl = 5 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN6  clockPLL6R8Ctl = 6 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN7  clockPLL6R8Ctl = 7 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN8  clockPLL6R8Ctl = 8 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN9  clockPLL6R8Ctl = 9 << 8  //
 | 
			
		||||
	clockPLL6FactorMulN10 clockPLL6R8Ctl = 10 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN11 clockPLL6R8Ctl = 11 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN12 clockPLL6R8Ctl = 12 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN13 clockPLL6R8Ctl = 13 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN14 clockPLL6R8Ctl = 14 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN15 clockPLL6R8Ctl = 15 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN16 clockPLL6R8Ctl = 16 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN17 clockPLL6R8Ctl = 17 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN18 clockPLL6R8Ctl = 18 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN19 clockPLL6R8Ctl = 19 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN20 clockPLL6R8Ctl = 20 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN21 clockPLL6R8Ctl = 21 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN22 clockPLL6R8Ctl = 22 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN23 clockPLL6R8Ctl = 23 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN24 clockPLL6R8Ctl = 24 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN25 clockPLL6R8Ctl = 25 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN26 clockPLL6R8Ctl = 26 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN27 clockPLL6R8Ctl = 27 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN28 clockPLL6R8Ctl = 28 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN29 clockPLL6R8Ctl = 29 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN30 clockPLL6R8Ctl = 30 << 8 //
 | 
			
		||||
	clockPLL6FactorMulN31 clockPLL6R8Ctl = 31 << 8 //
 | 
			
		||||
	clockPLL6Damping      clockPLL6R8Ctl = 2 << 6  //
 | 
			
		||||
	clockPLL6FactorMulK1  clockPLL6R8Ctl = 0 << 4  // PLL6_FACTOR_K
 | 
			
		||||
	clockPLL6FactorMulK2  clockPLL6R8Ctl = 1 << 4  //
 | 
			
		||||
	clockPLL6FactorMulK3  clockPLL6R8Ctl = 2 << 4  //
 | 
			
		||||
	clockPLL6FactorMulK4  clockPLL6R8Ctl = 3 << 4  //
 | 
			
		||||
	// 3:2 reserved
 | 
			
		||||
	clockPLL6FactorDivM1 clockPLL6R8Ctl = 0 << 4 // PLL6_FACTOR_M
 | 
			
		||||
	clockPLL6FactorDivM2 clockPLL6R8Ctl = 1 << 4 //
 | 
			
		||||
	clockPLL6FactorDivM3 clockPLL6R8Ctl = 2 << 4 //
 | 
			
		||||
	clockPLL6FactorDivM4 clockPLL6R8Ctl = 3 << 4 //
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// PLL6_CFG_REG
 | 
			
		||||
// R8: Page 63; default 0x21009931
 | 
			
		||||
//
 | 
			
		||||
// Output = (24MHz*N*K)/M/2
 | 
			
		||||
// Note: the output 24MHz*N*K clock must be in the range of 240MHz~3GHz if the
 | 
			
		||||
// bypass is disabled.
 | 
			
		||||
type clockPLL6R8Ctl uint32
 | 
			
		||||
 | 
			
		||||
// clockMap is the mapping of important registers across CPUs.
 | 
			
		||||
type clockMap struct {
 | 
			
		||||
	reserved0 [0xA0 / 4]uint32 //
 | 
			
		||||
	spi0Clk   clockSPI         // 0x0A0 SPI0_SCLK_CFG_REG SPI0 Clock
 | 
			
		||||
	spi1Clk   clockSPI         // 0x0A4 SPI1_SCLK_CFG_REG SPI1 Clock
 | 
			
		||||
	spi2Clk   clockSPI         // 0x0A8 SPI2_SCLK_CFG_REG SPI2 Clock (Not on A64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// R8: Page 57-59.
 | 
			
		||||
type clockMapR8 struct {
 | 
			
		||||
	r0      uint32         // 0x000 PLL1_CFG_REG PLL1 Control
 | 
			
		||||
	r1      uint32         // 0x004 PLL1_TUN_REG PLL1 Tuning
 | 
			
		||||
	r2      uint32         // 0x008 PLL2_CFG_REG PLL2 Control
 | 
			
		||||
	r3      uint32         // 0x00C PLL2_TUN_REG PLL2 Tuning
 | 
			
		||||
	r4      uint32         // 0x010 PLL3_CFG_REG PLL3 Control
 | 
			
		||||
	r5      uint32         // 0x014
 | 
			
		||||
	r6      uint32         // 0x018 PLL4_CFG_REG PLL4 Control
 | 
			
		||||
	r7      uint32         // 0x01C
 | 
			
		||||
	r8      uint32         // 0x020 PLL5_CFG_REG PLL5 Control
 | 
			
		||||
	r9      uint32         // 0x024 PLL5_TUN_REG PLL5 Tuning
 | 
			
		||||
	r10     clockPLL6R8Ctl // 0x028 PLL6_CFG_REG PLL6 Control
 | 
			
		||||
	r11     uint32         // 0x02C PLL6 Tuning
 | 
			
		||||
	r12     uint32         // 0x030 PLL7_CFG_REG
 | 
			
		||||
	r13     uint32         // 0x034
 | 
			
		||||
	r14     uint32         // 0x038 PLL1_TUN2_REG PLL1 Tuning2
 | 
			
		||||
	r15     uint32         // 0x03C PLL5_TUN2_REG PLL5 Tuning2
 | 
			
		||||
	r16     uint32         // 0x04C
 | 
			
		||||
	r17     uint32         // 0x050 OSC24M_CFG_REG OSC24M control
 | 
			
		||||
	r18     uint32         // 0x054 CPU_AHB_APB0_CFG_REG CPU, AHB And APB0 Divide Ratio
 | 
			
		||||
	r19     uint32         // 0x058 APB1_CLK_DIV_REG APB1 Clock Divider
 | 
			
		||||
	r20     uint32         // 0x05C AXI_GATING_REG AXI Module Clock Gating
 | 
			
		||||
	r21     uint32         // 0x060 AHB_GATING_REG0 AHB Module Clock Gating 0
 | 
			
		||||
	r22     uint32         // 0x064 AHB_GATING_REG1 AHB Module Clock Gating 1
 | 
			
		||||
	r23     uint32         // 0x068 APB0_GATING_REG APB0 Module Clock Gating
 | 
			
		||||
	r24     uint32         // 0x06C APB1_GATING_REG APB1 Module Clock Gating
 | 
			
		||||
	r25     uint32         // 0x080 NAND_SCLK_CFG_REG Nand Flash Clock
 | 
			
		||||
	r26     uint32         // 0x084
 | 
			
		||||
	r27     uint32         // 0x088 SD0_SCLK_CFG_REG SD0 Clock
 | 
			
		||||
	r28     uint32         // 0x08C SD1_SCLK_CFG_REG SD1 Clock
 | 
			
		||||
	r29     uint32         // 0x090 SD2_SCLK_CFG_REG SD2 Clock
 | 
			
		||||
	r30     uint32         // 0x094
 | 
			
		||||
	r31     uint32         // 0x098
 | 
			
		||||
	r32     uint32         // 0x09C CE_SCLK_CFG_REG Crypto Engine Clock
 | 
			
		||||
	spi0Clk clockSPI       // 0x0A0 SPI0_SCLK_CFG_REG SPI0 Clock
 | 
			
		||||
	spi1Clk clockSPI       // 0x0A4 SPI1_SCLK_CFG_REG SPI1 Clock
 | 
			
		||||
	spi2Clk clockSPI       // 0x0A8 SPI2_SCLK_CFG_REG SPI2 Clock
 | 
			
		||||
	r33     uint32         // 0x0AC
 | 
			
		||||
	irClk   clockSPI       // 0x0B0 IR_SCLK_CFG_REG IR Clock
 | 
			
		||||
	r34     uint32         // 0x0B4
 | 
			
		||||
	r35     uint32         // 0x0B8
 | 
			
		||||
	r36     uint32         // 0x0BC
 | 
			
		||||
	r37     uint32         // 0x0C0
 | 
			
		||||
	r38     uint32         // 0x0C4
 | 
			
		||||
	r39     uint32         // 0x0C8
 | 
			
		||||
	r40     uint32         // 0x0CC
 | 
			
		||||
	r41     uint32         // 0x0D0
 | 
			
		||||
	r42     uint32         // 0x0D4
 | 
			
		||||
	r43     uint32         // 0x100 DRAM_SCLK_CFG_REG DRAM Clock
 | 
			
		||||
	r44     uint32         // 0x104 BE_CFG_REG Display Engine Backend Clock
 | 
			
		||||
	r45     uint32         // 0x108
 | 
			
		||||
	r46     uint32         // 0x10C FE_CFG_REG Display Engine Front End Clock
 | 
			
		||||
	r47     uint32         // 0x110
 | 
			
		||||
	r48     uint32         // 0x114
 | 
			
		||||
	r49     uint32         // 0x118
 | 
			
		||||
	r50     uint32         // 0x11C
 | 
			
		||||
	r51     uint32         // 0x120
 | 
			
		||||
	r52     uint32         // 0x124
 | 
			
		||||
	r53     uint32         // 0x128
 | 
			
		||||
	r54     uint32         // 0x12C LCD_CH1_CFG_REG LCD Channel1 Clock
 | 
			
		||||
	r55     uint32         // 0x130
 | 
			
		||||
	r56     uint32         // 0x134 CSI_CFG_REG CSI Clock
 | 
			
		||||
	r57     uint32         // 0x138
 | 
			
		||||
	r58     uint32         // 0x13C VE_CFG_REG Video Engine Clock
 | 
			
		||||
	r59     uint32         // 0x140 AUDIO_CODEC_SCLK_CFG_REG Audio Codec Gating Special Clock
 | 
			
		||||
	r60     uint32         // 0x144 AVS_SCLK_CFG_REG AVS Gating Special Clock
 | 
			
		||||
	r61     uint32         // 0x148
 | 
			
		||||
	r62     uint32         // 0x14C
 | 
			
		||||
	r63     uint32         // 0x150
 | 
			
		||||
	r64     uint32         // 0x154 MALI_CLOCK_CFG_REG Mali400 Gating Special Clock
 | 
			
		||||
	r65     uint32         // 0x158
 | 
			
		||||
	r66     uint32         // 0x15C MBUS_SCLK_CFG_REG MBUS Gating Clock
 | 
			
		||||
	r67     uint32         // 0x160 IEP_SCLK_CFG_REG IEP Gating Clock
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A64: Page 81-84.
 | 
			
		||||
type clockMapA64 struct {
 | 
			
		||||
	r0      uint32   // 0x000 PLL_CPUX_CTRL_REG PLL_CPUX Control Register
 | 
			
		||||
	r1      uint32   // 0x008 PLL_AUDIO_CTRL_REG PLL_AUDIO Control Register
 | 
			
		||||
	r2      uint32   // 0x010 PLL_VIDEO0_CTRL_REG PLL_VIDEO0 Control Register
 | 
			
		||||
	r3      uint32   // 0x018 PLL_VE_CTRL_REG PLL_VE Control Register
 | 
			
		||||
	r4      uint32   // 0x020 PLL_DDR0_CTRL_REG PLL_DDR0 Control Register
 | 
			
		||||
	r5      uint32   // 0x028 PLL_PERIPH0_CTRL_REG PLL_PERIPH0 Control Register
 | 
			
		||||
	r6      uint32   // 0x02C PLL_PERIPH1_CTRL_REG PLL_PERIPH1 Control Register
 | 
			
		||||
	r7      uint32   // 0x030 PLL_VIDEO1_CTRL_REG PLL_VIDEO1 Control Register
 | 
			
		||||
	r8      uint32   // 0x038 PLL_GPU_CTRL_REG PLL_GPU Control Register
 | 
			
		||||
	r9      uint32   // 0x040 PLL_MIPI_CTRL_REG PLL_MIPI Control Register
 | 
			
		||||
	r10     uint32   // 0x044 PLL_HSIC_CTRL_REG PLL_HSIC Control Register
 | 
			
		||||
	r11     uint32   // 0x048 PLL_DE_CTRL_REG PLL_DE Control Register
 | 
			
		||||
	r12     uint32   // 0x04C PLL_DDR1_CTRL_REG PLL_DDR1 Control Register
 | 
			
		||||
	r13     uint32   // 0x050 CPU_AXI_CFG_REG CPUX/AXI Configuration Register
 | 
			
		||||
	r14     uint32   // 0x054 AHB1_APB1_CFG_REG AHB1/APB1 Configuration Register
 | 
			
		||||
	r15     uint32   // 0x058 APB2_CFG_REG APB2 Configuration Register
 | 
			
		||||
	r16     uint32   // 0x05C AHB2_CFG_REG AHB2 Configuration Register
 | 
			
		||||
	r17     uint32   // 0x060 BUS_CLK_GATING_REG0 Bus Clock Gating Register 0
 | 
			
		||||
	r18     uint32   // 0x064 BUS_CLK_GATING_REG1 Bus Clock Gating Register 1
 | 
			
		||||
	r19     uint32   // 0x068 BUS_CLK_GATING_REG2 Bus Clock Gating Register 2
 | 
			
		||||
	r20     uint32   // 0x06C BUS_CLK_GATING_REG3 Bus Clock Gating Register 3
 | 
			
		||||
	r21     uint32   // 0x070 BUS_CLK_GATING_REG4 Bus Clock Gating Register 4
 | 
			
		||||
	r22     uint32   // 0x074 THS_CLK_REG THS Clock Register
 | 
			
		||||
	r23     uint32   // 0x080 NAND_CLK_REG NAND Clock Register
 | 
			
		||||
	r24     uint32   // 0x088 SDMMC0_CLK_REG SDMMC0 Clock Register
 | 
			
		||||
	r25     uint32   // 0x08C SDMMC1_CLK_REG SDMMC1 Clock Register
 | 
			
		||||
	r26     uint32   // 0x090 SDMMC2_CLK_REG SDMMC2 Clock Register
 | 
			
		||||
	r27     uint32   // 0x098 TS_CLK_REG TS Clock Register
 | 
			
		||||
	r28     uint32   // 0x09C CE_CLK_REG CE Clock Register
 | 
			
		||||
	spi0Clk clockSPI // 0x0A0 SPI0_CLK_REG SPI0 Clock Register
 | 
			
		||||
	spi1Clk clockSPI // 0x0A4 SPI1_CLK_REG SPI1 Clock Register
 | 
			
		||||
	r29     uint32   // 0x0B0 I2S/PCM-0_CLK_REG I2S/PCM-0 Clock Register
 | 
			
		||||
	r30     uint32   // 0x0B4 I2S/PCM-1_CLK_REG I2S/PCM-1 Clock Register
 | 
			
		||||
	r31     uint32   // 0x0B8 I2S/PCM-2_CLK_REG I2S/PCM-2 Clock Register
 | 
			
		||||
	r32     uint32   // 0x0C0 SPDIF_CLK_REG SPDIF Clock Register
 | 
			
		||||
	r33     uint32   // 0x0CC USBPHY_CFG_REG USBPHY Configuration Register
 | 
			
		||||
	r34     uint32   // 0x0F4 DRAM_CFG_REG DRAM Configuration Register
 | 
			
		||||
	r35     uint32   // 0x0F8 PLL_DDR_CFG_REG PLL_DDR Configuration Register
 | 
			
		||||
	r36     uint32   // 0x0FC MBUS_RST_REG MBUS Reset Register
 | 
			
		||||
	r37     uint32   // 0x100 DRAM_CLK_GATING_REG DRAM Clock Gating Register
 | 
			
		||||
	r38     uint32   // 0x104 DE_CLK_REG DE Clock Register
 | 
			
		||||
	r39     uint32   // 0x118 TCON0_CLK_REG TCON0 Clock Register
 | 
			
		||||
	r40     uint32   // 0x11C TCON1_CLK_REG TCON1 Clock Register
 | 
			
		||||
	r41     uint32   // 0x124 DEINTERLACE_CLK_REG DEINTERLACE Clock Register
 | 
			
		||||
	r42     uint32   // 0x130 CSI_MISC_CLK_REG CSI_MISC Clock Register
 | 
			
		||||
	r43     uint32   // 0x134 CSI_CLK_REG CSI Clock Register
 | 
			
		||||
	r44     uint32   // 0x13C VE_CLK_REG VE Clock Register
 | 
			
		||||
	r45     uint32   // 0x140 AC_DIG_CLK_REG AC Digital Clock Register
 | 
			
		||||
	r46     uint32   // 0x144 AVS_CLK_REG AVS Clock Register
 | 
			
		||||
	r47     uint32   // 0x150 HDMI_CLK_REG HDMI Clock Register
 | 
			
		||||
	r48     uint32   // 0x154 HDMI_SLOW_CLK_REG HDMI Slow Clock Register
 | 
			
		||||
	r49     uint32   // 0x15C MBUS_CLK_REG MBUS Clock Register
 | 
			
		||||
	r50     uint32   // 0x168 MIPI_DSI_CLK_REG MIPI_DSI Clock Register
 | 
			
		||||
	r51     uint32   // 0x1A0 GPU_CLK_REG GPU Clock Register
 | 
			
		||||
	r52     uint32   // 0x200 PLL_STABLE_TIME_REG0 PLL Stable Time Register0
 | 
			
		||||
	r53     uint32   // 0x204 PLL_STABLE_TIME_REG1 PLL Stable Time Register1
 | 
			
		||||
	r54     uint32   // 0x21C PLL_PERIPH1_BIAS_REG PLL_PERIPH1 Bias Register
 | 
			
		||||
	r55     uint32   // 0x220 PLL_CPUX_BIAS_REG PLL_CPUX Bias Register
 | 
			
		||||
	r56     uint32   // 0x224 PLL_AUDIO_BIAS_REG PLL_AUDIO Bias Register
 | 
			
		||||
	r57     uint32   // 0x228 PLL_VIDEO0_BIAS_REG PLL_VIDEO0 Bias Register
 | 
			
		||||
	r58     uint32   // 0x22C PLL_VE_BIAS_REG PLL_VE Bias Register
 | 
			
		||||
	r59     uint32   // 0x230 PLL_DDR0_BIAS_REG PLL_DDR0 Bias Register
 | 
			
		||||
	r60     uint32   // 0x234 PLL_PERIPH0_BIAS_REG PLL_PERIPH0 Bias Register
 | 
			
		||||
	r61     uint32   // 0x238 PLL_VIDEO1_BIAS_REG PLL_VIDEO1 Bias Register
 | 
			
		||||
	r62     uint32   // 0x23C PLL_GPU_BIAS_REG PLL_GPU Bias Register
 | 
			
		||||
	r63     uint32   // 0x240 PLL_MIPI_BIAS_REG PLL_MIPI Bias Register
 | 
			
		||||
	r64     uint32   // 0x244 PLL_HSIC_BIAS_REG PLL_HSIC Bias Register
 | 
			
		||||
	r65     uint32   // 0x248 PLL_DE_BIAS_REG PLL_DE Bias Register
 | 
			
		||||
	r66     uint32   // 0x24C PLL_DDR1_BIAS_REG PLL_DDR1 Bias Register
 | 
			
		||||
	r67     uint32   // 0x250 PLL_CPUX_TUN_REG PLL_CPUX Tuning Register
 | 
			
		||||
	r68     uint32   // 0x260 PLL_DDR0_TUN_REG PLL_DDR0 Tuning Register
 | 
			
		||||
	r69     uint32   // 0x270 PLL_MIPI_TUN_REG PLL_MIPI Tuning Register
 | 
			
		||||
	r70     uint32   // 0x27C PLL_PERIPH1_PAT_CTRL_REG PLL_PERIPH1 Pattern Control Register
 | 
			
		||||
	r71     uint32   // 0x280 PLL_CPUX_PAT_CTRL_REG PLL_CPUX Pattern Control Register
 | 
			
		||||
	r72     uint32   // 0x284 PLL_AUDIO_PAT_CTRL_REG PLL_AUDIO Pattern Control Register
 | 
			
		||||
	r73     uint32   // 0x288 PLL_VIDEO0_PAT_CTRL_REG PLL_VIDEO0 Pattern Control Register
 | 
			
		||||
	r74     uint32   // 0x28C PLL_VE_PAT_CTRL_REG PLL_VE Pattern Control Register
 | 
			
		||||
	r75     uint32   // 0x290 PLL_DDR0_PAT_CTRL_REG PLL_DDR0 Pattern Control Register
 | 
			
		||||
	r76     uint32   // 0x298 PLL_VIDEO1_PAT_CTRL_REG PLL_VIDEO1 Pattern Control Register
 | 
			
		||||
	r77     uint32   // 0x29C PLL_GPU_PAT_CTRL_REG PLL_GPU Pattern Control Register
 | 
			
		||||
	r78     uint32   // 0x2A0 PLL_MIPI_PAT_CTRL_REG PLL_MIPI Pattern Control Register
 | 
			
		||||
	r79     uint32   // 0x2A4 PLL_HSIC_PAT_CTRL_REG PLL_HSIC Pattern Control Register
 | 
			
		||||
	r80     uint32   // 0x2A8 PLL_DE_PAT_CTRL_REG PLL_DE Pattern Control Register
 | 
			
		||||
	r81     uint32   // 0x2AC PLL_DDR1_PAT_CTRL_REG0 PLL_DDR1 Pattern Control Register0
 | 
			
		||||
	r82     uint32   // 0x2B0 PLL_DDR1_PAT_CTRL_REG1 PLL_DDR1 Pattern Control Register1
 | 
			
		||||
	r83     uint32   // 0x2C0 BUS_SOFT_RST_REG0 Bus Software Reset Register 0
 | 
			
		||||
	r84     uint32   // 0x2C4 BUS_SOFT_RST_REG1 Bus Software Reset Register 1
 | 
			
		||||
	r85     uint32   // 0x2C8 BUS_SOFT_RST_REG2 Bus Software Reset Register 2
 | 
			
		||||
	r86     uint32   // 0x2D0 BUS_SOFT_RST_REG3 Bus Software Reset Register 3
 | 
			
		||||
	r87     uint32   // 0x2D8 BUS_SOFT_RST_REG4 Bus Software Reset Register 4
 | 
			
		||||
	r88     uint32   // 0x2F0 CCM_SEC_SWITCH_REG CCM Security Switch Register
 | 
			
		||||
	r89     uint32   // 0x300 PS_CTRL_REG PS Control Register
 | 
			
		||||
	r90     uint32   // 0x304 PS_CNT_REG PS Counter Register
 | 
			
		||||
	r91     uint32   // 0x320 PLL_LOCK_CTRL_REG PLL Lock Control Register
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										98
									
								
								vendor/periph.io/x/periph/host/allwinner/detect.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								vendor/periph.io/x/periph/host/allwinner/detect.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
			
		||||
// 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 allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/host/distro"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Present detects whether the host CPU is an Allwinner CPU.
 | 
			
		||||
//
 | 
			
		||||
// https://en.wikipedia.org/wiki/Allwinner_Technology
 | 
			
		||||
func Present() bool {
 | 
			
		||||
	detection.do()
 | 
			
		||||
	return detection.isAllwinner
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsR8 detects whether the host CPU is an Allwinner R8 CPU.
 | 
			
		||||
//
 | 
			
		||||
// It looks for the string "sun5i-r8" in /proc/device-tree/compatible.
 | 
			
		||||
func IsR8() bool {
 | 
			
		||||
	detection.do()
 | 
			
		||||
	return detection.isR8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsA20 detects whether the host CPU is an Allwinner A20 CPU.
 | 
			
		||||
//
 | 
			
		||||
// It first looks for the string "sun71-a20" in /proc/device-tree/compatible,
 | 
			
		||||
// and if that fails it checks for "Hardware : sun7i" in /proc/cpuinfo.
 | 
			
		||||
func IsA20() bool {
 | 
			
		||||
	detection.do()
 | 
			
		||||
	return detection.isA20
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsA64 detects whether the host CPU is an Allwinner A64 CPU.
 | 
			
		||||
//
 | 
			
		||||
// It looks for the string "sun50iw1p1" in /proc/device-tree/compatible.
 | 
			
		||||
func IsA64() bool {
 | 
			
		||||
	detection.do()
 | 
			
		||||
	return detection.isA64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
type detectionS struct {
 | 
			
		||||
	mu          sync.Mutex
 | 
			
		||||
	done        bool
 | 
			
		||||
	isAllwinner bool
 | 
			
		||||
	isR8        bool
 | 
			
		||||
	isA20       bool
 | 
			
		||||
	isA64       bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var detection detectionS
 | 
			
		||||
 | 
			
		||||
// do contains the CPU detection logic that determines whether we have an
 | 
			
		||||
// Allwinner CPU and if so, which exact model.
 | 
			
		||||
//
 | 
			
		||||
// Sadly there is no science behind this, it's more of a trial and error using
 | 
			
		||||
// as many boards and OS flavors as possible.
 | 
			
		||||
func (d *detectionS) do() {
 | 
			
		||||
	d.mu.Lock()
 | 
			
		||||
	defer d.mu.Unlock()
 | 
			
		||||
	if !d.done {
 | 
			
		||||
		d.done = true
 | 
			
		||||
		if isArm {
 | 
			
		||||
			for _, c := range distro.DTCompatible() {
 | 
			
		||||
				if strings.Contains(c, "sun50iw1p1") {
 | 
			
		||||
					d.isA64 = true
 | 
			
		||||
				}
 | 
			
		||||
				if strings.Contains(c, "sun5i-r8") {
 | 
			
		||||
					d.isR8 = true
 | 
			
		||||
				}
 | 
			
		||||
				if strings.Contains(c, "sun7i-a20") {
 | 
			
		||||
					d.isA20 = true
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			d.isAllwinner = d.isA64 || d.isR8 || d.isA20
 | 
			
		||||
 | 
			
		||||
			if !d.isAllwinner {
 | 
			
		||||
				// The kernel in the image that comes pre-installed on the pcDuino3 Nano
 | 
			
		||||
				// is an old 3.x kernel that doesn't expose the device-tree in procfs,
 | 
			
		||||
				// so do an extra check in cpuinfo as well if we haven't detected
 | 
			
		||||
				// anything yet.
 | 
			
		||||
				// Distros based on 4.x kernels do expose it.
 | 
			
		||||
				if hw, ok := distro.CPUInfo()["Hardware"]; ok {
 | 
			
		||||
					if hw == "sun7i" {
 | 
			
		||||
						d.isA20 = true
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										474
									
								
								vendor/periph.io/x/periph/host/allwinner/dma.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								vendor/periph.io/x/periph/host/allwinner/dma.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,474 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// Unlike the bcm283x, the allwinner CPUs do not have a "clear bit" and "set
 | 
			
		||||
// bit" registers, they only have the data register. Also, allwinner CPUs do
 | 
			
		||||
// not support linked lists of DMA buffers. On the other hand, the Allwinner DMA
 | 
			
		||||
// controller supports 8 bits transfers instead of 32-128 bits that the bcm283x
 | 
			
		||||
// DMA controller supports.
 | 
			
		||||
//
 | 
			
		||||
// This means that only 8 bits can be used per sample, and only one stream is
 | 
			
		||||
// necessary. This results in 1/8th th memory usage than on the bcm283x. The
 | 
			
		||||
// drawback is that a block of 8 contiguous GPIO pins must be dedicated to the
 | 
			
		||||
// stream.
 | 
			
		||||
 | 
			
		||||
package allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph"
 | 
			
		||||
	"periph.io/x/periph/host/pmem"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// dmaMap represents the DMA memory mapped CPU registers.
 | 
			
		||||
//
 | 
			
		||||
// This map is specific to the currently supported CPUs and will have to be
 | 
			
		||||
// adapted as more CPUs are supported. In particular the number of physical
 | 
			
		||||
// channels varies across different CPUs.
 | 
			
		||||
//
 | 
			
		||||
// Note that we modify the DMA controllers without telling the kernel driver.
 | 
			
		||||
// The driver keeps its own table of which DMA channel is available so this
 | 
			
		||||
// code could effectively crash the whole system. It practice this works.
 | 
			
		||||
// #everythingisfine
 | 
			
		||||
type dmaMap struct {
 | 
			
		||||
	irqEn       dmaR8Irq                // DMA_IRQ_EN_REG
 | 
			
		||||
	irqPendStas dmaR8PendingIrq         // DMA_IRQ_PEND_STAS_REG
 | 
			
		||||
	reserved0   [(0x100 - 8) / 4]uint32 //
 | 
			
		||||
	normal      [8]dmaR8NormalGroup     // 0x100 The "8" "normal" DMA channels (only one active at a time so there's effectively one)
 | 
			
		||||
	reserved1   [0x100 / 4]uint32       //
 | 
			
		||||
	dedicated   [8]dmaDedicatedGroup    // 0x300 The 8 "dedicated" (as in actually existing) DMA channels
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *dmaMap) getDedicated() int {
 | 
			
		||||
	for i := len(d.dedicated) - 1; i >= 0; i-- {
 | 
			
		||||
		if d.dedicated[i].isAvailable() {
 | 
			
		||||
			return i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// dmaNormalGroup is the control registers for the first block of 8 DMA
 | 
			
		||||
// controllers.
 | 
			
		||||
//
 | 
			
		||||
// They can be intentionally slowed down, unlike the dedicated DMA ones.
 | 
			
		||||
//
 | 
			
		||||
// The big caveat is that only one controller can be active at a time and the
 | 
			
		||||
// execution sequence is in accordance with the priority level. This means that
 | 
			
		||||
// two normal DMA cannot be used to do simultaneous read and write. This
 | 
			
		||||
// feature is critical for bus bitbanging.
 | 
			
		||||
type dmaR8NormalGroup struct {
 | 
			
		||||
	cfg         ndmaR8Cfg // NDMA_CTRL_REG
 | 
			
		||||
	srcAddr     uint32    // NDMA_SRC_ADDR_REG
 | 
			
		||||
	dstAddr     uint32    // NDMA_DEST_ADDR_REG
 | 
			
		||||
	byteCounter uint32    // NDMA_BC_REG
 | 
			
		||||
	reserved    [4]uint32 //
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *dmaR8NormalGroup) isAvailable() bool {
 | 
			
		||||
	return d.cfg == 0 && d.srcAddr == 0 && d.dstAddr == 0 && d.byteCounter == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *dmaR8NormalGroup) release() error {
 | 
			
		||||
	d.srcAddr = 0
 | 
			
		||||
	d.dstAddr = 0
 | 
			
		||||
	d.byteCounter = 0
 | 
			
		||||
	d.cfg = ndmaLoad
 | 
			
		||||
	//drvDMA.dmaMemory.irqEn &^= ...
 | 
			
		||||
	//drvDMA.dmaMemory.irqPendStas &^= ...
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// dmaNormalGroup is the control registers for the second block of 8 DMA
 | 
			
		||||
// controllers.
 | 
			
		||||
//
 | 
			
		||||
// They support different DReq and can do non-linear streaming.
 | 
			
		||||
type dmaDedicatedGroup struct {
 | 
			
		||||
	cfg         ddmaR8Cfg   // DDMA_CTRL_REG
 | 
			
		||||
	srcAddr     uint32      // DDMA_SRC_ADDR_REG
 | 
			
		||||
	dstAddr     uint32      // DDMA_DEST_ADDR_REG
 | 
			
		||||
	byteCounter uint32      // DDMA_BC_REG (24 bits)
 | 
			
		||||
	reserved0   [2]uint32   //
 | 
			
		||||
	param       ddmaR8Param // DDMA_PARA_REG (dedicated DMA only)
 | 
			
		||||
	reserved1   uint32      //
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *dmaDedicatedGroup) isAvailable() bool {
 | 
			
		||||
	return d.cfg == 0 && d.srcAddr == 0 && d.dstAddr == 0 && d.byteCounter == 0 && d.param == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *dmaDedicatedGroup) set(srcAddr, dstAddr, l uint32, srcIO, dstIO bool, src ddmaR8Cfg) {
 | 
			
		||||
	d.srcAddr = srcAddr
 | 
			
		||||
	d.dstAddr = dstAddr
 | 
			
		||||
	d.byteCounter = l
 | 
			
		||||
	// TODO(maruel): Slow down the clock by another 2*250x
 | 
			
		||||
	//d.param = ddmaR8Param(250 | 250<<16)
 | 
			
		||||
	d.param = ddmaR8Param(1<<24 | 1<<8 | 1)
 | 
			
		||||
	// All these have value 0. This statement only exist for documentation.
 | 
			
		||||
	cfg := ddmaDstWidth8 | ddmaDstBurst1 | ddmaDstLinear | ddmaSrcWidth8 | ddmaSrcLinear | ddmaSrcBurst1
 | 
			
		||||
	cfg |= src | ddmaBCRemain
 | 
			
		||||
	if srcIO {
 | 
			
		||||
		cfg |= ddmaSrcIOMode
 | 
			
		||||
	} else if dstIO {
 | 
			
		||||
		cfg |= ddmaDstIOMode
 | 
			
		||||
	}
 | 
			
		||||
	d.cfg = ddmaLoad | cfg
 | 
			
		||||
	for i := 0; d.cfg&ddmaLoad != 0 && i < 100000; i++ {
 | 
			
		||||
	}
 | 
			
		||||
	if d.cfg&ddmaLoad != 0 {
 | 
			
		||||
		log.Printf("failed to load DDMA: %# v\n", d)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *dmaDedicatedGroup) release() error {
 | 
			
		||||
	d.param = 0
 | 
			
		||||
	d.srcAddr = 0
 | 
			
		||||
	d.dstAddr = 0
 | 
			
		||||
	d.byteCounter = 0
 | 
			
		||||
	d.cfg = ddmaLoad
 | 
			
		||||
	//drvDMA.dmaMemory.irqEn &^= ...
 | 
			
		||||
	//drvDMA.dmaMemory.irqPendStas &^= ...
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31 reserved
 | 
			
		||||
	dma7QueueEndIrq   dmaA64Irq = 1 << 30 // DMA7_END_IRQ_EN; DMA 7 Queue End Transfer Interrupt Enable.
 | 
			
		||||
	dma7PackageEndIrq dmaA64Irq = 1 << 29 // DMA7_PKG_IRQ_EN; DMA 7 Package End Transfer Interrupt Enable.
 | 
			
		||||
	dma7HalfIrq       dmaA64Irq = 1 << 28 // DMA7_HLAF_IRQ_EN; DMA 7 Half Package Transfer Interrupt Enable.
 | 
			
		||||
	// ...
 | 
			
		||||
	// 3 reserved
 | 
			
		||||
	dma0QueueEndIrq   dmaA64Irq = 1 << 2 // DMA0_END_IRQ_EN; DMA 0 Queue End Transfer Interrupt Enable.
 | 
			
		||||
	dma0PackageEndIrq dmaA64Irq = 1 << 1 // DMA0_PKG_IRQ_EN; DMA 0 Package End Transfer Interrupt Enable.
 | 
			
		||||
	dma0HalfIrq       dmaA64Irq = 1 << 0 // DMA0_HLAF_IRQ_EN; DMA 0 Half Package Transfer Interrupt Enable.
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DMA_IRQ_EN_REG
 | 
			
		||||
// A64: Page 199-201.
 | 
			
		||||
type dmaA64Irq uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ddma7EndIrq   dmaR8Irq = 1 << 31 // DDMA7_END_IRQ_EN
 | 
			
		||||
	ddma7HalfIreq dmaR8Irq = 1 << 30 // DDMA7_HF_IRQ_EN
 | 
			
		||||
	// ...
 | 
			
		||||
	ddma0EndIrq   dmaR8Irq = 1 << 17 // DDMA0_END_IRQ_EN
 | 
			
		||||
	ddma0HalfIreq dmaR8Irq = 1 << 16 // DDMA0_HF_IRQ_EN
 | 
			
		||||
	ndma7EndIrq   dmaR8Irq = 1 << 15 // NDMA7_END_IRQ_EN
 | 
			
		||||
	ndma7HalfIreq dmaR8Irq = 1 << 16 // NDDMA7_HF_IRQ_EN
 | 
			
		||||
	// ...
 | 
			
		||||
	ndma0EndIrq dmaR8Irq = 1 << 1 // NDMA0_END_IRQ_EN
 | 
			
		||||
	ndma0HFIreq dmaR8Irq = 1 << 0 // NDMA0_HF_IRQ_EN
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DMA_IRQ_EN_REG
 | 
			
		||||
// R8: Page 124-126.
 | 
			
		||||
type dmaR8Irq uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31 reserved
 | 
			
		||||
	dma7QueueEndIrqPend   dmaA64PendingIrq = 1 << 30 // DMA7_QUEUE_IRQ_PEND; DMA 7 Queue End Transfer Interrupt Pending. Set 1 to the bit will clear it.
 | 
			
		||||
	dma7PackageEndIrqPend dmaA64PendingIrq = 1 << 29 // DMA7_PKG_IRQ_PEND; DMA 7 Package End Transfer Interrupt Pending. Set 1 to the bit will clear it.
 | 
			
		||||
	dma7HalfIrqPend       dmaA64PendingIrq = 1 << 28 // DMA7_HLAF_IRQ_PEND; DMA 7 Half Package Transfer Interrupt Pending. Set 1 to the bit will clear it.
 | 
			
		||||
	// ...
 | 
			
		||||
	// 3 reserved
 | 
			
		||||
	dma0QueueEndIrqPend   dmaA64PendingIrq = 1 << 2 // DMA0_QUEUE_IRQ_PEND; DMA 0 Queue End Transfer Interrupt Pending. Set 1 to the bit will clear it.
 | 
			
		||||
	dma0PackageEndIrqPend dmaA64PendingIrq = 1 << 1 // DMA0_PKG_IRQ_PEND; DMA 0 Package End Transfer Interrupt Pending. Set 1 to the bit will clear it.
 | 
			
		||||
	dma0HalfIrqPend       dmaA64PendingIrq = 1 << 0 // DMA0_HLAF_IRQ_PEND; DMA 0 Half Package Transfer Interrupt Pending. Set 1 to the bit will clear it.
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DMA_IRQ_PEND_REG0
 | 
			
		||||
// A64: Page 201-203.
 | 
			
		||||
type dmaA64PendingIrq uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ddma7EndIrqPend   dmaR8PendingIrq = 1 << 31 // DDMA7_END_IRQ_PEND
 | 
			
		||||
	ddma7HalfIreqPend dmaR8PendingIrq = 1 << 30 // DDMA7_HF_IRQ_PEND
 | 
			
		||||
	// ...
 | 
			
		||||
	ddma0EndIrqPend   dmaR8PendingIrq = 1 << 17 // DDMA0_END_IRQ_PEND
 | 
			
		||||
	ddma0HalfIreqPend dmaR8PendingIrq = 1 << 16 // DDMA0_HF_IRQ_PEND
 | 
			
		||||
	ndma7EndIrqPend   dmaR8PendingIrq = 1 << 15 // NDMA7_END_IRQ_PEND
 | 
			
		||||
	ndma7HalfIreqPend dmaR8PendingIrq = 1 << 16 // NDDMA7_HF_IRQ_PEND
 | 
			
		||||
	// ...
 | 
			
		||||
	ndma0EndIrqPend   dmaR8PendingIrq = 1 << 1 // NDMA0_END_IRQ_PEND
 | 
			
		||||
	ndma0HalfIreqPend dmaR8PendingIrq = 1 << 0 // NDMA0_HF_IRQ_PEND
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DMA_IRQ_PEND_STAS_REG
 | 
			
		||||
// R8: Page 126-129.
 | 
			
		||||
type dmaR8PendingIrq uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ndmaLoad       ndmaR8Cfg = 1 << 31 // NDMA_LOAD
 | 
			
		||||
	ndmaContinuous ndmaR8Cfg = 1 << 30 // NDMA_CONTI_EN Continuous mode
 | 
			
		||||
	ndmaWaitClk0   ndmaR8Cfg = 0 << 27 // NDMA_WAIT_STATE Number of clock to wait for
 | 
			
		||||
	ndmaWaitClk2   ndmaR8Cfg = 1 << 27 // 2(n+1)
 | 
			
		||||
	ndmaWaitClk6   ndmaR8Cfg = 2 << 27 //
 | 
			
		||||
	ndmaWaitClk8   ndmaR8Cfg = 3 << 27 //
 | 
			
		||||
	ndmaWaitClk10  ndmaR8Cfg = 4 << 27 //
 | 
			
		||||
	ndmaWaitClk12  ndmaR8Cfg = 5 << 27 //
 | 
			
		||||
	ndmaWaitClk14  ndmaR8Cfg = 6 << 27 //
 | 
			
		||||
	ndmaWaitClk16  ndmaR8Cfg = 7 << 27 //
 | 
			
		||||
	ndmaDstWidth32 ndmaR8Cfg = 2 << 25 // NDMA_DST_DATA_WIDTH
 | 
			
		||||
	ndmaDstWidth16 ndmaR8Cfg = 1 << 25 //
 | 
			
		||||
	ndmaDstWidth8  ndmaR8Cfg = 0 << 25 //
 | 
			
		||||
	ndmaDstBurst8  ndmaR8Cfg = 2 << 23 // NDMA_DST_BST_LEN
 | 
			
		||||
	ndmaDstBurst4  ndmaR8Cfg = 1 << 23 //
 | 
			
		||||
	ndmaDstBurst1  ndmaR8Cfg = 0 << 23 //
 | 
			
		||||
	// 22 reserved NDMA_CFG_DST_NON_SECURE ?
 | 
			
		||||
	ndmaDstAddrNoInc  ndmaR8Cfg = 1 << 21  // NDMA_DST_ADDR_TYPE
 | 
			
		||||
	ndmaDstDrqIRTX    ndmaR8Cfg = 0 << 16  // NDMA_DST_DRQ_TYPE
 | 
			
		||||
	ndmaDstDrqUART1TX ndmaR8Cfg = 9 << 16  //
 | 
			
		||||
	ndmaDstDrqUART3TX ndmaR8Cfg = 11 << 16 //
 | 
			
		||||
	ndmaDstDrqAudio   ndmaR8Cfg = 19 << 16 // 24.576MHz (Page 53)
 | 
			
		||||
	ndmaDstDrqSRAM    ndmaR8Cfg = 21 << 16 //
 | 
			
		||||
	ndmaDstDrqSPI0TX  ndmaR8Cfg = 24 << 16 //
 | 
			
		||||
	ndmaDstDrqSPI1TX  ndmaR8Cfg = 25 << 16 //
 | 
			
		||||
	ndmaDstDrqSPI2TX  ndmaR8Cfg = 26 << 16 //
 | 
			
		||||
	ndmaDstDrqUSB1    ndmaR8Cfg = 27 << 16 // 480MHz
 | 
			
		||||
	ndmaDstDrqUSB2    ndmaR8Cfg = 28 << 16 //
 | 
			
		||||
	ndmaDstDrqUSB3    ndmaR8Cfg = 29 << 16 //
 | 
			
		||||
	ndmaDstDrqUSB4    ndmaR8Cfg = 30 << 16 //
 | 
			
		||||
	ndmaDstDrqUSB5    ndmaR8Cfg = 31 << 16 //
 | 
			
		||||
	ndmaBCRemain      ndmaR8Cfg = 1 << 15  // BC_MODE_SEL
 | 
			
		||||
	// 14:11 reserved
 | 
			
		||||
	ndmaSrcWidth32 ndmaR8Cfg = 2 << 9 // NDMA_SRC_DATA_WIDTH
 | 
			
		||||
	ndmaSrcWidth16 ndmaR8Cfg = 1 << 9 //
 | 
			
		||||
	ndmaSrcWidth8  ndmaR8Cfg = 0 << 9 //
 | 
			
		||||
	ndmaSrcBurst8  ndmaR8Cfg = 2 << 7 // NDMA_SRC_BST_LEN
 | 
			
		||||
	ndmaSrcBurst4  ndmaR8Cfg = 1 << 7 //
 | 
			
		||||
	ndmaSrcBurst1  ndmaR8Cfg = 0 << 7 //
 | 
			
		||||
	// 6 reserved NDMA_CFG_SRC_NON_SECURE ?
 | 
			
		||||
	ndmaSrcAddrNoInc  ndmaR8Cfg = 1 << 5  // NDMA_SRC_ADDR_TYPE
 | 
			
		||||
	ndmaSrcDrqIRTX    ndmaR8Cfg = 0 << 0  // NDMA_SRC_DRQ_TYPE
 | 
			
		||||
	ndmaSrcDrqUART1RX ndmaR8Cfg = 9 << 0  //
 | 
			
		||||
	ndmaSrcDrqUART3RX ndmaR8Cfg = 11 << 0 //
 | 
			
		||||
	ndmaSrcDrqAudio   ndmaR8Cfg = 19 << 0 // 24.576MHz (Page 53)
 | 
			
		||||
	ndmaSrcDrqSRAM    ndmaR8Cfg = 21 << 0 //
 | 
			
		||||
	ndmaSrcDrqSDRAM   ndmaR8Cfg = 22 << 0 // 0~400MHz
 | 
			
		||||
	ndmaSrcDrqTPAD    ndmaR8Cfg = 23 << 0 //
 | 
			
		||||
	ndmaSrcDrqSPI0RX  ndmaR8Cfg = 24 << 0 //
 | 
			
		||||
	ndmaSrcDrqSPI1RX  ndmaR8Cfg = 25 << 0 //
 | 
			
		||||
	ndmaSrcDrqSPI2RX  ndmaR8Cfg = 26 << 0 //
 | 
			
		||||
	ndmaSrcDrqUSB1    ndmaR8Cfg = 27 << 0 // 480MHz
 | 
			
		||||
	ndmaSrcDrqUSB2    ndmaR8Cfg = 28 << 0 //
 | 
			
		||||
	ndmaSrcDrqUSB3    ndmaR8Cfg = 29 << 0 //
 | 
			
		||||
	ndmaSrcDrqUSB4    ndmaR8Cfg = 30 << 0 //
 | 
			
		||||
	ndmaSrcDrqUSB5    ndmaR8Cfg = 31 << 0 //
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NDMA_CTRL_REG
 | 
			
		||||
// R8: Page 129-131.
 | 
			
		||||
type ndmaR8Cfg uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	ddmaLoad       ddmaR8Cfg = 1 << 31 // DDMA_LOAD
 | 
			
		||||
	ddmaBusy       ddmaR8Cfg = 1 << 30 // DDMA_BSY_STA
 | 
			
		||||
	ddmaContinuous ddmaR8Cfg = 1 << 29 // DDMA_CONTI_MODE_EN
 | 
			
		||||
	// 28:27 reserved  28 = DDMA_CFG_DST_NON_SECURE ?
 | 
			
		||||
	ddmaDstWidth32     ddmaR8Cfg = 2 << 25  // DDMA_DST_DATA_WIDTH
 | 
			
		||||
	ddmaDstWidth16     ddmaR8Cfg = 1 << 25  //
 | 
			
		||||
	ddmaDstWidth8      ddmaR8Cfg = 0 << 25  //
 | 
			
		||||
	ddmaDstBurst8      ddmaR8Cfg = 2 << 23  // DDMA_DST_BST_LEN
 | 
			
		||||
	ddmaDstBurst4      ddmaR8Cfg = 1 << 23  //
 | 
			
		||||
	ddmaDstBurst1      ddmaR8Cfg = 0 << 23  //
 | 
			
		||||
	ddmaDstVertical    ddmaR8Cfg = 3 << 21  // DDMA_ADDR_MODE; no idea what it's use it. It's not explained in the datasheet ...
 | 
			
		||||
	ddmaDstHorizontal  ddmaR8Cfg = 2 << 21  // ... and the official drivers/dma/sun6i-dma.c driver doesn't use it
 | 
			
		||||
	ddmaDstIOMode      ddmaR8Cfg = 1 << 21  // Non incrementing
 | 
			
		||||
	ddmaDstLinear      ddmaR8Cfg = 0 << 21  // Normal incrementing position
 | 
			
		||||
	ddmaDstDrqSRAM     ddmaR8Cfg = 0 << 16  // DDMA_DST_DRQ_SEL
 | 
			
		||||
	ddmaDstDrqSDRAM    ddmaR8Cfg = 1 << 16  // DDR ram speed
 | 
			
		||||
	ddmaDstDrqNAND     ddmaR8Cfg = 3 << 16  //
 | 
			
		||||
	ddmaDstDrqUSB0     ddmaR8Cfg = 4 << 16  //
 | 
			
		||||
	ddmaDstDrqSPI1TX   ddmaR8Cfg = 8 << 16  //
 | 
			
		||||
	ddmaDstDrqCryptoTX ddmaR8Cfg = 10 << 16 //
 | 
			
		||||
	ddmaDstDrqTCON0    ddmaR8Cfg = 14 << 16 //
 | 
			
		||||
	ddmaDstDrqSPI0TX   ddmaR8Cfg = 26 << 16 //
 | 
			
		||||
	ddmaDstDrqSPI2TX   ddmaR8Cfg = 28 << 16 //
 | 
			
		||||
	ddmaBCRemain       ddmaR8Cfg = 1 << 15  // BC_MODE_SEL
 | 
			
		||||
	// 14:11 reserved
 | 
			
		||||
	ddmaSrcWidth32    ddmaR8Cfg = 2 << 9 // DDMA_SRC_DATA_WIDTH
 | 
			
		||||
	ddmaSrcWidth16    ddmaR8Cfg = 1 << 9 //
 | 
			
		||||
	ddmaSrcWidth8     ddmaR8Cfg = 0 << 9 //
 | 
			
		||||
	ddmaSrcBurst8     ddmaR8Cfg = 2 << 7 // DDMA_SRC_BST_LEN
 | 
			
		||||
	ddmaSrcBurst4     ddmaR8Cfg = 1 << 7 //
 | 
			
		||||
	ddmaSrcBurst1     ddmaR8Cfg = 0 << 7 //
 | 
			
		||||
	ddmaSrcVertical   ddmaR8Cfg = 3 << 5 // DDMA_SRC_ADDR_MODE
 | 
			
		||||
	ddmaSrcHorizontal ddmaR8Cfg = 2 << 5 //
 | 
			
		||||
	ddmaSrcIOMode     ddmaR8Cfg = 1 << 5 // Non incrementing
 | 
			
		||||
	ddmaSrcLinear     ddmaR8Cfg = 0 << 5 // Normal incrementing position
 | 
			
		||||
	// 4:0 drq
 | 
			
		||||
	ddmaSrcDrqSRAM     ddmaR8Cfg = 0 << 0  // DDMA_SRC_DRQ_TYPE
 | 
			
		||||
	ddmaSrcDrqSDRAM    ddmaR8Cfg = 1 << 0  //
 | 
			
		||||
	ddmaSrcDrqNAND     ddmaR8Cfg = 3 << 0  //
 | 
			
		||||
	ddmaSrcDrqUSB0     ddmaR8Cfg = 4 << 0  //
 | 
			
		||||
	ddmaSrcDrqSPI1RX   ddmaR8Cfg = 9 << 0  //
 | 
			
		||||
	ddmaSrcDrqCryptoRX ddmaR8Cfg = 11 << 0 //
 | 
			
		||||
	ddmaSrcDrqSPI0RX   ddmaR8Cfg = 27 << 0 //
 | 
			
		||||
	ddmaSrcDrqSPI2RX   ddmaR8Cfg = 29 << 0 //
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DDMA_CFG_REG
 | 
			
		||||
// R8: Page 131-134.
 | 
			
		||||
type ddmaR8Cfg uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// For each value, N+1 is actually used.
 | 
			
		||||
	ddmaDstBlkSizeMask      ddmaR8Param = 0xFF << 24 // DEST_DATA_BLK_SIZE
 | 
			
		||||
	ddmaDstWaitClkCycleMask ddmaR8Param = 0xFF << 16 // DEST_WAIT_CLK_CYC
 | 
			
		||||
	ddmaSrcBlkSizeMask      ddmaR8Param = 0xFF << 8  // SRC_DATA_BLK_SIZE
 | 
			
		||||
	ddmaSrcWaitClkCycleMask ddmaR8Param = 0xFF << 0  // SRC_WAIT_CLK_CYC
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// DDMA_PARA_REG
 | 
			
		||||
// R8: Page 134.
 | 
			
		||||
type ddmaR8Param uint32
 | 
			
		||||
 | 
			
		||||
// smokeTest allocates two physical pages, ask the DMA controller to copy the
 | 
			
		||||
// data from one page to another (with a small offset) and make sure the
 | 
			
		||||
// content is as expected.
 | 
			
		||||
//
 | 
			
		||||
// This should take a fraction of a second and will make sure the driver is
 | 
			
		||||
// usable.
 | 
			
		||||
func smokeTest() error {
 | 
			
		||||
	const size = 4096  // 4kb
 | 
			
		||||
	const holeSize = 1 // Minimum DMA alignment.
 | 
			
		||||
 | 
			
		||||
	alloc := func(s int) (pmem.Mem, error) {
 | 
			
		||||
		return pmem.Alloc(s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	copyMem := func(pDst, pSrc uint64) error {
 | 
			
		||||
		n := drvDMA.dmaMemory.getDedicated()
 | 
			
		||||
		if n == -1 {
 | 
			
		||||
			return errors.New("no channel available")
 | 
			
		||||
		}
 | 
			
		||||
		drvDMA.dmaMemory.irqEn &^= 3 << uint(2*n+16)
 | 
			
		||||
		drvDMA.dmaMemory.irqPendStas = 3 << uint(2*n+16)
 | 
			
		||||
		ch := &drvDMA.dmaMemory.dedicated[n]
 | 
			
		||||
		defer func() {
 | 
			
		||||
			_ = ch.release()
 | 
			
		||||
		}()
 | 
			
		||||
		ch.set(uint32(pSrc), uint32(pDst)+holeSize, 4096-2*holeSize, false, false, ddmaDstDrqSDRAM|ddmaSrcDrqSDRAM)
 | 
			
		||||
 | 
			
		||||
		for ch.cfg&ddmaBusy != 0 {
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return pmem.TestCopy(size, holeSize, alloc, copyMem)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// driverDMA implements periph.Driver.
 | 
			
		||||
//
 | 
			
		||||
// It implements much more than the DMA controller, it also exposes the clocks,
 | 
			
		||||
// the PWM and PCM controllers.
 | 
			
		||||
type driverDMA struct {
 | 
			
		||||
	// dmaMemory is the memory map of the CPU DMA registers.
 | 
			
		||||
	dmaMemory *dmaMap
 | 
			
		||||
	// pwmMemory is the memory map of the CPU PWM registers.
 | 
			
		||||
	pwmMemory *pwmMap
 | 
			
		||||
	// spiMemory is the memory mapping for the spi CPU registers.
 | 
			
		||||
	spiMemory *spiMap
 | 
			
		||||
	// clockMemory is the memory mapping for the clock CPU registers.
 | 
			
		||||
	clockMemory *clockMap
 | 
			
		||||
	// timerMemory is the memory mapping for the timer CPU registers.
 | 
			
		||||
	timerMemory *timerMap
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverDMA) String() string {
 | 
			
		||||
	return "allwinner-dma"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverDMA) Prerequisites() []string {
 | 
			
		||||
	return []string{"allwinner-gpio"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverDMA) After() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverDMA) Init() (bool, error) {
 | 
			
		||||
	// dmaBaseAddr is the physical base address of the DMA registers.
 | 
			
		||||
	var dmaBaseAddr uint32
 | 
			
		||||
	// pwmBaseAddr is the physical base address of the PWM registers.
 | 
			
		||||
	var pwmBaseAddr uint32
 | 
			
		||||
	// spiBaseAddr is the physical base address of the clock registers.
 | 
			
		||||
	var spiBaseAddr uint32
 | 
			
		||||
	// clockBaseAddr is the physical base address of the clock registers.
 | 
			
		||||
	var clockBaseAddr uint32
 | 
			
		||||
	// timerBaseAddr is the physical base address of the timer registers.
 | 
			
		||||
	var timerBaseAddr uint32
 | 
			
		||||
	if IsA64() {
 | 
			
		||||
		// Page 198.
 | 
			
		||||
		dmaBaseAddr = 0x1C02000
 | 
			
		||||
		// Page 194.
 | 
			
		||||
		pwmBaseAddr = 0x1C21400
 | 
			
		||||
		// Page 161.
 | 
			
		||||
		timerBaseAddr = 0x1C20C00
 | 
			
		||||
		// Page 81.
 | 
			
		||||
		clockBaseAddr = 0x1C20000
 | 
			
		||||
		// Page Page 545.
 | 
			
		||||
		spiBaseAddr = 0x01C68000
 | 
			
		||||
	} else if IsR8() {
 | 
			
		||||
		// Page 124.
 | 
			
		||||
		dmaBaseAddr = 0x1C02000
 | 
			
		||||
		// Page 83.
 | 
			
		||||
		pwmBaseAddr = 0x1C20C00 + 0x200
 | 
			
		||||
		// Page 85.
 | 
			
		||||
		timerBaseAddr = 0x1C20C00
 | 
			
		||||
		// Page 57.
 | 
			
		||||
		clockBaseAddr = 0x1C20000
 | 
			
		||||
		// Page 151.
 | 
			
		||||
		spiBaseAddr = 0x01C05000
 | 
			
		||||
	} else {
 | 
			
		||||
		// H3
 | 
			
		||||
		// Page 194.
 | 
			
		||||
		//dmaBaseAddr = 0x1C02000
 | 
			
		||||
		// Page 187.
 | 
			
		||||
		//pwmBaseAddr = 0x1C21400
 | 
			
		||||
		// Page 154.
 | 
			
		||||
		//timerBaseAddr = 0x1C20C00
 | 
			
		||||
		return false, errors.New("unsupported CPU architecture")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := pmem.MapAsPOD(uint64(dmaBaseAddr), &d.dmaMemory); err != nil {
 | 
			
		||||
		if os.IsPermission(err) {
 | 
			
		||||
			return true, fmt.Errorf("need more access, try as root: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := pmem.MapAsPOD(uint64(pwmBaseAddr), &d.pwmMemory); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := pmem.MapAsPOD(uint64(timerBaseAddr), &d.timerMemory); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := pmem.MapAsPOD(uint64(clockBaseAddr), &d.clockMemory); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := pmem.MapAsPOD(uint64(spiBaseAddr), &d.spiMemory); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true, smokeTest()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverDMA) Close() error {
 | 
			
		||||
	// Stop DMA and PWM controllers.
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if false && isArm {
 | 
			
		||||
		// TODO(maruel): This is intense, wait to be sure it works.
 | 
			
		||||
		periph.MustRegister(&drvDMA)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drvDMA driverDMA
 | 
			
		||||
							
								
								
									
										33
									
								
								vendor/periph.io/x/periph/host/allwinner/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								vendor/periph.io/x/periph/host/allwinner/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
// 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 allwinner exposes the GPIO functionality that is common to all
 | 
			
		||||
// AllWinner processors.
 | 
			
		||||
//
 | 
			
		||||
// This driver implements memory-mapped GPIO pin manipulation and leverages
 | 
			
		||||
// sysfs-gpio for edge detection.
 | 
			
		||||
//
 | 
			
		||||
// If you are looking at the actual implementation, open doc.go for further
 | 
			
		||||
// implementation details.
 | 
			
		||||
//
 | 
			
		||||
// Datasheets
 | 
			
		||||
//
 | 
			
		||||
// A64: http://files.pine64.org/doc/datasheet/pine64/Allwinner_A64_User_Manual_V1.0.pdf
 | 
			
		||||
//
 | 
			
		||||
// H3: http://dl.linux-sunxi.org/H3/Allwinner_H3_Datasheet_V1.0.pdf
 | 
			
		||||
//
 | 
			
		||||
// R8: https://github.com/NextThingCo/CHIP-Hardware/raw/master/CHIP%5Bv1_0%5D/CHIPv1_0-BOM-Datasheets/Allwinner%20R8%20User%20Manual%20V1.1.pdf
 | 
			
		||||
//
 | 
			
		||||
// Physical overview: http://files.pine64.org/doc/datasheet/pine64/A64_Datasheet_V1.1.pdf
 | 
			
		||||
package allwinner
 | 
			
		||||
 | 
			
		||||
// Other implementation details
 | 
			
		||||
//
 | 
			
		||||
// The most active kernel branch is
 | 
			
		||||
// https://github.com/linux-sunxi/linux-sunxi/commits/sunxi-next
 | 
			
		||||
//
 | 
			
		||||
// In particular look at
 | 
			
		||||
// https://github.com/linux-sunxi/linux-sunxi/blob/sunxi-next/drivers/dma/sun4i-dma.c
 | 
			
		||||
// and
 | 
			
		||||
// https://github.com/linux-sunxi/linux-sunxi/blob/sunxi-next/drivers/dma/sun6i-dma.c
 | 
			
		||||
							
								
								
									
										1065
									
								
								vendor/periph.io/x/periph/host/allwinner/gpio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1065
									
								
								vendor/periph.io/x/periph/host/allwinner/gpio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										563
									
								
								vendor/periph.io/x/periph/host/allwinner/gpio_pl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								vendor/periph.io/x/periph/host/allwinner/gpio_pl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,563 @@
 | 
			
		||||
// 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 allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio/gpioreg"
 | 
			
		||||
	"periph.io/x/periph/conn/physic"
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/host/pmem"
 | 
			
		||||
	"periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// All the pins in the PL group.
 | 
			
		||||
var PL0, PL1, PL2, PL3, PL4, PL5, PL6, PL7, PL8, PL9, PL10, PL11, PL12 *PinPL
 | 
			
		||||
 | 
			
		||||
// PinPL defines one CPU supported pin in the PL group.
 | 
			
		||||
//
 | 
			
		||||
// PinPL implements gpio.PinIO.
 | 
			
		||||
type PinPL struct {
 | 
			
		||||
	// Immutable.
 | 
			
		||||
	offset      uint8     // as per register offset calculation
 | 
			
		||||
	name        string    // name as per datasheet
 | 
			
		||||
	defaultPull gpio.Pull // default pull at startup
 | 
			
		||||
 | 
			
		||||
	// Immutable after driver initialization.
 | 
			
		||||
	sysfsPin  *sysfs.Pin // Set to the corresponding sysfs.Pin, if any.
 | 
			
		||||
	available bool       // Set when the pin is available on this CPU architecture.
 | 
			
		||||
 | 
			
		||||
	// Mutable.
 | 
			
		||||
	usingEdge bool // Set when edge detection is enabled.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String implements conn.Resource.
 | 
			
		||||
//
 | 
			
		||||
// It returns the pin name and number, ex: "PL5(352)".
 | 
			
		||||
func (p *PinPL) String() string {
 | 
			
		||||
	return fmt.Sprintf("%s(%d)", p.name, p.Number())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Halt implements conn.Resource.
 | 
			
		||||
//
 | 
			
		||||
// It stops edge detection if enabled.
 | 
			
		||||
func (p *PinPL) Halt() error {
 | 
			
		||||
	if p.usingEdge {
 | 
			
		||||
		if err := p.sysfsPin.Halt(); err != nil {
 | 
			
		||||
			return p.wrap(err)
 | 
			
		||||
		}
 | 
			
		||||
		p.usingEdge = false
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Name implements pin.Pin.
 | 
			
		||||
//
 | 
			
		||||
// It returns the pin name, ex: "PL5".
 | 
			
		||||
func (p *PinPL) Name() string {
 | 
			
		||||
	return p.name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Number implements pin.Pin.
 | 
			
		||||
//
 | 
			
		||||
// It returns the GPIO pin number as represented by gpio sysfs.
 | 
			
		||||
func (p *PinPL) Number() int {
 | 
			
		||||
	return 11*32 + int(p.offset)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Function implements pin.Pin.
 | 
			
		||||
func (p *PinPL) Function() string {
 | 
			
		||||
	return string(p.Func())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Func implements pin.PinFunc.
 | 
			
		||||
func (p *PinPL) Func() pin.Func {
 | 
			
		||||
	if !p.available {
 | 
			
		||||
		// We do not want the error message about uninitialized system.
 | 
			
		||||
		return pin.FuncNone
 | 
			
		||||
	}
 | 
			
		||||
	if drvGPIOPL.gpioMemoryPL == nil {
 | 
			
		||||
		if p.sysfsPin == nil {
 | 
			
		||||
			return pin.FuncNone
 | 
			
		||||
		}
 | 
			
		||||
		return p.sysfsPin.Func()
 | 
			
		||||
	}
 | 
			
		||||
	switch f := p.function(); f {
 | 
			
		||||
	case in:
 | 
			
		||||
		if p.FastRead() {
 | 
			
		||||
			return gpio.IN_HIGH
 | 
			
		||||
		}
 | 
			
		||||
		return gpio.IN_LOW
 | 
			
		||||
	case out:
 | 
			
		||||
		if p.FastRead() {
 | 
			
		||||
			return gpio.OUT_HIGH
 | 
			
		||||
		}
 | 
			
		||||
		return gpio.OUT_LOW
 | 
			
		||||
	case alt1:
 | 
			
		||||
		if s := mappingPL[p.offset][0]; len(s) != 0 {
 | 
			
		||||
			return pin.Func(s)
 | 
			
		||||
		}
 | 
			
		||||
		return pin.Func("ALT1")
 | 
			
		||||
	case alt2:
 | 
			
		||||
		if s := mappingPL[p.offset][1]; len(s) != 0 {
 | 
			
		||||
			return pin.Func(s)
 | 
			
		||||
		}
 | 
			
		||||
		return pin.Func("ALT2")
 | 
			
		||||
	case alt3:
 | 
			
		||||
		if s := mappingPL[p.offset][2]; len(s) != 0 {
 | 
			
		||||
			return pin.Func(s)
 | 
			
		||||
		}
 | 
			
		||||
		return pin.Func("ALT3")
 | 
			
		||||
	case alt4:
 | 
			
		||||
		if s := mappingPL[p.offset][3]; len(s) != 0 {
 | 
			
		||||
			return pin.Func(s)
 | 
			
		||||
		}
 | 
			
		||||
		return pin.Func("ALT4")
 | 
			
		||||
	case alt5:
 | 
			
		||||
		if s := mappingPL[p.offset][4]; len(s) != 0 {
 | 
			
		||||
			if strings.Contains(string(s), "_EINT") {
 | 
			
		||||
				// It's an input supporting interrupts.
 | 
			
		||||
				if p.FastRead() {
 | 
			
		||||
					return gpio.IN_HIGH
 | 
			
		||||
				}
 | 
			
		||||
				return gpio.IN_LOW
 | 
			
		||||
			}
 | 
			
		||||
			return pin.Func(s)
 | 
			
		||||
		}
 | 
			
		||||
		return pin.Func("ALT5")
 | 
			
		||||
	case disabled:
 | 
			
		||||
		return pin.FuncNone
 | 
			
		||||
	default:
 | 
			
		||||
		return pin.FuncNone
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SupportedFuncs implements pin.PinFunc.
 | 
			
		||||
func (p *PinPL) SupportedFuncs() []pin.Func {
 | 
			
		||||
	f := make([]pin.Func, 0, 2+2)
 | 
			
		||||
	f = append(f, gpio.IN, gpio.OUT)
 | 
			
		||||
	for _, m := range mappingPL[p.offset] {
 | 
			
		||||
		if m != pin.FuncNone && !strings.Contains(string(m), "_EINT") {
 | 
			
		||||
			f = append(f, m)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetFunc implements pin.PinFunc.
 | 
			
		||||
func (p *PinPL) SetFunc(f pin.Func) error {
 | 
			
		||||
	switch f {
 | 
			
		||||
	case gpio.FLOAT:
 | 
			
		||||
		return p.In(gpio.Float, gpio.NoEdge)
 | 
			
		||||
	case gpio.IN:
 | 
			
		||||
		return p.In(gpio.PullNoChange, gpio.NoEdge)
 | 
			
		||||
	case gpio.IN_LOW:
 | 
			
		||||
		return p.In(gpio.PullDown, gpio.NoEdge)
 | 
			
		||||
	case gpio.IN_HIGH:
 | 
			
		||||
		return p.In(gpio.PullUp, gpio.NoEdge)
 | 
			
		||||
	case gpio.OUT_HIGH:
 | 
			
		||||
		return p.Out(gpio.High)
 | 
			
		||||
	case gpio.OUT_LOW:
 | 
			
		||||
		return p.Out(gpio.Low)
 | 
			
		||||
	default:
 | 
			
		||||
		isGeneral := f == f.Generalize()
 | 
			
		||||
		for i, m := range mappingPL[p.offset] {
 | 
			
		||||
			if m == f || (isGeneral && m.Generalize() == f) {
 | 
			
		||||
				if err := p.Halt(); err != nil {
 | 
			
		||||
					return err
 | 
			
		||||
				}
 | 
			
		||||
				switch i {
 | 
			
		||||
				case 0:
 | 
			
		||||
					p.setFunction(alt1)
 | 
			
		||||
				case 1:
 | 
			
		||||
					p.setFunction(alt2)
 | 
			
		||||
				case 2:
 | 
			
		||||
					p.setFunction(alt3)
 | 
			
		||||
				case 3:
 | 
			
		||||
					p.setFunction(alt4)
 | 
			
		||||
				case 4:
 | 
			
		||||
					p.setFunction(alt5)
 | 
			
		||||
				}
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return p.wrap(errors.New("unsupported function"))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// In implements gpio.PinIn.
 | 
			
		||||
func (p *PinPL) In(pull gpio.Pull, edge gpio.Edge) error {
 | 
			
		||||
	if !p.available {
 | 
			
		||||
		// We do not want the error message about uninitialized system.
 | 
			
		||||
		return p.wrap(errors.New("not available on this CPU architecture"))
 | 
			
		||||
	}
 | 
			
		||||
	if p.usingEdge && edge == gpio.NoEdge {
 | 
			
		||||
		if err := p.sysfsPin.Halt(); err != nil {
 | 
			
		||||
			return p.wrap(err)
 | 
			
		||||
		}
 | 
			
		||||
		p.usingEdge = false
 | 
			
		||||
	}
 | 
			
		||||
	if drvGPIOPL.gpioMemoryPL == nil {
 | 
			
		||||
		if p.sysfsPin == nil {
 | 
			
		||||
			return p.wrap(errors.New("subsystem gpiomem not initialized and sysfs not accessible; try running as root?"))
 | 
			
		||||
		}
 | 
			
		||||
		if pull != gpio.PullNoChange {
 | 
			
		||||
			return p.wrap(errors.New("pull cannot be used when subsystem gpiomem not initialized; try running as root?"))
 | 
			
		||||
		}
 | 
			
		||||
		if err := p.sysfsPin.In(pull, edge); err != nil {
 | 
			
		||||
			return p.wrap(err)
 | 
			
		||||
		}
 | 
			
		||||
		p.usingEdge = edge != gpio.NoEdge
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	if !p.setFunction(in) {
 | 
			
		||||
		return p.wrap(errors.New("failed to set pin as input"))
 | 
			
		||||
	}
 | 
			
		||||
	if pull != gpio.PullNoChange {
 | 
			
		||||
		off := p.offset / 16
 | 
			
		||||
		shift := 2 * (p.offset % 16)
 | 
			
		||||
		// Do it in a way that is concurrent safe.
 | 
			
		||||
		drvGPIOPL.gpioMemoryPL.pull[off] &^= 3 << shift
 | 
			
		||||
		switch pull {
 | 
			
		||||
		case gpio.PullDown:
 | 
			
		||||
			drvGPIOPL.gpioMemoryPL.pull[off] = 2 << shift
 | 
			
		||||
		case gpio.PullUp:
 | 
			
		||||
			drvGPIOPL.gpioMemoryPL.pull[off] = 1 << shift
 | 
			
		||||
		default:
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if edge != gpio.NoEdge {
 | 
			
		||||
		if p.sysfsPin == nil {
 | 
			
		||||
			return p.wrap(fmt.Errorf("pin %d is not exported by sysfs", p.Number()))
 | 
			
		||||
		}
 | 
			
		||||
		// This resets pending edges.
 | 
			
		||||
		if err := p.sysfsPin.In(gpio.PullNoChange, edge); err != nil {
 | 
			
		||||
			return p.wrap(err)
 | 
			
		||||
		}
 | 
			
		||||
		p.usingEdge = true
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Read implements gpio.PinIn.
 | 
			
		||||
func (p *PinPL) Read() gpio.Level {
 | 
			
		||||
	if drvGPIOPL.gpioMemoryPL == nil {
 | 
			
		||||
		if p.sysfsPin == nil {
 | 
			
		||||
			return gpio.Low
 | 
			
		||||
		}
 | 
			
		||||
		return p.sysfsPin.Read()
 | 
			
		||||
	}
 | 
			
		||||
	return gpio.Level(drvGPIOPL.gpioMemoryPL.data&(1<<p.offset) != 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FastRead reads without verification.
 | 
			
		||||
func (p *PinPL) FastRead() gpio.Level {
 | 
			
		||||
	return gpio.Level(drvGPIOPL.gpioMemoryPL.data&(1<<p.offset) != 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WaitForEdge implements gpio.PinIn.
 | 
			
		||||
func (p *PinPL) WaitForEdge(timeout time.Duration) bool {
 | 
			
		||||
	if p.sysfsPin != nil {
 | 
			
		||||
		return p.sysfsPin.WaitForEdge(timeout)
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pull implements gpio.PinIn.
 | 
			
		||||
func (p *PinPL) Pull() gpio.Pull {
 | 
			
		||||
	if drvGPIOPL.gpioMemoryPL == nil {
 | 
			
		||||
		// If gpioMemoryPL is set, p.available is true.
 | 
			
		||||
		return gpio.PullNoChange
 | 
			
		||||
	}
 | 
			
		||||
	switch (drvGPIOPL.gpioMemoryPL.pull[p.offset/16] >> (2 * (p.offset % 16))) & 3 {
 | 
			
		||||
	case 0:
 | 
			
		||||
		return gpio.Float
 | 
			
		||||
	case 1:
 | 
			
		||||
		return gpio.PullUp
 | 
			
		||||
	case 2:
 | 
			
		||||
		return gpio.PullDown
 | 
			
		||||
	default:
 | 
			
		||||
		// Confused.
 | 
			
		||||
		return gpio.PullNoChange
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DefaultPull implements gpio.PinIn.
 | 
			
		||||
func (p *PinPL) DefaultPull() gpio.Pull {
 | 
			
		||||
	return p.defaultPull
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Out implements gpio.PinOut.
 | 
			
		||||
func (p *PinPL) Out(l gpio.Level) error {
 | 
			
		||||
	if !p.available {
 | 
			
		||||
		// We do not want the error message about uninitialized system.
 | 
			
		||||
		return p.wrap(errors.New("not available on this CPU architecture"))
 | 
			
		||||
	}
 | 
			
		||||
	if drvGPIOPL.gpioMemoryPL == nil {
 | 
			
		||||
		if p.sysfsPin != nil {
 | 
			
		||||
			return p.wrap(errors.New("subsystem gpiomem not initialized and sysfs not accessible; try running as root?"))
 | 
			
		||||
		}
 | 
			
		||||
		return p.sysfsPin.Out(l)
 | 
			
		||||
	}
 | 
			
		||||
	// First disable edges.
 | 
			
		||||
	if err := p.Halt(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	p.FastOut(l)
 | 
			
		||||
	if !p.setFunction(out) {
 | 
			
		||||
		return p.wrap(errors.New("failed to set pin as output"))
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FastOut sets a pin output level with Absolutely No error checking.
 | 
			
		||||
//
 | 
			
		||||
// See Pin.FastOut for more information.
 | 
			
		||||
func (p *PinPL) FastOut(l gpio.Level) {
 | 
			
		||||
	bit := uint32(1 << p.offset)
 | 
			
		||||
	if l {
 | 
			
		||||
		drvGPIOPL.gpioMemoryPL.data |= bit
 | 
			
		||||
	} else {
 | 
			
		||||
		drvGPIOPL.gpioMemoryPL.data &^= bit
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PWM implements gpio.PinOut.
 | 
			
		||||
func (p *PinPL) PWM(gpio.Duty, physic.Frequency) error {
 | 
			
		||||
	// TODO(maruel): PWM support for PL10.
 | 
			
		||||
	return p.wrap(errors.New("not available on this CPU architecture"))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// function returns the current GPIO pin function.
 | 
			
		||||
//
 | 
			
		||||
// It must not be called if drvGPIOPL.gpioMemoryPL is nil.
 | 
			
		||||
func (p *PinPL) function() function {
 | 
			
		||||
	shift := 4 * (p.offset % 8)
 | 
			
		||||
	return function((drvGPIOPL.gpioMemoryPL.cfg[p.offset/8] >> shift) & 7)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setFunction changes the GPIO pin function.
 | 
			
		||||
//
 | 
			
		||||
// Returns false if the pin was in AltN. Only accepts in and out
 | 
			
		||||
//
 | 
			
		||||
// It must not be called if drvGPIOPL.gpioMemoryPL is nil.
 | 
			
		||||
func (p *PinPL) setFunction(f function) bool {
 | 
			
		||||
	if f != in && f != out {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	// Interrupt based edge triggering is Alt5 but this is only supported on some
 | 
			
		||||
	// pins.
 | 
			
		||||
	// TODO(maruel): This check should use a whitelist of pins.
 | 
			
		||||
	if actual := p.function(); actual != in && actual != out && actual != disabled && actual != alt5 {
 | 
			
		||||
		// Pin is in special mode.
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	off := p.offset / 8
 | 
			
		||||
	shift := 4 * (p.offset % 8)
 | 
			
		||||
	mask := uint32(disabled) << shift
 | 
			
		||||
	v := (uint32(f) << shift) ^ mask
 | 
			
		||||
	// First disable, then setup. This is concurrent safe.
 | 
			
		||||
	drvGPIOPL.gpioMemoryPL.cfg[off] |= mask
 | 
			
		||||
	drvGPIOPL.gpioMemoryPL.cfg[off] &^= v
 | 
			
		||||
	if p.function() != f {
 | 
			
		||||
		panic(f)
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *PinPL) wrap(err error) error {
 | 
			
		||||
	return fmt.Errorf("allwinner-gpio-pl (%s): %v", p, err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// cpuPinsPL is all the pins as supported by the CPU. There is no guarantee that
 | 
			
		||||
// they are actually connected to anything on the board.
 | 
			
		||||
var cpuPinsPL = []PinPL{
 | 
			
		||||
	{offset: 0, name: "PL0", defaultPull: gpio.PullUp},
 | 
			
		||||
	{offset: 1, name: "PL1", defaultPull: gpio.PullUp},
 | 
			
		||||
	{offset: 2, name: "PL2", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 3, name: "PL3", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 4, name: "PL4", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 5, name: "PL5", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 6, name: "PL6", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 7, name: "PL7", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 8, name: "PL8", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 9, name: "PL9", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 10, name: "PL10", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 11, name: "PL11", defaultPull: gpio.Float},
 | 
			
		||||
	{offset: 12, name: "PL12", defaultPull: gpio.Float},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// See gpio.go for details.
 | 
			
		||||
var mappingPL = [13][5]pin.Func{
 | 
			
		||||
	{"RSB_SCK", "I2C_SCL", "", "", "PL_EINT0"}, // PL0
 | 
			
		||||
	{"RSB_SDA", "I2C_SDA", "", "", "PL_EINT1"}, // PL1
 | 
			
		||||
	{"UART_TX", "", "", "", "PL_EINT2"},        // PL2
 | 
			
		||||
	{"UART_RX", "", "", "", "PL_EINT3"},        // PL3
 | 
			
		||||
	{"JTAG_TMS", "", "", "", "PL_EINT4"},       // PL4
 | 
			
		||||
	{"JTAG_TCK", "", "", "", "PL_EINT5"},       // PL5
 | 
			
		||||
	{"JTAG_TDO", "", "", "", "PL_EINT6"},       // PL6
 | 
			
		||||
	{"JTAG_TDI", "", "", "", "PL_EINT7"},       // PL7
 | 
			
		||||
	{"I2C_SCL", "", "", "", "PL_EINT8"},        // PL8
 | 
			
		||||
	{"I2C_SDA", "", "", "", "PL_EINT9"},        // PL9
 | 
			
		||||
	{"PWM0", "", "", "", "PL_EINT10"},          // PL10
 | 
			
		||||
	{"CIR_RX", "", "", "", "PL_EINT11"},        // PL11
 | 
			
		||||
	{"", "", "", "", "PL_EINT12"},              // PL12
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	PL0 = &cpuPinsPL[0]
 | 
			
		||||
	PL1 = &cpuPinsPL[1]
 | 
			
		||||
	PL2 = &cpuPinsPL[2]
 | 
			
		||||
	PL3 = &cpuPinsPL[3]
 | 
			
		||||
	PL4 = &cpuPinsPL[4]
 | 
			
		||||
	PL5 = &cpuPinsPL[5]
 | 
			
		||||
	PL6 = &cpuPinsPL[6]
 | 
			
		||||
	PL7 = &cpuPinsPL[7]
 | 
			
		||||
	PL8 = &cpuPinsPL[8]
 | 
			
		||||
	PL9 = &cpuPinsPL[9]
 | 
			
		||||
	PL10 = &cpuPinsPL[10]
 | 
			
		||||
	PL11 = &cpuPinsPL[11]
 | 
			
		||||
	PL12 = &cpuPinsPL[12]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getBaseAddressPL queries the virtual file system to retrieve the base address
 | 
			
		||||
// of the GPIO registers for GPIO pins in group PL.
 | 
			
		||||
//
 | 
			
		||||
// Defaults to 0x01F02C00 as per datasheet if could query the file system.
 | 
			
		||||
func getBaseAddressPL() uint64 {
 | 
			
		||||
	base := uint64(0x01F02C00)
 | 
			
		||||
	link, err := os.Readlink("/sys/bus/platform/drivers/sun50i-r-pinctrl/driver")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return base
 | 
			
		||||
	}
 | 
			
		||||
	parts := strings.SplitN(path.Base(link), ".", 2)
 | 
			
		||||
	if len(parts) != 2 {
 | 
			
		||||
		return base
 | 
			
		||||
	}
 | 
			
		||||
	base2, err := strconv.ParseUint(parts[0], 16, 64)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return base
 | 
			
		||||
	}
 | 
			
		||||
	return base2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// driverGPIOPL implements periph.Driver.
 | 
			
		||||
type driverGPIOPL struct {
 | 
			
		||||
	// gpioMemoryPL is only the PL group in that case. Note that groups PI, PJ, PK
 | 
			
		||||
	// do not exist.
 | 
			
		||||
	gpioMemoryPL *gpioGroup
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverGPIOPL) String() string {
 | 
			
		||||
	return "allwinner-gpio-pl"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverGPIOPL) Prerequisites() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverGPIOPL) After() []string {
 | 
			
		||||
	return []string{"sysfs-gpio"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driverGPIOPL) Init() (bool, error) {
 | 
			
		||||
	// BUG(maruel): H3 supports group PL too.
 | 
			
		||||
	if !IsA64() {
 | 
			
		||||
		return false, errors.New("A64 CPU not detected")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Mark the right pins as available even if the memory map fails so they can
 | 
			
		||||
	// callback to sysfs.Pins.
 | 
			
		||||
	functions := map[pin.Func]struct{}{}
 | 
			
		||||
	for i := range cpuPinsPL {
 | 
			
		||||
		name := cpuPinsPL[i].Name()
 | 
			
		||||
		num := strconv.Itoa(cpuPinsPL[i].Number())
 | 
			
		||||
		cpuPinsPL[i].available = true
 | 
			
		||||
		gpion := "GPIO" + num
 | 
			
		||||
 | 
			
		||||
		// Unregister the pin if already registered. This happens with sysfs-gpio.
 | 
			
		||||
		// Do not error on it, since sysfs-gpio may have failed to load.
 | 
			
		||||
		_ = gpioreg.Unregister(gpion)
 | 
			
		||||
		_ = gpioreg.Unregister(num)
 | 
			
		||||
 | 
			
		||||
		// Register the pin with gpio.
 | 
			
		||||
		if err := gpioreg.Register(&cpuPinsPL[i]); err != nil {
 | 
			
		||||
			return true, err
 | 
			
		||||
		}
 | 
			
		||||
		if err := gpioreg.RegisterAlias(gpion, name); err != nil {
 | 
			
		||||
			return true, err
 | 
			
		||||
		}
 | 
			
		||||
		if err := gpioreg.RegisterAlias(num, name); err != nil {
 | 
			
		||||
			return true, err
 | 
			
		||||
		}
 | 
			
		||||
		switch f := cpuPinsPL[i].Func(); f {
 | 
			
		||||
		case gpio.IN, gpio.OUT, pin.FuncNone:
 | 
			
		||||
		default:
 | 
			
		||||
			// Registering the same alias twice fails. This can happen if two pins
 | 
			
		||||
			// are configured with the same function.
 | 
			
		||||
			if _, ok := functions[f]; !ok {
 | 
			
		||||
				// TODO(maruel): We'd have to clear out the ones from allwinner-gpio
 | 
			
		||||
				// too.
 | 
			
		||||
				functions[f] = struct{}{}
 | 
			
		||||
				_ = gpioreg.RegisterAlias(string(f), name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Now do a second loop but do the alternate functions.
 | 
			
		||||
	for i := range cpuPinsPL {
 | 
			
		||||
		for _, f := range cpuPinsPL[i].SupportedFuncs() {
 | 
			
		||||
			switch f {
 | 
			
		||||
			case gpio.IN, gpio.OUT:
 | 
			
		||||
			default:
 | 
			
		||||
				if _, ok := functions[f]; !ok {
 | 
			
		||||
					// TODO(maruel): We'd have to clear out the ones from allwinner-gpio
 | 
			
		||||
					// too.
 | 
			
		||||
					functions[f] = struct{}{}
 | 
			
		||||
					_ = gpioreg.RegisterAlias(string(f), cpuPinsPL[i].name)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m, err := pmem.Map(getBaseAddressPL(), 4096)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if os.IsPermission(err) {
 | 
			
		||||
			return true, fmt.Errorf("need more access, try as root: %v", err)
 | 
			
		||||
		}
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
	if err := m.AsPOD(&d.gpioMemoryPL); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		periph.MustRegister(&drvGPIOPL)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drvGPIOPL driverGPIOPL
 | 
			
		||||
 | 
			
		||||
var _ gpio.PinIO = &PinPL{}
 | 
			
		||||
var _ gpio.PinIn = &PinPL{}
 | 
			
		||||
var _ gpio.PinOut = &PinPL{}
 | 
			
		||||
var _ pin.PinFunc = &PinPL{}
 | 
			
		||||
							
								
								
									
										197
									
								
								vendor/periph.io/x/periph/host/allwinner/pwm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								vendor/periph.io/x/periph/host/allwinner/pwm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
// 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 allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const pwmClock = 24000000
 | 
			
		||||
const pwmMaxPeriod = 0x10000
 | 
			
		||||
 | 
			
		||||
// prescalers is the value for pwm0Prescale*
 | 
			
		||||
var prescalers = []struct {
 | 
			
		||||
	freq   uint32
 | 
			
		||||
	scaler pwmPrescale
 | 
			
		||||
}{
 | 
			
		||||
	// Base frequency (min freq is half that) / PWM clock at pwmMaxPeriod
 | 
			
		||||
	{pwmClock, pwmPrescale1},             //  24MHz / 366Hz
 | 
			
		||||
	{pwmClock / 120, pwmPrescale120},     // 200kHz / 3Hz
 | 
			
		||||
	{pwmClock / 180, pwmPrescale180},     // 133kHz / 2Hz
 | 
			
		||||
	{pwmClock / 240, pwmPrescale240},     // 100kHz / 1.5Hz
 | 
			
		||||
	{pwmClock / 360, pwmPrescale360},     //  66kHz / 1.01Hz
 | 
			
		||||
	{pwmClock / 480, pwmPrescale480},     //  50kHz / 0.7Hz
 | 
			
		||||
	{pwmClock / 12000, pwmPrescale12000}, //   2kHz
 | 
			
		||||
	{pwmClock / 24000, pwmPrescale24000}, //   1kHz
 | 
			
		||||
	{pwmClock / 36000, pwmPrescale36000}, // 666 Hz
 | 
			
		||||
	{pwmClock / 48000, pwmPrescale48000}, // 500 Hz
 | 
			
		||||
	{pwmClock / 72000, pwmPrescale72000}, // 333 Hz / 0.005Hz
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:29 reserved
 | 
			
		||||
	pwmBusy pwmCtl = 1 << 28 // PWM0_RDY
 | 
			
		||||
	// 27:10 reserved (used for pwm1)
 | 
			
		||||
	pwm0Mask       pwmCtl = (1 << 10) - 1
 | 
			
		||||
	pwm0Bypass     pwmCtl = 1 << 9 // PWM0_BYPASS (marked as unused on some drivers?)
 | 
			
		||||
	pwm0PulseStart pwmCtl = 1 << 8 // PWM_CH0_PUL_START
 | 
			
		||||
	pwm0ModePulse  pwmCtl = 1 << 7 // PWM_CHANNEL0_MODE
 | 
			
		||||
	pwm0SCLK       pwmCtl = 1 << 6 // SCLK_CH0_GATING
 | 
			
		||||
	pwm0Polarity   pwmCtl = 1 << 5 // PWM_CH0_ACT_STA
 | 
			
		||||
	pwm0Enable     pwmCtl = 1 << 4 // PWM_CH0_EN
 | 
			
		||||
	// 3:0
 | 
			
		||||
	pwm0PrescaleMask pwmCtl = pwmCtl(pwmPrescaleMask) // PWM_CH0_PRESCAL
 | 
			
		||||
	pwm0Prescale120  pwmCtl = pwmCtl(pwmPrescale120)
 | 
			
		||||
	pwm0Prescale180  pwmCtl = pwmCtl(pwmPrescale180)
 | 
			
		||||
	pwm0Prescale240  pwmCtl = pwmCtl(pwmPrescale240)
 | 
			
		||||
	pwm0Prescale360  pwmCtl = pwmCtl(pwmPrescale360)
 | 
			
		||||
	pwm0Prescale480  pwmCtl = pwmCtl(pwmPrescale480)
 | 
			
		||||
	// 5, 6, 7 reserved
 | 
			
		||||
	pwm0Prescale12000 pwmCtl = pwmCtl(pwmPrescale12000)
 | 
			
		||||
	pwm0Prescale24000 pwmCtl = pwmCtl(pwmPrescale24000)
 | 
			
		||||
	pwm0Prescale36000 pwmCtl = pwmCtl(pwmPrescale36000)
 | 
			
		||||
	pwm0Prescale48000 pwmCtl = pwmCtl(pwmPrescale48000)
 | 
			
		||||
	pwm0Prescale72000 pwmCtl = pwmCtl(pwmPrescale72000)
 | 
			
		||||
	// 13, 14 reserved
 | 
			
		||||
	pwm0Prescale1 pwmCtl = pwmCtl(pwmPrescale1)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A64: Pages 194-195.
 | 
			
		||||
// R8: Pages 83-84.
 | 
			
		||||
type pwmCtl uint32
 | 
			
		||||
 | 
			
		||||
func (p pwmCtl) String() string {
 | 
			
		||||
	var out []string
 | 
			
		||||
	if p&pwmBusy != 0 {
 | 
			
		||||
		out = append(out, "PWM0_RDY")
 | 
			
		||||
		p &^= pwmBusy
 | 
			
		||||
	}
 | 
			
		||||
	if p&pwm0Bypass != 0 {
 | 
			
		||||
		out = append(out, "PWM0_BYPASS")
 | 
			
		||||
		p &^= pwm0Bypass
 | 
			
		||||
	}
 | 
			
		||||
	if p&pwm0PulseStart != 0 {
 | 
			
		||||
		out = append(out, "PWM0_CH0_PUL_START")
 | 
			
		||||
		p &^= pwm0PulseStart
 | 
			
		||||
	}
 | 
			
		||||
	if p&pwm0ModePulse != 0 {
 | 
			
		||||
		out = append(out, "PWM0_CHANNEL0_MODE")
 | 
			
		||||
		p &^= pwm0ModePulse
 | 
			
		||||
	}
 | 
			
		||||
	if p&pwm0SCLK != 0 {
 | 
			
		||||
		out = append(out, "SCLK_CH0_GATING")
 | 
			
		||||
		p &^= pwm0SCLK
 | 
			
		||||
	}
 | 
			
		||||
	if p&pwm0Polarity != 0 {
 | 
			
		||||
		out = append(out, "PWM_CH0_ACT_STA")
 | 
			
		||||
		p &^= pwm0Polarity
 | 
			
		||||
	}
 | 
			
		||||
	if p&pwm0Enable != 0 {
 | 
			
		||||
		out = append(out, "PWM_CH0_EN")
 | 
			
		||||
		p &^= pwm0Enable
 | 
			
		||||
	}
 | 
			
		||||
	out = append(out, pwmPrescale(p&pwm0PrescaleMask).String())
 | 
			
		||||
	p &^= pwm0PrescaleMask
 | 
			
		||||
	if p != 0 {
 | 
			
		||||
		out = append(out, fmt.Sprintf("Unknown(0x%08X)", uint32(p)))
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(out, "|")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	pwmPrescaleMask pwmPrescale = 0xF
 | 
			
		||||
	pwmPrescale120  pwmPrescale = 0
 | 
			
		||||
	pwmPrescale180  pwmPrescale = 1
 | 
			
		||||
	pwmPrescale240  pwmPrescale = 2
 | 
			
		||||
	pwmPrescale360  pwmPrescale = 3
 | 
			
		||||
	pwmPrescale480  pwmPrescale = 4
 | 
			
		||||
	// 5, 6, 7 reserved
 | 
			
		||||
	pwmPrescale12000 pwmPrescale = 8
 | 
			
		||||
	pwmPrescale24000 pwmPrescale = 9
 | 
			
		||||
	pwmPrescale36000 pwmPrescale = 10
 | 
			
		||||
	pwmPrescale48000 pwmPrescale = 11
 | 
			
		||||
	pwmPrescale72000 pwmPrescale = 12
 | 
			
		||||
	// 13, 14 reserved
 | 
			
		||||
	pwmPrescale1 pwmPrescale = 15
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pwmPrescale uint32
 | 
			
		||||
 | 
			
		||||
func (p pwmPrescale) String() string {
 | 
			
		||||
	switch p {
 | 
			
		||||
	case pwmPrescale120:
 | 
			
		||||
		return "/120"
 | 
			
		||||
	case pwmPrescale180:
 | 
			
		||||
		return "/180"
 | 
			
		||||
	case pwmPrescale240:
 | 
			
		||||
		return "/240"
 | 
			
		||||
	case pwmPrescale360:
 | 
			
		||||
		return "/360"
 | 
			
		||||
	case pwmPrescale480:
 | 
			
		||||
		return "/480"
 | 
			
		||||
	case pwmPrescale12000:
 | 
			
		||||
		return "/12k"
 | 
			
		||||
	case pwmPrescale24000:
 | 
			
		||||
		return "/24k"
 | 
			
		||||
	case pwmPrescale36000:
 | 
			
		||||
		return "/36k"
 | 
			
		||||
	case pwmPrescale48000:
 | 
			
		||||
		return "/48k"
 | 
			
		||||
	case pwmPrescale72000:
 | 
			
		||||
		return "/72k"
 | 
			
		||||
	case pwmPrescale1:
 | 
			
		||||
		return "/1"
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Sprintf("InvalidScalar(%d)", p&pwmPrescaleMask)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A64: Page 195.
 | 
			
		||||
// R8: Page 84
 | 
			
		||||
type pwmPeriod uint32
 | 
			
		||||
 | 
			
		||||
func (p pwmPeriod) String() string {
 | 
			
		||||
	return fmt.Sprintf("%d/%d", p&0xFFFF, uint32((p>>16)&0xFFFF)+1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func toPeriod(total uint32, active uint16) pwmPeriod {
 | 
			
		||||
	if total > pwmMaxPeriod {
 | 
			
		||||
		total = pwmMaxPeriod
 | 
			
		||||
	}
 | 
			
		||||
	return pwmPeriod(total-1)<<16 | pwmPeriod(active)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// getBestPrescale finds the best prescaler.
 | 
			
		||||
//
 | 
			
		||||
// Cycles must be between 2 and 0x10000/2.
 | 
			
		||||
func getBestPrescale(period time.Duration) pwmPrescale {
 | 
			
		||||
	// TODO(maruel): Rewrite this function, it is incorrect.
 | 
			
		||||
	for _, v := range prescalers {
 | 
			
		||||
		p := time.Second / time.Duration(v.freq)
 | 
			
		||||
		smallest := (period / pwmMaxPeriod)
 | 
			
		||||
		largest := (period / 2)
 | 
			
		||||
		if p > smallest && p < largest {
 | 
			
		||||
			return v.scaler
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// Period is longer than 196s.
 | 
			
		||||
	return pwmPrescale72000
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// pwmMap represents the PWM memory mapped CPU registers.
 | 
			
		||||
//
 | 
			
		||||
// The base frequency is 24Mhz.
 | 
			
		||||
//
 | 
			
		||||
// TODO(maruel): Some CPU have 2 PWMs.
 | 
			
		||||
type pwmMap struct {
 | 
			
		||||
	ctl    pwmCtl    // PWM_CTRL_REG
 | 
			
		||||
	period pwmPeriod // PWM_CH0_PERIOD
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *pwmMap) String() string {
 | 
			
		||||
	return fmt.Sprintf("pwmMap{%s, %v}", p.ctl, p.period)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										149
									
								
								vendor/periph.io/x/periph/host/allwinner/r8.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								vendor/periph.io/x/periph/host/allwinner/r8.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,149 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// This file contains pin mapping information that is specific to the Allwinner
 | 
			
		||||
// R8 model.
 | 
			
		||||
 | 
			
		||||
package allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// R8 specific pins.
 | 
			
		||||
var (
 | 
			
		||||
	FEL            *pin.BasicPin // Boot mode selection
 | 
			
		||||
	MIC_IN         *pin.BasicPin // Microphone in
 | 
			
		||||
	MIC_GND        *pin.BasicPin // Microphone ground
 | 
			
		||||
	HP_LEFT        *pin.BasicPin // Left speaker out
 | 
			
		||||
	HP_RIGHT       *pin.BasicPin // Right speaker out
 | 
			
		||||
	HP_COM         *pin.BasicPin // Speaker common
 | 
			
		||||
	X1, X2, Y1, Y2 *pin.BasicPin // Touch screen pins
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	FEL = &pin.BasicPin{N: "FEL"}
 | 
			
		||||
	MIC_IN = &pin.BasicPin{N: "MIC_IN"}
 | 
			
		||||
	MIC_GND = &pin.BasicPin{N: "MIC_GND"}
 | 
			
		||||
	HP_LEFT = &pin.BasicPin{N: "HP_LEFT"}
 | 
			
		||||
	HP_RIGHT = &pin.BasicPin{N: "HP_RIGHT"}
 | 
			
		||||
	HP_COM = &pin.BasicPin{N: "HP_COM"}
 | 
			
		||||
 | 
			
		||||
	X1 = &pin.BasicPin{N: "X1"}
 | 
			
		||||
	X2 = &pin.BasicPin{N: "X2"}
 | 
			
		||||
	Y1 = &pin.BasicPin{N: "Y1"}
 | 
			
		||||
	Y2 = &pin.BasicPin{N: "Y2"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mappingR8 describes the mapping of each R8 processor gpio to their alternate
 | 
			
		||||
// functions.
 | 
			
		||||
//
 | 
			
		||||
// It omits the in & out functions which are available on all pins.
 | 
			
		||||
//
 | 
			
		||||
// The mapping comes from the datasheet page 18:
 | 
			
		||||
// https://github.com/NextThingCo/CHIP-Hardware/raw/master/CHIP%5Bv1_0%5D/CHIPv1_0-BOM-Datasheets/Allwinner%20R8%20Datasheet%20V1.2.pdf
 | 
			
		||||
//
 | 
			
		||||
// - The datasheet uses TWI instead of I2C but this is renamed here for consistency.
 | 
			
		||||
var mappingR8 = map[string][5]pin.Func{
 | 
			
		||||
	"PB0":  {"I2C0_SCL"},
 | 
			
		||||
	"PB1":  {"I2C0_SDA"},
 | 
			
		||||
	"PB2":  {"PWM0", "", "", "", "EINT16"},
 | 
			
		||||
	"PB3":  {"IR_TX", "", "", "", "EINT17"},
 | 
			
		||||
	"PB4":  {"IR_RX", "", "", "", "EINT18"},
 | 
			
		||||
	"PB10": {"SPI2_CS1"},
 | 
			
		||||
	"PB15": {"I2C1_SCL"},
 | 
			
		||||
	"PB16": {"I2C1_SDA"},
 | 
			
		||||
	"PB17": {"I2C2_SCL"},
 | 
			
		||||
	"PB18": {"I2C2_SDA"},
 | 
			
		||||
	"PC0":  {"NAND_WE", "SPI0_MOSI"},
 | 
			
		||||
	"PC1":  {"NAND_ALE", "SPI0_MISO"},
 | 
			
		||||
	"PC2":  {"NAND_CLE", "SPI0_CLK"},
 | 
			
		||||
	"PC3":  {"NAND_CE1", "SPI0_CS0"},
 | 
			
		||||
	"PC4":  {"NAND_CE0"},
 | 
			
		||||
	"PC5":  {"NAND_RE"},
 | 
			
		||||
	"PC6":  {"NAND_RB0", "SDC2_CMD"},
 | 
			
		||||
	"PC7":  {"NAND_RB1", "SDC2_CLK"},
 | 
			
		||||
	"PC8":  {"NAND_DQ0", "SDC2_D0"},
 | 
			
		||||
	"PC9":  {"NAND_DQ1", "SDC2_D1"},
 | 
			
		||||
	"PC10": {"NAND_DQ2", "SDC2_D2"},
 | 
			
		||||
	"PC11": {"NAND_DQ3", "SDC2_D3"},
 | 
			
		||||
	"PC12": {"NAND_DQ4", "SDC2_D4"},
 | 
			
		||||
	"PC13": {"NAND_DQ5", "SDC2_D5"},
 | 
			
		||||
	"PC14": {"NAND_DQ6", "SDC2_D6"},
 | 
			
		||||
	"PC15": {"NAND_DQ7", "SDC2_D7"},
 | 
			
		||||
	"PC19": {""},
 | 
			
		||||
	"PD2":  {"LCD_D2", "UART2_TX"},
 | 
			
		||||
	"PD3":  {"LCD_D3", "UART2_RX"},
 | 
			
		||||
	"PD4":  {"LCD_D4", "UART2_CTX"},
 | 
			
		||||
	"PD5":  {"LCD_D5", "UART2_RTS"},
 | 
			
		||||
	"PD6":  {"LCD_D6", "ECRS"},
 | 
			
		||||
	"PD7":  {"LCD_D7", "ECOL"},
 | 
			
		||||
	"PD10": {"LCD_D10", "ERXD0"},
 | 
			
		||||
	"PD11": {"LCD_D11", "ERXD1"},
 | 
			
		||||
	"PD12": {"LCD_D12", "ERXD2"},
 | 
			
		||||
	"PD13": {"LCD_D13", "ERXD3"},
 | 
			
		||||
	"PD14": {"LCD_D14", "ERXCK"},
 | 
			
		||||
	"PD15": {"LCD_D15", "ERXERR"},
 | 
			
		||||
	"PD18": {"LCD_D18", "ERXDV"},
 | 
			
		||||
	"PD19": {"LCD_D19", "ETXD0"},
 | 
			
		||||
	"PD20": {"LCD_D20", "ETXD1"},
 | 
			
		||||
	"PD21": {"LCD_D21", "ETXD2"},
 | 
			
		||||
	"PD22": {"LCD_D22", "ETXD3"},
 | 
			
		||||
	"PD23": {"LCD_D23", "ETXEN"},
 | 
			
		||||
	"PD24": {"LCD_CLK", "ETXCK"},
 | 
			
		||||
	"PD25": {"LCD_DE", "ETXERR"},
 | 
			
		||||
	"PD26": {"LCD_HSYNC", "EMDC"},
 | 
			
		||||
	"PD27": {"LCD_VSYNC", "EMDIO"},
 | 
			
		||||
	"PE0":  {"TS_CLK", "CSI_PCLK", "SPI2_CS0", "", "EINT14"},
 | 
			
		||||
	"PE1":  {"TS_ERR", "CSI_MCLK", "SPI2_CLK", "", "EINT15"},
 | 
			
		||||
	"PE2":  {"TS_SYNC", "CSI_HSYNC", "SPI2_MOSI"},
 | 
			
		||||
	"PE3":  {"TS_DVLD", "CSI_VSYNC", "SPI2_MISO"},
 | 
			
		||||
	"PE4":  {"TS_D0", "CSI_D0", "SDC2_D0"},
 | 
			
		||||
	"PE5":  {"TS_D1", "CSI_D1", "SDC2_D1"},
 | 
			
		||||
	"PE6":  {"TS_D2", "CSI_D2", "SDC2_D2"},
 | 
			
		||||
	"PE7":  {"TS_D3", "CSI_D3", "SDC2_D3"},
 | 
			
		||||
	"PE8":  {"TS_D4", "CSI_D4", "SDC2_CMD"},
 | 
			
		||||
	"PE9":  {"TS_D5", "CSI_D5", "SDC2_CLK"},
 | 
			
		||||
	"PE10": {"TS_D6", "CSI_D6", "UART1_TX"},
 | 
			
		||||
	"PE11": {"TS_D7", "CSI_D7", "UART1_RX"},
 | 
			
		||||
	"PF0":  {"SDC0_D1", "", "JTAG1_TMS"},
 | 
			
		||||
	"PF1":  {"SDC0_D0", "", "JTAG1_TDI"},
 | 
			
		||||
	"PF2":  {"SDC0_CLK", "", "UART0_TX"},
 | 
			
		||||
	"PF3":  {"SDC0_CMD", "", "JTAG1_TDO"},
 | 
			
		||||
	"PF4":  {"SDC0_D3", "", "UART0_RX"},
 | 
			
		||||
	"PF5":  {"SDC0_D2", "", "JTAG1_TCK"},
 | 
			
		||||
	"PG0":  {"GPS_CLK", "", "", "", "EINT0"},
 | 
			
		||||
	"PG1":  {"GPS_SIGN", "", "", "", "EINT1"},
 | 
			
		||||
	"PG2":  {"GPS_MAG", "", "", "", "EINT2"},
 | 
			
		||||
	"PG3":  {"", "", "UART1_TX", "", "EINT3"},
 | 
			
		||||
	"PG4":  {"", "", "UART1_RX", "", "EINT4"},
 | 
			
		||||
	"PG9":  {"SPI1_CS0", "UART3_TX", "", "", "EINT9"},
 | 
			
		||||
	"PG10": {"SPI1_CLK", "UART3_RX", "", "", "EINT10"},
 | 
			
		||||
	"PG11": {"SPI1_MOSI", "UART3_CTS", "", "", "EINT11"},
 | 
			
		||||
	"PG12": {"SPI1_MISO", "UART3_RTS", "", "", "EINT12"},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mapR8Pins uses mappingR8 to actually set the altFunc fields of all gpio and
 | 
			
		||||
// mark them as available.
 | 
			
		||||
//
 | 
			
		||||
// It is called by the generic allwinner processor code if a R8 is detected.
 | 
			
		||||
func mapR8Pins() error {
 | 
			
		||||
	for name, altFuncs := range mappingR8 {
 | 
			
		||||
		pin := cpupins[name]
 | 
			
		||||
		pin.altFunc = altFuncs
 | 
			
		||||
		pin.available = true
 | 
			
		||||
		if strings.Contains(string(altFuncs[4]), "EINT") {
 | 
			
		||||
			pin.supportEdge = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Initializes the sysfs corresponding pin right away.
 | 
			
		||||
		pin.sysfsPin = sysfs.Pins[pin.Number()]
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										207
									
								
								vendor/periph.io/x/periph/host/allwinner/spi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								vendor/periph.io/x/periph/host/allwinner/spi.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
			
		||||
// 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 allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:20 reserved
 | 
			
		||||
	// Set this bit to ‘1’ to make the internal read sample point with a delay of
 | 
			
		||||
	// half cycle of SPI_CLK. It is used in high speed read operation to reduce
 | 
			
		||||
	// the error caused by the time delay of SPI_CLK propagating between master
 | 
			
		||||
	// and slave.
 | 
			
		||||
	// 1 – delay internal read sample point
 | 
			
		||||
	// 0 – normal operation, do not delay internal read sample point
 | 
			
		||||
	spiR8HalfDelay       spiR8Ctl = 1 << 19 // Master Sample Data Control
 | 
			
		||||
	spiR8TransmitPause   spiR8Ctl = 1 << 18 // Transmit Pause Enable
 | 
			
		||||
	spiR8CSLevel         spiR8Ctl = 1 << 17 // SS_LEVEL; Chip Select level
 | 
			
		||||
	spiR8CSManual        spiR8Ctl = 1 << 16 // SS_CTRL; Do not switch CS automatically
 | 
			
		||||
	spiR8DiscardHash     spiR8Ctl = 1 << 15 // DHB
 | 
			
		||||
	spiR8DummyBurst      spiR8Ctl = 1 << 14 // DDB
 | 
			
		||||
	spiR8CS0             spiR8Ctl = 0 << 12 // SS; Which CS line to use. For SPI0 only
 | 
			
		||||
	spiR8CS1             spiR8Ctl = 1 << 12 //
 | 
			
		||||
	spiR8CS2             spiR8Ctl = 2 << 12 //
 | 
			
		||||
	spiR8CS3             spiR8Ctl = 3 << 12 //
 | 
			
		||||
	spiR8RapidsReadMode  spiR8Ctl = 1 << 11 // RPSM
 | 
			
		||||
	spiR8ExchangeBurst   spiR8Ctl = 1 << 10 // XCH
 | 
			
		||||
	spiR8RXFIFOReset     spiR8Ctl = 1 << 9  // RXFIFO Reset; Write to reset the FIFO as empty
 | 
			
		||||
	spiR8TXFIFOReset     spiR8Ctl = 1 << 8  // TXFIFO Reset; Write to reset the FIFO as empty
 | 
			
		||||
	spiR8CSBetweenBursts spiR8Ctl = 1 << 7  // SSCTL
 | 
			
		||||
	spiR8LSB             spiR8Ctl = 1 << 6  // LMTF; MSB by default, LSB when set
 | 
			
		||||
	spiR8DDMA            spiR8Ctl = 1 << 5  // DMAM; Use dedicated DMA if set, normal DMA otherwise
 | 
			
		||||
	spiR8CSActiveLow     spiR8Ctl = 1 << 4  // SSPOL; CS line polarity
 | 
			
		||||
	spiR8ClkActiveLow    spiR8Ctl = 1 << 3  // POL; Clock line polarity
 | 
			
		||||
	spiR8PHA             spiR8Ctl = 1 << 2  // PHA; Phase 1 if set (leading edge for setup data)
 | 
			
		||||
	spiR8Master          spiR8Ctl = 1 << 1  // MODE; Slave mode if not set
 | 
			
		||||
	spiR8Enable          spiR8Ctl = 1 << 0  // EN; Enable mode
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SPI_CTL
 | 
			
		||||
// R8: Page 153-155.  Default: 0x0002001C
 | 
			
		||||
type spiR8Ctl uint32
 | 
			
		||||
 | 
			
		||||
// SPI_INTCTL
 | 
			
		||||
// R8: Page 155-156.
 | 
			
		||||
type spiR8IntCtl uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	spiR8ClearInterrupt spiR8IntStatus = 1 << 31 // Clear interrupt busy flag
 | 
			
		||||
	// 30:18 reserved
 | 
			
		||||
	spiR8InvalidSS spiR8IntStatus = 1 << 17 // SSI
 | 
			
		||||
	spiR8TC        spiR8IntStatus = 1 << 16 // TC; Transfer Completed
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SPI_INT_STA
 | 
			
		||||
// R8: Page 156-157.
 | 
			
		||||
type spiR8IntStatus uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:13 reserved
 | 
			
		||||
	spiR8DMATX3Quarter spiR8DMACtl = 1 << 12 // TXFIFO 3/4 empty
 | 
			
		||||
	spiR8DMATX1Quarter spiR8DMACtl = 1 << 11 // TXFIFO 1/4 empty
 | 
			
		||||
	spiR8DMATXByte     spiR8DMACtl = 1 << 10 // TXFIFO Not Full
 | 
			
		||||
	spiR8DMATXHalf     spiR8DMACtl = 1 << 9  // TXFIFO 1/2 empty
 | 
			
		||||
	spiR8DMATXEmpty    spiR8DMACtl = 1 << 8  // TXFIFO empty
 | 
			
		||||
	// 7:5 reserved
 | 
			
		||||
	spiR8DMARX3Quarter spiR8DMACtl = 1 << 4 // RXFIFO 3/4 empty
 | 
			
		||||
	spiR8DMARX1Quarter spiR8DMACtl = 1 << 3 // RXFIFO 1/4 empty
 | 
			
		||||
	spiR8DMARXByte     spiR8DMACtl = 1 << 2 // RXFIFO Not Full
 | 
			
		||||
	spiR8DMARXHalf     spiR8DMACtl = 1 << 1 // RXFIFO 1/2 empty
 | 
			
		||||
	spiR8DMARXEmpty    spiR8DMACtl = 1 << 0 // RXFIFO empty
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SPI_DMACTL
 | 
			
		||||
// R8: Page 158.
 | 
			
		||||
type spiR8DMACtl uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:13 reserved
 | 
			
		||||
	spiR8DivRateSelect2 spiR8ClockCtl = 1 << 12 // DRS; Use spiDivXX if set, use mask otherwise
 | 
			
		||||
	spiR8Div2           spiR8ClockCtl = 0 << 8  // CDR1; Use divisor 2^(n+1)
 | 
			
		||||
	spiR8Div4           spiR8ClockCtl = 1 << 8  //
 | 
			
		||||
	spiR8Div8           spiR8ClockCtl = 2 << 8  //
 | 
			
		||||
	spiR8Div16          spiR8ClockCtl = 3 << 8  //
 | 
			
		||||
	spiR8Div32          spiR8ClockCtl = 4 << 8  //
 | 
			
		||||
	spiR8Div64          spiR8ClockCtl = 5 << 8  //
 | 
			
		||||
	spiR8Div128         spiR8ClockCtl = 6 << 8  //
 | 
			
		||||
	spiR8Div256         spiR8ClockCtl = 7 << 8  //
 | 
			
		||||
	spiR8Div512         spiR8ClockCtl = 8 << 8  //
 | 
			
		||||
	spiR8Div1024        spiR8ClockCtl = 9 << 8  //
 | 
			
		||||
	spiR8Div2048        spiR8ClockCtl = 10 << 8 //
 | 
			
		||||
	spiR8Div4096        spiR8ClockCtl = 11 << 8 //
 | 
			
		||||
	spiR8Div8192        spiR8ClockCtl = 12 << 8 //
 | 
			
		||||
	spiR8Div16384       spiR8ClockCtl = 13 << 8 //
 | 
			
		||||
	spiR8Div32768       spiR8ClockCtl = 14 << 8 //
 | 
			
		||||
	spiR8Div65536       spiR8ClockCtl = 15 << 8 //
 | 
			
		||||
	spiR8Div1Mask       spiR8ClockCtl = 0xFF    // CDR2; Use divisor 2*(n+1)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SPI_CCTL
 | 
			
		||||
// R8: Page 159.
 | 
			
		||||
type spiR8ClockCtl uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:25 reserved
 | 
			
		||||
	spiR8FIFOTXShift = 16 // 0 to 64
 | 
			
		||||
	// 15:7 reserved
 | 
			
		||||
	spiR8FIFORXShift = 0 // 0 to 64
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// SPI_FIFO_STA
 | 
			
		||||
// R8: Page 160.
 | 
			
		||||
type spiR8FIFOStatus uint32
 | 
			
		||||
 | 
			
		||||
func (s spiR8FIFOStatus) tx() uint8 {
 | 
			
		||||
	return uint8((uint32(s) >> 16) & 127)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s spiR8FIFOStatus) rx() uint8 {
 | 
			
		||||
	return uint8(uint32(s) & 127)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// spiR8Group is the mapping of SPI registers for one SPI controller.
 | 
			
		||||
// R8: Page 152-153.
 | 
			
		||||
type spiR8Group struct {
 | 
			
		||||
	rx              uint32          // 0x00 SPI_RX_DATA RX Data
 | 
			
		||||
	tx              uint32          // 0x04 SPI_TX_DATA TX Data
 | 
			
		||||
	ctl             spiR8Ctl        // 0x08 SPI_CTL Control
 | 
			
		||||
	intCtl          spiR8IntCtl     // 0x0C SPI_INTCTL Interrupt Control
 | 
			
		||||
	status          spiR8IntStatus  // 0x10 SPI_ST Status
 | 
			
		||||
	dmaCtl          spiR8DMACtl     // 0x14 SPI_DMACTL DMA Control
 | 
			
		||||
	wait            uint32          // 0x18 SPI_WAIT Clock Counter; 16 bits
 | 
			
		||||
	clockCtl        spiR8ClockCtl   // 0x1C SPI_CCTL Clock Rate Control
 | 
			
		||||
	burstCounter    uint32          // 0x20 SPI_BC Burst Counter; 24 bits
 | 
			
		||||
	transmitCounter uint32          // 0x24 SPI_TC Transmit Counter; 24 bits
 | 
			
		||||
	fifoStatus      spiR8FIFOStatus // 0x28 SPI_FIFO_STA FIFO Status
 | 
			
		||||
	reserved        [(0x1000 - 0x02C) / 4]uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *spiR8Group) setup() {
 | 
			
		||||
	s.intCtl = 0
 | 
			
		||||
	s.status = 0
 | 
			
		||||
	//s.dmaCtl = spiR8DMARXByte
 | 
			
		||||
	s.dmaCtl = 0
 | 
			
		||||
	s.wait = 2
 | 
			
		||||
	s.clockCtl = spiR8DivRateSelect2 | spiR8Div1024
 | 
			
		||||
	// spiR8DDMA
 | 
			
		||||
	s.ctl = spiR8CSManual | spiR8LSB | spiR8Master | spiR8Enable
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// spiMap is the mapping of SPI registers.
 | 
			
		||||
// R8: Page 152-153.
 | 
			
		||||
type spiMap struct {
 | 
			
		||||
	groups [3]spiR8Group
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// spi2Write do a write on SPI2_MOSI via polling.
 | 
			
		||||
func spi2Write(w []byte) error {
 | 
			
		||||
	if drvDMA.clockMemory == nil || drvDMA.spiMemory == nil {
 | 
			
		||||
		return errors.New("subsystem not initialized")
 | 
			
		||||
	}
 | 
			
		||||
	// Make sure the source clock is disabled. Set it at 250kHz.
 | 
			
		||||
	//drvDMA.clockMemory.spi2Clk &^= clockSPIEnable
 | 
			
		||||
	drvDMA.clockMemory.spi2Clk |= clockSPIEnable
 | 
			
		||||
	drvDMA.clockMemory.spi2Clk = clockSPIDiv8a | clockSPIDiv12b
 | 
			
		||||
	ch := &drvDMA.spiMemory.groups[2]
 | 
			
		||||
	ch.setup()
 | 
			
		||||
	fmt.Printf("Setup done\n")
 | 
			
		||||
	for i := 0; i < len(w)/4; i++ {
 | 
			
		||||
		// TODO(maruel): Access it in 8bit mode.
 | 
			
		||||
		ch.tx = uint32(w[0])
 | 
			
		||||
		for ch.fifoStatus.tx() == 0 {
 | 
			
		||||
			log.Printf("Waiting for bit %# v\n", ch)
 | 
			
		||||
			time.Sleep(time.Second)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Printf("Done\n")
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// spi2Read do a read on SPI2_MISO via polling.
 | 
			
		||||
func spi2Read(r []byte) error {
 | 
			
		||||
	if drvDMA.clockMemory == nil || drvDMA.spiMemory == nil {
 | 
			
		||||
		return errors.New("subsystem not initialized")
 | 
			
		||||
	}
 | 
			
		||||
	// Make sure the source clock is disabled. Set it at 250kHz.
 | 
			
		||||
	//drvDMA.clockMemory.spi2Clk &^= clockSPIEnable
 | 
			
		||||
	drvDMA.clockMemory.spi2Clk |= clockSPIEnable
 | 
			
		||||
	drvDMA.clockMemory.spi2Clk = clockSPIDiv8a | clockSPIDiv12b
 | 
			
		||||
	ch := &drvDMA.spiMemory.groups[2]
 | 
			
		||||
	ch.setup()
 | 
			
		||||
	for i := 0; i < len(r)/4; i++ {
 | 
			
		||||
		ch.tx = 0
 | 
			
		||||
		for ch.status&spiR8TC == 0 {
 | 
			
		||||
		}
 | 
			
		||||
		// TODO(maruel): Access it in 8bit mode.
 | 
			
		||||
		r[i] = uint8(ch.rx)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Printf("Done\n")
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										128
									
								
								vendor/periph.io/x/periph/host/allwinner/timer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								vendor/periph.io/x/periph/host/allwinner/timer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
			
		||||
// 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 allwinner
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/host/cpu"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ReadTime returns the time on a monotonic timer.
 | 
			
		||||
//
 | 
			
		||||
// It only works if allwinner-dma successfully loaded. Otherwise it returns 0.
 | 
			
		||||
func ReadTime() time.Duration {
 | 
			
		||||
	if drvDMA.timerMemory == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	v := uint64(drvDMA.timerMemory.counterHigh)<<32 | uint64(drvDMA.timerMemory.counterLow)
 | 
			
		||||
	if v == 0 {
 | 
			
		||||
		// BUG(maruel): Implement using AVS_CNT0_REG on A64.
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	// BUG(maruel): Assumes that counterCtrl & timerPLL6 is not set.
 | 
			
		||||
	const tick = time.Microsecond / 24
 | 
			
		||||
	return time.Duration(v) * tick
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Nanospin spins the CPU without calling into the kernel code if possible.
 | 
			
		||||
func Nanospin(t time.Duration) {
 | 
			
		||||
	start := ReadTime()
 | 
			
		||||
	if start == 0 {
 | 
			
		||||
		// Use the slow generic version.
 | 
			
		||||
		cpu.Nanospin(t)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	for ReadTime()-start < t {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:3 reserved
 | 
			
		||||
	timerPLL6            timerCtrl = 2 << 1 // CONT64_CLK_SRC_SEL; OSC24M if not set;
 | 
			
		||||
	timerReadLatchEnable timerCtrl = 1 << 1 // CONT64_RLATCH_EN; 1 to latch the counter to the registers
 | 
			
		||||
	timerClear                     = 1 << 0 // CONT64_CLR_EN; clears the counter
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// R8: Page 96
 | 
			
		||||
type timerCtrl uint32
 | 
			
		||||
 | 
			
		||||
// timerMap is the mapping of important registers across CPUs.
 | 
			
		||||
type timerMap struct {
 | 
			
		||||
	reserved0   [0x80 / 4]uint32 //
 | 
			
		||||
	cntCtl      timerCtrl        // 0x80 AVS_CNT_CTL_REG AVS Control Register
 | 
			
		||||
	cnt0        uint32           // 0x84 AVS_CNT0_REG AVS Counter 0 Register
 | 
			
		||||
	cnt1        uint32           // 0x88 AVS_CNT1_REG AVS Counter 1 Register
 | 
			
		||||
	cndDrv      uint32           // 0x8C AVS_CNT_DIV_REG AVS Divisor Register
 | 
			
		||||
	reserved1   [0x10 / 4]uint32 // On R8 only.
 | 
			
		||||
	counterCtrl timerCtrl        // 0x0A0 COUNTER64_CTRL_REG 64-bit Counter control
 | 
			
		||||
	counterLow  uint32           // 0x0A4 COUNTER64_LOW_REG 64-bit Counter low
 | 
			
		||||
	counterHigh uint32           // 0x0A8 COUNTER64_HI_REG 64-bit Counter high
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A64: Page 161.
 | 
			
		||||
type timerMapA64 struct {
 | 
			
		||||
	reserved0  uint32    // 0x0 TMR_IRQ_EN_REG Timer IRQ Enable Register
 | 
			
		||||
	reserved1  uint32    // 0x4 TMR_IRQ_STA_REG Timer Status Register
 | 
			
		||||
	reserved2  uint32    // 0x10 TMR0_CTRL_REG Timer 0 Control Register
 | 
			
		||||
	reserved3  uint32    // 0x14 TMR0_INTV_VALUE_REG Timer 0 Interval Value Register
 | 
			
		||||
	reserved4  uint32    // 0x18 TMR0_CUR_VALUE_REG Timer 0 Current Value Register
 | 
			
		||||
	reserved5  uint32    // 0x20 TMR1_CTRL_REG Timer 1 Control Register
 | 
			
		||||
	reserved6  uint32    // 0x24 TMR1_INTV_VALUE_REG Timer 1 Interval Value Register
 | 
			
		||||
	reserved7  uint32    // 0x28 TMR1_CUR_VALUE_REG Timer 1 Current Value Register
 | 
			
		||||
	cntCtl     timerCtrl // 0x80 AVS_CNT_CTL_REG AVS Control Register
 | 
			
		||||
	cnt0       uint32    // 0x84 AVS_CNT0_REG AVS Counter 0 Register
 | 
			
		||||
	cnt1       uint32    // 0x88 AVS_CNT1_REG AVS Counter 1 Register
 | 
			
		||||
	cndDrv     uint32    // 0x8C AVS_CNT_DIV_REG AVS Divisor Register
 | 
			
		||||
	reserved8  uint32    // 0xA0 WDOG0_IRQ_EN_REG Watchdog 0 IRQ Enable Register
 | 
			
		||||
	reserved9  uint32    // 0xA4 WDOG0_IRQ_STA_REG Watchdog 0 Status Register
 | 
			
		||||
	reserved10 uint32    // 0xB0 WDOG0_CTRL_REG Watchdog 0 Control Register
 | 
			
		||||
	reserved11 uint32    // 0xB4 WDOG0_CFG_REG Watchdog 0 Configuration Register
 | 
			
		||||
	reserved12 uint32    // 0xB8 WDOG0_MODE_REG Watchdog 0 Mode Register
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// R8: Page 85
 | 
			
		||||
type timerMapR8 struct {
 | 
			
		||||
	reserved0   uint32       // 0x000 ASYNC_TMR_IRQ_EN_REG Timer IRQ Enable
 | 
			
		||||
	reserved1   uint32       // 0x004 ASYNC_TMR_IRQ_STAS_REG Timer Status
 | 
			
		||||
	reserved2   [2]uint32    // 0x008-0x00C
 | 
			
		||||
	reserved3   uint32       // 0x010 ASYNC_TMR0_CTRL_REG Timer 0 Control
 | 
			
		||||
	reserved4   uint32       // 0x014 ASYNC_TMR0_INTV_VALUE_REG Timer 0 Interval Value
 | 
			
		||||
	reserved5   uint32       // 0x018 ASYNC_TMR0_CURNT_VALUE_REG Timer 0 Current Value
 | 
			
		||||
	reserved6   uint32       // 0x01C
 | 
			
		||||
	reserved7   uint32       // 0x020 ASYNC_TMR1_CTRL_REG Timer 1 Control
 | 
			
		||||
	reserved8   uint32       // 0x024 ASYNC_TMR1_INTV_VALUE_REG Timer 1 Interval Value
 | 
			
		||||
	reserved9   uint32       // 0x028 ASYNC_TMR1_CURNT_VALUE_REG Timer 1 Current Value
 | 
			
		||||
	reserved10  uint32       // 0x02C
 | 
			
		||||
	reserved11  uint32       // 0x030 ASYNC_TMR2_CTRL_REG Timer 2 Control
 | 
			
		||||
	reserved12  uint32       // 0x034 ASYNC_TMR2_INTV_VALUE_REG Timer 2 Interval Value
 | 
			
		||||
	reserved13  uint32       // 0x038 ASYNC_TMR2_CURNT_VALUE_REG Timer 2 Current Value
 | 
			
		||||
	reserved14  uint32       // 0x03C
 | 
			
		||||
	reserved15  uint32       // 0x040 ASYNC_TMR3_CTRL_REG Timer 3 Control
 | 
			
		||||
	reserved16  uint32       // 0x044 ASYNC_TMR3_INTV_VALUE_REG Timer 3 Interval Value
 | 
			
		||||
	reserved17  [2]uint32    // 0x048-0x04C
 | 
			
		||||
	reserved18  uint32       // 0x050 ASYNC_TMR4_CTRL_REG Timer 4 Control
 | 
			
		||||
	reserved19  uint32       // 0x054 ASYNC_TMR4_INTV_VALUE_REG Timer 4 Interval Value
 | 
			
		||||
	reserved20  uint32       // 0x058 ASYNC_TMR4_CURNT_VALUE_REG Timer 4 Current Value
 | 
			
		||||
	reserved21  uint32       // 0x05C
 | 
			
		||||
	reserved22  uint32       // 0x060 ASYNC_TMR5_CTRL_REG Timer 5 Control
 | 
			
		||||
	reserved23  uint32       // 0x064 ASYNC_TMR5_INTV_VALUE_REG Timer 5 Interval Value
 | 
			
		||||
	reserved24  uint32       // 0x068 ASYNC_TMR5_CURNT_VALUE_REG Timer 5 Current Value
 | 
			
		||||
	reserved25  [5]uint32    // 0x06C-0x07C
 | 
			
		||||
	cntCtl      timerCtrl    // 0x080 AVS_CNT_CTL_REG AVS Control Register
 | 
			
		||||
	cnt0        uint32       // 0x084 AVS_CNT0_REG AVS Counter 0 Register
 | 
			
		||||
	cnt1        uint32       // 0x088 AVS_CNT1_REG AVS Counter 1 Register
 | 
			
		||||
	cndDiv      uint32       // 0x08C AVS_CNT_DIVISOR_REG AVS Divisor
 | 
			
		||||
	reserved26  uint32       // 0x090 WDOG_CTRL_REG
 | 
			
		||||
	reserved27  uint32       // 0x094 WDOG_MODE_REG Watchdog Mode
 | 
			
		||||
	reserved28  [2]uint32    // 0x098-0x09C
 | 
			
		||||
	counterCtrl timerCtrl    // 0x0A0 COUNTER64_CTRL_REG 64-bit Counter control
 | 
			
		||||
	counterLow  uint32       // 0x0A4 COUNTER64_LOW_REG 64-bit Counter low
 | 
			
		||||
	counterHigh uint32       // 0x0A8 COUNTER64_HI_REG 64-bit Counter high
 | 
			
		||||
	reserved29  [0x94]uint32 // 0x0AC-0x13C
 | 
			
		||||
	reserved30  uint32       // 0x140 CPU_CFG_REG CPU configuration register
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/periph.io/x/periph/host/am335x/am335x.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/periph.io/x/periph/host/am335x/am335x.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
// 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 am335x
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph"
 | 
			
		||||
	"periph.io/x/periph/host/distro"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Present returns true if a TM AM335x processor is detected.
 | 
			
		||||
func Present() bool {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		return strings.HasPrefix(distro.DTModel(), "TI AM335x")
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// driver implements periph.Driver.
 | 
			
		||||
type driver struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) String() string {
 | 
			
		||||
	return "am335x"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Prerequisites() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) After() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Init() (bool, error) {
 | 
			
		||||
	if !Present() {
 | 
			
		||||
		return false, errors.New("am335x CPU not detected")
 | 
			
		||||
	}
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		periph.MustRegister(&drv)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drv driver
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/am335x/am335x_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/am335x/am335x_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// 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 am335x
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/am335x/am335x_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/am335x/am335x_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// Copyright 2017 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !arm
 | 
			
		||||
 | 
			
		||||
package am335x
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										28
									
								
								vendor/periph.io/x/periph/host/am335x/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/periph.io/x/periph/host/am335x/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
// 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 am335x exposes functionality for the Texas Instruments Sitara AM335x
 | 
			
		||||
// processor family.
 | 
			
		||||
//
 | 
			
		||||
// This processor family is found on the BeagleBone. PRU-ICSS functionality is
 | 
			
		||||
// implemented in package pru.
 | 
			
		||||
//
 | 
			
		||||
// The GPIO pins of the AM335x CPU are grouped into 3 groups of 32 pins: GPIO0,
 | 
			
		||||
// GPIO1, and GPIO2. The CPU documentation refers to GPIO in the form of
 | 
			
		||||
// GPIOx_y. To get the absolute number, as exposed by sysfs, use 32*x+y to get
 | 
			
		||||
// the absolute number.
 | 
			
		||||
//
 | 
			
		||||
// Datasheet
 | 
			
		||||
//
 | 
			
		||||
// Technical Reference Manual
 | 
			
		||||
// https://www.ti.com/lit/ug/spruh73p/spruh73p.pdf
 | 
			
		||||
//
 | 
			
		||||
// Other
 | 
			
		||||
//
 | 
			
		||||
// Marketing page
 | 
			
		||||
// https://www.ti.com/processors/sitara/arm-cortex-a8/am335x/overview.html
 | 
			
		||||
//
 | 
			
		||||
// Family overview
 | 
			
		||||
// https://www.ti.com/lit/ds/symlink/am3359.pdf
 | 
			
		||||
package am335x
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm.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 bcm283x
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/bcm283x/bcm283x_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build arm64
 | 
			
		||||
 | 
			
		||||
package bcm283x
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/bcm283x/bcm283x_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/bcm283x/bcm283x_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !arm,!arm64
 | 
			
		||||
 | 
			
		||||
package bcm283x
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										330
									
								
								vendor/periph.io/x/periph/host/bcm283x/clock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										330
									
								
								vendor/periph.io/x/periph/host/bcm283x/clock.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,330 @@
 | 
			
		||||
// 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 bcm283x
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/physic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// errClockRegister is returned in a situation where the clock memory is not
 | 
			
		||||
// working as expected. It is mocked in tests.
 | 
			
		||||
var errClockRegister = errors.New("can't write to clock divisor CPU register")
 | 
			
		||||
 | 
			
		||||
// Clock sources frequency in hertz.
 | 
			
		||||
const (
 | 
			
		||||
	clk19dot2MHz = 19200 * physic.KiloHertz
 | 
			
		||||
	clk500MHz    = 500 * physic.MegaHertz
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:24 password
 | 
			
		||||
	clockPasswdCtl clockCtl = 0x5A << 24 // PASSWD
 | 
			
		||||
	// 23:11 reserved
 | 
			
		||||
	clockMashMask clockCtl = 3 << 9 // MASH
 | 
			
		||||
	clockMash0    clockCtl = 0 << 9 // src_freq / divI  (ignores divF)
 | 
			
		||||
	clockMash1    clockCtl = 1 << 9
 | 
			
		||||
	clockMash2    clockCtl = 2 << 9
 | 
			
		||||
	clockMash3    clockCtl = 3 << 9 // will cause higher spread
 | 
			
		||||
	clockFlip     clockCtl = 1 << 8 // FLIP
 | 
			
		||||
	clockBusy     clockCtl = 1 << 7 // BUSY
 | 
			
		||||
	// 6 reserved
 | 
			
		||||
	clockKill          clockCtl = 1 << 5   // KILL
 | 
			
		||||
	clockEnable        clockCtl = 1 << 4   // ENAB
 | 
			
		||||
	clockSrcMask       clockCtl = 0xF << 0 // SRC
 | 
			
		||||
	clockSrcGND        clockCtl = 0        // 0Hz
 | 
			
		||||
	clockSrc19dot2MHz  clockCtl = 1        // 19.2MHz
 | 
			
		||||
	clockSrcTestDebug0 clockCtl = 2        // 0Hz
 | 
			
		||||
	clockSrcTestDebug1 clockCtl = 3        // 0Hz
 | 
			
		||||
	clockSrcPLLA       clockCtl = 4        // 0Hz
 | 
			
		||||
	clockSrcPLLC       clockCtl = 5        // 1000MHz (changes with overclock settings)
 | 
			
		||||
	clockSrcPLLD       clockCtl = 6        // 500MHz
 | 
			
		||||
	clockSrcHDMI       clockCtl = 7        // 216MHz; may be disabled
 | 
			
		||||
	// 8-15 == GND.
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// clockCtl controls the clock properties.
 | 
			
		||||
//
 | 
			
		||||
// It must not be changed while busy is set or a glitch may occur.
 | 
			
		||||
//
 | 
			
		||||
// Page 107
 | 
			
		||||
type clockCtl uint32
 | 
			
		||||
 | 
			
		||||
func (c clockCtl) String() string {
 | 
			
		||||
	var out []string
 | 
			
		||||
	if c&0xFF000000 == clockPasswdCtl {
 | 
			
		||||
		c &^= 0xFF000000
 | 
			
		||||
		out = append(out, "PWD")
 | 
			
		||||
	}
 | 
			
		||||
	switch c & clockMashMask {
 | 
			
		||||
	case clockMash1:
 | 
			
		||||
		out = append(out, "Mash1")
 | 
			
		||||
	case clockMash2:
 | 
			
		||||
		out = append(out, "Mash2")
 | 
			
		||||
	case clockMash3:
 | 
			
		||||
		out = append(out, "Mash3")
 | 
			
		||||
	default:
 | 
			
		||||
	}
 | 
			
		||||
	c &^= clockMashMask
 | 
			
		||||
	if c&clockFlip != 0 {
 | 
			
		||||
		out = append(out, "Flip")
 | 
			
		||||
		c &^= clockFlip
 | 
			
		||||
	}
 | 
			
		||||
	if c&clockBusy != 0 {
 | 
			
		||||
		out = append(out, "Busy")
 | 
			
		||||
		c &^= clockBusy
 | 
			
		||||
	}
 | 
			
		||||
	if c&clockKill != 0 {
 | 
			
		||||
		out = append(out, "Kill")
 | 
			
		||||
		c &^= clockKill
 | 
			
		||||
	}
 | 
			
		||||
	if c&clockEnable != 0 {
 | 
			
		||||
		out = append(out, "Enable")
 | 
			
		||||
		c &^= clockEnable
 | 
			
		||||
	}
 | 
			
		||||
	switch x := c & clockSrcMask; x {
 | 
			
		||||
	case clockSrcGND:
 | 
			
		||||
		out = append(out, "GND(0Hz)")
 | 
			
		||||
	case clockSrc19dot2MHz:
 | 
			
		||||
		out = append(out, "19.2MHz")
 | 
			
		||||
	case clockSrcTestDebug0:
 | 
			
		||||
		out = append(out, "Debug0(0Hz)")
 | 
			
		||||
	case clockSrcTestDebug1:
 | 
			
		||||
		out = append(out, "Debug1(0Hz)")
 | 
			
		||||
	case clockSrcPLLA:
 | 
			
		||||
		out = append(out, "PLLA(0Hz)")
 | 
			
		||||
	case clockSrcPLLC:
 | 
			
		||||
		out = append(out, "PLLD(1000MHz)")
 | 
			
		||||
	case clockSrcPLLD:
 | 
			
		||||
		out = append(out, "PLLD(500MHz)")
 | 
			
		||||
	case clockSrcHDMI:
 | 
			
		||||
		out = append(out, "HDMI(216MHz)")
 | 
			
		||||
	default:
 | 
			
		||||
		out = append(out, fmt.Sprintf("GND(%d)", x))
 | 
			
		||||
	}
 | 
			
		||||
	c &^= clockSrcMask
 | 
			
		||||
	if c != 0 {
 | 
			
		||||
		out = append(out, fmt.Sprintf("clockCtl(0x%0x)", uint32(c)))
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(out, "|")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:24 password
 | 
			
		||||
	clockPasswdDiv clockDiv = 0x5A << 24 // PASSWD
 | 
			
		||||
	// Integer part of the divisor
 | 
			
		||||
	clockDiviShift          = 12
 | 
			
		||||
	clockDiviMax            = (1 << 12) - 1
 | 
			
		||||
	clockDiviMask  clockDiv = clockDiviMax << clockDiviShift // DIVI
 | 
			
		||||
	// Fractional part of the divisor
 | 
			
		||||
	clockDivfMask clockDiv = (1 << 12) - 1 // DIVF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// clockDiv is a 12.12 fixed point value.
 | 
			
		||||
//
 | 
			
		||||
// The fractional part generates a significant amount of noise so it is
 | 
			
		||||
// preferable to not use it.
 | 
			
		||||
//
 | 
			
		||||
// Page 108
 | 
			
		||||
type clockDiv uint32
 | 
			
		||||
 | 
			
		||||
func (c clockDiv) String() string {
 | 
			
		||||
	i := (c & clockDiviMask) >> clockDiviShift
 | 
			
		||||
	c &^= clockDiviMask
 | 
			
		||||
	if c == 0 {
 | 
			
		||||
		return fmt.Sprintf("%d.0", i)
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("%d.(%d/%d)", i, c, clockDiviMax)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clock is a pair of clockCtl / clockDiv.
 | 
			
		||||
//
 | 
			
		||||
// It can be set to one of the sources: clockSrc19dot2MHz(19.2MHz) and
 | 
			
		||||
// clockSrcPLLD(500Mhz), then divided to a value to get the resulting clock.
 | 
			
		||||
// Per spec the resulting frequency should be under 25Mhz.
 | 
			
		||||
type clock struct {
 | 
			
		||||
	ctl clockCtl
 | 
			
		||||
	div clockDiv
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// findDivisorExact finds the clock divisor and wait cycles to reduce src to
 | 
			
		||||
// desired hz.
 | 
			
		||||
//
 | 
			
		||||
// The clock divisor is capped to clockDiviMax.
 | 
			
		||||
//
 | 
			
		||||
// Returns clock divisor, wait cycles. Returns 0, 0 if no exact match is found.
 | 
			
		||||
// Favorizes high clock divisor value over high clock wait cycles. This means
 | 
			
		||||
// that the function is slower than it could be, but results in more stable
 | 
			
		||||
// clock.
 | 
			
		||||
func findDivisorExact(src, desired physic.Frequency, maxWaitCycles uint32) (uint32, uint32) {
 | 
			
		||||
	if src < desired || src%desired != 0 || src/physic.Frequency(maxWaitCycles*clockDiviMax) > desired {
 | 
			
		||||
		// Can't attain without oversampling (too low) or desired frequency is
 | 
			
		||||
		// higher than the source (too high) or is not a multiple.
 | 
			
		||||
		return 0, 0
 | 
			
		||||
	}
 | 
			
		||||
	factor := uint32(src / desired)
 | 
			
		||||
	// TODO(maruel): Only iterate over valid divisors to save a bit more
 | 
			
		||||
	// calculations. Since it's is only doing 32 loops, this is not a big deal.
 | 
			
		||||
	for wait := uint32(1); wait <= maxWaitCycles; wait++ {
 | 
			
		||||
		if rest := factor % wait; rest != 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		clk := factor / wait
 | 
			
		||||
		if clk == 0 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if clk <= clockDiviMax {
 | 
			
		||||
			return clk, wait
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0, 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// findDivisorOversampled tries to find the lowest allowed oversampling to make
 | 
			
		||||
// desiredHz a multiple of srcHz.
 | 
			
		||||
//
 | 
			
		||||
// Allowed oversampling depends on the desiredHz. Cap oversampling because
 | 
			
		||||
// oversampling at 10x in the 1Mhz range becomes unreasonable in term of
 | 
			
		||||
// memory usage.
 | 
			
		||||
func findDivisorOversampled(src, desired physic.Frequency, maxWaitCycles uint32) (uint32, uint32, physic.Frequency) {
 | 
			
		||||
	//log.Printf("findDivisorOversampled(%s, %s, %d)", src, desired, maxWaitCycles)
 | 
			
		||||
	// There are 2 reasons:
 | 
			
		||||
	// - desired is so low it is not possible to lower src to this frequency
 | 
			
		||||
	// - not a multiple, there's a need for a prime number
 | 
			
		||||
	// TODO(maruel): Rewrite without a loop, this is not needed. Leverage primes
 | 
			
		||||
	// to reduce the number of iterations.
 | 
			
		||||
	for multiple := physic.Frequency(2); ; multiple++ {
 | 
			
		||||
		n := multiple * desired
 | 
			
		||||
		if n > 100*physic.KiloHertz && multiple > 10 {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if clk, wait := findDivisorExact(src, n, maxWaitCycles); clk != 0 {
 | 
			
		||||
			return clk, wait, n
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0, 0, 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// calcSource choose the best source to get the exact desired clock.
 | 
			
		||||
//
 | 
			
		||||
// It calculates the clock source, the clock divisor and the wait cycles, if
 | 
			
		||||
// applicable. Wait cycles is 'div minus 1'.
 | 
			
		||||
func calcSource(f physic.Frequency, maxWaitCycles uint32) (clockCtl, uint32, uint32, physic.Frequency, error) {
 | 
			
		||||
	if f < physic.Hertz {
 | 
			
		||||
		return 0, 0, 0, 0, fmt.Errorf("bcm283x-clock: desired frequency %s must be >1hz", f)
 | 
			
		||||
	}
 | 
			
		||||
	if f > 125*physic.MegaHertz {
 | 
			
		||||
		return 0, 0, 0, 0, fmt.Errorf("bcm283x-clock: desired frequency %s is too high", f)
 | 
			
		||||
	}
 | 
			
		||||
	// http://elinux.org/BCM2835_datasheet_errata states that clockSrc19dot2MHz
 | 
			
		||||
	// is the cleanest clock source so try it first.
 | 
			
		||||
	div, wait := findDivisorExact(clk19dot2MHz, f, maxWaitCycles)
 | 
			
		||||
	if div != 0 {
 | 
			
		||||
		return clockSrc19dot2MHz, div, wait, f, nil
 | 
			
		||||
	}
 | 
			
		||||
	// Try 500Mhz.
 | 
			
		||||
	div, wait = findDivisorExact(clk500MHz, f, maxWaitCycles)
 | 
			
		||||
	if div != 0 {
 | 
			
		||||
		return clockSrcPLLD, div, wait, f, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Try with up to 10x oversampling. This is generally useful for lower
 | 
			
		||||
	// frequencies, below 10kHz. Prefer the one with less oversampling. Only for
 | 
			
		||||
	// non-aliased matches.
 | 
			
		||||
	div19, wait19, f19 := findDivisorOversampled(clk19dot2MHz, f, maxWaitCycles)
 | 
			
		||||
	div500, wait500, f500 := findDivisorOversampled(clk500MHz, f, maxWaitCycles)
 | 
			
		||||
	if div19 != 0 && (div500 == 0 || f19 < f500) {
 | 
			
		||||
		return clockSrc19dot2MHz, div19, wait19, f19, nil
 | 
			
		||||
	}
 | 
			
		||||
	if div500 != 0 {
 | 
			
		||||
		return clockSrcPLLD, div500, wait500, f500, nil
 | 
			
		||||
	}
 | 
			
		||||
	return 0, 0, 0, 0, errors.New("failed to find a good clock")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set changes the clock frequency to the desired value or the closest one
 | 
			
		||||
// otherwise.
 | 
			
		||||
//
 | 
			
		||||
// f=0 means disabled.
 | 
			
		||||
//
 | 
			
		||||
// maxWaitCycles is the maximum oversampling via an additional wait cycles that
 | 
			
		||||
// can further divide the clock. Use 1 if no additional wait cycle is
 | 
			
		||||
// available. It is expected to be dmaWaitcyclesMax+1.
 | 
			
		||||
//
 | 
			
		||||
// Returns the actual clock used and divisor.
 | 
			
		||||
func (c *clock) set(f physic.Frequency, maxWaitCycles uint32) (physic.Frequency, uint32, error) {
 | 
			
		||||
	if f == 0 {
 | 
			
		||||
		c.ctl = clockPasswdCtl | clockKill
 | 
			
		||||
		for c.ctl&clockBusy != 0 {
 | 
			
		||||
		}
 | 
			
		||||
		return 0, 0, nil
 | 
			
		||||
	}
 | 
			
		||||
	ctl, div, div2, actual, err := calcSource(f, maxWaitCycles)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return actual, div2, c.setRaw(ctl, div)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setRaw sets the clock speed with the clock source and the divisor.
 | 
			
		||||
func (c *clock) setRaw(ctl clockCtl, div uint32) error {
 | 
			
		||||
	if div < 1 || div > clockDiviMax {
 | 
			
		||||
		return errors.New("invalid clock divisor")
 | 
			
		||||
	}
 | 
			
		||||
	if ctl != clockSrc19dot2MHz && ctl != clockSrcPLLD {
 | 
			
		||||
		return errors.New("invalid clock control")
 | 
			
		||||
	}
 | 
			
		||||
	// Stop the clock.
 | 
			
		||||
	// TODO(maruel): Do not stop the clock if the current clock rate is the one
 | 
			
		||||
	// desired.
 | 
			
		||||
	for c.ctl&clockBusy != 0 {
 | 
			
		||||
		c.ctl = clockPasswdCtl | clockKill
 | 
			
		||||
	}
 | 
			
		||||
	d := clockDiv(div << clockDiviShift)
 | 
			
		||||
	c.div = clockPasswdDiv | d
 | 
			
		||||
	Nanospin(10 * time.Nanosecond)
 | 
			
		||||
	// Page 107
 | 
			
		||||
	c.ctl = clockPasswdCtl | ctl
 | 
			
		||||
	Nanospin(10 * time.Nanosecond)
 | 
			
		||||
	c.ctl = clockPasswdCtl | ctl | clockEnable
 | 
			
		||||
	if c.div != d {
 | 
			
		||||
		// This error is mocked out in tests, so the code path of set() callers can
 | 
			
		||||
		// follow on.
 | 
			
		||||
		return errClockRegister
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *clock) String() string {
 | 
			
		||||
	return fmt.Sprintf("%s / %s", c.ctl, c.div)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// clockMap is the memory mapped clock registers.
 | 
			
		||||
//
 | 
			
		||||
// The clock #1 must not be touched since it is being used by the ethernet
 | 
			
		||||
// controller.
 | 
			
		||||
//
 | 
			
		||||
// Page 107 for gp0~gp2.
 | 
			
		||||
// https://scribd.com/doc/127599939/BCM2835-Audio-clocks for PCM/PWM.
 | 
			
		||||
type clockMap struct {
 | 
			
		||||
	reserved0 [0x70 / 4]uint32          //
 | 
			
		||||
	gp0       clock                     // CM_GP0CTL+CM_GP0DIV; 0x70-0x74 (125MHz max)
 | 
			
		||||
	gp1ctl    uint32                    // CM_GP1CTL+CM_GP1DIV; 0x78-0x7A must not use (used by ethernet)
 | 
			
		||||
	gp1div    uint32                    // CM_GP1CTL+CM_GP1DIV; 0x78-0x7A must not use (used by ethernet)
 | 
			
		||||
	gp2       clock                     // CM_GP2CTL+CM_GP2DIV; 0x80-0x84 (125MHz max)
 | 
			
		||||
	reserved1 [(0x98 - 0x88) / 4]uint32 // 0x88-0x94
 | 
			
		||||
	pcm       clock                     // CM_PCMCTL+CM_PCMDIV 0x98-0x9C
 | 
			
		||||
	pwm       clock                     // CM_PWMCTL+CM_PWMDIV 0xA0-0xA4
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *clockMap) GoString() string {
 | 
			
		||||
	return fmt.Sprintf(
 | 
			
		||||
		"{\n  gp0: %s,\n  gp1: %s,\n  gp2: %s,\n  pcm: %sw,\n  pwm: %s,\n}",
 | 
			
		||||
		&c.gp0, &clock{clockCtl(c.gp1ctl), clockDiv(c.gp1div)}, &c.gp2, &c.pcm, &c.pwm)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1224
									
								
								vendor/periph.io/x/periph/host/bcm283x/dma.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1224
									
								
								vendor/periph.io/x/periph/host/bcm283x/dma.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										42
									
								
								vendor/periph.io/x/periph/host/bcm283x/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								vendor/periph.io/x/periph/host/bcm283x/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// 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 bcm283x exposes the BCM283x GPIO functionality.
 | 
			
		||||
//
 | 
			
		||||
// This driver implements memory-mapped GPIO pin manipulation and leverages
 | 
			
		||||
// sysfs-gpio for edge detection.
 | 
			
		||||
//
 | 
			
		||||
// If you are looking for the actual implementation, open doc.go for further
 | 
			
		||||
// implementation details.
 | 
			
		||||
//
 | 
			
		||||
// GPIOs
 | 
			
		||||
//
 | 
			
		||||
// Aliases for GPCLK0, GPCLK1, GPCLK2 are created for corresponding CLKn pins.
 | 
			
		||||
// Same for PWM0_OUT and PWM1_OUT, which point respectively to PWM0 and PWM1.
 | 
			
		||||
//
 | 
			
		||||
// Datasheet
 | 
			
		||||
//
 | 
			
		||||
// https://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
 | 
			
		||||
//
 | 
			
		||||
// Its crowd-sourced errata: http://elinux.org/BCM2835_datasheet_errata
 | 
			
		||||
//
 | 
			
		||||
// BCM2836:
 | 
			
		||||
// https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836/QA7_rev3.4.pdf
 | 
			
		||||
//
 | 
			
		||||
// Another doc about PCM and PWM:
 | 
			
		||||
// https://scribd.com/doc/127599939/BCM2835-Audio-clocks
 | 
			
		||||
//
 | 
			
		||||
// GPIO pad control:
 | 
			
		||||
// https://scribd.com/doc/101830961/GPIO-Pads-Control2
 | 
			
		||||
package bcm283x
 | 
			
		||||
 | 
			
		||||
// Other implementations details
 | 
			
		||||
//
 | 
			
		||||
// mainline:
 | 
			
		||||
// https://github.com/torvalds/linux/blob/master/drivers/dma/bcm2835-dma.c
 | 
			
		||||
// https://github.com/torvalds/linux/blob/master/drivers/gpio
 | 
			
		||||
//
 | 
			
		||||
// Raspbian kernel:
 | 
			
		||||
// https://github.com/raspberrypi/linux/blob/rpi-4.11.y/drivers/dma
 | 
			
		||||
// https://github.com/raspberrypi/linux/blob/rpi-4.11.y/drivers/gpio
 | 
			
		||||
							
								
								
									
										1361
									
								
								vendor/periph.io/x/periph/host/bcm283x/gpio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1361
									
								
								vendor/periph.io/x/periph/host/bcm283x/gpio.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										234
									
								
								vendor/periph.io/x/periph/host/bcm283x/pcm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								vendor/periph.io/x/periph/host/bcm283x/pcm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// pcm means I2S.
 | 
			
		||||
 | 
			
		||||
package bcm283x
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/physic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pcmCS uint32
 | 
			
		||||
 | 
			
		||||
// Pages 126-129
 | 
			
		||||
const (
 | 
			
		||||
	// 31:26 reserved
 | 
			
		||||
	pcmStandby      pcmCS = 1 << 25 // STBY Allow at least 4 PCM clock cycles to take effect
 | 
			
		||||
	pcmSync         pcmCS = 1 << 24 // SYNC Two PCM clocks have occurred since last write
 | 
			
		||||
	pcmRXSignExtend pcmCS = 1 << 23 // RXSEX Sign extend RXZ data
 | 
			
		||||
	pcmRXFull       pcmCS = 1 << 22 // RXF RX FIFO is full
 | 
			
		||||
	pcmTXEmpty      pcmCS = 1 << 21 // TXE TX FIFO is empty
 | 
			
		||||
	pcmRXData       pcmCS = 1 << 20 // RXD RX FIFO contains data
 | 
			
		||||
	pcmTXData       pcmCS = 1 << 19 // TXD TX FIFO ready to accept data
 | 
			
		||||
	pcmRXR          pcmCS = 1 << 18 // RXR RX FIFO needs reading
 | 
			
		||||
	pcmTXW          pcmCS = 1 << 17 // TXW TX FIFO needs writing
 | 
			
		||||
	pcmRXErr        pcmCS = 1 << 16 // RXERR RX FIFO error
 | 
			
		||||
	pcmTXErr        pcmCS = 1 << 15 // TXERR TX FIFO error
 | 
			
		||||
	pcmRXSync       pcmCS = 1 << 14 // RXSYNC RX FIFO is out of sync
 | 
			
		||||
	pcmTXSync       pcmCS = 1 << 13 // TXSYNC TX FIFO is out of sync
 | 
			
		||||
	// 12:10 reserved
 | 
			
		||||
	pcmDMAEnable pcmCS = 1 << 9 // DMAEN Generate TX&RX DMA DREQ
 | 
			
		||||
	// 8:7 RXTHR controls when pcmRXR is set
 | 
			
		||||
	pcmRXThresholdOne  pcmCS = 0 << 7 // One sample in RX FIFO
 | 
			
		||||
	pcmRXThreshold1    pcmCS = 1 << 7 // RX FIFO is at least (?) full
 | 
			
		||||
	pcmRXThreshold2    pcmCS = 2 << 7 // ?
 | 
			
		||||
	pcmRXThresholdFull pcmCS = 3 << 7 // RX is full
 | 
			
		||||
	// 6:5 TXTHR controls when pcmTXW is set
 | 
			
		||||
	pcmTXThresholdEmpty    pcmCS = 0 << 5 // TX FIFO is empty
 | 
			
		||||
	pcmTXThresholdNotFull1 pcmCS = 1 << 5 // At least one sample can be put
 | 
			
		||||
	pcmTXThresholdNotFull2 pcmCS = 2 << 5 // At least one sample can be put
 | 
			
		||||
	pcmTXThresholdOne      pcmCS = 3 << 5 // One sample can be put
 | 
			
		||||
	pcmRXClear             pcmCS = 1 << 4 // RXCLR Clear RX FIFO; takes 2 PCM clock to take effect
 | 
			
		||||
	pcmTXClear             pcmCS = 1 << 3 // TXCLR Clear TX FIFO; takes 2 PCM clock to take effect
 | 
			
		||||
	pcmTXEnable            pcmCS = 1 << 2 // TXON Enable TX
 | 
			
		||||
	pcmRXEnable            pcmCS = 1 << 1 // RXON Enable FX
 | 
			
		||||
	pcmEnable              pcmCS = 1 << 0 // EN Enable the PCM
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pcmMode uint32
 | 
			
		||||
 | 
			
		||||
// Page 129-131
 | 
			
		||||
const (
 | 
			
		||||
	// 31:29 reserved
 | 
			
		||||
	pcmClockDisable     pcmMode = 1 << 28                     // CLK_DIS Cleanly disable the PCM clock
 | 
			
		||||
	pcmDecimation32     pcmMode = 1 << 27                     // PDMN; 0 is factor 16, 1 is factor 32
 | 
			
		||||
	pcmRXPDMFilter      pcmMode = 1 << 26                     // PDME Enable input CIC filter on PDM input
 | 
			
		||||
	pcmRXMerge          pcmMode = 1 << 25                     // FRXP Merge both channels as single FIFO entry
 | 
			
		||||
	pcmTXMerge          pcmMode = 1 << 24                     // FTXP Merge both channels as singe FIFO entry
 | 
			
		||||
	pcmClockSlave       pcmMode = 1 << 23                     // CLKM PCM CLK is input
 | 
			
		||||
	pcmClockInverted    pcmMode = 1 << 22                     // CLKI Inverse clock signal
 | 
			
		||||
	pcmFSSlave          pcmMode = 1 << 21                     // FSM PCM FS is input
 | 
			
		||||
	pcmFSInverted       pcmMode = 1 << 20                     // FSI Invese FS signal
 | 
			
		||||
	pcmFrameLengthShift         = 10                          //
 | 
			
		||||
	pcmFrameLenghtMask  pcmMode = 0x3F << pcmFrameLengthShift // FLEN Frame length + 1
 | 
			
		||||
	pcmFSLenghtMask     pcmMode = 0x3F << 0                   // FSLEN FS pulse clock width
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pcmRX uint32
 | 
			
		||||
 | 
			
		||||
// Page 131-132
 | 
			
		||||
const (
 | 
			
		||||
	pcmRX1Width     pcmRX = 1 << 31 // CH1WEX Legacy
 | 
			
		||||
	pcmRX1Enable    pcmRX = 1 << 30 // CH1EN
 | 
			
		||||
	pcmRX1PosShift        = 20
 | 
			
		||||
	pcmRX1PosMask   pcmRX = 0x3F << pcmRX1PosShift // CH1POS Clock delay
 | 
			
		||||
	pcmRX1Channel16 pcmRX = 8 << 16                // CH1WID (Arbitrary width between 8 and 16 is supported)
 | 
			
		||||
	pcmRX2Width     pcmRX = 1 << 15                // CH2WEX Legacy
 | 
			
		||||
	pcmRX2Enable    pcmRX = 1 << 14                // CH2EN
 | 
			
		||||
	pcmRX2PosShift        = 4
 | 
			
		||||
	pcmRX2PosMask   pcmRX = 0x3F << pcmRX2PosShift // CH2POS Clock delay
 | 
			
		||||
	pcmRX2Channel16 pcmRX = 8 << 0                 // CH2WID (Arbitrary width between 8 and 16 is supported)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pcmTX uint32
 | 
			
		||||
 | 
			
		||||
// Page 133-134
 | 
			
		||||
const (
 | 
			
		||||
	pcmTX1Width     pcmTX = 1 << 31 // CH1WX Legacy
 | 
			
		||||
	pcmTX1Enable    pcmTX = 1 << 30 // CH1EN Enable channel 1
 | 
			
		||||
	pcmTX1PosShift        = 20
 | 
			
		||||
	pcmTX1PosMask   pcmTX = 0x3F << pcmTX1PosShift // CH1POS Clock delay
 | 
			
		||||
	pcmTX1Channel16 pcmTX = 8 << 16                // CH1WID (Arbitrary width between 8 and 16 is supported)
 | 
			
		||||
	pcmTX2Width     pcmTX = 1 << 15                // CH2WEX Legacy
 | 
			
		||||
	pcmTX2Enable    pcmTX = 1 << 14                // CH2EN
 | 
			
		||||
	pcmTX2PosShift        = 4
 | 
			
		||||
	pcmTX2PosMask   pcmTX = 0x3F << pcmTX2PosShift // CH2POS Clock delay
 | 
			
		||||
	pcmTX2Channel16 pcmTX = 8 << 0                 // CH2WID (Arbitrary width between 8 and 16 is supported)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pcmDreq uint32
 | 
			
		||||
 | 
			
		||||
// Page 134-135
 | 
			
		||||
const (
 | 
			
		||||
	// 31 reserved
 | 
			
		||||
	pcmDreqTXPanicShift         = 24
 | 
			
		||||
	pcmDreqTXPanicMask  pcmDreq = 0x7F << pcmDreqTXPanicShift // TX_PANIC Panic level
 | 
			
		||||
	// 23 reserved
 | 
			
		||||
	pcmDreqRXPanicShift         = 16
 | 
			
		||||
	pcmDreqRXPanicMask  pcmDreq = 0x7F << pcmDreqRXPanicShift // RX_PANIC Panic level
 | 
			
		||||
	// 15 reserved
 | 
			
		||||
	pcmDreqTXLevelShift         = 8
 | 
			
		||||
	pcmDreqTXLevelMask  pcmDreq = 0x7F << pcmDreqTXPanicShift // TX Request Level
 | 
			
		||||
	// 7 reserved
 | 
			
		||||
	pcmDreqRXLevelShift         = 0
 | 
			
		||||
	pcmDreqRXLevelMask  pcmDreq = 0x7F << pcmDreqRXPanicShift // RX Request Level
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pcmInterrupt uint32
 | 
			
		||||
 | 
			
		||||
// Page 135
 | 
			
		||||
const (
 | 
			
		||||
	// 31:4 reserved
 | 
			
		||||
	pcmIntRXErr    pcmInterrupt = 1 << 3 // RXERR RX error interrupt enable
 | 
			
		||||
	pcmIntTXErr    pcmInterrupt = 1 << 2 // TXERR TX error interrupt enable
 | 
			
		||||
	pcmIntRXEnable pcmInterrupt = 1 << 1 // RXR RX Read interrupt enable
 | 
			
		||||
	pcmIntTXEnable pcmInterrupt = 1 << 0 // TXW TX Write interrupt enable
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type pcmIntStatus uint32
 | 
			
		||||
 | 
			
		||||
// Page 135-136
 | 
			
		||||
const (
 | 
			
		||||
	// 31:4 reserved
 | 
			
		||||
	pcmIntStatRXErr    pcmIntStatus = 1 << 3 // RXERR RX error occurred / clear
 | 
			
		||||
	pcmIntStatTXErr    pcmIntStatus = 1 << 2 // TXERR TX error occurred / clear
 | 
			
		||||
	pcmIntStatRXEnable pcmIntStatus = 1 << 1 // RXR RX Read interrupt occurred / clear
 | 
			
		||||
	pcmIntStatTXEnable pcmIntStatus = 1 << 0 // TXW TX Write interrupt occurred / clear
 | 
			
		||||
	pcmIntStatusClear  pcmIntStatus = 0xF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// pcmGray puts it into a special data/strobe mode that is under 'best effort'
 | 
			
		||||
// contract.
 | 
			
		||||
type pcmGray uint32
 | 
			
		||||
 | 
			
		||||
// Page 136-137
 | 
			
		||||
const (
 | 
			
		||||
	// 31:22 reserved
 | 
			
		||||
	pcmGrayRXFIFOLevelShift         = 16
 | 
			
		||||
	pcmGrayRXFIFOLevelMask  pcmGray = 0x3F << pcmGrayRXFIFOLevelShift // RXFIFOLEVEL How many words in RXFIFO
 | 
			
		||||
	pcmGrayFlushShift               = 10
 | 
			
		||||
	pcmGrayFlushMask                = 0x3F << pcmGrayFlushShift // FLUSHED How many bits were valid when flush occurred
 | 
			
		||||
	pcmGrayRXLevelShift             = 4
 | 
			
		||||
	pcmGrayRXLevelMask      pcmGray = 0x3F << pcmGrayRXLevelShift // RXLEVEL How many GRAY coded bits received
 | 
			
		||||
	pcmGrayFlush            pcmGray = 1 << 2                      // FLUSH
 | 
			
		||||
	pcmGrayClear            pcmGray = 1 << 1                      // CLR
 | 
			
		||||
	pcmGrayEnable           pcmGray = 1 << 0                      // EN
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Page 119
 | 
			
		||||
type pcmMap struct {
 | 
			
		||||
	cs     pcmCS        // CS_A Control Status
 | 
			
		||||
	fifo   uint32       // FIFO_A FIFO register
 | 
			
		||||
	mode   pcmMode      // MODE_A Operation mode
 | 
			
		||||
	rxc    pcmRX        // RXC_A RX control
 | 
			
		||||
	txc    pcmTX        // TXC_A TX control
 | 
			
		||||
	dreq   pcmDreq      // DREQ_A DMA control
 | 
			
		||||
	inten  pcmInterrupt // INTEN_A Interrupt enable
 | 
			
		||||
	intstc pcmIntStatus // INTSTC_A Interrupt status
 | 
			
		||||
	gray   pcmGray      // GRAY Gray mode input processing
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *pcmMap) GoString() string {
 | 
			
		||||
	return fmt.Sprintf(
 | 
			
		||||
		"{\n  cs:     0x%x,\n  mode:   0x%x,\n  rxc:    0x%x,\n  txc:    0x%x,\n  dreq:   0x%x,\n  inten:  0x%x,\n  intstc: 0x%x,\n  gray:   0x%x,\n}",
 | 
			
		||||
		p.cs, p.mode, p.rxc, p.txc, p.dreq, p.inten, p.intstc, p.gray)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *pcmMap) reset() {
 | 
			
		||||
	p.cs = 0
 | 
			
		||||
	// In theory need to wait the equivalent of 2 PCM clocks.
 | 
			
		||||
	// TODO(maruel): Use pcmSync busy loop to synchronize.
 | 
			
		||||
	Nanospin(time.Microsecond)
 | 
			
		||||
	// Hard reset
 | 
			
		||||
	p.fifo = 0
 | 
			
		||||
	p.mode = 0
 | 
			
		||||
	p.rxc = 0
 | 
			
		||||
	p.txc = 0
 | 
			
		||||
	p.dreq = 0
 | 
			
		||||
	p.inten = 0
 | 
			
		||||
	p.intstc = pcmIntStatusClear
 | 
			
		||||
	p.gray = 0
 | 
			
		||||
 | 
			
		||||
	// Clear pcmStandby / pcm
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// set initializes 8 bits stream via DMA with no delay and no FS.
 | 
			
		||||
func (p *pcmMap) set() {
 | 
			
		||||
	p.cs |= pcmEnable
 | 
			
		||||
	p.txc = pcmTX1Width | pcmTX1Channel16 | pcmTX1Enable // 32bit TX
 | 
			
		||||
	p.mode = (32 - 1) << pcmFrameLengthShift
 | 
			
		||||
	p.cs |= pcmTXClear | pcmRXClear
 | 
			
		||||
	// In theory need to wait the equivalent of 2 PCM clocks.
 | 
			
		||||
	// TODO(maruel): Use pcmSync busy loop to synchronize.
 | 
			
		||||
	Nanospin(time.Microsecond)
 | 
			
		||||
	p.dreq = 0x10<<pcmDreqTXPanicShift | 0x30<<pcmDreqTXLevelShift
 | 
			
		||||
	p.cs |= pcmDMAEnable
 | 
			
		||||
	//  pcmTXThresholdOne ?
 | 
			
		||||
	p.cs |= pcmTXEnable
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setPCMClockSource sets the PCM clock.
 | 
			
		||||
//
 | 
			
		||||
// It may select an higher frequency than the one requested.
 | 
			
		||||
//
 | 
			
		||||
// Other potentially good clock sources are PWM, SPI and UART.
 | 
			
		||||
func setPCMClockSource(f physic.Frequency) (physic.Frequency, uint32, error) {
 | 
			
		||||
	if drvDMA.pcmMemory == nil {
 | 
			
		||||
		return 0, 0, errors.New("subsystem PCM not initialized")
 | 
			
		||||
	}
 | 
			
		||||
	if drvDMA.clockMemory == nil {
 | 
			
		||||
		return 0, 0, errors.New("subsystem Clock not initialized")
 | 
			
		||||
	}
 | 
			
		||||
	actual, divs, err := drvDMA.clockMemory.pcm.set(f, 1)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		drvDMA.pcmMemory.cs = 0
 | 
			
		||||
	}
 | 
			
		||||
	// Convert divisor into wait cycles.
 | 
			
		||||
	return actual, divs, err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										272
									
								
								vendor/periph.io/x/periph/host/bcm283x/pwm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								vendor/periph.io/x/periph/host/bcm283x/pwm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,272 @@
 | 
			
		||||
// 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 bcm283x
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/physic"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// PWENi is used to enable/disable the corresponding channel. Setting this bit
 | 
			
		||||
// to 1 enables the channel and transmitter state machine. All registers and
 | 
			
		||||
// FIFO is writable without setting this bit.
 | 
			
		||||
//
 | 
			
		||||
// MODEi bit is used to determine mode of operation. Setting this bit to 0
 | 
			
		||||
// enables PWM mode. In this mode data stored in either PWM_DATi or FIFO is
 | 
			
		||||
// transmitted by pulse width modulation within the range defined by PWM_RNGi.
 | 
			
		||||
// When this mode is used MSENi defines whether to use PWM algorithm. Setting
 | 
			
		||||
// MODEi to 1 enables serial mode, in which data stored in either PWM_DATi or
 | 
			
		||||
// FIFO is transmitted serially within the range defined by PWM_RNGi. Data is
 | 
			
		||||
// transmitted MSB first and truncated or zeropadded depending on PWM_RNGi.
 | 
			
		||||
// Default mode is PWM.
 | 
			
		||||
//
 | 
			
		||||
// RPTLi is used to enable/disable repeating of the last data available in the
 | 
			
		||||
// FIFO just before it empties. When this bit is 1 and FIFO is used, the last
 | 
			
		||||
// available data in the FIFO is repeatedly sent. This may be useful in PWM
 | 
			
		||||
// mode to avoid duty cycle gaps. If the FIFO is not used this bit does not
 | 
			
		||||
// have any effect. Default operation is do-notrepeat.
 | 
			
		||||
//
 | 
			
		||||
// SBITi defines the state of the output when no transmission takes place. It
 | 
			
		||||
// also defines the zero polarity for the zero padding in serialiser mode. This
 | 
			
		||||
// bit is padded between two consecutive transfers as well as tail of the data
 | 
			
		||||
// when PWM_RNGi is larger than bit depth of data being transferred. this bit
 | 
			
		||||
// is zero by default.
 | 
			
		||||
//
 | 
			
		||||
// POLAi is used to configure the polarity of the output bit. When set to high
 | 
			
		||||
// the final output is inverted. Default operation is no inversion.
 | 
			
		||||
//
 | 
			
		||||
// USEFi bit is used to enable/disable FIFO transfer. When this bit is high
 | 
			
		||||
// data stored in the FIFO is used for transmission. When it is low, data
 | 
			
		||||
// written to PWM_DATi is transferred. This bit is 0 as default.
 | 
			
		||||
//
 | 
			
		||||
// CLRF is used to clear the FIFO. Writing a 1 to this bit clears the FIFO.
 | 
			
		||||
// Writing 0 has no effect. This is a single shot operation and reading the bit
 | 
			
		||||
// always returns 0.
 | 
			
		||||
//
 | 
			
		||||
// MSENi is used to determine whether to use PWM algorithm or simple M/S ratio
 | 
			
		||||
// transmission. When this bit is high M/S transmission is used. This bit is
 | 
			
		||||
// zero as default. When MODEi is 1, this configuration bit has no effect.
 | 
			
		||||
//
 | 
			
		||||
// See page 139-140 for the description of the PWM and M/S ratio algorithms.
 | 
			
		||||
const (
 | 
			
		||||
	// 31:16 reserved
 | 
			
		||||
	pwm2MS pwmControl = 1 << 15 // MSEN2; 0: PWM algorithm is used; 1: M/S transmission is used
 | 
			
		||||
	// 14 reserved
 | 
			
		||||
	pwm2UseFIFO        pwmControl = 1 << 13 // USEF2; 0: Data register is transmitted; 1: Fifo is used for transmission
 | 
			
		||||
	pwm2Polarity       pwmControl = 1 << 12 // POLA2; 0: 0=low 1=high; 1: 1=low 0=high
 | 
			
		||||
	pwm2SilenceHigh    pwmControl = 1 << 11 // SBIT2; Defines the state of the output when no transmission takes place
 | 
			
		||||
	pwm2RepeatLastData pwmControl = 1 << 10 // RPTL2; 0: Transmission interrupts when FIFO is empty; 1: Last data in FIFO is transmitted repetedly until FIFO is not empty
 | 
			
		||||
	pwm2Serialiser     pwmControl = 1 << 9  // MODE2; 0: PWM mode; 1: Serialiser mode
 | 
			
		||||
	pwm2Enable         pwmControl = 1 << 8  // PWEN2; Enable channel 2
 | 
			
		||||
	pwm2Mask           pwmControl = pwm2MS | pwm2UseFIFO | pwm2Polarity | pwm2SilenceHigh | pwm2RepeatLastData | pwm2Serialiser | pwm2Enable
 | 
			
		||||
	pwm1MS             pwmControl = 1 << 7 // MSEN1; 0: PWM algorithm is used; 1: M/S transmission is used
 | 
			
		||||
	pwmClearFIFO       pwmControl = 1 << 6 // CLRF1; Clear the fifo
 | 
			
		||||
	pwm1UseFIFO        pwmControl = 1 << 5 // USEF1; 0: Data register is transmitted; 1: Fifo is used for transmission
 | 
			
		||||
	pwm1Polarity       pwmControl = 1 << 4 // POLA1; 0: 0=low 1=high; 1: 1=low 0=high
 | 
			
		||||
	pwm1SilenceHigh    pwmControl = 1 << 3 // SBIT1; Defines the state of the output when no transmission takes place
 | 
			
		||||
	pwm1RepeatLastData pwmControl = 1 << 2 // RPTL1; 0: Transmission interrupts when FIFO is empty; 1: Last data in FIFO is transmitted repetedly until FIFO is not empty
 | 
			
		||||
	pwm1Serialiser     pwmControl = 1 << 1 // MODE1; 0: PWM mode; 1: Serialiser mode
 | 
			
		||||
	pwm1Enable         pwmControl = 1 << 0 // PWEN1; Enable channel 1
 | 
			
		||||
	pwm1Mask           pwmControl = pwm1MS | pwm1UseFIFO | pwm1Polarity | pwm1SilenceHigh | pwm1RepeatLastData | pwm1Serialiser | pwm1Enable
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Pages 141-143.
 | 
			
		||||
type pwmControl uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:13 reserved
 | 
			
		||||
	// STAi bit indicates the current state of the channel which is useful for
 | 
			
		||||
	// debugging purposes. The bit set means the channel is currently
 | 
			
		||||
	// transmitting data.
 | 
			
		||||
	pwmSta4 pwmStatus = 1 << 12 // STA4
 | 
			
		||||
	pwmSta3 pwmStatus = 1 << 11 // STA3
 | 
			
		||||
	pwmSta2 pwmStatus = 1 << 10 // STA2
 | 
			
		||||
	pwmSta1 pwmStatus = 1 << 9  // STA1
 | 
			
		||||
	// BERR sets to high when an error has occurred while writing to registers
 | 
			
		||||
	// via APB. This may happen if the bus tries to write successively to same
 | 
			
		||||
	// set of registers faster than the synchroniser block can cope with.
 | 
			
		||||
	// Multiple switching may occur and contaminate the data during
 | 
			
		||||
	// synchronisation. Software should clear this bit by writing 1. Writing 0
 | 
			
		||||
	// to this bit has no effect.
 | 
			
		||||
	pwmBusErr pwmStatus = 1 << 8 // BERR Bus Error flag
 | 
			
		||||
	// GAPOi. bit indicates that there has been a gap between transmission of two
 | 
			
		||||
	// consecutive data from FIFO. This may happen when FIFO gets empty after
 | 
			
		||||
	// state machine has sent a word and waits for the next. If control bit RPTLi
 | 
			
		||||
	// is set to high this event will not occur. Software must clear this bit by
 | 
			
		||||
	// writing 1. Writing 0 to this bit has no effect.
 | 
			
		||||
	pwmGapo4 pwmStatus = 1 << 7 // GAPO4 Channel 4 Gap Occurred flag
 | 
			
		||||
	pwmGapo3 pwmStatus = 1 << 6 // GAPO3 Channel 3 Gap Occurred flag
 | 
			
		||||
	pwmGapo2 pwmStatus = 1 << 5 // GAPO2 Channel 2 Gap Occurred flag
 | 
			
		||||
	pwmGapo1 pwmStatus = 1 << 4 // GAPO1 Channel 1 Gap Occurred flag
 | 
			
		||||
	// RERR1 bit sets to high when a read when empty error occurs. Software must
 | 
			
		||||
	// clear this bit by writing 1. Writing 0 to this bit has no effect.
 | 
			
		||||
	pwmRerr1 pwmStatus = 1 << 3 // RERR1
 | 
			
		||||
	// WERR1 bit sets to high when a write when full error occurs. Software must
 | 
			
		||||
	// clear this bit by writing 1. Writing 0 to this bit has no effect.
 | 
			
		||||
	pwmWerr1 pwmStatus = 1 << 2 // WERR1
 | 
			
		||||
	// EMPT1 bit indicates the empty status of the FIFO. If this bit is high FIFO
 | 
			
		||||
	// is empty.
 | 
			
		||||
	pwmEmpt1 pwmStatus = 1 << 1 // EMPT1
 | 
			
		||||
	// FULL1 bit indicates the full status of the FIFO. If this bit is high FIFO
 | 
			
		||||
	// is full.
 | 
			
		||||
	pwmFull1      pwmStatus = 1 << 0 // FULL1
 | 
			
		||||
	pwmStatusMask           = pwmSta4 | pwmSta3 | pwmSta2 | pwmSta1 | pwmBusErr | pwmGapo4 | pwmGapo3 | pwmGapo2 | pwmGapo1 | pwmRerr1 | pwmWerr1 | pwmEmpt1 | pwmFull1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Pages 144-145.
 | 
			
		||||
type pwmStatus uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	pwmDMAEnable pwmDMACfg = 1 << 31 // ENAB
 | 
			
		||||
	// 30:16 reserved
 | 
			
		||||
	pwmPanicShift           = 16
 | 
			
		||||
	pwmPanicMask  pwmDMACfg = 0xFF << pwmPanicShift // PANIC Default is 7
 | 
			
		||||
	pwmDreqMask   pwmDMACfg = 0xFF                  // DREQ Default is 7
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Page 145.
 | 
			
		||||
type pwmDMACfg uint32
 | 
			
		||||
 | 
			
		||||
// pwmMap is the block to control the PWM generator.
 | 
			
		||||
//
 | 
			
		||||
// Note that pins are named PWM0 and PWM1 but the mapping uses channel numbers
 | 
			
		||||
// 1 and 2.
 | 
			
		||||
//   - PWM0: GPIO12, GPIO18, GPIO40, GPIO52.
 | 
			
		||||
//   - PWM1: GPIO13, GPIO19, GPIO41, GPIO45, GPIO53.
 | 
			
		||||
//
 | 
			
		||||
// Each channel works independently. They can either output a bitstream or a
 | 
			
		||||
// serialised version of up to eight 32 bits words.
 | 
			
		||||
//
 | 
			
		||||
// The default base PWM frequency is 100Mhz.
 | 
			
		||||
//
 | 
			
		||||
// Description at page 138-139.
 | 
			
		||||
//
 | 
			
		||||
// Page 140-141.
 | 
			
		||||
type pwmMap struct {
 | 
			
		||||
	ctl    pwmControl // CTL
 | 
			
		||||
	status pwmStatus  // STA
 | 
			
		||||
	dmaCfg pwmDMACfg  // DMAC
 | 
			
		||||
	// This register is used to define the range for the corresponding channel.
 | 
			
		||||
	// In PWM mode evenly distributed pulses are sent within a period of length
 | 
			
		||||
	// defined by this register. In serial mode serialised data is transmitted
 | 
			
		||||
	// within the same period. If the value in PWM_RNGi is less than 32, only the
 | 
			
		||||
	// first PWM_RNGi bits are sent resulting in a truncation. If it is larger
 | 
			
		||||
	// than 32 excess zero bits are padded at the end of data. Default value for
 | 
			
		||||
	// this register is 32.
 | 
			
		||||
	dummy1 uint32 // Padding
 | 
			
		||||
	rng1   uint32 // RNG1
 | 
			
		||||
	// This register stores the 32 bit data to be sent by the PWM Controller when
 | 
			
		||||
	// USEFi is 0. In PWM mode data is sent by pulse width modulation: the value
 | 
			
		||||
	// of this register defines the number of pulses which is sent within the
 | 
			
		||||
	// period defined by PWM_RNGi. In serialiser mode data stored in this
 | 
			
		||||
	// register is serialised and transmitted.
 | 
			
		||||
	dat1 uint32 // DAT1
 | 
			
		||||
	// This register is the FIFO input for the all channels. Data written to this
 | 
			
		||||
	// address is stored in channel FIFO and if USEFi is enabled for the channel
 | 
			
		||||
	// i it is used as data to be sent. This register is write only, and reading
 | 
			
		||||
	// this register will always return bus default return value, pwm0.
 | 
			
		||||
	// When more than one channel is enabled for FIFO usage, the data written
 | 
			
		||||
	// into the FIFO is shared between these channels in turn. For example if the
 | 
			
		||||
	// word series A B C D E F G H I .. is written to FIFO and two channels are
 | 
			
		||||
	// active and configured to use FIFO then channel 1 will transmit words A C E
 | 
			
		||||
	// G I .. and channel 2 will transmit words B D F H .. .  Note that
 | 
			
		||||
	// requesting data from the FIFO is in locked-step manner and therefore
 | 
			
		||||
	// requires tight coupling of state machines of the channels. If any of the
 | 
			
		||||
	// channel range (period) value is different than the others this will cause
 | 
			
		||||
	// the channels with small range values to wait between words hence resulting
 | 
			
		||||
	// in gaps between words. To avoid that, each channel sharing the FIFO should
 | 
			
		||||
	// be configured to use the same range value. Also note that RPTLi are not
 | 
			
		||||
	// meaningful when the FIFO is shared between channels as there is no defined
 | 
			
		||||
	// channel to own the last data in the FIFO. Therefore sharing channels must
 | 
			
		||||
	// have their RPTLi set to zero.
 | 
			
		||||
	//
 | 
			
		||||
	// If the set of channels to share the FIFO has been modified after a
 | 
			
		||||
	// configuration change, FIFO should be cleared before writing new data.
 | 
			
		||||
	fifo   uint32 // FIF1
 | 
			
		||||
	dummy2 uint32 // Padding
 | 
			
		||||
	rng2   uint32 // RNG2 Equivalent of rng1 for channel 2
 | 
			
		||||
	dat2   uint32 // DAT2 Equivalent of dat1 for channel 2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reset stops the PWM.
 | 
			
		||||
func (p *pwmMap) reset() {
 | 
			
		||||
	p.dmaCfg = 0
 | 
			
		||||
	p.ctl |= pwmClearFIFO
 | 
			
		||||
	p.ctl &^= pwm1Enable | pwm2Enable
 | 
			
		||||
	Nanospin(100 * time.Microsecond) // Cargo cult copied. Probably not necessary.
 | 
			
		||||
	p.status = pwmBusErr | pwmGapo1 | pwmGapo2 | pwmGapo3 | pwmGapo4 | pwmRerr1 | pwmWerr1
 | 
			
		||||
	Nanospin(100 * time.Microsecond)
 | 
			
		||||
	// Use the full 32 bits of DATi.
 | 
			
		||||
	p.rng1 = 32
 | 
			
		||||
	p.rng2 = 32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// setPWMClockSource sets the PWM clock for use by the DMA controller for
 | 
			
		||||
// pacing.
 | 
			
		||||
//
 | 
			
		||||
// It may select an higher frequency than the one requested.
 | 
			
		||||
//
 | 
			
		||||
// Other potentially good clock sources are PCM, SPI and UART.
 | 
			
		||||
func setPWMClockSource() (physic.Frequency, error) {
 | 
			
		||||
	if drvDMA.pwmMemory == nil {
 | 
			
		||||
		return 0, errors.New("subsystem PWM not initialized")
 | 
			
		||||
	}
 | 
			
		||||
	if drvDMA.clockMemory == nil {
 | 
			
		||||
		return 0, errors.New("subsystem Clock not initialized")
 | 
			
		||||
	}
 | 
			
		||||
	if drvDMA.pwmDMACh != nil {
 | 
			
		||||
		// Already initialized
 | 
			
		||||
		return drvDMA.pwmDMAFreq, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// divs * div must fit in rng1 registor.
 | 
			
		||||
	div := uint32(drvDMA.pwmBaseFreq / drvDMA.pwmDMAFreq)
 | 
			
		||||
	actual, divs, err := drvDMA.clockMemory.pwm.set(drvDMA.pwmBaseFreq, div)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if e := actual / physic.Frequency(divs*div); drvDMA.pwmDMAFreq != e {
 | 
			
		||||
		return 0, fmt.Errorf("unexpected DMA frequency %s != %s (%d/%d/%d)", drvDMA.pwmDMAFreq, e, actual, divs, div)
 | 
			
		||||
	}
 | 
			
		||||
	// It acts as a clock multiplier, since this amount of data is sent per
 | 
			
		||||
	// clock tick.
 | 
			
		||||
	drvDMA.pwmMemory.rng1 = divs * div
 | 
			
		||||
	Nanospin(10 * time.Microsecond)
 | 
			
		||||
	// Periph data (?)
 | 
			
		||||
 | 
			
		||||
	// Use low priority.
 | 
			
		||||
	drvDMA.pwmMemory.dmaCfg = pwmDMAEnable | pwmDMACfg(15<<pwmPanicShift|15)
 | 
			
		||||
	Nanospin(10 * time.Microsecond)
 | 
			
		||||
	drvDMA.pwmMemory.ctl |= pwmClearFIFO
 | 
			
		||||
	Nanospin(10 * time.Microsecond)
 | 
			
		||||
	old := drvDMA.pwmMemory.ctl
 | 
			
		||||
	drvDMA.pwmMemory.ctl = (old & ^pwmControl(0xff)) | pwm1UseFIFO | pwm1Enable
 | 
			
		||||
 | 
			
		||||
	// Start DMA
 | 
			
		||||
	if drvDMA.pwmDMACh, drvDMA.pwmDMABuf, err = dmaWritePWMFIFO(); err != nil {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return drvDMA.pwmDMAFreq, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func resetPWMClockSource() error {
 | 
			
		||||
	if drvDMA.pwmDMACh != nil {
 | 
			
		||||
		drvDMA.pwmDMACh.reset()
 | 
			
		||||
		drvDMA.pwmDMACh = nil
 | 
			
		||||
	}
 | 
			
		||||
	if drvDMA.pwmDMABuf != nil {
 | 
			
		||||
		if err := drvDMA.pwmDMABuf.Close(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
		drvDMA.pwmDMABuf = nil
 | 
			
		||||
	}
 | 
			
		||||
	_, _, err := drvDMA.clockMemory.pwm.set(0, 0)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										134
									
								
								vendor/periph.io/x/periph/host/bcm283x/streams.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								vendor/periph.io/x/periph/host/bcm283x/streams.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
// 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 bcm283x
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/conn/gpio/gpiostream"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// uint32ToBitLSBF packs a bit offset found on slice `d` (that is actually
 | 
			
		||||
// uint32) back into a densely packed Bits stream.
 | 
			
		||||
func uint32ToBitLSBF(w []byte, d []uint8, bit uint8, skip int) {
 | 
			
		||||
	// Little endian.
 | 
			
		||||
	x := bit / 8
 | 
			
		||||
	d = d[x:]
 | 
			
		||||
	bit -= 8 * x
 | 
			
		||||
	mask := uint8(1) << bit
 | 
			
		||||
	for i := range w {
 | 
			
		||||
		w[i] = ((d[0]&mask)>>bit<<0 |
 | 
			
		||||
			(d[skip*1]&mask)>>bit<<1 |
 | 
			
		||||
			(d[skip*2]&mask)>>bit<<2 |
 | 
			
		||||
			(d[skip*3]&mask)>>bit<<3 |
 | 
			
		||||
			(d[skip*4]&mask)>>bit<<4 |
 | 
			
		||||
			(d[skip*5]&mask)>>bit<<5 |
 | 
			
		||||
			(d[skip*6]&mask)>>bit<<6 |
 | 
			
		||||
			(d[skip*7]&mask)>>bit<<7)
 | 
			
		||||
		d = d[skip*8:]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getBit(b byte, index int, msb bool) byte {
 | 
			
		||||
	var shift uint
 | 
			
		||||
	if msb {
 | 
			
		||||
		shift = uint(7 - index)
 | 
			
		||||
	} else {
 | 
			
		||||
		shift = uint(index)
 | 
			
		||||
	}
 | 
			
		||||
	return (b >> shift) & 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func raster32Bits(s gpiostream.Stream, skip int, clear, set []uint32, mask uint32) error {
 | 
			
		||||
	var msb bool
 | 
			
		||||
	var bits []byte
 | 
			
		||||
	switch b := s.(type) {
 | 
			
		||||
	case *gpiostream.BitStream:
 | 
			
		||||
		msb = !b.LSBF
 | 
			
		||||
		bits = b.Bits
 | 
			
		||||
	default:
 | 
			
		||||
		return fmt.Errorf("unsupported type %T", b)
 | 
			
		||||
	}
 | 
			
		||||
	m := len(clear) / 8
 | 
			
		||||
	if n := len(bits); n < m {
 | 
			
		||||
		m = n
 | 
			
		||||
	}
 | 
			
		||||
	index := 0
 | 
			
		||||
	for i := 0; i < m; i++ {
 | 
			
		||||
		for j := 0; j < 8; j++ {
 | 
			
		||||
			if getBit(bits[i], j, msb) != 0 {
 | 
			
		||||
				for k := 0; k < skip; k++ {
 | 
			
		||||
					set[index] |= mask
 | 
			
		||||
					index++
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				for k := 0; k < skip; k++ {
 | 
			
		||||
					clear[index] |= mask
 | 
			
		||||
					index++
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// raster32 rasters the stream into a uint32 stream with the specified masks to
 | 
			
		||||
// put in the correctly slice when the bit is set and when it is clear.
 | 
			
		||||
//
 | 
			
		||||
// `s` must be one of the types in this package.
 | 
			
		||||
func raster32(s gpiostream.Stream, skip int, clear, set []uint32, mask uint32) error {
 | 
			
		||||
	if mask == 0 {
 | 
			
		||||
		return errors.New("bcm283x: mask is 0")
 | 
			
		||||
	}
 | 
			
		||||
	if len(clear) == 0 {
 | 
			
		||||
		return errors.New("bcm283x: clear buffer is empty")
 | 
			
		||||
	}
 | 
			
		||||
	if len(set) == 0 {
 | 
			
		||||
		return errors.New("bcm283x: set buffer is empty")
 | 
			
		||||
	}
 | 
			
		||||
	if len(clear) != len(set) {
 | 
			
		||||
		return errors.New("bcm283x: clear and set buffers have different length")
 | 
			
		||||
	}
 | 
			
		||||
	switch x := s.(type) {
 | 
			
		||||
	case *gpiostream.BitStream:
 | 
			
		||||
		// TODO
 | 
			
		||||
		return raster32Bits(x, skip, clear, set, mask)
 | 
			
		||||
	case *gpiostream.EdgeStream:
 | 
			
		||||
		return errors.New("bcm283x: EdgeStream is not supported yet")
 | 
			
		||||
	case *gpiostream.Program:
 | 
			
		||||
		return errors.New("bcm283x: Program is not supported yet")
 | 
			
		||||
	default:
 | 
			
		||||
		return errors.New("bcm283x: unknown stream type")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PCM/PWM DMA buf is encoded as little-endian and MSB first.
 | 
			
		||||
func copyStreamToDMABuf(w gpiostream.Stream, dst []uint32) error {
 | 
			
		||||
	switch v := w.(type) {
 | 
			
		||||
	case *gpiostream.BitStream:
 | 
			
		||||
		if v.LSBF {
 | 
			
		||||
			return errors.New("TODO(simokawa): handle BitStream.LSBF")
 | 
			
		||||
		}
 | 
			
		||||
		// This is big-endian and MSB first.
 | 
			
		||||
		i := 0
 | 
			
		||||
		for ; i < len(v.Bits)/4; i++ {
 | 
			
		||||
			dst[i] = binary.BigEndian.Uint32(v.Bits[i*4:])
 | 
			
		||||
		}
 | 
			
		||||
		last := uint32(0)
 | 
			
		||||
		if mod := len(v.Bits) % 4; mod > 0 {
 | 
			
		||||
			for j := 0; j < mod; j++ {
 | 
			
		||||
				last |= (uint32(v.Bits[i*4+j])) << uint32(8*(3-j))
 | 
			
		||||
			}
 | 
			
		||||
			dst[i] = last
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	case *gpiostream.EdgeStream:
 | 
			
		||||
		return errors.New("TODO(simokawa): handle EdgeStream")
 | 
			
		||||
	default:
 | 
			
		||||
		return errors.New("unsupported Stream type")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								vendor/periph.io/x/periph/host/bcm283x/timer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								vendor/periph.io/x/periph/host/bcm283x/timer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
// 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 bcm283x
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/host/cpu"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ReadTime returns the time on a monotonic 1Mhz clock (1µs resolution).
 | 
			
		||||
//
 | 
			
		||||
// It only works if bcm283x-dma successfully loaded. Otherwise it returns 0.
 | 
			
		||||
func ReadTime() time.Duration {
 | 
			
		||||
	if drvDMA.timerMemory == nil {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	return (time.Duration(drvDMA.timerMemory.high)<<32 | time.Duration(drvDMA.timerMemory.low)) * time.Microsecond
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Nanospin spins the CPU without calling into the kernel code if possible.
 | 
			
		||||
func Nanospin(t time.Duration) {
 | 
			
		||||
	start := ReadTime()
 | 
			
		||||
	if start == 0 {
 | 
			
		||||
		// Use the slow generic version.
 | 
			
		||||
		cpu.Nanospin(t)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	// TODO(maruel): Optimize code path for sub-1µs duration.
 | 
			
		||||
	for ReadTime()-start < t {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// 31:4 reserved
 | 
			
		||||
	timerM3 = 1 << 3 // M3
 | 
			
		||||
	timerM2 = 1 << 2 // M2
 | 
			
		||||
	timerM1 = 1 << 1 // M1
 | 
			
		||||
	timerM0 = 1 << 0 // M0
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Page 173
 | 
			
		||||
type timerCtl uint32
 | 
			
		||||
 | 
			
		||||
// timerMap represents the registers to access the 1Mhz timer.
 | 
			
		||||
//
 | 
			
		||||
// Page 172
 | 
			
		||||
type timerMap struct {
 | 
			
		||||
	ctl  timerCtl // CS
 | 
			
		||||
	low  uint32   // CLO
 | 
			
		||||
	high uint32   // CHI
 | 
			
		||||
	c0   uint32   // 0
 | 
			
		||||
	c1   uint32   // C1
 | 
			
		||||
	c2   uint32   // C2
 | 
			
		||||
	c3   uint32   // C3
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								vendor/periph.io/x/periph/host/beagle/black/black.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/periph.io/x/periph/host/beagle/black/black.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
// 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 black implements headers for the BeagleBone Black and BeagleBone
 | 
			
		||||
// Black Wireless micro-computers.
 | 
			
		||||
//
 | 
			
		||||
// Reference
 | 
			
		||||
//
 | 
			
		||||
// https://beagleboard.org/black
 | 
			
		||||
//
 | 
			
		||||
// Datasheet
 | 
			
		||||
//
 | 
			
		||||
// https://elinux.org/Beagleboard:BeagleBoneBlack
 | 
			
		||||
//
 | 
			
		||||
// https://github.com/CircuitCo/BeagleBone-Black/blob/rev_b/BBB_SRM.pdf
 | 
			
		||||
//
 | 
			
		||||
// https://elinux.org/Beagleboard:Cape_Expansion_Headers
 | 
			
		||||
package black
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/host/distro"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Present returns true if the host is a BeagleBone Black or BeagleBone Black
 | 
			
		||||
// Wireless.
 | 
			
		||||
func Present() bool {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		return strings.HasPrefix(distro.DTModel(), "TI AM335x BeagleBone Black")
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/beagle/black/black_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/beagle/black/black_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// 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 black
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/beagle/black/black_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/beagle/black/black_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !arm
 | 
			
		||||
 | 
			
		||||
package black
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										318
									
								
								vendor/periph.io/x/periph/host/beagle/bone/bone.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								vendor/periph.io/x/periph/host/beagle/bone/bone.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,318 @@
 | 
			
		||||
// 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 bone implements headers J1, P8 and P9 found on many (but not all)
 | 
			
		||||
// BeagleBone micro-computer.
 | 
			
		||||
//
 | 
			
		||||
// In particular, the headers are found on the models using a TI AM335x
 | 
			
		||||
// processor: BeagleBone Black, Black Wireless, Green and Green Wireless.
 | 
			
		||||
//
 | 
			
		||||
// Reference
 | 
			
		||||
//
 | 
			
		||||
// http://beagleboard.org/Support/bone101/#hardware
 | 
			
		||||
package bone
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/conn/pin/pinreg"
 | 
			
		||||
	"periph.io/x/periph/host/beagle/black"
 | 
			
		||||
	"periph.io/x/periph/host/beagle/green"
 | 
			
		||||
	"periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// TODO(maruel): Use specialized am335x or pru implementation once available.
 | 
			
		||||
 | 
			
		||||
// Common pin types on BeagleBones.
 | 
			
		||||
var (
 | 
			
		||||
	PWR_BUT   = &pin.BasicPin{N: "PWR_BUT"}   //
 | 
			
		||||
	RESET_OUT = &pin.BasicPin{N: "RESET_OUT"} // SYS_RESETn
 | 
			
		||||
	VADC      = &pin.BasicPin{N: "VADC"}      // VDD_ADC
 | 
			
		||||
	AIN4      = &pin.BasicPin{N: "AIN4"}      // AIN4
 | 
			
		||||
	AGND      = &pin.BasicPin{N: "AGND"}      // GNDA_ADC
 | 
			
		||||
	AIN6      = &pin.BasicPin{N: "AIN6"}      // AIN6
 | 
			
		||||
	AIN5      = &pin.BasicPin{N: "AIN5"}      // AIN5
 | 
			
		||||
	AIN2      = &pin.BasicPin{N: "AIN2"}      // AIN2
 | 
			
		||||
	AIN3      = &pin.BasicPin{N: "AIN3"}      // AIN3
 | 
			
		||||
	AIN0      = &pin.BasicPin{N: "AIN0"}      // AIN0
 | 
			
		||||
	AIN1      = &pin.BasicPin{N: "AIN1"}      // AIN1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Headers found on BeagleBones.
 | 
			
		||||
var (
 | 
			
		||||
	// Port J1 is the UART port where the default terminal is connected to.
 | 
			
		||||
	J1_1 pin.Pin    = pin.GROUND
 | 
			
		||||
	J1_2 pin.Pin    = pin.INVALID
 | 
			
		||||
	J1_3 pin.Pin    = pin.INVALID
 | 
			
		||||
	J1_4 gpio.PinIO = gpio.INVALID // GPIO42, UART0_RX
 | 
			
		||||
	J1_5 gpio.PinIO = gpio.INVALID // GPIO43, UART0_TX
 | 
			
		||||
	J1_6 pin.Pin    = pin.INVALID
 | 
			
		||||
 | 
			
		||||
	P8_1  pin.Pin    = pin.GROUND
 | 
			
		||||
	P8_2  pin.Pin    = pin.GROUND
 | 
			
		||||
	P8_3  gpio.PinIO = gpio.INVALID // GPIO38, MMC1_DAT6
 | 
			
		||||
	P8_4  gpio.PinIO = gpio.INVALID // GPIO39, MMC1_DAT7
 | 
			
		||||
	P8_5  gpio.PinIO = gpio.INVALID // GPIO34, MMC1_DAT2
 | 
			
		||||
	P8_6  gpio.PinIO = gpio.INVALID // GPIO35, MMC1_DAT3
 | 
			
		||||
	P8_7  gpio.PinIO = gpio.INVALID // GPIO66, Timer4
 | 
			
		||||
	P8_8  gpio.PinIO = gpio.INVALID // GPIO67, Timer7
 | 
			
		||||
	P8_9  gpio.PinIO = gpio.INVALID // GPIO69, Timer5
 | 
			
		||||
	P8_10 gpio.PinIO = gpio.INVALID // GPIO68, Timer6
 | 
			
		||||
	P8_11 gpio.PinIO = gpio.INVALID // GPIO45,
 | 
			
		||||
	P8_12 gpio.PinIO = gpio.INVALID // GPIO44,
 | 
			
		||||
	P8_13 gpio.PinIO = gpio.INVALID // GPIO23, EHRPWM2B
 | 
			
		||||
	P8_14 gpio.PinIO = gpio.INVALID // GPIO26,
 | 
			
		||||
	P8_15 gpio.PinIO = gpio.INVALID // GPIO47,
 | 
			
		||||
	P8_16 gpio.PinIO = gpio.INVALID // GPIO46,
 | 
			
		||||
	P8_17 gpio.PinIO = gpio.INVALID // GPIO27,
 | 
			
		||||
	P8_18 gpio.PinIO = gpio.INVALID // GPIO65,
 | 
			
		||||
	P8_19 gpio.PinIO = gpio.INVALID // GPIO22, EHRPWM2A
 | 
			
		||||
	P8_20 gpio.PinIO = gpio.INVALID // GPIO63, MMC1_CMD
 | 
			
		||||
	P8_21 gpio.PinIO = gpio.INVALID // GPIO62, MMC1_CLK
 | 
			
		||||
	P8_22 gpio.PinIO = gpio.INVALID // GPIO37, MMC1_DAT5
 | 
			
		||||
	P8_23 gpio.PinIO = gpio.INVALID // GPIO36, MMC1_DAT4
 | 
			
		||||
	P8_24 gpio.PinIO = gpio.INVALID // GPIO33, MMC1_DAT1
 | 
			
		||||
	P8_25 gpio.PinIO = gpio.INVALID // GPIO32, MMC1_DAT0
 | 
			
		||||
	P8_26 gpio.PinIO = gpio.INVALID // GPIO61,
 | 
			
		||||
	P8_27 gpio.PinIO = gpio.INVALID // GPIO86, LCD_VSYNC
 | 
			
		||||
	P8_28 gpio.PinIO = gpio.INVALID // GPIO88, LCD_PCLK
 | 
			
		||||
	P8_29 gpio.PinIO = gpio.INVALID // GPIO87, LCD_HSYNC
 | 
			
		||||
	P8_30 gpio.PinIO = gpio.INVALID // GPIO89, LCD_AC_BIAS_E
 | 
			
		||||
	P8_31 gpio.PinIO = gpio.INVALID // GPIO10, LCD_DATA14, UART4_CTS
 | 
			
		||||
	P8_32 gpio.PinIO = gpio.INVALID // GPIO11, LCD_DATA15, UART5_RTS
 | 
			
		||||
	P8_33 gpio.PinIO = gpio.INVALID // GPIO9, LCD_DATA13, UART4_RTS
 | 
			
		||||
	P8_34 gpio.PinIO = gpio.INVALID // GPIO81, LCD_DATA11, EHRPWM1B, UART3_RTS
 | 
			
		||||
	P8_35 gpio.PinIO = gpio.INVALID // GPIO8, LCD_DATA12, UART4_CTS
 | 
			
		||||
	P8_36 gpio.PinIO = gpio.INVALID // GPIO80, LCD_DATA10, EHRPWM1A, UART3_CTS
 | 
			
		||||
	P8_37 gpio.PinIO = gpio.INVALID // GPIO78, LCD_DATA8, UART5_TX
 | 
			
		||||
	P8_38 gpio.PinIO = gpio.INVALID // GPIO79, LCD_DATA9, UART5_RX
 | 
			
		||||
	P8_39 gpio.PinIO = gpio.INVALID // GPIO76, LCD_DATA6
 | 
			
		||||
	P8_40 gpio.PinIO = gpio.INVALID // GPIO77, LCD_DATA7
 | 
			
		||||
	P8_41 gpio.PinIO = gpio.INVALID // GPIO74, LCD_DATA4
 | 
			
		||||
	P8_42 gpio.PinIO = gpio.INVALID // GPIO75, LCD_DATA5
 | 
			
		||||
	P8_43 gpio.PinIO = gpio.INVALID // GPIO72, LCD_DATA2
 | 
			
		||||
	P8_44 gpio.PinIO = gpio.INVALID // GPIO73, LCD_DATA3
 | 
			
		||||
	P8_45 gpio.PinIO = gpio.INVALID // GPIO70, LCD_DATA0, EHRPWM2A
 | 
			
		||||
	P8_46 gpio.PinIO = gpio.INVALID // GPIO71, LCD_DATA1, EHRPWM2B
 | 
			
		||||
 | 
			
		||||
	P9_1  pin.Pin    = pin.GROUND
 | 
			
		||||
	P9_2  pin.Pin    = pin.GROUND
 | 
			
		||||
	P9_3  pin.Pin    = pin.V3_3
 | 
			
		||||
	P9_4  pin.Pin    = pin.V3_3
 | 
			
		||||
	P9_5  pin.Pin    = pin.V5
 | 
			
		||||
	P9_6  pin.Pin    = pin.V5
 | 
			
		||||
	P9_7  pin.Pin    = pin.V5
 | 
			
		||||
	P9_8  pin.Pin    = pin.V5
 | 
			
		||||
	P9_9  pin.Pin    = PWR_BUT      // PWR_BUT
 | 
			
		||||
	P9_10 pin.Pin    = RESET_OUT    // SYS_RESETn
 | 
			
		||||
	P9_11 gpio.PinIO = gpio.INVALID // GPIO30, UART4_RX
 | 
			
		||||
	P9_12 gpio.PinIO = gpio.INVALID // GPIO60
 | 
			
		||||
	P9_13 gpio.PinIO = gpio.INVALID // GPIO31, UART4_TX
 | 
			
		||||
	P9_14 gpio.PinIO = gpio.INVALID // GPIO50, EHRPWM1A
 | 
			
		||||
	P9_15 gpio.PinIO = gpio.INVALID // GPIO48
 | 
			
		||||
	P9_16 gpio.PinIO = gpio.INVALID // GPIO51, EHRPWM1B
 | 
			
		||||
	P9_17 gpio.PinIO = gpio.INVALID // GPIO5, I2C1_SCL, SPI0_CS0
 | 
			
		||||
	P9_18 gpio.PinIO = gpio.INVALID // GPIO4, I2C1_SDA, SPI0_MISO
 | 
			
		||||
	P9_19 gpio.PinIO = gpio.INVALID // GPIO13, I2C2_SCL, UART1_RTS, SPI1_CS1
 | 
			
		||||
	P9_20 gpio.PinIO = gpio.INVALID // GPIO12, I2C2_SDA, UART1_CTS, SPI1_CS0
 | 
			
		||||
	P9_21 gpio.PinIO = gpio.INVALID // GPIO3, EHRPWM0B, I2C2_SCL, UART2_TX, SPI0_MOSI
 | 
			
		||||
	P9_22 gpio.PinIO = gpio.INVALID // GPIO2, EHRPWM0A, I2C2_SDA, UART2_RX, SPI0_CLK
 | 
			
		||||
	P9_23 gpio.PinIO = gpio.INVALID // GPIO49
 | 
			
		||||
	P9_24 gpio.PinIO = gpio.INVALID // GPIO15, I2C1_SCL, UART1_TX
 | 
			
		||||
	P9_25 gpio.PinIO = gpio.INVALID // GPIO117
 | 
			
		||||
	P9_26 gpio.PinIO = gpio.INVALID // GPIO14, I2C1_SDA, UART1_RX
 | 
			
		||||
	P9_27 gpio.PinIO = gpio.INVALID // GPIO115
 | 
			
		||||
	P9_28 gpio.PinIO = gpio.INVALID // GPIO113, ECAPPWM2, SPI1_CS0
 | 
			
		||||
	P9_29 gpio.PinIO = gpio.INVALID // GPIO111, EHRPWM0B, SPI1_MOSI
 | 
			
		||||
	P9_30 gpio.PinIO = gpio.INVALID // GPIO112, SPI1_MISO
 | 
			
		||||
	P9_31 gpio.PinIO = gpio.INVALID // GPIO110, EHRPWM0A, SPI1_CLK
 | 
			
		||||
	P9_32 pin.Pin    = VADC         // VDD_ADC
 | 
			
		||||
	P9_33 pin.Pin    = AIN4         // AIN4
 | 
			
		||||
	P9_34 pin.Pin    = AGND         // GNDA_ADC
 | 
			
		||||
	P9_35 pin.Pin    = AIN6         // AIN6
 | 
			
		||||
	P9_36 pin.Pin    = AIN5         // AIN5
 | 
			
		||||
	P9_37 pin.Pin    = AIN2         // AIN2
 | 
			
		||||
	P9_38 pin.Pin    = AIN3         // AIN3
 | 
			
		||||
	P9_39 pin.Pin    = AIN0         // AIN0
 | 
			
		||||
	P9_40 pin.Pin    = AIN1         // AIN1
 | 
			
		||||
	P9_41 gpio.PinIO = gpio.INVALID // GPIO20
 | 
			
		||||
	P9_42 gpio.PinIO = gpio.INVALID // GPIO7, ECAPPWM0, UART3_TX, SPI1_CS1
 | 
			
		||||
	P9_43 pin.Pin    = pin.GROUND
 | 
			
		||||
	P9_44 pin.Pin    = pin.GROUND
 | 
			
		||||
	P9_45 pin.Pin    = pin.GROUND
 | 
			
		||||
	P9_46 pin.Pin    = pin.GROUND
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Present returns true if the host is a BeagleBone Black/Green or their
 | 
			
		||||
// Wireless version.
 | 
			
		||||
func Present() bool {
 | 
			
		||||
	return black.Present() || green.Present()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// driver implements periph.Driver.
 | 
			
		||||
type driver struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) String() string {
 | 
			
		||||
	return "beaglebone"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Prerequisites() []string {
 | 
			
		||||
	return []string{"am335x"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) After() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Init() (bool, error) {
 | 
			
		||||
	if !Present() {
 | 
			
		||||
		return false, errors.New("BeagleBone board not detected")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	J1_4 = sysfs.Pins[42]
 | 
			
		||||
	J1_5 = sysfs.Pins[43]
 | 
			
		||||
 | 
			
		||||
	P8_3 = sysfs.Pins[38]
 | 
			
		||||
	P8_4 = sysfs.Pins[39]
 | 
			
		||||
	P8_5 = sysfs.Pins[34]
 | 
			
		||||
	P8_6 = sysfs.Pins[35]
 | 
			
		||||
	P8_7 = sysfs.Pins[66]
 | 
			
		||||
	P8_8 = sysfs.Pins[67]
 | 
			
		||||
	P8_9 = sysfs.Pins[69]
 | 
			
		||||
	P8_10 = sysfs.Pins[68]
 | 
			
		||||
	P8_11 = sysfs.Pins[45]
 | 
			
		||||
	P8_12 = sysfs.Pins[44]
 | 
			
		||||
	P8_13 = sysfs.Pins[23]
 | 
			
		||||
	P8_14 = sysfs.Pins[26]
 | 
			
		||||
	P8_15 = sysfs.Pins[47]
 | 
			
		||||
	P8_16 = sysfs.Pins[46]
 | 
			
		||||
	P8_17 = sysfs.Pins[27]
 | 
			
		||||
	P8_18 = sysfs.Pins[65]
 | 
			
		||||
	P8_19 = sysfs.Pins[22]
 | 
			
		||||
	P8_20 = sysfs.Pins[63]
 | 
			
		||||
	P8_21 = sysfs.Pins[62]
 | 
			
		||||
	P8_22 = sysfs.Pins[37]
 | 
			
		||||
	P8_23 = sysfs.Pins[36]
 | 
			
		||||
	P8_24 = sysfs.Pins[33]
 | 
			
		||||
	P8_25 = sysfs.Pins[32]
 | 
			
		||||
	P8_26 = sysfs.Pins[61]
 | 
			
		||||
	P8_27 = sysfs.Pins[86]
 | 
			
		||||
	P8_28 = sysfs.Pins[88]
 | 
			
		||||
	P8_29 = sysfs.Pins[87]
 | 
			
		||||
	P8_30 = sysfs.Pins[89]
 | 
			
		||||
	P8_31 = sysfs.Pins[10]
 | 
			
		||||
	P8_32 = sysfs.Pins[11]
 | 
			
		||||
	P8_33 = sysfs.Pins[9]
 | 
			
		||||
	P8_34 = sysfs.Pins[81]
 | 
			
		||||
	P8_35 = sysfs.Pins[8]
 | 
			
		||||
	P8_36 = sysfs.Pins[80]
 | 
			
		||||
	P8_37 = sysfs.Pins[78]
 | 
			
		||||
	P8_38 = sysfs.Pins[79]
 | 
			
		||||
	P8_39 = sysfs.Pins[76]
 | 
			
		||||
	P8_40 = sysfs.Pins[77]
 | 
			
		||||
	P8_41 = sysfs.Pins[74]
 | 
			
		||||
	P8_42 = sysfs.Pins[75]
 | 
			
		||||
	P8_43 = sysfs.Pins[72]
 | 
			
		||||
	P8_44 = sysfs.Pins[73]
 | 
			
		||||
	P8_45 = sysfs.Pins[70]
 | 
			
		||||
	P8_46 = sysfs.Pins[71]
 | 
			
		||||
 | 
			
		||||
	P9_11 = sysfs.Pins[30]
 | 
			
		||||
	P9_12 = sysfs.Pins[60]
 | 
			
		||||
	P9_13 = sysfs.Pins[31]
 | 
			
		||||
	P9_14 = sysfs.Pins[50]
 | 
			
		||||
	P9_15 = sysfs.Pins[48]
 | 
			
		||||
	P9_16 = sysfs.Pins[51]
 | 
			
		||||
	P9_17 = sysfs.Pins[5]
 | 
			
		||||
	P9_18 = sysfs.Pins[4]
 | 
			
		||||
	P9_19 = sysfs.Pins[13]
 | 
			
		||||
	P9_20 = sysfs.Pins[12]
 | 
			
		||||
	P9_21 = sysfs.Pins[3]
 | 
			
		||||
	P9_22 = sysfs.Pins[2]
 | 
			
		||||
	P9_23 = sysfs.Pins[49]
 | 
			
		||||
	P9_24 = sysfs.Pins[15]
 | 
			
		||||
	P9_25 = sysfs.Pins[117]
 | 
			
		||||
	P9_26 = sysfs.Pins[14]
 | 
			
		||||
	P9_27 = sysfs.Pins[115]
 | 
			
		||||
	P9_28 = sysfs.Pins[113]
 | 
			
		||||
	P9_29 = sysfs.Pins[111]
 | 
			
		||||
	P9_30 = sysfs.Pins[112]
 | 
			
		||||
	P9_31 = sysfs.Pins[110]
 | 
			
		||||
	P9_41 = sysfs.Pins[20]
 | 
			
		||||
	P9_42 = sysfs.Pins[7]
 | 
			
		||||
 | 
			
		||||
	hdr := [][]pin.Pin{{J1_1}, {J1_2}, {J1_3}, {J1_4}, {J1_5}, {J1_6}}
 | 
			
		||||
	if err := pinreg.Register("J1", hdr); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hdr = [][]pin.Pin{
 | 
			
		||||
		{P8_1, P8_2},
 | 
			
		||||
		{P8_3, P8_4},
 | 
			
		||||
		{P8_5, P8_6},
 | 
			
		||||
		{P8_7, P8_8},
 | 
			
		||||
		{P8_9, P8_10},
 | 
			
		||||
		{P8_11, P8_12},
 | 
			
		||||
		{P8_13, P8_14},
 | 
			
		||||
		{P8_15, P8_16},
 | 
			
		||||
		{P8_17, P8_18},
 | 
			
		||||
		{P8_19, P8_20},
 | 
			
		||||
		{P8_21, P8_22},
 | 
			
		||||
		{P8_23, P8_24},
 | 
			
		||||
		{P8_25, P8_26},
 | 
			
		||||
		{P8_27, P8_28},
 | 
			
		||||
		{P8_29, P8_30},
 | 
			
		||||
		{P8_31, P8_32},
 | 
			
		||||
		{P8_33, P8_34},
 | 
			
		||||
		{P8_35, P8_36},
 | 
			
		||||
		{P8_37, P8_38},
 | 
			
		||||
		{P8_39, P8_40},
 | 
			
		||||
		{P8_41, P8_42},
 | 
			
		||||
		{P8_43, P8_44},
 | 
			
		||||
		{P8_45, P8_46},
 | 
			
		||||
	}
 | 
			
		||||
	if err := pinreg.Register("P8", hdr); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hdr = [][]pin.Pin{
 | 
			
		||||
		{P9_1, P9_2},
 | 
			
		||||
		{P9_3, P9_4},
 | 
			
		||||
		{P9_5, P9_6},
 | 
			
		||||
		{P9_7, P9_8},
 | 
			
		||||
		{P9_9, P9_10},
 | 
			
		||||
		{P9_11, P9_12},
 | 
			
		||||
		{P9_13, P9_14},
 | 
			
		||||
		{P9_15, P9_16},
 | 
			
		||||
		{P9_17, P9_18},
 | 
			
		||||
		{P9_19, P9_20},
 | 
			
		||||
		{P9_21, P9_22},
 | 
			
		||||
		{P9_23, P9_24},
 | 
			
		||||
		{P9_25, P9_26},
 | 
			
		||||
		{P9_27, P9_28},
 | 
			
		||||
		{P9_29, P9_30},
 | 
			
		||||
		{P9_31, P9_32},
 | 
			
		||||
		{P9_33, P9_34},
 | 
			
		||||
		{P9_35, P9_36},
 | 
			
		||||
		{P9_37, P9_38},
 | 
			
		||||
		{P9_39, P9_40},
 | 
			
		||||
		{P9_41, P9_42},
 | 
			
		||||
		{P9_43, P9_44},
 | 
			
		||||
		{P9_45, P9_46},
 | 
			
		||||
	}
 | 
			
		||||
	err := pinreg.Register("P9", hdr)
 | 
			
		||||
	return true, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		periph.MustRegister(&drv)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drv driver
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/beagle/bone/bone_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/beagle/bone/bone_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// 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 bone
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/beagle/bone/bone_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/beagle/bone/bone_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !arm
 | 
			
		||||
 | 
			
		||||
package bone
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										95
									
								
								vendor/periph.io/x/periph/host/beagle/green/green.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								vendor/periph.io/x/periph/host/beagle/green/green.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
// 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 green implements headers for the BeagleBone Green and BeagleBone
 | 
			
		||||
// Green Wireless micro-computers.
 | 
			
		||||
//
 | 
			
		||||
// Reference
 | 
			
		||||
//
 | 
			
		||||
// https://beagleboard.org/green
 | 
			
		||||
//
 | 
			
		||||
// https://beagleboard.org/green-wireless
 | 
			
		||||
//
 | 
			
		||||
// Datasheet
 | 
			
		||||
//
 | 
			
		||||
// http://wiki.seeedstudio.com/BeagleBone_Green/
 | 
			
		||||
package green
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/conn/pin/pinreg"
 | 
			
		||||
	"periph.io/x/periph/host/distro"
 | 
			
		||||
	"periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Headers found on BeagleBone Green.
 | 
			
		||||
var (
 | 
			
		||||
	// I2C Groove port.
 | 
			
		||||
	I2C_SCL gpio.PinIO = gpio.INVALID // GPIO13, I2C2_SCL, UART1_RTS, SPI1_CS1
 | 
			
		||||
	I2C_SDA gpio.PinIO = gpio.INVALID // GPIO12, I2C2_SDA, UART1_CTS, SPI1_CS0
 | 
			
		||||
 | 
			
		||||
	// UART Groove port connected to UART2.
 | 
			
		||||
	UART_TX gpio.PinIO = gpio.INVALID // GPIO3, EHRPWM0B, I2C2_SCL, UART2_TX, SPI0_MISO
 | 
			
		||||
	UART_RX gpio.PinIO = gpio.INVALID // GPIO2, EHRPWM0A, I2C2_SDA, UART2_RX, SPI0_CLK
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Present returns true if the host is a BeagleBone Green or BeagleBone Green
 | 
			
		||||
// Wireless.
 | 
			
		||||
func Present() bool {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		return strings.HasPrefix(distro.DTModel(), "TI AM335x BeagleBone Green")
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// driver implements periph.Driver.
 | 
			
		||||
type driver struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) String() string {
 | 
			
		||||
	return "beaglebone-green"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Prerequisites() []string {
 | 
			
		||||
	return []string{"am335x"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) After() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Init() (bool, error) {
 | 
			
		||||
	if !Present() {
 | 
			
		||||
		return false, errors.New("BeagleBone Green board not detected")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	I2C_SDA = sysfs.Pins[12]
 | 
			
		||||
	I2C_SCL = sysfs.Pins[13]
 | 
			
		||||
	hdr := [][]pin.Pin{{pin.GROUND}, {pin.V3_3}, {I2C_SDA}, {I2C_SCL}}
 | 
			
		||||
	if err := pinreg.Register("I2C", hdr); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	UART_TX = sysfs.Pins[3]
 | 
			
		||||
	UART_RX = sysfs.Pins[2]
 | 
			
		||||
	hdr = [][]pin.Pin{{pin.GROUND}, {pin.V3_3}, {UART_TX}, {UART_RX}}
 | 
			
		||||
	if err := pinreg.Register("UART", hdr); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		periph.MustRegister(&drv)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drv driver
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/beagle/green/green_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/beagle/green/green_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// 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 green
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/beagle/green/green_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/beagle/green/green_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !arm
 | 
			
		||||
 | 
			
		||||
package green
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										358
									
								
								vendor/periph.io/x/periph/host/chip/chip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										358
									
								
								vendor/periph.io/x/periph/host/chip/chip.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,358 @@
 | 
			
		||||
// 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 chip
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio/gpioreg"
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/conn/pin/pinreg"
 | 
			
		||||
	"periph.io/x/periph/host/allwinner"
 | 
			
		||||
	"periph.io/x/periph/host/distro"
 | 
			
		||||
	"periph.io/x/periph/host/fs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// C.H.I.P. hardware pins.
 | 
			
		||||
var (
 | 
			
		||||
	TEMP_SENSOR = &pin.BasicPin{N: "TEMP_SENSOR"}
 | 
			
		||||
	PWR_SWITCH  = &pin.BasicPin{N: "PWR_SWITCH"}
 | 
			
		||||
	// XIO "gpio" pins attached to the pcf8574 I²C port extender.
 | 
			
		||||
	XIO0, XIO1, XIO2, XIO3, XIO4, XIO5, XIO6, XIO7 gpio.PinIO
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// The U13 header is opposite the power LED.
 | 
			
		||||
//
 | 
			
		||||
// The alternate pin functionality is described at pages 322-323 of
 | 
			
		||||
// https://github.com/NextThingCo/CHIP-Hardware/raw/master/CHIP%5Bv1_0%5D/CHIPv1_0-BOM-Datasheets/Allwinner%20R8%20User%20Manual%20V1.1.pdf
 | 
			
		||||
var (
 | 
			
		||||
	U13_1  = pin.GROUND     //
 | 
			
		||||
	U13_2  = pin.DC_IN      //
 | 
			
		||||
	U13_3  = pin.V5         // (filtered)
 | 
			
		||||
	U13_4  = pin.GROUND     //
 | 
			
		||||
	U13_5  = pin.V3_3       //
 | 
			
		||||
	U13_6  = TEMP_SENSOR    // Analog temp sensor input
 | 
			
		||||
	U13_7  = pin.V1_8       //
 | 
			
		||||
	U13_8  = pin.BAT_PLUS   // External LiPo battery
 | 
			
		||||
	U13_9  = allwinner.PB16 // I2C1_SDA
 | 
			
		||||
	U13_10 = PWR_SWITCH     // Power button
 | 
			
		||||
	U13_11 = allwinner.PB15 // I2C1_SCL
 | 
			
		||||
	U13_12 = pin.GROUND     //
 | 
			
		||||
	U13_13 = allwinner.X1   // Touch screen X1
 | 
			
		||||
	U13_14 = allwinner.X2   // Touch screen X2
 | 
			
		||||
	U13_15 = allwinner.Y1   // Touch screen Y1
 | 
			
		||||
	U13_16 = allwinner.Y2   // Touch screen Y2
 | 
			
		||||
	U13_17 = allwinner.PD2  // LCD-D2; UART2_TX firmware probe for 1-wire to detect DIP at boot; http://docs.getchip.com/dip.html#dip-identification
 | 
			
		||||
	U13_18 = allwinner.PB2  // PWM0; EINT16
 | 
			
		||||
	U13_19 = allwinner.PD4  // LCD-D4; UART2_CTS
 | 
			
		||||
	U13_20 = allwinner.PD3  // LCD-D3; UART2_RX
 | 
			
		||||
	U13_21 = allwinner.PD6  // LCD-D6
 | 
			
		||||
	U13_22 = allwinner.PD5  // LCD-D5
 | 
			
		||||
	U13_23 = allwinner.PD10 // LCD-D10
 | 
			
		||||
	U13_24 = allwinner.PD7  // LCD-D7
 | 
			
		||||
	U13_25 = allwinner.PD12 // LCD-D12
 | 
			
		||||
	U13_26 = allwinner.PD11 // LCD-D11
 | 
			
		||||
	U13_27 = allwinner.PD14 // LCD-D14
 | 
			
		||||
	U13_28 = allwinner.PD13 // LCD-D13
 | 
			
		||||
	U13_29 = allwinner.PD18 // LCD-D18
 | 
			
		||||
	U13_30 = allwinner.PD15 // LCD-D15
 | 
			
		||||
	U13_31 = allwinner.PD20 // LCD-D20
 | 
			
		||||
	U13_32 = allwinner.PD19 // LCD-D19
 | 
			
		||||
	U13_33 = allwinner.PD22 // LCD-D22
 | 
			
		||||
	U13_34 = allwinner.PD21 // LCD-D21
 | 
			
		||||
	U13_35 = allwinner.PD24 // LCD-CLK
 | 
			
		||||
	U13_36 = allwinner.PD23 // LCD-D23
 | 
			
		||||
	U13_37 = allwinner.PD26 // LCD-VSYNC
 | 
			
		||||
	U13_38 = allwinner.PD27 // LCD-HSYNC
 | 
			
		||||
	U13_39 = pin.GROUND     //
 | 
			
		||||
	U13_40 = allwinner.PD25 // LCD-DE: RGB666 data
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// The U14 header is right next to the power LED.
 | 
			
		||||
var (
 | 
			
		||||
	U14_1  = pin.GROUND         //
 | 
			
		||||
	U14_2  = pin.V5             // (filtered)
 | 
			
		||||
	U14_3  = allwinner.PG3      // UART1_TX; EINT3
 | 
			
		||||
	U14_4  = allwinner.HP_LEFT  // Headphone left output
 | 
			
		||||
	U14_5  = allwinner.PG4      // UART1_RX; EINT4
 | 
			
		||||
	U14_6  = allwinner.HP_COM   // Headphone amp out
 | 
			
		||||
	U14_7  = allwinner.FEL      // Boot mode selection
 | 
			
		||||
	U14_8  = allwinner.HP_RIGHT // Headphone right output
 | 
			
		||||
	U14_9  = pin.V3_3           //
 | 
			
		||||
	U14_10 = allwinner.MIC_GND  // Microphone ground
 | 
			
		||||
	U14_11 = allwinner.KEY_ADC  // LRADC Low res analog to digital
 | 
			
		||||
	U14_12 = allwinner.MIC_IN   // Microphone input
 | 
			
		||||
	U14_13 = XIO0               // gpio via I²C controller
 | 
			
		||||
	U14_14 = XIO1               // gpio via I²C controller
 | 
			
		||||
	U14_15 = XIO2               // gpio via I²C controller
 | 
			
		||||
	U14_16 = XIO3               // gpio via I²C controller
 | 
			
		||||
	U14_17 = XIO4               // gpio via I²C controller
 | 
			
		||||
	U14_18 = XIO5               // gpio via I²C controller
 | 
			
		||||
	U14_19 = XIO6               // gpio via I²C controller
 | 
			
		||||
	U14_20 = XIO7               // gpio via I²C controller
 | 
			
		||||
	U14_21 = pin.GROUND         //
 | 
			
		||||
	U14_22 = pin.GROUND         //
 | 
			
		||||
	U14_23 = allwinner.PG1      // GPS_CLK; AP-EINT1
 | 
			
		||||
	U14_24 = allwinner.PB3      // IR_TX; AP-EINT3 (EINT17)
 | 
			
		||||
	U14_25 = allwinner.PB18     // I2C2_SDA
 | 
			
		||||
	U14_26 = allwinner.PB17     // I2C2_SCL
 | 
			
		||||
	U14_27 = allwinner.PE0      // CSIPCK: CMOS serial interface; SPI2_CS0; EINT14
 | 
			
		||||
	U14_28 = allwinner.PE1      // CSICK: CMOS serial interface; SPI2_CLK; EINT15
 | 
			
		||||
	U14_29 = allwinner.PE2      // CSIHSYNC; SPI2_MOSI
 | 
			
		||||
	U14_30 = allwinner.PE3      // CSIVSYNC; SPI2_MISO
 | 
			
		||||
	U14_31 = allwinner.PE4      // CSID0
 | 
			
		||||
	U14_32 = allwinner.PE5      // CSID1
 | 
			
		||||
	U14_33 = allwinner.PE6      // CSID2
 | 
			
		||||
	U14_34 = allwinner.PE7      // CSID3
 | 
			
		||||
	U14_35 = allwinner.PE8      // CSID4
 | 
			
		||||
	U14_36 = allwinner.PE9      // CSID5
 | 
			
		||||
	U14_37 = allwinner.PE10     // CSID6; UART1_RX
 | 
			
		||||
	U14_38 = allwinner.PE11     // CSID7; UART1_TX
 | 
			
		||||
	U14_39 = pin.GROUND         //
 | 
			
		||||
	U14_40 = pin.GROUND         //
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Present returns true if running on a NextThing Co's C.H.I.P. board.
 | 
			
		||||
//
 | 
			
		||||
// It looks for "C.H.I.P" in the device tree. The following information is
 | 
			
		||||
// expected in the device dtree:
 | 
			
		||||
//   root@chip2:/proc/device-tree# od -c compatible
 | 
			
		||||
//   0000000   n   e   x   t   t   h   i   n   g   ,   c   h   i   p  \0   a
 | 
			
		||||
//   0000020   l   l   w   i   n   n   e   r   ,   s   u   n   5   i   -   r
 | 
			
		||||
//   0000040   8  \0
 | 
			
		||||
//   root@chip2:/proc/device-tree# od -c model
 | 
			
		||||
//   0000000   N   e   x   t   T   h   i   n   g       C   .   H   .   I   .
 | 
			
		||||
//   0000020   P   .  \0
 | 
			
		||||
func Present() bool {
 | 
			
		||||
	return strings.Contains(distro.DTModel(), "C.H.I.P")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// aliases is a list of aliases for the various gpio pins, this allows users to
 | 
			
		||||
// refer to pins using the documented and labeled names instead of some GPIOnnn
 | 
			
		||||
// name. The map key is the alias and the value is the real pin name.
 | 
			
		||||
var aliases = map[string]string{
 | 
			
		||||
	"AP-EINT1":  "PG1",
 | 
			
		||||
	"AP-EINT3":  "PB3",
 | 
			
		||||
	"CSIPCK":    "PE0",
 | 
			
		||||
	"CSIHSYNC":  "PE2",
 | 
			
		||||
	"CSID0":     "PE4",
 | 
			
		||||
	"CSID2":     "PE6",
 | 
			
		||||
	"CSID4":     "PE8",
 | 
			
		||||
	"CSID6":     "PE10",
 | 
			
		||||
	"CSICK":     "PE1",
 | 
			
		||||
	"CSIVSYNC":  "PE3",
 | 
			
		||||
	"CSID1":     "PE5",
 | 
			
		||||
	"CSID3":     "PE7",
 | 
			
		||||
	"CSID5":     "PE9",
 | 
			
		||||
	"CSID7":     "PE11",
 | 
			
		||||
	"LCD-CLK":   "PD24",
 | 
			
		||||
	"LCD-D10":   "PD10",
 | 
			
		||||
	"LCD-D11":   "PD11",
 | 
			
		||||
	"LCD-D12":   "PD12",
 | 
			
		||||
	"LCD-D13":   "PD13",
 | 
			
		||||
	"LCD-D14":   "PD14",
 | 
			
		||||
	"LCD-D15":   "PD15",
 | 
			
		||||
	"LCD-D18":   "PD18",
 | 
			
		||||
	"LCD-D19":   "PD19",
 | 
			
		||||
	"LCD-D2":    "PD2",
 | 
			
		||||
	"LCD-D20":   "PD20",
 | 
			
		||||
	"LCD-D21":   "PD21",
 | 
			
		||||
	"LCD-D22":   "PD22",
 | 
			
		||||
	"LCD-D23":   "PD23",
 | 
			
		||||
	"LCD-D3":    "PD3",
 | 
			
		||||
	"LCD-D4":    "PD4",
 | 
			
		||||
	"LCD-D5":    "PD5",
 | 
			
		||||
	"LCD-D6":    "PD6",
 | 
			
		||||
	"LCD-D7":    "PD7",
 | 
			
		||||
	"LCD-DE":    "PD25",
 | 
			
		||||
	"LCD-HSYNC": "PD27",
 | 
			
		||||
	"LCD-VSYNC": "PD26",
 | 
			
		||||
	"TWI1-SCK":  "PB15",
 | 
			
		||||
	"TWI1-SDA":  "PB16",
 | 
			
		||||
	"TWI2-SCK":  "PB17",
 | 
			
		||||
	"TWI2-SDA":  "PB18",
 | 
			
		||||
	"UART1-RX":  "PG4",
 | 
			
		||||
	"UART1-TX":  "PG3",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	// These are initialized later by the driver.
 | 
			
		||||
	XIO0 = gpio.INVALID
 | 
			
		||||
	XIO1 = gpio.INVALID
 | 
			
		||||
	XIO2 = gpio.INVALID
 | 
			
		||||
	XIO3 = gpio.INVALID
 | 
			
		||||
	XIO4 = gpio.INVALID
 | 
			
		||||
	XIO5 = gpio.INVALID
 | 
			
		||||
	XIO6 = gpio.INVALID
 | 
			
		||||
	XIO7 = gpio.INVALID
 | 
			
		||||
	// These must be reinitialized.
 | 
			
		||||
	U14_13 = XIO0
 | 
			
		||||
	U14_14 = XIO1
 | 
			
		||||
	U14_15 = XIO2
 | 
			
		||||
	U14_16 = XIO3
 | 
			
		||||
	U14_17 = XIO4
 | 
			
		||||
	U14_18 = XIO5
 | 
			
		||||
	U14_19 = XIO6
 | 
			
		||||
	U14_20 = XIO7
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// findXIOBase calculates the base of the XIO-P? gpio pins as explained in
 | 
			
		||||
// http://docs.getchip.com/chip.html#kernel-4-3-vs-4-4-gpio-how-to-tell-the-difference
 | 
			
		||||
//
 | 
			
		||||
// The XIO-P? sysfs mapped pin number changed in kernel 4.3, 4.4.11 and again
 | 
			
		||||
// in 4.4.13 so it is better to query sysfs.
 | 
			
		||||
func findXIOBase() int {
 | 
			
		||||
	chips, err := filepath.Glob("/sys/class/gpio/gpiochip*/label")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	for _, item := range chips {
 | 
			
		||||
		f, err := fs.Open(item, os.O_RDONLY)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		b, err := ioutil.ReadAll(f)
 | 
			
		||||
		if err1 := f.Close(); err == nil {
 | 
			
		||||
			err = err1
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if string(b) == "pcf8574a\n" {
 | 
			
		||||
			id, err := strconv.Atoi(filepath.Base(filepath.Dir(item))[8:])
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return -1
 | 
			
		||||
			}
 | 
			
		||||
			return id
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// driver implements drivers.Driver.
 | 
			
		||||
type driver struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) String() string {
 | 
			
		||||
	return "chip"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Prerequisites() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) After() []string {
 | 
			
		||||
	// has allwinner cpu, needs sysfs for XIO0-XIO7 "gpio" pins
 | 
			
		||||
	return []string{"allwinner-gpio", "sysfs-gpio"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Init() (bool, error) {
 | 
			
		||||
	if !Present() {
 | 
			
		||||
		return false, errors.New("NextThing Co. CHIP board not detected")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	base := findXIOBase()
 | 
			
		||||
	if base == -1 {
 | 
			
		||||
		return true, errors.New("couldn't find XIO pins base number")
 | 
			
		||||
	}
 | 
			
		||||
	for i := 0; i < 8; i++ {
 | 
			
		||||
		aliases[fmt.Sprintf("XIO-P%d", i)] = fmt.Sprintf("GPIO%d", base+i)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// At this point the sysfs driver has initialized and discovered its pins,
 | 
			
		||||
	// we can now hook-up the appropriate CHIP pins to sysfs gpio pins.
 | 
			
		||||
	for alias, real := range aliases {
 | 
			
		||||
		if err := gpioreg.RegisterAlias(alias, real); err != nil {
 | 
			
		||||
			return true, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// These must be explicitly initialized.
 | 
			
		||||
	XIO0 = gpioreg.ByName("XIO-P0")
 | 
			
		||||
	XIO1 = gpioreg.ByName("XIO-P1")
 | 
			
		||||
	XIO2 = gpioreg.ByName("XIO-P2")
 | 
			
		||||
	XIO3 = gpioreg.ByName("XIO-P3")
 | 
			
		||||
	XIO4 = gpioreg.ByName("XIO-P4")
 | 
			
		||||
	XIO5 = gpioreg.ByName("XIO-P5")
 | 
			
		||||
	XIO6 = gpioreg.ByName("XIO-P6")
 | 
			
		||||
	XIO7 = gpioreg.ByName("XIO-P7")
 | 
			
		||||
	U14_13 = XIO0
 | 
			
		||||
	U14_14 = XIO1
 | 
			
		||||
	U14_15 = XIO2
 | 
			
		||||
	U14_16 = XIO3
 | 
			
		||||
	U14_17 = XIO4
 | 
			
		||||
	U14_18 = XIO5
 | 
			
		||||
	U14_19 = XIO6
 | 
			
		||||
	U14_20 = XIO7
 | 
			
		||||
 | 
			
		||||
	// U13 is one of the 20x2 connectors.
 | 
			
		||||
	U13 := [][]pin.Pin{
 | 
			
		||||
		{U13_1, U13_2},
 | 
			
		||||
		{U13_3, U13_4},
 | 
			
		||||
		{U13_5, U13_6},
 | 
			
		||||
		{U13_7, U13_8},
 | 
			
		||||
		{gpioreg.ByName("TWI1-SDA"), U13_10},
 | 
			
		||||
		{gpioreg.ByName("TWI1-SCK"), U13_12},
 | 
			
		||||
		{U13_13, U13_14},
 | 
			
		||||
		{U13_15, U13_16},
 | 
			
		||||
		{gpioreg.ByName("LCD-D2"), gpioreg.ByName("PWM0")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D4"), gpioreg.ByName("LCD-D3")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D6"), gpioreg.ByName("LCD-D5")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D10"), gpioreg.ByName("LCD-D7")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D12"), gpioreg.ByName("LCD-D11")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D14"), gpioreg.ByName("LCD-D13")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D18"), gpioreg.ByName("LCD-D15")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D20"), gpioreg.ByName("LCD-D19")},
 | 
			
		||||
		{gpioreg.ByName("LCD-D22"), gpioreg.ByName("LCD-D21")},
 | 
			
		||||
		{gpioreg.ByName("LCD-CLK"), gpioreg.ByName("LCD-D23")},
 | 
			
		||||
		{gpioreg.ByName("LCD-VSYNC"), gpioreg.ByName("LCD-HSYNC")},
 | 
			
		||||
		{U13_39, gpioreg.ByName("LCD-DE")},
 | 
			
		||||
	}
 | 
			
		||||
	if err := pinreg.Register("U13", U13); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// U14 is one of the 20x2 connectors.
 | 
			
		||||
	U14 := [][]pin.Pin{
 | 
			
		||||
		{U14_1, U14_2},
 | 
			
		||||
		{gpioreg.ByName("UART1-TX"), U14_4},
 | 
			
		||||
		{gpioreg.ByName("UART1-RX"), U14_6},
 | 
			
		||||
		{U14_7, U14_8},
 | 
			
		||||
		{U14_9, U14_10},
 | 
			
		||||
		{U14_11, U14_12}, // TODO(maruel): switch to LRADC once analog support is added
 | 
			
		||||
		{U14_13, U14_14},
 | 
			
		||||
		{U14_15, U14_16},
 | 
			
		||||
		{U14_17, U14_18},
 | 
			
		||||
		{U14_19, U14_20},
 | 
			
		||||
		{U14_21, U14_22},
 | 
			
		||||
		{gpioreg.ByName("AP-EINT1"), gpioreg.ByName("AP-EINT3")},
 | 
			
		||||
		{gpioreg.ByName("TWI2-SDA"), gpioreg.ByName("TWI2-SCK")},
 | 
			
		||||
		{gpioreg.ByName("CSIPCK"), gpioreg.ByName("CSICK")},
 | 
			
		||||
		{gpioreg.ByName("CSIHSYNC"), gpioreg.ByName("CSIVSYNC")},
 | 
			
		||||
		{gpioreg.ByName("CSID0"), gpioreg.ByName("CSID1")},
 | 
			
		||||
		{gpioreg.ByName("CSID2"), gpioreg.ByName("CSID3")},
 | 
			
		||||
		{gpioreg.ByName("CSID4"), gpioreg.ByName("CSID5")},
 | 
			
		||||
		{gpioreg.ByName("CSID6"), gpioreg.ByName("CSID7")},
 | 
			
		||||
		{U14_39, U14_40},
 | 
			
		||||
	}
 | 
			
		||||
	return true, pinreg.Register("U14", U14)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		periph.MustRegister(&drv)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drv driver
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/chip/chip_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/chip/chip_arm.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 chip
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/chip/chip_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/chip/chip_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !arm
 | 
			
		||||
 | 
			
		||||
package chip
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										30
									
								
								vendor/periph.io/x/periph/host/chip/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								vendor/periph.io/x/periph/host/chip/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
// 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 chip contains header definitions for NextThing Co's C.H.I.P. board.
 | 
			
		||||
//
 | 
			
		||||
// CHIP uses the Allwinner R8 processor and thus the allwinner host package is
 | 
			
		||||
// automatically imported.
 | 
			
		||||
//
 | 
			
		||||
// This package exports the U13 header, which is opposite the power LED, and
 | 
			
		||||
// U14, which is right next to the power LED. Most of the pins are usable as
 | 
			
		||||
// GPIO and are directly to the processor. These can use memory-mapped GPIO,
 | 
			
		||||
// which is very fast. The XIO-P0 through XIO-P7 pins are attached to a pcf8574
 | 
			
		||||
// I²C expander which has the result that all accesses to these pins have to go
 | 
			
		||||
// through the kernel and the I²C bus protocol, i.e., they're slow.
 | 
			
		||||
//
 | 
			
		||||
// GPIO edge detection (using interrupts) is only supported on a few of the
 | 
			
		||||
// processor's pins: AP-EINT1, AP-EINT3, CSIPCK, and CSICK. Edge detection is
 | 
			
		||||
// also supported on the XIO pins, but this feature is rather limited due to
 | 
			
		||||
// the device and the driver (for example, the driver interrupts on all edges).
 | 
			
		||||
//
 | 
			
		||||
// References
 | 
			
		||||
//
 | 
			
		||||
// http://www.chip-community.org/index.php/Hardware_Information
 | 
			
		||||
//
 | 
			
		||||
// http://docs.getchip.com/chip.html#chip-hardware
 | 
			
		||||
//
 | 
			
		||||
// A graphical view of the board headers is available at:
 | 
			
		||||
// http://docs.getchip.com/chip.html#pin-headers
 | 
			
		||||
package chip
 | 
			
		||||
							
								
								
									
										83
									
								
								vendor/periph.io/x/periph/host/cpu/cpu.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								vendor/periph.io/x/periph/host/cpu/cpu.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
// 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 cpu
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph/host/fs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// MaxSpeed returns the processor maximum speed in Hz.
 | 
			
		||||
//
 | 
			
		||||
// Returns 0 if it couldn't be calculated.
 | 
			
		||||
func MaxSpeed() int64 {
 | 
			
		||||
	if isLinux {
 | 
			
		||||
		return getMaxSpeedLinux()
 | 
			
		||||
	}
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Nanospin spins for a short amount of time doing a busy loop.
 | 
			
		||||
//
 | 
			
		||||
// This function should be called with durations of 10µs or less.
 | 
			
		||||
func Nanospin(d time.Duration) {
 | 
			
		||||
	// TODO(maruel): Use runtime.LockOSThread()?
 | 
			
		||||
	if isLinux {
 | 
			
		||||
		nanospinLinux(d)
 | 
			
		||||
	} else {
 | 
			
		||||
		nanospinTime(d)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu       sync.Mutex
 | 
			
		||||
	maxSpeed int64 = -1
 | 
			
		||||
	openFile       = openFileOrig
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func openFileOrig(path string, flag int) (io.ReadCloser, error) {
 | 
			
		||||
	f, err := fs.Open(path, flag)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return f, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getMaxSpeedLinux() int64 {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if maxSpeed == -1 {
 | 
			
		||||
		maxSpeed = 0
 | 
			
		||||
		if f, err := openFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", os.O_RDONLY); err == nil {
 | 
			
		||||
			defer f.Close()
 | 
			
		||||
			if b, err := ioutil.ReadAll(f); err == nil {
 | 
			
		||||
				s := strings.TrimSpace(string(b))
 | 
			
		||||
				if i, err := strconv.ParseInt(s, 10, 64); err == nil {
 | 
			
		||||
					// Weirdly, the speed is listed as khz. :(
 | 
			
		||||
					maxSpeed = i * 1000
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return maxSpeed
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func nanospinTime(d time.Duration) {
 | 
			
		||||
	// TODO(maruel): That's not optimal; it's actually pretty bad.
 | 
			
		||||
	// time.Sleep() sleeps for really too long, calling it repeatedly with
 | 
			
		||||
	// minimal value will give the caller a wake rate of 5KHz or so, depending on
 | 
			
		||||
	// the host. This makes it useless for bitbanging protocol implementations.
 | 
			
		||||
	for start := time.Now(); time.Since(start) < d; {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								vendor/periph.io/x/periph/host/cpu/cpu_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								vendor/periph.io/x/periph/host/cpu/cpu_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
// 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 cpu
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const isLinux = true
 | 
			
		||||
 | 
			
		||||
func nanospinLinux(d time.Duration) {
 | 
			
		||||
	// runtime.nanotime() is not exported so it cannot be used to busy loop for
 | 
			
		||||
	// very short sleep (10µs or less).
 | 
			
		||||
	time := syscall.NsecToTimespec(d.Nanoseconds())
 | 
			
		||||
	leftover := syscall.Timespec{}
 | 
			
		||||
	for syscall.Nanosleep(&time, &leftover) != nil {
 | 
			
		||||
		time = leftover
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								vendor/periph.io/x/periph/host/cpu/cpu_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/periph.io/x/periph/host/cpu/cpu_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package cpu
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
 | 
			
		||||
const isLinux = false
 | 
			
		||||
 | 
			
		||||
func nanospinLinux(d time.Duration) {
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								vendor/periph.io/x/periph/host/cpu/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								vendor/periph.io/x/periph/host/cpu/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
// 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 cpu implements functions relating to the host CPU itself.
 | 
			
		||||
package cpu
 | 
			
		||||
							
								
								
									
										61
									
								
								vendor/periph.io/x/periph/host/distro/devtree.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								vendor/periph.io/x/periph/host/distro/devtree.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
// 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 distro
 | 
			
		||||
 | 
			
		||||
// DTModel returns platform model info from the Linux device tree (/proc/device-tree/model), and
 | 
			
		||||
// returns "unknown" on non-linux systems or if the file is missing.
 | 
			
		||||
func DTModel() string {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	if dtModel == "" {
 | 
			
		||||
		dtModel = "<unknown>"
 | 
			
		||||
		if isLinux {
 | 
			
		||||
			dtModel = makeDTModelLinux()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return dtModel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DTCompatible returns platform compatibility info from the Linux device tree
 | 
			
		||||
// (/proc/device-tree/compatible), and returns []{"unknown"} on non-linux systems or if the file is
 | 
			
		||||
// missing.
 | 
			
		||||
func DTCompatible() []string {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	if dtCompatible == nil {
 | 
			
		||||
		dtCompatible = []string{}
 | 
			
		||||
		if isLinux {
 | 
			
		||||
			dtCompatible = makeDTCompatible()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return dtCompatible
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	dtModel      string   // cached /proc/device-tree/model
 | 
			
		||||
	dtCompatible []string // cached /proc/device-tree/compatible
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func makeDTModelLinux() string {
 | 
			
		||||
	// Read model from device tree.
 | 
			
		||||
	if bytes, err := readFile("/proc/device-tree/model"); err == nil {
 | 
			
		||||
		if model := splitNull(bytes); len(model) > 0 {
 | 
			
		||||
			return model[0]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return "<unknown>"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func makeDTCompatible() []string {
 | 
			
		||||
	// Read compatible from device tree.
 | 
			
		||||
	if bytes, err := readFile("/proc/device-tree/compatible"); err == nil {
 | 
			
		||||
		return splitNull(bytes)
 | 
			
		||||
	}
 | 
			
		||||
	return []string{}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										189
									
								
								vendor/periph.io/x/periph/host/distro/distro.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								vendor/periph.io/x/periph/host/distro/distro.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
// 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 distro implements common functionality to auto-detect features on
 | 
			
		||||
// the host; generally about linux distributions.
 | 
			
		||||
//
 | 
			
		||||
// Most of the functions exported as in the form IsFoo() where Foo is a linux
 | 
			
		||||
// distribution.
 | 
			
		||||
package distro
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"unicode"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// IsArmbian returns true if running on a Armbian distribution.
 | 
			
		||||
//
 | 
			
		||||
// http://www.armbian.com/
 | 
			
		||||
func IsArmbian() bool {
 | 
			
		||||
	if isArm && isLinux {
 | 
			
		||||
		// Armbian presents itself as debian in /etc/os-release so OSRelease()
 | 
			
		||||
		// cannot be used..
 | 
			
		||||
		_, err := os.Stat("/etc/armbian.txt")
 | 
			
		||||
		return err == nil
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsDebian returns true if running on an Debian derived distribution.
 | 
			
		||||
//
 | 
			
		||||
// This function returns true on both Armbian, Raspbian and Ubuntu.
 | 
			
		||||
//
 | 
			
		||||
// https://debian.org/
 | 
			
		||||
func IsDebian() bool {
 | 
			
		||||
	if isLinux {
 | 
			
		||||
		// http://0pointer.de/public/systemd-man/os-release.html#ID_LIKE=
 | 
			
		||||
		if OSRelease()["ID"] == "debian" {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
		for _, part := range strings.Split(OSRelease()["ID_LIKE"], " ") {
 | 
			
		||||
			if part == "debian" {
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsRaspbian returns true if running on a Raspbian distribution.
 | 
			
		||||
//
 | 
			
		||||
// https://raspbian.org/
 | 
			
		||||
func IsRaspbian() bool {
 | 
			
		||||
	if isArm && isLinux {
 | 
			
		||||
		return OSRelease()["ID"] == "raspbian"
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsUbuntu returns true if running on an Ubuntu derived distribution.
 | 
			
		||||
//
 | 
			
		||||
// https://ubuntu.com/
 | 
			
		||||
func IsUbuntu() bool {
 | 
			
		||||
	if isLinux {
 | 
			
		||||
		return OSRelease()["ID"] == "ubuntu"
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OSRelease returns parsed data from /etc/os-release.
 | 
			
		||||
//
 | 
			
		||||
// For more information, see
 | 
			
		||||
// http://0pointer.de/public/systemd-man/os-release.html
 | 
			
		||||
func OSRelease() map[string]string {
 | 
			
		||||
	if isLinux {
 | 
			
		||||
		return makeOSReleaseLinux()
 | 
			
		||||
	}
 | 
			
		||||
	return osRelease
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CPU
 | 
			
		||||
 | 
			
		||||
// CPUInfo returns parsed data from /proc/cpuinfo.
 | 
			
		||||
func CPUInfo() map[string]string {
 | 
			
		||||
	if isLinux {
 | 
			
		||||
		return makeCPUInfoLinux()
 | 
			
		||||
	}
 | 
			
		||||
	return cpuInfo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu        sync.Mutex
 | 
			
		||||
	cpuInfo   map[string]string
 | 
			
		||||
	osRelease map[string]string
 | 
			
		||||
	readFile  = ioutil.ReadFile
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func splitSemiColon(content string) map[string]string {
 | 
			
		||||
	// Strictly speaking this format isn't ok, there can be multiple group.
 | 
			
		||||
	out := map[string]string{}
 | 
			
		||||
	for _, line := range strings.Split(content, "\n") {
 | 
			
		||||
		parts := strings.SplitN(line, ":", 2)
 | 
			
		||||
		if len(parts) != 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// This format may have space around the ':'.
 | 
			
		||||
		key := strings.TrimRightFunc(parts[0], unicode.IsSpace)
 | 
			
		||||
		if len(key) == 0 || key[0] == '#' {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// Ignore duplicate keys.
 | 
			
		||||
		// TODO(maruel): Keep them all.
 | 
			
		||||
		if _, ok := out[key]; !ok {
 | 
			
		||||
			// Trim on both side, trailing space was observed on "Features" value.
 | 
			
		||||
			out[key] = strings.TrimFunc(parts[1], unicode.IsSpace)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func splitStrict(content string) map[string]string {
 | 
			
		||||
	out := map[string]string{}
 | 
			
		||||
	for _, line := range strings.Split(content, "\n") {
 | 
			
		||||
		parts := strings.SplitN(line, "=", 2)
 | 
			
		||||
		if len(parts) != 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		key := parts[0]
 | 
			
		||||
		if len(key) == 0 || key[0] == '#' {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// Overwrite previous key.
 | 
			
		||||
		value := parts[1]
 | 
			
		||||
		if len(value) > 2 && value[0] == '"' && value[len(value)-1] == '"' {
 | 
			
		||||
			// Not exactly 100% right but #closeenough. See for more details
 | 
			
		||||
			// https://www.freedesktop.org/software/systemd/man/os-release.html
 | 
			
		||||
			var err error
 | 
			
		||||
			value, err = strconv.Unquote(value)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		out[key] = value
 | 
			
		||||
	}
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// splitNull returns the null-terminated strings in the data
 | 
			
		||||
func splitNull(data []byte) []string {
 | 
			
		||||
	ss := strings.Split(string(data), "\x00")
 | 
			
		||||
	// The last string is typically null-terminated, so remove empty string
 | 
			
		||||
	// from end of array.
 | 
			
		||||
	if len(ss) > 0 && len(ss[len(ss)-1]) == 0 {
 | 
			
		||||
		ss = ss[:len(ss)-1]
 | 
			
		||||
	}
 | 
			
		||||
	return ss
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func makeCPUInfoLinux() map[string]string {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if cpuInfo == nil {
 | 
			
		||||
		cpuInfo = map[string]string{}
 | 
			
		||||
		if bytes, err := readFile("/proc/cpuinfo"); err == nil {
 | 
			
		||||
			cpuInfo = splitSemiColon(string(bytes))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return cpuInfo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func makeOSReleaseLinux() map[string]string {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	defer mu.Unlock()
 | 
			
		||||
	if osRelease == nil {
 | 
			
		||||
		// This file may not exist on older distros. Send a PR if you want to have
 | 
			
		||||
		// a specific fallback.
 | 
			
		||||
		osRelease = map[string]string{}
 | 
			
		||||
		if bytes, err := readFile("/etc/os-release"); err == nil {
 | 
			
		||||
			osRelease = splitStrict(string(bytes))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return osRelease
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/distro/distro_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/distro/distro_arm.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 distro
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/distro/distro_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/distro/distro_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build arm64
 | 
			
		||||
 | 
			
		||||
package distro
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/distro/distro_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/distro/distro_linux.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 distro
 | 
			
		||||
 | 
			
		||||
const isLinux = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/distro/distro_nonarm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/distro/distro_nonarm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !arm,!arm64
 | 
			
		||||
 | 
			
		||||
package distro
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/distro/distro_nonlinux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/distro/distro_nonlinux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package distro
 | 
			
		||||
 | 
			
		||||
const isLinux = false
 | 
			
		||||
							
								
								
									
										10
									
								
								vendor/periph.io/x/periph/host/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/periph.io/x/periph/host/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Package host defines the host itself.
 | 
			
		||||
//
 | 
			
		||||
// The host is the machine where this code is running.
 | 
			
		||||
//
 | 
			
		||||
// Subpackages contain the drivers that are loaded automatically.
 | 
			
		||||
package host
 | 
			
		||||
							
								
								
									
										100
									
								
								vendor/periph.io/x/periph/host/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								vendor/periph.io/x/periph/host/fs/fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
// 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 fs provides access to the file system on the host.
 | 
			
		||||
//
 | 
			
		||||
// It exposes ioctl syscall and epoll in an OS agnostic way and permits
 | 
			
		||||
// completely disabling file access to lock down unit tests.
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"os"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Ioctler is a file handle that supports ioctl calls.
 | 
			
		||||
type Ioctler interface {
 | 
			
		||||
	// Ioctl sends a linux ioctl on the file handle.
 | 
			
		||||
	//
 | 
			
		||||
	// op is effectively an uint32. op is expected to be encoded in the format on
 | 
			
		||||
	// x64. ARM happens to share the same format.
 | 
			
		||||
	Ioctl(op uint, data uintptr) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Open opens a file.
 | 
			
		||||
//
 | 
			
		||||
// Returns an error if Inhibit() was called.
 | 
			
		||||
func Open(path string, flag int) (*File, error) {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	if inhibited {
 | 
			
		||||
		mu.Unlock()
 | 
			
		||||
		return nil, errors.New("file I/O is inhibited")
 | 
			
		||||
	}
 | 
			
		||||
	used = true
 | 
			
		||||
	mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	f, err := os.OpenFile(path, flag, 0600)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &File{f}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Inhibit inhibits any future file I/O. It panics if any file was opened up to
 | 
			
		||||
// now.
 | 
			
		||||
//
 | 
			
		||||
// It should only be called in unit tests.
 | 
			
		||||
func Inhibit() {
 | 
			
		||||
	mu.Lock()
 | 
			
		||||
	inhibited = true
 | 
			
		||||
	if used {
 | 
			
		||||
		panic("calling Inhibit() while files were already opened")
 | 
			
		||||
	}
 | 
			
		||||
	mu.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// File is a superset of os.File.
 | 
			
		||||
type File struct {
 | 
			
		||||
	*os.File
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Ioctl sends an ioctl to the file handle.
 | 
			
		||||
func (f *File) Ioctl(op uint, data uintptr) error {
 | 
			
		||||
	return ioctl(f.Fd(), op, data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Event is a file system event.
 | 
			
		||||
type Event struct {
 | 
			
		||||
	event
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MakeEvent initializes an epoll *edge* triggered event on linux.
 | 
			
		||||
//
 | 
			
		||||
// An edge triggered event is basically an "auto-reset" event, where waiting on
 | 
			
		||||
// the edge resets it. A level triggered event requires manual resetting; this
 | 
			
		||||
// could be done via a Read() call but there's no need to require the user to
 | 
			
		||||
// call Read(). This is particularly useless in the case of gpio.RisingEdge and
 | 
			
		||||
// gpio.FallingEdge.
 | 
			
		||||
//
 | 
			
		||||
// As per the official doc, edge triggers is still remembered even when no
 | 
			
		||||
// epoll_wait() call is running, so no edge is missed. Two edges will be
 | 
			
		||||
// coallesced into one if the user mode process can't keep up. There's no
 | 
			
		||||
// accumulation of edges.
 | 
			
		||||
func (e *Event) MakeEvent(fd uintptr) error {
 | 
			
		||||
	return e.event.makeEvent(fd)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Wait waits for an event or the specified amount of time.
 | 
			
		||||
func (e *Event) Wait(timeoutms int) (int, error) {
 | 
			
		||||
	return e.event.wait(timeoutms)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	mu        sync.Mutex
 | 
			
		||||
	inhibited bool
 | 
			
		||||
	used      bool
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										124
									
								
								vendor/periph.io/x/periph/host/fs/fs_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								vendor/periph.io/x/periph/host/fs/fs_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
			
		||||
// 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 fs
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const isLinux = true
 | 
			
		||||
 | 
			
		||||
// syscall.EpollCtl() commands.
 | 
			
		||||
//
 | 
			
		||||
// These are defined here so we don't need to import golang.org/x/sys/unix.
 | 
			
		||||
//
 | 
			
		||||
// http://man7.org/linux/man-pages/man2/epoll_ctl.2.html
 | 
			
		||||
const (
 | 
			
		||||
	epollCTLAdd = 1 // EPOLL_CTL_ADD
 | 
			
		||||
	epollCTLDel = 2 // EPOLL_CTL_DEL
 | 
			
		||||
	epollCTLMod = 3 // EPOLL_CTL_MOD
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Bitmask for field syscall.EpollEvent.Events.
 | 
			
		||||
//
 | 
			
		||||
// These are defined here so we don't need to import golang.org/x/sys/unix.
 | 
			
		||||
//
 | 
			
		||||
// http://man7.org/linux/man-pages/man2/epoll_ctl.2.html
 | 
			
		||||
type epollEvent uint32
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	epollIN        epollEvent = 0x1        // EPOLLIN: available for read
 | 
			
		||||
	epollOUT       epollEvent = 0x4        // EPOLLOUT: available for write
 | 
			
		||||
	epollPRI       epollEvent = 0x2        // EPOLLPRI: exceptional urgent condition
 | 
			
		||||
	epollERR       epollEvent = 0x8        // EPOLLERR: error
 | 
			
		||||
	epollHUP       epollEvent = 0x10       // EPOLLHUP: hangup
 | 
			
		||||
	epollET        epollEvent = 0x80000000 // EPOLLET: Edge Triggered behavior
 | 
			
		||||
	epollONESHOT   epollEvent = 0x40000000 // EPOLLONESHOT: One shot
 | 
			
		||||
	epollWAKEUP    epollEvent = 0x20000000 // EPOLLWAKEUP: disable system sleep; kernel >=3.5
 | 
			
		||||
	epollEXCLUSIVE epollEvent = 0x10000000 // EPOLLEXCLUSIVE: only wake one; kernel >=4.5
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var bitmaskString = [...]struct {
 | 
			
		||||
	e epollEvent
 | 
			
		||||
	s string
 | 
			
		||||
}{
 | 
			
		||||
	{epollIN, "IN"},
 | 
			
		||||
	{epollOUT, "OUT"},
 | 
			
		||||
	{epollPRI, "PRI"},
 | 
			
		||||
	{epollERR, "ERR"},
 | 
			
		||||
	{epollHUP, "HUP"},
 | 
			
		||||
	{epollET, "ET"},
 | 
			
		||||
	{epollONESHOT, "ONESHOT"},
 | 
			
		||||
	{epollWAKEUP, "WAKEUP"},
 | 
			
		||||
	{epollEXCLUSIVE, "EXCLUSIVE"},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String is useful for debugging.
 | 
			
		||||
func (e epollEvent) String() string {
 | 
			
		||||
	var out []string
 | 
			
		||||
	for _, b := range bitmaskString {
 | 
			
		||||
		if e&b.e != 0 {
 | 
			
		||||
			out = append(out, b.s)
 | 
			
		||||
			e &^= b.e
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if e != 0 {
 | 
			
		||||
		out = append(out, "0x"+strconv.FormatUint(uint64(e), 16))
 | 
			
		||||
	}
 | 
			
		||||
	if len(out) == 0 {
 | 
			
		||||
		out = []string{"0"}
 | 
			
		||||
	}
 | 
			
		||||
	return strings.Join(out, "|")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctl(f uintptr, op uint, arg uintptr) error {
 | 
			
		||||
	if _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, f, uintptr(op), arg); errno != 0 {
 | 
			
		||||
		return syscall.Errno(errno)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type event struct {
 | 
			
		||||
	event   [1]syscall.EpollEvent
 | 
			
		||||
	epollFd int
 | 
			
		||||
	fd      int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// makeEvent creates an epoll *edge* triggered event.
 | 
			
		||||
//
 | 
			
		||||
// References:
 | 
			
		||||
// behavior and flags: http://man7.org/linux/man-pages/man7/epoll.7.html
 | 
			
		||||
// syscall.EpollCreate: http://man7.org/linux/man-pages/man2/epoll_create.2.html
 | 
			
		||||
// syscall.EpollCtl: http://man7.org/linux/man-pages/man2/epoll_ctl.2.html
 | 
			
		||||
func (e *event) makeEvent(fd uintptr) error {
 | 
			
		||||
	epollFd, err := syscall.EpollCreate(1)
 | 
			
		||||
	switch {
 | 
			
		||||
	case err == nil:
 | 
			
		||||
		break
 | 
			
		||||
	case err.Error() == "function not implemented":
 | 
			
		||||
		// Some arch (arm64) do not implement EpollCreate().
 | 
			
		||||
		if epollFd, err = syscall.EpollCreate1(0); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	e.epollFd = epollFd
 | 
			
		||||
	e.fd = int(fd)
 | 
			
		||||
	// EPOLLWAKEUP could be used to force the system to not go do sleep while
 | 
			
		||||
	// waiting for an edge. This is generally a bad idea, as we'd instead have
 | 
			
		||||
	// the system to *wake up* when an edge is triggered. Achieving this is
 | 
			
		||||
	// outside the scope of this interface.
 | 
			
		||||
	e.event[0].Events = uint32(epollPRI | epollET)
 | 
			
		||||
	e.event[0].Fd = int32(e.fd)
 | 
			
		||||
	return syscall.EpollCtl(e.epollFd, epollCTLAdd, e.fd, &e.event[0])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *event) wait(timeoutms int) (int, error) {
 | 
			
		||||
	// http://man7.org/linux/man-pages/man2/epoll_wait.2.html
 | 
			
		||||
	return syscall.EpollWait(e.epollFd, e.event[:], timeoutms)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								vendor/periph.io/x/periph/host/fs/fs_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								vendor/periph.io/x/periph/host/fs/fs_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
// Copyright 2017 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !linux
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
import "errors"
 | 
			
		||||
 | 
			
		||||
const isLinux = false
 | 
			
		||||
 | 
			
		||||
func ioctl(f uintptr, op uint, arg uintptr) error {
 | 
			
		||||
	return errors.New("fs: ioctl not supported on non-linux")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type event struct{}
 | 
			
		||||
 | 
			
		||||
func (e *event) makeEvent(f uintptr) error {
 | 
			
		||||
	return errors.New("fs: unreachable code")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *event) wait(timeoutms int) (int, error) {
 | 
			
		||||
	return 0, errors.New("fs: unreachable code")
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								vendor/periph.io/x/periph/host/fs/ioctl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								vendor/periph.io/x/periph/host/fs/ioctl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
// Copyright 2019 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
// These constants, variables and functions are ported from the Linux userland
 | 
			
		||||
// API header ioctl.h (commonly packaged at /usr/include/linux/ioctl.h which
 | 
			
		||||
// includes /usr/include/asm-generic/ioctl.h).
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	iocNrbits   uint = 8
 | 
			
		||||
	iocTypebits uint = 8
 | 
			
		||||
 | 
			
		||||
	iocNrshift uint = 0
 | 
			
		||||
 | 
			
		||||
	iocTypeshift = iocNrshift + iocNrbits
 | 
			
		||||
	iocSizeshift = iocTypeshift + iocTypebits
 | 
			
		||||
	iocDirshift  = iocSizeshift + iocSizebits
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func ioc(dir, typ, nr, size uint) uint {
 | 
			
		||||
	return (dir << iocDirshift) |
 | 
			
		||||
		(typ << iocTypeshift) |
 | 
			
		||||
		(nr << iocNrshift) |
 | 
			
		||||
		(size << iocSizeshift)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IO defines an ioctl with no parameters. It corresponds to _IO in the Linux
 | 
			
		||||
// userland API.
 | 
			
		||||
func IO(typ, nr uint) uint {
 | 
			
		||||
	return ioc(iocNone, typ, nr, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IOR defines an ioctl with read (userland perspective) parameters. It
 | 
			
		||||
// corresponds to _IOR in the Linux userland API.
 | 
			
		||||
func IOR(typ, nr, size uint) uint {
 | 
			
		||||
	return ioc(iocRead, typ, nr, size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IOW defines an ioctl with write (userland perspective) parameters. It
 | 
			
		||||
// corresponds to _IOW in the Linux userland API.
 | 
			
		||||
func IOW(typ, nr, size uint) uint {
 | 
			
		||||
	return ioc(iocWrite, typ, nr, size)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IOWR defines an ioctl with both read and write parameters. It corresponds to
 | 
			
		||||
// _IOWR in the Linux userland API.
 | 
			
		||||
func IOWR(typ, nr, size uint) uint {
 | 
			
		||||
	return ioc(iocRead|iocWrite, typ, nr, size)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/periph.io/x/periph/host/fs/ioctl_mips_like.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/periph.io/x/periph/host/fs/ioctl_mips_like.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build mips mipsle
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	iocNone  uint = 1
 | 
			
		||||
	iocRead  uint = 2
 | 
			
		||||
	iocWrite uint = 4
 | 
			
		||||
 | 
			
		||||
	iocSizebits uint = 13
 | 
			
		||||
	iocDirbits  uint = 3
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/periph.io/x/periph/host/fs/ioctl_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/periph.io/x/periph/host/fs/ioctl_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
// 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.
 | 
			
		||||
 | 
			
		||||
// +build !mips,!mipsle
 | 
			
		||||
 | 
			
		||||
package fs
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	iocNone  uint = 0
 | 
			
		||||
	iocWrite uint = 1
 | 
			
		||||
	iocRead  uint = 2
 | 
			
		||||
 | 
			
		||||
	iocSizebits uint = 14
 | 
			
		||||
	iocDirbits  uint = 2
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/periph.io/x/periph/host/host.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/periph.io/x/periph/host/host.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package host
 | 
			
		||||
 | 
			
		||||
import "periph.io/x/periph"
 | 
			
		||||
 | 
			
		||||
// Init calls periph.Init() and returns it as-is.
 | 
			
		||||
//
 | 
			
		||||
// The only difference is that by calling host.Init(), you are guaranteed to
 | 
			
		||||
// have all the drivers implemented in this library to be implicitly loaded.
 | 
			
		||||
func Init() (*periph.State, error) {
 | 
			
		||||
	return periph.Init()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								vendor/periph.io/x/periph/host/host_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								vendor/periph.io/x/periph/host/host_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package host
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	// Make sure CPU and board drivers are registered.
 | 
			
		||||
	_ "periph.io/x/periph/host/allwinner"
 | 
			
		||||
	_ "periph.io/x/periph/host/am335x"
 | 
			
		||||
	_ "periph.io/x/periph/host/bcm283x"
 | 
			
		||||
	_ "periph.io/x/periph/host/beagle/bone"
 | 
			
		||||
	_ "periph.io/x/periph/host/beagle/green"
 | 
			
		||||
	_ "periph.io/x/periph/host/chip"
 | 
			
		||||
	_ "periph.io/x/periph/host/odroidc1"
 | 
			
		||||
	// While this board is ARM64, it may run ARM 32 bits binaries so load it on
 | 
			
		||||
	// 32 bits builds too.
 | 
			
		||||
	_ "periph.io/x/periph/host/pine64"
 | 
			
		||||
	_ "periph.io/x/periph/host/rpi"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										13
									
								
								vendor/periph.io/x/periph/host/host_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								vendor/periph.io/x/periph/host/host_arm64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package host
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	// Make sure CPU and board drivers are registered.
 | 
			
		||||
	_ "periph.io/x/periph/host/allwinner"
 | 
			
		||||
	_ "periph.io/x/periph/host/bcm283x"
 | 
			
		||||
	_ "periph.io/x/periph/host/pine64"
 | 
			
		||||
	_ "periph.io/x/periph/host/rpi"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										10
									
								
								vendor/periph.io/x/periph/host/host_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								vendor/periph.io/x/periph/host/host_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
// Copyright 2016 The Periph Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package host
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	// Make sure sysfs drivers are registered.
 | 
			
		||||
	_ "periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/periph.io/x/periph/host/odroidc1/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/periph.io/x/periph/host/odroidc1/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
// 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 odroidc1 contains header definitions for Hardkernel's ODROID C0, C1,
 | 
			
		||||
// and C1+ boards.
 | 
			
		||||
//
 | 
			
		||||
// These boards use an Amlogic S805 processor (called "meson_8b" in the linux
 | 
			
		||||
// kernel). Currently no package for memory-mapped I/O has been written for
 | 
			
		||||
// this processor, thus all gpio functions are implemented via sysfs.
 | 
			
		||||
//
 | 
			
		||||
// This package only exports the main J2 header, which is rPi compatible except
 | 
			
		||||
// for a couple of analog pins (which are not currently supported). The J2
 | 
			
		||||
// header has two I²C buses on header pins 3/5 and 27/28, the I²C functionality
 | 
			
		||||
// can be enabled by loading the aml_i2c kernel module. It has one SPI bus on
 | 
			
		||||
// header pins 19/21/23/24. The onewire gpio driver appears to be loaded by
 | 
			
		||||
// default on header pin 7.
 | 
			
		||||
//
 | 
			
		||||
// References
 | 
			
		||||
//
 | 
			
		||||
// Product page: http://www.hardkernel.com/main/products/prdt_info.php?g_code=G143703355573&tab_idx=2
 | 
			
		||||
//
 | 
			
		||||
// Hardware wiki: http://odroid.com/dokuwiki/doku.php?id=en:c1_hardware
 | 
			
		||||
//
 | 
			
		||||
// Ubuntu drivers: http://odroid.com/dokuwiki/doku.php?id=en:odroid-c1#ubuntu
 | 
			
		||||
package odroidc1
 | 
			
		||||
							
								
								
									
										195
									
								
								vendor/periph.io/x/periph/host/odroidc1/odroidc1.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								vendor/periph.io/x/periph/host/odroidc1/odroidc1.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,195 @@
 | 
			
		||||
// 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 odroidc1
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"periph.io/x/periph"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio"
 | 
			
		||||
	"periph.io/x/periph/conn/gpio/gpioreg"
 | 
			
		||||
	"periph.io/x/periph/conn/pin"
 | 
			
		||||
	"periph.io/x/periph/conn/pin/pinreg"
 | 
			
		||||
	"periph.io/x/periph/host/distro"
 | 
			
		||||
	"periph.io/x/periph/host/sysfs"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// The J2 header is rPi compatible, except for the two analog pins and the 1.8V
 | 
			
		||||
// output.
 | 
			
		||||
var (
 | 
			
		||||
	J2_1             = pin.V3_3     // 3.3V; max 30mA
 | 
			
		||||
	J2_2             = pin.V5       // 5V (after filtering)
 | 
			
		||||
	J2_3  gpio.PinIO = gpio.INVALID // I2C1_SDA
 | 
			
		||||
	J2_4             = pin.V5       // 5V (after filtering)
 | 
			
		||||
	J2_5  gpio.PinIO = gpio.INVALID // I2C1_SCL
 | 
			
		||||
	J2_6             = pin.GROUND   //
 | 
			
		||||
	J2_7  gpio.PinIO = gpio.INVALID // CLK0
 | 
			
		||||
	J2_8  gpio.PinIO = gpio.INVALID // UART0_TX, UART1_TX
 | 
			
		||||
	J2_9             = pin.GROUND   //
 | 
			
		||||
	J2_10 gpio.PinIO = gpio.INVALID // UART0_RX, UART1_RX
 | 
			
		||||
	J2_11 gpio.PinIO = gpio.INVALID // UART0_RTS, SPI1_CS1, UART1_RTS
 | 
			
		||||
	J2_12 gpio.PinIO = gpio.INVALID // I2S_SCK, SPI1_CS0, PWM0
 | 
			
		||||
	J2_13 gpio.PinIO = gpio.INVALID // GPIO116
 | 
			
		||||
	J2_14            = pin.GROUND   //
 | 
			
		||||
	J2_15 gpio.PinIO = gpio.INVALID // GPIO115
 | 
			
		||||
	J2_16 gpio.PinIO = gpio.INVALID // GPIO104
 | 
			
		||||
	J2_17            = pin.V3_3     //
 | 
			
		||||
	J2_18 gpio.PinIO = gpio.INVALID // GPIO102
 | 
			
		||||
	J2_19 gpio.PinIO = gpio.INVALID // SPI0_MOSI
 | 
			
		||||
	J2_20            = pin.GROUND   //
 | 
			
		||||
	J2_21 gpio.PinIO = gpio.INVALID // SPI0_MISO
 | 
			
		||||
	J2_22 gpio.PinIO = gpio.INVALID // GPIO103
 | 
			
		||||
	J2_23 gpio.PinIO = gpio.INVALID // SPI0_CLK
 | 
			
		||||
	J2_24 gpio.PinIO = gpio.INVALID // SPI0_CS0
 | 
			
		||||
	J2_25            = pin.GROUND   //
 | 
			
		||||
	J2_26 gpio.PinIO = gpio.INVALID // SPI0_CS1
 | 
			
		||||
	J2_27 gpio.PinIO = gpio.INVALID // I2C0_SDA
 | 
			
		||||
	J2_28 gpio.PinIO = gpio.INVALID // I2C0_SCL
 | 
			
		||||
	J2_29 gpio.PinIO = gpio.INVALID // CLK1
 | 
			
		||||
	J2_30            = pin.GROUND   //
 | 
			
		||||
	J2_31 gpio.PinIO = gpio.INVALID // CLK2
 | 
			
		||||
	J2_32 gpio.PinIO = gpio.INVALID // PWM0
 | 
			
		||||
	J2_33 gpio.PinIO = gpio.INVALID // PWM1
 | 
			
		||||
	J2_34            = pin.GROUND   //
 | 
			
		||||
	J2_35 gpio.PinIO = gpio.INVALID // I2S_WS, SPI1_MISO, PWM1
 | 
			
		||||
	J2_36 gpio.PinIO = gpio.INVALID // UART0_CTS, SPI1_CS2, UART1_CTS
 | 
			
		||||
	J2_37            = pin.INVALID  // BUG(tve): make pins J2_37 and J2_40 functional once analog support is implemented
 | 
			
		||||
	J2_38            = pin.V1_8     //
 | 
			
		||||
	J2_39            = pin.GROUND   //
 | 
			
		||||
	J2_40            = pin.INVALID  // See above.
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Present returns true if running on a Hardkernel ODROID-C0/C1/C1+ board.
 | 
			
		||||
//
 | 
			
		||||
// It looks for "8726_M8B" in the device tree or "ODROIDC" in cpuinfo. The
 | 
			
		||||
// following information is expected in the device dtree:
 | 
			
		||||
//   root@odroid:/proc/device-tree# od -c compatible
 | 
			
		||||
//   0000000   A   M   L   O   G   I   C   ,   8   7   2   6   _   M   8   B
 | 
			
		||||
func Present() bool {
 | 
			
		||||
	for _, c := range distro.DTCompatible() {
 | 
			
		||||
		if strings.Contains(c, "8726_M8B") {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return distro.CPUInfo()["Hardware"] == "ODROIDC"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// aliases is a list of aliases for the various gpio pins, this allows users to
 | 
			
		||||
// refer to pins using the documented and labeled names instead of some GPIOnnn
 | 
			
		||||
// name. The map key is the alias and the value is the real pin name.
 | 
			
		||||
var aliases = map[string]int{
 | 
			
		||||
	"I2C0_SDA":  74,
 | 
			
		||||
	"I2C0_SCL":  75,
 | 
			
		||||
	"I2C1_SDA":  76,
 | 
			
		||||
	"I2C1_SCL":  77,
 | 
			
		||||
	"I2CA_SDA":  74,
 | 
			
		||||
	"I2CA_SCL":  75,
 | 
			
		||||
	"I2CB_SDA":  76,
 | 
			
		||||
	"I2CB_SCL":  77,
 | 
			
		||||
	"SPI0_MOSI": 107,
 | 
			
		||||
	"SPI0_MISO": 106,
 | 
			
		||||
	"SPI0_CLK":  105,
 | 
			
		||||
	"SPI0_CS0":  117,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// sysfsPin is a safe way to get a sysfs pin
 | 
			
		||||
func sysfsPin(n int) gpio.PinIO {
 | 
			
		||||
	if p, ok := sysfs.Pins[n]; ok {
 | 
			
		||||
		return p
 | 
			
		||||
	}
 | 
			
		||||
	return gpio.INVALID
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// driver implements drivers.Driver.
 | 
			
		||||
type driver struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) String() string {
 | 
			
		||||
	return "odroid-c1"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Prerequisites() []string {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) After() []string {
 | 
			
		||||
	return []string{"sysfs-gpio"}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *driver) Init() (bool, error) {
 | 
			
		||||
	if !Present() {
 | 
			
		||||
		return false, errors.New("Hardkernel ODROID-C0/C1/C1+ board not detected")
 | 
			
		||||
	}
 | 
			
		||||
	J2_3 = sysfsPin(74)
 | 
			
		||||
	J2_5 = sysfsPin(75)
 | 
			
		||||
	J2_7 = sysfsPin(83)   // usually taken by 1-wire driver
 | 
			
		||||
	J2_8 = sysfsPin(113)  // usually not available
 | 
			
		||||
	J2_10 = sysfsPin(114) // usually not available
 | 
			
		||||
	J2_11 = sysfsPin(88)
 | 
			
		||||
	J2_12 = sysfsPin(87)
 | 
			
		||||
	J2_13 = sysfsPin(116)
 | 
			
		||||
	J2_15 = sysfsPin(115)
 | 
			
		||||
	J2_16 = sysfsPin(104)
 | 
			
		||||
	J2_18 = sysfsPin(102)
 | 
			
		||||
	J2_19 = sysfsPin(107)
 | 
			
		||||
	J2_21 = sysfsPin(106)
 | 
			
		||||
	J2_22 = sysfsPin(103)
 | 
			
		||||
	J2_23 = sysfsPin(105)
 | 
			
		||||
	J2_24 = sysfsPin(117)
 | 
			
		||||
	J2_26 = sysfsPin(118)
 | 
			
		||||
	J2_27 = sysfsPin(76)
 | 
			
		||||
	J2_28 = sysfsPin(77)
 | 
			
		||||
	J2_29 = sysfsPin(101)
 | 
			
		||||
	J2_31 = sysfsPin(100)
 | 
			
		||||
	J2_32 = sysfsPin(99)
 | 
			
		||||
	J2_33 = sysfsPin(108)
 | 
			
		||||
	J2_35 = sysfsPin(97)
 | 
			
		||||
	J2_36 = sysfsPin(98)
 | 
			
		||||
 | 
			
		||||
	// J2 is the 40-pin rPi-compatible header
 | 
			
		||||
	J2 := [][]pin.Pin{
 | 
			
		||||
		{J2_1, J2_2},
 | 
			
		||||
		{J2_3, J2_4},
 | 
			
		||||
		{J2_5, J2_6},
 | 
			
		||||
		{J2_7, J2_8},
 | 
			
		||||
		{J2_9, J2_10},
 | 
			
		||||
		{J2_11, J2_12},
 | 
			
		||||
		{J2_13, J2_14},
 | 
			
		||||
		{J2_15, J2_16},
 | 
			
		||||
		{J2_17, J2_18},
 | 
			
		||||
		{J2_19, J2_20},
 | 
			
		||||
		{J2_21, J2_22},
 | 
			
		||||
		{J2_23, J2_24},
 | 
			
		||||
		{J2_25, J2_26},
 | 
			
		||||
		{J2_27, J2_28},
 | 
			
		||||
		{J2_29, J2_30},
 | 
			
		||||
		{J2_31, J2_32},
 | 
			
		||||
		{J2_33, J2_34},
 | 
			
		||||
		{J2_35, J2_36},
 | 
			
		||||
		{J2_37, J2_38},
 | 
			
		||||
		{J2_39, J2_40},
 | 
			
		||||
	}
 | 
			
		||||
	if err := pinreg.Register("J2", J2); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
	for alias, number := range aliases {
 | 
			
		||||
		if err := gpioreg.RegisterAlias(alias, strconv.Itoa(number)); err != nil {
 | 
			
		||||
			return true, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if isArm {
 | 
			
		||||
		periph.MustRegister(&drv)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var drv driver
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/periph.io/x/periph/host/odroidc1/odroidc1_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/periph.io/x/periph/host/odroidc1/odroidc1_arm.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// Copyright 2016 The PIO 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 odroidc1
 | 
			
		||||
 | 
			
		||||
const isArm = true
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/periph.io/x/periph/host/odroidc1/odroidc1_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/periph.io/x/periph/host/odroidc1/odroidc1_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
// Copyright 2016 The PIO Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed under the Apache License, Version 2.0
 | 
			
		||||
// that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !arm
 | 
			
		||||
 | 
			
		||||
package odroidc1
 | 
			
		||||
 | 
			
		||||
const isArm = false
 | 
			
		||||
							
								
								
									
										15
									
								
								vendor/periph.io/x/periph/host/pine64/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								vendor/periph.io/x/periph/host/pine64/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
// 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 pine64 contains Pine64 hardware logic. It is intrinsically
 | 
			
		||||
// related to package a64.
 | 
			
		||||
//
 | 
			
		||||
// Requires Armbian Jessie Server.
 | 
			
		||||
//
 | 
			
		||||
// Physical
 | 
			
		||||
//
 | 
			
		||||
// http://files.pine64.org/doc/Pine%20A64%20Schematic/Pine%20A64%20Pin%20Assignment%20160119.pdf
 | 
			
		||||
//
 | 
			
		||||
// http://wiki.pine64.org/images/2/2e/Pine64_Board_Connector_heatsink.png
 | 
			
		||||
package pine64
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user