Try using an mmap() pointer to read the registers themselves: It is much, much 
faster.  Of course, then you will be responsible for setting the right register 
bits to start conversions, wait until they are done, etc.  You still may want 
to open the device driver so the power and clock is turned on for the ADCs.  
You may also need to disable the ADC interrupts so the device driver does not 
interfere with your user-space code.

But you still have a basic problem with doing this from user-space:  Any system 
interrupt can take execution time and even run other threads when you need to 
be capturing your ADC samples.  Linux is not suitable for real-time aps that 
need to run below several milliseconds latency, even if you write your own 
device drivers.  This is why TI included the PRUs.  Get your code running in 
user-space, and then move the critical part to one of the PRUs.  They can run 
without interrupts to give you perfectly deterministic ADC sampling, so you 
could even run an FFT on the samples and get decent results.

From: John Syn 
Sent: Wednesday, February 19, 2014 9:55 AM
To: [email protected] 
Subject: Re: [beagleboard] Re: Help: "Fast" ADC sampling on the beagleboneblack


From: <[email protected]>
Reply-To: <[email protected]>
Date: Wednesday, February 19, 2014 at 5:53 AM
To: <[email protected]>
Subject: [beagleboard] Re: Help: "Fast" ADC sampling on the beagleboneblack


  Hi we fi 

  So how did it end up for you? I am having similar problem, would you care 
posting your solution?

  Regards
            Hernando

  On Monday, November 25, 2013 12:19:19 PM UTC+1, fe wi wrote: 
    Hi! 

    I am currently using my Beaglebone Black with the following KERNEL: 
3.8.13xenomai-bone28.1 (including the ti_am335_adc driver).

    Part of my Project is reading signals from an ADC and then processing them. 
I would love to use the onboard ADC for that, but I require to sample 5 
channels @ 2 kHz each. (I have installed the Xenomai Kernel mainly for 
processing purposes but it might be useful for sampling as well ;) )

    My first simplistic try was to just read the voltage values from the files 
provided in "/sys/bus/iio/devices/iio:device0/in_voltage0_raw" . 
    This works fine so far, but is just not fast enough. ( I get about 500 sps 
on ONE channel)

    Here is that part of my CODE: 
    for(;;) {

    rt_task_wait_period(NULL); // Xenomai

    now=rt_timer_read(); // Xenomai 

    // Work for the current period //

           FILE *read = fopen ( 
"/sys/bus/iio/devices/iio:device0/in_voltage0_raw", "r");
         

            fscanf (read, "%f", &value);
            float voltage = value * (1800.0/4095.0);   
            fprintf (write, "Value: %f    Voltage: %f\n", value, voltage);

                 printf("Time since last turn: %ld,%06ld ms    Value:%f   
Voltage: %f\n",
                           (long)(now - previous) / 1000000,
                           (long)(now - previous) % 1000000, value, voltage);
                           previous = now;

        fclose ( read );
        fclose ( write );

      }  
    (I know that leaving out the printf part and the voltage calculation 
increases performance, but still not enough)

    Is there any other way reading the values, directly from the memory 
location or a register? Perhaps using mmap? 
    Or is there a Xenomai function for reading from an iio device? (I couldn't 
find any...)

    I have seen two interesting links about continuous sampling:
    - 
http://beagleboard-gsoc13.blogspot.de/2013/07/sampling-analogue-signals-using-adc-on.html
Read the latest updates:

http://beagleboard-gsoc13.blogspot.com/2013/09/success-at-last.html

Regards,
John
    - http://processors.wiki.ti.com/index.php/AM335x_ADC_Driver%27s_Guide

    But i can't get the generic_buffer.c from those sites to work correctly (as 
the trigger handling seems to be outdated), plus i might need to know a kind of 
"oneshot" read function anyway to mux the 5 channels i want to sample. Or is it 
possible to continuous sample multiple channels? The Driver guide says 'no', 
but the Author from the other link seems to have worked a lot on the adc Driver 
since.

    I am currently trying to figure out the code in generic_buffer.c and the 
used iio_utils.h and the adc driver, but it is a lot of code and drivers are 
not my strong suit.
    So far I think I need to setup the ADC to my needs (somewhat similar to 
generic_buffer.c) and then read from it somehow, but I am really struggling 
with that!


    So now you know the state of my project :) but to sum it up:

    Are my demands (5 channels @ 2 kHz) even possible using only the on-board 
ADC?
    And if yes how do i read the values fast enough? Any tips?

    Thank you in advance!!


  -- 
  For more options, visit http://beagleboard.org/discuss
  --- 
  You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
  To unsubscribe from this group and stop receiving emails from it, send an 
email to [email protected].
  For more options, visit https://groups.google.com/groups/opt_out.

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to