Compare commits

..

17 Commits

Author SHA1 Message Date
sago35 20883b9fac build: make msd flash faster 2021-03-15 23:07:27 +09:00
ardnew 99b129d366 Add board support for Adafruit Grand Central M4 (SAMD51) (#1714)
machine/grandcentral-m4: implementation for Adafruit Grand Central M4 board.
2021-03-15 14:06:09 +01:00
Federico G. Schwindt 303acf5ed6 Upgrade WASI version to wasi_snapshot_preview1 (#1691)
wasm: Upgrade WASI version to wasi_snapshot_preview1

Addresses #1647.
2021-03-15 12:41:37 +01:00
ardnew 7d1ce24be5 fix data shift/mask in func newUSBSetup 2021-03-14 23:58:25 +01:00
ardnew 774c86e21b goenv: use physical path instead of cached GOROOT in function getGoroot (fixes #433, #1658) 2021-03-14 22:26:44 +01:00
sago35 0cabd4de69 atsamd5x: improve SPI 2021-03-14 15:40:53 +01:00
Thomas Tromp 56bbc5bf6d Fix fe310 SPI read 2021-03-13 08:56:15 +01:00
ardnew 0b44d0bcc5 add UART0 as alias for UART1 2021-03-13 07:34:44 +01:00
ardnew 6275b3a8d1 teensy40: move txBuffer allocation to UART declaration 2021-03-13 07:34:44 +01:00
Ayke van Laethem 34b50efdcd interp: support GEP on fixed (MMIO) addresses
GetElementPtr would not work on values that weren't pointers. Because
fixed addresses (often used in memory-mapped I/O) are integers rather
than pointers in interp, it would return an error.

This resulted in the teensy40 target not compiling correctly since the
interp package rewrite. This commit should fix that.
2021-03-12 12:35:06 +01:00
Ayke van Laethem 42088f938e attiny: remove dummy UART
I think it's better not to provide a UART0 global at all than one that
does nothing.
2021-03-10 22:28:58 +01:00
Ayke van Laethem c60c36f0a8 all: use ExitCode() call to get exit code of exited process
This is an addition that landed in Go 1.12 but we couldn't use before
because we were supporting Go back until Go 1.11. It simplifies the code
around processes a bit.
2021-03-09 18:15:49 +01:00
Ayke van Laethem e3aa13c2a6 all: replace strings.Replace with strings.ReplaceAll
This was an addition to Go 1.13 and results in slightly easier to read
code.
2021-03-09 18:15:49 +01:00
Ayke van Laethem b0366743cd all: remove support for Go 1.11 and 1.12
Go 1.13 has some important improvements that we would like to use, such
as the new integer literals and `errors.Is` which both arrived in Go
1.13.
2021-03-09 18:15:49 +01:00
Ayke van Laethem c54bdf8b51 runtime: add dummy debug package
This package does not implement any methods, which is of course not
useful. However, by creating this package in advance it's possible to
see the next issue that's preventing something from building in TinyGo.

Motivated by: https://github.com/tinygo-org/tinygo/issues/1634
2021-03-09 16:09:51 +01:00
sago35 1fd4669bee docs: add QT Py and Teensy 4.0 2021-03-09 16:07:50 +01:00
sago35 e36dfe58ac version: update TinyGo version to 0.18.0-dev 2021-03-07 08:53:48 +09:00
42 changed files with 709 additions and 163 deletions
-14
View File
@@ -342,18 +342,6 @@ commands:
- /go/pkg/mod
jobs:
test-llvm10-go111:
docker:
- image: circleci/golang:1.11-buster
steps:
- test-linux:
llvm: "10"
test-llvm10-go112:
docker:
- image: circleci/golang:1.12-buster
steps:
- test-linux:
llvm: "10"
test-llvm10-go113:
docker:
- image: circleci/golang:1.13-buster
@@ -399,8 +387,6 @@ jobs:
workflows:
test-all:
jobs:
- test-llvm10-go111
- test-llvm10-go112
- test-llvm10-go113
- test-llvm10-go114
- test-llvm11-go115
+1 -6
View File
@@ -23,7 +23,7 @@ different guide:
LLVM, Clang and LLD are quite light on dependencies, requiring only standard
build tools to be built. Go is of course necessary to build TinyGo itself.
* Go (1.11+)
* Go (1.13+)
* Standard build tools (gcc/clang)
* git
* CMake
@@ -43,11 +43,6 @@ You can also store LLVM outside of the TinyGo root directory by setting the
`LLVM_BUILDDIR`, `CLANG_SRC` and `LLD_SRC` make variables, but that is not
covered by this guide.
TinyGo uses Go modules, so if you clone TinyGo inside your GOPATH (and are using
Go below 1.13), make sure that Go modules are enabled:
export GO111MODULE=on
## Build LLVM, Clang, LLD
Before starting the build, you may want to set the following environment
+3 -1
View File
@@ -43,7 +43,7 @@ See the [getting started instructions](https://tinygo.org/getting-started/) for
You can compile TinyGo programs for microcontrollers, WebAssembly and Linux.
The following 53 microcontroller boards are currently supported:
The following 55 microcontroller boards are currently supported:
* [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333)
* [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333)
@@ -60,6 +60,7 @@ The following 53 microcontroller boards are currently supported:
* [Adafruit PyBadge](https://www.adafruit.com/product/4200)
* [Adafruit PyGamer](https://www.adafruit.com/product/4242)
* [Adafruit PyPortal](https://www.adafruit.com/product/4116)
* [Adafruit QT Py](https://www.adafruit.com/product/4600)
* [Adafruit Trinket M0](https://www.adafruit.com/product/3500)
* [Arduino Mega 2560](https://store.arduino.cc/arduino-mega-2560-rev3)
* [Arduino MKR1000](https://store.arduino.cc/arduino-mkr1000-wifi)
@@ -87,6 +88,7 @@ The following 53 microcontroller boards are currently supported:
* [Phytec reel board](https://www.phytec.eu/product-eu/internet-of-things/reelboard/)
* [PineTime DevKit](https://www.pine64.org/pinetime/)
* [PJRC Teensy 3.6](https://www.pjrc.com/store/teensy36.html)
* [PJRC Teensy 4.0](https://www.pjrc.com/store/teensy40.html)
* [ProductivityOpen P1AM-100](https://facts-engineering.github.io/modules/P1AM-100/P1AM-100.html)
* [Seeed Wio Terminal](https://www.seeedstudio.com/Wio-Terminal-p-4509.html)
* [Seeed Seeeduino XIAO](https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html)
+9 -1
View File
@@ -44,7 +44,7 @@ type BuildResult struct {
//
// The error value may be of type *MultiError. Callers will likely want to check
// for this case and print such errors individually.
func Build(pkgName, outpath string, config *compileopts.Config, action func(BuildResult) error) error {
func Build(pkgName, outpath string, config *compileopts.Config, preAction func() error, action func(BuildResult) error) error {
compilerConfig := &compiler.Config{
Triple: config.Triple(),
CPU: config.CPU(),
@@ -87,6 +87,14 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
// Makefile target.
var jobs []*compileJob
if preAction != nil {
// Add job to preAction.
jobs = append(jobs, &compileJob{
description: "preAction",
run: preAction,
})
}
// Add job to compile and optimize all Go files at once.
// TODO: parallelize this.
var mod llvm.Module
+2 -2
View File
@@ -25,8 +25,8 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
if err != nil {
return nil, fmt.Errorf("could not read version from GOROOT (%v): %v", goroot, err)
}
if major != 1 || minor < 11 || minor > 16 {
return nil, fmt.Errorf("requires go version 1.11 through 1.16, got go%d.%d", major, minor)
if major != 1 || minor < 13 || minor > 16 {
return nil, fmt.Errorf("requires go version 1.13 through 1.16, got go%d.%d", major, minor)
}
clangHeaderPath := getClangHeaderPath(goenv.Get("TINYGOROOT"))
return &compileopts.Config{
+3 -3
View File
@@ -24,7 +24,7 @@ var flagUpdate = flag.Bool("update", false, "Update images based on test output.
// normalizeResult normalizes Go source code that comes out of tests across
// platforms and Go versions.
func normalizeResult(result string) string {
actual := strings.Replace(result, "\r\n", "\n", -1)
actual := strings.ReplaceAll(result, "\r\n", "\n")
// Make sure all functions are wrapped, even those that would otherwise be
// single-line functions. This is necessary because Go 1.14 changed the way
@@ -113,7 +113,7 @@ func TestCGo(t *testing.T) {
if err != nil {
t.Fatalf("could not read expected output: %v", err)
}
expected := strings.Replace(string(expectedBytes), "\r\n", "\n", -1)
expected := strings.ReplaceAll(string(expectedBytes), "\r\n", "\n")
// Check whether the output is as expected.
if expected != actual {
@@ -154,7 +154,7 @@ func formatDiagnostic(err error) string {
msg := err.Error()
if runtime.GOOS == "windows" {
// Fix Windows path slashes.
msg = strings.Replace(msg, "testdata\\", "testdata/", -1)
msg = strings.ReplaceAll(msg, "testdata\\", "testdata/")
}
return "// " + msg + "\n"
}
+2 -2
View File
@@ -165,7 +165,7 @@ func (c *Config) AutomaticStackSize() bool {
func (c *Config) CFlags() []string {
cflags := append([]string{}, c.Options.CFlags...)
for _, flag := range c.Target.CFlags {
cflags = append(cflags, strings.Replace(flag, "{root}", goenv.Get("TINYGOROOT"), -1))
cflags = append(cflags, strings.ReplaceAll(flag, "{root}", goenv.Get("TINYGOROOT")))
}
if c.Target.Libc == "picolibc" {
root := goenv.Get("TINYGOROOT")
@@ -186,7 +186,7 @@ func (c *Config) LDFlags() []string {
// Merge and adjust LDFlags.
ldflags := append([]string{}, c.Options.LDFlags...)
for _, flag := range c.Target.LDFlags {
ldflags = append(ldflags, strings.Replace(flag, "{root}", root, -1))
ldflags = append(ldflags, strings.ReplaceAll(flag, "{root}", root))
}
ldflags = append(ldflags, "-L", root)
if c.Target.LinkerScript != "" {
+1 -1
View File
@@ -1,6 +1,6 @@
module github.com/tinygo-org/tinygo
go 1.11
go 1.13
require (
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
+21 -2
View File
@@ -142,10 +142,11 @@ func getHomeDir() string {
// getGoroot returns an appropriate GOROOT from various sources. If it can't be
// found, it returns an empty string.
func getGoroot() string {
// An explicitly set GOROOT always has preference.
goroot := os.Getenv("GOROOT")
if goroot != "" {
// An explicitly set GOROOT always has preference.
return goroot
// Convert to the standard GOROOT being referenced, if it's a TinyGo cache.
return getStandardGoroot(goroot)
}
// Check for the location of the 'go' binary and base GOROOT on that.
@@ -195,3 +196,21 @@ func isGoroot(goroot string) bool {
_, err := os.Stat(filepath.Join(goroot, "src", "runtime", "internal", "sys", "zversion.go"))
return err == nil
}
// getStandardGoroot returns the physical path to a real, standard Go GOROOT
// implied by the given path.
// If the given path appears to be a TinyGo cached GOROOT, it returns the path
// referenced by symlinks contained in the cache. Otherwise, it returns the
// given path as-is.
func getStandardGoroot(path string) string {
// Check if the "bin" subdirectory of our given GOROOT is a symlink, and then
// return the _parent_ directory of its destination.
if dest, err := os.Readlink(filepath.Join(path, "bin")); nil == err {
// Clean the destination to remove any trailing slashes, so that
// filepath.Dir will always return the parent.
// (because both "/foo" and "/foo/" are valid symlink destinations,
// but filepath.Dir would return "/" and "/foo", respectively)
return filepath.Dir(filepath.Clean(dest))
}
return path
}
+1 -1
View File
@@ -12,7 +12,7 @@ import (
// Version of TinyGo.
// Update this value before release of new version of software.
const Version = "0.17.0"
const Version = "0.18.0-dev"
// GetGorootVersion returns the major and minor version for a given GOROOT path.
// If the goroot cannot be determined, (0, 0) is returned.
+2 -4
View File
@@ -11,19 +11,17 @@ import (
"tinygo.org/x/go-llvm"
)
var errLiteralToPointer = errors.New("interp: trying to convert literal value to pointer")
// These errors are expected during normal execution and can be recovered from
// by running the affected function at runtime instead of compile time.
var (
errExpectedPointer = errors.New("interp: trying to use an integer as a pointer (memory-mapped I/O?)")
errIntegerAsPointer = errors.New("interp: trying to use an integer as a pointer (memory-mapped I/O?)")
errUnsupportedInst = errors.New("interp: unsupported instruction")
errUnsupportedRuntimeInst = errors.New("interp: unsupported instruction (to be emitted at runtime)")
errMapAlreadyCreated = errors.New("interp: map already created")
)
func isRecoverableError(err error) bool {
return err == errExpectedPointer || err == errUnsupportedInst || err == errUnsupportedRuntimeInst || err == errMapAlreadyCreated
return err == errIntegerAsPointer || err == errUnsupportedInst || err == errUnsupportedRuntimeInst || err == errMapAlreadyCreated
}
// ErrorLine is one line in a traceback. The position may be missing.
+1 -1
View File
@@ -102,7 +102,7 @@ func Run(mod llvm.Module, debug bool) error {
if callErr != nil {
if isRecoverableError(callErr.Err) {
if r.debug {
fmt.Fprintln(os.Stderr, "not interpretring", r.pkgName, "because of error:", callErr.Err)
fmt.Fprintln(os.Stderr, "not interpreting", r.pkgName, "because of error:", callErr.Error())
}
mem.revert()
continue
+16 -1
View File
@@ -550,7 +550,22 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
}
ptr, err := operands[0].asPointer(r)
if err != nil {
return nil, mem, r.errorAt(inst, err)
if err != errIntegerAsPointer {
return nil, mem, r.errorAt(inst, err)
}
// GEP on fixed pointer value (for example, memory-mapped I/O).
ptrValue := operands[0].Uint() + offset
switch operands[0].len(r) {
case 8:
locals[inst.localIndex] = literalValue{uint64(ptrValue)}
case 4:
locals[inst.localIndex] = literalValue{uint32(ptrValue)}
case 2:
locals[inst.localIndex] = literalValue{uint16(ptrValue)}
default:
panic("pointer operand is not of a known pointer size")
}
continue
}
ptr = ptr.addOffset(uint32(offset))
locals[inst.localIndex] = ptr
+2 -2
View File
@@ -348,7 +348,7 @@ func (v literalValue) clone() value {
}
func (v literalValue) asPointer(r *runner) (pointerValue, error) {
return pointerValue{}, errLiteralToPointer
return pointerValue{}, errIntegerAsPointer
}
func (v literalValue) asRawValue(r *runner) rawValue {
@@ -949,7 +949,7 @@ func (v rawValue) clone() value {
func (v rawValue) asPointer(r *runner) (pointerValue, error) {
if v.buf[0] <= 255 {
// Probably a null pointer or memory-mapped I/O.
return pointerValue{}, errExpectedPointer
return pointerValue{}, errIntegerAsPointer
}
return pointerValue{v.buf[0]}, nil
}
+1 -5
View File
@@ -16,7 +16,6 @@ import (
"path/filepath"
"strconv"
"strings"
"syscall"
"github.com/tinygo-org/tinygo/cgo"
"github.com/tinygo-org/tinygo/compileopts"
@@ -110,10 +109,7 @@ func Load(config *compileopts.Config, inputPkgs []string, clangHeaders string, t
err = cmd.Run()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
os.Exit(status.ExitStatus())
}
os.Exit(1)
os.Exit(exitErr.ExitCode())
}
return nil, fmt.Errorf("failed to run `go list`: %s", err)
}
+12 -17
View File
@@ -16,7 +16,6 @@ import (
"runtime"
"strings"
"sync/atomic"
"syscall"
"time"
"github.com/mattn/go-colorable"
@@ -106,7 +105,7 @@ func Build(pkgName, outpath string, options *compileopts.Options) error {
return err
}
return builder.Build(pkgName, outpath, config, func(result builder.BuildResult) error {
return builder.Build(pkgName, outpath, config, nil, func(result builder.BuildResult) error {
if err := os.Rename(result.Binary, outpath); err != nil {
// Moving failed. Do a file copy.
inf, err := os.Open(result.Binary)
@@ -142,7 +141,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly bool, ou
return err
}
return builder.Build(pkgName, outpath, config, func(result builder.BuildResult) error {
return builder.Build(pkgName, outpath, config, nil, func(result builder.BuildResult) error {
if testCompileOnly || outpath != "" {
// Write test binary to the specified file name.
if outpath == "" {
@@ -166,10 +165,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly bool, ou
if err != nil {
// Propagate the exit code
if err, ok := err.(*exec.ExitError); ok {
if status, ok := err.Sys().(syscall.WaitStatus); ok {
os.Exit(status.ExitStatus())
}
os.Exit(1)
os.Exit(err.ExitCode())
}
return &commandError{"failed to run compiled binary", result.Binary, err}
}
@@ -241,7 +237,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
return errors.New("unknown flash method: " + flashMethod)
}
return builder.Build(pkgName, fileExt, config, func(result builder.BuildResult) error {
return builder.Build(pkgName, fileExt, config, func() error {
// do we need port reset to put MCU into bootloader mode?
if config.Target.PortReset == "true" && flashMethod != "openocd" {
if port == "" {
@@ -254,19 +250,21 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
err := touchSerialPortAt1200bps(port)
if err != nil {
return &commandError{"failed to reset port", result.Binary, err}
return &commandError{"failed to reset port", "", err}
}
// give the target MCU a chance to restart into bootloader
time.Sleep(3 * time.Second)
}
return nil
}, func(result builder.BuildResult) error {
// this flashing method copies the binary data to a Mass Storage Device (msd)
switch flashMethod {
case "", "command":
// Create the command.
flashCmd := config.Target.FlashCommand
fileToken := "{" + fileExt[1:] + "}"
flashCmd = strings.Replace(flashCmd, fileToken, result.Binary, -1)
flashCmd = strings.ReplaceAll(flashCmd, fileToken, result.Binary)
if port == "" && strings.Contains(flashCmd, "{port}") {
var err error
@@ -276,7 +274,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
}
}
flashCmd = strings.Replace(flashCmd, "{port}", port, -1)
flashCmd = strings.ReplaceAll(flashCmd, "{port}", port)
// Execute the command.
var cmd *exec.Cmd
@@ -352,7 +350,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro
return errors.New("gdb not configured in the target specification")
}
return builder.Build(pkgName, "", config, func(result builder.BuildResult) error {
return builder.Build(pkgName, "", config, nil, func(result builder.BuildResult) error {
// Find a good way to run GDB.
gdbInterface, openocdInterface := config.Programmer()
switch gdbInterface {
@@ -516,7 +514,7 @@ func Run(pkgName string, options *compileopts.Options) error {
return err
}
return builder.Build(pkgName, ".elf", config, func(result builder.BuildResult) error {
return builder.Build(pkgName, ".elf", config, nil, func(result builder.BuildResult) error {
if len(config.Target.Emulator) == 0 {
// Run directly.
cmd := executeCommand(config.Options, result.Binary)
@@ -1080,10 +1078,7 @@ func main() {
err = cmd.Run()
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
if status, ok := exitErr.Sys().(syscall.WaitStatus); ok {
os.Exit(status.ExitStatus())
}
os.Exit(1)
os.Exit(exitErr.ExitCode())
}
fmt.Fprintln(os.Stderr, "failed to run `go list`:", err)
os.Exit(1)
+243
View File
@@ -0,0 +1,243 @@
// +build grandcentral_m4
package machine
// Digital pins
const (
// = Pin Alt. Function SERCOM PWM Timer Interrupt
// ------ -------------------- -------- ----------- -----------
D0 = PB25 // UART1 RX 0[1] EXTI9
D1 = PB24 // UART1 TX 0[0] EXTI8
D2 = PC18 // TCC0[2] EXTI2
D3 = PC19 // TCC0[3] EXTI3
D4 = PC20 // TCC0[4] EXTI4
D5 = PC21 // TCC0[5] EXTI5
D6 = PD20 // TCC1[0] EXTI10
D7 = PD21 // TCC1[1] EXTI11
D8 = PB18 // TCC1[0] EXTI2
D9 = PB02 // TC6[0] EXTI3
D10 = PB22 // TC7[0] EXTI6
D11 = PB23 // EXTI7
D12 = PB00 // TC7[0] EXTI0
D13 = PB01 // On-board LED TC7[1] EXTI1
D14 = PB16 // UART4 TX, I2S0 SCK 5[0] TC6[0] EXTI0
D15 = PB17 // UART4 RX, I2S0 MCK 5[1] EXTI1
D16 = PC22 // UART3 TX 1[0] EXTI6
D17 = PC23 // UART3 RX 1[1] EXTI6
D18 = PB12 // UART2 TX 4[0] TCC3[0] EXTI12
D19 = PB13 // UART2 RX 4[1] TCC3[1] EXTI13
D20 = PB20 // I2C0 SDA 3[0] EXTI4
D21 = PB21 // I2C0 SCL 3[1] EXTI5
D22 = PD12 // EXTI7
D23 = PA15 // TCC2[1] EXTI15
D24 = PC17 // I2C1 SCL 6[1] TCC0[1] EXTI1
D25 = PC16 // I2C1 SDA 6[0] TCC0[0] EXTI0
D26 = PA12 // PCC DEN1 TC2[0] EXTI12
D27 = PA13 // PCC DEN2 TC2[1] EXTI13
D28 = PA14 // PCC CLK TCC2[0] EXTI14
D29 = PB19 // PCC XCLK EXTI3
D30 = PA23 // PCC D7 TC4[1] EXTI7
D31 = PA22 // PCC D6, I2S0 SDI TC4[0] EXTI6
D32 = PA21 // PCC D5, I2S0 SDO EXTI5
D33 = PA20 // PCC D4, I2S0 FS EXTI4
D34 = PA19 // PCC D3 TC3[1] EXTI3
D35 = PA18 // PCC D2 TC3[0] EXTI2
D36 = PA17 // PCC D1 EXTI1
D37 = PA16 // PCC D0 EXTI0
D38 = PB15 // PCC D9 TCC4[1] EXTI15
D39 = PB14 // PCC D8 TCC4[0] EXTI14
D40 = PC13 // PCC D11 EXTI13
D41 = PC12 // PCC D10 EXTI12
D42 = PC15 // PCC D13 EXTI15
D43 = PC14 // PCC D12 EXTI14
D44 = PC11 // EXTI11
D45 = PC10 // EXTI10
D46 = PC06 // EXTI6
D47 = PC07 // EXTI5
D48 = PC04 // EXTI4
D49 = PC05 // EXTI5
D50 = PD11 // SPI0 SDI 7[3] EXTI11
D51 = PD08 // SPI0 SDO 7[0] EXTI8
D52 = PD09 // SPI0 SCK 7[1] EXTI9
D53 = PD10 // SPI0 CS EXTI10
D54 = PB05 // ADC1 (A8) EXTI5
D55 = PB06 // ADC1 (A9) EXTI6
D56 = PB07 // ADC1 (A10) EXTI7
D57 = PB08 // ADC1 (A11) EXTI8
D58 = PB09 // ADC1 (A12) EXTI9
D59 = PA04 // ADC0 (A13) TC0[0] EXTI4
D60 = PA06 // ADC0 (A14) TC1[0] EXTI6
D61 = PA07 // ADC0 (A15) TC1[1] EXTI7
D62 = PB20 // I2C0 SDA 3[0] TCC1[2] EXTI4
D63 = PB21 // I2C0 SCL 3[1] TCC1[3] EXTI5
D64 = PD11 // SPI0 SDI 7[3] EXTI6
D65 = PD08 // SPI0 SDO 7[0] EXTI3
D66 = PD09 // SPI0 SCK 7[1] EXTI4
D67 = PA02 // ADC0 (A0), DAC0 EXTI2
D68 = PA05 // ADC0 (A1), DAC1 EXTI5
D69 = PB03 // ADC0 (A2) TC6[1] EXTI3
D70 = PC00 // ADC1 (A3) EXTI0
D71 = PC01 // ADC1 (A4) EXTI1
D72 = PC02 // ADC1 (A5) EXTI2
D73 = PC03 // ADC1 (A6) EXTI3
D74 = PB04 // ADC1 (A7) EXTI4
D75 = PC31 // UART RX LED
D76 = PC30 // UART TX LED
D77 = PA27 // USB HOST EN
D78 = PA24 // USB DM EXTI8
D79 = PA25 // USB DP EXTI9
D80 = PB29 // SD/SPI1 SDI 2[3]
D81 = PB27 // SD/SPI1 SCK 2[1]
D82 = PB26 // SD/SPI1 SDO 2[0]
D83 = PB28 // SD/SPI1 CS
D84 = PA03 // AREF EXTI3
D85 = PA02 // DAC0 EXTI2
D86 = PA05 // DAC1 EXTI5
D87 = PB01 // On-board LED (D13) TC7[1] EXTI1
D88 = PC24 // On-board NeoPixel
D89 = PB10 // QSPI SCK EXTI10
D90 = PB11 // QSPI CS EXTI11
D91 = PA08 // QSPI ID0 EXTI(NMI)
D92 = PA09 // QSPI ID1 EXTI9
D93 = PA10 // QSPI ID2 EXTI10
D94 = PA11 // QSPI ID3 EXTI11
D95 = PB31 // SD Detect EXTI15
D96 = PB30 // SWO EXTI14
)
// Analog pins
const (
A0 = D67 // (PA02) ADC0 ch. 0,
A1 = D68 // (PA05) ADC0 ch. 5,
A2 = D69 // (PB03) ADC0 ch. 15
A3 = D70 // (PC00) ADC1 ch. 10
A4 = D71 // (PC01) ADC1 ch. 11
A5 = D72 // (PC02) ADC1 ch. 4
A6 = D73 // (PC03) ADC1 ch. 5
A7 = D74 // (PB04) ADC1 ch. 6
A8 = D54 // (PB05) ADC1 ch. 7
A9 = D55 // (PB06) ADC1 ch. 8
A10 = D56 // (PB07) ADC1 ch. 9
A11 = D57 // (PB08) ADC1 ch. 0
A12 = D58 // (PB09) ADC1 ch. 1
A13 = D59 // (PA04) ADC0 ch. 4
A14 = D60 // (PA06) ADC0 ch. 6
A15 = D61 // (PA07) ADC0 ch. 7
AREF = D84 // (PA03)
)
// LED pins
const (
LED_PIN = D13 // (PB01), also on D87
UART_RX_LED_PIN = D75 // (PC31)
UART_TX_LED_PIN = D76 // (PC30)
NEOPIXEL_PIN = D88 // (PC24)
// aliases used by examples and drivers
LED = LED_PIN
LED_RX = UART_RX_LED_PIN
LED_TX = UART_TX_LED_PIN
NEOPIXEL = NEOPIXEL_PIN
)
// UART pins
const (
UART1_RX_PIN = D0 // (PB25)
UART1_TX_PIN = D1 // (PB24)
UART2_RX_PIN = D19 // (PB13)
UART2_TX_PIN = D18 // (PB12)
UART3_RX_PIN = D17 // (PC23)
UART3_TX_PIN = D16 // (PC22)
UART4_RX_PIN = D15 // (PB17)
UART4_TX_PIN = D14 // (PB16)
UART_RX_PIN = UART1_RX_PIN // default pins
UART_TX_PIN = UART1_TX_PIN //
)
// SPI pins
const (
SPI0_SCK_PIN = D66 // (PD09), also on D52
SPI0_SDO_PIN = D65 // (PD08), also on D51
SPI0_SDI_PIN = D64 // (PD11), also on D50
SPI0_CS_PIN = D53 // (PD10)
SPI1_SCK_PIN = D81 // (PB27)
SPI1_SDO_PIN = D82 // (PB26)
SPI1_SDI_PIN = D80 // (PB29)
SPI_SCK_PIN = SPI0_SCK_PIN // default pins
SPI_SDO_PIN = SPI0_SDO_PIN //
SPI_SDI_PIN = SPI0_SDI_PIN //
SPI_CS_PIN = SPI0_CS_PIN //
)
// I2C pins
const (
I2C0_SDA_PIN = D62 // (PB20), also on D20
I2C0_SCL_PIN = D63 // (PB21), also on D21
I2C1_SDA_PIN = D25 // (PC16)
I2C1_SCL_PIN = D24 // (PC17)
I2C_SDA_PIN = I2C0_SDA_PIN // default pins
I2C_SCL_PIN = I2C0_SCL_PIN //
SDA_PIN = I2C_SDA_PIN // unconventional pin names
SCL_PIN = I2C_SCL_PIN // (required by machine_atsamd51.go)
)
// I2S pins
const (
I2S0_SCK_PIN = D14 // (PB16)
I2S0_MCK_PIN = D15 // (PB17)
I2S0_FS_PIN = D33 // (PA20)
I2S0_SDO_PIN = D32 // (PA21)
I2S0_SDI_PIN = D31 // (PA22)
I2S_SCK_PIN = I2S0_SCK_PIN // default pins
I2S_WS_PIN = I2S0_FS_PIN //
I2S_SD_PIN = I2S0_SDO_PIN //
)
// SD card pins
const (
SD0_SCK_PIN = D81 // (PB27)
SD0_SDO_PIN = D82 // (PB26)
SD0_SDI_PIN = D80 // (PB29)
SD0_CS_PIN = D83 // (PB28)
SD0_DET_PIN = D95 // (PB31)
SDCARD_SCK_PIN = SD0_SCK_PIN // default pins
SDCARD_SDO_PIN = SD0_SDO_PIN //
SDCARD_SDI_PIN = SD0_SDI_PIN //
SDCARD_CS_PIN = SD0_CS_PIN //
SDCARD_DET_PIN = SD0_DET_PIN //
)
// Other peripheral constants
const (
RESET_MAGIC_VALUE = 0xF01669EF // Used to reset into bootloader
)
// USB CDC pins
const (
USBCDC_HOSTEN_PIN = D77 // (PA27) host enable
USBCDC_DM_PIN = D78 // (PA24) D-
USBCDC_DP_PIN = D79 // (PA25) D+
)
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "Adafruit Grand Central M4"
usb_STRING_MANUFACTURER = "Adafruit"
)
var (
usb_VID uint16 = 0x239A
usb_PID uint16 = 0x8031
)
@@ -0,0 +1,63 @@
// +build grandcentral_m4
package machine
import (
"device/sam"
"runtime/interrupt"
)
func init() {
UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM0_2, UART1.handleInterrupt)
UART2.Interrupt = interrupt.New(sam.IRQ_SERCOM4_2, UART2.handleInterrupt)
UART3.Interrupt = interrupt.New(sam.IRQ_SERCOM1_2, UART3.handleInterrupt)
UART4.Interrupt = interrupt.New(sam.IRQ_SERCOM5_2, UART4.handleInterrupt)
}
// UART on the Grand Central M4
var (
UART1 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM0_USART_INT,
SERCOM: 0,
}
UART2 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM4_USART_INT,
SERCOM: 4,
}
UART3 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM1_USART_INT,
SERCOM: 1,
}
UART4 = UART{
Buffer: NewRingBuffer(),
Bus: sam.SERCOM5_USART_INT,
SERCOM: 5,
}
)
// I2C on the Grand Central M4
var (
I2C0 = I2C{
Bus: sam.SERCOM3_I2CM,
SERCOM: 3,
}
I2C1 = I2C{
Bus: sam.SERCOM6_I2CM,
SERCOM: 6,
}
)
// SPI on the Grand Central M4
var (
SPI0 = SPI{
Bus: sam.SERCOM7_SPIM,
SERCOM: 7,
}
SPI1 = SPI{ // SD card
Bus: sam.SERCOM2_SPIM,
SERCOM: 2,
}
)
+22 -14
View File
@@ -136,9 +136,11 @@ const (
)
var (
UART0 = &UART1 // alias UART0 to UART1
UART1 = UART{
Buffer: NewRingBuffer(),
Bus: nxp.LPUART6,
Bus: nxp.LPUART6,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
muxRX: muxSelect{ // D0 (PA3 [AD_B0_03])
mux: nxp.IOMUXC_LPUART6_RX_SELECT_INPUT_DAISY_GPIO_AD_B0_03_ALT2,
sel: &nxp.IOMUXC.LPUART6_RX_SELECT_INPUT,
@@ -149,8 +151,9 @@ var (
},
}
UART2 = UART{
Buffer: NewRingBuffer(),
Bus: nxp.LPUART4,
Bus: nxp.LPUART4,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
muxRX: muxSelect{ // D7 (PB17 [B1_01])
mux: nxp.IOMUXC_LPUART4_RX_SELECT_INPUT_DAISY_GPIO_B1_01_ALT2,
sel: &nxp.IOMUXC.LPUART4_RX_SELECT_INPUT,
@@ -161,8 +164,9 @@ var (
},
}
UART3 = UART{
Buffer: NewRingBuffer(),
Bus: nxp.LPUART2,
Bus: nxp.LPUART2,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
muxRX: muxSelect{ // D15 (PA19 [AD_B1_03])
mux: nxp.IOMUXC_LPUART2_RX_SELECT_INPUT_DAISY_GPIO_AD_B1_03_ALT2,
sel: &nxp.IOMUXC.LPUART2_RX_SELECT_INPUT,
@@ -173,8 +177,9 @@ var (
},
}
UART4 = UART{
Buffer: NewRingBuffer(),
Bus: nxp.LPUART3,
Bus: nxp.LPUART3,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
muxRX: muxSelect{ // D16 (PA23 [AD_B1_07])
mux: nxp.IOMUXC_LPUART3_RX_SELECT_INPUT_DAISY_GPIO_AD_B1_07_ALT2,
sel: &nxp.IOMUXC.LPUART3_RX_SELECT_INPUT,
@@ -185,8 +190,9 @@ var (
},
}
UART5 = UART{
Buffer: NewRingBuffer(),
Bus: nxp.LPUART8,
Bus: nxp.LPUART8,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
muxRX: muxSelect{ // D21 (PA27 [AD_B1_11])
mux: nxp.IOMUXC_LPUART8_RX_SELECT_INPUT_DAISY_GPIO_AD_B1_11_ALT2,
sel: &nxp.IOMUXC.LPUART8_RX_SELECT_INPUT,
@@ -197,15 +203,17 @@ var (
},
}
UART6 = UART{
Buffer: NewRingBuffer(),
Bus: nxp.LPUART1,
Bus: nxp.LPUART1,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
// LPUART1 not connected via IOMUXC
// RX: D24 (PA12 [AD_B0_12])
// TX: D25 (PA13 [AD_B0_13])
}
UART7 = UART{
Buffer: NewRingBuffer(),
Bus: nxp.LPUART7,
Bus: nxp.LPUART7,
Buffer: NewRingBuffer(),
txBuffer: NewRingBuffer(),
muxRX: muxSelect{ // D28 (PC18 [EMC_32])
mux: nxp.IOMUXC_LPUART7_RX_SELECT_INPUT_DAISY_GPIO_EMC_32_ALT2,
sel: &nxp.IOMUXC.LPUART7_RX_SELECT_INPUT,
+6
View File
@@ -114,6 +114,12 @@ func (i2c I2C) readByte() byte {
return byte(avr.TWDR.Get())
}
// UART
var (
// UART0 is the hardware serial port on the AVR.
UART0 = UART{Buffer: NewRingBuffer()}
)
// UART on the AVR.
type UART struct {
Buffer *RingBuffer
+91
View File
@@ -10,6 +10,7 @@ package machine
import (
"device/arm"
"device/sam"
"errors"
"runtime/interrupt"
"runtime/volatile"
"unsafe"
@@ -1469,6 +1470,96 @@ func (spi SPI) Transfer(w byte) (byte, error) {
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
// 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 {
switch {
case w == nil:
// read only, so write zero and read a result.
spi.rx(r)
case r == nil:
// write only
spi.tx(w)
default:
// write/read
if len(w) != len(r) {
return ErrTxInvalidSliceSize
}
spi.txrx(w, r)
}
return nil
}
func (spi SPI) tx(tx []byte) {
for i := 0; i < len(tx); i++ {
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
}
spi.Bus.DATA.Set(uint32(tx[i]))
}
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_TXC) {
}
// read to clear RXC register
for spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_RXC) {
spi.Bus.DATA.Get()
}
}
func (spi SPI) rx(rx []byte) {
spi.Bus.DATA.Set(0)
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
}
for i := 1; i < len(rx); i++ {
spi.Bus.DATA.Set(0)
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_RXC) {
}
rx[i-1] = byte(spi.Bus.DATA.Get())
}
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_RXC) {
}
rx[len(rx)-1] = byte(spi.Bus.DATA.Get())
}
func (spi SPI) txrx(tx, rx []byte) {
spi.Bus.DATA.Set(uint32(tx[0]))
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_DRE) {
}
for i := 1; i < len(rx); i++ {
spi.Bus.DATA.Set(uint32(tx[i]))
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_RXC) {
}
rx[i-1] = byte(spi.Bus.DATA.Get())
}
for !spi.Bus.INTFLAG.HasBits(sam.SERCOM_SPIM_INTFLAG_RXC) {
}
rx[len(rx)-1] = byte(spi.Bus.DATA.Get())
}
// The QSPI peripheral on ATSAMD51 is only available on the following pins
const (
QSPI_SCK = PB10
+70
View File
@@ -0,0 +1,70 @@
// +build sam,atsamd51,atsamd51p20
// Peripheral abstraction layer for the atsamd51.
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
//
package machine
import "device/sam"
const HSRAM_SIZE = 0x00040000
// InitPWM initializes the PWM interface.
func InitPWM() {
// turn on timer clocks used for PWM
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC0_ | sam.MCLK_APBBMASK_TCC1_)
sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC2_ | sam.MCLK_APBCMASK_TCC3_)
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_TCC4_)
//use clock generator 0
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC0].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC2].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_TCC4].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
}
// getTimer returns the timer to be used for PWM on this pin
func (pwm PWM) getTimer() *sam.TCC_Type {
switch pwm.Pin {
case PC18:
return sam.TCC0
case PC19:
return sam.TCC0
case PC20:
return sam.TCC0
case PC21:
return sam.TCC0
case PD20:
return sam.TCC1
case PD21:
return sam.TCC1
case PB18:
return sam.TCC1
case PB12:
return sam.TCC3
case PB13:
return sam.TCC3
case PA15:
return sam.TCC2
case PC17:
return sam.TCC0
case PC16:
return sam.TCC0
case PA14:
return sam.TCC2
case PB15:
return sam.TCC4
case PB14:
return sam.TCC4
case PB20:
return sam.TCC1
case PB21:
return sam.TCC1
default:
return nil // not supported on this pin
}
}
-17
View File
@@ -2,23 +2,6 @@
package machine
// UART on the AVR is a dummy implementation. UART has not been implemented for ATtiny
// devices.
type UART struct {
Buffer *RingBuffer
}
// Configure is a dummy implementation. UART has not been implemented for ATtiny
// devices.
func (uart UART) Configure(config UARTConfig) {
}
// WriteByte is a dummy implementation. UART has not been implemented for ATtiny
// devices.
func (uart UART) WriteByte(c byte) error {
return nil
}
// Tx is a dummy implementation. I2C has not been implemented for ATtiny
// devices.
func (i2c I2C) Tx(addr uint16, w, r []byte) error {
-6
View File
@@ -148,9 +148,3 @@ type I2C struct {
// I2C0 is the only I2C interface on most AVRs.
var I2C0 = I2C{}
// UART
var (
// UART0 is the hardware serial port on the AVR.
UART0 = UART{Buffer: NewRingBuffer()}
)
+4 -2
View File
@@ -174,11 +174,13 @@ func (spi SPI) Transfer(w byte) (byte, error) {
spi.Bus.TXDATA.Set(uint32(w))
// wait until receive has data
for spi.Bus.RXDATA.HasBits(sifive.QSPI_RXDATA_EMPTY) {
data := spi.Bus.RXDATA.Get()
for data&sifive.QSPI_RXDATA_EMPTY > 0 {
data = spi.Bus.RXDATA.Get()
}
// return data
return byte(spi.Bus.RXDATA.Get() & sifive.QSPI_RXDATA_DATA_Msk), nil
return byte(data), nil
}
// I2C on the FE310-G002.
+4 -4
View File
@@ -15,6 +15,10 @@ type UART struct {
Buffer *RingBuffer
Interrupt interrupt.Interrupt
// txBuffer should be allocated globally (such as when UART is created) to
// prevent it being reclaimed or cleaned up prematurely.
txBuffer *RingBuffer
// these hold the input selector ("daisy chain") values that select which pins
// are connected to the LPUART device, and should be defined where the UART
// instance is declared. see the godoc comments on type muxSelect for more
@@ -31,7 +35,6 @@ type UART struct {
configured bool
msbFirst bool
transmitting volatile.Register32
txBuffer *RingBuffer
}
func (uart *UART) isTransmitting() bool { return uart.transmitting.Get() != 0 }
@@ -197,9 +200,6 @@ func (uart *UART) Sync() error {
// WriteByte writes a single byte of data to the UART interface.
func (uart *UART) WriteByte(c byte) error {
if nil == uart.txBuffer {
uart.txBuffer = NewRingBuffer()
}
uart.startTransmitting()
for !uart.txBuffer.Put(c) {
}
+1 -1
View File
@@ -1,4 +1,4 @@
// +build !baremetal sam stm32,!stm32f7x2,!stm32l5x2 fe310 k210 atmega
// +build !baremetal atsamd21 stm32,!stm32f7x2,!stm32l5x2 fe310 k210 atmega
package machine
+1 -1
View File
@@ -1,4 +1,4 @@
// +build avr esp nrf sam sifive stm32 k210 nxp
// +build atmega esp nrf sam sifive stm32 k210 nxp
package machine
+2 -2
View File
@@ -547,8 +547,8 @@ func newUSBSetup(data []byte) usbSetup {
u.bRequest = uint8(data[1])
u.wValueL = uint8(data[2])
u.wValueH = uint8(data[3])
u.wIndex = uint16(data[4]) | uint16(data[5]<<8)
u.wLength = uint16(data[6]) | uint16(data[7]<<8)
u.wIndex = uint16(data[4]) | (uint16(data[5]) << 8)
u.wLength = uint16(data[6]) | (uint16(data[7]) << 8)
return u
}
+2
View File
@@ -0,0 +1,2 @@
// Package debug is a dummy package that is not yet implemented.
package debug
+9
View File
@@ -4,8 +4,17 @@ package runtime
import (
"device/avr"
"machine"
)
func initUART() {
machine.UART0.Configure(machine.UARTConfig{})
}
func putchar(c byte) {
machine.UART0.WriteByte(c)
}
// Sleep for a given period. The period is defined by the WDT peripheral, and is
// on most chips (at least) 3 bits wide, in powers of two from 16ms to 2s
// (0=16ms, 1=32ms, 2=64ms...). Note that the WDT is not very accurate: it can
+53
View File
@@ -0,0 +1,53 @@
// +build sam,atsamd51,atsamd51p20
package runtime
import (
"device/sam"
)
func initSERCOMClocks() {
// Turn on clock to SERCOM0 for UART0
sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM0_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM0_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// sets the "slow" clock shared by all SERCOM
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOMX_SLOW].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM1
sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM1_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM1_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM2
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM2_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM2_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM3
sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM3_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM3_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM4
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM4_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM4_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM5
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM5_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM5_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM6
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM6_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM6_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
// Turn on clock to SERCOM7
sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM7_)
sam.GCLK.PCHCTRL[sam.PCHCTRL_GCLK_SERCOM7_CORE].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
sam.GCLK_PCHCTRL_CHEN)
}
+7
View File
@@ -6,6 +6,13 @@ import (
"device/avr"
)
func initUART() {
}
func putchar(c byte) {
// UART is not supported.
}
func sleepWDT(period uint8) {
// TODO: use the watchdog timer instead of a busy loop.
for i := 0x45; i != 0; i-- {
-9
View File
@@ -4,7 +4,6 @@ package runtime
import (
"device/avr"
"machine"
"unsafe"
)
@@ -59,14 +58,6 @@ func init() {
initUART()
}
func initUART() {
machine.UART0.Configure(machine.UARTConfig{})
}
func putchar(c byte) {
machine.UART0.WriteByte(c)
}
const asyncScheduler = false
const tickNanos = 1024 * 16384 // roughly 16ms in nanoseconds
+1 -1
View File
@@ -12,7 +12,7 @@ type __wasi_iovec_t struct {
bufLen uint
}
//go:wasm-module wasi_unstable
//go:wasm-module wasi_snapshot_preview1
//export fd_write
func fd_write(id uint32, iovs *__wasi_iovec_t, iovs_len uint, nwritten *uint) (errno uint)
+10 -12
View File
@@ -35,7 +35,6 @@ var (
u: __wasi_subscription_u_t{
tag: __wasi_eventtype_t_clock,
u: __wasi_subscription_clock_t{
userData: 0,
id: 0,
timeout: 0,
precision: timePrecisionNanoseconds,
@@ -48,23 +47,23 @@ var (
)
func sleepTicks(d timeUnit) {
sleepTicksSubscription.u.u.timeout = int64(d)
sleepTicksSubscription.u.u.timeout = uint64(d)
poll_oneoff(&sleepTicksSubscription, &sleepTicksResult, 1, &sleepTicksNEvents)
}
func ticks() timeUnit {
var nano int64
var nano uint64
clock_time_get(0, timePrecisionNanoseconds, &nano)
return timeUnit(nano)
}
// Implementations of wasi_unstable APIs
//go:wasm-module wasi_unstable
//go:wasm-module wasi_snapshot_preview1
//export clock_time_get
func clock_time_get(clockid uint32, precision uint64, time *int64) (errno uint16)
func clock_time_get(clockid uint32, precision uint64, time *uint64) (errno uint16)
//go:wasm-module wasi_unstable
//go:wasm-module wasi_snapshot_preview1
//export poll_oneoff
func poll_oneoff(in *__wasi_subscription_t, out *__wasi_event_t, nsubscriptions uint32, nevents *uint32) (errno uint16)
@@ -77,7 +76,7 @@ const (
)
type (
// https://github.com/wasmerio/wasmer/blob/1.0.0-alpha3/lib/wasi/src/syscalls/types.rs#L584-L588
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-subscription-record
__wasi_subscription_t struct {
userData uint64
u __wasi_subscription_u_t
@@ -90,18 +89,17 @@ type (
u __wasi_subscription_clock_t
}
// https://github.com/wasmerio/wasmer/blob/1.0.0-alpha3/lib/wasi/src/syscalls/types.rs#L711-L718
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-subscription_clock-record
__wasi_subscription_clock_t struct {
userData uint64
id uint32
timeout int64
precision int64
timeout uint64
precision uint64
flags uint16
}
)
type (
// https://github.com/wasmerio/wasmer/blob/1.0.0-alpha3/lib/wasi/src/syscalls/types.rs#L191-L198
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#-event-record
__wasi_event_t struct {
userData uint64
errno uint16
-20
View File
@@ -1,20 +0,0 @@
// +build !go1.12
package runtime
import "internal/bytealg"
// The following functions provide compatibility with Go 1.11.
// See the following:
// https://github.com/tinygo-org/tinygo/issues/351
// https://github.com/golang/go/commit/ad4a58e31501bce5de2aad90a620eaecdc1eecb8
//go:linkname indexByte strings.IndexByte
func indexByte(s string, c byte) int {
return bytealg.IndexByteString(s, c)
}
//go:linkname bytesEqual bytes.Equal
func bytesEqual(a, b []byte) bool {
return bytealg.Equal(a, b)
}
+13
View File
@@ -0,0 +1,13 @@
{
"inherits": ["cortex-m4"],
"build-tags": ["sam", "atsamd51", "atsamd51p20", "atsamd51p20a"],
"cflags": [
"-Qunused-arguments"
],
"linkerscript": "targets/atsamd51p20a.ld",
"extra-files": [
"src/device/sam/atsamd51p20a.s"
],
"openocd-transport": "swd",
"openocd-target": "atsame5x"
}
+10
View File
@@ -0,0 +1,10 @@
MEMORY
{
FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00100000-0x4000 /* First 16KB used by bootloader */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00040000
}
_stack_size = 4K;
INCLUDE "targets/arm.ld"
+9
View File
@@ -0,0 +1,9 @@
{
"inherits": ["atsamd51p20a"],
"build-tags": ["grandcentral_m4"],
"flash-1200-bps-reset": "true",
"flash-method": "msd",
"msd-volume-name": "GCM4BOOT",
"msd-firmware-name": "firmware.uf2",
"openocd-interface": "jlink"
}
+2 -2
View File
@@ -247,8 +247,8 @@
const timeOrigin = Date.now() - performance.now();
this.importObject = {
wasi_unstable: {
// https://github.com/bytecodealliance/wasmtime/blob/master/docs/WASI-api.md#__wasi_fd_write
wasi_snapshot_preview1: {
// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write
fd_write: function(fd, iovs_ptr, iovs_len, nwritten_ptr) {
let nwritten = 0;
if (fd == 1) {
+9 -9
View File
@@ -135,7 +135,7 @@ type Bitfield struct {
func formatText(text string) string {
text = regexp.MustCompile(`[ \t\n]+`).ReplaceAllString(text, " ") // Collapse whitespace (like in HTML)
text = strings.Replace(text, "\\n ", "\n", -1)
text = strings.ReplaceAll(text, "\\n ", "\n")
text = strings.TrimSpace(text)
return text
}
@@ -273,9 +273,9 @@ func readSVD(path, sourceURL string) (*Device, error) {
p.Registers = append(p.Registers, parseRegister(regName, register, baseAddress, "")...)
}
for _, cluster := range periphEl.Clusters {
clusterName := strings.Replace(cluster.Name, "[%s]", "", -1)
clusterName := strings.ReplaceAll(cluster.Name, "[%s]", "")
if cluster.DimIndex != nil {
clusterName = strings.Replace(clusterName, "%s", "", -1)
clusterName = strings.ReplaceAll(clusterName, "%s", "")
}
clusterPrefix := clusterName + "_"
clusterOffset, err := strconv.ParseUint(cluster.AddressOffset, 0, 32)
@@ -292,7 +292,7 @@ func readSVD(path, sourceURL string) (*Device, error) {
}
// handle sub-clusters of registers
for _, subClusterEl := range cluster.Clusters {
subclusterName := strings.Replace(subClusterEl.Name, "[%s]", "", -1)
subclusterName := strings.ReplaceAll(subClusterEl.Name, "[%s]", "")
subclusterPrefix := subclusterName + "_"
subclusterOffset, err := strconv.ParseUint(subClusterEl.AddressOffset, 0, 32)
if err != nil {
@@ -414,7 +414,7 @@ func readSVD(path, sourceURL string) (*Device, error) {
// Properly format the license block, with comments.
licenseBlock := ""
if text := formatText(device.LicenseText); text != "" {
licenseBlock = "// " + strings.Replace(text, "\n", "\n// ", -1)
licenseBlock = "// " + strings.ReplaceAll(text, "\n", "\n// ")
licenseBlock = regexp.MustCompile(`\s+\n`).ReplaceAllString(licenseBlock, "\n")
}
@@ -595,7 +595,7 @@ func parseBitfields(groupName, regName string, fieldEls []*SVDField, bitfieldPre
if err != nil {
if enumBitSpecifier.MatchString(enumEl.Value) {
// NXP SVDs use the form #xx1x, #x0xx, etc for values
enumValue, err = strconv.ParseUint(strings.Replace(enumEl.Value[1:], "x", "0", -1), 2, 32)
enumValue, err = strconv.ParseUint(strings.ReplaceAll(enumEl.Value[1:], "x", "0"), 2, 32)
if err != nil {
panic(err)
}
@@ -656,7 +656,7 @@ func NewRegister(element *SVDRegister, baseAddress uint64) *Register {
}
func (r *Register) name() string {
return strings.Replace(r.element.Name, "[%s]", "", -1)
return strings.ReplaceAll(r.element.Name, "[%s]", "")
}
func (r *Register) description() string {
@@ -765,7 +765,7 @@ func parseRegister(groupName string, regEl *SVDRegister, baseAddress uint64, bit
for i, j := range reg.dimIndex() {
regAddress := reg.address() + (uint64(i) * dimIncrement)
results = append(results, &PeripheralField{
Name: strings.ToUpper(strings.Replace(reg.name(), "%s", j, -1)),
Name: strings.ToUpper(strings.ReplaceAll(reg.name(), "%s", j)),
Address: regAddress,
Description: reg.description(),
Array: -1,
@@ -773,7 +773,7 @@ func parseRegister(groupName string, regEl *SVDRegister, baseAddress uint64, bit
})
}
// set first result bitfield
shortName := strings.ToUpper(strings.Replace(strings.Replace(reg.name(), "_%s", "", -1), "%s", "", -1))
shortName := strings.ToUpper(strings.ReplaceAll(strings.ReplaceAll(reg.name(), "_%s", ""), "%s", ""))
results[0].Bitfields = parseBitfields(groupName, shortName, regEl.Fields, bitfieldPrefix)
return results
}