package autotest import ( "fmt" "os" "os/exec" "time" ) const defaultResetWaitMS = 2000 // ResetESP32 toggles EN via esptool (USB-JTAG / ttyACM console port). func ResetESP32(port string) error { if port == "" { return fmt.Errorf("empty console port") } tries := [][]string{ {"python", "-m", "esptool", "--chip", "esp32s3", "-p", port, "--before", "default_reset", "--after", "hard_reset", "chip_id"}, {"esptool.py", "--chip", "esp32s3", "-p", port, "--before", "default_reset", "--after", "hard_reset", "chip_id"}, {"esptool", "--chip", "esp32s3", "-p", port, "--before", "default_reset", "--after", "hard_reset", "chip_id"}, } var lastErr error for _, argv := range tries { if _, err := exec.LookPath(argv[0]); err != nil { lastErr = err continue } cmd := exec.Command(argv[0], argv[1:]...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { lastErr = err continue } return nil } if lastErr != nil { return fmt.Errorf("esptool reset on %s: %w (install ESP-IDF esptool or python -m esptool)", port, lastErr) } return fmt.Errorf("esptool not found; cannot reset %s", port) } func (b *Bench) resetNode(target string) (string, error) { switch target { case "master", "": if b.UART.MasterConsole == "" { return "", fmt.Errorf("uart.master_console not set in config %q", b.ID) } return b.UART.MasterConsole, nil default: s, err := b.Slave(target) if err != nil { return "", err } if s.Console == "" { return "", fmt.Errorf("slave %q has no console port in config", target) } return s.Console, nil } } func (b *Bench) ResetTargets(targets []string, waitMS int) error { if waitMS <= 0 { waitMS = defaultResetWaitMS } if len(targets) == 0 { targets = []string{"master"} } for _, t := range targets { port, err := b.resetNode(t) if err != nil { return err } if err := ResetESP32(port); err != nil { return err } time.Sleep(time.Duration(waitMS) * time.Millisecond) } return nil } func (b *Bench) ResetAll(waitMS int) error { // Slaves first, master last — master discover runs after slaves are booting. var targets []string for i := range b.Slaves { if b.Slaves[i].Console != "" { targets = append(targets, b.Slaves[i].ID) } } if b.UART.MasterConsole != "" { targets = append(targets, "master") } if len(targets) == 0 { return fmt.Errorf("config %q: no console ports defined for reset", b.ID) } return b.ResetTargets(targets, waitMS) }