powerpods/goTool/main.go
simon bde4c473ef Add Go UART tool to query firmware VERSION over serial.
Framed protobuf client for /dev/ttyUSB0 at 921600 baud with generated
uart_messages types matching the device protocol.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-18 22:06:58 +02:00

91 lines
1.9 KiB
Go

package main
import (
"flag"
"fmt"
"log"
"os"
"time"
"go.bug.st/serial"
"google.golang.org/protobuf/proto"
"powerpod/gotool/pb"
uartframe "powerpod/gotool/uart"
)
const (
defaultBaud = 921600
versionCmdID = byte(pb.MessageType_VERSION)
readTimeout = 3 * time.Second
)
func main() {
portName := flag.String("port", "", "serial port (e.g. /dev/ttyUSB0)")
baud := flag.Int("baud", defaultBaud, "UART baud rate")
flag.Parse()
if *portName == "" {
fmt.Fprintln(os.Stderr, "usage: gotool -port /dev/ttyUSB0")
flag.PrintDefaults()
os.Exit(2)
}
mode := &serial.Mode{
BaudRate: *baud,
DataBits: 8,
Parity: serial.NoParity,
StopBits: serial.OneStopBit,
}
port, err := serial.Open(*portName, mode)
if err != nil {
log.Fatalf("open serial: %v", err)
}
defer port.Close()
if err := port.SetReadTimeout(readTimeout); err != nil {
log.Fatalf("set read timeout: %v", err)
}
frame, err := uartframe.EncodeFrame([]byte{versionCmdID})
if err != nil {
log.Fatalf("encode frame: %v", err)
}
log.Printf("sending VERSION command (%d bytes): % x", len(frame), frame)
if _, err := port.Write(frame); err != nil {
log.Fatalf("write: %v", err)
}
payload, err := uartframe.ReadFrame(port, nil)
if err != nil {
log.Fatalf("read response: %v", err)
}
log.Printf("response payload (%d bytes): % x", len(payload), payload)
if len(payload) == 0 {
log.Fatal("empty response payload")
}
if payload[0] != versionCmdID {
log.Fatalf("unexpected command id 0x%02x (want 0x%02x)", payload[0], versionCmdID)
}
var msg pb.UartMessage
if err := proto.Unmarshal(payload[1:], &msg); err != nil {
log.Fatalf("decode protobuf: %v", err)
}
if msg.GetType() != pb.MessageType_VERSION {
log.Fatalf("unexpected message type %v", msg.GetType())
}
ver := msg.GetVersionResponse()
if ver == nil {
log.Fatal("response missing version_response")
}
fmt.Printf("version: %d\n", ver.GetVersion())
fmt.Printf("git_hash: %s\n", ver.GetGitHash())
}