2.3.3. AXI mode
2.3.3.1. Description
The axi mode will allow you to set a buffer of any size (The buffer must be a multiple of 64 bytes) for capturing data from the ADC. Data is written directly to RAM.
Features
Axi mode can work in parallel with regular data capture mode in 0.94, only work with triggers is common.
By default, the maximum size of two buffers (1 and 2 channels) can be a maximum of 1.5 MB.
Axi mode can run at maximum ADC speed.
AXI can assign only one buffer, thereby allocating all memory to only 1 channel.
2.3.3.2. Required hardware
Red Pitaya device
FPGA v0.94
2.3.3.3. API functions
API |
DESCRIPTION |
---|---|
|
Indicates whether the ADC AXI buffer was full of data.
|
|
Sets the decimation used at acquiring signal for AXI.
|
|
Sets the number of decimated data after trigger written into memory.
|
|
Returns current position of AXI ADC write pointer.
|
|
Returns position of AXI ADC write pointer at time when trigger arrived.
|
|
Sets the AXI enable state.
|
|
Returns the AXI ADC buffer
in raw units from specified position and desired size.
|
|
Returns the AXI ADC buffer
in Volt units from specified position and desired size.
|
|
Sets the AXI ADC buffer address and size in samples.
|
Additional information about function parameters is in this file:
2.3.3.4. Example
The example shows how to use capturing data into two 1024 byte buffers.
/* 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)
{
if (rp_InitReset(false) != RP_OK) {
fprintf(stderr, "Rp api init failed!\n");
return -1;
}
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;
}
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;
}
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;
}
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;
}
rp_AcqSetTriggerLevel(RP_T_CH_1,0);
if (rp_AcqStart() != RP_OK) {
fprintf(stderr, "rp_AcqStart failed!\n");
return -1;
}
rp_AcqSetTriggerSrc(RP_TRIG_SRC_CHA_PE);
rp_acq_trig_state_t state = RP_TRIG_STATE_TRIGGERED;
while(1){
rp_AcqGetTriggerState(&state);
if(state == RP_TRIG_STATE_TRIGGERED){
sleep(1);
break;
}
}
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;
}
}
rp_AcqStop();
uint32_t posChA,posChB;
rp_AcqAxiGetWritePointerAtTrig(RP_CH_1,&posChA);
rp_AcqAxiGetWritePointerAtTrig(RP_CH_2,&posChB);
int16_t *buff1 = (uint16_t *)malloc(DATA_SIZE * sizeof(int16_t));
int16_t *buff2 = (uint16_t *)malloc(DATA_SIZE * sizeof(int16_t));
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);
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;
}
Note
Instructions on how to compile the code are here.