Logic Analyzer
Logic Analyzer (LA) commands allow interaction with the Logic Analyzer functionality on the Red Pitaya platform. They enable users to configure, start, stop, and retrieve data from the GPIO pins using the Logic Analyzer.
Functionality overview
The Logic Analyzer is currently controllable only on the API level. It works through the CLAController and CLACallback classes, which provide methods
for configuring the analyzer, setting triggers, starting and stopping data acquisition, and retrieving captured data. The data is captured and saved in the
OutputPacket structure.
CLACallbackis a callback interface for controlling the response to Logic Analyzer events. It is called whenever the data is captured by the FPGA, a block of data is uploaded by the user, has been decoded, or after the board has finished decoding the captured data.CLAControlleris the main interface for controlling the Logic Analyzer. It provides methods for configuring the analyzer, setting triggers, starting and stopping data acquisition, and retrieving captured data.
Important notes
The SCPI column is intentionally empty, as there are no SCPI commands for the Logic Analyzer yet. The C++ functions are in the rp_la namespace. The Python functions have the same
names and arguments as the C++ ones, except for the differences listed below:
NumPy buffer functions (
getDataNP,getUnpackedRLEDataNP,decodeNP,printRLENP) take the NumPy array only; its size is determined automatically.wait(timeoutMs)returnsTrueon timeout in Python, while C++ returns the result through theisTimeoutpointer argument.Functions that return decoded data (
getDecodedData,decode,decodeNP) return a list of dictionaries (one perOutputPacket) in Python.Callbacks are implemented by inheriting from
rp_la.CLACallbackand passing the object tosetDelegate(callback.__disown__()).
Code examples
Here are some examples of how to use the Logic analyzer commands on Red Pitaya:
Parameters and command tables
Output packet format
The decoders return the decoded data as a list of OutputPacket structures (rp_la::OutputPacket). Each packet describes one recognized block of the decoded protocol
(for example a UART byte, an I2C address or a CAN CRC). In Python, each packet is a dictionary with the same keys as the structure members (e.g., decode[index]['control']).
Member |
Type |
Description |
|---|---|---|
|
string |
Name of the protocol line the data was decoded from (for example RX, TX, MOSI, MISO, SDA). Only lines specified in the decoder settings are listed. |
|
uint8 |
Data identifier. Use it with |
|
uint32 |
Data contained in the protocol block (for example ID, DATA, CRC). |
|
float |
Number of recognized data bits. A multiple of 0.5 (0, 0.5, 1, 1.5, 2, …). |
|
double |
Start position of the block in samples (0 = first sample, 1 = second sample, …). The value is not an integer, since the bit width can be non-integer depending on the protocol. |
|
double |
Length of the recognized block in samples. |
Example of reading the packets in Python:
decode = rp_cla.getDecodedData("UART")
for packet in decode:
print(rp_cla.getAnnotation(rp_la.LA_DECODER_UART, packet['control']), "=", packet)
CLAController commands
CLAController is the main interface for configuring the Logic Analyzer, running the capture and retrieving or decoding data.
Parameter options:
<la_decoder> = {LA_DECODER_NONE, LA_DECODER_CAN, LA_DECODER_I2C, LA_DECODER_SPI, LA_DECODER_UART}(Logic Analyzer decoder type). DefaultLA_DECODER_NONE<la_trigger> = {LA_ERROR, LA_NONE, LA_LOW, LA_HIGH, LA_RISING, LA_FALLING, LA_RISING_OR_FALLING}(Logic Analyzer trigger type). DefaultLA_NONE<la_trig_channel> = {LA_T_CHANNEL_1, ... , LA_T_CHANNEL_8}(Logic Analyzer trigger channel number).<la_mode> = {LA_BASIC, LA_PRO}(Logic Analyzer mode).LA_BASICis used without an external logic analyzer unit,LA_PROwhen the extension module is connected.
Available Jupyter and API macros:
(Future OS release)
Setup and trigger
SCPI |
API, Jupyter |
DESCRIPTION |
ECOSYSTEM |
|---|---|---|---|
C++:
CLAController()Python:
CLAController() |
Creates the controller object. Release the resources with |
3.00-57 and up |
|
C++:
bool initFpga()Python:
initFpga() |
Initializes the FPGA registers and the reserved memory area. |
3.00-57 and up |
|
C++:
void setMode(la_Mode_t mode)Python:
setMode(mode) |
Sets the operating mode with or without an external unit. Affects only data capture from the FPGA. |
3.00-57 and up |
|
C++:
void setTrigger(la_Trigger_Channel_t channel, la_Trigger_Mode_t mode)Python:
setTrigger(channel, mode) |
Sets the trigger for the FPGA. Valid channels are 0 to 7 ( |
3.00-57 and up |
|
C++:
la_Trigger_Mode_t getTrigger(la_Trigger_Channel_t channel)Python:
getTrigger(channel) |
Returns the trigger setting for the specified channel. |
3.00-57 and up |
|
C++:
bool isNoTriggers()Python:
isNoTriggers() |
Returns true if triggers on all channels are set to |
3.00-57 and up |
|
C++:
void resetTriggers()Python:
resetTriggers() |
Sets triggers on all channels to |
3.00-57 and up |
|
C++:
bool softwareTrigger()Python:
softwareTrigger() |
Sends a trigger signal to the FPGA. Only makes sense during data capture on the FPGA, when the user wants to stop waiting for the trigger. |
3.00-57 and up |
Acquisition settings
SCPI |
API, Jupyter |
DESCRIPTION |
ECOSYSTEM |
|---|---|---|---|
C++:
bool setEnableRLE(bool enable)Python:
setEnableRLE(enable) |
Enables recording the data in the FPGA in RLE format; otherwise the data is recorded through DMA without compression. Decoders only work with RLE data.
RLE: |
3.00-57 and up |
|
C++:
bool isRLEEnable()Python:
isRLEEnable() |
Returns whether RLE mode is enabled. |
3.00-57 and up |
|
C++:
void setDecimation(uint32_t decimation)Python:
setDecimation(decimation) |
Sets the decimation used when capturing data with the FPGA. |
3.00-57 and up |
|
C++:
uint32_t getDecimation()Python:
getDecimation() |
Returns the decimation. |
3.00-57 and up |
|
C++:
void setPreTriggerSamples(uint32_t value)Python:
setPreTriggerSamples(value) |
Sets the number of samples the FPGA must write before the trigger. |
3.00-57 and up |
|
C++:
uint32_t getPreTriggerSamples()Python:
getPreTriggerSamples() |
Returns the number of pre-trigger samples. |
3.00-57 and up |
|
C++:
void setPostTriggerSamples(uint32_t value)Python:
setPostTriggerSamples(value) |
Sets the number of samples the FPGA records after the trigger. |
3.00-57 and up |
|
C++:
uint32_t getPostTriggerSamples()Python:
getPostTriggerSamples() |
Returns the number of post-trigger samples. |
3.00-57 and up |
|
C++:
uint32_t getDMAMemorySize()Python:
getDMAMemorySize() |
Returns the size of the reserved DMA memory in bytes. Without compression 1 sample equals 1 byte. With RLE the amount of data depends on the signal (for 1 MB of memory: 512k samples in the worst case, 131M samples in the best case). Take this into account when setting the pre/post trigger samples, as the buffer is circular and the data can overlap. |
3.00-57 and up |
Decoders
SCPI |
API, Jupyter |
DESCRIPTION |
ECOSYSTEM |
|---|---|---|---|
C++:
bool addDecoder(std::string name, la_Decoder_t decoder)Python:
addDecoder(name, decoder) |
Adds a decoder of the specified type under the specified name. |
3.00-57 and up |
|
C++:
std::vector<std::string> getDecoders()Python:
getDecoders() |
Returns the list of decoder names added by the user. |
3.00-57 and up |
|
C++:
bool isDecoderExist(std::string name)Python:
isDecoderExist(name) |
Checks if the specified decoder is installed. |
3.00-57 and up |
|
C++:
la_Decoder_t getDecoderType(std::string name)Python:
getDecoderType(name) |
Returns the decoder type for the specified name. |
3.00-57 and up |
|
C++:
void setDecoderEnable(std::string name, bool enable)Python:
setDecoderEnable(name, enable) |
Enables or disables the decoder. A disabled decoder is not used to decode data after a capture or after loading data. |
3.00-57 and up |
|
C++:
bool getDecoderEnable(std::string name)Python:
getDecoderEnable(name) |
Returns the decoder status (enabled or disabled). |
3.00-57 and up |
|
C++:
bool removeDecoder(std::string name)Python:
removeDecoder(name) |
Removes the specified decoder. |
3.00-57 and up |
|
C++:
void removeAllDecoders()Python:
removeAllDecoders() |
Removes all decoders. |
3.00-57 and up |
|
C++:
std::vector<OutputPacket> getDecodedData(std::string name)Python:
getDecodedData(name) |
Returns the decoded data of the specified decoder. See Output packet format. |
3.00-57 and up |
|
C++:
bool setDecoderSettings(std::string name, std::string json)Python:
setDecoderSettings(name, json) |
Sets the settings of the specified decoder in JSON format. |
3.00-57 and up |
|
C++:
std::string getDecoderSettings(std::string name)Python:
getDecoderSettings(name) |
Returns the settings of the specified decoder in JSON format. |
3.00-57 and up |
|
C++:
std::string getDefaultSettings(la_Decoder_t decoder)Python:
getDefaultSettings(decoder) |
Returns the default settings of the specified decoder type. Each decoder has its own set of keys. |
3.00-57 and up |
|
C++:
bool setDecoderSettingsUInt(std::string name, std::string key, uint32_t value)Python:
setDecoderSettingsUInt(name, key, value) |
Sets an unsigned integer setting of the decoder by key. Keys are taken from the JSON settings. Returns false if the key is not found. |
3.00-57 and up |
|
C++:
bool setDecoderSettingsFloat(std::string name, std::string key, float value)Python:
setDecoderSettingsFloat(name, key, value) |
Sets a float setting of the decoder by key. Returns false if the key is not found. |
3.00-57 and up |
|
C++:
bool setDecoderSettingsString(std::string name, std::string key, std::string value)Python:
setDecoderSettingsString(name, key, value) |
Sets a string setting of the decoder by key. Returns false if the key is not found. |
3.00-57 and up |
|
C++:
bool getDecoderSettingsUInt(std::string name, std::string key, uint32_t* value)Python:
getDecoderSettingsUInt(name, key) |
Returns the unsigned integer setting for the specified key. Returns false if the key is not found. |
3.00-57 and up |
|
C++:
bool getDecoderSettingsFloat(std::string name, std::string key, float* value)Python:
getDecoderSettingsFloat(name, key) |
Returns the float setting for the specified key. Returns false if the key is not found. |
3.00-57 and up |
|
C++:
bool getDecoderSettingsString(std::string name, std::string key, std::string* value)Python:
getDecoderSettingsString(name, key) |
Returns the string setting for the specified key. Returns false if the key is not found. |
3.00-57 and up |
|
C++:
std::map<uint8_t, std::string> getAnnotationList(la_Decoder_t decoder)Python:
getAnnotationList(decoder) |
Returns all annotations (control value to text) of the specified decoder type. |
3.00-57 and up |
|
C++:
std::string getAnnotation(la_Decoder_t decoder, uint8_t control)Python:
getAnnotation(decoder, control) |
Returns the annotation text for the |
3.00-57 and up |
Capture, decode and data access
SCPI |
API, Jupyter |
DESCRIPTION |
ECOSYSTEM |
|---|---|---|---|
C++:
void setDelegate(CLACallback* callbacks)Python:
setDelegate(callback.__disown__()) |
Sets the object with the callback functions. See CLACallback commands. |
3.00-57 and up |
|
C++:
void removeDelegate()Python:
removeDelegate() |
Removes the callback object. |
3.00-57 and up |
|
C++:
bool isCaptureRun()Python:
isCaptureRun() |
Shows whether data capture is running. |
3.00-57 and up |
|
C++:
void runAsync(uint32_t timeoutMs)Python:
runAsync(timeoutMs) |
Starts capturing data from the FPGA asynchronously and decodes the captured data. A timeout of 0 means no timeout. |
3.00-57 and up |
|
C++:
void runAsync(std::vector<uint8_t> data, bool isRLE, uint64_t triggerSamplePosition)Python:
runAsync(data, isRLE, triggerSamplePosition) |
Asynchronously decodes user data. |
3.00-57 and up |
|
C++:
void decodeAsync()Python:
decodeAsync() |
Asynchronously decodes data captured with the FPGA or loaded with |
3.00-57 and up |
|
C++:
void wait(uint32_t timeoutMs, bool* isTimeout)Python:
wait(timeoutMs) |
Waits for the asynchronous function to complete or time out. Python returns |
3.00-57 and up |
|
C++:
std::vector<OutputPacket> decode(std::string name)Python:
decode(name) |
Synchronous decoding of the data with the specified decoder. A copy of the decoder with its settings is used, so the decoder itself is not changed. Callback functions are not called. |
3.00-57 and up |
|
C++:
std::vector<OutputPacket> decodeNP(la_Decoder_t decoder, std::string json_settings, uint8_t* np_buffer, int size)Python:
decodeNP(decoder, json_settings, np_buffer) |
Synchronously decodes the data from a NumPy buffer with the specified decoder type and JSON settings. Callback functions are not called. |
3.00-57 and up |
|
C++:
bool saveCaptureDataToFile(std::string file)Python:
saveCaptureDataToFile(file) |
Saves the data from the buffer to a file. |
3.00-57 and up |
|
C++:
bool loadFromFile(std::string file, bool isRLE, uint64_t triggerSamplePosition)Python:
loadFromFile(file, isRLE, triggerSamplePosition) |
Loads the data from a file into the analyzer buffer, without decoding. |
3.00-57 and up |
|
C++:
bool loadFromFileAndDecode(std::string file, bool isRLE, uint64_t triggerSamplePosition)Python:
loadFromFileAndDecode(file, isRLE, triggerSamplePosition) |
Loads the data from a file into the analyzer buffer and decodes it. Loading and decoding are asynchronous. |
3.00-57 and up |
|
C++:
uint32_t getCapturedDataSize()Python:
getCapturedDataSize() |
Returns the number of bytes captured by the FPGA or loaded from the user data array. |
3.00-57 and up |
|
C++:
uint64_t getCapturedSamples()Python:
getCapturedSamples() |
Returns the number of samples captured by the FPGA or loaded from the user data array (also calculated from RLE). |
3.00-57 and up |
|
C++:
uint32_t getDataNP(uint8_t* np_buffer, int size)Python:
getDataNP(np_buffer) |
Returns the data from the buffer into a NumPy array. Returns the number of samples. |
3.00-57 and up |
|
C++:
uint64_t getUnpackedRLEDataNP(uint8_t* np_buffer, int size)Python:
getUnpackedRLEDataNP(np_buffer) |
Returns the unpacked RLE data into a NumPy array. Size the array with |
3.00-57 and up |
|
C++:
void printRLE(bool useHex)Python:
printRLE(useHex) |
Prints the RLE data. |
3.00-57 and up |
|
C++:
void printRLENP(uint8_t* np_buffer, int size, bool useHex)Python:
printRLENP(np_buffer, useHex) |
Prints the RLE data from a NumPy buffer. |
3.00-57 and up |
CLACallback commands
CLACallback is the callback interface. Inherit from it and override the functions you need, then register the object with setDelegate. The callbacks are not called by the synchronous decode functions.
SCPI |
API, Jupyter |
DESCRIPTION |
ECOSYSTEM |
|---|---|---|---|
C++:
void captureStatus(CLAController* controller, bool isTimeout, uint32_t numBytes, uint64_t numSamples, uint64_t preTriggerSamples, uint64_t postTriggerSamples)Python:
captureStatus(self, controller, isTimeout, bytes, samples, preTrig, postTrig) |
Called after data is captured on the FPGA (after |
3.00-57 and up |
|
C++:
void decodeStatus(CLAController* controller, uint32_t numBytes, uint64_t numSamples, uint64_t preTriggerSamples, uint64_t postTriggerSamples)Python:
decodeStatus(self, controller, bytes, samples, preTrig, postTrig) |
Called after a block of data uploaded by the user has been decoded (after |
3.00-57 and up |
|
C++:
void decodeDone(CLAController* controller, std::string name)Python:
decodeDone(self, controller, name) |
Called after each of the configured decoders has finished decoding. |
3.00-57 and up |