Refactor into version/clients subcommands with shared serial framing to list registered slaves from the master over UART. Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"go.bug.st/serial"
|
|
uartframe "powerpod/gotool/uart"
|
|
)
|
|
|
|
const readTimeout = 3 * time.Second
|
|
|
|
type serialPort struct {
|
|
port serial.Port
|
|
}
|
|
|
|
func openSerial(portName string, baud int) (*serialPort, error) {
|
|
mode := &serial.Mode{
|
|
BaudRate: baud,
|
|
DataBits: 8,
|
|
Parity: serial.NoParity,
|
|
StopBits: serial.OneStopBit,
|
|
}
|
|
|
|
port, err := serial.Open(portName, mode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := port.SetReadTimeout(readTimeout); err != nil {
|
|
port.Close()
|
|
return nil, err
|
|
}
|
|
return &serialPort{port: port}, nil
|
|
}
|
|
|
|
func (s *serialPort) Close() error {
|
|
return s.port.Close()
|
|
}
|
|
|
|
func (s *serialPort) exchange(cmdID byte, cmdName string) ([]byte, error) {
|
|
frame, err := uartframe.EncodeFrame([]byte{cmdID})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("encode frame: %w", err)
|
|
}
|
|
|
|
log.Printf("sending %s command (%d bytes): % x", cmdName, len(frame), frame)
|
|
if _, err := s.port.Write(frame); err != nil {
|
|
return nil, fmt.Errorf("write: %w", err)
|
|
}
|
|
|
|
payload, err := uartframe.ReadFrame(s.port, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read response: %w", err)
|
|
}
|
|
|
|
log.Printf("response payload (%d bytes): % x", len(payload), payload)
|
|
if len(payload) == 0 {
|
|
return nil, fmt.Errorf("empty response payload")
|
|
}
|
|
if payload[0] != cmdID {
|
|
return nil, fmt.Errorf("unexpected command id 0x%02x (want 0x%02x)", payload[0], cmdID)
|
|
}
|
|
return payload, nil
|
|
}
|