Compare commits

...

229 Commits

Author SHA1 Message Date
Ayke van Laethem 15361c829e main: release 0.16.0 2020-11-17 11:15:15 +01:00
Ayke van Laethem 3f680b75f3 sam: remove redundant build tags
Some build tags were duplicated. This commit removes them.
2020-11-15 16:19:51 +01:00
Ayke van Laethem 9a7e633997 teensy36: add to smoketest
This required some changes to the UART code to get it to compile on Go
1.11.
2020-11-15 13:08:36 +01:00
ardnew 39b1f8b6f5 teensy40: UART: add missing godocs, rename Flush to Sync 2020-11-15 12:34:15 +01:00
ardnew 9aa50853b8 teensy40: add UART support 2020-11-15 12:34:15 +01:00
Ayke van Laethem 9ca0e3f2d1 Makefile: fix issue with Go 1.15.5
For details, see https://github.com/golang/go/issues/42606
2020-11-14 15:04:11 +01:00
ardnew 3cdc110462 teensy40: use implicit const defs (PinMode/PinChange) 2020-11-13 07:53:16 +01:00
ardnew 7cc687d416 teensy40: Add GPIO external interrupt support 2020-11-13 07:53:16 +01:00
Ron Evans ce57a034c3 ci: update CircleCI, Azure, and Docker builds to Go 1.15
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-11-13 03:07:35 +01:00
ardnew 30bee3afef add better fault identification for Cortex-M3/M33/M4/M7 hardfault handlers, add fault description registers to SCB_Type 2020-11-11 18:34:47 +01:00
ardnew b1d24a72c1 teensy40: fix typo in target JSON 2020-11-11 18:34:47 +01:00
ardnew 6e24c86320 teensy40: remove FPU spec in target JSON list of cflags 2020-11-11 18:34:47 +01:00
ardnew 19a0270303 teensy40: refactor to remove unnecessary code and constants 2020-11-11 18:34:47 +01:00
ardnew 47410a4b54 teensy40: init RTC and use ARM cycle counter for improved SysTick accuracy 2020-11-11 18:34:47 +01:00
ardnew 0d9c46b59e teensy40: fix PIT clock, which actually uses 24 MHz OSC
see: https://forum.pjrc.com/threads/63979-What-peripherals-are-affected-by-the-undocumented-24-MHz-OSC-circuit-on-Teensy-4-0
2020-11-11 18:34:47 +01:00
ardnew f93b28057a mimxrt1062: move device-specific files to "device/nxp" package 2020-11-11 18:34:47 +01:00
ardnew 691185f5f4 teensy40: initial implementation 2020-11-11 18:34:47 +01:00
Ayke van Laethem 163df7670a main: update go-llvm to fix LLVM build tags for Linux
This should make TinyGo buildable again on Darwin with a Homebrew
installed LLVM.
2020-11-09 18:45:37 +01:00
deadprogram 77c70d2758 machine/qtpy: add board definition for Adafruit QTPy
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-11-08 22:56:01 +01:00
Ayke van Laethem 7c4e83f5c0 machine: clarify caller's responsibility in SetInterrupt 2020-11-08 15:11:50 +01:00
jypelle db27541b1a Fix #1483 2020-11-08 09:32:13 +01:00
tom-horn 3bb994da9f Allow interrupts in stm32f103xx (#1466)
machine/stm32f103xx: allow interrupts in stm32f103xx
2020-11-07 12:21:38 +01:00
Elliott Sales de Andrade b3bd891ee0 Make lib64 clang include path check more robust.
On Fedora 33+, there is a buggy package that installs to
`/usr/lib64/clang/{version}/lib`, even on 32-bit systems. The original
code sees the `/usr/lib64/clang/{version}` directory, checks for an
`include` subdirectory, and then gives up because it doesn't exist.

To be more robust, check both `/usr/lib64/clang/{version}/include` and
`/usr/lib/clang/{version}/include`, and only allow versions that match
the LLVM major version used to build tinygo.
2020-11-04 00:04:33 +01:00
Lucas Teske 387bca8e32 nintendoswitch: Add env parser and removed unused stuff
*	Heap allocation based on available ram
*	Added homebrew launcher parser (for overriden heap)
*	Removed unused stuff (moved to gonx)
*	Kept require code at minimum to work in a real device
*	Moved everything to a single file
2020-11-03 23:28:55 +01:00
Nia Weiss d424b3d7ea add missing return pointer restore for regular coroutine tail calls
This fixes an issue where a normal suspending call followed by a plain tail call would result in the tail return value being written to the return pointer of the normal suspending call.
This is fixed by saving the return pointer at the start of the function and restoring it before initiating a plain tail call.
2020-11-01 08:32:55 +01:00
deadprogram c20328472b make: fixes error detecting llvm-nm tool for wasi-libc build
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-11-01 01:12:39 +01:00
Ayke van Laethem 171f793c1e avr: properly support the .rodata section
Unfortunately, the .rodata section can't be stored in flash. Instead, an
explicit .progmem section should be used, which is supported in LLVM as
address space 1 but not exposed to normal programs.

Eventually a pass should be written that converts trivial const globals
of which all loads are visible to be in addrspace 1, to get the benefits
of storing those globals directly in ROM.
2020-10-31 21:06:26 +01:00
Nia Weiss 3364da6f25 improve autodetection of LLVM tooling
Previously, our autodetection would fail on LLVM 11.
This now checks all common names for LLVM 10 and 11.
2020-10-31 18:17:38 +01:00
Ayke van Laethem e99b8a24fe runtime: allow ranging over a nil map
This appears to be allowed by the specification, at least it is allowed
by the main Go implementation: https://play.golang.org/p/S8jxAMytKDB

Allow it in TinyGo too, for consistency.

Found because it is triggered with `tinygo test flags`. This doesn't
make the flags package pass all tests, but is a step closer.
2020-10-29 21:53:41 +01:00
Ayke van Laethem 69e1aa4878 testing: add Run method
This patch adds subtests via the Run function. This gets two more
packages to pass tests: encoding/base32 and hash/fnv.
2020-10-28 18:25:56 +01:00
Ayke van Laethem 7a78b2dc0e all: replace underscores with dashes in target names
This is the convention, so use it everywhere.
2020-10-28 12:40:54 +01:00
Ayke van Laethem 2b1d4ce96e main: update go.sum 2020-10-28 08:48:11 +01:00
Ayke van Laethem 3e40b08ba0 compiler: implement negate for complex numbers 2020-10-28 07:38:51 +01:00
Takeshi Yoneda ffeff55706 wasm: use the fixed length buffer for putchar
Signed-off-by: mathetake <takeshi@tetrate.io>
2020-10-23 22:04:32 +02:00
Takeshi Yoneda 1dec9dcbc4 implement reflect.Swapper
Signed-off-by: mathetake <takeshi@tetrate.io>
2020-10-23 21:37:35 +02:00
Martin Tournoij ff833ef998 Add os.LookupEnv() stub
os.Getenv() was already stubbed out, but os.LookupEnv() wasn't. This
will allow me to compile my program unmodified without using separate
files and build tags.
2020-10-23 14:39:15 +02:00
Connor 6eeebfeb5c WIP: Esp8266 Get Function (#1438)
machine/esp8266: add Pin Get() support
2020-10-22 20:58:44 +02:00
Ayke van Laethem 6ab0106af3 nrf: fix nrf52832 flash size
I've accidentally specified just half of the available flash in the
linker script. This change fixes that.

There is in fact a 256kB version of the nrf52832, but it also has 32kB
of RAM so if you had used that it wouldn't actually work right now.
Also, extending the available flash should not affect existing programs
(as I haven't seen any run into size limitations yet).
2020-10-20 19:13:43 +02:00
蒼時弦也 e690ff0d8c Add instanceof support for WebAssembly 2020-10-18 22:15:47 +02:00
Ayke van Laethem 06564cbdb2 Switch default frequency to 4MHz
Let's use the same default frequency everywhere, for consistency.
It could be any frequency, but 4MHz is already used for other chips and
it seems like a reasonable frequency to me (not too fast for most chips
but still reasonably fast). Oh, and 4MHz is slow enough that it can be
inspected by a Saleae Logic 4 (that sadly has been discontinued).
2020-10-18 22:14:21 +02:00
Ayke van Laethem 47dc76fc34 nrf: give more flexibility in picking SPI speeds
Instead of only allowing a limited number of speeds, use the provided
speed as an upper bound on the allowed speed. The reasoning is that
picking a higher speed than requrested will likely result in malfunction
while picking a lower speed will usually only result in slower
operation.
This behavior matches the ESP32 at least.
2020-10-18 22:11:03 +02:00
deadprogram d382f3a259 esp8266: add target for d1mini board and add pin mappings for SPI/I2C to help out implementers
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-10-17 19:57:53 +02:00
Ayke van Laethem 47dc1087e8 ci: work around bug in Go 1.15.3
This works around a bug in Go 1.15.3 by pinning an older version.
See: https://github.com/golang/go/issues/42032
2020-10-17 12:23:03 +02:00
deadprogram c7d8223ab7 machine/esp32, targets/esp32: correct board definitions for actual boards not processor variants, also define all labeled pins
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-10-14 21:48:48 +02:00
ardnew 3eb33dff5d feather-stm32f405: add I2C support (#1378)
* machine/stm32f405: add initial I2C support
2020-10-14 18:00:24 +02:00
deadprogram bb146edb47 wasi: remove --no-threads flag as no longer in LLVM 11 linker
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-10-14 13:58:01 +02:00
Nia Weiss ed9b97cc0d runtime: add cheap atomic condition variable 2020-10-14 13:35:00 +02:00
Ayke van Laethem b40f250530 main: add initial support for (in-development) LLVM 11
This can be useful to test improvements in LLVM master and to make it
possible to support LLVM 11 for the most part already before the next
release. That also allows catching LLVM bugs early to fix them upstream.

Note that tests do not yet pass for this LLVM version, but the TinyGo
compiler can be built with the binaries from apt.llvm.org (at the time
of making this commit).
2020-10-13 20:23:50 +02:00
ardnew 184175378f gen-device-svd: ensure enum bitfields are unique 2020-10-10 12:52:11 +02:00
Ayke van Laethem d8dbe5748a testing: implement some benchmark stubs
This allows the following packages to pass tests:

  * crypto/des
  * encoding/hex

I have not included crypto/rc4 as it doesn't pass tests on Go 1.11 (but
it works on later versions).
2020-10-09 15:22:19 +02:00
Lucas Teske c2bfe6bc8d arm64: Add support for system calls (SVC) 2020-10-03 20:07:51 +02:00
Takeshi Yoneda 9a015f4f64 add wasm-abi field in TargetSpec && set generic for WASI by default (#1421)
Signed-off-by: mathetake <takeshi@tetrate.io>
2020-10-03 19:52:01 +02:00
ardnew 9ad2315079 feather-stm32f405: add SPI support (#1377)
* machine/stm32f405: add SPI support
2020-10-02 20:05:58 +02:00
Ayke van Laethem 431e51b8a0 runtime: use dedicated printfloat32
It can be unexpected that printing a float32 involves 64-bit floating
point routines, see for example:
https://github.com/tinygo-org/tinygo/issues/1415

This commit adds a dedicated printfloat32 instead just for printing
float32 values. It comes with a possible code size increase, but only if
both float32 and float64 values are printed. Therefore, this should be
an improvement in almost all cases.

I also tried using printfloat32 for everything (and casting a float64 to
float32 to print) but the printed values are slightly different,
breaking the testdata/math.go test for example.
2020-10-02 11:26:22 +02:00
Ayke van Laethem 67de8b490d gc: use raw stack access whenever possible
The only architecture that actually needs special support for scanning
the stack is WebAssembly. All others allow raw access to the stack with
a small bit of assembly. Therefore, don't manually keep track of all
these objects on the stack manually and instead just use conservative
stack scanning.

This results in a massive code size decrease in the affected targets
(only tested linux/amd64 for code size) - sometimes around 33%. It also
allows for future improvements such as using proper stackful goroutines.
2020-10-02 08:54:43 +02:00
Ayke van Laethem bfa29f17da runtime: move/refactor some GC-related code
Instead of putting tinygo_scanCurrentStack in scheduler_*.S files, put
them in dedicated files. The function tinygo_scanCurrentStack has
nothing to do with scheduling and so doesn't belong there. Additionally,
while scheduling code is made specific for the Cortex-M, the
tinygo_scanCurrentStack is generic to all ARM targets so this move
removes some duplication there.

Specifically:

  * tinygo_scanCurrentStack is moved out of scheduler_cortexm.S as it
    isn't really part of the scheduler. It is now gc_arm.S.
  * Same for the AVR target.
  * Same for the RISCV target.
  * scheduler_gba.S is removed, using gc_arm.S instead as it only
    contains tinygo_scanCurrentStack.
2020-10-02 08:54:43 +02:00
Ayke van Laethem 7123941df0 main: add support for debugging qemu-user targets
This commit allows debugging like the following:

    GOARCH=arm tinygo gdb ./testdata/alias.go

This can be very useful to debug issues on a different instruction set
architecture but still on a host system.

I tested the following 7 configurations to make sure it works and I
didn't break anything:

    GOOS=amd64
    GOOS=386
    GOOS=arm
    GOOS=arm64
    tinygo gdb -target=hifive1-qemu
    tinygo gdb -target=cortex-m-qemu
    tinygo gdb -target=microbit
2020-10-02 08:54:43 +02:00
Ayke van Laethem 05d2f2c412 main: improve support for x86-32 and add tests
To avoid breaking this, make sure we actually test x86-32 (aka i386 aka
GOARCH=386) support in CI.

Also remove the now-unnecessary binutils-arm-none-eabi package to speed
up CI a bit.
2020-10-02 08:54:43 +02:00
Ayke van Laethem 9a12d129ab testing: implement dummy Helper method
This lets a few more packages pass tests: container/heap and
encoding/ascii85.
2020-10-01 02:14:59 +02:00
Ayke van Laethem 0ecfe9eade ci: fix make wasmtest
This fixes issue https://github.com/tinygo-org/tinygo/issues/1418. In
short, it appears there was a race condition that was only visible on
GOARCH=386 but not on GOARCH=amd64. Updating to a more recent chromedp
version fixes the issue.
2020-10-01 02:07:00 +02:00
Takeshi Yoneda f50ad3585d support WASI target (#1373)
* initial commit for WASI support

* merge "time" package with wasi build tag
* override syscall package with wasi build tag
* create runtime_wasm_{js,wasi}.go files
* create syscall_wasi.go file
* create time/zoneinfo_wasi.go file as the replacement of zoneinfo_js.go
* add targets/wasi.json target

* set visbility hidden for runtime extern variables

Accodring to the WASI docs (https://github.com/WebAssembly/WASI/blob/master/design/application-abi.md#current-unstable-abi),
none of exports of WASI executable(Command) should no be accessed.

v0.19.0 of bytecodealliance/wasmetime, which is often refered to as the reference implementation of WASI,
does not accept any exports except functions and the only limited variables like "table", "memory".

* merge syscall_{baremetal,wasi}.go

* fix js target build

* mv wasi functions to syscall/wasi && implement sleepTicks

* WASI: set visibility hidden for globals variables

* mv back syscall/wasi/* to runtime package

* WASI: add test

* unexport wasi types

* WASI test: fix wasmtime path

* stop changing visibility of runtime.alloc

* use GOOS=linux, GOARCH=arm for wasi target

Signed-off-by: mathetake <takeshi@tetrate.io>

* WASI: fix build tags for os/runtime packages

Signed-off-by: mathetake <takeshi@tetrate.io>

* run WASI test only on Linux

Signed-off-by: mathetake <takeshi@tetrate.io>

* set InternalLinkage instead of changing visibility

Signed-off-by: mathetake <takeshi@tetrate.io>
2020-09-29 21:58:03 +02:00
Ayke van Laethem d39c7abb4d nrf: fix double stop signal in I2C 2020-09-27 15:21:54 +02:00
Daniel M. Lambea 9e61e6fe4d nrf: add I2C error checking (#1392)
* machine/nrf: add I2C error checking
2020-09-26 09:20:43 +02:00
Lucas Teske d1f90ef59c nintendoswitch: fix crash when printing long lines (> 120) 2020-09-26 02:52:10 +02:00
Ayke van Laethem 54602fe0c3 main: add support for -c and -o flags to tinygo test 2020-09-25 16:18:10 +02:00
Ayke van Laethem c10dcd429c main: refactor -o flag 2020-09-25 16:18:10 +02:00
Ayke van Laethem b713001313 test: support non-host tests
For example, for running tests with -target=wasm or
-target=cortex-m-qemu. It looks at the output to determine whether tests
were successful in the absence of a status code.
2020-09-24 21:17:26 +02:00
Ayke van Laethem 1096596b69 compiler: fix floating point bugs
There were a few bugs related to floating point. After fixing these, the
math package started passing all tests.
2020-09-21 10:43:46 +02:00
Ayke van Laethem 7b601b3e3c loader: fix linkname in test binaries
This is an issue in particular in the math package, of which most
functions are defined in the runtime package.
2020-09-21 10:43:46 +02:00
Ayke van Laethem ec54e7763d runtime: fix UTF-8 decoding
The algorithm now checks for invalid UTF-8 sequences, which is required
by the Go spec.

This gets the tests of the unicode/utf8 package to pass.

Also add bytes.Equal for Go 1.11, which again is necessary for the
unicode/utf8 package.
2020-09-21 08:49:13 +02:00
Elliott Sales de Andrade 41afb77080 builder: also check lib64 for clang include path.
On 64-bit Fedora, `lib64` is where the clang headers are, not `lib`. For
multiarch systems, both will exist, but it's likely you want 64-bit, so
check that first.
2020-09-20 14:00:02 +02:00
Jacques Supcik 13fe668929 compileopts: simplify copyProperties using reflection 2020-09-20 13:49:16 +02:00
sago35 2a72262c33 version: update TinyGo version to 0.16.0-dev 2020-09-18 01:32:31 +02:00
deadprogram e8615d1007 Prepare for 0.15.0 release
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-09-17 11:48:55 +02:00
sago35 9245337ecf atsamd2x: fix BAUD value 2020-09-17 09:46:15 +02:00
sago35 8170f59440 atsamd5x: fix BAUD value 2020-09-17 09:46:15 +02:00
Lucas Teske 622de53854 nintendoswitch: simplified assembly code 2020-09-17 07:46:29 +02:00
Lucas Teske 6cd9e3c348 arm64: make dynamic loader structs and constants private 2020-09-17 07:46:29 +02:00
Lucas Teske 33e2411b6a nintendoswitch: fix import cycle on dynamic_arm64.go 2020-09-17 07:46:29 +02:00
Lucas Teske fb1fc267ab nintendoswitch: Add dynamic loader for runtime loading PIE sections 2020-09-17 07:46:29 +02:00
Olivier Fauchon 490e377bba bluepill: Enable stm32's USART2 for the board and map it to UART1 tinygo's device 2020-09-17 06:26:57 +02:00
Ayke van Laethem fcedf0beaa stacksize: deal with DW_CFA_advance_loc1
In some cases this operation is emitted. It appears to be emitted when a
switch is lowered to a jump table in the ARM backend.
2020-09-16 05:06:34 +02:00
Ayke van Laethem 4dadb31e18 microbit: reelboard: flash using OpenOCD when needed
When using a SoftDevice, the MSD flash method is not appropriate as it
will erase the entire flash area before writing the new firmware. This
also wipes the SoftDevice. Instead, use OpenOCD to only rewrite the
parts of flash that need to be rewritten and leave the SoftDevice alone.
2020-09-15 17:07:40 +02:00
Ayke van Laethem 5b81b835ba esp32: add SPI support 2020-09-14 12:24:46 +02:00
ardnew a9a6d0ee63 add basic UART handler 2020-09-14 08:48:01 +02:00
Ayke van Laethem 19d5e05e37 esp32: configure the I/O matrix for GPIO pins
Only some pins (notably including GPIO2 aka machine.LED) have GPIO for
the default function 1. Other pins (such as GPIO 15) had a different
function by default. Function 3 means GPIO for all the pins, so always
use that when configuring a pin to use as a GPIO pin.

In the future, the mux configuration will need to be updated for other
functions such as SPI, I2C, etc.
2020-09-13 11:24:33 +02:00
Ayke van Laethem 9e599bac49 nintendoswitch: support outputting .nro files directly
By modifying the linker script a bit and adding the NRO0 header directly
in the assembly, it's possible to craft an ELF file that can be
converted straight to a binary (using objcopy or similar) that is a NRO
file. This avoids custom code for NRO files or an extra build step.

With another change, .nro files are recognized by TinyGo so that this
will create a ready-to-run NRO file:

    tinygo build -o test.nro -target=nintendoswitch examples/serial
2020-09-12 18:37:58 +02:00
Nia Weiss 81e325205f update my name in the contributors list 2020-09-12 16:51:47 +02:00
deadprogram 71cbb1495e docs: add ESP32, ESP8266, and Adafruit Feather STM32F405 to list of supported boards
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-09-11 09:36:19 +02:00
ardnew efc824a103 change default flash method to DFU (using dfu-util over USB) 2020-09-11 09:09:02 +02:00
ardnew cb4f3f12e6 replace flash method with openocd, disable automatic stack sizing 2020-09-11 09:09:02 +02:00
ardnew d1b470f04e remove UART/SPI vars until peripherals implemented 2020-09-11 09:09:02 +02:00
ardnew 7aaa9e45a6 add pin/bus doc comments, I2C pins 2020-09-11 09:09:02 +02:00
ardnew 5c9930df3f move clock settings docs comment to respective const definitions 2020-09-11 09:09:02 +02:00
ardnew cf6b544cd9 remove (or stub) UART/SPI/I2C peripheral code from initial feather-stm32f405 board support 2020-09-11 09:09:02 +02:00
ardnew 097f628955 add feather-stm32f405 smoketest target 2020-09-11 09:09:02 +02:00
ardnew 20a1c730a1 add STM32F405 machine/runtime, and new board/target feather-stm32f405 2020-09-11 09:09:02 +02:00
jreamy 04f65f1189 Adding support for the Arduino Zero (#1365)
* machine/arduino-zero: adding support for Arduino Zero

Co-authored-by: Ayke
Co-authored-by: Jack Reamy
2020-09-10 10:32:12 +02:00
Ayke van Laethem 2ce17a1892 esp8266: add support for this chip
Many thanks to cnlohr for the nosdk8266 project:
    https://github.com/cnlohr/nosdk8266
2020-09-09 19:17:11 +02:00
Lucas Teske 0b9b293651 nintendoswitch: Fix invalid memory read / write in print calls 2020-09-09 18:51:00 +02:00
Ayke van Laethem f20c932bb9 nrf52840: use higher priority for USB-CDC code
This ensures that stdout (println etc) keeps working in interrupts.

Generally you shouldn't print anything in an interrupt. However,
printing things for debugging is very useful and printing panic messages
can be critical when the code doesn't work for some reason.
2020-09-09 17:15:50 +02:00
Ayke van Laethem e7227df80d main: implement tinygo targets to list usable targets
This patch adds the `tinygo targets` command, which lists usable
targets (targets that can be used in the `-target` flag).

The assumption here is that usable targets can either be flashed or
emulated by TinyGo. There is one exception where it doesn't work yet:
the nintendoswitch target. Right now it requires some manual steps to
build a .nro file which can then be run by yuzu, hence why it doesn't
show up in the list.
2020-09-09 13:05:14 +02:00
Ayke van Laethem b99175a436 avr: configure emulator in board files
Instead of specifying the emulator command in atmega328p.json, specify
it in the two boards based on it (arduino and arduino-nano). This makes
the configuration consistent with the machine package, which only
defines the CPUFrequency function in the board files (and not in
machine_atmega328p.json).
2020-09-09 13:05:14 +02:00
Ayke van Laethem de3ffe0af7 main: add cached GOROOT to info subcommand
This is necessary for an upcoming VS Code extension to support TinyGo,
and may be useful for other people wanting to use proper autocompletion
etc in their IDE.
2020-09-07 13:07:17 +02:00
sago35 1e47d9efac docker: fix the problem with the wasm build (#1357)
* docker: fix the problem with the wasm build
2020-09-06 10:22:47 +02:00
Ayke van Laethem 8a2e7bac04 esp32: add libgcc ROM functions to linker script
They are copied from ESP-IDF. They are always available (burned in the
mask ROM) so best to use them.
2020-09-05 10:41:35 +02:00
sago35 ae13db917f ci: set git-fetch-depth to 1 2020-09-05 10:41:04 +02:00
Ayke van Laethem 98dbbbfda6 esp32: export machine.PortMask* for bitbanging implementations
This is useful for some drivers, in particular for the WS2812 driver.
2020-09-05 09:23:31 +02:00
Ayke van Laethem 475135f546 ci: run tinygo test for known-working packages
These packages are known to pass tests with `tinygo test`. It's still a
very short list, but hopefully this list can be expanded to eventually
cover most or all of the standard library.
2020-09-04 14:10:48 +02:00
Ayke van Laethem 88fd2823df all: run test binaries in the correct directory
Test binaries must be run in the source directory of the package to be
tested. This wasn't done, leading to a few "file not found" errors.

This commit implements this. Unfortunately, it does not allow more
packages to be tested as both affected packages (debug/macho and
debug/plan9obj) will still fail with this patch even though the "file
not found" errors are gone.
2020-09-04 12:21:19 +02:00
Ayke van Laethem 57a5b833b2 Makefile: check whether submodules have been downloaded in some common cases
This should help new people making this very common mistake.
2020-09-04 12:07:00 +02:00
Ayke van Laethem c810628a20 loader: rewrite/refactor much of the code to use go list directly
There were a few problems with the go/packages package. While it is more
or less designed for our purpose, it didn't work quite well as it didn't
provide access to indirectly imported packages (most importantly the
runtime package). This led to a workaround that sometimes broke
`tinygo test`.

This PR contains a number of related changes:

  * It uses `go list` directly to retrieve the list of packages/files to
    compile, instead of relying on the go/packages package.
  * It replaces our custom TestMain replace code with the standard code
    for running tests (generated by `go list`).
  * It adds a dummy runtime/pprof package and modifies the testing
    package, to get tests to run again with the code generated by
    `go list`.
2020-09-03 22:10:14 +02:00
Ayke van Laethem 51238fba50 arduino-mega2560: fix flashing on Windows
Without the extra `:i` at the end, avrdude will misinterpret the colon
in Windows paths.
2020-09-03 06:24:18 +02:00
ardnew 7f829fe153 machine/stm32f4: refactor common code and add new build tag stm32f4 (#1332)
* machine/STM32F4: break out STM32F4 machine with new build tag
2020-09-01 11:31:41 +02:00
sago35 946184b8ba flash: call PortReset only on other than openocd 2020-08-31 20:01:22 +02:00
Ayke van Laethem 753162f4e0 esp32: add support for basic GPIO
GPIO is much more advanced on the ESP32, but this is a starting point.
It gets examples/blinky1 to work.
2020-08-31 16:43:31 +02:00
Johan Brandhorst 0e6d2af028 Fix arch release job
Instead of using su, which is blocking, set the
user explicitly for each command.
2020-08-31 14:15:05 +02:00
Ayke van Laethem 0df4a7a35f esp32: support flashing directly from tinygo
Right now this requires setting the -port parameter, but other than that
it totally works (if esptool.py is installed). It works by converting
the ELF file to the custom ESP32 image format and flashing that using
esptool.py.
2020-08-31 13:59:32 +02:00
Ayke van Laethem 9a17698d6a compileopts: add support for custom binary formats
Some chips (like the ESP family) have a particular image format that is
more complex than simply dumping everything in a raw image.
2020-08-31 13:59:32 +02:00
Ayke van Laethem 3ee47a9c1b esp: add support for the Espressif ESP32 chip
This is only very minimal support. More support (such as tinygo flash,
or peripheral access) should be added in later commits, to keep this one
focused.

Importantly, this commit changes the LLVM repo from llvm/llvm-project to
tinygo-org/llvm-project. This provides a little bit of versioning in
case something changes in the Espressif fork. If we want to upgrade to
LLVM 11 it's easy to switch back to llvm/llvm-project until Espressif
has updated their fork.
2020-08-31 09:02:23 +02:00
Ayke van Laethem da7db81087 cortexm: fix stack size calculation with interrupts
Interrupts store 32 bytes on the current stack, which may be a goroutine
stack. After that the interrupt switches to the main stack pointer so
nothing more is pushed to the current stack. However, these 32 bytes
were not included in the stack size calculation.

This commit adds those 32 bytes. The code is rather verbose, but that is
intentional to make sure it is readable. This is tricky code that's hard
to get right, so I'd rather keep it well documented.
2020-08-30 18:23:20 +02:00
Ayke van Laethem 098fb5f39c nrf52840: add build tags for SoftDevice support
The SoftDevice should already be installed on these chips. Adding the
right build tags makes them work with the bluetooth package.

I did not change the HasLowFrequencyCrystal property: all these boards
use the MDBT50Q which appears to include a low-frequency oscillator.
That is, I tested the ItsyBitsy nRF52840 with the property set to true
and advertisement worked just fine.
2020-08-30 16:16:31 +02:00
Ayke van Laethem 47a975a44f nrf: add SoftDevice support for the Circuit Playground Bluefruit
This also fixes a bug: the Bluefruit doesn't have a low frequency
crystal. Somehow non-SoftDevice code still worked. However, the
SoftDevice won't initialize when this flag is set incorrectly.
2020-08-30 16:16:31 +02:00
deadprogram 83252448b0 device/atsamd51x: add all remaining bitfield values for PCHCTRLm Mapping
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-30 09:27:17 +02:00
deadprogram 222977a642 runtime/atsamd51x: use PCHCTRL_GCLK_SERCOMX_SLOW for setting clocks on all SERCOM ports
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-30 09:27:17 +02:00
deadprogram 58565fa46d machine/atsamd51x,runtime/atsamd51x: fixes needed for full support for all PWM pins. Also adds some useful constants to clarify peripheral clock usage
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-30 09:27:17 +02:00
Ayke van Laethem ecaf9461ce loader: be more robust when creating the cached GOROOT
This commit fixes two issues:

  * Do not try to create the cached GOROOT multiple times in parallel.
    This may happen in tests and is a waste of resources (and thus
    speed).
  * Check for an "access denied" error when trying to rename a directory
    over an existing directory. On *nix systems, this results in the
    expected "file exists" error. Unfortunately, Windows gives an access
    denied. This commit fixes the Windows behavior.
2020-08-29 00:02:55 +02:00
sago35 ae01904ab0 flash: add openocd settings to nrf5 2020-08-28 14:54:53 +02:00
Ayke van Laethem 2194d447e9 loader: use ioutil.TempDir to create a temporary directory
... instead of generating one with math/rand. The problem was that
math/rand is deterministic across runs, resulting in a possible race
when trying to create the same directory between two processes.
Additionally, because I used `os.MkdirAll`, no error was reported when
the directory already existed. The solution to this is to use the stdlib
function designed for this: ioutil.TempDir.
2020-08-28 14:48:37 +02:00
Ayke van Laethem a21a039ac7 arm: automatically determine stack sizes
This is a big change that will determine the stack size for many
goroutines automatically. Functions that aren't recursive and don't call
function pointers can in many cases have an automatically determined
worst case stack size. This is useful, as the stack size is usually much
lower than the previous hardcoded default of 1024 bytes: somewhere
around 200-500 bytes is common.

A side effect of this change is that the default stack sizes (including
the stack size for other architectures such as AVR) can now be changed
in the config JSON file, making it tunable per application.
2020-08-27 19:23:22 +02:00
Ayke van Laethem a761f556ff compiler: improve display of goroutine wrappers
This commit stores the original name of functions in metadata so it can
be recovered when printing goroutine names. This removes the .L prefix.
2020-08-27 19:23:22 +02:00
Ron Evans 29d65cb637 machine/itsybitsy-nrf52840: add support for Adafruit Itsybitsy nrf52840 (#1243)
* machine/itsybitsy-nrf52840: add support for Adafruit Itsybitsy nrf52840 Express board
2020-08-25 19:16:42 +02:00
Ayke van Laethem 63005622ae wasm: update wasi-libc dependency
Several updates are necessary for LLVM 11 support, so simply update to
the latest commit.
2020-08-25 18:42:42 +02:00
Ayke van Laethem 510f145a3a interp: show error line in first line of the traceback 2020-08-25 17:34:32 +02:00
sago35 e5e324f93e main: embed git-hash in tinygo-dev executable 2020-08-25 16:23:16 +02:00
Ayke van Laethem 4fa1fc6e72 interp: don't panic in the Store method
Instead return an error, which indicates where it goes wrong. That's
less user unfriendly than panicking.
2020-08-25 16:16:35 +02:00
Ayke van Laethem ccb803e35d interp: replace some panics with error messages
A number of functions now return errors instead of panicking, which
should help greatly when investigating interp errors. It at least shows
the package responsible for it.
2020-08-25 16:16:35 +02:00
sago35 d1ac0138e6 main: use ToSlash() to specify program path 2020-08-25 14:25:49 +02:00
sago35 b132b5bc60 flash: add openocd settings to atsamd21 / atsamd51 2020-08-25 14:18:01 +02:00
deadprogram 743254d5bc main: use simpler file copy instead of file renaming to avoid issues on nrf52840 UF2 bootloaders
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-25 13:51:15 +02:00
Ayke van Laethem 9d625a1ccb nrf: call sd_app_evt_wait when the SoftDevice is enabled
This reduces current consumption from 500-1000µA to very low (<10µA)
current consumption. This change is important for battery powered
devices, especially devices that may be running for long periods of
time.
2020-08-24 22:46:21 +02:00
Ayke van Laethem b75f042c23 runtime: use waitForEvents when appropriate
This is better than using the wfe or wfi instruction directly as it can
be replaced with build tags.
2020-08-24 22:46:21 +02:00
Elliott Sales de Andrade 32c7f3baf9 Remove --no-threads from wasm-ld calls.
The bugs linked from the original addition of this flag are fixed:
https://bugs.llvm.org/show_bug.cgi?id=41508
or 'possibly fixed':
https://bugs.llvm.org/show_bug.cgi?id=37064#c8
since LLVM 8.0.1. TinyGo only support LLVM 9+, and as noted in the
original PR (#377), this can be removed when switching to 9.

Additionally, this flag was dropped from LLVM 11.
2020-08-24 12:04:47 +02:00
deadprogram 1dc85ded47 version: update TinyGo version to 0.15.0-dev
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-24 12:04:47 +02:00
deadprogram 26a0819119 main: release 0.14.1
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-19 08:37:16 +02:00
Ayke van Laethem b59a46eef0 loader: work around Windows symlink limitation
Currently there will be a problem if the TinyGo installation directory
is not the same filesystem as the cache directory (usually the C drive)
and Developer Mode is disabled. Therefore, let's add another fallback
for when both conditions are true, falling back to copying the file
instead of symlinking/hardlinking it.
2020-08-19 08:37:16 +02:00
deadprogram 8a410b993b make,builder: incorporate feedback from code review on Go 1.15 update
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-19 08:37:16 +02:00
deadprogram e412a63a1c make: use buildmode flag to set exe for windows to use standard linker
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-19 08:37:16 +02:00
deadprogram a81face618 builder: simplify Go version check message
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-19 08:37:16 +02:00
deadprogram 0ac216b093 build: use Golang 1.15 for MS Azure builds
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-19 08:37:16 +02:00
deadprogram 9575fe628f internal/bytealg: naive attempt to copy the main Go 1.15 implementatation
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-19 08:37:16 +02:00
deadprogram f4e8ea0d23 builder: allow Go 1.15 to pass config check
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-19 08:37:16 +02:00
deadprogram 2d03f65d67 build: add Go 1.15 to CircleCI build 2020-08-19 08:37:16 +02:00
Ayke van Laethem 154d4a781f main: release 0.14.0 2020-08-03 12:46:32 +02:00
deadprogram b5ab114514 dockerhub: use post checkout hook for git submodule init
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-08-03 08:30:31 +02:00
BCG 0a7e74045a feather-nrf52840: corrected USB identifier constants 2020-08-01 10:55:33 +02:00
Ayke van Laethem f05b378b89 compiler: add proper parameter names to runtime.initAll
This is required by the coroutines pass, otherwise it will panic. It
checks for the proper parameter names to make sure the function is not
exported. In this case, the runtime.initAll function wasn't exported but
simply didn't have the correct parameter names so the check triggered
even though it shouldn't.
2020-07-31 17:34:44 +02:00
Ayke van Laethem 888ca4ab0c interp: fix sync/atomic.Value load/store methods
These methods do some unsafe pointer casting but can be assumed to not
have significant side effects. Simply call these functions at runtime
instead of compile time.

This is a partial fix for importing image/png.
2020-07-31 17:34:44 +02:00
deadprogram 903bebd071 docs: add Nintendo Switch to list of supported boards/devices
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-07-31 09:12:44 +02:00
waj334 848c3e55a9 compiler: implement func value and builtin defers
Co-authored-by: Justin A. Wilson <maker.pro.game@gmail.com>
2020-07-31 01:48:57 +02:00
Lucas Teske 3650c2c739 nintendoswitch: Add experimental Nintendo Switch support without CRT
Bare minimal nintendo switch support using LLD
2020-07-31 00:58:09 +02:00
Ayke van Laethem d4e04e4e49 compiler: fix named string to []byte slice conversion
This was missing a `.Underlying()` call to avoid testing the named type
(but instead test for the underlying type).
2020-07-29 12:13:37 +02:00
Ayke van Laethem e41e5106cc main: add -target flag to tests
This makes it easy to test one particular architecture, for example:

    go test -v -target=hifive1-qemu

This speeds up testing and allows testing targets that are not included
in the test by default (such as RISC-V tests on Linux).
2020-07-24 16:59:37 +02:00
Ayke van Laethem ca03b8d442 ci: fix Windows QEMU version
It appears that version 2020.07.22 or 2020.07.23 introduced a breaking
change in RISC-V. We will have to fix this eventually, but for now it's
easiest to just pin the QEMU version. Once this new QEMU version
(version 5?) is more widely available, it becomes easier to debug and
fix the underlying cause.
2020-07-24 08:24:20 +02:00
deadprogram d1c4ed664e all: changeover to eliminate all direct use of master/slave terminology
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-07-23 22:45:23 +02:00
Ayke van Laethem fdaddf6917 ci: do not cache TinyGo cache dir
It doesn't seem to speed up the build and it causes issues with a stale
cache.
2020-07-23 21:49:20 +02:00
Ayke van Laethem 50a677e9b7 arm: use CFI directives for stack usage
Call Frame Information is stored in the .debug_frame section and is used
by debuggers for unwinding. For assembly, this information is not known.
Debuggers will normally use heuristics to figure out the parent function
in the absence of call frame information.

This usually works fine, but is not enough for determining stack sizes.
Instead, I hardcoded the stack size information in
stacksize/stacksize.go, which is somewhat fragile. This change uses CFI
assembly directives to store this information instead of hardcoding it.

This change also fixes the following error message that would appear in
GDB:

    Backtrace stopped: previous frame identical to this frame (corrupt stack?)

More information on CFI:
  * https://sourceware.org/binutils/docs/as/CFI-directives.html
  * https://www.imperialviolet.org/2017/01/18/cfi.html
2020-07-20 17:36:50 +02:00
Ethan Reesor 6ad6f14a04 Use a jump table instead of if-then-else 2020-07-18 08:39:26 -04:00
Jaden Weiss 19e0f4709e transform: track 0-index GEPs
It appears that LLVM is turning bitcasts into 0-index GEPs.
This caused stuff to not be tracked, resulting in use-after-free issues.
This solution is sub-optimal, but is the most reasonable solution I could come up with without redesigning the stack slots pass.
2020-07-16 20:50:23 +02:00
Jaden Weiss ae5b297d59 builder: remove optimization level 0
Currently, turning optimizations off causes compile failures.
We rely on the optimizer removing some dead symbols.
Avoid providing an option that does not work right now.
In the future once everything has been fixed we can re-enable this.
2020-07-16 16:41:52 +02:00
Ethan Reesor ca1a282495 Use runtime/volatile.T.ReplaceBits 2020-07-14 06:08:08 +02:00
deadprogram 01f5c51b77 machine/feather-nrf52840: add smoketest for Adafruit Feather nrf52840 board
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-07-14 00:13:10 +02:00
BCG ad6adfd8ff Added board definition for Feather nRF52840 Express 2020-07-13 16:50:06 +02:00
Ethan Reesor 9815628930 Cleanup Teensy 3.6 linker script 2020-07-13 12:35:53 +02:00
Ayke van Laethem 05495c4282 all: fix -gc=none
This option was broken for a long time, in part because we didn't test
for it. This commit fixes that and adds a test to make sure it won't
break again unnoticed.
2020-07-13 12:20:09 +02:00
Ayke van Laethem d606315515 builder: try to determine stack size information at compile time
For now, this is just an extra flag that can be used to print stack
frame information, but this is intended to provide a way to determine
stack sizes for goroutines at compile time in many cases.

Stack sizes are often somewhere around 350 bytes so are in fact not all
that big usually. Once this can be determined at compile time in many
cases, it is possible to use this information when available and as a
result increase the fallback stack size if the size cannot be determined
at compile time. This should reduce stack overflows while at the same
time reducing RAM consumption in many cases.

Interesting output for testdata/channel.go:

    function                                 stack usage (in bytes)
    Reset_Handler                            332
    .Lcommand-line-arguments.fastreceiver    220
    .Lcommand-line-arguments.fastsender      192
    .Lcommand-line-arguments.iterator        192
    .Lcommand-line-arguments.main$1          184
    .Lcommand-line-arguments.main$2          200
    .Lcommand-line-arguments.main$3          200
    .Lcommand-line-arguments.main$4          328
    .Lcommand-line-arguments.receive         176
    .Lcommand-line-arguments.selectDeadlock  72
    .Lcommand-line-arguments.selectNoOp      72
    .Lcommand-line-arguments.send            184
    .Lcommand-line-arguments.sendComplex     192
    .Lcommand-line-arguments.sender          192
    .Lruntime.run$1                          548

This shows that the stack size (if these numbers are correct) can in
fact be determined automatically in many cases, especially for small
goroutines. One of the great things about Go is lightweight goroutines,
and reducing stack sizes is very important to make goroutines
lightweight on microcontrollers.
2020-07-11 14:47:43 +02:00
sago35 60fdf81209 docs: add MAix BiT and Teensy 3.6 to list of supported boards (#1230)
* docs: add MAix BiT and Teensy 3.6 to list of supported boards
2020-07-11 09:21:16 +02:00
Ayke van Laethem 39433a3553 compileopts: automatically add -g flag when including debug symbols
Debug information is often useful and there is no reason to include it
for Go code but not for C code. Also, disabling debug information should
disable it entirely, not just for Go code.
2020-07-10 16:56:13 +02:00
Ethan Reesor 04d097f4ea Implement custom abort and fault handler for debugging 2020-07-08 21:58:15 +02:00
Ethan Reesor 4750635a20 Viable NXP/Teensy support
- Fix UART & putChar
- Timer-based sleep
- Enable systick in abort
- Buffered, interrupt-based UART TX
- Use the new interrupt API and fix sleepTicks
- Make pins behave more like other boards
- Use the MCU's UART numbering
- Allow interrupts to wake the scheduler (#1214)
2020-07-08 21:58:15 +02:00
Ethan Reesor 59218cd784 Working on NXP/Teensy support 2020-07-08 21:58:15 +02:00
Ethan Reesor 079a789d49 Minimal NXP/Teensy support 2020-07-08 21:58:15 +02:00
deadprogram ca8e1b075a targets/maixbit: cleanup output from kflash command by removing ansi colors
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-07-08 20:16:03 +02:00
Branden Timm 33024d4aa2 Fix portL mappings for atmega2560 (#1222)
* machine/atmega2560: fix portL mapping for atmega2560
2020-07-08 19:02:10 +02:00
Branden Timm 49df129ccd docs: add submodule update step prior to 'make release' (#1213)
* docs: add submodule update step prior to 'make release'
2020-07-08 17:37:43 +02:00
Ayke van Laethem 3088dcadec building: add links to tinygo.org
The BUILDING.md file is not intended for developer builds but for
release builds. The website contains more specific and more complete
information on how to build TinyGo, so provide links to these pages.

The Windows link doesn't work yet, but should work with the next
release when we update the website.
2020-07-08 17:35:31 +02:00
Yannis Huber 7ed7e6cb11 risc-v: disable linker relaxations during gp init 2020-07-08 01:58:12 +02:00
Yannis Huber 0b94e486c1 maixbit: changes according to feedback 2020-07-08 00:21:59 +02:00
Yannis Huber 5ff76aacab runtime: reuse common code between 32 and 64-bit RISC-V 2020-07-08 00:21:59 +02:00
Yannis Huber 3ee7599a09 maixbit: use custom linker script
This linker script does not offer stack overflow protection
because the stack cannot be placed at the bottom of the RAM.
2020-07-08 00:21:59 +02:00
Yannis Huber 43a66b39cc riscv: refactor assembly files to support RV64 and F extension 2020-07-08 00:21:59 +02:00
Yannis Huber 66b21b4c86 maixbit (interruptions): fix fpioa function test 2020-07-08 00:21:59 +02:00
Yannis Huber a9568932be maixbit: workaround to avoid medium code model 2020-07-08 00:21:59 +02:00
Yannis Huber f2fbd1dd7e maixbit (gpio): fix pin configuration 2020-07-08 00:21:59 +02:00
Yannis Huber 21a9aa8102 maixbit (i2c): fix rx fifo buffer length 2020-07-08 00:21:59 +02:00
Yannis Huber e1757e0347 builder: add support for 64-bit RISC-V 2020-07-08 00:21:59 +02:00
Yannis Huber a05fc10699 maixbit: add smoke test 2020-07-08 00:21:59 +02:00
Yannis Huber a685217743 maixbit: add I2C support 2020-07-08 00:21:59 +02:00
Yannis Huber ad0c15080a maixbit: add SPI support 2020-07-08 00:21:59 +02:00
Yannis Huber 5446c6927e maixbit: add GPIOHS pin interrupt support 2020-07-08 00:21:59 +02:00
Yannis Huber 53c83fa445 maixbit: support both GPIO and GPIOHS controllers 2020-07-08 00:21:59 +02:00
Yannis Huber 804dc8b1f9 maixbit: init fpioa clock at reset 2020-07-08 00:21:59 +02:00
Yannis Huber e1ceca1931 maixbit: remove atomic operations 2020-07-08 00:21:59 +02:00
Yannis Huber 6620c4d2aa maixbit: add chip datasheet link and reformat code 2020-07-08 00:21:59 +02:00
Yannis Huber ccc604d2e0 riscv: fix offset in 64bit scheduler
Also keep common start.S file for 64 and 32 bit architectures.
2020-07-08 00:21:59 +02:00
Yannis Huber dfab1aa717 maixbit (uart): serial is working with echo example 2020-07-08 00:21:59 +02:00
Yannis Huber 75bcbbe6d8 riscv: align stack and data sections to 8 bytes
Alignment on 4 bytes can cause load/store address misalignment
exceptions when loading/storing 64bit values on the stack.
2020-07-08 00:21:59 +02:00
Yannis Huber d599959711 maixbit (uart): working on data tx
When the data to send is too long the program gives an exception.
2020-07-08 00:21:59 +02:00
Yannis Huber 7814964693 maixbit: add board definition and dummy runtime 2020-07-08 00:21:59 +02:00
Yannis Huber 2fe4a9be71 maix-bit: add code model in target definition
This is needed to avoid linking errors because the globals are placed
in memory at address 0x80000000 which is out of bounds for the default
code model.
2020-07-08 00:21:59 +02:00
Yannis Huber 163631df9e cmsis-svd: change submodule url to the TinyGo fork 2020-07-08 00:21:59 +02:00
Yannis Huber 9ad96fd809 Changes according to @aykevl's feedback 2020-07-08 00:21:59 +02:00
Yannis Huber 4a658b9082 Add llvm code model option in target definition 2020-07-08 00:21:59 +02:00
Yannis Huber 34e0961a79 Split RISC-V targets into 32/64-bit 2020-07-08 00:21:59 +02:00
Yannis Huber 875d36cba0 Add new kendryte k210 target definition 2020-07-08 00:21:59 +02:00
sago35 1a6bed3305 machine/samd51: add DAC support (#1198)
* machine/samd51: add DAC support
2020-07-06 14:02:51 +02:00
Branden Timm e0b9b1ecd1 machine: fix atmega2560 mapping for pins D2 and D5 2020-07-05 21:18:20 +02:00
Johan Brandhorst 149c9533e2 ci: add archlinux release job
Adds the arch-release job, which automatically updates
the tinygo-bin AUR package on every new git tag with
a semver version.
2020-07-05 09:51:44 +02:00
Ron Evans a85df334e6 machine/samd21: basic implementation for DAC (#1183)
* machine/samd21: basic DAC implementation

Signed-off-by: Ron Evans <ron@hybridgroup.com>
2020-07-04 18:16:25 +02:00
Jaden Weiss 89a9c09af5 runtime (atsamd51): allow interrupts to wake the scheduler 2020-07-04 15:00:44 +02:00
Ayke van Laethem 1451eeaf41 machine: change machine.Pin type to uint8
The `machine.Pin` type was a int8, which works fine but limits the
number of pin numbers to 127. This patch changes the type to uint8 and
changes NoPin to 0xff, which allows more pins to be used.

Some boards might not have that many pins but their internal
organization requires more pin numbers to be used (because it is
organized in pin ports and not all pins in a port have a physical
connection). Therefore the range of a int8 is too low to address these
higher pins.

This patch also has the surprising side effect of reducing binary size
in a number of cases. If there is a reduction it's usually just a few
bytes, with one outlier: the driver example amg88xx when compiled for
the pybadge board. I have not seen any increases in binary size.
2020-07-04 09:46:12 +02:00
Jaden Weiss e8c84d24a0 runtime (gc): do not scan the runqueue when the platform is not baremetal with a scheduler 2020-07-04 08:34:39 +02:00
Jaden Weiss a4f3457747 runtime: make channels work in interrupts 2020-07-04 08:34:39 +02:00
Ayke van Laethem aa3481e06a avr: fix target triple
It was `avr-atmel-none`, which is incorrect. It must be
`avr-unknown-unknown`.

Additionally, there is no reason to specify the target triple per chip,
it can be done for all AVR chips at once as it doesn't vary like
Cortex-M chips.
2020-06-30 20:48:42 +02:00
Hiroki Noda 2136cb2f59 Building self-built LLVM faster
Disable LIBEDIT/Z3/OCAMLDOC in LLVM build and use shallow-clone.
2020-06-30 19:09:23 +02:00
Ayke van Laethem acb3cfba6d avr: work around codegen bug in LLVM 10
Commit fc4857e98c (runtime: avoid recursion in printuint64 function)
caused a regression for AVR. I have tried locally with LLVM 11 (which
contains a number of codegen bugs) and the issue is no longer present,
so I'm assuming it's a codegen bug that is now fixed. However, LLVM 11
is not yet released so it seems best to me to work around this
temporarily (for the next few months).

This commit can easily be reverted when we start using LLVM 11.
2020-06-30 17:56:10 +02:00
deadprogram 8cfc4005d3 machine/stm32f4disco: add smoketests for newer version of board
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-06-30 14:08:20 +02:00
deadprogram 2dbe29327a machine/stm32f4disco: add updated target file for newer version of board that have updated st-link
Signed-off-by: deadprogram <ron@hybridgroup.com>
2020-06-30 14:08:20 +02:00
sago35 de0fbb5e2f docs: add PyGamer to list of supported boards 2020-06-27 14:16:36 -04:00
357 changed files with 17135 additions and 1984 deletions
+124 -25
View File
@@ -28,6 +28,7 @@ commands:
qemu-user \
gcc-avr \
avr-libc
sudo apt-get install --no-install-recommends libc6-dev-i386 lib32gcc-8-dev
install-node:
steps:
- run:
@@ -44,28 +45,47 @@ commands:
command: |
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
install-wasmtime:
steps:
- run:
name: "Install wasmtime"
command: |
curl https://wasmtime.dev/install.sh -sSf | bash
sudo ln -s ~/.wasmtime/bin/wasmtime /usr/local/bin/wasmtime
install-xtensa-toolchain:
parameters:
variant:
type: string
steps:
- run:
name: "Install Xtensa toolchain"
command: |
curl -L https://github.com/espressif/crosstool-NG/releases/download/esp-2020r2/xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz -o xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
sudo tar -C /usr/local -xf xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
sudo ln -s /usr/local/xtensa-esp32-elf/bin/xtensa-esp32-elf-ld /usr/local/bin/xtensa-esp32-elf-ld
rm xtensa-esp32-elf-gcc8_2_0-esp-2020r2-<<parameters.variant>>.tar.gz
llvm-source-linux:
steps:
- restore_cache:
keys:
- llvm-source-10-v0
- llvm-source-10-v1
- run:
name: "Fetch LLVM source"
command: make llvm-source
- save_cache:
key: llvm-source-10-v0
key: llvm-source-10-v1
paths:
- llvm-project
build-wasi-libc:
steps:
- restore_cache:
keys:
- wasi-libc-sysroot-v2
- wasi-libc-sysroot-v3
- run:
name: "Build wasi-libc"
command: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-v2
key: wasi-libc-sysroot-v3
paths:
- lib/wasi-libc/sysroot
test-linux:
@@ -79,6 +99,7 @@ commands:
llvm: "<<parameters.llvm>>"
- install-node
- install-chrome
- install-wasmtime
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
@@ -87,22 +108,21 @@ commands:
- run: go install -tags=llvm<<parameters.llvm>> .
- restore_cache:
keys:
- wasi-libc-sysroot-systemclang-v1
- wasi-libc-sysroot-systemclang-v2
- run: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-systemclang-v1
key: wasi-libc-sysroot-systemclang-v2
paths:
- lib/wasi-libc/sysroot
- run: tinygo clean
- run: go test -v -tags=llvm<<parameters.llvm>> ./cgo ./compileopts ./interp ./transform .
- run: make gen-device -j4
- run: make smoketest
- run: make smoketest XTENSA=0
- run: make tinygo-test
- run: make wasmtest
- save_cache:
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- ~/.cache/tinygo
- /go/pkg/mod
- run: make fmt-check
assert-test-linux:
@@ -114,7 +134,6 @@ commands:
command: |
sudo apt-get install \
gcc-arm-linux-gnueabihf \
binutils-arm-none-eabi \
libc6-dev-armel-cross \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
@@ -122,7 +141,11 @@ commands:
qemu-user \
gcc-avr \
avr-libc
sudo apt-get install --no-install-recommends libc6-dev-i386 lib32gcc-6-dev
- install-node
- install-wasmtime
- install-xtensa-toolchain:
variant: "linux-amd64"
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
@@ -130,7 +153,7 @@ commands:
- llvm-source-linux
- restore_cache:
keys:
- llvm-build-10-linux-v0-assert
- llvm-build-10-linux-v1-assert
- run:
name: "Build LLVM"
command: |
@@ -148,7 +171,7 @@ commands:
make ASSERT=1 llvm-build
fi
- save_cache:
key: llvm-build-10-linux-v0-assert
key: llvm-build-10-linux-v1-assert
paths:
llvm-build
- run: make ASSERT=1
@@ -160,7 +183,6 @@ commands:
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- ~/.cache/tinygo
- /go/pkg/mod
- run: make gen-device -j4
- run: make smoketest TINYGO=build/tinygo
@@ -173,7 +195,6 @@ commands:
command: |
sudo apt-get install \
gcc-arm-linux-gnueabihf \
binutils-arm-none-eabi \
libc6-dev-armel-cross \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
@@ -181,7 +202,11 @@ commands:
qemu-user \
gcc-avr \
avr-libc
sudo apt-get install --no-install-recommends libc6-dev-i386 lib32gcc-6-dev
- install-node
- install-wasmtime
- install-xtensa-toolchain:
variant: "linux-amd64"
- restore_cache:
keys:
- go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
@@ -189,7 +214,7 @@ commands:
- llvm-source-linux
- restore_cache:
keys:
- llvm-build-10-linux-v0
- llvm-build-10-linux-v1
- run:
name: "Build LLVM"
command: |
@@ -207,7 +232,7 @@ commands:
make llvm-build
fi
- save_cache:
key: llvm-build-10-linux-v0
key: llvm-build-10-linux-v1
paths:
llvm-build
- build-wasi-libc
@@ -233,7 +258,6 @@ commands:
key: go-cache-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- ~/.cache/tinygo
- /go/pkg/mod
- run:
name: "Extract release tarball"
@@ -254,23 +278,25 @@ commands:
sudo tar -C /usr/local -xzf go1.14.darwin-amd64.tar.gz
ln -s /usr/local/go/bin/go /usr/local/bin/go
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu
- install-xtensa-toolchain:
variant: "macos"
- restore_cache:
keys:
- go-cache-macos-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_PREVIOUS_BUILD_NUM }}
- go-cache-macos-v2-{{ checksum "go.mod" }}
- restore_cache:
keys:
- llvm-source-10-macos-v0
- llvm-source-10-macos-v1
- run:
name: "Fetch LLVM source"
command: make llvm-source
- save_cache:
key: llvm-source-10-macos-v0
key: llvm-source-10-macos-v1
paths:
- llvm-project
- restore_cache:
keys:
- llvm-build-10-macos-v0
- llvm-build-10-macos-v1
- run:
name: "Build LLVM"
command: |
@@ -282,17 +308,17 @@ commands:
make llvm-build
fi
- save_cache:
key: llvm-build-10-macos-v0
key: llvm-build-10-macos-v1
paths:
llvm-build
- restore_cache:
keys:
- wasi-libc-sysroot-macos-v1
- wasi-libc-sysroot-macos-v2
- run:
name: "Build wasi-libc"
command: make wasi-libc
- save_cache:
key: wasi-libc-sysroot-macos-v1
key: wasi-libc-sysroot-macos-v2
paths:
- lib/wasi-libc/sysroot
- run:
@@ -317,9 +343,61 @@ commands:
key: go-cache-macos-v2-{{ checksum "go.mod" }}-{{ .Environment.CIRCLE_BUILD_NUM }}
paths:
- ~/.cache/go-build
- ~/.cache/tinygo
- /go/pkg/mod
arch-release:
steps:
- run:
name: Install dependencies
command: pacman -Sy --noconfirm openssh git pacman-contrib binutils
- run:
name: Create TinyGo user
command: useradd -m tinygo
- run:
name: Start SSH Agent
user: tinygo
command: eval $(ssh-agent -s)
- run:
name: Add ARCH_RELEASE_SSH_PRIVATE_KEY identity
user: tinygo
command: echo "${ARCH_RELEASE_SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add -
- run:
name: Create SSH directory
user: tinygo
command: mkdir -p ~/.ssh && chmod 700 ~/.ssh
- run:
name: Add aur.archlinux.org to known hosts
user: tinygo
command: ssh-keyscan aur.archlinux.org >> ~/.ssh/known_hosts
- run:
name: Clone tinygo-bin repo
user: tinygo
command: git clone ssh://aur@aur.archlinux.org/tinygo-bin.git ~/tinygo-bin
- run:
name: Update package version
user: tinygo
command: sed -i -E "s/(pkgver=)(.*)$/\1${CIRCLE_TAG}/" ~/tinygo-bin/PKGBUILD
- run:
name: Update file checksums
user: tinygo
command: cd ~/tinygo-bin && updpkgsums
- run:
name: Update .SRCINFO
user: tinygo
command: cd ~/tinygo-bin && makepkg --printsrcinfo > .SRCINFO
# Commit the update
- run:
name: Set git commit config
user: tinygo
command: |
git config --global user.email "tinygo-bot@tinygo.org" &&
git config --global user.name "TinyGo Release Bot"
- run:
name: Commit and push changes
user: tinygo
command: |
cd ~/tinygo-bin &&
git commit -a -m "Update tinygo-bin to v${CIRCLE_TAG}" &&
git push origin master
jobs:
test-llvm9-go111:
@@ -346,6 +424,12 @@ jobs:
steps:
- test-linux:
llvm: "10"
test-llvm11-go115:
docker:
- image: circleci/golang:1.15-buster
steps:
- test-linux:
llvm: "11"
assert-test-linux:
docker:
- image: circleci/golang:1.14-stretch
@@ -361,6 +445,11 @@ jobs:
xcode: "10.1.0"
steps:
- build-macos
arch-release:
docker:
- image: archlinux:latest
steps:
- arch-release
@@ -372,6 +461,16 @@ workflows:
- test-llvm10-go112
- test-llvm10-go113
- test-llvm10-go114
- test-llvm11-go115
- build-linux
- build-macos
- assert-test-linux
release:
jobs:
- arch-release:
filters:
branches:
ignore: /.*/
tags:
# Runs on every semver release
only: /v[0-9]+(\.[0-9]+)*(-.*)*/
+5
View File
@@ -3,14 +3,19 @@ docs/_build
src/device/avr/*.go
src/device/avr/*.ld
src/device/avr/*.s
src/device/esp/*.go
src/device/nrf/*.go
src/device/nrf/*.s
src/device/nxp/*.go
src/device/nxp/*.s
src/device/sam/*.go
src/device/sam/*.s
src/device/sifive/*.go
src/device/sifive/*.s
src/device/stm32/*.go
src/device/stm32/*.s
src/device/kendryte/*.go
src/device/kendryte/*.s
vendor
llvm-build
llvm-project
+1 -1
View File
@@ -9,7 +9,7 @@
url = https://github.com/avr-rust/avr-mcu.git
[submodule "lib/cmsis-svd"]
path = lib/cmsis-svd
url = https://github.com/posborne/cmsis-svd
url = https://github.com/tinygo-org/cmsis-svd
[submodule "lib/compiler-rt"]
path = lib/compiler-rt
url = https://github.com/llvm-mirror/compiler-rt.git
+12
View File
@@ -10,6 +10,14 @@ This guide describes how to statically link TinyGo against LLVM, libclang and
lld so that the binary can be easily moved between systems. It also shows how to
build a release tarball that includes this binary and all necessary extra files.
**Note**: this documentation describes how to build a statically linked release
tarball. If you want to develop TinyGo, you will probably want to follow a
different guide:
* [Linux](https://tinygo.org/getting-started/linux/#source-install)
* [macOS](https://tinygo.org/getting-started/macos/#source-install)
* [Windows](https://tinygo.org/getting-started/windows/#source-install)
## Dependencies
LLVM, Clang and LLD are quite light on dependencies, requiring only standard
@@ -84,6 +92,10 @@ Now that we have a working static build, it's time to make a release tarball:
make release
If you did not clone the repository with the `--recursive` option, you will get errors until you initialize the project submodules:
git submodule update --init
The release tarball is stored in build/release.tar.gz, and can be extracted with
the following command (for example in ~/lib):
+223
View File
@@ -1,3 +1,226 @@
0.16.0
---
* **command-line**
- add initial support for LLVM 11
- make lib64 clang include path check more robust
- `build`: improve support for GOARCH=386 and add tests
- `gdb`: add support for qemu-user targets
- `test`: support non-host tests
- `test`: add support for -c and -o flags
- `test`: implement some benchmark stubs
* **compiler**
- `builder`: improve detection of clang on Fedora
- `compiler`: fix floating point comparison bugs
- `compiler`: implement negate for complex numbers
- `loader`: fix linkname in test binaries
- `transform`: add missing return pointer restore for regular coroutine tail
calls
* **standard library**
- `machine`: switch default frequency to 4MHz
- `machine`: clarify caller's responsibility in `SetInterrupt`
- `os`: add `LookupEnv()` stub
- `reflect`: implement `Swapper`
- `runtime`: fix UTF-8 decoding
- `runtime`: gc: use raw stack access whenever possible
- `runtime`: use dedicated printfloat32
- `runtime`: allow ranging over a nil map
- `runtime`: avoid device/nxp dependency in HardFault handler
- `testing`: implement dummy Helper method
- `testing`: add Run method
* **targets**
- `arm64`: add support for SVCall intrinsic
- `atsamd51`: avoid panic when configuring SPI with SDI=NoPin
- `avr`: properly support the `.rodata` section
- `esp8266`: implement `Pin.Get` function
- `nintendoswitch`: fix crash when printing long lines (> 120)
- `nintendoswitch`: add env parser and removed unused stuff
- `nrf`: add I2C error checking
- `nrf`: give more flexibility in picking SPI speeds
- `nrf`: fix nrf52832 flash size
- `stm32f103`: support wakeups from interrupts
- `stm32f405`: add SPI support
- `stm32f405`: add I2C support
- `wasi`: add support for this target
- `wasi`: use 'generic' ABI by default
- `wasi`: remove --no-threads flag from wasm-ld
- `wasm`: add instanceof support for WebAssembly
- `wasm`: use fixed length buffer for putchar
* **boards**
- `d1mini`: add this ESP8266 based board
- `esp32`: use board definitions instead of chip names
- `qtpy`: add board definition for Adafruit QTPy
- `teensy40`: add this board
0.15.0
---
* **command-line**
- add cached GOROOT to info subcommand
- embed git-hash in tinygo-dev executable
- implement tinygo targets to list usable targets
- use simpler file copy instead of file renaming to avoid issues on nrf52840 UF2 bootloaders
- use ToSlash() to specify program path
- support flashing esp32/esp8266 directly from tinygo
- when flashing call PortReset only on other than openocd
* **compiler**
- `compileopts`: add support for custom binary formats
- `compiler`: improve display of goroutine wrappers
- `interp`: don't panic in the Store method
- `interp`: replace some panics with error messages
- `interp`: show error line in first line of the traceback
- `loader`: be more robust when creating the cached GOROOT
- `loader`: rewrite/refactor much of the code to use go list directly
- `loader`: use ioutil.TempDir to create a temporary directory
- `stacksize`: deal with DW_CFA_advance_loc1
* **standard library**
- `runtime`: use waitForEvents when appropriate
* **wasm**
- `wasm`: Remove --no-threads from wasm-ld calls.
- `wasm`: update wasi-libc dependency
* **targets**
- `arduino-mega2560`: fix flashing on Windows
- `arm`: automatically determine stack sizes
- `arm64`: make dynamic loader structs and constants private
- `avr`: configure emulator in board files
- `cortexm`: fix stack size calculation with interrupts
- `flash`: add openocd settings to atsamd21 / atsamd51
- `flash`: add openocd settings to nrf5
- `microbit`: reelboard: flash using OpenOCD when needed
- `nintendoswitch`: Add dynamic loader for runtime loading PIE sections
- `nintendoswitch`: fix import cycle on dynamic_arm64.go
- `nintendoswitch`: Fix invalid memory read / write in print calls
- `nintendoswitch`: simplified assembly code
- `nintendoswitch`: support outputting .nro files directly
* **boards**
- `arduino-zero`: Adding support for the Arduino Zero (#1365)
- `atsamd2x`: fix BAUD value
- `atsamd5x`: fix BAUD value
- `bluepill`: Enable stm32's USART2 for the board and map it to UART1 tinygo's device
- `device/atsamd51x`: add all remaining bitfield values for PCHCTRLm Mapping
- `esp32`: add libgcc ROM functions to linker script
- `esp32`: add SPI support
- `esp32`: add support for basic GPIO
- `esp32`: add support for the Espressif ESP32 chip
- `esp32`: configure the I/O matrix for GPIO pins
- `esp32`: export machine.PortMask* for bitbanging implementations
- `esp8266`: add support for this chip
- `machine/atsamd51x,runtime/atsamd51x`: fixes needed for full support for all PWM pins. Also adds some useful constants to clarify peripheral clock usage
- `machine/itsybitsy-nrf52840`: add support for Adafruit Itsybitsy nrf52840 (#1243)
- `machine/stm32f4`: refactor common code and add new build tag stm32f4 (#1332)
- `nrf`: add SoftDevice support for the Circuit Playground Bluefruit
- `nrf`: call sd_app_evt_wait when the SoftDevice is enabled
- `nrf52840`: add build tags for SoftDevice support
- `nrf52840`: use higher priority for USB-CDC code
- `runtime/atsamd51x`: use PCHCTRL_GCLK_SERCOMX_SLOW for setting clocks on all SERCOM ports
- `stm32f405`: add basic UART handler
- `stm32f405`: add STM32F405 machine/runtime, and new board/target feather-stm32f405
* **build**
- `all`: run test binaries in the correct directory
- `build`: Fix arch release job
- `ci`: run `tinygo test` for known-working packages
- `ci`: set git-fetch-depth to 1
- `docker`: fix the problem with the wasm build (#1357)
- `Makefile`: check whether submodules have been downloaded in some common cases
* **docs**
- add ESP32, ESP8266, and Adafruit Feather STM32F405 to list of supported boards
0.14.1
---
* **command-line**
- support for Go 1.15
* **compiler**
- loader: work around Windows symlink limitation
0.14.0
---
* **command-line**
- fix `getDefaultPort()` on non-English Windows locales
- compileopts: improve error reporting of unsupported flags
- fix test subcommand
- use auto-retry to locate MSD for UF2 and HEX flashing
- fix touchSerialPortAt1200bps on Windows
- support package names with backslashes on Windows
* **compiler**
- fix a few crashes due to named types
- add support for atomic operations
- move the channel blocked list onto the stack
- fix -gc=none
- fix named string to `[]byte` slice conversion
- implement func value and builtin defers
- add proper parameter names to runtime.initAll, to fix a panic
- builder: fix picolibc include path
- builder: use newer version of gohex
- builder: try to determine stack size information at compile time
- builder: remove -opt=0
- interp: fix sync/atomic.Value load/store methods
- loader: add Go module support
- transform: fix debug information in func lowering pass
- transform: do not special-case zero or one implementations of a method call
- transform: introduce check for method calls on nil interfaces
- transform: gc: track 0-index GEPs to fix miscompilation
* **cgo**
- Add LDFlags support
* **standard library**
- extend stdlib to allow import of more packages
- replace master/slave terminology with appropriate alternatives (MOSI->SDO
etc)
- `internal/bytealg`: reimplement bytealg in pure Go
- `internal/task`: fix nil panic in (*internal/task.Stack).Pop
- `os`: add Args and stub it with mock data
- `os`: implement virtual filesystem support
- `reflect`: add Cap and Len support for map and chan
- `runtime`: fix return address in scheduler on RISC-V
- `runtime`: avoid recursion in printuint64 function
- `runtime`: replace ReadRegister with AsmFull inline assembly
- `runtime`: fix compilation errors when using gc.extalloc
- `runtime`: add cap and len support for chans
- `runtime`: refactor time handling (improving accuracy)
- `runtime`: make channels work in interrupts
- `runtime/interrupt`: add cross-chip disable/restore interrupt support
- `sync`: implement `sync.Cond`
- `sync`: add WaitGroup
* **targets**
- `arm`: allow nesting in DisableInterrupts and EnableInterrupts
- `arm`: make FPU configuraton consistent
- `arm`: do not mask fault handlers in critical sections
- `atmega2560`: fix pin mapping for pins D2, D5 and the L port
- `atsamd`: return an error when an incorrect PWM pin is used
- `atsamd`: add support for pin change interrupts
- `atsamd`: add DAC support
- `atsamd21`: add more ADC pins
- `atsamd51`: fix ROM / RAM size on atsamd51j20
- `atsamd51`: add more pins
- `atsamd51`: add more ADC pins
- `atsamd51`: add pin change interrupt settings
- `atsamd51`: extend pinPadMapping
- `arduino-nano33`: use (U)SB flag to ensure that device can be found when
not on default port
- `arduino-nano33`: remove (d)ebug flag to reduce console noise when flashing
- `avr`: use standard pin numbering
- `avr`: unify GPIO pin/port code
- `avr`: add support for PinInputPullup
- `avr`: work around codegen bug in LLVM 10
- `avr`: fix target triple
- `fe310`: remove extra println left in by mistake
- `feather-nrf52840`: add support for the Feather nRF52840
- `maixbit`: add board definition and dummy runtime
- `nintendoswitch`: Add experimental Nintendo Switch support without CRT
- `nrf`: expose the RAM base address
- `nrf`: add support for pin change interrupts
- `nrf`: add microbit-s110v8 target
- `nrf`: fix bug in SPI.Tx
- `nrf`: support debugging the PCA10056
- `pygamer`: add Adafruit PyGamer suport
- `riscv`: fix interrupt configuration bug
- `riscv`: disable linker relaxations during gp init
- `stm32f4disco`: add new target with ST-Link v2.1 debugger
- `teensy36`: add Teensy 3.6 support
- `wasm`: fix event handling
- `wasm`: add --no-demangle linker option
- `wioterminal`: add support for the Seeed Wio Terminal
- `xiao`: add support for the Seeed XIAO
0.13.1
---
* **standard library**
+1 -1
View File
@@ -32,7 +32,7 @@ Microcontrollers have lots of peripherals (I2C, SPI, ADC, etc.) and many don't h
## How to use our Github repository
The `master` branch of this repo will always have the latest released version of TinyGo. All of the active development work for the next release will take place in the `dev` branch. TinyGo will use semantic versioning and will create a tag/release for each release.
The `release` branch of this repo will always have the latest released version of TinyGo. All of the active development work for the next release will take place in the `dev` branch. TinyGo will use semantic versioning and will create a tag/release for each release.
Here is how to contribute back some code or documentation:
+1 -1
View File
@@ -15,4 +15,4 @@ Ayke van Laethem <aykevanlaethem@gmail.com>
Daniel Esteban <conejo@conejo.me>
Loon, LLC.
Ron Evans <ron@hybridgroup.com>
Jaden Weiss <jaden@jadendw.dev>
Nia Weiss <niaow1234@gmail.com>
+6 -3
View File
@@ -1,5 +1,5 @@
# TinyGo base stage installs Go 1.14, LLVM 10 and the TinyGo compiler itself.
FROM golang:1.14 AS tinygo-base
# TinyGo base stage installs the most recent Go 1.15.x, LLVM 10 and the TinyGo compiler itself.
FROM golang:1.15 AS tinygo-base
RUN wget -O- https://apt.llvm.org/llvm-snapshot.gpg.key| apt-key add - && \
echo "deb http://apt.llvm.org/buster/ llvm-toolchain-buster-10 main" >> /etc/apt/sources.list && \
@@ -27,7 +27,10 @@ COPY --from=tinygo-base /go/bin/tinygo /go/bin/tinygo
COPY --from=tinygo-base /tinygo/src /tinygo/src
COPY --from=tinygo-base /tinygo/targets /tinygo/targets
RUN apt-get install -y libllvm10 lld-10
RUN cd /tinygo/ && \
apt-get update && \
apt-get install -y make clang-10 libllvm10 lld-10 && \
make wasi-libc
# tinygo-avr stage installs the needed dependencies to compile TinyGo programs for AVR microcontrollers.
FROM tinygo-base AS tinygo-avr
+88 -31
View File
@@ -9,25 +9,10 @@ CLANG_SRC ?= $(LLVM_PROJECTDIR)/clang
LLD_SRC ?= $(LLVM_PROJECTDIR)/lld
# Try to autodetect LLVM build tools.
ifneq (, $(shell command -v llvm-build/bin/clang 2> /dev/null))
CLANG ?= $(abspath llvm-build/bin/clang)
else
CLANG ?= clang-10
endif
ifneq (, $(shell command -v llvm-build/bin/llvm-ar 2> /dev/null))
LLVM_AR ?= $(abspath llvm-build/bin/llvm-ar)
else ifneq (, $(shell command -v llvm-ar-10 2> /dev/null))
LLVM_AR ?= llvm-ar-10
else
LLVM_AR ?= llvm-ar
endif
ifneq (, $(shell command -v llvm-build/bin/llvm-nm 2> /dev/null))
LLVM_NM ?= $(abspath llvm-build/bin/llvm-nm)
else ifneq (, $(shell command -v llvm-nm-10 2> /dev/null))
LLVM_NM ?= llvm-nm-10
else
LLVM_NM ?= llvm-nm
endif
detect = $(shell command -v $(1) 2> /dev/null && echo $(1))
CLANG ?= $(word 1,$(abspath $(call detect,llvm-build/bin/clang))$(call detect,clang-11)$(call detect,clang-10)$(call detect,clang))
LLVM_AR ?= $(word 1,$(abspath $(call detect,llvm-build/bin/llvm-ar))$(call detect,llvm-ar-11)$(call detect,llvm-ar-10)$(call detect,llvm-ar))
LLVM_NM ?= $(word 1,$(abspath $(call detect,llvm-build/bin/llvm-nm))$(call detect,llvm-nm-11)$(call detect,llvm-nm-10)$(call detect,llvm-nm))
# Go binary and GOROOT to select
GO ?= go
@@ -37,7 +22,7 @@ export GOROOT = $(shell $(GO) env GOROOT)
MD5SUM = md5sum
# tinygo binary for tests
TINYGO ?= tinygo
TINYGO ?= $(word 1,$(call detect,tinygo)$(call detect,build/tinygo))
# Use CCACHE for LLVM if possible
ifneq (, $(shell command -v ccache 2> /dev/null))
@@ -51,7 +36,7 @@ else
LLVM_OPTION += '-DLLVM_ENABLE_ASSERTIONS=OFF'
endif
.PHONY: all tinygo test $(LLVM_BUILDDIR) llvm-source clean fmt gen-device gen-device-nrf gen-device-avr
.PHONY: all tinygo test $(LLVM_BUILDDIR) llvm-source clean fmt gen-device gen-device-nrf gen-device-nxp gen-device-avr
LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf executionengine frontendopenmp instrumentation interpreter ipo irreader linker lto mc mcjit objcarcopts option profiledata scalaropts support target
@@ -104,7 +89,7 @@ LLD_LIBS = $(START_GROUP) -llldCOFF -llldCommon -llldCore -llldDriver -llldELF -
ifneq ("$(wildcard $(LLVM_BUILDDIR)/bin/llvm-config*)","")
CGO_CPPFLAGS=$(shell $(LLVM_BUILDDIR)/bin/llvm-config --cppflags) -I$(abspath $(LLVM_BUILDDIR))/tools/clang/include -I$(abspath $(CLANG_SRC))/include -I$(abspath $(LLD_SRC))/include
CGO_CXXFLAGS=-std=c++14
CGO_LDFLAGS+=$(LIBCLANG_PATH) -std=c++14 -L$(abspath $(LLVM_BUILDDIR)/lib) $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA)
CGO_LDFLAGS+=$(LIBCLANG_PATH) -L$(abspath $(LLVM_BUILDDIR)/lib) $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA)
endif
@@ -118,9 +103,10 @@ fmt-check:
@unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1
gen-device: gen-device-avr gen-device-nrf gen-device-sam gen-device-sifive gen-device-stm32
gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-stm32 gen-device-kendryte gen-device-nxp
gen-device-avr:
@if [ ! -e lib/avr/README.md ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init"; exit 1; fi
$(GO) build -o ./build/gen-device-avr ./tools/gen-device-avr/
./build/gen-device-avr lib/avr/packs/atmega src/device/avr/
./build/gen-device-avr lib/avr/packs/tiny src/device/avr/
@@ -129,10 +115,18 @@ gen-device-avr:
build/gen-device-svd: ./tools/gen-device-svd/*.go
$(GO) build -o $@ ./tools/gen-device-svd/
gen-device-esp: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/Espressif-Community -interrupts=software lib/cmsis-svd/data/Espressif-Community/ src/device/esp/
GO111MODULE=off $(GO) fmt ./src/device/esp
gen-device-nrf: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/NordicSemiconductor/nrfx/tree/master/mdk lib/nrfx/mdk/ src/device/nrf/
GO111MODULE=off $(GO) fmt ./src/device/nrf
gen-device-nxp: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/NXP lib/cmsis-svd/data/NXP/ src/device/nxp/
GO111MODULE=off $(GO) fmt ./src/device/nxp
gen-device-sam: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/Atmel lib/cmsis-svd/data/Atmel/ src/device/sam/
GO111MODULE=off $(GO) fmt ./src/device/sam
@@ -141,6 +135,10 @@ gen-device-sifive: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/SiFive-Community -interrupts=software lib/cmsis-svd/data/SiFive-Community/ src/device/sifive/
GO111MODULE=off $(GO) fmt ./src/device/sifive
gen-device-kendryte: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/Kendryte-Community -interrupts=software lib/cmsis-svd/data/Kendryte-Community/ src/device/kendryte/
GO111MODULE=off $(GO) fmt ./src/device/kendryte
gen-device-stm32: build/gen-device-svd
./build/gen-device-svd -source=https://github.com/posborne/cmsis-svd/tree/master/data/STMicro lib/cmsis-svd/data/STMicro/ src/device/stm32/
GO111MODULE=off $(GO) fmt ./src/device/stm32
@@ -148,13 +146,13 @@ gen-device-stm32: build/gen-device-svd
# Get LLVM sources.
$(LLVM_PROJECTDIR)/README.md:
git clone -b release/10.x https://github.com/llvm/llvm-project $(LLVM_PROJECTDIR)
git clone -b xtensa_release_10.0.1 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
llvm-source: $(LLVM_PROJECTDIR)/README.md
# Configure LLVM.
TINYGO_SOURCE_DIR=$(shell pwd)
$(LLVM_BUILDDIR)/build.ninja: llvm-source
mkdir -p $(LLVM_BUILDDIR); cd $(LLVM_BUILDDIR); cmake -G Ninja $(TINYGO_SOURCE_DIR)/$(LLVM_PROJECTDIR)/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;RISCV;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF $(LLVM_OPTION)
mkdir -p $(LLVM_BUILDDIR); cd $(LLVM_BUILDDIR); cmake -G Ninja $(TINYGO_SOURCE_DIR)/$(LLVM_PROJECTDIR)/llvm "-DLLVM_TARGETS_TO_BUILD=X86;ARM;AArch64;RISCV;WebAssembly" "-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR;Xtensa" -DCMAKE_BUILD_TYPE=Release -DLIBCLANG_BUILD_STATIC=ON -DLLVM_ENABLE_TERMINFO=OFF -DLLVM_ENABLE_ZLIB=OFF -DLLVM_ENABLE_LIBEDIT=OFF -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_OCAMLDOC=OFF -DLLVM_ENABLE_PROJECTS="clang;lld" -DLLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD=OFF $(LLVM_OPTION)
# Build LLVM.
$(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
@@ -165,19 +163,35 @@ $(LLVM_BUILDDIR): $(LLVM_BUILDDIR)/build.ninja
.PHONY: wasi-libc
wasi-libc: lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a
lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a:
@if [ ! -e lib/wasi-libc/Makefile ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init"; exit 1; fi
cd lib/wasi-libc && make -j4 WASM_CC=$(CLANG) WASM_AR=$(LLVM_AR) WASM_NM=$(LLVM_NM)
# Build the Go compiler.
tinygo:
@if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " make llvm-source"; echo " make $(LLVM_BUILDDIR)"; exit 1; fi
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o build/tinygo$(EXE) -tags byollvm .
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags byollvm -ldflags="-X main.gitSha1=`git rev-parse --short HEAD`" .
test: wasi-libc
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test -v -tags byollvm ./cgo ./compileopts ./interp ./transform .
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test -v -buildmode exe -tags byollvm ./cgo ./compileopts ./interp ./transform .
# Test known-working standard library packages.
# TODO: do this in one command, parallelize, and only show failing tests (no
# implied -v flag).
.PHONY: tinygo-test
tinygo-test:
cd tests/tinygotest && tinygo test
$(TINYGO) test container/heap
$(TINYGO) test container/list
$(TINYGO) test container/ring
$(TINYGO) test crypto/des
$(TINYGO) test encoding/ascii85
$(TINYGO) test encoding/base32
$(TINYGO) test encoding/hex
$(TINYGO) test hash/fnv
$(TINYGO) test hash/crc64
$(TINYGO) test math
$(TINYGO) test text/scanner
$(TINYGO) test unicode/utf8
.PHONY: smoketest
smoketest:
@@ -214,8 +228,6 @@ smoketest:
# test simulated boards on play.tinygo.org
$(TINYGO) build -o test.wasm -tags=arduino examples/blinky1
@$(MD5SUM) test.wasm
$(TINYGO) build -o test.wasm -tags=hifive1-qemu examples/serial
@$(MD5SUM) test.wasm
$(TINYGO) build -o test.wasm -tags=hifive1b examples/blinky1
@$(MD5SUM) test.wasm
$(TINYGO) build -o test.wasm -tags=reelboard examples/blinky1
@@ -259,11 +271,15 @@ smoketest:
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=stm32f4disco examples/blinky2
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=stm32f4disco-1 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=feather-stm32f405 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=circuitplay-bluefruit examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=circuitplay-express examples/i2s
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=clue_alpha examples/blinky1
$(TINYGO) build -size short -o test.hex -target=clue-alpha examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.gba -target=gameboy-advance examples/gba-display
@$(MD5SUM) test.gba
@@ -296,8 +312,32 @@ smoketest:
$(TINYGO) build -size short -o test.hex -target=wioterminal examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pygamer examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=xiao examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=circuitplay-express examples/dac
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pyportal examples/dac
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=feather-nrf52840 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=itsybitsy-nrf52840 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=qtpy examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=teensy40 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=teensy36 examples/blinky1
@$(MD5SUM) test.hex
# test pwm
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m4 examples/pwm
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=feather-m4 examples/pwm
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pyportal examples/pwm
@$(MD5SUM) test.hex
ifneq ($(AVR), 0)
$(TINYGO) build -size short -o test.hex -target=atmega1284p examples/serial
@$(MD5SUM) test.hex
@@ -313,11 +353,28 @@ ifneq ($(AVR), 0)
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=digispark -gc=leaking examples/blinky1
@$(MD5SUM) test.hex
endif
ifneq ($(XTENSA), 0)
$(TINYGO) build -size short -o test.bin -target=esp32-mini32 examples/blinky1
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target=nodemcu examples/blinky1
@$(MD5SUM) test.bin
endif
$(TINYGO) build -size short -o test.hex -target=hifive1b examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=hifive1-qemu examples/serial
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=maixbit examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -o wasm.wasm -target=wasm examples/wasm/export
$(TINYGO) build -o wasm.wasm -target=wasm examples/wasm/main
# test various compiler flags
$(TINYGO) build -size short -o test.hex -target=pca10040 -gc=none -scheduler=none examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=pca10040 -opt=1 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -o test.nro -target=nintendoswitch examples/serial
@$(MD5SUM) test.nro
wasmtest:
$(GO) test ./tests/wasm
+13 -1
View File
@@ -43,27 +43,35 @@ See the [getting started instructions](https://tinygo.org/getting-started/) for
You can compile TinyGo programs for microcontrollers, WebAssembly and Linux.
The following 34 microcontroller boards are currently supported:
The following 44 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)
* [Adafruit CLUE Alpha](https://www.adafruit.com/product/4500)
* [Adafruit Feather M0](https://www.adafruit.com/product/2772)
* [Adafruit Feather M4](https://www.adafruit.com/product/3857)
* [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
* [Adafruit Feather STM32F405 Express](https://www.adafruit.com/product/4382)
* [Adafruit ItsyBitsy M0](https://www.adafruit.com/product/3727)
* [Adafruit ItsyBitsy M4](https://www.adafruit.com/product/3800)
* [Adafruit ItsyBitsy nRF52840](https://www.adafruit.com/product/4481)
* [Adafruit Metro M4 Express Airlift](https://www.adafruit.com/product/4000)
* [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 Trinket M0](https://www.adafruit.com/product/3500)
* [Arduino Mega 2560](https://store.arduino.cc/arduino-mega-2560-rev3)
* [Arduino Nano](https://store.arduino.cc/arduino-nano)
* [Arduino Nano33 IoT](https://store.arduino.cc/nano-33-iot)
* [Arduino Uno](https://store.arduino.cc/arduino-uno-rev3)
* [Arduino Zero](https://store.arduino.cc/usa/arduino-zero)
* [BBC micro:bit](https://microbit.org/)
* [Digispark](http://digistump.com/products/1)
* [ESP32](https://www.espressif.com/en/products/socs/esp32)
* [ESP8266](https://www.espressif.com/en/products/socs/esp8266)
* [Game Boy Advance](https://en.wikipedia.org/wiki/Game_Boy_Advance)
* [Makerdiary nRF52840-MDK](https://wiki.makerdiary.com/nrf52840-mdk/)
* [Nintendo Switch](https://www.nintendo.com/switch/)
* [Nordic Semiconductor PCA10031](https://www.nordicsemi.com/eng/Products/nRF51-Dongle)
* [Nordic Semiconductor PCA10040](https://www.nordicsemi.com/eng/Products/Bluetooth-low-energy/nRF52-DK)
* [Nordic Semiconductor PCA10056](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK)
@@ -72,8 +80,10 @@ The following 34 microcontroller boards are currently supported:
* [Particle Xenon](https://docs.particle.io/datasheets/discontinued/xenon-datasheet/)
* [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)
* [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)
* [Seeed Sipeed MAix BiT](https://www.seeedstudio.com/Sipeed-MAix-BiT-for-RISC-V-AI-IoT-p-2872.html)
* [SiFIve HiFive1](https://www.sifive.com/boards/hifive1)
* [ST Micro "Nucleo F103RB"](https://www.st.com/en/evaluation-tools/nucleo-f103rb.html)
* [ST Micro STM32F103XX "Bluepill"](http://wiki.stm32duino.com/index.php?title=Blue_Pill)
@@ -139,3 +149,5 @@ The original reasoning was: if [Python](https://micropython.org/) can run on mic
This project is licensed under the BSD 3-clause license, just like the [Go project](https://golang.org/LICENSE) itself.
Some code has been copied from the LLVM project and is therefore licensed under [a variant of the Apache 2.0 license](http://releases.llvm.org/10.0.0/LICENSE.TXT). This has been clearly indicated in the header of these files.
Some code has been copied and/or ported from Paul Stoffregen's Teensy libraries and is therefore licensed under PJRC's license. This has been clearly indicated in the header of these files.
+14 -9
View File
@@ -1,7 +1,7 @@
# Avoid lengthy LLVM rebuilds on each newly pushed branch. Pull requests will
# be built anyway.
trigger:
- master
- release
- dev
jobs:
@@ -12,22 +12,27 @@ jobs:
steps:
- task: GoTool@0
inputs:
version: '1.14.1'
version: '1.15'
- checkout: self
- task: CacheBeta@0
fetchDepth: 1
- task: Cache@2
displayName: Cache LLVM source
inputs:
key: llvm-source-10-windows-v0
key: llvm-source-10-windows-v1
path: llvm-project
- task: Bash@3
displayName: Download LLVM source
inputs:
targetType: inline
script: make llvm-source
script: |
make llvm-source
# Workaround for bad symlinks:
# https://github.com/microsoft/azure-pipelines-tasks/issues/13418
rm -f llvm-project/libcxx/test/std/input.output/filesystems/Inputs/static_test_env/bad_symlink
- task: CacheBeta@0
displayName: Cache LLVM build
inputs:
key: llvm-build-10-windows-v0
key: llvm-build-10-windows-v1
path: llvm-build
- task: Bash@3
displayName: Build LLVM
@@ -43,11 +48,11 @@ jobs:
displayName: Install QEMU
inputs:
targetType: inline
script: choco install qemu
script: choco install qemu --version=2020.06.12
- task: CacheBeta@0
displayName: Cache wasi-libc sysroot
inputs:
key: wasi-libc-sysroot-v2
key: wasi-libc-sysroot-v3
path: lib/wasi-libc/sysroot
- task: Bash@3
displayName: Build wasi-libc
@@ -80,4 +85,4 @@ jobs:
script: |
export PATH="$PATH:./llvm-build/bin:/c/Program Files/qemu"
unset GOROOT
make smoketest TINYGO=build/tinygo AVR=0
make smoketest TINYGO=build/tinygo AVR=0 XTENSA=0
+329 -22
View File
@@ -4,11 +4,14 @@
package builder
import (
"debug/elf"
"encoding/binary"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strconv"
"strings"
@@ -16,26 +19,40 @@ import (
"github.com/tinygo-org/tinygo/compiler"
"github.com/tinygo-org/tinygo/goenv"
"github.com/tinygo-org/tinygo/interp"
"github.com/tinygo-org/tinygo/stacksize"
"github.com/tinygo-org/tinygo/transform"
"tinygo.org/x/go-llvm"
)
// BuildResult is the output of a build. This includes the binary itself and
// some other metadata that is obtained while building the binary.
type BuildResult struct {
// A path to the output binary. It will be removed after Build returns, so
// if it should be kept it must be copied or moved away.
Binary string
// The directory of the main package. This is useful for testing as the test
// binary must be run in the directory of the tested package.
MainDir string
}
// Build performs a single package to executable Go build. It takes in a package
// name, an output path, and set of compile options and from that it manages the
// whole compilation process.
//
// 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(string) error) error {
func Build(pkgName, outpath string, config *compileopts.Config, action func(BuildResult) error) error {
// Compile Go code to IR.
machine, err := compiler.NewTargetMachine(config)
if err != nil {
return err
}
mod, extraFiles, extraLDFlags, errs := compiler.Compile(pkgName, machine, config)
buildOutput, errs := compiler.Compile(pkgName, machine, config)
if errs != nil {
return newMultiError(errs)
}
mod := buildOutput.Mod
if config.Options.PrintIR {
fmt.Println("; Generated LLVM IR:")
@@ -62,7 +79,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
// keep functions interoperable, pass int64 types as pointers to
// stack-allocated values.
// Use -wasm-abi=generic to disable this behaviour.
if config.Options.WasmAbi == "js" && strings.HasPrefix(config.Triple(), "wasm") {
if config.WasmAbi() == "js" {
err := transform.ExternalInt64AsPtr(mod)
if err != nil {
return err
@@ -73,8 +90,15 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
// exactly.
errs = nil
switch config.Options.Opt {
case "none", "0":
errs = transform.Optimize(mod, config, 0, 0, 0) // -O0
/*
Currently, turning optimizations off causes compile failures.
We rely on the optimizer removing some dead symbols.
Avoid providing an option that does not work right now.
In the future once everything has been fixed we can re-enable this.
case "none", "0":
errs = transform.Optimize(mod, config, 0, 0, 0) // -O0
*/
case "1":
errs = transform.Optimize(mod, config, 1, 0, 0) // -O1
case "2":
@@ -93,16 +117,22 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
return errors.New("verification failure after LLVM optimization passes")
}
// On the AVR, pointers can point either to flash or to RAM, but we don't
// know. As a temporary fix, load all global variables in RAM.
// In the future, there should be a compiler pass that determines which
// pointers are flash and which are in RAM so that pointers can have a
// correct address space parameter (address space 1 is for flash).
if strings.HasPrefix(config.Triple(), "avr") {
transform.NonConstGlobals(mod)
if err := llvm.VerifyModule(mod, llvm.PrintMessageAction); err != nil {
return errors.New("verification error after making all globals non-constant on AVR")
}
// LLVM 11 by default tries to emit tail calls (even with the target feature
// disabled) unless it is explicitly disabled with a function attribute.
// This is a problem, as it tries to emit them and prints an error when it
// can't with this feature disabled.
// Because as of september 2020 tail calls are not yet widely supported,
// they need to be disabled until they are widely supported (at which point
// the +tail-call target feautre can be set).
if strings.HasPrefix(config.Triple(), "wasm") {
transform.DisableTailCalls(mod)
}
// Make sure stack sizes are loaded from a separate section so they can be
// modified after linking.
var stackSizeLoads []string
if config.AutomaticStackSize() {
stackSizeLoads = transform.CreateStackSizeLoads(mod, config)
}
// Generate output.
@@ -178,7 +208,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
}
// Compile C files in packages.
for i, file := range extraFiles {
for i, file := range buildOutput.ExtraFiles {
outpath := filepath.Join(dir, "pkg"+strconv.Itoa(i)+"-"+filepath.Base(file)+".o")
err := runCCompiler(config.Target.Compiler, append(config.CFlags(), "-c", "-o", outpath, file)...)
if err != nil {
@@ -187,8 +217,8 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
ldflags = append(ldflags, outpath)
}
if len(extraLDFlags) > 0 {
ldflags = append(ldflags, extraLDFlags...)
if len(buildOutput.ExtraLDFlags) > 0 {
ldflags = append(ldflags, buildOutput.ExtraLDFlags...)
}
// Link the object files together.
@@ -197,6 +227,26 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
return &commandError{"failed to link", executable, err}
}
var calculatedStacks []string
var stackSizes map[string]functionStackSize
if config.Options.PrintStacks || config.AutomaticStackSize() {
// Try to determine stack sizes at compile time.
// Don't do this by default as it usually doesn't work on
// unsupported architectures.
calculatedStacks, stackSizes, err = determineStackSizes(mod, executable)
if err != nil {
return err
}
}
if config.AutomaticStackSize() {
// Modify the .tinygo_stacksizes section that contains a stack size
// for each goroutine.
err = modifyStackSizes(executable, stackSizeLoads, stackSizes)
if err != nil {
return fmt.Errorf("could not modify stack sizes: %w", err)
}
}
if config.Options.PrintSizes == "short" || config.Options.PrintSizes == "full" {
sizes, err := loadProgramSize(executable)
if err != nil {
@@ -216,21 +266,278 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(stri
}
}
// Print goroutine stack sizes, as far as possible.
if config.Options.PrintStacks {
printStacks(calculatedStacks, stackSizes)
}
// Get an Intel .hex file or .bin file from the .elf file.
if outext == ".hex" || outext == ".bin" || outext == ".gba" {
outputBinaryFormat := config.BinaryFormat(outext)
switch outputBinaryFormat {
case "elf":
// do nothing, file is already in ELF format
case "hex", "bin":
// Extract raw binary, either encoding it as a hex file or as a raw
// firmware file.
tmppath = filepath.Join(dir, "main"+outext)
err := objcopy(executable, tmppath)
err := objcopy(executable, tmppath, outputBinaryFormat)
if err != nil {
return err
}
} else if outext == ".uf2" {
case "uf2":
// Get UF2 from the .elf file.
tmppath = filepath.Join(dir, "main"+outext)
err := convertELFFileToUF2File(executable, tmppath, config.Target.UF2FamilyID)
if err != nil {
return err
}
case "esp32", "esp8266":
// Special format for the ESP family of chips (parsed by the ROM
// bootloader).
tmppath = filepath.Join(dir, "main"+outext)
err := makeESPFirmareImage(executable, tmppath, outputBinaryFormat)
if err != nil {
return err
}
default:
return fmt.Errorf("unknown output binary format: %s", outputBinaryFormat)
}
return action(BuildResult{
Binary: tmppath,
MainDir: buildOutput.MainDir,
})
}
}
// functionStackSizes keeps stack size information about a single function
// (usually a goroutine).
type functionStackSize struct {
humanName string
stackSize uint64
stackSizeType stacksize.SizeType
missingStackSize *stacksize.CallNode
}
// determineStackSizes tries to determine the stack sizes of all started
// goroutines and of the reset vector. The LLVM module is necessary to find
// functions that call a function pointer.
func determineStackSizes(mod llvm.Module, executable string) ([]string, map[string]functionStackSize, error) {
var callsIndirectFunction []string
gowrappers := []string{}
gowrapperNames := make(map[string]string)
for fn := mod.FirstFunction(); !fn.IsNil(); fn = llvm.NextFunction(fn) {
// Determine which functions call a function pointer.
for bb := fn.FirstBasicBlock(); !bb.IsNil(); bb = llvm.NextBasicBlock(bb) {
for inst := bb.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) {
if inst.IsACallInst().IsNil() {
continue
}
if callee := inst.CalledValue(); callee.IsAFunction().IsNil() && callee.IsAInlineAsm().IsNil() {
callsIndirectFunction = append(callsIndirectFunction, fn.Name())
}
}
}
// Get a list of "go wrappers", small wrapper functions that decode
// parameters when starting a new goroutine.
attr := fn.GetStringAttributeAtIndex(-1, "tinygo-gowrapper")
if !attr.IsNil() {
gowrappers = append(gowrappers, fn.Name())
gowrapperNames[fn.Name()] = attr.GetStringValue()
}
}
sort.Strings(gowrappers)
// Load the ELF binary.
f, err := elf.Open(executable)
if err != nil {
return nil, nil, fmt.Errorf("could not load executable for stack size analysis: %w", err)
}
defer f.Close()
// Determine the frame size of each function (if available) and the callgraph.
functions, err := stacksize.CallGraph(f, callsIndirectFunction)
if err != nil {
return nil, nil, fmt.Errorf("could not parse executable for stack size analysis: %w", err)
}
// Goroutines need to be started and finished and take up some stack space
// that way. This can be measured by measuing the stack size of
// tinygo_startTask.
if numFuncs := len(functions["tinygo_startTask"]); numFuncs != 1 {
return nil, nil, fmt.Errorf("expected exactly one definition of tinygo_startTask, got %d", numFuncs)
}
baseStackSize, baseStackSizeType, baseStackSizeFailedAt := functions["tinygo_startTask"][0].StackSize()
sizes := make(map[string]functionStackSize)
// Add the reset handler function, for convenience. The reset handler runs
// startup code and the scheduler. The listed stack size is not the full
// stack size: interrupts are not counted.
var resetFunction string
switch f.Machine {
case elf.EM_ARM:
// Note: all interrupts happen on this stack so the real size is bigger.
resetFunction = "Reset_Handler"
}
if resetFunction != "" {
funcs := functions[resetFunction]
if len(funcs) != 1 {
return nil, nil, fmt.Errorf("expected exactly one definition of %s in the callgraph, found %d", resetFunction, len(funcs))
}
stackSize, stackSizeType, missingStackSize := funcs[0].StackSize()
sizes[resetFunction] = functionStackSize{
stackSize: stackSize,
stackSizeType: stackSizeType,
missingStackSize: missingStackSize,
humanName: resetFunction,
}
}
// Add all goroutine wrapper functions.
for _, name := range gowrappers {
funcs := functions[name]
if len(funcs) != 1 {
return nil, nil, fmt.Errorf("expected exactly one definition of %s in the callgraph, found %d", name, len(funcs))
}
humanName := gowrapperNames[name]
if humanName == "" {
humanName = name // fallback
}
stackSize, stackSizeType, missingStackSize := funcs[0].StackSize()
if baseStackSizeType != stacksize.Bounded {
// It was not possible to determine the stack size at compile time
// because tinygo_startTask does not have a fixed stack size. This
// can happen when using -opt=1.
stackSizeType = baseStackSizeType
missingStackSize = baseStackSizeFailedAt
} else if stackSize < baseStackSize {
// This goroutine has a very small stack, but still needs to fit all
// registers to start and suspend the goroutine. Otherwise a stack
// overflow will occur even before the goroutine is started.
stackSize = baseStackSize
}
sizes[name] = functionStackSize{
stackSize: stackSize,
stackSizeType: stackSizeType,
missingStackSize: missingStackSize,
humanName: humanName,
}
}
if resetFunction != "" {
return append([]string{resetFunction}, gowrappers...), sizes, nil
}
return gowrappers, sizes, nil
}
// modifyStackSizes modifies the .tinygo_stacksizes section with the updated
// stack size information. Before this modification, all stack sizes in the
// section assume the default stack size (which is relatively big).
func modifyStackSizes(executable string, stackSizeLoads []string, stackSizes map[string]functionStackSize) error {
fp, err := os.OpenFile(executable, os.O_RDWR, 0)
if err != nil {
return err
}
defer fp.Close()
elfFile, err := elf.NewFile(fp)
if err != nil {
return err
}
section := elfFile.Section(".tinygo_stacksizes")
if section == nil {
return errors.New("could not find .tinygo_stacksizes section")
}
if section.Size != section.FileSize {
// Sanity check.
return fmt.Errorf("expected .tinygo_stacksizes to have identical size and file size, got %d and %d", section.Size, section.FileSize)
}
// Read all goroutine stack sizes.
data := make([]byte, section.Size)
_, err = fp.ReadAt(data, int64(section.Offset))
if err != nil {
return err
}
if len(stackSizeLoads)*4 != len(data) {
// Note: while AVR should use 2 byte stack sizes, even 64-bit platforms
// should probably stick to 4 byte stack sizes as a larger than 4GB
// stack doesn't make much sense.
return errors.New("expected 4 byte stack sizes")
}
// Modify goroutine stack sizes with a compile-time known worst case stack
// size.
for i, name := range stackSizeLoads {
fn, ok := stackSizes[name]
if !ok {
return fmt.Errorf("could not find symbol %s in ELF file", name)
}
if fn.stackSizeType == stacksize.Bounded {
stackSize := uint32(fn.stackSize)
// Adding 4 for the stack canary. Even though the size may be
// automatically determined, stack overflow checking is still
// important as the stack size cannot be determined for all
// goroutines.
stackSize += 4
// Add stack size used by interrupts.
switch elfFile.Machine {
case elf.EM_ARM:
// On Cortex-M (assumed here), this stack size is 8 words or 32
// bytes. This is only to store the registers that the interrupt
// may modify, the interrupt will switch to the interrupt stack
// (MSP).
// Some background:
// https://interrupt.memfault.com/blog/cortex-m-rtos-context-switching
stackSize += 32
}
// Finally write the stack size to the binary.
binary.LittleEndian.PutUint32(data[i*4:], stackSize)
}
}
// Write back the modified stack sizes.
_, err = fp.WriteAt(data, int64(section.Offset))
if err != nil {
return err
}
return nil
}
// printStacks prints the maximum stack depth for functions that are started as
// goroutines. Stack sizes cannot always be determined statically, in particular
// recursive functions and functions that call interface methods or function
// pointers may have an unknown stack depth (depending on what the optimizer
// manages to optimize away).
//
// It might print something like the following:
//
// function stack usage (in bytes)
// Reset_Handler 316
// examples/blinky2.led1 92
// runtime.run$1 300
func printStacks(calculatedStacks []string, stackSizes map[string]functionStackSize) {
// Print the sizes of all stacks.
fmt.Printf("%-32s %s\n", "function", "stack usage (in bytes)")
for _, name := range calculatedStacks {
fn := stackSizes[name]
switch fn.stackSizeType {
case stacksize.Bounded:
fmt.Printf("%-32s %d\n", fn.humanName, fn.stackSize)
case stacksize.Unknown:
fmt.Printf("%-32s unknown, %s does not have stack frame information\n", fn.humanName, fn.missingStackSize)
case stacksize.Recursive:
fmt.Printf("%-32s recursive, %s may call itself\n", fn.humanName, fn.missingStackSize)
case stacksize.IndirectCall:
fmt.Printf("%-32s unknown, %s calls a function pointer\n", fn.humanName, fn.missingStackSize)
}
return action(tmppath)
}
}
+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 > 14 {
return nil, fmt.Errorf("requires go version 1.11, 1.12, 1.13, or 1.14, got go%d.%d", major, minor)
if major != 1 || minor < 11 || minor > 15 {
return nil, fmt.Errorf("requires go version 1.11 through 1.15, got go%d.%d", major, minor)
}
clangHeaderPath := getClangHeaderPath(goenv.Get("TINYGOROOT"))
return &compileopts.Config{
+29 -9
View File
@@ -6,6 +6,9 @@ import (
"os/exec"
"path/filepath"
"sort"
"strings"
"tinygo.org/x/go-llvm"
)
// getClangHeaderPath returns the path to the built-in Clang headers. It tries
@@ -26,6 +29,7 @@ func getClangHeaderPath(TINYGOROOT string) string {
// It looks like we are built with a system-installed LLVM. Do a last
// attempt: try to use Clang headers relative to the clang binary.
llvmMajor := strings.Split(llvm.Version, ".")[0]
for _, cmdName := range commands["clang"] {
binpath, err := exec.LookPath(cmdName)
if err == nil {
@@ -40,22 +44,38 @@ func getClangHeaderPath(TINYGOROOT string) string {
// Example executable:
// /usr/lib/llvm-9/bin/clang
// Example include path:
// /usr/lib/llvm-9/lib/clang/9.0.1/include/
// /usr/lib/llvm-9/lib64/clang/9.0.1/include/
llvmRoot := filepath.Dir(filepath.Dir(binpath))
clangVersionRoot := filepath.Join(llvmRoot, "lib", "clang")
dirs, err := ioutil.ReadDir(clangVersionRoot)
if err != nil {
clangVersionRoot := filepath.Join(llvmRoot, "lib64", "clang")
dirs64, err64 := ioutil.ReadDir(clangVersionRoot)
// Example include path:
// /usr/lib/llvm-9/lib/clang/9.0.1/include/
clangVersionRoot = filepath.Join(llvmRoot, "lib", "clang")
dirs32, err32 := ioutil.ReadDir(clangVersionRoot)
if err64 != nil && err32 != nil {
// Unexpected.
continue
}
dirnames := make([]string, len(dirs))
for i, d := range dirs {
dirnames[i] = d.Name()
dirnames := make([]string, len(dirs64)+len(dirs32))
dirCount := 0
for _, d := range dirs32 {
name := d.Name()
if name == llvmMajor || strings.HasPrefix(name, llvmMajor+".") {
dirnames[dirCount] = filepath.Join(llvmRoot, "lib", "clang", name)
dirCount++
}
}
for _, d := range dirs64 {
name := d.Name()
if name == llvmMajor || strings.HasPrefix(name, llvmMajor+".") {
dirnames[dirCount] = filepath.Join(llvmRoot, "lib64", "clang", name)
dirCount++
}
}
sort.Strings(dirnames)
// Check for the highest version first.
for i := len(dirnames) - 1; i >= 0; i-- {
path := filepath.Join(clangVersionRoot, dirnames[i], "include")
for i := dirCount - 1; i >= 0; i-- {
path := filepath.Join(dirnames[i], "include")
_, err := os.Stat(filepath.Join(path, "stdint.h"))
if err == nil {
return path
+153
View File
@@ -0,0 +1,153 @@
package builder
// This file implements support for writing ESP image files. These image files
// are read by the ROM bootloader so have to be in a particular format.
//
// In the future, it may be necessary to implement support for other image
// formats, such as the ESP8266 image formats (again, used by the ROM bootloader
// to load the firmware).
import (
"bytes"
"crypto/sha256"
"debug/elf"
"encoding/binary"
"fmt"
"io/ioutil"
"sort"
)
type espImageSegment struct {
addr uint32
data []byte
}
// makeESPFirmare converts an input ELF file to an image file for an ESP32 or
// ESP8266 chip. This is a special purpose image format just for the ESP chip
// family, and is parsed by the on-chip mask ROM bootloader.
//
// The following documentation has been used:
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format
// https://github.com/espressif/esp-idf/blob/8fbb63c2a701c22ccf4ce249f43aded73e134a34/components/bootloader_support/include/esp_image_format.h#L58
// https://github.com/espressif/esptool/blob/master/esptool.py
func makeESPFirmareImage(infile, outfile, format string) error {
inf, err := elf.Open(infile)
if err != nil {
return err
}
defer inf.Close()
// Load all segments to be written to the image. These are actually ELF
// sections, not true ELF segments (similar to how esptool does it).
var segments []*espImageSegment
for _, section := range inf.Sections {
if section.Type != elf.SHT_PROGBITS || section.Size == 0 || section.Flags&elf.SHF_ALLOC == 0 {
continue
}
data, err := section.Data()
if err != nil {
return fmt.Errorf("failed to read section data: %w", err)
}
for len(data)%4 != 0 {
// Align segment to 4 bytes.
data = append(data, 0)
}
if uint64(uint32(section.Addr)) != section.Addr {
return fmt.Errorf("section address too big: 0x%x", section.Addr)
}
segments = append(segments, &espImageSegment{
addr: uint32(section.Addr),
data: data,
})
}
// Sort the segments by address. This is what esptool does too.
sort.SliceStable(segments, func(i, j int) bool { return segments[i].addr < segments[j].addr })
// Calculate checksum over the segment data. This is used in the image
// footer.
checksum := uint8(0xef)
for _, segment := range segments {
for _, b := range segment.data {
checksum ^= b
}
}
// Write first to an in-memory buffer, primarily so that we can easily
// calculate a hash over the entire image.
// An added benefit is that we don't need to check for errors all the time.
outf := &bytes.Buffer{}
// Image header.
switch format {
case "esp32":
// Header format:
// https://github.com/espressif/esp-idf/blob/8fbb63c2/components/bootloader_support/include/esp_image_format.h#L58
binary.Write(outf, binary.LittleEndian, struct {
magic uint8
segment_count uint8
spi_mode uint8
spi_speed_size uint8
entry_addr uint32
wp_pin uint8
spi_pin_drv [3]uint8
reserved [11]uint8
hash_appended bool
}{
magic: 0xE9,
segment_count: byte(len(segments)),
spi_mode: 0, // irrelevant, replaced by esptool when flashing
spi_speed_size: 0, // spi_speed, spi_size: replaced by esptool when flashing
entry_addr: uint32(inf.Entry),
wp_pin: 0xEE, // disable WP pin
hash_appended: true, // add a SHA256 hash
})
case "esp8266":
// Header format:
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format
// Basically a truncated version of the ESP32 header.
binary.Write(outf, binary.LittleEndian, struct {
magic uint8
segment_count uint8
spi_mode uint8
spi_speed_size uint8
entry_addr uint32
}{
magic: 0xE9,
segment_count: byte(len(segments)),
spi_mode: 0, // irrelevant, replaced by esptool when flashing
spi_speed_size: 0x20, // spi_speed, spi_size: replaced by esptool when flashing
entry_addr: uint32(inf.Entry),
})
default:
return fmt.Errorf("builder: unknown binary format %#v, expected esp32 or esp8266", format)
}
// Write all segments to the image.
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format#segment
for _, segment := range segments {
binary.Write(outf, binary.LittleEndian, struct {
addr uint32
length uint32
}{
addr: segment.addr,
length: uint32(len(segment.data)),
})
outf.Write(segment.data)
}
// Footer, including checksum.
// The entire image size must be a multiple of 16, so pad the image to one
// byte less than that before writing the checksum.
outf.Write(make([]byte, 15-outf.Len()%16))
outf.WriteByte(checksum)
if format == "esp32" {
// SHA256 hash (to protect against image corruption, not for security).
hash := sha256.Sum256(outf.Bytes())
outf.Write(hash[:])
}
// Write the image to the output file.
return ioutil.WriteFile(outfile, outf.Bytes(), 0666)
}
+3
View File
@@ -74,6 +74,9 @@ func (l *Library) Load(target string) (path string, err error) {
if strings.HasPrefix(target, "riscv32-") {
args = append(args, "-march=rv32imac", "-mabi=ilp32", "-fforce-enable-int128")
}
if strings.HasPrefix(target, "riscv64-") {
args = append(args, "-march=rv64gc", "-mabi=lp64")
}
// Compile all sources.
var objs []string
+26 -15
View File
@@ -4,12 +4,15 @@ import (
"debug/elf"
"io/ioutil"
"os"
"path/filepath"
"sort"
"github.com/marcinbor85/gohex"
)
// maxPadBytes is the maximum allowed bytes to be padded in a rom extraction
// this value is currently defined by Nintendo Switch Page Alignment (4096 bytes)
const maxPadBytes = 4095
// objcopyError is an error returned by functions that act like objcopy.
type objcopyError struct {
Op string
@@ -58,7 +61,7 @@ func extractROM(path string) (uint64, []byte, error) {
progs := make(progSlice, 0, 2)
for _, prog := range f.Progs {
if prog.Type != elf.PT_LOAD || prog.Filesz == 0 {
if prog.Type != elf.PT_LOAD || prog.Filesz == 0 || prog.Off == 0 {
continue
}
progs = append(progs, prog)
@@ -70,8 +73,19 @@ func extractROM(path string) (uint64, []byte, error) {
var rom []byte
for _, prog := range progs {
romEnd := progs[0].Paddr + uint64(len(rom))
if prog.Paddr > romEnd && prog.Paddr < romEnd+16 {
// Sometimes, the linker seems to insert a bit of padding between
// segments. Simply zero-fill these parts.
rom = append(rom, make([]byte, prog.Paddr-romEnd)...)
}
if prog.Paddr != progs[0].Paddr+uint64(len(rom)) {
return 0, nil, objcopyError{"ROM segments are non-contiguous: " + path, nil}
diff := prog.Paddr - (progs[0].Paddr + uint64(len(rom)))
if diff > maxPadBytes {
return 0, nil, objcopyError{"ROM segments are non-contiguous: " + path, nil}
}
// Pad the difference
rom = append(rom, make([]byte, diff)...)
}
data, err := ioutil.ReadAll(prog.Open())
if err != nil {
@@ -93,7 +107,7 @@ func extractROM(path string) (uint64, []byte, error) {
// objcopy converts an ELF file to a different (simpler) output file format:
// .bin or .hex. It extracts only the .text section.
func objcopy(infile, outfile string) error {
func objcopy(infile, outfile, binaryFormat string) error {
f, err := os.OpenFile(outfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
return err
@@ -107,23 +121,20 @@ func objcopy(infile, outfile string) error {
}
// Write to the file, in the correct format.
switch filepath.Ext(outfile) {
case ".gba":
// The address is not stored in a .gba file.
_, err := f.Write(data)
return err
case ".bin":
// The address is not stored in a .bin file (therefore you
// should use .hex files in most cases).
_, err := f.Write(data)
return err
case ".hex":
switch binaryFormat {
case "hex":
// Intel hex file, includes the firmware start address.
mem := gohex.NewMemory()
err := mem.AddBinary(uint32(addr), data)
if err != nil {
return objcopyError{"failed to create .hex file", err}
}
return mem.DumpIntelHex(f, 16)
case "bin":
// The start address is not stored in raw firmware files (therefore you
// should use .hex files in most cases).
_, err := f.Write(data)
return err
default:
panic("unreachable")
}
+1 -1
View File
@@ -1,5 +1,5 @@
// +build !byollvm
// +build !llvm9
// +build !llvm9,!llvm11
package cgo
+14
View File
@@ -0,0 +1,14 @@
// +build !byollvm
// +build llvm11
package cgo
/*
#cgo linux CFLAGS: -I/usr/lib/llvm-11/include
#cgo darwin CFLAGS: -I/usr/local/opt/llvm@11/include
#cgo freebsd CFLAGS: -I/usr/local/llvm11/include
#cgo linux LDFLAGS: -L/usr/lib/llvm-11/lib -lclang
#cgo darwin LDFLAGS: -L/usr/local/opt/llvm@11/lib -lclang -lffi
#cgo freebsd LDFLAGS: -L/usr/local/llvm11/lib -lclang
*/
import "C"
+60 -3
View File
@@ -118,12 +118,12 @@ func (c *Config) NeedsStackObjects() bool {
switch c.GC() {
case "conservative", "extalloc":
for _, tag := range c.BuildTags() {
if tag == "baremetal" {
return false
if tag == "wasm" {
return true
}
}
return true
return false
default:
return false
}
@@ -164,6 +164,16 @@ func (c *Config) PanicStrategy() string {
return c.Options.PanicStrategy
}
// AutomaticStackSize returns whether goroutine stack sizes should be determined
// automatically at compile time, if possible. If it is false, no attempt is
// made.
func (c *Config) AutomaticStackSize() bool {
if c.Target.AutoStackSize != nil && c.Scheduler() == "tasks" {
return *c.Target.AutoStackSize
}
return false
}
// CFlags returns the flags to pass to the C compiler. This is necessary for CGo
// preprocessing.
func (c *Config) CFlags() []string {
@@ -176,6 +186,9 @@ func (c *Config) CFlags() []string {
cflags = append(cflags, "-nostdlibinc", "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "picolibc", "newlib", "libc", "include"))
cflags = append(cflags, "-I"+filepath.Join(root, "lib/picolibc-include"))
}
if c.Debug() {
cflags = append(cflags, "-g")
}
return cflags
}
@@ -226,6 +239,31 @@ func (c *Config) Debug() bool {
return c.Options.Debug
}
// BinaryFormat returns an appropriate binary format, based on the file
// extension and the configured binary format in the target JSON file.
func (c *Config) BinaryFormat(ext string) string {
switch ext {
case ".bin", ".gba", ".nro":
// The simplest format possible: dump everything in a raw binary file.
if c.Target.BinaryFormat != "" {
return c.Target.BinaryFormat
}
return "bin"
case ".hex":
// Similar to bin, but includes the start address and is thus usually a
// better format.
return "hex"
case ".uf2":
// Special purpose firmware format, mainly used on Adafruit boards.
// More information:
// https://github.com/Microsoft/uf2
return "uf2"
default:
// Use the ELF format for unrecognized file formats.
return "elf"
}
}
// Programmer returns the flash method and OpenOCD interface name given a
// particular configuration. It may either be all configured in the target JSON
// file or be modified using the -programmmer command-line option.
@@ -281,6 +319,25 @@ func (c *Config) CodeModel() string {
return "default"
}
// RelocationModel returns the relocation model in use on this platform. Valid
// values are "static", "pic", "dynamicnopic".
func (c *Config) RelocationModel() string {
if c.Target.RelocationModel != "" {
return c.Target.RelocationModel
}
return "static"
}
// WasmAbi returns the WASM ABI which is specified in the target JSON file, and
// the value is overridden by `-wasm-abi` flag if it is provided
func (c *Config) WasmAbi() string {
if c.Options.WasmAbi != "" {
return c.Options.WasmAbi
}
return c.Target.WasmAbi
}
type TestConfig struct {
CompileTestBinary bool
// TODO: Filter the test functions to run, include verbose flag, etc
+1
View File
@@ -25,6 +25,7 @@ type Options struct {
VerifyIR bool
Debug bool
PrintSizes string
PrintStacks bool
CFlags []string
LDFlags []string
Tags string
+66 -99
View File
@@ -8,6 +8,7 @@ import (
"io"
"os"
"path/filepath"
"reflect"
"runtime"
"strings"
@@ -33,11 +34,13 @@ type TargetSpec struct {
Linker string `json:"linker"`
RTLib string `json:"rtlib"` // compiler runtime library (libgcc, compiler-rt)
Libc string `json:"libc"`
AutoStackSize *bool `json:"automatic-stack-size"` // Determine stack size automatically at compile time.
DefaultStackSize uint64 `json:"default-stack-size"` // Default stack size if the size couldn't be determined at compile time.
CFlags []string `json:"cflags"`
LDFlags []string `json:"ldflags"`
LinkerScript string `json:"linkerscript"`
ExtraFiles []string `json:"extra-files"`
Emulator []string `json:"emulator"`
Emulator []string `json:"emulator" override:"copy"` // inherited Emulator must not be append
FlashCommand string `json:"flash-command"`
GDB string `json:"gdb"`
PortReset string `json:"flash-1200-bps-reset"`
@@ -45,94 +48,56 @@ type TargetSpec struct {
FlashVolume string `json:"msd-volume-name"`
FlashFilename string `json:"msd-firmware-name"`
UF2FamilyID string `json:"uf2-family-id"`
BinaryFormat string `json:"binary-format"`
OpenOCDInterface string `json:"openocd-interface"`
OpenOCDTarget string `json:"openocd-target"`
OpenOCDTransport string `json:"openocd-transport"`
JLinkDevice string `json:"jlink-device"`
CodeModel string `json:"code-model"`
RelocationModel string `json:"relocation-model"`
WasmAbi string `json:"wasm-abi"`
}
// copyProperties copies all properties that are set in spec2 into itself.
func (spec *TargetSpec) copyProperties(spec2 *TargetSpec) {
// TODO: simplify this using reflection? Inherits and BuildTags are special
// cases, but the rest can simply be copied if set.
spec.Inherits = append(spec.Inherits, spec2.Inherits...)
if spec2.Triple != "" {
spec.Triple = spec2.Triple
}
if spec2.CPU != "" {
spec.CPU = spec2.CPU
}
spec.Features = append(spec.Features, spec2.Features...)
if spec2.GOOS != "" {
spec.GOOS = spec2.GOOS
}
if spec2.GOARCH != "" {
spec.GOARCH = spec2.GOARCH
}
spec.BuildTags = append(spec.BuildTags, spec2.BuildTags...)
if spec2.GC != "" {
spec.GC = spec2.GC
}
if spec2.Scheduler != "" {
spec.Scheduler = spec2.Scheduler
}
if spec2.Compiler != "" {
spec.Compiler = spec2.Compiler
}
if spec2.Linker != "" {
spec.Linker = spec2.Linker
}
if spec2.RTLib != "" {
spec.RTLib = spec2.RTLib
}
if spec2.Libc != "" {
spec.Libc = spec2.Libc
}
spec.CFlags = append(spec.CFlags, spec2.CFlags...)
spec.LDFlags = append(spec.LDFlags, spec2.LDFlags...)
if spec2.LinkerScript != "" {
spec.LinkerScript = spec2.LinkerScript
}
spec.ExtraFiles = append(spec.ExtraFiles, spec2.ExtraFiles...)
if len(spec2.Emulator) != 0 {
spec.Emulator = spec2.Emulator
}
if spec2.FlashCommand != "" {
spec.FlashCommand = spec2.FlashCommand
}
if spec2.GDB != "" {
spec.GDB = spec2.GDB
}
if spec2.PortReset != "" {
spec.PortReset = spec2.PortReset
}
if spec2.FlashMethod != "" {
spec.FlashMethod = spec2.FlashMethod
}
if spec2.FlashVolume != "" {
spec.FlashVolume = spec2.FlashVolume
}
if spec2.FlashFilename != "" {
spec.FlashFilename = spec2.FlashFilename
}
if spec2.UF2FamilyID != "" {
spec.UF2FamilyID = spec2.UF2FamilyID
}
if spec2.OpenOCDInterface != "" {
spec.OpenOCDInterface = spec2.OpenOCDInterface
}
if spec2.OpenOCDTarget != "" {
spec.OpenOCDTarget = spec2.OpenOCDTarget
}
if spec2.OpenOCDTransport != "" {
spec.OpenOCDTransport = spec2.OpenOCDTransport
}
if spec2.JLinkDevice != "" {
spec.JLinkDevice = spec2.JLinkDevice
}
if spec2.CodeModel != "" {
spec.CodeModel = spec2.CodeModel
// overrideProperties overrides all properties that are set in child into itself using reflection.
func (spec *TargetSpec) overrideProperties(child *TargetSpec) {
specType := reflect.TypeOf(spec).Elem()
specValue := reflect.ValueOf(spec).Elem()
childValue := reflect.ValueOf(child).Elem()
for i := 0; i < specType.NumField(); i++ {
field := specType.Field(i)
src := childValue.Field(i)
dst := specValue.Field(i)
switch kind := field.Type.Kind(); kind {
case reflect.String: // for strings, just copy the field of child to spec if not empty
if src.Len() > 0 {
dst.Set(src)
}
case reflect.Uint, reflect.Uint32, reflect.Uint64: // for Uint, copy if not zero
if src.Uint() != 0 {
dst.Set(src)
}
case reflect.Ptr: // for pointers, copy if not nil
if !src.IsNil() {
dst.Set(src)
}
case reflect.Slice: // for slices...
if src.Len() > 0 { // ... if not empty ...
switch tag := field.Tag.Get("override"); tag {
case "copy":
// copy the field of child to spec
dst.Set(src)
case "append", "":
// or append the field of child to spec
dst.Set(reflect.AppendSlice(src, dst))
default:
panic("override mode must be 'copy' or 'append' (default). I don't know how to '" + tag + "'.")
}
}
default:
panic("unknown field type : " + kind.String())
}
}
}
@@ -181,11 +146,11 @@ func (spec *TargetSpec) resolveInherits() error {
if err != nil {
return err
}
newSpec.copyProperties(subtarget)
newSpec.overrideProperties(subtarget)
}
// When all properties are loaded, make sure they are properly inherited.
newSpec.copyProperties(spec)
newSpec.overrideProperties(spec)
*spec = *newSpec
return nil
@@ -251,6 +216,7 @@ func LoadTarget(target string) (*TargetSpec, error) {
}
goarch := map[string]string{ // map from LLVM arch to Go arch
"i386": "386",
"i686": "386",
"x86_64": "amd64",
"aarch64": "arm64",
"armv7": "arm",
@@ -266,39 +232,40 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
// No target spec available. Use the default one, useful on most systems
// with a regular OS.
spec := TargetSpec{
Triple: triple,
GOOS: goos,
GOARCH: goarch,
BuildTags: []string{goos, goarch},
Compiler: "clang",
Linker: "cc",
CFlags: []string{"--target=" + triple},
GDB: "gdb",
PortReset: "false",
FlashMethod: "native",
Triple: triple,
GOOS: goos,
GOARCH: goarch,
BuildTags: []string{goos, goarch},
Compiler: "clang",
Linker: "cc",
CFlags: []string{"--target=" + triple},
GDB: "gdb",
PortReset: "false",
}
if goos == "darwin" {
spec.LDFlags = append(spec.LDFlags, "-Wl,-dead_strip")
} else {
spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie
}
if goarch != "wasm" {
spec.ExtraFiles = append(spec.ExtraFiles, "src/runtime/gc_"+goarch+".S")
}
if goarch != runtime.GOARCH {
// Some educated guesses as to how to invoke helper programs.
spec.GDB = "gdb-multiarch"
if goarch == "arm" && goos == "linux" {
spec.CFlags = append(spec.CFlags, "--sysroot=/usr/arm-linux-gnueabihf")
spec.Linker = "arm-linux-gnueabihf-gcc"
spec.GDB = "arm-linux-gnueabihf-gdb"
spec.Emulator = []string{"qemu-arm", "-L", "/usr/arm-linux-gnueabihf"}
}
if goarch == "arm64" && goos == "linux" {
spec.CFlags = append(spec.CFlags, "--sysroot=/usr/aarch64-linux-gnu")
spec.Linker = "aarch64-linux-gnu-gcc"
spec.GDB = "aarch64-linux-gnu-gdb"
spec.Emulator = []string{"qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"}
}
if goarch == "386" {
spec.CFlags = []string{"-m32"}
spec.LDFlags = []string{"-m32"}
if goarch == "386" && runtime.GOARCH == "amd64" {
spec.CFlags = append(spec.CFlags, "-m32")
spec.LDFlags = append(spec.LDFlags, "-m32")
}
}
return &spec, nil
+68 -1
View File
@@ -1,6 +1,9 @@
package compileopts
import "testing"
import (
"reflect"
"testing"
)
func TestLoadTarget(t *testing.T) {
_, err := LoadTarget("arduino")
@@ -17,3 +20,67 @@ func TestLoadTarget(t *testing.T) {
t.Error("LoadTarget failed for wrong reason:", err)
}
}
func TestOverrideProperties(t *testing.T) {
baseAutoStackSize := true
base := &TargetSpec{
GOOS: "baseGoos",
CPU: "baseCpu",
Features: []string{"bf1", "bf2"},
BuildTags: []string{"bt1", "bt2"},
Emulator: []string{"be1", "be2"},
DefaultStackSize: 42,
AutoStackSize: &baseAutoStackSize,
}
childAutoStackSize := false
child := &TargetSpec{
GOOS: "",
CPU: "chlidCpu",
Features: []string{"cf1", "cf2"},
Emulator: []string{"ce1", "ce2"},
AutoStackSize: &childAutoStackSize,
DefaultStackSize: 64,
}
base.overrideProperties(child)
if base.GOOS != "baseGoos" {
t.Errorf("Overriding failed : got %v", base.GOOS)
}
if base.CPU != "chlidCpu" {
t.Errorf("Overriding failed : got %v", base.CPU)
}
if !reflect.DeepEqual(base.Features, []string{"cf1", "cf2", "bf1", "bf2"}) {
t.Errorf("Overriding failed : got %v", base.Features)
}
if !reflect.DeepEqual(base.BuildTags, []string{"bt1", "bt2"}) {
t.Errorf("Overriding failed : got %v", base.BuildTags)
}
if !reflect.DeepEqual(base.Emulator, []string{"ce1", "ce2"}) {
t.Errorf("Overriding failed : got %v", base.Emulator)
}
if *base.AutoStackSize != false {
t.Errorf("Overriding failed : got %v", base.AutoStackSize)
}
if base.DefaultStackSize != 64 {
t.Errorf("Overriding failed : got %v", base.DefaultStackSize)
}
baseAutoStackSize = true
base = &TargetSpec{
AutoStackSize: &baseAutoStackSize,
DefaultStackSize: 42,
}
child = &TargetSpec{
AutoStackSize: nil,
DefaultStackSize: 0,
}
base.overrideProperties(child)
if *base.AutoStackSize != true {
t.Errorf("Overriding failed : got %v", base.AutoStackSize)
}
if base.DefaultStackSize != 42 {
t.Errorf("Overriding failed : got %v", base.DefaultStackSize)
}
}
+79 -58
View File
@@ -5,18 +5,15 @@ import (
"errors"
"fmt"
"go/ast"
"go/build"
"go/constant"
"go/token"
"go/types"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/compiler/llvmutil"
"github.com/tinygo-org/tinygo/goenv"
"github.com/tinygo-org/tinygo/ir"
"github.com/tinygo-org/tinygo/loader"
"golang.org/x/tools/go/ssa"
@@ -74,7 +71,14 @@ type builder struct {
deferFuncs map[*ir.Function]int
deferInvokeFuncs map[string]int
deferClosureFuncs map[*ir.Function]int
deferExprFuncs map[ssa.Value]int
selectRecvBuf map[*ssa.Select]llvm.Value
deferBuiltinFuncs map[ssa.Value]deferBuiltin
}
type deferBuiltin struct {
funcName string
callback int
}
type phiNode struct {
@@ -93,6 +97,7 @@ func NewTargetMachine(config *compileopts.Config) (llvm.TargetMachine, error) {
features := strings.Join(config.Features(), ",")
var codeModel llvm.CodeModel
var relocationModel llvm.RelocMode
switch config.CodeModel() {
case "default":
@@ -109,10 +114,41 @@ func NewTargetMachine(config *compileopts.Config) (llvm.TargetMachine, error) {
codeModel = llvm.CodeModelLarge
}
machine := target.CreateTargetMachine(config.Triple(), config.CPU(), features, llvm.CodeGenLevelDefault, llvm.RelocStatic, codeModel)
switch config.RelocationModel() {
case "static":
relocationModel = llvm.RelocStatic
case "pic":
relocationModel = llvm.RelocPIC
case "dynamicnopic":
relocationModel = llvm.RelocDynamicNoPic
}
machine := target.CreateTargetMachine(config.Triple(), config.CPU(), features, llvm.CodeGenLevelDefault, relocationModel, codeModel)
return machine, nil
}
// CompilerOutput is returned from the Compile() call. It contains the compile
// output and information necessary to continue to compile and link the program.
type CompilerOutput struct {
// The LLVM module that contains the compiled but not optimized LLVM module
// for all the Go code in the program.
Mod llvm.Module
// ExtraFiles is a list of C source files included in packages that should
// be built and linked together with the main executable to form one
// program. They can be used from CGo, for example.
ExtraFiles []string
// ExtraLDFlags are linker flags obtained during CGo processing. These flags
// must be passed to the linker which links the entire executable.
ExtraLDFlags []string
// MainDir is the absolute directory path to the directory of the main
// package. This is useful for testing: tests must be run in the package
// directory that is being tested.
MainDir string
}
// Compile the given package path or .go file path. Return an error when this
// fails (in any stage). If successful it returns the LLVM module and a list of
// extra C files to be compiled. If not, one or more errors will be returned.
@@ -121,7 +157,7 @@ func NewTargetMachine(config *compileopts.Config) (llvm.TargetMachine, error) {
// violation. Eventually, this Compile function should only compile a single
// package and not the whole program, and loading of the program (including CGo
// processing) should be moved outside the compiler package.
func Compile(pkgName string, machine llvm.TargetMachine, config *compileopts.Config) (mod llvm.Module, extrafiles []string, extraldflags []string, errors []error) {
func Compile(pkgName string, machine llvm.TargetMachine, config *compileopts.Config) (output CompilerOutput, errors []error) {
c := &compilerContext{
Config: config,
difiles: make(map[string]llvm.Metadata),
@@ -137,6 +173,7 @@ func Compile(pkgName string, machine llvm.TargetMachine, config *compileopts.Con
if c.Debug() {
c.dibuilder = llvm.NewDIBuilder(c.mod)
}
output.Mod = c.mod
c.uintptrType = c.ctx.IntType(c.targetData.PointerSize() * 8)
if c.targetData.PointerSize() <= 4 {
@@ -155,55 +192,29 @@ func Compile(pkgName string, machine llvm.TargetMachine, config *compileopts.Con
c.funcPtrAddrSpace = dummyFunc.Type().PointerAddressSpace()
dummyFunc.EraseFromParentAsFunction()
wd, err := os.Getwd()
lprogram, err := loader.Load(c.Config, []string{pkgName}, c.ClangHeaders, types.Config{
Sizes: &stdSizes{
IntSize: int64(c.targetData.TypeAllocSize(c.intType)),
PtrSize: int64(c.targetData.PointerSize()),
MaxAlign: int64(c.targetData.PrefTypeAlignment(c.i8ptrType)),
}})
if err != nil {
return c.mod, nil, nil, []error{err}
}
goroot, err := loader.GetCachedGoroot(c.Config)
if err != nil {
return c.mod, nil, nil, []error{err}
}
lprogram := &loader.Program{
Build: &build.Context{
GOARCH: c.GOARCH(),
GOOS: c.GOOS(),
GOROOT: goroot,
GOPATH: goenv.Get("GOPATH"),
CgoEnabled: c.CgoEnabled(),
UseAllFiles: false,
Compiler: "gc", // must be one of the recognized compilers
BuildTags: c.BuildTags(),
},
Tests: c.TestConfig.CompileTestBinary,
TypeChecker: types.Config{
Sizes: &stdSizes{
IntSize: int64(c.targetData.TypeAllocSize(c.intType)),
PtrSize: int64(c.targetData.PointerSize()),
MaxAlign: int64(c.targetData.PrefTypeAlignment(c.i8ptrType)),
},
},
Dir: wd,
TINYGOROOT: goenv.Get("TINYGOROOT"),
CFlags: c.CFlags(),
ClangHeaders: c.ClangHeaders,
}
err = lprogram.Load(pkgName)
if err != nil {
return c.mod, nil, nil, []error{err}
return output, []error{err}
}
err = lprogram.Parse()
if err != nil {
return c.mod, nil, nil, []error{err}
return output, []error{err}
}
output.ExtraLDFlags = lprogram.LDFlags
output.MainDir = lprogram.MainPkg().Dir
c.ir = ir.NewProgram(lprogram)
// Run a simple dead code elimination pass.
err = c.ir.SimpleDCE()
if err != nil {
return c.mod, nil, nil, []error{err}
return output, []error{err}
}
// Initialize debug information.
@@ -276,6 +287,8 @@ func Compile(pkgName string, machine llvm.TargetMachine, config *compileopts.Con
pos := c.ir.Program.Fset.Position(initFn.Pos())
irbuilder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{})
}
initFn.LLVMFn.Param(0).SetName("context")
initFn.LLVMFn.Param(1).SetName("parentHandle")
block := c.ctx.AddBasicBlock(initFn.LLVMFn, "entry")
irbuilder.SetInsertPointAtEnd(block)
for _, fn := range initFuncs {
@@ -340,17 +353,13 @@ func Compile(pkgName string, machine llvm.TargetMachine, config *compileopts.Con
}
// Gather the list of (C) file paths that should be included in the build.
var extraFiles []string
for _, pkg := range c.ir.LoaderProgram.Sorted() {
for _, file := range pkg.OtherFiles {
switch strings.ToLower(filepath.Ext(file)) {
case ".c":
extraFiles = append(extraFiles, file)
}
for _, filename := range pkg.CFiles {
output.ExtraFiles = append(output.ExtraFiles, filepath.Join(pkg.Dir, filename))
}
}
return c.mod, extraFiles, lprogram.LDFlags, c.diagnostics
return output, c.diagnostics
}
// getLLVMRuntimeType obtains a named type from the runtime package and returns
@@ -1327,12 +1336,14 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
return b.createMemoryCopyCall(fn, instr.Args)
case name == "runtime.memzero":
return b.createMemoryZeroCall(instr.Args)
case name == "device.Asm" || name == "device/arm.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm":
case name == "device.Asm" || name == "device/arm.Asm" || name == "device/arm64.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm":
return b.createInlineAsm(instr.Args)
case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull":
case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/arm64.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull":
return b.createInlineAsmFull(instr)
case strings.HasPrefix(name, "device/arm.SVCall"):
return b.emitSVCall(instr.Args)
case strings.HasPrefix(name, "device/arm64.SVCall"):
return b.emitSV64Call(instr.Args)
case strings.HasPrefix(name, "(device/riscv.CSR)."):
return b.emitCSROperation(instr)
case strings.HasPrefix(name, "syscall.Syscall"):
@@ -2035,17 +2046,17 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va
case token.QUO: // /
return b.CreateFDiv(x, y, ""), nil
case token.EQL: // ==
return b.CreateFCmp(llvm.FloatUEQ, x, y, ""), nil
return b.CreateFCmp(llvm.FloatOEQ, x, y, ""), nil
case token.NEQ: // !=
return b.CreateFCmp(llvm.FloatUNE, x, y, ""), nil
case token.LSS: // <
return b.CreateFCmp(llvm.FloatULT, x, y, ""), nil
return b.CreateFCmp(llvm.FloatOLT, x, y, ""), nil
case token.LEQ: // <=
return b.CreateFCmp(llvm.FloatULE, x, y, ""), nil
return b.CreateFCmp(llvm.FloatOLE, x, y, ""), nil
case token.GTR: // >
return b.CreateFCmp(llvm.FloatUGT, x, y, ""), nil
return b.CreateFCmp(llvm.FloatOGT, x, y, ""), nil
case token.GEQ: // >=
return b.CreateFCmp(llvm.FloatUGE, x, y, ""), nil
return b.CreateFCmp(llvm.FloatOGE, x, y, ""), nil
default:
panic("binop on float: " + op.String())
}
@@ -2536,7 +2547,7 @@ func (b *builder) createConvert(typeFrom, typeTo types.Type, value llvm.Value, p
return llvm.Value{}, b.makeError(pos, "todo: convert: basic non-integer type: "+typeFrom.String()+" -> "+typeTo.String())
case *types.Slice:
if basic, ok := typeFrom.(*types.Basic); !ok || basic.Info()&types.IsString == 0 {
if basic, ok := typeFrom.Underlying().(*types.Basic); !ok || basic.Info()&types.IsString == 0 {
panic("can only convert from a string to a slice")
}
@@ -2569,7 +2580,17 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) {
if typ.Info()&types.IsInteger != 0 {
return b.CreateSub(llvm.ConstInt(x.Type(), 0, false), x, ""), nil
} else if typ.Info()&types.IsFloat != 0 {
return b.CreateFSub(llvm.ConstFloat(x.Type(), 0.0), x, ""), nil
return b.CreateFNeg(x, ""), nil
} else if typ.Info()&types.IsComplex != 0 {
// Negate both components of the complex number.
r := b.CreateExtractValue(x, 0, "r")
i := b.CreateExtractValue(x, 1, "i")
r = b.CreateFNeg(r, "")
i = b.CreateFNeg(i, "")
cplx := llvm.Undef(x.Type())
cplx = b.CreateInsertValue(cplx, r, 0, "")
cplx = b.CreateInsertValue(cplx, i, 1, "")
return cplx, nil
} else {
return llvm.Value{}, b.makeError(unop.Pos(), "todo: unknown basic type for negate: "+typ.String())
}
+109 -14
View File
@@ -16,6 +16,7 @@ package compiler
import (
"github.com/tinygo-org/tinygo/compiler/llvmutil"
"github.com/tinygo-org/tinygo/ir"
"go/types"
"golang.org/x/tools/go/ssa"
"tinygo.org/x/go-llvm"
)
@@ -28,6 +29,8 @@ func (b *builder) deferInitFunc() {
b.deferFuncs = make(map[*ir.Function]int)
b.deferInvokeFuncs = make(map[string]int)
b.deferClosureFuncs = make(map[*ir.Function]int)
b.deferExprFuncs = make(map[ssa.Value]int)
b.deferBuiltinFuncs = make(map[ssa.Value]deferBuiltin)
// Create defer list pointer.
deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0)
@@ -151,9 +154,54 @@ func (b *builder) createDefer(instr *ssa.Defer) {
values = append(values, context)
valueTypes = append(valueTypes, context.Type())
} else if builtin, ok := instr.Call.Value.(*ssa.Builtin); ok {
var funcName string
switch builtin.Name() {
case "close":
funcName = "chanClose"
default:
b.addError(instr.Pos(), "todo: Implement defer for "+builtin.Name())
return
}
if _, ok := b.deferBuiltinFuncs[instr.Call.Value]; !ok {
b.deferBuiltinFuncs[instr.Call.Value] = deferBuiltin{
funcName,
len(b.allDeferFuncs),
}
b.allDeferFuncs = append(b.allDeferFuncs, instr.Call.Value)
}
callback := llvm.ConstInt(b.uintptrType, uint64(b.deferBuiltinFuncs[instr.Call.Value].callback), false)
// Collect all values to be put in the struct (starting with
// runtime._defer fields).
values = []llvm.Value{callback, next}
for _, param := range instr.Call.Args {
llvmParam := b.getValue(param)
values = append(values, llvmParam)
valueTypes = append(valueTypes, llvmParam.Type())
}
} else {
b.addError(instr.Pos(), "todo: defer on uncommon function call type")
return
funcValue := b.getValue(instr.Call.Value)
if _, ok := b.deferExprFuncs[instr.Call.Value]; !ok {
b.deferExprFuncs[instr.Call.Value] = len(b.allDeferFuncs)
b.allDeferFuncs = append(b.allDeferFuncs, &instr.Call)
}
callback := llvm.ConstInt(b.uintptrType, uint64(b.deferExprFuncs[instr.Call.Value]), false)
// Collect all values to be put in the struct (starting with
// runtime._defer fields, followed by all parameters including the
// context pointer).
values = []llvm.Value{callback, next, funcValue}
valueTypes = append(valueTypes, funcValue.Type())
for _, param := range instr.Call.Args {
llvmParam := b.getValue(param)
values = append(values, llvmParam)
valueTypes = append(valueTypes, llvmParam.Type())
}
}
// Make a struct out of the collected values to put in the defer frame.
@@ -243,16 +291,23 @@ func (b *builder) createRunDefers() {
b.SetInsertPointAtEnd(block)
switch callback := callback.(type) {
case *ssa.CallCommon:
// Call on an interface value.
if !callback.IsInvoke() {
panic("expected an invoke call, not a direct call")
}
// Call on an value or interface value.
// Get the real defer struct type and cast to it.
valueTypes := []llvm.Type{b.uintptrType, llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0), b.uintptrType, b.i8ptrType}
valueTypes := []llvm.Type{b.uintptrType, llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0)}
if !callback.IsInvoke() {
//Expect funcValue to be passed through the defer frame.
valueTypes = append(valueTypes, b.getFuncType(callback.Signature()))
} else {
//Expect typecode
valueTypes = append(valueTypes, b.uintptrType, b.i8ptrType)
}
for _, arg := range callback.Args {
valueTypes = append(valueTypes, b.getLLVMType(arg.Type()))
}
deferFrameType := b.ctx.StructType(valueTypes, false)
deferFramePtr := b.CreateBitCast(deferData, llvm.PointerType(deferFrameType, 0), "deferFrame")
@@ -265,18 +320,34 @@ func (b *builder) createRunDefers() {
forwardParams = append(forwardParams, forwardParam)
}
// Isolate the typecode.
typecode, forwardParams := forwardParams[0], forwardParams[1:]
var fnPtr llvm.Value
// Add the context parameter. An interface call cannot also be a
// closure but we have to supply the parameter anyway for platforms
// with a strict calling convention.
forwardParams = append(forwardParams, llvm.Undef(b.i8ptrType))
if !callback.IsInvoke() {
// Isolate the func value.
funcValue := forwardParams[0]
forwardParams = forwardParams[1:]
//Get function pointer and context
fp, context := b.decodeFuncValue(funcValue, callback.Signature())
fnPtr = fp
//Pass context
forwardParams = append(forwardParams, context)
} else {
// Isolate the typecode.
typecode := forwardParams[0]
forwardParams = forwardParams[1:]
fnPtr = b.getInvokePtr(callback, typecode)
// Add the context parameter. An interface call cannot also be a
// closure but we have to supply the parameter anyway for platforms
// with a strict calling convention.
forwardParams = append(forwardParams, llvm.Undef(b.i8ptrType))
}
// Parent coroutine handle.
forwardParams = append(forwardParams, llvm.Undef(b.i8ptrType))
fnPtr := b.getInvokePtr(callback, typecode)
b.createCall(fnPtr, forwardParams, "")
case *ir.Function:
@@ -339,7 +410,31 @@ func (b *builder) createRunDefers() {
// Call deferred function.
b.createCall(fn.LLVMFn, forwardParams, "")
case *ssa.Builtin:
db := b.deferBuiltinFuncs[callback]
//Get parameter types
valueTypes := []llvm.Type{b.uintptrType, llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0)}
//Get signature from call results
params := callback.Type().Underlying().(*types.Signature).Params()
for i := 0; i < params.Len(); i++ {
valueTypes = append(valueTypes, b.getLLVMType(params.At(i).Type()))
}
deferFrameType := b.ctx.StructType(valueTypes, false)
deferFramePtr := b.CreateBitCast(deferData, llvm.PointerType(deferFrameType, 0), "deferFrame")
// Extract the params from the struct.
var forwardParams []llvm.Value
zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false)
for i := 0; i < params.Len(); i++ {
gep := b.CreateInBoundsGEP(deferFramePtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep")
forwardParam := b.CreateLoad(gep, "param")
forwardParams = append(forwardParams, forwardParam)
}
b.createRuntimeCall(db.funcName, forwardParams, "")
default:
panic("unknown deferred function type")
}
+19 -3
View File
@@ -19,16 +19,30 @@ import (
// Because a go statement doesn't return anything, return undef.
func (b *builder) createGoInstruction(funcPtr llvm.Value, params []llvm.Value, prefix string, pos token.Pos) llvm.Value {
paramBundle := b.emitPointerPack(params)
var callee llvm.Value
var callee, stackSize llvm.Value
switch b.Scheduler() {
case "none", "tasks":
callee = b.createGoroutineStartWrapper(funcPtr, prefix, pos)
if b.AutomaticStackSize() {
// The stack size is not known until after linking. Call a dummy
// function that will be replaced with a load from a special ELF
// section that contains the stack size (and is modified after
// linking).
stackSize = b.createCall(b.mod.NamedFunction("internal/task.getGoroutineStackSize"), []llvm.Value{callee, llvm.Undef(b.i8ptrType), llvm.Undef(b.i8ptrType)}, "stacksize")
} else {
// The stack size is fixed at compile time. By emitting it here as a
// constant, it can be optimized.
stackSize = llvm.ConstInt(b.uintptrType, b.Target.DefaultStackSize, false)
}
case "coroutines":
callee = b.CreatePtrToInt(funcPtr, b.uintptrType, "")
// There is no goroutine stack size: coroutines are used instead of
// stacks.
stackSize = llvm.Undef(b.uintptrType)
default:
panic("unreachable")
}
b.createCall(b.mod.NamedFunction("internal/task.start"), []llvm.Value{callee, paramBundle, llvm.Undef(b.i8ptrType), llvm.ConstPointerNull(b.i8ptrType)}, "")
b.createCall(b.mod.NamedFunction("internal/task.start"), []llvm.Value{callee, paramBundle, stackSize, llvm.Undef(b.i8ptrType), llvm.ConstPointerNull(b.i8ptrType)}, "")
return llvm.Undef(funcPtr.Type().ElementType().ReturnType())
}
@@ -67,8 +81,9 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
// Create the wrapper.
wrapperType := llvm.FunctionType(c.ctx.VoidType(), []llvm.Type{c.i8ptrType}, false)
wrapper = llvm.AddFunction(c.mod, name+"$gowrapper", wrapperType)
wrapper.SetLinkage(llvm.PrivateLinkage)
wrapper.SetLinkage(llvm.InternalLinkage)
wrapper.SetUnnamedAddr(true)
wrapper.AddAttributeAtIndex(-1, c.ctx.CreateStringAttribute("tinygo-gowrapper", name))
entry := c.ctx.AddBasicBlock(wrapper, "entry")
builder.SetInsertPointAtEnd(entry)
@@ -125,6 +140,7 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
wrapper = llvm.AddFunction(c.mod, prefix+".gowrapper", wrapperType)
wrapper.SetLinkage(llvm.InternalLinkage)
wrapper.SetUnnamedAddr(true)
wrapper.AddAttributeAtIndex(-1, c.ctx.CreateStringAttribute("tinygo-gowrapper", ""))
entry := c.ctx.AddBasicBlock(wrapper, "entry")
builder.SetInsertPointAtEnd(entry)
+38
View File
@@ -163,6 +163,44 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) {
return b.CreateCall(target, llvmArgs, ""), nil
}
// This is a compiler builtin which emits an inline SVCall instruction. It can
// be one of:
//
// func SVCall0(num uintptr) uintptr
// func SVCall1(num uintptr, a1 interface{}) uintptr
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
//
// The num parameter must be a constant. All other parameters may be any scalar
// value supported by LLVM inline assembly.
// Same as emitSVCall but for AArch64
func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) {
num, _ := constant.Uint64Val(args[0].(*ssa.Const).Value)
llvmArgs := []llvm.Value{}
argTypes := []llvm.Type{}
asm := "svc #" + strconv.FormatUint(num, 10)
constraints := "={x0}"
for i, arg := range args[1:] {
arg = arg.(*ssa.MakeInterface).X
if i == 0 {
constraints += ",0"
} else {
constraints += ",{x" + strconv.Itoa(i) + "}"
}
llvmValue := b.getValue(arg)
llvmArgs = append(llvmArgs, llvmValue)
argTypes = append(argTypes, llvmValue.Type())
}
// Implement the ARM64 calling convention by marking x1-x7 as
// clobbered. x0 is used as an output register so doesn't have to be
// marked as clobbered.
constraints += ",~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7}"
fnType := llvm.FunctionType(b.uintptrType, argTypes, false)
target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0)
return b.CreateCall(target, llvmArgs, ""), nil
}
// This is a compiler builtin which emits CSR instructions. It can be one of:
//
// func (csr CSR) Get() uintptr
+3 -3
View File
@@ -4,11 +4,11 @@ go 1.11
require (
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
github.com/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac
github.com/chromedp/chromedp v0.5.3
github.com/chromedp/cdproto v0.0.0-20200709115526-d1f6fc58448b
github.com/chromedp/chromedp v0.5.4-0.20200303084119-2bb39134ab9e
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
go.bug.st/serial v1.0.0
golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2
tinygo.org/x/go-llvm v0.0.0-20200503225853-345b2947b59d
tinygo.org/x/go-llvm v0.0.0-20201104183921-570e7a6841d9
)
+10 -8
View File
@@ -1,9 +1,10 @@
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI=
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
github.com/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac h1:T7V5BXqnYd55Hj/g5uhDYumg9Fp3rMTS6bykYtTIFX4=
github.com/chromedp/cdproto v0.0.0-20200116234248-4da64dd111ac/go.mod h1:PfAWWKJqjlGFYJEidUM6aVIWPr0EpobeyVWEEmplX7g=
github.com/chromedp/chromedp v0.5.3 h1:F9LafxmYpsQhWQBdCs+6Sret1zzeeFyHS5LkRF//Ffg=
github.com/chromedp/chromedp v0.5.3/go.mod h1:YLdPtndaHQ4rCpSpBG+IPpy9JvX0VD+7aaLxYgYj28w=
github.com/chromedp/cdproto v0.0.0-20200709115526-d1f6fc58448b h1:LF+GRwyzxrO3MUzPvejv+yBup0lNG+/QdIRrkxOPseA=
github.com/chromedp/cdproto v0.0.0-20200709115526-d1f6fc58448b/go.mod h1:E6LPWRdIJc11h/di5p0rwvRmUYbhGpBEH7ZbPfzDIOE=
github.com/chromedp/chromedp v0.5.4-0.20200303084119-2bb39134ab9e h1:Hv0JVyHhbIXb9NiYQe4NsrfgrSofAp0q2FnhhJOXgi8=
github.com/chromedp/chromedp v0.5.4-0.20200303084119-2bb39134ab9e/go.mod h1:vmQMRHFZrY3T+Jv51T0n87OK/i6bK+5P9a+Fg5jPwgQ=
github.com/creack/goselect v0.1.1 h1:tiSSgKE1eJtxs1h/VgGQWuXUP0YS4CDIFMp6vaI1ls0=
github.com/creack/goselect v0.1.1/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -11,14 +12,15 @@ github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/gobwas/ws v1.0.3 h1:ZOigqf7iBxkA4jdQ3am7ATzdlOFp9YzA6NmuvEEZc9g=
github.com/gobwas/ws v1.0.3/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
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/knq/sysutil v0.0.0-20191005231841-15668db23d08 h1:V0an7KRw92wmJysvFvtqtKMAPmvS5O0jtB0nYo6t+gs=
github.com/knq/sysutil v0.0.0-20191005231841-15668db23d08/go.mod h1:dFWs1zEqDjFtnBXsd1vPOZaLsESovai349994nHx3e0=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8=
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -46,5 +48,5 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbO
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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=
tinygo.org/x/go-llvm v0.0.0-20200503225853-345b2947b59d h1:hcX7vpB067GWM/EH4sGGOti0PMgIx+0bbZwUXctOIvE=
tinygo.org/x/go-llvm v0.0.0-20200503225853-345b2947b59d/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE=
tinygo.org/x/go-llvm v0.0.0-20201104183921-570e7a6841d9 h1:l2kTQOhqEoeDTK3ckUnwReOQwMPUmURMIdjJbeAuDT4=
tinygo.org/x/go-llvm v0.0.0-20201104183921-570e7a6841d9/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE=
+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.14.0-dev"
const Version = "0.16.0"
// GetGorootVersion returns the major and minor version for a given GOROOT path.
// If the goroot cannot be determined, (0, 0) is returned.
+5
View File
@@ -0,0 +1,5 @@
# Hooks for Docker Hub
Files in this directory are custom commands to be run during the different Docker Hub build phases.
See https://docs.docker.com/docker-hub/builds/advanced/#custom-build-phase-hooks
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
# Docker hub does a recursive clone, then checks the branch out,
# so when a PR adds a submodule (or updates it), it fails.
git submodule update --init
+3 -1
View File
@@ -47,10 +47,12 @@ func (e *Error) Error() string {
// location of the instruction. The location information may not be complete as
// it depends on debug information in the IR.
func (e *evalPackage) errorAt(inst llvm.Value, err error) *Error {
pos := getPosition(inst)
return &Error{
ImportPath: e.packagePath,
Pos: getPosition(inst),
Pos: pos,
Err: err,
Traceback: []ErrorLine{{pos, inst}},
}
}
+37 -9
View File
@@ -95,7 +95,11 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
if !operand.IsConstant() || inst.IsVolatile() || (!operand.Underlying.IsAConstantExpr().IsNil() && operand.Underlying.Opcode() == llvm.BitCast) {
value = fr.builder.CreateLoad(operand.Value(), inst.Name())
} else {
value = operand.Load()
var err error
value, err = operand.Load()
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
}
if value.Type() != inst.Type() {
return nil, nil, fr.errorAt(inst, errors.New("interp: load: type does not match"))
@@ -107,7 +111,10 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
if inst.IsVolatile() {
fr.builder.CreateStore(value.Value(), ptr.Value())
} else {
ptr.Store(value.Value())
err := ptr.Store(value.Value())
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
}
case !inst.IsAGetElementPtrInst().IsNil():
value := fr.getLocal(inst.Operand(0))
@@ -308,7 +315,10 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
}
// "key" is a Go string value, which in the TinyGo calling convention is split up
// into separate pointer and length parameters.
m.PutString(keyBuf, keyLen, valPtr)
err := m.PutString(keyBuf, keyLen, valPtr)
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
case callee.Name() == "runtime.hashmapBinarySet":
// set a binary (int etc.) key in the map
keyBuf := fr.getLocal(inst.Operand(1)).(*LocalValue)
@@ -329,15 +339,24 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
fr.builder.CreateCall(callee, llvmParams, "")
continue
}
m.PutBinary(keyBuf, valPtr)
err := m.PutBinary(keyBuf, valPtr)
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
case callee.Name() == "runtime.stringConcat":
// adding two strings together
buf1Ptr := fr.getLocal(inst.Operand(0))
buf1Len := fr.getLocal(inst.Operand(1))
buf2Ptr := fr.getLocal(inst.Operand(2))
buf2Len := fr.getLocal(inst.Operand(3))
buf1 := getStringBytes(buf1Ptr, buf1Len.Value())
buf2 := getStringBytes(buf2Ptr, buf2Len.Value())
buf1, err := getStringBytes(buf1Ptr, buf1Len.Value())
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
buf2, err := getStringBytes(buf2Ptr, buf2Len.Value())
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
result := []byte(string(buf1) + string(buf2))
vals := make([]llvm.Value, len(result))
for i := range vals {
@@ -401,9 +420,15 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
return nil, nil, fr.errorAt(inst, errors.New("interp: trying to copy a slice with negative length?"))
}
for i := int64(0); i < length; i++ {
var err error
// *dst = *src
dstArray.Store(srcArray.Load())
val, err := srcArray.Load()
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
err = dstArray.Store(val)
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
// dst++
dstArrayValue, err := dstArray.GetElementPtr([]uint32{1})
if err != nil {
@@ -421,7 +446,10 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
// convert a string to a []byte
bufPtr := fr.getLocal(inst.Operand(0))
bufLen := fr.getLocal(inst.Operand(1))
result := getStringBytes(bufPtr, bufLen.Value())
result, err := getStringBytes(bufPtr, bufLen.Value())
if err != nil {
return nil, nil, fr.errorAt(inst, err)
}
vals := make([]llvm.Value, len(result))
for i := range vals {
vals[i] = llvm.ConstInt(fr.Mod.Context().Int8Type(), uint64(result[i]), false)
+15 -2
View File
@@ -3,6 +3,7 @@ package interp
import (
"io/ioutil"
"os"
"regexp"
"strings"
"testing"
@@ -66,6 +67,8 @@ func runTest(t *testing.T, pathPrefix string) {
}
}
var alignRegexp = regexp.MustCompile(", align [0-9]+$")
// fuzzyEqualIR returns true if the two LLVM IR strings passed in are roughly
// equal. That means, only relevant lines are compared (excluding comments
// etc.).
@@ -75,8 +78,18 @@ func fuzzyEqualIR(s1, s2 string) bool {
if len(lines1) != len(lines2) {
return false
}
for i, line := range lines1 {
if line != lines2[i] {
for i, line1 := range lines1 {
line2 := lines2[i]
match1 := alignRegexp.MatchString(line1)
match2 := alignRegexp.MatchString(line2)
if match1 != match2 {
// Only one of the lines has the align keyword. Remove it.
// This is a change to make the test work in both LLVM 10 and LLVM
// 11 (LLVM 11 appears to automatically add alignment everywhere).
line1 = alignRegexp.ReplaceAllString(line1, "")
line2 = alignRegexp.ReplaceAllString(line2, "")
}
if line1 != line2 {
return false
}
}
+6
View File
@@ -62,6 +62,10 @@ func (e *evalPackage) hasSideEffects(fn llvm.Value) (*sideEffectResult, *Error)
return &sideEffectResult{severity: sideEffectNone}, nil
case name == "llvm.dbg.value":
return &sideEffectResult{severity: sideEffectNone}, nil
case name == "(*sync/atomic.Value).Load" || name == "(*sync/atomic.Value).Store":
// These functions do some unsafe pointer loading/storing but are
// otherwise safe.
return &sideEffectResult{severity: sideEffectLimited}, nil
case strings.HasPrefix(name, "llvm.lifetime."):
return &sideEffectResult{severity: sideEffectNone}, nil
}
@@ -122,6 +126,8 @@ func (e *evalPackage) hasSideEffects(fn llvm.Value) (*sideEffectResult, *Error)
// External function call. Assume only limited side effects
// (no affected globals, etc.).
switch child.Name() {
case "runtime.alloc":
continue
case "runtime.typeAssert":
continue // implemented in interp
case "runtime.interfaceImplements":
+10 -5
View File
@@ -1,6 +1,8 @@
package interp
import (
"errors"
"tinygo.org/x/go-llvm"
)
@@ -18,20 +20,23 @@ func getUses(value llvm.Value) []llvm.Value {
// getStringBytes loads the byte slice of a Go string represented as a
// {ptr, len} pair.
func getStringBytes(strPtr Value, strLen llvm.Value) []byte {
func getStringBytes(strPtr Value, strLen llvm.Value) ([]byte, error) {
if !strLen.IsConstant() {
panic("getStringBytes with a non-constant length")
return nil, errors.New("getStringBytes with a non-constant length")
}
buf := make([]byte, strLen.ZExtValue())
for i := range buf {
gep, err := strPtr.GetElementPtr([]uint32{uint32(i)})
if err != nil {
panic(err) // TODO
return nil, err
}
c, err := gep.Load()
if err != nil {
return nil, err
}
c := gep.Load()
buf[i] = byte(c.ZExtValue())
}
return buf
return buf, nil
}
// getLLVMIndices converts an []uint32 into an []llvm.Value, for use in
+60 -36
View File
@@ -15,8 +15,8 @@ type Value interface {
Value() llvm.Value // returns a LLVM value
Type() llvm.Type // equal to Value().Type()
IsConstant() bool // returns true if this value is a constant value
Load() llvm.Value // dereference a pointer
Store(llvm.Value) // store to a pointer
Load() (llvm.Value, error) // dereference a pointer
Store(llvm.Value) error // store to a pointer
GetElementPtr([]uint32) (Value, error) // returns an interior pointer
String() string // string representation, for debugging
}
@@ -44,29 +44,32 @@ func (v *LocalValue) IsConstant() bool {
}
// Load loads a constant value if this is a constant pointer.
func (v *LocalValue) Load() llvm.Value {
func (v *LocalValue) Load() (llvm.Value, error) {
if !v.Underlying.IsAGlobalVariable().IsNil() {
return v.Underlying.Initializer()
return v.Underlying.Initializer(), nil
}
switch v.Underlying.Opcode() {
case llvm.GetElementPtr:
indices := v.getConstGEPIndices()
if indices[0] != 0 {
panic("invalid GEP")
return llvm.Value{}, errors.New("invalid GEP")
}
global := v.Eval.getValue(v.Underlying.Operand(0))
agg := global.Load()
return llvm.ConstExtractValue(agg, indices[1:])
agg, err := global.Load()
if err != nil {
return llvm.Value{}, err
}
return llvm.ConstExtractValue(agg, indices[1:]), nil
case llvm.BitCast:
panic("interp: load from a bitcast")
return llvm.Value{}, errors.New("interp: load from a bitcast")
default:
panic("interp: load from a constant")
return llvm.Value{}, errors.New("interp: load from a constant")
}
}
// Store stores to the underlying value if the value type is a pointer type,
// otherwise it panics.
func (v *LocalValue) Store(value llvm.Value) {
// otherwise it returns an error.
func (v *LocalValue) Store(value llvm.Value) error {
if !v.Underlying.IsAGlobalVariable().IsNil() {
if !value.IsConstant() {
v.MarkDirty()
@@ -74,26 +77,28 @@ func (v *LocalValue) Store(value llvm.Value) {
} else {
v.Underlying.SetInitializer(value)
}
return
return nil
}
if !value.IsConstant() {
v.MarkDirty()
v.Eval.builder.CreateStore(value, v.Underlying)
return
return nil
}
switch v.Underlying.Opcode() {
case llvm.GetElementPtr:
indices := v.getConstGEPIndices()
if indices[0] != 0 {
panic("invalid GEP")
return errors.New("invalid GEP")
}
global := &LocalValue{v.Eval, v.Underlying.Operand(0)}
agg := global.Load()
agg, err := global.Load()
if err != nil {
return err
}
agg = llvm.ConstInsertValue(agg, value, indices[1:])
global.Store(agg)
return
return global.Store(agg)
default:
panic("interp: store on a constant")
return errors.New("interp: store on a constant")
}
}
@@ -225,7 +230,11 @@ func (v *MapValue) Value() llvm.Value {
keyPtr := llvm.ConstExtractValue(llvmKey, []uint32{0})
keyLen := llvm.ConstExtractValue(llvmKey, []uint32{1})
keyPtrVal := v.Eval.getValue(keyPtr)
keyBuf = getStringBytes(keyPtrVal, keyLen)
var err error
keyBuf, err = getStringBytes(keyPtrVal, keyLen)
if err != nil {
panic(err) // TODO
}
} else if key.Type().TypeKind() == llvm.IntegerTypeKind {
keyBuf = make([]byte, v.Eval.TargetData.TypeAllocSize(key.Type()))
n := key.Value().ZExtValue()
@@ -299,13 +308,15 @@ func (v *MapValue) IsConstant() bool {
}
// Load panics: maps are of reference type so cannot be dereferenced.
func (v *MapValue) Load() llvm.Value {
func (v *MapValue) Load() (llvm.Value, error) {
panic("interp: load from a map")
}
// Store panics: maps are of reference type so cannot be stored to.
func (v *MapValue) Store(value llvm.Value) {
panic("interp: store on a map")
// Store returns an error: maps are of reference type so cannot be stored to.
func (v *MapValue) Store(value llvm.Value) error {
// This must be a bug, but it might be helpful to indicate the location
// anyway.
return errors.New("interp: store on a map")
}
// GetElementPtr panics: maps are of reference type so their (interior)
@@ -316,23 +327,26 @@ func (v *MapValue) GetElementPtr(indices []uint32) (Value, error) {
// PutString does a map assign operation, assuming that the map is of type
// map[string]T.
func (v *MapValue) PutString(keyBuf, keyLen, valPtr *LocalValue) {
func (v *MapValue) PutString(keyBuf, keyLen, valPtr *LocalValue) error {
if !v.Underlying.IsNil() {
panic("map already created")
return errors.New("map already created")
}
if valPtr.Underlying.Opcode() == llvm.BitCast {
valPtr = &LocalValue{v.Eval, valPtr.Underlying.Operand(0)}
}
value := valPtr.Load()
value, err := valPtr.Load()
if err != nil {
return err
}
if v.ValueType.IsNil() {
v.ValueType = value.Type()
if int(v.Eval.TargetData.TypeAllocSize(v.ValueType)) != v.ValueSize {
panic("interp: map store value type has the wrong size")
return errors.New("interp: map store value type has the wrong size")
}
} else {
if value.Type() != v.ValueType {
panic("interp: map store value type is inconsistent")
return errors.New("interp: map store value type is inconsistent")
}
}
@@ -345,26 +359,31 @@ func (v *MapValue) PutString(keyBuf, keyLen, valPtr *LocalValue) {
// TODO: avoid duplicate keys
v.Keys = append(v.Keys, &LocalValue{v.Eval, key})
v.Values = append(v.Values, &LocalValue{v.Eval, value})
return nil
}
// PutBinary does a map assign operation.
func (v *MapValue) PutBinary(keyPtr, valPtr *LocalValue) {
func (v *MapValue) PutBinary(keyPtr, valPtr *LocalValue) error {
if !v.Underlying.IsNil() {
panic("map already created")
return errors.New("map already created")
}
if valPtr.Underlying.Opcode() == llvm.BitCast {
valPtr = &LocalValue{v.Eval, valPtr.Underlying.Operand(0)}
}
value := valPtr.Load()
value, err := valPtr.Load()
if err != nil {
return err
}
if v.ValueType.IsNil() {
v.ValueType = value.Type()
if int(v.Eval.TargetData.TypeAllocSize(v.ValueType)) != v.ValueSize {
panic("interp: map store value type has the wrong size")
return errors.New("interp: map store value type has the wrong size")
}
} else {
if value.Type() != v.ValueType {
panic("interp: map store value type is inconsistent")
return errors.New("interp: map store value type is inconsistent")
}
}
@@ -375,21 +394,26 @@ func (v *MapValue) PutBinary(keyPtr, valPtr *LocalValue) {
keyPtr = &LocalValue{v.Eval, keyPtr.Underlying.Operand(0)}
}
}
key := keyPtr.Load()
key, err := keyPtr.Load()
if err != nil {
return err
}
if v.KeyType.IsNil() {
v.KeyType = key.Type()
if int(v.Eval.TargetData.TypeAllocSize(v.KeyType)) != v.KeySize {
panic("interp: map store key type has the wrong size")
return errors.New("interp: map store key type has the wrong size")
}
} else {
if key.Type() != v.KeyType {
panic("interp: map store key type is inconsistent")
return errors.New("interp: map store key type is inconsistent")
}
}
// TODO: avoid duplicate keys
v.Keys = append(v.Keys, &LocalValue{v.Eval, key})
v.Values = append(v.Values, &LocalValue{v.Eval, value})
return nil
}
// Get FNV-1a hash of this string.
+2 -2
View File
@@ -67,7 +67,7 @@ func NewProgram(lprogram *loader.Program) *Program {
program := lprogram.LoadSSA()
program.Build()
mainPkg := program.ImportedPackage(lprogram.MainPkg.PkgPath)
mainPkg := program.ImportedPackage(lprogram.MainPkg().ImportPath)
if mainPkg == nil {
panic("could not find main package")
}
@@ -79,7 +79,7 @@ func NewProgram(lprogram *loader.Program) *Program {
}
for _, pkg := range lprogram.Sorted() {
p.AddPackage(program.ImportedPackage(pkg.PkgPath))
p.AddPackage(program.ImportedPackage(pkg.ImportPath))
}
return p
+13
View File
@@ -1,5 +1,7 @@
package loader
import "go/scanner"
// Errors contains a list of parser errors or a list of typechecker errors for
// the given package.
type Errors struct {
@@ -10,3 +12,14 @@ type Errors struct {
func (e Errors) Error() string {
return "could not compile: " + e.Errs[0].Error()
}
// Error is a regular error but with an added import stack. This is especially
// useful for debugging import cycle errors.
type Error struct {
ImportStack []string
Err scanner.Error
}
func (e Error) Error() string {
return e.Err.Error()
}
+50 -9
View File
@@ -8,19 +8,21 @@ import (
"encoding/hex"
"errors"
"fmt"
"io"
"io/ioutil"
"math/rand"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strconv"
"sync"
"github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/goenv"
)
var gorootCreateMutex sync.Mutex
// GetCachedGoroot creates a new GOROOT by merging both the standard GOROOT and
// the GOROOT from TinyGo using lots of symbolic links.
func GetCachedGoroot(config *compileopts.Config) (string, error) {
@@ -49,16 +51,29 @@ func GetCachedGoroot(config *compileopts.Config) (string, error) {
fmt.Fprintln(hash, tinygoroot)
gorootsHash := hash.Sum(nil)
gorootsHashHex := hex.EncodeToString(gorootsHash[:])
cachedgoroot := filepath.Join(goenv.Get("GOCACHE"), "goroot-"+version+"-"+gorootsHashHex)
cachedgorootName := "goroot-" + version + "-" + gorootsHashHex
cachedgoroot := filepath.Join(goenv.Get("GOCACHE"), cachedgorootName)
if needsSyscallPackage(config.BuildTags()) {
cachedgoroot += "-syscall"
}
// Do not try to create the cached GOROOT in parallel, that's only a waste
// of I/O bandwidth and thus speed. Instead, use a mutex to make sure only
// one goroutine does it at a time.
// This is not a way to ensure atomicity (a different TinyGo invocation
// could be creating the same directory), but instead a way to avoid
// creating it many times in parallel when running tests in parallel.
gorootCreateMutex.Lock()
defer gorootCreateMutex.Unlock()
if _, err := os.Stat(cachedgoroot); err == nil {
return cachedgoroot, nil
}
tmpgoroot := cachedgoroot + ".tmp" + strconv.Itoa(rand.Int())
err = os.MkdirAll(tmpgoroot, 0777)
err = os.MkdirAll(goenv.Get("GOCACHE"), 0777)
if err != nil {
return "", err
}
tmpgoroot, err := ioutil.TempDir(goenv.Get("GOCACHE"), cachedgorootName+".tmp")
if err != nil {
return "", err
}
@@ -85,6 +100,15 @@ func GetCachedGoroot(config *compileopts.Config) (string, error) {
// deleted by the defer above.
return cachedgoroot, nil
}
if runtime.GOOS == "windows" && os.IsPermission(err) {
// On Windows, a rename with a destination directory that already
// exists does not result in an IsExist error, but rather in an
// access denied error. To be sure, check for this case by checking
// whether the target directory exists.
if _, err := os.Stat(cachedgoroot); err == nil {
return cachedgoroot, nil
}
}
return "", err
}
return cachedgoroot, nil
@@ -165,7 +189,7 @@ func mergeDirectory(goroot, tinygoroot, tmpgoroot, importPath string, overrides
// with the TinyGo version. This is the case on some targets.
func needsSyscallPackage(buildTags []string) bool {
for _, tag := range buildTags {
if tag == "baremetal" || tag == "darwin" {
if tag == "baremetal" || tag == "darwin" || tag == "nintendoswitch" || tag == "wasi" {
return true
}
}
@@ -188,7 +212,7 @@ func pathsToOverride(needsSyscallPackage bool) map[string]bool {
"reflect/": false,
"runtime/": false,
"sync/": true,
"testing/": false,
"testing/": true,
}
if needsSyscallPackage {
paths["syscall/"] = true // include syscall/js
@@ -228,10 +252,27 @@ func symlink(oldname, newname string) error {
return symlinkErr
}
} else {
// Make a hard link.
// Try making a hard link.
err := os.Link(oldname, newname)
if err != nil {
return symlinkErr
// Making a hardlink failed. Try copying the file as a last
// fallback.
inf, err := os.Open(oldname)
if err != nil {
return err
}
defer inf.Close()
outf, err := os.Create(newname)
if err != nil {
return err
}
defer outf.Close()
_, err = io.Copy(outf, inf)
if err != nil {
os.Remove(newname)
return err
}
// File was copied.
}
}
return nil // success
+30
View File
@@ -0,0 +1,30 @@
package loader
import (
"os"
"os/exec"
"strings"
"github.com/tinygo-org/tinygo/compileopts"
)
// List returns a ready-to-run *exec.Cmd for running the `go list` command with
// the configuration used for TinyGo.
func List(config *compileopts.Config, extraArgs, pkgs []string) (*exec.Cmd, error) {
goroot, err := GetCachedGoroot(config)
if err != nil {
return nil, err
}
args := append([]string{"list"}, extraArgs...)
if len(config.BuildTags()) != 0 {
args = append(args, "-tags", strings.Join(config.BuildTags(), " "))
}
args = append(args, pkgs...)
cgoEnabled := "0"
if config.CgoEnabled() {
cgoEnabled = "1"
}
cmd := exec.Command("go", args...)
cmd.Env = append(os.Environ(), "GOROOT="+goroot, "GOOS="+config.GOOS(), "GOARCH="+config.GOARCH(), "CGO_ENABLED="+cgoEnabled)
return cmd, nil
}
+214 -254
View File
@@ -2,165 +2,212 @@ package loader
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"go/ast"
"go/build"
"go/parser"
"go/scanner"
"go/token"
"go/types"
"io"
"os"
"os/exec"
"path/filepath"
"sort"
"strconv"
"strings"
"text/template"
"syscall"
"github.com/tinygo-org/tinygo/cgo"
"github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/goenv"
"golang.org/x/tools/go/packages"
)
// Program holds all packages and some metadata about the program as a whole.
type Program struct {
Build *build.Context
Tests bool
Packages map[string]*Package
MainPkg *Package
sorted []*Package
fset *token.FileSet
TypeChecker types.Config
Dir string // current working directory (for error reporting)
TINYGOROOT string // root of the TinyGo installation or root of the source code
CFlags []string
LDFlags []string
ClangHeaders string
config *compileopts.Config
clangHeaders string
typeChecker types.Config
goroot string // synthetic GOROOT
workingDir string
Packages map[string]*Package
sorted []*Package
fset *token.FileSet
// Information obtained during parsing.
LDFlags []string
}
// PackageJSON is a subset of the JSON struct returned from `go list`.
type PackageJSON struct {
Dir string
ImportPath string
ForTest string
// Source files
GoFiles []string
CgoFiles []string
CFiles []string
// Dependency information
Imports []string
// Error information
Error *struct {
ImportStack []string
Pos string
Err string
}
}
// Package holds a loaded package, its imports, and its parsed files.
type Package struct {
*Program
*packages.Package
Files []*ast.File
Pkg *types.Package
types.Info
PackageJSON
program *Program
Files []*ast.File
Pkg *types.Package
info types.Info
}
// Load loads the given package with all dependencies (including the runtime
// package). Call .Parse() afterwards to parse all Go files (including CGo
// processing, if necessary).
func (p *Program) Load(importPath string) error {
if p.Packages == nil {
p.Packages = make(map[string]*Package)
func Load(config *compileopts.Config, inputPkgs []string, clangHeaders string, typeChecker types.Config) (*Program, error) {
goroot, err := GetCachedGoroot(config)
if err != nil {
return nil, err
}
wd, err := os.Getwd()
if err != nil {
return nil, err
}
p := &Program{
config: config,
clangHeaders: clangHeaders,
typeChecker: typeChecker,
goroot: goroot,
workingDir: wd,
Packages: make(map[string]*Package),
fset: token.NewFileSet(),
}
err := p.loadPackage(importPath)
// List the dependencies of this package, in raw JSON format.
extraArgs := []string{"-json", "-deps"}
if config.TestConfig.CompileTestBinary {
extraArgs = append(extraArgs, "-test")
}
cmd, err := List(config, extraArgs, inputPkgs)
if err != nil {
return err
return nil, err
}
p.MainPkg = p.sorted[len(p.sorted)-1]
if _, ok := p.Packages["runtime"]; !ok {
// The runtime package wasn't loaded. Although `go list -deps` seems to
// return the full dependency list, there is no way to get those
// packages from the go/packages package. Therefore load the runtime
// manually and add it to the list of to-be-compiled packages
// (duplicates are already filtered).
return p.loadPackage("runtime")
buf := &bytes.Buffer{}
cmd.Stdout = buf
cmd.Stderr = os.Stderr
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)
}
return nil, fmt.Errorf("failed to run `go list`: %s", err)
}
return nil
}
func (p *Program) loadPackage(importPath string) error {
cgoEnabled := "0"
if p.Build.CgoEnabled {
cgoEnabled = "1"
}
pkgs, err := packages.Load(&packages.Config{
Mode: packages.NeedName | packages.NeedFiles | packages.NeedImports | packages.NeedDeps,
Env: append(os.Environ(), "GOROOT="+p.Build.GOROOT, "GOOS="+p.Build.GOOS, "GOARCH="+p.Build.GOARCH, "CGO_ENABLED="+cgoEnabled),
BuildFlags: []string{"-tags", strings.Join(p.Build.BuildTags, " ")},
Tests: p.Tests,
}, importPath)
if err != nil {
return err
}
var pkg *packages.Package
if p.Tests {
// We need the second package. Quoting from the docs:
// > For example, when using the go command, loading "fmt" with Tests=true
// > returns four packages, with IDs "fmt" (the standard package),
// > "fmt [fmt.test]" (the package as compiled for the test),
// > "fmt_test" (the test functions from source files in package fmt_test),
// > and "fmt.test" (the test binary).
pkg = pkgs[1]
} else {
if len(pkgs) != 1 {
return fmt.Errorf("expected exactly one package while importing %s, got %d", importPath, len(pkgs))
// Parse the returned json from `go list`.
decoder := json.NewDecoder(buf)
for {
pkg := &Package{
program: p,
info: types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
Implicits: make(map[ast.Node]types.Object),
Scopes: make(map[ast.Node]*types.Scope),
Selections: make(map[*ast.SelectorExpr]*types.Selection),
},
}
pkg = pkgs[0]
}
var importError *Errors
var addPackages func(pkg *packages.Package)
addPackages = func(pkg *packages.Package) {
if _, ok := p.Packages[pkg.PkgPath]; ok {
return
err := decoder.Decode(&pkg.PackageJSON)
if err != nil {
if err == io.EOF {
break
}
return nil, err
}
pkg2 := p.newPackage(pkg)
p.Packages[pkg.PkgPath] = pkg2
if len(pkg.Errors) != 0 {
if importError != nil {
// There was another error reported already. Do not report
// errors from multiple packages at once.
return
}
importError = &Errors{
Pkg: pkg2,
}
for _, err := range pkg.Errors {
pos := token.Position{}
fields := strings.Split(err.Pos, ":")
if len(fields) >= 2 {
// There is some file/line/column information.
if n, err := strconv.Atoi(fields[len(fields)-2]); err == nil {
// Format: filename.go:line:colum
pos.Filename = strings.Join(fields[:len(fields)-2], ":")
pos.Line = n
pos.Column, _ = strconv.Atoi(fields[len(fields)-1])
} else {
// Format: filename.go:line
pos.Filename = strings.Join(fields[:len(fields)-1], ":")
pos.Line, _ = strconv.Atoi(fields[len(fields)-1])
}
pos.Filename = p.getOriginalPath(pos.Filename)
if pkg.Error != nil {
// There was an error while importing (for example, a circular
// dependency).
pos := token.Position{}
fields := strings.Split(pkg.Error.Pos, ":")
if len(fields) >= 2 {
// There is some file/line/column information.
if n, err := strconv.Atoi(fields[len(fields)-2]); err == nil {
// Format: filename.go:line:colum
pos.Filename = strings.Join(fields[:len(fields)-2], ":")
pos.Line = n
pos.Column, _ = strconv.Atoi(fields[len(fields)-1])
} else {
// Format: filename.go:line
pos.Filename = strings.Join(fields[:len(fields)-1], ":")
pos.Line, _ = strconv.Atoi(fields[len(fields)-1])
}
importError.Errs = append(importError.Errs, scanner.Error{
Pos: pos,
Msg: err.Msg,
})
pos.Filename = p.getOriginalPath(pos.Filename)
}
return
err := scanner.Error{
Pos: pos,
Msg: pkg.Error.Err,
}
if len(pkg.Error.ImportStack) != 0 {
return nil, Error{
ImportStack: pkg.Error.ImportStack,
Err: err,
}
}
return nil, err
}
// Get the list of imports (sorted alphabetically).
names := make([]string, 0, len(pkg.Imports))
for name := range pkg.Imports {
names = append(names, name)
if config.TestConfig.CompileTestBinary {
// When creating a test binary, `go list` will list two or three
// packages used for testing the package. The first is the original
// package as if it were built normally, the second is the same
// package but with the *_test.go files included. A possible third
// may be included for _test packages (such as math_test), used to
// test the external API with no access to internal functions.
// All packages that are necessary for testing (including the to be
// tested package with *_test.go files, but excluding the original
// unmodified package) have a suffix added to the import path, for
// example the math package has import path "math [math.test]" and
// test dependencies such as fmt will have an import path of the
// form "fmt [math.test]".
// The code below removes this suffix, and if this results in a
// duplicate (which happens with the to-be-tested package without
// *.test.go files) the previous package is removed from the list of
// packages included in this build.
// This is necessary because the change in import paths results in
// breakage to //go:linkname. Additionally, the duplicated package
// slows down the build and so is best removed.
if pkg.ForTest != "" && strings.HasSuffix(pkg.ImportPath, " ["+pkg.ForTest+".test]") {
newImportPath := pkg.ImportPath[:len(pkg.ImportPath)-len(" ["+pkg.ForTest+".test]")]
if _, ok := p.Packages[newImportPath]; ok {
// Delete the previous package (that this package overrides).
delete(p.Packages, newImportPath)
for i, pkg := range p.sorted {
if pkg.ImportPath == newImportPath {
p.sorted = append(p.sorted[:i], p.sorted[i+1:]...) // remove element from slice
break
}
}
}
pkg.ImportPath = newImportPath
}
}
sort.Strings(names)
// Add all the imports.
for _, name := range names {
addPackages(pkg.Imports[name])
}
p.sorted = append(p.sorted, pkg2)
p.sorted = append(p.sorted, pkg)
p.Packages[pkg.ImportPath] = pkg
}
addPackages(pkg)
if importError != nil {
return *importError
}
return nil
return p, nil
}
// getOriginalPath looks whether this path is in the generated GOROOT and if so,
@@ -168,23 +215,23 @@ func (p *Program) loadPackage(importPath string) error {
// the input path is returned.
func (p *Program) getOriginalPath(path string) string {
originalPath := path
if strings.HasPrefix(path, p.Build.GOROOT+string(filepath.Separator)) {
if strings.HasPrefix(path, p.goroot+string(filepath.Separator)) {
// If this file is part of the synthetic GOROOT, try to infer the
// original path.
relpath := path[len(filepath.Join(p.Build.GOROOT, "src"))+1:]
relpath := path[len(filepath.Join(p.goroot, "src"))+1:]
realgorootPath := filepath.Join(goenv.Get("GOROOT"), "src", relpath)
if _, err := os.Stat(realgorootPath); err == nil {
originalPath = realgorootPath
}
maybeInTinyGoRoot := false
for prefix := range pathsToOverride(needsSyscallPackage(p.Build.BuildTags)) {
for prefix := range pathsToOverride(needsSyscallPackage(p.config.BuildTags())) {
if !strings.HasPrefix(relpath, prefix) {
continue
}
maybeInTinyGoRoot = true
}
if maybeInTinyGoRoot {
tinygoPath := filepath.Join(p.TINYGOROOT, "src", relpath)
tinygoPath := filepath.Join(goenv.Get("TINYGOROOT"), "src", relpath)
if _, err := os.Stat(tinygoPath); err == nil {
originalPath = tinygoPath
}
@@ -193,28 +240,18 @@ func (p *Program) getOriginalPath(path string) string {
return originalPath
}
// newPackage instantiates a new *Package object with initialized members.
func (p *Program) newPackage(pkg *packages.Package) *Package {
return &Package{
Program: p,
Package: pkg,
Info: types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
Implicits: make(map[ast.Node]types.Object),
Scopes: make(map[ast.Node]*types.Scope),
Selections: make(map[*ast.SelectorExpr]*types.Selection),
},
}
}
// Sorted returns a list of all packages, sorted in a way that no packages come
// before the packages they depend upon.
func (p *Program) Sorted() []*Package {
return p.sorted
}
// MainPkg returns the last package in the Sorted() slice. This is the main
// package of the program.
func (p *Program) MainPkg() *Package {
return p.sorted[len(p.sorted)-1]
}
// Parse parses all packages and typechecks them.
//
// The returned error may be an Errors error, which contains a list of errors.
@@ -222,22 +259,16 @@ func (p *Program) Sorted() []*Package {
// Idempotent.
func (p *Program) Parse() error {
// Parse all packages.
for _, pkg := range p.Sorted() {
// TODO: do this in parallel.
for _, pkg := range p.sorted {
err := pkg.Parse()
if err != nil {
return err
}
}
if p.Tests {
err := p.swapTestMain()
if err != nil {
return err
}
}
// Typecheck all packages.
for _, pkg := range p.Sorted() {
for _, pkg := range p.sorted {
err := pkg.Check()
if err != nil {
return err
@@ -247,82 +278,6 @@ func (p *Program) Parse() error {
return nil
}
func (p *Program) swapTestMain() error {
var tests []string
isTestFunc := func(f *ast.FuncDecl) bool {
// TODO: improve signature check
if strings.HasPrefix(f.Name.Name, "Test") && f.Name.Name != "TestMain" {
return true
}
return false
}
for _, f := range p.MainPkg.Files {
for i, d := range f.Decls {
switch v := d.(type) {
case *ast.FuncDecl:
if isTestFunc(v) {
tests = append(tests, v.Name.Name)
}
if v.Name.Name == "main" {
// Remove main
if len(f.Decls) == 1 {
f.Decls = make([]ast.Decl, 0)
} else {
f.Decls[i] = f.Decls[len(f.Decls)-1]
f.Decls = f.Decls[:len(f.Decls)-1]
}
}
}
}
}
// TODO: Check if they defined a TestMain and call it instead of testing.TestMain
const mainBody = `package main
import (
"testing"
)
func main () {
m := &testing.M{
Tests: []testing.TestToCall{
{{range .TestFunctions}}
{Name: "{{.}}", Func: {{.}}},
{{end}}
},
}
testing.TestMain(m)
}
`
tmpl := template.Must(template.New("testmain").Parse(mainBody))
b := bytes.Buffer{}
tmplData := struct {
TestFunctions []string
}{
TestFunctions: tests,
}
err := tmpl.Execute(&b, tmplData)
if err != nil {
return err
}
path := filepath.Join(p.MainPkg.Dir, "$testmain.go")
if p.fset == nil {
p.fset = token.NewFileSet()
}
newMain, err := parser.ParseFile(p.fset, path, b.Bytes(), parser.AllErrors)
if err != nil {
return err
}
p.MainPkg.Files = append(p.MainPkg.Files, newMain)
return nil
}
// parseFile is a wrapper around parser.ParseFile.
func (p *Program) parseFile(path string, mode parser.Mode) (*ast.File, error) {
if p.fset == nil {
@@ -342,14 +297,13 @@ func (p *Program) parseFile(path string, mode parser.Mode) (*ast.File, error) {
// Idempotent.
func (p *Package) Parse() error {
if len(p.Files) != 0 {
return nil
return nil // nothing to do (?)
}
// Load the AST.
// TODO: do this in parallel.
if p.PkgPath == "unsafe" {
// Special case for the unsafe package. Don't even bother loading
// the files.
if p.ImportPath == "unsafe" {
// Special case for the unsafe package, which is defined internally by
// the types package.
p.Pkg = types.Unsafe
return nil
}
@@ -369,11 +323,11 @@ func (p *Package) Parse() error {
// Idempotent.
func (p *Package) Check() error {
if p.Pkg != nil {
return nil
return nil // already typechecked
}
var typeErrors []error
checker := p.TypeChecker
checker := p.program.typeChecker // make a copy, because it will be modified
checker.Error = func(err error) {
typeErrors = append(typeErrors, err)
}
@@ -381,7 +335,7 @@ func (p *Package) Check() error {
// Do typechecking of the package.
checker.Importer = p
typesPkg, err := checker.Check(p.PkgPath, p.fset, p.Files, &p.Info)
typesPkg, err := checker.Check(p.ImportPath, p.program.fset, p.Files, &p.info)
if err != nil {
if err, ok := err.(Errors); ok {
return err
@@ -394,40 +348,46 @@ func (p *Package) Check() error {
// parseFiles parses the loaded list of files and returns this list.
func (p *Package) parseFiles() ([]*ast.File, error) {
// TODO: do this concurrently.
var files []*ast.File
var fileErrs []error
var cgoFiles []*ast.File
for _, file := range p.GoFiles {
f, err := p.parseFile(file, parser.ParseComments)
// Parse all files (incuding CgoFiles).
parseFile := func(file string) {
if !filepath.IsAbs(file) {
file = filepath.Join(p.Dir, file)
}
f, err := p.program.parseFile(file, parser.ParseComments)
if err != nil {
fileErrs = append(fileErrs, err)
continue
}
if err != nil {
fileErrs = append(fileErrs, err)
continue
}
for _, importSpec := range f.Imports {
if importSpec.Path.Value == `"C"` {
cgoFiles = append(cgoFiles, f)
}
return
}
files = append(files, f)
}
if len(cgoFiles) != 0 {
cflags := append(p.CFlags, "-I"+filepath.Dir(p.GoFiles[0]))
if p.ClangHeaders != "" {
cflags = append(cflags, "-Xclang", "-internal-isystem", "-Xclang", p.ClangHeaders)
for _, file := range p.GoFiles {
parseFile(file)
}
for _, file := range p.CgoFiles {
parseFile(file)
}
// Do CGo processing.
if len(p.CgoFiles) != 0 {
var cflags []string
cflags = append(cflags, p.program.config.CFlags()...)
cflags = append(cflags, "-I"+p.Dir)
if p.program.clangHeaders != "" {
cflags = append(cflags, "-Xclang", "-internal-isystem", "-Xclang", p.program.clangHeaders)
}
generated, ldflags, errs := cgo.Process(files, p.Program.Dir, p.fset, cflags)
generated, ldflags, errs := cgo.Process(files, p.program.workingDir, p.program.fset, cflags)
if errs != nil {
fileErrs = append(fileErrs, errs...)
}
files = append(files, generated)
p.LDFlags = append(p.LDFlags, ldflags...)
p.program.LDFlags = append(p.program.LDFlags, ldflags...)
}
// Only return an error after CGo processing, so that errors in parsing and
// CGo can be reported together.
if len(fileErrs) != 0 {
return nil, Errors{p, fileErrs}
}
@@ -441,8 +401,8 @@ func (p *Package) Import(to string) (*types.Package, error) {
if to == "unsafe" {
return types.Unsafe, nil
}
if _, ok := p.Imports[to]; ok {
return p.Packages[p.Imports[to].PkgPath].Pkg, nil
if imported, ok := p.program.Packages[to]; ok {
return imported.Pkg, nil
} else {
return nil, errors.New("package not imported: " + to)
}
+2 -2
View File
@@ -10,8 +10,8 @@ import (
func (p *Program) LoadSSA() *ssa.Program {
prog := ssa.NewProgram(p.fset, ssa.SanityCheckFunctions|ssa.BareInits|ssa.GlobalDebug)
for _, pkg := range p.Sorted() {
prog.CreatePackage(pkg.Pkg, pkg.Files, &pkg.Info, true)
for _, pkg := range p.sorted {
prog.CreatePackage(pkg.Pkg, pkg.Files, &pkg.info, true)
}
return prog
+197 -108
View File
@@ -8,6 +8,7 @@ import (
"go/scanner"
"go/types"
"io"
"io/ioutil"
"os"
"os/exec"
"os/signal"
@@ -28,6 +29,12 @@ import (
"go.bug.st/serial"
)
var (
// This variable is set at build time using -ldflags parameters.
// See: https://stackoverflow.com/a/11355611
gitSha1 string
)
// commandError is an error type to wrap os/exec.Command errors. This provides
// some more information regarding what went wrong while running a command.
type commandError struct {
@@ -58,33 +65,28 @@ func moveFile(src, dst string) error {
return os.Remove(src)
}
// copyFile copies the given file from src to dst. It copies first to a .tmp
// file which is then moved over a possibly already existing file at the
// destination.
// copyFile copies the given file from src to dst. It can copy over
// a possibly already existing file at the destination.
func copyFile(src, dst string) error {
inf, err := os.Open(src)
source, err := os.Open(src)
if err != nil {
return err
}
defer inf.Close()
outpath := dst + ".tmp"
outf, err := os.Create(outpath)
defer source.Close()
st, err := source.Stat()
if err != nil {
return err
}
_, err = io.Copy(outf, inf)
if err != nil {
os.Remove(outpath)
return err
}
err = outf.Close()
destination, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, st.Mode())
if err != nil {
return err
}
defer destination.Close()
return os.Rename(dst+".tmp", dst)
_, err = io.Copy(destination, source)
return err
}
// Build compiles and links the given package and writes it to outpath.
@@ -94,10 +96,10 @@ func Build(pkgName, outpath string, options *compileopts.Options) error {
return err
}
return builder.Build(pkgName, outpath, config, func(tmppath string) error {
if err := os.Rename(tmppath, outpath); err != nil {
return builder.Build(pkgName, outpath, config, func(result builder.BuildResult) error {
if err := os.Rename(result.Binary, outpath); err != nil {
// Moving failed. Do a file copy.
inf, err := os.Open(tmppath)
inf, err := os.Open(result.Binary)
if err != nil {
return err
}
@@ -123,35 +125,71 @@ func Build(pkgName, outpath string, options *compileopts.Options) error {
}
// Test runs the tests in the given package.
func Test(pkgName string, options *compileopts.Options) error {
func Test(pkgName string, options *compileopts.Options, testCompileOnly bool, outpath string) error {
options.TestConfig.CompileTestBinary = true
config, err := builder.NewConfig(options)
if err != nil {
return err
}
// Add test build tag. This is incorrect: `go test` only looks at the
// _test.go file suffix but does not add the test build tag in the process.
// However, it's a simple fix right now.
// For details: https://github.com/golang/go/issues/21360
config.Target.BuildTags = append(config.Target.BuildTags, "test")
return builder.Build(pkgName, ".elf", config, func(tmppath string) error {
cmd := exec.Command(tmppath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
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)
return builder.Build(pkgName, outpath, config, func(result builder.BuildResult) error {
if testCompileOnly || outpath != "" {
// Write test binary to the specified file name.
if outpath == "" {
// No -o path was given, so create one now.
// This matches the behavior of go test.
outpath = filepath.Base(result.MainDir) + ".test"
}
copyFile(result.Binary, outpath)
}
if testCompileOnly {
// Do not run the test.
return nil
}
if len(config.Target.Emulator) == 0 {
// Run directly.
cmd := exec.Command(result.Binary)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = result.MainDir
err := cmd.Run()
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)
}
return &commandError{"failed to run compiled binary", result.Binary, err}
}
return nil
} else {
// Run in an emulator.
args := append(config.Target.Emulator[1:], result.Binary)
cmd := exec.Command(config.Target.Emulator[0], args...)
buf := &bytes.Buffer{}
w := io.MultiWriter(os.Stdout, buf)
cmd.Stdout = w
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
if err, ok := err.(*exec.ExitError); !ok || !err.Exited() {
// Workaround for QEMU which always exits with an error.
return &commandError{"failed to run emulator with", result.Binary, err}
}
}
testOutput := string(buf.Bytes())
if testOutput == "PASS\n" || strings.HasSuffix(testOutput, "\nPASS\n") {
// Test passed.
return nil
} else {
// Test failed, either by ending with the word "FAIL" or with a
// panic of some sort.
os.Exit(1)
return nil // unreachable
}
return &commandError{"failed to run compiled binary", tmppath, err}
}
return nil
})
}
@@ -193,9 +231,9 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
return errors.New("unknown flash method: " + flashMethod)
}
return builder.Build(pkgName, fileExt, config, func(tmppath string) error {
return builder.Build(pkgName, fileExt, config, func(result builder.BuildResult) error {
// do we need port reset to put MCU into bootloader mode?
if config.Target.PortReset == "true" {
if config.Target.PortReset == "true" && flashMethod != "openocd" {
if port == "" {
var err error
port, err = getDefaultPort()
@@ -206,7 +244,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
err := touchSerialPortAt1200bps(port)
if err != nil {
return &commandError{"failed to reset port", tmppath, err}
return &commandError{"failed to reset port", result.Binary, err}
}
// give the target MCU a chance to restart into bootloader
time.Sleep(3 * time.Second)
@@ -218,7 +256,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
// Create the command.
flashCmd := config.Target.FlashCommand
fileToken := "{" + fileExt[1:] + "}"
flashCmd = strings.Replace(flashCmd, fileToken, tmppath, -1)
flashCmd = strings.Replace(flashCmd, fileToken, result.Binary, -1)
if port == "" && strings.Contains(flashCmd, "{port}") {
var err error
@@ -248,21 +286,21 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
cmd.Dir = goenv.Get("TINYGOROOT")
err := cmd.Run()
if err != nil {
return &commandError{"failed to flash", tmppath, err}
return &commandError{"failed to flash", result.Binary, err}
}
return nil
case "msd":
switch fileExt {
case ".uf2":
err := flashUF2UsingMSD(config.Target.FlashVolume, tmppath)
err := flashUF2UsingMSD(config.Target.FlashVolume, result.Binary)
if err != nil {
return &commandError{"failed to flash", tmppath, err}
return &commandError{"failed to flash", result.Binary, err}
}
return nil
case ".hex":
err := flashHexUsingMSD(config.Target.FlashVolume, tmppath)
err := flashHexUsingMSD(config.Target.FlashVolume, result.Binary)
if err != nil {
return &commandError{"failed to flash", tmppath, err}
return &commandError{"failed to flash", result.Binary, err}
}
return nil
default:
@@ -273,13 +311,13 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
if err != nil {
return err
}
args = append(args, "-c", "program "+tmppath+" reset exit")
args = append(args, "-c", "program "+filepath.ToSlash(result.Binary)+" reset exit")
cmd := exec.Command("openocd", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
return &commandError{"failed to flash", tmppath, err}
return &commandError{"failed to flash", result.Binary, err}
}
return nil
default:
@@ -304,7 +342,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(tmppath string) error {
return builder.Build(pkgName, "", config, func(result builder.BuildResult) error {
// Find a good way to run GDB.
gdbInterface, openocdInterface := config.Programmer()
switch gdbInterface {
@@ -313,13 +351,17 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro
// Assume QEMU as an emulator.
if config.Target.Emulator[0] == "mgba" {
gdbInterface = "mgba"
} else {
} else if strings.HasPrefix(config.Target.Emulator[0], "qemu-system-") {
gdbInterface = "qemu"
} else {
gdbInterface = "qemu-user"
}
} else if openocdInterface != "" && config.Target.OpenOCDTarget != "" {
gdbInterface = "openocd"
} else if config.Target.JLinkDevice != "" {
gdbInterface = "jlink"
} else {
gdbInterface = "native"
}
}
@@ -367,7 +409,15 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro
gdbCommands = append(gdbCommands, "target remote :1234")
// Run in an emulator.
args := append(config.Target.Emulator[1:], tmppath, "-s", "-S")
args := append(config.Target.Emulator[1:], result.Binary, "-s", "-S")
daemon = exec.Command(config.Target.Emulator[0], args...)
daemon.Stdout = os.Stdout
daemon.Stderr = os.Stderr
case "qemu-user":
gdbCommands = append(gdbCommands, "target remote :1234")
// Run in an emulator.
args := append(config.Target.Emulator[1:], "-g", "1234", result.Binary)
daemon = exec.Command(config.Target.Emulator[0], args...)
daemon.Stdout = os.Stdout
daemon.Stderr = os.Stderr
@@ -375,7 +425,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro
gdbCommands = append(gdbCommands, "target remote :2345")
// Run in an emulator.
args := append(config.Target.Emulator[1:], tmppath, "-g")
args := append(config.Target.Emulator[1:], result.Binary, "-g")
daemon = exec.Command(config.Target.Emulator[0], args...)
daemon.Stdout = os.Stdout
daemon.Stderr = os.Stderr
@@ -413,7 +463,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro
// Construct and execute a gdb command.
// By default: gdb -ex run <binary>
// Exit GDB with Ctrl-D.
params := []string{tmppath}
params := []string{result.Binary}
for _, cmd := range gdbCommands {
params = append(params, "-ex", cmd)
}
@@ -423,7 +473,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return &commandError{"failed to run gdb with", tmppath, err}
return &commandError{"failed to run gdb with", result.Binary, err}
}
return nil
})
@@ -439,10 +489,10 @@ func Run(pkgName string, options *compileopts.Options) error {
return err
}
return builder.Build(pkgName, ".elf", config, func(tmppath string) error {
return builder.Build(pkgName, ".elf", config, func(result builder.BuildResult) error {
if len(config.Target.Emulator) == 0 {
// Run directly.
cmd := exec.Command(tmppath)
cmd := exec.Command(result.Binary)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
@@ -451,12 +501,12 @@ func Run(pkgName string, options *compileopts.Options) error {
// Workaround for QEMU which always exits with an error.
return nil
}
return &commandError{"failed to run compiled binary", tmppath, err}
return &commandError{"failed to run compiled binary", result.Binary, err}
}
return nil
} else {
// Run in an emulator.
args := append(config.Target.Emulator[1:], tmppath)
args := append(config.Target.Emulator[1:], result.Binary)
cmd := exec.Command(config.Target.Emulator[0], args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@@ -466,7 +516,7 @@ func Run(pkgName string, options *compileopts.Options) error {
// Workaround for QEMU which always exits with an error.
return nil
}
return &commandError{"failed to run emulator with", tmppath, err}
return &commandError{"failed to run emulator with", result.Binary, err}
}
return nil
}
@@ -652,36 +702,6 @@ func getDefaultPort() (port string, err error) {
return d[0], nil
}
// runGoList runs the `go list` command but using the configuration used for
// TinyGo.
func runGoList(config *compileopts.Config, flagJSON, flagDeps bool, pkgs []string) error {
goroot, err := loader.GetCachedGoroot(config)
if err != nil {
return err
}
args := []string{"list"}
if flagJSON {
args = append(args, "-json")
}
if flagDeps {
args = append(args, "-deps")
}
if len(config.BuildTags()) != 0 {
args = append(args, "-tags", strings.Join(config.BuildTags(), " "))
}
args = append(args, pkgs...)
cgoEnabled := "0"
if config.CgoEnabled() {
cgoEnabled = "1"
}
cmd := exec.Command("go", args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = append(os.Environ(), "GOROOT="+goroot, "GOOS="+config.GOOS(), "GOARCH="+config.GOARCH(), "CGO_ENABLED="+cgoEnabled)
cmd.Run()
return nil
}
func usage() {
fmt.Fprintln(os.Stderr, "TinyGo is a Go compiler for small places.")
fmt.Fprintln(os.Stderr, "version:", goenv.Version)
@@ -755,10 +775,16 @@ func printCompilerError(logln func(...interface{}), err error) {
}
}
case loader.Errors:
logln("#", err.Pkg.PkgPath)
logln("#", err.Pkg.ImportPath)
for _, err := range err.Errs {
printCompilerError(logln, err)
}
case loader.Error:
logln(err.Err.Error())
logln("package", err.ImportStack[0])
for _, pkgPath := range err.ImportStack[1:] {
logln("\timports", pkgPath)
}
case *builder.MultiError:
for _, err := range err.Errs {
printCompilerError(logln, err)
@@ -785,7 +811,6 @@ func main() {
}
command := os.Args[1]
outpath := flag.String("o", "", "output filename")
opt := flag.String("opt", "z", "optimization level: 0, 1, 2, s, z")
gc := flag.String("gc", "", "garbage collector to use (none, leaking, extalloc, conservative)")
panicStrategy := flag.String("panic", "print", "panic strategy (print, trap)")
@@ -796,20 +821,29 @@ func main() {
tags := flag.String("tags", "", "a space-separated list of extra build tags")
target := flag.String("target", "", "LLVM target | .json file with TargetSpec")
printSize := flag.String("size", "", "print sizes (none, short, full)")
printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines")
nodebug := flag.Bool("no-debug", false, "disable DWARF debug symbol generation")
ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug")
port := flag.String("port", "", "flash port")
programmer := flag.String("programmer", "", "which hardware programmer to use")
cFlags := flag.String("cflags", "", "additional cflags for compiler")
ldFlags := flag.String("ldflags", "", "additional ldflags for linker")
wasmAbi := flag.String("wasm-abi", "js", "WebAssembly ABI conventions: js (no i64 params) or generic")
wasmAbi := flag.String("wasm-abi", "", "WebAssembly ABI conventions: js (no i64 params) or generic")
heapSize := flag.String("heap-size", "1M", "default heap size in bytes (only supported by WebAssembly)")
var flagJSON, flagDeps *bool
if command == "list" {
if command == "help" || command == "list" {
flagJSON = flag.Bool("json", false, "print data in JSON format")
flagDeps = flag.Bool("deps", false, "")
}
var outpath string
if command == "help" || command == "build" || command == "build-library" || command == "test" {
flag.StringVar(&outpath, "o", "", "output filename")
}
var testCompileOnlyFlag *bool
if command == "help" || command == "test" {
testCompileOnlyFlag = flag.Bool("c", false, "compile the test binary but do not run it")
}
// Early command processing, before commands are interpreted by the Go flag
// library.
@@ -835,6 +869,7 @@ func main() {
VerifyIR: *verifyIR,
Debug: !*nodebug,
PrintSizes: *printSize,
PrintStacks: *printStacks,
Tags: *tags,
WasmAbi: *wasmAbi,
Programmer: *programmer,
@@ -866,7 +901,7 @@ func main() {
switch command {
case "build":
if *outpath == "" {
if outpath == "" {
fmt.Fprintln(os.Stderr, "No output filename supplied (-o).")
usage()
os.Exit(1)
@@ -879,15 +914,15 @@ func main() {
usage()
os.Exit(1)
}
if options.Target == "" && filepath.Ext(*outpath) == ".wasm" {
if options.Target == "" && filepath.Ext(outpath) == ".wasm" {
options.Target = "wasm"
}
err := Build(pkgName, *outpath, options)
err := Build(pkgName, outpath, options)
handleCompilerError(err)
case "build-library":
// Note: this command is only meant to be used while making a release!
if *outpath == "" {
if outpath == "" {
fmt.Fprintln(os.Stderr, "No output filename supplied (-o).")
usage()
os.Exit(1)
@@ -912,13 +947,8 @@ func main() {
}
path, err := lib.Load(*target)
handleCompilerError(err)
copyFile(path, *outpath)
copyFile(path, outpath)
case "flash", "gdb":
if *outpath != "" {
fmt.Fprintln(os.Stderr, "Output cannot be specified with the flash command.")
usage()
os.Exit(1)
}
pkgName := filepath.ToSlash(flag.Arg(0))
if command == "flash" {
err := Flash(pkgName, *port, options)
@@ -950,8 +980,37 @@ func main() {
usage()
os.Exit(1)
}
err := Test(pkgName, options)
err := Test(pkgName, options, *testCompileOnlyFlag, outpath)
handleCompilerError(err)
case "targets":
dir := filepath.Join(goenv.Get("TINYGOROOT"), "targets")
entries, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Fprintln(os.Stderr, "could not list targets:", err)
os.Exit(1)
return
}
for _, entry := range entries {
if !entry.Mode().IsRegular() || !strings.HasSuffix(entry.Name(), ".json") {
// Only inspect JSON files.
continue
}
path := filepath.Join(dir, entry.Name())
spec, err := compileopts.LoadTarget(path)
if err != nil {
fmt.Fprintln(os.Stderr, "could not list target:", err)
os.Exit(1)
return
}
if spec.FlashMethod == "" && spec.FlashCommand == "" && spec.Emulator == nil {
// This doesn't look like a regular target file, but rather like
// a parent target (such as targets/cortex-m.json).
continue
}
name := entry.Name()
name = name[:len(name)-5]
fmt.Println(name)
}
case "info":
if flag.NArg() == 1 {
options.Target = flag.Arg(0)
@@ -971,12 +1030,18 @@ func main() {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
cachedGOROOT, err := loader.GetCachedGoroot(config)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("LLVM triple: %s\n", config.Triple())
fmt.Printf("GOOS: %s\n", config.GOOS())
fmt.Printf("GOARCH: %s\n", config.GOARCH())
fmt.Printf("build tags: %s\n", strings.Join(config.BuildTags(), " "))
fmt.Printf("garbage collector: %s\n", config.GC())
fmt.Printf("scheduler: %s\n", config.Scheduler())
fmt.Printf("cached GOROOT: %s\n", cachedGOROOT)
case "list":
config, err := builder.NewConfig(options)
if err != nil {
@@ -984,11 +1049,31 @@ func main() {
usage()
os.Exit(1)
}
err = runGoList(config, *flagJSON, *flagDeps, flag.Args())
var extraArgs []string
if *flagJSON {
extraArgs = append(extraArgs, "-json")
}
if *flagDeps {
extraArgs = append(extraArgs, "-deps")
}
cmd, err := loader.List(config, extraArgs, flag.Args())
if err != nil {
fmt.Fprintln(os.Stderr, "failed to run `go list`:", err)
os.Exit(1)
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
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)
}
fmt.Fprintln(os.Stderr, "failed to run `go list`:", err)
os.Exit(1)
}
case "clean":
// remove cache directory
err := os.RemoveAll(goenv.Get("GOCACHE"))
@@ -1003,7 +1088,11 @@ func main() {
if s, err := goenv.GorootVersionString(goenv.Get("GOROOT")); err == nil {
goversion = s
}
fmt.Printf("tinygo version %s %s/%s (using go version %s and LLVM version %s)\n", goenv.Version, runtime.GOOS, runtime.GOARCH, goversion, llvm.Version)
version := goenv.Version
if strings.HasSuffix(goenv.Version, "-dev") && gitSha1 != "" {
version += "-" + gitSha1
}
fmt.Printf("tinygo version %s %s/%s (using go version %s and LLVM version %s)\n", version, runtime.GOOS, runtime.GOARCH, goversion, llvm.Version)
case "env":
if flag.NArg() == 0 {
// Show all environment variables.
+25 -6
View File
@@ -6,6 +6,7 @@ package main
import (
"bufio"
"bytes"
"flag"
"fmt"
"io/ioutil"
"os"
@@ -25,6 +26,8 @@ import (
const TESTDATA = "testdata"
var testTarget = flag.String("target", "", "override test target")
func TestCompiler(t *testing.T) {
matches, err := filepath.Glob(filepath.Join(TESTDATA, "*.go"))
if err != nil {
@@ -44,6 +47,14 @@ func TestCompiler(t *testing.T) {
sort.Strings(matches)
if *testTarget != "" {
// This makes it possible to run one specific test (instead of all),
// which is especially useful to quickly check whether some changes
// affect a particular target architecture.
runPlatTests(*testTarget, matches, t)
return
}
if runtime.GOOS != "windows" {
t.Run("Host", func(t *testing.T) {
runPlatTests("", matches, t)
@@ -67,6 +78,9 @@ func TestCompiler(t *testing.T) {
}
if runtime.GOOS == "linux" {
t.Run("X86Linux", func(t *testing.T) {
runPlatTests("i386--linux-gnu", matches, t)
})
t.Run("ARMLinux", func(t *testing.T) {
runPlatTests("arm--linux-gnueabihf", matches, t)
})
@@ -87,6 +101,10 @@ func TestCompiler(t *testing.T) {
runPlatTests("wasm", matches, t)
})
}
t.Run("WASI", func(t *testing.T) {
runPlatTests("wasi", matches, t)
})
}
}
@@ -98,7 +116,6 @@ func runPlatTests(target string, matches []string, t *testing.T) {
t.Run(filepath.Base(path), func(t *testing.T) {
t.Parallel()
runTest(path, target, t)
})
}
@@ -146,10 +163,11 @@ func runTest(path, target string, t *testing.T) {
PrintIR: false,
DumpSSA: false,
VerifyIR: true,
Debug: false,
Debug: true,
PrintSizes: "",
WasmAbi: "js",
WasmAbi: "",
}
binary := filepath.Join(tmpdir, "test")
err = runBuild("./"+path, binary, config)
if err != nil {
@@ -170,10 +188,11 @@ func runTest(path, target string, t *testing.T) {
t.Fatal("failed to load target spec:", err)
}
if len(spec.Emulator) == 0 {
t.Fatal("no emulator available for target:", target)
cmd = exec.Command(binary)
} else {
args := append(spec.Emulator[1:], binary)
cmd = exec.Command(spec.Emulator[0], args...)
}
args := append(spec.Emulator[1:], binary)
cmd = exec.Command(spec.Emulator[0], args...)
}
stdout := &bytes.Buffer{}
cmd.Stdout = stdout
+5 -35
View File
@@ -76,32 +76,8 @@ const (
SCS_BASE = 0xE000E000
SYST_BASE = SCS_BASE + 0x0010
NVIC_BASE = SCS_BASE + 0x0100
SCB_BASE = SCS_BASE + 0x0D00
)
const (
SCB_AIRCR_VECTKEY_Pos = 16
SCB_AIRCR_SYSRESETREQ_Pos = 2
SCB_AIRCR_SYSRESETREQ_Msk = 1 << SCB_AIRCR_SYSRESETREQ_Pos
)
// System Control Block (SCB)
//
// SCB_Type provides the definitions for the System Control Block Registers.
type SCB_Type struct {
CPUID volatile.Register32 // CPUID Base Register
ICSR volatile.Register32 // Interrupt Control and State Register
VTOR volatile.Register32 // Vector Table Offset Register
AIRCR volatile.Register32 // Application Interrupt and Reset Control Register
SCR volatile.Register32 // System Control Register
CCR volatile.Register32 // Configuration Control Register
_ volatile.Register32 // RESERVED1;
SHP [2]volatile.Register32 // System Handlers Priority Registers. [0] is RESERVED
SHCSR volatile.Register32 // System Handler Control and State Register
}
var SCB = (*SCB_Type)(unsafe.Pointer(uintptr(SCB_BASE)))
// Nested Vectored Interrupt Controller (NVIC).
//
// Source:
@@ -174,6 +150,11 @@ func EnableIRQ(irq uint32) {
NVIC.ISER[irq>>5].Set(1 << (irq & 0x1F))
}
// Disable the given interrupt number.
func DisableIRQ(irq uint32) {
NVIC.ICER[irq>>5].Set(1 << (irq & 0x1F))
}
// Set the priority of the given interrupt number.
// Note that the priority is given as a 0-255 number, where some of the lower
// bits are not implemented by the hardware. For example, to set a low interrupt
@@ -208,17 +189,6 @@ func EnableInterrupts(mask uintptr) {
})
}
// SystemReset performs a hard system reset.
func SystemReset() {
// SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
// SCB_AIRCR_SYSRESETREQ_Msk);
SCB.AIRCR.Set((0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk)
for {
Asm("wfi")
}
}
// Set up the system timer to generate periodic tick events.
// This will cause SysTick_Handler to fire once per tick.
// The cyclecount parameter is a counter value which can range from 0 to
+7
View File
@@ -1,9 +1,11 @@
.syntax unified
.cfi_sections .debug_frame
.section .text.HardFault_Handler
.global HardFault_Handler
.type HardFault_Handler, %function
HardFault_Handler:
.cfi_startproc
// Put the old stack pointer in the first argument, for easy debugging. This
// is especially useful on Cortex-M0, which supports far fewer debug
// facilities.
@@ -19,6 +21,8 @@ HardFault_Handler:
// Continue handling this error in Go.
bl handleHardFault
.cfi_endproc
.size HardFault_Handler, .-HardFault_Handler
// This is a convenience function for semihosting support.
// At some point, this should be replaced by inline assembly.
@@ -26,5 +30,8 @@ HardFault_Handler:
.global SemihostingCall
.type SemihostingCall, %function
SemihostingCall:
.cfi_startproc
bkpt 0xab
bx lr
.cfi_endproc
.size SemihostingCall, .-SemihostingCall
+431
View File
@@ -0,0 +1,431 @@
// Hand created file. DO NOT DELETE.
// Cortex-M System Control Block-related definitions.
// +build cortexm
package arm
import (
"runtime/volatile"
"unsafe"
)
const SCB_BASE = SCS_BASE + 0x0D00
// System Control Block (SCB)
//
// SCB_Type provides the definitions for the System Control Block Registers.
type SCB_Type struct {
CPUID volatile.Register32 // 0xD00: CPUID Base Register
ICSR volatile.Register32 // 0xD04: Interrupt Control and State Register
VTOR volatile.Register32 // 0xD08: Vector Table Offset Register
AIRCR volatile.Register32 // 0xD0C: Application Interrupt and Reset Control Register
SCR volatile.Register32 // 0xD10: System Control Register
CCR volatile.Register32 // 0xD14: Configuration and Control Register
SHPR1 volatile.Register32 // 0xD18: System Handler Priority Register 1 (Cortex-M3/M33/M4/M7 only)
SHPR2 volatile.Register32 // 0xD1C: System Handler Priority Register 2
SHPR3 volatile.Register32 // 0xD20: System Handler Priority Register 3
// the following are only applicable for Cortex-M3/M33/M4/M7
SHCSR volatile.Register32 // 0xD24: System Handler Control and State Register
CFSR volatile.Register32 // 0xD28: Configurable Fault Status Register
HFSR volatile.Register32 // 0xD2C: HardFault Status Register
DFSR volatile.Register32 // 0xD30: Debug Fault Status Register
MMFAR volatile.Register32 // 0xD34: MemManage Fault Address Register
BFAR volatile.Register32 // 0xD38: BusFault Address Register
}
var SCB = (*SCB_Type)(unsafe.Pointer(uintptr(SCB_BASE)))
// SystemReset performs a hard system reset.
func SystemReset() {
SCB.AIRCR.Set((0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk)
for {
Asm("wfi")
}
}
const (
// CPUID: CPUID Base Register
SCB_CPUID_REVISION_Pos = 0x0 // Position of REVISION field.
SCB_CPUID_REVISION_Msk = 0xf // Bit mask of REVISION field.
SCB_CPUID_PARTNO_Pos = 0x4 // Position of PARTNO field.
SCB_CPUID_PARTNO_Msk = 0xfff0 // Bit mask of PARTNO field.
SCB_CPUID_ARCHITECTURE_Pos = 0x10 // Position of ARCHITECTURE field.
SCB_CPUID_ARCHITECTURE_Msk = 0xf0000 // Bit mask of ARCHITECTURE field.
SCB_CPUID_VARIANT_Pos = 0x14 // Position of VARIANT field.
SCB_CPUID_VARIANT_Msk = 0xf00000 // Bit mask of VARIANT field.
SCB_CPUID_IMPLEMENTER_Pos = 0x18 // Position of IMPLEMENTER field.
SCB_CPUID_IMPLEMENTER_Msk = 0xff000000 // Bit mask of IMPLEMENTER field.
// ICSR: Interrupt Control and State Register
SCB_ICSR_VECTACTIVE_Pos = 0x0 // Position of VECTACTIVE field.
SCB_ICSR_VECTACTIVE_Msk = 0x1ff // Bit mask of VECTACTIVE field.
SCB_ICSR_RETTOBASE_Pos = 0xb // Position of RETTOBASE field.
SCB_ICSR_RETTOBASE_Msk = 0x800 // Bit mask of RETTOBASE field.
SCB_ICSR_RETTOBASE = 0x800 // Bit RETTOBASE.
SCB_ICSR_RETTOBASE_RETTOBASE_0 = 0x0 // there are preempted active exceptions to execute
SCB_ICSR_RETTOBASE_RETTOBASE_1 = 0x1 // there are no active exceptions, or the currently-executing exception is the only active exception
SCB_ICSR_VECTPENDING_Pos = 0xc // Position of VECTPENDING field.
SCB_ICSR_VECTPENDING_Msk = 0x1ff000 // Bit mask of VECTPENDING field.
SCB_ICSR_ISRPENDING_Pos = 0x16 // Position of ISRPENDING field.
SCB_ICSR_ISRPENDING_Msk = 0x400000 // Bit mask of ISRPENDING field.
SCB_ICSR_ISRPENDING = 0x400000 // Bit ISRPENDING.
SCB_ICSR_ISRPENDING_ISRPENDING_0 = 0x0 // No external interrupt pending.
SCB_ICSR_ISRPENDING_ISRPENDING_1 = 0x1 // External interrupt pending.
SCB_ICSR_PENDSTCLR_Pos = 0x19 // Position of PENDSTCLR field.
SCB_ICSR_PENDSTCLR_Msk = 0x2000000 // Bit mask of PENDSTCLR field.
SCB_ICSR_PENDSTCLR = 0x2000000 // Bit PENDSTCLR.
SCB_ICSR_PENDSTCLR_PENDSTCLR_0 = 0x0 // no effect
SCB_ICSR_PENDSTCLR_PENDSTCLR_1 = 0x1 // removes the pending state from the SysTick exception
SCB_ICSR_PENDSTSET_Pos = 0x1a // Position of PENDSTSET field.
SCB_ICSR_PENDSTSET_Msk = 0x4000000 // Bit mask of PENDSTSET field.
SCB_ICSR_PENDSTSET = 0x4000000 // Bit PENDSTSET.
SCB_ICSR_PENDSTSET_PENDSTSET_0 = 0x0 // write: no effect; read: SysTick exception is not pending
SCB_ICSR_PENDSTSET_PENDSTSET_1 = 0x1 // write: changes SysTick exception state to pending; read: SysTick exception is pending
SCB_ICSR_PENDSVCLR_Pos = 0x1b // Position of PENDSVCLR field.
SCB_ICSR_PENDSVCLR_Msk = 0x8000000 // Bit mask of PENDSVCLR field.
SCB_ICSR_PENDSVCLR = 0x8000000 // Bit PENDSVCLR.
SCB_ICSR_PENDSVCLR_PENDSVCLR_0 = 0x0 // no effect
SCB_ICSR_PENDSVCLR_PENDSVCLR_1 = 0x1 // removes the pending state from the PendSV exception
SCB_ICSR_PENDSVSET_Pos = 0x1c // Position of PENDSVSET field.
SCB_ICSR_PENDSVSET_Msk = 0x10000000 // Bit mask of PENDSVSET field.
SCB_ICSR_PENDSVSET = 0x10000000 // Bit PENDSVSET.
SCB_ICSR_PENDSVSET_PENDSVSET_0 = 0x0 // write: no effect; read: PendSV exception is not pending
SCB_ICSR_PENDSVSET_PENDSVSET_1 = 0x1 // write: changes PendSV exception state to pending; read: PendSV exception is pending
SCB_ICSR_NMIPENDSET_Pos = 0x1f // Position of NMIPENDSET field.
SCB_ICSR_NMIPENDSET_Msk = 0x80000000 // Bit mask of NMIPENDSET field.
SCB_ICSR_NMIPENDSET = 0x80000000 // Bit NMIPENDSET.
SCB_ICSR_NMIPENDSET_NMIPENDSET_0 = 0x0 // write: no effect; read: NMI exception is not pending
SCB_ICSR_NMIPENDSET_NMIPENDSET_1 = 0x1 // write: changes NMI exception state to pending; read: NMI exception is pending
// VTOR: Vector Table Offset Register
SCB_VTOR_TBLOFF_Pos = 0x7 // Position of TBLOFF field.
SCB_VTOR_TBLOFF_Msk = 0xffffff80 // Bit mask of TBLOFF field.
// AIRCR: Application Interrupt and Reset Control Register
SCB_AIRCR_VECTRESET_Pos = 0x0 // Position of VECTRESET field.
SCB_AIRCR_VECTRESET_Msk = 0x1 // Bit mask of VECTRESET field.
SCB_AIRCR_VECTRESET = 0x1 // Bit VECTRESET.
SCB_AIRCR_VECTRESET_VECTRESET_0 = 0x0 // No change
SCB_AIRCR_VECTRESET_VECTRESET_1 = 0x1 // Causes a local system reset
SCB_AIRCR_VECTCLRACTIVE_Pos = 0x1 // Position of VECTCLRACTIVE field.
SCB_AIRCR_VECTCLRACTIVE_Msk = 0x2 // Bit mask of VECTCLRACTIVE field.
SCB_AIRCR_VECTCLRACTIVE = 0x2 // Bit VECTCLRACTIVE.
SCB_AIRCR_VECTCLRACTIVE_VECTCLRACTIVE_0 = 0x0 // No change
SCB_AIRCR_VECTCLRACTIVE_VECTCLRACTIVE_1 = 0x1 // Clears all active state information for fixed and configurable exceptions
SCB_AIRCR_SYSRESETREQ_Pos = 0x2 // Position of SYSRESETREQ field.
SCB_AIRCR_SYSRESETREQ_Msk = 0x4 // Bit mask of SYSRESETREQ field.
SCB_AIRCR_SYSRESETREQ = 0x4 // Bit SYSRESETREQ.
SCB_AIRCR_SYSRESETREQ_SYSRESETREQ_0 = 0x0 // no system reset request
SCB_AIRCR_SYSRESETREQ_SYSRESETREQ_1 = 0x1 // asserts a signal to the outer system that requests a reset
SCB_AIRCR_PRIGROUP_Pos = 0x8 // Position of PRIGROUP field.
SCB_AIRCR_PRIGROUP_Msk = 0x700 // Bit mask of PRIGROUP field.
SCB_AIRCR_ENDIANNESS_Pos = 0xf // Position of ENDIANNESS field.
SCB_AIRCR_ENDIANNESS_Msk = 0x8000 // Bit mask of ENDIANNESS field.
SCB_AIRCR_ENDIANNESS = 0x8000 // Bit ENDIANNESS.
SCB_AIRCR_ENDIANNESS_ENDIANNESS_0 = 0x0 // Little-endian
SCB_AIRCR_ENDIANNESS_ENDIANNESS_1 = 0x1 // Big-endian
SCB_AIRCR_VECTKEY_Pos = 0x10 // Position of VECTKEY field.
SCB_AIRCR_VECTKEY_Msk = 0xffff0000 // Bit mask of VECTKEY field.
// SCR: System Control Register
SCB_SCR_SLEEPONEXIT_Pos = 0x1 // Position of SLEEPONEXIT field.
SCB_SCR_SLEEPONEXIT_Msk = 0x2 // Bit mask of SLEEPONEXIT field.
SCB_SCR_SLEEPONEXIT = 0x2 // Bit SLEEPONEXIT.
SCB_SCR_SLEEPONEXIT_SLEEPONEXIT_0 = 0x0 // o not sleep when returning to Thread mode
SCB_SCR_SLEEPONEXIT_SLEEPONEXIT_1 = 0x1 // enter sleep, or deep sleep, on return from an ISR
SCB_SCR_SLEEPDEEP_Pos = 0x2 // Position of SLEEPDEEP field.
SCB_SCR_SLEEPDEEP_Msk = 0x4 // Bit mask of SLEEPDEEP field.
SCB_SCR_SLEEPDEEP = 0x4 // Bit SLEEPDEEP.
SCB_SCR_SLEEPDEEP_SLEEPDEEP_0 = 0x0 // sleep
SCB_SCR_SLEEPDEEP_SLEEPDEEP_1 = 0x1 // deep sleep
SCB_SCR_SEVONPEND_Pos = 0x4 // Position of SEVONPEND field.
SCB_SCR_SEVONPEND_Msk = 0x10 // Bit mask of SEVONPEND field.
SCB_SCR_SEVONPEND = 0x10 // Bit SEVONPEND.
SCB_SCR_SEVONPEND_SEVONPEND_0 = 0x0 // only enabled interrupts or events can wakeup the processor, disabled interrupts are excluded
SCB_SCR_SEVONPEND_SEVONPEND_1 = 0x1 // enabled events and all interrupts, including disabled interrupts, can wakeup the processor
// CCR: Configuration and Control Register
SCB_CCR_NONBASETHRDENA_Pos = 0x0 // Position of NONBASETHRDENA field.
SCB_CCR_NONBASETHRDENA_Msk = 0x1 // Bit mask of NONBASETHRDENA field.
SCB_CCR_NONBASETHRDENA = 0x1 // Bit NONBASETHRDENA.
SCB_CCR_NONBASETHRDENA_NONBASETHRDENA_0 = 0x0 // processor can enter Thread mode only when no exception is active
SCB_CCR_NONBASETHRDENA_NONBASETHRDENA_1 = 0x1 // processor can enter Thread mode from any level under the control of an EXC_RETURN value
SCB_CCR_USERSETMPEND_Pos = 0x1 // Position of USERSETMPEND field.
SCB_CCR_USERSETMPEND_Msk = 0x2 // Bit mask of USERSETMPEND field.
SCB_CCR_USERSETMPEND = 0x2 // Bit USERSETMPEND.
SCB_CCR_USERSETMPEND_USERSETMPEND_0 = 0x0 // disable
SCB_CCR_USERSETMPEND_USERSETMPEND_1 = 0x1 // enable
SCB_CCR_UNALIGN_TRP_Pos = 0x3 // Position of UNALIGN_TRP field.
SCB_CCR_UNALIGN_TRP_Msk = 0x8 // Bit mask of UNALIGN_TRP field.
SCB_CCR_UNALIGN_TRP = 0x8 // Bit UNALIGN_TRP.
SCB_CCR_UNALIGN_TRP_UNALIGN_TRP_0 = 0x0 // do not trap unaligned halfword and word accesses
SCB_CCR_UNALIGN_TRP_UNALIGN_TRP_1 = 0x1 // trap unaligned halfword and word accesses
SCB_CCR_DIV_0_TRP_Pos = 0x4 // Position of DIV_0_TRP field.
SCB_CCR_DIV_0_TRP_Msk = 0x10 // Bit mask of DIV_0_TRP field.
SCB_CCR_DIV_0_TRP = 0x10 // Bit DIV_0_TRP.
SCB_CCR_DIV_0_TRP_DIV_0_TRP_0 = 0x0 // do not trap divide by 0
SCB_CCR_DIV_0_TRP_DIV_0_TRP_1 = 0x1 // trap divide by 0
SCB_CCR_BFHFNMIGN_Pos = 0x8 // Position of BFHFNMIGN field.
SCB_CCR_BFHFNMIGN_Msk = 0x100 // Bit mask of BFHFNMIGN field.
SCB_CCR_BFHFNMIGN = 0x100 // Bit BFHFNMIGN.
SCB_CCR_BFHFNMIGN_BFHFNMIGN_0 = 0x0 // data bus faults caused by load and store instructions cause a lock-up
SCB_CCR_BFHFNMIGN_BFHFNMIGN_1 = 0x1 // handlers running at priority -1 and -2 ignore data bus faults caused by load and store instructions
SCB_CCR_STKALIGN_Pos = 0x9 // Position of STKALIGN field.
SCB_CCR_STKALIGN_Msk = 0x200 // Bit mask of STKALIGN field.
SCB_CCR_STKALIGN = 0x200 // Bit STKALIGN.
SCB_CCR_STKALIGN_STKALIGN_0 = 0x0 // 4-byte aligned
SCB_CCR_STKALIGN_STKALIGN_1 = 0x1 // 8-byte aligned
SCB_CCR_DC_Pos = 0x10 // Position of DC field.
SCB_CCR_DC_Msk = 0x10000 // Bit mask of DC field.
SCB_CCR_DC = 0x10000 // Bit DC.
SCB_CCR_DC_DC_0 = 0x0 // L1 data cache disabled
SCB_CCR_DC_DC_1 = 0x1 // L1 data cache enabled
SCB_CCR_IC_Pos = 0x11 // Position of IC field.
SCB_CCR_IC_Msk = 0x20000 // Bit mask of IC field.
SCB_CCR_IC = 0x20000 // Bit IC.
SCB_CCR_IC_IC_0 = 0x0 // L1 instruction cache disabled
SCB_CCR_IC_IC_1 = 0x1 // L1 instruction cache enabled
SCB_CCR_BP_Pos = 0x12 // Position of BP field.
SCB_CCR_BP_Msk = 0x40000 // Bit mask of BP field.
SCB_CCR_BP = 0x40000 // Bit BP.
// SHPR1: System Handler Priority Register 1
SCB_SHPR1_PRI_4_Pos = 0x0 // Position of PRI_4 field.
SCB_SHPR1_PRI_4_Msk = 0xff // Bit mask of PRI_4 field.
SCB_SHPR1_PRI_5_Pos = 0x8 // Position of PRI_5 field.
SCB_SHPR1_PRI_5_Msk = 0xff00 // Bit mask of PRI_5 field.
SCB_SHPR1_PRI_6_Pos = 0x10 // Position of PRI_6 field.
SCB_SHPR1_PRI_6_Msk = 0xff0000 // Bit mask of PRI_6 field.
// SHPR2: System Handler Priority Register 2
SCB_SHPR2_PRI_11_Pos = 0x18 // Position of PRI_11 field.
SCB_SHPR2_PRI_11_Msk = 0xff000000 // Bit mask of PRI_11 field.
// SHPR3: System Handler Priority Register 3
SCB_SHPR3_PRI_14_Pos = 0x10 // Position of PRI_14 field.
SCB_SHPR3_PRI_14_Msk = 0xff0000 // Bit mask of PRI_14 field.
SCB_SHPR3_PRI_15_Pos = 0x18 // Position of PRI_15 field.
SCB_SHPR3_PRI_15_Msk = 0xff000000 // Bit mask of PRI_15 field.
// SHCSR: System Handler Control and State Register
SCB_SHCSR_MEMFAULTACT_Pos = 0x0 // Position of MEMFAULTACT field.
SCB_SHCSR_MEMFAULTACT_Msk = 0x1 // Bit mask of MEMFAULTACT field.
SCB_SHCSR_MEMFAULTACT = 0x1 // Bit MEMFAULTACT.
SCB_SHCSR_MEMFAULTACT_MEMFAULTACT_0 = 0x0 // exception is not active
SCB_SHCSR_MEMFAULTACT_MEMFAULTACT_1 = 0x1 // exception is active
SCB_SHCSR_BUSFAULTACT_Pos = 0x1 // Position of BUSFAULTACT field.
SCB_SHCSR_BUSFAULTACT_Msk = 0x2 // Bit mask of BUSFAULTACT field.
SCB_SHCSR_BUSFAULTACT = 0x2 // Bit BUSFAULTACT.
SCB_SHCSR_BUSFAULTACT_BUSFAULTACT_0 = 0x0 // exception is not active
SCB_SHCSR_BUSFAULTACT_BUSFAULTACT_1 = 0x1 // exception is active
SCB_SHCSR_USGFAULTACT_Pos = 0x3 // Position of USGFAULTACT field.
SCB_SHCSR_USGFAULTACT_Msk = 0x8 // Bit mask of USGFAULTACT field.
SCB_SHCSR_USGFAULTACT = 0x8 // Bit USGFAULTACT.
SCB_SHCSR_USGFAULTACT_USGFAULTACT_0 = 0x0 // exception is not active
SCB_SHCSR_USGFAULTACT_USGFAULTACT_1 = 0x1 // exception is active
SCB_SHCSR_SVCALLACT_Pos = 0x7 // Position of SVCALLACT field.
SCB_SHCSR_SVCALLACT_Msk = 0x80 // Bit mask of SVCALLACT field.
SCB_SHCSR_SVCALLACT = 0x80 // Bit SVCALLACT.
SCB_SHCSR_SVCALLACT_SVCALLACT_0 = 0x0 // exception is not active
SCB_SHCSR_SVCALLACT_SVCALLACT_1 = 0x1 // exception is active
SCB_SHCSR_MONITORACT_Pos = 0x8 // Position of MONITORACT field.
SCB_SHCSR_MONITORACT_Msk = 0x100 // Bit mask of MONITORACT field.
SCB_SHCSR_MONITORACT = 0x100 // Bit MONITORACT.
SCB_SHCSR_MONITORACT_MONITORACT_0 = 0x0 // exception is not active
SCB_SHCSR_MONITORACT_MONITORACT_1 = 0x1 // exception is active
SCB_SHCSR_PENDSVACT_Pos = 0xa // Position of PENDSVACT field.
SCB_SHCSR_PENDSVACT_Msk = 0x400 // Bit mask of PENDSVACT field.
SCB_SHCSR_PENDSVACT = 0x400 // Bit PENDSVACT.
SCB_SHCSR_PENDSVACT_PENDSVACT_0 = 0x0 // exception is not active
SCB_SHCSR_PENDSVACT_PENDSVACT_1 = 0x1 // exception is active
SCB_SHCSR_SYSTICKACT_Pos = 0xb // Position of SYSTICKACT field.
SCB_SHCSR_SYSTICKACT_Msk = 0x800 // Bit mask of SYSTICKACT field.
SCB_SHCSR_SYSTICKACT = 0x800 // Bit SYSTICKACT.
SCB_SHCSR_SYSTICKACT_SYSTICKACT_0 = 0x0 // exception is not active
SCB_SHCSR_SYSTICKACT_SYSTICKACT_1 = 0x1 // exception is active
SCB_SHCSR_USGFAULTPENDED_Pos = 0xc // Position of USGFAULTPENDED field.
SCB_SHCSR_USGFAULTPENDED_Msk = 0x1000 // Bit mask of USGFAULTPENDED field.
SCB_SHCSR_USGFAULTPENDED = 0x1000 // Bit USGFAULTPENDED.
SCB_SHCSR_USGFAULTPENDED_USGFAULTPENDED_0 = 0x0 // exception is not pending
SCB_SHCSR_USGFAULTPENDED_USGFAULTPENDED_1 = 0x1 // exception is pending
SCB_SHCSR_MEMFAULTPENDED_Pos = 0xd // Position of MEMFAULTPENDED field.
SCB_SHCSR_MEMFAULTPENDED_Msk = 0x2000 // Bit mask of MEMFAULTPENDED field.
SCB_SHCSR_MEMFAULTPENDED = 0x2000 // Bit MEMFAULTPENDED.
SCB_SHCSR_MEMFAULTPENDED_MEMFAULTPENDED_0 = 0x0 // exception is not pending
SCB_SHCSR_MEMFAULTPENDED_MEMFAULTPENDED_1 = 0x1 // exception is pending
SCB_SHCSR_BUSFAULTPENDED_Pos = 0xe // Position of BUSFAULTPENDED field.
SCB_SHCSR_BUSFAULTPENDED_Msk = 0x4000 // Bit mask of BUSFAULTPENDED field.
SCB_SHCSR_BUSFAULTPENDED = 0x4000 // Bit BUSFAULTPENDED.
SCB_SHCSR_BUSFAULTPENDED_BUSFAULTPENDED_0 = 0x0 // exception is not pending
SCB_SHCSR_BUSFAULTPENDED_BUSFAULTPENDED_1 = 0x1 // exception is pending
SCB_SHCSR_SVCALLPENDED_Pos = 0xf // Position of SVCALLPENDED field.
SCB_SHCSR_SVCALLPENDED_Msk = 0x8000 // Bit mask of SVCALLPENDED field.
SCB_SHCSR_SVCALLPENDED = 0x8000 // Bit SVCALLPENDED.
SCB_SHCSR_SVCALLPENDED_SVCALLPENDED_0 = 0x0 // exception is not pending
SCB_SHCSR_SVCALLPENDED_SVCALLPENDED_1 = 0x1 // exception is pending
SCB_SHCSR_MEMFAULTENA_Pos = 0x10 // Position of MEMFAULTENA field.
SCB_SHCSR_MEMFAULTENA_Msk = 0x10000 // Bit mask of MEMFAULTENA field.
SCB_SHCSR_MEMFAULTENA = 0x10000 // Bit MEMFAULTENA.
SCB_SHCSR_MEMFAULTENA_MEMFAULTENA_0 = 0x0 // disable the exception
SCB_SHCSR_MEMFAULTENA_MEMFAULTENA_1 = 0x1 // enable the exception
SCB_SHCSR_BUSFAULTENA_Pos = 0x11 // Position of BUSFAULTENA field.
SCB_SHCSR_BUSFAULTENA_Msk = 0x20000 // Bit mask of BUSFAULTENA field.
SCB_SHCSR_BUSFAULTENA = 0x20000 // Bit BUSFAULTENA.
SCB_SHCSR_BUSFAULTENA_BUSFAULTENA_0 = 0x0 // disable the exception
SCB_SHCSR_BUSFAULTENA_BUSFAULTENA_1 = 0x1 // enable the exception
SCB_SHCSR_USGFAULTENA_Pos = 0x12 // Position of USGFAULTENA field.
SCB_SHCSR_USGFAULTENA_Msk = 0x40000 // Bit mask of USGFAULTENA field.
SCB_SHCSR_USGFAULTENA = 0x40000 // Bit USGFAULTENA.
SCB_SHCSR_USGFAULTENA_USGFAULTENA_0 = 0x0 // disable the exception
SCB_SHCSR_USGFAULTENA_USGFAULTENA_1 = 0x1 // enable the exception
// CFSR: Configurable Fault Status Register
SCB_CFSR_IACCVIOL_Pos = 0x0 // Position of IACCVIOL field.
SCB_CFSR_IACCVIOL_Msk = 0x1 // Bit mask of IACCVIOL field.
SCB_CFSR_IACCVIOL = 0x1 // Bit IACCVIOL.
SCB_CFSR_IACCVIOL_IACCVIOL_0 = 0x0 // no instruction access violation fault
SCB_CFSR_IACCVIOL_IACCVIOL_1 = 0x1 // the processor attempted an instruction fetch from a location that does not permit execution
SCB_CFSR_DACCVIOL_Pos = 0x1 // Position of DACCVIOL field.
SCB_CFSR_DACCVIOL_Msk = 0x2 // Bit mask of DACCVIOL field.
SCB_CFSR_DACCVIOL = 0x2 // Bit DACCVIOL.
SCB_CFSR_DACCVIOL_DACCVIOL_0 = 0x0 // no data access violation fault
SCB_CFSR_DACCVIOL_DACCVIOL_1 = 0x1 // the processor attempted a load or store at a location that does not permit the operation
SCB_CFSR_MUNSTKERR_Pos = 0x3 // Position of MUNSTKERR field.
SCB_CFSR_MUNSTKERR_Msk = 0x8 // Bit mask of MUNSTKERR field.
SCB_CFSR_MUNSTKERR = 0x8 // Bit MUNSTKERR.
SCB_CFSR_MUNSTKERR_MUNSTKERR_0 = 0x0 // no unstacking fault
SCB_CFSR_MUNSTKERR_MUNSTKERR_1 = 0x1 // unstack for an exception return has caused one or more access violations
SCB_CFSR_MSTKERR_Pos = 0x4 // Position of MSTKERR field.
SCB_CFSR_MSTKERR_Msk = 0x10 // Bit mask of MSTKERR field.
SCB_CFSR_MSTKERR = 0x10 // Bit MSTKERR.
SCB_CFSR_MSTKERR_MSTKERR_0 = 0x0 // no stacking fault
SCB_CFSR_MSTKERR_MSTKERR_1 = 0x1 // stacking for an exception entry has caused one or more access violations
SCB_CFSR_MLSPERR_Pos = 0x5 // Position of MLSPERR field.
SCB_CFSR_MLSPERR_Msk = 0x20 // Bit mask of MLSPERR field.
SCB_CFSR_MLSPERR = 0x20 // Bit MLSPERR.
SCB_CFSR_MLSPERR_MLSPERR_0 = 0x0 // No MemManage fault occurred during floating-point lazy state preservation
SCB_CFSR_MLSPERR_MLSPERR_1 = 0x1 // A MemManage fault occurred during floating-point lazy state preservation
SCB_CFSR_MMARVALID_Pos = 0x7 // Position of MMARVALID field.
SCB_CFSR_MMARVALID_Msk = 0x80 // Bit mask of MMARVALID field.
SCB_CFSR_MMARVALID = 0x80 // Bit MMARVALID.
SCB_CFSR_MMARVALID_MMARVALID_0 = 0x0 // value in MMAR is not a valid fault address
SCB_CFSR_MMARVALID_MMARVALID_1 = 0x1 // MMAR holds a valid fault address
SCB_CFSR_IBUSERR_Pos = 0x8 // Position of IBUSERR field.
SCB_CFSR_IBUSERR_Msk = 0x100 // Bit mask of IBUSERR field.
SCB_CFSR_IBUSERR = 0x100 // Bit IBUSERR.
SCB_CFSR_IBUSERR_IBUSERR_0 = 0x0 // no instruction bus error
SCB_CFSR_IBUSERR_IBUSERR_1 = 0x1 // instruction bus error
SCB_CFSR_PRECISERR_Pos = 0x9 // Position of PRECISERR field.
SCB_CFSR_PRECISERR_Msk = 0x200 // Bit mask of PRECISERR field.
SCB_CFSR_PRECISERR = 0x200 // Bit PRECISERR.
SCB_CFSR_PRECISERR_PRECISERR_0 = 0x0 // no precise data bus error
SCB_CFSR_PRECISERR_PRECISERR_1 = 0x1 // a data bus error has occurred, and the PC value stacked for the exception return points to the instruction that caused the fault
SCB_CFSR_IMPRECISERR_Pos = 0xa // Position of IMPRECISERR field.
SCB_CFSR_IMPRECISERR_Msk = 0x400 // Bit mask of IMPRECISERR field.
SCB_CFSR_IMPRECISERR = 0x400 // Bit IMPRECISERR.
SCB_CFSR_IMPRECISERR_IMPRECISERR_0 = 0x0 // no imprecise data bus error
SCB_CFSR_IMPRECISERR_IMPRECISERR_1 = 0x1 // a data bus error has occurred, but the return address in the stack frame is not related to the instruction that caused the error
SCB_CFSR_UNSTKERR_Pos = 0xb // Position of UNSTKERR field.
SCB_CFSR_UNSTKERR_Msk = 0x800 // Bit mask of UNSTKERR field.
SCB_CFSR_UNSTKERR = 0x800 // Bit UNSTKERR.
SCB_CFSR_UNSTKERR_UNSTKERR_0 = 0x0 // no unstacking fault
SCB_CFSR_UNSTKERR_UNSTKERR_1 = 0x1 // unstack for an exception return has caused one or more BusFaults
SCB_CFSR_STKERR_Pos = 0xc // Position of STKERR field.
SCB_CFSR_STKERR_Msk = 0x1000 // Bit mask of STKERR field.
SCB_CFSR_STKERR = 0x1000 // Bit STKERR.
SCB_CFSR_STKERR_STKERR_0 = 0x0 // no stacking fault
SCB_CFSR_STKERR_STKERR_1 = 0x1 // stacking for an exception entry has caused one or more BusFaults
SCB_CFSR_LSPERR_Pos = 0xd // Position of LSPERR field.
SCB_CFSR_LSPERR_Msk = 0x2000 // Bit mask of LSPERR field.
SCB_CFSR_LSPERR = 0x2000 // Bit LSPERR.
SCB_CFSR_LSPERR_LSPERR_0 = 0x0 // No bus fault occurred during floating-point lazy state preservation
SCB_CFSR_LSPERR_LSPERR_1 = 0x1 // A bus fault occurred during floating-point lazy state preservation
SCB_CFSR_BFARVALID_Pos = 0xf // Position of BFARVALID field.
SCB_CFSR_BFARVALID_Msk = 0x8000 // Bit mask of BFARVALID field.
SCB_CFSR_BFARVALID = 0x8000 // Bit BFARVALID.
SCB_CFSR_BFARVALID_BFARVALID_0 = 0x0 // value in BFAR is not a valid fault address
SCB_CFSR_BFARVALID_BFARVALID_1 = 0x1 // BFAR holds a valid fault address
SCB_CFSR_UNDEFINSTR_Pos = 0x10 // Position of UNDEFINSTR field.
SCB_CFSR_UNDEFINSTR_Msk = 0x10000 // Bit mask of UNDEFINSTR field.
SCB_CFSR_UNDEFINSTR = 0x10000 // Bit UNDEFINSTR.
SCB_CFSR_UNDEFINSTR_UNDEFINSTR_0 = 0x0 // no undefined instruction UsageFault
SCB_CFSR_UNDEFINSTR_UNDEFINSTR_1 = 0x1 // the processor has attempted to execute an undefined instruction
SCB_CFSR_INVSTATE_Pos = 0x11 // Position of INVSTATE field.
SCB_CFSR_INVSTATE_Msk = 0x20000 // Bit mask of INVSTATE field.
SCB_CFSR_INVSTATE = 0x20000 // Bit INVSTATE.
SCB_CFSR_INVSTATE_INVSTATE_0 = 0x0 // no invalid state UsageFault
SCB_CFSR_INVSTATE_INVSTATE_1 = 0x1 // the processor has attempted to execute an instruction that makes illegal use of the EPSR
SCB_CFSR_INVPC_Pos = 0x12 // Position of INVPC field.
SCB_CFSR_INVPC_Msk = 0x40000 // Bit mask of INVPC field.
SCB_CFSR_INVPC = 0x40000 // Bit INVPC.
SCB_CFSR_INVPC_INVPC_0 = 0x0 // no invalid PC load UsageFault
SCB_CFSR_INVPC_INVPC_1 = 0x1 // the processor has attempted an illegal load of EXC_RETURN to the PC
SCB_CFSR_NOCP_Pos = 0x13 // Position of NOCP field.
SCB_CFSR_NOCP_Msk = 0x80000 // Bit mask of NOCP field.
SCB_CFSR_NOCP = 0x80000 // Bit NOCP.
SCB_CFSR_NOCP_NOCP_0 = 0x0 // no UsageFault caused by attempting to access a coprocessor
SCB_CFSR_NOCP_NOCP_1 = 0x1 // the processor has attempted to access a coprocessor
SCB_CFSR_UNALIGNED_Pos = 0x18 // Position of UNALIGNED field.
SCB_CFSR_UNALIGNED_Msk = 0x1000000 // Bit mask of UNALIGNED field.
SCB_CFSR_UNALIGNED = 0x1000000 // Bit UNALIGNED.
SCB_CFSR_UNALIGNED_UNALIGNED_0 = 0x0 // no unaligned access fault, or unaligned access trapping not enabled
SCB_CFSR_UNALIGNED_UNALIGNED_1 = 0x1 // the processor has made an unaligned memory access
SCB_CFSR_DIVBYZERO_Pos = 0x19 // Position of DIVBYZERO field.
SCB_CFSR_DIVBYZERO_Msk = 0x2000000 // Bit mask of DIVBYZERO field.
SCB_CFSR_DIVBYZERO = 0x2000000 // Bit DIVBYZERO.
SCB_CFSR_DIVBYZERO_DIVBYZERO_0 = 0x0 // no divide by zero fault, or divide by zero trapping not enabled
SCB_CFSR_DIVBYZERO_DIVBYZERO_1 = 0x1 // the processor has executed an SDIV or UDIV instruction with a divisor of 0
// HFSR: HardFault Status register
SCB_HFSR_VECTTBL_Pos = 0x1 // Position of VECTTBL field.
SCB_HFSR_VECTTBL_Msk = 0x2 // Bit mask of VECTTBL field.
SCB_HFSR_VECTTBL = 0x2 // Bit VECTTBL.
SCB_HFSR_VECTTBL_VECTTBL_0 = 0x0 // no BusFault on vector table read
SCB_HFSR_VECTTBL_VECTTBL_1 = 0x1 // BusFault on vector table read
SCB_HFSR_FORCED_Pos = 0x1e // Position of FORCED field.
SCB_HFSR_FORCED_Msk = 0x40000000 // Bit mask of FORCED field.
SCB_HFSR_FORCED = 0x40000000 // Bit FORCED.
SCB_HFSR_FORCED_FORCED_0 = 0x0 // no forced HardFault
SCB_HFSR_FORCED_FORCED_1 = 0x1 // forced HardFault
SCB_HFSR_DEBUGEVT_Pos = 0x1f // Position of DEBUGEVT field.
SCB_HFSR_DEBUGEVT_Msk = 0x80000000 // Bit mask of DEBUGEVT field.
SCB_HFSR_DEBUGEVT = 0x80000000 // Bit DEBUGEVT.
SCB_HFSR_DEBUGEVT_DEBUGEVT_0 = 0x0 // No Debug event has occurred.
SCB_HFSR_DEBUGEVT_DEBUGEVT_1 = 0x1 // Debug event has occurred. The Debug Fault Status Register has been updated.
// DFSR: Debug Fault Status Register
SCB_DFSR_HALTED_Pos = 0x0 // Position of HALTED field.
SCB_DFSR_HALTED_Msk = 0x1 // Bit mask of HALTED field.
SCB_DFSR_HALTED = 0x1 // Bit HALTED.
SCB_DFSR_HALTED_HALTED_0 = 0x0 // No active halt request debug event
SCB_DFSR_HALTED_HALTED_1 = 0x1 // Halt request debug event active
SCB_DFSR_BKPT_Pos = 0x1 // Position of BKPT field.
SCB_DFSR_BKPT_Msk = 0x2 // Bit mask of BKPT field.
SCB_DFSR_BKPT = 0x2 // Bit BKPT.
SCB_DFSR_BKPT_BKPT_0 = 0x0 // No current breakpoint debug event
SCB_DFSR_BKPT_BKPT_1 = 0x1 // At least one current breakpoint debug event
SCB_DFSR_DWTTRAP_Pos = 0x2 // Position of DWTTRAP field.
SCB_DFSR_DWTTRAP_Msk = 0x4 // Bit mask of DWTTRAP field.
SCB_DFSR_DWTTRAP = 0x4 // Bit DWTTRAP.
SCB_DFSR_DWTTRAP_DWTTRAP_0 = 0x0 // No current debug events generated by the DWT
SCB_DFSR_DWTTRAP_DWTTRAP_1 = 0x1 // At least one current debug event generated by the DWT
SCB_DFSR_VCATCH_Pos = 0x3 // Position of VCATCH field.
SCB_DFSR_VCATCH_Msk = 0x8 // Bit mask of VCATCH field.
SCB_DFSR_VCATCH = 0x8 // Bit VCATCH.
SCB_DFSR_VCATCH_VCATCH_0 = 0x0 // No Vector catch triggered
SCB_DFSR_VCATCH_VCATCH_1 = 0x1 // Vector catch triggered
SCB_DFSR_EXTERNAL_Pos = 0x4 // Position of EXTERNAL field.
SCB_DFSR_EXTERNAL_Msk = 0x10 // Bit mask of EXTERNAL field.
SCB_DFSR_EXTERNAL = 0x10 // Bit EXTERNAL.
SCB_DFSR_EXTERNAL_EXTERNAL_0 = 0x0 // No external debug request debug event
SCB_DFSR_EXTERNAL_EXTERNAL_1 = 0x1 // External debug request debug event
// MMFAR: MemManage Fault Address Register
SCB_MMFAR_ADDRESS_Pos = 0x0 // Position of ADDRESS field.
SCB_MMFAR_ADDRESS_Msk = 0xffffffff // Bit mask of ADDRESS field.
// BFAR: BusFault Address Register
SCB_BFAR_ADDRESS_Pos = 0x0 // Position of ADDRESS field.
SCB_BFAR_ADDRESS_Msk = 0xffffffff // Bit mask of ADDRESS field.
)
+36
View File
@@ -0,0 +1,36 @@
package arm64
// Run the given assembly code. The code will be marked as having side effects,
// as it doesn't produce output and thus would normally be eliminated by the
// optimizer.
func Asm(asm string)
// Run the given inline assembly. The code will be marked as having side
// effects, as it would otherwise be optimized away. The inline assembly string
// recognizes template values in the form {name}, like so:
//
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
//
// You can use {} in the asm string (which expands to a register) to set the
// return value.
func AsmFull(asm string, regs map[string]interface{}) uintptr
// Run the following system call (SVCall) with 0 arguments.
func SVCall0(num uintptr) uintptr
// Run the following system call (SVCall) with 1 argument.
func SVCall1(num uintptr, a1 interface{}) uintptr
// Run the following system call (SVCall) with 2 arguments.
func SVCall2(num uintptr, a1, a2 interface{}) uintptr
// Run the following system call (SVCall) with 3 arguments.
func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
// Run the following system call (SVCall) with 4 arguments.
func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
+52
View File
@@ -0,0 +1,52 @@
// The following definitions were copied from:
// esp-idf/components/xtensa/include/xtensa/corebits.h
#define PS_WOE_MASK 0x00040000
#define PS_OWB_MASK 0x00000F00
#define PS_CALLINC_MASK 0x00030000
#define PS_WOE PS_WOE_MASK
// Only calling it call_start_cpu0 for consistency with ESP-IDF.
.section .text.call_start_cpu0
1:
.long _stack_top
.global call_start_cpu0
call_start_cpu0:
// We need to set the stack pointer to a different value. This is somewhat
// complicated in the Xtensa architecture. The code below is a modified
// version of the following code:
// https://github.com/espressif/esp-idf/blob/c77c4ccf/components/xtensa/include/xt_instr_macros.h#L47
// Disable WOE.
rsr.ps a2
movi a3, ~(PS_WOE_MASK)
and a2, a2, a3
wsr.ps a2
rsync
// Set WINDOWBASE to 1 << WINDOWSTART.
rsr.windowbase a2
ssl a2
movi a2, 1
sll a2, a2
wsr.windowstart a2
rsync
// Load new stack pointer.
l32r sp, 1b
// Re-enable WOE.
rsr.ps a2
movi a3, PS_WOE
or a2, a2, a3
wsr.ps a2
rsync
// Jump to the runtime start function written in Go.
j main
.section .text.tinygo_scanCurrentStack
.global tinygo_scanCurrentStack
tinygo_scanCurrentStack:
// TODO: save callee saved registers on the stack
j tinygo_scanstack
+6
View File
@@ -0,0 +1,6 @@
.section .text.tinygo_scanCurrentStack
.global tinygo_scanCurrentStack
tinygo_scanCurrentStack:
// TODO: save callee saved registers on the stack
j tinygo_scanstack
+29
View File
@@ -0,0 +1,29 @@
// Hand created file. DO NOT DELETE.
// Hardfault aliases for definitions that have inconsistent naming (which are
// auto-generated by gen-device-svd.go) among devices in package nxp.
// +build nxp,!mimxrt1062
package nxp
const (
HardFault_CFSR_IACCVIOL = SystemControl_CFSR_IACCVIOL
HardFault_CFSR_DACCVIOL = SystemControl_CFSR_DACCVIOL
HardFault_CFSR_MUNSTKERR = SystemControl_CFSR_MUNSTKERR
HardFault_CFSR_MSTKERR = SystemControl_CFSR_MSTKERR
HardFault_CFSR_MLSPERR = SystemControl_CFSR_MLSPERR
HardFault_CFSR_IBUSERR = SystemControl_CFSR_IBUSERR
HardFault_CFSR_PRECISERR = SystemControl_CFSR_PRECISERR
HardFault_CFSR_IMPRECISERR = SystemControl_CFSR_IMPRECISERR
HardFault_CFSR_UNSTKERR = SystemControl_CFSR_UNSTKERR
HardFault_CFSR_STKERR = SystemControl_CFSR_STKERR
HardFault_CFSR_LSPERR = SystemControl_CFSR_LSPERR
HardFault_CFSR_UNDEFINSTR = SystemControl_CFSR_UNDEFINSTR
HardFault_CFSR_INVSTATE = SystemControl_CFSR_INVSTATE
HardFault_CFSR_INVPC = SystemControl_CFSR_INVPC
HardFault_CFSR_NOCP = SystemControl_CFSR_NOCP
HardFault_CFSR_UNALIGNED = SystemControl_CFSR_UNALIGNED
HardFault_CFSR_DIVBYZERO = SystemControl_CFSR_DIVBYZERO
HardFault_CFSR_MMARVALID = SystemControl_CFSR_MMARVALID
HardFault_CFSR_BFARVALID = SystemControl_CFSR_BFARVALID
)
+529
View File
@@ -0,0 +1,529 @@
// Hand created file. DO NOT DELETE.
// Type definitions, fields, and constants associated with various clocks and
// peripherals of the NXP MIMXRT1062.
// +build nxp,mimxrt1062
package nxp
import (
"runtime/volatile"
"unsafe"
)
// Clock represents an individual peripheral clock that may be enabled/disabled
// at runtime. Clocks also have a method `Mux` for selecting the clock source
// and a method `Div` for selecting the hardware divisor. Note that many
// peripherals have an independent prescalar configuration applied to the output
// of this divisor.
type (
Clock uint32
ClockMode uint8
)
// Enable activates or deactivates the clock gate of receiver Clock c.
func (c Clock) Enable(enable bool) {
if enable {
c.setGate(clockNeededRunWait)
} else {
c.setGate(clockNotNeeded)
}
}
// Mux selects a clock source for the mux of the receiver Clock c.
func (c Clock) Mux(mux uint32) { c.setCcm(mux) }
// Div configures the prescalar divisor of the receiver Clock c.
func (c Clock) Div(div uint32) { c.setCcm(div) }
const (
ClockModeRun ClockMode = 0 // Remain in run mode
ClockModeWait ClockMode = 1 // Transfer to wait mode
ClockModeStop ClockMode = 2 // Transfer to stop mode
)
// Set configures the run mode of the MCU.
func (m ClockMode) Set() {
CCM.CLPCR.Set((CCM.CLPCR.Get() & ^uint32(CCM_CLPCR_LPM_Msk)) |
((uint32(m) << CCM_CLPCR_LPM_Pos) & CCM_CLPCR_LPM_Msk))
}
// Named oscillators
const (
ClockCpu Clock = 0x0 // CPU clock
ClockAhb Clock = 0x1 // AHB clock
ClockSemc Clock = 0x2 // SEMC clock
ClockIpg Clock = 0x3 // IPG clock
ClockPer Clock = 0x4 // PER clock
ClockOsc Clock = 0x5 // OSC clock selected by PMU_LOWPWR_CTRL[OSC_SEL]
ClockRtc Clock = 0x6 // RTC clock (RTCCLK)
ClockArmPll Clock = 0x7 // ARMPLLCLK
ClockUsb1Pll Clock = 0x8 // USB1PLLCLK
ClockUsb1PllPfd0 Clock = 0x9 // USB1PLLPDF0CLK
ClockUsb1PllPfd1 Clock = 0xA // USB1PLLPFD1CLK
ClockUsb1PllPfd2 Clock = 0xB // USB1PLLPFD2CLK
ClockUsb1PllPfd3 Clock = 0xC // USB1PLLPFD3CLK
ClockUsb2Pll Clock = 0xD // USB2PLLCLK
ClockSysPll Clock = 0xE // SYSPLLCLK
ClockSysPllPfd0 Clock = 0xF // SYSPLLPDF0CLK
ClockSysPllPfd1 Clock = 0x10 // SYSPLLPFD1CLK
ClockSysPllPfd2 Clock = 0x11 // SYSPLLPFD2CLK
ClockSysPllPfd3 Clock = 0x12 // SYSPLLPFD3CLK
ClockEnetPll0 Clock = 0x13 // Enet PLLCLK ref_enetpll0
ClockEnetPll1 Clock = 0x14 // Enet PLLCLK ref_enetpll1
ClockEnetPll2 Clock = 0x15 // Enet PLLCLK ref_enetpll2
ClockAudioPll Clock = 0x16 // Audio PLLCLK
ClockVideoPll Clock = 0x17 // Video PLLCLK
)
// Named clocks of integrated peripherals
const (
ClockIpAipsTz1 Clock = (0 << 8) | CCM_CCGR0_CG0_Pos // CCGR0, CG0
ClockIpAipsTz2 Clock = (0 << 8) | CCM_CCGR0_CG1_Pos // CCGR0, CG1
ClockIpMqs Clock = (0 << 8) | CCM_CCGR0_CG2_Pos // CCGR0, CG2
ClockIpFlexSpiExsc Clock = (0 << 8) | CCM_CCGR0_CG3_Pos // CCGR0, CG3
ClockIpSimMMain Clock = (0 << 8) | CCM_CCGR0_CG4_Pos // CCGR0, CG4
ClockIpDcp Clock = (0 << 8) | CCM_CCGR0_CG5_Pos // CCGR0, CG5
ClockIpLpuart3 Clock = (0 << 8) | CCM_CCGR0_CG6_Pos // CCGR0, CG6
ClockIpCan1 Clock = (0 << 8) | CCM_CCGR0_CG7_Pos // CCGR0, CG7
ClockIpCan1S Clock = (0 << 8) | CCM_CCGR0_CG8_Pos // CCGR0, CG8
ClockIpCan2 Clock = (0 << 8) | CCM_CCGR0_CG9_Pos // CCGR0, CG9
ClockIpCan2S Clock = (0 << 8) | CCM_CCGR0_CG10_Pos // CCGR0, CG10
ClockIpTrace Clock = (0 << 8) | CCM_CCGR0_CG11_Pos // CCGR0, CG11
ClockIpGpt2 Clock = (0 << 8) | CCM_CCGR0_CG12_Pos // CCGR0, CG12
ClockIpGpt2S Clock = (0 << 8) | CCM_CCGR0_CG13_Pos // CCGR0, CG13
ClockIpLpuart2 Clock = (0 << 8) | CCM_CCGR0_CG14_Pos // CCGR0, CG14
ClockIpGpio2 Clock = (0 << 8) | CCM_CCGR0_CG15_Pos // CCGR0, CG15
ClockIpLpspi1 Clock = (1 << 8) | CCM_CCGR1_CG0_Pos // CCGR1, CG0
ClockIpLpspi2 Clock = (1 << 8) | CCM_CCGR1_CG1_Pos // CCGR1, CG1
ClockIpLpspi3 Clock = (1 << 8) | CCM_CCGR1_CG2_Pos // CCGR1, CG2
ClockIpLpspi4 Clock = (1 << 8) | CCM_CCGR1_CG3_Pos // CCGR1, CG3
ClockIpAdc2 Clock = (1 << 8) | CCM_CCGR1_CG4_Pos // CCGR1, CG4
ClockIpEnet Clock = (1 << 8) | CCM_CCGR1_CG5_Pos // CCGR1, CG5
ClockIpPit Clock = (1 << 8) | CCM_CCGR1_CG6_Pos // CCGR1, CG6
ClockIpAoi2 Clock = (1 << 8) | CCM_CCGR1_CG7_Pos // CCGR1, CG7
ClockIpAdc1 Clock = (1 << 8) | CCM_CCGR1_CG8_Pos // CCGR1, CG8
ClockIpSemcExsc Clock = (1 << 8) | CCM_CCGR1_CG9_Pos // CCGR1, CG9
ClockIpGpt1 Clock = (1 << 8) | CCM_CCGR1_CG10_Pos // CCGR1, CG10
ClockIpGpt1S Clock = (1 << 8) | CCM_CCGR1_CG11_Pos // CCGR1, CG11
ClockIpLpuart4 Clock = (1 << 8) | CCM_CCGR1_CG12_Pos // CCGR1, CG12
ClockIpGpio1 Clock = (1 << 8) | CCM_CCGR1_CG13_Pos // CCGR1, CG13
ClockIpCsu Clock = (1 << 8) | CCM_CCGR1_CG14_Pos // CCGR1, CG14
ClockIpGpio5 Clock = (1 << 8) | CCM_CCGR1_CG15_Pos // CCGR1, CG15
ClockIpOcramExsc Clock = (2 << 8) | CCM_CCGR2_CG0_Pos // CCGR2, CG0
ClockIpCsi Clock = (2 << 8) | CCM_CCGR2_CG1_Pos // CCGR2, CG1
ClockIpIomuxcSnvs Clock = (2 << 8) | CCM_CCGR2_CG2_Pos // CCGR2, CG2
ClockIpLpi2c1 Clock = (2 << 8) | CCM_CCGR2_CG3_Pos // CCGR2, CG3
ClockIpLpi2c2 Clock = (2 << 8) | CCM_CCGR2_CG4_Pos // CCGR2, CG4
ClockIpLpi2c3 Clock = (2 << 8) | CCM_CCGR2_CG5_Pos // CCGR2, CG5
ClockIpOcotp Clock = (2 << 8) | CCM_CCGR2_CG6_Pos // CCGR2, CG6
ClockIpXbar3 Clock = (2 << 8) | CCM_CCGR2_CG7_Pos // CCGR2, CG7
ClockIpIpmux1 Clock = (2 << 8) | CCM_CCGR2_CG8_Pos // CCGR2, CG8
ClockIpIpmux2 Clock = (2 << 8) | CCM_CCGR2_CG9_Pos // CCGR2, CG9
ClockIpIpmux3 Clock = (2 << 8) | CCM_CCGR2_CG10_Pos // CCGR2, CG10
ClockIpXbar1 Clock = (2 << 8) | CCM_CCGR2_CG11_Pos // CCGR2, CG11
ClockIpXbar2 Clock = (2 << 8) | CCM_CCGR2_CG12_Pos // CCGR2, CG12
ClockIpGpio3 Clock = (2 << 8) | CCM_CCGR2_CG13_Pos // CCGR2, CG13
ClockIpLcd Clock = (2 << 8) | CCM_CCGR2_CG14_Pos // CCGR2, CG14
ClockIpPxp Clock = (2 << 8) | CCM_CCGR2_CG15_Pos // CCGR2, CG15
ClockIpFlexio2 Clock = (3 << 8) | CCM_CCGR3_CG0_Pos // CCGR3, CG0
ClockIpLpuart5 Clock = (3 << 8) | CCM_CCGR3_CG1_Pos // CCGR3, CG1
ClockIpSemc Clock = (3 << 8) | CCM_CCGR3_CG2_Pos // CCGR3, CG2
ClockIpLpuart6 Clock = (3 << 8) | CCM_CCGR3_CG3_Pos // CCGR3, CG3
ClockIpAoi1 Clock = (3 << 8) | CCM_CCGR3_CG4_Pos // CCGR3, CG4
ClockIpLcdPixel Clock = (3 << 8) | CCM_CCGR3_CG5_Pos // CCGR3, CG5
ClockIpGpio4 Clock = (3 << 8) | CCM_CCGR3_CG6_Pos // CCGR3, CG6
ClockIpEwm0 Clock = (3 << 8) | CCM_CCGR3_CG7_Pos // CCGR3, CG7
ClockIpWdog1 Clock = (3 << 8) | CCM_CCGR3_CG8_Pos // CCGR3, CG8
ClockIpFlexRam Clock = (3 << 8) | CCM_CCGR3_CG9_Pos // CCGR3, CG9
ClockIpAcmp1 Clock = (3 << 8) | CCM_CCGR3_CG10_Pos // CCGR3, CG10
ClockIpAcmp2 Clock = (3 << 8) | CCM_CCGR3_CG11_Pos // CCGR3, CG11
ClockIpAcmp3 Clock = (3 << 8) | CCM_CCGR3_CG12_Pos // CCGR3, CG12
ClockIpAcmp4 Clock = (3 << 8) | CCM_CCGR3_CG13_Pos // CCGR3, CG13
ClockIpOcram Clock = (3 << 8) | CCM_CCGR3_CG14_Pos // CCGR3, CG14
ClockIpIomuxcSnvsGpr Clock = (3 << 8) | CCM_CCGR3_CG15_Pos // CCGR3, CG15
ClockIpIomuxc Clock = (4 << 8) | CCM_CCGR4_CG1_Pos // CCGR4, CG1
ClockIpIomuxcGpr Clock = (4 << 8) | CCM_CCGR4_CG2_Pos // CCGR4, CG2
ClockIpBee Clock = (4 << 8) | CCM_CCGR4_CG3_Pos // CCGR4, CG3
ClockIpSimM7 Clock = (4 << 8) | CCM_CCGR4_CG4_Pos // CCGR4, CG4
ClockIpTsc Clock = (4 << 8) | CCM_CCGR4_CG5_Pos // CCGR4, CG5
ClockIpSimM Clock = (4 << 8) | CCM_CCGR4_CG6_Pos // CCGR4, CG6
ClockIpSimEms Clock = (4 << 8) | CCM_CCGR4_CG7_Pos // CCGR4, CG7
ClockIpPwm1 Clock = (4 << 8) | CCM_CCGR4_CG8_Pos // CCGR4, CG8
ClockIpPwm2 Clock = (4 << 8) | CCM_CCGR4_CG9_Pos // CCGR4, CG9
ClockIpPwm3 Clock = (4 << 8) | CCM_CCGR4_CG10_Pos // CCGR4, CG10
ClockIpPwm4 Clock = (4 << 8) | CCM_CCGR4_CG11_Pos // CCGR4, CG11
ClockIpEnc1 Clock = (4 << 8) | CCM_CCGR4_CG12_Pos // CCGR4, CG12
ClockIpEnc2 Clock = (4 << 8) | CCM_CCGR4_CG13_Pos // CCGR4, CG13
ClockIpEnc3 Clock = (4 << 8) | CCM_CCGR4_CG14_Pos // CCGR4, CG14
ClockIpEnc4 Clock = (4 << 8) | CCM_CCGR4_CG15_Pos // CCGR4, CG15
ClockIpRom Clock = (5 << 8) | CCM_CCGR5_CG0_Pos // CCGR5, CG0
ClockIpFlexio1 Clock = (5 << 8) | CCM_CCGR5_CG1_Pos // CCGR5, CG1
ClockIpWdog3 Clock = (5 << 8) | CCM_CCGR5_CG2_Pos // CCGR5, CG2
ClockIpDma Clock = (5 << 8) | CCM_CCGR5_CG3_Pos // CCGR5, CG3
ClockIpKpp Clock = (5 << 8) | CCM_CCGR5_CG4_Pos // CCGR5, CG4
ClockIpWdog2 Clock = (5 << 8) | CCM_CCGR5_CG5_Pos // CCGR5, CG5
ClockIpAipsTz4 Clock = (5 << 8) | CCM_CCGR5_CG6_Pos // CCGR5, CG6
ClockIpSpdif Clock = (5 << 8) | CCM_CCGR5_CG7_Pos // CCGR5, CG7
ClockIpSimMain Clock = (5 << 8) | CCM_CCGR5_CG8_Pos // CCGR5, CG8
ClockIpSai1 Clock = (5 << 8) | CCM_CCGR5_CG9_Pos // CCGR5, CG9
ClockIpSai2 Clock = (5 << 8) | CCM_CCGR5_CG10_Pos // CCGR5, CG10
ClockIpSai3 Clock = (5 << 8) | CCM_CCGR5_CG11_Pos // CCGR5, CG11
ClockIpLpuart1 Clock = (5 << 8) | CCM_CCGR5_CG12_Pos // CCGR5, CG12
ClockIpLpuart7 Clock = (5 << 8) | CCM_CCGR5_CG13_Pos // CCGR5, CG13
ClockIpSnvsHp Clock = (5 << 8) | CCM_CCGR5_CG14_Pos // CCGR5, CG14
ClockIpSnvsLp Clock = (5 << 8) | CCM_CCGR5_CG15_Pos // CCGR5, CG15
ClockIpUsbOh3 Clock = (6 << 8) | CCM_CCGR6_CG0_Pos // CCGR6, CG0
ClockIpUsdhc1 Clock = (6 << 8) | CCM_CCGR6_CG1_Pos // CCGR6, CG1
ClockIpUsdhc2 Clock = (6 << 8) | CCM_CCGR6_CG2_Pos // CCGR6, CG2
ClockIpDcdc Clock = (6 << 8) | CCM_CCGR6_CG3_Pos // CCGR6, CG3
ClockIpIpmux4 Clock = (6 << 8) | CCM_CCGR6_CG4_Pos // CCGR6, CG4
ClockIpFlexSpi Clock = (6 << 8) | CCM_CCGR6_CG5_Pos // CCGR6, CG5
ClockIpTrng Clock = (6 << 8) | CCM_CCGR6_CG6_Pos // CCGR6, CG6
ClockIpLpuart8 Clock = (6 << 8) | CCM_CCGR6_CG7_Pos // CCGR6, CG7
ClockIpTimer4 Clock = (6 << 8) | CCM_CCGR6_CG8_Pos // CCGR6, CG8
ClockIpAipsTz3 Clock = (6 << 8) | CCM_CCGR6_CG9_Pos // CCGR6, CG9
ClockIpSimPer Clock = (6 << 8) | CCM_CCGR6_CG10_Pos // CCGR6, CG10
ClockIpAnadig Clock = (6 << 8) | CCM_CCGR6_CG11_Pos // CCGR6, CG11
ClockIpLpi2c4 Clock = (6 << 8) | CCM_CCGR6_CG12_Pos // CCGR6, CG12
ClockIpTimer1 Clock = (6 << 8) | CCM_CCGR6_CG13_Pos // CCGR6, CG13
ClockIpTimer2 Clock = (6 << 8) | CCM_CCGR6_CG14_Pos // CCGR6, CG14
ClockIpTimer3 Clock = (6 << 8) | CCM_CCGR6_CG15_Pos // CCGR6, CG15
ClockIpEnet2 Clock = (7 << 8) | CCM_CCGR7_CG0_Pos // CCGR7, CG0
ClockIpFlexSpi2 Clock = (7 << 8) | CCM_CCGR7_CG1_Pos // CCGR7, CG1
ClockIpAxbsL Clock = (7 << 8) | CCM_CCGR7_CG2_Pos // CCGR7, CG2
ClockIpCan3 Clock = (7 << 8) | CCM_CCGR7_CG3_Pos // CCGR7, CG3
ClockIpCan3S Clock = (7 << 8) | CCM_CCGR7_CG4_Pos // CCGR7, CG4
ClockIpAipsLite Clock = (7 << 8) | CCM_CCGR7_CG5_Pos // CCGR7, CG5
ClockIpFlexio3 Clock = (7 << 8) | CCM_CCGR7_CG6_Pos // CCGR7, CG6
)
// PLL name
const (
ClockPllArm Clock = ((offPllArm & 0xFFF) << 16) | CCM_ANALOG_PLL_ARM_ENABLE_Pos // PLL ARM
ClockPllSys Clock = ((offPllSys & 0xFFF) << 16) | CCM_ANALOG_PLL_SYS_ENABLE_Pos // PLL SYS
ClockPllUsb1 Clock = ((offPllUsb1 & 0xFFF) << 16) | CCM_ANALOG_PLL_USB1_ENABLE_Pos // PLL USB1
ClockPllAudio Clock = ((offPllAudio & 0xFFF) << 16) | CCM_ANALOG_PLL_AUDIO_ENABLE_Pos // PLL Audio
ClockPllVideo Clock = ((offPllVideo & 0xFFF) << 16) | CCM_ANALOG_PLL_VIDEO_ENABLE_Pos // PLL Video
ClockPllEnet Clock = ((offPllEnet & 0xFFF) << 16) | CCM_ANALOG_PLL_ENET_ENABLE_Pos // PLL Enet0
ClockPllEnet2 Clock = ((offPllEnet & 0xFFF) << 16) | CCM_ANALOG_PLL_ENET_ENET2_REF_EN_Pos // PLL Enet1
ClockPllEnet25M Clock = ((offPllEnet & 0xFFF) << 16) | CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_Pos // PLL Enet2
ClockPllUsb2 Clock = ((offPllUsb2 & 0xFFF) << 16) | CCM_ANALOG_PLL_USB2_ENABLE_Pos // PLL USB2
)
// PLL PFD name
const (
ClockPfd0 Clock = 0 // PLL PFD0
ClockPfd1 Clock = 1 // PLL PFD1
ClockPfd2 Clock = 2 // PLL PFD2
ClockPfd3 Clock = 3 // PLL PFD3
)
// Named clock muxes of integrated peripherals
const (
MuxIpPll3Sw Clock = (offCCSR & 0xFF) | (CCM_CCSR_PLL3_SW_CLK_SEL_Pos << 8) | (((CCM_CCSR_PLL3_SW_CLK_SEL_Msk >> CCM_CCSR_PLL3_SW_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // pll3_sw_clk mux name
MuxIpPeriph Clock = (offCBCDR & 0xFF) | (CCM_CBCDR_PERIPH_CLK_SEL_Pos << 8) | (((CCM_CBCDR_PERIPH_CLK_SEL_Msk >> CCM_CBCDR_PERIPH_CLK_SEL_Pos) & 0x1FFF) << 13) | (CCM_CDHIPR_PERIPH_CLK_SEL_BUSY_Pos << 26) // periph mux name
MuxIpSemcAlt Clock = (offCBCDR & 0xFF) | (CCM_CBCDR_SEMC_ALT_CLK_SEL_Pos << 8) | (((CCM_CBCDR_SEMC_ALT_CLK_SEL_Msk >> CCM_CBCDR_SEMC_ALT_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // semc mux name
MuxIpSemc Clock = (offCBCDR & 0xFF) | (CCM_CBCDR_SEMC_CLK_SEL_Pos << 8) | (((CCM_CBCDR_SEMC_CLK_SEL_Msk >> CCM_CBCDR_SEMC_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // semc mux name
MuxIpPrePeriph Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_PRE_PERIPH_CLK_SEL_Pos << 8) | (((CCM_CBCMR_PRE_PERIPH_CLK_SEL_Msk >> CCM_CBCMR_PRE_PERIPH_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // pre-periph mux name
MuxIpTrace Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_TRACE_CLK_SEL_Pos << 8) | (((CCM_CBCMR_TRACE_CLK_SEL_Msk >> CCM_CBCMR_TRACE_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // trace mux name
MuxIpPeriphClk2 Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_PERIPH_CLK2_SEL_Pos << 8) | (((CCM_CBCMR_PERIPH_CLK2_SEL_Msk >> CCM_CBCMR_PERIPH_CLK2_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // periph clock2 mux name
MuxIpFlexSpi2 Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_FLEXSPI2_CLK_SEL_Pos << 8) | (((CCM_CBCMR_FLEXSPI2_CLK_SEL_Msk >> CCM_CBCMR_FLEXSPI2_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexspi2 mux name
MuxIpLpspi Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_LPSPI_CLK_SEL_Pos << 8) | (((CCM_CBCMR_LPSPI_CLK_SEL_Msk >> CCM_CBCMR_LPSPI_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // lpspi mux name
MuxIpFlexSpi Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_FLEXSPI_CLK_SEL_Pos << 8) | (((CCM_CSCMR1_FLEXSPI_CLK_SEL_Msk >> CCM_CSCMR1_FLEXSPI_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexspi mux name
MuxIpUsdhc2 Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_USDHC2_CLK_SEL_Pos << 8) | (((CCM_CSCMR1_USDHC2_CLK_SEL_Msk >> CCM_CSCMR1_USDHC2_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // usdhc2 mux name
MuxIpUsdhc1 Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_USDHC1_CLK_SEL_Pos << 8) | (((CCM_CSCMR1_USDHC1_CLK_SEL_Msk >> CCM_CSCMR1_USDHC1_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // usdhc1 mux name
MuxIpSai3 Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_SAI3_CLK_SEL_Pos << 8) | (((CCM_CSCMR1_SAI3_CLK_SEL_Msk >> CCM_CSCMR1_SAI3_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai3 mux name
MuxIpSai2 Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_SAI2_CLK_SEL_Pos << 8) | (((CCM_CSCMR1_SAI2_CLK_SEL_Msk >> CCM_CSCMR1_SAI2_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai2 mux name
MuxIpSai1 Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_SAI1_CLK_SEL_Pos << 8) | (((CCM_CSCMR1_SAI1_CLK_SEL_Msk >> CCM_CSCMR1_SAI1_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai1 mux name
MuxIpPerclk Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_PERCLK_CLK_SEL_Pos << 8) | (((CCM_CSCMR1_PERCLK_CLK_SEL_Msk >> CCM_CSCMR1_PERCLK_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // perclk mux name
MuxIpFlexio2 Clock = (offCSCMR2 & 0xFF) | (CCM_CSCMR2_FLEXIO2_CLK_SEL_Pos << 8) | (((CCM_CSCMR2_FLEXIO2_CLK_SEL_Msk >> CCM_CSCMR2_FLEXIO2_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexio2 mux name
MuxIpCan Clock = (offCSCMR2 & 0xFF) | (CCM_CSCMR2_CAN_CLK_SEL_Pos << 8) | (((CCM_CSCMR2_CAN_CLK_SEL_Msk >> CCM_CSCMR2_CAN_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // can mux name
MuxIpUart Clock = (offCSCDR1 & 0xFF) | (CCM_CSCDR1_UART_CLK_SEL_Pos << 8) | (((CCM_CSCDR1_UART_CLK_SEL_Msk >> CCM_CSCDR1_UART_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // uart mux name
MuxIpSpdif Clock = (offCDCDR & 0xFF) | (CCM_CDCDR_SPDIF0_CLK_SEL_Pos << 8) | (((CCM_CDCDR_SPDIF0_CLK_SEL_Msk >> CCM_CDCDR_SPDIF0_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // spdif mux name
MuxIpFlexio1 Clock = (offCDCDR & 0xFF) | (CCM_CDCDR_FLEXIO1_CLK_SEL_Pos << 8) | (((CCM_CDCDR_FLEXIO1_CLK_SEL_Msk >> CCM_CDCDR_FLEXIO1_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexio1 mux name
MuxIpLpi2c Clock = (offCSCDR2 & 0xFF) | (CCM_CSCDR2_LPI2C_CLK_SEL_Pos << 8) | (((CCM_CSCDR2_LPI2C_CLK_SEL_Msk >> CCM_CSCDR2_LPI2C_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // lpi2c mux name
MuxIpLcdifPre Clock = (offCSCDR2 & 0xFF) | (CCM_CSCDR2_LCDIF_PRE_CLK_SEL_Pos << 8) | (((CCM_CSCDR2_LCDIF_PRE_CLK_SEL_Msk >> CCM_CSCDR2_LCDIF_PRE_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // lcdif pre mux name
MuxIpCsi Clock = (offCSCDR3 & 0xFF) | (CCM_CSCDR3_CSI_CLK_SEL_Pos << 8) | (((CCM_CSCDR3_CSI_CLK_SEL_Msk >> CCM_CSCDR3_CSI_CLK_SEL_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // csi mux name
)
// Named hardware clock divisors of integrated peripherals
const (
DivIpArm Clock = (offCACRR & 0xFF) | (CCM_CACRR_ARM_PODF_Pos << 8) | (((CCM_CACRR_ARM_PODF_Msk >> CCM_CACRR_ARM_PODF_Pos) & 0x1FFF) << 13) | (CCM_CDHIPR_ARM_PODF_BUSY_Pos << 26) // core div name
DivIpPeriphClk2 Clock = (offCBCDR & 0xFF) | (CCM_CBCDR_PERIPH_CLK2_PODF_Pos << 8) | (((CCM_CBCDR_PERIPH_CLK2_PODF_Msk >> CCM_CBCDR_PERIPH_CLK2_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // periph clock2 div name
DivIpSemc Clock = (offCBCDR & 0xFF) | (CCM_CBCDR_SEMC_PODF_Pos << 8) | (((CCM_CBCDR_SEMC_PODF_Msk >> CCM_CBCDR_SEMC_PODF_Pos) & 0x1FFF) << 13) | (CCM_CDHIPR_SEMC_PODF_BUSY_Pos << 26) // semc div name
DivIpAhb Clock = (offCBCDR & 0xFF) | (CCM_CBCDR_AHB_PODF_Pos << 8) | (((CCM_CBCDR_AHB_PODF_Msk >> CCM_CBCDR_AHB_PODF_Pos) & 0x1FFF) << 13) | (CCM_CDHIPR_AHB_PODF_BUSY_Pos << 26) // ahb div name
DivIpIpg Clock = (offCBCDR & 0xFF) | (CCM_CBCDR_IPG_PODF_Pos << 8) | (((CCM_CBCDR_IPG_PODF_Msk >> CCM_CBCDR_IPG_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // ipg div name
DivIpFlexSpi2 Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_FLEXSPI2_PODF_Pos << 8) | (((CCM_CBCMR_FLEXSPI2_PODF_Msk >> CCM_CBCMR_FLEXSPI2_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexspi2 div name
DivIpLpspi Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_LPSPI_PODF_Pos << 8) | (((CCM_CBCMR_LPSPI_PODF_Msk >> CCM_CBCMR_LPSPI_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // lpspi div name
DivIpLcdif Clock = (offCBCMR & 0xFF) | (CCM_CBCMR_LCDIF_PODF_Pos << 8) | (((CCM_CBCMR_LCDIF_PODF_Msk >> CCM_CBCMR_LCDIF_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // lcdif div name
DivIpFlexSpi Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_FLEXSPI_PODF_Pos << 8) | (((CCM_CSCMR1_FLEXSPI_PODF_Msk >> CCM_CSCMR1_FLEXSPI_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexspi div name
DivIpPerclk Clock = (offCSCMR1 & 0xFF) | (CCM_CSCMR1_PERCLK_PODF_Pos << 8) | (((CCM_CSCMR1_PERCLK_PODF_Msk >> CCM_CSCMR1_PERCLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // perclk div name
DivIpCan Clock = (offCSCMR2 & 0xFF) | (CCM_CSCMR2_CAN_CLK_PODF_Pos << 8) | (((CCM_CSCMR2_CAN_CLK_PODF_Msk >> CCM_CSCMR2_CAN_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // can div name
DivIpTrace Clock = (offCSCDR1 & 0xFF) | (CCM_CSCDR1_TRACE_PODF_Pos << 8) | (((CCM_CSCDR1_TRACE_PODF_Msk >> CCM_CSCDR1_TRACE_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // trace div name
DivIpUsdhc2 Clock = (offCSCDR1 & 0xFF) | (CCM_CSCDR1_USDHC2_PODF_Pos << 8) | (((CCM_CSCDR1_USDHC2_PODF_Msk >> CCM_CSCDR1_USDHC2_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // usdhc2 div name
DivIpUsdhc1 Clock = (offCSCDR1 & 0xFF) | (CCM_CSCDR1_USDHC1_PODF_Pos << 8) | (((CCM_CSCDR1_USDHC1_PODF_Msk >> CCM_CSCDR1_USDHC1_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // usdhc1 div name
DivIpUart Clock = (offCSCDR1 & 0xFF) | (CCM_CSCDR1_UART_CLK_PODF_Pos << 8) | (((CCM_CSCDR1_UART_CLK_PODF_Msk >> CCM_CSCDR1_UART_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // uart div name
DivIpFlexio2 Clock = (offCS1CDR & 0xFF) | (CCM_CS1CDR_FLEXIO2_CLK_PODF_Pos << 8) | (((CCM_CS1CDR_FLEXIO2_CLK_PODF_Msk >> CCM_CS1CDR_FLEXIO2_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexio2 pre div name
DivIpSai3Pre Clock = (offCS1CDR & 0xFF) | (CCM_CS1CDR_SAI3_CLK_PRED_Pos << 8) | (((CCM_CS1CDR_SAI3_CLK_PRED_Msk >> CCM_CS1CDR_SAI3_CLK_PRED_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai3 pre div name
DivIpSai3 Clock = (offCS1CDR & 0xFF) | (CCM_CS1CDR_SAI3_CLK_PODF_Pos << 8) | (((CCM_CS1CDR_SAI3_CLK_PODF_Msk >> CCM_CS1CDR_SAI3_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai3 div name
DivIpFlexio2Pre Clock = (offCS1CDR & 0xFF) | (CCM_CS1CDR_FLEXIO2_CLK_PRED_Pos << 8) | (((CCM_CS1CDR_FLEXIO2_CLK_PRED_Msk >> CCM_CS1CDR_FLEXIO2_CLK_PRED_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai3 pre div name
DivIpSai1Pre Clock = (offCS1CDR & 0xFF) | (CCM_CS1CDR_SAI1_CLK_PRED_Pos << 8) | (((CCM_CS1CDR_SAI1_CLK_PRED_Msk >> CCM_CS1CDR_SAI1_CLK_PRED_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai1 pre div name
DivIpSai1 Clock = (offCS1CDR & 0xFF) | (CCM_CS1CDR_SAI1_CLK_PODF_Pos << 8) | (((CCM_CS1CDR_SAI1_CLK_PODF_Msk >> CCM_CS1CDR_SAI1_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai1 div name
DivIpSai2Pre Clock = (offCS2CDR & 0xFF) | (CCM_CS2CDR_SAI2_CLK_PRED_Pos << 8) | (((CCM_CS2CDR_SAI2_CLK_PRED_Msk >> CCM_CS2CDR_SAI2_CLK_PRED_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai2 pre div name
DivIpSai2 Clock = (offCS2CDR & 0xFF) | (CCM_CS2CDR_SAI2_CLK_PODF_Pos << 8) | (((CCM_CS2CDR_SAI2_CLK_PODF_Msk >> CCM_CS2CDR_SAI2_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // sai2 div name
DivIpSpdif0Pre Clock = (offCDCDR & 0xFF) | (CCM_CDCDR_SPDIF0_CLK_PRED_Pos << 8) | (((CCM_CDCDR_SPDIF0_CLK_PRED_Msk >> CCM_CDCDR_SPDIF0_CLK_PRED_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // spdif pre div name
DivIpSpdif0 Clock = (offCDCDR & 0xFF) | (CCM_CDCDR_SPDIF0_CLK_PODF_Pos << 8) | (((CCM_CDCDR_SPDIF0_CLK_PODF_Msk >> CCM_CDCDR_SPDIF0_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // spdif div name
DivIpFlexio1Pre Clock = (offCDCDR & 0xFF) | (CCM_CDCDR_FLEXIO1_CLK_PRED_Pos << 8) | (((CCM_CDCDR_FLEXIO1_CLK_PRED_Msk >> CCM_CDCDR_FLEXIO1_CLK_PRED_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexio1 pre div name
DivIpFlexio1 Clock = (offCDCDR & 0xFF) | (CCM_CDCDR_FLEXIO1_CLK_PODF_Pos << 8) | (((CCM_CDCDR_FLEXIO1_CLK_PODF_Msk >> CCM_CDCDR_FLEXIO1_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // flexio1 div name
DivIpLpi2c Clock = (offCSCDR2 & 0xFF) | (CCM_CSCDR2_LPI2C_CLK_PODF_Pos << 8) | (((CCM_CSCDR2_LPI2C_CLK_PODF_Msk >> CCM_CSCDR2_LPI2C_CLK_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // lpi2c div name
DivIpLcdifPre Clock = (offCSCDR2 & 0xFF) | (CCM_CSCDR2_LCDIF_PRED_Pos << 8) | (((CCM_CSCDR2_LCDIF_PRED_Msk >> CCM_CSCDR2_LCDIF_PRED_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // lcdif pre div name
DivIpCsi Clock = (offCSCDR3 & 0xFF) | (CCM_CSCDR3_CSI_PODF_Pos << 8) | (((CCM_CSCDR3_CSI_PODF_Msk >> CCM_CSCDR3_CSI_PODF_Pos) & 0x1FFF) << 13) | (noBusyWait << 26) // csi div name
)
// Selected clock offsets
const (
offCCSR = 0x0C
offCBCDR = 0x14
offCBCMR = 0x18
offCSCMR1 = 0x1C
offCSCMR2 = 0x20
offCSCDR1 = 0x24
offCDCDR = 0x30
offCSCDR2 = 0x38
offCSCDR3 = 0x3C
offCACRR = 0x10
offCS1CDR = 0x28
offCS2CDR = 0x2C
offPllArm = 0x00
offPllSys = 0x30
offPllUsb1 = 0x10
offPllAudio = 0x70
offPllVideo = 0xA0
offPllEnet = 0xE0
offPllUsb2 = 0x20
noBusyWait = 0x20
)
// analog PLL definition
const (
pllBypassPos = 16
pllBypassClkSrcMsk = 0xC000
pllBypassClkSrcPos = 14
)
// PLL clock source, bypass cloco source also
const (
pllSrc24M = 0 // Pll clock source 24M
pllSrcClkPN = 1 // Pll clock source CLK1_P and CLK1_N
)
const (
clockNotNeeded uint32 = 0 // Clock is off during all modes
clockNeededRun uint32 = 1 // Clock is on in run mode, but off in WAIT and STOP modes
clockNeededRunWait uint32 = 3 // Clock is on during all modes, except STOP mode
)
// getGate returns the CCM clock gating register for the receiver clk.
func (clk Clock) getGate() *volatile.Register32 {
switch clk >> 8 {
case 0:
return &CCM.CCGR0
case 1:
return &CCM.CCGR1
case 2:
return &CCM.CCGR2
case 3:
return &CCM.CCGR3
case 4:
return &CCM.CCGR4
case 5:
return &CCM.CCGR5
case 6:
return &CCM.CCGR6
case 7:
return &CCM.CCGR7
default:
panic("nxp: invalid clock")
}
}
// setGate enables or disables the receiver clk using its gating register.
func (clk Clock) setGate(value uint32) {
reg := clk.getGate()
shift := clk & 0x1F
reg.Set((reg.Get() & ^(3 << shift)) | (value << shift))
}
func (clk Clock) setCcm(value uint32) {
const ccmBase = 0x400fc000
reg := (*volatile.Register32)(unsafe.Pointer(uintptr(ccmBase + (uint32(clk) & 0xFF))))
msk := ((uint32(clk) >> 13) & 0x1FFF) << ((uint32(clk) >> 8) & 0x1F)
pos := (uint32(clk) >> 8) & 0x1F
bsy := (uint32(clk) >> 26) & 0x3F
reg.Set((reg.Get() & ^uint32(msk)) | ((value << pos) & msk))
if bsy < noBusyWait {
for CCM.CDHIPR.HasBits(1 << bsy) {
}
}
}
func setSysPfd(value ...uint32) {
for i, val := range value {
pfd528 := CCM_ANALOG.PFD_528.Get() &
^((CCM_ANALOG_PFD_528_PFD0_CLKGATE_Msk | CCM_ANALOG_PFD_528_PFD0_FRAC_Msk) << (8 * uint32(i)))
frac := (val << CCM_ANALOG_PFD_528_PFD0_FRAC_Pos) & CCM_ANALOG_PFD_528_PFD0_FRAC_Msk
// disable the clock output first
CCM_ANALOG.PFD_528.Set(pfd528 | (CCM_ANALOG_PFD_528_PFD0_CLKGATE_Msk << (8 * uint32(i))))
// set the new value and enable output
CCM_ANALOG.PFD_528.Set(pfd528 | (frac << (8 * uint32(i))))
}
}
func setUsb1Pfd(value ...uint32) {
for i, val := range value {
pfd480 := CCM_ANALOG.PFD_480.Get() &
^((CCM_ANALOG_PFD_480_PFD0_CLKGATE_Msk | CCM_ANALOG_PFD_480_PFD0_FRAC_Msk) << (8 * uint32(i)))
frac := (val << CCM_ANALOG_PFD_480_PFD0_FRAC_Pos) & CCM_ANALOG_PFD_480_PFD0_FRAC_Msk
// disable the clock output first
CCM_ANALOG.PFD_480.Set(pfd480 | (CCM_ANALOG_PFD_480_PFD0_CLKGATE_Msk << (8 * uint32(i))))
// set the new value and enable output
CCM_ANALOG.PFD_480.Set(pfd480 | (frac << (8 * uint32(i))))
}
}
// PLL configuration for ARM
type ClockConfigArmPll struct {
LoopDivider uint32 // PLL loop divider. Valid range for divider value: 54-108. Fout=Fin*LoopDivider/2.
Src uint8 // Pll clock source, reference _clock_pll_clk_src
}
func (cfg ClockConfigArmPll) Configure() {
// bypass PLL first
src := (uint32(cfg.Src) << CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_Pos) & CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_Msk
CCM_ANALOG.PLL_ARM.Set(
(CCM_ANALOG.PLL_ARM.Get() & ^uint32(CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_Msk)) |
CCM_ANALOG_PLL_ARM_BYPASS_Msk | src)
sel := (cfg.LoopDivider << CCM_ANALOG_PLL_ARM_DIV_SELECT_Pos) & CCM_ANALOG_PLL_ARM_DIV_SELECT_Msk
CCM_ANALOG.PLL_ARM.Set(
(CCM_ANALOG.PLL_ARM.Get() & ^uint32(CCM_ANALOG_PLL_ARM_DIV_SELECT_Msk|CCM_ANALOG_PLL_ARM_POWERDOWN_Msk)) |
CCM_ANALOG_PLL_ARM_ENABLE_Msk | sel)
for !CCM_ANALOG.PLL_ARM.HasBits(CCM_ANALOG_PLL_ARM_LOCK_Msk) {
}
// disable bypass
CCM_ANALOG.PLL_ARM.ClearBits(CCM_ANALOG_PLL_ARM_BYPASS_Msk)
}
// PLL configuration for System
type ClockConfigSysPll struct {
LoopDivider uint8 // PLL loop divider. Intended to be 1 (528M): 0 - Fout=Fref*20, 1 - Fout=Fref*22
Numerator uint32 // 30 bit Numerator of fractional loop divider.
Denominator uint32 // 30 bit Denominator of fractional loop divider
Src uint8 // Pll clock source, reference _clock_pll_clk_src
SsStop uint16 // Stop value to get frequency change.
SsEnable uint8 // Enable spread spectrum modulation
SsStep uint16 // Step value to get frequency change step.
}
func (cfg ClockConfigSysPll) Configure(pfd ...uint32) {
// bypass PLL first
src := (uint32(cfg.Src) << CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_Pos) & CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_Msk
CCM_ANALOG.PLL_SYS.Set(
(CCM_ANALOG.PLL_SYS.Get() & ^uint32(CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_Msk)) |
CCM_ANALOG_PLL_SYS_BYPASS_Msk | src)
sel := (uint32(cfg.LoopDivider) << CCM_ANALOG_PLL_SYS_DIV_SELECT_Pos) & CCM_ANALOG_PLL_SYS_DIV_SELECT_Msk
CCM_ANALOG.PLL_SYS.Set(
(CCM_ANALOG.PLL_SYS.Get() & ^uint32(CCM_ANALOG_PLL_SYS_DIV_SELECT_Msk|CCM_ANALOG_PLL_SYS_POWERDOWN_Msk)) |
CCM_ANALOG_PLL_SYS_ENABLE_Msk | sel)
// initialize the fractional mode
CCM_ANALOG.PLL_SYS_NUM.Set((cfg.Numerator << CCM_ANALOG_PLL_SYS_NUM_A_Pos) & CCM_ANALOG_PLL_SYS_NUM_A_Msk)
CCM_ANALOG.PLL_SYS_DENOM.Set((cfg.Denominator << CCM_ANALOG_PLL_SYS_DENOM_B_Pos) & CCM_ANALOG_PLL_SYS_DENOM_B_Msk)
// initialize the spread spectrum mode
inc := (uint32(cfg.SsStep) << CCM_ANALOG_PLL_SYS_SS_STEP_Pos) & CCM_ANALOG_PLL_SYS_SS_STEP_Msk
enb := (uint32(cfg.SsEnable) << CCM_ANALOG_PLL_SYS_SS_ENABLE_Pos) & CCM_ANALOG_PLL_SYS_SS_ENABLE_Msk
stp := (uint32(cfg.SsStop) << CCM_ANALOG_PLL_SYS_SS_STOP_Pos) & CCM_ANALOG_PLL_SYS_SS_STOP_Msk
CCM_ANALOG.PLL_SYS_SS.Set(inc | enb | stp)
for !CCM_ANALOG.PLL_SYS.HasBits(CCM_ANALOG_PLL_SYS_LOCK_Msk) {
}
// disable bypass
CCM_ANALOG.PLL_SYS.ClearBits(CCM_ANALOG_PLL_SYS_BYPASS_Msk)
// update PFDs after update
setSysPfd(pfd...)
}
// PLL configuration for USB
type ClockConfigUsbPll struct {
Instance uint8 // USB PLL number (1 or 2)
LoopDivider uint8 // PLL loop divider: 0 - Fout=Fref*20, 1 - Fout=Fref*22
Src uint8 // Pll clock source, reference _clock_pll_clk_src
}
func (cfg ClockConfigUsbPll) Configure(pfd ...uint32) {
switch cfg.Instance {
case 1:
// bypass PLL first
src := (uint32(cfg.Src) << CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_Pos) & CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_Msk
CCM_ANALOG.PLL_USB1.Set(
(CCM_ANALOG.PLL_USB1.Get() & ^uint32(CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_Msk)) |
CCM_ANALOG_PLL_USB1_BYPASS_Msk | src)
sel := uint32((cfg.LoopDivider << CCM_ANALOG_PLL_USB1_DIV_SELECT_Pos) & CCM_ANALOG_PLL_USB1_DIV_SELECT_Msk)
CCM_ANALOG.PLL_USB1_SET.Set(
(CCM_ANALOG.PLL_USB1.Get() & ^uint32(CCM_ANALOG_PLL_USB1_DIV_SELECT_Msk)) |
CCM_ANALOG_PLL_USB1_ENABLE_Msk | CCM_ANALOG_PLL_USB1_POWER_Msk |
CCM_ANALOG_PLL_USB1_EN_USB_CLKS_Msk | sel)
for !CCM_ANALOG.PLL_USB1.HasBits(CCM_ANALOG_PLL_USB1_LOCK_Msk) {
}
// disable bypass
CCM_ANALOG.PLL_USB1_CLR.Set(CCM_ANALOG_PLL_USB1_BYPASS_Msk)
// update PFDs after update
setUsb1Pfd(pfd...)
case 2:
// bypass PLL first
src := (uint32(cfg.Src) << CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC_Pos) & CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC_Msk
CCM_ANALOG.PLL_USB2.Set(
(CCM_ANALOG.PLL_USB2.Get() & ^uint32(CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC_Msk)) |
CCM_ANALOG_PLL_USB2_BYPASS_Msk | src)
sel := uint32((cfg.LoopDivider << CCM_ANALOG_PLL_USB2_DIV_SELECT_Pos) & CCM_ANALOG_PLL_USB2_DIV_SELECT_Msk)
CCM_ANALOG.PLL_USB2.Set(
(CCM_ANALOG.PLL_USB2.Get() & ^uint32(CCM_ANALOG_PLL_USB2_DIV_SELECT_Msk)) |
CCM_ANALOG_PLL_USB2_ENABLE_Msk | CCM_ANALOG_PLL_USB2_POWER_Msk |
CCM_ANALOG_PLL_USB2_EN_USB_CLKS_Msk | sel)
for !CCM_ANALOG.PLL_USB2.HasBits(CCM_ANALOG_PLL_USB2_LOCK_Msk) {
}
// disable bypass
CCM_ANALOG.PLL_USB2.ClearBits(CCM_ANALOG_PLL_USB2_BYPASS_Msk)
default:
panic("nxp: invalid USB PLL")
}
}
+29
View File
@@ -0,0 +1,29 @@
// Hand created file. DO NOT DELETE.
// Hardfault aliases for definitions that have inconsistent naming (which are
// auto-generated by gen-device-svd.go) among devices in package nxp.
// +build nxp,mimxrt1062
package nxp
const (
HardFault_CFSR_IACCVIOL = SCB_CFSR_IACCVIOL
HardFault_CFSR_DACCVIOL = SCB_CFSR_DACCVIOL
HardFault_CFSR_MUNSTKERR = SCB_CFSR_MUNSTKERR
HardFault_CFSR_MSTKERR = SCB_CFSR_MSTKERR
HardFault_CFSR_MLSPERR = SCB_CFSR_MLSPERR
HardFault_CFSR_IBUSERR = SCB_CFSR_IBUSERR
HardFault_CFSR_PRECISERR = SCB_CFSR_PRECISERR
HardFault_CFSR_IMPRECISERR = SCB_CFSR_IMPRECISERR
HardFault_CFSR_UNSTKERR = SCB_CFSR_UNSTKERR
HardFault_CFSR_STKERR = SCB_CFSR_STKERR
HardFault_CFSR_LSPERR = SCB_CFSR_LSPERR
HardFault_CFSR_UNDEFINSTR = SCB_CFSR_UNDEFINSTR
HardFault_CFSR_INVSTATE = SCB_CFSR_INVSTATE
HardFault_CFSR_INVPC = SCB_CFSR_INVPC
HardFault_CFSR_NOCP = SCB_CFSR_NOCP
HardFault_CFSR_UNALIGNED = SCB_CFSR_UNALIGNED
HardFault_CFSR_DIVBYZERO = SCB_CFSR_DIVBYZERO
HardFault_CFSR_MMARVALID = SCB_CFSR_MMARVALID
HardFault_CFSR_BFARVALID = SCB_CFSR_BFARVALID
)
+278
View File
@@ -0,0 +1,278 @@
// Hand created file. DO NOT DELETE.
// Type definitions, fields, and constants associated with the MPU peripheral
// of the NXP MIMXRT1062.
// +build nxp,mimxrt1062
package nxp
import (
"device/arm"
"runtime/volatile"
"unsafe"
)
type MPU_Type struct {
TYPE volatile.Register32 // 0x000 (R/ ) - MPU Type Register
CTRL volatile.Register32 // 0x004 (R/W) - MPU Control Register
RNR volatile.Register32 // 0x008 (R/W) - MPU Region RNRber Register
RBAR volatile.Register32 // 0x00C (R/W) - MPU Region Base Address Register
RASR volatile.Register32 // 0x010 (R/W) - MPU Region Attribute and Size Register
RBAR_A1 volatile.Register32 // 0x014 (R/W) - MPU Alias 1 Region Base Address Register
RASR_A1 volatile.Register32 // 0x018 (R/W) - MPU Alias 1 Region Attribute and Size Register
RBAR_A2 volatile.Register32 // 0x01C (R/W) - MPU Alias 2 Region Base Address Register
RASR_A2 volatile.Register32 // 0x020 (R/W) - MPU Alias 2 Region Attribute and Size Register
RBAR_A3 volatile.Register32 // 0x024 (R/W) - MPU Alias 3 Region Base Address Register
RASR_A3 volatile.Register32 // 0x028 (R/W) - MPU Alias 3 Region Attribute and Size Register
}
var MPU = (*MPU_Type)(unsafe.Pointer(uintptr(0xe000ed90)))
type (
RegionSize uint32
AccessPerms uint32
Extension uint32
)
// MPU Control Register Definitions
const (
MPU_CTRL_PRIVDEFENA_Pos = 2 // MPU CTRL: PRIVDEFENA Position
MPU_CTRL_PRIVDEFENA_Msk = 1 << MPU_CTRL_PRIVDEFENA_Pos // MPU CTRL: PRIVDEFENA Mask
MPU_CTRL_HFNMIENA_Pos = 1 // MPU CTRL: HFNMIENA Position
MPU_CTRL_HFNMIENA_Msk = 1 << MPU_CTRL_HFNMIENA_Pos // MPU CTRL: HFNMIENA Mask
MPU_CTRL_ENABLE_Pos = 0 // MPU CTRL: ENABLE Position
MPU_CTRL_ENABLE_Msk = 1 // MPU CTRL: ENABLE Mask
)
// MPU Region Base Address Register Definitions
const (
MPU_RBAR_ADDR_Pos = 5 // MPU RBAR: ADDR Position
MPU_RBAR_ADDR_Msk = 0x7FFFFFF << MPU_RBAR_ADDR_Pos // MPU RBAR: ADDR Mask
MPU_RBAR_VALID_Pos = 4 // MPU RBAR: VALID Position
MPU_RBAR_VALID_Msk = 1 << MPU_RBAR_VALID_Pos // MPU RBAR: VALID Mask
MPU_RBAR_REGION_Pos = 0 // MPU RBAR: REGION Position
MPU_RBAR_REGION_Msk = 0xF // MPU RBAR: REGION Mask
)
// MPU Region Attribute and Size Register Definitions
const (
MPU_RASR_ATTRS_Pos = 16 // MPU RASR: MPU Region Attribute field Position
MPU_RASR_ATTRS_Msk = 0xFFFF << MPU_RASR_ATTRS_Pos // MPU RASR: MPU Region Attribute field Mask
MPU_RASR_XN_Pos = 28 // MPU RASR: ATTRS.XN Position
MPU_RASR_XN_Msk = 1 << MPU_RASR_XN_Pos // MPU RASR: ATTRS.XN Mask
MPU_RASR_AP_Pos = 24 // MPU RASR: ATTRS.AP Position
MPU_RASR_AP_Msk = 0x7 << MPU_RASR_AP_Pos // MPU RASR: ATTRS.AP Mask
MPU_RASR_TEX_Pos = 19 // MPU RASR: ATTRS.TEX Position
MPU_RASR_TEX_Msk = 0x7 << MPU_RASR_TEX_Pos // MPU RASR: ATTRS.TEX Mask
MPU_RASR_S_Pos = 18 // MPU RASR: ATTRS.S Position
MPU_RASR_S_Msk = 1 << MPU_RASR_S_Pos // MPU RASR: ATTRS.S Mask
MPU_RASR_C_Pos = 17 // MPU RASR: ATTRS.C Position
MPU_RASR_C_Msk = 1 << MPU_RASR_C_Pos // MPU RASR: ATTRS.C Mask
MPU_RASR_B_Pos = 16 // MPU RASR: ATTRS.B Position
MPU_RASR_B_Msk = 1 << MPU_RASR_B_Pos // MPU RASR: ATTRS.B Mask
MPU_RASR_SRD_Pos = 8 // MPU RASR: Sub-Region Disable Position
MPU_RASR_SRD_Msk = 0xFF << MPU_RASR_SRD_Pos // MPU RASR: Sub-Region Disable Mask
MPU_RASR_SIZE_Pos = 1 // MPU RASR: Region Size Field Position
MPU_RASR_SIZE_Msk = 0x1F << MPU_RASR_SIZE_Pos // MPU RASR: Region Size Field Mask
MPU_RASR_ENABLE_Pos = 0 // MPU RASR: Region enable bit Position
MPU_RASR_ENABLE_Msk = 1 // MPU RASR: Region enable bit Disable Mask
)
const (
SCB_DCISW_WAY_Pos = 30 // SCB DCISW: Way Position
SCB_DCISW_WAY_Msk = 3 << SCB_DCISW_WAY_Pos // SCB DCISW: Way Mask
SCB_DCISW_SET_Pos = 5 // SCB DCISW: Set Position
SCB_DCISW_SET_Msk = 0x1FF << SCB_DCISW_SET_Pos // SCB DCISW: Set Mask
)
const (
SCB_DCCISW_WAY_Pos = 30 // SCB DCCISW: Way Position
SCB_DCCISW_WAY_Msk = 3 << SCB_DCCISW_WAY_Pos // SCB DCCISW: Way Mask
SCB_DCCISW_SET_Pos = 5 // SCB DCCISW: Set Position
SCB_DCCISW_SET_Msk = 0x1FF << SCB_DCCISW_SET_Pos // SCB DCCISW: Set Mask
)
const (
RGNSZ_32B RegionSize = 0x04 // MPU Region Size 32 Bytes
RGNSZ_64B RegionSize = 0x05 // MPU Region Size 64 Bytes
RGNSZ_128B RegionSize = 0x06 // MPU Region Size 128 Bytes
RGNSZ_256B RegionSize = 0x07 // MPU Region Size 256 Bytes
RGNSZ_512B RegionSize = 0x08 // MPU Region Size 512 Bytes
RGNSZ_1KB RegionSize = 0x09 // MPU Region Size 1 KByte
RGNSZ_2KB RegionSize = 0x0A // MPU Region Size 2 KBytes
RGNSZ_4KB RegionSize = 0x0B // MPU Region Size 4 KBytes
RGNSZ_8KB RegionSize = 0x0C // MPU Region Size 8 KBytes
RGNSZ_16KB RegionSize = 0x0D // MPU Region Size 16 KBytes
RGNSZ_32KB RegionSize = 0x0E // MPU Region Size 32 KBytes
RGNSZ_64KB RegionSize = 0x0F // MPU Region Size 64 KBytes
RGNSZ_128KB RegionSize = 0x10 // MPU Region Size 128 KBytes
RGNSZ_256KB RegionSize = 0x11 // MPU Region Size 256 KBytes
RGNSZ_512KB RegionSize = 0x12 // MPU Region Size 512 KBytes
RGNSZ_1MB RegionSize = 0x13 // MPU Region Size 1 MByte
RGNSZ_2MB RegionSize = 0x14 // MPU Region Size 2 MBytes
RGNSZ_4MB RegionSize = 0x15 // MPU Region Size 4 MBytes
RGNSZ_8MB RegionSize = 0x16 // MPU Region Size 8 MBytes
RGNSZ_16MB RegionSize = 0x17 // MPU Region Size 16 MBytes
RGNSZ_32MB RegionSize = 0x18 // MPU Region Size 32 MBytes
RGNSZ_64MB RegionSize = 0x19 // MPU Region Size 64 MBytes
RGNSZ_128MB RegionSize = 0x1A // MPU Region Size 128 MBytes
RGNSZ_256MB RegionSize = 0x1B // MPU Region Size 256 MBytes
RGNSZ_512MB RegionSize = 0x1C // MPU Region Size 512 MBytes
RGNSZ_1GB RegionSize = 0x1D // MPU Region Size 1 GByte
RGNSZ_2GB RegionSize = 0x1E // MPU Region Size 2 GBytes
RGNSZ_4GB RegionSize = 0x1F // MPU Region Size 4 GBytes
)
const (
PERM_NONE AccessPerms = 0 // MPU Access Permission no access
PERM_PRIV AccessPerms = 1 // MPU Access Permission privileged access only
PERM_URO AccessPerms = 2 // MPU Access Permission unprivileged access read-only
PERM_FULL AccessPerms = 3 // MPU Access Permission full access
PERM_PRO AccessPerms = 5 // MPU Access Permission privileged access read-only
PERM_RO AccessPerms = 6 // MPU Access Permission read-only access
)
const (
EXTN_NORMAL Extension = 0
EXTN_DEVICE Extension = 2
)
func (mpu *MPU_Type) Enable(enable bool) {
if enable {
mpu.CTRL.Set(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk)
SystemControl.SHCSR.SetBits(SCB_SHCSR_MEMFAULTENA_Msk)
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
enableDcache(true)
enableIcache(true)
} else {
enableIcache(false)
enableDcache(false)
arm.AsmFull(`
dmb 0xF
`, nil)
SystemControl.SHCSR.ClearBits(SCB_SHCSR_MEMFAULTENA_Msk)
mpu.CTRL.ClearBits(MPU_CTRL_ENABLE_Msk)
}
}
// MPU Region Base Address Register value
func (mpu *MPU_Type) SetRBAR(region uint32, baseAddress uint32) {
mpu.RBAR.Set((baseAddress & MPU_RBAR_ADDR_Msk) |
(region & MPU_RBAR_REGION_Msk) | MPU_RBAR_VALID_Msk)
}
// MPU Region Attribute and Size Register value
func (mpu *MPU_Type) SetRASR(size RegionSize, access AccessPerms, ext Extension, exec, share, cache, buffer, disable bool) {
boolBit := func(b bool) uint32 {
if b {
return 1
}
return 0
}
attr := ((uint32(ext) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) |
((boolBit(share) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) |
((boolBit(cache) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) |
((boolBit(buffer) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)
mpu.RASR.Set(((boolBit(!exec) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) |
((uint32(access) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) |
(attr & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk)) |
((boolBit(disable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) |
((uint32(size) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) |
MPU_RASR_ENABLE_Msk)
}
func enableIcache(enable bool) {
if enable != SystemControl.CCR.HasBits(SCB_CCR_IC_Msk) {
if enable {
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
SystemControl.ICIALLU.Set(0)
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
SystemControl.CCR.SetBits(SCB_CCR_IC_Msk)
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
} else {
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
SystemControl.CCR.ClearBits(SCB_CCR_IC_Msk)
SystemControl.ICIALLU.Set(0)
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
}
}
}
func enableDcache(enable bool) {
if enable != SystemControl.CCR.HasBits(SCB_CCR_DC_Msk) {
if enable {
SystemControl.CSSELR.Set(0)
arm.AsmFull(`
dsb 0xF
`, nil)
ccsidr := SystemControl.CCSIDR.Get()
sets := (ccsidr & SCB_CCSIDR_NUMSETS_Msk) >> SCB_CCSIDR_NUMSETS_Pos
for sets != 0 {
ways := (ccsidr & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos
for ways != 0 {
SystemControl.DCISW.Set(
((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk))
ways--
}
sets--
}
arm.AsmFull(`
dsb 0xF
`, nil)
SystemControl.CCR.SetBits(SCB_CCR_DC_Msk)
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
} else {
var (
ccsidr volatile.Register32
sets volatile.Register32
ways volatile.Register32
)
SystemControl.CSSELR.Set(0)
arm.AsmFull(`
dsb 0xF
`, nil)
SystemControl.CCR.ClearBits(SCB_CCR_DC_Msk)
arm.AsmFull(`
dsb 0xF
`, nil)
ccsidr.Set(SystemControl.CCSIDR.Get())
sets.Set((ccsidr.Get() & SCB_CCSIDR_NUMSETS_Msk) >> SCB_CCSIDR_NUMSETS_Pos)
for sets.Get() != 0 {
ways.Set((ccsidr.Get() & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
for ways.Get() != 0 {
SystemControl.DCCISW.Set(
((sets.Get() << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
((ways.Get() << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk))
ways.Set(ways.Get() - 1)
}
sets.Set(sets.Get() - 1)
}
arm.AsmFull(`
dsb 0xF
isb 0xF
`, nil)
}
}
}
+130
View File
@@ -0,0 +1,130 @@
#ifdef __riscv_flen
#define NREG 48
#define LFREG flw
#define SFREG fsw
#else
#define NREG 16
#endif
#if __riscv_xlen==64
#define REGSIZE 8
#define SREG sd
#define LREG ld
#else
#define REGSIZE 4
#define SREG sw
#define LREG lw
#endif
.section .text.handleInterruptASM
.global handleInterruptASM
.type handleInterruptASM,@function
handleInterruptASM:
// Save and restore all registers, because the hardware only saves/restores
// the pc.
// Note: we have to do this in assembly because the "interrupt"="machine"
// attribute is broken in LLVM: https://bugs.llvm.org/show_bug.cgi?id=42984
addi sp, sp, -NREG*REGSIZE
SREG ra, 0*REGSIZE(sp)
SREG t0, 1*REGSIZE(sp)
SREG t1, 2*REGSIZE(sp)
SREG t2, 3*REGSIZE(sp)
SREG a0, 4*REGSIZE(sp)
SREG a1, 5*REGSIZE(sp)
SREG a2, 6*REGSIZE(sp)
SREG a3, 7*REGSIZE(sp)
SREG a4, 8*REGSIZE(sp)
SREG a5, 9*REGSIZE(sp)
SREG a6, 10*REGSIZE(sp)
SREG a7, 11*REGSIZE(sp)
SREG t3, 12*REGSIZE(sp)
SREG t4, 13*REGSIZE(sp)
SREG t5, 14*REGSIZE(sp)
SREG t6, 15*REGSIZE(sp)
#ifdef __riscv_flen
SFREG f0, (0 + 16)*REGSIZE(sp)
SFREG f1, (1 + 16)*REGSIZE(sp)
SFREG f2, (2 + 16)*REGSIZE(sp)
SFREG f3, (3 + 16)*REGSIZE(sp)
SFREG f4, (4 + 16)*REGSIZE(sp)
SFREG f5, (5 + 16)*REGSIZE(sp)
SFREG f6, (6 + 16)*REGSIZE(sp)
SFREG f7, (7 + 16)*REGSIZE(sp)
SFREG f8, (8 + 16)*REGSIZE(sp)
SFREG f9, (9 + 16)*REGSIZE(sp)
SFREG f10,(10 + 16)*REGSIZE(sp)
SFREG f11,(11 + 16)*REGSIZE(sp)
SFREG f12,(12 + 16)*REGSIZE(sp)
SFREG f13,(13 + 16)*REGSIZE(sp)
SFREG f14,(14 + 16)*REGSIZE(sp)
SFREG f15,(15 + 16)*REGSIZE(sp)
SFREG f16,(16 + 16)*REGSIZE(sp)
SFREG f17,(17 + 16)*REGSIZE(sp)
SFREG f18,(18 + 16)*REGSIZE(sp)
SFREG f19,(19 + 16)*REGSIZE(sp)
SFREG f20,(20 + 16)*REGSIZE(sp)
SFREG f21,(21 + 16)*REGSIZE(sp)
SFREG f22,(22 + 16)*REGSIZE(sp)
SFREG f23,(23 + 16)*REGSIZE(sp)
SFREG f24,(24 + 16)*REGSIZE(sp)
SFREG f25,(25 + 16)*REGSIZE(sp)
SFREG f26,(26 + 16)*REGSIZE(sp)
SFREG f27,(27 + 16)*REGSIZE(sp)
SFREG f28,(28 + 16)*REGSIZE(sp)
SFREG f29,(29 + 16)*REGSIZE(sp)
SFREG f30,(30 + 16)*REGSIZE(sp)
SFREG f31,(31 + 16)*REGSIZE(sp)
#endif
call handleInterrupt
#ifdef __riscv_flen
LFREG f0, (31 + 16)*REGSIZE(sp)
LFREG f1, (30 + 16)*REGSIZE(sp)
LFREG f2, (29 + 16)*REGSIZE(sp)
LFREG f3, (28 + 16)*REGSIZE(sp)
LFREG f4, (27 + 16)*REGSIZE(sp)
LFREG f5, (26 + 16)*REGSIZE(sp)
LFREG f6, (25 + 16)*REGSIZE(sp)
LFREG f7, (24 + 16)*REGSIZE(sp)
LFREG f8, (23 + 16)*REGSIZE(sp)
LFREG f9, (22 + 16)*REGSIZE(sp)
LFREG f10,(21 + 16)*REGSIZE(sp)
LFREG f11,(20 + 16)*REGSIZE(sp)
LFREG f12,(19 + 16)*REGSIZE(sp)
LFREG f13,(18 + 16)*REGSIZE(sp)
LFREG f14,(17 + 16)*REGSIZE(sp)
LFREG f15,(16 + 16)*REGSIZE(sp)
LFREG f16,(15 + 16)*REGSIZE(sp)
LFREG f17,(14 + 16)*REGSIZE(sp)
LFREG f18,(13 + 16)*REGSIZE(sp)
LFREG f19,(12 + 16)*REGSIZE(sp)
LFREG f20,(11 + 16)*REGSIZE(sp)
LFREG f21,(10 + 16)*REGSIZE(sp)
LFREG f22,(9 + 16)*REGSIZE(sp)
LFREG f23,(8 + 16)*REGSIZE(sp)
LFREG f24,(7 + 16)*REGSIZE(sp)
LFREG f25,(6 + 16)*REGSIZE(sp)
LFREG f26,(5 + 16)*REGSIZE(sp)
LFREG f27,(4 + 16)*REGSIZE(sp)
LFREG f28,(3 + 16)*REGSIZE(sp)
LFREG f29,(2 + 16)*REGSIZE(sp)
LFREG f30,(1 + 16)*REGSIZE(sp)
LFREG f31,(0 + 16)*REGSIZE(sp)
#endif
LREG t6, 15*REGSIZE(sp)
LREG t5, 14*REGSIZE(sp)
LREG t4, 13*REGSIZE(sp)
LREG t3, 12*REGSIZE(sp)
LREG a7, 11*REGSIZE(sp)
LREG a6, 10*REGSIZE(sp)
LREG a5, 9*REGSIZE(sp)
LREG a4, 8*REGSIZE(sp)
LREG a3, 7*REGSIZE(sp)
LREG a2, 6*REGSIZE(sp)
LREG a1, 5*REGSIZE(sp)
LREG a0, 4*REGSIZE(sp)
LREG t2, 3*REGSIZE(sp)
LREG t1, 2*REGSIZE(sp)
LREG t0, 1*REGSIZE(sp)
LREG ra, 0*REGSIZE(sp)
addi sp, sp, NREG*REGSIZE
mret
+5 -45
View File
@@ -9,52 +9,12 @@ _start:
// Load the globals pointer. The program will load pointers relative to this
// register, so it must be set to the right value on startup.
// See: https://gnu-mcu-eclipse.github.io/arch/riscv/programmer/#the-gp-global-pointer-register
// Linker relaxations must be disabled to avoid the initialization beign
// relaxed with an uninitialized global pointer: mv gp, gp
.option push
.option norelax
la gp, __global_pointer$
.option pop
// Jump to runtime.main
call main
.section .text.handleInterruptASM
.global handleInterruptASM
.type handleInterruptASM,@function
handleInterruptASM:
// Save and restore all registers, because the hardware only saves/restores
// the pc.
// Note: we have to do this in assembly because the "interrupt"="machine"
// attribute is broken in LLVM: https://bugs.llvm.org/show_bug.cgi?id=42984
addi sp, sp, -64
sw ra, 60(sp)
sw t0, 56(sp)
sw t1, 52(sp)
sw t2, 48(sp)
sw a0, 44(sp)
sw a1, 40(sp)
sw a2, 36(sp)
sw a3, 32(sp)
sw a4, 28(sp)
sw a5, 24(sp)
sw a6, 20(sp)
sw a7, 16(sp)
sw t3, 12(sp)
sw t4, 8(sp)
sw t5, 4(sp)
sw t6, 0(sp)
call handleInterrupt
lw t6, 0(sp)
lw t5, 4(sp)
lw t4, 8(sp)
lw t3, 12(sp)
lw a7, 16(sp)
lw a6, 20(sp)
lw a5, 24(sp)
lw a4, 28(sp)
lw a3, 32(sp)
lw a2, 36(sp)
lw a1, 40(sp)
lw a0, 44(sp)
lw t2, 48(sp)
lw t1, 52(sp)
lw t0, 56(sp)
lw ra, 60(sp)
addi sp, sp, 64
mret
+71
View File
@@ -0,0 +1,71 @@
// Hand created file. DO NOT DELETE.
// atsamd51x bitfield definitions that are not auto-generated by gen-device-svd.go
// +build sam,atsamd51
// These are the supported pchctrl function numberings on the atsamd51x
// See http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
// table 14-9
package sam
const (
PCHCTRL_GCLK_OSCCTRL_DFLL48 = 0 // DFLL48 input clock source
PCHCTRL_GCLK_OSCCTRL_FDPLL0 = 1 // Reference clock for FDPLL0
PCHCTRL_GCLK_OSCCTRL_FDPLL1 = 2 // Reference clock for FDPLL1
PCHCTRL_GCLK_OSCCTRL_FDPLL0_32K = 3 // FDPLL0 = 3 // 32KHz clock for internal lock timer
PCHCTRL_GCLK_OSCCTRL_FDPLL1_32K = 3 // FDPLL1 = 3 // 32KHz clock for internal lock timer
PCHCTRL_GCLK_SDHC0_SLOW = 3 // SDHC0 = 3 // Slow
PCHCTRL_GCLK_SDHC1_SLOW = 3 // SDHC1 = 3 // Slow
PCHCTRL_GCLK_SERCOMX_SLOW = 3 // GCLK_SERCOM[0..7]_SLOW = 3
PCHCTRL_GCLK_EIC = 4
PCHCTRL_GCLK_FREQM_MSR = 5 // FREQM Measure
PCHCTRL_GCLK_FREQM_REF = 6 // FREQM Reference
PCHCTRL_GCLK_SERCOM0_CORE = 7 // SERCOM0 Core
PCHCTRL_GCLK_SERCOM1_CORE = 8 // SERCOM1 Core
PCHCTRL_GCLK_TC0 = 9
PCHCTRL_GCLK_TC1 = 9 // TC0, TC1
PCHCTRL_GCLK_USB = 10 // USB
PCHCTRL_GCLK_EVSYS0 = 11
PCHCTRL_GCLK_EVSYS1 = 12
PCHCTRL_GCLK_EVSYS2 = 13
PCHCTRL_GCLK_EVSYS3 = 14
PCHCTRL_GCLK_EVSYS4 = 15
PCHCTRL_GCLK_EVSYS5 = 16
PCHCTRL_GCLK_EVSYS6 = 17
PCHCTRL_GCLK_EVSYS7 = 18
PCHCTRL_GCLK_EVSYS8 = 19
PCHCTRL_GCLK_EVSYS9 = 20
PCHCTRL_GCLK_EVSYS10 = 21
PCHCTRL_GCLK_EVSYS11 = 22
PCHCTRL_GCLK_SERCOM2_CORE = 23 // SERCOM2 Core
PCHCTRL_GCLK_SERCOM3_CORE = 24 // SERCOM3 Core
PCHCTRL_GCLK_TCC0 = 25
PCHCTRL_GCLK_TCC1 = 25 // TCC0, TCC1
PCHCTRL_GCLK_TC2 = 26
PCHCTRL_GCLK_TC3 = 26 // TC2, TC3
PCHCTRL_GCLK_CAN0 = 27 // CAN0
PCHCTRL_GCLK_CAN1 = 28 // CAN1
PCHCTRL_GCLK_TCC2 = 29
PCHCTRL_GCLK_TCC3 = 29 // TCC2, TCC3
PCHCTRL_GCLK_TC4 = 30
PCHCTRL_GCLK_TC5 = 30 // TC4, TC5
PCHCTRL_GCLK_PDEC = 31 // PDEC
PCHCTRL_GCLK_AC = 32 // AC
PCHCTRL_GCLK_CCL = 33 // CCL
PCHCTRL_GCLK_SERCOM4_CORE = 34 // SERCOM4 Core
PCHCTRL_GCLK_SERCOM5_CORE = 35 // SERCOM5 Core
PCHCTRL_GCLK_SERCOM6_CORE = 36 // SERCOM6 Core
PCHCTRL_GCLK_SERCOM7_CORE = 37 // SERCOM7 Core
PCHCTRL_GCLK_TCC4 = 38 // TCC4
PCHCTRL_GCLK_TC6 = 39
PCHCTRL_GCLK_TC7 = 39 // TC6, TC7
PCHCTRL_GCLK_ADC0 = 40 // ADC0
PCHCTRL_GCLK_ADC1 = 41 // ADC1
PCHCTRL_GCLK_DAC = 42 // DAC
PCHCTRL_GCLK_I2S0 = 43
PCHCTRL_GCLK_I2S1 = 44
PCHCTRL_GCLK_SDHC0 = 45 // SDHC0
PCHCTRL_GCLK_SDHC1 = 46 // SDHC1
PCHCTRL_GCLK_CM4_TRACE = 47 // CM4 Trace
)
@@ -1,7 +1,9 @@
// These are the supported alternate function numberings on the stm32f407
// +build stm32,stm32f407
// Hand created file. DO NOT DELETE.
// STM32FXXX (except stm32f1xx) bitfield definitions that are not
// auto-generated by gen-device-svd.go
// +build stm32f4
// Alternate function settings on the stm32f4xx series
// Alternate function settings on the stm32f4 series
package stm32
+13
View File
@@ -0,0 +1,13 @@
// +build circuitplay_express
package main
import (
"machine"
)
func init() {
enable := machine.PA30
enable.Configure(machine.PinConfig{Mode: machine.PinOutput})
enable.Set(true)
}
+36
View File
@@ -0,0 +1,36 @@
// Simplistic example using the DAC on the Circuit Playground Express.
//
// To actually use the DAC for producing complex waveforms or samples requires a DMA
// timer-based playback mechanism which is beyond the scope of this example.
package main
import (
"machine"
"time"
)
func main() {
speaker := machine.A0
speaker.Configure(machine.PinConfig{Mode: machine.PinOutput})
machine.DAC0.Configure(machine.DACConfig{})
data := []uint16{0xFFFF, 0x8000, 0x4000, 0x2000, 0x1000, 0x0000}
for {
for _, val := range data {
play(val)
time.Sleep(500 * time.Millisecond)
}
}
}
func play(val uint16) {
for i := 0; i < 100; i++ {
machine.DAC0.Set(val)
time.Sleep(2 * time.Millisecond)
machine.DAC0.Set(0)
time.Sleep(2 * time.Millisecond)
}
}
+13
View File
@@ -0,0 +1,13 @@
// +build pyportal
package main
import (
"machine"
)
func init() {
enable := machine.SPK_SD
enable.Configure(machine.PinConfig{Mode: machine.PinOutput})
enable.Set(true)
}
+1 -1
View File
@@ -8,7 +8,7 @@ import (
// This example assumes that an RGB LED is connected to pins 3, 5 and 6 on an Arduino.
// Change the values below to use different pins.
const (
redPin = machine.D3
redPin = machine.D4
greenPin = machine.D5
bluePin = machine.D6
)
+10 -7
View File
@@ -5,6 +5,8 @@ import (
"machine"
)
var timerCh = make(chan struct{}, 1)
func main() {
machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
@@ -12,17 +14,18 @@ func main() {
arm.SetupSystemTimer(machine.CPUFrequency() / 10)
for {
machine.LED.Low()
<-timerCh
machine.LED.High()
<-timerCh
}
}
var led_state bool
//export SysTick_Handler
func timer_isr() {
if led_state {
machine.LED.Low()
} else {
machine.LED.High()
select {
case timerCh <- struct{}{}:
default:
// The consumer is running behind.
}
led_state = !led_state
}
+127
View File
@@ -124,3 +124,130 @@ func IndexString(str, sub string) int {
}
return -1
}
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// The following code has been copied from the Go 1.15 release tree.
// PrimeRK is the prime base used in Rabin-Karp algorithm.
const PrimeRK = 16777619
// HashStrBytes returns the hash and the appropriate multiplicative
// factor for use in Rabin-Karp algorithm.
func HashStrBytes(sep []byte) (uint32, uint32) {
hash := uint32(0)
for i := 0; i < len(sep); i++ {
hash = hash*PrimeRK + uint32(sep[i])
}
var pow, sq uint32 = 1, PrimeRK
for i := len(sep); i > 0; i >>= 1 {
if i&1 != 0 {
pow *= sq
}
sq *= sq
}
return hash, pow
}
// HashStr returns the hash and the appropriate multiplicative
// factor for use in Rabin-Karp algorithm.
func HashStr(sep string) (uint32, uint32) {
hash := uint32(0)
for i := 0; i < len(sep); i++ {
hash = hash*PrimeRK + uint32(sep[i])
}
var pow, sq uint32 = 1, PrimeRK
for i := len(sep); i > 0; i >>= 1 {
if i&1 != 0 {
pow *= sq
}
sq *= sq
}
return hash, pow
}
// HashStrRevBytes returns the hash of the reverse of sep and the
// appropriate multiplicative factor for use in Rabin-Karp algorithm.
func HashStrRevBytes(sep []byte) (uint32, uint32) {
hash := uint32(0)
for i := len(sep) - 1; i >= 0; i-- {
hash = hash*PrimeRK + uint32(sep[i])
}
var pow, sq uint32 = 1, PrimeRK
for i := len(sep); i > 0; i >>= 1 {
if i&1 != 0 {
pow *= sq
}
sq *= sq
}
return hash, pow
}
// HashStrRev returns the hash of the reverse of sep and the
// appropriate multiplicative factor for use in Rabin-Karp algorithm.
func HashStrRev(sep string) (uint32, uint32) {
hash := uint32(0)
for i := len(sep) - 1; i >= 0; i-- {
hash = hash*PrimeRK + uint32(sep[i])
}
var pow, sq uint32 = 1, PrimeRK
for i := len(sep); i > 0; i >>= 1 {
if i&1 != 0 {
pow *= sq
}
sq *= sq
}
return hash, pow
}
// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
// first occurence of substr in s, or -1 if not present.
func IndexRabinKarpBytes(s, sep []byte) int {
// Rabin-Karp search
hashsep, pow := HashStrBytes(sep)
n := len(sep)
var h uint32
for i := 0; i < n; i++ {
h = h*PrimeRK + uint32(s[i])
}
if h == hashsep && Equal(s[:n], sep) {
return 0
}
for i := n; i < len(s); {
h *= PrimeRK
h += uint32(s[i])
h -= pow * uint32(s[i-n])
i++
if h == hashsep && Equal(s[i-n:i], sep) {
return i - n
}
}
return -1
}
// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
// first occurence of substr in s, or -1 if not present.
func IndexRabinKarp(s, substr string) int {
// Rabin-Karp search
hashss, pow := HashStr(substr)
n := len(substr)
var h uint32
for i := 0; i < n; i++ {
h = h*PrimeRK + uint32(s[i])
}
if h == hashss && s[:n] == substr {
return 0
}
for i := n; i < len(s); {
h *= PrimeRK
h += uint32(s[i])
h -= pow * uint32(s[i-n])
i++
if h == hashss && s[i-n:i] == substr {
return i - n
}
}
return -1
}
+27 -1
View File
@@ -1,5 +1,7 @@
package task
import "runtime/interrupt"
const asserts = false
// Queue is a FIFO container of tasks.
@@ -10,7 +12,9 @@ type Queue struct {
// Push a task onto the queue.
func (q *Queue) Push(t *Task) {
i := interrupt.Disable()
if asserts && t.Next != nil {
interrupt.Restore(i)
panic("runtime: pushing a task to a queue with a non-nil Next pointer")
}
if q.tail != nil {
@@ -21,12 +25,15 @@ func (q *Queue) Push(t *Task) {
if q.head == nil {
q.head = t
}
interrupt.Restore(i)
}
// Pop a task off of the queue.
func (q *Queue) Pop() *Task {
i := interrupt.Disable()
t := q.head
if t == nil {
interrupt.Restore(i)
return nil
}
q.head = t.Next
@@ -34,11 +41,13 @@ func (q *Queue) Pop() *Task {
q.tail = nil
}
t.Next = nil
interrupt.Restore(i)
return t
}
// Append pops the contents of another queue and pushes them onto the end of this queue.
func (q *Queue) Append(other *Queue) {
i := interrupt.Disable()
if q.head == nil {
q.head = other.head
} else {
@@ -46,6 +55,15 @@ func (q *Queue) Append(other *Queue) {
}
q.tail = other.tail
other.head, other.tail = nil, nil
interrupt.Restore(i)
}
// Empty checks if the queue is empty.
func (q *Queue) Empty() bool {
i := interrupt.Disable()
empty := q.head == nil
interrupt.Restore(i)
return empty
}
// Stack is a LIFO container of tasks.
@@ -57,19 +75,24 @@ type Stack struct {
// Push a task onto the stack.
func (s *Stack) Push(t *Task) {
i := interrupt.Disable()
if asserts && t.Next != nil {
interrupt.Restore(i)
panic("runtime: pushing a task to a stack with a non-nil Next pointer")
}
s.top, t.Next = t, s.top
interrupt.Restore(i)
}
// Pop a task off of the stack.
func (s *Stack) Pop() *Task {
i := interrupt.Disable()
t := s.top
if t != nil {
s.top = t.Next
t.Next = nil
}
interrupt.Restore(i)
return t
}
@@ -89,10 +112,13 @@ func (t *Task) tail() *Task {
// Queue moves the contents of the stack into a queue.
// Elements can be popped from the queue in the same order that they would be popped from the stack.
func (s *Stack) Queue() Queue {
i := interrupt.Disable()
head := s.top
s.top = nil
return Queue{
q := Queue{
head: head,
tail: head.tail(),
}
interrupt.Restore(i)
return q
}
+5
View File
@@ -18,3 +18,8 @@ type Task struct {
// state is the underlying running state of the task.
state state
}
// getGoroutineStackSize is a compiler intrinsic that returns the stack size for
// the given function and falls back to the default stack size. It is replaced
// with a load from a special section just before codegen.
func getGoroutineStackSize(fn uintptr) uintptr
+1 -1
View File
@@ -67,7 +67,7 @@ func createTask() *Task {
// start invokes a function in a new goroutine. Calls to this are inserted by the compiler.
// The created goroutine starts running immediately.
// This is implemented inside the compiler.
func start(fn uintptr, args unsafe.Pointer)
func start(fn uintptr, args unsafe.Pointer, stackSize uintptr)
// Current returns the current active task.
// This is implemented inside the compiler.
+1 -1
View File
@@ -17,7 +17,7 @@ func Current() *Task {
}
//go:noinline
func start(fn uintptr, args unsafe.Pointer) {
func start(fn uintptr, args unsafe.Pointer, stackSize uintptr) {
// The compiler will error if this is reachable.
runtimePanic("scheduler is disabled")
}
+3 -3
View File
@@ -54,7 +54,7 @@ func (t *Task) Resume() {
}
// initialize the state and prepare to call the specified function with the specified argument bundle.
func (s *state) initialize(fn uintptr, args unsafe.Pointer) {
func (s *state) initialize(fn uintptr, args unsafe.Pointer, stackSize uintptr) {
// Create a stack.
stack := make([]uintptr, stackSize/unsafe.Sizeof(uintptr(0)))
@@ -67,9 +67,9 @@ func runqueuePushBack(*Task)
// start creates and starts a new goroutine with the given function and arguments.
// The new goroutine is scheduled to run later.
func start(fn uintptr, args unsafe.Pointer) {
func start(fn uintptr, args unsafe.Pointer, stackSize uintptr) {
t := &Task{}
t.state.initialize(fn, args)
t.state.initialize(fn, args, stackSize)
runqueuePushBack(t)
}
-2
View File
@@ -4,8 +4,6 @@ package task
import "unsafe"
const stackSize = 256
// calleeSavedRegs is the list of registers that must be saved and restored when
// switching between tasks. Also see scheduler_avr.S that relies on the
// exact layout of this struct.
-2
View File
@@ -4,8 +4,6 @@ package task
import "unsafe"
const stackSize = 1024
// calleeSavedRegs is the list of registers that must be saved and restored when
// switching between tasks. Also see scheduler_cortexm.S that relies on the
// exact layout of this struct.
+1 -1
View File
@@ -49,7 +49,7 @@ const (
// Digital pins
D0 Pin = PE0
D1 Pin = PE1
D2 Pin = PE6
D2 Pin = PE4
D3 Pin = PE5
D4 Pin = PG5
D5 Pin = PE3
+5 -5
View File
@@ -66,15 +66,15 @@ const (
// SPI pins
const (
SPI0_SCK_PIN Pin = D13 // SCK: SERCOM1/PAD[1]
SPI0_MOSI_PIN Pin = D11 // MOSI: SERCOM1/PAD[0]
SPI0_MISO_PIN Pin = D12 // MISO: SERCOM1/PAD[3]
SPI0_SCK_PIN Pin = D13 // SCK: SERCOM1/PAD[1]
SPI0_SDO_PIN Pin = D11 // SDO: SERCOM1/PAD[0]
SPI0_SDI_PIN Pin = D12 // SDI: SERCOM1/PAD[3]
)
// NINA-W102 Pins
const (
NINA_MOSI Pin = PA12
NINA_MISO Pin = PA13
NINA_SDO Pin = PA12
NINA_SDI Pin = PA13
NINA_CS Pin = PA14
NINA_SCK Pin = PA15
NINA_GPIO0 Pin = PA27
+101
View File
@@ -0,0 +1,101 @@
// +build sam,atsamd21,arduino_zero
package machine
// used to reset into bootloader
const RESET_MAGIC_VALUE = 0x07738135
// GPIO Pins - Digital Low
const (
D0 = PA11 // RX
D1 = PA10 // TX
D2 = PA14
D3 = PA09 // PWM available
D4 = PA08 // PWM available
D5 = PA15 // PWM available
D6 = PA20 // PWM available
D7 = PA21
)
// GPIO Pins - Digital High
const (
D8 = PA06 // PWM available
D9 = PA07 // PWM available
D10 = PA18 // PWM available
D11 = PA16 // PWM available
D12 = PA19 // PWM available
D13 = PA17 // PWM available
)
// LEDs on the Arduino Zero
const (
LED = LED1
LED1 Pin = D13
LED2 Pin = PA27 // TX LED
LED3 Pin = PB03 // RX LED
)
// ADC pins
const (
AREF Pin = PA03
ADC0 Pin = PA02
ADC1 Pin = PB08
ADC2 Pin = PB09
ADC3 Pin = PA04
ADC4 Pin = PA05
ADC5 Pin = PB02
)
// SPI pins - EDBG connected
const (
SPI0_SDO_PIN Pin = PA16 // MOSI: SERCOM1/PAD[0]
SPI0_SDI_PIN Pin = PA19 // MISO: SERCOM1/PAD[2]
SPI0_SCK_PIN Pin = PA17 // SCK: SERCOM1/PAD[3]
)
// SPI pins (Legacy ICSP)
const (
SPI1_SDO_PIN Pin = PB10 // MOSI: SERCOM4/PAD[2] - Pin 4
SPI1_SDI_PIN Pin = PA12 // MISO: SERCOM4/PAD[0] - Pin 1
SPI1_SCK_PIN Pin = PB11 // SCK: SERCOM4/PAD[3] - Pin 3
)
// I2C pins - EDBG connected
const (
SDA_PIN Pin = PA22 // SDA: SERCOM3/PAD[0] - Pin 20
SCL_PIN Pin = PA23 // SCL: SERCOM3/PAD[1] - Pin 21
)
// I2S pins - might not be exposed
const (
I2S_SCK_PIN Pin = PA10
I2S_SD_PIN Pin = PA07
I2S_WS_PIN Pin = PA11
)
// UART0 pins - EDBG connected
const (
UART_RX_PIN Pin = D0
UART_TX_PIN Pin = D1
)
// 'native' USB port pins
const (
USBCDC_DM_PIN Pin = PA24
USBCDC_DP_PIN Pin = PA25
)
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "Arduino Zero"
usb_STRING_MANUFACTURER = "Arduino LLC"
usb_VID uint16 = 0x2341
usb_PID uint16 = 0x804d
)
// 32.768 KHz Crystal
const (
XIN32 Pin = PA00
XOUT32 Pin = PA01
)
+8 -4
View File
@@ -65,18 +65,22 @@ var (
Buffer: NewRingBuffer(),
Bus: stm32.USART1,
}
UART1 = &UART0
UART1 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART2,
}
)
func init() {
UART0.Interrupt = interrupt.New(stm32.IRQ_USART1, UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(stm32.IRQ_USART2, UART1.handleInterrupt)
}
// SPI pins
const (
SPI0_SCK_PIN = PA5
SPI0_MOSI_PIN = PA7
SPI0_MISO_PIN = PA6
SPI0_SCK_PIN = PA5
SPI0_SDO_PIN = PA7
SPI0_SDI_PIN = PA6
)
// I2C pins
+4 -4
View File
@@ -2,7 +2,7 @@
package machine
const HasLowFrequencyCrystal = true
const HasLowFrequencyCrystal = false
// GPIO Pins
const (
@@ -72,9 +72,9 @@ const (
// SPI pins (internal flash)
const (
SPI0_SCK_PIN = P0_19 // SCK
SPI0_MOSI_PIN = P0_21 // MOSI
SPI0_MISO_PIN = P0_23 // MISO
SPI0_SCK_PIN = P0_19 // SCK
SPI0_SDO_PIN = P0_21 // SDO
SPI0_SDI_PIN = P0_23 // SDI
)
// USB CDC identifiers
+3 -3
View File
@@ -77,9 +77,9 @@ const (
// SPI pins (internal flash)
const (
SPI0_SCK_PIN = PA21 // SCK: SERCOM3/PAD[3]
SPI0_MOSI_PIN = PA20 // MOSI: SERCOM3/PAD[2]
SPI0_MISO_PIN = PA16 // MISO: SERCOM3/PAD[0]
SPI0_SCK_PIN = PA21 // SCK: SERCOM3/PAD[3]
SPI0_SDO_PIN = PA20 // SDO: SERCOM3/PAD[2]
SPI0_SDI_PIN = PA16 // SDI: SERCOM3/PAD[0]
)
// I2S pins
+4 -4
View File
@@ -78,7 +78,7 @@ const (
// 240x240 ST7789 display is connected to these pins (use RowOffset = 80)
TFT_SCK = D29
TFT_MOSI = D30
TFT_SDO = D30
TFT_CS = D31
TFT_DC = D32
TFT_RESET = D33
@@ -116,9 +116,9 @@ const (
// SPI pins
const (
SPI0_SCK_PIN = D13 // SCK
SPI0_MOSI_PIN = D15 // MOSI
SPI0_MISO_PIN = D14 // MISO
SPI0_SCK_PIN = D13 // SCK
SPI0_SDO_PIN = D15 // SDO
SPI0_SDI_PIN = D14 // SDI
)
// USB CDC identifiers
+88
View File
@@ -0,0 +1,88 @@
// +build esp32_coreboard_v2
package machine
// Built-in LED on some ESP32 boards.
const LED = IO2
const (
CLK Pin = 6
CMD Pin = 11
IO0 Pin = 0
IO1 Pin = 1
IO10 Pin = 10
IO16 Pin = 16
IO17 Pin = 17
IO18 Pin = 18
IO19 Pin = 19
IO2 Pin = 2
IO21 Pin = 21
IO22 Pin = 22
IO23 Pin = 23
IO25 Pin = 25
IO26 Pin = 26
IO27 Pin = 27
IO3 Pin = 3
IO32 Pin = 32
IO33 Pin = 33
IO34 Pin = 34
IO35 Pin = 35
IO36 Pin = 36
IO39 Pin = 39
IO4 Pin = 4
IO5 Pin = 5
IO9 Pin = 9
RXD Pin = 3
SD0 Pin = 7
SD1 Pin = 8
SD2 Pin = 9
SD3 Pin = 10
SVN Pin = 39
SVP Pin = 36
TCK Pin = 13
TD0 Pin = 15
TDI Pin = 12
TMS Pin = 14
TXD Pin = 1
)
// SPI pins
const (
SPI0_SCK_PIN = IO18
SPI0_SDO_PIN = IO23
SPI0_SDI_PIN = IO19
SPI0_CS0_PIN = IO5
)
// I2C pins
const (
SDA_PIN = IO21
SCL_PIN = IO22
)
// ADC pins
const (
ADC0 Pin = IO34
ADC1 Pin = IO35
ADC2 Pin = IO36
ADC3 Pin = IO39
)
// UART0 pins
const (
UART_TX_PIN = IO1
UART_RX_PIN = IO3
)
// UART1 pins
const (
UART1_TX_PIN = IO9
UART1_RX_PIN = IO10
)
// PWM pins
const (
PWM0_PIN Pin = IO2
PWM1_PIN Pin = IO0
PWM2_PIN Pin = IO4
)
+3 -3
View File
@@ -83,9 +83,9 @@ var (
// SPI pins
const (
SPI0_SCK_PIN = PB11 // SCK: SERCOM4/PAD[3]
SPI0_MOSI_PIN = PB10 // MOSI: SERCOM4/PAD[2]
SPI0_MISO_PIN = PA12 // MISO: SERCOM4/PAD[0]
SPI0_SCK_PIN = PB11 // SCK: SERCOM4/PAD[3]
SPI0_SDO_PIN = PB10 // SDO: SERCOM4/PAD[2]
SPI0_SDI_PIN = PA12 // SDI: SERCOM4/PAD[0]
)
// SPI on the Feather M0.
+3 -3
View File
@@ -63,9 +63,9 @@ const (
// SPI pins
const (
SPI0_SCK_PIN = D25 // SCK: SERCOM1/PAD[1]
SPI0_MOSI_PIN = D24 // MOSI: SERCOM1/PAD[3]
SPI0_MISO_PIN = D23 // MISO: SERCOM1/PAD[2]
SPI0_SCK_PIN = D25 // SCK: SERCOM1/PAD[1]
SPI0_SDO_PIN = D24 // SDO: SERCOM1/PAD[3]
SPI0_SDI_PIN = D23 // SDI: SERCOM1/PAD[2]
)
// USB CDC identifiers
+105
View File
@@ -0,0 +1,105 @@
// +build feather_nrf52840
package machine
const HasLowFrequencyCrystal = true
// GPIO Pins
const (
D0 = P0_25 // UART TX
D1 = P0_24 // UART RX
D2 = P0_10 // NFC2
D3 = P1_15 // LED1
D4 = P1_10 // LED2
D5 = P1_08
D6 = P0_07
D7 = P1_02 // Button
D8 = P0_16 // NeoPixel
D9 = P0_26
D10 = P0_27
D11 = P0_06
D12 = P0_08
D13 = P1_09
D14 = P0_04 // A0
D15 = P0_05 // A1
D16 = P0_30 // A2
D17 = P0_28 // A3
D18 = P0_02 // A4
D19 = P0_03 // A5
D20 = P0_29 // Battery
D21 = P0_31 // AREF
D22 = P0_12 // I2C SDA
D23 = P0_11 // I2C SCL
D24 = P0_15 // SPI MISO
D25 = P0_13 // SPI MOSI
D26 = P0_14 // SPI SCK
D27 = P0_19 // QSPI CLK
D28 = P0_20 // QSPI CS
D29 = P0_17 // QSPI Data 0
D30 = P0_22 // QSPI Data 1
D31 = P0_23 // QSPI Data 2
D32 = P0_21 // QSPI Data 3
D33 = P0_09 // NFC1 (test point on bottom of board)
)
// Analog Pins
const (
A0 = D14
A1 = D15
A2 = D16
A3 = D17
A4 = D18
A5 = D19
A6 = D20 // Battery
A7 = D21 // ARef
)
const (
LED = D3
LED1 = LED
LED2 = D4
NEOPIXEL = D8
BUTTON = D7
QSPI_SCK = D27
QSPI_CS = D28
QSPI_DATA0 = D29
QSPI_DATA1 = D30
QSPI_DATA2 = D31
QSPI_DATA3 = D32
)
// UART0 pins (logical UART1)
const (
UART_RX_PIN = D0
UART_TX_PIN = D1
)
// UART0 is the USB device
var (
UART0 = USB
)
// I2C pins
const (
SDA_PIN = D22 // I2C0 external
SCL_PIN = D23 // I2C0 external
)
// SPI pins
const (
SPI0_SCK_PIN = D26 // SCK
SPI0_SDO_PIN = D25 // SDO
SPI0_SDI_PIN = D24 // SDI
)
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "Feather nRF52840 Express"
usb_STRING_MANUFACTURER = "Adafruit Industries LLC"
)
var (
usb_VID uint16 = 0x239A
usb_PID uint16 = 0x802A
)
+245
View File
@@ -0,0 +1,245 @@
// +build feather_stm32f405
package machine
import (
"device/stm32"
"runtime/interrupt"
)
const (
NUM_DIGITAL_IO_PINS = 39
NUM_ANALOG_IO_PINS = 7
)
// Digital pins
const (
// Arduino pin = MCU port pin // primary functions (alternate functions)
D0 = PB11 // USART3 RX, PWM TIM2_CH4 (I2C2 SDA)
D1 = PB10 // USART3 TX, PWM TIM2_CH3 (I2C2 SCL, I2S2 BCK)
D2 = PB3 // GPIO, SPI3 FLASH SCK
D3 = PB4 // GPIO, SPI3 FLASH MISO
D4 = PB5 // GPIO, SPI3 FLASH MOSI
D5 = PC7 // GPIO, PWM TIM3_CH2 (USART6 RX, I2S3 MCK)
D6 = PC6 // GPIO, PWM TIM3_CH1 (USART6 TX, I2S2 MCK)
D7 = PA15 // GPIO, SPI3 FLASH CS
D8 = PC0 // GPIO, Neopixel
D9 = PB8 // GPIO, PWM TIM4_CH3 (CAN1 RX, I2C1 SCL)
D10 = PB9 // GPIO, PWM TIM4_CH4 (CAN1 TX, I2C1 SDA, I2S2 WSL)
D11 = PC3 // GPIO (I2S2 SD, SPI2 MOSI)
D12 = PC2 // GPIO (I2S2ext SD, SPI2 MISO)
D13 = PC1 // GPIO, Builtin LED
D14 = PB7 // I2C1 SDA, PWM TIM4_CH2 (USART1 RX)
D15 = PB6 // I2C1 SCL, PWM TIM4_CH1 (USART1 TX, CAN2 TX)
D16 = PA4 // A0 (DAC OUT1)
D17 = PA5 // A1 (DAC OUT2, SPI1 SCK)
D18 = PA6 // A2, PWM TIM3_CH1 (SPI1 MISO)
D19 = PA7 // A3, PWM TIM3_CH2 (SPI1 MOSI)
D20 = PC4 // A4
D21 = PC5 // A5
D22 = PA3 // A6
D23 = PB13 // SPI2 SCK, PWM TIM1_CH1N (I2S2 BCK, CAN2 TX)
D24 = PB14 // SPI2 MISO, PWM TIM1_CH2N (I2S2ext SD)
D25 = PB15 // SPI2 MOSI, PWM TIM1_CH3N (I2S2 SD)
D26 = PC8 // SDIO
D27 = PC9 // SDIO
D28 = PC10 // SDIO
D29 = PC11 // SDIO
D30 = PC12 // SDIO
D31 = PD2 // SDIO
D32 = PB12 // SD Detect
D33 = PC14 // OSC32
D34 = PC15 // OSC32
D35 = PA11 // USB D+
D36 = PA12 // USB D-
D37 = PA13 // SWDIO
D38 = PA14 // SWCLK
)
// Analog pins
const (
A0 = D16 // ADC12 IN4
A1 = D17 // ADC12 IN5
A2 = D18 // ADC12 IN6
A3 = D19 // ADC12 IN7
A4 = D20 // ADC12 IN14
A5 = D21 // ADC12 IN15
A6 = D22 // VBAT
)
func init() {
initLED()
initUART()
initSPI()
initI2C()
}
// -- LEDs ---------------------------------------------------------------------
const (
NUM_BOARD_LED = 1
NUM_BOARD_NEOPIXEL = 1
LED_RED = D13
LED_NEOPIXEL = D8
LED_BUILTIN = LED_RED
LED = LED_BUILTIN
)
func initLED() {}
// -- UART ---------------------------------------------------------------------
const (
// #===========#==========#==============#============#=======#=======#
// | Interface | Hardware | Bus(Freq) | RX/TX Pins | AltFn | Alias |
// #===========#==========#==============#============#=======#=======#
// | UART1 | USART3 | APB1(42 MHz) | D0/D1 | 7 | ~ |
// | UART2 | USART6 | APB2(84 MHz) | D5/D6 | 8 | ~ |
// | UART3 | USART1 | APB2(84 MHz) | D14/D15 | 7 | ~ |
// | --------- | -------- | ------------ | ---------- | ----- | ----- |
// | UART0 | USART3 | APB1(42 MHz) | D0/D1 | 7 | UART1 |
// #===========#==========#==============#============#=======#=======#
NUM_UART_INTERFACES = 3
UART1_RX_PIN = D0 // UART1 = hardware: USART3
UART1_TX_PIN = D1 //
UART2_RX_PIN = D5 // UART2 = hardware: USART6
UART2_TX_PIN = D6 //
UART3_RX_PIN = D14 // UART3 = hardware: USART1
UART3_TX_PIN = D15 //
UART0_RX_PIN = UART1_RX_PIN // UART0 = alias: UART1
UART0_TX_PIN = UART1_TX_PIN //
UART_RX_PIN = UART0_RX_PIN // default/primary UART pins
UART_TX_PIN = UART0_TX_PIN //
)
var (
UART1 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART3,
AltFuncSelector: stm32.AF7_USART1_2_3,
}
UART2 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART6,
AltFuncSelector: stm32.AF8_USART4_5_6,
}
UART3 = UART{
Buffer: NewRingBuffer(),
Bus: stm32.USART1,
AltFuncSelector: stm32.AF7_USART1_2_3,
}
UART0 = UART1
)
func initUART() {
UART1.Interrupt = interrupt.New(stm32.IRQ_USART3, UART1.handleInterrupt)
UART2.Interrupt = interrupt.New(stm32.IRQ_USART6, UART2.handleInterrupt)
UART3.Interrupt = interrupt.New(stm32.IRQ_USART1, UART3.handleInterrupt)
}
// -- SPI ----------------------------------------------------------------------
const (
// #===========#==========#==============#==================#=======#=======#
// | Interface | Hardware | Bus(Freq) | SCK/SDI/SDO Pins | AltFn | Alias |
// #===========#==========#==============#==================#=======#=======#
// | SPI1 | SPI2 | APB1(42 MHz) | D23/D24/D25 | 5 | ~ |
// | SPI2 | SPI3 | APB1(42 MHz) | D2/D3/D4 | 6 | ~ |
// | SPI3 | SPI1 | APB2(84 MHz) | D17/D18/D19 | 5 | ~ |
// | --------- | -------- | ------------ | ---------------- | ----- | ----- |
// | SPI0 | SPI2 | APB1(42 MHz) | D23/D24/D25 | 5 | SPI1 |
// #===========#==========#==============#==================#=======#=======#
NUM_SPI_INTERFACES = 3
SPI1_SCK_PIN = D23 //
SPI1_SDI_PIN = D24 // SPI1 = hardware: SPI2
SPI1_SDO_PIN = D25 //
SPI2_SCK_PIN = D2 //
SPI2_SDI_PIN = D3 // SPI2 = hardware: SPI3
SPI2_SDO_PIN = D4 //
SPI3_SCK_PIN = D17 //
SPI3_SDI_PIN = D18 // SPI3 = hardware: SPI1
SPI3_SDO_PIN = D19 //
SPI0_SCK_PIN = SPI1_SCK_PIN //
SPI0_SDI_PIN = SPI1_SDI_PIN // SPI0 = alias: SPI1
SPI0_SDO_PIN = SPI1_SDO_PIN //
SPI_SCK_PIN = SPI0_SCK_PIN //
SPI_SDI_PIN = SPI0_SDI_PIN // default/primary SPI pins
SPI_SDO_PIN = SPI0_SDO_PIN //
)
var (
SPI1 = SPI{
Bus: stm32.SPI2,
AltFuncSelector: stm32.AF5_SPI1_SPI2,
}
SPI2 = SPI{
Bus: stm32.SPI3,
AltFuncSelector: stm32.AF6_SPI3,
}
SPI3 = SPI{
Bus: stm32.SPI1,
AltFuncSelector: stm32.AF5_SPI1_SPI2,
}
SPI0 = SPI1
)
func initSPI() {}
// -- I2C ----------------------------------------------------------------------
const (
// #===========#==========#==============#==============#=======#=======#
// | Interface | Hardware | Bus(Freq) | SDA/SCL Pins | AltFn | Alias |
// #===========#==========#==============#==============#=======#=======#
// | I2C1 | I2C1 | APB1(42 MHz) | D14/D15 | 4 | ~ |
// | I2C2 | I2C2 | APB1(42 MHz) | D0/D1 | 4 | ~ |
// | I2C3 | I2C1 | APB1(42 MHz) | D9/D10 | 4 | ~ |
// | --------- | -------- | ------------ | ------------ | ----- | ----- |
// | I2C0 | I2C1 | APB1(42 MHz) | D14/D15 | 4 | I2C1 |
// #===========#==========#==============#==============#=======#=======#
NUM_I2C_INTERFACES = 3
I2C1_SDA_PIN = D14 // I2C1 = hardware: I2C1
I2C1_SCL_PIN = D15 //
I2C2_SDA_PIN = D0 // I2C2 = hardware: I2C2
I2C2_SCL_PIN = D1 //
I2C3_SDA_PIN = D9 // I2C3 = hardware: I2C1
I2C3_SCL_PIN = D10 // (interface duplicated on second pair of pins)
I2C0_SDA_PIN = I2C1_SDA_PIN // I2C0 = alias: I2C1
I2C0_SCL_PIN = I2C1_SCL_PIN //
I2C_SDA_PIN = I2C0_SDA_PIN // default/primary I2C pins
I2C_SCL_PIN = I2C0_SCL_PIN //
)
var (
I2C1 = I2C{
Bus: stm32.I2C1,
AltFuncSelector: stm32.AF4_I2C1_2_3,
}
I2C2 = I2C{
Bus: stm32.I2C2,
AltFuncSelector: stm32.AF4_I2C1_2_3,
}
I2C3 = I2C{
Bus: stm32.I2C1,
AltFuncSelector: stm32.AF4_I2C1_2_3,
}
I2C0 = I2C1
)
func initI2C() {}
+6 -6
View File
@@ -43,13 +43,13 @@ const (
// SPI pins
const (
SPI0_SCK_PIN = NoPin
SPI0_MOSI_PIN = NoPin
SPI0_MISO_PIN = NoPin
SPI0_SCK_PIN = NoPin
SPI0_SDO_PIN = NoPin
SPI0_SDI_PIN = NoPin
SPI1_SCK_PIN = D13
SPI1_MOSI_PIN = D11
SPI1_MISO_PIN = D12
SPI1_SCK_PIN = D13
SPI1_SDO_PIN = D11
SPI1_SDI_PIN = D12
)
// I2C pins
+7 -7
View File
@@ -83,9 +83,9 @@ var (
// SPI pins
const (
SPI0_SCK_PIN = PB11 // SCK: SERCOM4/PAD[3]
SPI0_MOSI_PIN = PB10 // MOSI: SERCOM4/PAD[2]
SPI0_MISO_PIN = PA12 // MISO: SERCOM4/PAD[0]
SPI0_SCK_PIN = PB11 // SCK: SERCOM4/PAD[3]
SPI0_SDO_PIN = PB10 // SDO: SERCOM4/PAD[2]
SPI0_SDI_PIN = PA12 // SDI: SERCOM4/PAD[0]
)
// SPI on the ItsyBitsy M0.
@@ -98,10 +98,10 @@ var (
// "Internal" SPI pins; SPI flash is attached to these on ItsyBitsy M0
const (
SPI1_CS_PIN = PA27
SPI1_SCK_PIN = PB23
SPI1_MOSI_PIN = PB22
SPI1_MISO_PIN = PB03
SPI1_CS_PIN = PA27
SPI1_SCK_PIN = PB23
SPI1_SDO_PIN = PB22
SPI1_SDI_PIN = PB03
)
// "Internal" SPI on Sercom 5
+3 -3
View File
@@ -62,9 +62,9 @@ const (
// SPI pins
const (
SPI0_SCK_PIN = PA01 // SCK: SERCOM1/PAD[1]
SPI0_MOSI_PIN = PA00 // MOSI: SERCOM1/PAD[0]
SPI0_MISO_PIN = PB23 // MISO: SERCOM1/PAD[3]
SPI0_SCK_PIN = PA01 // SCK: SERCOM1/PAD[1]
SPI0_SDO_PIN = PA00 // SDO: SERCOM1/PAD[0]
SPI0_SDI_PIN = PB23 // SDI: SERCOM1/PAD[3]
)
// USB CDC identifiers
+100
View File
@@ -0,0 +1,100 @@
// +build itsybitsy_nrf52840
package machine
const HasLowFrequencyCrystal = true
// GPIO Pins
const (
D0 = P0_25 // UART TX
D1 = P0_24 // UART RX
D2 = P1_02
D3 = P0_06 // LED1
D4 = P0_29 // Button
D5 = P0_27
D6 = P1_09 // DotStar Clock
D7 = P1_08
D8 = P0_08 // DotStar Data
D9 = P0_07
D10 = P0_05
D11 = P0_26
D12 = P0_11
D13 = P0_12
D14 = P0_04 // A0
D15 = P0_30 // A1
D16 = P0_28 // A2
D17 = P0_31 // A3
D18 = P0_02 // A4
D19 = P0_03 // A5
D20 = P0_05 // A6
D21 = P0_16 // I2C SDA
D22 = P0_14 // I2C SCL
D23 = P0_20 // SPI SDI
D24 = P0_15 // SPI SDO
D25 = P0_13 // SPI SCK
D26 = P0_19 // QSPI SCK
D27 = P0_23 // QSPI CS
D28 = P0_21 // QSPI Data 0
D29 = P0_22 // QSPI Data 1
D30 = P1_00 // QSPI Data 2
D31 = P0_17 // QSPI Data 3
)
// Analog Pins
const (
A0 = D14
A1 = D15
A2 = D16
A3 = D17
A4 = D18
A5 = D19
A6 = D20
)
const (
LED = D3
LED1 = LED
BUTTON = D4
QSPI_SCK = D26
QSPI_CS = D27
QSPI_DATA0 = D28
QSPI_DATA1 = D29
QSPI_DATA2 = D30
QSPI_DATA3 = D31
)
// UART0 pins (logical UART1)
const (
UART_RX_PIN = D0
UART_TX_PIN = D1
)
// UART0 is the USB device
var (
UART0 = USB
)
// I2C pins
const (
SDA_PIN = D21 // I2C0 external
SCL_PIN = D22 // I2C0 external
)
// SPI pins
const (
SPI0_SCK_PIN = D25
SPI0_SDO_PIN = D24
SPI0_SDI_PIN = D23
)
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "Adafruit ItsyBitsy nRF52840 Express"
usb_STRING_MANUFACTURER = "Adafruit"
)
var (
usb_VID uint16 = 0x239A
usb_PID uint16 = 0x8051
)
+354
View File
@@ -0,0 +1,354 @@
// +build maixbit
// Chip datasheet: https://s3.cn-north-1.amazonaws.com.cn/dl.kendryte.com/documents/kendryte_datasheet_20181011163248_en.pdf
package machine
// K210 IO pins.
const (
P00 Pin = 0
P01 Pin = 1
P02 Pin = 2
P03 Pin = 3
P04 Pin = 4
P05 Pin = 5
P06 Pin = 6
P07 Pin = 7
P08 Pin = 8
P09 Pin = 9
P10 Pin = 10
P11 Pin = 11
P12 Pin = 12
P13 Pin = 13
P14 Pin = 14
P15 Pin = 15
P16 Pin = 16
P17 Pin = 17
P18 Pin = 18
P19 Pin = 19
P20 Pin = 20
P21 Pin = 21
P22 Pin = 22
P23 Pin = 23
P24 Pin = 24
P25 Pin = 25
P26 Pin = 26
P27 Pin = 27
P28 Pin = 28
P29 Pin = 29
P30 Pin = 30
P31 Pin = 31
P32 Pin = 32
P33 Pin = 33
P34 Pin = 34
P35 Pin = 35
P36 Pin = 36
P37 Pin = 37
P38 Pin = 38
P39 Pin = 39
P40 Pin = 40
P41 Pin = 41
P42 Pin = 42
P43 Pin = 43
P44 Pin = 44
P45 Pin = 45
P46 Pin = 46
P47 Pin = 47
)
type FPIOAFunction uint8
// Every pin on the Kendryte K210 is assigned to an FPIOA function.
// Each pin can be configured with every function below.
const (
FUNC_JTAG_TCLK FPIOAFunction = 0 // JTAG Test Clock
FUNC_JTAG_TDI FPIOAFunction = 1 // JTAG Test Data In
FUNC_JTAG_TMS FPIOAFunction = 2 // JTAG Test Mode Select
FUNC_JTAG_TDO FPIOAFunction = 3 // JTAG Test Data Out
FUNC_SPI0_D0 FPIOAFunction = 4 // SPI0 Data 0
FUNC_SPI0_D1 FPIOAFunction = 5 // SPI0 Data 1
FUNC_SPI0_D2 FPIOAFunction = 6 // SPI0 Data 2
FUNC_SPI0_D3 FPIOAFunction = 7 // SPI0 Data 3
FUNC_SPI0_D4 FPIOAFunction = 8 // SPI0 Data 4
FUNC_SPI0_D5 FPIOAFunction = 9 // SPI0 Data 5
FUNC_SPI0_D6 FPIOAFunction = 10 // SPI0 Data 6
FUNC_SPI0_D7 FPIOAFunction = 11 // SPI0 Data 7
FUNC_SPI0_SS0 FPIOAFunction = 12 // SPI0 Chip Select 0
FUNC_SPI0_SS1 FPIOAFunction = 13 // SPI0 Chip Select 1
FUNC_SPI0_SS2 FPIOAFunction = 14 // SPI0 Chip Select 2
FUNC_SPI0_SS3 FPIOAFunction = 15 // SPI0 Chip Select 3
FUNC_SPI0_ARB FPIOAFunction = 16 // SPI0 Arbitration
FUNC_SPI0_SCLK FPIOAFunction = 17 // SPI0 Serial Clock
FUNC_UARTHS_RX FPIOAFunction = 18 // UART High speed Receiver
FUNC_UARTHS_TX FPIOAFunction = 19 // UART High speed Transmitter
FUNC_RESV6 FPIOAFunction = 20 // Reserved function
FUNC_RESV7 FPIOAFunction = 21 // Reserved function
FUNC_CLK_SPI1 FPIOAFunction = 22 // Clock SPI1
FUNC_CLK_I2C1 FPIOAFunction = 23 // Clock I2C1
FUNC_GPIOHS0 FPIOAFunction = 24 // GPIO High speed 0
FUNC_GPIOHS1 FPIOAFunction = 25 // GPIO High speed 1
FUNC_GPIOHS2 FPIOAFunction = 26 // GPIO High speed 2
FUNC_GPIOHS3 FPIOAFunction = 27 // GPIO High speed 3
FUNC_GPIOHS4 FPIOAFunction = 28 // GPIO High speed 4
FUNC_GPIOHS5 FPIOAFunction = 29 // GPIO High speed 5
FUNC_GPIOHS6 FPIOAFunction = 30 // GPIO High speed 6
FUNC_GPIOHS7 FPIOAFunction = 31 // GPIO High speed 7
FUNC_GPIOHS8 FPIOAFunction = 32 // GPIO High speed 8
FUNC_GPIOHS9 FPIOAFunction = 33 // GPIO High speed 9
FUNC_GPIOHS10 FPIOAFunction = 34 // GPIO High speed 10
FUNC_GPIOHS11 FPIOAFunction = 35 // GPIO High speed 11
FUNC_GPIOHS12 FPIOAFunction = 36 // GPIO High speed 12
FUNC_GPIOHS13 FPIOAFunction = 37 // GPIO High speed 13
FUNC_GPIOHS14 FPIOAFunction = 38 // GPIO High speed 14
FUNC_GPIOHS15 FPIOAFunction = 39 // GPIO High speed 15
FUNC_GPIOHS16 FPIOAFunction = 40 // GPIO High speed 16
FUNC_GPIOHS17 FPIOAFunction = 41 // GPIO High speed 17
FUNC_GPIOHS18 FPIOAFunction = 42 // GPIO High speed 18
FUNC_GPIOHS19 FPIOAFunction = 43 // GPIO High speed 19
FUNC_GPIOHS20 FPIOAFunction = 44 // GPIO High speed 20
FUNC_GPIOHS21 FPIOAFunction = 45 // GPIO High speed 21
FUNC_GPIOHS22 FPIOAFunction = 46 // GPIO High speed 22
FUNC_GPIOHS23 FPIOAFunction = 47 // GPIO High speed 23
FUNC_GPIOHS24 FPIOAFunction = 48 // GPIO High speed 24
FUNC_GPIOHS25 FPIOAFunction = 49 // GPIO High speed 25
FUNC_GPIOHS26 FPIOAFunction = 50 // GPIO High speed 26
FUNC_GPIOHS27 FPIOAFunction = 51 // GPIO High speed 27
FUNC_GPIOHS28 FPIOAFunction = 52 // GPIO High speed 28
FUNC_GPIOHS29 FPIOAFunction = 53 // GPIO High speed 29
FUNC_GPIOHS30 FPIOAFunction = 54 // GPIO High speed 30
FUNC_GPIOHS31 FPIOAFunction = 55 // GPIO High speed 31
FUNC_GPIO0 FPIOAFunction = 56 // GPIO pin 0
FUNC_GPIO1 FPIOAFunction = 57 // GPIO pin 1
FUNC_GPIO2 FPIOAFunction = 58 // GPIO pin 2
FUNC_GPIO3 FPIOAFunction = 59 // GPIO pin 3
FUNC_GPIO4 FPIOAFunction = 60 // GPIO pin 4
FUNC_GPIO5 FPIOAFunction = 61 // GPIO pin 5
FUNC_GPIO6 FPIOAFunction = 62 // GPIO pin 6
FUNC_GPIO7 FPIOAFunction = 63 // GPIO pin 7
FUNC_UART1_RX FPIOAFunction = 64 // UART1 Receiver
FUNC_UART1_TX FPIOAFunction = 65 // UART1 Transmitter
FUNC_UART2_RX FPIOAFunction = 66 // UART2 Receiver
FUNC_UART2_TX FPIOAFunction = 67 // UART2 Transmitter
FUNC_UART3_RX FPIOAFunction = 68 // UART3 Receiver
FUNC_UART3_TX FPIOAFunction = 69 // UART3 Transmitter
FUNC_SPI1_D0 FPIOAFunction = 70 // SPI1 Data 0
FUNC_SPI1_D1 FPIOAFunction = 71 // SPI1 Data 1
FUNC_SPI1_D2 FPIOAFunction = 72 // SPI1 Data 2
FUNC_SPI1_D3 FPIOAFunction = 73 // SPI1 Data 3
FUNC_SPI1_D4 FPIOAFunction = 74 // SPI1 Data 4
FUNC_SPI1_D5 FPIOAFunction = 75 // SPI1 Data 5
FUNC_SPI1_D6 FPIOAFunction = 76 // SPI1 Data 6
FUNC_SPI1_D7 FPIOAFunction = 77 // SPI1 Data 7
FUNC_SPI1_SS0 FPIOAFunction = 78 // SPI1 Chip Select 0
FUNC_SPI1_SS1 FPIOAFunction = 79 // SPI1 Chip Select 1
FUNC_SPI1_SS2 FPIOAFunction = 80 // SPI1 Chip Select 2
FUNC_SPI1_SS3 FPIOAFunction = 81 // SPI1 Chip Select 3
FUNC_SPI1_ARB FPIOAFunction = 82 // SPI1 Arbitration
FUNC_SPI1_SCLK FPIOAFunction = 83 // SPI1 Serial Clock
FUNC_SPI_PERIPHERAL_D0 FPIOAFunction = 84 // SPI Peripheral Data 0
FUNC_SPI_PERIPHERAL_SS FPIOAFunction = 85 // SPI Peripheral Select
FUNC_SPI_PERIPHERAL_SCLK FPIOAFunction = 86 // SPI Peripheral Serial Clock
FUNC_I2S0_MCLK FPIOAFunction = 87 // I2S0 Main Clock
FUNC_I2S0_SCLK FPIOAFunction = 88 // I2S0 Serial Clock(BCLK)
FUNC_I2S0_WS FPIOAFunction = 89 // I2S0 Word Select(LRCLK)
FUNC_I2S0_IN_D0 FPIOAFunction = 90 // I2S0 Serial Data Input 0
FUNC_I2S0_IN_D1 FPIOAFunction = 91 // I2S0 Serial Data Input 1
FUNC_I2S0_IN_D2 FPIOAFunction = 92 // I2S0 Serial Data Input 2
FUNC_I2S0_IN_D3 FPIOAFunction = 93 // I2S0 Serial Data Input 3
FUNC_I2S0_OUT_D0 FPIOAFunction = 94 // I2S0 Serial Data Output 0
FUNC_I2S0_OUT_D1 FPIOAFunction = 95 // I2S0 Serial Data Output 1
FUNC_I2S0_OUT_D2 FPIOAFunction = 96 // I2S0 Serial Data Output 2
FUNC_I2S0_OUT_D3 FPIOAFunction = 97 // I2S0 Serial Data Output 3
FUNC_I2S1_MCLK FPIOAFunction = 98 // I2S1 Main Clock
FUNC_I2S1_SCLK FPIOAFunction = 99 // I2S1 Serial Clock(BCLK)
FUNC_I2S1_WS FPIOAFunction = 100 // I2S1 Word Select(LRCLK)
FUNC_I2S1_IN_D0 FPIOAFunction = 101 // I2S1 Serial Data Input 0
FUNC_I2S1_IN_D1 FPIOAFunction = 102 // I2S1 Serial Data Input 1
FUNC_I2S1_IN_D2 FPIOAFunction = 103 // I2S1 Serial Data Input 2
FUNC_I2S1_IN_D3 FPIOAFunction = 104 // I2S1 Serial Data Input 3
FUNC_I2S1_OUT_D0 FPIOAFunction = 105 // I2S1 Serial Data Output 0
FUNC_I2S1_OUT_D1 FPIOAFunction = 106 // I2S1 Serial Data Output 1
FUNC_I2S1_OUT_D2 FPIOAFunction = 107 // I2S1 Serial Data Output 2
FUNC_I2S1_OUT_D3 FPIOAFunction = 108 // I2S1 Serial Data Output 3
FUNC_I2S2_MCLK FPIOAFunction = 109 // I2S2 Main Clock
FUNC_I2S2_SCLK FPIOAFunction = 110 // I2S2 Serial Clock(BCLK)
FUNC_I2S2_WS FPIOAFunction = 111 // I2S2 Word Select(LRCLK)
FUNC_I2S2_IN_D0 FPIOAFunction = 112 // I2S2 Serial Data Input 0
FUNC_I2S2_IN_D1 FPIOAFunction = 113 // I2S2 Serial Data Input 1
FUNC_I2S2_IN_D2 FPIOAFunction = 114 // I2S2 Serial Data Input 2
FUNC_I2S2_IN_D3 FPIOAFunction = 115 // I2S2 Serial Data Input 3
FUNC_I2S2_OUT_D0 FPIOAFunction = 116 // I2S2 Serial Data Output 0
FUNC_I2S2_OUT_D1 FPIOAFunction = 117 // I2S2 Serial Data Output 1
FUNC_I2S2_OUT_D2 FPIOAFunction = 118 // I2S2 Serial Data Output 2
FUNC_I2S2_OUT_D3 FPIOAFunction = 119 // I2S2 Serial Data Output 3
FUNC_RESV0 FPIOAFunction = 120 // Reserved function
FUNC_RESV1 FPIOAFunction = 121 // Reserved function
FUNC_RESV2 FPIOAFunction = 122 // Reserved function
FUNC_RESV3 FPIOAFunction = 123 // Reserved function
FUNC_RESV4 FPIOAFunction = 124 // Reserved function
FUNC_RESV5 FPIOAFunction = 125 // Reserved function
FUNC_I2C0_SCLK FPIOAFunction = 126 // I2C0 Serial Clock
FUNC_I2C0_SDA FPIOAFunction = 127 // I2C0 Serial Data
FUNC_I2C1_SCLK FPIOAFunction = 128 // I2C1 Serial Clock
FUNC_I2C1_SDA FPIOAFunction = 129 // I2C1 Serial Data
FUNC_I2C2_SCLK FPIOAFunction = 130 // I2C2 Serial Clock
FUNC_I2C2_SDA FPIOAFunction = 131 // I2C2 Serial Data
FUNC_CMOS_XCLK FPIOAFunction = 132 // DVP System Clock
FUNC_CMOS_RST FPIOAFunction = 133 // DVP System Reset
FUNC_CMOS_PWDN FPIOAFunction = 134 // DVP Power Down Mode
FUNC_CMOS_VSYNC FPIOAFunction = 135 // DVP Vertical Sync
FUNC_CMOS_HREF FPIOAFunction = 136 // DVP Horizontal Reference output
FUNC_CMOS_PCLK FPIOAFunction = 137 // Pixel Clock
FUNC_CMOS_D0 FPIOAFunction = 138 // Data Bit 0
FUNC_CMOS_D1 FPIOAFunction = 139 // Data Bit 1
FUNC_CMOS_D2 FPIOAFunction = 140 // Data Bit 2
FUNC_CMOS_D3 FPIOAFunction = 141 // Data Bit 3
FUNC_CMOS_D4 FPIOAFunction = 142 // Data Bit 4
FUNC_CMOS_D5 FPIOAFunction = 143 // Data Bit 5
FUNC_CMOS_D6 FPIOAFunction = 144 // Data Bit 6
FUNC_CMOS_D7 FPIOAFunction = 145 // Data Bit 7
FUNC_SCCB_SCLK FPIOAFunction = 146 // SCCB Serial Clock
FUNC_SCCB_SDA FPIOAFunction = 147 // SCCB Serial Data
FUNC_UART1_CTS FPIOAFunction = 148 // UART1 Clear To Send
FUNC_UART1_DSR FPIOAFunction = 149 // UART1 Data Set Ready
FUNC_UART1_DCD FPIOAFunction = 150 // UART1 Data Carrier Detect
FUNC_UART1_RI FPIOAFunction = 151 // UART1 Ring Indicator
FUNC_UART1_SIR_IN FPIOAFunction = 152 // UART1 Serial Infrared Input
FUNC_UART1_DTR FPIOAFunction = 153 // UART1 Data Terminal Ready
FUNC_UART1_RTS FPIOAFunction = 154 // UART1 Request To Send
FUNC_UART1_OUT2 FPIOAFunction = 155 // UART1 User-designated Output 2
FUNC_UART1_OUT1 FPIOAFunction = 156 // UART1 User-designated Output 1
FUNC_UART1_SIR_OUT FPIOAFunction = 157 // UART1 Serial Infrared Output
FUNC_UART1_BAUD FPIOAFunction = 158 // UART1 Transmit Clock Output
FUNC_UART1_RE FPIOAFunction = 159 // UART1 Receiver Output Enable
FUNC_UART1_DE FPIOAFunction = 160 // UART1 Driver Output Enable
FUNC_UART1_RS485_EN FPIOAFunction = 161 // UART1 RS485 Enable
FUNC_UART2_CTS FPIOAFunction = 162 // UART2 Clear To Send
FUNC_UART2_DSR FPIOAFunction = 163 // UART2 Data Set Ready
FUNC_UART2_DCD FPIOAFunction = 164 // UART2 Data Carrier Detect
FUNC_UART2_RI FPIOAFunction = 165 // UART2 Ring Indicator
FUNC_UART2_SIR_IN FPIOAFunction = 166 // UART2 Serial Infrared Input
FUNC_UART2_DTR FPIOAFunction = 167 // UART2 Data Terminal Ready
FUNC_UART2_RTS FPIOAFunction = 168 // UART2 Request To Send
FUNC_UART2_OUT2 FPIOAFunction = 169 // UART2 User-designated Output 2
FUNC_UART2_OUT1 FPIOAFunction = 170 // UART2 User-designated Output 1
FUNC_UART2_SIR_OUT FPIOAFunction = 171 // UART2 Serial Infrared Output
FUNC_UART2_BAUD FPIOAFunction = 172 // UART2 Transmit Clock Output
FUNC_UART2_RE FPIOAFunction = 173 // UART2 Receiver Output Enable
FUNC_UART2_DE FPIOAFunction = 174 // UART2 Driver Output Enable
FUNC_UART2_RS485_EN FPIOAFunction = 175 // UART2 RS485 Enable
FUNC_UART3_CTS FPIOAFunction = 176 // UART3 Clear To Send
FUNC_UART3_DSR FPIOAFunction = 177 // UART3 Data Set Ready
FUNC_UART3_DCD FPIOAFunction = 178 // UART3 Data Carrier Detect
FUNC_UART3_RI FPIOAFunction = 179 // UART3 Ring Indicator
FUNC_UART3_SIR_IN FPIOAFunction = 180 // UART3 Serial Infrared Input
FUNC_UART3_DTR FPIOAFunction = 181 // UART3 Data Terminal Ready
FUNC_UART3_RTS FPIOAFunction = 182 // UART3 Request To Send
FUNC_UART3_OUT2 FPIOAFunction = 183 // UART3 User-designated Output 2
FUNC_UART3_OUT1 FPIOAFunction = 184 // UART3 User-designated Output 1
FUNC_UART3_SIR_OUT FPIOAFunction = 185 // UART3 Serial Infrared Output
FUNC_UART3_BAUD FPIOAFunction = 186 // UART3 Transmit Clock Output
FUNC_UART3_RE FPIOAFunction = 187 // UART3 Receiver Output Enable
FUNC_UART3_DE FPIOAFunction = 188 // UART3 Driver Output Enable
FUNC_UART3_RS485_EN FPIOAFunction = 189 // UART3 RS485 Enable
FUNC_TIMER0_TOGGLE1 FPIOAFunction = 190 // TIMER0 Toggle Output 1
FUNC_TIMER0_TOGGLE2 FPIOAFunction = 191 // TIMER0 Toggle Output 2
FUNC_TIMER0_TOGGLE3 FPIOAFunction = 192 // TIMER0 Toggle Output 3
FUNC_TIMER0_TOGGLE4 FPIOAFunction = 193 // TIMER0 Toggle Output 4
FUNC_TIMER1_TOGGLE1 FPIOAFunction = 194 // TIMER1 Toggle Output 1
FUNC_TIMER1_TOGGLE2 FPIOAFunction = 195 // TIMER1 Toggle Output 2
FUNC_TIMER1_TOGGLE3 FPIOAFunction = 196 // TIMER1 Toggle Output 3
FUNC_TIMER1_TOGGLE4 FPIOAFunction = 197 // TIMER1 Toggle Output 4
FUNC_TIMER2_TOGGLE1 FPIOAFunction = 198 // TIMER2 Toggle Output 1
FUNC_TIMER2_TOGGLE2 FPIOAFunction = 199 // TIMER2 Toggle Output 2
FUNC_TIMER2_TOGGLE3 FPIOAFunction = 200 // TIMER2 Toggle Output 3
FUNC_TIMER2_TOGGLE4 FPIOAFunction = 201 // TIMER2 Toggle Output 4
FUNC_CLK_SPI2 FPIOAFunction = 202 // Clock SPI2
FUNC_CLK_I2C2 FPIOAFunction = 203 // Clock I2C2
FUNC_INTERNAL0 FPIOAFunction = 204 // Internal function signal 0
FUNC_INTERNAL1 FPIOAFunction = 205 // Internal function signal 1
FUNC_INTERNAL2 FPIOAFunction = 206 // Internal function signal 2
FUNC_INTERNAL3 FPIOAFunction = 207 // Internal function signal 3
FUNC_INTERNAL4 FPIOAFunction = 208 // Internal function signal 4
FUNC_INTERNAL5 FPIOAFunction = 209 // Internal function signal 5
FUNC_INTERNAL6 FPIOAFunction = 210 // Internal function signal 6
FUNC_INTERNAL7 FPIOAFunction = 211 // Internal function signal 7
FUNC_INTERNAL8 FPIOAFunction = 212 // Internal function signal 8
FUNC_INTERNAL9 FPIOAFunction = 213 // Internal function signal 9
FUNC_INTERNAL10 FPIOAFunction = 214 // Internal function signal 10
FUNC_INTERNAL11 FPIOAFunction = 215 // Internal function signal 11
FUNC_INTERNAL12 FPIOAFunction = 216 // Internal function signal 12
FUNC_INTERNAL13 FPIOAFunction = 217 // Internal function signal 13
FUNC_INTERNAL14 FPIOAFunction = 218 // Internal function signal 14
FUNC_INTERNAL15 FPIOAFunction = 219 // Internal function signal 15
FUNC_INTERNAL16 FPIOAFunction = 220 // Internal function signal 16
FUNC_INTERNAL17 FPIOAFunction = 221 // Internal function signal 17
FUNC_CONSTANT FPIOAFunction = 222 // Constant function
FUNC_INTERNAL18 FPIOAFunction = 223 // Internal function signal 18
FUNC_DEBUG0 FPIOAFunction = 224 // Debug function 0
FUNC_DEBUG1 FPIOAFunction = 225 // Debug function 1
FUNC_DEBUG2 FPIOAFunction = 226 // Debug function 2
FUNC_DEBUG3 FPIOAFunction = 227 // Debug function 3
FUNC_DEBUG4 FPIOAFunction = 228 // Debug function 4
FUNC_DEBUG5 FPIOAFunction = 229 // Debug function 5
FUNC_DEBUG6 FPIOAFunction = 230 // Debug function 6
FUNC_DEBUG7 FPIOAFunction = 231 // Debug function 7
FUNC_DEBUG8 FPIOAFunction = 232 // Debug function 8
FUNC_DEBUG9 FPIOAFunction = 233 // Debug function 9
FUNC_DEBUG10 FPIOAFunction = 234 // Debug function 10
FUNC_DEBUG11 FPIOAFunction = 235 // Debug function 11
FUNC_DEBUG12 FPIOAFunction = 236 // Debug function 12
FUNC_DEBUG13 FPIOAFunction = 237 // Debug function 13
FUNC_DEBUG14 FPIOAFunction = 238 // Debug function 14
FUNC_DEBUG15 FPIOAFunction = 239 // Debug function 15
FUNC_DEBUG16 FPIOAFunction = 240 // Debug function 16
FUNC_DEBUG17 FPIOAFunction = 241 // Debug function 17
FUNC_DEBUG18 FPIOAFunction = 242 // Debug function 18
FUNC_DEBUG19 FPIOAFunction = 243 // Debug function 19
FUNC_DEBUG20 FPIOAFunction = 244 // Debug function 20
FUNC_DEBUG21 FPIOAFunction = 245 // Debug function 21
FUNC_DEBUG22 FPIOAFunction = 246 // Debug function 22
FUNC_DEBUG23 FPIOAFunction = 247 // Debug function 23
FUNC_DEBUG24 FPIOAFunction = 248 // Debug function 24
FUNC_DEBUG25 FPIOAFunction = 249 // Debug function 25
FUNC_DEBUG26 FPIOAFunction = 250 // Debug function 26
FUNC_DEBUG27 FPIOAFunction = 251 // Debug function 27
FUNC_DEBUG28 FPIOAFunction = 252 // Debug function 28
FUNC_DEBUG29 FPIOAFunction = 253 // Debug function 29
FUNC_DEBUG30 FPIOAFunction = 254 // Debug function 30
FUNC_DEBUG31 FPIOAFunction = 255 // Debug function 31
)
// These are the default FPIOA values for each function.
// (source: https://github.com/kendryte/kendryte-standalone-sdk/blob/develop/lib/drivers/fpioa.c#L69)
var fpioaFuncDefaults [256]uint32 = [256]uint32{
0x00900000, 0x00900001, 0x00900002, 0x00001f03, 0x00b03f04, 0x00b03f05, 0x00b03f06, 0x00b03f07, 0x00b03f08,
0x00b03f09, 0x00b03f0a, 0x00b03f0b, 0x00001f0c, 0x00001f0d, 0x00001f0e, 0x00001f0f, 0x03900010, 0x00001f11,
0x00900012, 0x00001f13, 0x00900014, 0x00900015, 0x00001f16, 0x00001f17, 0x00901f18, 0x00901f19, 0x00901f1a,
0x00901f1b, 0x00901f1c, 0x00901f1d, 0x00901f1e, 0x00901f1f, 0x00901f20, 0x00901f21, 0x00901f22, 0x00901f23,
0x00901f24, 0x00901f25, 0x00901f26, 0x00901f27, 0x00901f28, 0x00901f29, 0x00901f2a, 0x00901f2b, 0x00901f2c,
0x00901f2d, 0x00901f2e, 0x00901f2f, 0x00901f30, 0x00901f31, 0x00901f32, 0x00901f33, 0x00901f34, 0x00901f35,
0x00901f36, 0x00901f37, 0x00901f38, 0x00901f39, 0x00901f3a, 0x00901f3b, 0x00901f3c, 0x00901f3d, 0x00901f3e,
0x00901f3f, 0x00900040, 0x00001f41, 0x00900042, 0x00001f43, 0x00900044, 0x00001f45, 0x00b03f46, 0x00b03f47,
0x00b03f48, 0x00b03f49, 0x00b03f4a, 0x00b03f4b, 0x00b03f4c, 0x00b03f4d, 0x00001f4e, 0x00001f4f, 0x00001f50,
0x00001f51, 0x03900052, 0x00001f53, 0x00b03f54, 0x00900055, 0x00900056, 0x00001f57, 0x00001f58, 0x00001f59,
0x0090005a, 0x0090005b, 0x0090005c, 0x0090005d, 0x00001f5e, 0x00001f5f, 0x00001f60, 0x00001f61, 0x00001f62,
0x00001f63, 0x00001f64, 0x00900065, 0x00900066, 0x00900067, 0x00900068, 0x00001f69, 0x00001f6a, 0x00001f6b,
0x00001f6c, 0x00001f6d, 0x00001f6e, 0x00001f6f, 0x00900070, 0x00900071, 0x00900072, 0x00900073, 0x00001f74,
0x00001f75, 0x00001f76, 0x00001f77, 0x00000078, 0x00000079, 0x0000007a, 0x0000007b, 0x0000007c, 0x0000007d,
0x0099107e, 0x0099107f, 0x00991080, 0x00991081, 0x00991082, 0x00991083, 0x00001f84, 0x00001f85, 0x00001f86,
0x00900087, 0x00900088, 0x00900089, 0x0090008a, 0x0090008b, 0x0090008c, 0x0090008d, 0x0090008e, 0x0090008f,
0x00900090, 0x00900091, 0x00993092, 0x00993093, 0x00900094, 0x00900095, 0x00900096, 0x00900097, 0x00900098,
0x00001f99, 0x00001f9a, 0x00001f9b, 0x00001f9c, 0x00001f9d, 0x00001f9e, 0x00001f9f, 0x00001fa0, 0x00001fa1,
0x009000a2, 0x009000a3, 0x009000a4, 0x009000a5, 0x009000a6, 0x00001fa7, 0x00001fa8, 0x00001fa9, 0x00001faa,
0x00001fab, 0x00001fac, 0x00001fad, 0x00001fae, 0x00001faf, 0x009000b0, 0x009000b1, 0x009000b2, 0x009000b3,
0x009000b4, 0x00001fb5, 0x00001fb6, 0x00001fb7, 0x00001fb8, 0x00001fb9, 0x00001fba, 0x00001fbb, 0x00001fbc,
0x00001fbd, 0x00001fbe, 0x00001fbf, 0x00001fc0, 0x00001fc1, 0x00001fc2, 0x00001fc3, 0x00001fc4, 0x00001fc5,
0x00001fc6, 0x00001fc7, 0x00001fc8, 0x00001fc9, 0x00001fca, 0x00001fcb, 0x00001fcc, 0x00001fcd, 0x00001fce,
0x00001fcf, 0x00001fd0, 0x00001fd1, 0x00001fd2, 0x00001fd3, 0x00001fd4, 0x009000d5, 0x009000d6, 0x009000d7,
0x009000d8, 0x009100d9, 0x00991fda, 0x009000db, 0x009000dc, 0x009000dd, 0x000000de, 0x009000df, 0x00001fe0,
0x00001fe1, 0x00001fe2, 0x00001fe3, 0x00001fe4, 0x00001fe5, 0x00001fe6, 0x00001fe7, 0x00001fe8, 0x00001fe9,
0x00001fea, 0x00001feb, 0x00001fec, 0x00001fed, 0x00001fee, 0x00001fef, 0x00001ff0, 0x00001ff1, 0x00001ff2,
0x00001ff3, 0x00001ff4, 0x00001ff5, 0x00001ff6, 0x00001ff7, 0x00001ff8, 0x00001ff9, 0x00001ffa, 0x00001ffb,
0x00001ffc, 0x00001ffd, 0x00001ffe, 0x00001fff,
}
+72
View File
@@ -0,0 +1,72 @@
// +build maixbit
package machine
// Pins on the MAix Bit.
const (
D0 = P00 // JTAG_TCLK
D1 = P01 // JTAG_TDI
D2 = P02 // JTAG_TMS
D3 = P03 // JTAG_TDO
D4 = P04 // UARTHS_RX
D5 = P05 // UARTHS_TX
D6 = P06 // RESV0
D7 = P07 // RESV0
D8 = P08 // GPIO1
D9 = P09 // GPIO2
D10 = P10 // GPIO3
D11 = P11 // GPIO4
D12 = P12 // GPIO5
D13 = P13 // GPIO6
D14 = P14 // GPIO7
D15 = P15 // GPIO8
D16 = P16 // GPIOHS0
D17 = P17 // GPIOHS1
D18 = P18 // GPIOHS2
D19 = P19 // GPIOHS3
D20 = P20 // GPIOHS4
D21 = P21 // GPIOHS5
D22 = P22 // GPIOHS6
D23 = P23 // GPIOHS7
D24 = P24 // GPIOHS8
D25 = P25 // GPIOHS9
D26 = P26 // GPIOHS10 / SPI0_SDI
D27 = P27 // GPIOHS11 / SPI0_SCLK
D28 = P28 // GPIOHS12 / SPI0_SDO
D29 = P29 // GPIOHS13
D30 = P30 // GPIOHS14
D31 = P31 // GPIOHS15
D32 = P32 // GPIOHS16
D33 = P33 // GPIOHS17
D34 = P34 // GPIOHS18
D35 = P35 // GPIOHS19
)
const (
LED = LED1
LED1 = LED_RED
LED2 = LED_GREEN
LED3 = LED_BLUE
LED_RED = D13
LED_GREEN = D12
LED_BLUE = D14
)
// Default pins for UARTHS.
const (
UART_TX_PIN = D5
UART_RX_PIN = D4
)
// SPI pins.
const (
SPI0_SCK_PIN = D27
SPI0_SDO_PIN = D28
SPI0_SDI_PIN = D26
)
// I2C pins.
const (
I2C0_SDA_PIN = D34
I2C0_SCL_PIN = D35
)
+28
View File
@@ -0,0 +1,28 @@
// +build k210,maixbit
package machine
import "device/kendryte"
// SPI on the MAix Bit.
var (
SPI0 = SPI{
Bus: kendryte.SPI0,
}
SPI1 = SPI{
Bus: kendryte.SPI1,
}
)
// I2C on the MAix Bit.
var (
I2C0 = I2C{
Bus: kendryte.I2C0,
}
I2C1 = I2C{
Bus: kendryte.I2C1,
}
I2C2 = I2C{
Bus: kendryte.I2C2,
}
)
+9 -9
View File
@@ -75,19 +75,19 @@ const (
// SPI pins
const (
SPI0_SCK_PIN = PA13 // SCK: SERCOM2/PAD[1]
SPI0_MOSI_PIN = PA12 // MOSI: SERCOM2/PAD[0]
SPI0_MISO_PIN = PA14 // MISO: SERCOM2/PAD[2]
SPI0_SCK_PIN = PA13 // SCK: SERCOM2/PAD[1]
SPI0_SDO_PIN = PA12 // SDO: SERCOM2/PAD[0]
SPI0_SDI_PIN = PA14 // SDI: SERCOM2/PAD[2]
NINA_MOSI = SPI0_MOSI_PIN
NINA_MISO = SPI0_MISO_PIN
NINA_SCK = SPI0_SCK_PIN
NINA_SDO = SPI0_SDO_PIN
NINA_SDI = SPI0_SDI_PIN
NINA_SCK = SPI0_SCK_PIN
)
const (
SPI1_SCK_PIN = D12 // MISO: SERCOM1/PAD[1]
SPI1_MOSI_PIN = D11 // MOSI: SERCOM1/PAD[3]
SPI1_MISO_PIN = D13 // SCK: SERCOM1/PAD[0]
SPI1_SCK_PIN = D12 // SDI: SERCOM1/PAD[1]
SPI1_SDO_PIN = D11 // SDO: SERCOM1/PAD[3]
SPI1_SDI_PIN = D13 // SCK: SERCOM1/PAD[0]
)
// USB CDC identifiers
+3 -3
View File
@@ -33,9 +33,9 @@ const (
// SPI pins
const (
SPI0_SCK_PIN Pin = 23 // P13 on the board
SPI0_MOSI_PIN Pin = 21 // P15 on the board
SPI0_MISO_PIN Pin = 22 // P14 on the board
SPI0_SCK_PIN Pin = 23 // P13 on the board
SPI0_SDO_PIN Pin = 21 // P15 on the board
SPI0_SDI_PIN Pin = 22 // P14 on the board
)
// GPIO/Analog pins
+35
View File
@@ -0,0 +1,35 @@
// +build nodemcu
// Pinout for the NodeMCU dev kit.
package machine
// GPIO pins on the NodeMCU board.
const (
D0 Pin = 16
D1 Pin = 5
D2 Pin = 4
D3 Pin = 0
D4 Pin = 2
D5 Pin = 14
D6 Pin = 12
D7 Pin = 13
D8 Pin = 15
)
// Onboard blue LED (on the AI-Thinker module).
const LED = D4
// SPI pins
const (
SPI0_SCK_PIN = D5
SPI0_SDO_PIN = D7
SPI0_SDI_PIN = D6
SPI0_CS0_PIN = D8
)
// I2C pins
const (
SDA_PIN = D2
SCL_PIN = D1
)
+3 -3
View File
@@ -31,9 +31,9 @@ const (
// SPI pins (unused)
const (
SPI0_SCK_PIN = NoPin
SPI0_MOSI_PIN = NoPin
SPI0_MISO_PIN = NoPin
SPI0_SCK_PIN = NoPin
SPI0_SDO_PIN = NoPin
SPI0_SDI_PIN = NoPin
)
// USB CDC identifiers
+3 -3
View File
@@ -113,9 +113,9 @@ func init() {
// SPI pins
const (
SPI0_SCK_PIN = PA5
SPI0_MISO_PIN = PA6
SPI0_MOSI_PIN = PA7
SPI0_SCK_PIN = PA5
SPI0_SDI_PIN = PA6
SPI0_SDO_PIN = PA7
)
// I2C pins
+7 -7
View File
@@ -34,8 +34,8 @@ const (
D8 Pin = 35
D9 Pin = 6 // Also TX
D10 Pin = 8 // Also RX
D11 Pin = 46 // Also MISO
D12 Pin = 45 // Also MOSI
D11 Pin = 46 // Also SDI
D12 Pin = 45 // Also SDO
D13 Pin = 47 // Also SCK
)
@@ -58,16 +58,16 @@ const (
// SPI pins
const (
SPI0_SCK_PIN Pin = 47
SPI0_MOSI_PIN Pin = 45
SPI0_MISO_PIN Pin = 46
SPI0_SCK_PIN Pin = 47
SPI0_SDO_PIN Pin = 45
SPI0_SDI_PIN Pin = 46
)
// Internal 4MB SPI Flash
const (
SPI1_SCK_PIN Pin = 19
SPI1_MOSI_PIN Pin = 20
SPI1_MISO_PIN Pin = 21
SPI1_SDO_PIN Pin = 20
SPI1_SDI_PIN Pin = 21
SPI1_CS_PIN Pin = 17
SPI1_WP_PIN Pin = 22
SPI1_HOLD_PIN Pin = 23

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