DA Family Guide

Overview

The DA family is NAI’s line of programmable digital-to-analog (D/A) smart function modules. Where an AD module measures an analog signal, a DA module produces one — it takes a number from your software and drives a precise analog voltage or current out each channel. Each channel is an independent 16-bit converter with a field-programmable range and polarity, output enable, and continuous built-in test, backed by FIFO buffering for streaming updates.

This page is the starting point for any DA module. Use it to understand the family, pick the member that fits your voltage/current range and channel count, wire an output to a load, confirm the module is driving, and set your first value from software. It’s aimed at engineers generating analog signals — command, stimulus, excitation, and reference outputs — on an NAI board or system.

In a real system, a DA module is the stimulus and command side of the analog interface — the mirror image of AD. Concretely, it drives the analog signals a system sends out: actuator and servo commands, valve/throttle/control-surface drive, programmable voltage and current references, 4–20 mA current-loop signals, sensor/transducer excitation, and simulated sensor outputs used to stimulate and test other equipment on the bench. NAI rolls these into control, data-acquisition, and Remote Data Concentrator (RDC) subsystems for mil-aero signal integration. (The mirror-image sibling is the AD family, which measures analog inputs — AD reads, DA produces.)

DA modules at a glance

Every DA module gives you independent 16-bit output channels with field-programmable range and polarity, continuous background BIT, and “output set to 0 V at reset/power-on” protection. They differ by channel count, output range, and the extra controls each adds:

ModuleChannelsOutput rangeNotable
DA112±10 V or ±25 mAProgrammable voltage or current loop mode
DA216±10 VPer-channel output enable
DA34±40 V (or ±25/50/100 mA)Per-channel V/I mode select + power supply
DA44±100 VHigh-voltage output
DA54±65 VFull-bridge mode + module power-supply enable

Choosing a member:

  • Many low-level (±10 V) command/reference channelsDA1 (12 ch, also does ±25 mA current mode) or DA2 (16 ch, with per-channel output enable).
  • Current-loop / 4–20 mA driveDA1 or DA3 (current mode).
  • Higher voltageDA3 (±40 V) or DA4 (±100 V).
  • Per-channel voltage or current with its own power supplyDA3.
  • Bridge/transducer simulationDA5 (full-bridge mode).

Combination modules that include D/A:

ModuleCombinesManual
CME / CMFA/D + D/ACME-CMF Manual

The CF1 module is a simplified write-through/strobe DAC. All use the same naibrd_DA_* API.

Physical setup

A DA channel is a single-ended analog output — it drives a programmed voltage (or current) onto whatever load you wire to that channel’s output pin and its return. A few things hold for the family:

  • Voltage vs current. In voltage mode the channel sources a voltage (low output impedance, <1 Ω on DA1); in current mode it drives a current loop (DA1/DA3). DA3 selects the mode per channel in software; DA1 is configured for one or the other.
  • Range and polarity are programmable. Pick the smallest range that covers your signal for the best resolution, and unipolar vs bipolar to match (e.g. 0–10 V vs ±10 V).
  • Outputs come up safe. On reset or power-on every channel is set to 0 V, and there’s automatic shutdown protection on a fault (reported in the status word).
  • High-voltage care (DA4). DA4 drives up to ±100 V — observe the usual high-voltage wiring and isolation precautions.
  • Triggering/sync. Updates can be paced by an internal update rate or, where supported, an external trigger/sync signal shared between modules.

The exact connector pins are per-module, so get them from the manual; the pattern is the same:

  1. Identify the module’s slot number on your NAI motherboard or system.
  2. Bring the channel outputs out through the breakout board, where the slot’s pins appear as generic IO# numbers.
  3. Map IO# pins to each channel’s output and return — by the pinout in the module’s manual or the module’s overlay card.
  4. Wire the channel output to your load (and, for current mode, complete the current loop).

Two worked examples (use your module’s pinout for the actual pins):

  • Drive a voltage command to a load. Set a channel’s range/polarity to cover your signal, set voltage mode, write the value with naibrd_DA_SetData, and (on DA2/DA5) enable the output. The channel holds that voltage until you change it.
  • Drive a 4–20 mA current loop. On a current-capable channel (DA1/DA3 in current mode), wire the channel into the loop, select current mode, and write the milliamp value — handy for driving current-loop instruments or simulating a 4–20 mA sensor.

Software

There’s nothing DA-specific about which software you run. The NAI SSK (naibrd library) is identical across every OS and architecture — PetaLinux, VxWorks, DEOS, Windows. What OS you’re on is determined by your motherboard/SBC, not by the DA module. The only family-specific part is which API functions you call: DA modules use the naibrd_DA_* calls, each taking the cardIndex / module / channel coordinates of the output you’re driving.

Where to find what you need:

  • Which functions/registers to call — the specific module’s manual (e.g. DA1 Manual) documents every naibrd_DA_* register (data, range/polarity, mode, output enable, BIT, status, watchdog).
  • Building and deploying on your platformConnecting to Boards covers the toolchain, deployment, and terminal access for PetaLinux/ARM Linux, VxWorks, DEOS, and Windows.
  • Launching the app on the board itselfRunning Applications from the Target walks through loading and launching your executable on the target.

Example — a 68ARM2 SBC with a DA1 module: pull the naibrd_DA_* calls from the DA1 Manual, set up the ARM Linux toolchain per Connecting to Boards, then load and launch a DA sample on the target per Running Applications from the Target.

Confirm communication

DA gives you an easy first check: Built-In Test. The module’s BIT continuously measures its own output and compares it against the value you commanded, so a passing BIT confirms the channel is actually driving the right level — no external meter required. That makes BIT the fastest way to confirm your board connection, the SSK, and the module are all working.

Power-On BIT runs automatically at power-up. Check it and read the per-channel result:

bool_t pbitComplete;
nai_status_bit_t bitFailed;
 
naibrd_DA_CheckPowerOnBITComplete(cardIndex, module, &pbitComplete);
if (pbitComplete)
   naibrd_DA_GetChanMappedStatus(cardIndex, module, channel,
                                 NAIBRD_DA_STATUS_BIT_LATCHED, &bitFailed);

If BIT is complete and no channel reports a BIT fault, the module is healthy end-to-end. To also prove the physical output, set a known voltage and confirm it — read it back, measure it on a DMM, or loop the DA output into an AD channel:

naibrd_DA_SetData(cardIndex, module, channel, NAIBRD_DA_MODE_VOLTAGE, 5.0);   /* drive 5 V */
naibrd_DA_GetData(cardIndex, module, channel, NAIBRD_DA_MODE_VOLTAGE, &readback);   /* confirm the setting */

If the channel reads/measures the value you set, your board connection, the SSK, and the module are confirmed. The da_basic_ops sample exercises all of this interactively.

Functions and APIs

Every DA operation works per channel (identified by cardIndex / module / channel) and starts from the standard connection flow — naiapp_RunBoardMenu() then naiapp_query_CardIndex() / naiapp_query_ModuleNumber() give you those coordinates, and naibrd_DA_GetChannelCount() confirms the slot holds a DA module (see Opening a Software Handle to Your Board). The blocks below are the things you can make a DA channel do — think of them like the controls on ESP2’s DA tab, each mapped to its naibrd_DA_* calls.

Set & pace the output

What it does: the core operation — write the value each channel drives, and control how fast updates are applied.

Applies to: all DA modules.

Relevant APIs:

/* SSK 1.x */
nai_status_t naibrd_DA_SetData(int32_t cardIndex, int32_t module, int32_t channel, nai_da_data_type_t type, float64_t data);
nai_status_t naibrd_DA_GetData(int32_t cardIndex, int32_t module, int32_t channel, nai_da_data_type_t type, float64_t* outdata);
nai_status_t naibrd_DA_SetWriteThroughMode(int32_t cardIndex, int32_t module, bool_t writeThroughEnable);   /* CF1 */
nai_status_t naibrd_DA_UpdateStrobe(int32_t cardIndex, int32_t module);                                     /* CF1 strobe */
/* SSK 2.x */
nai_status_t naibrd_DA_SetData(int32_t cardIndex, int32_t module, int32_t channel, naibrd_da_mode_t mode, float64_t data);
nai_status_t naibrd_DA_GetData(int32_t cardIndex, int32_t module, int32_t channel, naibrd_da_mode_t mode, float64_t* p_outdata);
nai_status_t naibrd_DA_SetUpdateRate(int32_t cardIndex, int32_t module, uint32_t rateHz);
nai_status_t naibrd_DA_SetWriteThroughMode(int32_t cardIndex, int32_t module, bool_t writeThroughEnable);   /* CF1 */
nai_status_t naibrd_DA_UpdateStrobe(int32_t cardIndex, int32_t module);                                     /* CF1 strobe */

Exercise it: DA Basic Ops (DATA, UPDATE_RATE) · ESP2 “DA” tab.

Configure the channel

What it does: shape the output before you drive it — range, polarity, mode, and enabling.

Applies to: all DA modules (with module-specific extras noted).

Relevant APIs:

/* SSK 1.x */
nai_status_t naibrd_DA_SetRange(int32_t cardIndex, int32_t module, int32_t channel, nai_da_data_type_t type, nai_da_range_mode_t mode, float64_t range);
nai_status_t naibrd_DA_SetOpMode(int32_t cardIndex, int32_t module, int32_t channel, nai_da_data_type_t opmode);            /* voltage or current (DA3) */
nai_status_t naibrd_DA_SetOutputEnable(int32_t cardIndex, int32_t module, int32_t channel, nai_da_output_enable_t enable);  /* DA2/DA5 */
nai_status_t naibrd_DA_SetFullBridgeMode(int32_t cardIndex, int32_t module, int32_t channel, bool_t fullBridgeMode);        /* DA5 */
/* SSK 2.x */
nai_status_t naibrd_DA_SetRangePolarity(int32_t cardIndex, int32_t module, int32_t channel, naibrd_da_mode_t mode, naibrd_da_polarity_t polarity, float64_t range);
nai_status_t naibrd_DA_SetOpMode(int32_t cardIndex, int32_t module, int32_t channel, naibrd_da_mode_t opMode);              /* voltage or current (DA3) */
nai_status_t naibrd_DA_SetOutputEnable(int32_t cardIndex, int32_t module, int32_t channel, bool_t enable);                  /* DA2/DA5 */
nai_status_t naibrd_DA_SetEnablePowerSupply(int32_t cardIndex, int32_t module, int32_t channel, bool_t enable);            /* DA3/DA5 */
nai_status_t naibrd_DA_SetFullBridgeMode(int32_t cardIndex, int32_t module, int32_t channel, bool_t fullBridgeMode);        /* DA5 */

Exercise it: DA Basic Ops (RANGE, POLARITY, MODE, CH_ENABLE, POWER, BRIDGE_ENABLE) · ESP2 “DA” tab.

Hardware floating-point conversion

What it does: apply an offset and scale factor in hardware so the module converts your engineering-unit value to the raw output automatically — handy for calibration or unit scaling without doing the math in your app.

Applies to: DA1–DA5 and the CME/CMF/CMG combos (not CF1). You can also confirm it at runtime with naibrd_GetFloatingPointModeCapability.

Relevant APIs: enable hardware floating-point mode first (naibrd_SetFloatingPointModeEnable), then set the per-channel offset and scale — 1.x has separate offset/scale calls, 2.x unifies them into one attribute call:

/* SSK 1.x */
nai_status_t naibrd_DA_SetFloatingPointOffset(int32_t cardIndex, int32_t module, int32_t channel, float64_t offset);
nai_status_t naibrd_DA_SetFloatingPointScaleFactor(int32_t cardIndex, int32_t module, int32_t channel, float64_t scaleFactor);
/* SSK 2.x */
nai_status_t naibrd_DA_SetFloatingPointAttribute(int32_t cardIndex, int32_t module, int32_t channel, naibrd_da_floating_point_attribute_t attribute, float64_t value);
nai_status_t naibrd_DA_GetFloatingPointAttribute(int32_t cardIndex, int32_t module, int32_t channel, naibrd_da_floating_point_attribute_t attribute, float64_t* p_outvalue);

Exercise it: DA Basic Ops (FP_MODE, OFFSET, SCALE).

Health, safety & status

What it does: run and tune Built-In Test, watch per-channel status, and use the safety features (watchdog, overload protection, power reset).

Applies to: all DA modules (BIT threshold/PBIT on DA2/DA3/DA4 and combos; watchdog where supported).

Relevant APIs:

/* SSK 1.x */
nai_status_t naibrd_DA_CheckPowerOnBITComplete(int32_t cardIndex, int32_t module, bool_t* p_outpbitComplete);
nai_status_t naibrd_DA_SetModuleBITEnable(int32_t cardIndex, int32_t module, nai_da_test_type_t type, bool_t bitEnable);
nai_status_t naibrd_DA_GetStatus(int32_t cardIndex, int32_t module, int32_t channel, nai_da_status_type_t type, nai_status_bit_t* outstatusBit);
nai_status_t naibrd_DA_ResetOverload(int32_t cardIndex, int32_t module);
nai_status_t naibrd_DA_SetWatchdogQuietTime(int32_t cardIndex, int32_t module, uint32_t quietTime);
nai_status_t naibrd_DA_WatchdogStrobe(int32_t cardIndex, int32_t module);
nai_status_t naibrd_DA_SetModulePowerReset(int32_t cardIndex, int32_t module, nai_da_module_power_reset_type_t modulePowerResetType, bool_t modulePowerResetBit);
/* SSK 2.x */
nai_status_t naibrd_DA_CheckPowerOnBITComplete(int32_t cardIndex, int32_t module, bool_t* p_outpbitComplete);
nai_status_t naibrd_DA_SetModuleBITEnable(int32_t cardIndex, int32_t module, naibrd_da_test_type_t type, bool_t bitEnable);
nai_status_t naibrd_DA_GetChanMappedStatus(int32_t cardIndex, int32_t module, int32_t channel, naibrd_da_chan_mapped_status_type_t statusType, nai_status_bit_t* p_outstatusBit);
nai_status_t naibrd_DA_ResetOverload(int32_t cardIndex, int32_t module);
nai_status_t naibrd_DA_SetWatchdogQuietTime(int32_t cardIndex, int32_t module, uint32_t quietTime);
nai_status_t naibrd_DA_WatchdogStrobe(int32_t cardIndex, int32_t module);
nai_status_t naibrd_DA_SetModulePowerReset(int32_t cardIndex, int32_t module, naibrd_da_module_power_reset_type_t modulePowerResetType, bool_t modulePowerResetBit);

Warning

If you start the watchdog and then stop strobing it, the module shuts off all outputs and must be power-cycled to recover. Only enable the watchdog when your application will keep strobing it.

Exercise it: DA Basic Ops (PBIT, BIT_THRESH, CHANSTAT, CLEAR, WATCHDOG, PWRRESET).

Run them: DA Basic Ops (all of the above, interactively) · DA Summary; the SSK 1.x equivalent is DA_BasicOps. For building/running, see Using NAI SSK 2.x Sample Applications · Using NAI SSK 1.x Sample Applications.

Features and status monitoring

Beyond the per-channel operations above, the DA hardware provides continuous background BIT, extended FIFO buffering for streaming output updates, external trigger/synchronization (between modules, where supported), and automatic shutdown protection on a fault.

Statuses you can monitor programmatically:

StatusWhat it tells youWhere
BIT (per channel)The commanded vs measured output mismatched — a channel-level faultnaibrd_DA_GetChanMappedStatus with NAIBRD_DA_STATUS_BIT_LATCHED
Overcurrent / overloadA channel is drawing too much current / the module overloaded…_STATUS_OVERCURRENT_LATCHED; reset with naibrd_DA_ResetOverload
Watchdog faultThe watchdog timer expired without a strobe (outputs shut off)…_STATUS_WATCHDOG_TIMER_FAULT_LATCHED / …_REALTIME
Module power-reset statusThe module powered down / not detected / comm error / FW not readynaibrd_DA_GetModulePowerResetStatus
Power-on BIT completeWhether PBIT has finished, so its results are valid to readnaibrd_DA_CheckPowerOnBITComplete

Disable a channel’s status reporting with naibrd_DA_SetChanStatusEnable if you don’t want it to assert status/interrupts. ESP2’s status panel shows DA status interactively if you’d rather watch it in a GUI first.

Common pitfalls

  • Output looks dead because it isn’t enabled. On DA2/DA5 the channel output must be enabled (naibrd_DA_SetOutputEnable); on DA3/DA5 the power supply must be on (naibrd_DA_SetEnablePowerSupply). A value written to a disabled channel produces nothing.
  • Output clipped at the range limit. If the value you set exceeds the configured range, it clamps. Raise the range (or lower the value) — and remember a smaller range gives better resolution.
  • Wrong mode (voltage vs current). naibrd_DA_SetData interprets the value as V or mA depending on the channel’s op-mode. Set the mode (DA3) and read it with naibrd_DA_GetOpMode before writing.
  • Floating-point scaling has no effect. Offset/scale only apply when floating-point mode is enabled (naibrd_SetFloatingPointModeEnable).
  • Watchdog left un-strobed shuts the module down. Once started, the watchdog must keep getting strobes or it kills all outputs and needs a power cycle — only enable it if you’ll service it.
  • CF1 output not updating. With write-through disabled, staged data isn’t applied until you issue naibrd_DA_UpdateStrobe — enable write-through or strobe.
  • High-voltage surprises (DA4). DA4 can drive ±100 V — wire and probe accordingly.