diff --git a/tests/hw/esp-tester/mini-jag.toit b/tests/hw/esp-tester/mini-jag.toit new file mode 100644 index 000000000..6e3be69f6 --- /dev/null +++ b/tests/hw/esp-tester/mini-jag.toit @@ -0,0 +1,60 @@ +// 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 + +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 diff --git a/tests/hw/esp-tester/package.lock b/tests/hw/esp-tester/package.lock new file mode 100644 index 000000000..d2da0dc8b --- /dev/null +++ b/tests/hw/esp-tester/package.lock @@ -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 diff --git a/tests/hw/esp-tester/package.yaml b/tests/hw/esp-tester/package.yaml new file mode 100644 index 000000000..58e64ccb5 --- /dev/null +++ b/tests/hw/esp-tester/package.yaml @@ -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 diff --git a/tests/hw/esp-tester/shared.toit b/tests/hw/esp-tester/shared.toit new file mode 100644 index 000000000..cb36f6e2c --- /dev/null +++ b/tests/hw/esp-tester/shared.toit @@ -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" diff --git a/tests/hw/esp-tester/tester.toit b/tests/hw/esp-tester/tester.toit new file mode 100644 index 000000000..37517621f --- /dev/null +++ b/tests/hw/esp-tester/tester.toit @@ -0,0 +1,257 @@ +// 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 + +MINI-JAG-LISTENING ::= "MINI-JAG LISTENING" +TEST-STARTED ::= "TEST STARTED" +ALL-TEST-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-TEST-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, + ] + diff --git a/tests/hw/esp32/adc.toit b/tests/hw/esp32/adc.toit index 2cca32141..c87869a77 100644 --- a/tests/hw/esp32/adc.toit +++ b/tests/hw/esp32/adc.toit @@ -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 @@ -89,5 +94,3 @@ main: // Now the voltage should be 3.3V. value = adc.get expect value > 3.0 - - print "done" diff --git a/tests/hw/esp32/ble1-board1.toit b/tests/hw/esp32/ble1-board1.toit index 0e8be4340..718ed2db3 100644 --- a/tests/hw/esp32/ble1-board1.toit +++ b/tests/hw/esp32/ble1-board1.toit @@ -9,6 +9,4 @@ See 'ble1-shared.toit' import .ble1-shared as shared main: - // Run twice to make sure the `close` works correctly. - 2.repeat: - shared.main-peripheral --iteration=it + shared.main-peripheral diff --git a/tests/hw/esp32/ble1-board2.toit b/tests/hw/esp32/ble1-board2.toit index afd5a0498..a377186a6 100644 --- a/tests/hw/esp32/ble1-board2.toit +++ b/tests/hw/esp32/ble1-board2.toit @@ -9,8 +9,4 @@ See 'ble1-shared.toit' import .ble1-shared as shared main: - // Run twice to make sure the `close` works correctly. - 2.repeat: - shared.main-central --iteration=it - // Give the other side time to shut down. - if it == 0: sleep --ms=500 + shared.main-central diff --git a/tests/hw/esp32/ble1-shared.toit b/tests/hw/esp32/ble1-shared.toit index e49a97185..212314d8a 100644 --- a/tests/hw/esp32/ble1-shared.toit +++ b/tests/hw/esp32/ble1-shared.toit @@ -14,6 +14,7 @@ import expect show * import monitor import .ble-util +import .test SERVICE-TEST ::= BleUuid "df451d2d-e899-4346-a8fd-bca9cbfebc0b" SERVICE-TEST2 ::= BleUuid "94a11d6a-fa23-4a09-aa6f-2ca0b7cdbb70" @@ -30,7 +31,13 @@ CHARACTERISTIC-WRITE-ONLY-WITH-RESPONSE ::= BleUuid "8e00e1c7-1b90-4f23-8dc9-384 VALUE-BYTES ::= #[0x70, 0x17] VALUE-STRING ::= "7017" -main-peripheral --iteration/int: +main-peripheral: + run-test: + // Run twice to make sure the `close` works correctly. + 2.repeat: + run-peripheral-test --iteration=it + +run-peripheral-test --iteration/int: print "Iteration $iteration" adapter := Adapter adapter.set-preferred-mtu 527 // Maximum value. @@ -146,7 +153,15 @@ main-peripheral --iteration/int: callback-task-done.get print "end of iteration" -main-central --iteration/int: +main-central: + run-test: + // Run twice to make sure the `close` works correctly. + 2.repeat: + run-central-test --iteration=it + // Give the other side time to shut down. + if it == 0: sleep --ms=500 + +run-central-test --iteration/int: print "Iteration $iteration" adapter := Adapter diff --git a/tests/hw/esp32/ble2-shared.toit b/tests/hw/esp32/ble2-shared.toit index 5faed359f..17614467e 100644 --- a/tests/hw/esp32/ble2-shared.toit +++ b/tests/hw/esp32/ble2-shared.toit @@ -14,6 +14,7 @@ import expect show * import monitor import .ble-util +import .test SERVICE-TEST ::= BleUuid "a1bcf0ba-7557-4968-91f8-6b0f187af2b5" @@ -27,8 +28,10 @@ TEST-BYTE-COUNT ::= 500_000 MTU ::= 512 PACKET-SIZE := MTU - 3 - main-peripheral: + run-test: test-peripheral + +test-peripheral: adapter := Adapter adapter.set-preferred-mtu MTU peripheral := adapter.peripheral @@ -56,6 +59,9 @@ main-peripheral: print "all data received" main-central: + run-test: test-central + +test-central: adapter := Adapter adapter.set-preferred-mtu MTU central := adapter.central @@ -84,5 +90,4 @@ main-central: print "awaiting response" write-only-with-response.write "done" - print "All done." adapter.close diff --git a/tests/hw/esp32/ble3-shared.toit b/tests/hw/esp32/ble3-shared.toit index 27e52a5ce..d4ac93dc4 100644 --- a/tests/hw/esp32/ble3-shared.toit +++ b/tests/hw/esp32/ble3-shared.toit @@ -21,6 +21,7 @@ import expect show * import monitor import .ble-util +import .test ITERATIONS ::= 100 @@ -78,6 +79,9 @@ UUIDS ::= [ DONE-CHARACTERISTIC-UUID := "3450e50b-d1c8-4e6d-ba54-ff3ff0f17b1d" main-peripheral: + run-test: test-peripheral + +test-peripheral: adapter := Adapter peripheral := adapter.peripheral @@ -98,11 +102,13 @@ main-peripheral: peripheral.start-advertise --connection-mode=BLE-CONNECT-MODE-UNDIRECTIONAL advertisement done-characteristic.read - print "Done" adapter.close main-central: + run-test: test-central + +test-central: done := false keep-alive := List 100 diff --git a/tests/hw/esp32/ble4-shared.toit b/tests/hw/esp32/ble4-shared.toit index 35dfca92a..73fe50c83 100644 --- a/tests/hw/esp32/ble4-shared.toit +++ b/tests/hw/esp32/ble4-shared.toit @@ -14,6 +14,7 @@ import expect show * import monitor import .ble-util +import .test TEST-SERVICE ::= BleUuid "650a73d3-d7fd-4d08-b734-d11e25b0856d" @@ -23,6 +24,9 @@ TEST-CHARACTERISTIC-CALLBACK ::= BleUuid "1a1bb179-c006-4217-a57b-342e24eca694" TEST-DESCRIPTOR ::= BleUuid "a2aef737-c09f-4f8f-bd6c-f80b993300ef" main-peripheral: + run-test: test-peripheral + +test-peripheral: adapter := Adapter peripheral := adapter.peripheral @@ -55,9 +59,11 @@ main-peripheral: peripheral.start-advertise --connection-mode=BLE-CONNECT-MODE-UNDIRECTIONAL advertisement done-latch.get - print "done" main-central: + run-test: test-central + +test-central: adapter := Adapter central := adapter.central address := find-device-with-service central TEST-SERVICE @@ -92,5 +98,3 @@ main-central: expect-equals #['b', 'a', 'r'] value characteristic-callback.write #['d', 'o', 'n', 'e'] - - print "done" diff --git a/tests/hw/esp32/ble5-shared.toit b/tests/hw/esp32/ble5-shared.toit index e6e63c374..fb6e26878 100644 --- a/tests/hw/esp32/ble5-shared.toit +++ b/tests/hw/esp32/ble5-shared.toit @@ -14,11 +14,15 @@ import expect show * import monitor import .ble-util +import .test TEST-SERVICE ::= BleUuid "e5c245a3-1b7e-44cf-bc37-7040b719fe46" TEST-CHARACTERISTIC ::= BleUuid "77d0b04e-bf49-4048-a4cd-fb46be32ebd0" main-peripheral: + run-test: test-peripheral + +test-peripheral: adapter := Adapter peripheral := adapter.peripheral @@ -46,9 +50,11 @@ main-peripheral: peripheral.start-advertise --connection-mode=BLE-CONNECT-MODE-UNDIRECTIONAL advertisement done-latch.get - print "done" main-central: + run-test: test-central + +test-central: adapter := Adapter central := adapter.central address := find-device-with-service central TEST-SERVICE @@ -70,5 +76,3 @@ main-central: expect-equals value.to-byte-array characteristic.read characteristic.write "done" - - print "done" diff --git a/tests/hw/esp32/ble6-advertise-shared.toit b/tests/hw/esp32/ble6-advertise-shared.toit index 057cacd9c..bf0154992 100644 --- a/tests/hw/esp32/ble6-advertise-shared.toit +++ b/tests/hw/esp32/ble6-advertise-shared.toit @@ -16,6 +16,7 @@ import expect show * import monitor import .ble-util +import .test TEST-SERVICE ::= BleUuid "eede145e-b6a6-4d61-8156-ed10d5b75903" TEST-CHARACTERISTIC ::= BleUuid "6b50d82f-ae33-4e0e-b161-50db92c49ad2" @@ -24,6 +25,9 @@ COMPANY-ID ::= #[0x12, 0x34] MANUFACTURER-DATA ::= #[0x56, 0x78] main-peripheral: + run-test: test-peripheral + +test-peripheral: adapter := Adapter peripheral := adapter.peripheral @@ -135,6 +139,9 @@ test-data characteristic.write #[central-test-counter++] main-central: + run-test: test-central + +test-central: adapter := Adapter central := adapter.central @@ -232,5 +239,3 @@ main-central: remote-device.close central.close adapter.close - - print "done" diff --git a/tests/hw/esp32/dac.toit b/tests/hw/esp32/dac.toit index 75a988dfd..e0517e8ea 100644 --- a/tests/hw/esp32/dac.toit +++ b/tests/hw/esp32/dac.toit @@ -16,6 +16,8 @@ import gpio.dac as gpio import gpio.adc as gpio import expect show * +import .test + ADC-IN1 := 33 ADC-IN2 := 32 DAC-OUT1 := 26 @@ -45,6 +47,9 @@ test-wave data/List: expect 1.3 <= average <= 2.0 main: + run-test: test + +test: dac1 := gpio.Dac (gpio.Pin DAC-OUT1) dac2 := gpio.Dac (gpio.Pin DAC-OUT2) adc1 := gpio.Adc (gpio.Pin ADC-IN1) @@ -119,5 +124,3 @@ main: dac1.close dac2.close - - print "done" diff --git a/tests/hw/esp32/espnow1-board1.toit b/tests/hw/esp32/espnow1-board1.toit index 4202a164b..1774506e3 100644 --- a/tests/hw/esp32/espnow1-board1.toit +++ b/tests/hw/esp32/espnow1-board1.toit @@ -18,9 +18,14 @@ Once that one is running, run `espnow1_board2.toit` on board2. import esp32.espnow import expect show * + import .espnow1-shared +import .test main: + run-test: test-espnow + +test-espnow: service ::= espnow.Service.station --key=PMK --channel=CHANNEL service.add-peer espnow.BROADCAST-ADDRESS diff --git a/tests/hw/esp32/espnow1-board2.toit b/tests/hw/esp32/espnow1-board2.toit index 65a27304b..add511f23 100644 --- a/tests/hw/esp32/espnow1-board2.toit +++ b/tests/hw/esp32/espnow1-board2.toit @@ -7,9 +7,14 @@ See 'espnow1_board1.toit' */ import esp32.espnow + import .espnow1-shared +import .test main: + run-test: test-espnow + +test-espnow: service ::= espnow.Service.station --key=PMK --channel=CHANNEL service.add-peer espnow.BROADCAST-ADDRESS diff --git a/tests/hw/esp32/gpio-open-drain.toit b/tests/hw/esp32/gpio-open-drain.toit index dd7094c01..8fddc48b2 100644 --- a/tests/hw/esp32/gpio-open-drain.toit +++ b/tests/hw/esp32/gpio-open-drain.toit @@ -14,6 +14,7 @@ Connect pin 18 to GND with a 1M Ohm resistor (or any other big number). import gpio import expect show * +import .test import ..shared.gpio-open-drain TEST-PIN ::= 18 @@ -21,6 +22,9 @@ LEVEL-PIN ::= 19 MEASURE-PIN ::= 34 main: + run-test: test + +test: measure-pin := gpio.Pin MEASURE-PIN --input test-pin := gpio.Pin TEST-PIN --output level-pin := gpio.Pin LEVEL-PIN // Will be reconfigured. @@ -33,4 +37,3 @@ main: measure-pin.close test-pin.close level-pin.close - print "All tests done" diff --git a/tests/hw/esp32/gpio.toit b/tests/hw/esp32/gpio.toit index a14499935..d69d449b5 100644 --- a/tests/hw/esp32/gpio.toit +++ b/tests/hw/esp32/gpio.toit @@ -12,6 +12,7 @@ Connect pin 18 to pin 19, optionally with a 330 Ohm resistor to avoid short circ import gpio import expect show * +import .test import ..shared.gpio as shared RESTRICTED ::= 7 @@ -65,6 +66,9 @@ class PinFactory implements shared.PinFactory: if pin2: pin2.close main: + run-test: test + +test: expect-throw "RESTRICTED_PIN": gpio.Pin RESTRICTED pin1 := gpio.Pin PIN1 pin2 := gpio.Pin PIN2 @@ -80,5 +84,3 @@ main: shared.test-configurations pin-factory PIN1 PIN2 pin-factory.close - - print "ALL TESTS PASSED" diff --git a/tests/hw/esp32/i2c-bad.toit b/tests/hw/esp32/i2c-bad.toit index c65f76e47..5a58af65b 100644 --- a/tests/hw/esp32/i2c-bad.toit +++ b/tests/hw/esp32/i2c-bad.toit @@ -13,10 +13,15 @@ import expect show * import gpio import i2c +import .test + SDA-PIN := 2 SCL-PIN := 4 main: + run-test: test + +test: bus := i2c.Bus --sda=gpio.Pin SDA-PIN --scl=gpio.Pin SCL-PIN diff --git a/tests/hw/esp32/i2c-pullup.toit b/tests/hw/esp32/i2c-pullup.toit index 1e60dc374..5915b441b 100644 --- a/tests/hw/esp32/i2c-pullup.toit +++ b/tests/hw/esp32/i2c-pullup.toit @@ -15,11 +15,16 @@ import expect show * import gpio import i2c +import .test + TEST-PIN := 18 OTHER-PIN := 4 MEASURE-PIN := 34 main: + run-test: test + +test: test-pin := gpio.Pin TEST-PIN other-pin := gpio.Pin OTHER-PIN measure-pin := gpio.Pin MEASURE-PIN --input diff --git a/tests/hw/esp32/pin-hold1-board1.toit b/tests/hw/esp32/pin-hold1-board1.toit index 8f675516d..ff6327f93 100644 --- a/tests/hw/esp32/pin-hold1-board1.toit +++ b/tests/hw/esp32/pin-hold1-board1.toit @@ -8,12 +8,16 @@ import monitor import uart import .pin-hold1-shared +import .test /** See 'pin-hold1-shared.toit'. */ main: + run-test: test + +test: port := uart.Port --rx=gpio.Pin PIN-FREE-AND-UNUSED --tx=gpio.Pin PIN-OUT @@ -65,4 +69,3 @@ main: expect (duration.in-ms > 250) channel.send "DONE" - print "done" diff --git a/tests/hw/esp32/pin-hold1-board2.toit b/tests/hw/esp32/pin-hold1-board2.toit index 7f0434d49..54fb67a3f 100644 --- a/tests/hw/esp32/pin-hold1-board2.toit +++ b/tests/hw/esp32/pin-hold1-board2.toit @@ -7,6 +7,7 @@ import esp32 import uart import .pin-hold1-shared +import .test /** See 'pin-hold1-shared.toit'. @@ -25,6 +26,9 @@ disable-hold-deepsleep: #primitive.esp32.deep_sleep_pin_hold_disable main: + run-test --background: test + +test: port := uart.Port --rx=gpio.Pin PIN-IN --tx=gpio.Pin PIN-FREE-AND-UNUSED diff --git a/tests/hw/esp32/pulse-counter.toit b/tests/hw/esp32/pulse-counter.toit index 1f3b7e540..e8fbfaacf 100644 --- a/tests/hw/esp32/pulse-counter.toit +++ b/tests/hw/esp32/pulse-counter.toit @@ -17,6 +17,8 @@ import gpio import pulse-counter import rmt +import .test + IN1 /int ::= 18 IN2 /int ::= 33 @@ -24,6 +26,9 @@ OUT1 /int := 19 OUT2 /int := 26 main: + run-test: test + +test: in := gpio.Pin IN1 out := gpio.Pin OUT1 --output @@ -324,5 +329,3 @@ main: expect-equals 2 unit.value // Up and down. unit.close - - print "all tests done" diff --git a/tests/hw/esp32/pulse-counter2.toit b/tests/hw/esp32/pulse-counter2.toit index a5da9ee34..39655e517 100644 --- a/tests/hw/esp32/pulse-counter2.toit +++ b/tests/hw/esp32/pulse-counter2.toit @@ -11,6 +11,8 @@ import expect show * import gpio import pulse-counter +import .test + IN1 /int ::= 18 IN2 /int ::= 25 @@ -22,6 +24,9 @@ allocate-unit --close/bool=false: unit.close main: + run-test: test + +test: print "Closing correctly" 10.repeat: spawn:: diff --git a/tests/hw/esp32/pwm.toit b/tests/hw/esp32/pwm.toit index d121d9884..babc57ea0 100644 --- a/tests/hw/esp32/pwm.toit +++ b/tests/hw/esp32/pwm.toit @@ -17,6 +17,8 @@ import gpio import pulse-counter import gpio.pwm +import .test + IN1 /int ::= 18 IN2 /int ::= 33 @@ -24,6 +26,9 @@ OUT1 /int := 19 OUT2 /int := 26 main: + run-test: test + +test: // Run several times to make sure we release the resources correctly. 10.repeat: in1 := gpio.Pin IN1 @@ -104,5 +109,3 @@ main: out2.close pulse-unit1.close pulse-unit2.close - - print "all tests done" diff --git a/tests/hw/esp32/rmt-drain-pullup.toit b/tests/hw/esp32/rmt-drain-pullup.toit index af7eab103..45c317892 100644 --- a/tests/hw/esp32/rmt-drain-pullup.toit +++ b/tests/hw/esp32/rmt-drain-pullup.toit @@ -16,15 +16,17 @@ import gpio import monitor import expect show * +import .test + RMT-PIN ::= 18 LEVEL-PIN ::= 19 MEASURE-PIN ::= 34 main: - 2.repeat: - test-no-pull-up --idle-level=it - test-pull-up --idle-level=it - print "All tests passed." + run-test: + 2.repeat: + test-no-pull-up --idle-level=it + test-pull-up --idle-level=it test-no-pull-up --idle-level/int: print "Testing no pull up idle_level=$idle-level" diff --git a/tests/hw/esp32/rmt-many.toit b/tests/hw/esp32/rmt-many.toit index 1ad12586b..679509345 100644 --- a/tests/hw/esp32/rmt-many.toit +++ b/tests/hw/esp32/rmt-many.toit @@ -18,12 +18,17 @@ import gpio import monitor import expect show * +import .test + RMT-PIN-1 ::= 18 RMT-PIN-2 ::= 19 RMT-PIN-3 ::= 21 RMT-PIN-4 ::= 32 main: + run-test: test + +test: pin1 := gpio.Pin RMT-PIN-1 pin2 := gpio.Pin RMT-PIN-2 pin3 := gpio.Pin RMT-PIN-3 diff --git a/tests/hw/esp32/rmt.toit b/tests/hw/esp32/rmt.toit index 3dde4339c..fb56d0f08 100644 --- a/tests/hw/esp32/rmt.toit +++ b/tests/hw/esp32/rmt.toit @@ -18,6 +18,8 @@ import gpio import monitor import expect show * +import .test + RMT-PIN-1 ::= 18 RMT-PIN-2 ::= 19 RMT-PIN-3 ::= 21 @@ -324,6 +326,9 @@ test-multiple-sequences pin-in/gpio.Pin pin-out/gpio.Pin: out.close main: + run-test: test + +test: pin1 := gpio.Pin RMT-PIN-1 pin2 := gpio.Pin RMT-PIN-2 diff --git a/tests/hw/esp32/spi-keep-active.toit b/tests/hw/esp32/spi-keep-active.toit index f5d841014..f747447cf 100644 --- a/tests/hw/esp32/spi-keep-active.toit +++ b/tests/hw/esp32/spi-keep-active.toit @@ -18,6 +18,7 @@ import spi import gpio import monitor +import .test CS ::= 21 MISO ::= 12 @@ -37,6 +38,9 @@ class DebugChannel: channel_.send x main: + run-test: test + +test: bus := spi.Bus --clock=gpio.Pin SCK --miso=gpio.Pin MISO @@ -88,5 +92,3 @@ main: in.close device.close bus.close - - print "Test finished successfully" diff --git a/tests/hw/esp32/test.toit b/tests/hw/esp32/test.toit new file mode 100644 index 000000000..29c895fa9 --- /dev/null +++ b/tests/hw/esp32/test.toit @@ -0,0 +1,11 @@ +// 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. + +ALL-TESTS-DONE ::= "All tests done." + +run-test --background/bool=false [block]: + // Background tests don't block the succesful completion of the tests. + if background: print ALL-TESTS-DONE + block.call + if not background: print ALL-TESTS-DONE diff --git a/tests/hw/esp32/uart-baud-rate.toit b/tests/hw/esp32/uart-baud-rate.toit index 13be19f71..2bd27e04e 100644 --- a/tests/hw/esp32/uart-baud-rate.toit +++ b/tests/hw/esp32/uart-baud-rate.toit @@ -14,6 +14,8 @@ import expect show * import gpio import uart +import .test + RX1 := 18 TX1 := 26 RX2 := 33 @@ -25,6 +27,9 @@ expect-baud expected/int actual/int: expect (expected - 5) <= actual <= (expected + 5) main: + run-test: test + +test: port1 := uart.Port --rx=gpio.Pin RX1 --tx=gpio.Pin TX1 @@ -58,7 +63,5 @@ main: bytes = port1.in.read expect-equals "tiger" bytes.to-string - print "done" - port1.close port2.close diff --git a/tests/hw/esp32/uart-big-data-board1.toit b/tests/hw/esp32/uart-big-data-board1.toit index 33af32493..7f1d0744d 100644 --- a/tests/hw/esp32/uart-big-data-board1.toit +++ b/tests/hw/esp32/uart-big-data-board1.toit @@ -15,7 +15,12 @@ import system show platform import uart import .uart-big-data-shared +import .test + main: + run-test: test + +test: port/uart.Port := ? if platform == system.PLATFORM-FREERTOS: port = uart.Port --rx=(gpio.Pin RX) --tx=null --baud-rate=BAUD-RATE @@ -33,4 +38,3 @@ main: break port.close - print "done" diff --git a/tests/hw/esp32/uart-big-data-board2.toit b/tests/hw/esp32/uart-big-data-board2.toit index 57afcbbe2..748d29cd3 100644 --- a/tests/hw/esp32/uart-big-data-board2.toit +++ b/tests/hw/esp32/uart-big-data-board2.toit @@ -15,8 +15,12 @@ import system show platform import uart import .uart-big-data-shared +import .test main: + run-test: test + +test: port/uart.Port := ? if platform == system.PLATFORM-FREERTOS: port = uart.Port --rx=null --tx=(gpio.Pin TX) --baud-rate=BAUD-RATE diff --git a/tests/hw/esp32/uart-flush.toit b/tests/hw/esp32/uart-flush.toit index 00a3554b6..a2e906f3a 100644 --- a/tests/hw/esp32/uart-flush.toit +++ b/tests/hw/esp32/uart-flush.toit @@ -14,12 +14,17 @@ import expect show * import gpio import uart +import .test + RX1 := 18 TX1 := 26 RX2 := 33 TX2 := 19 main: + run-test: test + +test: succeeded := false pin-rx1 := gpio.Pin RX1 pin-tx1 := gpio.Pin TX1 diff --git a/tests/hw/esp32/uart-flush2-board1.toit b/tests/hw/esp32/uart-flush2-board1.toit index b7e991be7..8891c9aca 100644 --- a/tests/hw/esp32/uart-flush2-board1.toit +++ b/tests/hw/esp32/uart-flush2-board1.toit @@ -16,10 +16,15 @@ Run uart-flush2-board1.toit on one ESP32 and uart-flush2-board2.toit on the othe import gpio import uart +import .test + RX ::= 22 SIGNAL ::= 23 main: + run-test: test + +test: rx := gpio.Pin RX --input --pull-up signal := gpio.Pin SIGNAL --input --pull-up diff --git a/tests/hw/esp32/uart-flush2-board2.toit b/tests/hw/esp32/uart-flush2-board2.toit index 8024d750b..bca2e69de 100644 --- a/tests/hw/esp32/uart-flush2-board2.toit +++ b/tests/hw/esp32/uart-flush2-board2.toit @@ -9,10 +9,15 @@ See uart-flush2-board1.toit. import gpio import uart +import .test + TX ::= 23 SIGNAL ::= 22 main: + run-test: test + +test: tx := gpio.Pin TX port := uart.Port --tx=tx --rx=null --baud-rate=9600 diff --git a/tests/hw/esp32/uart-io-data-shared.toit b/tests/hw/esp32/uart-io-data-shared.toit index 3a33d35c0..1761efbcc 100644 --- a/tests/hw/esp32/uart-io-data-shared.toit +++ b/tests/hw/esp32/uart-io-data-shared.toit @@ -22,6 +22,8 @@ import system import system.firmware import uart +import .test + RX ::= 22 TX ::= 23 BAUD-RATE ::= 115200 @@ -48,6 +50,9 @@ class FwData implements io.Data: mapping.copy --into=ba (from_ + from) (from_ + to) main-board1: + run-test: test-board1 + +test-board1: port := uart.Port --rx=(gpio.Pin RX) --tx=null --baud-rate=BAUD-RATE hasher := md5.Md5 @@ -71,9 +76,11 @@ main-board1: expect-equals expected-hash hash port.close - print "done" main-board2: + run-test: test-board2 + +test-board2: port := uart.Port --rx=(gpio.Pin RX) --tx=(gpio.Pin TX) --baud-rate=BAUD-RATE firmware.map: | mapping/firmware.FirmwareMapping | @@ -95,4 +102,3 @@ main-board2: // we would otherwise lose buffered data. sleep --ms=500 port.close - print "done" diff --git a/tests/hw/esp32/uart-no-garbage-rs485.toit b/tests/hw/esp32/uart-no-garbage-rs485.toit index 13b7580bc..7d4389a45 100644 --- a/tests/hw/esp32/uart-no-garbage-rs485.toit +++ b/tests/hw/esp32/uart-no-garbage-rs485.toit @@ -6,6 +6,8 @@ import expect show * import gpio import uart +import .test + /** Tests that the UART buffer doesn't start with garbage in it when initialized as rs485 half-duplex. @@ -16,6 +18,9 @@ Setup: */ main: + run-test: test + +test: rx := gpio.Pin 16 rts := gpio.Pin 23 port := uart.Port diff --git a/tests/hw/esp32/uart-no-garbage.toit b/tests/hw/esp32/uart-no-garbage.toit index f3794bde2..becb6023c 100644 --- a/tests/hw/esp32/uart-no-garbage.toit +++ b/tests/hw/esp32/uart-no-garbage.toit @@ -6,6 +6,8 @@ import expect show * import gpio import uart +import .test + /** Tests that the UART buffer doesn't start with garbage in it. @@ -15,6 +17,9 @@ Setup: */ main: + run-test: test + +test: rx := gpio.Pin 16 port := uart.Port --rx=rx --tx=null --baud-rate=9600 expect-throw DEADLINE-EXCEEDED-ERROR: diff --git a/tests/hw/esp32/uart-no-garbage500.toit b/tests/hw/esp32/uart-no-garbage500.toit index 0a011c61e..6880345bf 100644 --- a/tests/hw/esp32/uart-no-garbage500.toit +++ b/tests/hw/esp32/uart-no-garbage500.toit @@ -6,6 +6,8 @@ import expect show * import gpio import uart +import .test + /** Tests that the UART buffer doesn't start with garbage in it. @@ -15,6 +17,9 @@ Setup: */ main: + run-test: test + +test: rx := gpio.Pin 16 port := uart.Port --rx=rx --tx=null --baud-rate=500 expect-throw DEADLINE-EXCEEDED-ERROR: diff --git a/tests/hw/esp32/uart-rs485-board1.toit b/tests/hw/esp32/uart-rs485-board1.toit index 3a999e42d..28d36ae4a 100644 --- a/tests/hw/esp32/uart-rs485-board1.toit +++ b/tests/hw/esp32/uart-rs485-board1.toit @@ -5,6 +5,7 @@ import gpio import uart +import .test import .uart-rs485-shared /** @@ -22,6 +23,9 @@ RX ::= 22 TX ::= 16 // Unused. main: + run-test: test + +test: rx := gpio.Pin RX tx := gpio.Pin TX rts := gpio.Pin RTS diff --git a/tests/hw/esp32/uart-rs485-board2.toit b/tests/hw/esp32/uart-rs485-board2.toit index aba00d321..7a7b34199 100644 --- a/tests/hw/esp32/uart-rs485-board2.toit +++ b/tests/hw/esp32/uart-rs485-board2.toit @@ -5,14 +5,19 @@ import gpio import uart -import .uart-rs485-shared import gpio import uart +import .test +import .uart-rs485-shared + RTS ::= 22 TX ::= 23 main: + run-test: test + +test: rts := gpio.Pin --input RTS --pull-down tx := gpio.Pin TX @@ -25,5 +30,3 @@ main: while rts.get == 0: while rts.get == 1: port.out.write RESPONSE-MESSAGE - - print "done" diff --git a/tests/hw/esp32/uart-small-data-shared.toit b/tests/hw/esp32/uart-small-data-shared.toit index 17dc9b063..4cfb924d4 100644 --- a/tests/hw/esp32/uart-small-data-shared.toit +++ b/tests/hw/esp32/uart-small-data-shared.toit @@ -22,6 +22,8 @@ import system import system.firmware import uart +import .test + RX ::= 22 TX ::= 23 BAUD-RATE ::= 115200 @@ -30,6 +32,9 @@ REPETITIONS ::= 1 ACK-BYTE ::= 99 main-board1: + run-test: test-board1 + +test-board1: rx := gpio.Pin RX tx := gpio.Pin TX REPETITIONS.repeat: @@ -41,9 +46,11 @@ main-board1: received += port.in.read.size port.out.write-byte ACK-BYTE port.close - print "done" main-board2: + run-test: test-board2 + +test-board2: rx := gpio.Pin RX tx := gpio.Pin TX REPETITIONS.repeat: @@ -57,4 +64,3 @@ main-board2: ack := port.in.read-byte expect-equals 99 ACK-BYTE port.close - print "done" diff --git a/tests/hw/esp32/ultrasound.toit b/tests/hw/esp32/ultrasound.toit index d105386b7..709f20161 100644 --- a/tests/hw/esp32/ultrasound.toit +++ b/tests/hw/esp32/ultrasound.toit @@ -2,14 +2,22 @@ // Use of this source code is governed by a Zero-Clause BSD license that can // be found in the tests/LICENSE file. +import expect show * import gpio import hc-sr04 +import .test + main: + run-test: test + +test: echo := gpio.Pin.in 19 trigger := gpio.Pin.out 18 driver := hc-sr04.Driver --echo=echo --trigger=trigger - while true: - print "The distance is: $driver.read-distance mm" - sleep --ms=2_000 + 5.repeat: + distance := driver.read-distance + // Requires the board to be pointing towards a wall with at most 1m distance. + expect 0 < distance < 1000 + sleep --ms=200 diff --git a/tests/hw/esp32/wait-for-close.toit b/tests/hw/esp32/wait-for-close.toit index ebba4263a..968c4153e 100644 --- a/tests/hw/esp32/wait-for-close.toit +++ b/tests/hw/esp32/wait-for-close.toit @@ -4,6 +4,8 @@ import gpio +import .test + /** Tests the $gpio.Pin.wait-for functionality while a parallel task closes the pin. @@ -15,6 +17,9 @@ Tests the $gpio.Pin.wait-for functionality while a parallel PIN-IN ::= 34 main: + run-test: test + +test: pin-in := gpio.Pin PIN-IN --input task:: @@ -24,5 +29,3 @@ main: print "waiting for pin to go high" pin-in.wait-for 1 - - print "done" diff --git a/tests/hw/esp32/wait-for1-board1.toit b/tests/hw/esp32/wait-for1-board1.toit index 81c7ed118..69f4dbd77 100644 --- a/tests/hw/esp32/wait-for1-board1.toit +++ b/tests/hw/esp32/wait-for1-board1.toit @@ -5,6 +5,8 @@ import gpio import monitor import rmt + +import .test import .wait-for1-shared /** @@ -14,6 +16,9 @@ See 'wait-for1-shared.toit'. MEDIUM-PULSE-DURATION-MS ::= 5 main: + run-test: test + +test: pin-in := gpio.Pin PIN-IN --input --pull-down pin-out := gpio.Pin PIN-OUT --output @@ -62,5 +67,3 @@ main: ULTRA-SHORT-PULSE-ITERATIONS.repeat: sleep --ms=10 channel.write signals - - print "done" diff --git a/tests/hw/esp32/wait-for1-board2.toit b/tests/hw/esp32/wait-for1-board2.toit index 8ea3d9c48..787364a80 100644 --- a/tests/hw/esp32/wait-for1-board2.toit +++ b/tests/hw/esp32/wait-for1-board2.toit @@ -5,6 +5,8 @@ import expect show * import gpio import monitor + +import .test import .wait-for1-shared /** @@ -12,6 +14,9 @@ See 'wait-for1-shared.toit'. */ main: + run-test: test + +test: pin-in := gpio.Pin PIN-IN --input pin-out := gpio.Pin PIN-OUT --output @@ -66,4 +71,3 @@ main: pin-out.set 1 sleep --ms=100 // Give wait_for1 time to see the last 0. - print "done"