mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 11:07:46 +00:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3b68f8f16a | |||
| fca2de21b1 | |||
| 107b1c2906 | |||
| 2409bbef69 | |||
| 8b078a9e8f | |||
| 9e24441978 | |||
| 1e6c14b3e4 | |||
| 25f6be1488 | |||
| 9a9106a297 | |||
| a68f7e4ce3 | |||
| 70b3ece6ec | |||
| 86ea216e7d | |||
| 5a92c35536 | |||
| 7513fa2c96 | |||
| bc946f346d | |||
| 6e6666519c | |||
| cecae8084c | |||
| 9720ccacbb | |||
| a5aa777c7b | |||
| aca1ad187d | |||
| 5a41ed6329 | |||
| 91e9c84d85 | |||
| 4af530f238 | |||
| d3863f337d | |||
| 5551ec7a1e | |||
| 91104b2f27 | |||
| 80f38e8449 | |||
| 22893c5180 | |||
| 9e4e182615 | |||
| 5f96d2b784 | |||
| bd1d93b705 | |||
| 03d1c44265 | |||
| dc0346d968 | |||
| dadae95448 | |||
| f5fc2fc072 | |||
| 4ba76a5df9 | |||
| ea1e08f53f | |||
| bba0dc9575 | |||
| 617c7586fe | |||
| 7366d5e185 | |||
| 96e3ecd949 | |||
| 8bbfb1ee68 | |||
| 07cdcc61f7 | |||
| 4ca9b34133 | |||
| d5e4b16911 | |||
| fd05254683 | |||
| c579e7e509 | |||
| d463528a72 | |||
| 49b0086f8f | |||
| d7814ff50b | |||
| 02160aa8d8 | |||
| c199dd03c7 | |||
| 472aecf07a | |||
| 09350e5719 | |||
| 623dd6a815 | |||
| e09bd5abb3 |
+1
-10
@@ -118,13 +118,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- test-linux:
|
- test-linux:
|
||||||
llvm: "14"
|
llvm: "14"
|
||||||
test-llvm14-go119:
|
resource_class: large
|
||||||
docker:
|
|
||||||
- image: golang:1.19beta1-buster
|
|
||||||
steps:
|
|
||||||
- test-linux:
|
|
||||||
llvm: "14"
|
|
||||||
fmt-check: false
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
test-all:
|
test-all:
|
||||||
@@ -132,6 +126,3 @@ workflows:
|
|||||||
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
||||||
# least the smoke tests still pass.
|
# least the smoke tests still pass.
|
||||||
- test-llvm14-go118
|
- test-llvm14-go118
|
||||||
# This tests a beta version of Go. It should be removed once regular
|
|
||||||
# release builds are built using this version.
|
|
||||||
- test-llvm14-go119
|
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ jobs:
|
|||||||
name: build-macos
|
name: build-macos
|
||||||
runs-on: macos-11
|
runs-on: macos-11
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: '1.18.1'
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -35,8 +31,13 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
- name: Install Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: '1.19'
|
||||||
|
cache: true
|
||||||
- name: Cache LLVM source
|
- name: Cache LLVM source
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-14-macos-v1
|
key: llvm-source-14-macos-v1
|
||||||
@@ -50,7 +51,7 @@ jobs:
|
|||||||
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
||||||
run: make llvm-source
|
run: make llvm-source
|
||||||
- name: Cache LLVM build
|
- name: Cache LLVM build
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-14-macos-v1
|
key: llvm-build-14-macos-v1
|
||||||
@@ -68,7 +69,7 @@ jobs:
|
|||||||
make llvm-build
|
make llvm-build
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
- name: Cache wasi-libc sysroot
|
- name: Cache wasi-libc sysroot
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-wasi-libc
|
id: cache-wasi-libc
|
||||||
with:
|
with:
|
||||||
key: wasi-libc-sysroot-v4
|
key: wasi-libc-sysroot-v4
|
||||||
@@ -104,23 +105,17 @@ jobs:
|
|||||||
name: homebrew-install
|
name: homebrew-install
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: '1.18'
|
|
||||||
- name: Install LLVM
|
- name: Install LLVM
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@14
|
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@14
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Cache Go
|
- name: Install Go
|
||||||
uses: actions/cache@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
key: go-cache-macos-homebrew-v1-${{ hashFiles('go.mod') }}
|
go-version: '1.19'
|
||||||
path: |
|
cache: true
|
||||||
~/Library/Caches/go-build
|
|
||||||
~/go/pkg/mod
|
|
||||||
- name: Build TinyGo
|
- name: Build TinyGo
|
||||||
run: go install
|
run: go install
|
||||||
- name: Check binary
|
- name: Check binary
|
||||||
|
|||||||
+30
-52
@@ -18,14 +18,13 @@ jobs:
|
|||||||
# statically linked binary.
|
# statically linked binary.
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: alpine:3.16
|
image: golang:1.19-alpine
|
||||||
steps:
|
steps:
|
||||||
- name: Install apk dependencies
|
- name: Install apk dependencies
|
||||||
# tar: needed for actions/cache@v2
|
# tar: needed for actions/cache@v3
|
||||||
# git+openssh: needed for checkout (I think?)
|
# git+openssh: needed for checkout (I think?)
|
||||||
# gcompat: needed for go binary
|
|
||||||
# ruby: needed to install fpm
|
# ruby: needed to install fpm
|
||||||
run: apk add tar git openssh gcompat make g++ ruby
|
run: apk add tar git openssh make g++ ruby
|
||||||
- name: Work around CVE-2022-24765
|
- name: Work around CVE-2022-24765
|
||||||
# We're not on a multi-user machine, so this is safe.
|
# We're not on a multi-user machine, so this is safe.
|
||||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
@@ -33,19 +32,15 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: '1.18.1'
|
|
||||||
- name: Cache Go
|
- name: Cache Go
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
key: go-cache-linux-alpine-v1-${{ hashFiles('go.mod') }}
|
key: go-cache-linux-alpine-v1-${{ hashFiles('go.mod') }}
|
||||||
path: |
|
path: |
|
||||||
~/.cache/go-build
|
~/.cache/go-build
|
||||||
~/go/pkg/mod
|
~/go/pkg/mod
|
||||||
- name: Cache LLVM source
|
- name: Cache LLVM source
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-14-linux-alpine-v1
|
key: llvm-source-14-linux-alpine-v1
|
||||||
@@ -59,7 +54,7 @@ jobs:
|
|||||||
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
||||||
run: make llvm-source
|
run: make llvm-source
|
||||||
- name: Cache LLVM build
|
- name: Cache LLVM build
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-14-linux-alpine-v1
|
key: llvm-build-14-linux-alpine-v1
|
||||||
@@ -77,7 +72,7 @@ jobs:
|
|||||||
# Remove unnecessary object files (to reduce cache size).
|
# Remove unnecessary object files (to reduce cache size).
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
- name: Cache Binaryen
|
- name: Cache Binaryen
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-binaryen
|
id: cache-binaryen
|
||||||
with:
|
with:
|
||||||
key: binaryen-linux-alpine-v1
|
key: binaryen-linux-alpine-v1
|
||||||
@@ -88,7 +83,7 @@ jobs:
|
|||||||
apk add cmake samurai python3
|
apk add cmake samurai python3
|
||||||
make binaryen STATIC=1
|
make binaryen STATIC=1
|
||||||
- name: Cache wasi-libc
|
- name: Cache wasi-libc
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-wasi-libc
|
id: cache-wasi-libc
|
||||||
with:
|
with:
|
||||||
key: wasi-libc-sysroot-linux-alpine-v1
|
key: wasi-libc-sysroot-linux-alpine-v1
|
||||||
@@ -121,9 +116,10 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: '1.18.1'
|
go-version: '1.19'
|
||||||
|
cache: true
|
||||||
- name: Install wasmtime
|
- name: Install wasmtime
|
||||||
run: |
|
run: |
|
||||||
curl https://wasmtime.dev/install.sh -sSf | bash
|
curl https://wasmtime.dev/install.sh -sSf | bash
|
||||||
@@ -173,9 +169,10 @@ jobs:
|
|||||||
simavr \
|
simavr \
|
||||||
ninja-build
|
ninja-build
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: '1.18.1'
|
go-version: '1.19'
|
||||||
|
cache: true
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
@@ -184,15 +181,8 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
curl https://wasmtime.dev/install.sh -sSf | bash
|
curl https://wasmtime.dev/install.sh -sSf | bash
|
||||||
echo "$HOME/.wasmtime/bin" >> $GITHUB_PATH
|
echo "$HOME/.wasmtime/bin" >> $GITHUB_PATH
|
||||||
- name: Cache Go
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
key: go-cache-linux-asserts-v1-${{ hashFiles('go.mod') }}
|
|
||||||
path: |
|
|
||||||
~/.cache/go-build
|
|
||||||
~/go/pkg/mod
|
|
||||||
- name: Cache LLVM source
|
- name: Cache LLVM source
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-14-linux-asserts-v2
|
key: llvm-source-14-linux-asserts-v2
|
||||||
@@ -206,7 +196,7 @@ jobs:
|
|||||||
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
||||||
run: make llvm-source
|
run: make llvm-source
|
||||||
- name: Cache LLVM build
|
- name: Cache LLVM build
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-14-linux-asserts-v1
|
key: llvm-build-14-linux-asserts-v1
|
||||||
@@ -222,7 +212,7 @@ jobs:
|
|||||||
# Remove unnecessary object files (to reduce cache size).
|
# Remove unnecessary object files (to reduce cache size).
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
- name: Cache Binaryen
|
- name: Cache Binaryen
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-binaryen
|
id: cache-binaryen
|
||||||
with:
|
with:
|
||||||
key: binaryen-linux-asserts-v1
|
key: binaryen-linux-asserts-v1
|
||||||
@@ -231,7 +221,7 @@ jobs:
|
|||||||
if: steps.cache-binaryen.outputs.cache-hit != 'true'
|
if: steps.cache-binaryen.outputs.cache-hit != 'true'
|
||||||
run: make binaryen
|
run: make binaryen
|
||||||
- name: Cache wasi-libc
|
- name: Cache wasi-libc
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-wasi-libc
|
id: cache-wasi-libc
|
||||||
with:
|
with:
|
||||||
key: wasi-libc-sysroot-linux-asserts-v5
|
key: wasi-libc-sysroot-linux-asserts-v5
|
||||||
@@ -279,18 +269,12 @@ jobs:
|
|||||||
g++-arm-linux-gnueabihf \
|
g++-arm-linux-gnueabihf \
|
||||||
libc6-dev-armhf-cross
|
libc6-dev-armhf-cross
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: '1.18.1'
|
go-version: '1.19'
|
||||||
- name: Cache Go
|
cache: true
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
key: go-cache-linux-arm-v2-${{ hashFiles('go.mod') }}
|
|
||||||
path: |
|
|
||||||
~/.cache/go-build
|
|
||||||
~/go/pkg/mod
|
|
||||||
- name: Cache LLVM source
|
- name: Cache LLVM source
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-14-linux-v2
|
key: llvm-source-14-linux-v2
|
||||||
@@ -304,7 +288,7 @@ jobs:
|
|||||||
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
||||||
run: make llvm-source
|
run: make llvm-source
|
||||||
- name: Cache LLVM build
|
- name: Cache LLVM build
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-14-linux-arm-v1
|
key: llvm-build-14-linux-arm-v1
|
||||||
@@ -322,7 +306,7 @@ jobs:
|
|||||||
# Remove unnecessary object files (to reduce cache size).
|
# Remove unnecessary object files (to reduce cache size).
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
- name: Cache Binaryen
|
- name: Cache Binaryen
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-binaryen
|
id: cache-binaryen
|
||||||
with:
|
with:
|
||||||
key: binaryen-linux-arm-v1
|
key: binaryen-linux-arm-v1
|
||||||
@@ -385,18 +369,12 @@ jobs:
|
|||||||
libc6-dev-arm64-cross \
|
libc6-dev-arm64-cross \
|
||||||
ninja-build
|
ninja-build
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: '1.18.1'
|
go-version: '1.19'
|
||||||
- name: Cache Go
|
cache: true
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
key: go-cache-linux-arm64-v2-${{ hashFiles('go.mod') }}
|
|
||||||
path: |
|
|
||||||
~/.cache/go-build
|
|
||||||
~/go/pkg/mod
|
|
||||||
- name: Cache LLVM source
|
- name: Cache LLVM source
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-14-linux-v1
|
key: llvm-source-14-linux-v1
|
||||||
@@ -410,7 +388,7 @@ jobs:
|
|||||||
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
||||||
run: make llvm-source
|
run: make llvm-source
|
||||||
- name: Cache LLVM build
|
- name: Cache LLVM build
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-14-linux-arm64-v1
|
key: llvm-build-14-linux-arm64-v1
|
||||||
@@ -426,7 +404,7 @@ jobs:
|
|||||||
# Remove unnecessary object files (to reduce cache size).
|
# Remove unnecessary object files (to reduce cache size).
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
- name: Cache Binaryen
|
- name: Cache Binaryen
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-binaryen
|
id: cache-binaryen
|
||||||
with:
|
with:
|
||||||
key: binaryen-linux-arm64-v1
|
key: binaryen-linux-arm64-v1
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ jobs:
|
|||||||
build-windows:
|
build-windows:
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
steps:
|
steps:
|
||||||
- name: Install Go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: '1.18.1'
|
|
||||||
- uses: brechtm/setup-scoop@v2
|
- uses: brechtm/setup-scoop@v2
|
||||||
with:
|
with:
|
||||||
scoop_update: 'false'
|
scoop_update: 'false'
|
||||||
@@ -30,15 +26,13 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Cache Go
|
- name: Install Go
|
||||||
uses: actions/cache@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
key: go-cache-windows-v1-${{ hashFiles('go.mod') }}
|
go-version: '1.19'
|
||||||
path: |
|
cache: true
|
||||||
~/AppData/Local/go-build
|
|
||||||
~/go/pkg/mod
|
|
||||||
- name: Cache LLVM source
|
- name: Cache LLVM source
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-14-windows-v2
|
key: llvm-source-14-windows-v2
|
||||||
@@ -52,7 +46,7 @@ jobs:
|
|||||||
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-source.outputs.cache-hit != 'true'
|
||||||
run: make llvm-source
|
run: make llvm-source
|
||||||
- name: Cache LLVM build
|
- name: Cache LLVM build
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-14-windows-v2
|
key: llvm-build-14-windows-v2
|
||||||
@@ -69,7 +63,7 @@ jobs:
|
|||||||
# Remove unnecessary object files (to reduce cache size).
|
# Remove unnecessary object files (to reduce cache size).
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
- name: Cache wasi-libc sysroot
|
- name: Cache wasi-libc sysroot
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
id: cache-wasi-libc
|
id: cache-wasi-libc
|
||||||
with:
|
with:
|
||||||
key: wasi-libc-sysroot-v4
|
key: wasi-libc-sysroot-v4
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
# tinygo-llvm stage obtains the llvm source for TinyGo
|
# tinygo-llvm stage obtains the llvm source for TinyGo
|
||||||
FROM golang:1.18 AS tinygo-llvm
|
FROM golang:1.19 AS tinygo-llvm
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y apt-utils make cmake clang-11 binutils-avr gcc-avr avr-libc ninja-build
|
apt-get install -y apt-utils make cmake clang-11 binutils-avr gcc-avr avr-libc ninja-build
|
||||||
|
|||||||
@@ -326,11 +326,14 @@ TEST_PACKAGES_FAST += crypto/elliptic/internal/fiat
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# archive/zip requires os.ReadAt, which is not yet supported on windows
|
# archive/zip requires os.ReadAt, which is not yet supported on windows
|
||||||
|
# compress/flate appears to hang on wasi
|
||||||
|
# compress/lzw appears to hang on wasi
|
||||||
|
# crypto/hmac fails on wasi, it exits with a "slice out of range" panic
|
||||||
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows
|
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows
|
||||||
# io/fs requires os.ReadDir, which is not yet supported on windows or wasi
|
# io/ioutil requires os.ReadDir, which is not yet supported on windows or wasi
|
||||||
|
# strconv requires recover() which is not yet supported on wasi
|
||||||
|
# text/template/parse requires recover(), which is not yet supported on wasi
|
||||||
# testing/fstest requires os.ReadDir, which is not yet supported on windows or wasi
|
# testing/fstest requires os.ReadDir, which is not yet supported on windows or wasi
|
||||||
# compress/flate fails windows go 1.18, https://github.com/tinygo-org/tinygo/issues/2762
|
|
||||||
# compress/lzw fails windows go 1.18 wasi, https://github.com/tinygo-org/tinygo/issues/2762
|
|
||||||
|
|
||||||
# Additional standard library packages that pass tests on individual platforms
|
# Additional standard library packages that pass tests on individual platforms
|
||||||
TEST_PACKAGES_LINUX := \
|
TEST_PACKAGES_LINUX := \
|
||||||
@@ -340,7 +343,6 @@ TEST_PACKAGES_LINUX := \
|
|||||||
crypto/hmac \
|
crypto/hmac \
|
||||||
debug/dwarf \
|
debug/dwarf \
|
||||||
debug/plan9obj \
|
debug/plan9obj \
|
||||||
io/fs \
|
|
||||||
io/ioutil \
|
io/ioutil \
|
||||||
strconv \
|
strconv \
|
||||||
testing/fstest \
|
testing/fstest \
|
||||||
@@ -349,7 +351,12 @@ TEST_PACKAGES_LINUX := \
|
|||||||
TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
|
TEST_PACKAGES_DARWIN := $(TEST_PACKAGES_LINUX)
|
||||||
|
|
||||||
TEST_PACKAGES_WINDOWS := \
|
TEST_PACKAGES_WINDOWS := \
|
||||||
compress/lzw
|
compress/flate \
|
||||||
|
compress/lzw \
|
||||||
|
crypto/hmac \
|
||||||
|
strconv \
|
||||||
|
text/template/parse \
|
||||||
|
$(nil)
|
||||||
|
|
||||||
# Report platforms on which each standard library package is known to pass tests
|
# Report platforms on which each standard library package is known to pass tests
|
||||||
jointmp := $(shell echo /tmp/join.$$$$)
|
jointmp := $(shell echo /tmp/join.$$$$)
|
||||||
@@ -364,12 +371,15 @@ report-stdlib-tests-pass:
|
|||||||
# Standard library packages that pass tests quickly on the current platform
|
# Standard library packages that pass tests quickly on the current platform
|
||||||
ifeq ($(shell uname),Darwin)
|
ifeq ($(shell uname),Darwin)
|
||||||
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_DARWIN)
|
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_DARWIN)
|
||||||
|
TEST_IOFS := true
|
||||||
endif
|
endif
|
||||||
ifeq ($(shell uname),Linux)
|
ifeq ($(shell uname),Linux)
|
||||||
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_LINUX)
|
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_LINUX)
|
||||||
|
TEST_IOFS := true
|
||||||
endif
|
endif
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS)
|
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS)
|
||||||
|
TEST_IOFS := false
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Test known-working standard library packages.
|
# Test known-working standard library packages.
|
||||||
@@ -377,6 +387,12 @@ endif
|
|||||||
.PHONY: tinygo-test
|
.PHONY: tinygo-test
|
||||||
tinygo-test:
|
tinygo-test:
|
||||||
$(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
$(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||||
|
@# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also
|
||||||
|
@# requires a large stack-size. Hence, io/fs is only run conditionally.
|
||||||
|
@# For more details, see the comments on issue #3143.
|
||||||
|
ifeq ($(TEST_IOFS),true)
|
||||||
|
$(TINYGO) test -stack-size=6MB io/fs
|
||||||
|
endif
|
||||||
tinygo-test-fast:
|
tinygo-test-fast:
|
||||||
$(TINYGO) test $(TEST_PACKAGES_HOST)
|
$(TINYGO) test $(TEST_PACKAGES_HOST)
|
||||||
tinygo-bench:
|
tinygo-bench:
|
||||||
@@ -386,9 +402,9 @@ tinygo-bench-fast:
|
|||||||
|
|
||||||
# Same thing, except for wasi rather than the current platform.
|
# Same thing, except for wasi rather than the current platform.
|
||||||
tinygo-test-wasi:
|
tinygo-test-wasi:
|
||||||
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW)
|
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||||
tinygo-test-wasi-fast:
|
tinygo-test-wasi-fast:
|
||||||
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST)
|
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||||
tinygo-bench-wasi:
|
tinygo-bench-wasi:
|
||||||
$(TINYGO) test -target wasi -bench . $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW)
|
$(TINYGO) test -target wasi -bench . $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW)
|
||||||
tinygo-bench-wasi-fast:
|
tinygo-bench-wasi-fast:
|
||||||
@@ -410,6 +426,7 @@ tinygo-baremetal:
|
|||||||
.PHONY: smoketest
|
.PHONY: smoketest
|
||||||
smoketest:
|
smoketest:
|
||||||
$(TINYGO) version
|
$(TINYGO) version
|
||||||
|
$(TINYGO) targets > /dev/null
|
||||||
# regression test for #2892
|
# regression test for #2892
|
||||||
cd tests/testing/recurse && ($(TINYGO) test ./... > recurse.log && cat recurse.log && test $$(wc -l < recurse.log) = 2 && rm recurse.log)
|
cd tests/testing/recurse && ($(TINYGO) test ./... > recurse.log && cat recurse.log && test $$(wc -l < recurse.log) = 2 && rm recurse.log)
|
||||||
# compile-only platform-independent examples
|
# compile-only platform-independent examples
|
||||||
@@ -519,6 +536,8 @@ endif
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=feather-m4 examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=feather-m4 examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=matrixportal-m4 examples/blinky1
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=pybadge examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=pybadge examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=metro-m4-airlift examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=metro-m4-airlift examples/blinky1
|
||||||
@@ -599,7 +618,7 @@ endif
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=challenger-rp2040 examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=challenger-rp2040 examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=trinkey-qt2040 examples/adc_rp2040
|
$(TINYGO) build -size short -o test.hex -target=trinkey-qt2040 examples/temp
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
# test pwm
|
# test pwm
|
||||||
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
|
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
|
||||||
@@ -681,7 +700,9 @@ ifneq ($(XTENSA), 0)
|
|||||||
$(TINYGO) build -size short -o test.bin -target mch2022 examples/serial
|
$(TINYGO) build -size short -o test.bin -target mch2022 examples/serial
|
||||||
@$(MD5SUM) test.bin
|
@$(MD5SUM) test.bin
|
||||||
endif
|
endif
|
||||||
$(TINYGO) build -size short -o test.bin -target=esp32c3 examples/serial
|
$(TINYGO) build -size short -o test.bin -target=esp32c3 examples/serial
|
||||||
|
@$(MD5SUM) test.bin
|
||||||
|
$(TINYGO) build -size short -o test.bin -target=esp32c3-12f examples/serial
|
||||||
@$(MD5SUM) test.bin
|
@$(MD5SUM) test.bin
|
||||||
$(TINYGO) build -size short -o test.bin -target=m5stamp-c3 examples/serial
|
$(TINYGO) build -size short -o test.bin -target=m5stamp-c3 examples/serial
|
||||||
@$(MD5SUM) test.bin
|
@$(MD5SUM) test.bin
|
||||||
@@ -689,8 +710,6 @@ endif
|
|||||||
@$(MD5SUM) test.bin
|
@$(MD5SUM) test.bin
|
||||||
$(TINYGO) build -size short -o test.hex -target=hifive1b examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=hifive1b examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=hifive1-qemu examples/serial
|
|
||||||
@$(MD5SUM) test.hex
|
|
||||||
$(TINYGO) build -size short -o test.hex -target=maixbit examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=maixbit examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
ifneq ($(WASM), 0)
|
ifneq ($(WASM), 0)
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ The following 91 microcontroller boards are currently supported:
|
|||||||
* [Seeed LoRa-E5 Development Kit](https://www.seeedstudio.com/LoRa-E5-Dev-Kit-p-4868.html)
|
* [Seeed LoRa-E5 Development Kit](https://www.seeedstudio.com/LoRa-E5-Dev-Kit-p-4868.html)
|
||||||
* [Seeed Sipeed MAix BiT](https://www.seeedstudio.com/Sipeed-MAix-BiT-for-RISC-V-AI-IoT-p-2872.html)
|
* [Seeed Sipeed MAix BiT](https://www.seeedstudio.com/Sipeed-MAix-BiT-for-RISC-V-AI-IoT-p-2872.html)
|
||||||
* [Seeed Wio Terminal](https://www.seeedstudio.com/Wio-Terminal-p-4509.html)
|
* [Seeed Wio Terminal](https://www.seeedstudio.com/Wio-Terminal-p-4509.html)
|
||||||
* [SiFIve HiFive1 Rev B](https://www.sifive.com/boards/hifive1)
|
* [SiFIve HiFive1 Rev B](https://www.sifive.com/boards/hifive1-rev-b)
|
||||||
* [Sparkfun Thing Plus RP2040](https://www.sparkfun.com/products/17745)
|
* [Sparkfun Thing Plus RP2040](https://www.sparkfun.com/products/17745)
|
||||||
* [ST Micro "Nucleo" F103RB](https://www.st.com/en/evaluation-tools/nucleo-f103rb.html)
|
* [ST Micro "Nucleo" F103RB](https://www.st.com/en/evaluation-tools/nucleo-f103rb.html)
|
||||||
* [ST Micro "Nucleo" F722ZE](https://www.st.com/en/evaluation-tools/nucleo-f722ze.html)
|
* [ST Micro "Nucleo" F722ZE](https://www.st.com/en/evaluation-tools/nucleo-f722ze.html)
|
||||||
|
|||||||
+1
-1
@@ -178,7 +178,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
|
|||||||
|
|
||||||
Scheduler: config.Scheduler(),
|
Scheduler: config.Scheduler(),
|
||||||
AutomaticStackSize: config.AutomaticStackSize(),
|
AutomaticStackSize: config.AutomaticStackSize(),
|
||||||
DefaultStackSize: config.Target.DefaultStackSize,
|
DefaultStackSize: config.StackSize(),
|
||||||
NeedsStackObjects: config.NeedsStackObjects(),
|
NeedsStackObjects: config.NeedsStackObjects(),
|
||||||
Debug: true,
|
Debug: true,
|
||||||
}
|
}
|
||||||
|
|||||||
+57
-16
@@ -32,6 +32,7 @@ type cgoPackage struct {
|
|||||||
errors []error
|
errors []error
|
||||||
currentDir string // current working directory
|
currentDir string // current working directory
|
||||||
packageDir string // full path to the package to process
|
packageDir string // full path to the package to process
|
||||||
|
importPath string
|
||||||
fset *token.FileSet
|
fset *token.FileSet
|
||||||
tokenFiles map[string]*token.File
|
tokenFiles map[string]*token.File
|
||||||
definedGlobally map[string]ast.Node
|
definedGlobally map[string]ast.Node
|
||||||
@@ -39,12 +40,15 @@ type cgoPackage struct {
|
|||||||
cflags []string // CFlags from #cgo lines
|
cflags []string // CFlags from #cgo lines
|
||||||
ldflags []string // LDFlags from #cgo lines
|
ldflags []string // LDFlags from #cgo lines
|
||||||
visitedFiles map[string][]byte
|
visitedFiles map[string][]byte
|
||||||
|
cgoHeaders []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// cgoFile holds information only for a single Go file (with one or more
|
// cgoFile holds information only for a single Go file (with one or more
|
||||||
// `import "C"` statements).
|
// `import "C"` statements).
|
||||||
type cgoFile struct {
|
type cgoFile struct {
|
||||||
*cgoPackage
|
*cgoPackage
|
||||||
|
file *ast.File
|
||||||
|
index int
|
||||||
defined map[string]ast.Node
|
defined map[string]ast.Node
|
||||||
names map[string]clangCursor
|
names map[string]clangCursor
|
||||||
}
|
}
|
||||||
@@ -158,9 +162,10 @@ func GoBytes(ptr unsafe.Pointer, length C.int) []byte {
|
|||||||
// functions), the CFLAGS and LDFLAGS found in #cgo lines, and a map of file
|
// functions), the CFLAGS and LDFLAGS found in #cgo lines, and a map of file
|
||||||
// hashes of the accessed C header files. If there is one or more error, it
|
// hashes of the accessed C header files. If there is one or more error, it
|
||||||
// returns these in the []error slice but still modifies the AST.
|
// returns these in the []error slice but still modifies the AST.
|
||||||
func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string, clangHeaders string) (*ast.File, []string, []string, []string, map[string][]byte, []error) {
|
func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cflags []string, clangHeaders string) (*ast.File, []string, []string, []string, map[string][]byte, []error) {
|
||||||
p := &cgoPackage{
|
p := &cgoPackage{
|
||||||
currentDir: dir,
|
currentDir: dir,
|
||||||
|
importPath: importPath,
|
||||||
fset: fset,
|
fset: fset,
|
||||||
tokenFiles: map[string]*token.File{},
|
tokenFiles: map[string]*token.File{},
|
||||||
definedGlobally: map[string]ast.Node{},
|
definedGlobally: map[string]ast.Node{},
|
||||||
@@ -210,13 +215,13 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Patch some types, for example *C.char in C.CString.
|
// Patch some types, for example *C.char in C.CString.
|
||||||
cf := p.newCGoFile()
|
cf := p.newCGoFile(nil, -1) // dummy *cgoFile for the walker
|
||||||
astutil.Apply(p.generated, func(cursor *astutil.Cursor) bool {
|
astutil.Apply(p.generated, func(cursor *astutil.Cursor) bool {
|
||||||
return cf.walker(cursor, nil)
|
return cf.walker(cursor, nil)
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
||||||
// Find `import "C"` C fragments in the file.
|
// Find `import "C"` C fragments in the file.
|
||||||
cgoHeaders := make([]string, len(files)) // combined CGo header fragment for each file
|
p.cgoHeaders = make([]string, len(files)) // combined CGo header fragment for each file
|
||||||
for i, f := range files {
|
for i, f := range files {
|
||||||
var cgoHeader string
|
var cgoHeader string
|
||||||
for i := 0; i < len(f.Decls); i++ {
|
for i := 0; i < len(f.Decls); i++ {
|
||||||
@@ -275,7 +280,7 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string
|
|||||||
cgoHeader += fragment
|
cgoHeader += fragment
|
||||||
}
|
}
|
||||||
|
|
||||||
cgoHeaders[i] = cgoHeader
|
p.cgoHeaders[i] = cgoHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define CFlags that will be used while parsing the package.
|
// Define CFlags that will be used while parsing the package.
|
||||||
@@ -289,7 +294,7 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve types such as C.int, C.longlong, etc from C.
|
// Retrieve types such as C.int, C.longlong, etc from C.
|
||||||
p.newCGoFile().readNames(builtinAliasTypedefs, cflagsForCGo, "", func(names map[string]clangCursor) {
|
p.newCGoFile(nil, -1).readNames(builtinAliasTypedefs, cflagsForCGo, "", func(names map[string]clangCursor) {
|
||||||
gen := &ast.GenDecl{
|
gen := &ast.GenDecl{
|
||||||
TokPos: token.NoPos,
|
TokPos: token.NoPos,
|
||||||
Tok: token.TYPE,
|
Tok: token.TYPE,
|
||||||
@@ -303,8 +308,8 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string
|
|||||||
|
|
||||||
// Process CGo imports for each file.
|
// Process CGo imports for each file.
|
||||||
for i, f := range files {
|
for i, f := range files {
|
||||||
cf := p.newCGoFile()
|
cf := p.newCGoFile(f, i)
|
||||||
cf.readNames(cgoHeaders[i], cflagsForCGo, filepath.Base(fset.File(f.Pos()).Name()), func(names map[string]clangCursor) {
|
cf.readNames(p.cgoHeaders[i], cflagsForCGo, filepath.Base(fset.File(f.Pos()).Name()), func(names map[string]clangCursor) {
|
||||||
for _, name := range builtinAliases {
|
for _, name := range builtinAliases {
|
||||||
// Names such as C.int should not be obtained from C.
|
// Names such as C.int should not be obtained from C.
|
||||||
// This works around an issue in picolibc that has `#define int`
|
// This works around an issue in picolibc that has `#define int`
|
||||||
@@ -320,12 +325,14 @@ func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string
|
|||||||
// Print the newly generated in-memory AST, for debugging.
|
// Print the newly generated in-memory AST, for debugging.
|
||||||
//ast.Print(fset, p.generated)
|
//ast.Print(fset, p.generated)
|
||||||
|
|
||||||
return p.generated, cgoHeaders, p.cflags, p.ldflags, p.visitedFiles, p.errors
|
return p.generated, p.cgoHeaders, p.cflags, p.ldflags, p.visitedFiles, p.errors
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *cgoPackage) newCGoFile() *cgoFile {
|
func (p *cgoPackage) newCGoFile(file *ast.File, index int) *cgoFile {
|
||||||
return &cgoFile{
|
return &cgoFile{
|
||||||
cgoPackage: p,
|
cgoPackage: p,
|
||||||
|
file: file,
|
||||||
|
index: index,
|
||||||
defined: make(map[string]ast.Node),
|
defined: make(map[string]ast.Node),
|
||||||
names: make(map[string]clangCursor),
|
names: make(map[string]clangCursor),
|
||||||
}
|
}
|
||||||
@@ -1117,8 +1124,11 @@ func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) st
|
|||||||
return alias
|
return alias
|
||||||
}
|
}
|
||||||
node := f.getASTDeclNode(name, found, iscall)
|
node := f.getASTDeclNode(name, found, iscall)
|
||||||
if _, ok := node.(*ast.FuncDecl); ok && !iscall {
|
if node, ok := node.(*ast.FuncDecl); ok {
|
||||||
return "C." + name + "$funcaddr"
|
if !iscall {
|
||||||
|
return node.Name.Name + "$funcaddr"
|
||||||
|
}
|
||||||
|
return node.Name.Name
|
||||||
}
|
}
|
||||||
return "C." + name
|
return "C." + name
|
||||||
}
|
}
|
||||||
@@ -1142,7 +1152,7 @@ func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) as
|
|||||||
// Original cgo reports an error like
|
// Original cgo reports an error like
|
||||||
// cgo: inconsistent definitions for C.myint
|
// cgo: inconsistent definitions for C.myint
|
||||||
// which is far less helpful.
|
// which is far less helpful.
|
||||||
f.addError(getPos(node), "defined previously at "+f.fset.Position(getPos(newNode)).String()+" with a different type")
|
f.addError(getPos(node), name+" defined previously at "+f.fset.Position(getPos(newNode)).String()+" with a different type")
|
||||||
}
|
}
|
||||||
f.defined[name] = node
|
f.defined[name] = node
|
||||||
return node
|
return node
|
||||||
@@ -1150,11 +1160,39 @@ func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) as
|
|||||||
|
|
||||||
// The declaration has no AST node. Create it now.
|
// The declaration has no AST node. Create it now.
|
||||||
f.defined[name] = nil
|
f.defined[name] = nil
|
||||||
node, elaboratedType := f.createASTNode(name, found)
|
node, extra := f.createASTNode(name, found)
|
||||||
f.defined[name] = node
|
f.defined[name] = node
|
||||||
f.definedGlobally[name] = node
|
|
||||||
switch node := node.(type) {
|
switch node := node.(type) {
|
||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
|
if strings.HasPrefix(node.Doc.List[0].Text, "//export _Cgo_static_") {
|
||||||
|
// Static function. Only accessible in the current Go file.
|
||||||
|
globalName := strings.TrimPrefix(node.Doc.List[0].Text, "//export ")
|
||||||
|
// Make an alias. Normally this is done using the alias function
|
||||||
|
// attribute, but MacOS for some reason doesn't support this (even
|
||||||
|
// though the linker has support for aliases in the form of N_INDR).
|
||||||
|
// Therefore, create an actual function for MacOS.
|
||||||
|
var params []string
|
||||||
|
for _, param := range node.Type.Params.List {
|
||||||
|
params = append(params, param.Names[0].Name)
|
||||||
|
}
|
||||||
|
callInst := fmt.Sprintf("%s(%s);", name, strings.Join(params, ", "))
|
||||||
|
if node.Type.Results != nil {
|
||||||
|
callInst = "return " + callInst
|
||||||
|
}
|
||||||
|
aliasDeclaration := fmt.Sprintf(`
|
||||||
|
#ifdef __APPLE__
|
||||||
|
%s {
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern __typeof(%s) %s __attribute__((alias(%#v)));
|
||||||
|
#endif
|
||||||
|
`, extra.(string), callInst, name, globalName, name)
|
||||||
|
f.cgoHeaders[f.index] += "\n\n" + aliasDeclaration
|
||||||
|
} else {
|
||||||
|
// Regular (non-static) function.
|
||||||
|
f.definedGlobally[name] = node
|
||||||
|
}
|
||||||
f.generated.Decls = append(f.generated.Decls, node)
|
f.generated.Decls = append(f.generated.Decls, node)
|
||||||
// Also add a declaration like the following:
|
// Also add a declaration like the following:
|
||||||
// var C.foo$funcaddr unsafe.Pointer
|
// var C.foo$funcaddr unsafe.Pointer
|
||||||
@@ -1162,7 +1200,7 @@ func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) as
|
|||||||
Tok: token.VAR,
|
Tok: token.VAR,
|
||||||
Specs: []ast.Spec{
|
Specs: []ast.Spec{
|
||||||
&ast.ValueSpec{
|
&ast.ValueSpec{
|
||||||
Names: []*ast.Ident{{Name: "C." + name + "$funcaddr"}},
|
Names: []*ast.Ident{{Name: node.Name.Name + "$funcaddr"}},
|
||||||
Type: &ast.SelectorExpr{
|
Type: &ast.SelectorExpr{
|
||||||
X: &ast.Ident{Name: "unsafe"},
|
X: &ast.Ident{Name: "unsafe"},
|
||||||
Sel: &ast.Ident{Name: "Pointer"},
|
Sel: &ast.Ident{Name: "Pointer"},
|
||||||
@@ -1171,8 +1209,10 @@ func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) as
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
case *ast.GenDecl:
|
case *ast.GenDecl:
|
||||||
|
f.definedGlobally[name] = node
|
||||||
f.generated.Decls = append(f.generated.Decls, node)
|
f.generated.Decls = append(f.generated.Decls, node)
|
||||||
case *ast.TypeSpec:
|
case *ast.TypeSpec:
|
||||||
|
f.definedGlobally[name] = node
|
||||||
f.generated.Decls = append(f.generated.Decls, &ast.GenDecl{
|
f.generated.Decls = append(f.generated.Decls, &ast.GenDecl{
|
||||||
Tok: token.TYPE,
|
Tok: token.TYPE,
|
||||||
Specs: []ast.Spec{node},
|
Specs: []ast.Spec{node},
|
||||||
@@ -1186,7 +1226,8 @@ func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) as
|
|||||||
|
|
||||||
// If this is a struct or union it may need bitfields or union accessor
|
// If this is a struct or union it may need bitfields or union accessor
|
||||||
// methods.
|
// methods.
|
||||||
if elaboratedType != nil {
|
switch elaboratedType := extra.(type) {
|
||||||
|
case *elaboratedTypeInfo:
|
||||||
// Add struct bitfields.
|
// Add struct bitfields.
|
||||||
for _, bitfield := range elaboratedType.bitfields {
|
for _, bitfield := range elaboratedType.bitfields {
|
||||||
f.createBitfieldGetter(bitfield, "C."+name)
|
f.createBitfieldGetter(bitfield, "C."+name)
|
||||||
|
|||||||
+1
-1
@@ -48,7 +48,7 @@ func TestCGo(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process the AST with CGo.
|
// Process the AST with CGo.
|
||||||
cgoAST, _, _, _, _, cgoErrors := Process([]*ast.File{f}, "testdata", fset, cflags, "")
|
cgoAST, _, _, _, _, cgoErrors := Process([]*ast.File{f}, "testdata", "main", fset, cflags, "")
|
||||||
|
|
||||||
// Check the AST for type errors.
|
// Check the AST for type errors.
|
||||||
var typecheckErrors []error
|
var typecheckErrors []error
|
||||||
|
|||||||
+33
-4
@@ -4,7 +4,9 @@ package cgo
|
|||||||
// modification. It does not touch the AST itself.
|
// modification. It does not touch the AST itself.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/scanner"
|
"go/scanner"
|
||||||
@@ -43,6 +45,8 @@ typedef struct {
|
|||||||
GoCXCursor tinygo_clang_getTranslationUnitCursor(CXTranslationUnit tu);
|
GoCXCursor tinygo_clang_getTranslationUnitCursor(CXTranslationUnit tu);
|
||||||
unsigned tinygo_clang_visitChildren(GoCXCursor parent, CXCursorVisitor visitor, CXClientData client_data);
|
unsigned tinygo_clang_visitChildren(GoCXCursor parent, CXCursorVisitor visitor, CXClientData client_data);
|
||||||
CXString tinygo_clang_getCursorSpelling(GoCXCursor c);
|
CXString tinygo_clang_getCursorSpelling(GoCXCursor c);
|
||||||
|
CXString tinygo_clang_getCursorPrettyPrinted(GoCXCursor c, CXPrintingPolicy Policy);
|
||||||
|
CXPrintingPolicy tinygo_clang_getCursorPrintingPolicy(GoCXCursor c);
|
||||||
enum CXCursorKind tinygo_clang_getCursorKind(GoCXCursor c);
|
enum CXCursorKind tinygo_clang_getCursorKind(GoCXCursor c);
|
||||||
CXType tinygo_clang_getCursorType(GoCXCursor c);
|
CXType tinygo_clang_getCursorType(GoCXCursor c);
|
||||||
GoCXCursor tinygo_clang_getTypeDeclaration(CXType t);
|
GoCXCursor tinygo_clang_getTypeDeclaration(CXType t);
|
||||||
@@ -50,6 +54,7 @@ CXType tinygo_clang_getTypedefDeclUnderlyingType(GoCXCursor c);
|
|||||||
CXType tinygo_clang_getCursorResultType(GoCXCursor c);
|
CXType tinygo_clang_getCursorResultType(GoCXCursor c);
|
||||||
int tinygo_clang_Cursor_getNumArguments(GoCXCursor c);
|
int tinygo_clang_Cursor_getNumArguments(GoCXCursor c);
|
||||||
GoCXCursor tinygo_clang_Cursor_getArgument(GoCXCursor c, unsigned i);
|
GoCXCursor tinygo_clang_Cursor_getArgument(GoCXCursor c, unsigned i);
|
||||||
|
enum CX_StorageClass tinygo_clang_Cursor_getStorageClass(GoCXCursor c);
|
||||||
CXSourceLocation tinygo_clang_getCursorLocation(GoCXCursor c);
|
CXSourceLocation tinygo_clang_getCursorLocation(GoCXCursor c);
|
||||||
CXSourceRange tinygo_clang_getCursorExtent(GoCXCursor c);
|
CXSourceRange tinygo_clang_getCursorExtent(GoCXCursor c);
|
||||||
CXTranslationUnit tinygo_clang_Cursor_getTranslationUnit(GoCXCursor c);
|
CXTranslationUnit tinygo_clang_Cursor_getTranslationUnit(GoCXCursor c);
|
||||||
@@ -189,7 +194,7 @@ func (f *cgoFile) readNames(fragment string, cflags []string, filename string, c
|
|||||||
|
|
||||||
// Convert the AST node under the given Clang cursor to a Go AST node and return
|
// Convert the AST node under the given Clang cursor to a Go AST node and return
|
||||||
// it.
|
// it.
|
||||||
func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, *elaboratedTypeInfo) {
|
func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
|
||||||
kind := C.tinygo_clang_getCursorKind(c)
|
kind := C.tinygo_clang_getCursorKind(c)
|
||||||
pos := f.getCursorPosition(c)
|
pos := f.getCursorPosition(c)
|
||||||
switch kind {
|
switch kind {
|
||||||
@@ -200,19 +205,43 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, *elaborat
|
|||||||
Kind: ast.Fun,
|
Kind: ast.Fun,
|
||||||
Name: "C." + name,
|
Name: "C." + name,
|
||||||
}
|
}
|
||||||
|
exportName := name
|
||||||
|
localName := name
|
||||||
|
var stringSignature string
|
||||||
|
if C.tinygo_clang_Cursor_getStorageClass(c) == C.CX_SC_Static {
|
||||||
|
// A static function is assigned a globally unique symbol name based
|
||||||
|
// on the file path (like _Cgo_static_2d09198adbf58f4f4655_foo) and
|
||||||
|
// has a different Go name in the form of C.foo!symbols.go instead
|
||||||
|
// of just C.foo.
|
||||||
|
path := f.importPath + "/" + filepath.Base(f.fset.File(f.file.Pos()).Name())
|
||||||
|
staticIDBuf := sha256.Sum256([]byte(path))
|
||||||
|
staticID := hex.EncodeToString(staticIDBuf[:10])
|
||||||
|
exportName = "_Cgo_static_" + staticID + "_" + name
|
||||||
|
localName = name + "!" + filepath.Base(path)
|
||||||
|
|
||||||
|
// Create a signature. This is necessary for MacOS to forward the
|
||||||
|
// call, because MacOS doesn't support aliases like ELF and PE do.
|
||||||
|
// (There is N_INDR but __attribute__((alias("..."))) doesn't work).
|
||||||
|
policy := C.tinygo_clang_getCursorPrintingPolicy(c)
|
||||||
|
defer C.clang_PrintingPolicy_dispose(policy)
|
||||||
|
C.clang_PrintingPolicy_setProperty(policy, C.CXPrintingPolicy_TerseOutput, 1)
|
||||||
|
stringSignature = getString(C.tinygo_clang_getCursorPrettyPrinted(c, policy))
|
||||||
|
stringSignature = strings.Replace(stringSignature, " "+name+"(", " "+exportName+"(", 1)
|
||||||
|
stringSignature = strings.TrimPrefix(stringSignature, "static ")
|
||||||
|
}
|
||||||
args := make([]*ast.Field, numArgs)
|
args := make([]*ast.Field, numArgs)
|
||||||
decl := &ast.FuncDecl{
|
decl := &ast.FuncDecl{
|
||||||
Doc: &ast.CommentGroup{
|
Doc: &ast.CommentGroup{
|
||||||
List: []*ast.Comment{
|
List: []*ast.Comment{
|
||||||
{
|
{
|
||||||
Slash: pos - 1,
|
Slash: pos - 1,
|
||||||
Text: "//export " + name,
|
Text: "//export " + exportName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Name: &ast.Ident{
|
Name: &ast.Ident{
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Name: "C." + name,
|
Name: "C." + localName,
|
||||||
Obj: obj,
|
Obj: obj,
|
||||||
},
|
},
|
||||||
Type: &ast.FuncType{
|
Type: &ast.FuncType{
|
||||||
@@ -263,7 +292,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, *elaborat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
obj.Decl = decl
|
obj.Decl = decl
|
||||||
return decl, nil
|
return decl, stringSignature
|
||||||
case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
|
case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
|
||||||
typ := f.makeASTRecordType(c, pos)
|
typ := f.makeASTRecordType(c, pos)
|
||||||
typeName := "C." + name
|
typeName := "C." + name
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ CXString tinygo_clang_getCursorSpelling(CXCursor c) {
|
|||||||
return clang_getCursorSpelling(c);
|
return clang_getCursorSpelling(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CXString tinygo_clang_getCursorPrettyPrinted(CXCursor c, CXPrintingPolicy policy) {
|
||||||
|
return clang_getCursorPrettyPrinted(c, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
CXPrintingPolicy tinygo_clang_getCursorPrintingPolicy(CXCursor c) {
|
||||||
|
return clang_getCursorPrintingPolicy(c);
|
||||||
|
}
|
||||||
|
|
||||||
enum CXCursorKind tinygo_clang_getCursorKind(CXCursor c) {
|
enum CXCursorKind tinygo_clang_getCursorKind(CXCursor c) {
|
||||||
return clang_getCursorKind(c);
|
return clang_getCursorKind(c);
|
||||||
}
|
}
|
||||||
@@ -45,6 +53,10 @@ CXCursor tinygo_clang_Cursor_getArgument(CXCursor c, unsigned i) {
|
|||||||
return clang_Cursor_getArgument(c, i);
|
return clang_Cursor_getArgument(c, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CX_StorageClass tinygo_clang_Cursor_getStorageClass(CXCursor c) {
|
||||||
|
return clang_Cursor_getStorageClass(c);
|
||||||
|
}
|
||||||
|
|
||||||
CXSourceLocation tinygo_clang_getCursorLocation(CXCursor c) {
|
CXSourceLocation tinygo_clang_getCursorLocation(CXCursor c) {
|
||||||
return clang_getCursorLocation(c);
|
return clang_getCursorLocation(c);
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
@@ -5,6 +5,7 @@ package main
|
|||||||
int foo(int a, int b);
|
int foo(int a, int b);
|
||||||
void variadic0();
|
void variadic0();
|
||||||
void variadic2(int x, int y, ...);
|
void variadic2(int x, int y, ...);
|
||||||
|
static void staticfunc(int x);
|
||||||
|
|
||||||
// Global variable signatures.
|
// Global variable signatures.
|
||||||
extern int someValue;
|
extern int someValue;
|
||||||
@@ -16,6 +17,7 @@ func accessFunctions() {
|
|||||||
C.foo(3, 4)
|
C.foo(3, 4)
|
||||||
C.variadic0()
|
C.variadic0()
|
||||||
C.variadic2(3, 5)
|
C.variadic2(3, 5)
|
||||||
|
C.staticfunc(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func accessGlobals() {
|
func accessGlobals() {
|
||||||
|
|||||||
Vendored
+5
@@ -55,5 +55,10 @@ func C.variadic2(x C.int, y C.int)
|
|||||||
|
|
||||||
var C.variadic2$funcaddr unsafe.Pointer
|
var C.variadic2$funcaddr unsafe.Pointer
|
||||||
|
|
||||||
|
//export _Cgo_static_173c95a79b6df1980521_staticfunc
|
||||||
|
func C.staticfunc!symbols.go(x C.int)
|
||||||
|
|
||||||
|
var C.staticfunc!symbols.go$funcaddr unsafe.Pointer
|
||||||
|
|
||||||
//go:extern someValue
|
//go:extern someValue
|
||||||
var C.someValue C.int
|
var C.someValue C.int
|
||||||
|
|||||||
+17
-1
@@ -175,6 +175,15 @@ func (c *Config) AutomaticStackSize() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StackSize returns the default stack size to be used for goroutines, if the
|
||||||
|
// stack size could not be determined automatically at compile time.
|
||||||
|
func (c *Config) StackSize() uint64 {
|
||||||
|
if c.Options.StackSize != 0 {
|
||||||
|
return c.Options.StackSize
|
||||||
|
}
|
||||||
|
return c.Target.DefaultStackSize
|
||||||
|
}
|
||||||
|
|
||||||
// UseThinLTO returns whether ThinLTO should be used for the given target. Some
|
// UseThinLTO returns whether ThinLTO should be used for the given target. Some
|
||||||
// targets (such as wasm) are not yet supported.
|
// targets (such as wasm) are not yet supported.
|
||||||
// We should try and remove as many exceptions as possible in the future, so
|
// We should try and remove as many exceptions as possible in the future, so
|
||||||
@@ -457,7 +466,14 @@ func (c *Config) OpenOCDConfiguration() (args []string, err error) {
|
|||||||
args = append(args, "-c", cmd)
|
args = append(args, "-c", cmd)
|
||||||
}
|
}
|
||||||
if c.Target.OpenOCDTransport != "" {
|
if c.Target.OpenOCDTransport != "" {
|
||||||
args = append(args, "-c", "transport select "+c.Target.OpenOCDTransport)
|
transport := c.Target.OpenOCDTransport
|
||||||
|
if transport == "swd" {
|
||||||
|
switch openocdInterface {
|
||||||
|
case "stlink-dap":
|
||||||
|
transport = "dapdirect_swd"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = append(args, "-c", "transport select "+transport)
|
||||||
}
|
}
|
||||||
args = append(args, "-f", "target/"+c.Target.OpenOCDTarget+".cfg")
|
args = append(args, "-f", "target/"+c.Target.OpenOCDTarget+".cfg")
|
||||||
return args, nil
|
return args, nil
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ type Options struct {
|
|||||||
GC string
|
GC string
|
||||||
PanicStrategy string
|
PanicStrategy string
|
||||||
Scheduler string
|
Scheduler string
|
||||||
|
StackSize uint64 // goroutine stack size (if none could be automatically determined)
|
||||||
Serial string
|
Serial string
|
||||||
Work bool // -work flag to print temporary build directory
|
Work bool // -work flag to print temporary build directory
|
||||||
InterpTimeout time.Duration
|
InterpTimeout time.Duration
|
||||||
@@ -49,6 +50,8 @@ type Options struct {
|
|||||||
LLVMFeatures string
|
LLVMFeatures string
|
||||||
Directory string
|
Directory string
|
||||||
PrintJSON bool
|
PrintJSON bool
|
||||||
|
Monitor bool
|
||||||
|
BaudRate int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify performs a validation on the given options, raising an error if options are not valid.
|
// Verify performs a validation on the given options, raising an error if options are not valid.
|
||||||
|
|||||||
+17
-10
@@ -65,7 +65,7 @@ type TargetSpec struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// overrideProperties overrides all properties that are set in child into itself using reflection.
|
// overrideProperties overrides all properties that are set in child into itself using reflection.
|
||||||
func (spec *TargetSpec) overrideProperties(child *TargetSpec) {
|
func (spec *TargetSpec) overrideProperties(child *TargetSpec) error {
|
||||||
specType := reflect.TypeOf(spec).Elem()
|
specType := reflect.TypeOf(spec).Elem()
|
||||||
specValue := reflect.ValueOf(spec).Elem()
|
specValue := reflect.ValueOf(spec).Elem()
|
||||||
childValue := reflect.ValueOf(child).Elem()
|
childValue := reflect.ValueOf(child).Elem()
|
||||||
@@ -95,14 +95,15 @@ func (spec *TargetSpec) overrideProperties(child *TargetSpec) {
|
|||||||
for j := i + 1; j < dst.Len(); j++ {
|
for j := i + 1; j < dst.Len(); j++ {
|
||||||
w := dst.Index(j).String()
|
w := dst.Index(j).String()
|
||||||
if v == w {
|
if v == w {
|
||||||
panic("duplicate value '" + v + "' in field : " + field.Name)
|
return fmt.Errorf("duplicate value '%s' in field %s", v, field.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field type : " + kind.String())
|
return fmt.Errorf("unknown field type: %s", kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// load reads a target specification from the JSON in the given io.Reader. It
|
// load reads a target specification from the JSON in the given io.Reader. It
|
||||||
@@ -117,10 +118,10 @@ func (spec *TargetSpec) load(r io.Reader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loadFromGivenStr loads the TargetSpec from the given string that could be:
|
// loadFromGivenStr loads the TargetSpec from the given string that could be:
|
||||||
// - targets/ directory inside the compiler sources
|
// - targets/ directory inside the compiler sources
|
||||||
// - a relative or absolute path to custom (project specific) target specification .json file;
|
// - a relative or absolute path to custom (project specific) target specification .json file;
|
||||||
// the Inherits[] could contain the files from target folder (ex. stm32f4disco)
|
// the Inherits[] could contain the files from target folder (ex. stm32f4disco)
|
||||||
// as well as path to custom files (ex. myAwesomeProject.json)
|
// as well as path to custom files (ex. myAwesomeProject.json)
|
||||||
func (spec *TargetSpec) loadFromGivenStr(str string) error {
|
func (spec *TargetSpec) loadFromGivenStr(str string) error {
|
||||||
path := ""
|
path := ""
|
||||||
if strings.HasSuffix(str, ".json") {
|
if strings.HasSuffix(str, ".json") {
|
||||||
@@ -150,11 +151,17 @@ func (spec *TargetSpec) resolveInherits() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
newSpec.overrideProperties(subtarget)
|
err = newSpec.overrideProperties(subtarget)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When all properties are loaded, make sure they are properly inherited.
|
// When all properties are loaded, make sure they are properly inherited.
|
||||||
newSpec.overrideProperties(spec)
|
err := newSpec.overrideProperties(spec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
*spec = *newSpec
|
*spec = *newSpec
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -221,7 +228,7 @@ func LoadTarget(options *Options) (*TargetSpec, error) {
|
|||||||
// it includes all parents as specified in the "inherits" key.
|
// it includes all parents as specified in the "inherits" key.
|
||||||
err = spec.resolveInherits()
|
err = spec.resolveInherits()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("%s : %w", options.Target, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if spec.Scheduler == "asyncify" {
|
if spec.Scheduler == "asyncify" {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func TestCompiler(t *testing.T) {
|
|||||||
RelocationModel: config.RelocationModel(),
|
RelocationModel: config.RelocationModel(),
|
||||||
Scheduler: config.Scheduler(),
|
Scheduler: config.Scheduler(),
|
||||||
AutomaticStackSize: config.AutomaticStackSize(),
|
AutomaticStackSize: config.AutomaticStackSize(),
|
||||||
DefaultStackSize: config.Target.DefaultStackSize,
|
DefaultStackSize: config.StackSize(),
|
||||||
NeedsStackObjects: config.NeedsStackObjects(),
|
NeedsStackObjects: config.NeedsStackObjects(),
|
||||||
}
|
}
|
||||||
machine, err := NewTargetMachine(compilerConfig)
|
machine, err := NewTargetMachine(compilerConfig)
|
||||||
|
|||||||
+12
-10
@@ -163,18 +163,20 @@ func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value {
|
|||||||
// External/exported functions may not retain pointer values.
|
// External/exported functions may not retain pointer values.
|
||||||
// https://golang.org/cmd/cgo/#hdr-Passing_pointers
|
// https://golang.org/cmd/cgo/#hdr-Passing_pointers
|
||||||
if info.exported {
|
if info.exported {
|
||||||
// Set the wasm-import-module attribute if the function's module is set.
|
if c.archFamily() == "wasm32" {
|
||||||
if info.module != "" {
|
|
||||||
|
|
||||||
// We need to add the wasm-import-module and the wasm-import-name
|
// We need to add the wasm-import-module and the wasm-import-name
|
||||||
wasmImportModuleAttr := c.ctx.CreateStringAttribute("wasm-import-module", info.module)
|
// attributes.
|
||||||
llvmFn.AddFunctionAttr(wasmImportModuleAttr)
|
module := info.module
|
||||||
|
if module == "" {
|
||||||
// Add the Wasm Import Name, if we are a named wasm import
|
module = "env"
|
||||||
if info.importName != "" {
|
|
||||||
wasmImportNameAttr := c.ctx.CreateStringAttribute("wasm-import-name", info.importName)
|
|
||||||
llvmFn.AddFunctionAttr(wasmImportNameAttr)
|
|
||||||
}
|
}
|
||||||
|
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-module", module))
|
||||||
|
|
||||||
|
name := info.importName
|
||||||
|
if name == "" {
|
||||||
|
name = info.linkName
|
||||||
|
}
|
||||||
|
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-name", name))
|
||||||
}
|
}
|
||||||
nocaptureKind := llvm.AttributeKindID("nocapture")
|
nocaptureKind := llvm.AttributeKindID("nocapture")
|
||||||
nocapture := c.ctx.CreateEnumAttribute(nocaptureKind, 0)
|
nocapture := c.ctx.CreateEnumAttribute(nocaptureKind, 0)
|
||||||
|
|||||||
Vendored
+2
-2
@@ -62,7 +62,7 @@ declare void @main.undefinedFunctionNotInSection(i8*) #0
|
|||||||
|
|
||||||
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||||
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="extern_func" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="extern_func" "wasm-import-module"="env" "wasm-import-name"="extern_func" }
|
||||||
attributes #3 = { inlinehint nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
attributes #3 = { inlinehint nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||||
attributes #4 = { noinline nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
attributes #4 = { noinline nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
|
||||||
attributes #5 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="exportedFunctionInSection" }
|
attributes #5 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="exportedFunctionInSection" "wasm-import-module"="env" "wasm-import-name"="exportedFunctionInSection" }
|
||||||
|
|||||||
@@ -9,8 +9,10 @@ require (
|
|||||||
github.com/chromedp/chromedp v0.7.6
|
github.com/chromedp/chromedp v0.7.6
|
||||||
github.com/gofrs/flock v0.8.1
|
github.com/gofrs/flock v0.8.1
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
||||||
|
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
||||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
|
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
|
||||||
github.com/mattn/go-colorable v0.1.8
|
github.com/mattn/go-colorable v0.1.8
|
||||||
|
github.com/mattn/go-tty v0.0.4
|
||||||
go.bug.st/serial v1.3.5
|
go.bug.st/serial v1.3.5
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
|
||||||
golang.org/x/tools v0.1.11
|
golang.org/x/tools v0.1.11
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moA
|
|||||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||||
@@ -23,44 +22,47 @@ github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
|||||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
|
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
||||||
|
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
|
||||||
|
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw=
|
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw=
|
||||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M=
|
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M=
|
||||||
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
|
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
|
||||||
|
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
|
||||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
|
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
|
||||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
go.bug.st/serial v1.1.3 h1:YEBxJa9pKS9Wdg46B/jiaKbvvbUrjhZZZITfJHEJhaE=
|
|
||||||
go.bug.st/serial v1.1.3/go.mod h1:8TT7u/SwwNIpJ8QaG4s+HTjFt9ReXs2cdOU7ZEk50Dk=
|
|
||||||
go.bug.st/serial v1.3.5 h1:k50SqGZCnHZ2MiBQgzccXWG+kd/XpOs1jUljpDDKzaE=
|
go.bug.st/serial v1.3.5 h1:k50SqGZCnHZ2MiBQgzccXWG+kd/XpOs1jUljpDDKzaE=
|
||||||
go.bug.st/serial v1.3.5/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304=
|
go.bug.st/serial v1.3.5/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
|
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
||||||
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
|
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
|
||||||
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
|
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 h1:nSLR52mUw7DPQQVA3ZJFH63zjU4ME84fKiin6mdnYWc=
|
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 h1:nSLR52mUw7DPQQVA3ZJFH63zjU4ME84fKiin6mdnYWc=
|
||||||
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||||
|
|||||||
@@ -369,6 +369,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
|||||||
nBytes := uint32(operands[3].Uint())
|
nBytes := uint32(operands[3].Uint())
|
||||||
dstObj := mem.getWritable(dst.index())
|
dstObj := mem.getWritable(dst.index())
|
||||||
dstBuf := dstObj.buffer.asRawValue(r)
|
dstBuf := dstObj.buffer.asRawValue(r)
|
||||||
|
if mem.get(src.index()).buffer == nil {
|
||||||
|
// Looks like the source buffer is not defined.
|
||||||
|
// This can happen with //extern or //go:embed.
|
||||||
|
return nil, mem, r.errorAt(inst, errUnsupportedRuntimeInst)
|
||||||
|
}
|
||||||
srcBuf := mem.get(src.index()).buffer.asRawValue(r)
|
srcBuf := mem.get(src.index()).buffer.asRawValue(r)
|
||||||
copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():])
|
copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():])
|
||||||
dstObj.buffer = dstBuf
|
dstObj.buffer = dstBuf
|
||||||
|
|||||||
+1
-1
@@ -440,7 +440,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) {
|
|||||||
var initialCFlags []string
|
var initialCFlags []string
|
||||||
initialCFlags = append(initialCFlags, p.program.config.CFlags()...)
|
initialCFlags = append(initialCFlags, p.program.config.CFlags()...)
|
||||||
initialCFlags = append(initialCFlags, "-I"+p.Dir)
|
initialCFlags = append(initialCFlags, "-I"+p.Dir)
|
||||||
generated, headerCode, cflags, ldflags, accessedFiles, errs := cgo.Process(files, p.program.workingDir, p.program.fset, initialCFlags, p.program.clangHeaders)
|
generated, headerCode, cflags, ldflags, accessedFiles, errs := cgo.Process(files, p.program.workingDir, p.ImportPath, p.program.fset, initialCFlags, p.program.clangHeaders)
|
||||||
p.CFlags = append(initialCFlags, cflags...)
|
p.CFlags = append(initialCFlags, cflags...)
|
||||||
p.CGoHeaders = headerCode
|
p.CGoHeaders = headerCode
|
||||||
for path, hash := range accessedFiles {
|
for path, hash := range accessedFiles {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/shlex"
|
"github.com/google/shlex"
|
||||||
|
"github.com/inhies/go-bytesize"
|
||||||
"github.com/mattn/go-colorable"
|
"github.com/mattn/go-colorable"
|
||||||
"github.com/tinygo-org/tinygo/builder"
|
"github.com/tinygo-org/tinygo/builder"
|
||||||
"github.com/tinygo-org/tinygo/compileopts"
|
"github.com/tinygo-org/tinygo/compileopts"
|
||||||
@@ -243,17 +244,36 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
|
|||||||
// Tests are always run in the package directory.
|
// Tests are always run in the package directory.
|
||||||
cmd.Dir = result.MainDir
|
cmd.Dir = result.MainDir
|
||||||
|
|
||||||
// Wasmtime needs a few extra flags to work.
|
// wasmtime is the default emulator used for `-target=wasi`. wasmtime
|
||||||
|
// is a WebAssembly runtime CLI with WASI enabled by default. However,
|
||||||
|
// only stdio are allowed by default. For example, while STDOUT routes
|
||||||
|
// to the host, other files don't. It also does not inherit environment
|
||||||
|
// variables from the host. Some tests read testdata files, often from
|
||||||
|
// outside the package directory. Other tests require temporary
|
||||||
|
// writeable directories. We allow this by adding wasmtime flags below.
|
||||||
if config.EmulatorName() == "wasmtime" {
|
if config.EmulatorName() == "wasmtime" {
|
||||||
// Add directories to the module root, but skip the current working
|
// At this point, The current working directory is at the package
|
||||||
// directory which is already added by buildAndRun.
|
// directory. Ex. $GOROOT/src/compress/flate for compress/flate.
|
||||||
|
// buildAndRun has already added arguments for wasmtime, that allow
|
||||||
|
// read-access to files such as "testdata/huffman-zero.in".
|
||||||
|
//
|
||||||
|
// Ex. main(.wasm) --dir=. -- -test.v
|
||||||
|
|
||||||
|
// Below adds additional wasmtime flags in case a test reads files
|
||||||
|
// outside its directory, like "../testdata/e.txt". This allows any
|
||||||
|
// relative directory up to the module root, even if the test never
|
||||||
|
// reads any files.
|
||||||
|
//
|
||||||
|
// Ex. --dir=.. --dir=../.. --dir=../../..
|
||||||
dirs := dirsToModuleRoot(result.MainDir, result.ModuleRoot)
|
dirs := dirsToModuleRoot(result.MainDir, result.ModuleRoot)
|
||||||
var args []string
|
var args []string
|
||||||
for _, d := range dirs[1:] {
|
for _, d := range dirs[1:] {
|
||||||
args = append(args, "--dir="+d)
|
args = append(args, "--dir="+d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new temp directory just for this run, announce it to os.TempDir() via TMPDIR
|
// Some tests create temp directories using os.MkdirTemp or via
|
||||||
|
// t.TempDir(). Create a writeable directory and map it to the
|
||||||
|
// default tempDir environment variable: TMPDIR.
|
||||||
tmpdir, err := os.MkdirTemp("", "tinygotmp")
|
tmpdir, err := os.MkdirTemp("", "tinygotmp")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create temporary directory: %w", err)
|
return fmt.Errorf("failed to create temporary directory: %w", err)
|
||||||
@@ -262,7 +282,8 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
|
|||||||
// TODO: add option to not delete temp dir for debugging?
|
// TODO: add option to not delete temp dir for debugging?
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
// Insert new argments at the front of the command line argments.
|
// The below re-organizes the arguments so that the current
|
||||||
|
// directory is added last.
|
||||||
args = append(args, cmd.Args[1:]...)
|
args = append(args, cmd.Args[1:]...)
|
||||||
cmd.Args = append(cmd.Args[:1:1], args...)
|
cmd.Args = append(cmd.Args[:1:1], args...)
|
||||||
}
|
}
|
||||||
@@ -402,7 +423,6 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to flash", result.Binary, err}
|
return &commandError{"failed to flash", result.Binary, err}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
case "msd":
|
case "msd":
|
||||||
switch fileExt {
|
switch fileExt {
|
||||||
case ".uf2":
|
case ".uf2":
|
||||||
@@ -410,13 +430,11 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to flash", result.Binary, err}
|
return &commandError{"failed to flash", result.Binary, err}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
case ".hex":
|
case ".hex":
|
||||||
err := flashHexUsingMSD(config.Target.FlashVolume, result.Binary, config.Options)
|
err := flashHexUsingMSD(config.Target.FlashVolume, result.Binary, config.Options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to flash", result.Binary, err}
|
return &commandError{"failed to flash", result.Binary, err}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
default:
|
default:
|
||||||
return errors.New("mass storage device flashing currently only supports uf2 and hex")
|
return errors.New("mass storage device flashing currently only supports uf2 and hex")
|
||||||
}
|
}
|
||||||
@@ -437,7 +455,6 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to flash", result.Binary, err}
|
return &commandError{"failed to flash", result.Binary, err}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
case "bmp":
|
case "bmp":
|
||||||
gdb, err := config.Target.LookupGDB()
|
gdb, err := config.Target.LookupGDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -456,10 +473,13 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to flash", result.Binary, err}
|
return &commandError{"failed to flash", result.Binary, err}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown flash method: %s", flashMethod)
|
return fmt.Errorf("unknown flash method: %s", flashMethod)
|
||||||
}
|
}
|
||||||
|
if options.Monitor {
|
||||||
|
return Monitor("", options)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -978,7 +998,8 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
|
|||||||
preferredPortIDs = append(preferredPortIDs, [2]uint16{uint16(vid), uint16(pid)})
|
preferredPortIDs = append(preferredPortIDs, [2]uint16{uint16(vid), uint16(pid)})
|
||||||
}
|
}
|
||||||
|
|
||||||
var primaryPorts []string // ports picked from preferred USB VID/PID
|
var primaryPorts []string // ports picked from preferred USB VID/PID
|
||||||
|
var secondaryPorts []string // other ports (as a fallback)
|
||||||
for _, p := range portsList {
|
for _, p := range portsList {
|
||||||
if !p.IsUSB {
|
if !p.IsUSB {
|
||||||
continue
|
continue
|
||||||
@@ -1000,6 +1021,8 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secondaryPorts = append(secondaryPorts, p.Name)
|
||||||
}
|
}
|
||||||
if len(primaryPorts) == 1 {
|
if len(primaryPorts) == 1 {
|
||||||
// There is exactly one match in the set of preferred ports. Use
|
// There is exactly one match in the set of preferred ports. Use
|
||||||
@@ -1011,18 +1034,10 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
|
|||||||
// one device of the same type are connected (e.g. two Arduino
|
// one device of the same type are connected (e.g. two Arduino
|
||||||
// Unos).
|
// Unos).
|
||||||
ports = primaryPorts
|
ports = primaryPorts
|
||||||
}
|
} else {
|
||||||
|
// No preferred ports found. Fall back to other serial ports
|
||||||
if len(ports) == 0 {
|
// available in the system.
|
||||||
// fallback
|
ports = secondaryPorts
|
||||||
switch runtime.GOOS {
|
|
||||||
case "darwin":
|
|
||||||
ports, err = filepath.Glob("/dev/cu.usb*")
|
|
||||||
case "linux":
|
|
||||||
ports, err = filepath.Glob("/dev/ttyACM*")
|
|
||||||
case "windows":
|
|
||||||
ports, err = serial.GetPortsList()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return "", errors.New("unable to search for a default USB device to be flashed on this OS")
|
return "", errors.New("unable to search for a default USB device to be flashed on this OS")
|
||||||
@@ -1037,7 +1052,9 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(portCandidates) == 0 {
|
if len(portCandidates) == 0 {
|
||||||
if len(ports) == 1 {
|
if len(usbInterfaces) > 0 {
|
||||||
|
return "", errors.New("unable to search for a default USB device - use -port flag, available ports are " + strings.Join(ports, ", "))
|
||||||
|
} else if len(ports) == 1 {
|
||||||
return ports[0], nil
|
return ports[0], nil
|
||||||
} else {
|
} else {
|
||||||
return "", errors.New("multiple serial ports available - use -port flag, available ports are " + strings.Join(ports, ", "))
|
return "", errors.New("multiple serial ports available - use -port flag, available ports are " + strings.Join(ports, ", "))
|
||||||
@@ -1102,6 +1119,7 @@ func usage(command string) {
|
|||||||
fmt.Fprintln(os.Stderr, " flash: compile and flash to the device")
|
fmt.Fprintln(os.Stderr, " flash: compile and flash to the device")
|
||||||
fmt.Fprintln(os.Stderr, " gdb: run/flash and immediately enter GDB")
|
fmt.Fprintln(os.Stderr, " gdb: run/flash and immediately enter GDB")
|
||||||
fmt.Fprintln(os.Stderr, " lldb: run/flash and immediately enter LLDB")
|
fmt.Fprintln(os.Stderr, " lldb: run/flash and immediately enter LLDB")
|
||||||
|
fmt.Fprintln(os.Stderr, " monitor: open communication port")
|
||||||
fmt.Fprintln(os.Stderr, " env: list environment variables used during build")
|
fmt.Fprintln(os.Stderr, " env: list environment variables used during build")
|
||||||
fmt.Fprintln(os.Stderr, " list: run go list using the TinyGo root")
|
fmt.Fprintln(os.Stderr, " list: run go list using the TinyGo root")
|
||||||
fmt.Fprintln(os.Stderr, " clean: empty cache directory ("+goenv.Get("GOCACHE")+")")
|
fmt.Fprintln(os.Stderr, " clean: empty cache directory ("+goenv.Get("GOCACHE")+")")
|
||||||
@@ -1298,6 +1316,12 @@ func main() {
|
|||||||
var tags buildutil.TagsFlag
|
var tags buildutil.TagsFlag
|
||||||
flag.Var(&tags, "tags", "a space-separated list of extra build tags")
|
flag.Var(&tags, "tags", "a space-separated list of extra build tags")
|
||||||
target := flag.String("target", "", "chip/board name or JSON target specification file")
|
target := flag.String("target", "", "chip/board name or JSON target specification file")
|
||||||
|
var stackSize uint64
|
||||||
|
flag.Func("stack-size", "goroutine stack size (if unknown at compile time)", func(s string) error {
|
||||||
|
size, err := bytesize.Parse(s)
|
||||||
|
stackSize = uint64(size)
|
||||||
|
return err
|
||||||
|
})
|
||||||
printSize := flag.String("size", "", "print sizes (none, short, full)")
|
printSize := flag.String("size", "", "print sizes (none, short, full)")
|
||||||
printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines")
|
printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines")
|
||||||
printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed")
|
printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed")
|
||||||
@@ -1312,6 +1336,8 @@ func main() {
|
|||||||
wasmAbi := flag.String("wasm-abi", "", "WebAssembly ABI conventions: js (no i64 params) or generic")
|
wasmAbi := flag.String("wasm-abi", "", "WebAssembly ABI conventions: js (no i64 params) or generic")
|
||||||
llvmFeatures := flag.String("llvm-features", "", "comma separated LLVM features to enable")
|
llvmFeatures := flag.String("llvm-features", "", "comma separated LLVM features to enable")
|
||||||
cpuprofile := flag.String("cpuprofile", "", "cpuprofile output")
|
cpuprofile := flag.String("cpuprofile", "", "cpuprofile output")
|
||||||
|
monitor := flag.Bool("monitor", false, "enable serial monitor")
|
||||||
|
baudrate := flag.Int("baudrate", 115200, "baudrate of serial monitor")
|
||||||
|
|
||||||
var flagJSON, flagDeps, flagTest bool
|
var flagJSON, flagDeps, flagTest bool
|
||||||
if command == "help" || command == "list" || command == "info" || command == "build" {
|
if command == "help" || command == "list" || command == "info" || command == "build" {
|
||||||
@@ -1378,6 +1404,7 @@ func main() {
|
|||||||
GOARCH: goenv.Get("GOARCH"),
|
GOARCH: goenv.Get("GOARCH"),
|
||||||
GOARM: goenv.Get("GOARM"),
|
GOARM: goenv.Get("GOARM"),
|
||||||
Target: *target,
|
Target: *target,
|
||||||
|
StackSize: stackSize,
|
||||||
Opt: *opt,
|
Opt: *opt,
|
||||||
GC: *gc,
|
GC: *gc,
|
||||||
PanicStrategy: *panicStrategy,
|
PanicStrategy: *panicStrategy,
|
||||||
@@ -1400,6 +1427,8 @@ func main() {
|
|||||||
OpenOCDCommands: ocdCommands,
|
OpenOCDCommands: ocdCommands,
|
||||||
LLVMFeatures: *llvmFeatures,
|
LLVMFeatures: *llvmFeatures,
|
||||||
PrintJSON: flagJSON,
|
PrintJSON: flagJSON,
|
||||||
|
Monitor: *monitor,
|
||||||
|
BaudRate: *baudrate,
|
||||||
}
|
}
|
||||||
if *printCommands {
|
if *printCommands {
|
||||||
options.PrintCommands = printCommand
|
options.PrintCommands = printCommand
|
||||||
@@ -1590,6 +1619,9 @@ func main() {
|
|||||||
fmt.Println("FAIL")
|
fmt.Println("FAIL")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
case "monitor":
|
||||||
|
err := Monitor(*port, options)
|
||||||
|
handleCompilerError(err)
|
||||||
case "targets":
|
case "targets":
|
||||||
dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets")
|
dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets")
|
||||||
entries, err := ioutil.ReadDir(dir)
|
entries, err := ioutil.ReadDir(dir)
|
||||||
|
|||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mattn/go-tty"
|
||||||
|
"github.com/tinygo-org/tinygo/builder"
|
||||||
|
"github.com/tinygo-org/tinygo/compileopts"
|
||||||
|
"go.bug.st/serial"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Monitor connects to the given port and reads/writes the serial port.
|
||||||
|
func Monitor(port string, options *compileopts.Options) error {
|
||||||
|
config, err := builder.NewConfig(options)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
wait := 300
|
||||||
|
for i := 0; i <= wait; i++ {
|
||||||
|
port, err = getDefaultPort(port, config.Target.SerialPort)
|
||||||
|
if err != nil {
|
||||||
|
if i < wait {
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
br := options.BaudRate
|
||||||
|
if br <= 0 {
|
||||||
|
br = 115200
|
||||||
|
}
|
||||||
|
|
||||||
|
wait = 300
|
||||||
|
var p serial.Port
|
||||||
|
for i := 0; i <= wait; i++ {
|
||||||
|
p, err = serial.Open(port, &serial.Mode{BaudRate: br})
|
||||||
|
if err != nil {
|
||||||
|
if i < wait {
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
defer p.Close()
|
||||||
|
|
||||||
|
tty, err := tty.Open()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer tty.Close()
|
||||||
|
|
||||||
|
sig := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sig, os.Interrupt)
|
||||||
|
defer signal.Stop(sig)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
<-sig
|
||||||
|
tty.Close()
|
||||||
|
os.Exit(0)
|
||||||
|
}()
|
||||||
|
|
||||||
|
fmt.Printf("Connected to %s. Press Ctrl-C to exit.\n", port)
|
||||||
|
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
buf := make([]byte, 100*1024)
|
||||||
|
for {
|
||||||
|
n, err := p.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
errCh <- fmt.Errorf("read error: %w", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if n == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Printf("%v", string(buf[:n]))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
r, err := tty.ReadRune()
|
||||||
|
if err != nil {
|
||||||
|
errCh <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p.Write([]byte(string(r)))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return <-errCh
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//go:build stm32 || (sam && atsamd51) || (sam && atsame5x)
|
//go:build nrf || stm32 || (sam && atsamd51) || (sam && atsame5x)
|
||||||
// +build stm32 sam,atsamd51 sam,atsame5x
|
// +build nrf stm32 sam,atsamd51 sam,atsame5x
|
||||||
|
|
||||||
package rand
|
package rand
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
// Reads multiple rp2040 ADC channels concurrently. Including the internal temperature sensor
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"machine"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type celsius float32
|
|
||||||
|
|
||||||
func (c celsius) String() string {
|
|
||||||
return fmt.Sprintf("%4.1f℃", c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// rp2040 ADC is 12 bits. Reading are shifted <<4 to fill the 16-bit range.
|
|
||||||
var adcReading [3]uint16
|
|
||||||
|
|
||||||
func readADC(a machine.ADC, w time.Duration, i int) {
|
|
||||||
for {
|
|
||||||
adcReading[i] = a.Get()
|
|
||||||
time.Sleep(w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
machine.InitADC()
|
|
||||||
a0 := machine.ADC{machine.ADC0} // GPIO26 input
|
|
||||||
a1 := machine.ADC{machine.ADC1} // GPIO27 input
|
|
||||||
a2 := machine.ADC{machine.ADC2} // GPIO28 input
|
|
||||||
t := machine.ADC_TEMP_SENSOR // Internal Temperature sensor
|
|
||||||
// Configure sets the GPIOs to PinAnalog mode
|
|
||||||
a0.Configure(machine.ADCConfig{})
|
|
||||||
a1.Configure(machine.ADCConfig{})
|
|
||||||
a2.Configure(machine.ADCConfig{})
|
|
||||||
// Configure powers on the temperature sensor
|
|
||||||
t.Configure(machine.ADCConfig{})
|
|
||||||
|
|
||||||
// Safe to read concurrently
|
|
||||||
go readADC(a0, 10*time.Millisecond, 0)
|
|
||||||
go readADC(a1, 17*time.Millisecond, 1)
|
|
||||||
go readADC(a2, 29*time.Millisecond, 2)
|
|
||||||
|
|
||||||
for {
|
|
||||||
fmt.Printf("ADC0: %5d ADC1: %5d ADC2: %5d Temp: %v\n\r", adcReading[0], adcReading[1], adcReading[2], celsius(float32(t.ReadTemperature())/1000))
|
|
||||||
time.Sleep(1000 * time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Read the internal temperature sensor of the chip.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type celsius float32
|
||||||
|
|
||||||
|
func (c celsius) String() string {
|
||||||
|
return fmt.Sprintf("%4.1f℃", c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
for {
|
||||||
|
temp := celsius(float32(machine.ReadTemperature()) / 1000)
|
||||||
|
println("temperature:", temp.String())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,12 +21,14 @@ $ tinygo build -o ./wasm.wasm -target wasm ./main/main.go
|
|||||||
This creates a `wasm.wasm` file, which we can load in JavaScript and execute in
|
This creates a `wasm.wasm` file, which we can load in JavaScript and execute in
|
||||||
a browser.
|
a browser.
|
||||||
|
|
||||||
This examples folder contains two examples that can be built using `make`:
|
Next, choose which example you want to use:
|
||||||
|
* [callback](callback): Defines and configures callbacks in Wasm.
|
||||||
```bash
|
* [export](export): Defines callbacks in Wasm, but configures them in JavaScript.
|
||||||
$ make export
|
* [invoke](invoke): Invokes a function defined in JavaScript from Wasm.
|
||||||
```
|
* [main](main): Prints a message to the JavaScript console from Wasm.
|
||||||
|
* [slices](slices): Splits an Array defined in JavaScript from Wasm.
|
||||||
|
|
||||||
|
Let's say you chose [main](main), you'd build it like so:
|
||||||
```bash
|
```bash
|
||||||
$ make main
|
$ make main
|
||||||
```
|
```
|
||||||
@@ -42,12 +44,8 @@ Serving ./html on http://localhost:8080
|
|||||||
|
|
||||||
Use your web browser to visit http://localhost:8080.
|
Use your web browser to visit http://localhost:8080.
|
||||||
|
|
||||||
* The wasm "export" example displays a simple math equation using HTML, with
|
* Tip: Open the browser development tools (e.g. Right-click, Inspect in
|
||||||
the result calculated dynamically using WebAssembly. Changing any of the
|
FireFox) to see console output.
|
||||||
values on the left hand side triggers the exported wasm `update` function to
|
|
||||||
recalculate the result.
|
|
||||||
* The wasm "main" example uses `println` to write to your browser JavaScript
|
|
||||||
console. You may need to open the browser development tools console to see it.
|
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,12 @@ import (
|
|||||||
var a, b int
|
var a, b int
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
wait := make(chan struct{}, 0)
|
||||||
document := js.Global().Get("document")
|
document := js.Global().Get("document")
|
||||||
document.Call("getElementById", "a").Set("oninput", updater(&a))
|
document.Call("getElementById", "a").Set("oninput", updater(&a))
|
||||||
document.Call("getElementById", "b").Set("oninput", updater(&b))
|
document.Call("getElementById", "b").Set("oninput", updater(&b))
|
||||||
update()
|
update()
|
||||||
|
<-wait
|
||||||
}
|
}
|
||||||
|
|
||||||
func updater(n *int) js.Func {
|
func updater(n *int) js.Func {
|
||||||
|
|||||||
@@ -2,12 +2,16 @@
|
|||||||
|
|
||||||
.functype start_unwind (i32) -> ()
|
.functype start_unwind (i32) -> ()
|
||||||
.import_module start_unwind, asyncify
|
.import_module start_unwind, asyncify
|
||||||
|
.import_name start_unwind, start_unwind
|
||||||
.functype stop_unwind () -> ()
|
.functype stop_unwind () -> ()
|
||||||
.import_module stop_unwind, asyncify
|
.import_module stop_unwind, asyncify
|
||||||
|
.import_name stop_unwind, stop_unwind
|
||||||
.functype start_rewind (i32) -> ()
|
.functype start_rewind (i32) -> ()
|
||||||
.import_module start_rewind, asyncify
|
.import_module start_rewind, asyncify
|
||||||
|
.import_name start_rewind, start_rewind
|
||||||
.functype stop_rewind () -> ()
|
.functype stop_rewind () -> ()
|
||||||
.import_module stop_rewind, asyncify
|
.import_module stop_rewind, asyncify
|
||||||
|
.import_name stop_rewind, stop_rewind
|
||||||
|
|
||||||
.global tinygo_unwind
|
.global tinygo_unwind
|
||||||
.hidden tinygo_unwind
|
.hidden tinygo_unwind
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
// Windows on amd64 has a slightly different ABI than other (*nix) systems.
|
// Windows on amd64 has a slightly different ABI than other (*nix) systems.
|
||||||
// Therefore, assembly functions need to be tweaked slightly.
|
// Therefore, assembly functions need to be tweaked slightly.
|
||||||
|
//
|
||||||
|
// The calling convention is described here:
|
||||||
|
// https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170
|
||||||
|
|
||||||
.section .text.tinygo_startTask,"ax"
|
.section .text.tinygo_startTask,"ax"
|
||||||
.global tinygo_startTask
|
.global tinygo_startTask
|
||||||
@@ -17,8 +20,9 @@ tinygo_startTask:
|
|||||||
// Branch to the "goroutine start" function.
|
// Branch to the "goroutine start" function.
|
||||||
callq *%r12
|
callq *%r12
|
||||||
|
|
||||||
// After return, exit this goroutine. This is a tail call.
|
// After return, exit this goroutine.
|
||||||
jmp tinygo_pause
|
// This has to be a call, not a jump, to keep the stack correctly aligned.
|
||||||
|
callq tinygo_pause
|
||||||
|
|
||||||
.global tinygo_swapTask
|
.global tinygo_swapTask
|
||||||
.section .text.tinygo_swapTask,"ax"
|
.section .text.tinygo_swapTask,"ax"
|
||||||
@@ -35,6 +39,17 @@ tinygo_swapTask:
|
|||||||
pushq %rsi
|
pushq %rsi
|
||||||
pushq %rdi
|
pushq %rdi
|
||||||
pushq %rbp
|
pushq %rbp
|
||||||
|
sub $160, %rsp
|
||||||
|
movaps %xmm6, 144(%rsp)
|
||||||
|
movaps %xmm7, 128(%rsp)
|
||||||
|
movaps %xmm8, 112(%rsp)
|
||||||
|
movaps %xmm9, 96(%rsp)
|
||||||
|
movaps %xmm10, 80(%rsp)
|
||||||
|
movaps %xmm11, 64(%rsp)
|
||||||
|
movaps %xmm12, 48(%rsp)
|
||||||
|
movaps %xmm13, 32(%rsp)
|
||||||
|
movaps %xmm14, 16(%rsp)
|
||||||
|
movaps %xmm15, 0(%rsp)
|
||||||
pushq %rbx
|
pushq %rbx
|
||||||
|
|
||||||
// Save the current stack pointer in oldStack.
|
// Save the current stack pointer in oldStack.
|
||||||
@@ -45,6 +60,17 @@ tinygo_swapTask:
|
|||||||
|
|
||||||
// Load saved register from the new stack.
|
// Load saved register from the new stack.
|
||||||
popq %rbx
|
popq %rbx
|
||||||
|
movaps 0(%rsp), %xmm15
|
||||||
|
movaps 16(%rsp), %xmm14
|
||||||
|
movaps 32(%rsp), %xmm13
|
||||||
|
movaps 48(%rsp), %xmm12
|
||||||
|
movaps 64(%rsp), %xmm11
|
||||||
|
movaps 80(%rsp), %xmm10
|
||||||
|
movaps 96(%rsp), %xmm9
|
||||||
|
movaps 112(%rsp), %xmm8
|
||||||
|
movaps 128(%rsp), %xmm7
|
||||||
|
movaps 144(%rsp), %xmm6
|
||||||
|
add $160, %rsp
|
||||||
popq %rbp
|
popq %rbp
|
||||||
popq %rdi
|
popq %rdi
|
||||||
popq %rsi
|
popq %rsi
|
||||||
|
|||||||
@@ -13,15 +13,34 @@ var systemStack uintptr
|
|||||||
// calleeSavedRegs is the list of registers that must be saved and restored when
|
// calleeSavedRegs is the list of registers that must be saved and restored when
|
||||||
// switching between tasks. Also see task_stack_amd64_windows.S that relies on
|
// switching between tasks. Also see task_stack_amd64_windows.S that relies on
|
||||||
// the exact layout of this struct.
|
// the exact layout of this struct.
|
||||||
|
// The calling convention is described here:
|
||||||
|
// https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170
|
||||||
|
// Most importantly, these are the registers we need to save/restore:
|
||||||
|
//
|
||||||
|
// > The x64 ABI considers registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14,
|
||||||
|
// > R15, and XMM6-XMM15 nonvolatile. They must be saved and restored by a
|
||||||
|
// > function that uses them.
|
||||||
type calleeSavedRegs struct {
|
type calleeSavedRegs struct {
|
||||||
rbx uintptr
|
// Note: rbx is placed here so that the stack is correctly aligned when
|
||||||
rbp uintptr
|
// loading/storing the xmm registers.
|
||||||
rdi uintptr
|
rbx uintptr
|
||||||
rsi uintptr
|
xmm15 [2]uint64
|
||||||
r12 uintptr
|
xmm14 [2]uint64
|
||||||
r13 uintptr
|
xmm13 [2]uint64
|
||||||
r14 uintptr
|
xmm12 [2]uint64
|
||||||
r15 uintptr
|
xmm11 [2]uint64
|
||||||
|
xmm10 [2]uint64
|
||||||
|
xmm9 [2]uint64
|
||||||
|
xmm8 [2]uint64
|
||||||
|
xmm7 [2]uint64
|
||||||
|
xmm6 [2]uint64
|
||||||
|
rbp uintptr
|
||||||
|
rdi uintptr
|
||||||
|
rsi uintptr
|
||||||
|
r12 uintptr
|
||||||
|
r13 uintptr
|
||||||
|
r14 uintptr
|
||||||
|
r15 uintptr
|
||||||
|
|
||||||
pc uintptr
|
pc uintptr
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0x07738135
|
const resetMagicValue = 0x07738135
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0x07738135
|
const resetMagicValue = 0x07738135
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0x07738135
|
const resetMagicValue = 0x07738135
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0x07738135
|
const resetMagicValue = 0x07738135
|
||||||
|
|
||||||
// GPIO Pins - Digital Low
|
// GPIO Pins - Digital Low
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ const (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
PB0 = portB + 0
|
PB0 = portB + 0
|
||||||
PB1 = portB + 1
|
PB1 = portB + 1 // peripherals: Timer1 channel A
|
||||||
PB2 = portB + 2
|
PB2 = portB + 2 // peripherals: Timer1 channel B
|
||||||
PB3 = portB + 3
|
PB3 = portB + 3 // peripherals: Timer2 channel A
|
||||||
PB4 = portB + 4
|
PB4 = portB + 4
|
||||||
PB5 = portB + 5
|
PB5 = portB + 5
|
||||||
PB6 = portB + 6
|
PB6 = portB + 6
|
||||||
@@ -30,9 +30,9 @@ const (
|
|||||||
PD0 = portD + 0
|
PD0 = portD + 0
|
||||||
PD1 = portD + 1
|
PD1 = portD + 1
|
||||||
PD2 = portD + 2
|
PD2 = portD + 2
|
||||||
PD3 = portD + 3
|
PD3 = portD + 3 // peripherals: Timer2 channel B
|
||||||
PD4 = portD + 4
|
PD4 = portD + 4
|
||||||
PD5 = portD + 5
|
PD5 = portD + 5 // peripherals: Timer0 channel B
|
||||||
PD6 = portD + 6
|
PD6 = portD + 6 // peripherals: Timer0 channel A
|
||||||
PD7 = portD + 7
|
PD7 = portD + 7
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,38 +10,38 @@ func CPUFrequency() uint32 {
|
|||||||
|
|
||||||
// Hardware pins
|
// Hardware pins
|
||||||
const (
|
const (
|
||||||
PA00 Pin = 0
|
PA00 Pin = 0 // peripherals: TCC2 channel 0
|
||||||
PA01 Pin = 1
|
PA01 Pin = 1 // peripherals: TCC2 channel 1
|
||||||
PA02 Pin = 2
|
PA02 Pin = 2
|
||||||
PA03 Pin = 3
|
PA03 Pin = 3
|
||||||
PA04 Pin = 4
|
PA04 Pin = 4 // peripherals: TCC0 channel 0
|
||||||
PA05 Pin = 5
|
PA05 Pin = 5 // peripherals: TCC0 channel 1
|
||||||
PA06 Pin = 6
|
PA06 Pin = 6 // peripherals: TCC1 channel 0
|
||||||
PA07 Pin = 7
|
PA07 Pin = 7 // peripherals: TCC1 channel 1
|
||||||
PA08 Pin = 8
|
PA08 Pin = 8 // peripherals: TCC0 channel 0, TCC1 channel 2
|
||||||
PA09 Pin = 9
|
PA09 Pin = 9 // peripherals: TCC0 channel 1, TCC1 channel 3
|
||||||
PA10 Pin = 10
|
PA10 Pin = 10 // peripherals: TCC1 channel 0, TCC0 channel 2
|
||||||
PA11 Pin = 11
|
PA11 Pin = 11 // peripherals: TCC1 channel 1, TCC0 channel 3
|
||||||
PA12 Pin = 12
|
PA12 Pin = 12 // peripherals: TCC2 channel 0, TCC0 channel 2
|
||||||
PA13 Pin = 13
|
PA13 Pin = 13 // peripherals: TCC2 channel 1, TCC0 channel 3
|
||||||
PA14 Pin = 14
|
PA14 Pin = 14 // peripherals: TCC0 channel 0
|
||||||
PA15 Pin = 15
|
PA15 Pin = 15 // peripherals: TCC0 channel 1
|
||||||
PA16 Pin = 16
|
PA16 Pin = 16 // peripherals: TCC2 channel 0, TCC0 channel 2
|
||||||
PA17 Pin = 17
|
PA17 Pin = 17 // peripherals: TCC2 channel 1, TCC0 channel 3
|
||||||
PA18 Pin = 18
|
PA18 Pin = 18 // peripherals: TCC0 channel 2
|
||||||
PA19 Pin = 19
|
PA19 Pin = 19 // peripherals: TCC0 channel 3
|
||||||
PA20 Pin = 20
|
PA20 Pin = 20 // peripherals: TCC0 channel 2
|
||||||
PA21 Pin = 21
|
PA21 Pin = 21 // peripherals: TCC0 channel 3
|
||||||
PA22 Pin = 22
|
PA22 Pin = 22 // peripherals: TCC0 channel 0
|
||||||
PA23 Pin = 23
|
PA23 Pin = 23 // peripherals: TCC0 channel 1
|
||||||
PA24 Pin = 24
|
PA24 Pin = 24 // peripherals: TCC1 channel 2
|
||||||
PA25 Pin = 25
|
PA25 Pin = 25 // peripherals: TCC1 channel 3
|
||||||
PA26 Pin = 26
|
PA26 Pin = 26
|
||||||
PA27 Pin = 27
|
PA27 Pin = 27
|
||||||
PA28 Pin = 28
|
PA28 Pin = 28
|
||||||
PA29 Pin = 29
|
PA29 Pin = 29
|
||||||
PA30 Pin = 30
|
PA30 Pin = 30 // peripherals: TCC1 channel 0
|
||||||
PA31 Pin = 31
|
PA31 Pin = 31 // peripherals: TCC1 channel 1
|
||||||
PB00 Pin = 32
|
PB00 Pin = 32
|
||||||
PB01 Pin = 33
|
PB01 Pin = 33
|
||||||
PB02 Pin = 34
|
PB02 Pin = 34
|
||||||
@@ -52,14 +52,14 @@ const (
|
|||||||
PB07 Pin = 39
|
PB07 Pin = 39
|
||||||
PB08 Pin = 40
|
PB08 Pin = 40
|
||||||
PB09 Pin = 41
|
PB09 Pin = 41
|
||||||
PB10 Pin = 42
|
PB10 Pin = 42 // peripherals: TCC0 channel 0
|
||||||
PB11 Pin = 43
|
PB11 Pin = 43 // peripherals: TCC0 channel 1
|
||||||
PB12 Pin = 44
|
PB12 Pin = 44 // peripherals: TCC0 channel 2
|
||||||
PB13 Pin = 45
|
PB13 Pin = 45 // peripherals: TCC0 channel 3
|
||||||
PB14 Pin = 46
|
PB14 Pin = 46
|
||||||
PB15 Pin = 47
|
PB15 Pin = 47
|
||||||
PB16 Pin = 48
|
PB16 Pin = 48 // peripherals: TCC0 channel 0
|
||||||
PB17 Pin = 49
|
PB17 Pin = 49 // peripherals: TCC0 channel 1
|
||||||
PB18 Pin = 50
|
PB18 Pin = 50
|
||||||
PB19 Pin = 51
|
PB19 Pin = 51
|
||||||
PB20 Pin = 52
|
PB20 Pin = 52
|
||||||
@@ -72,6 +72,6 @@ const (
|
|||||||
PB27 Pin = 59
|
PB27 Pin = 59
|
||||||
PB28 Pin = 60
|
PB28 Pin = 60
|
||||||
PB29 Pin = 61
|
PB29 Pin = 61
|
||||||
PB30 Pin = 62
|
PB30 Pin = 62 // peripherals: TCC0 channel 0, TCC1 channel 2
|
||||||
PB31 Pin = 63
|
PB31 Pin = 63 // peripherals: TCC0 channel 1, TCC1 channel 3
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Definition for compatibility, but not used
|
// Definition for compatibility, but not used
|
||||||
const RESET_MAGIC_VALUE = 0x00000000
|
const resetMagicValue = 0x00000000
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LED = PC18
|
LED = PC18
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ const (
|
|||||||
|
|
||||||
// Other peripheral constants
|
// Other peripheral constants
|
||||||
const (
|
const (
|
||||||
RESET_MAGIC_VALUE = 0xF01669EF // Used to reset into bootloader
|
resetMagicValue = 0xF01669EF // Used to reset into bootloader
|
||||||
)
|
)
|
||||||
|
|
||||||
// USB CDC pins
|
// USB CDC pins
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xF01669EF
|
const resetMagicValue = 0xF01669EF
|
||||||
|
|
||||||
// Digital pins
|
// Digital pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0x07738135
|
const resetMagicValue = 0x07738135
|
||||||
|
|
||||||
// Note: On the P1AM-100, pins D8, D9, D10, A3, and A4 are used for
|
// Note: On the P1AM-100, pins D8, D9, D10, A3, and A4 are used for
|
||||||
// communication with the base controller.
|
// communication with the base controller.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -36,10 +36,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NEOPIXELS = GPIO12
|
NEOPIXEL = GPIO12
|
||||||
WS2812 = GPIO12
|
WS2812 = GPIO12
|
||||||
NEOPIXELS_POWER = GPIO11
|
NEOPIXEL_POWER = GPIO11
|
||||||
LED = GPIO20
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// I2C Pins.
|
// I2C Pins.
|
||||||
@@ -116,5 +115,5 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
usb_VID uint16 = 0x239A
|
usb_VID uint16 = 0x239A
|
||||||
usb_PID uint16 = 0x80F1
|
usb_PID uint16 = 0x80F7
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ADC0 = A0
|
ADC0 = A0
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ const (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
usb_VID uint16 = 0x2886
|
usb_VID uint16 = 0x2886
|
||||||
usb_PID uint16 = 0x0045
|
usb_PID uint16 = 0x8045
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
package machine
|
package machine
|
||||||
|
|
||||||
// used to reset into bootloader
|
// used to reset into bootloader
|
||||||
const RESET_MAGIC_VALUE = 0xf01669ef
|
const resetMagicValue = 0xf01669ef
|
||||||
|
|
||||||
// GPIO Pins
|
// GPIO Pins
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// TWI_FREQ is the I2C bus speed. Normally either 100 kHz, or 400 kHz for high-speed bus.
|
// TWI_FREQ is the I2C bus speed. Normally either 100 kHz, or 400 kHz for high-speed bus.
|
||||||
|
//
|
||||||
|
// Deprecated: use 100 * machine.KHz or 400 * machine.KHz instead.
|
||||||
const (
|
const (
|
||||||
TWI_FREQ_100KHZ = 100000
|
TWI_FREQ_100KHZ = 100000
|
||||||
TWI_FREQ_400KHZ = 400000
|
TWI_FREQ_400KHZ = 400000
|
||||||
|
|||||||
@@ -18,6 +18,13 @@ var (
|
|||||||
// particular chip but instead runs in WebAssembly for example.
|
// particular chip but instead runs in WebAssembly for example.
|
||||||
const Device = deviceName
|
const Device = deviceName
|
||||||
|
|
||||||
|
// Generic constants.
|
||||||
|
const (
|
||||||
|
KHz = 1000
|
||||||
|
MHz = 1000_000
|
||||||
|
GHz = 1000_000_000
|
||||||
|
)
|
||||||
|
|
||||||
// PinMode sets the direction and pull mode of the pin. For example, PinOutput
|
// PinMode sets the direction and pull mode of the pin. For example, PinOutput
|
||||||
// sets the pin as an output and PinInputPullup sets the pin as an input with a
|
// sets the pin as an output and PinInputPullup sets the pin as an input with a
|
||||||
// pull-up.
|
// pull-up.
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ type I2CConfig struct {
|
|||||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
// Default I2C bus speed is 100 kHz.
|
// Default I2C bus speed is 100 kHz.
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = 100 * KHz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate internal pullups for twi.
|
// Activate internal pullups for twi.
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ const (
|
|||||||
PB1 = portB + 1
|
PB1 = portB + 1
|
||||||
PB2 = portB + 2
|
PB2 = portB + 2
|
||||||
PB3 = portB + 3
|
PB3 = portB + 3
|
||||||
PB4 = portB + 4
|
PB4 = portB + 4 // peripherals: Timer2 channel A
|
||||||
PB5 = portB + 5
|
PB5 = portB + 5 // peripherals: Timer1 channel A
|
||||||
PB6 = portB + 6
|
PB6 = portB + 6 // peripherals: Timer1 channel B
|
||||||
PB7 = portB + 7
|
PB7 = portB + 7 // peripherals: Timer0 channel A
|
||||||
PC0 = portC + 0
|
PC0 = portC + 0
|
||||||
PC1 = portC + 1
|
PC1 = portC + 1
|
||||||
PC2 = portC + 2
|
PC2 = portC + 2
|
||||||
@@ -57,9 +57,9 @@ const (
|
|||||||
PD7 = portD + 7
|
PD7 = portD + 7
|
||||||
PE0 = portE + 0
|
PE0 = portE + 0
|
||||||
PE1 = portE + 1
|
PE1 = portE + 1
|
||||||
PE3 = portE + 3
|
PE3 = portE + 3 // peripherals: Timer3 channel A
|
||||||
PE4 = portE + 4
|
PE4 = portE + 4 // peripherals: Timer3 channel B
|
||||||
PE5 = portE + 5
|
PE5 = portE + 5 // peripherals: Timer3 channel C
|
||||||
PE6 = portE + 6
|
PE6 = portE + 6
|
||||||
PF0 = portF + 0
|
PF0 = portF + 0
|
||||||
PF1 = portF + 1
|
PF1 = portF + 1
|
||||||
@@ -72,13 +72,13 @@ const (
|
|||||||
PG0 = portG + 0
|
PG0 = portG + 0
|
||||||
PG1 = portG + 1
|
PG1 = portG + 1
|
||||||
PG2 = portG + 2
|
PG2 = portG + 2
|
||||||
PG5 = portG + 5
|
PG5 = portG + 5 // peripherals: Timer0 channel B
|
||||||
PH0 = portH + 0
|
PH0 = portH + 0
|
||||||
PH1 = portH + 1
|
PH1 = portH + 1
|
||||||
PH3 = portH + 3
|
PH3 = portH + 3 // peripherals: Timer4 channel A
|
||||||
PH4 = portH + 4
|
PH4 = portH + 4 // peripherals: Timer4 channel B
|
||||||
PH5 = portH + 5
|
PH5 = portH + 5 // peripherals: Timer4 channel C
|
||||||
PH6 = portH + 6
|
PH6 = portH + 6 // peripherals: Timer0 channel B
|
||||||
PJ0 = portJ + 0
|
PJ0 = portJ + 0
|
||||||
PJ1 = portJ + 1
|
PJ1 = portJ + 1
|
||||||
PK0 = portK + 0
|
PK0 = portK + 0
|
||||||
@@ -92,9 +92,9 @@ const (
|
|||||||
PL0 = portL + 0
|
PL0 = portL + 0
|
||||||
PL1 = portL + 1
|
PL1 = portL + 1
|
||||||
PL2 = portL + 2
|
PL2 = portL + 2
|
||||||
PL3 = portL + 3
|
PL3 = portL + 3 // peripherals: Timer5 channel A
|
||||||
PL4 = portL + 4
|
PL4 = portL + 4 // peripherals: Timer5 channel B
|
||||||
PL5 = portL + 5
|
PL5 = portL + 5 // peripherals: Timer5 channel C
|
||||||
PL6 = portL + 6
|
PL6 = portL + 6
|
||||||
PL7 = portL + 7
|
PL7 = portL + 7
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ package machine
|
|||||||
import (
|
import (
|
||||||
"device/arm"
|
"device/arm"
|
||||||
"device/sam"
|
"device/sam"
|
||||||
"errors"
|
|
||||||
"runtime/interrupt"
|
"runtime/interrupt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@@ -18,20 +17,20 @@ import (
|
|||||||
const deviceName = sam.Device
|
const deviceName = sam.Device
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PinAnalog PinMode = 1
|
|
||||||
PinSERCOM PinMode = 2
|
|
||||||
PinSERCOMAlt PinMode = 3
|
|
||||||
PinTimer PinMode = 4
|
|
||||||
PinTimerAlt PinMode = 5
|
|
||||||
PinCom PinMode = 6
|
|
||||||
//PinAC_CLK PinMode = 7
|
|
||||||
PinDigital PinMode = 8
|
|
||||||
PinInput PinMode = 9
|
PinInput PinMode = 9
|
||||||
PinInputPullup PinMode = 10
|
PinInputPullup PinMode = 10
|
||||||
PinOutput PinMode = 11
|
PinOutput PinMode = 11
|
||||||
PinTCC PinMode = PinTimer
|
|
||||||
PinTCCAlt PinMode = PinTimerAlt
|
|
||||||
PinInputPulldown PinMode = 12
|
PinInputPulldown PinMode = 12
|
||||||
|
|
||||||
|
// internal pin modes
|
||||||
|
pinAnalog PinMode = 1
|
||||||
|
pinSERCOM PinMode = 2
|
||||||
|
pinSERCOMAlt PinMode = 3
|
||||||
|
pinTCC PinMode = 4
|
||||||
|
pinTCCAlt PinMode = 5
|
||||||
|
pinCom PinMode = 6
|
||||||
|
//PinAC_CLK PinMode = 7
|
||||||
|
pinDigital PinMode = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
type PinChange uint8
|
type PinChange uint8
|
||||||
@@ -150,7 +149,7 @@ func findPinPadMapping(sercom uint8, pin Pin) (pinMode PinMode, pad uint32, ok b
|
|||||||
if upper != 0 {
|
if upper != 0 {
|
||||||
// SERCOM
|
// SERCOM
|
||||||
if (upper>>1)-1 == sercom {
|
if (upper>>1)-1 == sercom {
|
||||||
pinMode = PinSERCOM
|
pinMode = pinSERCOM
|
||||||
pad |= uint32((upper & 1) << 1)
|
pad |= uint32((upper & 1) << 1)
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -158,7 +157,7 @@ func findPinPadMapping(sercom uint8, pin Pin) (pinMode PinMode, pad uint32, ok b
|
|||||||
if lower != 0 {
|
if lower != 0 {
|
||||||
// SERCOM-ALT
|
// SERCOM-ALT
|
||||||
if (lower>>1)-1 == sercom {
|
if (lower>>1)-1 == sercom {
|
||||||
pinMode = PinSERCOMAlt
|
pinMode = pinSERCOMAlt
|
||||||
pad |= uint32((lower & 1) << 1)
|
pad |= uint32((lower & 1) << 1)
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -382,7 +381,7 @@ func (a ADC) Configure(config ADCConfig) {
|
|||||||
// 1/2 VDDANA = 0.5 * 3V3 = 1.65V
|
// 1/2 VDDANA = 0.5 * 3V3 = 1.65V
|
||||||
sam.ADC.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1 << sam.ADC_REFCTRL_REFSEL_Pos)
|
sam.ADC.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1 << sam.ADC_REFCTRL_REFSEL_Pos)
|
||||||
|
|
||||||
a.Pin.Configure(PinConfig{Mode: PinAnalog})
|
a.Pin.Configure(PinConfig{Mode: pinAnalog})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -677,7 +676,7 @@ const i2cTimeout = 1000
|
|||||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
// Default I2C bus speed is 100 kHz.
|
// Default I2C bus speed is 100 kHz.
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = 100 * KHz
|
||||||
}
|
}
|
||||||
if config.SDA == 0 && config.SCL == 0 {
|
if config.SDA == 0 && config.SCL == 0 {
|
||||||
config.SDA = SDA_PIN
|
config.SDA = SDA_PIN
|
||||||
@@ -1001,11 +1000,11 @@ func (i2s I2S) Configure(config I2SConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// configure pin for clock
|
// configure pin for clock
|
||||||
config.SCK.Configure(PinConfig{Mode: PinCom})
|
config.SCK.Configure(PinConfig{Mode: pinCom})
|
||||||
|
|
||||||
// configure pin for WS, if needed
|
// configure pin for WS, if needed
|
||||||
if config.WS != NoPin {
|
if config.WS != NoPin {
|
||||||
config.WS.Configure(PinConfig{Mode: PinCom})
|
config.WS.Configure(PinConfig{Mode: pinCom})
|
||||||
}
|
}
|
||||||
|
|
||||||
// now set serializer data size.
|
// now set serializer data size.
|
||||||
@@ -1044,7 +1043,7 @@ func (i2s I2S) Configure(config I2SConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// configure data pin
|
// configure data pin
|
||||||
config.SD.Configure(PinConfig{Mode: PinCom})
|
config.SD.Configure(PinConfig{Mode: pinCom})
|
||||||
|
|
||||||
// re-enable
|
// re-enable
|
||||||
i2s.Bus.CTRLA.SetBits(sam.I2S_CTRLA_ENABLE)
|
i2s.Bus.CTRLA.SetBits(sam.I2S_CTRLA_ENABLE)
|
||||||
@@ -1274,10 +1273,6 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
|||||||
return byte(spi.Bus.DATA.Get()), nil
|
return byte(spi.Bus.DATA.Get()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||||
// interface, there must always be the same number of bytes written as bytes read.
|
// interface, there must always be the same number of bytes written as bytes read.
|
||||||
// The Tx method knows about this, and offers a few different ways of calling it.
|
// The Tx method knows about this, and offers a few different ways of calling it.
|
||||||
@@ -1641,12 +1636,12 @@ func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
|
|||||||
if mapping&0x07 == timer+1 {
|
if mapping&0x07 == timer+1 {
|
||||||
// PWM output is on peripheral function E.
|
// PWM output is on peripheral function E.
|
||||||
evenChannel := ((mapping >> 3) & 1) * 2
|
evenChannel := ((mapping >> 3) & 1) * 2
|
||||||
return PinTCC, evenChannel + uint8(pin&1)
|
return pinTCC, evenChannel + uint8(pin&1)
|
||||||
}
|
}
|
||||||
if (mapping&0x70)>>4 == timer+1 {
|
if (mapping&0x70)>>4 == timer+1 {
|
||||||
// PWM output is on peripheral function F.
|
// PWM output is on peripheral function F.
|
||||||
evenChannel := ((mapping >> 7) & 1) * 2
|
evenChannel := ((mapping >> 7) & 1) * 2
|
||||||
return PinTCCAlt, evenChannel + uint8(pin&1)
|
return pinTCCAlt, evenChannel + uint8(pin&1)
|
||||||
}
|
}
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
@@ -1740,7 +1735,7 @@ func EnterBootloader() {
|
|||||||
|
|
||||||
// Perform magic reset into bootloader, as mentioned in
|
// Perform magic reset into bootloader, as mentioned in
|
||||||
// https://github.com/arduino/ArduinoCore-samd/issues/197
|
// https://github.com/arduino/ArduinoCore-samd/issues/197
|
||||||
*(*uint32)(unsafe.Pointer(uintptr(0x20007FFC))) = RESET_MAGIC_VALUE
|
*(*uint32)(unsafe.Pointer(uintptr(0x20007FFC))) = resetMagicValue
|
||||||
|
|
||||||
arm.SystemReset()
|
arm.SystemReset()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ func (dev *USBDevice) Configure(config UARTConfig) {
|
|||||||
sam.USB_DEVICE.DESCADD.Set(uint32(uintptr(unsafe.Pointer(&usbEndpointDescriptors))))
|
sam.USB_DEVICE.DESCADD.Set(uint32(uintptr(unsafe.Pointer(&usbEndpointDescriptors))))
|
||||||
|
|
||||||
// configure pins
|
// configure pins
|
||||||
USBCDC_DM_PIN.Configure(PinConfig{Mode: PinCom})
|
USBCDC_DM_PIN.Configure(PinConfig{Mode: pinCom})
|
||||||
USBCDC_DP_PIN.Configure(PinConfig{Mode: PinCom})
|
USBCDC_DP_PIN.Configure(PinConfig{Mode: pinCom})
|
||||||
|
|
||||||
// performs pad calibration from store fuses
|
// performs pad calibration from store fuses
|
||||||
handlePadCalibration()
|
handlePadCalibration()
|
||||||
|
|||||||
@@ -86,53 +86,53 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
sam.PORT.OUTSET0.Set(1 << uint8(p))
|
sam.PORT.OUTSET0.Set(1 << uint8(p))
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||||
|
|
||||||
case PinSERCOM:
|
case pinSERCOM:
|
||||||
if uint8(p)&1 > 0 {
|
if uint8(p)&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinSERCOM) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinSERCOM) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR | sam.PORT_PINCFG0_INEN)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR | sam.PORT_PINCFG0_INEN)
|
||||||
|
|
||||||
case PinSERCOMAlt:
|
case pinSERCOMAlt:
|
||||||
if uint8(p)&1 > 0 {
|
if uint8(p)&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinSERCOMAlt) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinSERCOMAlt) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||||
|
|
||||||
case PinCom:
|
case pinCom:
|
||||||
if uint8(p)&1 > 0 {
|
if uint8(p)&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinCom) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinCom) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
||||||
case PinAnalog:
|
case pinAnalog:
|
||||||
if uint8(p)&1 > 0 {
|
if uint8(p)&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinAnalog) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinAnalog) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinAnalog) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinAnalog) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||||
|
|||||||
@@ -137,53 +137,53 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
p.setPinCfg(sam.PORT_PINCFG0_INEN | sam.PORT_PINCFG0_PULLEN)
|
||||||
}
|
}
|
||||||
|
|
||||||
case PinSERCOM:
|
case pinSERCOM:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinSERCOM) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinSERCOM) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR | sam.PORT_PINCFG0_INEN)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR | sam.PORT_PINCFG0_INEN)
|
||||||
|
|
||||||
case PinSERCOMAlt:
|
case pinSERCOMAlt:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinSERCOMAlt) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinSERCOMAlt) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||||
|
|
||||||
case PinCom:
|
case pinCom:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinCom) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinCom) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinCom) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN)
|
||||||
case PinAnalog:
|
case pinAnalog:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinAnalog) << sam.PORT_PMUX0_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinAnalog) << sam.PORT_PMUX0_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_PMUX0_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinAnalog) << sam.PORT_PMUX0_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinAnalog) << sam.PORT_PMUX0_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
p.setPinCfg(sam.PORT_PINCFG0_PMUXEN | sam.PORT_PINCFG0_DRVSTR)
|
||||||
|
|||||||
+106
-112
@@ -10,7 +10,6 @@ package machine
|
|||||||
import (
|
import (
|
||||||
"device/arm"
|
"device/arm"
|
||||||
"device/sam"
|
"device/sam"
|
||||||
"errors"
|
|
||||||
"runtime/interrupt"
|
"runtime/interrupt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
@@ -22,30 +21,29 @@ func CPUFrequency() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PinAnalog PinMode = 1
|
|
||||||
PinSERCOM PinMode = 2
|
|
||||||
PinSERCOMAlt PinMode = 3
|
|
||||||
PinTimer PinMode = 4
|
|
||||||
PinTimerAlt PinMode = 5
|
|
||||||
PinTCCPDEC PinMode = 6
|
|
||||||
PinCom PinMode = 7
|
|
||||||
PinSDHC PinMode = 8
|
|
||||||
PinI2S PinMode = 9
|
|
||||||
PinPCC PinMode = 10
|
|
||||||
PinGMAC PinMode = 11
|
|
||||||
PinACCLK PinMode = 12
|
|
||||||
PinCCL PinMode = 13
|
|
||||||
PinDigital PinMode = 14
|
|
||||||
PinInput PinMode = 15
|
PinInput PinMode = 15
|
||||||
PinInputPullup PinMode = 16
|
PinInputPullup PinMode = 16
|
||||||
PinOutput PinMode = 17
|
PinOutput PinMode = 17
|
||||||
PinTCCE PinMode = PinTimer
|
|
||||||
PinTCCF PinMode = PinTimerAlt
|
|
||||||
PinTCCG PinMode = PinTCCPDEC
|
|
||||||
PinInputPulldown PinMode = 18
|
PinInputPulldown PinMode = 18
|
||||||
PinCAN PinMode = 19
|
|
||||||
PinCAN0 PinMode = PinSDHC
|
// internal pin modes
|
||||||
PinCAN1 PinMode = PinCom
|
pinAnalog PinMode = 1
|
||||||
|
pinSERCOM PinMode = 2
|
||||||
|
pinSERCOMAlt PinMode = 3
|
||||||
|
pinTCCE PinMode = 4
|
||||||
|
pinTCCF PinMode = 5
|
||||||
|
pinTCCG PinMode = 6
|
||||||
|
pinCom PinMode = 7
|
||||||
|
pinSDHC PinMode = 8
|
||||||
|
pinI2S PinMode = 9
|
||||||
|
pinPCC PinMode = 10
|
||||||
|
pinGMAC PinMode = 11
|
||||||
|
pinACCLK PinMode = 12
|
||||||
|
pinCCL PinMode = 13
|
||||||
|
pinDigital PinMode = 14
|
||||||
|
pinCAN PinMode = 19
|
||||||
|
pinCAN0 PinMode = pinSDHC
|
||||||
|
pinCAN1 PinMode = pinCom
|
||||||
)
|
)
|
||||||
|
|
||||||
type PinChange uint8
|
type PinChange uint8
|
||||||
@@ -78,86 +76,86 @@ const (
|
|||||||
PA05 Pin = 5
|
PA05 Pin = 5
|
||||||
PA06 Pin = 6
|
PA06 Pin = 6
|
||||||
PA07 Pin = 7
|
PA07 Pin = 7
|
||||||
PA08 Pin = 8
|
PA08 Pin = 8 // peripherals: TCC0 channel 0, TCC1 channel 4
|
||||||
PA09 Pin = 9
|
PA09 Pin = 9 // peripherals: TCC0 channel 1, TCC1 channel 5
|
||||||
PA10 Pin = 10
|
PA10 Pin = 10 // peripherals: TCC0 channel 2, TCC1 channel 6
|
||||||
PA11 Pin = 11
|
PA11 Pin = 11 // peripherals: TCC0 channel 3, TCC1 channel 7
|
||||||
PA12 Pin = 12
|
PA12 Pin = 12 // peripherals: TCC0 channel 6, TCC1 channel 2
|
||||||
PA13 Pin = 13
|
PA13 Pin = 13 // peripherals: TCC0 channel 7, TCC1 channel 3
|
||||||
PA14 Pin = 14
|
PA14 Pin = 14 // peripherals: TCC2 channel 0, TCC1 channel 2
|
||||||
PA15 Pin = 15
|
PA15 Pin = 15 // peripherals: TCC2 channel 1, TCC1 channel 3
|
||||||
PA16 Pin = 16
|
PA16 Pin = 16 // peripherals: TCC1 channel 0, TCC0 channel 4
|
||||||
PA17 Pin = 17
|
PA17 Pin = 17 // peripherals: TCC1 channel 1, TCC0 channel 5
|
||||||
PA18 Pin = 18
|
PA18 Pin = 18 // peripherals: TCC1 channel 2, TCC0 channel 6
|
||||||
PA19 Pin = 19
|
PA19 Pin = 19 // peripherals: TCC1 channel 3, TCC0 channel 7
|
||||||
PA20 Pin = 20
|
PA20 Pin = 20 // peripherals: TCC1 channel 4, TCC0 channel 0
|
||||||
PA21 Pin = 21
|
PA21 Pin = 21 // peripherals: TCC1 channel 5, TCC0 channel 1
|
||||||
PA22 Pin = 22
|
PA22 Pin = 22 // peripherals: TCC1 channel 6, TCC0 channel 2
|
||||||
PA23 Pin = 23
|
PA23 Pin = 23 // peripherals: TCC1 channel 7, TCC0 channel 3
|
||||||
PA24 Pin = 24
|
PA24 Pin = 24 // peripherals: TCC2 channel 2
|
||||||
PA25 Pin = 25
|
PA25 Pin = 25 // peripherals: TCC2 channel 3
|
||||||
PA26 Pin = 26
|
PA26 Pin = 26
|
||||||
PA27 Pin = 27
|
PA27 Pin = 27
|
||||||
PA28 Pin = 28
|
PA28 Pin = 28
|
||||||
PA29 Pin = 29
|
PA29 Pin = 29
|
||||||
PA30 Pin = 30
|
PA30 Pin = 30 // peripherals: TCC2 channel 0
|
||||||
PA31 Pin = 31
|
PA31 Pin = 31 // peripherals: TCC2 channel 1
|
||||||
PB00 Pin = 32
|
PB00 Pin = 32
|
||||||
PB01 Pin = 33
|
PB01 Pin = 33
|
||||||
PB02 Pin = 34
|
PB02 Pin = 34 // peripherals: TCC2 channel 2
|
||||||
PB03 Pin = 35
|
PB03 Pin = 35 // peripherals: TCC2 channel 3
|
||||||
PB04 Pin = 36
|
PB04 Pin = 36
|
||||||
PB05 Pin = 37
|
PB05 Pin = 37
|
||||||
PB06 Pin = 38
|
PB06 Pin = 38
|
||||||
PB07 Pin = 39
|
PB07 Pin = 39
|
||||||
PB08 Pin = 40
|
PB08 Pin = 40
|
||||||
PB09 Pin = 41
|
PB09 Pin = 41
|
||||||
PB10 Pin = 42
|
PB10 Pin = 42 // peripherals: TCC0 channel 4, TCC1 channel 0
|
||||||
PB11 Pin = 43
|
PB11 Pin = 43 // peripherals: TCC0 channel 5, TCC1 channel 1
|
||||||
PB12 Pin = 44
|
PB12 Pin = 44 // peripherals: TCC3 channel 0, TCC0 channel 0
|
||||||
PB13 Pin = 45
|
PB13 Pin = 45 // peripherals: TCC3 channel 1, TCC0 channel 1
|
||||||
PB14 Pin = 46
|
PB14 Pin = 46 // peripherals: TCC4 channel 0, TCC0 channel 2
|
||||||
PB15 Pin = 47
|
PB15 Pin = 47 // peripherals: TCC4 channel 1, TCC0 channel 3
|
||||||
PB16 Pin = 48
|
PB16 Pin = 48 // peripherals: TCC3 channel 0, TCC0 channel 4
|
||||||
PB17 Pin = 49
|
PB17 Pin = 49 // peripherals: TCC3 channel 1, TCC0 channel 5
|
||||||
PB18 Pin = 50
|
PB18 Pin = 50 // peripherals: TCC1 channel 0
|
||||||
PB19 Pin = 51
|
PB19 Pin = 51 // peripherals: TCC1 channel 1
|
||||||
PB20 Pin = 52
|
PB20 Pin = 52 // peripherals: TCC1 channel 2
|
||||||
PB21 Pin = 53
|
PB21 Pin = 53 // peripherals: TCC1 channel 3
|
||||||
PB22 Pin = 54
|
PB22 Pin = 54
|
||||||
PB23 Pin = 55
|
PB23 Pin = 55
|
||||||
PB24 Pin = 56
|
PB24 Pin = 56
|
||||||
PB25 Pin = 57
|
PB25 Pin = 57
|
||||||
PB26 Pin = 58
|
PB26 Pin = 58 // peripherals: TCC1 channel 2
|
||||||
PB27 Pin = 59
|
PB27 Pin = 59 // peripherals: TCC1 channel 3
|
||||||
PB28 Pin = 60
|
PB28 Pin = 60 // peripherals: TCC1 channel 4
|
||||||
PB29 Pin = 61
|
PB29 Pin = 61 // peripherals: TCC1 channel 5
|
||||||
PB30 Pin = 62
|
PB30 Pin = 62 // peripherals: TCC4 channel 0, TCC0 channel 6
|
||||||
PB31 Pin = 63
|
PB31 Pin = 63 // peripherals: TCC4 channel 1, TCC0 channel 7
|
||||||
PC00 Pin = 64
|
PC00 Pin = 64
|
||||||
PC01 Pin = 65
|
PC01 Pin = 65
|
||||||
PC02 Pin = 66
|
PC02 Pin = 66
|
||||||
PC03 Pin = 67
|
PC03 Pin = 67
|
||||||
PC04 Pin = 68
|
PC04 Pin = 68 // peripherals: TCC0 channel 0
|
||||||
PC05 Pin = 69
|
PC05 Pin = 69 // peripherals: TCC0 channel 1
|
||||||
PC06 Pin = 70
|
PC06 Pin = 70
|
||||||
PC07 Pin = 71
|
PC07 Pin = 71
|
||||||
PC08 Pin = 72
|
PC08 Pin = 72
|
||||||
PC09 Pin = 73
|
PC09 Pin = 73
|
||||||
PC10 Pin = 74
|
PC10 Pin = 74 // peripherals: TCC0 channel 0, TCC1 channel 4
|
||||||
PC11 Pin = 75
|
PC11 Pin = 75 // peripherals: TCC0 channel 1, TCC1 channel 5
|
||||||
PC12 Pin = 76
|
PC12 Pin = 76 // peripherals: TCC0 channel 2, TCC1 channel 6
|
||||||
PC13 Pin = 77
|
PC13 Pin = 77 // peripherals: TCC0 channel 3, TCC1 channel 7
|
||||||
PC14 Pin = 78
|
PC14 Pin = 78 // peripherals: TCC0 channel 4, TCC1 channel 0
|
||||||
PC15 Pin = 79
|
PC15 Pin = 79 // peripherals: TCC0 channel 5, TCC1 channel 1
|
||||||
PC16 Pin = 80
|
PC16 Pin = 80 // peripherals: TCC0 channel 0
|
||||||
PC17 Pin = 81
|
PC17 Pin = 81 // peripherals: TCC0 channel 1
|
||||||
PC18 Pin = 82
|
PC18 Pin = 82 // peripherals: TCC0 channel 2
|
||||||
PC19 Pin = 83
|
PC19 Pin = 83 // peripherals: TCC0 channel 3
|
||||||
PC20 Pin = 84
|
PC20 Pin = 84 // peripherals: TCC0 channel 4
|
||||||
PC21 Pin = 85
|
PC21 Pin = 85 // peripherals: TCC0 channel 5
|
||||||
PC22 Pin = 86
|
PC22 Pin = 86 // peripherals: TCC0 channel 6
|
||||||
PC23 Pin = 87
|
PC23 Pin = 87 // peripherals: TCC0 channel 7
|
||||||
PC24 Pin = 88
|
PC24 Pin = 88
|
||||||
PC25 Pin = 89
|
PC25 Pin = 89
|
||||||
PC26 Pin = 90
|
PC26 Pin = 90
|
||||||
@@ -174,20 +172,20 @@ const (
|
|||||||
PD05 Pin = 101
|
PD05 Pin = 101
|
||||||
PD06 Pin = 102
|
PD06 Pin = 102
|
||||||
PD07 Pin = 103
|
PD07 Pin = 103
|
||||||
PD08 Pin = 104
|
PD08 Pin = 104 // peripherals: TCC0 channel 1
|
||||||
PD09 Pin = 105
|
PD09 Pin = 105 // peripherals: TCC0 channel 2
|
||||||
PD10 Pin = 106
|
PD10 Pin = 106 // peripherals: TCC0 channel 3
|
||||||
PD11 Pin = 107
|
PD11 Pin = 107 // peripherals: TCC0 channel 4
|
||||||
PD12 Pin = 108
|
PD12 Pin = 108 // peripherals: TCC0 channel 5
|
||||||
PD13 Pin = 109
|
PD13 Pin = 109 // peripherals: TCC0 channel 6
|
||||||
PD14 Pin = 110
|
PD14 Pin = 110
|
||||||
PD15 Pin = 111
|
PD15 Pin = 111
|
||||||
PD16 Pin = 112
|
PD16 Pin = 112
|
||||||
PD17 Pin = 113
|
PD17 Pin = 113
|
||||||
PD18 Pin = 114
|
PD18 Pin = 114
|
||||||
PD19 Pin = 115
|
PD19 Pin = 115
|
||||||
PD20 Pin = 116
|
PD20 Pin = 116 // peripherals: TCC1 channel 0
|
||||||
PD21 Pin = 117
|
PD21 Pin = 117 // peripherals: TCC1 channel 1
|
||||||
PD22 Pin = 118
|
PD22 Pin = 118
|
||||||
PD23 Pin = 119
|
PD23 Pin = 119
|
||||||
PD24 Pin = 120
|
PD24 Pin = 120
|
||||||
@@ -339,7 +337,7 @@ func findPinPadMapping(sercom uint8, pin Pin) (pinMode PinMode, pad uint32, ok b
|
|||||||
if upper != 0 {
|
if upper != 0 {
|
||||||
// SERCOM
|
// SERCOM
|
||||||
if (upper>>4)-1 == sercom {
|
if (upper>>4)-1 == sercom {
|
||||||
pinMode = PinSERCOM
|
pinMode = pinSERCOM
|
||||||
pad |= uint32(upper % 4)
|
pad |= uint32(upper % 4)
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -347,7 +345,7 @@ func findPinPadMapping(sercom uint8, pin Pin) (pinMode PinMode, pad uint32, ok b
|
|||||||
if lower != 0 {
|
if lower != 0 {
|
||||||
// SERCOM-ALT
|
// SERCOM-ALT
|
||||||
if (lower>>4)-1 == sercom {
|
if (lower>>4)-1 == sercom {
|
||||||
pinMode = PinSERCOMAlt
|
pinMode = pinSERCOMAlt
|
||||||
pad |= uint32(lower % 4)
|
pad |= uint32(lower % 4)
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
@@ -581,65 +579,65 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
sam.PORT.GROUP[group].OUTSET.Set(1 << pin_in_group)
|
sam.PORT.GROUP[group].OUTSET.Set(1 << pin_in_group)
|
||||||
p.setPinCfg(sam.PORT_GROUP_PINCFG_INEN | sam.PORT_GROUP_PINCFG_PULLEN)
|
p.setPinCfg(sam.PORT_GROUP_PINCFG_INEN | sam.PORT_GROUP_PINCFG_PULLEN)
|
||||||
|
|
||||||
case PinSERCOM:
|
case pinSERCOM:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinSERCOM) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOM) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinSERCOM) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN | sam.PORT_GROUP_PINCFG_DRVSTR | sam.PORT_GROUP_PINCFG_INEN)
|
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN | sam.PORT_GROUP_PINCFG_DRVSTR | sam.PORT_GROUP_PINCFG_INEN)
|
||||||
|
|
||||||
case PinSERCOMAlt:
|
case pinSERCOMAlt:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinSERCOMAlt) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinSERCOMAlt) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinSERCOMAlt) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN | sam.PORT_GROUP_PINCFG_DRVSTR)
|
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN | sam.PORT_GROUP_PINCFG_DRVSTR)
|
||||||
|
|
||||||
case PinCom:
|
case pinCom:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinCom) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinCom) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinCom) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinCom) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN)
|
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN)
|
||||||
case PinAnalog:
|
case pinAnalog:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinAnalog) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinAnalog) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinAnalog) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinAnalog) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN | sam.PORT_GROUP_PINCFG_DRVSTR)
|
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN | sam.PORT_GROUP_PINCFG_DRVSTR)
|
||||||
case PinSDHC:
|
case pinSDHC:
|
||||||
if p&1 > 0 {
|
if p&1 > 0 {
|
||||||
// odd pin, so save the even pins
|
// odd pin, so save the even pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXE_Msk
|
||||||
p.setPMux(val | (uint8(PinSDHC) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
p.setPMux(val | (uint8(pinSDHC) << sam.PORT_GROUP_PMUX_PMUXO_Pos))
|
||||||
} else {
|
} else {
|
||||||
// even pin, so save the odd pins
|
// even pin, so save the odd pins
|
||||||
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
val := p.getPMux() & sam.PORT_GROUP_PMUX_PMUXO_Msk
|
||||||
p.setPMux(val | (uint8(PinSDHC) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
p.setPMux(val | (uint8(pinSDHC) << sam.PORT_GROUP_PMUX_PMUXE_Pos))
|
||||||
}
|
}
|
||||||
// enable port config
|
// enable port config
|
||||||
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN)
|
p.setPinCfg(sam.PORT_GROUP_PINCFG_PMUXEN)
|
||||||
@@ -815,7 +813,7 @@ func (a ADC) Configure(config ADCConfig) {
|
|||||||
adc.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1)
|
adc.REFCTRL.SetBits(sam.ADC_REFCTRL_REFSEL_INTVCC1)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Pin.Configure(PinConfig{Mode: PinAnalog})
|
a.Pin.Configure(PinConfig{Mode: pinAnalog})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the current value of a ADC pin, in the range 0..0xffff.
|
// Get returns the current value of a ADC pin, in the range 0..0xffff.
|
||||||
@@ -1151,7 +1149,7 @@ const i2cTimeout = 1000
|
|||||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
// Default I2C bus speed is 100 kHz.
|
// Default I2C bus speed is 100 kHz.
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = 100 * KHz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use default I2C pins if not set.
|
// Use default I2C pins if not set.
|
||||||
@@ -1527,10 +1525,6 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
|||||||
return byte(spi.Bus.DATA.Get()), nil
|
return byte(spi.Bus.DATA.Get()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||||
// interface, there must always be the same number of bytes written as bytes read.
|
// interface, there must always be the same number of bytes written as bytes read.
|
||||||
// The Tx method knows about this, and offers a few different ways of calling it.
|
// The Tx method knows about this, and offers a few different ways of calling it.
|
||||||
@@ -1872,7 +1866,7 @@ var pinTimerMapping = [...]struct{ F, G uint8 }{
|
|||||||
PB02 / 2: {pinTCC2_2, 0},
|
PB02 / 2: {pinTCC2_2, 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
// findPinPadMapping returns the pin mode (PinTCCF or PinTCCG) and the channel
|
// findPinPadMapping returns the pin mode (pinTCCF or pinTCCG) and the channel
|
||||||
// number for a given timer and pin. A zero PinMode is returned if no mapping
|
// number for a given timer and pin. A zero PinMode is returned if no mapping
|
||||||
// could be found.
|
// could be found.
|
||||||
func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
|
func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
|
||||||
@@ -1884,12 +1878,12 @@ func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
|
|||||||
|
|
||||||
// Check for column F in the datasheet.
|
// Check for column F in the datasheet.
|
||||||
if mapping.F>>4-1 == timer {
|
if mapping.F>>4-1 == timer {
|
||||||
return PinTCCF, mapping.F&0x0f + uint8(pin)&1
|
return pinTCCF, mapping.F&0x0f + uint8(pin)&1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for column G in the datasheet.
|
// Check for column G in the datasheet.
|
||||||
if mapping.G>>4-1 == timer {
|
if mapping.G>>4-1 == timer {
|
||||||
return PinTCCG, mapping.G&0x0f + uint8(pin)&1
|
return pinTCCG, mapping.G&0x0f + uint8(pin)&1
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing found.
|
// Nothing found.
|
||||||
@@ -1980,7 +1974,7 @@ func EnterBootloader() {
|
|||||||
|
|
||||||
// Perform magic reset into bootloader, as mentioned in
|
// Perform magic reset into bootloader, as mentioned in
|
||||||
// https://github.com/arduino/ArduinoCore-samd/issues/197
|
// https://github.com/arduino/ArduinoCore-samd/issues/197
|
||||||
*(*uint32)(unsafe.Pointer(uintptr(0x20000000 + HSRAM_SIZE - 4))) = RESET_MAGIC_VALUE
|
*(*uint32)(unsafe.Pointer(uintptr(0x20000000 + HSRAM_SIZE - 4))) = resetMagicValue
|
||||||
|
|
||||||
arm.SystemReset()
|
arm.SystemReset()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ func (dev *USBDevice) Configure(config UARTConfig) {
|
|||||||
sam.USB_DEVICE.DESCADD.Set(uint32(uintptr(unsafe.Pointer(&usbEndpointDescriptors))))
|
sam.USB_DEVICE.DESCADD.Set(uint32(uintptr(unsafe.Pointer(&usbEndpointDescriptors))))
|
||||||
|
|
||||||
// configure pins
|
// configure pins
|
||||||
USBCDC_DM_PIN.Configure(PinConfig{Mode: PinCom})
|
USBCDC_DM_PIN.Configure(PinConfig{Mode: pinCom})
|
||||||
USBCDC_DP_PIN.Configure(PinConfig{Mode: PinCom})
|
USBCDC_DP_PIN.Configure(PinConfig{Mode: pinCom})
|
||||||
|
|
||||||
// performs pad calibration from store fuses
|
// performs pad calibration from store fuses
|
||||||
handlePadCalibration()
|
handlePadCalibration()
|
||||||
|
|||||||
@@ -68,9 +68,9 @@ func (can *CAN) Configure(config CANConfig) error {
|
|||||||
config.Standby.Low()
|
config.Standby.Low()
|
||||||
}
|
}
|
||||||
|
|
||||||
mode := PinCAN0
|
mode := pinCAN0
|
||||||
if can.instance() == 1 {
|
if can.instance() == 1 {
|
||||||
mode = PinCAN1
|
mode = pinCAN1
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Rx.Configure(PinConfig{Mode: mode})
|
config.Rx.Configure(PinConfig{Mode: mode})
|
||||||
|
|||||||
@@ -59,12 +59,9 @@ type PinChange uint8
|
|||||||
|
|
||||||
// Pin change interrupt constants for SetInterrupt.
|
// Pin change interrupt constants for SetInterrupt.
|
||||||
const (
|
const (
|
||||||
PinNoInterrupt PinChange = iota
|
PinRising PinChange = iota + 1
|
||||||
PinRising
|
|
||||||
PinFalling
|
PinFalling
|
||||||
PinToggle
|
PinToggle
|
||||||
PinLowLevel
|
|
||||||
PinHighLevel
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configure this pin with the given configuration.
|
// Configure this pin with the given configuration.
|
||||||
@@ -190,7 +187,7 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) (err error) {
|
|||||||
return ErrInvalidInputPin
|
return ErrInvalidInputPin
|
||||||
}
|
}
|
||||||
|
|
||||||
if callback == nil || change == PinNoInterrupt {
|
if callback == nil {
|
||||||
// Disable this pin interrupt
|
// Disable this pin interrupt
|
||||||
p.pin().ClearBits(esp.GPIO_PIN_PIN_INT_TYPE_Msk | esp.GPIO_PIN_PIN_INT_ENA_Msk)
|
p.pin().ClearBits(esp.GPIO_PIN_PIN_INT_TYPE_Msk | esp.GPIO_PIN_PIN_INT_ENA_Msk)
|
||||||
|
|
||||||
@@ -264,15 +261,6 @@ type UART struct {
|
|||||||
DataOverflowDetected bool // set when data overflow detected in UART FIFO buffer or RingBuffer
|
DataOverflowDetected bool // set when data overflow detected in UART FIFO buffer or RingBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
type UARTStopBits int
|
|
||||||
|
|
||||||
const (
|
|
||||||
UARTStopBits_Default UARTStopBits = iota
|
|
||||||
UARTStopBits_1
|
|
||||||
UARTStopBits_1_5
|
|
||||||
UARTStopBits_2
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultDataBits = 8
|
defaultDataBits = 8
|
||||||
defaultStopBit = 1
|
defaultStopBit = 1
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ func CPUFrequency() uint32 {
|
|||||||
const (
|
const (
|
||||||
PinInput PinMode = iota
|
PinInput PinMode = iota
|
||||||
PinOutput
|
PinOutput
|
||||||
PinPWM
|
|
||||||
PinSPI
|
// internal pin modes
|
||||||
PinI2C = PinSPI
|
pinPWM
|
||||||
|
pinSPI
|
||||||
|
pinI2C = pinSPI
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configure this pin with the given configuration.
|
// Configure this pin with the given configuration.
|
||||||
@@ -29,10 +31,10 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
switch config.Mode {
|
switch config.Mode {
|
||||||
case PinOutput:
|
case PinOutput:
|
||||||
sifive.GPIO0.OUTPUT_EN.SetBits(1 << uint8(p))
|
sifive.GPIO0.OUTPUT_EN.SetBits(1 << uint8(p))
|
||||||
case PinPWM:
|
case pinPWM:
|
||||||
sifive.GPIO0.IOF_EN.SetBits(1 << uint8(p))
|
sifive.GPIO0.IOF_EN.SetBits(1 << uint8(p))
|
||||||
sifive.GPIO0.IOF_SEL.SetBits(1 << uint8(p))
|
sifive.GPIO0.IOF_SEL.SetBits(1 << uint8(p))
|
||||||
case PinSPI:
|
case pinSPI:
|
||||||
sifive.GPIO0.IOF_EN.SetBits(1 << uint8(p))
|
sifive.GPIO0.IOF_EN.SetBits(1 << uint8(p))
|
||||||
sifive.GPIO0.IOF_SEL.ClearBits(1 << uint8(p))
|
sifive.GPIO0.IOF_SEL.ClearBits(1 << uint8(p))
|
||||||
}
|
}
|
||||||
@@ -145,9 +147,9 @@ func (spi SPI) Configure(config SPIConfig) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// enable pins for SPI
|
// enable pins for SPI
|
||||||
config.SCK.Configure(PinConfig{Mode: PinSPI})
|
config.SCK.Configure(PinConfig{Mode: pinSPI})
|
||||||
config.SDO.Configure(PinConfig{Mode: PinSPI})
|
config.SDO.Configure(PinConfig{Mode: pinSPI})
|
||||||
config.SDI.Configure(PinConfig{Mode: PinSPI})
|
config.SDI.Configure(PinConfig{Mode: pinSPI})
|
||||||
|
|
||||||
// set default frequency
|
// set default frequency
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
@@ -231,7 +233,7 @@ type I2CConfig struct {
|
|||||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
var i2cClockFrequency uint32 = 32000000
|
var i2cClockFrequency uint32 = 32000000
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = 100 * KHz
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.SDA == 0 && config.SCL == 0 {
|
if config.SDA == 0 && config.SCL == 0 {
|
||||||
@@ -251,8 +253,8 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
|||||||
// enable controller
|
// enable controller
|
||||||
i2c.Bus.CTR.SetBits(sifive.I2C_CTR_EN)
|
i2c.Bus.CTR.SetBits(sifive.I2C_CTR_EN)
|
||||||
|
|
||||||
config.SDA.Configure(PinConfig{Mode: PinI2C})
|
config.SDA.Configure(PinConfig{Mode: pinI2C})
|
||||||
config.SCL.Configure(PinConfig{Mode: PinI2C})
|
config.SCL.Configure(PinConfig{Mode: pinI2C})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,17 @@ type PinChange uint8
|
|||||||
// Pin modes.
|
// Pin modes.
|
||||||
const (
|
const (
|
||||||
PinInput PinMode = iota
|
PinInput PinMode = iota
|
||||||
PinInputPullUp
|
PinInputPullup
|
||||||
PinInputPullDown
|
PinInputPulldown
|
||||||
PinOutput
|
PinOutput
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated: use PinInputPullup and PinInputPulldown instead.
|
||||||
|
const (
|
||||||
|
PinInputPullUp = PinInputPullup
|
||||||
|
PinInputPullDown = PinInputPulldown
|
||||||
|
)
|
||||||
|
|
||||||
// FPIOA internal pull resistors.
|
// FPIOA internal pull resistors.
|
||||||
const (
|
const (
|
||||||
fpioaPullNone fpioaPullMode = iota
|
fpioaPullNone fpioaPullMode = iota
|
||||||
@@ -89,10 +95,10 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
case PinInput:
|
case PinInput:
|
||||||
p.setFPIOAIOPull(fpioaPullNone)
|
p.setFPIOAIOPull(fpioaPullNone)
|
||||||
input = true
|
input = true
|
||||||
case PinInputPullUp:
|
case PinInputPullup:
|
||||||
p.setFPIOAIOPull(fpioaPullUp)
|
p.setFPIOAIOPull(fpioaPullUp)
|
||||||
input = true
|
input = true
|
||||||
case PinInputPullDown:
|
case PinInputPulldown:
|
||||||
p.setFPIOAIOPull(fpioaPullDown)
|
p.setFPIOAIOPull(fpioaPullDown)
|
||||||
input = true
|
input = true
|
||||||
case PinOutput:
|
case PinOutput:
|
||||||
@@ -517,7 +523,7 @@ type I2CConfig struct {
|
|||||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
|
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = 100 * KHz
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.SDA == 0 && config.SCL == 0 {
|
if config.SDA == 0 && config.SCL == 0 {
|
||||||
|
|||||||
@@ -21,36 +21,40 @@ func CPUFrequency() uint32 {
|
|||||||
const (
|
const (
|
||||||
// GPIO
|
// GPIO
|
||||||
PinInput PinMode = iota
|
PinInput PinMode = iota
|
||||||
PinInputPullUp
|
PinInputPullup
|
||||||
PinInputPullDown
|
PinInputPulldown
|
||||||
PinOutput
|
PinOutput
|
||||||
PinOutputOpenDrain
|
PinOutputOpenDrain
|
||||||
PinDisable
|
PinDisable
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
PinInputAnalog
|
pinInputAnalog
|
||||||
|
|
||||||
// UART
|
// UART
|
||||||
PinModeUARTTX
|
pinModeUARTTX
|
||||||
PinModeUARTRX
|
pinModeUARTRX
|
||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
PinModeSPISDI
|
pinModeSPISDI
|
||||||
PinModeSPISDO
|
pinModeSPISDO
|
||||||
PinModeSPICLK
|
pinModeSPICLK
|
||||||
PinModeSPICS
|
pinModeSPICS
|
||||||
|
|
||||||
// I2C
|
// I2C
|
||||||
PinModeI2CSDA
|
pinModeI2CSDA
|
||||||
PinModeI2CSCL
|
pinModeI2CSCL
|
||||||
|
)
|
||||||
|
|
||||||
|
// Deprecated: use PinInputPullup and PinInputPulldown instead.
|
||||||
|
const (
|
||||||
|
PinInputPullUp = PinInputPullup
|
||||||
|
PinInputPullDown = PinInputPulldown
|
||||||
)
|
)
|
||||||
|
|
||||||
type PinChange uint8
|
type PinChange uint8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PinLow PinChange = iota
|
PinRising PinChange = iota + 2
|
||||||
PinHigh
|
|
||||||
PinRising
|
|
||||||
PinFalling
|
PinFalling
|
||||||
PinToggle
|
PinToggle
|
||||||
)
|
)
|
||||||
@@ -259,11 +263,11 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
gpio.GDIR.ClearBits(p.getMask())
|
gpio.GDIR.ClearBits(p.getMask())
|
||||||
pad.Set(dse(7))
|
pad.Set(dse(7))
|
||||||
|
|
||||||
case PinInputPullUp:
|
case PinInputPullup:
|
||||||
gpio.GDIR.ClearBits(p.getMask())
|
gpio.GDIR.ClearBits(p.getMask())
|
||||||
pad.Set(dse(7) | pke | pue | pup(3) | hys)
|
pad.Set(dse(7) | pke | pue | pup(3) | hys)
|
||||||
|
|
||||||
case PinInputPullDown:
|
case PinInputPulldown:
|
||||||
gpio.GDIR.ClearBits(p.getMask())
|
gpio.GDIR.ClearBits(p.getMask())
|
||||||
pad.Set(dse(7) | pke | pue | hys)
|
pad.Set(dse(7) | pke | pue | hys)
|
||||||
|
|
||||||
@@ -279,29 +283,29 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
gpio.GDIR.ClearBits(p.getMask())
|
gpio.GDIR.ClearBits(p.getMask())
|
||||||
pad.Set(dse(7) | hys)
|
pad.Set(dse(7) | hys)
|
||||||
|
|
||||||
case PinInputAnalog:
|
case pinInputAnalog:
|
||||||
gpio.GDIR.ClearBits(p.getMask())
|
gpio.GDIR.ClearBits(p.getMask())
|
||||||
pad.Set(dse(7))
|
pad.Set(dse(7))
|
||||||
|
|
||||||
case PinModeUARTTX:
|
case pinModeUARTTX:
|
||||||
pad.Set(sre | dse(3) | spd(3))
|
pad.Set(sre | dse(3) | spd(3))
|
||||||
|
|
||||||
case PinModeUARTRX:
|
case pinModeUARTRX:
|
||||||
pad.Set(dse(7) | pke | pue | pup(3) | hys)
|
pad.Set(dse(7) | pke | pue | pup(3) | hys)
|
||||||
|
|
||||||
case PinModeSPISDI:
|
case pinModeSPISDI:
|
||||||
pad.Set(dse(7) | spd(2))
|
pad.Set(dse(7) | spd(2))
|
||||||
|
|
||||||
case PinModeSPISDO:
|
case pinModeSPISDO:
|
||||||
pad.Set(dse(7) | spd(2))
|
pad.Set(dse(7) | spd(2))
|
||||||
|
|
||||||
case PinModeSPICLK:
|
case pinModeSPICLK:
|
||||||
pad.Set(dse(7) | spd(2))
|
pad.Set(dse(7) | spd(2))
|
||||||
|
|
||||||
case PinModeSPICS:
|
case pinModeSPICS:
|
||||||
pad.Set(dse(7))
|
pad.Set(dse(7))
|
||||||
|
|
||||||
case PinModeI2CSDA, PinModeI2CSCL:
|
case pinModeI2CSDA, pinModeI2CSCL:
|
||||||
pad.Set(ode | sre | dse(4) | spd(1) | pke | pue | pup(3))
|
pad.Set(ode | sre | dse(4) | spd(1) | pke | pue | pup(3))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +391,7 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
|
|||||||
mask := p.getMask()
|
mask := p.getMask()
|
||||||
if nil != callback {
|
if nil != callback {
|
||||||
switch change {
|
switch change {
|
||||||
case PinLow, PinHigh, PinRising, PinFalling:
|
case PinRising, PinFalling:
|
||||||
gpio.EDGE_SEL.ClearBits(mask)
|
gpio.EDGE_SEL.ClearBits(mask)
|
||||||
var reg *volatile.Register32
|
var reg *volatile.Register32
|
||||||
var pos uint8
|
var pos uint8
|
||||||
@@ -746,7 +750,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
switch config.Mode {
|
switch config.Mode {
|
||||||
|
|
||||||
// GPIO
|
// GPIO
|
||||||
case PinInput, PinInputPullUp, PinInputPullDown,
|
case PinInput, PinInputPullup, PinInputPulldown,
|
||||||
PinOutput, PinOutputOpenDrain, PinDisable:
|
PinOutput, PinOutputOpenDrain, PinDisable:
|
||||||
mode := uint32(0x5) // GPIO is always alternate function 5
|
mode := uint32(0x5) // GPIO is always alternate function 5
|
||||||
if forcePath {
|
if forcePath {
|
||||||
@@ -755,7 +759,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
case PinInputAnalog:
|
case pinInputAnalog:
|
||||||
mode := uint32(0x5) // use alternate function 5 (GPIO)
|
mode := uint32(0x5) // use alternate function 5 (GPIO)
|
||||||
if forcePath {
|
if forcePath {
|
||||||
mode |= 0x10 // SION bit
|
mode |= 0x10 // SION bit
|
||||||
@@ -763,7 +767,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// UART RX/TX
|
// UART RX/TX
|
||||||
case PinModeUARTRX, PinModeUARTTX:
|
case pinModeUARTRX, pinModeUARTTX:
|
||||||
mode := uint32(0x2) // UART is usually alternate function 2 on Teensy 4.x
|
mode := uint32(0x2) // UART is usually alternate function 2 on Teensy 4.x
|
||||||
// Teensy 4.1 has a UART (LPUART5) with alternate function 1
|
// Teensy 4.1 has a UART (LPUART5) with alternate function 1
|
||||||
if p == PB28 || p == PB29 {
|
if p == PB28 || p == PB29 {
|
||||||
@@ -772,7 +776,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// SPI SDI
|
// SPI SDI
|
||||||
case PinModeSPISDI:
|
case pinModeSPISDI:
|
||||||
var mode uint32
|
var mode uint32
|
||||||
switch p {
|
switch p {
|
||||||
case PC15: // LPSPI1 SDI on PC15 alternate function 4
|
case PC15: // LPSPI1 SDI on PC15 alternate function 4
|
||||||
@@ -790,7 +794,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// SPI SDO
|
// SPI SDO
|
||||||
case PinModeSPISDO:
|
case pinModeSPISDO:
|
||||||
var mode uint32
|
var mode uint32
|
||||||
switch p {
|
switch p {
|
||||||
case PC14: // LPSPI1 SDO on PC14 alternate function 4
|
case PC14: // LPSPI1 SDO on PC14 alternate function 4
|
||||||
@@ -808,7 +812,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// SPI SCK
|
// SPI SCK
|
||||||
case PinModeSPICLK:
|
case pinModeSPICLK:
|
||||||
var mode uint32
|
var mode uint32
|
||||||
switch p {
|
switch p {
|
||||||
case PC12: // LPSPI1 SCK on PC12 alternate function 4
|
case PC12: // LPSPI1 SCK on PC12 alternate function 4
|
||||||
@@ -826,7 +830,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// SPI CS
|
// SPI CS
|
||||||
case PinModeSPICS:
|
case pinModeSPICS:
|
||||||
var mode uint32
|
var mode uint32
|
||||||
switch p {
|
switch p {
|
||||||
case PC13: // LPSPI1 CS on PC13 alternate function 4
|
case PC13: // LPSPI1 CS on PC13 alternate function 4
|
||||||
@@ -844,7 +848,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// I2C SDA
|
// I2C SDA
|
||||||
case PinModeI2CSDA:
|
case pinModeI2CSDA:
|
||||||
var mode uint32
|
var mode uint32
|
||||||
switch p {
|
switch p {
|
||||||
case PA13: // LPI2C4 SDA on PA13 alternate function 0
|
case PA13: // LPI2C4 SDA on PA13 alternate function 0
|
||||||
@@ -862,7 +866,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
|
|||||||
return mode
|
return mode
|
||||||
|
|
||||||
// I2C SCL
|
// I2C SCL
|
||||||
case PinModeI2CSCL:
|
case pinModeI2CSCL:
|
||||||
var mode uint32
|
var mode uint32
|
||||||
switch p {
|
switch p {
|
||||||
case PA12: // LPI2C4 SCL on PA12 alternate function 0
|
case PA12: // LPI2C4 SCL on PA12 alternate function 0
|
||||||
@@ -898,7 +902,7 @@ func (a ADC) Configure(config ADCConfig) {
|
|||||||
defaultSamples = uint32(4)
|
defaultSamples = uint32(4)
|
||||||
)
|
)
|
||||||
|
|
||||||
a.Pin.Configure(PinConfig{Mode: PinInputAnalog})
|
a.Pin.Configure(PinConfig{Mode: pinInputAnalog})
|
||||||
|
|
||||||
resolution, samples := config.Resolution, config.Samples
|
resolution, samples := config.Resolution, config.Samples
|
||||||
if 0 == resolution {
|
if 0 == resolution {
|
||||||
|
|||||||
@@ -10,15 +10,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
TWI_FREQ_BUS = 24000000 // LPI2C root clock is on 24 MHz OSC
|
|
||||||
TWI_FREQ_100KHZ = 100000 // StandardMode (100 kHz)
|
|
||||||
TWI_FREQ_400KHZ = 400000 // FastMode (400 kHz)
|
|
||||||
TWI_FREQ_1MHZ = 1000000 // FastModePlus (1 MHz)
|
|
||||||
TWI_FREQ_5MHZ = 5000000 // UltraFastMode (5 MHz)
|
|
||||||
TWI_FREQ_DEFAULT = TWI_FREQ_100KHZ // default to StandardMode (100 kHz)
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errI2CWriteTimeout = errors.New("I2C timeout during write")
|
errI2CWriteTimeout = errors.New("I2C timeout during write")
|
||||||
errI2CReadTimeout = errors.New("I2C timeout during read")
|
errI2CReadTimeout = errors.New("I2C timeout during read")
|
||||||
@@ -165,8 +156,8 @@ func (i2c *I2C) Configure(config I2CConfig) {
|
|||||||
sda, scl := i2c.setPins(config)
|
sda, scl := i2c.setPins(config)
|
||||||
|
|
||||||
// configure the mux and pad control registers
|
// configure the mux and pad control registers
|
||||||
sda.Configure(PinConfig{Mode: PinModeI2CSDA})
|
sda.Configure(PinConfig{Mode: pinModeI2CSDA})
|
||||||
scl.Configure(PinConfig{Mode: PinModeI2CSCL})
|
scl.Configure(PinConfig{Mode: pinModeI2CSCL})
|
||||||
|
|
||||||
// configure the mux input selector
|
// configure the mux input selector
|
||||||
i2c.muxSDA.connect()
|
i2c.muxSDA.connect()
|
||||||
@@ -174,7 +165,7 @@ func (i2c *I2C) Configure(config I2CConfig) {
|
|||||||
|
|
||||||
freq := config.Frequency
|
freq := config.Frequency
|
||||||
if 0 == freq {
|
if 0 == freq {
|
||||||
freq = TWI_FREQ_DEFAULT
|
freq = 100 * KHz
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset clock and registers, and enable LPI2C module interface
|
// reset clock and registers, and enable LPI2C module interface
|
||||||
@@ -305,7 +296,7 @@ func (i2c *I2C) setFrequency(freq uint32) {
|
|||||||
wasEnabled := i2c.Bus.MCR.HasBits(nxp.LPI2C_MCR_MEN)
|
wasEnabled := i2c.Bus.MCR.HasBits(nxp.LPI2C_MCR_MEN)
|
||||||
i2c.Bus.MCR.ClearBits(nxp.LPI2C_MCR_MEN)
|
i2c.Bus.MCR.ClearBits(nxp.LPI2C_MCR_MEN)
|
||||||
|
|
||||||
// baud rate = (TWI_FREQ_BUS/(2^pre))/(CLKLO+1 + CLKHI+1 + FLOOR((2+FILTSCL)/(2^pre)))
|
// baud rate = (24MHz/(2^pre))/(CLKLO+1 + CLKHI+1 + FLOOR((2+FILTSCL)/(2^pre)))
|
||||||
// assume: CLKLO=2*CLKHI, SETHOLD=CLKHI, DATAVD=CLKHI/2
|
// assume: CLKLO=2*CLKHI, SETHOLD=CLKHI, DATAVD=CLKHI/2
|
||||||
for pre := uint32(1); pre <= 128; pre *= 2 {
|
for pre := uint32(1); pre <= 128; pre *= 2 {
|
||||||
if bestError == 0 {
|
if bestError == 0 {
|
||||||
@@ -314,9 +305,9 @@ func (i2c *I2C) setFrequency(freq uint32) {
|
|||||||
for clkHi := uint32(1); clkHi < 32; clkHi++ {
|
for clkHi := uint32(1); clkHi < 32; clkHi++ {
|
||||||
var absError, rate uint32
|
var absError, rate uint32
|
||||||
if clkHi == 1 {
|
if clkHi == 1 {
|
||||||
rate = (TWI_FREQ_BUS / pre) / (1 + 3 + 2 + 2/pre)
|
rate = (24 * MHz / pre) / (1 + 3 + 2 + 2/pre)
|
||||||
} else {
|
} else {
|
||||||
rate = (TWI_FREQ_BUS / pre) / (3*clkHi + 2 + 2/pre)
|
rate = (24 * MHz / pre) / (3*clkHi + 2 + 2/pre)
|
||||||
}
|
}
|
||||||
if freq > rate {
|
if freq > rate {
|
||||||
absError = freq - rate
|
absError = freq - rate
|
||||||
@@ -370,15 +361,15 @@ func (i2c *I2C) setFrequency(freq uint32) {
|
|||||||
mcfgr2, mcfgr3 uint32
|
mcfgr2, mcfgr3 uint32
|
||||||
)
|
)
|
||||||
const i2cClockStretchTimeout = 15000 // microseconds
|
const i2cClockStretchTimeout = 15000 // microseconds
|
||||||
if freq >= TWI_FREQ_5MHZ {
|
if freq >= 5*MHz {
|
||||||
// I2C UltraFastMode 5 MHz
|
// I2C UltraFastMode 5 MHz
|
||||||
mcfgr2 = 0 // disable glitch filters and timeout for UltraFastMode
|
mcfgr2 = 0 // disable glitch filters and timeout for UltraFastMode
|
||||||
mcfgr3 = 0 //
|
mcfgr3 = 0 //
|
||||||
} else if freq >= TWI_FREQ_1MHZ {
|
} else if freq >= 1*MHz {
|
||||||
// I2C FastModePlus 1 MHz
|
// I2C FastModePlus 1 MHz
|
||||||
mcfgr2 = filtsda(1) | filtscl(1) | busidle(2400) // 100us timeout
|
mcfgr2 = filtsda(1) | filtscl(1) | busidle(2400) // 100us timeout
|
||||||
mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1)
|
mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1)
|
||||||
} else if freq >= TWI_FREQ_400KHZ {
|
} else if freq >= 400*KHz {
|
||||||
// I2C FastMode 400 kHz
|
// I2C FastMode 400 kHz
|
||||||
mcfgr2 = filtsda(2) | filtscl(2) | busidle(3600) // 150us timeout
|
mcfgr2 = filtsda(2) | filtscl(2) | busidle(3600) // 150us timeout
|
||||||
mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1)
|
mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1)
|
||||||
|
|||||||
@@ -77,10 +77,10 @@ func (spi *SPI) Configure(config SPIConfig) {
|
|||||||
spi.sdi, spi.sdo, spi.sck, spi.cs = config.getPins()
|
spi.sdi, spi.sdo, spi.sck, spi.cs = config.getPins()
|
||||||
|
|
||||||
// configure the mux and pad control registers
|
// configure the mux and pad control registers
|
||||||
spi.sdi.Configure(PinConfig{Mode: PinModeSPISDI})
|
spi.sdi.Configure(PinConfig{Mode: pinModeSPISDI})
|
||||||
spi.sdo.Configure(PinConfig{Mode: PinModeSPISDO})
|
spi.sdo.Configure(PinConfig{Mode: pinModeSPISDO})
|
||||||
spi.sck.Configure(PinConfig{Mode: PinModeSPICLK})
|
spi.sck.Configure(PinConfig{Mode: pinModeSPICLK})
|
||||||
spi.cs.Configure(PinConfig{Mode: PinModeSPICS})
|
spi.cs.Configure(PinConfig{Mode: pinModeSPICS})
|
||||||
|
|
||||||
// configure the mux input selector
|
// configure the mux input selector
|
||||||
spi.muxSDI.connect()
|
spi.muxSDI.connect()
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ func (uart *UART) Configure(config UARTConfig) {
|
|||||||
uart.tx = config.TX
|
uart.tx = config.TX
|
||||||
|
|
||||||
// configure the mux and pad control registers
|
// configure the mux and pad control registers
|
||||||
uart.rx.Configure(PinConfig{Mode: PinModeUARTRX})
|
uart.rx.Configure(PinConfig{Mode: pinModeUARTRX})
|
||||||
uart.tx.Configure(PinConfig{Mode: PinModeUARTTX})
|
uart.tx.Configure(PinConfig{Mode: pinModeUARTTX})
|
||||||
|
|
||||||
// configure the mux input selector
|
// configure the mux input selector
|
||||||
uart.muxRX.connect()
|
uart.muxRX.connect()
|
||||||
@@ -159,8 +159,8 @@ func (uart *UART) Disable() {
|
|||||||
uart.Bus.CTRL.ClearBits(nxp.LPUART_CTRL_TE | nxp.LPUART_CTRL_RE)
|
uart.Bus.CTRL.ClearBits(nxp.LPUART_CTRL_TE | nxp.LPUART_CTRL_RE)
|
||||||
|
|
||||||
// put pins back into GPIO mode
|
// put pins back into GPIO mode
|
||||||
uart.rx.Configure(PinConfig{Mode: PinInputPullUp})
|
uart.rx.Configure(PinConfig{Mode: PinInputPullup})
|
||||||
uart.tx.Configure(PinConfig{Mode: PinInputPullUp})
|
uart.tx.Configure(PinConfig{Mode: PinInputPullup})
|
||||||
}
|
}
|
||||||
uart.configured = false
|
uart.configured = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,10 @@ package machine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"device/nrf"
|
"device/nrf"
|
||||||
"errors"
|
|
||||||
"runtime/interrupt"
|
"runtime/interrupt"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
|
|
||||||
)
|
|
||||||
|
|
||||||
const deviceName = nrf.Device
|
const deviceName = nrf.Device
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -230,7 +225,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
|||||||
|
|
||||||
// Default I2C bus speed is 100 kHz.
|
// Default I2C bus speed is 100 kHz.
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = 100 * KHz
|
||||||
}
|
}
|
||||||
// Default I2C pins if not set.
|
// Default I2C pins if not set.
|
||||||
if config.SDA == 0 && config.SCL == 0 {
|
if config.SDA == 0 && config.SCL == 0 {
|
||||||
@@ -253,7 +248,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
|||||||
(nrf.GPIO_PIN_CNF_DRIVE_S0D1 << nrf.GPIO_PIN_CNF_DRIVE_Pos) |
|
(nrf.GPIO_PIN_CNF_DRIVE_S0D1 << nrf.GPIO_PIN_CNF_DRIVE_Pos) |
|
||||||
(nrf.GPIO_PIN_CNF_SENSE_Disabled << nrf.GPIO_PIN_CNF_SENSE_Pos))
|
(nrf.GPIO_PIN_CNF_SENSE_Disabled << nrf.GPIO_PIN_CNF_SENSE_Pos))
|
||||||
|
|
||||||
if config.Frequency == TWI_FREQ_400KHZ {
|
if config.Frequency >= 400*KHz {
|
||||||
i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K400)
|
i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K400)
|
||||||
} else {
|
} else {
|
||||||
i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K100)
|
i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K100)
|
||||||
@@ -350,3 +345,41 @@ func (i2c *I2C) readByte() (byte, error) {
|
|||||||
i2c.Bus.EVENTS_RXDREADY.Set(0)
|
i2c.Bus.EVENTS_RXDREADY.Set(0)
|
||||||
return byte(i2c.Bus.RXD.Get()), nil
|
return byte(i2c.Bus.RXD.Get()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var rngStarted = false
|
||||||
|
|
||||||
|
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
|
||||||
|
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
|
||||||
|
func GetRNG() (ret uint32, err error) {
|
||||||
|
// There's no apparent way to check the status of the RNG peripheral's task, so simply start it
|
||||||
|
// to avoid deadlocking while waiting for output.
|
||||||
|
if !rngStarted {
|
||||||
|
nrf.RNG.TASKS_START.Set(1)
|
||||||
|
nrf.RNG.SetCONFIG_DERCEN(nrf.RNG_CONFIG_DERCEN_Enabled)
|
||||||
|
rngStarted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// The RNG returns one byte at a time, so stack up four bytes into a single uint32 for return.
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
// Wait for data to be ready.
|
||||||
|
for nrf.RNG.EVENTS_VALRDY.Get() == 0 {
|
||||||
|
}
|
||||||
|
// Append random byte to output.
|
||||||
|
ret = (ret << 8) ^ nrf.RNG.GetVALUE()
|
||||||
|
// Unset the EVENTS_VALRDY register to avoid reading the same random output twice.
|
||||||
|
nrf.RNG.EVENTS_VALRDY.Set(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadTemperature reads the silicon die temperature of the chip. The return
|
||||||
|
// value is in milli-celsius.
|
||||||
|
func ReadTemperature() int32 {
|
||||||
|
nrf.TEMP.TASKS_START.Set(1)
|
||||||
|
for nrf.TEMP.EVENTS_DATARDY.Get() == 0 {
|
||||||
|
}
|
||||||
|
temp := int32(nrf.TEMP.TEMP.Get()) * 250 // the returned value is in units of 0.25°C
|
||||||
|
nrf.TEMP.EVENTS_DATARDY.Set(0)
|
||||||
|
return temp
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,16 +9,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DFU_MAGIC_SERIAL_ONLY_RESET = 0x4e
|
dfuMagicSerialOnlyReset = 0x4e
|
||||||
DFU_MAGIC_UF2_RESET = 0x57
|
dfuMagicUF2Reset = 0x57
|
||||||
DFU_MAGIC_OTA_RESET = 0xA8
|
dfuMagicOTAReset = 0xA8
|
||||||
)
|
)
|
||||||
|
|
||||||
// EnterSerialBootloader resets the chip into the serial bootloader. After
|
// EnterSerialBootloader resets the chip into the serial bootloader. After
|
||||||
// reset, it can be flashed using serial/nrfutil.
|
// reset, it can be flashed using serial/nrfutil.
|
||||||
func EnterSerialBootloader() {
|
func EnterSerialBootloader() {
|
||||||
arm.DisableInterrupts()
|
arm.DisableInterrupts()
|
||||||
nrf.POWER.GPREGRET.Set(DFU_MAGIC_SERIAL_ONLY_RESET)
|
nrf.POWER.GPREGRET.Set(dfuMagicSerialOnlyReset)
|
||||||
arm.SystemReset()
|
arm.SystemReset()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ func EnterSerialBootloader() {
|
|||||||
// can be flashed via nrfutil or by copying a UF2 file to the mass storage device
|
// can be flashed via nrfutil or by copying a UF2 file to the mass storage device
|
||||||
func EnterUF2Bootloader() {
|
func EnterUF2Bootloader() {
|
||||||
arm.DisableInterrupts()
|
arm.DisableInterrupts()
|
||||||
nrf.POWER.GPREGRET.Set(DFU_MAGIC_UF2_RESET)
|
nrf.POWER.GPREGRET.Set(dfuMagicUF2Reset)
|
||||||
arm.SystemReset()
|
arm.SystemReset()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +34,6 @@ func EnterUF2Bootloader() {
|
|||||||
// flashed via an OTA update
|
// flashed via an OTA update
|
||||||
func EnterOTABootloader() {
|
func EnterOTABootloader() {
|
||||||
arm.DisableInterrupts()
|
arm.DisableInterrupts()
|
||||||
nrf.POWER.GPREGRET.Set(DFU_MAGIC_OTA_RESET)
|
nrf.POWER.GPREGRET.Set(dfuMagicOTAReset)
|
||||||
arm.SystemReset()
|
arm.SystemReset()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,13 +42,19 @@ const deviceName = nxp.Device
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
PinInput PinMode = iota
|
PinInput PinMode = iota
|
||||||
PinInputPullUp
|
PinInputPullup
|
||||||
PinInputPullDown
|
PinInputPulldown
|
||||||
PinOutput
|
PinOutput
|
||||||
PinOutputOpenDrain
|
PinOutputOpenDrain
|
||||||
PinDisable
|
PinDisable
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Deprecated: use PinInputPullup and PinInputPulldown instead.
|
||||||
|
const (
|
||||||
|
PinInputPullUp = PinInputPullup
|
||||||
|
PinInputPullDown = PinInputPulldown
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PA00 Pin = iota
|
PA00 Pin = iota
|
||||||
PA01
|
PA01
|
||||||
@@ -223,11 +229,11 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
gpio.PDDR.ClearBits(1 << pos)
|
gpio.PDDR.ClearBits(1 << pos)
|
||||||
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos))
|
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos))
|
||||||
|
|
||||||
case PinInputPullUp:
|
case PinInputPullup:
|
||||||
gpio.PDDR.ClearBits(1 << pos)
|
gpio.PDDR.ClearBits(1 << pos)
|
||||||
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE | nxp.PORT_PCR0_PS)
|
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE | nxp.PORT_PCR0_PS)
|
||||||
|
|
||||||
case PinInputPullDown:
|
case PinInputPulldown:
|
||||||
gpio.PDDR.ClearBits(1 << pos)
|
gpio.PDDR.ClearBits(1 << pos)
|
||||||
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE)
|
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE)
|
||||||
|
|
||||||
|
|||||||
@@ -203,8 +203,8 @@ func (u *UART) Disable() {
|
|||||||
u.C2.Set(0)
|
u.C2.Set(0)
|
||||||
|
|
||||||
// reconfigure pin
|
// reconfigure pin
|
||||||
u.DefaultRX.Configure(PinConfig{Mode: PinInputPullUp})
|
u.DefaultRX.Configure(PinConfig{Mode: PinInputPullup})
|
||||||
u.DefaultTX.Configure(PinConfig{Mode: PinInputPullUp})
|
u.DefaultTX.Configure(PinConfig{Mode: PinInputPullup})
|
||||||
|
|
||||||
// clear flags
|
// clear flags
|
||||||
u.S1.Get()
|
u.S1.Get()
|
||||||
|
|||||||
@@ -11,36 +11,36 @@ const deviceName = rp.Device
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// GPIO pins
|
// GPIO pins
|
||||||
GPIO0 Pin = 0
|
GPIO0 Pin = 0 // peripherals: PWM0 channel A
|
||||||
GPIO1 Pin = 1
|
GPIO1 Pin = 1 // peripherals: PWM0 channel B
|
||||||
GPIO2 Pin = 2
|
GPIO2 Pin = 2 // peripherals: PWM1 channel A
|
||||||
GPIO3 Pin = 3
|
GPIO3 Pin = 3 // peripherals: PWM1 channel B
|
||||||
GPIO4 Pin = 4
|
GPIO4 Pin = 4 // peripherals: PWM2 channel A
|
||||||
GPIO5 Pin = 5
|
GPIO5 Pin = 5 // peripherals: PWM2 channel B
|
||||||
GPIO6 Pin = 6
|
GPIO6 Pin = 6 // peripherals: PWM3 channel A
|
||||||
GPIO7 Pin = 7
|
GPIO7 Pin = 7 // peripherals: PWM3 channel B
|
||||||
GPIO8 Pin = 8
|
GPIO8 Pin = 8 // peripherals: PWM4 channel A
|
||||||
GPIO9 Pin = 9
|
GPIO9 Pin = 9 // peripherals: PWM4 channel B
|
||||||
GPIO10 Pin = 10
|
GPIO10 Pin = 10 // peripherals: PWM5 channel A
|
||||||
GPIO11 Pin = 11
|
GPIO11 Pin = 11 // peripherals: PWM5 channel B
|
||||||
GPIO12 Pin = 12
|
GPIO12 Pin = 12 // peripherals: PWM6 channel A
|
||||||
GPIO13 Pin = 13
|
GPIO13 Pin = 13 // peripherals: PWM6 channel B
|
||||||
GPIO14 Pin = 14
|
GPIO14 Pin = 14 // peripherals: PWM7 channel A
|
||||||
GPIO15 Pin = 15
|
GPIO15 Pin = 15 // peripherals: PWM7 channel B
|
||||||
GPIO16 Pin = 16
|
GPIO16 Pin = 16 // peripherals: PWM0 channel A
|
||||||
GPIO17 Pin = 17
|
GPIO17 Pin = 17 // peripherals: PWM0 channel B
|
||||||
GPIO18 Pin = 18
|
GPIO18 Pin = 18 // peripherals: PWM1 channel A
|
||||||
GPIO19 Pin = 19
|
GPIO19 Pin = 19 // peripherals: PWM1 channel B
|
||||||
GPIO20 Pin = 20
|
GPIO20 Pin = 20 // peripherals: PWM2 channel A
|
||||||
GPIO21 Pin = 21
|
GPIO21 Pin = 21 // peripherals: PWM2 channel B
|
||||||
GPIO22 Pin = 22
|
GPIO22 Pin = 22 // peripherals: PWM3 channel A
|
||||||
GPIO23 Pin = 23
|
GPIO23 Pin = 23 // peripherals: PWM3 channel B
|
||||||
GPIO24 Pin = 24
|
GPIO24 Pin = 24 // peripherals: PWM4 channel A
|
||||||
GPIO25 Pin = 25
|
GPIO25 Pin = 25 // peripherals: PWM4 channel B
|
||||||
GPIO26 Pin = 26
|
GPIO26 Pin = 26 // peripherals: PWM5 channel A
|
||||||
GPIO27 Pin = 27
|
GPIO27 Pin = 27 // peripherals: PWM5 channel B
|
||||||
GPIO28 Pin = 28
|
GPIO28 Pin = 28 // peripherals: PWM6 channel A
|
||||||
GPIO29 Pin = 29
|
GPIO29 Pin = 29 // peripherals: PWM6 channel B
|
||||||
|
|
||||||
// Analog pins
|
// Analog pins
|
||||||
ADC0 Pin = GPIO26
|
ADC0 Pin = GPIO26
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ const (
|
|||||||
adc0_CH ADCChannel = iota
|
adc0_CH ADCChannel = iota
|
||||||
adc1_CH
|
adc1_CH
|
||||||
adc2_CH
|
adc2_CH
|
||||||
adc3_CH // Note: GPIO29 not broken out on pico board
|
adc3_CH // Note: GPIO29 not broken out on pico board
|
||||||
ADC_TEMP_SENSOR // Internal temperature sensor channel
|
adcTempSensor // Internal temperature sensor channel
|
||||||
)
|
)
|
||||||
|
|
||||||
// Used to serialise ADC sampling
|
// Used to serialise ADC sampling
|
||||||
@@ -75,19 +75,17 @@ func (a ADC) GetADCChannel() (c ADCChannel, err error) {
|
|||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure sets the channel's associated pin to analog input mode or powers on the temperature sensor for ADC_TEMP_SENSOR.
|
// Configure sets the channel's associated pin to analog input mode.
|
||||||
// The powered on temperature sensor increases ADC_AVDD current by approximately 40 μA.
|
// The powered on temperature sensor increases ADC_AVDD current by approximately 40 μA.
|
||||||
func (c ADCChannel) Configure(config ADCConfig) error {
|
func (c ADCChannel) Configure(config ADCConfig) error {
|
||||||
if config.Reference != 0 {
|
if config.Reference != 0 {
|
||||||
adcAref = config.Reference
|
adcAref = config.Reference
|
||||||
}
|
}
|
||||||
if p, err := c.Pin(); err == nil {
|
p, err := c.Pin()
|
||||||
p.Configure(PinConfig{Mode: PinAnalog})
|
if err != nil {
|
||||||
}
|
return err
|
||||||
if c == ADC_TEMP_SENSOR {
|
|
||||||
// Enable temperature sensor bias source
|
|
||||||
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
|
||||||
}
|
}
|
||||||
|
p.Configure(PinConfig{Mode: pinAnalog})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,13 +110,16 @@ func (c ADCChannel) getVoltage() uint32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReadTemperature does a one-shot sample of the internal temperature sensor and returns a milli-celsius reading.
|
// ReadTemperature does a one-shot sample of the internal temperature sensor and returns a milli-celsius reading.
|
||||||
// Only works on the ADC_TEMP_SENSOR channel. aka AINSEL=4. Other channels will return 0
|
func ReadTemperature() (millicelsius int32) {
|
||||||
func (c ADCChannel) ReadTemperature() (millicelsius uint32) {
|
if rp.ADC.CS.Get()&rp.ADC_CS_EN == 0 {
|
||||||
if c != ADC_TEMP_SENSOR {
|
InitADC()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable temperature sensor bias source
|
||||||
|
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
||||||
|
|
||||||
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
||||||
return (27000<<16 - (c.getVoltage()-706<<16)*581) >> 16
|
return (27000<<16 - (int32(adcTempSensor.getVoltage())-706<<16)*581) >> 16
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForReady spins waiting for the ADC peripheral to become ready.
|
// waitForReady spins waiting for the ADC peripheral to become ready.
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
KHz = 1000
|
|
||||||
MHz = 1000000
|
|
||||||
)
|
|
||||||
|
|
||||||
func CPUFrequency() uint32 {
|
func CPUFrequency() uint32 {
|
||||||
return 125 * MHz
|
return 125 * MHz
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,11 +81,13 @@ const (
|
|||||||
PinInput
|
PinInput
|
||||||
PinInputPulldown
|
PinInputPulldown
|
||||||
PinInputPullup
|
PinInputPullup
|
||||||
PinAnalog
|
|
||||||
PinUART
|
// internal pin modes
|
||||||
PinPWM
|
pinAnalog
|
||||||
PinI2C
|
pinUART
|
||||||
PinSPI
|
pinPWM
|
||||||
|
pinI2C
|
||||||
|
pinSPI
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p Pin) PortMaskSet() (*uint32, uint32) {
|
func (p Pin) PortMaskSet() (*uint32, uint32) {
|
||||||
@@ -188,20 +190,20 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
case PinInputPullup:
|
case PinInputPullup:
|
||||||
p.setFunc(fnSIO)
|
p.setFunc(fnSIO)
|
||||||
p.pullup()
|
p.pullup()
|
||||||
case PinAnalog:
|
case pinAnalog:
|
||||||
p.setFunc(fnNULL)
|
p.setFunc(fnNULL)
|
||||||
p.pulloff()
|
p.pulloff()
|
||||||
case PinUART:
|
case pinUART:
|
||||||
p.setFunc(fnUART)
|
p.setFunc(fnUART)
|
||||||
case PinPWM:
|
case pinPWM:
|
||||||
p.setFunc(fnPWM)
|
p.setFunc(fnPWM)
|
||||||
case PinI2C:
|
case pinI2C:
|
||||||
// IO config according to 4.3.1.3 of rp2040 datasheet.
|
// IO config according to 4.3.1.3 of rp2040 datasheet.
|
||||||
p.setFunc(fnI2C)
|
p.setFunc(fnI2C)
|
||||||
p.pullup()
|
p.pullup()
|
||||||
p.setSchmitt(true)
|
p.setSchmitt(true)
|
||||||
p.setSlew(false)
|
p.setSlew(false)
|
||||||
case PinSPI:
|
case pinSPI:
|
||||||
p.setFunc(fnSPI)
|
p.setFunc(fnSPI)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,12 +228,8 @@ type PinChange uint8
|
|||||||
|
|
||||||
// Pin change interrupt constants for SetInterrupt.
|
// Pin change interrupt constants for SetInterrupt.
|
||||||
const (
|
const (
|
||||||
// PinLevelLow triggers whenever pin is at a low (around 0V) logic level.
|
|
||||||
PinLevelLow PinChange = 1 << iota
|
|
||||||
// PinLevelLow triggers whenever pin is at a high (around 3V) logic level.
|
|
||||||
PinLevelHigh
|
|
||||||
// Edge falling
|
// Edge falling
|
||||||
PinFalling
|
PinFalling PinChange = 4 << iota
|
||||||
// Edge rising
|
// Edge rising
|
||||||
PinRising
|
PinRising
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -105,8 +105,8 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
|||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = defaultBaud
|
config.Frequency = defaultBaud
|
||||||
}
|
}
|
||||||
config.SDA.Configure(PinConfig{PinI2C})
|
config.SDA.Configure(PinConfig{pinI2C})
|
||||||
config.SCL.Configure(PinConfig{PinI2C})
|
config.SCL.Configure(PinConfig{pinI2C})
|
||||||
return i2c.init(config)
|
return i2c.init(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ func (pwm *pwmGroup) Channel(pin Pin) (channel uint8, err error) {
|
|||||||
if pin > maxPWMPins || pwmGPIOToSlice(pin) != pwm.peripheral() {
|
if pin > maxPWMPins || pwmGPIOToSlice(pin) != pwm.peripheral() {
|
||||||
return 3, ErrInvalidOutputPin
|
return 3, ErrInvalidOutputPin
|
||||||
}
|
}
|
||||||
pin.Configure(PinConfig{PinPWM})
|
pin.Configure(PinConfig{pinPWM})
|
||||||
return pwmGPIOToChannel(pin), nil
|
return pwmGPIOToChannel(pin), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
//go:build rp2040
|
||||||
|
// +build rp2040
|
||||||
|
|
||||||
|
// Implementation based on code located here:
|
||||||
|
// https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_lwip/random.c
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/rp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const numberOfCycles = 32
|
||||||
|
|
||||||
|
// GetRNG returns 32 bits of semi-random data based on ring oscillator.
|
||||||
|
//
|
||||||
|
// Unlike some other implementations of GetRNG, these random numbers are not
|
||||||
|
// cryptographically secure and must not be used for cryptographic operations
|
||||||
|
// (nonces, etc).
|
||||||
|
func GetRNG() (uint32, error) {
|
||||||
|
var val uint32
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
val = (val << 8) | uint32(roscRandByte())
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var randomByte uint8
|
||||||
|
|
||||||
|
func roscRandByte() uint8 {
|
||||||
|
var poly uint8
|
||||||
|
for i := 0; i < numberOfCycles; i++ {
|
||||||
|
if randomByte&0x80 != 0 {
|
||||||
|
poly = 0x35
|
||||||
|
} else {
|
||||||
|
poly = 0
|
||||||
|
}
|
||||||
|
randomByte = ((randomByte << 1) | uint8(rp.ROSC.GetRANDOMBIT()) ^ poly)
|
||||||
|
// TODO: delay a little because the random bit is a little slow
|
||||||
|
}
|
||||||
|
return randomByte
|
||||||
|
}
|
||||||
@@ -38,10 +38,9 @@ type SPIConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrLSBNotSupported = errors.New("SPI LSB unsupported on PL022")
|
ErrLSBNotSupported = errors.New("SPI LSB unsupported on PL022")
|
||||||
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
|
ErrSPITimeout = errors.New("SPI timeout")
|
||||||
ErrSPITimeout = errors.New("SPI timeout")
|
ErrSPIBaud = errors.New("SPI baud too low or above 66.5Mhz")
|
||||||
ErrSPIBaud = errors.New("SPI baud too low or above 66.5Mhz")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SPI struct {
|
type SPI struct {
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ func (uart *UART) Configure(config UARTConfig) error {
|
|||||||
rp.UART0_UARTCR_TXE)
|
rp.UART0_UARTCR_TXE)
|
||||||
|
|
||||||
// set GPIO mux to UART for the pins
|
// set GPIO mux to UART for the pins
|
||||||
config.TX.Configure(PinConfig{Mode: PinUART})
|
config.TX.Configure(PinConfig{Mode: pinUART})
|
||||||
config.RX.Configure(PinConfig{Mode: PinUART})
|
config.RX.Configure(PinConfig{Mode: pinUART})
|
||||||
|
|
||||||
// Enable RX IRQ.
|
// Enable RX IRQ.
|
||||||
uart.Interrupt.SetPriority(0x80)
|
uart.Interrupt.SetPriority(0x80)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func InitADC() {
|
|||||||
|
|
||||||
// Configure configures an ADC pin to be able to read analog data.
|
// Configure configures an ADC pin to be able to read analog data.
|
||||||
func (a ADC) Configure(ADCConfig) {
|
func (a ADC) Configure(ADCConfig) {
|
||||||
a.Pin.Configure(PinConfig{Mode: PinInputModeAnalog})
|
a.Pin.Configure(PinConfig{Mode: pinInputModeAnalog})
|
||||||
|
|
||||||
// set sample time
|
// set sample time
|
||||||
ch := a.getChannel()
|
ch := a.getChannel()
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ func InitADC() {
|
|||||||
|
|
||||||
// Configure configures an ADC pin to be able to read analog data.
|
// Configure configures an ADC pin to be able to read analog data.
|
||||||
func (a ADC) Configure(ADCConfig) {
|
func (a ADC) Configure(ADCConfig) {
|
||||||
a.Pin.ConfigureAltFunc(PinConfig{Mode: PinInputAnalog}, 0)
|
a.Pin.ConfigureAltFunc(PinConfig{Mode: pinInputAnalog}, 0)
|
||||||
|
|
||||||
// set sample time
|
// set sample time
|
||||||
ch := a.getChannel()
|
ch := a.getChannel()
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
|||||||
|
|
||||||
// default to 100 kHz (Sm, standard mode) if no frequency is set
|
// default to 100 kHz (Sm, standard mode) if no frequency is set
|
||||||
if config.Frequency == 0 {
|
if config.Frequency == 0 {
|
||||||
config.Frequency = TWI_FREQ_100KHZ
|
config.Frequency = 100 * KHz
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure I2C input clock
|
// configure I2C input clock
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i2c *I2C) configurePins(config I2CConfig) {
|
func (i2c *I2C) configurePins(config I2CConfig) {
|
||||||
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector)
|
config.SCL.ConfigureAltFunc(PinConfig{Mode: pinModeI2CSCL}, i2c.AltFuncSelector)
|
||||||
config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector)
|
config.SDA.ConfigureAltFunc(PinConfig{Mode: pinModeI2CSDA}, i2c.AltFuncSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i2c *I2C) controllerTransmit(addr uint16, w []byte) error {
|
func (i2c *I2C) controllerTransmit(addr uint16, w []byte) error {
|
||||||
|
|||||||
@@ -14,29 +14,28 @@ import (
|
|||||||
const (
|
const (
|
||||||
// Mode Flag
|
// Mode Flag
|
||||||
PinOutput PinMode = 0
|
PinOutput PinMode = 0
|
||||||
PinInput PinMode = PinInputFloating
|
PinInput PinMode = 1
|
||||||
PinInputFloating PinMode = 1
|
|
||||||
PinInputPulldown PinMode = 2
|
PinInputPulldown PinMode = 2
|
||||||
PinInputPullup PinMode = 3
|
PinInputPullup PinMode = 3
|
||||||
|
|
||||||
// for UART
|
// for UART
|
||||||
PinModeUARTTX PinMode = 4
|
pinModeUARTTX PinMode = 4
|
||||||
PinModeUARTRX PinMode = 5
|
pinModeUARTRX PinMode = 5
|
||||||
|
|
||||||
// for I2C
|
// for I2C
|
||||||
PinModeI2CSCL PinMode = 6
|
pinModeI2CSCL PinMode = 6
|
||||||
PinModeI2CSDA PinMode = 7
|
pinModeI2CSDA PinMode = 7
|
||||||
|
|
||||||
// for SPI
|
// for SPI
|
||||||
PinModeSPICLK PinMode = 8
|
pinModeSPICLK PinMode = 8
|
||||||
PinModeSPISDO PinMode = 9
|
pinModeSPISDO PinMode = 9
|
||||||
PinModeSPISDI PinMode = 10
|
pinModeSPISDI PinMode = 10
|
||||||
|
|
||||||
// for analog/ADC
|
// for analog/ADC
|
||||||
PinInputAnalog PinMode = 11
|
pinInputAnalog PinMode = 11
|
||||||
|
|
||||||
// for PWM
|
// for PWM
|
||||||
PinModePWMOutput PinMode = 12
|
pinModePWMOutput PinMode = 12
|
||||||
)
|
)
|
||||||
|
|
||||||
// Define several bitfields that have different names across chip families but
|
// Define several bitfields that have different names across chip families but
|
||||||
@@ -83,7 +82,7 @@ func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) {
|
|||||||
switch config.Mode {
|
switch config.Mode {
|
||||||
|
|
||||||
// GPIO
|
// GPIO
|
||||||
case PinInputFloating:
|
case PinInput:
|
||||||
port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeInput, gpioModeMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||||
case PinInputPulldown:
|
case PinInputPulldown:
|
||||||
@@ -97,24 +96,24 @@ func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) {
|
|||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
||||||
|
|
||||||
// UART
|
// UART
|
||||||
case PinModeUARTTX:
|
case pinModeUARTTX:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
|
||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
case PinModeUARTRX:
|
case pinModeUARTRX:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
|
|
||||||
// I2C
|
// I2C
|
||||||
case PinModeI2CSCL:
|
case pinModeI2CSCL:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
|
port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
|
||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullUp, gpioPullMask, pos)
|
||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
case PinModeI2CSDA:
|
case pinModeI2CSDA:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
|
port.OTYPER.ReplaceBits(stm32.GPIO_OTYPER_OT0_OpenDrain, stm32.GPIO_OTYPER_OT0_Msk, pos/2)
|
||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||||
@@ -122,31 +121,31 @@ func (p Pin) ConfigureAltFunc(config PinConfig, altFunc uint8) {
|
|||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
|
|
||||||
// SPI
|
// SPI
|
||||||
case PinModeSPICLK:
|
case pinModeSPICLK:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
case PinModeSPISDO:
|
case pinModeSPISDO:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
case PinModeSPISDI:
|
case pinModeSPISDI:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedLow, gpioOutputSpeedMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
|
|
||||||
// PWM
|
// PWM
|
||||||
case PinModePWMOutput:
|
case pinModePWMOutput:
|
||||||
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAlternate, gpioModeMask, pos)
|
||||||
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
port.OSPEEDR.ReplaceBits(gpioOutputSpeedHigh, gpioOutputSpeedMask, pos)
|
||||||
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
port.PUPDR.ReplaceBits(gpioPullFloating, gpioPullMask, pos)
|
||||||
p.SetAltFunc(altFunc)
|
p.SetAltFunc(altFunc)
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
case PinInputAnalog:
|
case pinInputAnalog:
|
||||||
port.MODER.ReplaceBits(gpioModeAnalog, gpioModeMask, pos)
|
port.MODER.ReplaceBits(gpioModeAnalog, gpioModeMask, pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ func (t *TIM) Channel(pin Pin) (uint8, error) {
|
|||||||
for _, p := range ch.Pins {
|
for _, p := range ch.Pins {
|
||||||
if p.Pin == pin {
|
if p.Pin == pin {
|
||||||
t.configurePin(uint8(chi), p)
|
t.configurePin(uint8(chi), p)
|
||||||
//p.Pin.ConfigureAltFunc(PinConfig{Mode: PinModePWMOutput}, p.AltFunc)
|
//p.Pin.ConfigureAltFunc(PinConfig{Mode: pinModePWMOutput}, p.AltFunc)
|
||||||
return uint8(chi), nil
|
return uint8(chi), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ package machine
|
|||||||
// register (most MCUs except STM32F1 series).
|
// register (most MCUs except STM32F1 series).
|
||||||
|
|
||||||
func (t *TIM) configurePin(channel uint8, pf PinFunction) {
|
func (t *TIM) configurePin(channel uint8, pf PinFunction) {
|
||||||
pf.Pin.ConfigureAltFunc(PinConfig{Mode: PinModePWMOutput}, pf.AltFunc)
|
pf.Pin.ConfigureAltFunc(PinConfig{Mode: pinModePWMOutput}, pf.AltFunc)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,20 +29,20 @@ const (
|
|||||||
PinOutput50MHz PinMode = 3 // Output mode, max speed 50MHz
|
PinOutput50MHz PinMode = 3 // Output mode, max speed 50MHz
|
||||||
PinOutput PinMode = PinOutput2MHz
|
PinOutput PinMode = PinOutput2MHz
|
||||||
|
|
||||||
PinInputModeAnalog PinMode = 0 // Input analog mode
|
pinInputModeAnalog PinMode = 0 // Input analog mode
|
||||||
PinInputModeFloating PinMode = 4 // Input floating mode
|
pinInputModeFloating PinMode = 4 // Input floating mode
|
||||||
PinInputModePullUpDown PinMode = 8 // Input pull up/down mode
|
pinInputModePullUpDown PinMode = 8 // Input pull up/down mode
|
||||||
PinInputModeReserved PinMode = 12 // Input mode (reserved)
|
pinInputModeReserved PinMode = 12 // Input mode (reserved)
|
||||||
|
|
||||||
PinOutputModeGPPushPull PinMode = 0 // Output mode general purpose push/pull
|
pinOutputModeGPPushPull PinMode = 0 // Output mode general purpose push/pull
|
||||||
PinOutputModeGPOpenDrain PinMode = 4 // Output mode general purpose open drain
|
pinOutputModeGPOpenDrain PinMode = 4 // Output mode general purpose open drain
|
||||||
PinOutputModeAltPushPull PinMode = 8 // Output mode alt. purpose push/pull
|
pinOutputModeAltPushPull PinMode = 8 // Output mode alt. purpose push/pull
|
||||||
PinOutputModeAltOpenDrain PinMode = 12 // Output mode alt. purpose open drain
|
pinOutputModeAltOpenDrain PinMode = 12 // Output mode alt. purpose open drain
|
||||||
|
|
||||||
// Pull-up vs Pull down is not part of the CNF0 / CNF1 bits, but is
|
// Pull-up vs Pull down is not part of the CNF0 / CNF1 bits, but is
|
||||||
// controlled by PxODR. Encoded using the 'spare' bit 5.
|
// controlled by PxODR. Encoded using the 'spare' bit 5.
|
||||||
PinInputPulldown PinMode = PinInputModePullUpDown
|
PinInputPulldown PinMode = pinInputModePullUpDown
|
||||||
PinInputPullup PinMode = PinInputModePullUpDown | 0x10
|
PinInputPullup PinMode = pinInputModePullUpDown | 0x10
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pin constants for all stm32f103 package sizes
|
// Pin constants for all stm32f103 package sizes
|
||||||
@@ -166,7 +166,7 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
|
|
||||||
// If configured for input pull-up or pull-down, set ODR
|
// If configured for input pull-up or pull-down, set ODR
|
||||||
// for desired pull-up or pull-down.
|
// for desired pull-up or pull-down.
|
||||||
if (config.Mode & 0xf) == PinInputModePullUpDown {
|
if (config.Mode & 0xf) == pinInputModePullUpDown {
|
||||||
var pullup uint32
|
var pullup uint32
|
||||||
if config.Mode == PinInputPullup {
|
if config.Mode == PinInputPullup {
|
||||||
pullup = 1
|
pullup = 1
|
||||||
@@ -290,8 +290,8 @@ func (uart *UART) configurePins(config UARTConfig) {
|
|||||||
default:
|
default:
|
||||||
// use standard TX/RX pins PA9 and PA10
|
// use standard TX/RX pins PA9 and PA10
|
||||||
}
|
}
|
||||||
config.TX.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
|
config.TX.Configure(PinConfig{Mode: PinOutput50MHz + pinOutputModeAltPushPull})
|
||||||
config.RX.Configure(PinConfig{Mode: PinInputModeFloating})
|
config.RX.Configure(PinConfig{Mode: pinInputModeFloating})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the divisor for USARTs to get the given baudrate
|
// Determine the divisor for USARTs to get the given baudrate
|
||||||
@@ -363,9 +363,9 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
|||||||
|
|
||||||
// Configure SPI pins for input output and clock
|
// Configure SPI pins for input output and clock
|
||||||
func (spi SPI) configurePins(config SPIConfig) {
|
func (spi SPI) configurePins(config SPIConfig) {
|
||||||
config.SCK.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
|
config.SCK.Configure(PinConfig{Mode: PinOutput50MHz + pinOutputModeAltPushPull})
|
||||||
config.SDO.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltPushPull})
|
config.SDO.Configure(PinConfig{Mode: PinOutput50MHz + pinOutputModeAltPushPull})
|
||||||
config.SDI.Configure(PinConfig{Mode: PinInputModeFloating})
|
config.SDI.Configure(PinConfig{Mode: pinInputModeFloating})
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------- I2C related types and code
|
//---------- I2C related types and code
|
||||||
@@ -390,8 +390,8 @@ func (i2c *I2C) configurePins(config I2CConfig) {
|
|||||||
stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_I2C1_REMAP)
|
stm32.AFIO.MAPR.SetBits(stm32.AFIO_MAPR_I2C1_REMAP)
|
||||||
}
|
}
|
||||||
|
|
||||||
config.SDA.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltOpenDrain})
|
config.SDA.Configure(PinConfig{Mode: PinOutput50MHz + pinOutputModeAltOpenDrain})
|
||||||
config.SCL.Configure(PinConfig{Mode: PinOutput50MHz + PinOutputModeAltOpenDrain})
|
config.SCL.Configure(PinConfig{Mode: PinOutput50MHz + pinOutputModeAltOpenDrain})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
|
func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
|
||||||
@@ -717,7 +717,7 @@ func (t *TIM) configurePin(channel uint8, pf PinFunction) {
|
|||||||
stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR2_TIM14_REMAP_Pos, stm32.AFIO_MAPR2_TIM14_REMAP_Msk, 0)
|
stm32.AFIO.MAPR.ReplaceBits(remap<<stm32.AFIO_MAPR2_TIM14_REMAP_Pos, stm32.AFIO_MAPR2_TIM14_REMAP_Msk, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pf.Pin.Configure(PinConfig{Mode: PinOutput + PinOutputModeAltPushPull})
|
pf.Pin.Configure(PinConfig{Mode: PinOutput + pinOutputModeAltPushPull})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TIM) enableMainOutput() {
|
func (t *TIM) enableMainOutput() {
|
||||||
|
|||||||
@@ -640,8 +640,8 @@ const (
|
|||||||
|
|
||||||
func (uart *UART) configurePins(config UARTConfig) {
|
func (uart *UART) configurePins(config UARTConfig) {
|
||||||
// enable the alternate functions on the TX and RX pins
|
// enable the alternate functions on the TX and RX pins
|
||||||
config.TX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTTX}, uart.TxAltFuncSelector)
|
config.TX.ConfigureAltFunc(PinConfig{Mode: pinModeUARTTX}, uart.TxAltFuncSelector)
|
||||||
config.RX.ConfigureAltFunc(PinConfig{Mode: PinModeUARTRX}, uart.RxAltFuncSelector)
|
config.RX.ConfigureAltFunc(PinConfig{Mode: pinModeUARTRX}, uart.RxAltFuncSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 {
|
func (uart *UART) getBaudRateDivisor(baudRate uint32) uint32 {
|
||||||
@@ -674,9 +674,9 @@ func (spi SPI) config8Bits() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (spi SPI) configurePins(config SPIConfig) {
|
func (spi SPI) configurePins(config SPIConfig) {
|
||||||
config.SCK.ConfigureAltFunc(PinConfig{Mode: PinModeSPICLK}, spi.AltFuncSelector)
|
config.SCK.ConfigureAltFunc(PinConfig{Mode: pinModeSPICLK}, spi.AltFuncSelector)
|
||||||
config.SDO.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDO}, spi.AltFuncSelector)
|
config.SDO.ConfigureAltFunc(PinConfig{Mode: pinModeSPISDO}, spi.AltFuncSelector)
|
||||||
config.SDI.ConfigureAltFunc(PinConfig{Mode: PinModeSPISDI}, spi.AltFuncSelector)
|
config.SDI.ConfigureAltFunc(PinConfig{Mode: pinModeSPISDI}, spi.AltFuncSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
func (spi SPI) getBaudRate(config SPIConfig) uint32 {
|
||||||
@@ -723,8 +723,8 @@ type I2C struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i2c *I2C) configurePins(config I2CConfig) {
|
func (i2c *I2C) configurePins(config I2CConfig) {
|
||||||
config.SCL.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSCL}, i2c.AltFuncSelector)
|
config.SCL.ConfigureAltFunc(PinConfig{Mode: pinModeI2CSCL}, i2c.AltFuncSelector)
|
||||||
config.SDA.ConfigureAltFunc(PinConfig{Mode: PinModeI2CSDA}, i2c.AltFuncSelector)
|
config.SDA.ConfigureAltFunc(PinConfig{Mode: pinModeI2CSDA}, i2c.AltFuncSelector)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
|
func (i2c *I2C) getFreqRange(config I2CConfig) uint32 {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user