hdo-tools/fRAMdump.go
2022-11-10 16:14:51 +01:00

199 lines
4.5 KiB
Go

package main
// build using
// GOOS=linux GOARCH=arm64 go build fRAMdump.go
import (
"bytes"
"compress/zlib"
"encoding/binary"
"fmt"
i2c "github.com/d2r2/go-i2c"
logger "github.com/d2r2/go-logger"
"hash/crc32"
"io/ioutil"
"log"
"os"
"strings"
"unicode"
)
func HexString(data []byte) string {
var buf bytes.Buffer
for i := 0; i < len(data)-1; i++ {
buf.WriteString(fmt.Sprintf("%02X ", data[i]))
}
buf.WriteString(fmt.Sprintf("%02X", data[len(data)-1]))
return buf.String()
}
func pstr(s []uint8) string {
return strings.Map(func(r rune) rune {
if unicode.IsPrint(r) {
return r
}
return '∿'
}, string(s))
}
func HexStringHdrN(data []byte, hdr string, N int) string {
var buf bytes.Buffer
NN := len(data)
for i := 0; i < len(data); {
t := NN
if t > N {
t = N
}
NN -= t
buf.WriteString(hdr)
for j := 0; j < t-1; j++ {
buf.WriteString(fmt.Sprintf("%02X ", data[i+j]))
}
buf.WriteString(fmt.Sprintf("%02X", data[i+t-1]))
if t < N {
for j := t; j < N; j++ {
buf.WriteString(" ")
}
}
buf.WriteString(" ")
buf.WriteString(pstr(data[i : i+t]))
buf.WriteString("\n")
i += t
}
return buf.String()
}
func dumpSystemSetup(data []uint8) {
crc1 := binary.LittleEndian.Uint32(data)
l := binary.LittleEndian.Uint32(data[4:])
crc2 := crc32.ChecksumIEEE(data[8 : 8+int(l)])
if crc1 != crc2 {
fmt.Printf("system setup crc error %x %x\n", crc1, crc2)
return
}
i := 8
fmt.Printf("System setup:\n")
fmt.Printf("\tLanguage: %x\n", data[i+1])
fmt.Printf("\tLoadLast: %x\n", data[i+2])
fmt.Printf("\tPowerStatus: %x\n", data[i+3])
fmt.Printf("\tGPIB: %x\n", data[i+4])
fmt.Printf("\tCycle count: %x\n", binary.LittleEndian.Uint64(data[i+5:]))
fmt.Printf("\tLive count: %d\n", binary.LittleEndian.Uint32(data[i+13:]))
fmt.Printf("\tKeep Imp: %x\n", data[i+17])
fmt.Printf("\tIPmode: %x\n\n", data[i+18])
}
func dumpMemFile(data []uint8) {
h1 := binary.LittleEndian.Uint32(data)
h2 := binary.LittleEndian.Uint32(data[4:])
if 0 != h1+h2 {
fmt.Printf("mem file header error %x %x\n", h1, h2)
return
}
for i := 8; i < len(data); {
id := binary.LittleEndian.Uint32(data[i:])
idn := binary.LittleEndian.Uint32(data[i+0x4:])
l := binary.LittleEndian.Uint32(data[i+0x8:])
ln := binary.LittleEndian.Uint32(data[i+0xC:])
if 0 != id+idn {
fmt.Printf("mem file id error %x %x\n", id, idn)
return
}
if 0 != l+ln {
fmt.Printf("mem file size error %x %x\n", l, ln)
return
}
if 0 == l {
return
}
i += 0x10
crc1 := binary.LittleEndian.Uint32(data[i:])
i += 0x4
crc2 := crc32.ChecksumIEEE(data[i : i+int(l)])
if crc1 != crc2 {
fmt.Printf("mem file crc error %x %x\n", crc1, crc2)
return
}
if l < 32 {
fmt.Printf("id:%04x data[%02x]:%v\n\n", id, l, HexString(data[i:i+int(l)]))
} else {
fmt.Printf("id:%04x data[%02x]:\n%v\n", id, l, HexStringHdrN(data[i:i+int(l)], "\t", 32))
}
i += int(l)
}
}
func dumpBinSetup(data []uint8) {
crc1 := binary.LittleEndian.Uint32(data)
l := binary.LittleEndian.Uint32(data[4:])
crc2 := crc32.ChecksumIEEE(data[8 : 8+int(l)])
if crc1 != crc2 {
fmt.Printf("setup data crc error %x %x\n", crc1, crc2)
return
}
l += 8
for i := 8; i < int(l); {
id := data[i]
i++
uncomp := data[i]
i++
x1 := data[i]
i++
x2 := data[i]
i++
dlen := int(binary.LittleEndian.Uint16(data[i:]))
i += 2
clen := int(binary.LittleEndian.Uint16(data[i:]))
i += 2
alen := int(binary.LittleEndian.Uint16(data[i:]))
i += 2
x3 := binary.LittleEndian.Uint16(data[i:])
i += 2
bd := data[i : i+clen]
if uncomp == 0 {
zr, err := zlib.NewReader(bytes.NewReader(bd))
if err != nil {
fmt.Printf("zlib error %v\n", err)
return
}
bd = make([]uint8, dlen)
n, err := zr.Read(bd)
if n != dlen {
i += alen
fmt.Printf("read %x %v\n", n, err)
continue
}
zr.Close()
}
fmt.Printf("ID:%02X,%02X,%02X,%X dlen:%3x clen:%3x alen:%3x\n%v\n", id, x1, x2, x3, dlen, clen, alen, HexStringHdrN(bd, "\t", 32))
i += alen
}
}
func main() {
logger.ChangePackageLogLevel("i2c", logger.InfoLevel)
i2c, err := i2c.NewI2C(0x50, 4)
if err != nil {
log.Fatal(err)
}
defer i2c.Close()
fmt.Printf("i2c ready\n")
_, err = i2c.WriteBytes([]byte{0x00, 0x00})
if err != nil {
log.Fatal(err)
}
buf := make([]uint8, 0x2000)
n, err := i2c.ReadBytes(buf)
if err != nil {
log.Fatal(err)
}
fmt.Printf("data[%x] %v\n", n, HexString(buf[:16]))
ioutil.WriteFile("fram.bin", buf, os.ModePerm)
dumpSystemSetup(buf[0:0x100])
dumpMemFile(buf[0x100:0x800])
dumpBinSetup(buf[0x800:])
}