Compare commits

..

2 Commits

Author SHA1 Message Date
Ayke van Laethem 28a083633c cgo: allow --export= in LDFLAGS
This allows people to export some functions, such as malloc. Example:

    // #cgo LDFLAGS: --export=malloc
    import "C"

This exports the function malloc.

Note that this is somewhat unsafe right now, but it is used regardless.
By using this workaround, people have some time to transition away from
using malloc/free directly or until malloc is made safe to be used in
this way.
2022-09-15 11:36:29 +02:00
Ayke van Laethem 7e7814a087 wasm: do not export malloc, calloc, realloc, free
These functions were exported by accident, because the compiler had no
way of saying these functions shouldn't be exported.

This can be a big code size reduction for small programs. Before:

    $ tinygo build -o test.wasm -target=wasi -no-debug -scheduler=none ./testdata/alias.go && ls -l test.wasm
    -rwxrwxr-x 1 ayke ayke 2947  8 sep 13:47 test.wasm

After:

    $ tinygo build -o test.wasm -target=wasi -no-debug -scheduler=none ./testdata/alias.go && ls -l test.wasm
    -rwxrwxr-x 1 ayke ayke 968  8 sep 13:47 test.wasm

This is all because the GC isn't needed anymore.

This commit also adds support for using //go:wasm-module to set the
module name of an exported function (the default remains env).
2022-09-15 11:36:26 +02:00
119 changed files with 512 additions and 931 deletions
+10 -1
View File
@@ -118,7 +118,13 @@ jobs:
steps: steps:
- test-linux: - test-linux:
llvm: "14" llvm: "14"
resource_class: large test-llvm14-go119:
docker:
- image: golang:1.19beta1-buster
steps:
- test-linux:
llvm: "14"
fmt-check: false
workflows: workflows:
test-all: test-all:
@@ -126,3 +132,6 @@ workflows:
# This tests our lowest supported versions of Go and LLVM, to make sure at # This tests our lowest supported versions of Go and LLVM, to make sure at
# least the smoke tests still pass. # least the smoke tests still pass.
- test-llvm14-go118 - test-llvm14-go118
# This tests a beta version of Go. It should be removed once regular
# release builds are built using this version.
- test-llvm14-go119
+2 -2
View File
@@ -34,7 +34,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.19' go-version: '1.18.1'
cache: true cache: true
- name: Cache LLVM source - name: Cache LLVM source
uses: actions/cache@v3 uses: actions/cache@v3
@@ -114,7 +114,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.19' go-version: '1.18'
cache: true cache: true
- name: Build TinyGo - name: Build TinyGo
run: go install run: go install
+5 -5
View File
@@ -18,7 +18,7 @@ jobs:
# statically linked binary. # statically linked binary.
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: golang:1.19-alpine image: golang:1.18-alpine
steps: steps:
- name: Install apk dependencies - name: Install apk dependencies
# tar: needed for actions/cache@v3 # tar: needed for actions/cache@v3
@@ -118,7 +118,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.19' go-version: '1.18.1'
cache: true cache: true
- name: Install wasmtime - name: Install wasmtime
run: | run: |
@@ -171,7 +171,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.19' go-version: '1.18.1'
cache: true cache: true
- name: Install Node.js - name: Install Node.js
uses: actions/setup-node@v2 uses: actions/setup-node@v2
@@ -271,7 +271,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.19' go-version: '1.18.1'
cache: true cache: true
- name: Cache LLVM source - name: Cache LLVM source
uses: actions/cache@v3 uses: actions/cache@v3
@@ -371,7 +371,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.19' go-version: '1.18.1'
cache: true cache: true
- name: Cache LLVM source - name: Cache LLVM source
uses: actions/cache@v3 uses: actions/cache@v3
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
- name: Install Go - name: Install Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: '1.19' go-version: '1.18.1'
cache: true cache: true
- name: Cache LLVM source - name: Cache LLVM source
uses: actions/cache@v3 uses: actions/cache@v3
-84
View File
@@ -1,87 +1,3 @@
0.26.0
---
* **general**
- remove support for LLVM 13
- remove calls to deprecated ioutil package
- move from `os.IsFoo` to `errors.Is(err, ErrFoo)`
- fix for builds using an Android host
- make interp timeout configurable from command line
- ignore ports with VID/PID if there is no candidates
- drop support for Go 1.16 and Go 1.17
- update serial package to v1.3.5 for latest bugfixes
- remove GOARM from `tinygo info`
- add flag for setting the goroutine stack size
- add serial port monitoring functionality
* **compiler**
- `cgo`: implement support for static functions
- `cgo`: fix panic when FuncType.Results is nil
- `compiler`: add aliases for `edwards25519/field.feMul` and `field.feSquare`
- `compiler`: fix incorrect DWARF type in some generic parameters
- `compiler`: use LLVM math builtins everywhere
- `compiler`: replace some math operation bodies with LLVM intrinsics
- `compiler`: replace math aliases with intrinsics
- `compiler`: fix `unsafe.Sizeof` for chan and map values
- `compileopts`: use tags parser from buildutil
- `compileopts`: use backticks for regexp to avoid extra escapes
- `compileopts`: fail fast on duplicate values in target field slices
- `compileopts`: fix windows/arm target triple
- `compileopts`: improve error handling when loading target/*.json
- `compileopts`: add support for stlink-dap programmer
- `compileopts`: do not complain about `-no-debug` on MacOS
- `goenv`: support `GOOS=android`
- `interp`: fix reading from external global
- `loader`: fix link error for `crypto/internal/boring/sig.StandardCrypto`
* **standard library**
- rename assembly files to .S extension
- `machine`: add PWM peripheral comments to pins
- `machine`: improve UARTParity slightly
- `machine`: do not export DFU_MAGIC_* constants on nrf52840
- `machine`: rename `PinInputPullUp`/`PinInputPullDown`
- `machine`: add `KHz`, `MHz`, `GHz` constants, deprecate `TWI_FREQ_*` constants
- `machine`: remove level triggered pin interrupts
- `machine`: do not expose `RESET_MAGIC_VALUE`
- `machine`: use `NoPin` constant where appropriate (instead of `0` for example)
- `net`: sync net.go with Go 1.18 stdlib
- `os`: add `SyscallError.Timeout`
- `os`: add `ErrProcessDone` error
- `reflect`: implement `CanInterface` and fix string `Index`
- `runtime`: make `MemStats` available to leaking collector
- `runtime`: add `MemStats.TotalAlloc`
- `runtime`: add `MemStats.Mallocs` and `Frees`
- `runtime`: add support for `time.NewTimer` and `time.NewTicker`
- `runtime`: implement `resetTimer`
- `runtime`: ensure some headroom for the GC to run
- `runtime`: make gc and scheduler asserts settable with build tags
- `runtime/pprof`: add `WriteHeapProfile`
- `runtime/pprof`: `runtime/trace`: stub some additional functions
- `sync`: implement `Map.LoadAndDelete`
- `syscall`: group WASI consts by purpose
- `syscall`: add WASI `{D,R}SYNC`, `NONBLOCK` FD flags
- `syscall`: add ENOTCONN on darwin
- `testing`: add support for -benchmem
* **targets**
- remove USB vid/pid pair of bootloader
- `esp32c3`: remove unused `UARTStopBits` constants
- `nrf`: implement `GetRNG` function
- `nrf`: `rp2040`: add `machine.ReadTemperature`
- `nrf52`: cleanup s140v6 and s140v7 uf2 targets
- `rp2040`: implement semi-random RNG based on ROSC based on pico-sdk
- `wasm`: add summary of wasm examples and fix callback bug
- `wasm`: do not allow undefined symbols (`--allow-undefined`)
- `wasm`: make sure buffers returned by `malloc` are kept until `free` is called
- `windows`: save and restore xmm registers when switching goroutines
* **boards**
- add Pimoroni's Tufty2040
- add XIAO ESP32C3
- add Adafruit QT2040
- add Adafruit QT Py RP2040
- `esp32c3-12f`: `matrixportal-m4`: `p1am-100`: remove duplicate build tags
- `hifive1-qemu`: remove this emulated board
- `wioterminal`: add UART3 for RTL8720DN
- `xiao-ble`: fix usbpid
0.25.0 0.25.0
--- ---
+1 -1
View File
@@ -1,5 +1,5 @@
# tinygo-llvm stage obtains the llvm source for TinyGo # tinygo-llvm stage obtains the llvm source for TinyGo
FROM golang:1.19 AS tinygo-llvm FROM golang:1.18 AS tinygo-llvm
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y apt-utils make cmake clang-11 binutils-avr gcc-avr avr-libc ninja-build apt-get install -y apt-utils make cmake clang-11 binutils-avr gcc-avr avr-libc ninja-build
+3 -10
View File
@@ -330,6 +330,7 @@ endif
# compress/lzw appears to hang on wasi # compress/lzw appears to hang on wasi
# crypto/hmac fails on wasi, it exits with a "slice out of range" panic # crypto/hmac fails on wasi, it exits with a "slice out of range" panic
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows # debug/plan9obj requires os.ReadAt, which is not yet supported on windows
# io/fs requires os.ReadDir, which is not yet supported on windows or wasi
# io/ioutil requires os.ReadDir, which is not yet supported on windows or wasi # io/ioutil requires os.ReadDir, which is not yet supported on windows or wasi
# strconv requires recover() which is not yet supported on wasi # strconv requires recover() which is not yet supported on wasi
# text/template/parse requires recover(), which is not yet supported on wasi # text/template/parse requires recover(), which is not yet supported on wasi
@@ -343,6 +344,7 @@ TEST_PACKAGES_LINUX := \
crypto/hmac \ crypto/hmac \
debug/dwarf \ debug/dwarf \
debug/plan9obj \ debug/plan9obj \
io/fs \
io/ioutil \ io/ioutil \
strconv \ strconv \
testing/fstest \ testing/fstest \
@@ -371,15 +373,12 @@ report-stdlib-tests-pass:
# Standard library packages that pass tests quickly on the current platform # Standard library packages that pass tests quickly on the current platform
ifeq ($(shell uname),Darwin) ifeq ($(shell uname),Darwin)
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_DARWIN) TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_DARWIN)
TEST_IOFS := true
endif endif
ifeq ($(shell uname),Linux) ifeq ($(shell uname),Linux)
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_LINUX) TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_LINUX)
TEST_IOFS := true
endif endif
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS) TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS)
TEST_IOFS := false
endif endif
# Test known-working standard library packages. # Test known-working standard library packages.
@@ -387,12 +386,6 @@ endif
.PHONY: tinygo-test .PHONY: tinygo-test
tinygo-test: tinygo-test:
$(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW) $(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
@# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also
@# requires a large stack-size. Hence, io/fs is only run conditionally.
@# For more details, see the comments on issue #3143.
ifeq ($(TEST_IOFS),true)
$(TINYGO) test -stack-size=6MB io/fs
endif
tinygo-test-fast: tinygo-test-fast:
$(TINYGO) test $(TEST_PACKAGES_HOST) $(TINYGO) test $(TEST_PACKAGES_HOST)
tinygo-bench: tinygo-bench:
@@ -618,7 +611,7 @@ endif
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=challenger-rp2040 examples/blinky1 $(TINYGO) build -size short -o test.hex -target=challenger-rp2040 examples/blinky1
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=trinkey-qt2040 examples/temp $(TINYGO) build -size short -o test.hex -target=trinkey-qt2040 examples/adc_rp2040
@$(MD5SUM) test.hex @$(MD5SUM) test.hex
# test pwm # test pwm
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm $(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
+15 -12
View File
@@ -178,7 +178,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
Scheduler: config.Scheduler(), Scheduler: config.Scheduler(),
AutomaticStackSize: config.AutomaticStackSize(), AutomaticStackSize: config.AutomaticStackSize(),
DefaultStackSize: config.StackSize(), DefaultStackSize: config.Target.DefaultStackSize,
NeedsStackObjects: config.NeedsStackObjects(), NeedsStackObjects: config.NeedsStackObjects(),
Debug: true, Debug: true,
} }
@@ -700,18 +700,21 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
// Add embedded files. // Add embedded files.
linkerDependencies = append(linkerDependencies, embedFileObjects...) linkerDependencies = append(linkerDependencies, embedFileObjects...)
// Determine whether the compilation configuration would result in debug
// (DWARF) information in the object files.
var hasDebug = true
if config.GOOS() == "darwin" {
// Debug information isn't stored in the binary itself on MacOS but
// is left in the object files by default. The binary does store the
// path to these object files though.
hasDebug = false
}
// Strip debug information with -no-debug. // Strip debug information with -no-debug.
if hasDebug && !config.Debug() { if !config.Debug() {
for _, tag := range config.BuildTags() {
if tag == "baremetal" {
// Don't use -no-debug on baremetal targets. It makes no sense:
// the debug information isn't flashed to the device anyway.
return fmt.Errorf("stripping debug information is unnecessary for baremetal targets")
}
}
if config.GOOS() == "darwin" {
// Debug information isn't stored in the binary itself on MacOS but
// is left in the object files by default. The binary does store the
// path to these object files though.
return errors.New("cannot remove debug information: MacOS doesn't store debug info in the executable by default")
}
if config.Target.Linker == "wasm-ld" { if config.Target.Linker == "wasm-ld" {
// Don't just strip debug information, also compress relocations // Don't just strip debug information, also compress relocations
// while we're at it. Relocations can only be compressed when debug // while we're at it. Relocations can only be compressed when debug
+16 -60
View File
@@ -32,7 +32,6 @@ type cgoPackage struct {
errors []error errors []error
currentDir string // current working directory currentDir string // current working directory
packageDir string // full path to the package to process packageDir string // full path to the package to process
importPath string
fset *token.FileSet fset *token.FileSet
tokenFiles map[string]*token.File tokenFiles map[string]*token.File
definedGlobally map[string]ast.Node definedGlobally map[string]ast.Node
@@ -40,15 +39,12 @@ type cgoPackage struct {
cflags []string // CFlags from #cgo lines cflags []string // CFlags from #cgo lines
ldflags []string // LDFlags from #cgo lines ldflags []string // LDFlags from #cgo lines
visitedFiles map[string][]byte visitedFiles map[string][]byte
cgoHeaders []string
} }
// cgoFile holds information only for a single Go file (with one or more // cgoFile holds information only for a single Go file (with one or more
// `import "C"` statements). // `import "C"` statements).
type cgoFile struct { type cgoFile struct {
*cgoPackage *cgoPackage
file *ast.File
index int
defined map[string]ast.Node defined map[string]ast.Node
names map[string]clangCursor names map[string]clangCursor
} }
@@ -162,10 +158,9 @@ func GoBytes(ptr unsafe.Pointer, length C.int) []byte {
// functions), the CFLAGS and LDFLAGS found in #cgo lines, and a map of file // functions), the CFLAGS and LDFLAGS found in #cgo lines, and a map of file
// hashes of the accessed C header files. If there is one or more error, it // hashes of the accessed C header files. If there is one or more error, it
// returns these in the []error slice but still modifies the AST. // returns these in the []error slice but still modifies the AST.
func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cflags []string, clangHeaders string) (*ast.File, []string, []string, []string, map[string][]byte, []error) { func Process(files []*ast.File, dir string, fset *token.FileSet, cflags []string, clangHeaders string) (*ast.File, []string, []string, []string, map[string][]byte, []error) {
p := &cgoPackage{ p := &cgoPackage{
currentDir: dir, currentDir: dir,
importPath: importPath,
fset: fset, fset: fset,
tokenFiles: map[string]*token.File{}, tokenFiles: map[string]*token.File{},
definedGlobally: map[string]ast.Node{}, definedGlobally: map[string]ast.Node{},
@@ -215,13 +210,13 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
} }
} }
// Patch some types, for example *C.char in C.CString. // Patch some types, for example *C.char in C.CString.
cf := p.newCGoFile(nil, -1) // dummy *cgoFile for the walker cf := p.newCGoFile()
astutil.Apply(p.generated, func(cursor *astutil.Cursor) bool { astutil.Apply(p.generated, func(cursor *astutil.Cursor) bool {
return cf.walker(cursor, nil) return cf.walker(cursor, nil)
}, nil) }, nil)
// Find `import "C"` C fragments in the file. // Find `import "C"` C fragments in the file.
p.cgoHeaders = make([]string, len(files)) // combined CGo header fragment for each file cgoHeaders := make([]string, len(files)) // combined CGo header fragment for each file
for i, f := range files { for i, f := range files {
var cgoHeader string var cgoHeader string
for i := 0; i < len(f.Decls); i++ { for i := 0; i < len(f.Decls); i++ {
@@ -280,7 +275,7 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
cgoHeader += fragment cgoHeader += fragment
} }
p.cgoHeaders[i] = cgoHeader cgoHeaders[i] = cgoHeader
} }
// Define CFlags that will be used while parsing the package. // Define CFlags that will be used while parsing the package.
@@ -294,7 +289,7 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
} }
// Retrieve types such as C.int, C.longlong, etc from C. // Retrieve types such as C.int, C.longlong, etc from C.
p.newCGoFile(nil, -1).readNames(builtinAliasTypedefs, cflagsForCGo, "", func(names map[string]clangCursor) { p.newCGoFile().readNames(builtinAliasTypedefs, cflagsForCGo, "", func(names map[string]clangCursor) {
gen := &ast.GenDecl{ gen := &ast.GenDecl{
TokPos: token.NoPos, TokPos: token.NoPos,
Tok: token.TYPE, Tok: token.TYPE,
@@ -308,8 +303,8 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
// Process CGo imports for each file. // Process CGo imports for each file.
for i, f := range files { for i, f := range files {
cf := p.newCGoFile(f, i) cf := p.newCGoFile()
cf.readNames(p.cgoHeaders[i], cflagsForCGo, filepath.Base(fset.File(f.Pos()).Name()), func(names map[string]clangCursor) { cf.readNames(cgoHeaders[i], cflagsForCGo, filepath.Base(fset.File(f.Pos()).Name()), func(names map[string]clangCursor) {
for _, name := range builtinAliases { for _, name := range builtinAliases {
// Names such as C.int should not be obtained from C. // Names such as C.int should not be obtained from C.
// This works around an issue in picolibc that has `#define int` // This works around an issue in picolibc that has `#define int`
@@ -325,14 +320,12 @@ func Process(files []*ast.File, dir, importPath string, fset *token.FileSet, cfl
// Print the newly generated in-memory AST, for debugging. // Print the newly generated in-memory AST, for debugging.
//ast.Print(fset, p.generated) //ast.Print(fset, p.generated)
return p.generated, p.cgoHeaders, p.cflags, p.ldflags, p.visitedFiles, p.errors return p.generated, cgoHeaders, p.cflags, p.ldflags, p.visitedFiles, p.errors
} }
func (p *cgoPackage) newCGoFile(file *ast.File, index int) *cgoFile { func (p *cgoPackage) newCGoFile() *cgoFile {
return &cgoFile{ return &cgoFile{
cgoPackage: p, cgoPackage: p,
file: file,
index: index,
defined: make(map[string]ast.Node), defined: make(map[string]ast.Node),
names: make(map[string]clangCursor), names: make(map[string]clangCursor),
} }
@@ -948,9 +941,6 @@ func (p *cgoPackage) isEquivalentAST(a, b ast.Node) bool {
if !ok { if !ok {
return false return false
} }
if node == nil || b == nil {
return node == b
}
if len(node.List) != len(b.List) { if len(node.List) != len(b.List) {
return false return false
} }
@@ -1127,11 +1117,8 @@ func (f *cgoFile) getASTDeclName(name string, found clangCursor, iscall bool) st
return alias return alias
} }
node := f.getASTDeclNode(name, found, iscall) node := f.getASTDeclNode(name, found, iscall)
if node, ok := node.(*ast.FuncDecl); ok { if _, ok := node.(*ast.FuncDecl); ok && !iscall {
if !iscall { return "C." + name + "$funcaddr"
return node.Name.Name + "$funcaddr"
}
return node.Name.Name
} }
return "C." + name return "C." + name
} }
@@ -1155,7 +1142,7 @@ func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) as
// Original cgo reports an error like // Original cgo reports an error like
// cgo: inconsistent definitions for C.myint // cgo: inconsistent definitions for C.myint
// which is far less helpful. // which is far less helpful.
f.addError(getPos(node), name+" defined previously at "+f.fset.Position(getPos(newNode)).String()+" with a different type") f.addError(getPos(node), "defined previously at "+f.fset.Position(getPos(newNode)).String()+" with a different type")
} }
f.defined[name] = node f.defined[name] = node
return node return node
@@ -1163,39 +1150,11 @@ func (f *cgoFile) getASTDeclNode(name string, found clangCursor, iscall bool) as
// The declaration has no AST node. Create it now. // The declaration has no AST node. Create it now.
f.defined[name] = nil f.defined[name] = nil
node, extra := f.createASTNode(name, found) node, elaboratedType := f.createASTNode(name, found)
f.defined[name] = node f.defined[name] = node
f.definedGlobally[name] = node
switch node := node.(type) { switch node := node.(type) {
case *ast.FuncDecl: case *ast.FuncDecl:
if strings.HasPrefix(node.Doc.List[0].Text, "//export _Cgo_static_") {
// Static function. Only accessible in the current Go file.
globalName := strings.TrimPrefix(node.Doc.List[0].Text, "//export ")
// Make an alias. Normally this is done using the alias function
// attribute, but MacOS for some reason doesn't support this (even
// though the linker has support for aliases in the form of N_INDR).
// Therefore, create an actual function for MacOS.
var params []string
for _, param := range node.Type.Params.List {
params = append(params, param.Names[0].Name)
}
callInst := fmt.Sprintf("%s(%s);", name, strings.Join(params, ", "))
if node.Type.Results != nil {
callInst = "return " + callInst
}
aliasDeclaration := fmt.Sprintf(`
#ifdef __APPLE__
%s {
%s
}
#else
extern __typeof(%s) %s __attribute__((alias(%#v)));
#endif
`, extra.(string), callInst, name, globalName, name)
f.cgoHeaders[f.index] += "\n\n" + aliasDeclaration
} else {
// Regular (non-static) function.
f.definedGlobally[name] = node
}
f.generated.Decls = append(f.generated.Decls, node) f.generated.Decls = append(f.generated.Decls, node)
// Also add a declaration like the following: // Also add a declaration like the following:
// var C.foo$funcaddr unsafe.Pointer // var C.foo$funcaddr unsafe.Pointer
@@ -1203,7 +1162,7 @@ extern __typeof(%s) %s __attribute__((alias(%#v)));
Tok: token.VAR, Tok: token.VAR,
Specs: []ast.Spec{ Specs: []ast.Spec{
&ast.ValueSpec{ &ast.ValueSpec{
Names: []*ast.Ident{{Name: node.Name.Name + "$funcaddr"}}, Names: []*ast.Ident{{Name: "C." + name + "$funcaddr"}},
Type: &ast.SelectorExpr{ Type: &ast.SelectorExpr{
X: &ast.Ident{Name: "unsafe"}, X: &ast.Ident{Name: "unsafe"},
Sel: &ast.Ident{Name: "Pointer"}, Sel: &ast.Ident{Name: "Pointer"},
@@ -1212,10 +1171,8 @@ extern __typeof(%s) %s __attribute__((alias(%#v)));
}, },
}) })
case *ast.GenDecl: case *ast.GenDecl:
f.definedGlobally[name] = node
f.generated.Decls = append(f.generated.Decls, node) f.generated.Decls = append(f.generated.Decls, node)
case *ast.TypeSpec: case *ast.TypeSpec:
f.definedGlobally[name] = node
f.generated.Decls = append(f.generated.Decls, &ast.GenDecl{ f.generated.Decls = append(f.generated.Decls, &ast.GenDecl{
Tok: token.TYPE, Tok: token.TYPE,
Specs: []ast.Spec{node}, Specs: []ast.Spec{node},
@@ -1229,8 +1186,7 @@ extern __typeof(%s) %s __attribute__((alias(%#v)));
// If this is a struct or union it may need bitfields or union accessor // If this is a struct or union it may need bitfields or union accessor
// methods. // methods.
switch elaboratedType := extra.(type) { if elaboratedType != nil {
case *elaboratedTypeInfo:
// Add struct bitfields. // Add struct bitfields.
for _, bitfield := range elaboratedType.bitfields { for _, bitfield := range elaboratedType.bitfields {
f.createBitfieldGetter(bitfield, "C."+name) f.createBitfieldGetter(bitfield, "C."+name)
+1 -79
View File
@@ -48,7 +48,7 @@ func TestCGo(t *testing.T) {
} }
// Process the AST with CGo. // Process the AST with CGo.
cgoAST, _, _, _, _, cgoErrors := Process([]*ast.File{f}, "testdata", "main", fset, cflags, "") cgoAST, _, _, _, _, cgoErrors := Process([]*ast.File{f}, "testdata", fset, cflags, "")
// Check the AST for type errors. // Check the AST for type errors.
var typecheckErrors []error var typecheckErrors []error
@@ -115,84 +115,6 @@ func TestCGo(t *testing.T) {
} }
} }
func Test_cgoPackage_isEquivalentAST(t *testing.T) {
fieldA := &ast.Field{Type: &ast.BasicLit{Kind: token.STRING, Value: "a"}}
fieldB := &ast.Field{Type: &ast.BasicLit{Kind: token.STRING, Value: "b"}}
listOfFieldA := &ast.FieldList{List: []*ast.Field{fieldA}}
listOfFieldB := &ast.FieldList{List: []*ast.Field{fieldB}}
funcDeclA := &ast.FuncDecl{Name: &ast.Ident{Name: "a"}, Type: &ast.FuncType{Params: &ast.FieldList{}, Results: listOfFieldA}}
funcDeclB := &ast.FuncDecl{Name: &ast.Ident{Name: "b"}, Type: &ast.FuncType{Params: &ast.FieldList{}, Results: listOfFieldB}}
funcDeclNoResults := &ast.FuncDecl{Name: &ast.Ident{Name: "C"}, Type: &ast.FuncType{Params: &ast.FieldList{}}}
testCases := []struct {
name string
a, b ast.Node
expected bool
}{
{
name: "both nil",
expected: true,
},
{
name: "not same type",
a: fieldA,
b: &ast.FuncDecl{},
expected: false,
},
{
name: "Field same",
a: fieldA,
b: fieldA,
expected: true,
},
{
name: "Field different",
a: fieldA,
b: fieldB,
expected: false,
},
{
name: "FuncDecl Type Results nil",
a: funcDeclNoResults,
b: funcDeclNoResults,
expected: true,
},
{
name: "FuncDecl Type Results same",
a: funcDeclA,
b: funcDeclA,
expected: true,
},
{
name: "FuncDecl Type Results different",
a: funcDeclA,
b: funcDeclB,
expected: false,
},
{
name: "FuncDecl Type Results a nil",
a: funcDeclNoResults,
b: funcDeclB,
expected: false,
},
{
name: "FuncDecl Type Results b nil",
a: funcDeclA,
b: funcDeclNoResults,
expected: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
p := &cgoPackage{}
if got := p.isEquivalentAST(tc.a, tc.b); tc.expected != got {
t.Errorf("expected %v, got %v", tc.expected, got)
}
})
}
}
// simpleImporter implements the types.Importer interface, but only allows // simpleImporter implements the types.Importer interface, but only allows
// importing the unsafe package. // importing the unsafe package.
type simpleImporter struct { type simpleImporter struct {
+4 -33
View File
@@ -4,9 +4,7 @@ package cgo
// modification. It does not touch the AST itself. // modification. It does not touch the AST itself.
import ( import (
"crypto/sha256"
"crypto/sha512" "crypto/sha512"
"encoding/hex"
"fmt" "fmt"
"go/ast" "go/ast"
"go/scanner" "go/scanner"
@@ -45,8 +43,6 @@ typedef struct {
GoCXCursor tinygo_clang_getTranslationUnitCursor(CXTranslationUnit tu); GoCXCursor tinygo_clang_getTranslationUnitCursor(CXTranslationUnit tu);
unsigned tinygo_clang_visitChildren(GoCXCursor parent, CXCursorVisitor visitor, CXClientData client_data); unsigned tinygo_clang_visitChildren(GoCXCursor parent, CXCursorVisitor visitor, CXClientData client_data);
CXString tinygo_clang_getCursorSpelling(GoCXCursor c); CXString tinygo_clang_getCursorSpelling(GoCXCursor c);
CXString tinygo_clang_getCursorPrettyPrinted(GoCXCursor c, CXPrintingPolicy Policy);
CXPrintingPolicy tinygo_clang_getCursorPrintingPolicy(GoCXCursor c);
enum CXCursorKind tinygo_clang_getCursorKind(GoCXCursor c); enum CXCursorKind tinygo_clang_getCursorKind(GoCXCursor c);
CXType tinygo_clang_getCursorType(GoCXCursor c); CXType tinygo_clang_getCursorType(GoCXCursor c);
GoCXCursor tinygo_clang_getTypeDeclaration(CXType t); GoCXCursor tinygo_clang_getTypeDeclaration(CXType t);
@@ -54,7 +50,6 @@ CXType tinygo_clang_getTypedefDeclUnderlyingType(GoCXCursor c);
CXType tinygo_clang_getCursorResultType(GoCXCursor c); CXType tinygo_clang_getCursorResultType(GoCXCursor c);
int tinygo_clang_Cursor_getNumArguments(GoCXCursor c); int tinygo_clang_Cursor_getNumArguments(GoCXCursor c);
GoCXCursor tinygo_clang_Cursor_getArgument(GoCXCursor c, unsigned i); GoCXCursor tinygo_clang_Cursor_getArgument(GoCXCursor c, unsigned i);
enum CX_StorageClass tinygo_clang_Cursor_getStorageClass(GoCXCursor c);
CXSourceLocation tinygo_clang_getCursorLocation(GoCXCursor c); CXSourceLocation tinygo_clang_getCursorLocation(GoCXCursor c);
CXSourceRange tinygo_clang_getCursorExtent(GoCXCursor c); CXSourceRange tinygo_clang_getCursorExtent(GoCXCursor c);
CXTranslationUnit tinygo_clang_Cursor_getTranslationUnit(GoCXCursor c); CXTranslationUnit tinygo_clang_Cursor_getTranslationUnit(GoCXCursor c);
@@ -194,7 +189,7 @@ func (f *cgoFile) readNames(fragment string, cflags []string, filename string, c
// Convert the AST node under the given Clang cursor to a Go AST node and return // Convert the AST node under the given Clang cursor to a Go AST node and return
// it. // it.
func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) { func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, *elaboratedTypeInfo) {
kind := C.tinygo_clang_getCursorKind(c) kind := C.tinygo_clang_getCursorKind(c)
pos := f.getCursorPosition(c) pos := f.getCursorPosition(c)
switch kind { switch kind {
@@ -205,43 +200,19 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
Kind: ast.Fun, Kind: ast.Fun,
Name: "C." + name, Name: "C." + name,
} }
exportName := name
localName := name
var stringSignature string
if C.tinygo_clang_Cursor_getStorageClass(c) == C.CX_SC_Static {
// A static function is assigned a globally unique symbol name based
// on the file path (like _Cgo_static_2d09198adbf58f4f4655_foo) and
// has a different Go name in the form of C.foo!symbols.go instead
// of just C.foo.
path := f.importPath + "/" + filepath.Base(f.fset.File(f.file.Pos()).Name())
staticIDBuf := sha256.Sum256([]byte(path))
staticID := hex.EncodeToString(staticIDBuf[:10])
exportName = "_Cgo_static_" + staticID + "_" + name
localName = name + "!" + filepath.Base(path)
// Create a signature. This is necessary for MacOS to forward the
// call, because MacOS doesn't support aliases like ELF and PE do.
// (There is N_INDR but __attribute__((alias("..."))) doesn't work).
policy := C.tinygo_clang_getCursorPrintingPolicy(c)
defer C.clang_PrintingPolicy_dispose(policy)
C.clang_PrintingPolicy_setProperty(policy, C.CXPrintingPolicy_TerseOutput, 1)
stringSignature = getString(C.tinygo_clang_getCursorPrettyPrinted(c, policy))
stringSignature = strings.Replace(stringSignature, " "+name+"(", " "+exportName+"(", 1)
stringSignature = strings.TrimPrefix(stringSignature, "static ")
}
args := make([]*ast.Field, numArgs) args := make([]*ast.Field, numArgs)
decl := &ast.FuncDecl{ decl := &ast.FuncDecl{
Doc: &ast.CommentGroup{ Doc: &ast.CommentGroup{
List: []*ast.Comment{ List: []*ast.Comment{
{ {
Slash: pos - 1, Slash: pos - 1,
Text: "//export " + exportName, Text: "//export " + name,
}, },
}, },
}, },
Name: &ast.Ident{ Name: &ast.Ident{
NamePos: pos, NamePos: pos,
Name: "C." + localName, Name: "C." + name,
Obj: obj, Obj: obj,
}, },
Type: &ast.FuncType{ Type: &ast.FuncType{
@@ -292,7 +263,7 @@ func (f *cgoFile) createASTNode(name string, c clangCursor) (ast.Node, any) {
} }
} }
obj.Decl = decl obj.Decl = decl
return decl, stringSignature return decl, nil
case C.CXCursor_StructDecl, C.CXCursor_UnionDecl: case C.CXCursor_StructDecl, C.CXCursor_UnionDecl:
typ := f.makeASTRecordType(c, pos) typ := f.makeASTRecordType(c, pos)
typeName := "C." + name typeName := "C." + name
-12
View File
@@ -17,14 +17,6 @@ CXString tinygo_clang_getCursorSpelling(CXCursor c) {
return clang_getCursorSpelling(c); return clang_getCursorSpelling(c);
} }
CXString tinygo_clang_getCursorPrettyPrinted(CXCursor c, CXPrintingPolicy policy) {
return clang_getCursorPrettyPrinted(c, policy);
}
CXPrintingPolicy tinygo_clang_getCursorPrintingPolicy(CXCursor c) {
return clang_getCursorPrintingPolicy(c);
}
enum CXCursorKind tinygo_clang_getCursorKind(CXCursor c) { enum CXCursorKind tinygo_clang_getCursorKind(CXCursor c) {
return clang_getCursorKind(c); return clang_getCursorKind(c);
} }
@@ -53,10 +45,6 @@ CXCursor tinygo_clang_Cursor_getArgument(CXCursor c, unsigned i) {
return clang_Cursor_getArgument(c, i); return clang_Cursor_getArgument(c, i);
} }
enum CX_StorageClass tinygo_clang_Cursor_getStorageClass(CXCursor c) {
return clang_Cursor_getStorageClass(c);
}
CXSourceLocation tinygo_clang_getCursorLocation(CXCursor c) { CXSourceLocation tinygo_clang_getCursorLocation(CXCursor c) {
return clang_getCursorLocation(c); return clang_getCursorLocation(c);
} }
+1
View File
@@ -142,6 +142,7 @@ var validLinkerFlags = []*regexp.Regexp{
re(`-L([^@\-].*)`), re(`-L([^@\-].*)`),
re(`-O`), re(`-O`),
re(`-O([^@\-].*)`), re(`-O([^@\-].*)`),
re(`--export=(.+)`), // for wasm-ld
re(`-f(no-)?(pic|PIC|pie|PIE)`), re(`-f(no-)?(pic|PIC|pie|PIE)`),
re(`-f(no-)?openmp(-simd)?`), re(`-f(no-)?openmp(-simd)?`),
re(`-fsanitize=([^@\-].*)`), re(`-fsanitize=([^@\-].*)`),
-2
View File
@@ -5,7 +5,6 @@ package main
int foo(int a, int b); int foo(int a, int b);
void variadic0(); void variadic0();
void variadic2(int x, int y, ...); void variadic2(int x, int y, ...);
static void staticfunc(int x);
// Global variable signatures. // Global variable signatures.
extern int someValue; extern int someValue;
@@ -17,7 +16,6 @@ func accessFunctions() {
C.foo(3, 4) C.foo(3, 4)
C.variadic0() C.variadic0()
C.variadic2(3, 5) C.variadic2(3, 5)
C.staticfunc(3)
} }
func accessGlobals() { func accessGlobals() {
-5
View File
@@ -55,10 +55,5 @@ func C.variadic2(x C.int, y C.int)
var C.variadic2$funcaddr unsafe.Pointer var C.variadic2$funcaddr unsafe.Pointer
//export _Cgo_static_173c95a79b6df1980521_staticfunc
func C.staticfunc!symbols.go(x C.int)
var C.staticfunc!symbols.go$funcaddr unsafe.Pointer
//go:extern someValue //go:extern someValue
var C.someValue C.int var C.someValue C.int
+2 -11
View File
@@ -175,15 +175,6 @@ func (c *Config) AutomaticStackSize() bool {
return false return false
} }
// StackSize returns the default stack size to be used for goroutines, if the
// stack size could not be determined automatically at compile time.
func (c *Config) StackSize() uint64 {
if c.Options.StackSize != 0 {
return c.Options.StackSize
}
return c.Target.DefaultStackSize
}
// UseThinLTO returns whether ThinLTO should be used for the given target. Some // UseThinLTO returns whether ThinLTO should be used for the given target. Some
// targets (such as wasm) are not yet supported. // targets (such as wasm) are not yet supported.
// We should try and remove as many exceptions as possible in the future, so // We should try and remove as many exceptions as possible in the future, so
@@ -377,8 +368,8 @@ func (c *Config) VerifyIR() bool {
} }
// Debug returns whether debug (DWARF) information should be retained by the // Debug returns whether debug (DWARF) information should be retained by the
// linker. By default, debug information is retained, but it can be removed // linker. By default, debug information is retained but it can be removed with
// with the -no-debug flag. // the -no-debug flag.
func (c *Config) Debug() bool { func (c *Config) Debug() bool {
return c.Options.Debug return c.Options.Debug
} }
-3
View File
@@ -28,7 +28,6 @@ type Options struct {
GC string GC string
PanicStrategy string PanicStrategy string
Scheduler string Scheduler string
StackSize uint64 // goroutine stack size (if none could be automatically determined)
Serial string Serial string
Work bool // -work flag to print temporary build directory Work bool // -work flag to print temporary build directory
InterpTimeout time.Duration InterpTimeout time.Duration
@@ -50,8 +49,6 @@ type Options struct {
LLVMFeatures string LLVMFeatures string
Directory string Directory string
PrintJSON bool PrintJSON bool
Monitor bool
BaudRate int
} }
// Verify performs a validation on the given options, raising an error if options are not valid. // Verify performs a validation on the given options, raising an error if options are not valid.
+4 -3
View File
@@ -1059,11 +1059,12 @@ func (b *builder) createFunctionStart(intrinsic bool) {
if b.info.section != "" { if b.info.section != "" {
b.llvmFn.SetSection(b.info.section) b.llvmFn.SetSection(b.info.section)
} }
if b.info.exported && strings.HasPrefix(b.Triple, "wasm") { if b.info.exported && b.info.module != "" && strings.HasPrefix(b.Triple, "wasm") {
// Set the exported name. This is necessary for WebAssembly because // Set the exported name. This is necessary for WebAssembly because
// otherwise the function is not exported. // otherwise the function is not exported.
functionAttr := b.ctx.CreateStringAttribute("wasm-export-name", b.info.linkName) b.llvmFn.AddFunctionAttr(b.ctx.CreateStringAttribute("wasm-export-name", b.info.linkName))
b.llvmFn.AddFunctionAttr(functionAttr) // Set the export module.
b.llvmFn.AddFunctionAttr(b.ctx.CreateStringAttribute("wasm-export-module", b.info.module))
} }
// Some functions have a pragma controlling the inlining level. // Some functions have a pragma controlling the inlining level.
+1 -1
View File
@@ -79,7 +79,7 @@ func TestCompiler(t *testing.T) {
RelocationModel: config.RelocationModel(), RelocationModel: config.RelocationModel(),
Scheduler: config.Scheduler(), Scheduler: config.Scheduler(),
AutomaticStackSize: config.AutomaticStackSize(), AutomaticStackSize: config.AutomaticStackSize(),
DefaultStackSize: config.StackSize(), DefaultStackSize: config.Target.DefaultStackSize,
NeedsStackObjects: config.NeedsStackObjects(), NeedsStackObjects: config.NeedsStackObjects(),
} }
machine, err := NewTargetMachine(compilerConfig) machine, err := NewTargetMachine(compilerConfig)
+11 -21
View File
@@ -210,8 +210,9 @@ func (c *compilerContext) getFunction(fn *ssa.Function) llvm.Value {
// exported. // exported.
func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo { func (c *compilerContext) getFunctionInfo(f *ssa.Function) functionInfo {
info := functionInfo{ info := functionInfo{
// Pick the default linkName. module: "env",
linkName: f.RelString(nil), importName: f.Name(),
linkName: f.RelString(nil), // pick the default linkName
} }
// Check for //go: pragmas, which may change the link name (among others). // Check for //go: pragmas, which may change the link name (among others).
info.parsePragmas(f) info.parsePragmas(f)
@@ -225,10 +226,6 @@ func (info *functionInfo) parsePragmas(f *ssa.Function) {
return return
} }
if decl, ok := f.Syntax().(*ast.FuncDecl); ok && decl.Doc != nil { if decl, ok := f.Syntax().(*ast.FuncDecl); ok && decl.Doc != nil {
// Our importName for a wasm module (if we are compiling to wasm), or llvm link name
var importName string
for _, comment := range decl.Doc.List { for _, comment := range decl.Doc.List {
text := comment.Text text := comment.Text
if strings.HasPrefix(text, "//export ") { if strings.HasPrefix(text, "//export ") {
@@ -246,7 +243,8 @@ func (info *functionInfo) parsePragmas(f *ssa.Function) {
continue continue
} }
importName = parts[1] info.importName = parts[1]
info.linkName = parts[1]
info.exported = true info.exported = true
case "//go:interrupt": case "//go:interrupt":
if hasUnsafeImport(f.Pkg.Pkg) { if hasUnsafeImport(f.Pkg.Pkg) {
@@ -254,10 +252,13 @@ func (info *functionInfo) parsePragmas(f *ssa.Function) {
} }
case "//go:wasm-module": case "//go:wasm-module":
// Alternative comment for setting the import module. // Alternative comment for setting the import module.
if len(parts) != 2 { if len(parts) == 1 {
continue // Function must not be exported outside of the WebAssembly
// module (but only be made available for linking).
info.module = ""
} else if len(parts) == 2 {
info.module = parts[1]
} }
info.module = parts[1]
case "//go:inline": case "//go:inline":
info.inline = inlineHint info.inline = inlineHint
case "//go:noinline": case "//go:noinline":
@@ -297,17 +298,6 @@ func (info *functionInfo) parsePragmas(f *ssa.Function) {
} }
} }
} }
// Set the importName for our exported function if we have one
if importName != "" {
if info.module == "" {
info.linkName = importName
} else {
// WebAssembly import
info.importName = importName
}
}
} }
} }
+2 -2
View File
@@ -62,7 +62,7 @@ declare void @main.undefinedFunctionNotInSection(i8*) #0
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #2 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="extern_func" "wasm-import-module"="env" "wasm-import-name"="extern_func" } attributes #2 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-module"="env" "wasm-export-name"="extern_func" "wasm-import-module"="env" "wasm-import-name"="extern_func" }
attributes #3 = { inlinehint nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } attributes #3 = { inlinehint nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #4 = { noinline nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" } attributes #4 = { noinline nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #5 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-name"="exportedFunctionInSection" "wasm-import-module"="env" "wasm-import-name"="exportedFunctionInSection" } attributes #5 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" "wasm-export-module"="env" "wasm-export-name"="exportedFunctionInSection" "wasm-import-module"="env" "wasm-import-name"="exportedFunctionInSection" }
-2
View File
@@ -9,10 +9,8 @@ require (
github.com/chromedp/chromedp v0.7.6 github.com/chromedp/chromedp v0.7.6
github.com/gofrs/flock v0.8.1 github.com/gofrs/flock v0.8.1
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-colorable v0.1.8
github.com/mattn/go-tty v0.0.4
go.bug.st/serial v1.3.5 go.bug.st/serial v1.3.5
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.org/x/tools v0.1.11 golang.org/x/tools v0.1.11
+11 -13
View File
@@ -12,6 +12,7 @@ github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moA
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0= github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY= github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
@@ -22,47 +23,44 @@ github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg= github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw= github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw=
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M= github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc= github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
go.bug.st/serial v1.1.3 h1:YEBxJa9pKS9Wdg46B/jiaKbvvbUrjhZZZITfJHEJhaE=
go.bug.st/serial v1.1.3/go.mod h1:8TT7u/SwwNIpJ8QaG4s+HTjFt9ReXs2cdOU7ZEk50Dk=
go.bug.st/serial v1.3.5 h1:k50SqGZCnHZ2MiBQgzccXWG+kd/XpOs1jUljpDDKzaE= go.bug.st/serial v1.3.5 h1:k50SqGZCnHZ2MiBQgzccXWG+kd/XpOs1jUljpDDKzaE=
go.bug.st/serial v1.3.5/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304= go.bug.st/serial v1.3.5/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY= golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 h1:nSLR52mUw7DPQQVA3ZJFH63zjU4ME84fKiin6mdnYWc= tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 h1:nSLR52mUw7DPQQVA3ZJFH63zjU4ME84fKiin6mdnYWc=
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+1 -1
View File
@@ -12,7 +12,7 @@ import (
// Version of TinyGo. // Version of TinyGo.
// Update this value before release of new version of software. // Update this value before release of new version of software.
const Version = "0.26.0" const Version = "0.26.0-dev"
var ( var (
// This variable is set at build time using -ldflags parameters. // This variable is set at build time using -ldflags parameters.
-5
View File
@@ -369,11 +369,6 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
nBytes := uint32(operands[3].Uint()) nBytes := uint32(operands[3].Uint())
dstObj := mem.getWritable(dst.index()) dstObj := mem.getWritable(dst.index())
dstBuf := dstObj.buffer.asRawValue(r) dstBuf := dstObj.buffer.asRawValue(r)
if mem.get(src.index()).buffer == nil {
// Looks like the source buffer is not defined.
// This can happen with //extern or //go:embed.
return nil, mem, r.errorAt(inst, errUnsupportedRuntimeInst)
}
srcBuf := mem.get(src.index()).buffer.asRawValue(r) srcBuf := mem.get(src.index()).buffer.asRawValue(r)
copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():]) copy(dstBuf.buf[dst.offset():dst.offset()+nBytes], srcBuf.buf[src.offset():])
dstObj.buffer = dstBuf dstObj.buffer = dstBuf
+1 -1
View File
@@ -440,7 +440,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) {
var initialCFlags []string var initialCFlags []string
initialCFlags = append(initialCFlags, p.program.config.CFlags()...) initialCFlags = append(initialCFlags, p.program.config.CFlags()...)
initialCFlags = append(initialCFlags, "-I"+p.Dir) initialCFlags = append(initialCFlags, "-I"+p.Dir)
generated, headerCode, cflags, ldflags, accessedFiles, errs := cgo.Process(files, p.program.workingDir, p.ImportPath, p.program.fset, initialCFlags, p.program.clangHeaders) generated, headerCode, cflags, ldflags, accessedFiles, errs := cgo.Process(files, p.program.workingDir, p.program.fset, initialCFlags, p.program.clangHeaders)
p.CFlags = append(initialCFlags, cflags...) p.CFlags = append(initialCFlags, cflags...)
p.CGoHeaders = headerCode p.CGoHeaders = headerCode
for path, hash := range accessedFiles { for path, hash := range accessedFiles {
+19 -31
View File
@@ -26,7 +26,6 @@ import (
"time" "time"
"github.com/google/shlex" "github.com/google/shlex"
"github.com/inhies/go-bytesize"
"github.com/mattn/go-colorable" "github.com/mattn/go-colorable"
"github.com/tinygo-org/tinygo/builder" "github.com/tinygo-org/tinygo/builder"
"github.com/tinygo-org/tinygo/compileopts" "github.com/tinygo-org/tinygo/compileopts"
@@ -423,6 +422,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
if err != nil { if err != nil {
return &commandError{"failed to flash", result.Binary, err} return &commandError{"failed to flash", result.Binary, err}
} }
return nil
case "msd": case "msd":
switch fileExt { switch fileExt {
case ".uf2": case ".uf2":
@@ -430,11 +430,13 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
if err != nil { if err != nil {
return &commandError{"failed to flash", result.Binary, err} return &commandError{"failed to flash", result.Binary, err}
} }
return nil
case ".hex": case ".hex":
err := flashHexUsingMSD(config.Target.FlashVolume, result.Binary, config.Options) err := flashHexUsingMSD(config.Target.FlashVolume, result.Binary, config.Options)
if err != nil { if err != nil {
return &commandError{"failed to flash", result.Binary, err} return &commandError{"failed to flash", result.Binary, err}
} }
return nil
default: default:
return errors.New("mass storage device flashing currently only supports uf2 and hex") return errors.New("mass storage device flashing currently only supports uf2 and hex")
} }
@@ -455,6 +457,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
if err != nil { if err != nil {
return &commandError{"failed to flash", result.Binary, err} return &commandError{"failed to flash", result.Binary, err}
} }
return nil
case "bmp": case "bmp":
gdb, err := config.Target.LookupGDB() gdb, err := config.Target.LookupGDB()
if err != nil { if err != nil {
@@ -473,13 +476,10 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
if err != nil { if err != nil {
return &commandError{"failed to flash", result.Binary, err} return &commandError{"failed to flash", result.Binary, err}
} }
return nil
default: default:
return fmt.Errorf("unknown flash method: %s", flashMethod) return fmt.Errorf("unknown flash method: %s", flashMethod)
} }
if options.Monitor {
return Monitor("", options)
}
return nil
}) })
} }
@@ -998,8 +998,7 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
preferredPortIDs = append(preferredPortIDs, [2]uint16{uint16(vid), uint16(pid)}) preferredPortIDs = append(preferredPortIDs, [2]uint16{uint16(vid), uint16(pid)})
} }
var primaryPorts []string // ports picked from preferred USB VID/PID var primaryPorts []string // ports picked from preferred USB VID/PID
var secondaryPorts []string // other ports (as a fallback)
for _, p := range portsList { for _, p := range portsList {
if !p.IsUSB { if !p.IsUSB {
continue continue
@@ -1021,8 +1020,6 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
continue continue
} }
} }
secondaryPorts = append(secondaryPorts, p.Name)
} }
if len(primaryPorts) == 1 { if len(primaryPorts) == 1 {
// There is exactly one match in the set of preferred ports. Use // There is exactly one match in the set of preferred ports. Use
@@ -1034,10 +1031,18 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
// one device of the same type are connected (e.g. two Arduino // one device of the same type are connected (e.g. two Arduino
// Unos). // Unos).
ports = primaryPorts ports = primaryPorts
} else { }
// No preferred ports found. Fall back to other serial ports
// available in the system. if len(ports) == 0 {
ports = secondaryPorts // fallback
switch runtime.GOOS {
case "darwin":
ports, err = filepath.Glob("/dev/cu.usb*")
case "linux":
ports, err = filepath.Glob("/dev/ttyACM*")
case "windows":
ports, err = serial.GetPortsList()
}
} }
default: default:
return "", errors.New("unable to search for a default USB device to be flashed on this OS") return "", errors.New("unable to search for a default USB device to be flashed on this OS")
@@ -1052,9 +1057,7 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
} }
if len(portCandidates) == 0 { if len(portCandidates) == 0 {
if len(usbInterfaces) > 0 { if len(ports) == 1 {
return "", errors.New("unable to search for a default USB device - use -port flag, available ports are " + strings.Join(ports, ", "))
} else if len(ports) == 1 {
return ports[0], nil return ports[0], nil
} else { } else {
return "", errors.New("multiple serial ports available - use -port flag, available ports are " + strings.Join(ports, ", ")) return "", errors.New("multiple serial ports available - use -port flag, available ports are " + strings.Join(ports, ", "))
@@ -1119,7 +1122,6 @@ func usage(command string) {
fmt.Fprintln(os.Stderr, " flash: compile and flash to the device") fmt.Fprintln(os.Stderr, " flash: compile and flash to the device")
fmt.Fprintln(os.Stderr, " gdb: run/flash and immediately enter GDB") fmt.Fprintln(os.Stderr, " gdb: run/flash and immediately enter GDB")
fmt.Fprintln(os.Stderr, " lldb: run/flash and immediately enter LLDB") fmt.Fprintln(os.Stderr, " lldb: run/flash and immediately enter LLDB")
fmt.Fprintln(os.Stderr, " monitor: open communication port")
fmt.Fprintln(os.Stderr, " env: list environment variables used during build") fmt.Fprintln(os.Stderr, " env: list environment variables used during build")
fmt.Fprintln(os.Stderr, " list: run go list using the TinyGo root") fmt.Fprintln(os.Stderr, " list: run go list using the TinyGo root")
fmt.Fprintln(os.Stderr, " clean: empty cache directory ("+goenv.Get("GOCACHE")+")") fmt.Fprintln(os.Stderr, " clean: empty cache directory ("+goenv.Get("GOCACHE")+")")
@@ -1316,12 +1318,6 @@ func main() {
var tags buildutil.TagsFlag var tags buildutil.TagsFlag
flag.Var(&tags, "tags", "a space-separated list of extra build tags") flag.Var(&tags, "tags", "a space-separated list of extra build tags")
target := flag.String("target", "", "chip/board name or JSON target specification file") target := flag.String("target", "", "chip/board name or JSON target specification file")
var stackSize uint64
flag.Func("stack-size", "goroutine stack size (if unknown at compile time)", func(s string) error {
size, err := bytesize.Parse(s)
stackSize = uint64(size)
return err
})
printSize := flag.String("size", "", "print sizes (none, short, full)") printSize := flag.String("size", "", "print sizes (none, short, full)")
printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines") printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines")
printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed") printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed")
@@ -1336,8 +1332,6 @@ func main() {
wasmAbi := flag.String("wasm-abi", "", "WebAssembly ABI conventions: js (no i64 params) or generic") wasmAbi := flag.String("wasm-abi", "", "WebAssembly ABI conventions: js (no i64 params) or generic")
llvmFeatures := flag.String("llvm-features", "", "comma separated LLVM features to enable") llvmFeatures := flag.String("llvm-features", "", "comma separated LLVM features to enable")
cpuprofile := flag.String("cpuprofile", "", "cpuprofile output") cpuprofile := flag.String("cpuprofile", "", "cpuprofile output")
monitor := flag.Bool("monitor", false, "enable serial monitor")
baudrate := flag.Int("baudrate", 115200, "baudrate of serial monitor")
var flagJSON, flagDeps, flagTest bool var flagJSON, flagDeps, flagTest bool
if command == "help" || command == "list" || command == "info" || command == "build" { if command == "help" || command == "list" || command == "info" || command == "build" {
@@ -1404,7 +1398,6 @@ func main() {
GOARCH: goenv.Get("GOARCH"), GOARCH: goenv.Get("GOARCH"),
GOARM: goenv.Get("GOARM"), GOARM: goenv.Get("GOARM"),
Target: *target, Target: *target,
StackSize: stackSize,
Opt: *opt, Opt: *opt,
GC: *gc, GC: *gc,
PanicStrategy: *panicStrategy, PanicStrategy: *panicStrategy,
@@ -1427,8 +1420,6 @@ func main() {
OpenOCDCommands: ocdCommands, OpenOCDCommands: ocdCommands,
LLVMFeatures: *llvmFeatures, LLVMFeatures: *llvmFeatures,
PrintJSON: flagJSON, PrintJSON: flagJSON,
Monitor: *monitor,
BaudRate: *baudrate,
} }
if *printCommands { if *printCommands {
options.PrintCommands = printCommand options.PrintCommands = printCommand
@@ -1619,9 +1610,6 @@ func main() {
fmt.Println("FAIL") fmt.Println("FAIL")
os.Exit(1) os.Exit(1)
} }
case "monitor":
err := Monitor(*port, options)
handleCompilerError(err)
case "targets": case "targets":
dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets") dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets")
entries, err := ioutil.ReadDir(dir) entries, err := ioutil.ReadDir(dir)
-106
View File
@@ -1,106 +0,0 @@
package main
import (
"fmt"
"os"
"os/signal"
"time"
"github.com/mattn/go-tty"
"github.com/tinygo-org/tinygo/builder"
"github.com/tinygo-org/tinygo/compileopts"
"go.bug.st/serial"
)
// Monitor connects to the given port and reads/writes the serial port.
func Monitor(port string, options *compileopts.Options) error {
config, err := builder.NewConfig(options)
if err != nil {
return err
}
wait := 300
for i := 0; i <= wait; i++ {
port, err = getDefaultPort(port, config.Target.SerialPort)
if err != nil {
if i < wait {
time.Sleep(10 * time.Millisecond)
continue
}
return err
}
break
}
br := options.BaudRate
if br <= 0 {
br = 115200
}
wait = 300
var p serial.Port
for i := 0; i <= wait; i++ {
p, err = serial.Open(port, &serial.Mode{BaudRate: br})
if err != nil {
if i < wait {
time.Sleep(10 * time.Millisecond)
continue
}
return err
}
break
}
defer p.Close()
tty, err := tty.Open()
if err != nil {
return err
}
defer tty.Close()
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt)
defer signal.Stop(sig)
go func() {
<-sig
tty.Close()
os.Exit(0)
}()
fmt.Printf("Connected to %s. Press Ctrl-C to exit.\n", port)
errCh := make(chan error, 1)
go func() {
buf := make([]byte, 100*1024)
for {
n, err := p.Read(buf)
if err != nil {
errCh <- fmt.Errorf("read error: %w", err)
return
}
if n == 0 {
continue
}
fmt.Printf("%v", string(buf[:n]))
}
}()
go func() {
for {
r, err := tty.ReadRune()
if err != nil {
errCh <- err
return
}
if r == 0 {
continue
}
p.Write([]byte(string(r)))
}
}()
return <-errCh
}
+2 -2
View File
@@ -1,5 +1,5 @@
//go:build nrf || stm32 || (sam && atsamd51) || (sam && atsame5x) //go:build nrf52840 || stm32 || (sam && atsamd51) || (sam && atsame5x) || rp2040
// +build nrf stm32 sam,atsamd51 sam,atsame5x // +build nrf52840 stm32 sam,atsamd51 sam,atsame5x rp2040
package rand package rand
+49
View File
@@ -0,0 +1,49 @@
// Reads multiple rp2040 ADC channels concurrently. Including the internal temperature sensor
package main
import (
"fmt"
"machine"
"time"
)
type celsius float32
func (c celsius) String() string {
return fmt.Sprintf("%4.1f℃", c)
}
// rp2040 ADC is 12 bits. Reading are shifted <<4 to fill the 16-bit range.
var adcReading [3]uint16
func readADC(a machine.ADC, w time.Duration, i int) {
for {
adcReading[i] = a.Get()
time.Sleep(w)
}
}
func main() {
machine.InitADC()
a0 := machine.ADC{machine.ADC0} // GPIO26 input
a1 := machine.ADC{machine.ADC1} // GPIO27 input
a2 := machine.ADC{machine.ADC2} // GPIO28 input
t := machine.ADC_TEMP_SENSOR // Internal Temperature sensor
// Configure sets the GPIOs to PinAnalog mode
a0.Configure(machine.ADCConfig{})
a1.Configure(machine.ADCConfig{})
a2.Configure(machine.ADCConfig{})
// Configure powers on the temperature sensor
t.Configure(machine.ADCConfig{})
// Safe to read concurrently
go readADC(a0, 10*time.Millisecond, 0)
go readADC(a1, 17*time.Millisecond, 1)
go readADC(a2, 29*time.Millisecond, 2)
for {
fmt.Printf("ADC0: %5d ADC1: %5d ADC2: %5d Temp: %v\n\r", adcReading[0], adcReading[1], adcReading[2], celsius(float32(t.ReadTemperature())/1000))
time.Sleep(1000 * time.Millisecond)
}
}
-23
View File
@@ -1,23 +0,0 @@
// Read the internal temperature sensor of the chip.
package main
import (
"fmt"
"machine"
"time"
)
type celsius float32
func (c celsius) String() string {
return fmt.Sprintf("%4.1f℃", c)
}
func main() {
for {
temp := celsius(float32(machine.ReadTemperature()) / 1000)
println("temperature:", temp.String())
time.Sleep(time.Second)
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0x07738135 const RESET_MAGIC_VALUE = 0x07738135
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -7,7 +7,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0x07738135 const RESET_MAGIC_VALUE = 0x07738135
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -7,7 +7,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0x07738135 const RESET_MAGIC_VALUE = 0x07738135
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0x07738135 const RESET_MAGIC_VALUE = 0x07738135
// GPIO Pins - Digital Low // GPIO Pins - Digital Low
const ( const (
+1 -1
View File
@@ -8,7 +8,7 @@ import (
) )
// Definition for compatibility, but not used // Definition for compatibility, but not used
const resetMagicValue = 0x00000000 const RESET_MAGIC_VALUE = 0x00000000
const ( const (
LED = PC18 LED = PC18
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -8,7 +8,7 @@ import (
) )
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -245,7 +245,7 @@ const (
// Other peripheral constants // Other peripheral constants
const ( const (
resetMagicValue = 0xF01669EF // Used to reset into bootloader RESET_MAGIC_VALUE = 0xF01669EF // Used to reset into bootloader
) )
// USB CDC pins // USB CDC pins
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+5 -5
View File
@@ -52,8 +52,8 @@ const (
I2C0_SDA_PIN = GPIO20 I2C0_SDA_PIN = GPIO20
I2C0_SCL_PIN = GPIO21 I2C0_SCL_PIN = GPIO21
I2C1_SDA_PIN = NoPin // not pinned out I2C1_SDA_PIN = 31 // not pinned out
I2C1_SCL_PIN = NoPin // not pinned out I2C1_SCL_PIN = 31 // not pinned out
) )
// SPI default pins // SPI default pins
@@ -65,9 +65,9 @@ const (
// Default Serial In Bus 1 for SPI communications // Default Serial In Bus 1 for SPI communications
SPI1_SDI_PIN = GPIO28 // Rx SPI1_SDI_PIN = GPIO28 // Rx
SPI0_SCK_PIN = NoPin // not pinned out SPI0_SCK_PIN = 31 // not pinned out
SPI0_SDO_PIN = NoPin // not pinned out SPI0_SDO_PIN = 31 // not pinned out
SPI0_SDI_PIN = NoPin // not pinned out SPI0_SDI_PIN = 31 // not pinned out
) )
// UART pins // UART pins
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xF01669EF const RESET_MAGIC_VALUE = 0xF01669EF
// Digital pins // Digital pins
const ( const (
+8 -8
View File
@@ -18,15 +18,15 @@ const (
// MDBT50Q-RX dongle does not have pins broken out for the peripherals below, // MDBT50Q-RX dongle does not have pins broken out for the peripherals below,
// however the machine_nrf*.go implementations of I2C/SPI/etc expect the pin // however the machine_nrf*.go implementations of I2C/SPI/etc expect the pin
// constants to be defined, so we are defining them all as NoPin // constants to be defined, so we are defining them all as 0
const ( const (
UART_TX_PIN = NoPin UART_TX_PIN = 0
UART_RX_PIN = NoPin UART_RX_PIN = 0
SDA_PIN = NoPin SDA_PIN = 0
SCL_PIN = NoPin SCL_PIN = 0
SPI0_SCK_PIN = NoPin SPI0_SCK_PIN = 0
SPI0_SDO_PIN = NoPin SPI0_SDO_PIN = 0
SPI0_SDI_PIN = NoPin SPI0_SDI_PIN = 0
) )
// USB CDC identifiers // USB CDC identifiers
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -7,7 +7,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0x07738135 const RESET_MAGIC_VALUE = 0x07738135
// Note: On the P1AM-100, pins D8, D9, D10, A3, and A4 are used for // Note: On the P1AM-100, pins D8, D9, D10, A3, and A4 are used for
// communication with the base controller. // communication with the base controller.
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
const ( const (
ADC0 = A0 ADC0 = A0
+1 -1
View File
@@ -104,7 +104,7 @@ const (
var ( var (
usb_VID uint16 = 0x2886 usb_VID uint16 = 0x2886
usb_PID uint16 = 0x8045 usb_PID uint16 = 0x0045
) )
var ( var (
+1 -1
View File
@@ -4,7 +4,7 @@
package machine package machine
// used to reset into bootloader // used to reset into bootloader
const resetMagicValue = 0xf01669ef const RESET_MAGIC_VALUE = 0xf01669ef
// GPIO Pins // GPIO Pins
const ( const (
-2
View File
@@ -8,8 +8,6 @@ import (
) )
// TWI_FREQ is the I2C bus speed. Normally either 100 kHz, or 400 kHz for high-speed bus. // TWI_FREQ is the I2C bus speed. Normally either 100 kHz, or 400 kHz for high-speed bus.
//
// Deprecated: use 100 * machine.KHz or 400 * machine.KHz instead.
const ( const (
TWI_FREQ_100KHZ = 100000 TWI_FREQ_100KHZ = 100000
TWI_FREQ_400KHZ = 400000 TWI_FREQ_400KHZ = 400000
-7
View File
@@ -18,13 +18,6 @@ var (
// particular chip but instead runs in WebAssembly for example. // particular chip but instead runs in WebAssembly for example.
const Device = deviceName const Device = deviceName
// Generic constants.
const (
KHz = 1000
MHz = 1000_000
GHz = 1000_000_000
)
// PinMode sets the direction and pull mode of the pin. For example, PinOutput // PinMode sets the direction and pull mode of the pin. For example, PinOutput
// sets the pin as an output and PinInputPullup sets the pin as an input with a // sets the pin as an output and PinInputPullup sets the pin as an input with a
// pull-up. // pull-up.
+1 -1
View File
@@ -26,7 +26,7 @@ type I2CConfig struct {
func (i2c *I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 100 * KHz config.Frequency = TWI_FREQ_100KHZ
} }
// Activate internal pullups for twi. // Activate internal pullups for twi.
+7 -2
View File
@@ -10,6 +10,7 @@ package machine
import ( import (
"device/arm" "device/arm"
"device/sam" "device/sam"
"errors"
"runtime/interrupt" "runtime/interrupt"
"unsafe" "unsafe"
) )
@@ -676,7 +677,7 @@ const i2cTimeout = 1000
func (i2c *I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 100 * KHz config.Frequency = TWI_FREQ_100KHZ
} }
if config.SDA == 0 && config.SCL == 0 { if config.SDA == 0 && config.SCL == 0 {
config.SDA = SDA_PIN config.SDA = SDA_PIN
@@ -1273,6 +1274,10 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return byte(spi.Bus.DATA.Get()), nil return byte(spi.Bus.DATA.Get()), nil
} }
var (
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
)
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read // Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
// interface, there must always be the same number of bytes written as bytes read. // interface, there must always be the same number of bytes written as bytes read.
// The Tx method knows about this, and offers a few different ways of calling it. // The Tx method knows about this, and offers a few different ways of calling it.
@@ -1735,7 +1740,7 @@ func EnterBootloader() {
// Perform magic reset into bootloader, as mentioned in // Perform magic reset into bootloader, as mentioned in
// https://github.com/arduino/ArduinoCore-samd/issues/197 // https://github.com/arduino/ArduinoCore-samd/issues/197
*(*uint32)(unsafe.Pointer(uintptr(0x20007FFC))) = resetMagicValue *(*uint32)(unsafe.Pointer(uintptr(0x20007FFC))) = RESET_MAGIC_VALUE
arm.SystemReset() arm.SystemReset()
} }
+7 -2
View File
@@ -10,6 +10,7 @@ package machine
import ( import (
"device/arm" "device/arm"
"device/sam" "device/sam"
"errors"
"runtime/interrupt" "runtime/interrupt"
"unsafe" "unsafe"
) )
@@ -1150,7 +1151,7 @@ const i2cTimeout = 1000
func (i2c *I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 100 * KHz config.Frequency = TWI_FREQ_100KHZ
} }
// Use default I2C pins if not set. // Use default I2C pins if not set.
@@ -1526,6 +1527,10 @@ func (spi SPI) Transfer(w byte) (byte, error) {
return byte(spi.Bus.DATA.Get()), nil return byte(spi.Bus.DATA.Get()), nil
} }
var (
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
)
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read // Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
// interface, there must always be the same number of bytes written as bytes read. // interface, there must always be the same number of bytes written as bytes read.
// The Tx method knows about this, and offers a few different ways of calling it. // The Tx method knows about this, and offers a few different ways of calling it.
@@ -1975,7 +1980,7 @@ func EnterBootloader() {
// Perform magic reset into bootloader, as mentioned in // Perform magic reset into bootloader, as mentioned in
// https://github.com/arduino/ArduinoCore-samd/issues/197 // https://github.com/arduino/ArduinoCore-samd/issues/197
*(*uint32)(unsafe.Pointer(uintptr(0x20000000 + HSRAM_SIZE - 4))) = resetMagicValue *(*uint32)(unsafe.Pointer(uintptr(0x20000000 + HSRAM_SIZE - 4))) = RESET_MAGIC_VALUE
arm.SystemReset() arm.SystemReset()
} }
+14 -2
View File
@@ -59,9 +59,12 @@ type PinChange uint8
// Pin change interrupt constants for SetInterrupt. // Pin change interrupt constants for SetInterrupt.
const ( const (
PinRising PinChange = iota + 1 PinNoInterrupt PinChange = iota
PinRising
PinFalling PinFalling
PinToggle PinToggle
PinLowLevel
PinHighLevel
) )
// Configure this pin with the given configuration. // Configure this pin with the given configuration.
@@ -187,7 +190,7 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) (err error) {
return ErrInvalidInputPin return ErrInvalidInputPin
} }
if callback == nil { if callback == nil || change == PinNoInterrupt {
// Disable this pin interrupt // Disable this pin interrupt
p.pin().ClearBits(esp.GPIO_PIN_PIN_INT_TYPE_Msk | esp.GPIO_PIN_PIN_INT_ENA_Msk) p.pin().ClearBits(esp.GPIO_PIN_PIN_INT_TYPE_Msk | esp.GPIO_PIN_PIN_INT_ENA_Msk)
@@ -261,6 +264,15 @@ type UART struct {
DataOverflowDetected bool // set when data overflow detected in UART FIFO buffer or RingBuffer DataOverflowDetected bool // set when data overflow detected in UART FIFO buffer or RingBuffer
} }
type UARTStopBits int
const (
UARTStopBits_Default UARTStopBits = iota
UARTStopBits_1
UARTStopBits_1_5
UARTStopBits_2
)
const ( const (
defaultDataBits = 8 defaultDataBits = 8
defaultStopBit = 1 defaultStopBit = 1
+1 -1
View File
@@ -231,7 +231,7 @@ type I2CConfig struct {
func (i2c *I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
var i2cClockFrequency uint32 = 32000000 var i2cClockFrequency uint32 = 32000000
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 100 * KHz config.Frequency = TWI_FREQ_100KHZ
} }
if config.SDA == 0 && config.SCL == 0 { if config.SDA == 0 && config.SCL == 0 {
+5 -11
View File
@@ -23,17 +23,11 @@ type PinChange uint8
// Pin modes. // Pin modes.
const ( const (
PinInput PinMode = iota PinInput PinMode = iota
PinInputPullup PinInputPullUp
PinInputPulldown PinInputPullDown
PinOutput PinOutput
) )
// Deprecated: use PinInputPullup and PinInputPulldown instead.
const (
PinInputPullUp = PinInputPullup
PinInputPullDown = PinInputPulldown
)
// FPIOA internal pull resistors. // FPIOA internal pull resistors.
const ( const (
fpioaPullNone fpioaPullMode = iota fpioaPullNone fpioaPullMode = iota
@@ -95,10 +89,10 @@ func (p Pin) Configure(config PinConfig) {
case PinInput: case PinInput:
p.setFPIOAIOPull(fpioaPullNone) p.setFPIOAIOPull(fpioaPullNone)
input = true input = true
case PinInputPullup: case PinInputPullUp:
p.setFPIOAIOPull(fpioaPullUp) p.setFPIOAIOPull(fpioaPullUp)
input = true input = true
case PinInputPulldown: case PinInputPullDown:
p.setFPIOAIOPull(fpioaPullDown) p.setFPIOAIOPull(fpioaPullDown)
input = true input = true
case PinOutput: case PinOutput:
@@ -523,7 +517,7 @@ type I2CConfig struct {
func (i2c *I2C) Configure(config I2CConfig) error { func (i2c *I2C) Configure(config I2CConfig) error {
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 100 * KHz config.Frequency = TWI_FREQ_100KHZ
} }
if config.SDA == 0 && config.SCL == 0 { if config.SDA == 0 && config.SCL == 0 {
+9 -13
View File
@@ -21,8 +21,8 @@ func CPUFrequency() uint32 {
const ( const (
// GPIO // GPIO
PinInput PinMode = iota PinInput PinMode = iota
PinInputPullup PinInputPullUp
PinInputPulldown PinInputPullDown
PinOutput PinOutput
PinOutputOpenDrain PinOutputOpenDrain
PinDisable PinDisable
@@ -45,16 +45,12 @@ const (
PinModeI2CSCL PinModeI2CSCL
) )
// Deprecated: use PinInputPullup and PinInputPulldown instead.
const (
PinInputPullUp = PinInputPullup
PinInputPullDown = PinInputPulldown
)
type PinChange uint8 type PinChange uint8
const ( const (
PinRising PinChange = iota + 2 PinLow PinChange = iota
PinHigh
PinRising
PinFalling PinFalling
PinToggle PinToggle
) )
@@ -263,11 +259,11 @@ func (p Pin) Configure(config PinConfig) {
gpio.GDIR.ClearBits(p.getMask()) gpio.GDIR.ClearBits(p.getMask())
pad.Set(dse(7)) pad.Set(dse(7))
case PinInputPullup: case PinInputPullUp:
gpio.GDIR.ClearBits(p.getMask()) gpio.GDIR.ClearBits(p.getMask())
pad.Set(dse(7) | pke | pue | pup(3) | hys) pad.Set(dse(7) | pke | pue | pup(3) | hys)
case PinInputPulldown: case PinInputPullDown:
gpio.GDIR.ClearBits(p.getMask()) gpio.GDIR.ClearBits(p.getMask())
pad.Set(dse(7) | pke | pue | hys) pad.Set(dse(7) | pke | pue | hys)
@@ -391,7 +387,7 @@ func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
mask := p.getMask() mask := p.getMask()
if nil != callback { if nil != callback {
switch change { switch change {
case PinRising, PinFalling: case PinLow, PinHigh, PinRising, PinFalling:
gpio.EDGE_SEL.ClearBits(mask) gpio.EDGE_SEL.ClearBits(mask)
var reg *volatile.Register32 var reg *volatile.Register32
var pos uint8 var pos uint8
@@ -750,7 +746,7 @@ func (p Pin) getMuxMode(config PinConfig) uint32 {
switch config.Mode { switch config.Mode {
// GPIO // GPIO
case PinInput, PinInputPullup, PinInputPulldown, case PinInput, PinInputPullUp, PinInputPullDown,
PinOutput, PinOutputOpenDrain, PinDisable: PinOutput, PinOutputOpenDrain, PinDisable:
mode := uint32(0x5) // GPIO is always alternate function 5 mode := uint32(0x5) // GPIO is always alternate function 5
if forcePath { if forcePath {
+16 -7
View File
@@ -10,6 +10,15 @@ import (
"errors" "errors"
) )
const (
TWI_FREQ_BUS = 24000000 // LPI2C root clock is on 24 MHz OSC
TWI_FREQ_100KHZ = 100000 // StandardMode (100 kHz)
TWI_FREQ_400KHZ = 400000 // FastMode (400 kHz)
TWI_FREQ_1MHZ = 1000000 // FastModePlus (1 MHz)
TWI_FREQ_5MHZ = 5000000 // UltraFastMode (5 MHz)
TWI_FREQ_DEFAULT = TWI_FREQ_100KHZ // default to StandardMode (100 kHz)
)
var ( var (
errI2CWriteTimeout = errors.New("I2C timeout during write") errI2CWriteTimeout = errors.New("I2C timeout during write")
errI2CReadTimeout = errors.New("I2C timeout during read") errI2CReadTimeout = errors.New("I2C timeout during read")
@@ -165,7 +174,7 @@ func (i2c *I2C) Configure(config I2CConfig) {
freq := config.Frequency freq := config.Frequency
if 0 == freq { if 0 == freq {
freq = 100 * KHz freq = TWI_FREQ_DEFAULT
} }
// reset clock and registers, and enable LPI2C module interface // reset clock and registers, and enable LPI2C module interface
@@ -296,7 +305,7 @@ func (i2c *I2C) setFrequency(freq uint32) {
wasEnabled := i2c.Bus.MCR.HasBits(nxp.LPI2C_MCR_MEN) wasEnabled := i2c.Bus.MCR.HasBits(nxp.LPI2C_MCR_MEN)
i2c.Bus.MCR.ClearBits(nxp.LPI2C_MCR_MEN) i2c.Bus.MCR.ClearBits(nxp.LPI2C_MCR_MEN)
// baud rate = (24MHz/(2^pre))/(CLKLO+1 + CLKHI+1 + FLOOR((2+FILTSCL)/(2^pre))) // baud rate = (TWI_FREQ_BUS/(2^pre))/(CLKLO+1 + CLKHI+1 + FLOOR((2+FILTSCL)/(2^pre)))
// assume: CLKLO=2*CLKHI, SETHOLD=CLKHI, DATAVD=CLKHI/2 // assume: CLKLO=2*CLKHI, SETHOLD=CLKHI, DATAVD=CLKHI/2
for pre := uint32(1); pre <= 128; pre *= 2 { for pre := uint32(1); pre <= 128; pre *= 2 {
if bestError == 0 { if bestError == 0 {
@@ -305,9 +314,9 @@ func (i2c *I2C) setFrequency(freq uint32) {
for clkHi := uint32(1); clkHi < 32; clkHi++ { for clkHi := uint32(1); clkHi < 32; clkHi++ {
var absError, rate uint32 var absError, rate uint32
if clkHi == 1 { if clkHi == 1 {
rate = (24 * MHz / pre) / (1 + 3 + 2 + 2/pre) rate = (TWI_FREQ_BUS / pre) / (1 + 3 + 2 + 2/pre)
} else { } else {
rate = (24 * MHz / pre) / (3*clkHi + 2 + 2/pre) rate = (TWI_FREQ_BUS / pre) / (3*clkHi + 2 + 2/pre)
} }
if freq > rate { if freq > rate {
absError = freq - rate absError = freq - rate
@@ -361,15 +370,15 @@ func (i2c *I2C) setFrequency(freq uint32) {
mcfgr2, mcfgr3 uint32 mcfgr2, mcfgr3 uint32
) )
const i2cClockStretchTimeout = 15000 // microseconds const i2cClockStretchTimeout = 15000 // microseconds
if freq >= 5*MHz { if freq >= TWI_FREQ_5MHZ {
// I2C UltraFastMode 5 MHz // I2C UltraFastMode 5 MHz
mcfgr2 = 0 // disable glitch filters and timeout for UltraFastMode mcfgr2 = 0 // disable glitch filters and timeout for UltraFastMode
mcfgr3 = 0 // mcfgr3 = 0 //
} else if freq >= 1*MHz { } else if freq >= TWI_FREQ_1MHZ {
// I2C FastModePlus 1 MHz // I2C FastModePlus 1 MHz
mcfgr2 = filtsda(1) | filtscl(1) | busidle(2400) // 100us timeout mcfgr2 = filtsda(1) | filtscl(1) | busidle(2400) // 100us timeout
mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1) mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1)
} else if freq >= 400*KHz { } else if freq >= TWI_FREQ_400KHZ {
// I2C FastMode 400 kHz // I2C FastMode 400 kHz
mcfgr2 = filtsda(2) | filtscl(2) | busidle(3600) // 150us timeout mcfgr2 = filtsda(2) | filtscl(2) | busidle(3600) // 150us timeout
mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1) mcfgr3 = pinlow(i2cClockStretchTimeout*24/256 + 1)
+2 -2
View File
@@ -159,8 +159,8 @@ func (uart *UART) Disable() {
uart.Bus.CTRL.ClearBits(nxp.LPUART_CTRL_TE | nxp.LPUART_CTRL_RE) uart.Bus.CTRL.ClearBits(nxp.LPUART_CTRL_TE | nxp.LPUART_CTRL_RE)
// put pins back into GPIO mode // put pins back into GPIO mode
uart.rx.Configure(PinConfig{Mode: PinInputPullup}) uart.rx.Configure(PinConfig{Mode: PinInputPullUp})
uart.tx.Configure(PinConfig{Mode: PinInputPullup}) uart.tx.Configure(PinConfig{Mode: PinInputPullUp})
} }
uart.configured = false uart.configured = false
} }
+7 -40
View File
@@ -5,10 +5,15 @@ package machine
import ( import (
"device/nrf" "device/nrf"
"errors"
"runtime/interrupt" "runtime/interrupt"
"unsafe" "unsafe"
) )
var (
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
)
const deviceName = nrf.Device const deviceName = nrf.Device
const ( const (
@@ -225,7 +230,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
// Default I2C bus speed is 100 kHz. // Default I2C bus speed is 100 kHz.
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 100 * KHz config.Frequency = TWI_FREQ_100KHZ
} }
// Default I2C pins if not set. // Default I2C pins if not set.
if config.SDA == 0 && config.SCL == 0 { if config.SDA == 0 && config.SCL == 0 {
@@ -248,7 +253,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
(nrf.GPIO_PIN_CNF_DRIVE_S0D1 << nrf.GPIO_PIN_CNF_DRIVE_Pos) | (nrf.GPIO_PIN_CNF_DRIVE_S0D1 << nrf.GPIO_PIN_CNF_DRIVE_Pos) |
(nrf.GPIO_PIN_CNF_SENSE_Disabled << nrf.GPIO_PIN_CNF_SENSE_Pos)) (nrf.GPIO_PIN_CNF_SENSE_Disabled << nrf.GPIO_PIN_CNF_SENSE_Pos))
if config.Frequency >= 400*KHz { if config.Frequency == TWI_FREQ_400KHZ {
i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K400) i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K400)
} else { } else {
i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K100) i2c.Bus.FREQUENCY.Set(nrf.TWI_FREQUENCY_FREQUENCY_K100)
@@ -345,41 +350,3 @@ func (i2c *I2C) readByte() (byte, error) {
i2c.Bus.EVENTS_RXDREADY.Set(0) i2c.Bus.EVENTS_RXDREADY.Set(0)
return byte(i2c.Bus.RXD.Get()), nil return byte(i2c.Bus.RXD.Get()), nil
} }
var rngStarted = false
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
func GetRNG() (ret uint32, err error) {
// There's no apparent way to check the status of the RNG peripheral's task, so simply start it
// to avoid deadlocking while waiting for output.
if !rngStarted {
nrf.RNG.TASKS_START.Set(1)
nrf.RNG.SetCONFIG_DERCEN(nrf.RNG_CONFIG_DERCEN_Enabled)
rngStarted = true
}
// The RNG returns one byte at a time, so stack up four bytes into a single uint32 for return.
for i := 0; i < 4; i++ {
// Wait for data to be ready.
for nrf.RNG.EVENTS_VALRDY.Get() == 0 {
}
// Append random byte to output.
ret = (ret << 8) ^ nrf.RNG.GetVALUE()
// Unset the EVENTS_VALRDY register to avoid reading the same random output twice.
nrf.RNG.EVENTS_VALRDY.Set(0)
}
return ret, nil
}
// ReadTemperature reads the silicon die temperature of the chip. The return
// value is in milli-celsius.
func ReadTemperature() int32 {
nrf.TEMP.TASKS_START.Set(1)
for nrf.TEMP.EVENTS_DATARDY.Get() == 0 {
}
temp := int32(nrf.TEMP.TEMP.Get()) * 250 // the returned value is in units of 0.25°C
nrf.TEMP.EVENTS_DATARDY.Set(0)
return temp
}
@@ -9,16 +9,16 @@ import (
) )
const ( const (
dfuMagicSerialOnlyReset = 0x4e DFU_MAGIC_SERIAL_ONLY_RESET = 0x4e
dfuMagicUF2Reset = 0x57 DFU_MAGIC_UF2_RESET = 0x57
dfuMagicOTAReset = 0xA8 DFU_MAGIC_OTA_RESET = 0xA8
) )
// EnterSerialBootloader resets the chip into the serial bootloader. After // EnterSerialBootloader resets the chip into the serial bootloader. After
// reset, it can be flashed using serial/nrfutil. // reset, it can be flashed using serial/nrfutil.
func EnterSerialBootloader() { func EnterSerialBootloader() {
arm.DisableInterrupts() arm.DisableInterrupts()
nrf.POWER.GPREGRET.Set(dfuMagicSerialOnlyReset) nrf.POWER.GPREGRET.Set(DFU_MAGIC_SERIAL_ONLY_RESET)
arm.SystemReset() arm.SystemReset()
} }
@@ -26,7 +26,7 @@ func EnterSerialBootloader() {
// can be flashed via nrfutil or by copying a UF2 file to the mass storage device // can be flashed via nrfutil or by copying a UF2 file to the mass storage device
func EnterUF2Bootloader() { func EnterUF2Bootloader() {
arm.DisableInterrupts() arm.DisableInterrupts()
nrf.POWER.GPREGRET.Set(dfuMagicUF2Reset) nrf.POWER.GPREGRET.Set(DFU_MAGIC_UF2_RESET)
arm.SystemReset() arm.SystemReset()
} }
@@ -34,6 +34,6 @@ func EnterUF2Bootloader() {
// flashed via an OTA update // flashed via an OTA update
func EnterOTABootloader() { func EnterOTABootloader() {
arm.DisableInterrupts() arm.DisableInterrupts()
nrf.POWER.GPREGRET.Set(dfuMagicOTAReset) nrf.POWER.GPREGRET.Set(DFU_MAGIC_OTA_RESET)
arm.SystemReset() arm.SystemReset()
} }
+60
View File
@@ -0,0 +1,60 @@
//go:build nrf52840
// +build nrf52840
package machine
import (
"device/nrf"
)
// Implementation based on Nordic Semiconductor's nRF52840 documentation version 1.7 found here:
// https://infocenter.nordicsemi.com/pdf/nRF52840_PS_v1.7.pdf
// SetRNGBiasCorrection configures the RNG peripheral's bias correction mechanism. Note that when
// bias correction is enabled, the peripheral is slower to produce random values.
func SetRNGBiasCorrection(enabled bool) {
var val uint32
if enabled {
val = nrf.RNG_CONFIG_DERCEN_Enabled
}
nrf.RNG.SetCONFIG_DERCEN(val)
}
// RNGBiasCorrectionEnabled determines whether the RNG peripheral's bias correction mechanism is
// enabled or not.
func RNGBiasCorrectionEnabled() bool {
return nrf.RNG.GetCONFIG_DERCEN() == nrf.RNG_CONFIG_DERCEN_Enabled
}
// StartRNG starts the RNG peripheral core. This is automatically called by GetRNG, but can be
// manually called for interacting with the RNG peripheral directly.
func StartRNG() {
nrf.RNG.SetTASKS_START(nrf.RNG_TASKS_START_TASKS_START_Trigger)
}
// StopRNG stops the RNG peripheral core. This is not called automatically. It may make sense to
// manually disable RNG peripheral for power conservation.
func StopRNG() {
nrf.RNG.SetTASKS_STOP(nrf.RNG_TASKS_STOP_TASKS_STOP_Trigger)
}
// GetRNG returns 32 bits of non-deterministic random data based on internal thermal noise.
// According to Nordic's documentation, the random output is suitable for cryptographic purposes.
func GetRNG() (ret uint32, err error) {
// There's no apparent way to check the status of the RNG peripheral's task, so simply start it
// to avoid deadlocking while waiting for output.
StartRNG()
// The RNG returns one byte at a time, so stack up four bytes into a single uint32 for return.
for i := 0; i < 4; i++ {
// Wait for data to be ready.
for nrf.RNG.GetEVENTS_VALRDY() == nrf.RNG_EVENTS_VALRDY_EVENTS_VALRDY_NotGenerated {
}
// Append random byte to output.
ret = (ret << 8) ^ nrf.RNG.GetVALUE()
// Unset the EVENTS_VALRDY register to avoid reading the same random output twice.
nrf.RNG.SetEVENTS_VALRDY(nrf.RNG_EVENTS_VALRDY_EVENTS_VALRDY_NotGenerated)
}
return ret, nil
}
+4 -10
View File
@@ -42,19 +42,13 @@ const deviceName = nxp.Device
const ( const (
PinInput PinMode = iota PinInput PinMode = iota
PinInputPullup PinInputPullUp
PinInputPulldown PinInputPullDown
PinOutput PinOutput
PinOutputOpenDrain PinOutputOpenDrain
PinDisable PinDisable
) )
// Deprecated: use PinInputPullup and PinInputPulldown instead.
const (
PinInputPullUp = PinInputPullup
PinInputPullDown = PinInputPulldown
)
const ( const (
PA00 Pin = iota PA00 Pin = iota
PA01 PA01
@@ -229,11 +223,11 @@ func (p Pin) Configure(config PinConfig) {
gpio.PDDR.ClearBits(1 << pos) gpio.PDDR.ClearBits(1 << pos)
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos)) pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos))
case PinInputPullup: case PinInputPullUp:
gpio.PDDR.ClearBits(1 << pos) gpio.PDDR.ClearBits(1 << pos)
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE | nxp.PORT_PCR0_PS) pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE | nxp.PORT_PCR0_PS)
case PinInputPulldown: case PinInputPullDown:
gpio.PDDR.ClearBits(1 << pos) gpio.PDDR.ClearBits(1 << pos)
pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE) pcr.Set((1 << nxp.PORT_PCR0_MUX_Pos) | nxp.PORT_PCR0_PE)
+2 -2
View File
@@ -203,8 +203,8 @@ func (u *UART) Disable() {
u.C2.Set(0) u.C2.Set(0)
// reconfigure pin // reconfigure pin
u.DefaultRX.Configure(PinConfig{Mode: PinInputPullup}) u.DefaultRX.Configure(PinConfig{Mode: PinInputPullUp})
u.DefaultTX.Configure(PinConfig{Mode: PinInputPullup}) u.DefaultTX.Configure(PinConfig{Mode: PinInputPullUp})
// clear flags // clear flags
u.S1.Get() u.S1.Get()
+14 -15
View File
@@ -17,8 +17,8 @@ const (
adc0_CH ADCChannel = iota adc0_CH ADCChannel = iota
adc1_CH adc1_CH
adc2_CH adc2_CH
adc3_CH // Note: GPIO29 not broken out on pico board adc3_CH // Note: GPIO29 not broken out on pico board
adcTempSensor // Internal temperature sensor channel ADC_TEMP_SENSOR // Internal temperature sensor channel
) )
// Used to serialise ADC sampling // Used to serialise ADC sampling
@@ -75,17 +75,19 @@ func (a ADC) GetADCChannel() (c ADCChannel, err error) {
return c, err return c, err
} }
// Configure sets the channel's associated pin to analog input mode. // Configure sets the channel's associated pin to analog input mode or powers on the temperature sensor for ADC_TEMP_SENSOR.
// The powered on temperature sensor increases ADC_AVDD current by approximately 40 μA. // The powered on temperature sensor increases ADC_AVDD current by approximately 40 μA.
func (c ADCChannel) Configure(config ADCConfig) error { func (c ADCChannel) Configure(config ADCConfig) error {
if config.Reference != 0 { if config.Reference != 0 {
adcAref = config.Reference adcAref = config.Reference
} }
p, err := c.Pin() if p, err := c.Pin(); err == nil {
if err != nil { p.Configure(PinConfig{Mode: PinAnalog})
return err }
if c == ADC_TEMP_SENSOR {
// Enable temperature sensor bias source
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
} }
p.Configure(PinConfig{Mode: PinAnalog})
return nil return nil
} }
@@ -110,16 +112,13 @@ func (c ADCChannel) getVoltage() uint32 {
} }
// ReadTemperature does a one-shot sample of the internal temperature sensor and returns a milli-celsius reading. // ReadTemperature does a one-shot sample of the internal temperature sensor and returns a milli-celsius reading.
func ReadTemperature() (millicelsius int32) { // Only works on the ADC_TEMP_SENSOR channel. aka AINSEL=4. Other channels will return 0
if rp.ADC.CS.Get()&rp.ADC_CS_EN == 0 { func (c ADCChannel) ReadTemperature() (millicelsius uint32) {
InitADC() if c != ADC_TEMP_SENSOR {
return
} }
// Enable temperature sensor bias source
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
// T = 27 - (ADC_voltage - 0.706)/0.001721 // T = 27 - (ADC_voltage - 0.706)/0.001721
return (27000<<16 - (int32(adcTempSensor.getVoltage())-706<<16)*581) >> 16 return (27000<<16 - (c.getVoltage()-706<<16)*581) >> 16
} }
// waitForReady spins waiting for the ADC peripheral to become ready. // waitForReady spins waiting for the ADC peripheral to become ready.
+5
View File
@@ -10,6 +10,11 @@ import (
"unsafe" "unsafe"
) )
const (
KHz = 1000
MHz = 1000000
)
func CPUFrequency() uint32 { func CPUFrequency() uint32 {
return 125 * MHz return 125 * MHz
} }
+5 -1
View File
@@ -226,8 +226,12 @@ type PinChange uint8
// Pin change interrupt constants for SetInterrupt. // Pin change interrupt constants for SetInterrupt.
const ( const (
// PinLevelLow triggers whenever pin is at a low (around 0V) logic level.
PinLevelLow PinChange = 1 << iota
// PinLevelLow triggers whenever pin is at a high (around 3V) logic level.
PinLevelHigh
// Edge falling // Edge falling
PinFalling PinChange = 4 << iota PinFalling
// Edge rising // Edge rising
PinRising PinRising
) )
-4
View File
@@ -13,10 +13,6 @@ import (
const numberOfCycles = 32 const numberOfCycles = 32
// GetRNG returns 32 bits of semi-random data based on ring oscillator. // GetRNG returns 32 bits of semi-random data based on ring oscillator.
//
// Unlike some other implementations of GetRNG, these random numbers are not
// cryptographically secure and must not be used for cryptographic operations
// (nonces, etc).
func GetRNG() (uint32, error) { func GetRNG() (uint32, error) {
var val uint32 var val uint32
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
+4 -3
View File
@@ -38,9 +38,10 @@ type SPIConfig struct {
} }
var ( var (
ErrLSBNotSupported = errors.New("SPI LSB unsupported on PL022") ErrLSBNotSupported = errors.New("SPI LSB unsupported on PL022")
ErrSPITimeout = errors.New("SPI timeout") ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
ErrSPIBaud = errors.New("SPI baud too low or above 66.5Mhz") ErrSPITimeout = errors.New("SPI timeout")
ErrSPIBaud = errors.New("SPI baud too low or above 66.5Mhz")
) )
type SPI struct { type SPI struct {
+1 -1
View File
@@ -137,7 +137,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
// default to 100 kHz (Sm, standard mode) if no frequency is set // default to 100 kHz (Sm, standard mode) if no frequency is set
if config.Frequency == 0 { if config.Frequency == 0 {
config.Frequency = 100 * KHz config.Frequency = TWI_FREQ_100KHZ
} }
// configure I2C input clock // configure I2C input clock
+57 -2
View File
@@ -1,5 +1,5 @@
//go:build !baremetal || atmega || esp32 || fe310 || k210 || nrf || (nxp && !mk66f18) || rp2040 || sam || (stm32 && !stm32f7x2 && !stm32l5x2) //go:build !baremetal || (stm32 && !stm32f7x2 && !stm32l5x2) || fe310 || k210 || (nxp && !mk66f18) || atmega
// +build !baremetal atmega esp32 fe310 k210 nrf nxp,!mk66f18 rp2040 sam stm32,!stm32f7x2,!stm32l5x2 // +build !baremetal stm32,!stm32f7x2,!stm32l5x2 fe310 k210 nxp,!mk66f18 atmega
package machine package machine
@@ -17,3 +17,58 @@ var (
ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size") ErrTxInvalidSliceSize = errors.New("SPI write and read slices must be same size")
errSPIInvalidMachineConfig = errors.New("SPI port was not configured properly by the machine") errSPIInvalidMachineConfig = errors.New("SPI port was not configured properly by the machine")
) )
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
// interface, there must always be the same number of bytes written as bytes read.
// 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 err error
switch {
case w == nil:
// read only, so write zero and read a result.
for i := range r {
r[i], err = spi.Transfer(0)
if err != nil {
return err
}
}
case r == nil:
// write only
for _, b := range w {
_, err = spi.Transfer(b)
if err != nil {
return err
}
}
default:
// write/read
if len(w) != len(r) {
return ErrTxInvalidSliceSize
}
for i, b := range w {
r[i], err = spi.Transfer(b)
if err != nil {
return err
}
}
}
return nil
}
-62
View File
@@ -1,62 +0,0 @@
//go:build !baremetal || atmega || fe310 || k210 || (nxp && !mk66f18) || (stm32 && !stm32f7x2 && !stm32l5x2)
// +build !baremetal atmega fe310 k210 nxp,!mk66f18 stm32,!stm32f7x2,!stm32l5x2
// This file implements the SPI Tx function for targets that don't have a custom
// (faster) implementation for it.
package machine
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
// interface, there must always be the same number of bytes written as bytes read.
// 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 err error
switch {
case w == nil:
// read only, so write zero and read a result.
for i := range r {
r[i], err = spi.Transfer(0)
if err != nil {
return err
}
}
case r == nil:
// write only
for _, b := range w {
_, err = spi.Transfer(b)
if err != nil {
return err
}
}
default:
// write/read
if len(w) != len(r) {
return ErrTxInvalidSliceSize
}
for i, b := range w {
r[i], err = spi.Transfer(b)
if err != nil {
return err
}
}
}
return nil
}
+4 -4
View File
@@ -8,20 +8,20 @@ import "errors"
var errUARTBufferEmpty = errors.New("UART buffer empty") var errUARTBufferEmpty = errors.New("UART buffer empty")
// UARTParity is the parity setting to be used for UART communication. // UARTParity is the parity setting to be used for UART communication.
type UARTParity uint8 type UARTParity int
const ( const (
// ParityNone means to not use any parity checking. This is // ParityNone means to not use any parity checking. This is
// the most common setting. // the most common setting.
ParityNone UARTParity = iota ParityNone UARTParity = 0
// ParityEven means to expect that the total number of 1 bits sent // ParityEven means to expect that the total number of 1 bits sent
// should be an even number. // should be an even number.
ParityEven ParityEven UARTParity = 1
// ParityOdd means to expect that the total number of 1 bits sent // ParityOdd means to expect that the total number of 1 bits sent
// should be an odd number. // should be an odd number.
ParityOdd ParityOdd UARTParity = 2
) )
// To implement the UART interface for a board, you must declare a concrete type as follows: // To implement the UART interface for a board, you must declare a concrete type as follows:
+11 -32
View File
@@ -20,46 +20,21 @@ var heapStartSymbol [0]byte
//go:extern __global_base //go:extern __global_base
var globalsStartSymbol [0]byte var globalsStartSymbol [0]byte
const (
// wasmMemoryIndex is always zero until the multi-memory feature is used.
//
// See https://github.com/WebAssembly/multi-memory
wasmMemoryIndex = 0
// wasmPageSize is the size of a page in WebAssembly's 32-bit memory. This
// is also its only unit of change.
//
// See https://www.w3.org/TR/wasm-core-1/#page-size
wasmPageSize = 64 * 1024
)
// wasm_memory_size invokes the "memory.size" instruction, which returns the
// current size to the memory at the given index (always wasmMemoryIndex), in
// pages.
//
//export llvm.wasm.memory.size.i32 //export llvm.wasm.memory.size.i32
func wasm_memory_size(index int32) int32 func wasm_memory_size(index int32) int32
// wasm_memory_grow invokes the "memory.grow" instruction, which attempts to
// increase the size of the memory at the given index (always wasmMemoryIndex),
// by the delta (in pages). This returns the previous size on success of -1 on
// failure.
//
//export llvm.wasm.memory.grow.i32 //export llvm.wasm.memory.grow.i32
func wasm_memory_grow(index int32, delta int32) int32 func wasm_memory_grow(index int32, delta int32) int32
var ( var (
// heapStart is the current memory offset which starts the heap. The heap heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
// extends from this offset until heapEnd (exclusive). heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
// heapEnd is the current memory length in bytes.
heapEnd = uintptr(wasm_memory_size(wasmMemoryIndex) * wasmPageSize)
globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol)) globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol))
globalsEnd = uintptr(unsafe.Pointer(&heapStartSymbol)) globalsEnd = uintptr(unsafe.Pointer(&heapStartSymbol))
) )
const wasmPageSize = 64 * 1024
func align(ptr uintptr) uintptr { func align(ptr uintptr) uintptr {
// Align to 16, which is the alignment of max_align_t: // Align to 16, which is the alignment of max_align_t:
// https://godbolt.org/z/dYqTsWrGq // https://godbolt.org/z/dYqTsWrGq
@@ -73,14 +48,14 @@ func getCurrentStackPointer() uintptr
// otherwise. // otherwise.
func growHeap() bool { func growHeap() bool {
// Grow memory by the available size, which means the heap size is doubled. // Grow memory by the available size, which means the heap size is doubled.
memorySize := wasm_memory_size(wasmMemoryIndex) memorySize := wasm_memory_size(0)
result := wasm_memory_grow(wasmMemoryIndex, memorySize) result := wasm_memory_grow(0, memorySize)
if result == -1 { if result == -1 {
// Grow failed. // Grow failed.
return false return false
} }
setHeapEnd(uintptr(wasm_memory_size(wasmMemoryIndex) * wasmPageSize)) setHeapEnd(uintptr(wasm_memory_size(0) * wasmPageSize))
// Heap has grown successfully. // Heap has grown successfully.
return true return true
@@ -93,6 +68,7 @@ func growHeap() bool {
var allocs = make(map[uintptr][]byte) var allocs = make(map[uintptr][]byte)
//export malloc //export malloc
//go:wasm-module
func libc_malloc(size uintptr) unsafe.Pointer { func libc_malloc(size uintptr) unsafe.Pointer {
buf := make([]byte, size) buf := make([]byte, size)
ptr := unsafe.Pointer(&buf[0]) ptr := unsafe.Pointer(&buf[0])
@@ -101,6 +77,7 @@ func libc_malloc(size uintptr) unsafe.Pointer {
} }
//export free //export free
//go:wasm-module
func libc_free(ptr unsafe.Pointer) { func libc_free(ptr unsafe.Pointer) {
if ptr == nil { if ptr == nil {
return return
@@ -113,12 +90,14 @@ func libc_free(ptr unsafe.Pointer) {
} }
//export calloc //export calloc
//go:wasm-module
func libc_calloc(nmemb, size uintptr) unsafe.Pointer { func libc_calloc(nmemb, size uintptr) unsafe.Pointer {
// No difference between calloc and malloc. // No difference between calloc and malloc.
return libc_malloc(nmemb * size) return libc_malloc(nmemb * size)
} }
//export realloc //export realloc
//go:wasm-module
func libc_realloc(oldPtr unsafe.Pointer, size uintptr) unsafe.Pointer { func libc_realloc(oldPtr unsafe.Pointer, size uintptr) unsafe.Pointer {
// It's hard to optimize this to expand the current buffer with our GC, but // It's hard to optimize this to expand the current buffer with our GC, but
// it is theoretically possible. For now, just always allocate fresh. // it is theoretically possible. For now, just always allocate fresh.
-9
View File
@@ -1,9 +0,0 @@
//go:build runtime_asserts
package runtime
// enable assertions for the garbage collector
const gcAsserts = true
// enable asserts for the scheduler
const schedulerAsserts = true
-9
View File
@@ -1,9 +0,0 @@
//go:build !runtime_asserts
package runtime
// disable assertions for the garbage collector
const gcAsserts = false
// disable assertions for the scheduler
const schedulerAsserts = false
+8 -28
View File
@@ -25,9 +25,7 @@ package runtime
// heapStart..metadataStart. // heapStart..metadataStart.
// //
// More information: // More information:
// https://aykevl.nl/2020/09/gc-tinygo
// https://github.com/micropython/micropython/wiki/Memory-Manager // https://github.com/micropython/micropython/wiki/Memory-Manager
// https://github.com/micropython/micropython/blob/master/py/gc.c
// "The Garbage Collection Handbook" by Richard Jones, Antony Hosking, Eliot // "The Garbage Collection Handbook" by Richard Jones, Antony Hosking, Eliot
// Moss. // Moss.
@@ -37,7 +35,11 @@ import (
"unsafe" "unsafe"
) )
const gcDebug = false // Set gcDebug to true to print debug information.
const (
gcDebug = false // print debug info
gcAsserts = gcDebug // perform sanity checks
)
// Some globals + constants for the entire GC. // Some globals + constants for the entire GC.
@@ -286,14 +288,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
// could be found. Run a garbage collection cycle to reclaim // could be found. Run a garbage collection cycle to reclaim
// free memory and try again. // free memory and try again.
heapScanCount = 2 heapScanCount = 2
freeBytes := runGC() GC()
heapSize := uintptr(metadataStart) - heapStart
if freeBytes < heapSize/3 {
// Ensure there is at least 33% headroom.
// This percentage was arbitrarily chosen, and may need to
// be tuned in the future.
growHeap()
}
} else { } else {
// Even after garbage collection, no free memory could be found. // Even after garbage collection, no free memory could be found.
// Try to increase heap size. // Try to increase heap size.
@@ -384,13 +379,6 @@ func free(ptr unsafe.Pointer) {
// GC performs a garbage collection cycle. // GC performs a garbage collection cycle.
func GC() { func GC() {
runGC()
}
// runGC performs a garbage colleciton cycle. It is the internal implementation
// of the runtime.GC() function. The difference is that it returns the number of
// free bytes in the heap after the GC is finished.
func runGC() (freeBytes uintptr) {
if gcDebug { if gcDebug {
println("running collection cycle...") println("running collection cycle...")
} }
@@ -432,14 +420,12 @@ func runGC() (freeBytes uintptr) {
// Sweep phase: free all non-marked objects and unmark marked objects for // Sweep phase: free all non-marked objects and unmark marked objects for
// the next collection cycle. // the next collection cycle.
freeBytes = sweep() sweep()
// Show how much has been sweeped, for debugging. // Show how much has been sweeped, for debugging.
if gcDebug { if gcDebug {
dumpHeap() dumpHeap()
} }
return
} }
// markRoots reads all pointers from start to end (exclusive) and if they look // markRoots reads all pointers from start to end (exclusive) and if they look
@@ -582,8 +568,7 @@ func markRoot(addr, root uintptr) {
} }
// Sweep goes through all memory and frees unmarked memory. // Sweep goes through all memory and frees unmarked memory.
// It returns how many bytes are free in the heap after the sweep. func sweep() {
func sweep() (freeBytes uintptr) {
freeCurrentObject := false freeCurrentObject := false
for block := gcBlock(0); block < endBlock; block++ { for block := gcBlock(0); block < endBlock; block++ {
switch block.state() { switch block.state() {
@@ -592,13 +577,11 @@ func sweep() (freeBytes uintptr) {
block.markFree() block.markFree()
freeCurrentObject = true freeCurrentObject = true
gcFrees++ gcFrees++
freeBytes += bytesPerBlock
case blockStateTail: case blockStateTail:
if freeCurrentObject { if freeCurrentObject {
// This is a tail object following an unmarked head. // This is a tail object following an unmarked head.
// Free it now. // Free it now.
block.markFree() block.markFree()
freeBytes += bytesPerBlock
} }
case blockStateMark: case blockStateMark:
// This is a marked object. The next tail blocks must not be freed, // This is a marked object. The next tail blocks must not be freed,
@@ -606,11 +589,8 @@ func sweep() (freeBytes uintptr) {
// collect this object if it is unreferenced then. // collect this object if it is unreferenced then.
block.unmark() block.unmark()
freeCurrentObject = false freeCurrentObject = false
case blockStateFree:
freeBytes += bytesPerBlock
} }
} }
return
} }
// looksLikePointer returns whether this could be a pointer. Currently, it // looksLikePointer returns whether this could be a pointer. Currently, it
+2
View File
@@ -11,6 +11,8 @@ import (
"unsafe" "unsafe"
) )
const gcAsserts = false // perform sanity checks
// Ever-incrementing pointer: no memory is freed. // Ever-incrementing pointer: no memory is freed.
var heapptr = heapStart var heapptr = heapStart
+2
View File
@@ -11,6 +11,8 @@ import (
"unsafe" "unsafe"
) )
const gcAsserts = false // perform sanity checks
var gcTotalAlloc uint64 // for runtime.MemStats var gcTotalAlloc uint64 // for runtime.MemStats
var gcMallocs uint64 var gcMallocs uint64
var gcFrees uint64 var gcFrees uint64
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"], "inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
"build-tags": ["circuitplay_bluefruit"], "build-tags": ["circuitplay_bluefruit"],
"serial-port": ["acm:239a:8045"], "serial-port": ["acm:239a:8045", "acm:239a:45"],
"msd-volume-name": "CPLAYBTBOOT" "msd-volume-name": "CPLAYBTBOOT"
} }
+1 -1
View File
@@ -3,7 +3,7 @@
"build-tags": ["circuitplay_express"], "build-tags": ["circuitplay_express"],
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"serial-port": ["acm:239a:8018"], "serial-port": ["acm:239a:8018", "acm:239a:18"],
"msd-volume-name": "CPLAYBOOT", "msd-volume-name": "CPLAYBOOT",
"msd-firmware-name": "firmware.uf2" "msd-firmware-name": "firmware.uf2"
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"], "inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
"build-tags": ["clue_alpha"], "build-tags": ["clue_alpha"],
"serial-port": ["acm:239a:8072", "acm:239a:8071"], "serial-port": ["acm:239a:8072", "acm:239a:0072", "acm:239a:0071", "acm:239a:8071"],
"msd-volume-name": "CLUEBOOT" "msd-volume-name": "CLUEBOOT"
} }
+1 -1
View File
@@ -2,7 +2,7 @@
"inherits": ["atsamd21g18a"], "inherits": ["atsamd21g18a"],
"build-tags": ["feather_m0"], "build-tags": ["feather_m0"],
"serial": "usb", "serial": "usb",
"serial-port": ["acm:239a:801b", "acm:239a:800b"], "serial-port": ["acm:239a:801b", "acm:239a:001b", "acm:239a:800b", "acm:239a:000b", "acm:239a:0015"],
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"msd-volume-name": "FEATHERBOOT", "msd-volume-name": "FEATHERBOOT",
+1 -1
View File
@@ -2,7 +2,7 @@
"inherits": ["atsame51j19a"], "inherits": ["atsame51j19a"],
"build-tags": ["feather_m4_can"], "build-tags": ["feather_m4_can"],
"serial": "usb", "serial": "usb",
"serial-port": ["acm:239a:80cd"], "serial-port": ["acm:239a:80cd", "acm:239a:00cd"],
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"msd-volume-name": "FTHRCANBOOT", "msd-volume-name": "FTHRCANBOOT",
+1 -1
View File
@@ -2,7 +2,7 @@
"inherits": ["atsamd51j19a"], "inherits": ["atsamd51j19a"],
"build-tags": ["feather_m4"], "build-tags": ["feather_m4"],
"serial": "usb", "serial": "usb",
"serial-port": ["acm:239a:8022"], "serial-port": ["acm:239a:8022", "acm:239a:0022"],
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"msd-volume-name": "FEATHERBOOT", "msd-volume-name": "FEATHERBOOT",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"], "inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
"build-tags": ["feather_nrf52840_sense"], "build-tags": ["feather_nrf52840_sense"],
"serial-port": ["acm:239a:8087", "acm:239a:8088"], "serial-port": ["acm:239a:8087", "acm:239a:0087", "acm:239a:0088", "acm:239a:8088"],
"msd-volume-name": "FTHRSNSBOOT" "msd-volume-name": "FTHRSNSBOOT"
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"], "inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
"build-tags": ["feather_nrf52840"], "build-tags": ["feather_nrf52840"],
"serial-port": ["acm:239a:8029", "acm:239a:802a"], "serial-port": ["acm:239a:8029", "acm:239a:0029", "acm:239a:002a", "acm:239a:802a"],
"msd-volume-name": "FTHR840BOOT" "msd-volume-name": "FTHR840BOOT"
} }
+1 -1
View File
@@ -2,7 +2,7 @@
"inherits": ["atsamd51p20a"], "inherits": ["atsamd51p20a"],
"build-tags": ["grandcentral_m4"], "build-tags": ["grandcentral_m4"],
"serial": "usb", "serial": "usb",
"serial-port": ["acm:239a:8031"], "serial-port": ["acm:239a:8031", "acm:239a:0031", "acm:239a:0032"],
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"msd-volume-name": "GCM4BOOT", "msd-volume-name": "GCM4BOOT",
+1 -1
View File
@@ -2,7 +2,7 @@
"inherits": ["atsamd21g18a"], "inherits": ["atsamd21g18a"],
"build-tags": ["itsybitsy_m0"], "build-tags": ["itsybitsy_m0"],
"serial": "usb", "serial": "usb",
"serial-port": ["acm:239a:800f", "acm:239a:8012"], "serial-port": ["acm:239a:800f", "acm:239a:000f", "acm:239a:8012"],
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"msd-volume-name": "ITSYBOOT", "msd-volume-name": "ITSYBOOT",
+1 -1
View File
@@ -4,7 +4,7 @@
"serial": "usb", "serial": "usb",
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"serial-port": ["acm:239a:802b"], "serial-port": ["acm:239a:802b", "acm:239a:002b"],
"msd-volume-name": "ITSYM4BOOT", "msd-volume-name": "ITSYM4BOOT",
"msd-firmware-name": "firmware.uf2" "msd-firmware-name": "firmware.uf2"
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"inherits": ["nrf52840", "nrf52840-s140v6-uf2"], "inherits": ["nrf52840", "nrf52840-s140v6-uf2"],
"build-tags": ["itsybitsy_nrf52840"], "build-tags": ["itsybitsy_nrf52840"],
"serial-port": ["acm:239A:8052", "acm:239A:8051"], "serial-port": ["acm:239A:8052", "acm:239A:0052", "acm:239A:0051", "acm:239A:8051"],
"msd-volume-name": "ITSY840BOOT" "msd-volume-name": "ITSY840BOOT"
} }
+1 -1
View File
@@ -2,7 +2,7 @@
"inherits": ["atsamd51j19a"], "inherits": ["atsamd51j19a"],
"build-tags": ["matrixportal_m4"], "build-tags": ["matrixportal_m4"],
"serial": "usb", "serial": "usb",
"serial-port": ["acm:239a:80c9", "acm:239a:80ca"], "serial-port": ["acm:239a:80c9", "acm:239a:00c9", "acm:239a:80ca"],
"flash-1200-bps-reset": "true", "flash-1200-bps-reset": "true",
"flash-method": "msd", "flash-method": "msd",
"msd-volume-name": "MATRIXBOOT", "msd-volume-name": "MATRIXBOOT",

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