Skip to content

Commit

Permalink
October-update-2.1
Browse files Browse the repository at this point in the history
Python API commands added, API commands parameters added, fixed image scaling under VNA, Deep Memory Acquisition, Code examples updated (added Python and C API examples), minor fixes to the FPGA section
  • Loading branch information
Lightsaver7 committed Oct 25, 2023
2 parents 7556d6e + fd0d039 commit 9de7612
Show file tree
Hide file tree
Showing 51 changed files with 5,637 additions and 2,995 deletions.
25 changes: 14 additions & 11 deletions appsFeatures/applications/vna/appVNA.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Connect Vector Network Analyzer bridge to the Red Pitaya

.. figure:: img/vna_bridge_module_connections.png
:align: center
:scale: 50%
:width: 600

=========================================================
Install & run network Vector Network Analyzer control app
Expand Down Expand Up @@ -73,7 +73,7 @@ Connect by entering the Red Pitaya's IP:

.. figure:: img/1_ip.png
:align: center
:scale: 80%
:width: 600

To find the IP address of the Red Pitaya board, first connect to RedPitaya by following these :ref:`instructions <quick_start>`.

Expand All @@ -82,7 +82,7 @@ Then go to System->Network Manager. The IP is written next to the label.
Address: xxx.xxx.xxx.xxx .

.. figure:: img/network_manager_icon.png
:width: 150px
:width: 150 px
:align: center

----------------------------------
Expand All @@ -91,7 +91,7 @@ Connect by entering RedPitaya URL:

.. figure:: img/1_url.png
:align: center
:scale: 80%
:width: 600

============================================================
Run the Vector Network Analyzer application on the RedPitaya
Expand All @@ -107,7 +107,7 @@ Click "Connect" inside the Vector Network Analyzer control app

.. figure:: img/2_connect.png
:align: center
:scale: 80%
:width: 600

***************************************
Perform calibration and start measuring
Expand All @@ -120,37 +120,37 @@ Perform calibration and start measuring

.. figure:: img/3_calibrate.png
:align: center
:scale: 80%
:width: 600

#. Connect the SMA OPEN calibration connector marked with the letter O to the DUT SMA connector of the network vector analyzer bridge module. Click the button "Open" and wait for the calibration procedure to complete.

.. figure:: img/04_Calibration_O.jpg
:align: center
:scale: 50%
:width: 600

#. Connect the SMA SHORT calibration connector marked with the letter S to the DUT SMA connector of the network vector analyzer bridge module. Click the button "Short" and wait for the calibration procedure to complete.

.. figure:: img/03_Calibration_S.jpg
:align: center
:scale: 50%
:width: 600

#. Connect the SMA LOAD calibration connector marked with the letter L to the DUT SMA connector of the network vector analyzer bridge module. Click the button "Load" and wait for the calibration procedure to complete.

.. figure:: img/05_Calibration_L.jpg
:align: center
:scale: 50%
:width: 600

#. Select the Smith chart tab at the bottom and then click the Single button to perform a single measurement of the DUT. A dot in the middle of the Smith chart circle (@ 50 Ohm) will indicate that VNA is properly measuring the reference 50 Ohm LOAD.

.. figure:: img/4-load_DUT_smith_chart.png
:align: center
:scale: 80%
:width: 600

#. Disconnect the LOAD SMA connector and connect whatever DUT you’d like to measure.

.. figure:: img/07_Product_Combo.jpg
:align: center
:scale: 60%
:width: 600

=========
Examples:
Expand All @@ -161,15 +161,18 @@ Examples:

.. figure:: img/antenna.png
:align: center
:width: 600

#. 20-meter bandpass filter for HAM RADIO
SWR is better than 1.5 between the start and stop band frequencies, and the filter load is around 50 Ohm.

.. figure:: img/bandpass_filter.png
:align: center
:width: 600

.. figure:: img/bandpass_filter_smith_chart.png
:align: center
:width: 600

.. admonition:: Credits

Expand Down
276 changes: 276 additions & 0 deletions appsFeatures/examples/DMA/deepMemoryAcq.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
.. _deepMemoryAcq_example:

Deep Memory Acquisition
########################

Description
============

The example shows how to capture data into two 1024-byte buffers using the Deep Memory Acquisition. DMA can work in parallel with starndard SCPI acquisition.


Required hardware
==================

- Red Pitaya device
- Signal (function) generator


Wiring example for STEMlab 125-14:

.. figure:: img/DMA_temp.png



SCPI Code Examples
====================

**Coming soon...**


API Code Examples
====================

.. note::

The API code examples don't require the use of the SCPI server. Instead, the code should be compiled and executed on the Red Pitaya itself (inside Linux OS).
Instructions on how to compile the code and other useful information are :ref:`here <comC>`.


Code - C API
---------------

Please note that checking whether a function was successful is not necessary.

.. code-block:: c
/* Red Pitaya C API example Acquiring a signal from a buffer
* This application acquires a signal on a specific channel */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "rp.h"
#define DATA_SIZE 1024
int main(int argc, char **argv)
{
/* Initialise Red Pitaya */
if (rp_InitReset(false) != RP_OK) {
fprintf(stderr, "Rp api init failed!\n");
return -1;
}
/* Set decimation for both channels */
if (rp_AcqAxiSetDecimationFactor(RP_CH_1, RP_DEC_1) != RP_OK) {
fprintf(stderr, "rp_AcqAxiSetDecimationFactor RP_CH_1 failed!\n");
return -1;
}
if (rp_AcqAxiSetDecimationFactor(RP_CH_2, RP_DEC_1) != RP_OK) {
fprintf(stderr, "rp_AcqAxiSetDecimationFactor RP_CH_2 failed!\n");
return -1;
}
/* Set trigger delay for both channels */
if (rp_AcqAxiSetTriggerDelay(RP_CH_1, DATA_SIZE ) != RP_OK) {
fprintf(stderr, "rp_AcqAxiSetTriggerDelay RP_CH_1 failed!\n");
return -1;
}
if (rp_AcqAxiSetTriggerDelay(RP_CH_2, DATA_SIZE ) != RP_OK) {
fprintf(stderr, "rp_AcqAxiSetTriggerDelay RP_CH_2 failed!\n");
return -1;
}
/*
Set-up the Channel 1 and channel 2 buffers to each work with half the available memory space.
ADC_AXI_START is a macro for the first address in the Deep Memory Acquisition region.
ADC_AXI_END is a macro for the last/end address in the DMA region.
*/
if (rp_AcqAxiSetBuffer(RP_CH_1, ADC_AXI_START, DATA_SIZE) != RP_OK) {
fprintf(stderr, "rp_AcqAxiSetBuffer RP_CH_1 failed!\n");
return -1;
}
if (rp_AcqAxiSetBuffer(RP_CH_2, (ADC_AXI_END + ADC_AXI_START) / 2, DATA_SIZE) != RP_OK) {
fprintf(stderr, "rp_AcqAxiSetBuffer RP_CH_2 failed!\n");
return -1;
}
/* Enable DMA on both channels */
if (rp_AcqAxiEnable(RP_CH_1, true)) {
fprintf(stderr, "rp_AcqAxiEnable RP_CH_1 failed!\n");
return -1;
}
if (rp_AcqAxiEnable(RP_CH_2, true)) {
fprintf(stderr, "rp_AcqAxiEnable RP_CH_2 failed!\n");
return -1;
}
/* Specify the acquisition trigger */
rp_AcqSetTriggerLevel(RP_T_CH_1,0);
/* Start the acquisition */
if (rp_AcqStart() != RP_OK) {
fprintf(stderr, "rp_AcqStart failed!\n");
return -1;
}
/* Specify trigger source */
rp_AcqSetTriggerSrc(RP_TRIG_SRC_CHA_PE);
rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;
/* Wait for the triggering moment */
while(1){
rp_AcqGetTriggerState(&state);
if(state == RP_TRIG_STATE_TRIGGERED){
sleep(1);
break;
}
}
/* Wait until both buggers are full/data is acquired */
bool fillState = false;
while (!fillState) {
if (rp_AcqAxiGetBufferFillState(RP_CH_1, &fillState) != RP_OK) {
fprintf(stderr, "rp_AcqAxiGetBufferFillState RP_CH_1 failed!\n");
return -1;
}
}
/* Stop the acquisition */
rp_AcqStop();
/* Get write pointer on the triggering location */
uint32_t posChA,posChB;
rp_AcqAxiGetWritePointerAtTrig(RP_CH_1,&posChA);
rp_AcqAxiGetWritePointerAtTrig(RP_CH_2,&posChB);
/* Allocate memory for the data */
int16_t *buff1 = (uint16_t *)malloc(DATA_SIZE * sizeof(int16_t));
int16_t *buff2 = (uint16_t *)malloc(DATA_SIZE * sizeof(int16_t));
/* Pass the write pointer value at trigger to get data. */
uint32_t size1 = DATA_SIZE;
uint32_t size2 = DATA_SIZE;
rp_AcqAxiGetDataRaw(RP_CH_1, posChA, &size1, buff1);
rp_AcqAxiGetDataRaw(RP_CH_2, posChB, &size2, buff2);
/* Print data */
for (int i = 0; i < DATA_SIZE; i++) {
printf("%d\t%d\n", buff1[i], buff2[i]);
}
/* Releasing resources */
rp_AcqAxiEnable(RP_CH_1, false);
rp_AcqAxiEnable(RP_CH_2, false);
rp_Release();
free(buff1);
free(buff2);
return 0;
}
Code - Python API
-------------------

.. code-block:: python
#!/usr/bin/python3
"""Example of DMA acquisition of 1024-samples of data on both channels"""
import time
import rp
DATA_SIZE = 1024
dec = rp.RP_DEC_1
trig_lvl = 0.2
# Initialize the interface
rp.rp_Init()
### Setting up DMA ###
# Get Memory region
memoryRegion = rp.rp_AcqAxiGetMemoryRegion()
print(f"Memory Region: {memoryRegion}")
start = memoryRegion[1]
size = memoryRegion[2]
# Set decimation
rp.rp_AcqAxiSetDecimationFactor(dec)
# Set trigger delay for both channels
rp.rp_AcqAxiSetTriggerDelay(rp.RP_CH_1, DATA_SIZE)
rp.rp_AcqAxiSetTriggerDelay(rp.RP_CH_2, DATA_SIZE)
# Set-up the Channel 1 and channel 2 buffers to each work with half the available memory space.
# - ADC_AXI_START is a macro for the first address in the Deep Memory Acquisition region.
# - ADC_AXI_END is a macro for the last/end address in the DMA region.
rp.rp_AcqAxiSetBufferSamples(rp.RP_CH_1, start, DATA_SIZE)
rp.rp_AcqAxiSetBufferSamples(rp.RP_CH_2, int(start + size/2), DATA_SIZE)
# Enable DMA on both channels
rp.rp_AcqAxiEnable(rp.RP_CH_1, True)
rp.rp_AcqAxiEnable(rp.RP_CH_2, True)
# Specify the acquisition trigger
rp.rp_AcqSetTriggerLevel(rp.RP_T_CH_1, trig_lvl)
### Acquisition ###
# Start the DMA acquisition
rp.rp_AcqStart()
print("DMA started")
# Specify trigger source
rp.rp_AcqSetTriggerSrc(rp.RP_TRIG_SRC_CHA_PE)
state = rp.RP_TRIG_STATE_TRIGGERED
# Wait for the triggering moment
while 1:
state = rp.rp_AcqGetTriggerState()[1]
if state == rp.RP_TRIG_STATE_TRIGGERED:
print("Triggered")
time.sleep(1)
break
# Wait until both buggers are full/data is acquired
fillState = False
print(type(rp.rp_AcqAxiGetBufferFillState(rp.RP_CH_1)[1]))
while not fillState:
fillState = rp.rp_AcqAxiGetBufferFillState(rp.RP_CH_1)[1]
print("DMA buffer full")
# Stop the acquisition
rp.rp_AcqStop()
print("DMA stopped")
# Get write pointer on the triggering location
posChA = rp.rp_AcqAxiGetWritePointerAtTrig(rp.RP_CH_1)[1]
posChB = rp.rp_AcqAxiGetWritePointerAtTrig(rp.RP_CH_2)[1]
# Allocate memory for the data
buff1 = rp.i16Buffer(DATA_SIZE)
buff2 = rp.i16Buffer(DATA_SIZE)
# Pass the write pointer value at trigger to get data. */
rp.rp_AcqAxiGetDataRaw(rp.RP_CH_1, posChA, DATA_SIZE, buff1.cast())
rp.rp_AcqAxiGetDataRaw(rp.RP_CH_2, posChB, DATA_SIZE, buff2.cast())
# Print data
print()
print(" CH 1 CH 2")
for i in range(0, DATA_SIZE):
print(f"{buff1[i]:5d} {buff2[i]:5d}")
### Releasing resources ###
print("\nReleasing resources\n")
rp.rp_AcqAxiEnable(rp.RP_CH_1, False)
rp.rp_AcqAxiEnable(rp.RP_CH_2, False)
rp.rp_Release()
Binary file added appsFeatures/examples/DMA/img/DMA_temp.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9de7612

Please sign in to comment.