package main import ( "fmt" "time" "go.bug.st/serial" "go.bug.st/serial/enumerator" ) // Device manages the serial connection to the Cardputer. type Device struct { PortName string Port serial.Port Connected bool } // NewDevice creates a new Device instance. func NewDevice() *Device { return &Device{} } // FindCardputer searches for a connected Cardputer by VID. func (d *Device) FindCardputer() (string, error) { ports, err := enumerator.GetDetailedPortsList() if err != nil { return "", err } for _, port := range ports { if port.VID == "303a" { // Cardputer VID d.PortName = port.Name return port.Name, nil } } return "", fmt.Errorf("Cardputer not found") } // Connect opens the serial port and requests dev mode. func (d *Device) Connect() error { if d.PortName == "" { return fmt.Errorf("no port name set") } mode := &serial.Mode{ BaudRate: 115200, } port, err := serial.Open(d.PortName, mode) if err != nil { return fmt.Errorf("failed to open port: %w", err) } d.Port = port d.Connected = true // Send dev mode request // 0xAA 0x04 0x00 0x00 0x00 is the command sequence for dev mode _, err = d.Port.Write([]byte{0xAA, 0x04, 0x00, 0x00, 0x00}) if err != nil { d.Close() return fmt.Errorf("failed to send dev mode request: %w", err) } // Allow some time for the device to respond or settle if needed time.Sleep(100 * time.Millisecond) return nil } // Close closes the serial port. func (d *Device) Close() error { if d.Port != nil { err := d.Port.Close() d.Port = nil d.Connected = false return err } return nil } // Write sends data to the device. func (d *Device) Write(data []byte) (int, error) { if !d.Connected || d.Port == nil { return 0, fmt.Errorf("device not connected") } return d.Port.Write(data) }