Rename the "arduino" target to "arduino-uno" to better reflect the
board it represents. The "arduino" name is kept as an alias that
inherits from "arduino-uno" for backward compatibility.
- Rename targets/arduino.json to targets/arduino-uno.json
- Create targets/arduino.json as alias inheriting from arduino-uno
- Rename board_arduino.go to board_arduino_uno.go
- Update build tag from "arduino" to "arduino_uno"
- Rename corresponding example files
Signed-off-by: deadprogram <ron@hybridgroup.com>
* reflect: implement method-set based AssignableTo and Implements
Based on the design from #4376 by aykevl.
Fixes#4277, fixes#3580.
Co-authored-by: Ayke van Laethem <aykevanlaethem@gmail.com>
* builder: update expected binary sizes for reflect changes
* Make interface checks similar to invoke, allowing typeImplementsMethodSet and method info to be dropped when reflect is not present
* Add more tests that BigGo reflect tests
* Even more pruning
* Add go/token and net/url to passing tests
* Prune even further, I am less happy with this, though
* Update size test now that we are smaller
* Skip some tests
* elide method lists
* format, oops
* fix tests
* Add a panic, pull out constant to keep in sync
* Add debug info
* Remove code that was leftover from a previous refactor
---------
Co-authored-by: Ayke van Laethem <aykevanlaethem@gmail.com>
* machine/attiny85: add USI-based SPI support
Implement SPI communication for ATTiny85 using the USI (Universal Serial
Interface) hardware in three-wire mode. The ATTiny85 lacks dedicated SPI
hardware but can emulate SPI using the USI module with software clock
strobing.
Implementation details:
- Configure USI in three-wire mode for SPI operation
- Use clock strobing technique to shift data in/out
- Pin mapping: PB2 (SCK), PB1 (MOSI/DO), PB0 (MISO/DI)
- Support both Transfer() and Tx() methods
The implementation uses the USI control register (USICR) to toggle the
clock pin, which triggers automatic bit shifting in hardware. This is
more efficient than pure software bit-banging.
Current limitations:
- Frequency configuration not yet implemented (runs at max software speed)
- Only SPI Mode 0 (CPOL=0, CPHA=0) supported
- Only MSB-first bit order supported
* machine/attiny85: add SPI frequency configuration support
Add software-based frequency control for USI SPI. The ATtiny85 USI lacks
hardware prescalers, so frequency is controlled via delay loops between
clock toggles.
- Calculate delay cycles based on requested frequency and CPU clock
- Fast path (no delay) when frequency is 0 or max speed requested
- Delay loop uses nop instructions for timing control
* machine/attiny85: add SPI mode configuration support
Add support for all 4 SPI modes (Mode 0-3) using USI hardware:
- Mode 0 (CPOL=0, CPHA=0): Clock idle low, sample on rising edge
- Mode 1 (CPOL=0, CPHA=1): Clock idle low, sample on falling edge
- Mode 2 (CPOL=1, CPHA=0): Clock idle high, sample on falling edge
- Mode 3 (CPOL=1, CPHA=1): Clock idle high, sample on rising edge
CPOL is controlled by setting the clock pin idle state.
CPHA is controlled via the USICS0 bit in USICR.
* machine/attiny85: add LSB-first bit order support
Add software-based LSB-first support for USI SPI. The USI hardware only
supports MSB-first, so bit reversal is done in software before sending
and after receiving.
Uses an efficient parallel bit swap algorithm (3 operations) to reverse
the byte.
* GNUmakefile: add mcp3008 SPI example to digispark smoketest
Test the USI-based SPI implementation for ATtiny85/digispark.
* machine/attiny85: minimize SPI RAM footprint
Reduce SPI struct from ~14 bytes to 1 byte to fit in ATtiny85's limited
512 bytes of RAM.
Changes:
- Remove register pointers (use avr.USIDR/USISR/USICR directly)
- Remove pin fields (USI pins are fixed: PB0/PB1/PB2)
- Remove CS pin management (user must handle CS)
- Remove frequency control (runs at max speed)
- Remove LSBFirst support
The SPI struct now only stores the USICR configuration byte.
* Revert "machine/attiny85: minimize SPI RAM footprint"
This reverts commit 387ccad494.
* machine/attiny85: reduce SPI RAM usage by 10 bytes
Remove unnecessary fields from SPI struct while keeping all functionality:
- Remove register pointers (use avr.USIDR/USISR/USICR directly)
- Remove pin fields (USI pins are fixed: PB0/PB1/PB2)
- Remove CS pin (user must manage it, standard practice)
Kept functional fields:
- delayCycles for frequency control
- usicrValue for SPI mode support
- lsbFirst for bit order support
SPI struct reduced from 14 bytes to 4 bytes.
---------
* machine/attiny85: add PWM support for Timer0 and Timer1
Add complete PWM implementation for ATtiny85, supporting both Timer0
and Timer1 with their respective output channels:
- Timer0: 8-bit timer for pins PB0 (OC0A) and PB1 (OC0B)
- Timer1: 8-bit high-speed timer for pins PB1 (OC1A) and PB4 (OC1B)
Timer1 provides more flexible period control with configurable top value
(OCR1C) and extended prescaler options (1-16384), making it well-suited
for LED PWM control and other applications requiring variable frequencies.
Implements full PWM interface including Configure, SetPeriod, Channel,
Set, SetInverting, Top, Counter, and Period methods.
* machine/digispark: document PWM support on pins
Add documentation to the Digispark board file indicating which pins
support PWM output:
- P0 (PB0): Timer0 channel A
- P1 (PB1): Timer0 channel B or Timer1 channel A
- P4 (PB4): Timer1 channel B
Includes package comment explaining Timer0 vs Timer1 capabilities,
with Timer1 recommended for more flexible frequency control.
* machine/attiny85: optimize PWM prescaler lookups
Replace verbose switch statements with more efficient implementations:
- SetPeriod: Use bit shift (top >>= prescaler-1) instead of 15-case
switch for dividing uint64 by power-of-2 prescaler values
- Period: Replace switch statements with compact uint16 lookup tables
for both Timer0 and Timer1, casting to uint64 only when needed
This addresses review feedback about inefficient switch-based lookups.
On AVR, this approach is significantly smaller:
- Bit shifts for uint64 division: ~34 bytes vs ~140 bytes
- uint16 tables: 22 bytes code + 32/16 bytes data vs ~140 bytes
- Total savings: ~190 bytes (68% reduction)
* examples/pwm: add digispark support and smoketest
Add digispark.go configuration for PWM example using Timer1 with pins P1 (LED) and P4. Also add digispark PWM example to GNUmakefile smoketests.
---------
* Create "pico2-ice" target board
This board has an rp2350b chip on it, as well as a Lattice Semiconductor
iCE40UP5K FPGA. More details of this open hardware board here:
https://pico2-ice.tinyvision.ai/
Tested on a pico2-ice board with:
~/go/bin/tinygo flash -target=pico2-ice src/examples/blinky1/blinky1.go
which blinks the GREEN LED (connected to GPIO0) on this board.
Signed-off-by: Tinkerer <tinkerer@zappem.net>
* More silkscreen labels for pico2-ice board
Reading the schematic and the rev2 board viewer:
https://raw.githubusercontent.com/tinyvision-ai-inc/pico2-ice/refs/heads/main/Board/Rev2/bom/ibom.html
concluded that the RP2350B GPIO pins are not labeled with these
pin numbers in the silkscreen. Instead, the silkscreen refers to
uses of the GPIOs or the ICE numbered pins. RP2340B devoted pins
map to the A1..4 B1..4 pins on the RP PMOD connector. Also
silkscreen "~0".."~6" are labeled as pins N0..N6.
Signed-off-by: Tinkerer <tinkerer@zappem.net>
* Added a smoketest for pico2-ice board and tidied up GPIO defs
Addresses review comments from aykevl.
Signed-off-by: Tinkerer <tinkerer@zappem.net>
This switches the Espressif fork from LLVM 19 to LLVM 20, so we can use
the improvements made between those LLVM versions. It also better aligns
with the system-LLVM build method, which currently also defaults to LLVM
20.
Note that this disables the machine outliner for RISC-V. It appears
there's a bug in there somewhere, with the machine outliner enabled the
crypto/elliptic package tests fail with -target=riscv-qemu.
This should ideally be investigated and reported upstream.
The revive command seems to have had a syntax error in the file
input glob. It appears to have been broken in a way that did not
result in a return code being set. This change uses 'find' to
build the input to the linter.
Note that it is expected to fail the CI script, because it is
uncovering some existing lint issues that were not being caught.
With these flags, the TinyGo binary gets 18.8MB (11.6%) smaller. That
seems like a quite useful win for such a small change!
This is only for Linux for now. MacOS and Windows can be tested later,
the flags for those probably need to be modified.
Originally inspired by:
https://discourse.llvm.org/t/state-of-the-art-for-reducing-executable-size-with-heavily-optimized-program/87952/18
There are some other flags like -Wl,--pack-dyn-relocs=relr that did not
shrink binary size in my testing, so I've left them out.
This also switches the linker to prefer mold or lld over the default
linker, since the system linker is usually ld.bfd which is very slow.
(Also, for some reason mold produces smaller binaries than lld).
Running tests against an installed TinyGoRoot fails with:
```
=== CONT TestBuild/WebAssembly/gc.go-boehm
main_test.go:441: wasi-libc: did not find any files for pattern builder.filePattern{glob:"dlmalloc/src/dlmalloc.c", exclude:[]string(nil)}
```
because these files are not there, and are required with Boehm GC.
* machine: add support for BTT SKR Pico
Adds support for the BigTreeTech SKR Pico 3D-printer mainboard.
This board uses the RP2040.
* Fix build tag
* Add I2C defaults
* Run UART test instead of blinky1
* Use NoPin for I2C and SPI on BTT SKR Pico
* Cleanup comments
* Don't use ADC pin names
For the threads scheduler, it makes sense to have NumCPU available.
For all other schedulers, the number of available CPUs is practically
limited to one by the scheduler (even though the system might have more
CPUs).
Instead of relying on a build when TinyGo is being built, do it like all
other libraries when it is needed.
This brings a few benefits:
* No more running `make wasi-libc` on the command line as a special
case for WebAssembly. The generic `git submodule update --init` step
is now enough for wasi-libc.
* It becomes much easier to customize the build per system. For
example: include/exclude malloc as needed, disable/enable bulk
memory operations per target, etc.
This *should* not be needed. Using the right `go` binary should do the
job. It might break if users have explicitly set GOROOT (in which case
they probably need to fix that).
This avoids a subprocess call inside `make`.
Instead of calling it 5 times, call it only once on Unix-like systems
(Linux, MacOS) and avoid it entirely on Windows.
The main benefit of this is that it avoids a ton of overhead doing
subprocess calls, which are very slow on Windows (~0.2s on my system).
Most make commands don't need to check for the NodeJS version, so only
do it when needed.
This avoids the following error on Windows for example when NodeJS is
not installed:
/usr/bin/sh: line 1: node: command not found
which: no node in (/c/Users/Ayke/bin:/clangarm64/bin:/usr/local/bin:/usr/bin:/usr/bin:/mingw64/bin:/usr/bin:/c/Users/Ayke/bin:/c/Users/Ayke/.vscode-server/cli/servers/Stable-e54c774e0add60467559eb0d1e229c6452cf8447/server/bin/remote-cli:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/WINDOWS/System32/OpenSSH:/cmd:/c/Users/Ayke/scoop/apps/mingw-mstorsjo-llvm-ucrt/current/bin:/c/Users/Ayke/scoop/apps/python/current/Scripts:/c/Users/Ayke/scoop/apps/python/current:/c/Users/Ayke/go/bin:/c/Users/Ayke/scoop/shims:/c/Users/Ayke/AppData/Local/Microsoft/WindowsApps:/usr/bin/vendor_perl:/usr/bin/core_perl)
Also, some users have been confused by the error message even though in
most cases it is harmless and can be ignored.
A few small changes were needed to make this work. In particular, I
found a critical bug (see the previous commit) that needed to be fixed
to make this work on Windows.