PO8eStreaming
PO8eStreaming is a library of methods for accessing data on one or several PO8e interfaces through a custom Windows or Linux application. See PO8e Streaming Interface for more hardware-related information.
The PO8eStreaming libraries and examples for C++, Python, and MATLAB install with the TDT drivers into:
C:\TDT\RPvdsEx\Examples\PO8e\
Users should be mindful of using good 'closed loop' access when working with PO8eStreaming. This means always releasing any open connections to PO8e cards.
A typical PO8e access session for a client consists of five main steps:
- Call
connectToCard
to get a pointer to an available PO8e card. - Call
startCollecting
to begin reading from PO8e card. - Run the circuit on the RZ device that streams to the PO8e card.
- Perform any number of buffer operations.
- Call
releaseCard
to release the card object from memory.
Setup and Control
The methods in this group are used to setup access to any PO8e card(s) in the system.
cardCount
Returns the number of PO8e cards detected in the system. Call this first to
determine the possible values for the cardIndex
passed to the constructor.
static int cardCount();
int cardCount();
Example
int totalCards = PO8e::cardCount();
int totalCards = cardCount();
connectToCard
Returns a pointer to the specified card index. Note that the index will be consistent across system boots and is dependent on the PCIe bus layout, so if you move the cards between slots their respective indices can change.
static PO8e* connectToCard(unsigned int cardIndex = 0);
void* connectToCard(unsigned int cardIndex = 0);
Example
This code sample creates a PO8e object pointing to the first card identified in the system.
PO8e *card = PO8e::connectToCard(0);
void *card = connectToCard(0);
releaseCard
Free the PO8e card objects through this interface. It is done this way to ensure that in Windows the objects are freed from the correct heap context.
static void releaseCard(PO8e *card);
void releaseCard(void* card);
Example
This code sample releases the card object memory.
PO8e::releaseCard(card);
releaseCard(card);
Hardware Data Access
The methods in this group are used to read data from PO8e card(s).
startCollecting
Call this to start collecting a data stream from the PO8e card. Collected data will be buffered as needed.
bool startCollecting(bool detectStops = true);
bool startCollecting(void* card, bool detectStops = true);
Example
This code sample tells an existing PO8e object to begin collecting data.
card->startCollecting(true);
startCollecting(card, true);
stopCollecting
Call this to stop collecting a data stream from the PO8e card.
void stopCollecting();
void stopCollecting(void* card);
Example
This code sample stops data collection on a PO8e object.
card->stopCollecting(true);
stopCollecting(card, true);
waitForDataReady
This function provides a means to efficiently wait for data to arrive from the RZ unit.
size_t waitForDataReady(int timeout = 0xFFFFFFFF);
int waitForDataReady(void* card, int timeout = 0xFFFFFFFF);
Example
This code sample blocks execution until buffered data is ready on the card.
card->waitForDataReady();
waitForDataReady(card);
samplesReady
Returns the number of samples (per channel) that are currently buffered.
size_t samplesReady(bool *stopped = 0);
int samplesReady(void* card, bool *stopped = 0);
Example
This code returns the number of samples (per channel) currently buffered on the card and detects if streaming has stopped.
bool stopped;
size_t numSamples = card->samplesReady(&stopped);
if (stopped)
PO8e::releaseCard(card);
bool stopped;
int numSamples = samplesReady(card, &stopped);
if (stopped)
releaseCard(card);
readChannel
Copy the data buffered for an individual channel. Note that this call does not
advance the data pointer. Use calls to flushBufferedData
to discard the data
copied using this function.
The user is responsible for ensuring that the buffer is large enough to hold
nSamples * dataSampleSize()
bytes.
The optional offsets array should be nSamples
long and will be populated with
the data offset of each block. This allows a user to detect if the buffer on
the RZ unit has overflowed.
int readChannel(int chanIndex, void *buffer, int nSamples, int64_t *offsets = NULL);
int readChannel(void* card, int chanIndex, void *buffer, int nSamples, int64_t *offsets);
Example
This code sample reads 1 sample from channel 2 and stores it in buff.
short buff[8192];
card->readChannel(2, buff, 1);
short buff[8192];
readChannel(card, 2, buff, 1);
readBlock
Copy the data buffered for all channels. Note that this call does not advance
the data pointer. Use calls to flushBufferedData
to discard the data copied
using this function.
The data will be grouped by channel and the number of samples returned applies
to all channels. The user is responsible for ensuring that the buffer is large
enough to hold nSamples * numChannels() * dataSampleSize()
bytes.
The optional offsets array should be nSamples long and will be populated with the data offset of each block. This allows a user to detect if the buffer on the RZ unit has overflowed.
int readBlock(void *buffer, int nSamples, int64_t *offsets = NULL);
int readBlock(void* card, void *buffer, int nSamples, int64_t *offsets);
Example
This code sample reads 1 sample from all channels, stores it in a buffer, and flushes that data from the card.
short buff[1024];
card->readBlock(buff, 1);
card->flushBufferedData(1);
short buff[1024];
readBlock(card, buff, 1);
flushBufferedData(card, 1);
flushBufferedData
Releases samples from each buffered channel.
void flushBufferedData(int numSamples = -1, bool freeBuffers = false);
void flushBufferedData(void* card, int numSamples = -1, bool freeBuffers = false);
Example
This code sample flushes one sample from all channels.
card->flushBufferedData(1);
flushBufferedData(card, 1);
Hardware Information Retrieval
The methods in this group access information pertaining to the current data stream, including number of channels and sample size in bytes.
numChannels
Counts the number of channels in the current stream. This value is set in the PO8e HAL in Synapse (or Stream_Remote_MC macro in RPvdsEx). Changing the number of channels mid-stream triggers an error condition.
int numChannels();
int numChannels(void* card);
Example
This code determines how many channels are in the current stream.
int nChannels = card->numChannels();
int nChannels = numChannels(card);
numBlocks
Counts the number of blocks that the current stream is divided into. This value will always be 1 when using Synapse, or can be set in the Stream_Remote_MC macro in RPvdsEx.
Each block will contain the same number of channels, so dividing the value from numChannels()
by this value will leave no remainder. Changing the number of blocks mid-stream triggers an
error condition.
int numBlocks();
int numBlocks(void* card);
Example
This code determines how many blocks are in the current stream.
int nBlocks = card->numBlocks();
int nBlocks = numBlocks(card);
dataSampleSize
Returns the size in bytes of each data sample (per channel). This value is set in the PO8e HAL in Synapse (or Stream_Remote_MC macro in RPvdsEx). Changing the data type mid-stream triggers an error condition.
int dataSampleSize();
int dataSampleSize(void* card);
Example
This code determines how many bytes are in each sample.
int dataSize = card->dataSampleSize();
int dataSize = dataSampleSize(card);
getLastError
This returns the most recent error.
int getLastError();
int getLastError(void* card);
Example
This code returns the most recent error code.
int errCode = card->getLastError();
int errCode = getLastError(card);
Examples
The example files below are installed with the TDT drivers package.
PO8eTest
C:\TDT\RPvdsEx\Examples\PO8e\PO8eTest.rcx
C:\TDT\RPvdsEx\Examples\PO8e\PO8eTest.exe
PO8eTest.exe connects to any PO8e card(s) in the PC, waits for a stream then displays the data rate that each PO8e card is receiving.
PO8eTest.rcx streams 256 channels of floats to the PO8e card at 6.1 kHz.
- Run PO8eTest.exe test application first.
- Verify that it connected to the PO8e card.
- Open PO8eTest.rcx in RPvdsEx.
- Assign the circuit to the DSPU or DSPS in your RZ.
- Run the circuit.
- Set the zBusA trigger high to begin streaming.
- Verify that PO8eTest.exe sees data.
- Set the zBusA trigger low to stop streaming.
Source Files:
C:\TDT\RPvdsEx\Examples\PO8e\Example\
C:\TDT\RPvdsEx\Examples\PO8e\Include\
MATLAB
C:\TDT\RPvdsEx\Examples\PO8e\Matlab\
The PO8e_4card.m class wraps the PO8e Streaming Library. The PO8e_4cardTest.m example demonstrates reading from PO8e card(s) in MATLAB.
Python
C:\TDT\RPvdsEx\Examples\PO8e\Python64
The PO8e.py class wraps the PO8e Streaming Library and contains demo code for reading from PO8e card(s) in Python.
Linux Support
Some Linux library files and example build instructions are installed to:
C:\TDT\RPvdsEx\Examples\PO8e\Linux
Please contact TDT if you need assistance.