« Close

Datasheets and User Guides

App Notes

Software & Driver

 

3.2.1 Stream-Out (Advanced)

Stream-out (Advanced) Overview

Stream-Out is a set of streamable registers that move data from a buffer to an output. The output can be digital I/O (DIO) or a DAC. The buffer can be read linearly to generate a irregular waveform or in a looping mode to generate a periodic waveform. The T7 can output up to 4 waveforms using stream out.

Targets

The following target list represents the I/O on the device that can be configured to output a waveform using stream out. Basically the list includes the analog and digital output lines.

DAC0
DAC1
FIO_STATE
FIO_DIRECTION
EIO_STATE
EIO_DIRECTION
CIO_STATE
CIO_DIRECTION
MIO_STATE
MIO_DIRECTION

Register Listing

Stream-Out
Name Start Address Type Access
STREAM_OUT#(0:3) 4800 UINT16 R
STREAM_OUT#(0:3)
- Starting Address: 4800
Include one or more of these registers in STREAM_SCANLIST_ADDRESS#(0:127) to trigger stream-out updates. When added to the scan list these do count against the max scan rate just like normal input addresses, but they do not return any data in the stream read.
  • Data type: UINT16  (type index = 0)
  • Read-only
  • Default value: 0
  • Minimum firmware version: 1.0012
Expanded Names Addresses
STREAM_OUT0, STREAM_OUT1, STREAM_OUT2, STREAM_OUT3 Show All 4800, 4801, 4802, 4803 Show All

Configuration

Register Listing

Configuration will set the buffer size and target. The target specifies which physical I/O to use. Data in the buffer will be output onto the target I/O as a generated waveform. Configuration can be done before or after stream has started.

Stream-Out Configuration
Name Start Address Type Access
STREAM_OUT#(0:3)_TARGET 4040 UINT32 R/W
STREAM_OUT#(0:3)_BUFFER_SIZE 4050 UINT32 R/W
STREAM_OUT#(0:3)_ENABLE 4090 UINT32 R/W
STREAM_OUT#(0:3)_TARGET
- Starting Address: 4040
Channel that data will be written to. Before writing data to _BUFFER_###, you must write to _TARGET so the device knows how to interpret and store values.
  • Data type: UINT32  (type index = 1)
  • Readable and writable
  • Default value: 0
  • Minimum firmware version: 1.0012
Expanded Names Addresses
STREAM_OUT0_TARGET, STREAM_OUT1_TARGET, STREAM_OUT2_TARGET, STREAM_OUT3_TARGET Show All 4040, 4042, 4044, 4046 Show All
STREAM_OUT#(0:3)_BUFFER_SIZE
- Starting Address: 4050
Size of the buffer in bytes as a power of 2. Should be at least twice the size of updates that will be written. Before writing data to _BUFFER_###, you must write to _BUFFER_ALLOCATE_NUM_BYTES to allocate RAM for the data. Max is 16384.
  • Data type: UINT32  (type index = 1)
  • Readable and writable
  • Default value: 0
  • Minimum firmware version: 0.9300
Expanded Names Addresses
STREAM_OUT0_BUFFER_SIZE, STREAM_OUT1_BUFFER_SIZE, STREAM_OUT2_BUFFER_SIZE, STREAM_OUT3_BUFFER_SIZE Show All 4050, 4052, 4054, 4056 Show All
STREAM_OUT#(0:3)_ENABLE
- Starting Address: 4090
Write 1 to enable, 0 to disable. When enabled, you get 1 update per target per stream scan, so a stream must be active for updates to happen.
  • Data type: UINT32  (type index = 1)
  • Readable and writable
  • Default value: 0
  • Minimum firmware version: 0.9300
Expanded Names Addresses
STREAM_OUT0_ENABLE, STREAM_OUT1_ENABLE, STREAM_OUT2_ENABLE, STREAM_OUT3_ENABLE Show All 4090, 4092, 4094, 4096 Show All

Buffers

Register Listing

Each Stream-Out has its own buffer. Data is loaded into the buffer by writing to the appropriate buffer register. Output waveform data points are stored in the buffer as 16-bit values, so values greater than 16-bits will be converted automatically before being stored in the buffer. Use only one buffer per STREAM_OUT channel. For outputting an analog waveform (DAC output), write an array of floating point numbers to the STREAM_OUT#(0:3)_BUFFER_F32 register. For outputting a digital waveform, pass an array of integer 0 or 1 values to the STREAM_OUT#(0:3)_BUFFER_U16 register.

Stream-Out Buffers
Name Start Address Type Access
STREAM_OUT#(0:3)_BUFFER_U16 4420 UINT16 W
STREAM_OUT#(0:3)_BUFFER_F32 4400 FLOAT32 W
STREAM_OUT#(0:3)_BUFFER_STATUS 4080 UINT32 R
STREAM_OUT#(0:3)_BUFFER_U16
- Starting Address: 4420
Data destination when sending 16-bit integer data. Each value uses 2 bytes of the stream-out buffer. This register is a buffer.
  • Data type: UINT16  (type index = 0)
  • Write-only
  • Default value: 0
  • Minimum firmware version: 0.9300
  • This register is a Buffer Register
Expanded Names Addresses
STREAM_OUT0_BUFFER_U16, STREAM_OUT1_BUFFER_U16, STREAM_OUT2_BUFFER_U16, STREAM_OUT3_BUFFER_U16 Show All 4420, 4421, 4422, 4423 Show All
STREAM_OUT#(0:3)_BUFFER_F32
- Starting Address: 4400
Data destination when sending floating point data. Appropriate cal constants are used to convert F32 values to 16-bit binary data, and thus each of these values uses 2 bytes of the stream-out buffer. This register is a buffer.
  • Data type: FLOAT32  (type index = 3)
  • Write-only
  • Default value: 0
  • Minimum firmware version: 0.9300
  • This register is a Buffer Register
Expanded Names Addresses
STREAM_OUT0_BUFFER_F32, STREAM_OUT1_BUFFER_F32, STREAM_OUT2_BUFFER_F32, STREAM_OUT3_BUFFER_F32 Show All 4400, 4402, 4404, 4406 Show All
STREAM_OUT#(0:3)_BUFFER_STATUS
- Starting Address: 4080
The number of values in the buffer that are not currently being used.
  • Data type: UINT32  (type index = 1)
  • Read-only
  • Default value: 0
  • Minimum firmware version: 0.9300
Expanded Names Addresses
STREAM_OUT0_BUFFER_STATUS, STREAM_OUT1_BUFFER_STATUS, STREAM_OUT2_BUFFER_STATUS, STREAM_OUT3_BUFFER_STATUS Show All 4080, 4082, 4084, 4086 Show All

Register Listing

Once the waveform data points are stored, the next step is to configure the STREAM_OUT#(0:3)_LOOP_SIZE and STREAM_OUT#(0:3)_SET_LOOP parameters to establish if/when the waveform repeats or stops, or if the waveform should be clipped relative

Stream-Out Waveform Periodicity
Name Start Address Type Access
STREAM_OUT#(0:3)_LOOP_SIZE 4060 UINT32 R/W
STREAM_OUT#(0:3)_SET_LOOP 4070 UINT32 W
STREAM_OUT#(0:3)_LOOP_SIZE
- Starting Address: 4060
The number of values, from the end of the array, that will be repeated after reaching the end of supplied data array.
  • Data type: UINT32  (type index = 1)
  • Readable and writable
  • Default value: 0
  • Minimum firmware version: 0.9300
Expanded Names Addresses
STREAM_OUT0_LOOP_SIZE, STREAM_OUT1_LOOP_SIZE, STREAM_OUT2_LOOP_SIZE, STREAM_OUT3_LOOP_SIZE Show All 4060, 4062, 4064, 4066 Show All
STREAM_OUT#(0:3)_SET_LOOP
- Starting Address: 4070
Controls when new data and loop size are used. 1=Use new data immediately. 2=Wait for synch. New data will not be used until a different stream-out channel is set to Synch. 3=Synch. This stream-out# as well as any stream-outs set to synch will start using new data immediately.
  • Data type: UINT32  (type index = 1)
  • Write-only
  • Default value: 0
  • Minimum firmware version: 0.9300
Expanded Names Addresses
STREAM_OUT0_SET_LOOP, STREAM_OUT1_SET_LOOP, STREAM_OUT2_SET_LOOP, STREAM_OUT3_SET_LOOP Show All 4070, 4072, 4074, 4076 Show All

Example

This example demonstrates how to configure DAC0 to output an analog waveform that resembles a triangle wave, and also quickly measure two analog inputs AIN0 and AIN2 in streaming context.

Configuration steps specific to stream-out

  1. STREAM_OUT0_ENABLE = 0 –> Turn off just in case it was already on.
  2. STREAM_OUT0_TARGET = 1000 –> Set the target to DAC0.
  3. STREAM_OUT0_BUFFER_SIZE = 512 –> A buffer to hold up to 256 values.
  4. STREAM_OUT0_ENABLE = 1 –> Turn on Stream-Out0.

General stream configuration

  1. STREAM_SCANLIST_ADDRESS0= AIN0 –> Add AIN0 to the list of things to stream in.
  2. STREAM_SCANLIST_ADDRESS1= STREAM_OUT0 –> Add STREAM_OUT0 (DAC0 is target) to the list of things to stream out.
  3. STREAM_SCANLIST_ADDRESS2= AIN2 –> Add AIN2 to the list of things to stream in.
  4. STREAM_ENABLE = 1 –> Start streaming.

Note that there are some other settings related to streaming the analog inputs, but those are covered under the section for stream mode.

Load the waveform data points

The following data points have been chosen to produce the triangle waveform: 0.5V, 1V, 1.5V, 1V, so the next step is to write these datum to the appropriate buffer. Because it is a DAC output (floating point number), use the STREAM_OUT0_BUFFER_F32 register.

  1. STREAM_OUT0_BUFFER_F32 –> Write the four values one at a time or as an array.
  2. STREAM_OUT0_LOOP_SIZE = 4 –> Loop four values.
  3. STREAM_OUT0_SET_LOOP = 1 –> Begin using new data set immediately.

Observe result with stream mode

Every time the stream is run, AIN0 is read, then DAC0 is updated with a data point from Stream-Out0's buffer, then AIN2 is read.  Thus, the streaming speed dictates the frequency of the output waveform. 

 

Sequential Data

Once a sequence of values has been set via the STREAM_OUT#_SET_LOOP register, that sequence of values will loop and only be interrupted at the end of the sequence. Therefore, to have stream out continuously output a sequence of values that is larger than the size of one stream out buffer, probably the easiest way to do so is to:

1. Start by dividing the stream out buffer into 2 halves,

2. Write one half of the buffer with your sequential data,

3. In a loop, every time the STREAM_OUT#_BUFFER_STATUS reads as being half full/empty, write another half buffer-worth of values.

Note that the buffer is a circular array, so you could end up overwriting values if you're not careful.

Here's an example:

 

Stream out buffer is 512 bytes, divide that by 2 to get the number of samples the buffer can hold => 256 samples

256 samples divided by 2 to get the "loop" size, AKA the set-of-data-to-be-written-at-a-time size => 128 samples

 

Write 128 samples:

Write 128 to STREAM_OUT0_LOOP_SIZE

Write 128 samples to STREAM_OUT0_BUFFER_F32 (This should probably be done by array write, which is much faster than writing values individually.)

Write 1 to STREAM_OUT0_SET_LOOP

 

Loop while you have more sequential data to write:

Read STREAM_OUT0_BUFFER_STATUS

If STREAM_OUT0_BUFFER_STATUS is 128 or greater, write the next 128 samples

Sleep for something like (1 / scanRate) to prevent unnecessary work for the hardware

 

6 comments

I think there is a potentially confusing typo in this article. In this chunk of text:

  1. STREAM_SCANLIST_ADDRESS0= AIN0 –> Add AIN0 to the list of things to stream in.
  2. STREAM_SCANLIST_ADDRESS0= STREAM_OUT0 –> Add STREAM_OUT0 (DAC0 is target) to the list of things to stream out.
  3. STREAM_SCANLIST_ADDRESS0= AIN2 –> Add AIN2 to the list of things to stream in.
  4. STREAM_ENABLE = 1 –> Start streaming.
I think STREAM_SCANLIST_ADDRESS0 should increment to 1 and 2 for the second and third entries. This pseudo-code just shows the first item in the stream list being overwritten with subsequent entries, right?

Are there any plans to add the DIO_EF output modes to stream out (for me in particular, PWM  _EF_CONFIG_A) or is there a good (read simple) way to do it with the low level methods?

Thanks in advance.

No plans for that.  With the PWM Out mode you update DIO#_EF_CONFIG_A to control the duty-cycle of the output.  Seems like a strange thing to do through stream-out.  Can you just do it with normal command-response calls?

I started experimenting with streaming to read 13 DI as part or a set of equipment controls.  Then I integrated 2 two channels of DIO_EF for Frequency In to speed up my cycle times (looking for 1 kHz resolution on my DI, total cycle time was getting into the 10s of msec without bringing my EF reads into streaming). With a little tuning this brought me back down to the ~3.5 msec cycle time.

At this point I am just interested to see if I could speed my code up further by streaming my outputs while I was at it as future proofing.

(Sorry about the late reply, I responded on the 10th, but it looks like it got lost in the ether.)

I have started to use stream mode get pulse data fast enough (~1kHz) from 13 electronic eyes.  This however broke my cycle times which previously had been ~3.5 ms.  In order to bring it back down switched to bringing in DIO_EF Frequency In through steam mode as well.  With some tuning, (had to figure out buffer management) I got my cycle times back. 

I still have a normal command response sending out in DIO_EF PWM and 4 relay signals though.  I assumed that if I switched these over to steam mode I would get a further speed up in my cycle times.  I have done simple simulations with dummy addresses and it look like this would be the case.  It's not something that I really need though.  I am just looking to speed my code up while I am working with this now so that when I need it in the future it is ready.

If all your output updates can be buffered and looped using stream out, then you wouldn't need the command/response call and its overhead. Keep in mind that if you need to update the stream out buffer while streaming you will need to make command/response calls for that.

As for your previous post getting "lost in the ether", it is now public. Comments are approved by us before becoming public, so comments made close to or on the weekend may not be approved until Monday.