Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
edbc7b5
Initial pass on cleanup
heucuva Mar 13, 2023
45d92a0
Add some functions from current europi firmware
heucuva Mar 17, 2023
ff50fa4
Swap out deprecated and magic numbers
heucuva Mar 17, 2023
8d93e62
Basic bootstrap support
heucuva Mar 18, 2023
73600de
Remove vfs
heucuva Mar 21, 2023
371527a
Fix up knob bank
heucuva Mar 22, 2023
b42f234
More cleanup of bootstrap and layout
heucuva Apr 4, 2023
eef6ad7
Updating diagnostic and clockwerk apps
heucuva Apr 4, 2023
972a92f
Merge pull request #2 from heucuva/cleanup
heucuva Apr 4, 2023
c0fea3f
Slimmer update with just bootstrap and 2 examples
heucuva Apr 20, 2023
ae09d68
remove local testing junk
heucuva Apr 20, 2023
48b76ff
Merge pull request #4 from heucuva/bootstrap-updates
heucuva Apr 20, 2023
2f29a56
Support for testability
heucuva Apr 23, 2023
74a3ac9
Allow setting just sampling size on analog input
heucuva Apr 23, 2023
1dfa0e9
Reduce to minimum viable startup
heucuva Apr 23, 2023
315d11d
add simple revision detection
heucuva Apr 23, 2023
41dd723
minimal diagnostics app
heucuva Apr 23, 2023
c254ba3
move some stuff around
heucuva Apr 23, 2023
3aecacc
Full code coverage for units
heucuva Apr 23, 2023
09af866
add lerp
heucuva Apr 23, 2023
21d5c37
add clamp tests
heucuva Apr 23, 2023
bf4490c
debounce tests
heucuva Apr 23, 2023
9a69dbb
Add parallel tests to debounce
heucuva Apr 23, 2023
ffecaae
event bus testing and cautionary tale
heucuva Apr 24, 2023
3833e05
move hal code around to make more sense.
heucuva Apr 24, 2023
767bb7d
Moved quantizer functions
heucuva Apr 24, 2023
be4978d
Better docs for hardware mappings.
heucuva Apr 24, 2023
10138b7
clean up linting
heucuva Apr 24, 2023
ba4c1b7
Better error handling on bad hardware detect
heucuva Apr 24, 2023
f477e4a
clean up panic handling
heucuva Apr 24, 2023
4be9641
simple testing rig for running on non-pico hw
heucuva Apr 24, 2023
f074364
added simulator of europi
heucuva Apr 25, 2023
a5c330f
Fix for read timeout issue
heucuva Apr 25, 2023
62e18f0
clean up websocket code
heucuva Apr 25, 2023
40ad1ec
adding pprof
heucuva Apr 25, 2023
846357a
clean up websocket api
heucuva Apr 25, 2023
f72e269
Rework code to support hardware detection
heucuva Apr 26, 2023
663ed67
removed junk
heucuva Apr 26, 2023
8cf5268
Merge pull request #8 from heucuva/testability
heucuva Apr 26, 2023
3ccf788
Fix readme files.
heucuva Apr 26, 2023
c1de526
Small fixes
heucuva Apr 26, 2023
a2ca2ef
Clean up lint warnings
heucuva Apr 26, 2023
84617fb
Fix issue with CV6 being incorrectly CV5
heucuva Apr 26, 2023
521ba39
Update README.md
heucuva Apr 27, 2023
f25258e
Update bootstrap_panicdisabled.go
heucuva Apr 27, 2023
8f8c2ae
Fixes for PR concerns
heucuva Apr 27, 2023
9245bdf
Merge branch 'main' of https://github.com/heucuva/europi-go into main
heucuva Apr 27, 2023
1cb0549
Clean up some bootstrap options
heucuva Apr 27, 2023
7ff7672
remapper support
heucuva Apr 30, 2023
37f0c04
allow for much better calibration of voltage
heucuva Apr 30, 2023
8273242
better support for rev0
heucuva May 4, 2023
6406331
fix for panic on wrong hw type conversion
heucuva May 4, 2023
0dc66ab
Fix issues with invalid setup during simulation
heucuva May 4, 2023
80602a5
Fix for rev0 params mismatch
heucuva May 5, 2023
ba2d559
move bootstrap into its own folder
heucuva May 5, 2023
bcb5742
simplify init slightly
heucuva May 5, 2023
6b49c57
simplify screenbank
heucuva May 5, 2023
0d614c7
add cancellation context directly on the hardware
heucuva May 5, 2023
ba799ba
memory cleanup
heucuva May 6, 2023
7fe0190
Common event bus for all revisions of hardware
heucuva May 6, 2023
fa23047
better name for monopolar feature
heucuva May 6, 2023
c374007
cleanup
heucuva May 6, 2023
b87eac0
simplify pico pwm interface
heucuva May 6, 2023
787c7fa
bifurcating components specific to bootstrap out
heucuva May 6, 2023
e6258de
missed in last checkin
heucuva May 6, 2023
543ef62
Fix for tinygo getting confused about generics
heucuva May 6, 2023
21aa3e8
Merge pull request #9 from heucuva/bootstrap-improvements
heucuva May 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
__debug_bin

# Test binary, built with `go test -c`
*.test
Expand All @@ -14,6 +18,9 @@
# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work

# TinyGo
*.elf
*.uf2
Expand Down
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,37 @@ Ctrl + Shift + P > Tasks: Run Build Task

TODO

## Why should I use this?
## Debugging using a browser

**NOTE**: This is a beta feature! Please do not expect it to function properly, if at all.

If your EuroPi project is set up via the `europi.Bootstrap()` execution paradigm, you may operate and visualize it via a browser instead of having to flash it to a EuroPi hardware module or build it via TinyGo.

There are some caveats that must be understood before using this functionality:
1. This builds via Pure Go and only simulates (to the best of ability) a RP2040 / Pico running the software.
1. The visualization web page is terrible. While some care was taken to make it minimally usable, it's not pretty and is rife with bugs.
1. The websocket interface presented can currently only bind to port 8080 on "all" network interfaces.
1. Projects which do not utilize the `europi.Bootstrap()` execution paradigm will not be able to partake in this functionality.
1. [pprof](https://github.com/google/pprof/blob/main/README.md) support is enabled while the websocket interface is available, but it does not represent how the code will run on a RP2040 / Pico or within a EuroPi module. It is specifically provided here for debugging multiprocessing functionality and gross abuses of memory and CPU.

### How to get the browser support to work

First, you need [Go installed](https://go.dev/doc/install). Preferably 1.18 or newer.

Second, set up your module project to build with the `europi.Bootstrap()` execution paradigm and add the following line to the `europi.Bootstrap()` parameter list:

```go
europi.AttachNonPicoWS(true),
```

Then, execute your module using Go (not TinyGo) and pass a buildflag tag parameter matching [which revision of hardware](hardware/README.md#revision-list) you want to run, like so:

```bash
go run -tags=revision1 internal/projects/randomskips/randomskips.go
```

Finally, open up a browser to [localhost:8080](http://localhost:8080/) to see your module in action!

## Why should I use the TinyGo version of the EuroPi firmware?

You probably shouldn't. This is my passion project because I love Go. You should probably be using the official [EuroPi firmware](https://github.com/Allen-Synthesis/EuroPi). But if you are interested in writing a dedicated script for the EuroPi that requires concurrency and faster performance than MicroPython can offer, then maybe this is the right firmware for you!
110 changes: 0 additions & 110 deletions analog_reader.go

This file was deleted.

15 changes: 15 additions & 0 deletions clamp/clamp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package clamp

type Clampable interface {
~int8 | ~int16 | ~int32 | ~int64 | ~int | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64
}

func Clamp[T Clampable](v, min, max T) T {
if v > max {
v = max
}
if v < min {
v = min
}
return v
}
41 changes: 41 additions & 0 deletions clamp/clamp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package clamp_test

import (
"testing"

"github.com/awonak/EuroPiGo/clamp"
)

func TestClamp(t *testing.T) {
t.Run("InRange", func(t *testing.T) {
t.Run("Min", func(t *testing.T) {
min, max := 0, 10
if expected, actual := min, clamp.Clamp(min, min, max); actual != expected {
t.Fatalf("Clamp[%v, %v] Clamp: expected[%v] actual[%v]", min, max, expected, actual)
}
})

t.Run("Max", func(t *testing.T) {
min, max := 0, 10
if expected, actual := max, clamp.Clamp(max, min, max); actual != expected {
t.Fatalf("Clamp[%v, %v] Clamp: expected[%v] actual[%v]", min, max, expected, actual)
}
})
})

t.Run("OutOfRange", func(t *testing.T) {
t.Run("BelowMin", func(t *testing.T) {
min, max := 0, 10
if expected, actual := min, clamp.Clamp(min-2, min, max); actual != expected {
t.Fatalf("Clamp[%v, %v] Clamp: expected[%v] actual[%v]", min, max, expected, actual)
}
})

t.Run("AboveMax", func(t *testing.T) {
min, max := 0, 10
if expected, actual := max, clamp.Clamp(max+2, min, max); actual != expected {
t.Fatalf("Clamp[%v, %v] Clamp: expected[%v] actual[%v]", min, max, expected, actual)
}
})
})
}
34 changes: 34 additions & 0 deletions debounce/debounce.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package debounce

import "time"

type Debouncer[T func(U, time.Duration), U any] interface {
Debounce(delay time.Duration) func(U)
LastChange() time.Time
}

type debouncer[T func(U, time.Duration), U any] struct {
last time.Time
fn T
}

func NewDebouncer[T func(U, time.Duration), U any](fn T) Debouncer[T, U] {
return &debouncer[T, U]{
last: time.Now(),
fn: fn,
}
}

func (d *debouncer[T, U]) Debounce(delay time.Duration) func(U) {
return func(u U) {
now := time.Now()
if deltaTime := now.Sub(d.last); deltaTime >= delay {
d.last = now
d.fn(u, deltaTime)
}
}
}

func (d debouncer[T, U]) LastChange() time.Time {
return d.last
}
89 changes: 89 additions & 0 deletions debounce/debounce_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package debounce_test

import (
"fmt"
"testing"
"time"

"github.com/awonak/EuroPiGo/debounce"
)

func TestDebouncer(t *testing.T) {
t.Run("New", func(t *testing.T) {
fn := func(any, time.Duration) {}
if actual := debounce.NewDebouncer(fn); actual == nil {
t.Fatalf("Debouncer[%p] NewDebouncer: expected[non-nil] actual[nil]", fn)
}
})

t.Run("Debounce", func(t *testing.T) {
t.Run("Delay0", func(t *testing.T) {
t.Parallel()
delay := time.Duration(0)
runs := 4
runDebouncerTest(t, runs, delay, time.Duration(0), 4)
runDebouncerTest(t, runs, delay, time.Millisecond*1, 4)
runDebouncerTest(t, runs, delay, time.Second*1, 4)
})

t.Run("Delay100ms", func(t *testing.T) {
t.Parallel()
delay := time.Millisecond * 100
runs := 4
runDebouncerTest(t, runs, delay, time.Duration(0), 0)
runDebouncerTest(t, runs, delay, time.Millisecond*1, 0)
runDebouncerTest(t, runs, delay, time.Second*1, 2)
})

t.Run("Delay10s", func(t *testing.T) {
t.Parallel()
delay := time.Millisecond * 100
runs := 4
runDebouncerTest(t, runs, delay, time.Duration(0), 0)
runDebouncerTest(t, runs, delay, time.Millisecond*1, 0)
runDebouncerTest(t, runs, delay, time.Second*1, 0)
})
})

t.Run("LastChange", func(t *testing.T) {
fn := func(any, time.Duration) {}
db := debounce.NewDebouncer(fn)
dbFunc := db.Debounce(0)

beforeExpected := time.Now()
dbFunc(nil)
if actual := db.LastChange(); !actual.After(beforeExpected) {
t.Fatalf("Debouncer[%p] LastChange: expected(after)[%v] actual[%v]", fn, beforeExpected, actual)
}
})
}

func runDebouncerTest(t *testing.T, runs int, delay, interval time.Duration, minimumExpected int) {
t.Helper()

var testName string
if interval == 0 {
testName = "Immediate"
} else {
testName = fmt.Sprintf("Interval%v", interval)
}

var actual int
fn := func(any, time.Duration) {
actual++

}

db := debounce.NewDebouncer(fn).Debounce(delay)

t.Run(testName, func(t *testing.T) {
for i := 0; i < runs; i++ {
db(nil)
time.Sleep(interval)
}
// since these are timing-based, we have to be lenient
if actual < minimumExpected {
t.Fatalf("Debouncer[%p] Debounce(%v): expected[%v] actual[%v]", fn, delay, minimumExpected, actual)
}
})
}
Loading