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:
| Module | Channels | Output range | Notable |
|---|---|---|---|
| DA1 | 12 | ±10 V or ±25 mA | Programmable voltage or current loop mode |
| DA2 | 16 | ±10 V | Per-channel output enable |
| DA3 | 4 | ±40 V (or ±25/50/100 mA) | Per-channel V/I mode select + power supply |
| DA4 | 4 | ±100 V | High-voltage output |
| DA5 | 4 | ±65 V | Full-bridge mode + module power-supply enable |
Choosing a member:
- Many low-level (±10 V) command/reference channels — DA1 (12 ch, also does ±25 mA current mode) or DA2 (16 ch, with per-channel output enable).
- Current-loop / 4–20 mA drive — DA1 or DA3 (current mode).
- Higher voltage — DA3 (±40 V) or DA4 (±100 V).
- Per-channel voltage or current with its own power supply — DA3.
- Bridge/transducer simulation — DA5 (full-bridge mode).
Combination modules that include D/A:
| Module | Combines | Manual |
|---|---|---|
| CME / CMF | A/D + D/A | CME-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:
- Identify the module’s slot number on your NAI motherboard or system.
- Bring the channel outputs out through the breakout board, where the slot’s pins appear as generic IO# numbers.
- Map IO# pins to each channel’s output and return — by the pinout in the module’s manual or the module’s overlay card.
- 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 platform — Connecting to Boards covers the toolchain, deployment, and terminal access for PetaLinux/ARM Linux, VxWorks, DEOS, and Windows.
- Launching the app on the board itself — Running 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:
| Status | What it tells you | Where |
|---|---|---|
| BIT (per channel) | The commanded vs measured output mismatched — a channel-level fault | naibrd_DA_GetChanMappedStatus with NAIBRD_DA_STATUS_BIT_LATCHED |
| Overcurrent / overload | A channel is drawing too much current / the module overloaded | …_STATUS_OVERCURRENT_LATCHED; reset with naibrd_DA_ResetOverload |
| Watchdog fault | The watchdog timer expired without a strobe (outputs shut off) | …_STATUS_WATCHDOG_TIMER_FAULT_LATCHED / …_REALTIME |
| Module power-reset status | The module powered down / not detected / comm error / FW not ready | naibrd_DA_GetModulePowerResetStatus |
| Power-on BIT complete | Whether PBIT has finished, so its results are valid to read | naibrd_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_SetDatainterprets the value as V or mA depending on the channel’s op-mode. Set the mode (DA3) and read it withnaibrd_DA_GetOpModebefore 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.
Related resources
- DA1 Manual — module manual (registers and the full
naibrd_DA_*API); see also the DA2–DA5 manuals for member specifics - Download the SSK — get the library and sample apps
- Connecting to Boards — power, network, terminal, and file transfer to your board
- Opening a Software Handle to Your Board — establish the connection your
naibrd_DA_*calls run against - Running Applications from the Target — load and launch a built sample on the board
- ESP2 Quick Start — drive DA channels with no code via the Embedded Soft Panel
