Compare commits

..

68 Commits

Author SHA1 Message Date
Ayke van Laethem 43e104e675 Debug race condition... 2024-06-05 13:18:20 +02:00
leongross 20b58a0128 Add signal stubs (#4270)
os: init signal ignore stub and add other stubs

Signed-off-by: leongross <leon.gross@9elements.com>
2024-06-02 09:52:31 +02:00
Damian Gryski bfccf3592a builder: make sure wasm-opt command line is printed if asked 2024-05-31 11:20:04 -07:00
Damian Gryski 272fea13e7 builder: keep un-wasm-opt'd .wasm if -work was passed 2024-05-31 11:20:04 -07:00
Damian Gryski b6fd0c818e src/reflect: uncomment more tests that pass 2024-05-29 13:56:04 -07:00
Ayke van Laethem c383a407e3 cgo: do a basic test that math functions work
They should, but we weren't testing this.
I discovered this while working on
https://github.com/tinygo-org/macos-minimal-sdk/pull/4 which will likely
make math.h not work anymore. So I wanted to make sure we have a test in
place before we update that dependency.
2024-05-29 21:51:39 +02:00
diamondburned 7b7601d77c os/user: add stubs for Lookup{,Group} and Group 2024-05-28 23:56:51 +02:00
frenkel26 f7c0466f78 compiler,reflect: fix NumMethods for Interface type 2024-05-28 14:09:59 +02:00
Ayke van Laethem 81ce7fb738 LLVM 18 support 2024-05-24 19:12:26 +02:00
Ayke van Laethem c2776dcf78 main: add -serial=rtt flag as possible option
I added this a while ago but forgot to change the help documentation.
2024-05-24 17:37:49 +02:00
leongross ad0340d437 fix fpm ci installion
Signed-off-by: leongross <leon.gross@9elements.com>
2024-05-18 12:00:28 +02:00
leongross 30c4df16f2 add aes generic aliases 2024-05-14 20:44:48 +02:00
Randy Reddig fe27b674cd reflect: use int in StringHeader and SliceHeader on non-AVR platforms (#4156) 2024-05-14 14:04:54 +02:00
Mateusz Nowak c78dbcd3f2 Support UF2 drives with space in their name on Linux
Some devices, such as Seeed Studio XIAO with Adafruit bootloader, use complex names for UF2 device. With this fix applied, /proc/mounts should be parsed correctly
2024-05-14 13:58:44 +02:00
Johann Freymuth 8890b57ba0 Add I2C support for esp32 (#4259)
machine/esp32: add i2c support
2024-05-13 21:58:06 +02:00
deadprogram ee3a05f1de targets: add support for Badger2040 W
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-05-13 20:10:36 +02:00
Elias Naur 9307204111 Revert "flake.nix: explicitly add libcxx as dependency"
This reverts commit 7b8ae2d6b6.
2024-05-13 19:04:01 +02:00
Marco Manino 71878c2c0c Adding a comment 2024-05-13 16:49:18 +02:00
Marco Manino cef2a82c97 Checking for methodset existance 2024-05-13 16:49:18 +02:00
Johann Freymuth 1d9f26cee1 targets: add support for m5paper 2024-05-12 16:09:27 +02:00
sago35 6e58c44390 machine: add TxFifoFreeLevel() for CAN 2024-05-10 18:45:06 +02:00
deadprogram 7d6b667bba machine/stm32: add i2c Frequency and SetBaudRate() function for boards that were missing implementation
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-05-08 10:57:46 +02:00
Christian Stewart 72f30ca6ec Makefile: add lld to list of build targets for wasm-ld
The current list of targets does not build wasm-ld.

wasm-ld is a symlink created in ./llvm-build/bin pointing to ./lld.

Add the "lld" build target to get wasm-ld into ./llvm-build/bin.

Fixes a build failure where wasm-ld is not found.

Signed-off-by: Christian Stewart <christian@aperture.us>
2024-05-05 11:31:46 +02:00
deadprogram 293b620faf build: update llvm cache to use tagged LLVM source version
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-04-30 19:02:45 +02:00
Dan Kegel ad0af607ef Add 'make spell' target, fix what it finds. In .go files, only checks comments. 2024-04-30 07:47:11 +02:00
deadprogram da23cdeae4 make: use release esp-17.0.1_20240419 tag for source from espressif LLVM fork for reproducible builds
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-04-29 20:50:23 +02:00
Ayke van Laethem d419cc11bf simulator: add support for GetRNG
This is needed to be able to simulate the Gopher Badge code:
https://github.com/conejoninja/gopherbadge
2024-04-28 23:59:23 +02:00
Ayke van Laethem 441dfc98d7 simulator: fix I2C support
- Add ReadRegister and WriteRegister (because they're still used by
    some packages).
  - Fix out-of-bounds panic in I2C.Tx when either w or r has a length of
    zero (or is nil).
2024-04-28 23:05:49 +02:00
Elias Naur 2b3b870bfe mksnanov3: limit programming speed to 1800 kHz
Both of my development boards exhibit stability problems when
programming at the default 4000 kHz speed of the target/stmf32d4x
OpenOCD configuration.

Note that the speed limit must be set by an event handler, because it
is hard-coded by a similar event handler in stmf32f4x.cfg:

  $_TARGETNAME configure -event reset-init {
  	# Configure PLL to boost clock to HSI x 4 (64 MHz)
    ...

  	# Boost JTAG frequency
  	adapter speed 8000     <-- resolves to 4000 kHz by the SWD interface
  }

While here, replace the reference to the deprecated "stlink-v2"
configuration.
2024-04-27 13:02:20 +02:00
Ayke van Laethem 7748c4922e compileopts: fix race condition
Appending to a slice can lead to a race condition if the capacity of the
slice is larger than the length (and therefore the returned slice will
overwrite some fields in the underlying array).

This fixes that race condition. I don't know how severe this particular
one is. It shouldn't be that severe, but it is a bug and it makes it
easier to hunt for possibly more serious race conditions.
2024-04-27 11:12:19 +02:00
Elias Naur 50f700ddb5 runtime: skip negative sleep durations in sleepTicks
sleepTicks calls machineLightSleep with the duration cast to an unsigned
integer. This underflow for negative durations.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
2024-04-27 09:52:44 +02:00
Ayke van Laethem f986ea84ac rp2040: fix timeUnit type
It should be int64 like for all other systems, not uint64.
2024-04-26 14:12:10 +02:00
sago35 797a5a2031 machine/thingplus_rp2040, machine/waveshare-rp2040-zero:add WS2812 definition 2024-04-24 08:50:53 +02:00
dkegel-fastly 3d433fe9f1 Lint: lint and fix src/{os,reflect} (#4228)
* lint: expand to src/{os,reflect}, fix or suppress what it found

* internal/tools/tools.go: the tools idiom requires a build tag guard to avoid go test complaints
2024-04-22 11:10:13 -07:00
hongkuang 1154212c15 chore: fix function names in comment
Signed-off-by: hongkuang <liurenhong@outlook.com>
2024-04-20 14:58:06 +02:00
Patrick Ting 22bf045c9a add stm32 nucleol476rg support 2024-04-19 20:50:00 +02:00
dkegel-fastly 39029cc376 Run Nick G's spellchecker github.com/client9/misspell, carefuly fix what it found (#4235) 2024-04-19 06:57:01 -07:00
Elias Naur 7122755725 compileopts: apply OpenOCD commands after target configuration
The openocd-commands option cannot refer to commands defined by the
target configuration. Lift this restriction by moving the commands to
after target loading.
2024-04-17 21:54:38 +02:00
leongross dcee228c4e add os.Link
Signed-off-by: leongross <leon.gross@9elements.com>
2024-04-14 16:56:53 +02:00
Dan Kegel 9d6e30701b lint: add "make lint" target, run it from ci
See https://github.com/tinygo-org/tinygo/issues/4225

Runs in both circleci and github, circleci is run on branch push, github is run on PR

Revive builds so fast, don't bother installing it; saves us wondering which one we get

Uses tools.go idiom to give control over linter versions to go.mod.

Also pacifies linter re AppendToGlobal as a token first fix.

TODO: gradually expand the number of directories that are linted,
uncomment more entries in revive.toml, and fix or suppress the
warnings lint finds.

TODO: add linters "go vet" and staticcheck

NOT TODO: don't add metalinters like golangci-lint that pull in
lots of new of dependencies; we'd rather not clutter go.mod that
much, let alone open ourselves up to the additional attack surface.
2024-04-13 18:57:31 +02:00
Ayke van Laethem 85b59e66da machine: add __tinygo_spi_tx function to simulator
This is much, _much_ faster than __tinygo_spi_transfer which can only
transfer a single byte at a time. This is especially important for
simulated displays.

I've already implemented the browser side of this on the playground and
have used this patch for local testing where it massively speeds up
display operations.
2024-04-13 11:38:18 +02:00
Ayke van Laethem 90b0bf646c rp2040: make all RP2040 boards available for simulation
This makes all rp2040 boards available for simulation using
-tags=<board_name>. Importantly, this includes the Gopher Badge which
I'm working on to add to the TinyGo Playground.
2024-04-04 19:34:01 +02:00
Ayke van Laethem c55ac9f28e rp2040: move UART0 and UART1 to common file
This is makes it easier to use these in simulation, plus it avoids
duplication. The only downside I see is that more UARTs get defined than
a board supports, but no existing code should break (no UARTs get
renamed for example).
2024-04-04 19:34:01 +02:00
leongross 2733e376bd fix square alias for ed25519
Signed-off-by: leongross <leon.gross@9elements.com>
2024-04-03 12:35:20 +02:00
Ayke van Laethem 331cfb65b7 nix: fix wasi-libc include headers
Apparently Nix really doesn't like --sysroot, so we have to use
`-nostdlibinc` and `-isystem` instead.
2024-03-28 15:46:00 +01:00
Randy Reddig 055950421a all: change references of 'wasi' to 'wasip1'; test hygiene 2024-03-27 16:01:40 +01:00
Randy Reddig cfcc894855 targets: add wasi.json that inherits wasip1.json
PR feedback
2024-03-27 16:01:40 +01:00
Randy Reddig 8bd0155c51 os, testing: just check runtime.GOOS == "wasip1" 2024-03-27 16:01:40 +01:00
Randy Reddig 32a056c32a syscall: use libc_getpagesize instead of hard-coded constant
TODO: should Getpagesize on wasip1 just return wasmPageSize?
2024-03-27 16:01:40 +01:00
Randy Reddig 8e8ad9004f all: replace target=wasi with target=wasip1
This eliminates the 'wasi' build tag in favor of 'GOOS=wasip1', introduced in Go 1.21.

For backwards compatablity, -target=wasi is a synonym for -target=wasip1.
2024-03-27 16:01:40 +01:00
Patrick Lindsay 62d8cdb218 Map the rest of the pinout 2024-03-27 11:55:25 +01:00
Patrick Lindsay b6fdbee14e Begin implementing support for Adafruit ESP32 Feather V2 2024-03-27 11:55:25 +01:00
deadprogram a5ceb793be builder: add check for error on creating needed directory as suggested by @b0ch3nski
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-03-26 12:20:50 +01:00
Ayke van Laethem 7c546525ea wasm-unknown: add math and memory builtins that LLVM needs
This new library is needed for wasm targets that aren't WASI and don't
need/want a libc, but still need some intrinsics that are generated by
LLVM.
2024-03-26 12:20:50 +01:00
Ayke van Laethem d628e3e2cb ci: don't add --recursive when updating submodules
It's not generally needed. It was added in
https://github.com/tinygo-org/tinygo/pull/3958 to fix an issue with
binaryen that has since been fixed in a different way, so we don't need
the googletest dependency anymore.
2024-03-24 13:04:47 +01:00
Jonathan Böcker d97e4dbccf Add smoke test for pca10059-s140v7 2024-03-23 10:23:07 +01:00
Jonathan Böcker a7ddb33bea Add pca10059-s140v7 as a target 2024-03-23 10:23:07 +01:00
Ayke van Laethem 8a93196f1f Makefile: allow overriding the packages to test in make test
This way you can for example run `make test GOTESTPKGS=./builder` to
only test the builder package.
I've often done this by manually modifying the Makefile, so having a
make parameter available would make this much easier.
2024-03-22 23:18:10 +01:00
Anders Savill 6714974aba feather-nrf52840-sense doesn't use LFXO 2024-03-21 20:29:02 +01:00
deadprogram d67ec3b266 goenv: put back @sago35 update to new v0.32.0 development version
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-03-21 06:41:10 +01:00
Ayke van Laethem 78775007fa wasm: fix symbol table index for archives
The symbol table was generated incorrectly. The correct way is to use
the custom linking WebAssembly section, which I implemented in go-wasm
for this purpose.

This fixes https://github.com/tinygo-org/tinygo/issues/4114 and is a
prerequisite for https://github.com/tinygo-org/tinygo/pull/4176.
2024-03-19 07:12:22 +01:00
Ayke van Laethem ad4d722f54 all: move -panic=trap support to the compiler/runtime
Support for `-panic=trap` was previously a pass in the optimization
pipeline. This change moves it to the compiler and runtime, which in my
opinion is a much better place.

As a side effect, it also fixes
https://github.com/tinygo-org/tinygo/issues/4161 by trapping inside
runtime.runtimePanicAt and not just runtime.runtimePanic.

This change also adds a test for the list of imported functions. This is
a more generic test where it's easy to add more tests for WebAssembly
file properties, such as exported functions.
2024-03-19 07:10:51 +01:00
deadprogram 6384ecace0 docs: update CHANGELOG for 0.31.2 patch release
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-03-10 15:13:23 +01:00
deadprogram 38881a2850 goenv: update to v0.31.2 for patch release
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-03-10 15:13:23 +01:00
deadprogram 0f1cf14743 net: update to net package with Buffers implementation
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-03-09 10:56:14 -05:00
sago35 7c34f7704e goenv: update to new v0.32.0 development version 2024-03-04 19:29:26 +01:00
Randy Reddig 377415a6c3 runtime: add Frame.Entry field
This enables compatibility with golang.org/x/tools/internal/pkgbits.

https://github.com/golang/tools/blob/master/internal/pkgbits/frames_go17.go
2024-03-02 21:17:34 +01:00
deadprogram 1e13c6d18f syscall: add wasm_unknown to some additional files so it can compile more code
Signed-off-by: deadprogram <ron@hybridgroup.com>
2024-03-02 20:49:56 +01:00
200 changed files with 2167 additions and 840 deletions
+10 -10
View File
@@ -5,17 +5,17 @@ commands:
steps:
- run:
name: "Pull submodules"
command: git submodule update --init --recursive
command: git submodule update --init
llvm-source-linux:
steps:
- restore_cache:
keys:
- llvm-source-17-v1
- llvm-source-18-v1
- run:
name: "Fetch LLVM source"
command: make llvm-source
- save_cache:
key: llvm-source-17-v1
key: llvm-source-18-v1
paths:
- llvm-project/clang/lib/Headers
- llvm-project/clang/include
@@ -33,13 +33,13 @@ commands:
steps:
- restore_cache:
keys:
- binaryen-linux-v2
- binaryen-linux-v3
- run:
name: "Build Binaryen"
command: |
make binaryen
- save_cache:
key: binaryen-linux-v2
key: binaryen-linux-v3
paths:
- build/wasm-opt
test-linux:
@@ -88,7 +88,7 @@ commands:
# Do this before gen-device so that it doesn't check the
# formatting of generated files.
name: Check Go code formatting
command: make fmt-check
command: make fmt-check lint
- run: make gen-device -j4
- run: make smoketest XTENSA=0
- save_cache:
@@ -105,12 +105,12 @@ jobs:
- test-linux:
llvm: "15"
resource_class: large
test-llvm17-go122:
test-llvm18-go122:
docker:
- image: golang:1.22-bullseye
steps:
- test-linux:
llvm: "17"
llvm: "18"
resource_class: large
workflows:
@@ -119,5 +119,5 @@ workflows:
# This tests our lowest supported versions of Go and LLVM, to make sure at
# least the smoke tests still pass.
- test-llvm15-go118
# This tests LLVM 17 support when linking against system libraries.
- test-llvm17-go122
# This tests LLVM 18 support when linking against system libraries.
- test-llvm18-go122
+5 -5
View File
@@ -43,7 +43,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-source
with:
key: llvm-source-17-${{ matrix.os }}-v1
key: llvm-source-18-${{ matrix.os }}-v2
path: |
llvm-project/clang/lib/Headers
llvm-project/clang/include
@@ -68,7 +68,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-build
with:
key: llvm-build-17-${{ matrix.os }}-v1
key: llvm-build-18-${{ matrix.os }}-v2
path: llvm-build
- name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
@@ -128,7 +128,7 @@ jobs:
runs-on: macos-latest
strategy:
matrix:
version: [16, 17]
version: [16, 17, 18]
steps:
- name: Set up Homebrew
uses: Homebrew/actions/setup-homebrew@master
@@ -152,8 +152,8 @@ jobs:
- name: Check binary
run: tinygo version
- name: Build TinyGo (default LLVM)
if: matrix.version == 17
if: matrix.version == 18
run: go install
- name: Check binary
if: matrix.version == 17
if: matrix.version == 18
run: tinygo version
+11 -9
View File
@@ -24,7 +24,7 @@ jobs:
# tar: needed for actions/cache@v4
# git+openssh: needed for checkout (I think?)
# ruby: needed to install fpm
run: apk add tar git openssh make g++ ruby
run: apk add tar git openssh make g++ ruby-dev
- name: Work around CVE-2022-24765
# We're not on a multi-user machine, so this is safe.
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
@@ -43,7 +43,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-source
with:
key: llvm-source-17-linux-alpine-v1
key: llvm-source-18-linux-alpine-v1
path: |
llvm-project/clang/lib/Headers
llvm-project/clang/include
@@ -68,7 +68,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-build
with:
key: llvm-build-17-linux-alpine-v1
key: llvm-build-18-linux-alpine-v1
path: llvm-build
- name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
@@ -113,6 +113,8 @@ jobs:
gem install --version 4.0.7 public_suffix
gem install --version 2.7.6 dotenv
gem install --no-document fpm
- name: Run linter
run: make lint
- name: Build TinyGo release
run: |
make release deb -j3 STATIC=1
@@ -194,7 +196,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-source
with:
key: llvm-source-17-linux-asserts-v1
key: llvm-source-18-linux-asserts-v1
path: |
llvm-project/clang/lib/Headers
llvm-project/clang/include
@@ -219,7 +221,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-build
with:
key: llvm-build-17-linux-asserts-v1
key: llvm-build-18-linux-asserts-v1
path: llvm-build
- name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
@@ -307,7 +309,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-source
with:
key: llvm-source-17-linux-v1
key: llvm-source-18-linux-v1
path: |
llvm-project/clang/lib/Headers
llvm-project/clang/include
@@ -332,7 +334,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-build
with:
key: llvm-build-17-linux-${{ matrix.goarch }}-v1
key: llvm-build-18-linux-${{ matrix.goarch }}-v1
path: llvm-build
- name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
@@ -356,13 +358,13 @@ jobs:
uses: actions/cache@v4
id: cache-binaryen
with:
key: binaryen-linux-${{ matrix.goarch }}-v3
key: binaryen-linux-${{ matrix.goarch }}-v4
path: build/wasm-opt
- name: Build Binaryen
if: steps.cache-binaryen.outputs.cache-hit != 'true'
run: |
sudo apt-get install --no-install-recommends ninja-build
git submodule update --init --recursive lib/binaryen
git submodule update --init lib/binaryen
make CROSS=${{ matrix.toolchain }} binaryen
- name: Install fpm
run: |
+2 -2
View File
@@ -35,8 +35,8 @@ jobs:
uses: docker/metadata-action@v5
with:
images: |
tinygo/llvm-17
ghcr.io/${{ github.repository_owner }}/llvm-17
tinygo/llvm-18
ghcr.io/${{ github.repository_owner }}/llvm-18
tags: |
type=sha,format=long
type=raw,value=latest
+1 -1
View File
@@ -24,7 +24,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-source
with:
key: llvm-source-17-linux-nix-v1
key: llvm-source-18-linux-nix-v1
path: |
llvm-project/compiler-rt
- name: Download LLVM source
+5 -5
View File
@@ -2,11 +2,11 @@
# still works after checking out the dev branch (that is, when going from LLVM
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
echo 'deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main' | sudo tee /etc/apt/sources.list.d/llvm.list
echo 'deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main' | sudo tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install --no-install-recommends -y \
llvm-17-dev \
clang-17 \
libclang-17-dev \
lld-17
llvm-18-dev \
clang-18 \
libclang-18-dev \
lld-18
+2 -2
View File
@@ -28,7 +28,7 @@ jobs:
uses: actions/cache@v4
id: cache-llvm-source
with:
key: llvm-source-17-sizediff-v1
key: llvm-source-18-sizediff-v1
path: |
llvm-project/compiler-rt
- name: Download LLVM source
@@ -37,7 +37,7 @@ jobs:
- name: Cache Go
uses: actions/cache@v4
with:
key: go-cache-linux-sizediff-v1-${{ hashFiles('go.mod') }}
key: go-cache-linux-sizediff-v2-${{ hashFiles('go.mod') }}
path: |
~/.cache/go-build
~/go/pkg/mod
+2 -2
View File
@@ -41,7 +41,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-source
with:
key: llvm-source-17-windows-v1
key: llvm-source-18-windows-v1
path: |
llvm-project/clang/lib/Headers
llvm-project/clang/include
@@ -66,7 +66,7 @@ jobs:
uses: actions/cache/restore@v4
id: cache-llvm-build
with:
key: llvm-build-17-windows-v1
key: llvm-build-18-windows-v1
path: llvm-build
- name: Build LLVM
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
+1 -1
View File
@@ -85,7 +85,7 @@ Now that we have a working static build, it's time to make a release tarball:
If you did not clone the repository with the `--recursive` option, you will get errors until you initialize the project submodules:
git submodule update --init --recursive
git submodule update --init
The release tarball is stored in build/release.tar.gz, and can be extracted with
the following command (for example in ~/lib):
+13
View File
@@ -1,3 +1,16 @@
0.31.2
---
* **general**
* update the `net` submodule to updated version with `Buffers` implementation
* **compiler**
* `syscall`: add wasm_unknown tag to some additional files so it can compile more code
* **standard library**
* `runtime`: add Frame.Entry field
0.31.1
---
+1 -1
View File
@@ -27,7 +27,7 @@ COPY . /tinygo
# build the compiler and tools
RUN cd /tinygo/ && \
git submodule update --init --recursive && \
git submodule update --init && \
make gen-device -j4 && \
make build/release
+48 -15
View File
@@ -10,7 +10,7 @@ LLD_SRC ?= $(LLVM_PROJECTDIR)/lld
# Try to autodetect LLVM build tools.
# Versions are listed here in descending priority order.
LLVM_VERSIONS = 17 16 15
LLVM_VERSIONS = 18 17 16 15
errifempty = $(if $(1),$(1),$(error $(2)))
detect = $(shell which $(call errifempty,$(firstword $(foreach p,$(2),$(shell command -v $(p) 2> /dev/null && echo $(p)))),failed to locate $(1) at any of: $(2)))
toolSearchPathsVersion = $(1)-$(2)
@@ -31,6 +31,7 @@ export GOROOT = $(shell $(GO) env GOROOT)
# Flags to pass to go test.
GOTESTFLAGS ?=
GOTESTPKGS ?= ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
# tinygo binary for tests
TINYGO ?= $(call detect,tinygo,tinygo $(CURDIR)/build/tinygo)
@@ -110,7 +111,7 @@ endif
.PHONY: all tinygo test $(LLVM_BUILDDIR) llvm-source clean fmt gen-device gen-device-nrf gen-device-nxp gen-device-avr gen-device-rp
LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontendhlsl frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsdriver windowsmanifest
LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontenddriver frontendhlsl frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsdriver windowsmanifest
ifeq ($(OS),Windows_NT)
EXE = .exe
@@ -146,7 +147,7 @@ endif
MD5SUM ?= md5sum
# Libraries that should be linked in for the statically linked Clang.
CLANG_LIB_NAMES = clangAnalysis clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangExtractAPI clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangSupport clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions
CLANG_LIB_NAMES = clangAnalysis clangAPINotes clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangExtractAPI clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangSupport clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions
CLANG_LIBS = $(START_GROUP) $(addprefix -l,$(CLANG_LIB_NAMES)) $(END_GROUP) -lstdc++
# Libraries that should be linked in for the statically linked LLD.
@@ -165,7 +166,7 @@ LIB_NAMES = clang $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES)
# library path (for ninja).
# This list also includes a few tools that are necessary as part of the full
# TinyGo build.
NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIB_NAMES)))
NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm lld $(addprefix lib/lib,$(addsuffix .a,$(LIB_NAMES)))
# For static linking.
ifneq ("$(wildcard $(LLVM_BUILDDIR)/bin/llvm-config*)","")
@@ -190,7 +191,7 @@ gen-device: gen-device-stm32
endif
gen-device-avr:
@if [ ! -e lib/avr/README.md ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init --recursive"; exit 1; fi
@if [ ! -e lib/avr/README.md ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init"; exit 1; fi
$(GO) build -o ./build/gen-device-avr ./tools/gen-device-avr/
./build/gen-device-avr lib/avr/packs/atmega src/device/avr/
./build/gen-device-avr lib/avr/packs/tiny src/device/avr/
@@ -238,7 +239,7 @@ gen-device-renesas: build/gen-device-svd
# Get LLVM sources.
$(LLVM_PROJECTDIR)/llvm:
git clone -b xtensa_release_17.0.1 --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR)
git clone -b tinygo_xtensa_release_18.1.2 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
llvm-source: $(LLVM_PROJECTDIR)/llvm
# Configure LLVM.
@@ -264,7 +265,7 @@ endif
.PHONY: wasi-libc
wasi-libc: lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a
lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a:
@if [ ! -e lib/wasi-libc/Makefile ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init --recursive"; exit 1; fi
@if [ ! -e lib/wasi-libc/Makefile ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init"; exit 1; fi
cd lib/wasi-libc && $(MAKE) -j4 EXTRA_CFLAGS="-O2 -g -DNDEBUG -mnontrapping-fptoint -msign-ext" MALLOC_IMPL=none CC="$(CLANG)" AR=$(LLVM_AR) NM=$(LLVM_NM)
# Check for Node.js used during WASM tests.
@@ -283,7 +284,7 @@ tinygo:
@if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " $(MAKE) llvm-source"; echo " $(MAKE) $(LLVM_BUILDDIR)"; exit 1; fi
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOENVFLAGS) $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags "byollvm osusergo" -ldflags="-X github.com/tinygo-org/tinygo/goenv.GitSha1=`git rev-parse --short HEAD`" .
test: wasi-libc check-nodejs-version
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags "byollvm osusergo" ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags "byollvm osusergo" $(GOTESTPKGS)
# Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi
TEST_PACKAGES_SLOW = \
@@ -426,17 +427,17 @@ tinygo-bench-fast:
# Same thing, except for wasi rather than the current platform.
tinygo-test-wasi:
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
$(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
tinygo-test-wasip1:
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
tinygo-test-wasi-fast:
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
$(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
tinygo-test-wasip1-fast:
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
tinygo-bench-wasi:
$(TINYGO) test -target wasi -bench . $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW)
$(TINYGO) test -target wasip1 -bench . $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW)
tinygo-bench-wasi-fast:
$(TINYGO) test -target wasi -bench . $(TEST_PACKAGES_FAST)
$(TINYGO) test -target wasip1 -bench . $(TEST_PACKAGES_FAST)
# Test external packages in a large corpus.
test-corpus:
@@ -444,7 +445,7 @@ test-corpus:
test-corpus-fast:
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus -short . -corpus=testdata/corpus.yaml
test-corpus-wasi: wasi-libc
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml -target=wasi
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml -target=wasip1
tinygo-baremetal:
# Regression tests that run on a baremetal target and don't fit in either main_test.go or smoketest.
@@ -524,6 +525,8 @@ ifneq ($(WASM), 0)
@$(MD5SUM) test.wasm
$(TINYGO) build -size short -o test.wasm -tags=mch2022 examples/serial
@$(MD5SUM) test.wasm
$(TINYGO) build -size short -o test.wasm -tags=gopher_badge examples/blinky1
@$(MD5SUM) test.wasm
endif
# test all targets/boards
$(TINYGO) build -size short -o test.hex -target=pca10040-s132v6 examples/blinky1
@@ -598,6 +601,8 @@ endif
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pca10056-s140v7 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pca10059-s140v7 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=reelboard-s140v7 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=wioterminal examples/blinky1
@@ -654,6 +659,8 @@ endif
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=badger2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=badger2040-w examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=tufty2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=thingplus-rp2040 examples/blinky1
@@ -703,6 +710,8 @@ ifneq ($(STM32), 0)
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=nucleo-l432kc examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=nucleo-l476rg examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=nucleo-l552ze examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=nucleo-wl55jc examples/blinky1
@@ -759,6 +768,8 @@ ifneq ($(XTENSA), 0)
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target m5stick-c examples/serial
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target m5paper examples/serial
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target mch2022 examples/serial
@$(MD5SUM) test.bin
endif
@@ -818,7 +829,9 @@ build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN
@mkdir -p build/release/tinygo/lib/nrfx
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libc
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libm
@mkdir -p build/release/tinygo/lib/wasi-libc
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0plus
@mkdir -p build/release/tinygo/pkg/thumbv7em-unknown-unknown-eabi-cortex-m4
@@ -869,7 +882,15 @@ endif
@cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
@cp -rp lib/wasi-libc/libc-bottom-half/headers/public build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
@cp -rp lib/wasi-libc/libc-top-half/musl/src/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/internal build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/math build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/src/string build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/musl/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
@cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
@cp -rp llvm-project/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
@cp -rp src build/release/tinygo/src
@@ -896,3 +917,15 @@ ifneq ($(RELEASEONLY), 1)
release: build/release
deb: build/release
endif
lint:
go run github.com/mgechev/revive -version
# TODO: lint more directories!
# revive.toml isn't flexible enough to filter out just one kind of error from a checker, so do it with grep here.
# Can't use grep with friendly formatter. Plain output isn't too bad, though.
# Use 'grep .' to get rid of stray blank line
go run github.com/mgechev/revive -config revive.toml compiler/... src/{os,reflect}/*.go | grep -v "should have comment or be unexported" | grep '.' | awk '{print}; END {exit NR>0}'
spell:
# Check for typos in comments. Skip git submodules etc.
go run github.com/client9/misspell/cmd/misspell -i 'ackward,devided,extint,inbetween,programmmer,rela' $$( find . -depth 1 -type d | egrep -w -v 'lib|llvm|src/net' )
+3 -3
View File
@@ -41,7 +41,7 @@ tinygo flash -target arduino examples/blinky1
TinyGo is very useful for compiling programs both for use in browsers (WASM) as well as for use on servers and other edge devices (WASI).
TinyGo programs can run in Fastly Compute@Edge (https://developer.fastly.com/learning/compute/go/), Fermyon Spin (https://developer.fermyon.com/spin/go-components), wazero (https://wazero.io/languages/tinygo/) and many other WebAssembly runtimes.
TinyGo programs can run in [Fastly Compute](https://www.fastly.com/documentation/guides/compute/go/), [Fermyon Spin](https://developer.fermyon.com/spin/go-components), [wazero](https://wazero.io/languages/tinygo/) and many other WebAssembly runtimes.
Here is a small TinyGo program for use by a WASI host application:
@@ -54,14 +54,14 @@ func add(x, y uint32) uint32 {
return x + y
}
// main is required for the `wasi` target, even if it isn't used.
// main is required for the `wasip1` target, even if it isn't used.
func main() {}
```
This compiles the above TinyGo program for use on any WASI runtime:
```shell
tinygo build -o main.wasm -target=wasi main.go
tinygo build -o main.wasm -target=wasip1 main.go
```
## Installation
+16 -6
View File
@@ -78,17 +78,27 @@ func makeArchive(arfile *os.File, objs []string) error {
} else if dbg, err := wasm.Parse(objfile); err == nil {
for _, s := range dbg.Sections {
switch section := s.(type) {
case *wasm.SectionImport:
for _, ln := range section.Entries {
if ln.Kind != wasm.ExtKindFunction {
// Not a function
case *wasm.SectionLinking:
for _, symbol := range section.Symbols {
if symbol.Flags&wasm.LinkingSymbolFlagUndefined != 0 {
// Don't list undefined functions.
continue
}
if symbol.Flags&wasm.LinkingSymbolFlagBindingLocal != 0 {
// Don't include local symbols.
continue
}
if symbol.Kind != wasm.LinkingSymbolKindFunction && symbol.Kind != wasm.LinkingSymbolKindData {
// Link functions and data symbols.
// Some data symbols need to be included, such as
// __log_data.
continue
}
// Include in the archive.
symbolTable = append(symbolTable, struct {
name string
fileIndex int
}{ln.Field, i})
}{symbol.Name, i})
}
}
}
+33 -5
View File
@@ -168,6 +168,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
return BuildResult{}, errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?")
}
libcDependencies = append(libcDependencies, dummyCompileJob(path))
case "wasmbuiltins":
libcJob, unlock, err := WasmBuiltins.load(config, tmpdir)
if err != nil {
return BuildResult{}, err
}
defer unlock()
libcDependencies = append(libcDependencies, libcJob)
case "mingw-w64":
_, unlock, err := MinGW.load(config, tmpdir)
if err != nil {
@@ -200,6 +207,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
MaxStackAlloc: config.MaxStackAlloc(),
NeedsStackObjects: config.NeedsStackObjects(),
Debug: !config.Options.SkipDWARF, // emit DWARF except when -internal-nodwarf is passed
PanicStrategy: config.PanicStrategy(),
}
// Load the target machine, which is the LLVM object that contains all
@@ -235,6 +243,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
// Create the *ssa.Program. This does not yet build the entire SSA of the
// program so it's pretty fast and doesn't need to be parallelized.
program := lprogram.LoadSSA()
program.Build()
// Add jobs to compile each package.
// Packages that have a cache hit will not be compiled again.
@@ -346,8 +355,8 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
packageActionIDJobs[pkg.ImportPath] = packageActionIDJob
// Build the SSA for the given package.
ssaPkg := program.Package(pkg.Pkg)
ssaPkg.Build()
//ssaPkg := program.Package(pkg.Pkg)
//ssaPkg.Build()
// Now create the job to actually build the package. It will exit early
// if the package is already compiled.
@@ -362,7 +371,12 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
if _, err := os.Stat(job.result); err == nil {
// Already cached, don't recreate this package.
return nil
switch pkg.ImportPath {
case "context": // seems to be needed
case "time": // often crashes in this package, so probably needed
default:
return nil
}
}
// Compile AST to IR. The compiler.CompilePackage function will
@@ -509,6 +523,8 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
run: func(*compileJob) error {
// Load and link all the bitcode files. This does not yet optimize
// anything, it only links the bitcode files together.
println("exit")
os.Exit(0)
ctx := llvm.NewContext()
mod = ctx.NewModule("main")
for _, pkgJob := range packageJobs {
@@ -765,7 +781,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
if sizeLevel >= 2 {
// Workaround with roughly the same effect as
// https://reviews.llvm.org/D119342.
// Can hopefully be removed in LLVM 18.
// Can hopefully be removed in LLVM 19.
ldflags = append(ldflags,
"-mllvm", "--rotation-max-header-size=0")
}
@@ -817,13 +833,25 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
args = append(args, "--asyncify")
}
exeunopt := result.Executable
if config.Options.Work {
// Keep the work direction around => don't overwrite the .wasm binary with the optimized version
exeunopt += ".pre-wasm-opt"
os.Rename(result.Executable, exeunopt)
}
args = append(args,
opt,
"-g",
result.Executable,
exeunopt,
"--output", result.Executable,
)
if config.Options.PrintCommands != nil {
config.Options.PrintCommands(goenv.Get("WASMOPT"), args...)
}
cmd := exec.Command(goenv.Get("WASMOPT"), args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
+1 -1
View File
@@ -33,7 +33,7 @@ func TestClangAttributes(t *testing.T) {
"k210",
"nintendoswitch",
"riscv-qemu",
"wasi",
"wasip1",
"wasm",
"wasm-unknown",
}
+5 -7
View File
@@ -8,14 +8,14 @@ import (
"github.com/tinygo-org/tinygo/goenv"
)
// These are the GENERIC_SOURCES according to CMakeList.txt.
// These are the GENERIC_SOURCES according to CMakeList.txt except for
// divmodsi4.c and udivmodsi4.c.
var genericBuiltins = []string{
"absvdi2.c",
"absvsi2.c",
"absvti2.c",
"adddf3.c",
"addsf3.c",
"addtf3.c",
"addvdi3.c",
"addvsi3.c",
"addvti3.c",
@@ -40,12 +40,12 @@ var genericBuiltins = []string{
"divdf3.c",
"divdi3.c",
"divmoddi4.c",
//"divmodsi4.c",
"divmodti4.c",
"divsc3.c",
"divsf3.c",
"divsi3.c",
"divtc3.c",
"divti3.c",
"divtf3.c",
"extendsfdf2.c",
"extendhfsf2.c",
"ffsdi2.c",
@@ -91,7 +91,6 @@ var genericBuiltins = []string{
"mulsc3.c",
"mulsf3.c",
"multi3.c",
"multf3.c",
"mulvdi3.c",
"mulvsi3.c",
"mulvti3.c",
@@ -111,13 +110,11 @@ var genericBuiltins = []string{
"popcountti2.c",
"powidf2.c",
"powisf2.c",
"powitf2.c",
"subdf3.c",
"subsf3.c",
"subvdi3.c",
"subvsi3.c",
"subvti3.c",
"subtf3.c",
"trampoline_setup.c",
"truncdfhf2.c",
"truncdfsf2.c",
@@ -126,6 +123,7 @@ var genericBuiltins = []string{
"ucmpti2.c",
"udivdi3.c",
"udivmoddi4.c",
//"udivmodsi4.c",
"udivmodti4.c",
"udivsi3.c",
"udivti3.c",
+8 -7
View File
@@ -82,10 +82,10 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
// Parse the arguments.
const OptTable &OptTbl = getDriverOptTable();
const unsigned IncludedFlagsBitmask = options::CC1AsOption;
llvm::opt::Visibility VisibilityMask(options::CC1AsOption);
unsigned MissingArgIndex, MissingArgCount;
InputArgList Args = OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount,
IncludedFlagsBitmask);
InputArgList Args =
OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount, VisibilityMask);
// Check for missing argument error.
if (MissingArgCount) {
@@ -98,7 +98,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
auto ArgString = A->getAsString(Args);
std::string Nearest;
if (OptTbl.findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
if (OptTbl.findNearest(ArgString, Nearest, VisibilityMask) > 1)
Diags.Report(diag::err_drv_unknown_argument) << ArgString;
else
Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
@@ -521,9 +521,10 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
if (Asm.ShowHelp) {
getDriverOptTable().printHelp(
llvm::outs(), "clang -cc1as [options] file...",
"Clang Integrated Assembler",
/*Include=*/driver::options::CC1AsOption, /*Exclude=*/0,
/*ShowAllAliases=*/false);
"Clang Integrated Assembler", /*ShowHidden=*/false,
/*ShowAllAliases=*/false,
llvm::opt::Visibility(driver::options::CC1AsOption));
return 0;
}
+3 -3
View File
@@ -41,9 +41,9 @@ func TestBinarySize(t *testing.T) {
// This is a small number of very diverse targets that we want to test.
tests := []sizeTest{
// microcontrollers
{"hifive1b", "examples/echo", 4476, 280, 0, 2252},
{"microbit", "examples/serial", 2724, 388, 8, 2256},
{"wioterminal", "examples/pininterrupt", 5996, 1484, 116, 6816},
{"hifive1b", "examples/echo", 4484, 280, 0, 2252},
{"microbit", "examples/serial", 2732, 388, 8, 2256},
{"wioterminal", "examples/pininterrupt", 6016, 1484, 116, 6816},
// TODO: also check wasm. Right now this is difficult, because
// wasm binaries are run through wasm-opt and therefore the
+81
View File
@@ -0,0 +1,81 @@
package builder
import (
"os"
"path/filepath"
"github.com/tinygo-org/tinygo/goenv"
)
var WasmBuiltins = Library{
name: "wasmbuiltins",
makeHeaders: func(target, includeDir string) error {
if err := os.Mkdir(includeDir+"/bits", 0o777); err != nil {
return err
}
f, err := os.Create(includeDir + "/bits/alltypes.h")
if err != nil {
return err
}
if _, err := f.Write([]byte(wasmAllTypes)); err != nil {
return err
}
return f.Close()
},
cflags: func(target, headerPath string) []string {
libcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc")
return []string{
"-Werror",
"-Wall",
"-std=gnu11",
"-nostdlibinc",
"-isystem", libcDir + "/libc-top-half/musl/arch/wasm32",
"-isystem", libcDir + "/libc-top-half/musl/arch/generic",
"-isystem", libcDir + "/libc-top-half/musl/src/internal",
"-isystem", libcDir + "/libc-top-half/musl/src/include",
"-isystem", libcDir + "/libc-top-half/musl/include",
"-isystem", libcDir + "/libc-bottom-half/headers/public",
"-I" + headerPath,
}
},
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc") },
librarySources: func(target string) ([]string, error) {
return []string{
// memory builtins needed for llvm.memcpy.*, llvm.memmove.*, and
// llvm.memset.* LLVM intrinsics.
"libc-top-half/musl/src/string/memcpy.c",
"libc-top-half/musl/src/string/memmove.c",
"libc-top-half/musl/src/string/memset.c",
// exp, exp2, and log are needed for LLVM math builtin functions
// like llvm.exp.*.
"libc-top-half/musl/src/math/__math_divzero.c",
"libc-top-half/musl/src/math/__math_invalid.c",
"libc-top-half/musl/src/math/__math_oflow.c",
"libc-top-half/musl/src/math/__math_uflow.c",
"libc-top-half/musl/src/math/__math_xflow.c",
"libc-top-half/musl/src/math/exp.c",
"libc-top-half/musl/src/math/exp_data.c",
"libc-top-half/musl/src/math/exp2.c",
"libc-top-half/musl/src/math/log.c",
"libc-top-half/musl/src/math/log_data.c",
}, nil
},
}
// alltypes.h for wasm-libc, using the types as defined inside Clang.
const wasmAllTypes = `
typedef __SIZE_TYPE__ size_t;
typedef __INT8_TYPE__ int8_t;
typedef __INT16_TYPE__ int16_t;
typedef __INT32_TYPE__ int32_t;
typedef __INT64_TYPE__ int64_t;
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __UINTPTR_TYPE__ uintptr_t;
// This type is used internally in wasi-libc.
typedef double double_t;
`
+1 -1
View File
@@ -216,7 +216,7 @@ func (i simpleImporter) Import(path string) (*types.Package, error) {
}
}
// formatDiagnostics formats the error message to be an indented comment. It
// formatDiagnostic formats the error message to be an indented comment. It
// also fixes Windows path name issues (backward slashes).
func formatDiagnostic(err error) string {
msg := err.Error()
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build !byollvm && !llvm15 && !llvm16
//go:build !byollvm && llvm17
package cgo
+15
View File
@@ -0,0 +1,15 @@
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17
package cgo
/*
#cgo linux CFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -I/usr/lib/llvm-18/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@18/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@18/include
#cgo freebsd CFLAGS: -I/usr/local/llvm18/include
#cgo linux LDFLAGS: -L/usr/lib/llvm-18/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@18/lib -lclang
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@18/lib -lclang
#cgo freebsd LDFLAGS: -L/usr/local/llvm18/lib -lclang
*/
import "C"
+10 -5
View File
@@ -74,7 +74,8 @@ func (c *Config) GOARM() string {
// BuildTags returns the complete list of build tags used during this build.
func (c *Config) BuildTags() []string {
tags := append(c.Target.BuildTags, []string{
tags := append([]string(nil), c.Target.BuildTags...) // copy slice (avoid a race)
tags = append(tags, []string{
"tinygo", // that's the compiler
"purego", // to get various crypto packages to work
"math_big_pure_go", // to get math/big to work
@@ -310,7 +311,11 @@ func (c *Config) CFlags(libclang bool) []string {
)
case "wasi-libc":
root := goenv.Get("TINYGOROOT")
cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot")
cflags = append(cflags,
"-nostdlibinc",
"-isystem", root+"/lib/wasi-libc/sysroot/include")
case "wasmbuiltins":
// nothing to add (library is purely for builtins)
case "mingw-w64":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("mingw-w64")
@@ -475,9 +480,6 @@ func (c *Config) OpenOCDConfiguration() (args []string, err error) {
return nil, fmt.Errorf("unknown OpenOCD transport: %#v", c.Target.OpenOCDTransport)
}
args = []string{"-f", "interface/" + openocdInterface + ".cfg"}
for _, cmd := range c.Target.OpenOCDCommands {
args = append(args, "-c", cmd)
}
if c.Target.OpenOCDTransport != "" {
transport := c.Target.OpenOCDTransport
if transport == "swd" {
@@ -489,6 +491,9 @@ func (c *Config) OpenOCDConfiguration() (args []string, err error) {
args = append(args, "-c", "transport select "+transport)
}
args = append(args, "-f", "target/"+c.Target.OpenOCDTarget+".cfg")
for _, cmd := range c.Target.OpenOCDCommands {
args = append(args, "-c", cmd)
}
return args, nil
}
+4 -4
View File
@@ -26,7 +26,7 @@ type TargetSpec struct {
Inherits []string `json:"inherits,omitempty"`
Triple string `json:"llvm-target,omitempty"`
CPU string `json:"cpu,omitempty"`
ABI string `json:"target-abi,omitempty"` // rougly equivalent to -mabi= flag
ABI string `json:"target-abi,omitempty"` // roughly equivalent to -mabi= flag
Features string `json:"features,omitempty"`
GOOS string `json:"goos,omitempty"`
GOARCH string `json:"goarch,omitempty"`
@@ -319,11 +319,11 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
case "arm64":
spec.CPU = "generic"
if goos == "darwin" {
spec.Features = "+neon"
spec.Features = "+fp-armv8,+neon"
} else if goos == "windows" {
spec.Features = "+neon,-fmv"
spec.Features = "+fp-armv8,+neon,-fmv"
} else { // linux
spec.Features = "+neon,-fmv,-outline-atomics"
spec.Features = "+fp-armv8,+neon,-fmv,-outline-atomics"
}
case "wasm":
spec.CPU = "generic"
+6 -2
View File
@@ -16,14 +16,18 @@ import "tinygo.org/x/go-llvm"
var stdlibAliases = map[string]string{
// crypto packages
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
"crypto/ed25519/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
"crypto/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
"crypto/md5.block": "crypto/md5.blockGeneric",
"crypto/sha1.block": "crypto/sha1.blockGeneric",
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
"crypto/sha256.block": "crypto/sha256.blockGeneric",
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
// AES
"crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock",
"crypto/aes.encryptBlockAsm": "crypto/aes.encryptBlock",
// math package
"math.archHypot": "math.hypot",
"math.archMax": "math.max",
+2 -2
View File
@@ -135,7 +135,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
// Calculate (^uintptr(0)) >> 1, which is the max value that fits in an
// uintptr if uintptrs were signed.
maxBufSize := llvm.ConstLShr(llvm.ConstNot(llvm.ConstInt(b.uintptrType, 0, false)), llvm.ConstInt(b.uintptrType, 1, false))
maxBufSize := b.CreateLShr(llvm.ConstNot(llvm.ConstInt(b.uintptrType, 0, false)), llvm.ConstInt(b.uintptrType, 1, false), "")
if elementSize > maxBufSize.ZExtValue() {
b.addError(pos, fmt.Sprintf("channel element type is too big (%v bytes)", elementSize))
return
@@ -150,7 +150,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
// Make sure maxBufSize has the same type as bufSize.
if maxBufSize.Type() != bufSize.Type() {
maxBufSize = llvm.ConstZExt(maxBufSize, bufSize.Type())
maxBufSize = b.CreateZExt(maxBufSize, bufSize.Type(), "")
}
// Do the check for a too large (or negative) buffer size.
+10 -2
View File
@@ -56,6 +56,7 @@ type Config struct {
MaxStackAlloc uint64
NeedsStackObjects bool
Debug bool // Whether to emit debug information in the LLVM module.
PanicStrategy string
}
// compilerContext contains function-independent data that should still be
@@ -1855,6 +1856,13 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
supportsRecover = 1
}
return llvm.ConstInt(b.ctx.Int1Type(), supportsRecover, false), nil
case name == "runtime.panicStrategy":
// These constants are defined in src/runtime/panic.go.
panicStrategy := map[string]uint64{
"print": 1, // panicStrategyPrint
"trap": 2, // panicStrategyTrap
}[b.Config.PanicStrategy]
return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil
case name == "runtime/interrupt.New":
return b.createInterruptGlobal(instr)
}
@@ -2173,7 +2181,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
return llvm.Value{}, b.makeError(expr.Pos(), "todo: indexaddr: "+ptrTyp.String())
}
// Make sure index is at least the size of uintptr becuase getelementptr
// Make sure index is at least the size of uintptr because getelementptr
// assumes index is a signed integer.
index = b.extendInteger(index, expr.Index.Type(), b.uintptrType)
@@ -2549,7 +2557,7 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va
sizeY := b.targetData.TypeAllocSize(y.Type())
// Check if the shift is bigger than the bit-width of the shifted value.
// This is UB in LLVM, so it needs to be handled seperately.
// This is UB in LLVM, so it needs to be handled separately.
// The Go spec indirectly defines the result as 0.
// Negative shifts are handled earlier, so we can treat y as unsigned.
overshifted := b.CreateICmp(llvm.IntUGE, y, llvm.ConstInt(y.Type(), 8*sizeX, false), "shift.overflow")
+9 -6
View File
@@ -124,16 +124,19 @@ func (c *compilerContext) pkgPathPtr(pkgpath string) llvm.Value {
func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
ms := c.program.MethodSets.MethodSet(typ)
hasMethodSet := ms.Len() != 0
if _, ok := typ.Underlying().(*types.Interface); ok {
_, isInterface := typ.Underlying().(*types.Interface)
if isInterface {
hasMethodSet = false
}
// As defined in https://pkg.go.dev/reflect#Type:
// NumMethod returns the number of methods accessible using Method.
// For a non-interface type, it returns the number of exported methods.
// For an interface type, it returns the number of exported and unexported methods.
var numMethods int
if hasMethodSet {
for i := 0; i < ms.Len(); i++ {
if ms.At(i).Obj().Exported() {
numMethods++
}
for i := 0; i < ms.Len(); i++ {
if isInterface || ms.At(i).Obj().Exported() {
numMethods++
}
}
+10
View File
@@ -23,6 +23,8 @@ func (b *builder) defineIntrinsicFunction() {
b.createMemoryCopyImpl()
case name == "runtime.memzero":
b.createMemoryZeroImpl()
case name == "runtime.stacksave":
b.createStackSaveImpl()
case name == "runtime.KeepAlive":
b.createKeepAliveImpl()
case strings.HasPrefix(name, "runtime/volatile.Load"):
@@ -77,6 +79,14 @@ func (b *builder) createMemoryZeroImpl() {
b.CreateRetVoid()
}
// createStackSaveImpl creates a call to llvm.stacksave.p0 to read the current
// stack pointer.
func (b *builder) createStackSaveImpl() {
b.createFunctionStart(true)
sp := b.readStackPointer()
b.CreateRet(sp)
}
// Return the llvm.memset.p0.i8 function declaration.
func (c *compilerContext) getMemsetFunc() llvm.Value {
fnName := "llvm.memset.p0.i" + strconv.Itoa(c.uintptrType.IntTypeWidth())
+6 -2
View File
@@ -451,10 +451,14 @@ func (c *compilerContext) isThumb() bool {
// readStackPointer emits a LLVM intrinsic call that returns the current stack
// pointer as an *i8.
func (b *builder) readStackPointer() llvm.Value {
stacksave := b.mod.NamedFunction("llvm.stacksave")
name := "llvm.stacksave.p0"
if llvmutil.Version() < 18 {
name = "llvm.stacksave" // backwards compatibility with LLVM 17 and below
}
stacksave := b.mod.NamedFunction(name)
if stacksave.IsNil() {
fnType := llvm.FunctionType(b.dataPtrType, nil, false)
stacksave = llvm.AddFunction(b.mod, "llvm.stacksave", fnType)
stacksave = llvm.AddFunction(b.mod, name, fnType)
}
return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "")
}
+16 -3
View File
@@ -1,5 +1,5 @@
// Package llvmutil contains utility functions used across multiple compiler
// packages. For example, they may be used by both the compiler pacakge and
// packages. For example, they may be used by both the compiler package and
// transformation packages.
//
// Normally, utility packages are avoided. However, in this case, the utility
@@ -8,6 +8,9 @@
package llvmutil
import (
"strconv"
"strings"
"tinygo.org/x/go-llvm"
)
@@ -28,7 +31,7 @@ func CreateEntryBlockAlloca(builder llvm.Builder, t llvm.Type, name string) llvm
}
// CreateTemporaryAlloca creates a new alloca in the entry block and adds
// lifetime start infromation in the IR signalling that the alloca won't be used
// lifetime start information in the IR signalling that the alloca won't be used
// before this point.
//
// This is useful for creating temporary allocas for intrinsics. Don't forget to
@@ -173,7 +176,7 @@ func SplitBasicBlock(builder llvm.Builder, afterInst llvm.Value, insertAfter llv
return newBlock
}
// Append the given values to a global array like llvm.used. The global might
// AppendToGlobal appends the given values to a global array like llvm.used. The global might
// not exist yet. The values can be any pointer type, they will be cast to i8*.
func AppendToGlobal(mod llvm.Module, globalName string, values ...llvm.Value) {
// Read the existing values in the llvm.used array (if it exists).
@@ -203,3 +206,13 @@ func AppendToGlobal(mod llvm.Module, globalName string, values ...llvm.Value) {
used.SetInitializer(usedInitializer)
used.SetLinkage(llvm.AppendingLinkage)
}
// Return the LLVM major version.
func Version() int {
majorStr := strings.Split(llvm.Version, ".")[0]
major, err := strconv.Atoi(majorStr)
if err != nil {
panic("unexpected error while parsing LLVM version: " + err.Error()) // should not happen
}
return major
}
+2 -2
View File
@@ -81,11 +81,11 @@ entry:
%select.send.value = alloca i32, align 4
store i32 1, ptr %select.send.value, align 4
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
store ptr %ch1, ptr %select.states.alloca, align 8
store ptr %ch1, ptr %select.states.alloca, align 4
%select.states.alloca.repack1 = getelementptr inbounds %runtime.chanSelectState, ptr %select.states.alloca, i32 0, i32 1
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
%0 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1
store ptr %ch2, ptr %0, align 8
store ptr %ch2, ptr %0, align 4
%.repack3 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1, i32 1
store ptr null, ptr %.repack3, align 4
%select.result = call { i32, i1 } @runtime.tryChanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr undef) #4
+3 -3
View File
@@ -25,7 +25,7 @@ entry:
%deferPtr = alloca ptr, align 4
store ptr null, ptr %deferPtr, align 4
%deferframe.buf = alloca %runtime.deferFrame, align 4
%0 = call ptr @llvm.stacksave()
%0 = call ptr @llvm.stacksave.p0()
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
store i32 0, ptr %defer.alloca, align 4
%defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
@@ -113,7 +113,7 @@ rundefers.end3: ; preds = %rundefers.loophead6
}
; Function Attrs: nocallback nofree nosync nounwind willreturn
declare ptr @llvm.stacksave() #3
declare ptr @llvm.stacksave.p0() #3
declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #2
@@ -136,7 +136,7 @@ entry:
%deferPtr = alloca ptr, align 4
store ptr null, ptr %deferPtr, align 4
%deferframe.buf = alloca %runtime.deferFrame, align 4
%0 = call ptr @llvm.stacksave()
%0 = call ptr @llvm.stacksave.p0()
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
store i32 0, ptr %defer.alloca, align 4
%defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
+9 -9
View File
@@ -16,9 +16,9 @@ target triple = "wasm32-unknown-wasi"
@main.struct2 = hidden global ptr null, align 4
@main.struct3 = hidden global ptr null, align 4
@main.struct4 = hidden global ptr null, align 4
@main.slice1 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
@main.slice2 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
@main.slice3 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
@main.slice1 = hidden global { ptr, i32, i32 } zeroinitializer, align 4
@main.slice2 = hidden global { ptr, i32, i32 } zeroinitializer, align 4
@main.slice3 = hidden global { ptr, i32, i32 } zeroinitializer, align 4
@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " }
@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00\00" }
@"reflect/types.type:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 80, ptr @"reflect/types.type:pointer:basic:complex128" }, align 4
@@ -104,19 +104,19 @@ entry:
%stackalloc = alloca i8, align 1
%makeslice = call dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
store ptr %makeslice, ptr @main.slice1, align 8
store ptr %makeslice, ptr @main.slice1, align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 4
%makeslice1 = call dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #3
store ptr %makeslice1, ptr @main.slice2, align 8
store ptr %makeslice1, ptr @main.slice2, align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 4
%makeslice3 = call dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #3
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #3
store ptr %makeslice3, ptr @main.slice3, align 8
store ptr %makeslice3, ptr @main.slice3, align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 4
ret void
}
+1 -1
View File
@@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi"
@"reflect/types.type:basic:int" = linkonce_odr constant { i8, ptr } { i8 -62, ptr @"reflect/types.type:pointer:basic:int" }, align 4
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:basic:int" }, align 4
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:named:error" }, align 4
@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, i16 0, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [7 x i8] c".error\00" }, align 4
@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, i16 1, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [7 x i8] c".error\00" }, align 4
@"reflect/types.type.pkgpath.empty" = linkonce_odr unnamed_addr constant [1 x i8] zeroinitializer, align 1
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 84, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" }, align 4
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}" }, align 4
+2 -2
View File
@@ -122,7 +122,7 @@ entry:
br i1 %slice.maxcap, label %slice.throw, label %slice.next
slice.next: ; preds = %entry
%makeslice.cap = shl i32 %len, 1
%makeslice.cap = shl nuw i32 %len, 1
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
@@ -164,7 +164,7 @@ entry:
br i1 %slice.maxcap, label %slice.throw, label %slice.next
slice.next: ; preds = %entry
%makeslice.cap = shl i32 %len, 2
%makeslice.cap = shl nuw i32 %len, 2
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
+4 -4
View File
@@ -26,7 +26,7 @@ entry:
%2 = insertvalue %main.hasPadding %1, i1 %s.b2, 2
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
store %main.hasPadding %2, ptr %hashmap.key, align 8
store %main.hasPadding %2, ptr %hashmap.key, align 4
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
@@ -59,7 +59,7 @@ entry:
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
store i32 5, ptr %hashmap.value, align 4
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
store %main.hasPadding %2, ptr %hashmap.key, align 8
store %main.hasPadding %2, ptr %hashmap.key, align 4
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
@@ -80,7 +80,7 @@ entry:
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
store %main.hasPadding %s.elt, ptr %hashmap.key, align 8
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
%hashmap.key.repack1 = getelementptr inbounds [2 x %main.hasPadding], ptr %hashmap.key, i32 0, i32 1
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
@@ -108,7 +108,7 @@ entry:
store i32 5, ptr %hashmap.value, align 4
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
store %main.hasPadding %s.elt, ptr %hashmap.key, align 8
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
%hashmap.key.repack1 = getelementptr inbounds [2 x %main.hasPadding], ptr %hashmap.key, i32 0, i32 1
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
+3 -2
View File
@@ -51,6 +51,7 @@ func TestCorpus(t *testing.T) {
if *testTarget != "" {
target = *testTarget
}
isWASI := strings.HasPrefix(target, "wasi")
repos, err := loadRepos(*corpus)
if err != nil {
@@ -69,7 +70,7 @@ func TestCorpus(t *testing.T) {
t.Run(name, func(t *testing.T) {
t.Parallel()
if target == "wasi" && repo.SkipWASI {
if isWASI && repo.SkipWASI {
t.Skip("skip wasi")
}
if repo.Slow && testing.Short() {
@@ -135,7 +136,7 @@ func TestCorpus(t *testing.T) {
t.Run(dir.Pkg, func(t *testing.T) {
t.Parallel()
if target == "wasi" && dir.SkipWASI {
if isWASI && dir.SkipWASI {
t.Skip("skip wasi")
}
if dir.Slow && testing.Short() {
+5 -6
View File
@@ -18,10 +18,10 @@
#
# But you'll need a bit more to make TinyGo actually able to compile code:
#
# make llvm-source # fetch compiler-rt
# git submodule update --init --recursive # fetch lots of other libraries and SVD files
# make gen-device -j4 # build src/device/*/*.go files
# make wasi-libc # build support for wasi/wasm
# make llvm-source # fetch compiler-rt
# git submodule update --init # fetch lots of other libraries and SVD files
# make gen-device -j4 # build src/device/*/*.go files
# make wasi-libc # build support for wasi/wasm
#
# With this, you should have an environment that can compile anything - except
# for the Xtensa architecture (ESP8266/ESP32) because support for that lives in
@@ -51,7 +51,6 @@
go
llvmPackages_17.llvm
llvmPackages_17.libclang
llvmPackages_17.libcxx
# Additional dependencies needed at runtime, for building and/or
# flashing.
llvmPackages_17.lld
@@ -78,7 +77,7 @@
export MD5SUM=md5sum
# Ugly hack to make the Clang resources directory available.
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_17.clang.cc.lib}/lib/clang/17"\"
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_17.clang.cc.lib}/lib/clang/17\" -tags=llvm17"
'';
};
}
+16 -4
View File
@@ -3,33 +3,45 @@ module github.com/tinygo-org/tinygo
go 1.18
require (
github.com/aykevl/go-wasm v0.0.2-0.20220616010729-4a0a888aebdc
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee
github.com/chromedp/chromedp v0.7.6
github.com/client9/misspell v0.3.4
github.com/gofrs/flock v0.8.1
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/mattn/go-colorable v0.1.8
github.com/mattn/go-colorable v0.1.13
github.com/mattn/go-tty v0.0.4
github.com/mgechev/revive v1.3.7
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
go.bug.st/serial v1.6.0
golang.org/x/net v0.20.0
golang.org/x/sys v0.16.0
golang.org/x/tools v0.17.0
gopkg.in/yaml.v2 v2.4.0
tinygo.org/x/go-llvm v0.0.0-20240106122909-c2c543540318
tinygo.org/x/go-llvm v0.0.0-20240518103902-697964f2a9dc
)
require (
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/chavacava/garif v0.1.0 // indirect
github.com/chromedp/sysutil v1.0.0 // indirect
github.com/creack/goselect v0.1.2 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/spf13/afero v1.11.0 // indirect
golang.org/x/text v0.14.0 // indirect
)
+49 -13
View File
@@ -1,7 +1,11 @@
github.com/aykevl/go-wasm v0.0.2-0.20220616010729-4a0a888aebdc h1:Yp49g+qqgQRPk/gcRSmAsXgnT16XPJ6Y5JM1poc6gYM=
github.com/aykevl/go-wasm v0.0.2-0.20220616010729-4a0a888aebdc/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c h1:4T0Vj1UkGgcpkRrmn7SbokebnlfxJcMZPgWtOYACAAA=
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw=
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI=
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc=
github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww=
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee h1:+SFdIVfQpG0s0DHYzou0kgfE0n0ZjKPwbiRJsXrZegU=
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
@@ -9,9 +13,17 @@ github.com/chromedp/chromedp v0.7.6 h1:2juGaktzjwULlsn+DnvIZXFUckEp5xs+GOBroaea+
github.com/chromedp/chromedp v0.7.6/go.mod h1:ayT4YU/MGAALNfOg9gNrpGSAdnU51PMx+FCeuT1iXzo=
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
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/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
@@ -31,21 +43,43 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
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/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/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
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/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/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/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0=
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE=
github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
go.bug.st/serial v1.6.0 h1:mAbRGN4cKE2J5gMwsMHC2KQisdLRQssO9WSM+rbZJ8A=
go.bug.st/serial v1.6.0/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
@@ -54,10 +88,10 @@ golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
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-20200223170610-d5e6a3e2c0ae/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
@@ -68,6 +102,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
tinygo.org/x/go-llvm v0.0.0-20240106122909-c2c543540318 h1:4KjZvPtcN1UwobevcGbdzeinx0L1i8HDdJu84bu7NI8=
tinygo.org/x/go-llvm v0.0.0-20240106122909-c2c543540318/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
tinygo.org/x/go-llvm v0.0.0-20240518103902-697964f2a9dc h1:TCzibFa4oLu+njEP3fnRUmZ+QQeb8BjtOwctgcjzL0k=
tinygo.org/x/go-llvm v0.0.0-20240518103902-697964f2a9dc/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+1 -1
View File
@@ -9,7 +9,7 @@ import (
// Version of TinyGo.
// Update this value before release of new version of software.
const version = "0.31.1"
const version = "0.32.0-dev"
var (
// This variable is set at build time using -ldflags parameters.
+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash
# Docker hub does a recursive clone, then checks the branch out,
# so when a PR adds a submodule (or updates it), it fails.
git submodule update --init --recursive
git submodule update --init
+10
View File
@@ -0,0 +1,10 @@
//go:build tools
// Install linter versions specified in go.mod
// See https://marcofranssen.nl/manage-go-tools-via-go-modules for idom
package tools
import (
_ "github.com/client9/misspell"
_ "github.com/mgechev/revive"
)
+12 -1
View File
@@ -427,9 +427,20 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
if err != nil {
return nil, mem, r.errorAt(inst, err)
}
// typecodePtr always point to the numMethod field in the type
// description struct. The methodSet, when present, comes right
// before the numMethod field (the compiler doesn't generate
// method sets for concrete types without methods).
// Considering that the compiler doesn't emit interface type
// asserts for interfaces with no methods (as the always succeed)
// then if the offset is zero, this assert must always fail.
if typecodePtr.offset() == 0 {
locals[inst.localIndex] = literalValue{uint8(0)}
break
}
typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize))
if err != nil {
return nil, mem, r.errorAt(inst, err) // unlikely
return nil, mem, r.errorAt(inst, err)
}
methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r)
if err != nil {
+1 -1
View File
@@ -214,7 +214,7 @@ func listGorootMergeLinks(goroot, tinygoroot string, overrides map[string]bool)
return merges, nil
}
// needsSyscallPackage returns whether the syscall package should be overriden
// needsSyscallPackage returns whether the syscall package should be overridden
// with the TinyGo version. This is the case on some targets.
func needsSyscallPackage(buildTags []string) bool {
for _, tag := range buildTags {
+1 -1
View File
@@ -430,7 +430,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) {
var files []*ast.File
var fileErrs []error
// Parse all files (incuding CgoFiles).
// Parse all files (including CgoFiles).
parseFile := func(file string) {
if !filepath.IsAbs(file) {
file = filepath.Join(p.Dir, file)
+5 -4
View File
@@ -285,7 +285,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
// Tests are always run in the package directory.
cmd.Dir = result.MainDir
// wasmtime is the default emulator used for `-target=wasi`. wasmtime
// wasmtime is the default emulator used for `-target=wasip1`. 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
@@ -1033,9 +1033,10 @@ func findFATMounts(options *compileopts.Options) ([]mountPoint, error) {
if fstype != "vfat" {
continue
}
fspath := strings.ReplaceAll(fields[1], "\\040", " ")
points = append(points, mountPoint{
name: filepath.Base(fields[1]),
path: fields[1],
name: filepath.Base(fspath),
path: fspath,
})
}
return points, nil
@@ -1411,7 +1412,7 @@ func main() {
gc := flag.String("gc", "", "garbage collector to use (none, leaking, conservative)")
panicStrategy := flag.String("panic", "print", "panic strategy (print, trap)")
scheduler := flag.String("scheduler", "", "which scheduler to use (none, tasks, asyncify)")
serial := flag.String("serial", "", "which serial output to use (none, uart, usb)")
serial := flag.String("serial", "", "which serial output to use (none, uart, usb, rtt)")
work := flag.Bool("work", false, "print the name of the temporary build directory and do not delete this directory on exit")
interpTimeout := flag.Duration("interp-timeout", 180*time.Second, "interp optimization pass timeout")
var tags buildutil.TagsFlag
+68 -5
View File
@@ -15,11 +15,13 @@ import (
"reflect"
"regexp"
"runtime"
"slices"
"strings"
"sync"
"testing"
"time"
"github.com/aykevl/go-wasm"
"github.com/tinygo-org/tinygo/builder"
"github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/goenv"
@@ -177,7 +179,7 @@ func TestBuild(t *testing.T) {
})
t.Run("WASI", func(t *testing.T) {
t.Parallel()
runPlatTests(optionsFromTarget("wasi", sema), tests, t)
runPlatTests(optionsFromTarget("wasip1", sema), tests, t)
})
}
}
@@ -190,7 +192,10 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
t.Fatal("failed to load target spec:", err)
}
isWebAssembly := options.Target == "wasi" || options.Target == "wasm" || (options.Target == "" && options.GOARCH == "wasm")
// FIXME: this should really be:
// isWebAssembly := strings.HasPrefix(spec.Triple, "wasm")
isWASI := strings.HasPrefix(options.Target, "wasi")
isWebAssembly := isWASI || strings.HasPrefix(options.Target, "wasm") || (options.Target == "" && strings.HasPrefix(options.GOARCH, "wasm"))
for _, name := range tests {
if options.GOOS == "linux" && (options.GOARCH == "arm" || options.GOARCH == "386") {
@@ -250,13 +255,13 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
runTest("alias.go", options, t, nil, nil)
})
}
if options.Target == "" || options.Target == "wasi" {
if options.Target == "" || isWASI {
t.Run("filesystem.go", func(t *testing.T) {
t.Parallel()
runTest("filesystem.go", options, t, nil, nil)
})
}
if options.Target == "" || options.Target == "wasi" || options.Target == "wasm" {
if options.Target == "" || options.Target == "wasm" || isWASI {
t.Run("rand.go", func(t *testing.T) {
t.Parallel()
runTest("rand.go", options, t, nil, nil)
@@ -404,6 +409,64 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
}
}
// Test WebAssembly files for certain properties.
func TestWebAssembly(t *testing.T) {
t.Parallel()
type testCase struct {
name string
panicStrategy string
imports []string
}
for _, tc := range []testCase{
// Test whether there really are no imports when using -panic=trap. This
// tests the bugfix for https://github.com/tinygo-org/tinygo/issues/4161.
{name: "panic-default", imports: []string{"wasi_snapshot_preview1.fd_write"}},
{name: "panic-trap", panicStrategy: "trap", imports: []string{}},
} {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
tmpdir := t.TempDir()
options := optionsFromTarget("wasi", sema)
options.PanicStrategy = tc.panicStrategy
config, err := builder.NewConfig(&options)
if err != nil {
t.Fatal(err)
}
result, err := builder.Build("testdata/trivialpanic.go", ".wasm", tmpdir, config)
if err != nil {
t.Fatal("failed to build binary:", err)
}
f, err := os.Open(result.Binary)
if err != nil {
t.Fatal("could not open output binary:", err)
}
defer f.Close()
module, err := wasm.Parse(f)
if err != nil {
t.Fatal("could not parse output binary:", err)
}
// Test the list of imports.
if tc.imports != nil {
var imports []string
for _, section := range module.Sections {
switch section := section.(type) {
case *wasm.SectionImport:
for _, symbol := range section.Entries {
imports = append(imports, symbol.Module+"."+symbol.Field)
}
}
}
if !slices.Equal(imports, tc.imports) {
t.Errorf("import list not as expected!\nexpected: %v\nactual: %v", tc.imports, imports)
}
}
})
}
}
func TestTest(t *testing.T) {
t.Parallel()
@@ -432,7 +495,7 @@ func TestTest(t *testing.T) {
// Node/Wasmtime
targ{"WASM", optionsFromTarget("wasm", sema)},
targ{"WASI", optionsFromTarget("wasi", sema)},
targ{"WASI", optionsFromTarget("wasip1", sema)},
)
}
for _, targ := range targs {
+35
View File
@@ -0,0 +1,35 @@
ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 0
warningCode = 0
# Enable these as we fix them
[rule.blank-imports]
Exclude=["src/os/file_other.go"]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.dot-imports]
Exclude=["**/*_test.go"]
[rule.error-return]
[rule.error-strings]
[rule.error-naming]
[rule.exported]
Exclude=["src/reflect/*.go"]
[rule.increment-decrement]
[rule.var-naming]
Exclude=["src/os/*.go"]
[rule.var-declaration]
#[rule.package-comments]
[rule.range]
[rule.receiver-naming]
[rule.time-naming]
[rule.unexported-return]
#[rule.indent-error-flow]
[rule.errorf]
#[rule.empty-block]
[rule.superfluous-else]
#[rule.unused-parameter]
[rule.unreachable-code]
Exclude=["src/reflect/visiblefields_test.go", "src/reflect/all_test.go"]
#[rule.redefines-builtin-id]
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build linux && !baremetal && !wasi
//go:build linux && !baremetal && !wasip1
// This implementation of crypto/rand uses the /dev/urandom pseudo-file to
// generate random numbers.
+2 -2
View File
@@ -57,7 +57,7 @@ func Count(b []byte, c byte) int {
// Count the number of instances of a byte in a string.
func CountString(s string, c byte) int {
// Use a simple implementation, as there is no intrinsic that does this like we want.
// Currently, the compiler does not generate zero-copy byte-string conversions, so this needs to be seperate from Count.
// Currently, the compiler does not generate zero-copy byte-string conversions, so this needs to be separate from Count.
n := 0
for i := 0; i < len(s); i++ {
if s[i] == c {
@@ -216,7 +216,7 @@ func HashStrRev[T string | []byte](sep T) (uint32, uint32) {
}
// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
// first occurence of substr in s, or -1 if not present.
// first occurrence of substr in s, or -1 if not present.
//
// This function was removed in Go 1.22.
func IndexRabinKarpBytes(s, sep []byte) int {
+1 -1
View File
@@ -44,7 +44,7 @@ func Current() *Task {
// This function may only be called when running on a goroutine stack, not when running on the system stack or in an interrupt.
func Pause() {
// Check whether the canary (the lowest address of the stack) is still
// valid. If it is not, a stack overflow has occured.
// valid. If it is not, a stack overflow has occurred.
if *currentTask.state.canaryPtr != stackCanary {
runtimePanic("goroutine stack overflow")
}
+1 -1
View File
@@ -28,7 +28,7 @@ tinygo_startTask:
// After return, exit this goroutine. This is a tail call.
#if __AVR_ARCH__ == 2 || __AVR_ARCH__ == 25
// Small memory devices (8kB flash) that do not have the long call
// instruction availble will need to use rcall instead.
// instruction available will need to use rcall instead.
// Note that they will probably not be able to run more than the main
// goroutine anyway, but this file is compiled for all AVRs so it needs to
// compile at least.
+1 -1
View File
@@ -78,7 +78,7 @@ tinygo_swapTask:
// Switch to the new stack pointer (newStack).
mov.n sp, a2
// Load a0, which is the previous return addres from before the previous
// Load a0, which is the previous return address from before the previous
// switch or the constructed return address to tinygo_startTask. This
// register also stores the parent register window.
l32i.n a0, sp, 0
@@ -0,0 +1,125 @@
//go:build adafruit_esp32_feather_v2
package machine
const GPIO20 Pin = 20
const (
IO0 = GPIO0
IO2 = GPIO2
IO4 = GPIO4
IO5 = GPIO5
IO7 = GPIO7
IO8 = GPIO8
IO12 = GPIO12
IO13 = GPIO13
IO14 = GPIO14
IO15 = GPIO15
IO19 = GPIO19
IO20 = GPIO20
IO21 = GPIO21
IO22 = GPIO22
IO25 = GPIO25
IO26 = GPIO26
IO27 = GPIO27
IO32 = GPIO32
IO33 = GPIO33
IO34 = GPIO34
IO35 = GPIO35
IO36 = GPIO36
IO37 = GPIO37
IO38 = GPIO38
IO39 = GPIO39
)
// Digital pins
const (
D12 = IO12
D13 = IO13
D14 = IO14
D15 = IO15
D27 = IO27
D32 = IO32
D33 = IO33
D37 = IO37
)
// Analog pins
const (
A0 = IO26
A1 = IO25
A2 = IO34
A3 = IO39
A4 = IO36
A5 = IO4
)
// Built-in LEDs and Button
const (
WS2812 = IO0
NEOPIXEL = WS2812
NEOPIXEL_I2C_POWER = IO2
LED = IO13
BUTTON = IO38
)
// SPI pins
const (
SPI_SCK_PIN = IO5
SPI_MOSI_PIN = IO19
SPI_MISO_PIN = IO21
SPI_SDO_PIN = SPI_MOSI_PIN
SPI_SDI_PIN = SPI_MISO_PIN
// Silk labels
SCK = SPI_SCK_PIN
MO = SPI_MOSI_PIN
MI = SPI_MISO_PIN
)
// I2C pins
const (
I2C_SCL_PIN = IO20
I2C_SDA_PIN = IO22
// Silk labels
SCL = I2C_SCL_PIN
SDA = I2C_SDA_PIN
)
// ADC pins
const (
ADC1_0 = IO36
ADC1_1 = IO37
ADC1_2 = IO38
ADC1_3 = IO39
ADC1_4 = IO32
ADC1_5 = IO33
ADC1_6 = IO34
ADC1_7 = IO35
ADC2_0 = IO4
ADC2_1 = IO0
ADC2_2 = IO2
ADC2_3 = IO15
ADC2_4 = IO13
ADC2_5 = IO12
ADC2_6 = IO14
ADC2_7 = IO27
ADC2_8 = IO25
ADC2_9 = IO26
)
// UART pins
const (
UART_TX_PIN = IO19
UART_RX_PIN = IO22
UART2_TX_PIN = IO8
UART2_RX_PIN = IO7
// Silk labels
RX = UART2_RX_PIN
TX = UART2_TX_PIN
)
-25
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
// GPIO pins
const (
GP0 Pin = GPIO0
@@ -77,28 +72,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "AE-RP2040"
+95
View File
@@ -0,0 +1,95 @@
//go:build badger2040_w
// This contains the pin mappings for the Badger 2040 W board.
//
// For more information, see: https://shop.pimoroni.com/products/badger-2040-w
// Also
// - Badger 2040 W schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/badger_w_schematic.pdf?v=1675859004
package machine
const (
LED Pin = GPIO22
BUTTON_A Pin = GPIO12
BUTTON_B Pin = GPIO13
BUTTON_C Pin = GPIO14
BUTTON_UP Pin = GPIO15
BUTTON_DOWN Pin = GPIO11
BUTTON_USER Pin = NoPin // Not available on Badger 2040 W
EPD_BUSY_PIN Pin = GPIO26
EPD_RESET_PIN Pin = GPIO21
EPD_DC_PIN Pin = GPIO20
EPD_CS_PIN Pin = GPIO17
EPD_SCK_PIN Pin = GPIO18
EPD_SDO_PIN Pin = GPIO19
VBUS_DETECT Pin = GPIO24
VREF_POWER Pin = GPIO27
VREF_1V24 Pin = GPIO28
VBAT_SENSE Pin = GPIO29
ENABLE_3V3 Pin = GPIO10
BATTERY = VBAT_SENSE
RTC_ALARM = GPIO8
)
// I2C pins
const (
I2C0_SDA_PIN Pin = GPIO4
I2C0_SCL_PIN Pin = GPIO5
I2C1_SDA_PIN Pin = NoPin
I2C1_SCL_PIN Pin = NoPin
)
// SPI pins.
const (
SPI0_SCK_PIN Pin = GPIO18
SPI0_SDO_PIN Pin = GPIO19
SPI0_SDI_PIN Pin = GPIO16
SPI1_SCK_PIN Pin = NoPin
SPI1_SDO_PIN Pin = NoPin
SPI1_SDI_PIN Pin = NoPin
)
// QSPI pins¿?
const (
/*
TODO
SPI0_SD0_PIN Pin = QSPI_SD0
SPI0_SD1_PIN Pin = QSPI_SD1
SPI0_SD2_PIN Pin = QSPI_SD2
SPI0_SD3_PIN Pin = QSPI_SD3
SPI0_SCK_PIN Pin = QSPI_SCLKGPIO6
SPI0_CS_PIN Pin = QSPI_CS
*/
)
// Onboard crystal oscillator frequency, in MHz.
const (
xoscFreq = 12 // MHz
)
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "Badger 2040 W"
usb_STRING_MANUFACTURER = "Pimoroni"
)
var (
usb_VID uint16 = 0x2e8a
usb_PID uint16 = 0x0003
)
// UART pins
const (
UART0_TX_PIN = GPIO0
UART0_RX_PIN = GPIO1
UART_TX_PIN = UART0_TX_PIN
UART_RX_PIN = UART0_RX_PIN
)
var DefaultUART = UART0
+6 -20
View File
@@ -1,17 +1,12 @@
//go:build badger2040
// This contains the pin mappings for the Badger 2040 Connect board.
// This contains the pin mappings for the Badger 2040 board.
//
// For more information, see: https://shop.pimoroni.com/products/badger-2040
// Also
// - Badger 2040 schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/badger_2040_schematic.pdf?v=1645702148
package machine
import (
"device/rp"
"runtime/interrupt"
)
const (
LED Pin = GPIO25
@@ -30,8 +25,12 @@ const (
EPD_SDO_PIN Pin = GPIO19
VBUS_DETECT Pin = GPIO24
BATTERY Pin = GPIO29
VREF_POWER Pin = GPIO27
VREF_1V24 Pin = GPIO28
VBAT_SENSE Pin = GPIO29
ENABLE_3V3 Pin = GPIO10
BATTERY = VBAT_SENSE
)
// I2C pins
@@ -92,17 +91,4 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
}
-25
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
const (
LED = GPIO24
@@ -84,28 +79,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "Challenger 2040 LoRa"
+1 -1
View File
@@ -2,7 +2,7 @@
package machine
const HasLowFrequencyCrystal = true
const HasLowFrequencyCrystal = false
// GPIO Pins
const (
-25
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Onboard crystal oscillator frequency, in MHz.
const xoscFreq = 12 // MHz
@@ -73,28 +68,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "Feather RP2040"
-18
View File
@@ -5,11 +5,6 @@
// For more information, see: https://gopherbadge.com/
package machine
import (
"device/rp"
"runtime/interrupt"
)
const (
/*ADC0 Pin = GPIO26
ADC1 Pin = GPIO27
@@ -92,17 +87,4 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART1
func init() {
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
-25
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Onboard crystal oscillator frequency, in MHz.
const xoscFreq = 12 // MHz
@@ -75,28 +70,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "KB2040"
+112
View File
@@ -0,0 +1,112 @@
//go:build m5paper
package machine
const (
IO0 = GPIO0
IO1 = GPIO1
IO2 = GPIO2
IO3 = GPIO3
IO4 = GPIO4
IO5 = GPIO5
IO6 = GPIO6
IO7 = GPIO7
IO8 = GPIO8
IO9 = GPIO9
IO10 = GPIO10
IO11 = GPIO11
IO12 = GPIO12
IO13 = GPIO13
IO14 = GPIO14
IO15 = GPIO15
IO16 = GPIO16
IO17 = GPIO17
IO18 = GPIO18
IO19 = GPIO19
IO21 = GPIO21
IO22 = GPIO22
IO23 = GPIO23
IO25 = GPIO25
IO26 = GPIO26
IO27 = GPIO27
IO32 = GPIO32
IO33 = GPIO33
IO34 = GPIO34
IO35 = GPIO35
IO36 = GPIO36
IO37 = GPIO37
IO38 = GPIO38
IO39 = GPIO39
)
const (
POWER_PIN = IO2
EXT_POWER_PIN = IO5
EPD_POWER_PIN = IO23
// Buttons
BUTTON_RIGHT = IO39
BUTTON_PUSH = IO38
BUTTON_LEFT = IO37
BUTTON = BUTTON_PUSH
// Touch Screen Interrupt
TOUCH_INT = IO36
)
// SPI pins
const (
SPI0_SCK_PIN = IO14
SPI0_SDO_PIN = IO12
SPI0_SDI_PIN = IO13
// EPD (IT8951)
EPD_SCK_PIN = SPI0_SCK_PIN
EPD_SDO_PIN = SPI0_SDO_PIN
EPD_SDI_PIN = SPI0_SDI_PIN
EPD_CS_PIN = IO15
EPD_BUSY_PIN = IO27
// SD CARD
SDCARD_SCK_PIN = SPI0_SCK_PIN
SDCARD_SDO_PIN = SPI0_SDO_PIN
SDCARD_SDI_PIN = SPI0_SDI_PIN
SDCARD_CS_PIN = IO4
)
// I2C pins
const (
SDA0_PIN = IO21
SCL0_PIN = IO22
SDA_PIN = SDA0_PIN
SCL_PIN = SCL0_PIN
I2C_TEMP_ADDR = 0x44 // temperature sensor (SHT30)
I2C_CLOCK_ADDR = 0x51 // real time clock (BM8563)
I2C_TOUCH_ADDR = 0x5D // touch screen controller (GT911)
)
// ADC pins
const (
ADC1 Pin = IO35
ADC2 Pin = IO36
BATTERY_ADC_PIN = ADC1
)
// DAC pins
const (
DAC1 Pin = IO25
DAC2 Pin = IO26
)
// UART pins
const (
// UART0 (CP2104)
UART0_TX_PIN = IO1
UART0_RX_PIN = IO3
UART_TX_PIN = UART0_TX_PIN
UART_RX_PIN = UART0_RX_PIN
)
-18
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
const (
NeopixelCount = 12
@@ -78,21 +73,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "MacroPad RP2040"
+1 -1
View File
@@ -26,7 +26,7 @@
// SoftDevice (s140v7) must be flashed first to enable use of bluetooth on this board.
// See https://github.com/tinygo-org/bluetooth
//
// SoftDevice overwrites original bootloader and flashing method described above is not avalable anymore.
// SoftDevice overwrites original bootloader and flashing method described above is not available anymore.
// Instead, please use debug probe and flash your code with "nano-33-ble-s140v7" target.
package machine
+2 -27
View File
@@ -11,11 +11,6 @@
// - Nano RP2040 Connect technical reference: https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-01-technical-reference
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Digital Pins
const (
D2 Pin = GPIO25
@@ -125,27 +120,7 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
// UART_NINA on the Arduino Nano RP2040 connects to the NINA HCI.
UART_NINA = UART1
)
// UART_NINA on the Arduino Nano RP2040 connects to the NINA HCI.
var UART_NINA = UART1
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
+105
View File
@@ -0,0 +1,105 @@
//go:build nucleol476rg
// Schematic: https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf
// Datasheet: https://www.st.com/resource/en/datasheet/stm32l476je.pdf
package machine
import (
"device/stm32"
"runtime/interrupt"
)
const (
// Arduino Pins
A0 = PA0
A1 = PA1
A2 = PA4
A3 = PB0
A4 = PC1
A5 = PC0
D0 = PA3
D1 = PA2
D2 = PA10
D3 = PB3
D4 = PB5
D5 = PB4
D6 = PB10
D7 = PA8
D8 = PA9
D9 = PC7
D10 = PB6
D11 = PA7
D12 = PA6
D13 = PA5
D14 = PB9
D15 = PB8
)
// User LD2: the green LED is a user LED connected to ARDUINO® signal D13 corresponding
// to STM32 I/O PA5 (pin 21) or PB13 (pin 34) depending on the STM32 target.
const (
LED = LED_BUILTIN
LED_BUILTIN = LED_GREEN
LED_GREEN = PA5
)
const (
// This board does not have a user button, so
// use first GPIO pin by default
BUTTON = PA0
)
const (
// UART pins
// PA2 and PA3 are connected to the ST-Link Virtual Com Port (VCP)
UART_TX_PIN = PA2
UART_RX_PIN = PA3
// I2C pins
// With default solder bridge settings:
// PB8 / Arduino D5 / CN3 Pin 8 is SCL
// PB7 / Arduino D4 / CN3 Pin 7 is SDA
I2C0_SCL_PIN = PB8
I2C0_SDA_PIN = PB9
// SPI pins
SPI1_SCK_PIN = PA5
SPI1_SDI_PIN = PA6
SPI1_SDO_PIN = PA7
SPI0_SCK_PIN = SPI1_SCK_PIN
SPI0_SDI_PIN = SPI1_SDI_PIN
SPI0_SDO_PIN = SPI1_SDO_PIN
)
var (
// USART2 is the hardware serial port connected to the onboard ST-LINK
// debugger to be exposed as virtual COM port over USB on Nucleo boards.
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART2,
TxAltFuncSelector: AF7_USART1_2_3,
RxAltFuncSelector: AF7_USART1_2_3,
}
DefaultUART = UART1
// I2C1 is documented, alias to I2C0 as well
I2C1 = &I2C{
Bus: stm32.I2C1,
AltFuncSelector: AF4_I2C1_2_3,
}
I2C0 = I2C1
// SPI1 is documented, alias to SPI0 as well
SPI1 = &SPI{
Bus: stm32.SPI1,
AltFuncSelector: AF5_SPI1_2,
}
SPI0 = SPI1
)
func init() {
UART1.Interrupt = interrupt.New(stm32.IRQ_USART2, _UART1.handleInterrupt)
}
-25
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
// GPIO pins
const (
GP0 Pin = GPIO0
@@ -79,28 +74,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "Pico"
-25
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Onboard crystal oscillator frequency, in MHz.
const xoscFreq = 12 // MHz
@@ -84,28 +79,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "QT Py RP2040"
+5 -19
View File
@@ -2,11 +2,6 @@
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Onboard crystal oscillator frequency, in MHz.
const xoscFreq = 12 // MHz
@@ -51,7 +46,11 @@ const (
A3 = GPIO29
)
const LED = GPIO25
// Onboard LEDs
const (
LED = GPIO25
WS2812 = GPIO8
)
// I2C Pins.
const (
@@ -90,21 +89,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "Thing Plus RP2040"
-18
View File
@@ -5,11 +5,6 @@
// https://thumby.us/
package machine
import (
"device/rp"
"runtime/interrupt"
)
const (
THUMBY_SCK_PIN = I2C1_SDA_PIN
THUMBY_SDA_PIN = I2C1_SCL_PIN
@@ -78,17 +73,4 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the Thumby
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
}
-18
View File
@@ -7,11 +7,6 @@
// - Tufty 2040 schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/tufty_schematic.pdf?v=1655385675
package machine
import (
"device/rp"
"runtime/interrupt"
)
const (
LED Pin = GPIO25
@@ -87,17 +82,4 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
}
+1 -24
View File
@@ -7,11 +7,6 @@
// - https://www.waveshare.com/wiki/RP2040-Zero
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Digital Pins
const (
D0 Pin = GPIO0
@@ -57,6 +52,7 @@ const (
// Onboard LEDs
const (
NEOPIXEL = GPIO16
WS2812 = GPIO16
)
// I2C pins
@@ -94,27 +90,8 @@ const (
UART1_RX_PIN = GPIO9
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "RP2040-Zero"
-18
View File
@@ -7,11 +7,6 @@
// - https://wiki.seeedstudio.com/XIAO-RP2040/
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Digital Pins
const (
D0 Pin = GPIO26
@@ -81,21 +76,8 @@ const (
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
}
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "XIAO RP2040"
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build atmega || nrf || sam || stm32 || fe310 || k210 || rp2040 || mimxrt1062 || (esp32c3 && !m5stamp_c3)
//go:build !baremetal || atmega || nrf || sam || stm32 || fe310 || k210 || rp2040 || mimxrt1062 || (esp32c3 && !m5stamp_c3) || esp32
package machine
+5 -5
View File
@@ -1304,7 +1304,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return byte(spi.Bus.DATA.Get()), nil
}
// 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 synchronous write/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.
//
@@ -1459,7 +1459,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
for tcc.timer().SYNCBUSY.Get() != 0 {
}
// Return any error that might have occured in the tcc.setPeriod call.
// Return any error that might have occurred in the tcc.setPeriod call.
return err
}
@@ -1606,7 +1606,7 @@ func (tcc *TCC) Counter() uint32 {
return tcc.timer().COUNT.Get()
}
// Some constans to make pinTimerMapping below easier to read.
// Some constants to make pinTimerMapping below easier to read.
const (
pinTCC0 = 1
pinTCC1 = 2
@@ -1657,7 +1657,7 @@ var pinTimerMapping = [...]uint8{
PB30 / 2: pinTCC0Ch0 | pinTCC1Ch2<<4,
}
// findPinPadMapping returns the pin mode (PinTCC or PinTCCAlt) and the channel
// findPinTimerMapping returns the pin mode (PinTCC or PinTCCAlt) and the channel
// number for a given timer and pin. A zero PinMode is returned if no mapping
// could be found.
func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
@@ -1759,7 +1759,7 @@ func (tcc *TCC) Set(channel uint8, value uint32) {
}
}
// EnterBootloader should perform a system reset in preperation
// EnterBootloader should perform a system reset in preparation
// to switch to the bootloader to flash new firmware.
func EnterBootloader() {
arm.DisableInterrupts()
+3 -3
View File
@@ -1587,7 +1587,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return byte(spi.Bus.DATA.Get()), nil
}
// 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 synchronous write/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.
//
@@ -1720,7 +1720,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
for tcc.timer().SYNCBUSY.Get() != 0 {
}
// Return any error that might have occured in the tcc.setPeriod call.
// Return any error that might have occurred in the tcc.setPeriod call.
return err
}
@@ -1928,7 +1928,7 @@ var pinTimerMapping = [...]struct{ F, G uint8 }{
PB02 / 2: {pinTCC2_2, 0},
}
// findPinPadMapping returns the pin mode (PinTCCF or PinTCCG) and the channel
// findPinTimerMapping 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
// could be found.
func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
+6 -1
View File
@@ -155,7 +155,7 @@ func (can *CAN) Configure(config CANConfig) error {
}
// Callbacks to be called for CAN.SetInterrupt(). Wre're using the magic
// constant 2 and 32 here beacuse th SAM E51/E54 has 2 CAN and 32 interrupt
// constant 2 and 32 here because the SAM E51/E54 has 2 CAN and 32 interrupt
// sources.
var (
canInstances [2]*CAN
@@ -221,6 +221,11 @@ func (can *CAN) TxFifoIsFull() bool {
return (can.Bus.TXFQS.Get() & sam.CAN_TXFQS_TFQF_Msk) == sam.CAN_TXFQS_TFQF_Msk
}
// TxFifoFreeLevel returns how many messages can still be set in the TxFifo.
func (can *CAN) TxFifoFreeLevel() int {
return int(can.Bus.GetTXFQS_TFFL())
}
// TxRaw sends a CAN Frame according to CANTxBufferElement.
func (can *CAN) TxRaw(e *CANTxBufferElement) {
putIndex := (can.Bus.TXFQS.Get() & sam.CAN_TXFQS_TFQPI_Msk) >> sam.CAN_TXFQS_TFQPI_Pos
+1 -1
View File
@@ -460,7 +460,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return byte(spi.Bus.W0.Get()), nil
}
// 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 synchronous write/read
// interface, there must always be the same number of bytes written as bytes read.
// This is accomplished by sending zero bits if r is bigger than w or discarding
// the incoming data if w is bigger than r.
+412
View File
@@ -0,0 +1,412 @@
//go:build esp32
package machine
import (
"device/esp"
"runtime/volatile"
"unsafe"
)
var (
I2C0 = &I2C{Bus: esp.I2C0, funcSCL: 29, funcSDA: 30}
I2C1 = &I2C{Bus: esp.I2C1, funcSCL: 95, funcSDA: 96}
)
type I2C struct {
Bus *esp.I2C_Type
funcSCL, funcSDA uint32
config I2CConfig
}
// I2CConfig is used to store config info for I2C.
type I2CConfig struct {
Frequency uint32 // in Hz
SCL Pin
SDA Pin
}
const (
i2cClkSourceFrequency = uint32(80 * MHz)
)
func (i2c *I2C) Configure(config I2CConfig) error {
if config.Frequency == 0 {
config.Frequency = 400 * KHz
}
if config.SCL == 0 {
config.SCL = SCL_PIN
}
if config.SDA == 0 {
config.SDA = SDA_PIN
}
i2c.config = config
i2c.initAll()
return nil
}
func (i2c *I2C) initAll() {
i2c.initClock()
i2c.initNoiseFilter()
i2c.initPins()
i2c.initFrequency()
i2c.startMaster()
}
//go:inline
func (i2c *I2C) initClock() {
// reset I2C clock
if i2c.Bus == esp.I2C0 {
esp.DPORT.SetPERIP_RST_EN_I2C0_EXT0_RST(1)
esp.DPORT.SetPERIP_CLK_EN_I2C0_EXT0_CLK_EN(1)
esp.DPORT.SetPERIP_RST_EN_I2C0_EXT0_RST(0)
} else {
esp.DPORT.SetPERIP_RST_EN_I2C_EXT1_RST(1)
esp.DPORT.SetPERIP_CLK_EN_I2C_EXT1_CLK_EN(1)
esp.DPORT.SetPERIP_RST_EN_I2C_EXT1_RST(0)
}
// disable interrupts
i2c.Bus.INT_ENA.Set(0)
i2c.Bus.INT_CLR.Set(0x3fff)
i2c.Bus.SetCTR_CLK_EN(1)
}
//go:inline
func (i2c *I2C) initNoiseFilter() {
i2c.Bus.SCL_FILTER_CFG.Set(0xF)
i2c.Bus.SDA_FILTER_CFG.Set(0xF)
}
//go:inline
func (i2c *I2C) initPins() {
var muxConfig uint32
const function = 2 // function 2 is just GPIO
// SDA
muxConfig = function << esp.IO_MUX_GPIO0_MCU_SEL_Pos
// Make this pin an input pin (always).
muxConfig |= esp.IO_MUX_GPIO0_FUN_IE
// Set drive strength: 0 is lowest, 3 is highest.
muxConfig |= 1 << esp.IO_MUX_GPIO0_FUN_DRV_Pos
i2c.config.SDA.mux().Set(muxConfig)
i2c.config.SDA.outFunc().Set(i2c.funcSDA)
inFunc(i2c.funcSDA).Set(uint32(esp.GPIO_FUNC_IN_SEL_CFG_SEL | i2c.config.SDA))
i2c.config.SDA.Set(true)
// Configure the pad with the given IO mux configuration.
i2c.config.SDA.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
esp.GPIO.ENABLE_W1TS.Set(1 << int(i2c.config.SDA))
i2c.Bus.SetCTR_SDA_FORCE_OUT(1)
// SCL
muxConfig = function << esp.IO_MUX_GPIO0_MCU_SEL_Pos
// Make this pin an input pin (always).
muxConfig |= esp.IO_MUX_GPIO0_FUN_IE
// Set drive strength: 0 is lowest, 3 is highest.
muxConfig |= 1 << esp.IO_MUX_GPIO0_FUN_DRV_Pos
i2c.config.SCL.mux().Set(muxConfig)
i2c.config.SCL.outFunc().Set(i2c.funcSCL)
inFunc(i2c.funcSCL).Set(uint32(esp.GPIO_FUNC_IN_SEL_CFG_SEL | i2c.config.SCL))
i2c.config.SCL.Set(true)
// Configure the pad with the given IO mux configuration.
i2c.config.SCL.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
esp.GPIO.ENABLE_W1TS.Set(1 << int(i2c.config.SCL))
i2c.Bus.SetCTR_SCL_FORCE_OUT(1)
}
//go:inline
func (i2c *I2C) initFrequency() {
clkmDiv := i2cClkSourceFrequency/(i2c.config.Frequency*1024) + 1
sclkFreq := i2cClkSourceFrequency / clkmDiv
halfCycle := sclkFreq / i2c.config.Frequency / 2
//SCL
sclLow := halfCycle
sclWaitHigh := uint32(0)
if i2c.config.Frequency > 50000 {
sclWaitHigh = halfCycle / 8 // compensate the time when freq > 50K
}
sclHigh := halfCycle - sclWaitHigh
// SDA
sdaHold := halfCycle / 4
sda_sample := halfCycle / 2
setup := halfCycle
hold := halfCycle
i2c.Bus.SetSCL_LOW_PERIOD(sclLow - 1)
i2c.Bus.SetSCL_HIGH_PERIOD(sclHigh)
i2c.Bus.SetSCL_RSTART_SETUP_TIME(setup)
i2c.Bus.SetSCL_STOP_SETUP_TIME(setup)
i2c.Bus.SetSCL_START_HOLD_TIME(hold - 1)
i2c.Bus.SetSCL_STOP_HOLD_TIME(hold - 1)
i2c.Bus.SetSDA_SAMPLE_TIME(sda_sample)
i2c.Bus.SetSDA_HOLD_TIME(sdaHold)
// set timeout value
i2c.Bus.SetTO_TIME_OUT(20 * halfCycle)
}
//go:inline
func (i2c *I2C) startMaster() {
// FIFO mode for data
i2c.Bus.SetFIFO_CONF_NONFIFO_EN(0)
// Reset TX & RX buffers
i2c.Bus.SetFIFO_CONF_RX_FIFO_RST(1)
i2c.Bus.SetFIFO_CONF_RX_FIFO_RST(0)
i2c.Bus.SetFIFO_CONF_TX_FIFO_RST(1)
i2c.Bus.SetFIFO_CONF_TX_FIFO_RST(0)
// enable master mode
i2c.Bus.SetCTR_MS_MODE(1)
}
func (i2c *I2C) resetBus() {
// unlike esp32c3, the esp32 i2c modules do not have a reset fsm register,
// so we need to:
// 1. disconnect the pins
// 2. generate a stop condition manually
// 3. do a full reset
// 4. redo all configuration
i2c.config.SDA.mux().Set(2<<esp.IO_MUX_GPIO0_MCU_SEL_Pos | esp.IO_MUX_GPIO0_FUN_IE | 1<<esp.IO_MUX_GPIO0_FUN_DRV_Pos)
i2c.config.SDA.outFunc().Set(0x500)
i2c.config.SDA.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
i2c.config.SCL.mux().Set(2<<esp.IO_MUX_GPIO0_MCU_SEL_Pos | esp.IO_MUX_GPIO0_FUN_IE | 1<<esp.IO_MUX_GPIO0_FUN_DRV_Pos)
i2c.config.SCL.outFunc().Set(0x500)
i2c.config.SCL.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
// bit-bang a read-NACK in case any device on the bus is in the middle of a write
i2c.config.SCL.Low()
i2c.config.SDA.High()
wait()
for i := 0; i < 9; i++ {
if i2c.config.SDA.Get() {
break
}
i2c.config.SCL.High()
wait()
i2c.config.SCL.Low()
wait()
}
i2c.config.SDA.Low()
i2c.config.SCL.High()
wait()
i2c.config.SDA.High()
// initAll contains initClock which contains a reset
i2c.initAll()
}
func wait() {
end := nanotime() + 5_000
for nanotime() < end {
//spin
}
}
type i2cCommandType = uint32
type i2cAck = uint32
const (
i2cCMD_RSTART i2cCommandType = 0 << 11
i2cCMD_WRITE i2cCommandType = 1<<11 | 1<<8 // WRITE + ack_check_en
i2cCMD_READ i2cCommandType = 2 << 11
i2cCMD_READLAST i2cCommandType = 2<<11 | 1<<10 // READ + NACK
i2cCMD_STOP i2cCommandType = 3 << 11
i2cCMD_END i2cCommandType = 4 << 11
)
type i2cCommand struct {
cmd i2cCommandType
data []byte
head int
}
//go:linkname nanotime runtime.nanotime
func nanotime() int64
func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
if i2c.Bus.GetSR_BUS_BUSY() == 1 {
i2c.resetBus()
}
const intMask = esp.I2C_INT_STATUS_END_DETECT_INT_ST_Msk | esp.I2C_INT_STATUS_TRANS_COMPLETE_INT_ST_Msk | esp.I2C_INT_STATUS_TIME_OUT_INT_ST_Msk | esp.I2C_INT_STATUS_ACK_ERR_INT_ST_Msk | esp.I2C_INT_STATUS_ARBITRATION_LOST_INT_ST_Msk
i2c.Bus.INT_CLR.Set(intMask)
i2c.Bus.INT_ENA.Set(intMask)
defer func() {
i2c.Bus.INT_CLR.Set(intMask)
i2c.Bus.INT_ENA.Set(0)
}()
timeoutNS := int64(timeoutMS) * 1000000
needAddress := true
needRestart := false
readLast := false
var readTo []byte
for cmdIdx, reg := 0, &i2c.Bus.COMD0; cmdIdx < len(cmd); {
c := &cmd[cmdIdx]
switch c.cmd {
case i2cCMD_RSTART:
reg.Set(i2cCMD_RSTART)
reg = nextAddress(reg)
cmdIdx++
case i2cCMD_WRITE:
count := 32
if needAddress {
needAddress = false
i2c.Bus.SetDATA_FIFO_RDATA((uint32(addr) & 0x7f) << 1)
count--
i2c.Bus.SLAVE_ADDR.Set(uint32(addr))
}
for ; count > 0 && c.head < len(c.data); count, c.head = count-1, c.head+1 {
i2c.Bus.SetDATA_FIFO_RDATA(uint32(c.data[c.head]))
}
reg.Set(i2cCMD_WRITE | uint32(32-count))
reg = nextAddress(reg)
if c.head < len(c.data) {
reg.Set(i2cCMD_END)
reg = nil
} else {
cmdIdx++
}
needRestart = true
case i2cCMD_READ:
if needAddress {
needAddress = false
i2c.Bus.SetDATA_FIFO_RDATA((uint32(addr)&0x7f)<<1 | 1)
i2c.Bus.SLAVE_ADDR.Set(uint32(addr))
reg.Set(i2cCMD_WRITE | 1)
reg = nextAddress(reg)
}
if needRestart {
// We need to send RESTART again after i2cCMD_WRITE.
reg.Set(i2cCMD_RSTART)
reg = nextAddress(reg)
reg.Set(i2cCMD_WRITE | 1)
reg = nextAddress(reg)
i2c.Bus.SetDATA_FIFO_RDATA((uint32(addr)&0x7f)<<1 | 1)
needRestart = false
}
count := 32
bytes := len(c.data) - c.head
// Only last byte in sequence must be sent with ACK set to 1 to indicate end of data.
split := bytes <= count
if split {
bytes--
}
if bytes > 32 {
bytes = 32
}
if bytes > 0 {
reg.Set(i2cCMD_READ | uint32(bytes))
reg = nextAddress(reg)
}
if split {
readLast = true
reg.Set(i2cCMD_READLAST | 1)
reg = nextAddress(reg)
readTo = c.data[c.head : c.head+bytes+1] // read bytes + 1 last byte
cmdIdx++
} else {
reg.Set(i2cCMD_END)
readTo = c.data[c.head : c.head+bytes]
reg = nil
}
case i2cCMD_STOP:
reg.Set(i2cCMD_STOP)
reg = nil
cmdIdx++
}
if reg == nil {
// transmit now
i2c.Bus.SetCTR_TRANS_START(1)
end := nanotime() + timeoutNS
var mask uint32
for mask = i2c.Bus.INT_STATUS.Get(); mask&intMask == 0; mask = i2c.Bus.INT_STATUS.Get() {
if nanotime() > end {
// timeout leaves the bus in an undefined state, reset
i2c.resetBus()
if readTo != nil {
return errI2CReadTimeout
}
return errI2CWriteTimeout
}
}
switch {
case mask&esp.I2C_INT_STATUS_ACK_ERR_INT_ST_Msk != 0 && !readLast:
return errI2CAckExpected
case mask&esp.I2C_INT_STATUS_TIME_OUT_INT_ST_Msk != 0:
// timeout leaves the bus in an undefined state, reset
i2c.resetBus()
if readTo != nil {
return errI2CReadTimeout
}
return errI2CWriteTimeout
}
i2c.Bus.INT_CLR.SetBits(intMask)
for i := 0; i < len(readTo); i++ {
readTo[i] = byte(i2c.Bus.GetDATA_FIFO_RDATA() & 0xff)
c.head++
}
readTo = nil
reg = &i2c.Bus.COMD0
}
}
return nil
}
// Tx does a single I2C transaction at the specified address.
// It clocks out the given address, writes the bytes in w, reads back len(r)
// bytes and stores them in r, and generates a stop condition on the bus.
func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
// timeout in microseconds.
const timeout = 40 // 40ms is a reasonable time for a real-time system.
cmd := make([]i2cCommand, 0, 8)
cmd = append(cmd, i2cCommand{cmd: i2cCMD_RSTART})
if len(w) > 0 {
cmd = append(cmd, i2cCommand{cmd: i2cCMD_WRITE, data: w})
}
if len(r) > 0 {
cmd = append(cmd, i2cCommand{cmd: i2cCMD_READ, data: r})
}
cmd = append(cmd, i2cCommand{cmd: i2cCMD_STOP})
return i2c.transmit(addr, cmd, timeout)
}
func (i2c *I2C) SetBaudRate(br uint32) error {
return errI2CNotImplemented
}
func (p Pin) pinReg() *volatile.Register32 {
return (*volatile.Register32)(unsafe.Pointer((uintptr(unsafe.Pointer(&esp.GPIO.PIN0)) + uintptr(p)*4)))
}
func nextAddress(reg *volatile.Register32) *volatile.Register32 {
return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(reg), 4))
}
// CheckDevice does an empty I2C transaction at the specified address.
// This can be used to find out if any device with that address is
// connected, e.g. for enumerating all devices on the bus.
func (i2c *I2C) CheckDevice(addr uint16) bool {
// timeout in microseconds.
const timeout = 40 // 40ms is a reasonable time for a real-time system.
cmd := []i2cCommand{
{cmd: i2cCMD_RSTART},
{cmd: i2cCMD_WRITE},
{cmd: i2cCMD_STOP},
}
return i2c.transmit(addr, cmd, timeout) == nil
}
+1 -1
View File
@@ -312,7 +312,7 @@ func (uart *UART) configure(config UARTConfig, regs registerSet) error {
initUARTClock(uart.Bus, regs)
// - disbale TX/RX clock to make sure the UART transmitter or receiver is not at work during configuration
// - disable TX/RX clock to make sure the UART transmitter or receiver is not at work during configuration
uart.Bus.SetCLK_CONF_TX_SCLK_EN(0)
uart.Bus.SetCLK_CONF_RX_SCLK_EN(0)
+1 -1
View File
@@ -234,7 +234,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return byte(spi.Bus.GetW0()), nil
}
// 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 synchronous write/read
// interface, there must always be the same number of bytes written as bytes read.
// This is accomplished by sending zero bits if r is bigger than w or discarding
// the incoming data if w is bigger than r.
+67 -4
View File
@@ -2,20 +2,23 @@
package machine
import (
"crypto/rand"
)
// Dummy machine package that calls out to external functions.
const deviceName = "generic"
var (
UART0 = &UART{0}
USB = &UART{100}
USB = &UART{100}
)
// The Serial port always points to the default UART in a simulated environment.
//
// TODO: perhaps this should be a special serial object that outputs via WASI
// stdout calls.
var Serial = UART0
var Serial = hardwareUART0
const (
PinInput PinMode = iota
@@ -67,12 +70,47 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return spiTransfer(spi.Bus, w), nil
}
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/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.
//
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
// Note that the tx and rx buffers must be the same size:
//
// spi.Tx(tx, rx)
//
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
// until all the bytes in the command packet have been received:
//
// spi.Tx(tx, nil)
//
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
//
// spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error {
var wptr, rptr *byte
var wlen, rlen int
if len(w) != 0 {
wptr = &w[0]
wlen = len(w)
}
if len(r) != 0 {
rptr = &r[0]
rlen = len(r)
}
spiTX(spi.Bus, wptr, wlen, rptr, rlen)
return nil
}
//export __tinygo_spi_configure
func spiConfigure(bus uint8, sck Pin, SDO Pin, SDI Pin)
//export __tinygo_spi_transfer
func spiTransfer(bus uint8, w uint8) uint8
//export __tinygo_spi_tx
func spiTX(bus uint8, wptr *byte, wlen int, rptr *byte, rlen int) uint8
// InitADC enables support for ADC peripherals.
func InitADC() {
// Nothing to do here.
@@ -116,7 +154,17 @@ func (i2c *I2C) SetBaudRate(br uint32) error {
// Tx does a single I2C transaction at the specified address.
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
i2cTransfer(i2c.Bus, &w[0], len(w), &r[0], len(r))
var wptr, rptr *byte
var wlen, rlen int
if len(w) != 0 {
wptr = &w[0]
wlen = len(w)
}
if len(r) != 0 {
rptr = &r[0]
rlen = len(r)
}
i2cTransfer(i2c.Bus, wptr, wlen, rptr, rlen)
// TODO: do something with the returned error code.
return nil
}
@@ -176,6 +224,11 @@ func uartRead(bus uint8, buf *byte, bufLen int) int
//export __tinygo_uart_write
func uartWrite(bus uint8, buf *byte, bufLen int) int
var (
hardwareUART0 = &UART{0}
hardwareUART1 = &UART{1}
)
// Some objects used by Atmel SAM D chips (samd21, samd51).
// Defined here (without build tag) for convenience.
var (
@@ -204,3 +257,13 @@ var (
sercomSPIM6 = SPI{6}
sercomSPIM7 = SPI{7}
)
// GetRNG returns 32 bits of random data from the WASI random source.
func GetRNG() (uint32, error) {
var buf [4]byte
_, err := rand.Read(buf[:])
if err != nil {
return 0, err
}
return uint32(buf[0])<<0 | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24, nil
}
+5 -2
View File
@@ -6,6 +6,9 @@ package machine
// boards that define their peripherals in the board file (e.g. board_qtpy.go).
var (
SPI0 = SPI{0}
I2C0 = &I2C{0}
UART0 = hardwareUART0
UART1 = hardwareUART1
SPI0 = SPI{0}
SPI1 = SPI{1}
I2C0 = &I2C{0}
)
+1 -1
View File
@@ -108,7 +108,7 @@ func (p Pin) Get() bool {
func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
// Some variables to easily check whether a channel was already configured
// as an event channel for the given pin.
// This is not just an optimization, this is requred: the datasheet says
// This is not just an optimization, this is required: the datasheet says
// that configuring more than one channel for a given pin results in
// unpredictable behavior.
expectedConfigMask := uint32(nrf.GPIOTE_CONFIG_MODE_Msk | nrf.GPIOTE_CONFIG_PSEL_Msk)
+1 -1
View File
@@ -133,7 +133,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return byte(r), nil
}
// 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 synchronous write/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.
//
+1 -1
View File
@@ -277,7 +277,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return buf[0], err
}
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous
// write/read interface, there must always be the same number of bytes written
// as bytes read. Therefore, if the number of bytes don't match it will be
// padded until they fit: if len(w) > len(r) the extra bytes received will be
-40
View File
@@ -10,46 +10,6 @@ import (
const deviceName = rp.Device
const (
// GPIO pins
GPIO0 Pin = 0 // peripherals: PWM0 channel A
GPIO1 Pin = 1 // peripherals: PWM0 channel B
GPIO2 Pin = 2 // peripherals: PWM1 channel A
GPIO3 Pin = 3 // peripherals: PWM1 channel B
GPIO4 Pin = 4 // peripherals: PWM2 channel A
GPIO5 Pin = 5 // peripherals: PWM2 channel B
GPIO6 Pin = 6 // peripherals: PWM3 channel A
GPIO7 Pin = 7 // peripherals: PWM3 channel B
GPIO8 Pin = 8 // peripherals: PWM4 channel A
GPIO9 Pin = 9 // peripherals: PWM4 channel B
GPIO10 Pin = 10 // peripherals: PWM5 channel A
GPIO11 Pin = 11 // peripherals: PWM5 channel B
GPIO12 Pin = 12 // peripherals: PWM6 channel A
GPIO13 Pin = 13 // peripherals: PWM6 channel B
GPIO14 Pin = 14 // peripherals: PWM7 channel A
GPIO15 Pin = 15 // peripherals: PWM7 channel B
GPIO16 Pin = 16 // peripherals: PWM0 channel A
GPIO17 Pin = 17 // peripherals: PWM0 channel B
GPIO18 Pin = 18 // peripherals: PWM1 channel A
GPIO19 Pin = 19 // peripherals: PWM1 channel B
GPIO20 Pin = 20 // peripherals: PWM2 channel A
GPIO21 Pin = 21 // peripherals: PWM2 channel B
GPIO22 Pin = 22 // peripherals: PWM3 channel A
GPIO23 Pin = 23 // peripherals: PWM3 channel B
GPIO24 Pin = 24 // peripherals: PWM4 channel A
GPIO25 Pin = 25 // peripherals: PWM4 channel B
GPIO26 Pin = 26 // peripherals: PWM5 channel A
GPIO27 Pin = 27 // peripherals: PWM5 channel B
GPIO28 Pin = 28 // peripherals: PWM6 channel A
GPIO29 Pin = 29 // peripherals: PWM6 channel B
// Analog pins
ADC0 Pin = GPIO26
ADC1 Pin = GPIO27
ADC2 Pin = GPIO28
ADC3 Pin = GPIO29
)
//go:linkname machineInit runtime.machineInit
func machineInit() {
// Reset all peripherals to put system into a known state,
+20
View File
@@ -331,3 +331,23 @@ func (p Pin) ioIntBit(change PinChange) uint32 {
func getIntChange(p Pin, status uint32) PinChange {
return PinChange(status>>(4*(p%8))) & 0xf
}
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
+1 -1
View File
@@ -348,7 +348,7 @@ func (i2c *I2C) tx(addr uint8, tx, rx []byte, timeout_us uint64) (err error) {
}
if abort || last {
// If the transaction was aborted or if it completed
// successfully wait until the STOP condition has occured.
// successfully wait until the STOP condition has occurred.
// TODO Could there be an abort while waiting for the STOP
// condition here? If so, additional code would be needed here
+43
View File
@@ -0,0 +1,43 @@
//go:build rp2040 || ae_rp2040 || badger2040 || challenger_rp2040 || feather_rp2040 || gopher_badge || kb2040 || macropad_rp2040 || nano_rp2040 || pico || qtpy_rp2040 || thingplus_rp2040 || thumby || tufty2040 || waveshare_rp2040_zero || xiao_rp2040
package machine
const (
// GPIO pins
GPIO0 Pin = 0 // peripherals: PWM0 channel A
GPIO1 Pin = 1 // peripherals: PWM0 channel B
GPIO2 Pin = 2 // peripherals: PWM1 channel A
GPIO3 Pin = 3 // peripherals: PWM1 channel B
GPIO4 Pin = 4 // peripherals: PWM2 channel A
GPIO5 Pin = 5 // peripherals: PWM2 channel B
GPIO6 Pin = 6 // peripherals: PWM3 channel A
GPIO7 Pin = 7 // peripherals: PWM3 channel B
GPIO8 Pin = 8 // peripherals: PWM4 channel A
GPIO9 Pin = 9 // peripherals: PWM4 channel B
GPIO10 Pin = 10 // peripherals: PWM5 channel A
GPIO11 Pin = 11 // peripherals: PWM5 channel B
GPIO12 Pin = 12 // peripherals: PWM6 channel A
GPIO13 Pin = 13 // peripherals: PWM6 channel B
GPIO14 Pin = 14 // peripherals: PWM7 channel A
GPIO15 Pin = 15 // peripherals: PWM7 channel B
GPIO16 Pin = 16 // peripherals: PWM0 channel A
GPIO17 Pin = 17 // peripherals: PWM0 channel B
GPIO18 Pin = 18 // peripherals: PWM1 channel A
GPIO19 Pin = 19 // peripherals: PWM1 channel B
GPIO20 Pin = 20 // peripherals: PWM2 channel A
GPIO21 Pin = 21 // peripherals: PWM2 channel B
GPIO22 Pin = 22 // peripherals: PWM3 channel A
GPIO23 Pin = 23 // peripherals: PWM3 channel B
GPIO24 Pin = 24 // peripherals: PWM4 channel A
GPIO25 Pin = 25 // peripherals: PWM4 channel B
GPIO26 Pin = 26 // peripherals: PWM5 channel A
GPIO27 Pin = 27 // peripherals: PWM5 channel B
GPIO28 Pin = 28 // peripherals: PWM6 channel A
GPIO29 Pin = 29 // peripherals: PWM6 channel B
// Analog pins
ADC0 Pin = GPIO26
ADC1 Pin = GPIO27
ADC2 Pin = GPIO28
ADC3 Pin = GPIO29
)
+1 -1
View File
@@ -48,7 +48,7 @@ type SPI struct {
Bus *rp.SPI0_Type
}
// 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 synchronous write/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.
//
+28 -6
View File
@@ -45,11 +45,21 @@ type I2C struct {
// I2CConfig is used to store config info for I2C.
type I2CConfig struct {
SCL Pin
SDA Pin
Frequency uint32
SCL Pin
SDA Pin
}
func (i2c *I2C) Configure(config I2CConfig) error {
// Frequency range
switch config.Frequency {
case 0:
config.Frequency = 100 * KHz
case 10 * KHz, 100 * KHz, 400 * KHz, 500 * KHz:
default:
return errI2CNotImplemented
}
// disable I2C interface before any configuration changes
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE)
@@ -63,8 +73,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
}
i2c.configurePins(config)
// Frequency range
i2c.Bus.TIMINGR.Set(i2c.getFreqRange())
i2c.Bus.TIMINGR.Set(i2c.getFreqRange(config.Frequency))
// Disable Own Address1 before set the Own Address1 configuration
i2c.Bus.OAR1.ClearBits(stm32.I2C_OAR1_OA1EN)
@@ -86,8 +95,21 @@ func (i2c *I2C) Configure(config I2CConfig) error {
// SetBaudRate sets the communication speed for I2C.
func (i2c *I2C) SetBaudRate(br uint32) error {
// TODO: implement
return errI2CNotImplemented
switch br {
case 10 * KHz, 100 * KHz, 400 * KHz, 500 * KHz:
default:
return errI2CNotImplemented
}
// disable I2C interface before any configuration changes
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE)
i2c.Bus.TIMINGR.Set(i2c.getFreqRange(br))
// Disable Generalcall and NoStretch, Enable peripheral
i2c.Bus.CR1.Set(stm32.I2C_CR1_PE)
return nil
}
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
+13 -2
View File
@@ -51,9 +51,20 @@ func (uart *UART) setRegisters() {
//---------- I2C related code
// Gets the value for TIMINGR register
func (i2c *I2C) getFreqRange() uint32 {
func (i2c *I2C) getFreqRange(br uint32) uint32 {
// This is a 'magic' value calculated by STM32CubeMX
// for 27MHz PCLK1 (216MHz CPU Freq / 8).
// TODO: Do calculations based on PCLK1
return 0x00606A9B
switch br {
case 10 * KHz:
return 0x5010C0FF
case 100 * KHz:
return 0x00606A9B
case 400 * KHz:
return 0x00201625
case 500 * KHz:
return 0x00100429
default:
return 0
}
}
+14 -3
View File
@@ -298,9 +298,20 @@ func (spi SPI) configurePins(config SPIConfig) {
//---------- I2C related types and code
// Gets the value for TIMINGR register
func (i2c I2C) getFreqRange() uint32 {
func (i2c I2C) getFreqRange(br uint32) uint32 {
// This is a 'magic' value calculated by STM32CubeMX
// for 80MHz PCLK1.
// for 16MHz PCLK1.
// TODO: Do calculations based on PCLK1
return 0x00303D5B
switch br {
case 10 * KHz:
return 0x40003EFF
case 100 * KHz:
return 0x00303D5B
case 400 * KHz:
return 0x0010061A
case 500 * KHz:
return 0x00000117
default:
return 0
}
}
+14 -3
View File
@@ -17,9 +17,20 @@ const APB2_TIM_FREQ = 80e6 // 80MHz
//---------- I2C related code
// Gets the value for TIMINGR register
func (i2c *I2C) getFreqRange() uint32 {
// This is a 'magic' value calculated by STM32CubeMX
func (i2c *I2C) getFreqRange(br uint32) uint32 {
// These are 'magic' values calculated by STM32CubeMX
// for 80MHz PCLK1.
// TODO: Do calculations based on PCLK1
return 0x10909CEC
switch br {
case 10 * KHz:
return 0xF010F3FE
case 100 * KHz:
return 0x10909CEC
case 400 * KHz:
return 0x00702991
case 500 * KHz:
return 0x00300E84
default:
return 0
}
}
+13 -2
View File
@@ -17,9 +17,20 @@ const APB2_TIM_FREQ = 120e6 // 120MHz
//---------- I2C related code
// Gets the value for TIMINGR register
func (i2c *I2C) getFreqRange() uint32 {
func (i2c *I2C) getFreqRange(br uint32) uint32 {
// This is a 'magic' value calculated by STM32CubeMX
// for 120MHz PCLK1.
// TODO: Do calculations based on PCLK1
return 0x307075B1
switch br {
case 10 * KHz:
return 0x0 // does this even work? zero is weird here.
case 100 * KHz:
return 0x307075B1
case 400 * KHz:
return 0x00B03FDB
case 500 * KHz:
return 0x005017C7
default:
return 0
}
}

Some files were not shown because too many files have changed in this diff Show More