PulseSYNC Sample Applications (SSK 2.x)

Overview

PulseSYNC keeps the timing of several NAI boards aligned by exchanging pulses between them. It is implemented in the motherboard FPGA and accessed through the naidev PulseSYNC API (naidev_pulse_sync.h). The hardware provides:

  • A 64-bit timestamp counter. Its resolution is set with a prescaler; the default of 125 system clocks gives a 1 µs tick.
  • A pulse generator with programmable high time, low time, and pulse count.
  • Rising- and falling-edge timestamp capture on the board’s own output (looped back internally) and on three external inputs, keeping the three most recent timestamps for each.

Each board announces its synchronization role through the duty cycle of its pulse, so every board can tell from its inputs which role the others are playing.

The SSK includes four PulseSYNC samples:

SampleWhat it doesSource folder (under base/nai_sample_apps/naiapp_src/devices/pulse_sync/)Deos project
PulseSYNC Basic OpsMenu-driven access to the pulse generator, timestamp counter, and edge capturespulse_sync_basic_opsnaiapp_dev_pulse_sync
Master SyncRuns the board as the timing master that the other boards followmaster_syncnaiapp_master_sync
Slave SyncFinds the master on its inputs and stays aligned to itslave_syncnaiapp_slave_sync
Phase Lock SyncAligns to the average timing of every active pulse in the systemphase_lock_syncnaiapp_phaselock_sync

There is no SSK 1.x counterpart for these samples.

Supported Boards

PulseSYNC has been tested on the 68ARM2-H, 68ARM2-L, and NIU3A. It should also work on the NIU3E, but that hasn’t been tested yet.

Supported Operating Systems

The master, slave, and phase-lock samples each come in two versions:

  • RMA version (*_app_rma.c), for Deos. Timing follows the rate monotonic scheduler, and each pulse is aligned to the boundaries of Deos’s Window Activation Table (WAT), DDC-I’s equivalent of a frame sync pulse. The algorithm described on this page is this version. These projects are in the Deos UltraScale workspace, deos/deos_kismet/nai-ultrascale.
  • Priority version (*_app_priority.c), for VxWorks. Each sample spawns a priority-100 task that times a 10 ms frame (100 Hz) by busy-waiting on the hardware timestamp. The busy-wait is deliberate: it keeps equal- and lower-priority tasks from delaying a pulse, at the cost of high CPU use. Instead of shifting a WAT, the slave and phase-lock tasks adjust their own pulse period, limited to 60–140% of the nominal frame.

On VxWorks, the entry points are Master_Sync(), Slave_Sync(), Phase_Lock_Sync(), and PulseSync_BasicOps(). On Deos, each sample builds as a standalone process.

Prerequisites

  • Two or more boards that support PulseSYNC, with each board’s pulse output wired to the external inputs of the others. Each board has three external inputs, so it can see the pulses of up to three other boards. The board manuals don’t list the PulseSYNC output and input pins yet, so contact NAI support for the connections on your board.
  • SSK 2.x and a build environment for your operating system. See the NAI Deos Quick-Start Guide or the NAI VxWorks 7 Quick-Start Guide.

How to Run

  • Deos: add the sample as a dependency of the platform project, rebuild, and reload the image, as described in Running Other Sample Applications.
  • VxWorks: load the sample and call its entry point from the shell.

Start one board with Master Sync and the others with Slave Sync, or start every board with Phase Lock Sync. A Slave Sync board waits until it sees a master on one of its inputs before it starts following.

Sync States

Each role has its own duty cycle. A board reads the duty cycle of each input pulse to decide which role that pulse belongs to. Only the Deos (RMA) versions use the Initial state.

StateDuty cycleAccepted rangeBehavior
Initial10%5–15%Board is aligning its pulse to its own frame
Master20%15–25%Self-synchronized; the timing authority
Slave30%25–35%Follows the master
Phase Lock40%35–45%Follows the average of all the active pulses

You can combine the roles in different ways. For example, a system of three boards could run as:

  • 1 Master and 2 Slaves
  • 3 Phase Lock

How Synchronization Works

This section and Algorithm Flow describe the Deos (RMA) versions of the samples. The VxWorks (priority) versions don’t use a WAT; see Supported Operating Systems.

Each pulse goes through two stages of synchronization: first it aligns itself (its loopback pulse) with its own WAT boundaries, then it synchronizes to the rest of the system. The Master only performs the first stage.

Stage 1: Self-Synchronization to the WAT Boundary

Before a board tries to match the other boards, it first makes sure its own pulse lines up with its own WAT boundary. Once synchronized, the length of the WAT matches the pulse period.

  1. Compare the rising edge of the loopback pulse with the start of the WAT.
  2. Calculate the error between the two.
  3. Apply a proportional correction (error × kError).
  4. Adjust the next pulse period by the correction.
  5. Repeat until the error is within tolerance.

For example, if the WAT starts after the loopback pulse, the board lengthens the current pulse period so that the next rising edge falls on the next WAT boundary. It repeats this until the rising edge is within tolerance.

All three roles self-synchronize at startup. The Slave and Phase Lock roles also keep self-synchronizing while they synchronize to the system, so their pulses stay aligned with their WAT throughout. The Master is its own authority, so after startup it only keeps its pulse aligned with its WAT.

Stage 2: Synchronization to the System

The Slave and Phase Lock roles then synchronize to the system:

  1. Compare the loopback pulse with the target time. For a Slave, the target is the Master’s pulse. For Phase Lock, it is the average time of all the active pulses, including the board’s own.
  2. Calculate the error between the loopback pulse and the target.
  3. If the error is outside tolerance, correct it in two steps:
    1. Shift the board’s timeline (its WAT boundaries) by the proportional correction (error × kError).
    2. Correct the pulse timing to compensate for the timeline shift.
  4. Repeat until the error is within tolerance.

For example, if the Master’s pulse arrives after the Slave’s, the Slave shifts its WAT timeline forward and lengthens its pulse period to match.

Algorithm Flow

This flow is for the Deos (RMA) versions.

1. Initialization

  • Generate an initial pulse with a 10% duty cycle.
  • Run the self-correction loop until the loopback pulse is within tolerance of the WAT start.

2. Master Mode

  • Switch to a 20% duty cycle so the other boards can identify the master.
  • Each frame, compare the loopback pulse with the WAT boundary and correct it if the error is outside tolerance.

3. Slave Mode

  • Search inputs 1–3 for a pulse with the master’s duty cycle, and wait until one appears.
  • Switch to a 30% duty cycle.
  • Each frame:
    1. Loopback to WAT: if the loopback pulse is outside tolerance of the WAT start, correct it and check again next frame.
    2. Sync to Master: once the loopback is aligned, compare the local pulse with the master’s. If the error is outside tolerance, shift the WAT timeline and adjust the local pulse to match.

4. Phase Lock Mode

  • Switch to a 40% duty cycle.
  • Each frame:
    1. Loopback to WAT: as in Slave mode.
    2. Sync to the average: average the timing of every active pulse (the loopback and any input showing a Master, Slave, or Phase Lock duty cycle), compare the local pulse with that average, and shift the WAT timeline and adjust the local pulse if the error is outside tolerance.

Tuning Parameters

These values are constants at the top of each sample’s source file. The two versions use different constants.

Deos (RMA Versions)

ParameterConstantMasterSlavePhase Lock
TolerancePULSE_SYNC_TOLERANCE_USEC10 µs10 µs10 µs
Correction factor (kError)PULSE_SYNC_CORRECTION_FACTOR0.500.400.20

A larger correction factor closes the error in fewer frames; a smaller one corrects more gently.

VxWorks (Priority Versions)

ParameterConstantMasterSlavePhase Lock
Pulse ratePULSE_RATE_HZ100 Hz100 Hz100 Hz
Proportional gainKPNot used0.30.3
Shortest pulse periodMIN_PERIOD_USECNot used60% (6 ms)60% (6 ms)
Longest pulse periodMAX_PERIOD_USECNot used140% (14 ms)140% (14 ms)

The priority versions have no tolerance. The Slave and Phase Lock tasks apply the correction every frame, and the Master keeps a fixed 10 ms period.

PulseSYNC Basic Ops Menu

PulseSYNC Basic Ops uses the standard board menu on startup (configuration file default_PulseSync_BasicOps.txt), then offers these commands:

CommandDescription
OSet Output Control (start or stop the pulse output)
PSet Prescaler (timestamp counter resolution)
CSet Pulse Count
HSet High Time
LSet Low Time
TDisplay Timestamp
BDisplay Loopback Edge Timestamps
IDisplay Input Edge Timestamps
SDisplay All Status

Use it to check the hardware before running the synchronization samples, for example to confirm that another board’s pulse is reaching an input by watching its edge timestamps change.

Troubleshooting Reference

SymptomPossible causeSuggested resolution
Slave Sync never starts followingNo input shows a 15–25% duty cycle, so the slave keeps searching for a master.Confirm a board is running Master Sync and that its output is wired to one of the slave’s inputs 1–3.
A board’s pulse is classified as the wrong roleIts duty cycle is outside the band for its role.Run PulseSYNC Basic Ops (S) on that board. Its duty cycle is High Time / (High Time + Low Time).
Boards never settle within toleranceCorrection factor too high (oscillation) or a noisy input.Lower the correction factor, and check the wiring and signal quality.
naidev_PulseSync_Open failsThe board or BSP doesn’t provide the PulseSYNC hardware.Confirm the board is one of the supported boards and that the workspace is configured for it.