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()) }