Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
20 changes: 20 additions & 0 deletions tools/uart-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Serial test programs

Checks the default serial port of a connected board.

go run ./tools/uart-test -target <target>

The tool flashes each program in the subdirectories with `tinygo flash`, then
talks to it over the board's serial port and checks the output. The tool
builds with the standard Go compiler. The programs it flashes build with
TinyGo. Tests:

- echo: bytes sent to the board come back unchanged
- burst: overflowing the RX buffer keeps the first bytes and receiving still works
- seq: 2000 numbered lines arrive in order
- bytes: all 256 byte values arrive intact
- conc: serial output and input work together with goroutines and allocation

Use `-port` if the board is not found, `-tinygo` for a different tinygo
binary and `-path-prepend` to put a flashing tool first on PATH. Names after
the flags select tests.
35 changes: 35 additions & 0 deletions tools/uart-test/burst/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//go:build tinygo

package main

import (
"machine"
"time"

"github.com/tinygo-org/tinygo/tools/uart-test/common"
)

func main() {
common.WaitGo("burst")
println("@@GO burst")

// Do not read while the host sends a burst bigger than the RX buffer.
time.Sleep(1500 * time.Millisecond)

var got []byte
for machine.Serial.Buffered() > 0 {
b, _ := machine.Serial.ReadByte()
got = append(got, b)
}
println("@@BUF", len(got))
println("@@DATA", common.Hex(got))

// The UART must keep receiving after an overrun.
println("@@RECOVER")
rec := common.ReadN(16, 5*time.Second)
println("@@REC", common.Hex(rec))
println("@@END burst")
for {
time.Sleep(time.Second)
}
}
45 changes: 45 additions & 0 deletions tools/uart-test/bytes/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//go:build tinygo

package main

import (
"machine"
"time"

"github.com/tinygo-org/tinygo/tools/uart-test/common"
)

func pattern(k int) []byte {
b := make([]byte, 256)
for i := range b {
switch k {
case 0:
b[i] = byte(i)
case 1:
b[i] = byte(255 - i)
case 2:
b[i] = 0x00
default:
if i%2 == 0 {
b[i] = 0xAA
} else {
b[i] = 0x55
}
}
}
return b
}

func main() {
common.WaitGo("bytes")
println("@@GO bytes")
for k := 0; k < 4; k++ {
println("@@BIN", k)
machine.Serial.Write(pattern(k))
println()
}
println("@@END bytes")
for {
time.Sleep(time.Second)
}
}
50 changes: 50 additions & 0 deletions tools/uart-test/common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//go:build tinygo

// Package common has helpers shared by the UART test programs.
package common

import (
"machine"
"time"
)

const hexDigits = "0123456789abcdef"

// WaitGo announces the test and blocks until the host sends 'G'.
func WaitGo(name string) {
machine.Serial.Configure(machine.UARTConfig{BaudRate: 115200})
for {
for machine.Serial.Buffered() > 0 {
b, _ := machine.Serial.ReadByte()
if b == 'G' {
return
}
}
println("@@READY", name)
time.Sleep(300 * time.Millisecond)
}
}

// Hex returns the lowercase hex encoding of b.
func Hex(b []byte) string {
out := make([]byte, 0, len(b)*2)
for _, c := range b {
out = append(out, hexDigits[c>>4], hexDigits[c&15])
}
return string(out)
}

// ReadN reads up to n bytes from the default serial, giving up after timeout.
func ReadN(n int, timeout time.Duration) []byte {
var got []byte
deadline := time.Now().Add(timeout)
for len(got) < n && time.Now().Before(deadline) {
if machine.Serial.Buffered() == 0 {
time.Sleep(time.Millisecond)
continue
}
b, _ := machine.Serial.ReadByte()
got = append(got, b)
}
return got
}
65 changes: 65 additions & 0 deletions tools/uart-test/conc/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//go:build tinygo

package main

import (
"sync"
"time"

"machine"

"github.com/tinygo-org/tinygo/tools/uart-test/common"
)

var sink []byte

func worker(id int, wg *sync.WaitGroup) {
defer wg.Done()
for k := 0; k < 200; k++ {
sink = make([]byte, 256)
println("G", id, k)
time.Sleep(time.Millisecond)
}
}

func main() {
common.WaitGo("conc")
println("@@GO conc")

var wg sync.WaitGroup
for id := 0; id < 3; id++ {
wg.Add(1)
go worker(id, &wg)
}
done := make(chan struct{})
go func() {
wg.Wait()
close(done)
}()

rx := 0
finished := false
for !finished {
for machine.Serial.Buffered() > 0 {
machine.Serial.ReadByte()
rx++
}
select {
case <-done:
finished = true
default:
time.Sleep(time.Millisecond)
}
}
// Let the host finish sending, then count what is left.
time.Sleep(500 * time.Millisecond)
for machine.Serial.Buffered() > 0 {
machine.Serial.ReadByte()
rx++
}
println("@@RXCOUNT", rx)
println("@@END conc")
for {
time.Sleep(time.Second)
}
}
23 changes: 23 additions & 0 deletions tools/uart-test/echo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build tinygo

package main

import (
"machine"
"time"

"github.com/tinygo-org/tinygo/tools/uart-test/common"
)

func main() {
common.WaitGo("echo")
println("@@GO echo")
for {
if machine.Serial.Buffered() > 0 {
b, _ := machine.Serial.ReadByte()
machine.Serial.WriteByte(b)
} else {
time.Sleep(time.Millisecond)
}
}
}
Loading
Loading