mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 04:23:41 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 22b5b69cf0 |
+60
-41
@@ -163,17 +163,20 @@ commands:
|
|||||||
command: |
|
command: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install --no-install-recommends \
|
sudo apt-get install --no-install-recommends \
|
||||||
|
libgnutls30 libssl1.0.2 \
|
||||||
qemu-system-arm \
|
qemu-system-arm \
|
||||||
qemu-system-riscv32 \
|
|
||||||
qemu-user \
|
qemu-user \
|
||||||
gcc-avr \
|
gcc-avr \
|
||||||
avr-libc \
|
avr-libc \
|
||||||
ninja-build \
|
ninja-build \
|
||||||
python3
|
python3
|
||||||
- install-node
|
- install-node
|
||||||
|
- install-chrome
|
||||||
- install-wasmtime
|
- install-wasmtime
|
||||||
- install-cmake
|
- install-cmake
|
||||||
- hack-ninja-jobs
|
- hack-ninja-jobs
|
||||||
|
- install-xtensa-toolchain:
|
||||||
|
variant: "linux-amd64"
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
keys:
|
keys:
|
||||||
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
|
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
|
||||||
@@ -198,7 +201,12 @@ commands:
|
|||||||
key: llvm-build-11-linux-v4-assert
|
key: llvm-build-11-linux-v4-assert
|
||||||
paths:
|
paths:
|
||||||
llvm-build
|
llvm-build
|
||||||
- build-binaryen-linux
|
- build-binaryen-linux-stretch
|
||||||
|
- run:
|
||||||
|
name: "Build TinyGo"
|
||||||
|
command: |
|
||||||
|
make ASSERT=1
|
||||||
|
echo 'export PATH=$(pwd)/build:$PATH' >> $BASH_ENV
|
||||||
- build-wasi-libc
|
- build-wasi-libc
|
||||||
- run:
|
- run:
|
||||||
name: "Test TinyGo"
|
name: "Test TinyGo"
|
||||||
@@ -209,63 +217,73 @@ commands:
|
|||||||
# necessary to keep memory consumption down and avoid OOM (for a
|
# necessary to keep memory consumption down and avoid OOM (for a
|
||||||
# 2CPU/4GB executor).
|
# 2CPU/4GB executor).
|
||||||
GOFLAGS: -p=2
|
GOFLAGS: -p=2
|
||||||
- run:
|
|
||||||
name: "Build TinyGo"
|
|
||||||
command: |
|
|
||||||
make ASSERT=1
|
|
||||||
echo 'export PATH=$(pwd)/build:$PATH' >> $BASH_ENV
|
|
||||||
- run: make tinygo-test
|
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
|
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
|
||||||
paths:
|
paths:
|
||||||
- ~/.cache/go-build
|
- ~/.cache/go-build
|
||||||
- /go/pkg/mod
|
- /go/pkg/mod
|
||||||
- install-xtensa-toolchain:
|
|
||||||
variant: "linux-amd64"
|
|
||||||
- run: make gen-device -j4
|
- run: make gen-device -j4
|
||||||
- run: make smoketest
|
- run: make smoketest
|
||||||
- install-chrome
|
- run: make tinygo-test
|
||||||
- run: make wasmtest
|
- run: make wasmtest
|
||||||
build-linux:
|
build-linux:
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
|
||||||
- submodules
|
|
||||||
- run:
|
- run:
|
||||||
name: "Install apt dependencies"
|
name: "Install apk dependencies"
|
||||||
command: |
|
command: |
|
||||||
sudo apt-get update
|
apk add git openssh make g++ gcompat
|
||||||
sudo apt-get install --no-install-recommends \
|
- checkout
|
||||||
libgnutls30 libssl1.0.2 \
|
- run:
|
||||||
ninja-build \
|
name: "Install Go"
|
||||||
python3
|
command: |
|
||||||
- install-cmake
|
wget https://dl.google.com/go/go1.17.3.linux-amd64.tar.gz
|
||||||
- hack-ninja-jobs
|
tar -C /usr/local -xzf go1.17.3.linux-amd64.tar.gz
|
||||||
|
ln -s /usr/local/go/bin/go /usr/local/bin/go
|
||||||
|
#- submodules
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
|
name: "Restore Go cache"
|
||||||
keys:
|
keys:
|
||||||
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
|
- go-cache-alpine-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
|
||||||
- go-cache-v2-{{ checksum "go.mod" }}
|
- go-cache-alpine-v2-{{ checksum "go.mod" }}
|
||||||
- llvm-source-linux
|
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
|
name: "Restore llvm-source cache"
|
||||||
keys:
|
keys:
|
||||||
- llvm-build-11-linux-v4-noassert
|
- llvm-source-11-alpine-v2-x0
|
||||||
|
- run:
|
||||||
|
name: "Fetch LLVM source"
|
||||||
|
command: make llvm-source
|
||||||
|
- save_cache:
|
||||||
|
name: "Save llvm-source cache"
|
||||||
|
key: llvm-source-11-alpine-v2-x0
|
||||||
|
paths:
|
||||||
|
- llvm-project
|
||||||
|
#- llvm-project/clang/lib/Headers
|
||||||
|
#- llvm-project/clang/include
|
||||||
|
#- llvm-project/lld/include
|
||||||
|
#- llvm-project/llvm/include
|
||||||
|
- restore_cache:
|
||||||
|
name: "Restore llvm-build cache"
|
||||||
|
keys:
|
||||||
|
- llvm-build-11-alpine-v1-noassert-x0
|
||||||
- run:
|
- run:
|
||||||
name: "Build LLVM"
|
name: "Build LLVM"
|
||||||
command: |
|
command: |
|
||||||
if [ ! -f llvm-build/lib/liblldELF.a ]
|
if [ ! -f llvm-build/lib/liblldELF.a ]
|
||||||
then
|
then
|
||||||
# fetch LLVM source (may only have headers right now)
|
# fetch LLVM source (may only have headers right now)
|
||||||
rm -rf llvm-project
|
#rm -rf llvm-project
|
||||||
make llvm-source
|
#make llvm-source
|
||||||
|
# install dependencies
|
||||||
|
apk add cmake samurai python3
|
||||||
# build!
|
# build!
|
||||||
make llvm-build
|
SAMUFLAGS=-j3 make llvm-build
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
#find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
fi
|
fi
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: llvm-build-11-linux-v4-noassert
|
name: "Save llvm-build cache"
|
||||||
|
key: llvm-build-11-alpine-v1-noassert-x0
|
||||||
paths:
|
paths:
|
||||||
llvm-build
|
llvm-build
|
||||||
- build-binaryen-linux-stretch
|
|
||||||
- build-wasi-libc
|
|
||||||
- run:
|
- run:
|
||||||
name: "Install fpm"
|
name: "Install fpm"
|
||||||
command: |
|
command: |
|
||||||
@@ -286,7 +304,8 @@ commands:
|
|||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: /tmp/tinygo_amd64.deb
|
path: /tmp/tinygo_amd64.deb
|
||||||
- save_cache:
|
- save_cache:
|
||||||
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
|
name: "Save Go cache"
|
||||||
|
key: go-cache-alpine-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
|
||||||
paths:
|
paths:
|
||||||
- ~/.cache/go-build
|
- ~/.cache/go-build
|
||||||
- /go/pkg/mod
|
- /go/pkg/mod
|
||||||
@@ -323,7 +342,7 @@ commands:
|
|||||||
curl https://dl.google.com/go/go1.17.darwin-amd64.tar.gz -o go1.17.darwin-amd64.tar.gz
|
curl https://dl.google.com/go/go1.17.darwin-amd64.tar.gz -o go1.17.darwin-amd64.tar.gz
|
||||||
sudo tar -C /usr/local -xzf go1.17.darwin-amd64.tar.gz
|
sudo tar -C /usr/local -xzf go1.17.darwin-amd64.tar.gz
|
||||||
ln -s /usr/local/go/bin/go /usr/local/bin/go
|
ln -s /usr/local/go/bin/go /usr/local/bin/go
|
||||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake ninja
|
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu cmake ninja
|
||||||
- install-xtensa-toolchain:
|
- install-xtensa-toolchain:
|
||||||
variant: "macos"
|
variant: "macos"
|
||||||
- restore_cache:
|
- restore_cache:
|
||||||
@@ -388,7 +407,7 @@ commands:
|
|||||||
- lib/wasi-libc/sysroot
|
- lib/wasi-libc/sysroot
|
||||||
- run:
|
- run:
|
||||||
name: "Test TinyGo"
|
name: "Test TinyGo"
|
||||||
command: make test GOTESTFLAGS="-v -short"
|
command: make test
|
||||||
no_output_timeout: 20m
|
no_output_timeout: 20m
|
||||||
- run:
|
- run:
|
||||||
name: "Build TinyGo release"
|
name: "Build TinyGo release"
|
||||||
@@ -426,12 +445,12 @@ jobs:
|
|||||||
llvm: "11"
|
llvm: "11"
|
||||||
assert-test-linux:
|
assert-test-linux:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.17-buster
|
- image: circleci/golang:1.17-stretch
|
||||||
steps:
|
steps:
|
||||||
- assert-test-linux
|
- assert-test-linux
|
||||||
build-linux:
|
build-linux:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/golang:1.17-stretch
|
- image: alpine:3.14
|
||||||
steps:
|
steps:
|
||||||
- build-linux
|
- build-linux
|
||||||
test-linux-build:
|
test-linux-build:
|
||||||
@@ -450,11 +469,11 @@ jobs:
|
|||||||
workflows:
|
workflows:
|
||||||
test-all:
|
test-all:
|
||||||
jobs:
|
jobs:
|
||||||
- test-llvm11-go115
|
#- test-llvm11-go115
|
||||||
- test-llvm11-go116
|
#- test-llvm11-go116
|
||||||
- build-linux
|
- build-linux
|
||||||
- test-linux-build:
|
- test-linux-build:
|
||||||
requires:
|
requires:
|
||||||
- build-linux
|
- build-linux
|
||||||
- build-macos
|
#- build-macos
|
||||||
- assert-test-linux
|
#- assert-test-linux
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: Windows
|
name: Windows
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
#pull_request:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@@ -15,6 +15,11 @@ jobs:
|
|||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '1.17'
|
go-version: '1.17'
|
||||||
|
- name: Install QEMU
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
choco install qemu --version=2020.06.12
|
||||||
|
echo "C:\Program Files\QEMU" >> $GITHUB_PATH
|
||||||
- name: Install Ninja
|
- name: Install Ninja
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
@@ -73,7 +78,7 @@ jobs:
|
|||||||
run: make binaryen
|
run: make binaryen
|
||||||
- name: Test TinyGo
|
- name: Test TinyGo
|
||||||
shell: bash
|
shell: bash
|
||||||
run: make test GOTESTFLAGS="-v -short"
|
run: make test
|
||||||
- name: Build TinyGo release tarball
|
- name: Build TinyGo release tarball
|
||||||
run: make build/release -j4
|
run: make build/release -j4
|
||||||
- name: Make release artifact
|
- name: Make release artifact
|
||||||
|
|||||||
@@ -1,97 +1,3 @@
|
|||||||
0.21.0
|
|
||||||
---
|
|
||||||
|
|
||||||
* **command line**
|
|
||||||
- drop support for LLVM 10
|
|
||||||
- `build`: drop support for LLVM targets in the -target flag
|
|
||||||
- `build`: fix paths in error messages on Windows
|
|
||||||
- `build`: add -p flag to set parallelism
|
|
||||||
- `lldb`: implement `tinygo lldb` subcommand
|
|
||||||
- `test`: use emulator exit code instead of parsing test output
|
|
||||||
- `test`: pass testing arguments to wasmtime
|
|
||||||
* **compiler**
|
|
||||||
- use -opt flag for optimization level in CFlags (-Os, etc)
|
|
||||||
- `builder`: improve accuracy of the -size=full flag
|
|
||||||
- `builder`: hardcode some more frame sizes for __aeabi_* functions
|
|
||||||
- `builder`: add support for -size= flag for WebAssembly
|
|
||||||
- `cgo`: fix line/column reporting in syntax error messages
|
|
||||||
- `cgo`: support function definitions in CGo headers
|
|
||||||
- `cgo`: implement rudimentary C array decaying
|
|
||||||
- `cgo`: add support for stdio in picolibc and wasi-libc
|
|
||||||
- `cgo`: run CGo parser per file, not per CGo fragment
|
|
||||||
- `compiler`: fix unintentionally exported math functions
|
|
||||||
- `compiler`: properly implement div and rem operations
|
|
||||||
- `compiler`: add support for recursive function types
|
|
||||||
- `compiler`: add support for the `go` keyword on interface methods
|
|
||||||
- `compiler`: add minsize attribute for -Oz
|
|
||||||
- `compiler`: add "target-cpu" and "target-features" attributes
|
|
||||||
- `compiler`: fix indices into strings and arrays
|
|
||||||
- `compiler`: fix string compare functions
|
|
||||||
- `interp`: simplify some code to avoid some errors
|
|
||||||
- `interp`: support recursive globals (like linked lists) in globals
|
|
||||||
- `interp`: support constant globals
|
|
||||||
- `interp`: fix reverting of extractvalue/insertvalue with multiple indices
|
|
||||||
- `transform`: work around renamed return type after merging LLVM modules
|
|
||||||
* **standard library**
|
|
||||||
- `internal/bytealg`: fix indexing error in Compare()
|
|
||||||
- `machine`: support Pin.Get() function when the pin is configured as output
|
|
||||||
- `net`, `syscall`: Reduce code duplication by switching to internal/itoa.
|
|
||||||
- `os`: don't try to read executable path on baremetal
|
|
||||||
- `os`: implement Getwd
|
|
||||||
- `os`: add File.WriteString and File.WriteAt
|
|
||||||
- `reflect`: fix type.Size() to account for struct padding
|
|
||||||
- `reflect`: don't construct an interface-in-interface value
|
|
||||||
- `reflect`: implement Value.Elem() for interface values
|
|
||||||
- `reflect`: fix Value.Index() in a specific case
|
|
||||||
- `reflect`: add support for DeepEqual
|
|
||||||
- `runtime`: add another set of invalid unicode runes to encodeUTF8()
|
|
||||||
- `runtime`: only initialize os.runtime_args when needed
|
|
||||||
- `runtime`: only use CRLF on baremetal systems for println
|
|
||||||
- `runtime/debug`: stub `debug.SetMaxStack`
|
|
||||||
- `runtime/debug`: stub `debug.Stack`
|
|
||||||
- `testing`: add a stub for t.Parallel()
|
|
||||||
- `testing`: add support for -test.short flag
|
|
||||||
- `testing`: stub B.ReportAllocs()
|
|
||||||
- `testing`: add `testing.Verbose`
|
|
||||||
- `testing`: stub `testing.AllocsPerRun`
|
|
||||||
* **targets**
|
|
||||||
- fix gen-device-svd to handle 64-bit values
|
|
||||||
- add CPU and Features property to all targets
|
|
||||||
- match LLVM triple to the one Clang uses
|
|
||||||
- `atsam`: simplify definition of SERCOM UART, I2C and SPI peripherals
|
|
||||||
- `atsam`: move I2S0 to machine file
|
|
||||||
- `esp32`: fix SPI configuration
|
|
||||||
- `esp32c3`: add support for GDB debugging
|
|
||||||
- `esp32c3`: add support for CPU interrupts
|
|
||||||
- `esp32c3`: use tasks scheduler by default
|
|
||||||
- `fe310`: increase CPU frequency from 16MHz to 320MHz
|
|
||||||
- `fe310`: add support for bit banging drivers
|
|
||||||
- `linux`: build static binaries using musl
|
|
||||||
- `linux`: reduce binary size by calling `write` instead of `putchar`
|
|
||||||
- `linux`: add support for GOARM
|
|
||||||
- `riscv`: implement 32-bit atomic operations
|
|
||||||
- `riscv`: align the heap to 16 bytes
|
|
||||||
- `riscv`: switch to tasks-based scheduler
|
|
||||||
- `rp2040`: add CPUFrequency()
|
|
||||||
- `rp2040`: improve I2C baud rate configuration
|
|
||||||
- `rp2040`: add pin interrupt API
|
|
||||||
- `rp2040`: refactor PWM code and fix Period calculation
|
|
||||||
- `stm32f103`: fix SPI
|
|
||||||
- `stm32f103`: make SPI frequency selection more flexible
|
|
||||||
- `qemu`: signal correct exit code to QEMU
|
|
||||||
- `wasi`: run C/C++ constructors at startup
|
|
||||||
- `wasm`: ensure heapptr is aligned
|
|
||||||
- `wasm`: update wasi-libc dependency
|
|
||||||
- `wasm`: wasi: use asyncify
|
|
||||||
- `wasm`: support `-scheduler=none`
|
|
||||||
- `windows`: add support for Windows (amd64 only for now)
|
|
||||||
* **boards**
|
|
||||||
- `feather-stm32f405`, `feather-rp2040`: add I2C pin names
|
|
||||||
- `m5stack-core2`: add M5Stack Core2
|
|
||||||
- `nano-33-ble`: SoftDevice s140v7 support
|
|
||||||
- `nano-33-ble`: add constants for more on-board pins
|
|
||||||
|
|
||||||
|
|
||||||
0.20.0
|
0.20.0
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,6 @@ LLVM_NM ?= $(word 1,$(abspath $(call detect,llvm-build/bin/llvm-nm))$(call detec
|
|||||||
GO ?= go
|
GO ?= go
|
||||||
export GOROOT = $(shell $(GO) env GOROOT)
|
export GOROOT = $(shell $(GO) env GOROOT)
|
||||||
|
|
||||||
# Flags to pass to go test.
|
|
||||||
GOTESTFLAGS ?= -v
|
|
||||||
|
|
||||||
# md5sum binary
|
# md5sum binary
|
||||||
MD5SUM = md5sum
|
MD5SUM = md5sum
|
||||||
|
|
||||||
@@ -171,8 +168,8 @@ $(LLVM_BUILDDIR)/build.ninja: llvm-source
|
|||||||
mkdir -p $(LLVM_BUILDDIR) && cd $(LLVM_BUILDDIR) && cmake -G Ninja $(TINYGO_SOURCE_DIR)/$(LLVM_PROJECTDIR)/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;RISCV;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR;Xtensa" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=OFF $(LLVM_OPTION)
|
mkdir -p $(LLVM_BUILDDIR) && cd $(LLVM_BUILDDIR) && cmake -G Ninja $(TINYGO_SOURCE_DIR)/$(LLVM_PROJECTDIR)/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;RISCV;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR;Xtensa" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF -DCLANG_ENABLE_STATIC_ANALYZER=OFF -DCLANG_ENABLE_ARCMT=OFF $(LLVM_OPTION)
|
||||||
|
|
||||||
# Build LLVM.
|
# Build LLVM.
|
||||||
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
|
$(LLVM_BUILDDIR): #$(LLVM_BUILDDIR)/build.ninja
|
||||||
cd $(LLVM_BUILDDIR) && ninja $(NINJA_BUILD_TARGETS)
|
cd $(LLVM_BUILDDIR) && ninja llvm-nm #$(NINJA_BUILD_TARGETS)
|
||||||
|
|
||||||
# Build Binaryen
|
# Build Binaryen
|
||||||
.PHONY: binaryen
|
.PHONY: binaryen
|
||||||
@@ -195,7 +192,7 @@ tinygo:
|
|||||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags byollvm -ldflags="-X main.gitSha1=`git rev-parse --short HEAD`" .
|
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags byollvm -ldflags="-X main.gitSha1=`git rev-parse --short HEAD`" .
|
||||||
|
|
||||||
test: wasi-libc
|
test: wasi-libc
|
||||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags byollvm ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
|
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test -v -timeout=20m -buildmode exe -tags byollvm ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
|
||||||
|
|
||||||
TEST_PACKAGES = \
|
TEST_PACKAGES = \
|
||||||
compress/bzip2 \
|
compress/bzip2 \
|
||||||
|
|||||||
@@ -2276,16 +2276,16 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va
|
|||||||
case token.NEQ: // !=
|
case token.NEQ: // !=
|
||||||
result := b.createRuntimeCall("stringEqual", []llvm.Value{x, y}, "")
|
result := b.createRuntimeCall("stringEqual", []llvm.Value{x, y}, "")
|
||||||
return b.CreateNot(result, ""), nil
|
return b.CreateNot(result, ""), nil
|
||||||
case token.LSS: // x < y
|
case token.LSS: // <
|
||||||
return b.createRuntimeCall("stringLess", []llvm.Value{x, y}, ""), nil
|
return b.createRuntimeCall("stringLess", []llvm.Value{x, y}, ""), nil
|
||||||
case token.LEQ: // x <= y becomes NOT (y < x)
|
case token.LEQ: // <=
|
||||||
result := b.createRuntimeCall("stringLess", []llvm.Value{y, x}, "")
|
result := b.createRuntimeCall("stringLess", []llvm.Value{y, x}, "")
|
||||||
return b.CreateNot(result, ""), nil
|
return b.CreateNot(result, ""), nil
|
||||||
case token.GTR: // x > y becomes y < x
|
case token.GTR: // >
|
||||||
return b.createRuntimeCall("stringLess", []llvm.Value{y, x}, ""), nil
|
|
||||||
case token.GEQ: // x >= y becomes NOT (x < y)
|
|
||||||
result := b.createRuntimeCall("stringLess", []llvm.Value{x, y}, "")
|
result := b.createRuntimeCall("stringLess", []llvm.Value{x, y}, "")
|
||||||
return b.CreateNot(result, ""), nil
|
return b.CreateNot(result, ""), nil
|
||||||
|
case token.GEQ: // >=
|
||||||
|
return b.createRuntimeCall("stringLess", []llvm.Value{y, x}, ""), nil
|
||||||
default:
|
default:
|
||||||
panic("binop on string: " + op.String())
|
panic("binop on string: " + op.String())
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-2
@@ -71,8 +71,9 @@ entry:
|
|||||||
; Function Attrs: nounwind
|
; Function Attrs: nounwind
|
||||||
define hidden i1 @main.stringCompareLarger(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context, i8* %parentHandle) unnamed_addr #0 {
|
define hidden i1 @main.stringCompareLarger(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* %context, i8* %parentHandle) unnamed_addr #0 {
|
||||||
entry:
|
entry:
|
||||||
%0 = call i1 @runtime.stringLess(i8* %s2.data, i32 %s2.len, i8* %s1.data, i32 %s1.len, i8* undef, i8* null) #0
|
%0 = call i1 @runtime.stringLess(i8* %s1.data, i32 %s1.len, i8* %s2.data, i32 %s2.len, i8* undef, i8* null) #0
|
||||||
ret i1 %0
|
%1 = xor i1 %0, true
|
||||||
|
ret i1 %1
|
||||||
}
|
}
|
||||||
|
|
||||||
declare i1 @runtime.stringLess(i8*, i32, i8*, i32, i8*, i8*)
|
declare i1 @runtime.stringLess(i8*, i32, i8*, i32, i8*, i8*)
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// Version of TinyGo.
|
// Version of TinyGo.
|
||||||
// Update this value before release of new version of software.
|
// Update this value before release of new version of software.
|
||||||
const Version = "0.21.0"
|
const Version = "0.21.0-dev"
|
||||||
|
|
||||||
// GetGorootVersion returns the major and minor version for a given GOROOT path.
|
// GetGorootVersion returns the major and minor version for a given GOROOT path.
|
||||||
// If the goroot cannot be determined, (0, 0) is returned.
|
// If the goroot cannot be determined, (0, 0) is returned.
|
||||||
|
|||||||
+35
-33
@@ -75,6 +75,40 @@ func TestCompiler(t *testing.T) {
|
|||||||
runPlatTests(optionsFromTarget(""), tests, t)
|
runPlatTests(optionsFromTarget(""), tests, t)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if testing.Short() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("EmulatedCortexM3", func(t *testing.T) {
|
||||||
|
runPlatTests(optionsFromTarget("cortex-m-qemu"), tests, t)
|
||||||
|
})
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
|
||||||
|
// Note: running only on Windows and macOS because Linux (as of 2020)
|
||||||
|
// usually has an outdated QEMU version that doesn't support RISC-V yet.
|
||||||
|
t.Run("EmulatedRISCV", func(t *testing.T) {
|
||||||
|
runPlatTests(optionsFromTarget("riscv-qemu"), tests, t)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "linux" {
|
||||||
|
t.Run("X86Linux", func(t *testing.T) {
|
||||||
|
runPlatTests(optionsFromOSARCH("linux/386"), tests, t)
|
||||||
|
})
|
||||||
|
t.Run("ARMLinux", func(t *testing.T) {
|
||||||
|
runPlatTests(optionsFromOSARCH("linux/arm/6"), tests, t)
|
||||||
|
})
|
||||||
|
t.Run("ARM64Linux", func(t *testing.T) {
|
||||||
|
runPlatTests(optionsFromOSARCH("linux/arm64"), tests, t)
|
||||||
|
})
|
||||||
|
t.Run("WebAssembly", func(t *testing.T) {
|
||||||
|
runPlatTests(optionsFromTarget("wasm"), tests, t)
|
||||||
|
})
|
||||||
|
t.Run("WASI", func(t *testing.T) {
|
||||||
|
runPlatTests(optionsFromTarget("wasi"), tests, t)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Test a few build options.
|
// Test a few build options.
|
||||||
t.Run("build-options", func(t *testing.T) {
|
t.Run("build-options", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
@@ -116,38 +150,6 @@ func TestCompiler(t *testing.T) {
|
|||||||
}, nil, nil)
|
}, nil, nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
if testing.Short() {
|
|
||||||
// Don't test other targets when the -short flag is used. Only test the
|
|
||||||
// host system.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Run("EmulatedCortexM3", func(t *testing.T) {
|
|
||||||
runPlatTests(optionsFromTarget("cortex-m-qemu"), tests, t)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("EmulatedRISCV", func(t *testing.T) {
|
|
||||||
runPlatTests(optionsFromTarget("riscv-qemu"), tests, t)
|
|
||||||
})
|
|
||||||
|
|
||||||
if runtime.GOOS == "linux" {
|
|
||||||
t.Run("X86Linux", func(t *testing.T) {
|
|
||||||
runPlatTests(optionsFromOSARCH("linux/386"), tests, t)
|
|
||||||
})
|
|
||||||
t.Run("ARMLinux", func(t *testing.T) {
|
|
||||||
runPlatTests(optionsFromOSARCH("linux/arm/6"), tests, t)
|
|
||||||
})
|
|
||||||
t.Run("ARM64Linux", func(t *testing.T) {
|
|
||||||
runPlatTests(optionsFromOSARCH("linux/arm64"), tests, t)
|
|
||||||
})
|
|
||||||
t.Run("WebAssembly", func(t *testing.T) {
|
|
||||||
runPlatTests(optionsFromTarget("wasm"), tests, t)
|
|
||||||
})
|
|
||||||
t.Run("WASI", func(t *testing.T) {
|
|
||||||
runPlatTests(optionsFromTarget("wasi"), tests, t)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||||
@@ -164,7 +166,7 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
runTest("env.go", options, t, []string{"first", "second"}, []string{"ENV1=VALUE1", "ENV2=VALUE2"})
|
runTest("env.go", options, t, []string{"first", "second"}, []string{"ENV1=VALUE1", "ENV2=VALUE2"})
|
||||||
})
|
})
|
||||||
if options.Target == "wasi" || options.Target == "wasm" {
|
if options.Target == "wasi" {
|
||||||
t.Run("alias.go-scheduler-none", func(t *testing.T) {
|
t.Run("alias.go-scheduler-none", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
options := compileopts.Options(options)
|
options := compileopts.Options(options)
|
||||||
|
|||||||
@@ -18,12 +18,6 @@ func CPUFrequency() uint32 {
|
|||||||
return 125 * MHz
|
return 125 * MHz
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the period of a clock cycle for the raspberry pi pico in nanoseconds.
|
|
||||||
// Used in PWM API.
|
|
||||||
func cpuPeriod() uint32 {
|
|
||||||
return 1e9 / CPUFrequency()
|
|
||||||
}
|
|
||||||
|
|
||||||
// clockIndex identifies a hardware clock
|
// clockIndex identifies a hardware clock
|
||||||
type clockIndex uint8
|
type clockIndex uint8
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//go:build rp2040
|
|
||||||
// +build rp2040
|
// +build rp2040
|
||||||
|
|
||||||
package machine
|
package machine
|
||||||
@@ -6,13 +5,12 @@ package machine
|
|||||||
import (
|
import (
|
||||||
"device/rp"
|
"device/rp"
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
|
||||||
"runtime/volatile"
|
"runtime/volatile"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrBadPeriod = errors.New("period outside valid range 8ns..268ms")
|
ErrPeriodTooBig = errors.New("period outside valid range 1..4e9ns")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -52,21 +50,8 @@ func getPWMGroup(index uintptr) *pwmGroup {
|
|||||||
return (*pwmGroup)(unsafe.Pointer(uintptr(unsafe.Pointer(rp.PWM)) + 0x14*index))
|
return (*pwmGroup)(unsafe.Pointer(uintptr(unsafe.Pointer(rp.PWM)) + 0x14*index))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hardware Pulse Width Modulation (PWM) API
|
|
||||||
// PWM peripherals available on RP2040. Each peripheral has 2 pins available for
|
// PWM peripherals available on RP2040. Each peripheral has 2 pins available for
|
||||||
// a total of 16 available PWM outputs. Some pins may not be available on some boards.
|
// a total of 16 available PWM outputs. Some pins may not be available on some boards.
|
||||||
//
|
|
||||||
// The RP2040 PWM block has 8 identical slices. Each slice can drive two PWM output signals, or
|
|
||||||
// measure the frequency or duty cycle of an input signal. This gives a total of up to 16 controllable
|
|
||||||
// PWM outputs. All 30 GPIOs can be driven by the PWM block
|
|
||||||
//
|
|
||||||
// The PWM hardware functions by continuously comparing the input value to a free-running counter. This produces a
|
|
||||||
// toggling output where the amount of time spent at the high output level is proportional to the input value. The fraction of
|
|
||||||
// time spent at the high signal level is known as the duty cycle of the signal.
|
|
||||||
//
|
|
||||||
// The default behaviour of a PWM slice is to count upward until the wrap value (\ref pwm_config_set_wrap) is reached, and then
|
|
||||||
// immediately wrap to 0. PWM slices also offer a phase-correct mode, where the counter starts to count downward after
|
|
||||||
// reaching TOP, until it reaches 0 again.
|
|
||||||
var (
|
var (
|
||||||
PWM0 = getPWMGroup(0)
|
PWM0 = getPWMGroup(0)
|
||||||
PWM1 = getPWMGroup(1)
|
PWM1 = getPWMGroup(1)
|
||||||
@@ -109,23 +94,30 @@ func (pwm *pwmGroup) peripheral() uint8 {
|
|||||||
return uint8((uintptr(unsafe.Pointer(pwm)) - uintptr(unsafe.Pointer(rp.PWM))) / 0x14)
|
return uint8((uintptr(unsafe.Pointer(pwm)) - uintptr(unsafe.Pointer(rp.PWM))) / 0x14)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetPeriod updates the period of this PWM peripheral in nanoseconds.
|
// SetPeriod updates the period of this PWM peripheral.
|
||||||
// To set a particular frequency, use the following formula:
|
// To set a particular frequency, use the following formula:
|
||||||
//
|
//
|
||||||
// period = 1e9 / frequency
|
// period = 1e9 / frequency
|
||||||
//
|
//
|
||||||
// Where frequency is in hertz. If you use a period of 0, a period
|
// If you use a period of 0, a period that works well for LEDs will be picked.
|
||||||
// that works well for LEDs will be picked.
|
|
||||||
//
|
//
|
||||||
// SetPeriod will try not to modify TOP if possible to reach the target period.
|
// SetPeriod will not change the prescaler, but also won't change the current
|
||||||
// If the period is unattainable with current TOP SetPeriod will modify TOP
|
// value in any of the channels. This means that you may need to update the
|
||||||
// by the bare minimum to reach the target period. It will also enable phase
|
// value for the particular channel.
|
||||||
// correct to reach periods above 130ms.
|
//
|
||||||
|
// Note that you cannot pick any arbitrary period after the PWM peripheral has
|
||||||
|
// been configured. If you want to switch between frequencies, pick the lowest
|
||||||
|
// frequency (longest period) once when calling Configure and adjust the
|
||||||
|
// frequency here as needed.
|
||||||
func (p *pwmGroup) SetPeriod(period uint64) error {
|
func (p *pwmGroup) SetPeriod(period uint64) error {
|
||||||
|
if period > 0xffff_ffff {
|
||||||
|
return ErrPeriodTooBig
|
||||||
|
}
|
||||||
if period == 0 {
|
if period == 0 {
|
||||||
period = 1e5
|
period = 1e5
|
||||||
}
|
}
|
||||||
return p.setPeriod(period)
|
p.setPeriod(period)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Top returns the current counter top, for use in duty cycle calculation.
|
// Top returns the current counter top, for use in duty cycle calculation.
|
||||||
@@ -143,14 +135,14 @@ func (p *pwmGroup) Counter() uint32 {
|
|||||||
return (p.CTR.Get() & rp.PWM_CH0_CTR_CH0_CTR_Msk) >> rp.PWM_CH0_CTR_CH0_CTR_Pos
|
return (p.CTR.Get() & rp.PWM_CH0_CTR_CH0_CTR_Msk) >> rp.PWM_CH0_CTR_CH0_CTR_Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
// Period returns the used PWM period in nanoseconds.
|
// Period returns the used PWM period in nanoseconds. It might deviate slightly
|
||||||
|
// from the configured period due to rounding.
|
||||||
func (p *pwmGroup) Period() uint64 {
|
func (p *pwmGroup) Period() uint64 {
|
||||||
periodPerCycle := cpuPeriod()
|
periodPerCycle := getPeriod()
|
||||||
top := p.getWrap()
|
top := p.getWrap()
|
||||||
phc := p.getPhaseCorrect()
|
phc := p.getPhaseCorrect()
|
||||||
Int, frac := p.getClockDiv()
|
Int, frac := p.getClockDiv()
|
||||||
// Line below can overflow if operations done without care.
|
return uint64((Int + frac/16) * (top + 1) * (phc + 1) * periodPerCycle) // cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
||||||
return (16*uint64(Int) + uint64(frac)) * uint64((top+1)*(phc+1)*periodPerCycle) / 16 // cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetInverting sets whether to invert the output of this channel.
|
// SetInverting sets whether to invert the output of this channel.
|
||||||
@@ -188,12 +180,6 @@ func (p *pwmGroup) SetTop(top uint32) {
|
|||||||
p.setWrap(uint16(top))
|
p.setWrap(uint16(top))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCounter sets counter control register. Max value is 16bit (0xffff).
|
|
||||||
// Useful for synchronising two different PWM peripherals.
|
|
||||||
func (p *pwmGroup) SetCounter(ctr uint32) {
|
|
||||||
p.CTR.Set(ctr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable enables or disables PWM peripheral channels.
|
// Enable enables or disables PWM peripheral channels.
|
||||||
func (p *pwmGroup) Enable(enable bool) {
|
func (p *pwmGroup) Enable(enable bool) {
|
||||||
p.enable(enable)
|
p.enable(enable)
|
||||||
@@ -204,6 +190,29 @@ func (p *pwmGroup) IsEnabled() (enabled bool) {
|
|||||||
return (p.CSR.Get()&rp.PWM_CH0_CSR_EN_Msk)>>rp.PWM_CH0_CSR_EN_Pos != 0
|
return (p.CSR.Get()&rp.PWM_CH0_CSR_EN_Msk)>>rp.PWM_CH0_CSR_EN_Pos != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hardware Pulse Width Modulation (PWM) API
|
||||||
|
//
|
||||||
|
// The RP2040 PWM block has 8 identical slices. Each slice can drive two PWM output signals, or
|
||||||
|
// measure the frequency or duty cycle of an input signal. This gives a total of up to 16 controllable
|
||||||
|
// PWM outputs. All 30 GPIOs can be driven by the PWM block
|
||||||
|
//
|
||||||
|
// The PWM hardware functions by continuously comparing the input value to a free-running counter. This produces a
|
||||||
|
// toggling output where the amount of time spent at the high output level is proportional to the input value. The fraction of
|
||||||
|
// time spent at the high signal level is known as the duty cycle of the signal.
|
||||||
|
//
|
||||||
|
// The default behaviour of a PWM slice is to count upward until the wrap value (\ref pwm_config_set_wrap) is reached, and then
|
||||||
|
// immediately wrap to 0. PWM slices also offer a phase-correct mode, where the counter starts to count downward after
|
||||||
|
// reaching TOP, until it reaches 0 again.
|
||||||
|
type pwms struct {
|
||||||
|
slice pwmGroup
|
||||||
|
hw *rp.PWM_Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle to all pwm peripheral registers.
|
||||||
|
var _PWM = pwms{
|
||||||
|
hw: rp.PWM,
|
||||||
|
}
|
||||||
|
|
||||||
// Initialise a PWM with settings from a configuration object.
|
// Initialise a PWM with settings from a configuration object.
|
||||||
// If start is true then PWM starts on initialization.
|
// If start is true then PWM starts on initialization.
|
||||||
func (pwm *pwmGroup) init(config PWMConfig, start bool) error {
|
func (pwm *pwmGroup) init(config PWMConfig, start bool) error {
|
||||||
@@ -244,53 +253,24 @@ func (pwm *pwmGroup) setDivMode(mode uint32) {
|
|||||||
pwm.CSR.ReplaceBits(mode<<rp.PWM_CH0_CSR_DIVMODE_Pos, rp.PWM_CH0_CSR_DIVMODE_Msk, 0)
|
pwm.CSR.ReplaceBits(mode<<rp.PWM_CH0_CSR_DIVMODE_Pos, rp.PWM_CH0_CSR_DIVMODE_Msk, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// setPeriod sets the pwm peripheral period (frequency). Calculates DIV_INT,DIV_FRAC and sets it from following equation:
|
// setPeriod sets the pwm peripheral period (frequency). Calculates DIV_INT and sets it from following equation:
|
||||||
// cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
// cycles = (TOP+1) * (CSRPHCorrect + 1) * (DIV_INT + DIV_FRAC/16)
|
||||||
// where cycles is amount of clock cycles per PWM period.
|
// where cycles is amount of clock cycles per PWM period.
|
||||||
func (pwm *pwmGroup) setPeriod(period uint64) error {
|
func (pwm *pwmGroup) setPeriod(period uint64) {
|
||||||
// This period calculation algorithm consists of
|
targetPeriod := uint32(period)
|
||||||
// 1. Calculating best-fit prescale at a slightly lower-than-max TOP value
|
periodPerCycle := getPeriod()
|
||||||
// 2. Calculate TOP value to reach target period given the calculated prescale
|
top := pwm.getWrap()
|
||||||
// 3. Apply calculated Prescale from step 1 and calculated Top from step 2
|
phc := pwm.getPhaseCorrect()
|
||||||
const (
|
_, frac := pwm.getClockDiv()
|
||||||
maxTop = math.MaxUint16
|
|
||||||
// start algorithm at 95% Top. This allows us to undershoot period with prescale.
|
|
||||||
topStart = 95 * maxTop / 100
|
|
||||||
milliseconds = 1_000_000_000
|
|
||||||
// Maximum Period is 268369920ns on rp2040, given by (16*255+15)*8*(1+0xffff)*(1+1)/16
|
|
||||||
// With no phase shift max period is half of this value.
|
|
||||||
maxPeriod = 268 * milliseconds
|
|
||||||
)
|
|
||||||
|
|
||||||
if period > maxPeriod || period < 8 {
|
|
||||||
return ErrBadPeriod
|
|
||||||
}
|
|
||||||
if period > maxPeriod/2 {
|
|
||||||
pwm.setPhaseCorrect(true) // Must enable Phase correct to reach large periods.
|
|
||||||
}
|
|
||||||
|
|
||||||
// clearing above expression:
|
// clearing above expression:
|
||||||
// DIV_INT + DIV_FRAC/16 = cycles / ( (TOP+1) * (CSRPHCorrect+1) ) // DIV_FRAC/16 is always 0 in this equation
|
// DIV_INT = cycles / ( (TOP+1) * (CSRPHCorrect+1) ) - DIV_FRAC/16
|
||||||
// where cycles must be converted to time:
|
// where cycles must be converted to time:
|
||||||
// target_period = cycles * period_per_cycle ==> cycles = target_period/period_per_cycle
|
// target_period = cycles * period_per_cycle ==> cycles = target_period/period_per_cycle
|
||||||
periodPerCycle := uint64(cpuPeriod())
|
Int := targetPeriod/((1+phc)*periodPerCycle*(1+top)) - frac/16
|
||||||
phc := uint64(pwm.getPhaseCorrect())
|
if Int > 0xff {
|
||||||
rhs := 16 * period / ((1 + phc) * periodPerCycle * (1 + topStart)) // right-hand-side of equation, scaled so frac is not divided
|
Int = 0xff
|
||||||
whole := rhs / 16
|
|
||||||
frac := rhs % 16
|
|
||||||
if whole > 0xff {
|
|
||||||
whole = 0xff
|
|
||||||
}
|
}
|
||||||
|
pwm.setClockDiv(uint8(Int), 0)
|
||||||
// Step 2 is acquiring a better top value. Clearing the equation:
|
|
||||||
// TOP = cycles / ( (DIVINT+DIVFRAC/16) * (CSRPHCorrect+1) ) - 1
|
|
||||||
top := 16*period/((16*whole+frac)*periodPerCycle*(1+phc)) - 1
|
|
||||||
if top > maxTop {
|
|
||||||
top = maxTop
|
|
||||||
}
|
|
||||||
pwm.SetTop(uint32(top))
|
|
||||||
pwm.setClockDiv(uint8(whole), uint8(frac))
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int is integer value to reduce counting rate by. Must be greater than or equal to 1. DIV_INT is bits 4:11 (8 bits).
|
// Int is integer value to reduce counting rate by. Must be greater than or equal to 1. DIV_INT is bits 4:11 (8 bits).
|
||||||
@@ -380,9 +360,9 @@ func (pwm *pwmGroup) getPhaseCorrect() (phCorrect uint32) {
|
|||||||
return (pwm.CSR.Get() & rp.PWM_CH0_CSR_PH_CORRECT_Msk) >> rp.PWM_CH0_CSR_PH_CORRECT_Pos
|
return (pwm.CSR.Get() & rp.PWM_CH0_CSR_PH_CORRECT_Msk) >> rp.PWM_CH0_CSR_PH_CORRECT_Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pwm *pwmGroup) getClockDiv() (Int, frac uint8) {
|
func (pwm *pwmGroup) getClockDiv() (Int, frac uint32) {
|
||||||
div := pwm.DIV.Get()
|
div := pwm.DIV.Get()
|
||||||
return uint8((div & rp.PWM_CH0_DIV_INT_Msk) >> rp.PWM_CH0_DIV_INT_Pos), uint8((div & rp.PWM_CH0_DIV_FRAC_Msk) >> rp.PWM_CH0_DIV_FRAC_Pos)
|
return (div & rp.PWM_CH0_DIV_INT_Msk) >> rp.PWM_CH0_DIV_INT_Pos, (div & rp.PWM_CH0_DIV_FRAC_Msk) >> rp.PWM_CH0_DIV_FRAC_Pos
|
||||||
}
|
}
|
||||||
|
|
||||||
// pwmGPIOToSlice Determine the PWM channel that is attached to the specified GPIO.
|
// pwmGPIOToSlice Determine the PWM channel that is attached to the specified GPIO.
|
||||||
@@ -396,3 +376,9 @@ func pwmGPIOToSlice(gpio Pin) (slicenum uint8) {
|
|||||||
func pwmGPIOToChannel(gpio Pin) (channel uint8) {
|
func pwmGPIOToChannel(gpio Pin) (channel uint8) {
|
||||||
return uint8(gpio) & 1
|
return uint8(gpio) & 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the period of a clock cycle for the raspberry pi pico in nanoseconds.
|
||||||
|
func getPeriod() uint32 {
|
||||||
|
const periodIn uint32 = 1e9 / (125 * MHz)
|
||||||
|
return periodIn
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,17 +1,2 @@
|
|||||||
// Package debug is a dummy package that is not yet implemented.
|
// Package debug is a dummy package that is not yet implemented.
|
||||||
package debug
|
package debug
|
||||||
|
|
||||||
// SetMaxStack sets the maximum amount of memory that can be used by a single
|
|
||||||
// goroutine stack.
|
|
||||||
//
|
|
||||||
// Not implemented.
|
|
||||||
func SetMaxStack(n int) int {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stack returns a formatted stack trace of the goroutine that calls it.
|
|
||||||
//
|
|
||||||
// Not implemented.
|
|
||||||
func Stack() []byte {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -29,6 +29,34 @@ func setEventHandler(fn func()) {
|
|||||||
handleEvent = fn
|
handleEvent = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export resume
|
||||||
|
func resume() {
|
||||||
|
go func() {
|
||||||
|
handleEvent()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if wasmNested {
|
||||||
|
minSched()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wasmNested = true
|
||||||
|
scheduler()
|
||||||
|
wasmNested = false
|
||||||
|
}
|
||||||
|
|
||||||
|
//export go_scheduler
|
||||||
|
func go_scheduler() {
|
||||||
|
if wasmNested {
|
||||||
|
minSched()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wasmNested = true
|
||||||
|
scheduler()
|
||||||
|
wasmNested = false
|
||||||
|
}
|
||||||
|
|
||||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
func ticksToNanoseconds(ticks timeUnit) int64 {
|
||||||
// The JavaScript API works in float64 milliseconds, so convert to
|
// The JavaScript API works in float64 milliseconds, so convert to
|
||||||
// nanoseconds first before converting to a timeUnit (which is a float64),
|
// nanoseconds first before converting to a timeUnit (which is a float64),
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
//go:build wasm && !wasi && !scheduler.none
|
|
||||||
// +build wasm,!wasi,!scheduler.none
|
|
||||||
|
|
||||||
package runtime
|
|
||||||
|
|
||||||
//export resume
|
|
||||||
func resume() {
|
|
||||||
go func() {
|
|
||||||
handleEvent()
|
|
||||||
}()
|
|
||||||
|
|
||||||
if wasmNested {
|
|
||||||
minSched()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
wasmNested = true
|
|
||||||
scheduler()
|
|
||||||
wasmNested = false
|
|
||||||
}
|
|
||||||
|
|
||||||
//export go_scheduler
|
|
||||||
func go_scheduler() {
|
|
||||||
if wasmNested {
|
|
||||||
minSched()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
wasmNested = true
|
|
||||||
scheduler()
|
|
||||||
wasmNested = false
|
|
||||||
}
|
|
||||||
@@ -297,24 +297,6 @@ func Short() bool {
|
|||||||
return flagShort
|
return flagShort
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verbose reports whether the -test.v flag is set.
|
|
||||||
func Verbose() bool {
|
|
||||||
return flagVerbose
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllocsPerRun returns the average number of allocations during calls to f.
|
|
||||||
// Although the return value has type float64, it will always be an integral
|
|
||||||
// value.
|
|
||||||
//
|
|
||||||
// Not implemented.
|
|
||||||
func AllocsPerRun(runs int, f func()) (avg float64) {
|
|
||||||
f()
|
|
||||||
for i := 0; i < runs; i++ {
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMain(m *M) {
|
func TestMain(m *M) {
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
-7
@@ -24,13 +24,6 @@ func main() {
|
|||||||
println("ab" < "aa")
|
println("ab" < "aa")
|
||||||
println("aa" < "ab")
|
println("aa" < "ab")
|
||||||
|
|
||||||
h := "hello"
|
|
||||||
println("h < h", h < h)
|
|
||||||
println("h <= h", h <= h)
|
|
||||||
println("h == h", h == h)
|
|
||||||
println("h >= h", h >= h)
|
|
||||||
println("h > h", h > h)
|
|
||||||
|
|
||||||
println("array equality")
|
println("array equality")
|
||||||
println(a1 == [2]int{1, 2})
|
println(a1 == [2]int{1, 2})
|
||||||
println(a1 != [2]int{1, 2})
|
println(a1 != [2]int{1, 2})
|
||||||
|
|||||||
Vendored
-5
@@ -20,11 +20,6 @@ true
|
|||||||
false
|
false
|
||||||
false
|
false
|
||||||
true
|
true
|
||||||
h < h false
|
|
||||||
h <= h true
|
|
||||||
h == h true
|
|
||||||
h >= h true
|
|
||||||
h > h false
|
|
||||||
array equality
|
array equality
|
||||||
true
|
true
|
||||||
false
|
false
|
||||||
|
|||||||
Reference in New Issue
Block a user