---
title: "W5500 Decoder in Logic Analyzer"
url: "https://maker.wiznet.io/louis_m/projects/spi-decoder-in-logic-analyzer/"
markdown_url: "https://maker.wiznet.io/louis_m/projects/spi-decoder-in-logic-analyzer/md"
type: "WCC: WIZnet Created Content"
author: "Louis"
author_url: "https://maker.wiznet.io/louis_m/"
original_author: "Louis"
published: "2025-04-16"
language: "en"
hardware: ["WIZnet W5500"]
likes: 0
views: 1295
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# W5500 Decoder in Logic Analyzer

> A custom protocol plug-in that allows Saleae Logic Analyzer software to decode SPI communication from the WIZnet W5500 Ethernet chip.

Original author: Louis

## Components

- **WIZnet W5500** x 1 ([docs](https://docs.wiznet.io/Product/Chip/Ethernet/W5500))

WIZnet parts: W5500 ([Datasheet](https://docs.wiznet.io/Product/Chip/Ethernet/W5500/datasheet?utm_source=maker&utm_medium=project&utm_campaign=w5500), [product hub](https://maker.wiznet.io/products/w5500/))

## Article

## Getting Started with the Python Extension Decoder in Logic 2

1. Launch Logic 2

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744800053%2Epng)

2. click the Extensions tab

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744800159%2Epng)

3. In the “Create Extension” window that opens, select “High-Level Analyzer”.

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744800175%2Epng)

4. Enter a name of your choice, specify a save location

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744800457%2Epng)

**High Level Analyzer Files**

In your new High Level Analyzer (HLA) extension folder you will find 3 files:

div]:mt-0 [&:is(h3)>div]:mt-0 [&:is(h4)>div]:mt-0 mx-0" style="margin-left:0px;">`README.md`

- Documentation for your extension, shown within Logic 2 when you select an extension, and what users will see if you put your extension on the Marketplace.

div]:mt-0 [&:is(h3)>div]:mt-0 [&:is(h4)>div]:mt-0 mx-0" style="margin-left:0px;">`extension.json`

- Every extension must have this file in its root directory.

- Contains metadata about the extension, and the HLAs and Measurement scripts that are included with the extension.

- See [Extension File Format](https://support.saleae.com/extensions/extension-file-format) for more information.

div]:mt-0 [&:is(h3)>div]:mt-0 [&:is(h4)>div]:mt-0 mx-0" style="margin-left:0px;">`HighLevelAnalyzer.py`

- Python source code for your HLA.

- For the purposes of this document, we will be focusing on `HighLevelAnalyzer.py`

5. You can do this by modifying HighLevelAnalyzer.py as shown below.

**HighLevelAnalyzer.py**

```plaintext
from typing import Optional, Union
from saleae.analyzers import HighLevelAnalyzer, AnalyzerFrame

regs = {
    0x0000: "MR",
    0x0001: "GAR0", 0x0002: "GAR1", 0x0003: "GAR2", 0x0004: "GAR3",
    0x0005: "SUBR0", 0x0006: "SUBR1", 0x0007: "SUBR2", 0x0008: "SUBR3",
    0x0009: "SHAR0", 0x000A: "SHAR1", 0x000B: "SHAR2",
    0x000C: "SHAR3", 0x000D: "SHAR4", 0x000E: "SHAR5",
    0x000F: "SIPR0", 0x0010: "SIPR1", 0x0011: "SIPR2", 0x0012: "SIPR3",
    0x0013: "INTLEVEL0", 0x0014: "INTLEVEL1",
    0x0015: "IR", 0x0016: "IMR", 0x0017: "SIR", 0x0018: "SIMR",
    0x0019: "RTR0", 0x001A: "RTR1", 0x001B: "RCR",
    0x001C: "PTIMER", 0x001D: "PMAGIC",
    0x001E: "PHAR0", 0x001F: "PHAR1", 0x0020: "PHAR2",
    0x0021: "PHAR3", 0x0022: "PHAR4", 0x0023: "PHAR5",
    0x0024: "PSID0", 0x0025: "PSID1", 0x0026: "PMRU0", 0x0027: "PMRU1",
    0x0028: "UIPR0", 0x0029: "UIPR1", 0x002A: "UIPR2", 0x002B: "UIPR3",
    0x002C: "UPORTR0", 0x002D: "UPORTR1", 0x002E: "PHYCFGR",
    0x0039: "VERSIONR"
}

sn_regs = {
    0x0000: "MR", 0x0001: "CR", 0x0002: "IR", 0x0003: "SR",
    0x0004: "PORT0", 0x0005: "PORT1",
    0x0006: "DHAR0", 0x0007: "DHAR1", 0x0008: "DHAR2",
    0x0009: "DHAR3", 0x000A: "DHAR4", 0x000B: "DHAR5",
    0x000C: "DIPR0", 0x000D: "DIPR1", 0x000E: "DIPR2", 0x000F: "DIPR3",
    0x0010: "DPORT0", 0x0011: "DPORT1",
    0x0012: "MSSR0", 0x0013: "MSSR1",
    0x0015: "TOS", 0x0016: "TTL",
    0x001E: "RXBUF_SIZE", 0x001F: "TXBUF_SIZE",
    0x0020: "TX_FSR0", 0x0021: "TX_FSR1",
    0x0022: "TX_RD0", 0x0023: "TX_RD1",
    0x0024: "TX_WR0", 0x0025: "TX_WR1",
    0x0026: "RX_RSR0", 0x0027: "RX_RSR1",
    0x0028: "RX_RD0", 0x0029: "RX_RD1",
    0x002A: "RX_WR0", 0x002B: "RX_WR1",
    0x002C: "IMR", 0x002D: "FRAG0", 0x002E: "FRAG1",
    0x002F: "KPALVTR"
}


def get_reg_name(address: int) -> str:
    return regs.get(address, "INVALID")

def get_sn_reg_name(address: int) -> str:
    return sn_regs.get(address, "INVALID")

class Hla(HighLevelAnalyzer):
    result_types = {
        "address": {"format": "Address {{data.address}}"},
        "control": {"format": "{{data.block}} block {{data.rw}}"},
        "read": {"format": "{{data.rw}} {{data.reg}} {{data.value}}"},
        "write": {"format": "{{data.rw}} {{data.reg}} {{data.value}}"},
    }

    def __init__(self):
        self._previous_type = ""
        self._address = None
        self._block = ""
        self._rw = ""
        self._byte_pos = 0
        self._sn = None
        self._start_of_address_frame = None

    def decode(self, frame: AnalyzerFrame) -> Optional[AnalyzerFrame]:
        is_first_byte = self._previous_type == "enable"
        self._previous_type = frame.type

        if is_first_byte:
            self._byte_pos = 0
        else:
            self._byte_pos += 1

        if frame.type != "result":
            return None

        mosi = frame.data["mosi"]
        miso = frame.data["miso"]

        if self._byte_pos == 0:
            self._address = mosi[0] << 8
            self._start_of_address_frame = frame.start_time
        elif self._byte_pos == 1:
            self._address |= mosi[0]
            return AnalyzerFrame("address", self._start_of_address_frame, frame.end_time, {
                "address": f"0x{self._address:04X}"
            })
        elif self._byte_pos == 2:
            control = mosi[0]
            self._rw = "write" if ((control >> 2) & 0b1) else "read"
            bsb = control >> 3
            self._sn = None
            if bsb == 0:
                self._block = "common"
            else:
                sn = int(bsb / 4)
                if sn <= 7:
                    self._sn = sn
                    snblock = bsb - sn * 4 - 1
                    if snblock == 0:
                        self._block = f"Sn{sn} Socket"
                    elif snblock == 1:
                        self._block = f"Sn{sn} TX"
                    elif snblock == 2:
                        self._block = f"Sn{sn} RX"
                    else:
                        self._block = "INVALID"
                else:
                    self._block = "INVALID"

            return AnalyzerFrame("control", frame.start_time, frame.end_time, {
                "block": self._block,
                "rw": self._rw
            })
        elif self._byte_pos > 2:
            byte = mosi[0] if self._rw == "write" else miso[0]
            if self._sn is not None:
                if self._block.endswith("TX"):
                    name = "TX"
                elif self._block.endswith("RX"):
                    name = "RX"
                else:
                    name = get_sn_reg_name(self._address)
            else:
                name = get_reg_name(self._address)

            result = AnalyzerFrame(self._rw.lower(), frame.start_time, frame.end_time, {
                "reg": name,
                "rw": self._rw,
                "value": f"0x{byte:02X}"
            })

            self._address = (self._address + 1) & 0xFFFF
            return result
```

6. On the Analyzers tab, add the W5500, connect the SPI, and you're ready to decode.

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744801823%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744801867%2Epng)

**1. read the chip version of the W5500**

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744802882%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744802827%2Epng)

2. Get the MAC Address of the W5500

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744803117%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744808382%2Epng)

3. read the socket's status register

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744808670%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744808649%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744809717%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/876584001%5F1744809752%2Epng)

---

Source: https://maker.wiznet.io/louis_m/projects/spi-decoder-in-logic-analyzer/
