saleae

package module
v0.0.0-...-72cbd6e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2023 License: MIT Imports: 13 Imported by: 1

README

saleae

Tools to work with Saleae's Logic 2 software.

SPI Analyzer

The SPI analyzer under analyzers extends the functionality of the provided SPI protocol analyzer in the Logic 2 software. It will group transactions using the enable signal. This is key to working with devices that communicate on an enable-line toggle basis such as the CYW43439 and other, if not most, SPI devices.

An example on how to use it can be found under examples_test.go

Documentation

Index

Examples

Constants

View Source
const (
	FileTypeDigital = 0
	FileTypeAnalog  = 1
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AnalogFile

type AnalogFile struct {
	Header AnalogHeader
	// Voltage readings.
	Data []float64
}

func ReadAnalogFile

func ReadAnalogFile(r io.Reader) (*AnalogFile, error)

ReadAnalogFile reads a Logic 2 version 0 Saleae analog binary capture file.

func (*AnalogFile) WriteTo

func (af *AnalogFile) WriteTo(w io.Writer) (int64, error)

WriteTo writes the file to w.

type AnalogHeader

type AnalogHeader struct {
	Info       FileHeader
	Begin      float64
	SampleRate uint64
	Downsample uint64
	NumSamples uint64
}

type Capture

type Capture struct {
	CaptureStart time.Time
	AnalogFiles  []AnalogFile
	DigitalFiles []DigitalFile
}

func ReadCapture

func ReadCapture(r io.ReaderAt, size int64) (*Capture, error)

ReadCapture reads a capture from a reader in .sal format. The reader must be seekable.

func ReadCaptureFile

func ReadCaptureFile(path string) (*Capture, error)

ReadCaptureFile reads a capture from a file in .sal format.

Example
package main

import (
	"fmt"
	"log"
	"os"
	"time"

	"github.com/soypat/saleae"
)

func main() {
	startprog := time.Now()
	defer func() {
		fmt.Fprintln(os.Stderr, "elapsed:", time.Since(startprog))
	}()
	cap, err := saleae.ReadCaptureFile("testdata/sx1278_pico.sal")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("capture time:", cap.CaptureStart.Format(time.Stamp))
	for i := range cap.DigitalFiles {
		fmt.Println("digital file version:", cap.DigitalFiles[i].Header.Info.Version)
	}
	
Output:

type DigitalFile

type DigitalFile struct {
	Header DigitalHeader
	// Times at which transitions happened
	Data []float64
}

DigitalFile is a version 0 Saleae digital binary capture file.

Example (Spi)
package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"os"
	"time"

	"github.com/soypat/saleae"
	"github.com/soypat/saleae/analyzers"
)

func main() {
	startprog := time.Now()
	defer func() {
		fmt.Fprintln(os.Stderr, "elapsed:", time.Since(startprog))
	}()
	const (
		clockFile  = "testdata/digital_spiclk.bin"
		enableFile = "testdata/digital_spienable.bin"
		sdoFile    = "testdata/digital_spisdo.bin"
		sdiFile    = "testdata/digital_spisdi.bin"
	)
	fp, _ := os.Open(clockFile)
	clock, err := saleae.ReadDigitalFile(fp)
	if err != nil {
		panic(err)
	}
	fp.Close()
	fp, _ = os.Open(enableFile)
	enable, err := saleae.ReadDigitalFile(fp)
	if err != nil {
		panic(err)
	}
	fp.Close()
	fp, _ = os.Open(sdoFile)
	sdo, err := saleae.ReadDigitalFile(fp)
	if err != nil {
		panic(err)
	}
	fp.Close()
	fp, _ = os.Open(sdiFile)
	sdi, err := saleae.ReadDigitalFile(fp)
	if err != nil {
		panic(err)
	}
	fp.Close()
	spi := analyzers.SPI{}
	txs, _ := spi.Scan(clock, enable, sdo, sdi)
	// report, _ := os.Create("report.txt")
	// defer report.Close()
	report := os.Stdout
	var accumulativeResults int
	for i := 0; i < len(txs); i++ {
		tx := txs[i]
		if len(tx.SDO) < 4 {
			panic("too short exchange for cyw43439!")
		}
		cmd, data := CommandFromBytes(tx.SDO)
		for j := i + 1; j < len(txs); j++ {
			accumulativeResults++
			nextcmd, nextdata := CommandFromBytes(txs[j].SDO)
			if nextcmd != cmd || !bytes.Equal(data, nextdata) {
				break
			}
			i = j
		}
		fmt.Fprintf(report, "cmd×%2d %s data=%#x\n", accumulativeResults, cmd.String(), data)
		accumulativeResults = 0
	}
}

type Function uint32

const (
	FuncBus Function = 0b00

	FuncBackplane Function = 0b01

	FuncDMA1 Function = 0b10
	FuncWLAN          = FuncDMA1

	FuncDMA2 Function = 0b11
)

func (f Function) String() (s string) {
	switch f {
	case FuncBus:
		s = "bus"
	case FuncBackplane:
		s = "backplane"
	case FuncWLAN:
		s = "wlan"
	case FuncDMA2:
		s = "dma2"
	default:
		s = "unknown"
	}
	return s
}

type CYW43439Cmd struct {
	Write   bool
	AutoInc bool
	Fn      Function
	Addr    uint32
	Size    uint32
}

func (cmd *CYW43439Cmd) String() string {
	return fmt.Sprintf("addr=%#7x  fn=%9s  sz=%4v write=%5v autoinc=%5v",
		cmd.Addr, cmd.Fn.String(), cmd.Size, cmd.Write, cmd.AutoInc)
}

func CommandFromBytes(b []byte) (cmd CYW43439Cmd, data []byte) {
	_ = b[3]
	command := binary.LittleEndian.Uint32(b)
	cmd.Write = command&(1<<31) != 0
	cmd.AutoInc = command&(1<<30) != 0
	cmd.Fn = Function(command>>28) & 0b11
	cmd.Addr = (command >> 11) & 0x1ffff
	cmd.Size = command & ((1 << 11) - 1)
	data = b[4:]
	if cmd.Fn == FuncBackplane && !cmd.Write && len(data) > 4 {
		data = b[8:]
	}
	return cmd, data
}
Output:

cmd× 1 addr=  0x800  fn=      bus  sz=1184 write=false autoinc=false data=0x03030303
cmd× 1 addr=  0x800  fn=      bus  sz=1184 write=false autoinc=false data=0xbeadfeed
cmd× 1 addr= 0x1800  fn=      bus  sz=1024 write=false autoinc=false data=0x04b30002
cmd× 1 addr=    0x0  fn=      bus  sz=   4 write=false autoinc= true data=0xb3000200
cmd× 1 addr=   0x1d  fn=      bus  sz=   1 write= true autoinc= true data=0x04000000
cmd× 1 addr=    0x4  fn=      bus  sz=   1 write= true autoinc= true data=0x99000000
cmd× 1 addr=    0x6  fn=      bus  sz=   2 write= true autoinc= true data=0xbe000000
cmd× 1 addr=0x1000e  fn=backplane  sz=   1 write= true autoinc= true data=0x08000000
cmd× 1 addr=0x1000e  fn=backplane  sz=   5 write=false autoinc= true data=0x48000040
cmd× 1 addr=0x1000e  fn=backplane  sz=   1 write= true autoinc= true data=0x00000000
cmd× 1 addr=0x1000c  fn=backplane  sz=   1 write= true autoinc= true data=0x18000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x3800  fn=backplane  sz=   5 write=false autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x3800  fn=backplane  sz=   5 write=false autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4800  fn=backplane  sz=   5 write=false autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4800  fn=backplane  sz=   5 write=false autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4800  fn=backplane  sz=   5 write=false autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4800  fn=backplane  sz=   5 write=false autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4408  fn=backplane  sz=   1 write= true autoinc= true data=0x03000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4408  fn=backplane  sz=   5 write=false autoinc= true data=0x03000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4800  fn=backplane  sz=   1 write= true autoinc= true data=0x00000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4408  fn=backplane  sz=   1 write= true autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x10180000
cmd× 1 addr= 0x4408  fn=backplane  sz=   5 write=false autoinc= true data=0x01000000
cmd× 1 addr=0x1000b  fn=backplane  sz=   1 write= true autoinc= true data=0x00180000
cmd× 1 addr= 0xc010  fn=backplane  sz=   4 write= true autoinc= true data=0x03000000
cmd× 1 addr= 0xc044  fn=backplane  sz=   4 write= true autoinc= true data=0x00000000
cmd× 0 addr=0x1e00c  fn=backplane  sz=   1 write= true autoinc= true data=0xffffffff

func ReadDigitalFile

func ReadDigitalFile(r io.Reader) (*DigitalFile, error)

ReadDigitalFile reads a Logic 2 version 0 Saleae digital file.

func (*DigitalFile) WriteTo

func (df *DigitalFile) WriteTo(w io.Writer) (int64, error)

WriteTo writes the digital file to w.

type DigitalHeader

type DigitalHeader struct {
	Info           FileHeader
	InitialState   uint32
	Begin          float64
	End            float64
	NumTransitions uint64
}

type FileHeader

type FileHeader struct {
	Version int32
	Type    FileType
}

func (*FileHeader) Validate

func (fh *FileHeader) Validate() error

type FileType

type FileType int32

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL