mirror of
https://gitlab.com/riglol/rigolee/hdo-tools.git
synced 2025-04-29 02:37:20 +09:00
See https://www.eevblog.com/forum/testgear/hacking-the-hdo1khdo4k-rigol-12-bit-scope/msg4501300/#msg4501300 Signed-off-by: Olliver Schinagl <oliver@schinagl.nl>
199 lines
4.5 KiB
Go
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:])
|
|
}
|