cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
sarissabenz
Contributor
Contributor
1,261 Views
Registered: ‎04-27-2018

Application code can not read XADC fast enough!

Hello everyone!

 

I got my XADC working, so that I am able to read my external voltages.

Now I wrote an application code to read these two voltages, via file.open(...) -> file >> array -> file.close()

The problem is, that I want to read the voltages with 320kSamples per second.

But these three commands take to fast time. The fastest time in my eyes is, to read the raw-values directly from the register.

 

But I am so far a newbie, and feeling a bit lost, how to do this! And the internet also don't have examples.

Is there a way/is someone having examples, to read these registers?

 

Hope someone could help me!

 

thanks!

 

 

@klumsde

0 Kudos
11 Replies
drjohnsmith
Teacher
Teacher
1,255 Views
Registered: ‎07-09-2009

To I under stand your reading a single value from the adc, via a processor,

 

which chip , tools an languages / strategies you using ?

 

where do you think the time is being taken ?

   

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
sarissabenz
Contributor
Contributor
1,250 Views
Registered: ‎04-27-2018

Sorry forgot these informations:

I use the Zybo Z7-20 Board from Digilent.

I have PetaLinux running on the PL.

 

I want to read two channels

 

My program code is in C++.

 

The time is taken from the commands:

 

file.read("path");

file >> array_to_save_the_voltage;

file.(close);

---> I need here arround 65 to 70 usec

0 Kudos
drjohnsmith
Teacher
Teacher
1,243 Views
Registered: ‎07-09-2009

You asking about how fast can you do something,

 

The question you need to know the answer for is   how long does each of the line ls of code take ?

 

Once you have some numbers you can delve into the solution

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
sarissabenz
Contributor
Contributor
1,234 Views
Registered: ‎04-27-2018

I know, that the way of my solution is to slow.

So I am looking for a faster way.

 

The faster way is to read the voltages directly from the registers. Work directly from the registers.

 

But I find no where examples or solutions.

 

How would you solve this problem, is there another way to solve it?

0 Kudos
drjohnsmith
Teacher
Teacher
1,221 Views
Registered: ‎07-09-2009

You ask how I would solve this problem

 

Like all problems, understand and quantify the problem is always the first step.

 

In your case, as a new to this,

 

you need to find out how long each of the different parts of your current solution take, 

 

Do you know how to get that timing information ?

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
sarissabenz
Contributor
Contributor
1,217 Views
Registered: ‎04-27-2018

The times are:

for read, write and close: 70uSec

multiplied for 2 channels: 140uSec.

 

And I know that to open a file (/sys/bus/iio/devices/iio\:device1/....) and to read is taking VERY long

 

 

0 Kudos
drjohnsmith
Teacher
Teacher
1,196 Views
Registered: ‎07-09-2009

Can I ask, are you after learning how, or heres the answer ?

 

 

 

 

 

<== If this was helpful, please feel free to give Kudos, and close if it answers your question ==>
0 Kudos
sarissabenz
Contributor
Contributor
1,185 Views
Registered: ‎04-27-2018

Is there a way to read the XADC like a GPIO button, with the function?

 

inline unsigned int gpio_read(void *gpio_base, unsigned int offset){

  return *((volatile unsigned *)(gpio_base + offset));

}

 

And if yes, where can I find the gpio_base (in the case of the XADC, the XADC_base?) and the offset?

0 Kudos
sarissabenz
Contributor
Contributor
1,111 Views
Registered: ‎04-27-2018

Hello again!

I wrote now some application code for the linux. to read directly the external voltages from the registers.

As an attachment you can see my code.

 

The offsets for VAUX6 and VAUX14 (0x16 and 0x1E) i rote in the XADC data sheet. But when I try to map from /dev/iio:device1, i get the message, that I am not able to map. And if I want to map from /dev/mem (with the same offsets) I get wrong values.

 

Can someone help me, why I can not map from /dev/iio:device1. Or that are the right offsets for /dev/mem/

 

Thanks a lot for your help ;-)

 

@klumsde

0 Kudos
sarissabenz
Contributor
Contributor
798 Views
Registered: ‎04-27-2018

sorry, forgot the attachment

 

or here is the code:

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <cstring>
#include <ctime>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/socket.h>

#define MAP_SIZE    0x10000
#define XADC_CHANNEL_US    0x16    //VAUX6
#define XADC_CHANNEL_IR    0x1E    //VAUX14

unsigned int read_data(void *base, unsigned int offset){
    return *((volatile unsigned *)(base + offset));
}

int main(int arg, char *argv[]){
    int fd_xadc;
    char *xadc_val = "/dev/iio:device1";
    //char *xadc_val = "/dev/mem";
    void *xadc_val_ptr;

    int i;
    unsigned int VolUS[i], VolIR[i];
    //char BuffVolUS[i], BuffVolIR[i];

    //++++++++++MAPPING++++++++++//
    fd_xadc = open(xadc_val, O_RDWR|O_SYNC);
    if (fd_xadc < 1){
        printf("Invalid XADC device file of Segment: %s\n", xadc_val);
        return -1;
    }
    xadc_val_ptr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd_xadc, 0);
    if (xadc_val_ptr == MAP_FAILED){
        printf("Mmap of XADC failed\n");
        return -1;
    }

    //++++++++++READ++++++++++//
    for(i=0;i<100;i++){
        VolUS[i] = read_data(xadc_val_ptr, XADC_CHANNEL_US);
        VolIR[i] = read_data(xadc_val_ptr, XADC_CHANNEL_IR);
        //sprintf(BuffVolUS[i], "%d", VolUS[i]);
        //sprintf(BuffVolIR[i], "%d", VolIR[i]);

        printf("%i --- %i\n", VolUS[i], VolIR[i]);
    }

    return 0;
}

 

0 Kudos
sarissabenz
Contributor
Contributor
774 Views
Registered: ‎04-27-2018

Found my mistake! I didn't add the baseaddress to the mmap command.

 

But now I can not see any voltages print.

I read something about disable the driver.

so I added to system-user.dtsi a   status = "disabled";

 

If i boot now my petalinux, in /dev/ there is the xadc not appearing.

But the voltages I print are still: 0

 

Does someone know why?

0 Kudos