pavel-demin / red-pitaya-notes

Notes on the Red Pitaya Open Source Instrument
http://pavel-demin.github.io/red-pitaya-notes/
MIT License
337 stars 209 forks source link

Reg Adc_recorder project #719

Closed falcon98 closed 5 years ago

falcon98 commented 6 years ago

Hi Pavel,

I used your ADC_recorder project and tried to build some understanding. The overall sampling rate is 2 MSps due to usage of CIC and FIR filters. The c code is able to print 1024K samples from both the ADCs. I am able to recover signals at 100 KHz frequency from this code. My queries to you are:

1) I want to sample the signals at 125 MSps frequency in order to digitize high bandwidth signals. I am planning to remove the CIC and fir filters from the block diagram and directly combine the stream combiner to packetizer. Do you think that this will work? 2) Since the RAM is of 512 MB size, I am thinking of increasing the buffer of acquired data from ADC. I changed the C program by setting the number of samples in multiples of 2 (like 8 10241024) . I am getting segmentation error when I am executing this code on RP. What changes do I need to do in the C program or the block diagram in order to read larger amount of data.

Thanks a lot Best Regards, David Falcon

falcon98 commented 6 years ago

Hi Pavel,

Just to put an update. I went through the earlier link (https://github.com/pavel-demin/red-pitaya-notes/issues/320) where similar discussion was initiated.

I have removed the blocks between ADC stream and RAM writer and now able to acquire the data at 125 MS from ADC. I have tested it to 20 Mhz signals for proper reconstruction. I am able to log the data in text file on RP . Now I am working on increasing the memory size of acquired data from 1M to 8M or higher.

Thanks.

pavel-demin commented 6 years ago

Hi David,

I think that the adc_recorder project should be able to write up to 32 MB of data or up to 8M samples.

To write more samples, the starting address and the address width should be changed.

Best regards,

Pavel

falcon98 commented 6 years ago

Thanks for your reply.I was able to test upto 8M and when I increased the limit to 16 M, I was getting garbage data . I just wanted to understand that since the RAM is 512MB, it should be possible to acquire upto (512/4) or 128M samples? Is my understanding correct here.

Also for your ADC-test project, I tried using Win builds for client but I am facing installation issues. Can you suggest some other compiler which can build the client program for windows? I tried codeblocks but that didnt worked.

Thanks a alot

pavel-demin commented 6 years ago

I just wanted to understand that since the RAM is 512MB, it should be possible to acquire upto (512/4) or 128M samples?

With Linux running on Red Pitaya, some RAM is used by Linux. It's possible to reduce the amount of RAM used by Linux to 64 MB or maybe even less. So, it should be possible to acquire up to (512-32)/4 or 120M samples.

Can you suggest some other compiler which can build the client program for windows? I tried codeblocks but that didnt worked.

I'm using MinGW GCC to compile the client program. If you have Code::Blocks that comes with MinGW GCC, then I think that it should be able to compile the client program. What error messages do you get?

falcon98 commented 6 years ago

Hi,

I am getting following warning and error:

error: 'MSG_WAITALL' undeclared (first use in this function)

warning: implicit declaration of function 'perror'

When I am commenting or changing the MSG_WAITALL parameter still I am unable to build it.

pavel-demin commented 6 years ago

I've just tried to compile adc-test-client.c with MinGW from this link. It works without any error message.

falcon98 commented 6 years ago

Finally I was able to compile the code with compiler given at your link. Thanks I started the server and then the client programs .the server did detected a new connection . I wanted to know how to observe the data from adc at client. Can simple printf statements work here like in your other programs. Is there any other utility by which data can be observed. Thanks again.

falcon98 commented 6 years ago

Hi Pavel,

Can you please suggest a possible way to continuous log the ADC data either in server or client program. I am trying multiple ways in C but nothing seems to work.

pavel-demin commented 6 years ago

Hi David,

I think that adding fopen and fwrite to the client program should be enough to continuously log the ADC data. Is there a problem with this approach?

Best regards,

Pavel

falcon98 commented 6 years ago

Hi Pavel, Thanks for your reply. I tried fwrite where I am giving the start address of the pointer to ram location and kept the size as the buffer , but I am unable to read the file . I have tried .bin and .TXT files. Also the memory is continuous , so in the file I am reading alternate samples for each Channel. I will post the code from my lab setup by tomorrow.

pavel-demin commented 6 years ago

but I am unable to read the file

How are you reading the file?

I am reading alternate samples for each Channel.

I've just checked that in the adc_test project only the samples from IN2 are recorded.

falcon98 commented 6 years ago

Hi Pavel,

THis is the code which I am trying:

int main(int argc, char**argv)
{
  SOCKET sock;
  int i=0;
  struct sockaddr_in addr;
  char buffer[256*4096];
 // int int_buffer[256*4096];
 size_t data_length;
  WSADATA wsaData;
  WSAStartup(MAKEWORD(2, 2), &wsaData);

  FILE *file = fopen("local.bin","wb");

  if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  {
    perror("socket");
    return 1;
  }
printf("start\n");
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = inet_addr(TCP_ADDR);
  addr.sin_port = htons(TCP_PORT);
printf("start1\n");
  if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
  {
    perror("connect");
    return 1;
  }
printf("start2\n");
  while(i<5)
  {
    data_length=   recv(sock, buffer, 256*4096, MSG_WAITALL);
   // int_buffer = sscanf(buffer);

    fwrite(buffer,data_length,1,file);

i = i+1;
    printf("Data recvd: %d, index: %d\n", data_length,i);

  }

fclose(file);
  getch();
}

as per the code, the sampling rate should be 125 MSps but I am getting random results. I am attaching a bin file for your reference which I am reading with LabVIEW. Pls let me know if the code is correct or not

local1MHz.zip

pavel-demin commented 6 years ago

the sampling rate should be 125 MSps but I am getting random results

It's probably the main source of the problem. It's impossible to transfer the 14-bit samples at 125 MSPS over a 1 Gbit/s Ethernet link without compression:

1 Gbit/s = 1.07e9 bit/s

14*125e6 bit/s = 1.75e9 bit/s

The main purpose of the adc_test project was to test how fast the ADC samples could be transferred to a remote PC. Here is a link to a post on the Red Pitaya forum with the results of those tests: http://forum.redpitaya.com/viewtopic.php?t=317&p=2118#p2118

The highest working sample rate that I achieved was 31.25 MSPS.

falcon98 commented 6 years ago

Oh ok, I understand now, by the data file I was able to calculate sampling rate as 30-32 MSps and got confused. SO basically the network transfer is averaging the data due to transmission bottleneck. It will be really interesting to work upon compression based data transmission. I will try this later.

Hence if such high rate acquisition needs to be done then the file should be saved locally and then transferred after acquisition. In you triggered acquisition project I modified the c code in order to log the data to file.

  for(i = 0; i < 32*1024 * 1024; ++i)
  {
    offset = ((start + i) & 0x007FFFFF) * 4;

    value[0] = *((int16_t *)(ram + offset + 0));

    value[1] = *((int16_t *)(ram + offset + 2));

   // printf("%5d %5d\n", value[0], value[1]);

fprintf(fPointer, "%d \n", value[0]);

  }

But this is taking time in seconds to log. I am trying faster ways to log the data in file by copying the entire buffer to file but it is giving me wrong results. Can you point me to the right direction

pavel-demin commented 6 years ago

Do I understand correctly that your current requirements are to continuously record more than 120M samples at 125 MSPS?

If it's so, then I'm afraid that the Red Pitaya board doesn't meet these requirements.

falcon98 commented 6 years ago

I don't need continuous recording. It's just event based recording. I am trying to benchmark the board for my better understanding. I am sorry if it looked that way. Your triggered recording project is perfect .I am trying to integrate it in client server mode. This is an excellent platform for exploring embedded systems

pavel-demin commented 6 years ago

I don't need continuous recording.

OK. Thanks for the clarification.

I am attaching a bin file for your reference which I am reading with LabVIEW.

Since you're using LabVIEW, I'd suggest to implement the TCP client functionality directly in LabVIEW using the TCP Read and Type Cast functions.

pavel-demin commented 6 years ago

Your triggered recording project is perfect.

It's possible that there is a problem in the code sending the recorded data. I'd suggest to replace this part with the code from the mcpha project:

https://github.com/pavel-demin/red-pitaya-notes/blob/master/projects/mcpha/server/mcpha-server.c#L443-L459

falcon98 commented 6 years ago

Thanks for your reply Pavel. i will replace this part in adc-test project in this segment

while(!interrupted)
      {
        read(pipefd[0], &buffer, sizeof(buffer));
        if(send(sockClient, buf, 4096*1024, 0) < 0) break;

        read(pipefd[0], &buffer, sizeof(buffer));
        if(send(sockClient, buf + 4096*1024, 4096*1024, 0) < 0) break;
      }

I will test and update here soon.

pavel-demin commented 6 years ago

i will replace this part in adc-test project in this segment

The code to be replaced is in the adc-recorder-trigger.c:

https://github.com/pavel-demin/red-pitaya-notes/blob/master/projects/adc_recorder_trigger/adc-recorder-trigger.c#L67-L76

pavel-demin commented 6 years ago

BTW. Since your project doesn't require the continuous recording, I think that the adc_test project isn't the best starting point. I'd suggest to use the parts of the adc_recorder_trigger and mcpha projects.

falcon98 commented 6 years ago

Yes adc_recorder_trigger is simple to understand. I have tested MCPHA and it worked very well, but it is bit complicated for me to understand with complex TCL and C involved. I have started to work upon C , python and Zynq and gradually building my understanding.

Thanks a lot for your efforts.

falcon98 commented 6 years ago

BTW is it possible to combine continuous recording at low sampling speeds like 10KSps and event based recording on RP board. Can you suggest from where I can start. Thanks

pavel-demin commented 6 years ago

BTW is it possible to combine continuous recording at low sampling speeds like 10KSps and event based recording on RP board.

It depends on your other requirements. If the event rate isn't very high, then it's possible.

Can you suggest from where I can start.

I'm afraid that I can't suggest anything without seeing a detailed specification of your requirements.

falcon98 commented 6 years ago

The main requirements are :the event repetition rate is 10 Hz. In absence of event the required sampling is 10 kSps. During event sampling of 100 MSps is needed for duration of 10 ms (which will correspond to 2MB sample/channel). This system is for optical signals of plasma and maximum pulse length is 1 hour . Events will be in burst of 2-3 sec after every 50 sec when we fire laser in the plasma source.

I am trying to achieve this by RP. I will need both ADCs working for slow and fast acquisition.

One possible solution which I thought is the use of CIC filters with high decimation for achieving lower sampling rates for one ADC and connecting other ADC to RAM writer block directly. The fast acquisition path will get activated only on trigger like your oscilloscope function.

pavel-demin commented 6 years ago

Thanks for the details. Looks like the required rates are indeed within the capabilities of the Red Pitaya board.

I will need both ADCs working for slow and fast acquisition.

I'm not sure if I understand this part correctly. Are you planning to use one ADC for the fast acquisition and one ADC for the slow acquisition?

One possible solution which I thought is the use of CIC filters with high decimation for achieving lower sampling rates for one ADC and connecting other ADC to RAM writer block directly. The fast acquisition path will get activated only on trigger like your oscilloscope function.

I think that the slow continuous acquisition can be taken from the sdr_transceiver project and the fast acquisition can be taken from the adc_recorder_trigger and mcpha projects.

falcon98 commented 6 years ago

What I meant was that one ADC should be in continuous slow acquisition mode and another can be activated only during event(exactly like adc_recorder_trigger).

As you suggested I will study the sdr_transceiver project. I guess in this project data is available to host PC through python client for slow continuous acquisition. I will remove second ADC in this project and try modifying the code. Then I will try integrating this project with adc_recorder_trigger for second ADC with event based acquisition. Thanks for your support

bert24-53 commented 5 years ago

Hi David, Pavel.

I am trying to do something very close to what you are talking about :

I tried a axi_adc.c file from Nils 2015 and modify it to wirte a files and a python algo to convert binary to text ... but the data are not correct .. i dont think I get the right ram part ....

Do youthink your adc recorder can do this ??

thanks for your help

bert24-53 commented 5 years ago

Pavel : using the adc_recorder.c I have a "bus error" ... do you know what is the problem ??

I only have put the file on a RP classical environnement... no other thing....

for the adc_recorder : The level of the trigger is in V ?? what is the Input channel for the trigger ??

pavel-demin commented 5 years ago

using the adc_recorder.c I have a "bus error"

I suspect that you are using the adc-recorder.c program without configuring the FPGA with the correct bitstream file (adc_recorder.bit).

pavel-demin commented 5 years ago

for the adc_recorder : The level of the trigger is in V

The adc_recorder project doesn't have any trigger.

pavel-demin commented 5 years ago

acquiring 50K samples at 125Mhz and writing data in a file in the rp sd card. Do youthink your adc recorder can do this ??

The adc_recorder project decimates the ADC samples by a factor of 64.

To write the samples at 125 MSPS, the CIC and FIR filter should be removed from the FPGA configuration. It can be done by removing the lines 93-176 in adc_recorder/block_design.tcl and connecting pktzr_0/S_AXIS directly to adc_0/M_AXIS.

bert24-53 commented 5 years ago

using the adc_recorder.c I have a "bus error"

I suspect that you are using the adc-recorder.c program without configuring the FPGA with the correct bitstream file (adc_recorder.bit).

Maybe ... but how can I check that and correct it (where is the right file and what must be checked inside ??)

pavel-demin commented 5 years ago

but how can I check that and correct it (where is the right file and what must be checked inside

I don't know how to check it. Just make sure to configure the FPGA with the correct bitstream file (adc_recorder.bit) before running the adc-recorder.c program. It can be done with the following command:

cat adc_recorder.bit > /dev/xdevcfg

The instructions on how to build the bitstream files can be found at the following links: http://pavel-demin.github.io/red-pitaya-notes/led-blinker http://pavel-demin.github.io/red-pitaya-notes/development-machine

bert24-53 commented 5 years ago

cat adc_recorder.bit > /dev/xdevcfg

give an error : "No such file or directory" ....

I should use the SD image from https://www.dropbox.com/sh/5fy49wae6xwxa8a/AAD4bP_EekcJK0oBx2sNQm7Qa/red-pitaya-debian-8.9-armhf-20171205.zip?dl=1

pavel-demin commented 5 years ago

cat adc_recorder.bit > /dev/xdevcfg give an error : "No such file or directory"

The adc_recorder.bit should be built and then copied to Red Pitaya.

More instructions can be found at the links from my previous post.

I'd also suggest to have a look at the tutorials by Anton Potočnik: http://antonpotocnik.com/?cat=29

falcon98 commented 5 years ago

Hi bert You need to first solve the dev machine issue as pavel suggested. If you are looking for trigger based acquisition , then adc-recorder-trigger project is the one you should look into.

bert24-53 commented 5 years ago

ok. I understand that i must be in dev mode.. using vivado..

I did the tutorials by Anton Potočnik : it works fine on my system.

I suppose I have to do the same with the files in the folder adc-recorder-trigger :

I have an error " invalid command name cell" to create the project ...

pavel-demin commented 5 years ago

What OS is installed on your development machine?

If it's Linux, then the commands to build adc_recorder_trigger.bit are

cd red-pitaya-notes
make NAME=adc_recorder_trigger bit

If it's Windows, then open Vivado, and in the Tcl console, paste the following lines:

cd c:/#your-path-to-the-code#/red-pitaya-notes-master
source helpers/build-cores.tcl
set argv [list adc_recorder_trigger xc7z010clg400-1]
source scripts/project.tcl
bert24-53 commented 5 years ago

windows 7.

the diagram seems strange .. and the bitstream genetion failed ..

sorry, I probably did something wrong...

bert24-53 commented 5 years ago
##   clk_in1_n adc_clk_n_i
## }
ERROR: [BD 5-216] VLNV <xilinx.com:ip:clk_wiz:6.0> is not supported for the current part. The latest supported version for this part is:5.3
ERROR: [Common 17-39] 'create_bd_cell' failed due to earlier errors.

    while executing
"create_bd_cell -type ip -vlnv $cell_vlnv $cell_name"
    (procedure "cell" line 2)
    invoked from within
"cell xilinx.com:ip:clk_wiz:6.0 pll_0 {
  PRIMITIVE PLL
  PRIM_IN_FREQ.VALUE_SRC USER
  PRIM_IN_FREQ 125.0
  PRIM_SOURCE Differential_clock_capable_pin..."
    (file "projects/adc_recorder_trigger/block_design.tcl" line 2)

    while executing
"source projects/$project_name/block_design.tcl"
    (file "scripts/project.tcl" line 68)
pavel-demin commented 5 years ago

Looks like you have an old Vivado version. I'm currently using Vivado 2018.2.

bert24-53 commented 5 years ago

ok. with 2018, it works for adc-recorder. the output value are integer related to the tension , not directly tension ??

now doing the same for adc-recorder-trigger ...

bert24-53 commented 5 years ago

compilation warning :

`root@rp-f05950:~/SHORE/adc-recorder-trigger# gcc adc_recorder_trigger.c -o adc_recorder_trigger

adc_recorder_trigger.c: In function ‘main’:
adc_recorder_trigger.c:81:10: warning: passing argument 1 of ‘munmap’ discards ‘volatile’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   munmap(cfg, sysconf(_SC_PAGESIZE));
          ^
In file included from adc_recorder_trigger.c:4:0:
/usr/include/arm-linux-gnueabihf/sys/mman.h:76:12: note: expected ‘void *’ but argument is of type ‘volatile void *’
 extern int munmap (void *__addr, size_t __len) __THROW;
            ^
adc_recorder_trigger.c:82:10: warning: passing argument 1 of ‘munmap’ discards ‘volatile’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   munmap(sts, sysconf(_SC_PAGESIZE));
          ^
In file included from adc_recorder_trigger.c:4:0:
/usr/include/arm-linux-gnueabihf/sys/mman.h:76:12: note: expected ‘void *’ but argument is of type ‘volatile void *’
 extern int munmap (void *__addr, size_t __len) __THROW;
            ^
adc_recorder_trigger.c:83:10: warning: passing argument 1 of ‘munmap’ discards ‘volatile’ qualifier from pointer target type [-Wdiscarded-qualifiers]
   munmap(ram, sysconf(_SC_PAGESIZE));
          ^
In file included from adc_recorder_trigger.c:4:0:
/usr/include/arm-linux-gnueabihf/sys/mman.h:76:12: note: expected ‘void *’ but argument is of type ‘volatile void *’
 extern int munmap (void *__addr, size_t __len) __THROW;`
bert24-53 commented 5 years ago

and when executing, nothing happen .. adding a printf ("top") at the beginning of the main... nothing appears...

pavel-demin commented 5 years ago

Please try to post fewer trivial questions that could be answered by yourself after a few minutes of thinking and please try to read what is already written in my notes and in the linked documents.

A brief description of my Vivado work flow can be found in the LED blinker notes and in the slides of my presentation at Club Vivado 2016:

http://pavel-demin.github.io/red-pitaya-notes/led-blinker https://www.dropbox.com/sh/5fy49wae6xwxa8a/AACl--BhQvcNgjeQLRaiX9dha/ClubVivado2016_Pavel_Demin.pdf?dl=1

Most of the Tcl commands that I'm using are described in the following user guides:

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug892-vivado-design-flows-overview.pdf https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug888-vivado-design-flows-overview-tutorial.pdf https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug896-vivado-ip.pdf https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug894-vivado-tcl-scripting.pdf https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_2/ug835-vivado-tcl-commands.pdf

the output value are integer related to the tension , not directly tension ??

Yes, integer values.

to get 125MHz, by removing the lines 93-176 in adc_recorder/block_design.tcl is done before building bitstream. ?

If you edit adc_recorder/block_design.tcl, then it should be done before running source scripts/project.tcl.

It's also possible to remove the blocks between adc_0 and pktzr_0 in Vivado using the IP Integrator GUI.

and how do you connect pktzr_0/S_AXIS directly to adc_0/M_AXIS. is harwarde or in Vivado ??

If you edit adc_recorder/block_design.tcl, then replace S_AXIS fir_0/M_AXIS_DATA with S_AXIS adc_0/M_AXIS.

You can also connect them in Vivado using the IP Integrator GUI.

pavel-demin commented 5 years ago

and when executing, nothing happen ..

Executing what?

BTW. Please don't hesitate to provide more information that would help to understand your problem.

bert24-53 commented 5 years ago

and when executing, nothing happen ..

Executing what?

BTW. Please don't hesitate to provide more information that would help to understand your problem.

I am testing the adc-recorder-trigger which is close to what I want to do. I built the bitstream like for the adc-record. when i compile the file ; I have warning shown in the post before .. (munmap problem)

the file is built and when I use "./adc_recorder_trigger" , the system is waiting... and i add a line printf("mark"); at the beginning of the C file but it doesnt appears shwoing that the program doesnt start... maybe the command ...

pavel-demin commented 5 years ago

I think that adc-recorder-trigger is waiting for the data. The data should start to flow after a trigger event. In the default configuration, the trigger signal should be connected to the pin DIO0_P of the extension connector E1.

bert24-53 commented 5 years ago

OK !

I though that the signal trigger was catch from one of the channel A or channel B....

no matter with th warning during compilation, so.