Files
parchment/device.go
T

106 lines
2.3 KiB
Go

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
}
// ExitDevMode sends the command to exit dev mode.
func (d *Device) ExitDevMode() error {
if !d.Connected || d.Port == nil {
return fmt.Errorf("device not connected")
}
// Send exit dev mode command
// TODO: Replace with the actual command sequence to exit dev mode
// This is currently not implemented on the Cardputer side.
return nil
}
// Close closes the serial port.
func (d *Device) Close() error {
if d.Port != nil {
// Try to exit dev mode before closing
_ = d.ExitDevMode()
// Allow some time for the command to be processed
time.Sleep(100 * time.Millisecond)
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)
}