diff --git a/fRAMdump.go b/fRAMdump.go new file mode 100644 index 0000000..602770d --- /dev/null +++ b/fRAMdump.go @@ -0,0 +1,198 @@ +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:]) +}