Skip to content

Commit

Permalink
Add esp32-tester. (#2680)
Browse files Browse the repository at this point in the history
  • Loading branch information
floitsch authored Dec 17, 2024
1 parent 06d4a55 commit 59734da
Show file tree
Hide file tree
Showing 49 changed files with 606 additions and 57 deletions.
6 changes: 6 additions & 0 deletions tests/health/gold/sdk/tests__hw__esp-tester__tester.toit.gold
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<sdk>/uart.toit:243:15: warning: Deprecated 'Port.errors'
errors++
^~
<sdk>/uart.toit:243:15: warning: Deprecated 'Port.errors'
errors++
^~
62 changes: 62 additions & 0 deletions tests/hw/esp-tester/mini-jag.toit
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (C) 2024 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the tests/LICENSE file.
import crypto.crc
import esp32
import net
import system.containers
import uuid show Uuid

import .shared

main:
cause := esp32.wakeup-cause
print "Wakeup cause: $cause"
// It looks like resetting the chip through the UART yields RST-UNKNOWN.
if cause == esp32.ESP-RST-POWERON or cause == esp32.ESP-RST-UNKNOWN:
install-new-test
esp32.deep-sleep Duration.ZERO
run-test

install-new-test:
// Clear all existing containers.
ids := containers.images.map: | image/containers.ContainerImage |
image.id
ids.do: | id/Uuid |
if id != containers.current:
containers.uninstall id

network := net.open
server-socket := network.tcp-listen 0
print "$network.address:$server-socket.local-address.port"
print MINI-JAG-LISTENING
socket := server-socket.accept
reader := socket.in
size := reader.little-endian.read-int32
expected-crc := reader.read-bytes 4
summer := crc.Crc32
print "SIZE: $size"
writer := containers.ContainerImageWriter size
written-size := 0
while written-size < size:
data := reader.read
summer.add data
writer.write data
written-size += data.size
print "WRITTEN: $written-size"
if summer.get != expected-crc:
throw"CRC MISMATCH"
return
writer.commit
reader.close
socket.close
server-socket.close
network.close
print "INSTALLED CONTAINER"

run-test:
print "RUNNING INSTALLED CONTAINER"
containers.images.do: | image/containers.ContainerImage |
if image.id != containers.current:
containers.start image.id
26 changes: 26 additions & 0 deletions tests/hw/esp-tester/package.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
sdk: ^2.0.0-alpha.161
prefixes:
cli: pkg-cli
fs: pkg-fs
host: pkg-host
packages:
pkg-cli:
url: github.com/toitlang/pkg-cli
name: cli
version: 2.2.0
hash: ae142d3c8783939935ba37a924f9b2c2a0ad2479
prefixes:
fs: pkg-fs
host: pkg-host
pkg-fs:
url: github.com/toitlang/pkg-fs
name: fs
version: 2.3.1
hash: 60836d4500317af2093d59d50c117d612c33f1fa
prefixes:
host: pkg-host
pkg-host:
url: github.com/toitlang/pkg-host
name: host
version: 1.15.3
hash: 62393e8522b77eafbafe60b9817935266117daf6
10 changes: 10 additions & 0 deletions tests/hw/esp-tester/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
dependencies:
cli:
url: github.com/toitlang/pkg-cli
version: ^2.2.0
fs:
url: github.com/toitlang/pkg-fs
version: ^2.3.1
host:
url: github.com/toitlang/pkg-host
version: ^1.15.3
5 changes: 5 additions & 0 deletions tests/hw/esp-tester/shared.toit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (C) 2024 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the tests/LICENSE file.
MINI-JAG-LISTENING ::= "MINI-JAG LISTENING"
255 changes: 255 additions & 0 deletions tests/hw/esp-tester/tester.toit
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
// Copyright (C) 2024 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the tests/LICENSE file.
import cli
import crypto.crc
import fs
import host.directory
import host.file
import host.pipe
import monitor
import net
import system
import uart
import .shared

ALL-TESTS-DONE ::= "All tests done"
JAG-DECODE ::= "jag decode"

main args:
root-cmd := cli.Command "tester"
--help="Run tests on an ESP tester"
--options=[
cli.Option "toit-exe"
--help="The path to the Toit executable"
--type="path"
--required,
]

setup-cmd := cli.Command "setup"
--help="Setup the ESP tester on the device"
--options=[
cli.Option "toit-exe"
--help="The path to the Toit executable"
--type="path"
--required,
cli.Option "port"
--help="The path to the UART port"
--type="path"
--required,
cli.Option "envelope"
--help="The path to the envelope"
--type="path"
--required,
cli.Option "wifi-ssid"
--help="The WiFi SSID"
--type="string"
--required,
cli.Option "wifi-password"
--help="The WiFi password"
--type="string"
--required,
cli.Option "port"
--help="The path to the UART port"
--type="path"
--required,
]
--run=:: | invocation/cli.Invocation |
setup-tester invocation

root-cmd.add setup-cmd

run-cmd := cli.Command "run"
--help="Run a test on the ESP"
--options=[
cli.Option "port-board1"
--help="The path to the UART port of board 1"
--type="path"
--required,
cli.Option "port-board2"
--help="The path to the UART port of board 2"
--type="path",
]
--rest=[
cli.Option "test"
--help="The path to the code for board 1"
--type="path"
--required,
cli.Option "test2"
--help="The path to the code for board 2"
--type="path",
]
--run=:: | invocation/cli.Invocation |
run-test invocation
root-cmd.add run-cmd

root-cmd.run args

with-tmp-dir [block]:
dir := directory.mkdtemp "/tmp/esp-tester"
try:
block.call dir
finally:
directory.rmdir --recursive dir

run-toit toit-exe/string args/List --ui/cli.Ui:
ui.emit --verbose "Running $toit-exe $args"
exit-code := pipe.run-program [toit-exe] + args
if exit-code != 0:
throw "Failed to run Toit"

run-test invocation/cli.Invocation:
ui := invocation.cli.ui
toit-exe := invocation["toit-exe"]
port-board1 := invocation["port-board1"]
port-board2 := invocation["port-board2"]
test-path := invocation["test"]
test2-path := invocation["test2"]

board1 := TestDevice --name="board1" --port-path=port-board1 --ui=ui --toit-exe=toit-exe
board2/TestDevice? := null

board1.run-test test-path

if port-board2:
board2 = TestDevice --name="board2" --port-path=port-board2 --ui=ui --toit-exe=toit-exe
board2.run-test test2-path

ui.emit --verbose "Waiting for all tests to be done"
board1.all-tests-done.get
if board2: board2.all-tests-done.get

board1.close
if board2: board2.close

class TestDevice:
name/string
port/uart.HostPort? := ?
toit-exe/string
read-task/Task? := null
is-active/bool := false
collected-output/string := ""
ready-latch/monitor.Latch := monitor.Latch
all-tests-done/monitor.Latch := monitor.Latch
ui/cli.Ui

constructor --.name --.toit-exe --port-path/string --.ui:
port = uart.HostPort port-path --baud-rate=115200
read-task = task --background::
try:
reader := port.in
stdout := pipe.stdout
while data/ByteArray? := reader.read:
if not is-active: continue
stdout.write data
collected-output += data.to-string-non-throwing
if not ready-latch.has-value and collected-output.contains "\n$MINI-JAG-LISTENING":
ready-latch.set true
if not all-tests-done.has-value and collected-output.contains ALL-TESTS-DONE:
all-tests-done.set true
if collected-output.contains JAG-DECODE:
ui.abort "Error detected"

finally:
read-task = null

close:
if read-task:
read-task.cancel
if port:
port.close
port = null

toit_ args/List:
run-toit toit-exe args --ui=ui

run-test test-path:
// Reset the device.
ui.emit --verbose "Resetting $name"
port.set-control-flag uart.HostPort.CONTROL-FLAG-DTR false
port.set-control-flag uart.HostPort.CONTROL-FLAG-RTS true
is-active = true
sleep --ms=200
port.set-control-flag uart.HostPort.CONTROL-FLAG-RTS false

ui.emit --verbose "Waiting for $name to be ready"
ready-latch.get
ui.emit --verbose "Device $name is ready"

lines/List := collected-output.split "\n"
lines.map --in-place: it.trim
listening-line-index := lines.index-of --last MINI-JAG-LISTENING
host-port-line := lines[listening-line-index - 1]
ui.emit --info "Running test on $host-port-line"

with-tmp-dir: | dir/string |
snapshot-path := "$dir/test.snap"
toit_ [
"compile",
"--snapshot",
"-o", snapshot-path,
test-path
]

snapshot := file.read-contents snapshot-path
image-path := fs.join dir "image.envelope"
toit_ [
"tool", "snapshot-to-image",
"--format", "binary",
"-m32",
"-o", image-path,
snapshot-path
]
image := file.read-contents image-path

network := net.open
parts := host-port-line.split ":"
socket := network.tcp-connect parts[0] (int.parse parts[1])
socket.out.little-endian.write-int32 image.size
summer := crc.Crc32
summer.add image
socket.out.write summer.get
socket.out.write image
socket.close

setup-tester invocation/cli.Invocation:
ui := invocation.cli.ui
toit-exe := invocation["toit-exe"]
port-path := invocation["port"]
envelope-path := invocation["envelope"]

with-tmp-dir: | dir/string |
tester-envelope-path := fs.join dir "tester.envelope"
my-path := system.program-path
my-dir := fs.dirname my-path
mini-jag-source := fs.join my-dir "mini-jag.toit"
mini-jag-snapshot-path := "$dir/mini-jag.snap"
run-toit --ui=ui toit-exe [
"compile",
"--snapshot",
"-o", mini-jag-snapshot-path,
mini-jag-source
]
run-toit --ui=ui toit-exe [
"tool", "firmware",
"container", "add", "mini-jag", mini-jag-snapshot-path,
"-e", envelope-path,
"-o", tester-envelope-path,
]
wifi-config-path := fs.join dir "wifi-config.json"
file.write-contents --path=wifi-config-path """
{
"wifi": {
"wifi.ssid": "$invocation["wifi-ssid"]",
"wifi.password": "$invocation["wifi-password"]"
}
}
"""
run-toit --ui=ui toit-exe [
"tool", "firmware", "flash",
"-e", tester-envelope-path,
"--config", wifi-config-path,
"--port", port-path,
]

7 changes: 5 additions & 2 deletions tests/hw/esp32/adc.toit
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ import gpio.adc as gpio
import gpio
import expect show *

import .test

ADC1-PIN ::= 32
ADC2-PIN ::= 14
CONTROL-PIN ::= 25
V33-PIN ::= 12

main:
run-test: test

test:
test-restricted := true

v33-pin := gpio.Pin V33-PIN --output
Expand Down Expand Up @@ -89,5 +94,3 @@ main:
// Now the voltage should be 3.3V.
value = adc.get
expect value > 3.0

print "done"
Loading

0 comments on commit 59734da

Please sign in to comment.