116 lines
2.1 KiB
Go
116 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"sync"
|
|
"time"
|
|
|
|
"go.bug.st/serial"
|
|
)
|
|
|
|
const portDev = "/dev/ttyUSB0"
|
|
|
|
func main() {
|
|
dbg, err := Open()
|
|
if err != nil {
|
|
log.Fatalf("connecting to debugger: %v", err)
|
|
}
|
|
defer dbg.Close()
|
|
|
|
if err := dbg.Write(0x42, 123); err != nil {
|
|
log.Fatalf("writing to memory: %v", err)
|
|
}
|
|
|
|
if err := UI(dbg); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
type Debugger struct {
|
|
port serial.Port
|
|
mu sync.Mutex
|
|
}
|
|
|
|
func Open() (*Debugger, error) {
|
|
mode := &serial.Mode{
|
|
BaudRate: 115_200,
|
|
}
|
|
port, err := serial.Open(portDev, mode)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Debugger{port: port}, nil
|
|
}
|
|
|
|
func (d *Debugger) Close() error {
|
|
d.mu.Lock() // note, deliberately no unlocking, to poison.
|
|
return d.port.Close()
|
|
}
|
|
|
|
func encode(addr int, write bool, data byte) [4]byte {
|
|
writeVal := uint8(0)
|
|
if write {
|
|
writeVal = 1
|
|
}
|
|
var ret [4]byte
|
|
ret[3] = data
|
|
ret[2] = byte(addr<<1) | writeVal
|
|
ret[1] = byte(addr >> 7)
|
|
ret[0] = byte(addr >> 15)
|
|
return ret
|
|
}
|
|
|
|
func (d *Debugger) Read(addr int) (byte, error) {
|
|
d.mu.Lock()
|
|
defer d.mu.Unlock()
|
|
if addr >= 2<<17 {
|
|
return 0, fmt.Errorf("read %d out of bounds", addr)
|
|
}
|
|
|
|
packet := encode(addr, false, 0)
|
|
//fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3])
|
|
if _, err := d.port.Write(packet[:]); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
d.port.SetReadTimeout(2 * time.Second)
|
|
|
|
n, err := d.port.Read(packet[:1])
|
|
if err != nil {
|
|
return 0, err
|
|
} else if n == 0 {
|
|
return 0, errors.New("no read")
|
|
}
|
|
return packet[0], nil
|
|
}
|
|
|
|
func (d *Debugger) Write(addr int, val byte) error {
|
|
d.mu.Lock()
|
|
defer d.mu.Unlock()
|
|
if addr >= 2<<17 {
|
|
return fmt.Errorf("write %d out of bounds", addr)
|
|
}
|
|
|
|
packet := encode(addr, true, val)
|
|
//fmt.Printf("Writing: %02x %02x %02x %02x\n", packet[0], packet[1], packet[2], packet[3])
|
|
if _, err := d.port.Write(packet[:]); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (d *Debugger) Dump(startAddr int, count int) ([]byte, error) {
|
|
ret := make([]byte, count)
|
|
var err error
|
|
for i := range ret {
|
|
ret[i], err = d.Read(startAddr + i)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return ret, nil
|
|
}
|