Skip to content

wxinix/SdlcAnalyzer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NEMA/ATC SDLC Analyzer

A Saleae Logic 2 protocol analyzer for decoding HDLC/SDLC frames, with support for external clock synchronization used in NEMA TS2 and ATC traffic signal communications.

Why This Exists

The official Saleae HDLC analyzer does not work for NEMA TS2 / ATC SDLC traffic. It only supports an internal baud-rate-derived sampling clock, which causes progressive drift on true synchronous protocols like SDLC where data must be sampled on edges of an external clock signal provided by the controller. This drift produces garbled frames, wrong CRC checks, and phantom abort sequences -- making the stock analyzer unusable for traffic signal fieldwork.

This plugin was built from the ground up to solve that problem. It adds external clock sampling, NRZ encoding support (NEMA TS2 single-ended RS-485 probing uses NRZ, not NRZI as standard SDLC assumes), and configurable data inversion to handle the opposite polarity between Tx and Rx on the "+" wire.

NEMA/ATC SDLC Analyzer decoding Tx command and Rx response frames in Saleae Logic 2

Features

  • External Clock Mode — A new "Bit Synchronous (External Clock)" transmission mode that samples the data line on edges of a user-specified external clock channel, eliminating sampling drift on true synchronous protocols like SDLC
  • NRZ / NRZI Data Encoding — Choose between NRZI (transition-based, standard SDLC) and NRZ (direct line level). NEMA TS2 signals probed single-ended on the RS-485 + wire use NRZ encoding
  • Data Polarity Inversion — Handle inverted RS-485 polarity when probing single-ended. On NEMA TS2, TxData+ and RxData+ have opposite polarity and require different inversion settings
  • Full HDLC frame decoding — Address (basic/extended), Control (modulo 8/128/32768/2G), Information, and FCS fields
  • CRC verification — CRC-8, CRC-16-CCITT, and CRC-32 with pass/fail indication
  • CSV export — Export decoded frames as timestamped CSV

Installation

  1. Build the analyzer (see below)
  2. Open Saleae Logic 2
  3. Go to Preferences (Ctrl+,) > Custom Low Level Analyzers
  4. Add the directory containing the built DLL (e.g. build/Analyzers/Release)
  5. Restart Logic 2
  6. The analyzer appears as "NEMA/ATC SDLC"

Analyzer Settings

Setting Options Description
SDLC Data Any digital channel The data channel carrying the HDLC/SDLC serial bit stream.
Clock Any digital channel / None External clock channel. Required when using "Bit Synchronous (External Clock)" mode; leave as "None" for other modes.
Baud Rate 1 - 6,000,000 Bit rate in symbols per second. Used only by the internal clock modes ("Bit Synchronous" and "Byte Asynchronous") to derive sampling timing. Ignored in External Clock mode.
Transmission Mode Bit Synchronous / Bit Synchronous (External Clock) / Byte Asynchronous See Transmission Modes below.
Clock Edge Rising Edge / Falling Edge Which clock edge to sample data on. Only applies to External Clock mode. For NEMA TS2, use Rising Edge (see below).
Data Encoding NRZI / NRZ NRZI = transition-based (1=no transition, 0=transition). NRZ = direct line level (1=HIGH, 0=LOW). NEMA TS2 single-ended probing uses NRZ.
Invert Data No / Yes Invert data line polarity. Needed when probing one side of an RS-485 differential pair. For NEMA TS2, Tx and Rx require different inversion settings (see below).
Address Field Basic / Extended Basic = single 8-bit address. Extended = variable-length address where the LSB of each byte indicates whether more address bytes follow (LSB = 1 continues, LSB = 0 terminates). NEMA TS2 uses Basic.
Control Field Basic - Modulo 8 / Extended - Modulo 128 / Extended - Modulo 32768 / Extended - Modulo 2147483648 Size of the control field: Basic = 1 byte (8-bit sequence numbers), Extended = 2, 4, or 8 bytes for larger sequence number spaces. NEMA TS2 uses Basic (Modulo 8).
FCS Type CRC-8 / CRC-16-CCITT / CRC-32 Frame Check Sequence algorithm for error detection. NEMA TS2 uses CRC-16-CCITT.

Transmission Modes

  • Bit Synchronous - Standard HDLC bit-oriented framing with NRZI encoding and zero-bit stuffing after 5 consecutive 1-bits. Uses an internal sampling clock derived from the specified baud rate. Best for captures where no external clock signal is available.
  • Bit Synchronous (External Clock) - Bit-stuffing framing with configurable NRZ/NRZI encoding, sampling on edges of a physical clock signal. Eliminates sampling drift on true synchronous links such as NEMA TS2 / ATC SDLC.
  • Byte Asynchronous - Byte-oriented framing with start/stop bits and byte-stuffing (escape sequences). Used by protocols that run HDLC over asynchronous serial links (e.g., PPP).

Usage for NEMA TS2 / ATC SDLC

Wiring

Connect the Saleae logic analyzer to the TS2 Type AB (EIA-485) port:

TS2 Port Signal Pin Logic Analyzer Direction
TxData+ 1 Digital Channel 0 Controller -> Field Device
TxClock+ 3 Digital Channel 3 Clock for Tx
RxData+ 5 Digital Channel 1 Field Device -> Controller
RxClock+ 7 Digital Channel 2 Clock for Rx
GND 2, 4, 6, 8 GND --

Recommended Configuration

Set up two analyzer instances -- one for Tx (command frames) and one for Rx (response frames).

Tx (Command Frame):

Tx analyzer setup
Setting Value
SDLC Data Pin 1 TxData+
Clock Pin 3 TxClock+
Transmission Mode Bit Synchronous (External Clock)
Clock Edge Rising Edge
Data Encoding NRZ
Invert Data No
Address Field Basic
Control Field Basic - Modulo 8
FCS Type CRC-16-CCITT

Rx (Response Frame):

Rx analyzer setup
Setting Value
SDLC Data Pin 5 RxData+
Clock Pin 7 RxClock+
Transmission Mode Bit Synchronous (External Clock)
Clock Edge Rising Edge
Data Encoding NRZ
Invert Data Yes
Address Field Basic
Control Field Basic - Modulo 8
FCS Type CRC-16-CCITT

Note: The only difference between Tx and Rx is Invert Data. TxData+ and RxData+ have opposite RS-485 polarity when probed single-ended on the + wire.

Baud Rates

  • NEMA TS2 operates at 153,600 bps (153.6 kbps)
  • ATC operates at 614,400 bps (614.4 kbps)

Note: When using External Clock mode, the baud rate setting is ignored -- timing is derived entirely from the clock signal. The baud rate only matters for the internal clock modes.

Clock Edge for NEMA TS2 / ATC

Both NEMA TS2 and ATC use Rising Edge sampling. Per the TS2 specification, "the receiving station shall read the data ... when the voltage potential of the Tx Clock+ line makes a positive going transition with respect to the Tx Clock-line." The clock's positive-going (rising) transition occurs at the midpoint of each bit cell. ATC follows the same convention.

If decoding produces garbled output, try switching to Falling Edge -- some signal conditioners or level translators may invert the clock polarity.

Building

Prerequisites

  • A C++23-compatible compiler (Visual Studio 2022, GCC 13+, or Clang 16+)
  • CMake 3.13+
  • git

MacOS

mkdir build && cd build
cmake ..
cmake --build .

Linux

mkdir build && cd build
cmake ..
cmake --build .

Windows

mkdir build && cd build
cmake .. -A x64
cmake --build . --config Release

The built analyzer DLL will be at build/Analyzers/Release/sdlc_analyzer.dll.

Architecture

Written in C++23 with modern patterns:

src/
  types.h        Core types, enums, pattern matching, monadic guard, CRTP utilities
  crc.h          Compile-time CRC engine template (CRC-8, CRC-16-CCITT, CRC-32)
  settings.h/cpp User-facing configuration with fold-expression serialization
  analyzer.h/cpp Frame decoder with CRTP mixins (FrameEmitter, BitDecoder)
  results.h/cpp  Display text rendering and CSV export
  sim.h/cpp      Synthetic waveform generator for simulation mode

Key design patterns:

Pattern Where Purpose
CRTP FrameEmitter<D>, BitDecoder<D> Static polymorphism for frame buffering and NRZ/NRZI decoding
Compile-time CRC CrcEngine<Bits,V,Poly,Init,Xout,Reflect> Table generation at compile time via constexpr lambda
Pattern matching match(), match_or(), select() Replaces switch/if-else chains with declarative dispatch
Monadic guard guard(flag) >> [&]{...} Short-circuit chaining on abort conditions
Fold expressions load_all(), save_all(), chain() Variadic archive serialization and export pipelines
Constexpr lambdas fcs_bytes, classify, ctrl_bytes Enum dispatch tables as first-class values

References

  1. ISO/IEC 13239:2002 - High-level Data Link Control (HDLC) Procedures
  2. NEMA TS 2 - Traffic Controller Assemblies with NTCIP Requirements
  3. ITE ATC 5201/5301 - Advanced Transportation Controller Standards
  4. Saleae Analyzer SDK - https://github.com/saleae/AnalyzerSDK
  5. Saleae Protocol Analyzer SDK documentation - https://github.com/saleae/SampleAnalyzer/blob/master/docs/Analyzer_API.md

License

MIT License - Copyright (c) 2026 Wuping Xin

About

A Saleae Logic 2 protocol analyzer for decoding HDLC/SDLC frames, with support for external clock synchronization used in NEMA TS2 and ATC traffic signal communications.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors